1
by OV2
Initial 1.52 import |
1 |
/***********************************************************************************
|
2 |
Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
|
|
3 |
||
4 |
(c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com),
|
|
5 |
Jerremy Koot (jkoot@snes9x.com)
|
|
6 |
||
7 |
(c) Copyright 2002 - 2004 Matthew Kendora
|
|
8 |
||
9 |
(c) Copyright 2002 - 2005 Peter Bortas (peter@bortas.org)
|
|
10 |
||
11 |
(c) Copyright 2004 - 2005 Joel Yliluoma (http://iki.fi/bisqwit/)
|
|
12 |
||
13 |
(c) Copyright 2001 - 2006 John Weidman (jweidman@slip.net)
|
|
14 |
||
15 |
(c) Copyright 2002 - 2006 funkyass (funkyass@spam.shaw.ca),
|
|
16 |
Kris Bleakley (codeviolation@hotmail.com)
|
|
17 |
||
18 |
(c) Copyright 2002 - 2010 Brad Jorsch (anomie@users.sourceforge.net),
|
|
19 |
Nach (n-a-c-h@users.sourceforge.net),
|
|
87
by OV2
Update copyright in all files |
20 |
|
21 |
(c) Copyright 2002 - 2011 zones (kasumitokoduck@yahoo.com)
|
|
1
by OV2
Initial 1.52 import |
22 |
|
23 |
(c) Copyright 2006 - 2007 nitsuja
|
|
24 |
||
290
by Brandon Wright
Update some copyrights, bump version number. |
25 |
(c) Copyright 2009 - 2016 BearOso,
|
1
by OV2
Initial 1.52 import |
26 |
OV2
|
27 |
||
28 |
||
29 |
BS-X C emulator code
|
|
30 |
(c) Copyright 2005 - 2006 Dreamer Nom,
|
|
31 |
zones
|
|
32 |
||
33 |
C4 x86 assembler and some C emulation code
|
|
34 |
(c) Copyright 2000 - 2003 _Demo_ (_demo_@zsnes.com),
|
|
35 |
Nach,
|
|
36 |
zsKnight (zsknight@zsnes.com)
|
|
37 |
||
38 |
C4 C++ code
|
|
39 |
(c) Copyright 2003 - 2006 Brad Jorsch,
|
|
40 |
Nach
|
|
41 |
||
42 |
DSP-1 emulator code
|
|
43 |
(c) Copyright 1998 - 2006 _Demo_,
|
|
44 |
Andreas Naive (andreasnaive@gmail.com),
|
|
45 |
Gary Henderson,
|
|
46 |
Ivar (ivar@snes9x.com),
|
|
47 |
John Weidman,
|
|
48 |
Kris Bleakley,
|
|
49 |
Matthew Kendora,
|
|
50 |
Nach,
|
|
51 |
neviksti (neviksti@hotmail.com)
|
|
52 |
||
53 |
DSP-2 emulator code
|
|
54 |
(c) Copyright 2003 John Weidman,
|
|
55 |
Kris Bleakley,
|
|
56 |
Lord Nightmare (lord_nightmare@users.sourceforge.net),
|
|
57 |
Matthew Kendora,
|
|
58 |
neviksti
|
|
59 |
||
60 |
DSP-3 emulator code
|
|
61 |
(c) Copyright 2003 - 2006 John Weidman,
|
|
62 |
Kris Bleakley,
|
|
63 |
Lancer,
|
|
64 |
z80 gaiden
|
|
65 |
||
66 |
DSP-4 emulator code
|
|
67 |
(c) Copyright 2004 - 2006 Dreamer Nom,
|
|
68 |
John Weidman,
|
|
69 |
Kris Bleakley,
|
|
70 |
Nach,
|
|
71 |
z80 gaiden
|
|
72 |
||
73 |
OBC1 emulator code
|
|
74 |
(c) Copyright 2001 - 2004 zsKnight,
|
|
75 |
pagefault (pagefault@zsnes.com),
|
|
76 |
Kris Bleakley
|
|
77 |
Ported from x86 assembler to C by sanmaiwashi
|
|
78 |
||
79 |
SPC7110 and RTC C++ emulator code used in 1.39-1.51
|
|
80 |
(c) Copyright 2002 Matthew Kendora with research by
|
|
81 |
zsKnight,
|
|
82 |
John Weidman,
|
|
83 |
Dark Force
|
|
84 |
||
85 |
SPC7110 and RTC C++ emulator code used in 1.52+
|
|
86 |
(c) Copyright 2009 byuu,
|
|
87 |
neviksti
|
|
88 |
||
89 |
S-DD1 C emulator code
|
|
90 |
(c) Copyright 2003 Brad Jorsch with research by
|
|
91 |
Andreas Naive,
|
|
92 |
John Weidman
|
|
93 |
||
94 |
S-RTC C emulator code
|
|
95 |
(c) Copyright 2001 - 2006 byuu,
|
|
96 |
John Weidman
|
|
97 |
||
98 |
ST010 C++ emulator code
|
|
99 |
(c) Copyright 2003 Feather,
|
|
100 |
John Weidman,
|
|
101 |
Kris Bleakley,
|
|
102 |
Matthew Kendora
|
|
103 |
||
104 |
Super FX x86 assembler emulator code
|
|
105 |
(c) Copyright 1998 - 2003 _Demo_,
|
|
106 |
pagefault,
|
|
107 |
zsKnight
|
|
108 |
||
109 |
Super FX C emulator code
|
|
110 |
(c) Copyright 1997 - 1999 Ivar,
|
|
111 |
Gary Henderson,
|
|
112 |
John Weidman
|
|
113 |
||
114 |
Sound emulator code used in 1.5-1.51
|
|
115 |
(c) Copyright 1998 - 2003 Brad Martin
|
|
116 |
(c) Copyright 1998 - 2006 Charles Bilyue'
|
|
117 |
||
118 |
Sound emulator code used in 1.52+
|
|
119 |
(c) Copyright 2004 - 2007 Shay Green (gblargg@gmail.com)
|
|
120 |
||
295
by Brandon Wright
Add byuu copyright for his S-SMP |
121 |
S-SMP emulator code used in 1.54+
|
122 |
(c) Copyright 2016 byuu
|
|
123 |
||
1
by OV2
Initial 1.52 import |
124 |
SH assembler code partly based on x86 assembler code
|
125 |
(c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se)
|
|
126 |
||
127 |
2xSaI filter
|
|
128 |
(c) Copyright 1999 - 2001 Derek Liauw Kie Fa
|
|
129 |
||
130 |
HQ2x, HQ3x, HQ4x filters
|
|
131 |
(c) Copyright 2003 Maxim Stepin (maxim@hiend3d.com)
|
|
132 |
||
133 |
NTSC filter
|
|
134 |
(c) Copyright 2006 - 2007 Shay Green
|
|
135 |
||
136 |
GTK+ GUI code
|
|
290
by Brandon Wright
Update some copyrights, bump version number. |
137 |
(c) Copyright 2004 - 2016 BearOso
|
1
by OV2
Initial 1.52 import |
138 |
|
139 |
Win32 GUI code
|
|
140 |
(c) Copyright 2003 - 2006 blip,
|
|
141 |
funkyass,
|
|
142 |
Matthew Kendora,
|
|
143 |
Nach,
|
|
144 |
nitsuja
|
|
298
by Brandon Wright
Bump OV2 Windows port copyright. |
145 |
(c) Copyright 2009 - 2016 OV2
|
1
by OV2
Initial 1.52 import |
146 |
|
147 |
Mac OS GUI code
|
|
148 |
(c) Copyright 1998 - 2001 John Stiles
|
|
87
by OV2
Update copyright in all files |
149 |
(c) Copyright 2001 - 2011 zones
|
1
by OV2
Initial 1.52 import |
150 |
|
151 |
||
152 |
Specific ports contains the works of other authors. See headers in
|
|
153 |
individual files.
|
|
154 |
||
155 |
||
156 |
Snes9x homepage: http://www.snes9x.com/
|
|
157 |
||
158 |
Permission to use, copy, modify and/or distribute Snes9x in both binary
|
|
159 |
and source form, for non-commercial purposes, is hereby granted without
|
|
160 |
fee, providing that this license information and copyright notice appear
|
|
161 |
with all copies and any derived work.
|
|
162 |
||
163 |
This software is provided 'as-is', without any express or implied
|
|
164 |
warranty. In no event shall the authors be held liable for any damages
|
|
165 |
arising from the use of this software or it's derivatives.
|
|
166 |
||
167 |
Snes9x is freeware for PERSONAL USE only. Commercial users should
|
|
168 |
seek permission of the copyright holders first. Commercial use includes,
|
|
169 |
but is not limited to, charging money for Snes9x or software derived from
|
|
170 |
Snes9x, including Snes9x or derivatives in commercial game bundles, and/or
|
|
171 |
using Snes9x as a promotion for your commercial product.
|
|
172 |
||
173 |
The copyright holders request that bug fixes and improvements to the code
|
|
174 |
should be forwarded to them so everyone can benefit from the modifications
|
|
175 |
in future versions.
|
|
176 |
||
177 |
Super NES and Super Nintendo Entertainment System are trademarks of
|
|
178 |
Nintendo Co., Limited and its subsidiary companies.
|
|
179 |
***********************************************************************************/
|
|
180 |
||
181 |
/***********************************************************************************
|
|
182 |
SNES9X for Mac OS (c) Copyright John Stiles
|
|
183 |
||
184 |
Snes9x for Mac OS X
|
|
185 |
||
85
by zones
Update changelog / update minizip to 1.01h / update docs / Mac: changed MusicBox to Cocoa interface |
186 |
(c) Copyright 2001 - 2011 zones
|
1
by OV2
Initial 1.52 import |
187 |
(c) Copyright 2002 - 2005 107
|
188 |
(c) Copyright 2002 PB1400c
|
|
189 |
(c) Copyright 2004 Alexander and Sander
|
|
190 |
(c) Copyright 2004 - 2005 Steven Seeger
|
|
191 |
(c) Copyright 2005 Ryan Vogt
|
|
192 |
***********************************************************************************/
|
|
193 |
||
194 |
||
195 |
#include "port.h" |
|
196 |
||
197 |
#include <IOKit/hid/IOHIDUsageTables.h> |
|
198 |
#include "HID_Utilities_External.h" |
|
199 |
||
200 |
#include "mac-prefix.h" |
|
201 |
#include "mac-dialog.h" |
|
202 |
#include "mac-os.h" |
|
203 |
#include "mac-joypad.h" |
|
204 |
||
205 |
#define kUp(i) (i * 4)
|
|
206 |
#define kDn(i) (i * 4 + 1)
|
|
207 |
#define kLf(i) (i * 4 + 2)
|
|
208 |
#define kRt(i) (i * 4 + 3)
|
|
209 |
||
210 |
#define kPadElemTypeNone 0
|
|
211 |
#define kPadElemTypeHat4 1
|
|
212 |
#define kPadElemTypeHat8 2
|
|
213 |
#define kPadElemTypeAxis 3
|
|
214 |
#define kPadElemTypeButton 4
|
|
215 |
#define kPadElemTypeOtherHat4 5
|
|
216 |
#define kPadElemTypeOtherHat8 6
|
|
217 |
||
218 |
#define kPadXAxis 1
|
|
219 |
#define kPadYAxis 0
|
|
220 |
#define kPadHat 0
|
|
221 |
||
222 |
#define kMaskUp 0x0800
|
|
223 |
#define kMaskDn 0x0400
|
|
224 |
#define kMaskLf 0x0200
|
|
225 |
#define kMaskRt 0x0100
|
|
226 |
||
227 |
typedef hu_device_t *pRecDevice; |
|
228 |
typedef hu_element_t *pRecElement; |
|
229 |
||
230 |
typedef struct actionStruct |
|
231 |
{
|
|
232 |
pRecDevice fDevice; |
|
233 |
pRecElement fElement; |
|
234 |
long fValue; |
|
235 |
long fOldValue; |
|
236 |
} actionRec, *actionPtr; |
|
237 |
||
238 |
typedef struct padDirectionInfo |
|
239 |
{
|
|
240 |
int type; |
|
241 |
pRecDevice device [2]; |
|
242 |
pRecElement element[2]; |
|
243 |
long max [2]; |
|
244 |
long maxmid [2]; |
|
245 |
long mid [2]; |
|
246 |
long midmin [2]; |
|
247 |
long min [2]; |
|
248 |
} directionInfo; |
|
249 |
||
250 |
static actionRec gActionRecs[kNeedCount]; |
|
251 |
static directionInfo gDirectionInfo[MAC_MAX_PLAYERS]; |
|
252 |
static int gDirectionHint[MAC_MAX_PLAYERS]; |
|
253 |
||
254 |
static const HIViewID gControlIDs[kNeedCount] = |
|
255 |
{
|
|
256 |
{ '1_Up', 0 }, |
|
257 |
{ '1_Dn', 0 }, |
|
258 |
{ '1_Lf', 0 }, |
|
259 |
{ '1_Rt', 0 }, |
|
260 |
||
261 |
{ '2_Up', 0 }, |
|
262 |
{ '2_Dn', 0 }, |
|
263 |
{ '2_Lf', 0 }, |
|
264 |
{ '2_Rt', 0 }, |
|
265 |
||
266 |
{ '3_Up', 0 }, |
|
267 |
{ '3_Dn', 0 }, |
|
268 |
{ '3_Lf', 0 }, |
|
269 |
{ '3_Rt', 0 }, |
|
270 |
||
271 |
{ '4_Up', 0 }, |
|
272 |
{ '4_Dn', 0 }, |
|
273 |
{ '4_Lf', 0 }, |
|
274 |
{ '4_Rt', 0 }, |
|
275 |
||
276 |
{ '5_Up', 0 }, |
|
277 |
{ '5_Dn', 0 }, |
|
278 |
{ '5_Lf', 0 }, |
|
279 |
{ '5_Rt', 0 }, |
|
280 |
||
281 |
{ '6_Up', 0 }, |
|
282 |
{ '6_Dn', 0 }, |
|
283 |
{ '6_Lf', 0 }, |
|
284 |
{ '6_Rt', 0 }, |
|
285 |
||
286 |
{ '7_Up', 0 }, |
|
287 |
{ '7_Dn', 0 }, |
|
288 |
{ '7_Lf', 0 }, |
|
289 |
{ '7_Rt', 0 }, |
|
290 |
||
291 |
{ '8_Up', 0 }, |
|
292 |
{ '8_Dn', 0 }, |
|
293 |
{ '8_Lf', 0 }, |
|
294 |
{ '8_Rt', 0 }, |
|
295 |
||
296 |
{ '1__B', 0 }, |
|
297 |
{ '1__A', 0 }, |
|
298 |
{ '1__X', 0 }, |
|
299 |
{ '1__Y', 0 }, |
|
300 |
{ '1__L', 0 }, |
|
301 |
{ '1__R', 0 }, |
|
302 |
{ '1Sel', 0 }, |
|
303 |
{ '1Srt', 0 }, |
|
304 |
||
305 |
{ '2__B', 0 }, |
|
306 |
{ '2__A', 0 }, |
|
307 |
{ '2__X', 0 }, |
|
308 |
{ '2__Y', 0 }, |
|
309 |
{ '2__L', 0 }, |
|
310 |
{ '2__R', 0 }, |
|
311 |
{ '2Sel', 0 }, |
|
312 |
{ '2Srt', 0 }, |
|
313 |
||
314 |
{ '3__B', 0 }, |
|
315 |
{ '3__A', 0 }, |
|
316 |
{ '3__X', 0 }, |
|
317 |
{ '3__Y', 0 }, |
|
318 |
{ '3__L', 0 }, |
|
319 |
{ '3__R', 0 }, |
|
320 |
{ '3Sel', 0 }, |
|
321 |
{ '3Srt', 0 }, |
|
322 |
||
323 |
{ '4__B', 0 }, |
|
324 |
{ '4__A', 0 }, |
|
325 |
{ '4__X', 0 }, |
|
326 |
{ '4__Y', 0 }, |
|
327 |
{ '4__L', 0 }, |
|
328 |
{ '4__R', 0 }, |
|
329 |
{ '4Sel', 0 }, |
|
330 |
{ '4Srt', 0 }, |
|
331 |
||
332 |
{ '5__B', 0 }, |
|
333 |
{ '5__A', 0 }, |
|
334 |
{ '5__X', 0 }, |
|
335 |
{ '5__Y', 0 }, |
|
336 |
{ '5__L', 0 }, |
|
337 |
{ '5__R', 0 }, |
|
338 |
{ '5Sel', 0 }, |
|
339 |
{ '5Srt', 0 }, |
|
340 |
||
341 |
{ '6__B', 0 }, |
|
342 |
{ '6__A', 0 }, |
|
343 |
{ '6__X', 0 }, |
|
344 |
{ '6__Y', 0 }, |
|
345 |
{ '6__L', 0 }, |
|
346 |
{ '6__R', 0 }, |
|
347 |
{ '6Sel', 0 }, |
|
348 |
{ '6Srt', 0 }, |
|
349 |
||
350 |
{ '7__B', 0 }, |
|
351 |
{ '7__A', 0 }, |
|
352 |
{ '7__X', 0 }, |
|
353 |
{ '7__Y', 0 }, |
|
354 |
{ '7__L', 0 }, |
|
355 |
{ '7__R', 0 }, |
|
356 |
{ '7Sel', 0 }, |
|
357 |
{ '7Srt', 0 }, |
|
358 |
||
359 |
{ '8__B', 0 }, |
|
360 |
{ '8__A', 0 }, |
|
361 |
{ '8__X', 0 }, |
|
362 |
{ '8__Y', 0 }, |
|
363 |
{ '8__L', 0 }, |
|
364 |
{ '8__R', 0 }, |
|
365 |
{ '8Sel', 0 }, |
|
366 |
{ '8Srt', 0 }, |
|
367 |
||
368 |
{ '__FF', 0 }, |
|
369 |
{ '_Frz', 0 }, |
|
370 |
{ '_DeF', 0 }, |
|
371 |
{ '_Snp', 0 }, |
|
372 |
{ '_Esc', 0 }, |
|
373 |
{ '_SPC', 0 }, |
|
374 |
{ 'MouL', 0 }, |
|
375 |
{ 'MouR', 0 }, |
|
376 |
{ 'ScoT', 0 }, |
|
377 |
{ 'ScoP', 0 }, |
|
378 |
{ 'ScoC', 0 }, |
|
379 |
{ 'Ofsc', 0 }, |
|
380 |
{ '__Fn', 0 }, |
|
381 |
{ '_Alt', 0 }, |
|
382 |
{ 'FFUp', 0 }, |
|
383 |
{ 'FFDn', 0 }, |
|
384 |
{ '__TC', 0 } |
|
385 |
};
|
|
386 |
||
387 |
static char gNeeds[kNeedCount][64] = |
|
388 |
{
|
|
389 |
"1P Up", |
|
390 |
"1P Down", |
|
391 |
"1P Left", |
|
392 |
"1P Right", |
|
393 |
||
394 |
"2P Up", |
|
395 |
"2P Down", |
|
396 |
"2P Left", |
|
397 |
"2P Right", |
|
398 |
||
399 |
"3P Up", |
|
400 |
"3P Down", |
|
401 |
"3P Left", |
|
402 |
"3P Right", |
|
403 |
||
404 |
"4P Up", |
|
405 |
"4P Down", |
|
406 |
"4P Left", |
|
407 |
"4P Right", |
|
408 |
||
409 |
"5P Up", |
|
410 |
"5P Down", |
|
411 |
"5P Left", |
|
412 |
"5P Right", |
|
413 |
||
414 |
"6P Up", |
|
415 |
"6P Down", |
|
416 |
"6P Left", |
|
417 |
"6P Right", |
|
418 |
||
419 |
"7P Up", |
|
420 |
"7P Down", |
|
421 |
"7P Left", |
|
422 |
"7P Right", |
|
423 |
||
424 |
"8P Up", |
|
425 |
"8P Down", |
|
426 |
"8P Left", |
|
427 |
"8P Right", |
|
428 |
||
429 |
"1P B Button", |
|
430 |
"1P A Button", |
|
431 |
"1P X Button", |
|
432 |
"1P Y Button", |
|
433 |
"1P L Button", |
|
434 |
"1P R Button", |
|
435 |
"1P Select", |
|
436 |
"1P Start", |
|
437 |
||
438 |
"2P B Button", |
|
439 |
"2P A Button", |
|
440 |
"2P X Button", |
|
441 |
"2P Y Button", |
|
442 |
"2P L Button", |
|
443 |
"2P R Button", |
|
444 |
"2P Select", |
|
445 |
"2P Start", |
|
446 |
||
447 |
"3P B Button", |
|
448 |
"3P A Button", |
|
449 |
"3P X Button", |
|
450 |
"3P Y Button", |
|
451 |
"3P L Button", |
|
452 |
"3P R Button", |
|
453 |
"3P Select", |
|
454 |
"3P Start", |
|
455 |
||
456 |
"4P B Button", |
|
457 |
"4P A Button", |
|
458 |
"4P X Button", |
|
459 |
"4P Y Button", |
|
460 |
"4P L Button", |
|
461 |
"4P R Button", |
|
462 |
"4P Select", |
|
463 |
"4P Start", |
|
464 |
||
465 |
"5P B Button", |
|
466 |
"5P A Button", |
|
467 |
"5P X Button", |
|
468 |
"5P Y Button", |
|
469 |
"5P L Button", |
|
470 |
"5P R Button", |
|
471 |
"5P Select", |
|
472 |
"5P Start", |
|
473 |
||
474 |
"6P B Button", |
|
475 |
"6P A Button", |
|
476 |
"6P X Button", |
|
477 |
"6P Y Button", |
|
478 |
"6P L Button", |
|
479 |
"6P R Button", |
|
480 |
"6P Select", |
|
481 |
"6P Start", |
|
482 |
||
483 |
"7P B Button", |
|
484 |
"7P A Button", |
|
485 |
"7P X Button", |
|
486 |
"7P Y Button", |
|
487 |
"7P L Button", |
|
488 |
"7P R Button", |
|
489 |
"7P Select", |
|
490 |
"7P Start", |
|
491 |
||
492 |
"8P B Button", |
|
493 |
"8P A Button", |
|
494 |
"8P X Button", |
|
495 |
"8P Y Button", |
|
496 |
"8P L Button", |
|
497 |
"8P R Button", |
|
498 |
"8P Select", |
|
499 |
"8P Start", |
|
500 |
||
501 |
"Fast Forward", |
|
502 |
"Freeze Game", |
|
503 |
"Defrost Game", |
|
504 |
"Screenshot", |
|
505 |
"Break", |
|
506 |
"Save SPC", |
|
507 |
"Mouse Left", |
|
508 |
"Mouse Right", |
|
509 |
"Scope Turbo", |
|
510 |
"Scope Pause", |
|
511 |
"Scope Cursor", |
|
512 |
"Offscreen", |
|
513 |
"Fn Modifier", |
|
514 |
"Alt Modifier", |
|
515 |
"Turbo Speed Up", |
|
516 |
"Turbo Speed Down", |
|
517 |
"Turbo Control Modifier"
|
|
518 |
};
|
|
519 |
||
520 |
static int gIconNumber[kNeedCount] = |
|
521 |
{
|
|
522 |
0, |
|
523 |
1, |
|
524 |
2, |
|
525 |
3, |
|
526 |
||
527 |
12, |
|
528 |
13, |
|
529 |
14, |
|
530 |
15, |
|
531 |
||
532 |
24, |
|
533 |
25, |
|
534 |
26, |
|
535 |
27, |
|
536 |
||
537 |
36, |
|
538 |
37, |
|
539 |
38, |
|
540 |
39, |
|
541 |
||
542 |
48, |
|
543 |
49, |
|
544 |
50, |
|
545 |
51, |
|
546 |
||
547 |
60, |
|
548 |
61, |
|
549 |
62, |
|
550 |
63, |
|
551 |
||
552 |
72, |
|
553 |
73, |
|
554 |
74, |
|
555 |
75, |
|
556 |
||
557 |
84, |
|
558 |
85, |
|
559 |
86, |
|
560 |
87, |
|
561 |
||
562 |
5, |
|
563 |
7, |
|
564 |
6, |
|
565 |
4, |
|
566 |
8, |
|
567 |
9, |
|
568 |
11, |
|
569 |
10, |
|
570 |
||
571 |
17, |
|
572 |
19, |
|
573 |
18, |
|
574 |
16, |
|
575 |
20, |
|
576 |
21, |
|
577 |
23, |
|
578 |
22, |
|
579 |
||
580 |
29, |
|
581 |
31, |
|
582 |
30, |
|
583 |
28, |
|
584 |
32, |
|
585 |
33, |
|
586 |
35, |
|
587 |
34, |
|
588 |
||
589 |
41, |
|
590 |
43, |
|
591 |
42, |
|
592 |
40, |
|
593 |
44, |
|
594 |
45, |
|
595 |
47, |
|
596 |
46, |
|
597 |
||
598 |
53, |
|
599 |
55, |
|
600 |
54, |
|
601 |
52, |
|
602 |
56, |
|
603 |
57, |
|
604 |
59, |
|
605 |
58, |
|
606 |
||
607 |
65, |
|
608 |
67, |
|
609 |
66, |
|
610 |
64, |
|
611 |
68, |
|
612 |
69, |
|
613 |
71, |
|
614 |
70, |
|
615 |
||
616 |
77, |
|
617 |
79, |
|
618 |
78, |
|
619 |
76, |
|
620 |
80, |
|
621 |
81, |
|
622 |
83, |
|
623 |
82, |
|
624 |
||
625 |
89, |
|
626 |
91, |
|
627 |
90, |
|
628 |
88, |
|
629 |
92, |
|
630 |
93, |
|
631 |
95, |
|
632 |
94, |
|
633 |
||
634 |
101, |
|
635 |
102, |
|
636 |
103, |
|
637 |
104, |
|
638 |
114, |
|
639 |
105, |
|
640 |
116, |
|
641 |
117, |
|
642 |
106, |
|
643 |
107, |
|
644 |
108, |
|
645 |
109, |
|
646 |
110, |
|
647 |
111, |
|
648 |
112, |
|
649 |
113, |
|
650 |
115
|
|
651 |
};
|
|
652 |
||
653 |
static void JoypadSetDirectionInfo (void); |
|
654 |
static pascal void IdleTimer (EventLoopTimerRef, void *); |
|
655 |
static pascal OSStatus ControllerEventHandler (EventHandlerCallRef, EventRef, void *); |
|
656 |
||
657 |
||
658 |
void SaveControllerSettings (void) |
|
659 |
{
|
|
660 |
CFStringRef keyCFStringRef; |
|
661 |
Boolean syncFlag; |
|
662 |
||
663 |
JoypadSetDirectionInfo(); |
|
664 |
||
665 |
for (int a = 0; a < kNeedCount; a++) |
|
666 |
{
|
|
667 |
char needCStr[64], num[10]; |
|
668 |
||
669 |
strcpy(needCStr, gNeeds[a]); |
|
670 |
if (padSetting > 1) |
|
671 |
{
|
|
672 |
sprintf(num, "_%d", padSetting); |
|
673 |
strcat(needCStr, num); |
|
674 |
}
|
|
675 |
||
676 |
keyCFStringRef = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, CFSTR("%s"), needCStr); |
|
677 |
if (keyCFStringRef) |
|
678 |
{
|
|
679 |
if (gActionRecs[a].fDevice && gActionRecs[a].fElement) |
|
680 |
syncFlag = HIDSaveElementPref(keyCFStringRef, kCFPreferencesCurrentApplication, gActionRecs[a].fDevice, gActionRecs[a].fElement); |
|
681 |
else
|
|
682 |
CFPreferencesSetAppValue(keyCFStringRef, NULL, kCFPreferencesCurrentApplication); |
|
683 |
||
684 |
CFRelease(keyCFStringRef); |
|
685 |
}
|
|
686 |
}
|
|
687 |
||
688 |
for (int a = 0; a < MAC_MAX_PLAYERS; a++) |
|
689 |
{
|
|
690 |
keyCFStringRef = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, CFSTR("DirectionHint_%d_%d"), a, padSetting); |
|
691 |
if (keyCFStringRef) |
|
692 |
{
|
|
693 |
CFNumberRef numRef; |
|
694 |
CFIndex v; |
|
695 |
||
696 |
v = (CFIndex) gDirectionHint[a]; |
|
697 |
numRef = CFNumberCreate(kCFAllocatorDefault, kCFNumberCFIndexType, &v); |
|
698 |
if (numRef) |
|
699 |
{
|
|
700 |
CFPreferencesSetAppValue(keyCFStringRef, numRef, kCFPreferencesCurrentApplication); |
|
701 |
CFRelease(numRef); |
|
702 |
}
|
|
703 |
||
704 |
CFRelease(keyCFStringRef); |
|
705 |
}
|
|
706 |
}
|
|
707 |
||
708 |
CFPreferencesAppSynchronize(kCFPreferencesCurrentApplication); |
|
709 |
}
|
|
710 |
||
711 |
void LoadControllerSettings (void) |
|
712 |
{
|
|
713 |
CFStringRef keyCFStringRef; |
|
714 |
||
715 |
for (int a = 0; a < kNeedCount; a++) |
|
716 |
{
|
|
717 |
pRecDevice pDevice = NULL; |
|
718 |
pRecElement pElement = NULL; |
|
719 |
Boolean r = false; |
|
720 |
char needCStr[64], num[10]; |
|
721 |
||
722 |
strcpy(needCStr, gNeeds[a]); |
|
723 |
if (padSetting > 1) |
|
724 |
{
|
|
725 |
sprintf(num, "_%d", padSetting); |
|
726 |
strcat(needCStr, num); |
|
727 |
}
|
|
728 |
||
729 |
keyCFStringRef = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, CFSTR("%s"), needCStr); |
|
730 |
if (keyCFStringRef) |
|
731 |
{
|
|
732 |
r = HIDRestoreElementPref(keyCFStringRef, kCFPreferencesCurrentApplication, &pDevice, &pElement); |
|
733 |
if (r && pDevice && pElement) |
|
734 |
{
|
|
735 |
gActionRecs[a].fDevice = pDevice; |
|
736 |
gActionRecs[a].fElement = pElement; |
|
737 |
}
|
|
738 |
else
|
|
739 |
{
|
|
740 |
gActionRecs[a].fDevice = NULL; |
|
741 |
gActionRecs[a].fElement = NULL; |
|
742 |
}
|
|
743 |
||
744 |
CFRelease(keyCFStringRef); |
|
745 |
}
|
|
746 |
}
|
|
747 |
||
748 |
for (int a = 0; a < MAC_MAX_PLAYERS; a++) |
|
749 |
{
|
|
750 |
keyCFStringRef = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, CFSTR("DirectionHint_%d_%d"), a, padSetting); |
|
751 |
if (keyCFStringRef) |
|
752 |
{
|
|
753 |
Boolean r; |
|
754 |
||
755 |
gDirectionHint[a] = (int) CFPreferencesGetAppIntegerValue(keyCFStringRef, kCFPreferencesCurrentApplication, &r); |
|
756 |
if (!r) |
|
757 |
gDirectionHint[a] = kPadElemTypeNone; |
|
758 |
||
759 |
CFRelease(keyCFStringRef); |
|
760 |
}
|
|
761 |
else
|
|
762 |
gDirectionHint[a] = kPadElemTypeNone; |
|
763 |
}
|
|
764 |
||
765 |
JoypadSetDirectionInfo(); |
|
766 |
}
|
|
767 |
||
768 |
static pascal OSStatus ControllerEventHandler (EventHandlerCallRef inHandlerCallRef, EventRef inEvent, void *inUserData) |
|
769 |
{
|
|
770 |
OSStatus err, result = eventNotHandledErr; |
|
771 |
WindowRef tWindowRef; |
|
772 |
||
773 |
tWindowRef = (WindowRef) inUserData; |
|
774 |
||
775 |
switch (GetEventClass(inEvent)) |
|
776 |
{
|
|
777 |
case kEventClassWindow: |
|
778 |
switch (GetEventKind(inEvent)) |
|
779 |
{
|
|
780 |
case kEventWindowClose: |
|
781 |
QuitAppModalLoopForWindow(tWindowRef); |
|
782 |
result = noErr; |
|
783 |
break; |
|
784 |
}
|
|
785 |
||
786 |
break; |
|
787 |
||
788 |
case kEventClassCommand: |
|
789 |
switch (GetEventKind(inEvent)) |
|
790 |
{
|
|
791 |
HICommand tHICommand; |
|
792 |
||
793 |
case kEventCommandUpdateStatus: |
|
794 |
err = GetEventParameter(inEvent, kEventParamDirectObject, typeHICommand, NULL, sizeof(HICommand), NULL, &tHICommand); |
|
795 |
if (err == noErr && tHICommand.commandID == 'clos') |
|
796 |
{
|
|
797 |
UpdateMenuCommandStatus(true); |
|
798 |
result = noErr; |
|
799 |
}
|
|
800 |
||
801 |
break; |
|
802 |
||
803 |
case kEventCommandProcess: |
|
804 |
err = GetEventParameter(inEvent, kEventParamDirectObject, typeHICommand, NULL, sizeof(HICommand), NULL, &tHICommand); |
|
805 |
if (err == noErr) |
|
806 |
{
|
|
807 |
if (tHICommand.commandID == 'CLRa') |
|
808 |
{
|
|
809 |
ClearPadSetting(); |
|
810 |
result = noErr; |
|
811 |
}
|
|
812 |
else
|
|
813 |
{
|
|
814 |
SInt32 command = -1, count; |
|
815 |
||
816 |
for (count = 0; count < kNeedCount; count++) |
|
817 |
if (tHICommand.commandID == gControlIDs[count].signature) |
|
818 |
command = count; |
|
819 |
||
820 |
if (command >= 0) |
|
821 |
{
|
|
822 |
pRecDevice pDevice; |
|
823 |
pRecElement pElement; |
|
824 |
||
825 |
FlushEventQueue(GetCurrentEventQueue()); |
|
826 |
||
827 |
if (HIDConfigureAction(&pDevice, &pElement, 2.5f)) |
|
828 |
{
|
|
829 |
if (command < MAC_MAX_PLAYERS * 4) // Direction |
|
830 |
{
|
|
831 |
int i = command >> 2; // Player |
|
832 |
long curv = HIDGetElementValue(pDevice, pElement); |
|
833 |
||
834 |
if (pElement->usage == kHIDUsage_GD_Hatswitch) // Hat Switch |
|
835 |
{
|
|
836 |
gActionRecs[kUp(i)].fDevice = gActionRecs[kDn(i)].fDevice = gActionRecs[kLf(i)].fDevice = gActionRecs[kRt(i)].fDevice = pDevice; |
|
837 |
gActionRecs[kUp(i)].fElement = gActionRecs[kDn(i)].fElement = gActionRecs[kLf(i)].fElement = gActionRecs[kRt(i)].fElement = pElement; |
|
838 |
||
839 |
if (pDevice->vendorID == 1103) // Thrustmaster |
|
840 |
gDirectionInfo[i].type = (pElement->max > 4) ? kPadElemTypeOtherHat8 : kPadElemTypeOtherHat4; |
|
841 |
else
|
|
842 |
{
|
|
843 |
if (pElement->max > 4) |
|
844 |
{
|
|
845 |
if (((command % 4 == 0) && (curv == 0)) || // Up : 0 |
|
846 |
((command % 4 == 1) && (curv == 4)) || // Down : 4 |
|
847 |
((command % 4 == 2) && (curv == 6)) || // Left : 6 |
|
848 |
((command % 4 == 3) && (curv == 2))) // Right : 2 |
|
849 |
gDirectionInfo[i].type = kPadElemTypeOtherHat8; |
|
850 |
else
|
|
851 |
gDirectionInfo[i].type = kPadElemTypeHat8; |
|
852 |
}
|
|
853 |
else
|
|
854 |
{
|
|
855 |
if (((command % 4 == 0) && (curv == 0)) || // Up : 0 |
|
856 |
((command % 4 == 1) && (curv == 2)) || // Down : 2 |
|
857 |
((command % 4 == 2) && (curv == 3)) || // Left : 3 |
|
858 |
((command % 4 == 3) && (curv == 1))) // Right : 1 |
|
859 |
gDirectionInfo[i].type = kPadElemTypeOtherHat4; |
|
860 |
else
|
|
861 |
gDirectionInfo[i].type = kPadElemTypeHat4; |
|
862 |
}
|
|
863 |
}
|
|
864 |
||
865 |
gDirectionInfo[i].device [kPadHat] = pDevice; |
|
866 |
gDirectionInfo[i].element[kPadHat] = pElement; |
|
867 |
gDirectionInfo[i].max [kPadHat] = pElement->max; |
|
868 |
gDirectionInfo[i].min [kPadHat] = pElement->min; |
|
869 |
}
|
|
870 |
else
|
|
871 |
if (pElement->max - pElement->min > 1) // Axis (maybe) |
|
872 |
{
|
|
873 |
if ((command % 4 == 0) || (command % 4 == 1)) // Up or Dn |
|
874 |
{
|
|
875 |
gActionRecs[kUp(i)].fDevice = gActionRecs[kDn(i)].fDevice = pDevice; |
|
876 |
gActionRecs[kUp(i)].fElement = gActionRecs[kDn(i)].fElement = pElement; |
|
877 |
||
878 |
gDirectionInfo[i].type = kPadElemTypeAxis; |
|
879 |
gDirectionInfo[i].device [kPadYAxis] = pDevice; |
|
880 |
gDirectionInfo[i].element[kPadYAxis] = pElement; |
|
881 |
gDirectionInfo[i].max [kPadYAxis] = pElement->max; |
|
882 |
gDirectionInfo[i].min [kPadYAxis] = pElement->min; |
|
883 |
gDirectionInfo[i].mid [kPadYAxis] = (gDirectionInfo[i].max[kPadYAxis] + gDirectionInfo[i].min[kPadYAxis]) >> 1; |
|
884 |
gDirectionInfo[i].maxmid [kPadYAxis] = (gDirectionInfo[i].max[kPadYAxis] + gDirectionInfo[i].mid[kPadYAxis]) >> 1; |
|
885 |
gDirectionInfo[i].midmin [kPadYAxis] = (gDirectionInfo[i].mid[kPadYAxis] + gDirectionInfo[i].min[kPadYAxis]) >> 1; |
|
886 |
}
|
|
887 |
else // Lf or Rt |
|
888 |
{
|
|
889 |
gActionRecs[kLf(i)].fDevice = gActionRecs[kRt(i)].fDevice = pDevice; |
|
890 |
gActionRecs[kLf(i)].fElement = gActionRecs[kRt(i)].fElement = pElement; |
|
891 |
||
892 |
gDirectionInfo[i].type = kPadElemTypeAxis; |
|
893 |
gDirectionInfo[i].device [kPadXAxis] = pDevice; |
|
894 |
gDirectionInfo[i].element[kPadXAxis] = pElement; |
|
895 |
gDirectionInfo[i].max [kPadXAxis] = pElement->max; |
|
896 |
gDirectionInfo[i].min [kPadXAxis] = pElement->min; |
|
897 |
gDirectionInfo[i].mid [kPadXAxis] = (gDirectionInfo[i].max[kPadXAxis] + gDirectionInfo[i].min[kPadXAxis]) >> 1; |
|
898 |
gDirectionInfo[i].maxmid [kPadXAxis] = (gDirectionInfo[i].max[kPadXAxis] + gDirectionInfo[i].mid[kPadXAxis]) >> 1; |
|
899 |
gDirectionInfo[i].midmin [kPadXAxis] = (gDirectionInfo[i].mid[kPadXAxis] + gDirectionInfo[i].min[kPadXAxis]) >> 1; |
|
900 |
}
|
|
901 |
}
|
|
902 |
else // Button (maybe) |
|
903 |
{
|
|
904 |
gActionRecs[command].fDevice = pDevice; |
|
905 |
gActionRecs[command].fElement = pElement; |
|
906 |
gDirectionInfo[i].type = kPadElemTypeButton; |
|
907 |
}
|
|
908 |
||
909 |
gDirectionHint[i] = gDirectionInfo[i].type; |
|
910 |
}
|
|
911 |
else
|
|
912 |
{
|
|
913 |
gActionRecs[command].fDevice = pDevice; |
|
914 |
gActionRecs[command].fElement = pElement; |
|
915 |
}
|
|
916 |
}
|
|
917 |
else
|
|
918 |
{
|
|
919 |
if (command < MAC_MAX_PLAYERS * 4) // Direction |
|
920 |
{
|
|
921 |
int i = command >> 2; // Player |
|
922 |
||
923 |
gActionRecs[kUp(i)].fDevice = gActionRecs[kDn(i)].fDevice = gActionRecs[kLf(i)].fDevice = gActionRecs[kRt(i)].fDevice = NULL; |
|
924 |
gActionRecs[kUp(i)].fElement = gActionRecs[kDn(i)].fElement = gActionRecs[kLf(i)].fElement = gActionRecs[kRt(i)].fElement = NULL; |
|
925 |
||
926 |
gDirectionInfo[i].type = gDirectionHint[i] = kPadElemTypeNone; |
|
927 |
gDirectionInfo[i].device [0] = gDirectionInfo[i].device [1] = NULL; |
|
928 |
gDirectionInfo[i].element[0] = gDirectionInfo[i].element[1] = NULL; |
|
929 |
}
|
|
930 |
else
|
|
931 |
{
|
|
932 |
gActionRecs[command].fDevice = NULL; |
|
933 |
gActionRecs[command].fElement = NULL; |
|
934 |
}
|
|
935 |
}
|
|
936 |
||
937 |
gActionRecs[command].fValue = 0; |
|
938 |
gActionRecs[command].fOldValue = -2; |
|
939 |
||
940 |
FlushEventQueue(GetCurrentEventQueue()); |
|
941 |
||
942 |
result = noErr; |
|
943 |
}
|
|
944 |
}
|
|
945 |
}
|
|
946 |
||
947 |
break; |
|
948 |
}
|
|
949 |
||
950 |
break; |
|
951 |
}
|
|
952 |
||
953 |
return (result); |
|
954 |
}
|
|
955 |
||
956 |
static pascal void IdleTimer (EventLoopTimerRef inTimer, void *userData) |
|
957 |
{
|
|
958 |
static uint32 old[MAC_MAX_PLAYERS] = { ~0, ~0, ~0, ~0, ~0, ~0, ~0, ~0 }; |
|
959 |
||
960 |
HIViewRef ctl, root; |
|
961 |
uint32 pad[MAC_MAX_PLAYERS]; |
|
962 |
||
963 |
root = HIViewGetRoot((WindowRef) userData); |
|
964 |
||
965 |
for (int i = 0; i < MAC_MAX_PLAYERS; i++) |
|
966 |
{
|
|
967 |
pad[i] = 0; |
|
968 |
JoypadScanDirection(i, &(pad[i])); |
|
969 |
||
970 |
if (old[i] != pad[i]) |
|
971 |
{
|
|
972 |
old[i] = pad[i]; |
|
973 |
||
974 |
HIViewFindByID(root, gControlIDs[kUp(i)], &ctl); |
|
975 |
SetControl32BitValue(ctl, (pad[i] & kMaskUp) ? 1 : 0); |
|
976 |
HIViewFindByID(root, gControlIDs[kDn(i)], &ctl); |
|
977 |
SetControl32BitValue(ctl, (pad[i] & kMaskDn) ? 1 : 0); |
|
978 |
HIViewFindByID(root, gControlIDs[kLf(i)], &ctl); |
|
979 |
SetControl32BitValue(ctl, (pad[i] & kMaskLf) ? 1 : 0); |
|
980 |
HIViewFindByID(root, gControlIDs[kRt(i)], &ctl); |
|
981 |
SetControl32BitValue(ctl, (pad[i] & kMaskRt) ? 1 : 0); |
|
982 |
}
|
|
983 |
}
|
|
984 |
||
985 |
for (int i = MAC_MAX_PLAYERS * 4; i < kNeedCount; i++) |
|
986 |
{
|
|
987 |
gActionRecs[i].fValue = ISpKeyIsPressed(i); |
|
988 |
||
989 |
if (gActionRecs[i].fOldValue != gActionRecs[i].fValue) |
|
990 |
{
|
|
991 |
gActionRecs[i].fOldValue = gActionRecs[i].fValue; |
|
992 |
||
993 |
HIViewFindByID(root, gControlIDs[i], &ctl); |
|
994 |
SetControl32BitValue(ctl, (gActionRecs[i].fValue ? 1 : 0)); |
|
995 |
}
|
|
996 |
}
|
|
997 |
}
|
|
998 |
||
999 |
void SetUpHID (void) |
|
1000 |
{
|
|
1001 |
pRecDevice device; |
|
1002 |
||
1003 |
HIDBuildDeviceList(NULL, NULL); |
|
1004 |
device = HIDGetFirstDevice(); |
|
1005 |
if (!device) |
|
1006 |
{
|
|
1007 |
hidExist = false; |
|
1008 |
return; |
|
1009 |
}
|
|
1010 |
||
1011 |
hidExist = true; |
|
1012 |
||
1013 |
ClearPadSetting(); |
|
1014 |
||
1015 |
LoadControllerSettings(); |
|
1016 |
}
|
|
1017 |
||
1018 |
void ClearPadSetting (void) |
|
1019 |
{
|
|
1020 |
for (int i = 0; i < MAC_MAX_PLAYERS; i++) |
|
1021 |
{
|
|
1022 |
gDirectionInfo[i].type = gDirectionHint[i] = kPadElemTypeNone; |
|
1023 |
gDirectionInfo[i].device [0] = gDirectionInfo[i].device [1] = NULL; |
|
1024 |
gDirectionInfo[i].element[0] = gDirectionInfo[i].element[1] = NULL; |
|
1025 |
}
|
|
1026 |
||
1027 |
for (int i = 0; i < kNeedCount; i++) |
|
1028 |
{
|
|
1029 |
gActionRecs[i].fDevice = NULL; |
|
1030 |
gActionRecs[i].fElement = NULL; |
|
1031 |
gActionRecs[i].fValue = 0; |
|
1032 |
gActionRecs[i].fOldValue = -2; |
|
1033 |
}
|
|
1034 |
}
|
|
1035 |
||
1036 |
void ReleaseHID (void) |
|
1037 |
{
|
|
1038 |
if (hidExist) |
|
1039 |
HIDReleaseDeviceList(); |
|
1040 |
}
|
|
1041 |
||
1042 |
void ConfigureHID (void) |
|
1043 |
{
|
|
1044 |
OSStatus err; |
|
1045 |
IBNibRef nibRef; |
|
1046 |
||
1047 |
if (!hidExist) |
|
1048 |
return; |
|
1049 |
||
1050 |
err = CreateNibReference(kMacS9XCFString, &nibRef); |
|
1051 |
if (err == noErr) |
|
1052 |
{
|
|
1053 |
WindowRef tWindowRef; |
|
1054 |
||
1055 |
err = CreateWindowFromNib(nibRef, CFSTR("Controllers"), &tWindowRef); |
|
1056 |
if (err == noErr) |
|
1057 |
{
|
|
1058 |
EventHandlerRef eref; |
|
1059 |
EventLoopTimerRef tref; |
|
1060 |
EventHandlerUPP eventUPP; |
|
1061 |
EventLoopTimerUPP timerUPP; |
|
1062 |
EventTypeSpec windowEvents[] = { { kEventClassCommand, kEventCommandProcess }, |
|
1063 |
{ kEventClassCommand, kEventCommandUpdateStatus }, |
|
1064 |
{ kEventClassWindow, kEventWindowClose } }; |
|
1065 |
HIViewRef ctl, root; |
|
1066 |
HIViewID cid; |
|
1067 |
CFStringRef str1, str2; |
|
1068 |
ControlButtonContentInfo info; |
|
1069 |
||
1070 |
LoadControllerSettings(); |
|
1071 |
||
1072 |
root = HIViewGetRoot(tWindowRef); |
|
1073 |
cid.id = 0; |
|
1074 |
cid.signature = 'PRES'; |
|
1075 |
HIViewFindByID(root, cid, &ctl); |
|
1076 |
str1 = CFCopyLocalizedString(CFSTR("PresetNum"), "PresetNum"); |
|
1077 |
str2 = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, str1, padSetting); |
|
1078 |
SetStaticTextCFString(ctl, str2, false); |
|
1079 |
CFRelease(str2); |
|
1080 |
CFRelease(str1); |
|
1081 |
||
1082 |
if (systemVersion >= 0x1040) |
|
1083 |
{
|
|
1084 |
info.contentType = kControlContentCGImageRef; |
|
1085 |
for (int i = 0; i < kNeedCount; i++) |
|
1086 |
{
|
|
1087 |
HIViewFindByID(root, gControlIDs[i], &ctl); |
|
1088 |
info.u.imageRef = macIconImage[gIconNumber[i]]; |
|
1089 |
err = SetBevelButtonContentInfo(ctl, &info); |
|
1090 |
}
|
|
1091 |
}
|
|
1092 |
#ifdef MAC_PANTHER_SUPPORT
|
|
1093 |
else
|
|
1094 |
{
|
|
1095 |
info.contentType = kControlContentIconRef; |
|
1096 |
for (int i = 0; i < kNeedCount; i++) |
|
1097 |
{
|
|
1098 |
HIViewFindByID(root, gControlIDs[i], &ctl); |
|
1099 |
info.u.iconRef = macIconRef[gIconNumber[i]]; |
|
1100 |
err = SetBevelButtonContentInfo(ctl, &info); |
|
1101 |
}
|
|
1102 |
}
|
|
1103 |
#endif
|
|
1104 |
||
1105 |
eventUPP = NewEventHandlerUPP(ControllerEventHandler); |
|
1106 |
err = InstallWindowEventHandler(tWindowRef, eventUPP, GetEventTypeCount(windowEvents), windowEvents, (void *) tWindowRef, &eref); |
|
1107 |
||
1108 |
timerUPP = NewEventLoopTimerUPP(IdleTimer); |
|
1109 |
err = InstallEventLoopTimer(GetCurrentEventLoop(), 0.0f, 0.1f, timerUPP, (void *) tWindowRef, &tref); |
|
1110 |
||
1111 |
MoveWindowPosition(tWindowRef, kWindowControllers, false); |
|
1112 |
ShowWindow(tWindowRef); |
|
1113 |
err = RunAppModalLoopForWindow(tWindowRef); |
|
1114 |
HideWindow(tWindowRef); |
|
1115 |
SaveWindowPosition(tWindowRef, kWindowControllers); |
|
1116 |
||
1117 |
err = RemoveEventLoopTimer(tref); |
|
1118 |
DisposeEventLoopTimerUPP(timerUPP); |
|
1119 |
||
1120 |
err = RemoveEventHandler(eref); |
|
1121 |
DisposeEventHandlerUPP(eventUPP); |
|
1122 |
||
1123 |
CFRelease(tWindowRef); |
|
1124 |
||
1125 |
SaveControllerSettings(); |
|
1126 |
}
|
|
1127 |
||
1128 |
DisposeNibReference(nibRef); |
|
1129 |
}
|
|
1130 |
}
|
|
1131 |
||
1132 |
long ISpKeyIsPressed (int needID) |
|
1133 |
{
|
|
1134 |
return (gActionRecs[needID].fDevice ? HIDGetElementValue(gActionRecs[needID].fDevice, gActionRecs[needID].fElement) : 0); |
|
1135 |
}
|
|
1136 |
||
1137 |
void JoypadScanDirection (int i, uint32 *pad) |
|
1138 |
{
|
|
1139 |
long state; |
|
1140 |
||
1141 |
switch (gDirectionInfo[i].type) |
|
1142 |
{
|
|
1143 |
case kPadElemTypeAxis: // Axis (maybe) |
|
1144 |
if (gDirectionInfo[i].device[kPadYAxis]) // Y-Axis |
|
1145 |
{
|
|
1146 |
state = HIDGetElementValue(gDirectionInfo[i].device[kPadYAxis], gDirectionInfo[i].element[kPadYAxis]); |
|
1147 |
if (state >= gDirectionInfo[i].maxmid[kPadYAxis]) |
|
1148 |
*pad |= kMaskDn; |
|
1149 |
else
|
|
1150 |
if (state <= gDirectionInfo[i].midmin[kPadYAxis]) |
|
1151 |
*pad |= kMaskUp; |
|
1152 |
}
|
|
1153 |
||
1154 |
if (gDirectionInfo[i].device[kPadXAxis]) // X-Axis |
|
1155 |
{
|
|
1156 |
state = HIDGetElementValue(gDirectionInfo[i].device[kPadXAxis], gDirectionInfo[i].element[kPadXAxis]); |
|
1157 |
if (state >= gDirectionInfo[i].maxmid[kPadXAxis]) |
|
1158 |
*pad |= kMaskRt; |
|
1159 |
else
|
|
1160 |
if (state <= gDirectionInfo[i].midmin[kPadXAxis]) |
|
1161 |
*pad |= kMaskLf; |
|
1162 |
}
|
|
1163 |
||
1164 |
break; |
|
1165 |
||
1166 |
case kPadElemTypeHat8: // Hat Switch (8 Directions) |
|
1167 |
if (gDirectionInfo[i].device[kPadHat]) |
|
1168 |
{
|
|
1169 |
state = HIDGetElementValue(gDirectionInfo[i].device[kPadHat], gDirectionInfo[i].element[kPadHat]); |
|
1170 |
switch (state) |
|
1171 |
{
|
|
1172 |
case 1: *pad |= kMaskUp ; break; |
|
1173 |
case 2: *pad |= (kMaskUp | kMaskRt); break; |
|
1174 |
case 3: *pad |= kMaskRt ; break; |
|
1175 |
case 4: *pad |= (kMaskRt | kMaskDn); break; |
|
1176 |
case 5: *pad |= kMaskDn ; break; |
|
1177 |
case 6: *pad |= (kMaskDn | kMaskLf); break; |
|
1178 |
case 7: *pad |= kMaskLf ; break; |
|
1179 |
case 8: *pad |= (kMaskLf | kMaskUp); break; |
|
1180 |
}
|
|
1181 |
}
|
|
1182 |
||
1183 |
break; |
|
1184 |
||
1185 |
case kPadElemTypeHat4: // Hat Switch (4 Directions) |
|
1186 |
if (gDirectionInfo[i].device[kPadHat]) |
|
1187 |
{
|
|
1188 |
state = HIDGetElementValue(gDirectionInfo[i].device[kPadHat], gDirectionInfo[i].element[kPadHat]); |
|
1189 |
switch (state) |
|
1190 |
{
|
|
1191 |
case 1: *pad |= kMaskUp; break; |
|
1192 |
case 2: *pad |= kMaskRt; break; |
|
1193 |
case 3: *pad |= kMaskDn; break; |
|
1194 |
case 4: *pad |= kMaskLf; break; |
|
1195 |
}
|
|
1196 |
}
|
|
1197 |
||
1198 |
break; |
|
1199 |
||
1200 |
case kPadElemTypeOtherHat8: // Hat Switch (8 Directions, Start at 0) |
|
1201 |
if (gDirectionInfo[i].device[kPadHat]) |
|
1202 |
{
|
|
1203 |
state = HIDGetElementValue(gDirectionInfo[i].device[kPadHat], gDirectionInfo[i].element[kPadHat]); |
|
1204 |
switch (state) |
|
1205 |
{
|
|
1206 |
case 0: *pad |= kMaskUp ; break; |
|
1207 |
case 1: *pad |= (kMaskUp | kMaskRt); break; |
|
1208 |
case 2: *pad |= kMaskRt ; break; |
|
1209 |
case 3: *pad |= (kMaskRt | kMaskDn); break; |
|
1210 |
case 4: *pad |= kMaskDn ; break; |
|
1211 |
case 5: *pad |= (kMaskDn | kMaskLf); break; |
|
1212 |
case 6: *pad |= kMaskLf ; break; |
|
1213 |
case 7: *pad |= (kMaskLf | kMaskUp); break; |
|
1214 |
}
|
|
1215 |
}
|
|
1216 |
||
1217 |
break; |
|
1218 |
||
1219 |
case kPadElemTypeOtherHat4: // Hat Switch (4 Directions, Start at 0) |
|
1220 |
if (gDirectionInfo[i].device[kPadHat]) |
|
1221 |
{
|
|
1222 |
state = HIDGetElementValue(gDirectionInfo[i].device[kPadHat], gDirectionInfo[i].element[kPadHat]); |
|
1223 |
switch (state) |
|
1224 |
{
|
|
1225 |
case 0: *pad |= kMaskUp; break; |
|
1226 |
case 1: *pad |= kMaskRt; break; |
|
1227 |
case 2: *pad |= kMaskDn; break; |
|
1228 |
case 3: *pad |= kMaskLf; break; |
|
1229 |
}
|
|
1230 |
}
|
|
1231 |
||
1232 |
break; |
|
1233 |
||
1234 |
case kPadElemTypeButton: // Button (maybe) |
|
1235 |
if (gActionRecs[kUp(i)].fDevice && HIDGetElementValue(gActionRecs[kUp(i)].fDevice, gActionRecs[kUp(i)].fElement)) |
|
1236 |
*pad |= kMaskUp; |
|
1237 |
if (gActionRecs[kDn(i)].fDevice && HIDGetElementValue(gActionRecs[kDn(i)].fDevice, gActionRecs[kDn(i)].fElement)) |
|
1238 |
*pad |= kMaskDn; |
|
1239 |
if (gActionRecs[kLf(i)].fDevice && HIDGetElementValue(gActionRecs[kLf(i)].fDevice, gActionRecs[kLf(i)].fElement)) |
|
1240 |
*pad |= kMaskLf; |
|
1241 |
if (gActionRecs[kRt(i)].fDevice && HIDGetElementValue(gActionRecs[kRt(i)].fDevice, gActionRecs[kRt(i)].fElement)) |
|
1242 |
*pad |= kMaskRt; |
|
1243 |
||
1244 |
break; |
|
1245 |
}
|
|
1246 |
}
|
|
1247 |
||
1248 |
static void JoypadSetDirectionInfo (void) |
|
1249 |
{
|
|
1250 |
for (int i = 0; i < MAC_MAX_PLAYERS; i++) |
|
1251 |
{
|
|
1252 |
if (((gActionRecs[kUp(i)].fDevice) && (gActionRecs[kUp(i)].fElement)) && |
|
1253 |
((gActionRecs[kDn(i)].fDevice) && (gActionRecs[kDn(i)].fElement)) && |
|
1254 |
((gActionRecs[kLf(i)].fDevice) && (gActionRecs[kLf(i)].fElement)) && |
|
1255 |
((gActionRecs[kRt(i)].fDevice) && (gActionRecs[kRt(i)].fElement))) |
|
1256 |
{
|
|
1257 |
if ((gActionRecs[kUp(i)].fDevice == gActionRecs[kDn(i)].fDevice) && |
|
1258 |
(gActionRecs[kDn(i)].fDevice == gActionRecs[kLf(i)].fDevice) && |
|
1259 |
(gActionRecs[kLf(i)].fDevice == gActionRecs[kRt(i)].fDevice) && |
|
1260 |
(gActionRecs[kUp(i)].fElement == gActionRecs[kDn(i)].fElement) && |
|
1261 |
(gActionRecs[kDn(i)].fElement == gActionRecs[kLf(i)].fElement) && |
|
1262 |
(gActionRecs[kLf(i)].fElement == gActionRecs[kRt(i)].fElement) && |
|
1263 |
(gActionRecs[kUp(i)].fElement->usage == kHIDUsage_GD_Hatswitch)) // Hat Switch |
|
1264 |
{
|
|
1265 |
if ((gDirectionHint[i] == kPadElemTypeHat8) || (gDirectionHint[i] == kPadElemTypeOtherHat8) || |
|
1266 |
(gDirectionHint[i] == kPadElemTypeHat4) || (gDirectionHint[i] == kPadElemTypeOtherHat4)) |
|
1267 |
gDirectionInfo[i].type = gDirectionHint[i]; |
|
1268 |
else // Assuming... |
|
1269 |
{
|
|
1270 |
if ((gActionRecs[kUp(i)].fDevice->vendorID == 1103) || (gActionRecs[kUp(i)].fElement->min == 0)) |
|
1271 |
gDirectionInfo[i].type = (gActionRecs[kUp(i)].fElement->max > 4) ? kPadElemTypeOtherHat8 : kPadElemTypeOtherHat4; |
|
1272 |
else
|
|
1273 |
gDirectionInfo[i].type = (gActionRecs[kUp(i)].fElement->max > 4) ? kPadElemTypeHat8 : kPadElemTypeHat4; |
|
1274 |
||
1275 |
gDirectionHint[i] = gDirectionInfo[i].type; |
|
1276 |
}
|
|
1277 |
||
1278 |
gDirectionInfo[i].device [kPadHat] = gActionRecs[kUp(i)].fDevice; |
|
1279 |
gDirectionInfo[i].element[kPadHat] = gActionRecs[kUp(i)].fElement; |
|
1280 |
gDirectionInfo[i].max [kPadHat] = gActionRecs[kUp(i)].fElement->max; |
|
1281 |
gDirectionInfo[i].min [kPadHat] = gActionRecs[kUp(i)].fElement->min; |
|
1282 |
}
|
|
1283 |
else
|
|
1284 |
if ((gActionRecs[kUp(i)].fDevice == gActionRecs[kDn(i)].fDevice) && |
|
1285 |
(gActionRecs[kLf(i)].fDevice == gActionRecs[kRt(i)].fDevice) && |
|
1286 |
(gActionRecs[kUp(i)].fElement == gActionRecs[kDn(i)].fElement) && |
|
1287 |
(gActionRecs[kLf(i)].fElement == gActionRecs[kRt(i)].fElement) && |
|
1288 |
(gActionRecs[kUp(i)].fElement->max - gActionRecs[kUp(i)].fElement->min > 1) && |
|
1289 |
(gActionRecs[kLf(i)].fElement->max - gActionRecs[kLf(i)].fElement->min > 1)) // Axis (maybe) |
|
1290 |
{
|
|
1291 |
gDirectionInfo[i].type = gDirectionHint[i] = kPadElemTypeAxis; |
|
1292 |
||
1293 |
gDirectionInfo[i].device [kPadYAxis] = gActionRecs[kUp(i)].fDevice; |
|
1294 |
gDirectionInfo[i].element[kPadYAxis] = gActionRecs[kUp(i)].fElement; |
|
1295 |
gDirectionInfo[i].max [kPadYAxis] = gActionRecs[kUp(i)].fElement->max; |
|
1296 |
gDirectionInfo[i].min [kPadYAxis] = gActionRecs[kUp(i)].fElement->min; |
|
1297 |
gDirectionInfo[i].mid [kPadYAxis] = (gDirectionInfo[i].max[kPadYAxis] + gDirectionInfo[i].min[kPadYAxis]) >> 1; |
|
1298 |
gDirectionInfo[i].maxmid [kPadYAxis] = (gDirectionInfo[i].max[kPadYAxis] + gDirectionInfo[i].mid[kPadYAxis]) >> 1; |
|
1299 |
gDirectionInfo[i].midmin [kPadYAxis] = (gDirectionInfo[i].mid[kPadYAxis] + gDirectionInfo[i].min[kPadYAxis]) >> 1; |
|
1300 |
||
1301 |
gDirectionInfo[i].device [kPadXAxis] = gActionRecs[kLf(i)].fDevice; |
|
1302 |
gDirectionInfo[i].element[kPadXAxis] = gActionRecs[kLf(i)].fElement; |
|
1303 |
gDirectionInfo[i].max [kPadXAxis] = gActionRecs[kLf(i)].fElement->max; |
|
1304 |
gDirectionInfo[i].min [kPadXAxis] = gActionRecs[kLf(i)].fElement->min; |
|
1305 |
gDirectionInfo[i].mid [kPadXAxis] = (gDirectionInfo[i].max[kPadXAxis] + gDirectionInfo[i].min[kPadXAxis]) >> 1; |
|
1306 |
gDirectionInfo[i].maxmid [kPadXAxis] = (gDirectionInfo[i].max[kPadXAxis] + gDirectionInfo[i].mid[kPadXAxis]) >> 1; |
|
1307 |
gDirectionInfo[i].midmin [kPadXAxis] = (gDirectionInfo[i].mid[kPadXAxis] + gDirectionInfo[i].min[kPadXAxis]) >> 1; |
|
1308 |
}
|
|
1309 |
else // Button (maybe) |
|
1310 |
gDirectionInfo[i].type = gDirectionHint[i] = kPadElemTypeButton; |
|
1311 |
}
|
|
1312 |
else
|
|
1313 |
{
|
|
1314 |
gActionRecs[kUp(i)].fDevice = gActionRecs[kDn(i)].fDevice = gActionRecs[kLf(i)].fDevice = gActionRecs[kRt(i)].fDevice = NULL; |
|
1315 |
gActionRecs[kUp(i)].fElement = gActionRecs[kDn(i)].fElement = gActionRecs[kLf(i)].fElement = gActionRecs[kRt(i)].fElement = NULL; |
|
1316 |
||
1317 |
gDirectionInfo[i].type = gDirectionHint[i] = kPadElemTypeNone; |
|
1318 |
gDirectionInfo[i].device [0] = gDirectionInfo[i].device [1] = NULL; |
|
1319 |
gDirectionInfo[i].element[0] = gDirectionInfo[i].element[1] = NULL; |
|
1320 |
}
|
|
1321 |
}
|
|
1322 |
}
|