1 // Burner Game Input
2 #include "burner.h"
3
4 // Player Default Controls
5 INT32 nPlayerDefaultControls[8] = {0, 1, 2, 3, 8, 8, 8, 8};
6 TCHAR szPlayerDefaultIni[5][MAX_PATH] = { _T(""), _T(""), _T(""), _T(""), _T("") };
7
8 // Mapping of PC inputs to game inputs
9 struct GameInp* GameInp = NULL;
10 UINT32 nGameInpCount = 0;
11 UINT32 nMacroCount = 0;
12 UINT32 nMaxMacro = 0;
13
14 INT32 nAnalogSpeed;
15
16 INT32 nFireButtons = 0;
17
18 bool bStreetFighterLayout = false;
19 bool bLeftAltkeyMapped = false;
20
21 // These are mappable global macros for mapping Pause/FFWD etc to controls in the input mapping dialogue. -dink
22 UINT8 macroSystemPause = 0;
23 UINT8 macroSystemFFWD = 0;
24 UINT8 macroSystemFrame = 0;
25 UINT8 macroSystemSaveState = 0;
26 UINT8 macroSystemLoadState = 0;
27 UINT8 macroSystemUNDOState = 0;
28 UINT8 macroSystemLuaHotkey1 = 0;
29 UINT8 macroSystemLuaHotkey2 = 0;
30 UINT8 macroSystemLuaHotkey3 = 0;
31 UINT8 macroSystemLuaHotkey4 = 0;
32 UINT8 macroSystemLuaHotkey5 = 0;
33 UINT8 macroSystemLuaHotkey6 = 0;
34 UINT8 macroSystemLuaHotkey7 = 0;
35 UINT8 macroSystemLuaHotkey8 = 0;
36 UINT8 macroSystemLuaHotkey9 = 0;
37
38 UINT8 *lua_hotkeys[] = {
39 ¯oSystemLuaHotkey1,
40 ¯oSystemLuaHotkey2,
41 ¯oSystemLuaHotkey3,
42 ¯oSystemLuaHotkey4,
43 ¯oSystemLuaHotkey5,
44 ¯oSystemLuaHotkey6,
45 ¯oSystemLuaHotkey7,
46 ¯oSystemLuaHotkey8,
47 ¯oSystemLuaHotkey9,
48 NULL
49 };
50
51
52 #define HW_NEOGEO ( ((BurnDrvGetHardwareCode() & HARDWARE_PUBLIC_MASK) == HARDWARE_SNK_NEOGEO) || ((BurnDrvGetHardwareCode() & HARDWARE_PUBLIC_MASK) == HARDWARE_SNK_NEOCD) )
53 #define HW_NES ( ((BurnDrvGetHardwareCode() & HARDWARE_PUBLIC_MASK) == HARDWARE_NES) || ((BurnDrvGetHardwareCode() & HARDWARE_PUBLIC_MASK) == HARDWARE_FDS) )
54 #define HW_MISC ( (! HW_NEOGEO) && (! HW_NES) && ((BurnDrvGetHardwareCode() & HARDWARE_PUBLIC_MASK) != HARDWARE_SEGA_MEGADRIVE) )
55 #define SETS_VS ( (BurnDrvGetGenreFlags() & GBF_VSFIGHT) && ((BurnDrvGetFamilyFlags() & FBF_SF) || (BurnDrvGetFamilyFlags() & FBF_DSTLK) || (BurnDrvGetFamilyFlags() &FBF_PWRINST) || HW_NEOGEO) )
56
57 #ifdef BUILD_MACOS
58 int MacOSinpInitControls(struct GameInp *pgi, const char *szi);
59 #endif
60
61 // ---------------------------------------------------------------------------
62
63 // Check if the left alt (menu) key is mapped
64 #ifndef __LIBRETRO__
GameInpCheckLeftAlt()65 void GameInpCheckLeftAlt()
66 {
67 struct GameInp* pgi;
68 UINT32 i;
69
70 bLeftAltkeyMapped = false;
71
72 for (i = 0, pgi = GameInp; i < (nGameInpCount + nMacroCount); i++, pgi++) {
73
74 if (bLeftAltkeyMapped) {
75 break;
76 }
77
78 switch (pgi->nInput) {
79 case GIT_SWITCH:
80 if (pgi->Input.Switch.nCode == FBK_LALT) {
81 bLeftAltkeyMapped = true;
82 }
83 break;
84 case GIT_MACRO_AUTO:
85 case GIT_MACRO_CUSTOM:
86 if (pgi->Macro.nMode) {
87 if (pgi->Macro.Switch.nCode == FBK_LALT) {
88 bLeftAltkeyMapped = true;
89 }
90 }
91 break;
92
93 default:
94 continue;
95 }
96 }
97 }
98
99 // Check if the sytem mouse is mapped and set the cooperative level apropriately
GameInpCheckMouse()100 void GameInpCheckMouse()
101 {
102 bool bMouseMapped = false;
103 struct GameInp* pgi;
104 UINT32 i;
105
106 for (i = 0, pgi = GameInp; i < (nGameInpCount + nMacroCount); i++, pgi++) {
107
108 if (bMouseMapped) {
109 break;
110 }
111
112 switch (pgi->nInput) {
113 case GIT_SWITCH:
114 if ((pgi->Input.Switch.nCode & 0xFF00) == 0x8000) {
115 bMouseMapped = true;
116 }
117 break;
118 case GIT_MOUSEAXIS:
119 if (pgi->Input.MouseAxis.nMouse == 0) {
120 bMouseMapped = true;
121 }
122 break;
123 case GIT_MACRO_AUTO:
124 case GIT_MACRO_CUSTOM:
125 if (pgi->Macro.nMode) {
126 if ((pgi->Macro.Switch.nCode & 0xFF00) == 0x8000) {
127 bMouseMapped = true;
128 }
129 }
130 break;
131
132 default:
133 continue;
134 }
135 }
136
137 if (bDrvOkay) {
138 if (!bRunPause) {
139 InputSetCooperativeLevel(bMouseMapped, bAlwaysProcessKeyboardInput);
140 } else {
141 InputSetCooperativeLevel(false, bAlwaysProcessKeyboardInput);
142 }
143 } else {
144 InputSetCooperativeLevel(false, false);
145 }
146 }
147 #endif
148
149 // ---------------------------------------------------------------------------
150
GameInpBlank(INT32 bDipSwitch)151 INT32 GameInpBlank(INT32 bDipSwitch)
152 {
153 UINT32 i = 0;
154 struct GameInp* pgi = NULL;
155
156 // Reset all inputs to undefined (even dip switches, if bDipSwitch==1)
157 if (GameInp == NULL) {
158 return 1;
159 }
160
161 // Get the targets in the library for the Input Values
162 for (i = 0, pgi = GameInp; i < nGameInpCount; i++, pgi++) {
163 struct BurnInputInfo bii;
164 memset(&bii, 0, sizeof(bii));
165 BurnDrvGetInputInfo(&bii, i);
166 if (bDipSwitch == 0 && (bii.nType & BIT_GROUP_CONSTANT)) { // Don't blank the dip switches
167 continue;
168 }
169
170 memset(pgi, 0, sizeof(*pgi)); // Clear input
171
172 pgi->nType = bii.nType; // store input type
173 pgi->Input.pVal = bii.pVal; // store input pointer to value
174
175 if (bii.nType & BIT_GROUP_CONSTANT) { // Further initialisation for constants/DIPs
176 pgi->nInput = GIT_CONSTANT;
177 pgi->Input.Constant.nConst = *bii.pVal;
178 }
179 }
180
181 for (i = 0; i < nMacroCount; i++, pgi++) {
182 pgi->Macro.nMode = 0;
183 if (pgi->nInput == GIT_MACRO_CUSTOM) {
184 pgi->nInput = 0;
185 }
186 }
187
188 bLeftAltkeyMapped = false;
189
190 return 0;
191 }
192
GameInpInitMacros()193 static void GameInpInitMacros()
194 {
195 struct GameInp* pgi;
196 struct BurnInputInfo bii;
197
198 INT32 nPunchx3[5] = {0, 0, 0, 0, 0};
199 INT32 nPunchInputs[5][3];
200 INT32 nKickx3[5] = {0, 0, 0, 0, 0};
201 INT32 nKickInputs[5][3];
202
203 INT32 nNeogeoButtons[5][4];
204 INT32 nPgmButtons[10][16];
205
206 bStreetFighterLayout = false;
207 nMacroCount = 0;
208
209 nFireButtons = 0;
210
211 memset(&nNeogeoButtons, 0, sizeof(nNeogeoButtons));
212 memset(&nPgmButtons, 0, sizeof(nPgmButtons));
213
214 for (UINT32 i = 0; i < nGameInpCount; i++) {
215 bii.szName = NULL;
216 BurnDrvGetInputInfo(&bii, i);
217 if (bii.szName == NULL) {
218 bii.szName = "";
219 }
220
221 // Fix for 6 players (xmen6p ...)
222 bool bPlayerInInfo = (toupper(bii.szInfo[0]) == 'P' && bii.szInfo[1] >= '1' && bii.szInfo[1] <= '6'); // Because some of the older drivers don't use the standard input naming.
223 bool bPlayerInName = (bii.szName[0] == 'P' && bii.szName[1] >= '1' && bii.szName[1] <= '6');
224
225 if (bPlayerInInfo || bPlayerInName) {
226 INT32 nPlayer = 0;
227
228 if (bPlayerInName)
229 nPlayer = bii.szName[1] - '1';
230 if (bPlayerInInfo && nPlayer == 0)
231 nPlayer = bii.szInfo[1] - '1';
232
233 if (nPlayer == 0) {
234 if (strncmp(" fire", bii.szInfo + 2, 5) == 0) {
235 nFireButtons++;
236 }
237 }
238
239 if (_stricmp(" Weak Punch", bii.szName + 2) == 0) {
240 nPunchx3[nPlayer] |= 1;
241 nPunchInputs[nPlayer][0] = i;
242 }
243 if (_stricmp(" Medium Punch", bii.szName + 2) == 0) {
244 nPunchx3[nPlayer] |= 2;
245 nPunchInputs[nPlayer][1] = i;
246 }
247 if (_stricmp(" Strong Punch", bii.szName + 2) == 0) {
248 nPunchx3[nPlayer] |= 4;
249 nPunchInputs[nPlayer][2] = i;
250 }
251 if (_stricmp(" Weak Kick", bii.szName + 2) == 0) {
252 nKickx3[nPlayer] |= 1;
253 nKickInputs[nPlayer][0] = i;
254 }
255 if (_stricmp(" Medium Kick", bii.szName + 2) == 0) {
256 nKickx3[nPlayer] |= 2;
257 nKickInputs[nPlayer][1] = i;
258 }
259 if (_stricmp(" Strong Kick", bii.szName + 2) == 0) {
260 nKickx3[nPlayer] |= 4;
261 nKickInputs[nPlayer][2] = i;
262 }
263
264 if (HW_NEOGEO) {
265 if (_stricmp(" Button A", bii.szName + 2) == 0) {
266 nNeogeoButtons[nPlayer][0] = i;
267 }
268 if (_stricmp(" Button B", bii.szName + 2) == 0) {
269 nNeogeoButtons[nPlayer][1] = i;
270 }
271 if (_stricmp(" Button C", bii.szName + 2) == 0) {
272 nNeogeoButtons[nPlayer][2] = i;
273 }
274 if (_stricmp(" Button D", bii.szName + 2) == 0) {
275 nNeogeoButtons[nPlayer][3] = i;
276 }
277 }
278
279 //if ((BurnDrvGetHardwareCode() & HARDWARE_PUBLIC_MASK) == HARDWARE_IGS_PGM) {
280 { // Use nPgmButtons for Autofire too -dink
281 if ((_stricmp(" Button 1", bii.szName + 2) == 0) || (_stricmp(" fire 1", bii.szInfo + 2) == 0)) {
282 nPgmButtons[nPlayer][0] = i;
283 }
284 if ((_stricmp(" Button 2", bii.szName + 2) == 0) || (_stricmp(" fire 2", bii.szInfo + 2) == 0)) {
285 nPgmButtons[nPlayer][1] = i;
286 }
287 if ((_stricmp(" Button 3", bii.szName + 2) == 0) || (_stricmp(" fire 3", bii.szInfo + 2) == 0)) {
288 nPgmButtons[nPlayer][2] = i;
289 }
290 if ((_stricmp(" Button 4", bii.szName + 2) == 0) || (_stricmp(" fire 4", bii.szInfo + 2) == 0)) {
291 nPgmButtons[nPlayer][3] = i;
292 }
293 if ((_stricmp(" Button 5", bii.szName + 2) == 0) || (_stricmp(" fire 5", bii.szInfo + 2) == 0)) {
294 nPgmButtons[nPlayer][4] = i;
295 }
296 if ((_stricmp(" Button 6", bii.szName + 2) == 0) || (_stricmp(" fire 6", bii.szInfo + 2) == 0)) {
297 nPgmButtons[nPlayer][5] = i;
298 }
299 }
300 }
301 }
302
303 pgi = GameInp + nGameInpCount;
304
305 { // Mappable system macros -dink
306 pgi->nInput = GIT_MACRO_AUTO;
307 pgi->nType = BIT_DIGITAL;
308 pgi->Macro.nMode = 0;
309 pgi->Macro.nSysMacro = 1;
310 sprintf(pgi->Macro.szName, "System Pause");
311 pgi->Macro.pVal[0] = ¯oSystemPause;
312 pgi->Macro.nVal[0] = 1;
313 nMacroCount++;
314 pgi++;
315
316 pgi->nInput = GIT_MACRO_AUTO;
317 pgi->nType = BIT_DIGITAL;
318 pgi->Macro.nMode = 0;
319 pgi->Macro.nSysMacro = 1;
320 sprintf(pgi->Macro.szName, "System FFWD");
321 pgi->Macro.pVal[0] = ¯oSystemFFWD;
322 pgi->Macro.nVal[0] = 1;
323 nMacroCount++;
324 pgi++;
325
326 pgi->nInput = GIT_MACRO_AUTO;
327 pgi->nType = BIT_DIGITAL;
328 pgi->Macro.nMode = 0;
329 pgi->Macro.nSysMacro = 1;
330 sprintf(pgi->Macro.szName, "System Frame");
331 pgi->Macro.pVal[0] = ¯oSystemFrame;
332 pgi->Macro.nVal[0] = 1;
333 nMacroCount++;
334 pgi++;
335
336 pgi->nInput = GIT_MACRO_AUTO;
337 pgi->nType = BIT_DIGITAL;
338 pgi->Macro.nMode = 0;
339 pgi->Macro.nSysMacro = 1;
340 sprintf(pgi->Macro.szName, "System Load State");
341 pgi->Macro.pVal[0] = ¯oSystemLoadState;
342 pgi->Macro.nVal[0] = 1;
343 nMacroCount++;
344 pgi++;
345
346 pgi->nInput = GIT_MACRO_AUTO;
347 pgi->nType = BIT_DIGITAL;
348 pgi->Macro.nMode = 0;
349 pgi->Macro.nSysMacro = 1;
350 sprintf(pgi->Macro.szName, "System Save State");
351 pgi->Macro.pVal[0] = ¯oSystemSaveState;
352 pgi->Macro.nVal[0] = 1;
353 nMacroCount++;
354 pgi++;
355
356 pgi->nInput = GIT_MACRO_AUTO;
357 pgi->nType = BIT_DIGITAL;
358 pgi->Macro.nMode = 0;
359 pgi->Macro.nSysMacro = 1;
360 sprintf(pgi->Macro.szName, "System UNDO State");
361 pgi->Macro.pVal[0] = ¯oSystemUNDOState;
362 pgi->Macro.nVal[0] = 1;
363 nMacroCount++;
364 pgi++;
365 }
366
367 // Remove two keys for volume adjustment of cps2
368 INT32 nRealButtons = ((BurnDrvGetHardwareCode() & HARDWARE_PUBLIC_MASK) == HARDWARE_CAPCOM_CPS2) ? nFireButtons - 2 : nFireButtons;
369 INT32 nIndex = 0;
370
371 for (UINT32 nPlayer = 0; nPlayer < nMaxPlayers; nPlayer++) {
372 UINT8* pArrow[4] = { 0, 0, 0, 0 }; // { up, down, left, right }
373
374 // Some games may require these buttons to have autofire as well
375 for (INT32 i = nIndex; i < nGameInpCount; i++, nIndex++)
376 {
377 bii.szName = NULL;
378 BurnDrvGetInputInfo(&bii, i);
379
380 if (bii.szName == NULL) {
381 bii.szName = "";
382 }
383 if (_stricmp(" Up", bii.szName + 2) == 0 ||
384 _stricmp(" Down", bii.szName + 2) == 0 ||
385 _stricmp(" Left", bii.szName + 2) == 0 ||
386 _stricmp(" Right", bii.szName + 2) == 0)
387 {
388 sprintf(pgi->Macro.szName, "%s", bii.szName);
389
390 pgi->nInput = GIT_MACRO_AUTO;
391 pgi->nType = BIT_DIGITAL;
392 pgi->Macro.nMode = 0;
393 pgi->Macro.pVal[0] = bii.pVal;
394 pgi->Macro.nVal[0] = 1;
395
396 nMacroCount++;
397 pgi++;
398
399 if (_stricmp(" Up", bii.szName + 2) == 0) pArrow[0] = bii.pVal;
400 if (_stricmp(" Down", bii.szName + 2) == 0) pArrow[1] = bii.pVal;
401 if (_stricmp(" Left", bii.szName + 2) == 0) pArrow[2] = bii.pVal;
402 if (_stricmp(" Right", bii.szName + 2) == 0) pArrow[3] = bii.pVal;
403
404 if ((SETS_VS) && pArrow[0] && pArrow[1] && pArrow[2] && pArrow[3]) {
405 sprintf(pgi->Macro.szName, "P%d %s", nPlayer + 1, "�I");
406 pgi->nInput = GIT_MACRO_AUTO;
407 pgi->nType = BIT_DIGITAL;
408 pgi->Macro.nMode = 0;
409 pgi->Macro.pVal[0] = pArrow[0];
410 pgi->Macro.nVal[0] = 1;
411 pgi->Macro.pVal[1] = pArrow[2];
412 pgi->Macro.nVal[1] = 1;
413 nMacroCount++;
414 pgi++;
415
416 sprintf(pgi->Macro.szName, "P%d %s", nPlayer + 1, "�J");
417 pgi->nInput = GIT_MACRO_AUTO;
418 pgi->nType = BIT_DIGITAL;
419 pgi->Macro.nMode = 0;
420 pgi->Macro.pVal[0] = pArrow[0];
421 pgi->Macro.nVal[0] = 1;
422 pgi->Macro.pVal[1] = pArrow[3];
423 pgi->Macro.nVal[1] = 1;
424 nMacroCount++;
425 pgi++;
426
427 sprintf(pgi->Macro.szName, "P%d %s", nPlayer + 1, "�L");
428 pgi->nInput = GIT_MACRO_AUTO;
429 pgi->nType = BIT_DIGITAL;
430 pgi->Macro.nMode = 0;
431 pgi->Macro.pVal[0] = pArrow[1];
432 pgi->Macro.nVal[0] = 1;
433 pgi->Macro.pVal[1] = pArrow[2];
434 pgi->Macro.nVal[1] = 1;
435 nMacroCount++;
436 pgi++;
437
438 sprintf(pgi->Macro.szName, "P%d %s", nPlayer + 1, "�K");
439 pgi->nInput = GIT_MACRO_AUTO;
440 pgi->nType = BIT_DIGITAL;
441 pgi->Macro.nMode = 0;
442 pgi->Macro.pVal[0] = pArrow[1];
443 pgi->Macro.nVal[0] = 1;
444 pgi->Macro.pVal[1] = pArrow[3];
445 pgi->Macro.nVal[1] = 1;
446 nMacroCount++;
447 pgi++;
448 }
449 if (_stricmp(" Right", bii.szName + 2) == 0) { // The last key value is ...
450 nIndex++;
451 break;
452 }
453 }
454 }
455 for (INT32 i = 0; i < nRealButtons; i++) {
456 BurnDrvGetInputInfo(&bii, (HW_NEOGEO) ? nNeogeoButtons[nPlayer][i] : nPgmButtons[nPlayer][i]);
457
458 // The appearance of "Px coin" caused by the asymmetric bond of shielding P1 --> Pn (no "Boom" button on P3 of jurassic99 ...)
459 if (_stricmp(" Coin", bii.szName + 2) != 0) {
460 pgi->nInput = GIT_MACRO_AUTO;
461 pgi->nType = BIT_DIGITAL;
462 pgi->Macro.nMode = 0;
463 sprintf(pgi->Macro.szName, "%s", bii.szName);
464
465 pgi->Macro.pVal[0] = bii.pVal;
466 pgi->Macro.nVal[0] = 1;
467 nMacroCount++;
468 pgi++;
469 }
470 }
471 if (nPunchx3[nPlayer] == 7) { // Create a 3x punch macro
472 pgi->nInput = GIT_MACRO_AUTO;
473 pgi->nType = BIT_DIGITAL;
474 pgi->Macro.nMode = 0;
475
476 sprintf(pgi->Macro.szName, "P%i Buttons 3x Punch", nPlayer + 1);
477 for (INT32 j = 0; j < 3; j++) {
478 BurnDrvGetInputInfo(&bii, nPunchInputs[nPlayer][j]);
479 pgi->Macro.pVal[j] = bii.pVal;
480 pgi->Macro.nVal[j] = 1;
481 }
482
483 nMacroCount++;
484 pgi++;
485 }
486 if (nKickx3[nPlayer] == 7) { // Create a 3x kick macro
487 pgi->nInput = GIT_MACRO_AUTO;
488 pgi->nType = BIT_DIGITAL;
489 pgi->Macro.nMode = 0;
490
491 sprintf(pgi->Macro.szName, "P%i Buttons 3x Kick", nPlayer + 1);
492 for (INT32 j = 0; j < 3; j++) {
493 BurnDrvGetInputInfo(&bii, nKickInputs[nPlayer][j]);
494 pgi->Macro.pVal[j] = bii.pVal;
495 pgi->Macro.nVal[j] = 1;
496 }
497
498 nMacroCount++;
499 pgi++;
500 }
501 if (nPunchx3[nPlayer] == 7 && nKickx3[nPlayer] == 7) { // Create a Weak Punch + Weak Kick macro, Combination keys in the sfa3 series
502 pgi->nInput = GIT_MACRO_AUTO;
503 pgi->nType = BIT_DIGITAL;
504 pgi->Macro.nMode = 0;
505
506 sprintf(pgi->Macro.szName, "P%i Buttons Weak PK", nPlayer + 1);
507 BurnDrvGetInputInfo(&bii, nPunchInputs[nPlayer][0]);
508 pgi->Macro.pVal[0] = bii.pVal;
509 pgi->Macro.nVal[0] = 1;
510 BurnDrvGetInputInfo(&bii, nKickInputs[nPlayer][0]);
511 pgi->Macro.pVal[1] = bii.pVal;
512 pgi->Macro.nVal[1] = 1;
513
514 nMacroCount++;
515 pgi++;
516 }
517 if (nPunchx3[nPlayer] == 7 && nKickx3[nPlayer] == 7) { // Create a Medium Punch + Medium Kick macro, Combination keys in the sfa3 series
518 pgi->nInput = GIT_MACRO_AUTO;
519 pgi->nType = BIT_DIGITAL;
520 pgi->Macro.nMode = 0;
521
522 sprintf(pgi->Macro.szName, "P%i Buttons Medium PK", nPlayer + 1);
523 BurnDrvGetInputInfo(&bii, nPunchInputs[nPlayer][1]);
524 pgi->Macro.pVal[0] = bii.pVal;
525 pgi->Macro.nVal[0] = 1;
526 BurnDrvGetInputInfo(&bii, nKickInputs[nPlayer][1]);
527 pgi->Macro.pVal[1] = bii.pVal;
528 pgi->Macro.nVal[1] = 1;
529
530 nMacroCount++;
531 pgi++;
532 }
533 if (nPunchx3[nPlayer] == 7 && nKickx3[nPlayer] == 7) { // Create a Strong Punch + Strong Kick macro, Combination keys in the sfa3 series
534 pgi->nInput = GIT_MACRO_AUTO;
535 pgi->nType = BIT_DIGITAL;
536 pgi->Macro.nMode = 0;
537
538 sprintf(pgi->Macro.szName, "P%i Buttons Strong PK", nPlayer + 1);
539 BurnDrvGetInputInfo(&bii, nPunchInputs[nPlayer][2]);
540 pgi->Macro.pVal[0] = bii.pVal;
541 pgi->Macro.nVal[0] = 1;
542 BurnDrvGetInputInfo(&bii, nKickInputs[nPlayer][2]);
543 pgi->Macro.pVal[1] = bii.pVal;
544 pgi->Macro.nVal[1] = 1;
545
546 nMacroCount++;
547 pgi++;
548 }
549 if (nPunchx3[nPlayer] == 7 && nKickx3[nPlayer] == 7) { // Create a Strong Punch + Weak Kick macro, Quick cancel technique in sf2ce series
550 pgi->nInput = GIT_MACRO_AUTO;
551 pgi->nType = BIT_DIGITAL;
552 pgi->Macro.nMode = 0;
553
554 sprintf(pgi->Macro.szName, "P%i Buttons SP + WK", nPlayer + 1);
555 BurnDrvGetInputInfo(&bii, nPunchInputs[nPlayer][2]);
556 pgi->Macro.pVal[0] = bii.pVal;
557 pgi->Macro.nVal[0] = 1;
558 BurnDrvGetInputInfo(&bii, nKickInputs[nPlayer][0]);
559 pgi->Macro.pVal[1] = bii.pVal;
560 pgi->Macro.nVal[1] = 1;
561
562 nMacroCount++;
563 pgi++;
564 }
565 if (nRealButtons == 4 && HW_NEOGEO) { // NeoGeo & NeoGeo cd
566 pgi->nInput = GIT_MACRO_AUTO;
567 pgi->nType = BIT_DIGITAL;
568 pgi->Macro.nMode = 0;
569 sprintf(pgi->Macro.szName, "P%i Buttons AB", nPlayer + 1);
570 BurnDrvGetInputInfo(&bii, nNeogeoButtons[nPlayer][0]);
571 pgi->Macro.pVal[0] = bii.pVal;
572 pgi->Macro.nVal[0] = 1;
573 BurnDrvGetInputInfo(&bii, nNeogeoButtons[nPlayer][1]);
574 pgi->Macro.pVal[1] = bii.pVal;
575 pgi->Macro.nVal[1] = 1;
576 nMacroCount++;
577 pgi++;
578
579 pgi->nInput = GIT_MACRO_AUTO;
580 pgi->nType = BIT_DIGITAL;
581 pgi->Macro.nMode = 0;
582 sprintf(pgi->Macro.szName, "P%i Buttons AC", nPlayer + 1);
583 BurnDrvGetInputInfo(&bii, nNeogeoButtons[nPlayer][0]);
584 pgi->Macro.pVal[0] = bii.pVal;
585 pgi->Macro.nVal[0] = 1;
586 BurnDrvGetInputInfo(&bii, nNeogeoButtons[nPlayer][2]);
587 pgi->Macro.pVal[1] = bii.pVal;
588 pgi->Macro.nVal[1] = 1;
589 nMacroCount++;
590 pgi++;
591
592 pgi->nInput = GIT_MACRO_AUTO;
593 pgi->nType = BIT_DIGITAL;
594 pgi->Macro.nMode = 0;
595 sprintf(pgi->Macro.szName, "P%i Buttons AD", nPlayer + 1);
596 BurnDrvGetInputInfo(&bii, nNeogeoButtons[nPlayer][0]);
597 pgi->Macro.pVal[0] = bii.pVal;
598 pgi->Macro.nVal[0] = 1;
599 BurnDrvGetInputInfo(&bii, nNeogeoButtons[nPlayer][3]);
600 pgi->Macro.pVal[1] = bii.pVal;
601 pgi->Macro.nVal[1] = 1;
602 nMacroCount++;
603 pgi++;
604
605 pgi->nInput = GIT_MACRO_AUTO;
606 pgi->nType = BIT_DIGITAL;
607 pgi->Macro.nMode = 0;
608 sprintf(pgi->Macro.szName, "P%i Buttons BC", nPlayer + 1);
609 BurnDrvGetInputInfo(&bii, nNeogeoButtons[nPlayer][1]);
610 pgi->Macro.pVal[0] = bii.pVal;
611 pgi->Macro.nVal[0] = 1;
612 BurnDrvGetInputInfo(&bii, nNeogeoButtons[nPlayer][2]);
613 pgi->Macro.pVal[1] = bii.pVal;
614 pgi->Macro.nVal[1] = 1;
615 nMacroCount++;
616 pgi++;
617
618 pgi->nInput = GIT_MACRO_AUTO;
619 pgi->nType = BIT_DIGITAL;
620 pgi->Macro.nMode = 0;
621 sprintf(pgi->Macro.szName, "P%i Buttons BD", nPlayer + 1);
622 BurnDrvGetInputInfo(&bii, nNeogeoButtons[nPlayer][1]);
623 pgi->Macro.pVal[0] = bii.pVal;
624 pgi->Macro.nVal[0] = 1;
625 BurnDrvGetInputInfo(&bii, nNeogeoButtons[nPlayer][3]);
626 pgi->Macro.pVal[1] = bii.pVal;
627 pgi->Macro.nVal[1] = 1;
628 nMacroCount++;
629 pgi++;
630
631 pgi->nInput = GIT_MACRO_AUTO;
632 pgi->nType = BIT_DIGITAL;
633 pgi->Macro.nMode = 0;
634 sprintf(pgi->Macro.szName, "P%i Buttons CD", nPlayer + 1);
635 BurnDrvGetInputInfo(&bii, nNeogeoButtons[nPlayer][2]);
636 pgi->Macro.pVal[0] = bii.pVal;
637 pgi->Macro.nVal[0] = 1;
638 BurnDrvGetInputInfo(&bii, nNeogeoButtons[nPlayer][3]);
639 pgi->Macro.pVal[1] = bii.pVal;
640 pgi->Macro.nVal[1] = 1;
641 nMacroCount++;
642 pgi++;
643
644 pgi->nInput = GIT_MACRO_AUTO;
645 pgi->nType = BIT_DIGITAL;
646 pgi->Macro.nMode = 0;
647 sprintf(pgi->Macro.szName, "P%i Buttons ABC", nPlayer + 1);
648 BurnDrvGetInputInfo(&bii, nNeogeoButtons[nPlayer][0]);
649 pgi->Macro.pVal[0] = bii.pVal;
650 pgi->Macro.nVal[0] = 1;
651 BurnDrvGetInputInfo(&bii, nNeogeoButtons[nPlayer][1]);
652 pgi->Macro.pVal[1] = bii.pVal;
653 pgi->Macro.nVal[1] = 1;
654 BurnDrvGetInputInfo(&bii, nNeogeoButtons[nPlayer][2]);
655 pgi->Macro.pVal[2] = bii.pVal;
656 pgi->Macro.nVal[2] = 1;
657 nMacroCount++;
658 pgi++;
659
660 pgi->nInput = GIT_MACRO_AUTO;
661 pgi->nType = BIT_DIGITAL;
662 pgi->Macro.nMode = 0;
663 sprintf(pgi->Macro.szName, "P%i Buttons ABD", nPlayer + 1);
664 BurnDrvGetInputInfo(&bii, nNeogeoButtons[nPlayer][0]);
665 pgi->Macro.pVal[0] = bii.pVal;
666 pgi->Macro.nVal[0] = 1;
667 BurnDrvGetInputInfo(&bii, nNeogeoButtons[nPlayer][1]);
668 pgi->Macro.pVal[1] = bii.pVal;
669 pgi->Macro.nVal[1] = 1;
670 BurnDrvGetInputInfo(&bii, nNeogeoButtons[nPlayer][3]);
671 pgi->Macro.pVal[2] = bii.pVal;
672 pgi->Macro.nVal[2] = 1;
673 nMacroCount++;
674 pgi++;
675
676 pgi->nInput = GIT_MACRO_AUTO;
677 pgi->nType = BIT_DIGITAL;
678 pgi->Macro.nMode = 0;
679 sprintf(pgi->Macro.szName, "P%i Buttons ACD", nPlayer + 1);
680 BurnDrvGetInputInfo(&bii, nNeogeoButtons[nPlayer][0]);
681 pgi->Macro.pVal[0] = bii.pVal;
682 pgi->Macro.nVal[0] = 1;
683 BurnDrvGetInputInfo(&bii, nNeogeoButtons[nPlayer][2]);
684 pgi->Macro.pVal[1] = bii.pVal;
685 pgi->Macro.nVal[1] = 1;
686 BurnDrvGetInputInfo(&bii, nNeogeoButtons[nPlayer][3]);
687 pgi->Macro.pVal[2] = bii.pVal;
688 pgi->Macro.nVal[2] = 1;
689 nMacroCount++;
690 pgi++;
691
692 pgi->nInput = GIT_MACRO_AUTO;
693 pgi->nType = BIT_DIGITAL;
694 pgi->Macro.nMode = 0;
695 sprintf(pgi->Macro.szName, "P%i Buttons BCD", nPlayer + 1);
696 BurnDrvGetInputInfo(&bii, nNeogeoButtons[nPlayer][1]);
697 pgi->Macro.pVal[0] = bii.pVal;
698 pgi->Macro.nVal[0] = 1;
699 BurnDrvGetInputInfo(&bii, nNeogeoButtons[nPlayer][2]);
700 pgi->Macro.pVal[1] = bii.pVal;
701 pgi->Macro.nVal[1] = 1;
702 BurnDrvGetInputInfo(&bii, nNeogeoButtons[nPlayer][3]);
703 pgi->Macro.pVal[2] = bii.pVal;
704 pgi->Macro.nVal[2] = 1;
705 nMacroCount++;
706 pgi++;
707
708 pgi->nInput = GIT_MACRO_AUTO;
709 pgi->nType = BIT_DIGITAL;
710 pgi->Macro.nMode = 0;
711 sprintf(pgi->Macro.szName, "P%i Buttons ABCD", nPlayer + 1);
712 BurnDrvGetInputInfo(&bii, nNeogeoButtons[nPlayer][0]);
713 pgi->Macro.pVal[0] = bii.pVal;
714 pgi->Macro.nVal[0] = 1;
715 BurnDrvGetInputInfo(&bii, nNeogeoButtons[nPlayer][1]);
716 pgi->Macro.pVal[1] = bii.pVal;
717 pgi->Macro.nVal[1] = 1;
718 BurnDrvGetInputInfo(&bii, nNeogeoButtons[nPlayer][2]);
719 pgi->Macro.pVal[2] = bii.pVal;
720 pgi->Macro.nVal[2] = 1;
721 BurnDrvGetInputInfo(&bii, nNeogeoButtons[nPlayer][3]);
722 pgi->Macro.pVal[3] = bii.pVal;
723 pgi->Macro.nVal[3] = 1;
724 nMacroCount++;
725 pgi++;
726 }
727 if (nRealButtons == 4 && HW_MISC) { // PGM & Other 4 key games;
728 pgi->nInput = GIT_MACRO_AUTO;
729 pgi->nType = BIT_DIGITAL;
730 pgi->Macro.nMode = 0;
731 sprintf(pgi->Macro.szName, "P%i Buttons 12", nPlayer + 1);
732 BurnDrvGetInputInfo(&bii, nPgmButtons[nPlayer][0]);
733 pgi->Macro.pVal[0] = bii.pVal;
734 pgi->Macro.nVal[0] = 1;
735 BurnDrvGetInputInfo(&bii, nPgmButtons[nPlayer][1]);
736 pgi->Macro.pVal[1] = bii.pVal;
737 pgi->Macro.nVal[1] = 1;
738 nMacroCount++;
739 pgi++;
740
741 pgi->nInput = GIT_MACRO_AUTO;
742 pgi->nType = BIT_DIGITAL;
743 pgi->Macro.nMode = 0;
744 sprintf(pgi->Macro.szName, "P%i Buttons 13", nPlayer + 1);
745 BurnDrvGetInputInfo(&bii, nPgmButtons[nPlayer][0]);
746 pgi->Macro.pVal[0] = bii.pVal;
747 pgi->Macro.nVal[0] = 1;
748 BurnDrvGetInputInfo(&bii, nPgmButtons[nPlayer][2]);
749 pgi->Macro.pVal[1] = bii.pVal;
750 pgi->Macro.nVal[1] = 1;
751 nMacroCount++;
752 pgi++;
753
754 pgi->nInput = GIT_MACRO_AUTO;
755 pgi->nType = BIT_DIGITAL;
756 pgi->Macro.nMode = 0;
757 sprintf(pgi->Macro.szName, "P%i Buttons 14", nPlayer + 1);
758 BurnDrvGetInputInfo(&bii, nPgmButtons[nPlayer][0]);
759 pgi->Macro.pVal[0] = bii.pVal;
760 pgi->Macro.nVal[0] = 1;
761 BurnDrvGetInputInfo(&bii, nPgmButtons[nPlayer][3]);
762 pgi->Macro.pVal[1] = bii.pVal;
763 pgi->Macro.nVal[1] = 1;
764 nMacroCount++;
765 pgi++;
766
767 pgi->nInput = GIT_MACRO_AUTO;
768 pgi->nType = BIT_DIGITAL;
769 pgi->Macro.nMode = 0;
770 sprintf(pgi->Macro.szName, "P%i Buttons 23", nPlayer + 1);
771 BurnDrvGetInputInfo(&bii, nPgmButtons[nPlayer][1]);
772 pgi->Macro.pVal[0] = bii.pVal;
773 pgi->Macro.nVal[0] = 1;
774 BurnDrvGetInputInfo(&bii, nPgmButtons[nPlayer][2]);
775 pgi->Macro.pVal[1] = bii.pVal;
776 pgi->Macro.nVal[1] = 1;
777 nMacroCount++;
778 pgi++;
779
780 pgi->nInput = GIT_MACRO_AUTO;
781 pgi->nType = BIT_DIGITAL;
782 pgi->Macro.nMode = 0;
783 sprintf(pgi->Macro.szName, "P%i Buttons 24", nPlayer + 1);
784 BurnDrvGetInputInfo(&bii, nPgmButtons[nPlayer][1]);
785 pgi->Macro.pVal[0] = bii.pVal;
786 pgi->Macro.nVal[0] = 1;
787 BurnDrvGetInputInfo(&bii, nPgmButtons[nPlayer][3]);
788 pgi->Macro.pVal[1] = bii.pVal;
789 pgi->Macro.nVal[1] = 1;
790 nMacroCount++;
791 pgi++;
792
793 pgi->nInput = GIT_MACRO_AUTO;
794 pgi->nType = BIT_DIGITAL;
795 pgi->Macro.nMode = 0;
796 sprintf(pgi->Macro.szName, "P%i Buttons 34", nPlayer + 1);
797 BurnDrvGetInputInfo(&bii, nPgmButtons[nPlayer][2]);
798 pgi->Macro.pVal[0] = bii.pVal;
799 pgi->Macro.nVal[0] = 1;
800 BurnDrvGetInputInfo(&bii, nPgmButtons[nPlayer][3]);
801 pgi->Macro.pVal[1] = bii.pVal;
802 pgi->Macro.nVal[1] = 1;
803 nMacroCount++;
804 pgi++;
805
806 pgi->nInput = GIT_MACRO_AUTO;
807 pgi->nType = BIT_DIGITAL;
808 pgi->Macro.nMode = 0;
809 sprintf(pgi->Macro.szName, "P%i Buttons 123", nPlayer + 1);
810 BurnDrvGetInputInfo(&bii, nPgmButtons[nPlayer][0]);
811 pgi->Macro.pVal[0] = bii.pVal;
812 pgi->Macro.nVal[0] = 1;
813 BurnDrvGetInputInfo(&bii, nPgmButtons[nPlayer][1]);
814 pgi->Macro.pVal[1] = bii.pVal;
815 pgi->Macro.nVal[1] = 1;
816 BurnDrvGetInputInfo(&bii, nPgmButtons[nPlayer][2]);
817 pgi->Macro.pVal[2] = bii.pVal;
818 pgi->Macro.nVal[2] = 1;
819 nMacroCount++;
820 pgi++;
821
822 pgi->nInput = GIT_MACRO_AUTO;
823 pgi->nType = BIT_DIGITAL;
824 pgi->Macro.nMode = 0;
825 sprintf(pgi->Macro.szName, "P%i Buttons 124", nPlayer + 1);
826 BurnDrvGetInputInfo(&bii, nPgmButtons[nPlayer][0]);
827 pgi->Macro.pVal[0] = bii.pVal;
828 pgi->Macro.nVal[0] = 1;
829 BurnDrvGetInputInfo(&bii, nPgmButtons[nPlayer][1]);
830 pgi->Macro.pVal[1] = bii.pVal;
831 pgi->Macro.nVal[1] = 1;
832 BurnDrvGetInputInfo(&bii, nPgmButtons[nPlayer][3]);
833 pgi->Macro.pVal[2] = bii.pVal;
834 pgi->Macro.nVal[2] = 1;
835 nMacroCount++;
836 pgi++;
837
838 pgi->nInput = GIT_MACRO_AUTO;
839 pgi->nType = BIT_DIGITAL;
840 pgi->Macro.nMode = 0;
841 sprintf(pgi->Macro.szName, "P%i Buttons 134", nPlayer + 1);
842 BurnDrvGetInputInfo(&bii, nPgmButtons[nPlayer][0]);
843 pgi->Macro.pVal[0] = bii.pVal;
844 pgi->Macro.nVal[0] = 1;
845 BurnDrvGetInputInfo(&bii, nPgmButtons[nPlayer][2]);
846 pgi->Macro.pVal[1] = bii.pVal;
847 pgi->Macro.nVal[1] = 1;
848 BurnDrvGetInputInfo(&bii, nPgmButtons[nPlayer][3]);
849 pgi->Macro.pVal[2] = bii.pVal;
850 pgi->Macro.nVal[2] = 1;
851 nMacroCount++;
852 pgi++;
853
854 pgi->nInput = GIT_MACRO_AUTO;
855 pgi->nType = BIT_DIGITAL;
856 pgi->Macro.nMode = 0;
857 sprintf(pgi->Macro.szName, "P%i Buttons 234", nPlayer + 1);
858 BurnDrvGetInputInfo(&bii, nPgmButtons[nPlayer][1]);
859 pgi->Macro.pVal[0] = bii.pVal;
860 pgi->Macro.nVal[0] = 1;
861 BurnDrvGetInputInfo(&bii, nPgmButtons[nPlayer][2]);
862 pgi->Macro.pVal[1] = bii.pVal;
863 pgi->Macro.nVal[1] = 1;
864 BurnDrvGetInputInfo(&bii, nPgmButtons[nPlayer][3]);
865 pgi->Macro.pVal[2] = bii.pVal;
866 pgi->Macro.nVal[2] = 1;
867 nMacroCount++;
868 pgi++;
869
870 pgi->nInput = GIT_MACRO_AUTO;
871 pgi->nType = BIT_DIGITAL;
872 pgi->Macro.nMode = 0;
873 sprintf(pgi->Macro.szName, "P%i Buttons 1234", nPlayer + 1);
874 BurnDrvGetInputInfo(&bii, nPgmButtons[nPlayer][0]);
875 pgi->Macro.pVal[0] = bii.pVal;
876 pgi->Macro.nVal[0] = 1;
877 BurnDrvGetInputInfo(&bii, nPgmButtons[nPlayer][1]);
878 pgi->Macro.pVal[1] = bii.pVal;
879 pgi->Macro.nVal[1] = 1;
880 BurnDrvGetInputInfo(&bii, nPgmButtons[nPlayer][2]);
881 pgi->Macro.pVal[2] = bii.pVal;
882 pgi->Macro.nVal[2] = 1;
883 BurnDrvGetInputInfo(&bii, nPgmButtons[nPlayer][3]);
884 pgi->Macro.pVal[3] = bii.pVal;
885 pgi->Macro.nVal[3] = 1;
886 nMacroCount++;
887 pgi++;
888 }
889 if (nRealButtons == 3 && HW_MISC) {
890 pgi->nInput = GIT_MACRO_AUTO;
891 pgi->nType = BIT_DIGITAL;
892 pgi->Macro.nMode = 0;
893 sprintf(pgi->Macro.szName, "P%i Buttons 12", nPlayer + 1);
894 BurnDrvGetInputInfo(&bii, nPgmButtons[nPlayer][0]);
895 pgi->Macro.pVal[0] = bii.pVal;
896 pgi->Macro.nVal[0] = 1;
897 BurnDrvGetInputInfo(&bii, nPgmButtons[nPlayer][1]);
898 pgi->Macro.pVal[1] = bii.pVal;
899 pgi->Macro.nVal[1] = 1;
900 nMacroCount++;
901 pgi++;
902
903 BurnDrvGetInputInfo(&bii, nPgmButtons[nPlayer][2]); // If it's like jurassic99 ...
904 if (_stricmp(" Coin", bii.szName + 2) != 0) {
905 pgi->nInput = GIT_MACRO_AUTO;
906 pgi->nType = BIT_DIGITAL;
907 pgi->Macro.nMode = 0;
908 sprintf(pgi->Macro.szName, "P%i Buttons 13", nPlayer + 1);
909 pgi->Macro.pVal[1] = bii.pVal;
910 pgi->Macro.nVal[1] = 1;
911 BurnDrvGetInputInfo(&bii, nPgmButtons[nPlayer][0]);
912 pgi->Macro.pVal[0] = bii.pVal;
913 pgi->Macro.nVal[0] = 1;
914 nMacroCount++;
915 pgi++;
916 }
917
918 BurnDrvGetInputInfo(&bii, nPgmButtons[nPlayer][2]); // If it's like jurassic99 ...
919 if (_stricmp(" Coin", bii.szName + 2) != 0) {
920 pgi->nInput = GIT_MACRO_AUTO;
921 pgi->nType = BIT_DIGITAL;
922 pgi->Macro.nMode = 0;
923 sprintf(pgi->Macro.szName, "P%i Buttons 23", nPlayer + 1);
924 pgi->Macro.pVal[1] = bii.pVal;
925 pgi->Macro.nVal[1] = 1;
926 BurnDrvGetInputInfo(&bii, nPgmButtons[nPlayer][1]);
927 pgi->Macro.pVal[0] = bii.pVal;
928 pgi->Macro.nVal[0] = 1;
929 nMacroCount++;
930 pgi++;
931 }
932
933 BurnDrvGetInputInfo(&bii, nPgmButtons[nPlayer][2]); // If it's like jurassic99 ...
934 if (_stricmp(" Coin", bii.szName + 2) != 0) {
935 pgi->nInput = GIT_MACRO_AUTO;
936 pgi->nType = BIT_DIGITAL;
937 pgi->Macro.nMode = 0;
938 sprintf(pgi->Macro.szName, "P%i Buttons 123", nPlayer + 1);
939 pgi->Macro.pVal[2] = bii.pVal;
940 pgi->Macro.nVal[2] = 1;
941 BurnDrvGetInputInfo(&bii, nPgmButtons[nPlayer][0]);
942 pgi->Macro.pVal[0] = bii.pVal;
943 pgi->Macro.nVal[0] = 1;
944 BurnDrvGetInputInfo(&bii, nPgmButtons[nPlayer][1]);
945 pgi->Macro.pVal[1] = bii.pVal;
946 pgi->Macro.nVal[1] = 1;
947 nMacroCount++;
948 pgi++;
949 }
950 }
951 if (nRealButtons == 2 && (HW_MISC || HW_NES)) {
952 const char* pChar = HW_NES ? "BA" : "12";
953 pgi->nInput = GIT_MACRO_AUTO;
954 pgi->nType = BIT_DIGITAL;
955 pgi->Macro.nMode = 0;
956 sprintf(pgi->Macro.szName, "P%i Buttons %s", nPlayer + 1, pChar);
957 BurnDrvGetInputInfo(&bii, nPgmButtons[nPlayer][0]);
958 pgi->Macro.pVal[0] = bii.pVal;
959 pgi->Macro.nVal[0] = 1;
960 BurnDrvGetInputInfo(&bii, nPgmButtons[nPlayer][1]);
961 pgi->Macro.pVal[1] = bii.pVal;
962 pgi->Macro.nVal[1] = 1;
963 nMacroCount++;
964 pgi++;
965 }
966 if ((BurnDrvGetHardwareCode() & HARDWARE_PUBLIC_MASK) == HARDWARE_SEGA_MEGADRIVE) {
967 pgi->nInput = GIT_MACRO_AUTO;
968 pgi->nType = BIT_DIGITAL;
969 pgi->Macro.nMode = 0;
970
971 sprintf(pgi->Macro.szName, "P%i Buttons ABC", nPlayer + 1);
972 for (INT32 j = 0; j < 3; j++) {
973 BurnDrvGetInputInfo(&bii, nPgmButtons[nPlayer][j]);
974 pgi->Macro.pVal[j] = bii.pVal;
975 pgi->Macro.nVal[j] = 1;
976 }
977 nMacroCount++;
978 pgi++;
979
980 if (nFireButtons == 6) {
981 pgi->nInput = GIT_MACRO_AUTO;
982 pgi->nType = BIT_DIGITAL;
983 pgi->Macro.nMode = 0;
984
985 sprintf(pgi->Macro.szName, "P%i Buttons XYZ", nPlayer + 1);
986 for (INT32 j = 0; j < 3; j++) {
987 BurnDrvGetInputInfo(&bii, nPgmButtons[nPlayer][j+3]);
988 pgi->Macro.pVal[j] = bii.pVal;
989 pgi->Macro.nVal[j] = 1;
990 }
991 nMacroCount++;
992 pgi++;
993 }
994 }
995 }
996
997 // LUA Hotkeys
998 for (int hotkey_num = 0; lua_hotkeys[hotkey_num] != NULL; hotkey_num++) {
999 char hotkey_name[40];
1000 sprintf(hotkey_name, "Lua Hotkey %d", (hotkey_num + 1));
1001 pgi->nInput = GIT_MACRO_AUTO;
1002 pgi->nType = BIT_DIGITAL;
1003 pgi->Macro.nMode = 0;
1004 pgi->Macro.nSysMacro = 1;
1005 sprintf(pgi->Macro.szName, hotkey_name);
1006 pgi->Macro.pVal[0] = lua_hotkeys[hotkey_num];
1007 pgi->Macro.nVal[0] = 1;
1008 nMacroCount++;
1009 pgi++;
1010 }
1011
1012 if ((nPunchx3[0] == 7) && (nKickx3[0] == 7)) {
1013 bStreetFighterLayout = true;
1014 }
1015 if (nFireButtons >= 7 && (BurnDrvGetHardwareCode() & HARDWARE_PUBLIC_MASK) == HARDWARE_CAPCOM_CPS2) {
1016 // used to be 5 buttons in the above check - now we have volume buttons it is 7
1017 bStreetFighterLayout = true;
1018 }
1019 }
1020
GameInpInit()1021 INT32 GameInpInit()
1022 {
1023 INT32 nRet = 0;
1024 // Count the number of inputs
1025 nGameInpCount = 0;
1026 nMacroCount = 0;
1027 nMaxMacro = nMaxPlayers * 52;
1028
1029 for (UINT32 i = 0; i < 0x1000; i++) {
1030 nRet = BurnDrvGetInputInfo(NULL,i);
1031 if (nRet) { // end of input list
1032 nGameInpCount = i;
1033 break;
1034 }
1035 }
1036
1037 // Allocate space for all the inputs
1038 INT32 nSize = (nGameInpCount + nMaxMacro) * sizeof(struct GameInp);
1039 GameInp = (struct GameInp*)malloc(nSize);
1040 if (GameInp == NULL) {
1041 return 1;
1042 }
1043 memset(GameInp, 0, nSize);
1044
1045 GameInpBlank(1);
1046
1047 InpDIPSWResetDIPs();
1048
1049 GameInpInitMacros();
1050
1051 nAnalogSpeed = 0x0100;
1052
1053 return 0;
1054 }
1055
GameInpExit()1056 INT32 GameInpExit()
1057 {
1058 if (GameInp) {
1059 free(GameInp);
1060 GameInp = NULL;
1061 }
1062
1063 nGameInpCount = 0;
1064 nMacroCount = 0;
1065
1066 nFireButtons = 0;
1067
1068 bStreetFighterLayout = false;
1069 bLeftAltkeyMapped = false;
1070
1071 return 0;
1072 }
1073
1074 // ---------------------------------------------------------------------------
1075 // Convert a string from a config file to an input
1076
SliderInfo(struct GameInp * pgi,TCHAR * s)1077 static TCHAR* SliderInfo(struct GameInp* pgi, TCHAR* s)
1078 {
1079 TCHAR* szRet = NULL;
1080 pgi->Input.Slider.nSliderSpeed = 0x700; // defaults
1081 pgi->Input.Slider.nSliderCenter = 0;
1082 pgi->Input.Slider.nSliderValue = 0x8000;
1083
1084 szRet = LabelCheck(s, _T("speed"));
1085 s = szRet;
1086 if (s == NULL) {
1087 return s;
1088 }
1089 pgi->Input.Slider.nSliderSpeed = (INT16)_tcstol(s, &szRet, 0);
1090 s = szRet;
1091 if (s==NULL) {
1092 return s;
1093 }
1094 szRet = LabelCheck(s, _T("center"));
1095 s = szRet;
1096 if (s == NULL) {
1097 return s;
1098 }
1099 pgi->Input.Slider.nSliderCenter = (INT16)_tcstol(s, &szRet, 0);
1100 s = szRet;
1101 if (s == NULL) {
1102 return s;
1103 }
1104
1105 return szRet;
1106 }
1107
StringToJoyAxis(struct GameInp * pgi,TCHAR * s)1108 static INT32 StringToJoyAxis(struct GameInp* pgi, TCHAR* s)
1109 {
1110 TCHAR* szRet = s;
1111
1112 pgi->Input.JoyAxis.nJoy = (UINT8)_tcstol(s, &szRet, 0);
1113 if (szRet == NULL) {
1114 return 1;
1115 }
1116 s = szRet;
1117 pgi->Input.JoyAxis.nAxis = (UINT8)_tcstol(s, &szRet, 0);
1118 if (szRet == NULL) {
1119 return 1;
1120 }
1121
1122 return 0;
1123 }
1124
StringToMouseAxis(struct GameInp * pgi,TCHAR * s)1125 static INT32 StringToMouseAxis(struct GameInp* pgi, TCHAR* s)
1126 {
1127 TCHAR* szRet = s;
1128
1129 pgi->Input.MouseAxis.nAxis = (UINT8)_tcstol(s, &szRet, 0);
1130 if (szRet == NULL) {
1131 return 1;
1132 }
1133
1134 return 0;
1135 }
1136
StringToMacro(struct GameInp * pgi,TCHAR * s)1137 static INT32 StringToMacro(struct GameInp* pgi, TCHAR* s)
1138 {
1139 TCHAR* szRet = NULL;
1140
1141 szRet = LabelCheck(s, _T("switch"));
1142 if (szRet) {
1143 s = szRet;
1144 pgi->Macro.nMode = 0x01;
1145 pgi->Macro.Switch.nCode = (UINT16)_tcstol(s, &szRet, 0);
1146 return 0;
1147 }
1148
1149 return 1;
1150 }
1151
StringToInp(struct GameInp * pgi,TCHAR * s)1152 static INT32 StringToInp(struct GameInp* pgi, TCHAR* s)
1153 {
1154 TCHAR* szRet = NULL;
1155
1156 SKIP_WS(s); // skip whitespace
1157 szRet = LabelCheck(s, _T("undefined"));
1158 if (szRet) {
1159 pgi->nInput = 0;
1160 return 0;
1161 }
1162
1163 szRet = LabelCheck(s, _T("constant"));
1164 if (szRet) {
1165 pgi->nInput = GIT_CONSTANT;
1166 s = szRet;
1167 pgi->Input.Constant.nConst=(UINT8)_tcstol(s, &szRet, 0);
1168 *(pgi->Input.pVal) = pgi->Input.Constant.nConst;
1169 return 0;
1170 }
1171
1172 szRet = LabelCheck(s, _T("switch"));
1173 if (szRet) {
1174 pgi->nInput = GIT_SWITCH;
1175 s = szRet;
1176 pgi->Input.Switch.nCode = (UINT16)_tcstol(s, &szRet, 0);
1177 return 0;
1178 }
1179
1180 // Analog using mouse axis:
1181 szRet = LabelCheck(s, _T("mouseaxis"));
1182 if (szRet) {
1183 pgi->nInput = GIT_MOUSEAXIS;
1184 return StringToMouseAxis(pgi, szRet);
1185 }
1186 // Analog using joystick axis:
1187 szRet = LabelCheck(s, _T("joyaxis-neg"));
1188 if (szRet) {
1189 pgi->nInput = GIT_JOYAXIS_NEG;
1190 return StringToJoyAxis(pgi, szRet);
1191 }
1192 szRet = LabelCheck(s, _T("joyaxis-pos"));
1193 if (szRet) {
1194 pgi->nInput = GIT_JOYAXIS_POS;
1195 return StringToJoyAxis(pgi, szRet);
1196 }
1197 szRet = LabelCheck(s, _T("joyaxis"));
1198 if (szRet) {
1199 pgi->nInput = GIT_JOYAXIS_FULL;
1200 return StringToJoyAxis(pgi, szRet);
1201 }
1202
1203 // Analog using keyboard slider
1204 szRet = LabelCheck(s, _T("slider"));
1205 if (szRet) {
1206 s = szRet;
1207 pgi->nInput = GIT_KEYSLIDER;
1208 pgi->Input.Slider.SliderAxis.nSlider[0] = 0; // defaults
1209 pgi->Input.Slider.SliderAxis.nSlider[1] = 0; //
1210
1211 pgi->Input.Slider.SliderAxis.nSlider[0] = (UINT16)_tcstol(s, &szRet, 0);
1212 s = szRet;
1213 if (s == NULL) {
1214 return 1;
1215 }
1216 pgi->Input.Slider.SliderAxis.nSlider[1] = (UINT16)_tcstol(s, &szRet, 0);
1217 s = szRet;
1218 if (s == NULL) {
1219 return 1;
1220 }
1221 szRet = SliderInfo(pgi, s);
1222 s = szRet;
1223 if (s == NULL) { // Get remaining slider info
1224 return 1;
1225 }
1226 return 0;
1227 }
1228
1229 // Analog using joystick slider
1230 szRet = LabelCheck(s, _T("joyslider"));
1231 if (szRet) {
1232 s = szRet;
1233 pgi->nInput = GIT_JOYSLIDER;
1234 pgi->Input.Slider.JoyAxis.nJoy = 0; // defaults
1235 pgi->Input.Slider.JoyAxis.nAxis = 0; //
1236
1237 pgi->Input.Slider.JoyAxis.nJoy = (UINT8)_tcstol(s, &szRet, 0);
1238 s = szRet;
1239 if (s == NULL) {
1240 return 1;
1241 }
1242 pgi->Input.Slider.JoyAxis.nAxis = (UINT8)_tcstol(s, &szRet, 0);
1243 s = szRet;
1244 if (s == NULL) {
1245 return 1;
1246 }
1247 szRet = SliderInfo(pgi, s); // Get remaining slider info
1248 s = szRet;
1249 if (s == NULL) {
1250 return 1;
1251 }
1252 return 0;
1253 }
1254
1255 return 1;
1256 }
1257
1258 // ---------------------------------------------------------------------------
1259 // Convert an input to a string for config files
1260
InpToString(struct GameInp * pgi)1261 TCHAR* InpToString(struct GameInp* pgi)
1262 {
1263 static TCHAR szString[80];
1264
1265 if (pgi->nInput == 0) {
1266 return _T("undefined");
1267 }
1268 if (pgi->nInput == GIT_CONSTANT) {
1269 _stprintf(szString, _T("constant 0x%.2X"), pgi->Input.Constant.nConst);
1270 return szString;
1271 }
1272 if (pgi->nInput == GIT_SWITCH) {
1273 _stprintf(szString, _T("switch 0x%.2X"), pgi->Input.Switch.nCode);
1274 return szString;
1275 }
1276 if (pgi->nInput == GIT_KEYSLIDER) {
1277 _stprintf(szString, _T("slider 0x%.2x 0x%.2x speed 0x%x center %d"), pgi->Input.Slider.SliderAxis.nSlider[0], pgi->Input.Slider.SliderAxis.nSlider[1], pgi->Input.Slider.nSliderSpeed, pgi->Input.Slider.nSliderCenter);
1278 return szString;
1279 }
1280 if (pgi->nInput == GIT_JOYSLIDER) {
1281 _stprintf(szString, _T("joyslider %d %d speed 0x%x center %d"), pgi->Input.Slider.JoyAxis.nJoy, pgi->Input.Slider.JoyAxis.nAxis, pgi->Input.Slider.nSliderSpeed, pgi->Input.Slider.nSliderCenter);
1282 return szString;
1283 }
1284 if (pgi->nInput == GIT_MOUSEAXIS) {
1285 _stprintf(szString, _T("mouseaxis %d"), pgi->Input.MouseAxis.nAxis);
1286 return szString;
1287 }
1288 if (pgi->nInput == GIT_JOYAXIS_FULL) {
1289 _stprintf(szString, _T("joyaxis %d %d"), pgi->Input.JoyAxis.nJoy, pgi->Input.JoyAxis.nAxis);
1290 return szString;
1291 }
1292 if (pgi->nInput == GIT_JOYAXIS_NEG) {
1293 _stprintf(szString, _T("joyaxis-neg %d %d"), pgi->Input.JoyAxis.nJoy, pgi->Input.JoyAxis.nAxis);
1294 return szString;
1295 }
1296 if (pgi->nInput == GIT_JOYAXIS_POS) {
1297 _stprintf(szString, _T("joyaxis-pos %d %d"), pgi->Input.JoyAxis.nJoy, pgi->Input.JoyAxis.nAxis);
1298 return szString;
1299 }
1300
1301 return _T("unknown");
1302 }
1303
InpMacroToString(struct GameInp * pgi)1304 TCHAR* InpMacroToString(struct GameInp* pgi)
1305 {
1306 static TCHAR szString[256];
1307
1308 if (pgi->nInput == GIT_MACRO_AUTO) {
1309 if (pgi->Macro.nMode) {
1310 _stprintf(szString, _T("switch 0x%.2X"), pgi->Macro.Switch.nCode);
1311 return szString;
1312 }
1313 }
1314
1315 if (pgi->nInput == GIT_MACRO_CUSTOM) {
1316 struct BurnInputInfo bii;
1317
1318 if (pgi->Macro.nMode) {
1319 _stprintf(szString, _T("switch 0x%.2X"), pgi->Macro.Switch.nCode);
1320 } else {
1321 _stprintf(szString, _T("undefined"));
1322 }
1323
1324 for (INT32 i = 0; i < 4; i++) {
1325 if (pgi->Macro.pVal[i]) {
1326 BurnDrvGetInputInfo(&bii, pgi->Macro.nInput[i]);
1327 _stprintf(szString + _tcslen(szString), _T(" \"%hs\" 0x%02X"), bii.szName, pgi->Macro.nVal[i]);
1328 }
1329 }
1330
1331 return szString;
1332 }
1333
1334 return _T("undefined");
1335 }
1336
1337 // ---------------------------------------------------------------------------
1338 // Generate a user-friendly name for a control (PC-side)
1339
1340 static struct { INT32 nCode; TCHAR* szName; } KeyNames[] = {
1341
1342 #define FBK_DEFNAME(k) k, _T(#k)
1343
1344 { FBK_ESCAPE, _T("ESCAPE") },
1345 { FBK_1, _T("1") },
1346 { FBK_2, _T("2") },
1347 { FBK_3, _T("3") },
1348 { FBK_4, _T("4") },
1349 { FBK_5, _T("5") },
1350 { FBK_6, _T("6") },
1351 { FBK_7, _T("7") },
1352 { FBK_8, _T("8") },
1353 { FBK_9, _T("9") },
1354 { FBK_0, _T("0") },
1355 { FBK_MINUS, _T("MINUS") },
1356 { FBK_EQUALS, _T("EQUALS") },
1357 { FBK_BACK, _T("BACKSPACE") },
1358 { FBK_TAB, _T("TAB") },
1359 { FBK_Q, _T("Q") },
1360 { FBK_W, _T("W") },
1361 { FBK_E, _T("E") },
1362 { FBK_R, _T("R") },
1363 { FBK_T, _T("T") },
1364 { FBK_Y, _T("Y") },
1365 { FBK_U, _T("U") },
1366 { FBK_I, _T("I") },
1367 { FBK_O, _T("O") },
1368 { FBK_P, _T("P") },
1369 { FBK_LBRACKET, _T("OPENING BRACKET") },
1370 { FBK_RBRACKET, _T("CLOSING BRACKET") },
1371 { FBK_RETURN, _T("ENTER") },
1372 { FBK_LCONTROL, _T("LEFT CONTROL") },
1373 { FBK_A, _T("A") },
1374 { FBK_S, _T("S") },
1375 { FBK_D, _T("D") },
1376 { FBK_F, _T("F") },
1377 { FBK_G, _T("G") },
1378 { FBK_H, _T("H") },
1379 { FBK_J, _T("J") },
1380 { FBK_K, _T("K") },
1381 { FBK_L, _T("L") },
1382 { FBK_SEMICOLON, _T("SEMICOLON") },
1383 { FBK_APOSTROPHE, _T("APOSTROPHE") },
1384 { FBK_GRAVE, _T("ACCENT GRAVE") },
1385 { FBK_LSHIFT, _T("LEFT SHIFT") },
1386 { FBK_BACKSLASH, _T("BACKSLASH") },
1387 { FBK_Z, _T("Z") },
1388 { FBK_X, _T("X") },
1389 { FBK_C, _T("C") },
1390 { FBK_V, _T("V") },
1391 { FBK_B, _T("B") },
1392 { FBK_N, _T("N") },
1393 { FBK_M, _T("M") },
1394 { FBK_COMMA, _T("COMMA") },
1395 { FBK_PERIOD, _T("PERIOD") },
1396 { FBK_SLASH, _T("SLASH") },
1397 { FBK_RSHIFT, _T("RIGHT SHIFT") },
1398 { FBK_MULTIPLY, _T("NUMPAD MULTIPLY") },
1399 { FBK_LALT, _T("LEFT MENU") },
1400 { FBK_SPACE, _T("SPACE") },
1401 { FBK_CAPITAL, _T("CAPSLOCK") },
1402 { FBK_F1, _T("F1") },
1403 { FBK_F2, _T("F2") },
1404 { FBK_F3, _T("F3") },
1405 { FBK_F4, _T("F4") },
1406 { FBK_F5, _T("F5") },
1407 { FBK_F6, _T("F6") },
1408 { FBK_F7, _T("F7") },
1409 { FBK_F8, _T("F8") },
1410 { FBK_F9, _T("F9") },
1411 { FBK_F10, _T("F10") },
1412 { FBK_NUMLOCK, _T("NUMLOCK") },
1413 { FBK_SCROLL, _T("SCROLLLOCK") },
1414 { FBK_NUMPAD7, _T("NUMPAD 7") },
1415 { FBK_NUMPAD8, _T("NUMPAD 8") },
1416 { FBK_NUMPAD9, _T("NUMPAD 9") },
1417 { FBK_SUBTRACT, _T("NUMPAD SUBTRACT") },
1418 { FBK_NUMPAD4, _T("NUMPAD 4") },
1419 { FBK_NUMPAD5, _T("NUMPAD 5") },
1420 { FBK_NUMPAD6, _T("NUMPAD 6") },
1421 { FBK_ADD, _T("NUMPAD ADD") },
1422 { FBK_NUMPAD1, _T("NUMPAD 1") },
1423 { FBK_NUMPAD2, _T("NUMPAD 2") },
1424 { FBK_NUMPAD3, _T("NUMPAD 3") },
1425 { FBK_NUMPAD0, _T("NUMPAD 0") },
1426 { FBK_DECIMAL, _T("NUMPAD DECIMAL POINT") },
1427 { FBK_DEFNAME(FBK_OEM_102) },
1428 { FBK_F11, _T("F11") },
1429 { FBK_F12, _T("F12") },
1430 { FBK_F13, _T("F13") },
1431 { FBK_F14, _T("F14") },
1432 { FBK_F15, _T("F15") },
1433 { FBK_DEFNAME(FBK_KANA) },
1434 { FBK_DEFNAME(FBK_ABNT_C1) },
1435 { FBK_DEFNAME(FBK_CONVERT) },
1436 { FBK_DEFNAME(FBK_NOCONVERT) },
1437 { FBK_DEFNAME(FBK_YEN) },
1438 { FBK_DEFNAME(FBK_ABNT_C2) },
1439 { FBK_NUMPADEQUALS, _T("NUMPAD EQUALS") },
1440 { FBK_DEFNAME(FBK_PREVTRACK) },
1441 { FBK_DEFNAME(FBK_AT) },
1442 { FBK_COLON, _T("COLON") },
1443 { FBK_UNDERLINE, _T("UNDERSCORE") },
1444 { FBK_DEFNAME(FBK_KANJI) },
1445 { FBK_DEFNAME(FBK_STOP) },
1446 { FBK_DEFNAME(FBK_AX) },
1447 { FBK_DEFNAME(FBK_UNLABELED) },
1448 { FBK_DEFNAME(FBK_NEXTTRACK) },
1449 { FBK_NUMPADENTER, _T("NUMPAD ENTER") },
1450 { FBK_RCONTROL, _T("RIGHT CONTROL") },
1451 { FBK_DEFNAME(FBK_MUTE) },
1452 { FBK_DEFNAME(FBK_CALCULATOR) },
1453 { FBK_DEFNAME(FBK_PLAYPAUSE) },
1454 { FBK_DEFNAME(FBK_MEDIASTOP) },
1455 { FBK_DEFNAME(FBK_VOLUMEDOWN) },
1456 { FBK_DEFNAME(FBK_VOLUMEUP) },
1457 { FBK_DEFNAME(FBK_WEBHOME) },
1458 { FBK_DEFNAME(FBK_NUMPADCOMMA) },
1459 { FBK_DIVIDE, _T("NUMPAD DIVIDE") },
1460 { FBK_SYSRQ, _T("PRINTSCREEN") },
1461 { FBK_RALT, _T("RIGHT MENU") },
1462 { FBK_PAUSE, _T("PAUSE") },
1463 { FBK_HOME, _T("HOME") },
1464 { FBK_UPARROW, _T("ARROW UP") },
1465 { FBK_PRIOR, _T("PAGE UP") },
1466 { FBK_LEFTARROW, _T("ARROW LEFT") },
1467 { FBK_RIGHTARROW, _T("ARROW RIGHT") },
1468 { FBK_END, _T("END") },
1469 { FBK_DOWNARROW, _T("ARROW DOWN") },
1470 { FBK_NEXT, _T("PAGE DOWN") },
1471 { FBK_INSERT, _T("INSERT") },
1472 { FBK_DELETE, _T("DELETE") },
1473 { FBK_LWIN, _T("LEFT WINDOWS") },
1474 { FBK_RWIN, _T("RIGHT WINDOWS") },
1475 { FBK_DEFNAME(FBK_APPS) },
1476 { FBK_DEFNAME(FBK_POWER) },
1477 { FBK_DEFNAME(FBK_SLEEP) },
1478 { FBK_DEFNAME(FBK_WAKE) },
1479 { FBK_DEFNAME(FBK_WEBSEARCH) },
1480 { FBK_DEFNAME(FBK_WEBFAVORITES) },
1481 { FBK_DEFNAME(FBK_WEBREFRESH) },
1482 { FBK_DEFNAME(FBK_WEBSTOP) },
1483 { FBK_DEFNAME(FBK_WEBFORWARD) },
1484 { FBK_DEFNAME(FBK_WEBBACK) },
1485 { FBK_DEFNAME(FBK_MYCOMPUTER) },
1486 { FBK_DEFNAME(FBK_MAIL) },
1487 { FBK_DEFNAME(FBK_MEDIASELECT) },
1488
1489 #undef FBK_DEFNAME
1490
1491 { 0, NULL }
1492 };
1493
InputCodeDesc(INT32 c)1494 TCHAR* InputCodeDesc(INT32 c)
1495 {
1496 static TCHAR szString[64];
1497 TCHAR* szName = _T("");
1498
1499 // Mouse
1500 if (c >= 0x8000) {
1501 INT32 nMouse = (c >> 8) & 0x3F;
1502 INT32 nCode = c & 0xFF;
1503 if (nCode >= 0x80) {
1504 _stprintf(szString, _T("Mouse %d Button %d"), nMouse, nCode & 0x7F);
1505 return szString;
1506 }
1507 if (nCode < 0x06) {
1508 TCHAR szAxis[3][3] = { _T("X"), _T("Y"), _T("Z") };
1509 TCHAR szDir[6][16] = { _T("negative"), _T("positive"), _T("Left"), _T("Right"), _T("Up"), _T("Down") };
1510 if (nCode < 4) {
1511 _stprintf(szString, _T("Mouse %d %s (%s %s)"), nMouse, szDir[nCode + 2], szAxis[nCode >> 1], szDir[nCode & 1]);
1512 } else {
1513 _stprintf(szString, _T("Mouse %d %s %s"), nMouse, szAxis[nCode >> 1], szDir[nCode & 1]);
1514 }
1515 return szString;
1516 }
1517 }
1518
1519 // Joystick
1520 if (c >= 0x4000 && c < 0x8000) {
1521 INT32 nJoy = (c >> 8) & 0x3F;
1522 INT32 nCode = c & 0xFF;
1523 if (nCode >= 0x80) {
1524 _stprintf(szString, _T("Joy %d Button %d"), nJoy, nCode & 0x7F);
1525 return szString;
1526 }
1527 if (nCode < 0x10) {
1528 TCHAR szAxis[8][3] = { _T("X"), _T("Y"), _T("Z"), _T("rX"), _T("rY"), _T("rZ"), _T("s0"), _T("s1") };
1529 TCHAR szDir[6][16] = { _T("negative"), _T("positive"), _T("Left"), _T("Right"), _T("Up"), _T("Down") };
1530 if (nCode < 4) {
1531 _stprintf(szString, _T("Joy %d %s (%s %s)"), nJoy, szDir[nCode + 2], szAxis[nCode >> 1], szDir[nCode & 1]);
1532 } else {
1533 _stprintf(szString, _T("Joy %d %s %s"), nJoy, szAxis[nCode >> 1], szDir[nCode & 1]);
1534 }
1535 return szString;
1536 }
1537 if (nCode < 0x20) {
1538 TCHAR szDir[4][16] = { _T("Left"), _T("Right"), _T("Up"), _T("Down") };
1539 _stprintf(szString, _T("Joy %d POV-hat %d %s"), nJoy, (nCode & 0x0F) >> 2, szDir[nCode & 3]);
1540 return szString;
1541 }
1542 }
1543
1544 for (INT32 i = 0; KeyNames[i].nCode; i++) {
1545 if (c == KeyNames[i].nCode) {
1546 if (KeyNames[i].szName) {
1547 szName = KeyNames[i].szName;
1548 }
1549 break;
1550 }
1551 }
1552
1553 if (szName[0]) {
1554 _stprintf(szString, _T("%s"), szName);
1555 } else {
1556 _stprintf(szString, _T("code 0x%.2X"), c);
1557 }
1558
1559 return szString;
1560 }
1561
InpToDesc(struct GameInp * pgi)1562 TCHAR* InpToDesc(struct GameInp* pgi)
1563 {
1564 static TCHAR szInputName[64] = _T("");
1565
1566 if (pgi->nInput == 0) {
1567 return _T("");
1568 }
1569 if (pgi->nInput == GIT_CONSTANT) {
1570 if (pgi->nType & BIT_GROUP_CONSTANT) {
1571 for (INT32 i = 0; i < 8; i++) {
1572 szInputName[7 - i] = pgi->Input.Constant.nConst & (1 << i) ? _T('1') : _T('0');
1573 }
1574 szInputName[8] = 0;
1575
1576 return szInputName;
1577 }
1578
1579 if (pgi->Input.Constant.nConst == 0) {
1580 return _T("-");
1581 }
1582 }
1583 if (pgi->nInput == GIT_SWITCH) {
1584 return InputCodeDesc(pgi->Input.Switch.nCode);
1585 }
1586 if (pgi->nInput == GIT_MOUSEAXIS) {
1587 TCHAR nAxis = _T('?');
1588 switch (pgi->Input.MouseAxis.nAxis) {
1589 case 0:
1590 nAxis = _T('X');
1591 break;
1592 case 1:
1593 nAxis = _T('Y');
1594 break;
1595 case 2:
1596 nAxis = _T('Z');
1597 break;
1598 }
1599 _stprintf(szInputName, _T("Mouse %i %c axis"), pgi->Input.MouseAxis.nMouse, nAxis);
1600 return szInputName;
1601 }
1602 if (pgi->nInput & GIT_GROUP_JOYSTICK) {
1603 TCHAR szAxis[8][3] = { _T("X"), _T("Y"), _T("Z"), _T("rX"), _T("rY"), _T("rZ"), _T("s0"), _T("s1") };
1604 TCHAR szRange[4][16] = { _T("unknown"), _T("full"), _T("negative"), _T("positive") };
1605 INT32 nRange = 0;
1606 switch (pgi->nInput) {
1607 case GIT_JOYAXIS_FULL:
1608 nRange = 1;
1609 break;
1610 case GIT_JOYAXIS_NEG:
1611 nRange = 2;
1612 break;
1613 case GIT_JOYAXIS_POS:
1614 nRange = 3;
1615 break;
1616 }
1617
1618 _stprintf(szInputName, _T("Joy %d %s axis (%s range)"), pgi->Input.JoyAxis.nJoy, szAxis[pgi->Input.JoyAxis.nAxis], szRange[nRange]);
1619 return szInputName;
1620 }
1621
1622 return InpToString(pgi); // Just do the rest as they are in the config file
1623 }
1624
InpMacroToDesc(struct GameInp * pgi)1625 TCHAR* InpMacroToDesc(struct GameInp* pgi)
1626 {
1627 if (pgi->nInput & GIT_GROUP_MACRO) {
1628 if (pgi->Macro.nMode) {
1629 return InputCodeDesc(pgi->Macro.Switch.nCode);
1630 }
1631 }
1632
1633 return _T("");
1634 }
1635
1636 // ---------------------------------------------------------------------------
1637
1638 // Find the input number by info
InputInfoToNum(TCHAR * szName)1639 static UINT32 InputInfoToNum(TCHAR* szName)
1640 {
1641 for (UINT32 i = 0; i < nGameInpCount; i++) {
1642 struct BurnInputInfo bii;
1643 BurnDrvGetInputInfo(&bii, i);
1644 if (bii.pVal == NULL) {
1645 continue;
1646 }
1647
1648 if (_tcsicmp(szName, ANSIToTCHAR(bii.szInfo, NULL, 0)) == 0) {
1649 return i;
1650 }
1651 }
1652 return ~0U;
1653 }
1654
1655 // Find the input number by name
InputNameToNum(TCHAR * szName)1656 static UINT32 InputNameToNum(TCHAR* szName)
1657 {
1658 for (UINT32 i = 0; i < nGameInpCount; i++) {
1659 struct BurnInputInfo bii;
1660 BurnDrvGetInputInfo(&bii, i);
1661 if (bii.pVal == NULL) {
1662 continue;
1663 }
1664
1665 if (_tcsicmp(szName, ANSIToTCHAR(bii.szName, NULL, 0)) == 0) {
1666 return i;
1667 }
1668 }
1669 return ~0U;
1670 }
1671
InputNumToName(UINT32 i)1672 TCHAR* InputNumToName(UINT32 i)
1673 {
1674 struct BurnInputInfo bii;
1675 bii.szName = NULL;
1676 BurnDrvGetInputInfo(&bii, i);
1677 if (bii.szName == NULL) {
1678 return _T("unknown");
1679 }
1680 return ANSIToTCHAR(bii.szName, NULL, 0);
1681 }
1682
MacroNameToNum(TCHAR * szName)1683 static UINT32 MacroNameToNum(TCHAR* szName)
1684 {
1685 struct GameInp* pgi = GameInp + nGameInpCount;
1686 for (UINT32 i = 0; i < nMacroCount; i++, pgi++) {
1687 if (pgi->nInput & GIT_GROUP_MACRO) {
1688 if (_tcsicmp(szName, ANSIToTCHAR(pgi->Macro.szName, NULL, 0)) == 0) {
1689 return i;
1690 }
1691 }
1692 }
1693 return ~0U;
1694 }
1695
1696 // ---------------------------------------------------------------------------
1697
GameInpAutoOne(struct GameInp * pgi,char * szi)1698 static INT32 GameInpAutoOne(struct GameInp* pgi, char* szi)
1699 {
1700 for (INT32 i = 0; i < nMaxPlayers; i++) {
1701 INT32 nSlide = nPlayerDefaultControls[i] >> 4;
1702 switch (nPlayerDefaultControls[i] & 0x0F) {
1703 case 0: // Keyboard
1704 GamcAnalogKey(pgi, szi, i, nSlide);
1705 GamcPlayer(pgi, szi, i, -1);
1706 GamcMisc(pgi, szi, i);
1707 break;
1708 case 1: // Joystick 1
1709 GamcAnalogJoy(pgi, szi, i, 0, nSlide);
1710 GamcPlayer(pgi, szi, i, 0);
1711 GamcMisc(pgi, szi, i);
1712 break;
1713 case 2: // Joystick 2
1714 GamcAnalogJoy(pgi, szi, i, 1, nSlide);
1715 GamcPlayer(pgi, szi, i, 1);
1716 GamcMisc(pgi, szi, i);
1717 break;
1718 case 3: // Joystick 3
1719 GamcAnalogJoy(pgi, szi, i, 2, nSlide);
1720 GamcPlayer(pgi, szi, i, 2);
1721 GamcMisc(pgi, szi, i);
1722 break;
1723 case 4: // X-Arcade left side
1724 GamcMisc(pgi, szi, i);
1725 GamcPlayerHotRod(pgi, szi, i, 0x10, nSlide);
1726 break;
1727 case 5: // X-Arcade right side
1728 GamcMisc(pgi, szi, i);
1729 GamcPlayerHotRod(pgi, szi, i, 0x11, nSlide);
1730 break;
1731 case 6: // Hot Rod left side
1732 GamcMisc(pgi, szi, i);
1733 GamcPlayerHotRod(pgi, szi, i, 0x00, nSlide);
1734 break;
1735 case 7: // Hot Rod right side
1736 GamcMisc(pgi, szi, i);
1737 GamcPlayerHotRod(pgi, szi, i, 0x01, nSlide);
1738 break;
1739 default:
1740 GamcMisc(pgi, szi, i);
1741 }
1742 }
1743
1744 return 0;
1745 }
1746
AddCustomMacro(TCHAR * szValue,bool bOverWrite)1747 static INT32 AddCustomMacro(TCHAR* szValue, bool bOverWrite)
1748 {
1749 TCHAR* szQuote = NULL;
1750 TCHAR* szEnd = NULL;
1751
1752 if (QuoteRead(&szQuote, &szEnd, szValue)) {
1753 return 1;
1754 }
1755
1756 INT32 nMode = -1;
1757 INT32 nInput = -1;
1758 bool bCreateNew = false;
1759 struct BurnInputInfo bii;
1760
1761 for (UINT32 j = nGameInpCount; j < nGameInpCount + nMacroCount; j++) {
1762 if (GameInp[j].nInput == GIT_MACRO_CUSTOM) {
1763 if (LabelCheck(szQuote, ANSIToTCHAR(GameInp[j].Macro.szName, NULL, 0))) {
1764 nInput = j;
1765 break;
1766 }
1767 }
1768 }
1769
1770 if (nInput == -1) {
1771 if (nMacroCount + 1 == nMaxMacro) {
1772 return 1;
1773 }
1774 nInput = nGameInpCount + nMacroCount;
1775 bCreateNew = true;
1776 }
1777
1778 _tcscpy(szQuote, ANSIToTCHAR(GameInp[nInput].Macro.szName, NULL, 0));
1779
1780 if ((szValue = LabelCheck(szEnd, _T("undefined"))) != NULL) {
1781 nMode = 0;
1782 } else {
1783 if ((szValue = LabelCheck(szEnd, _T("switch"))) != NULL) {
1784
1785 if (bOverWrite || GameInp[nInput].Macro.nMode == 0) {
1786 GameInp[nInput].Macro.Switch.nCode = (UINT16)_tcstol(szValue, &szValue, 0);
1787 }
1788
1789 nMode = 1;
1790 }
1791 }
1792
1793 if (nMode >= 0) {
1794 INT32 nFound = 0;
1795
1796 for (INT32 i = 0; i < 4; i++) {
1797 GameInp[nInput].Macro.pVal[i] = NULL;
1798 GameInp[nInput].Macro.nVal[i] = 0;
1799 GameInp[nInput].Macro.nInput[i] = 0;
1800
1801 if (szValue == NULL) {
1802 break;
1803 }
1804
1805 if (QuoteRead(&szQuote, &szEnd, szValue)) {
1806 break;
1807 }
1808
1809 for (UINT32 j = 0; j < nGameInpCount; j++) {
1810 bii.szName = NULL;
1811 BurnDrvGetInputInfo(&bii, j);
1812 if (bii.pVal == NULL) {
1813 continue;
1814 }
1815
1816 TCHAR* szString = LabelCheck(szQuote, ANSIToTCHAR(bii.szName, NULL, 0));
1817 if (szString && szEnd) {
1818 GameInp[nInput].Macro.pVal[i] = bii.pVal;
1819 GameInp[nInput].Macro.nInput[i] = j;
1820
1821 GameInp[nInput].Macro.nVal[i] = (UINT8)_tcstol(szEnd, &szValue, 0);
1822
1823 nFound++;
1824
1825 break;
1826 }
1827 }
1828 }
1829
1830 if (nFound) {
1831 if (GameInp[nInput].Macro.pVal[nFound - 1]) {
1832 GameInp[nInput].nInput = GIT_MACRO_CUSTOM;
1833 GameInp[nInput].Macro.nMode = nMode;
1834 if (bCreateNew) {
1835 nMacroCount++;
1836 }
1837 return 0;
1838 }
1839 }
1840 }
1841
1842 return 1;
1843 }
1844
GameInputAutoIni(INT32 nPlayer,TCHAR * lpszFile,bool bOverWrite)1845 INT32 GameInputAutoIni(INT32 nPlayer, TCHAR* lpszFile, bool bOverWrite)
1846 {
1847 TCHAR szLine[1024];
1848 INT32 nFileVersion = 0;
1849 UINT32 i;
1850
1851 //nAnalogSpeed = 0x0100; /* this clobbers the setting read at the beginning of the file. */
1852
1853 FILE* h = _tfopen(lpszFile, _T("rt"));
1854 if (h == NULL) {
1855 return 1;
1856 }
1857
1858 // Go through each line of the config file and process inputs
1859 while (_fgetts(szLine, sizeof(szLine), h)) {
1860 TCHAR* szValue;
1861 INT32 nLen = _tcslen(szLine);
1862
1863 // Get rid of the linefeed at the end
1864 if (szLine[nLen - 1] == 10) {
1865 szLine[nLen - 1] = 0;
1866 nLen--;
1867 }
1868
1869 szValue = LabelCheck(szLine, _T("version"));
1870 if (szValue) {
1871 nFileVersion = _tcstol(szValue, NULL, 0);
1872 }
1873 szValue = LabelCheck(szLine, _T("analog"));
1874 if (szValue) {
1875 nAnalogSpeed = _tcstol(szValue, NULL, 0);
1876 }
1877
1878 if (nConfigMinVersion <= nFileVersion && nFileVersion <= nBurnVer) {
1879 szValue = LabelCheck(szLine, _T("input"));
1880 if (szValue) {
1881 TCHAR* szQuote = NULL;
1882 TCHAR* szEnd = NULL;
1883 if (QuoteRead(&szQuote, &szEnd, szValue)) {
1884 continue;
1885 }
1886
1887 if ((szQuote[0] == _T('p') || szQuote[0] == _T('P')) && szQuote[1] >= _T('1') && szQuote[1] <= _T('0') + nMaxPlayers && szQuote[2] == _T(' ')) {
1888 if (szQuote[1] != _T('1') + nPlayer) {
1889 continue;
1890 }
1891 } else {
1892 if (nPlayer != 0) {
1893 continue;
1894 }
1895 }
1896
1897 // Find which input number this refers to
1898 i = InputNameToNum(szQuote);
1899 if (i == ~0U) {
1900 i = InputInfoToNum(szQuote);
1901 if (i == ~0U) {
1902 continue;
1903 }
1904 }
1905
1906 if (GameInp[i].nInput == 0 || bOverWrite) { // Undefined - assign mapping
1907 StringToInp(GameInp + i, szEnd);
1908 }
1909 }
1910
1911 szValue = LabelCheck(szLine, _T("macro"));
1912 if (szValue) {
1913 TCHAR* szQuote = NULL;
1914 TCHAR* szEnd = NULL;
1915 if (QuoteRead(&szQuote, &szEnd, szValue)) {
1916 continue;
1917 }
1918
1919 i = MacroNameToNum(szQuote);
1920 if (i != ~0U) {
1921 i += nGameInpCount;
1922 if (GameInp[i].Macro.nMode == 0 || bOverWrite) { // Undefined - assign mapping
1923 StringToMacro(GameInp + i, szEnd);
1924 }
1925 }
1926 }
1927
1928 szValue = LabelCheck(szLine, _T("afire")); // Hardware Default Preset - load autofire
1929 if (szValue) {
1930 TCHAR* szQuote = NULL;
1931 TCHAR* szEnd = NULL;
1932
1933 if (QuoteRead(&szQuote, &szEnd, szValue)) continue;
1934
1935 i = MacroNameToNum(szQuote);
1936 if (i != ~0U) {
1937 i += nGameInpCount;
1938 if (GameInp[i].Macro.nMode == 0 || bOverWrite) {
1939 (GameInp + i)->Macro.nSysMacro = 15;
1940 }
1941 }
1942 }
1943
1944 szValue = LabelCheck(szLine, _T("custom"));
1945 if (szValue) {
1946 AddCustomMacro(szValue, bOverWrite);
1947 }
1948 }
1949 }
1950
1951 fclose(h);
1952
1953 return 0;
1954 }
1955
1956 // Hardware description, preset file, {hardware, codes}, history.dat token
1957 tIniStruct gamehw_cfg[] = {
1958 {_T("CPS-1/CPS-2/CPS-3 hardware"), _T("config/presets/cps.ini"), { HARDWARE_CAPCOM_CPS1, HARDWARE_CAPCOM_CPS1_QSOUND, HARDWARE_CAPCOM_CPS1_GENERIC, HARDWARE_CAPCOM_CPSCHANGER, HARDWARE_CAPCOM_CPS2, HARDWARE_CAPCOM_CPS3, 0 }, "$info=" },
1959 {_T("Neo-Geo hardware"), _T("config/presets/neogeo.ini"), { HARDWARE_SNK_NEOGEO, 0 }, "$info=" },
1960 {_T("Neo-Geo hardware"), _T("config/presets/neogeo.ini"), { HARDWARE_SNK_NEOCD, 0 }, "$neocd=" },
1961 {_T("Neo Geo Pocket hardware"), _T("config/presets/ngp.ini"), { HARDWARE_SNK_NGP, 0 }, "$ngp=" },
1962 {_T("Neo Geo Pocket hardware"), _T("config/presets/ngp.ini"), { HARDWARE_SNK_NGPC, 0 }, "$ngpc=" },
1963 {_T("NES hardware"), _T("config/presets/nes.ini"), { HARDWARE_NES, 0 }, "$nes=" },
1964 {_T("FDS hardware"), _T("config/presets/fds.ini"), { HARDWARE_FDS, 0 }, "$famicom_flop="},
1965 {_T("PGM hardware"), _T("config/presets/pgm.ini"), { HARDWARE_IGS_PGM, 0 }, "$info=" },
1966 {_T("MegaDrive hardware"), _T("config/presets/megadrive.ini"), { HARDWARE_SEGA_MEGADRIVE, 0 }, "$megadriv=" },
1967 {_T("PCE/SGX hardware"), _T("config/presets/pce.ini"), { HARDWARE_PCENGINE_PCENGINE, 0 }, "$pce=" },
1968 {_T("TG16 hardware"), _T("config/presets/pce.ini"), { HARDWARE_PCENGINE_TG16, 0 }, "$tg16=" },
1969 {_T("MSX1 hardware"), _T("config/presets/msx.ini"), { HARDWARE_MSX, 0 }, "$msx1_cart=" },
1970 {_T("Coleco hardware"), _T("config/presets/coleco.ini"), { HARDWARE_COLECO, 0 }, "$coleco=" },
1971 {_T("SG1000 hardware"), _T("config/presets/sg1000.ini"), { HARDWARE_SEGA_SG1000, 0 }, "$sg1000=" },
1972 {_T("Sega Master System hardware"), _T("config/presets/sms.ini"), { HARDWARE_SEGA_MASTER_SYSTEM, 0 }, "$sms=" },
1973 {_T("Sega Game Gear hardware"), _T("config/presets/gg.ini"), { HARDWARE_SEGA_GAME_GEAR, 0 }, "$gamegear=" },
1974 {_T("Sinclair Spectrum hardware"), _T("config/presets/spectrum.ini"), { HARDWARE_SPECTRUM, 0 }, "$spectrum_cass=" },
1975 {_T("Fairchild Channel F hardware"),_T("config/presets/channelf.ini"), { HARDWARE_CHANNELF, 0 }, "$channelf=" },
1976 {_T("\0"), _T("\0"), { 0 }, "" } // END of list
1977 };
1978
GetHistoryDatHardwareToken(char * to_string)1979 void GetHistoryDatHardwareToken(char *to_string)
1980 {
1981 INT32 nHardwareFlag = (BurnDrvGetHardwareCode() & HARDWARE_PUBLIC_MASK);
1982
1983 // See if nHardwareFlag belongs to any systems in gamehw_config
1984 for (INT32 i = 0; gamehw_cfg[i].ini[0] != '\0'; i++) {
1985 for (INT32 hw = 0; gamehw_cfg[i].hw[hw] != 0; hw++) {
1986 if (gamehw_cfg[i].hw[hw] == nHardwareFlag)
1987 {
1988 strcpy(to_string, gamehw_cfg[i].gameinfotoken);
1989 return;
1990 }
1991 }
1992 }
1993
1994 // HW not found, default to "$info=" (arcade game)
1995 strcpy(to_string, "$info=");
1996 }
1997
ConfigGameLoadHardwareDefaults()1998 INT32 ConfigGameLoadHardwareDefaults()
1999 {
2000 TCHAR *szFileName = _T("");
2001 INT32 nApplyHardwareDefaults = 0;
2002
2003 INT32 nHardwareFlag = (BurnDrvGetHardwareCode() & HARDWARE_PUBLIC_MASK);
2004
2005 // See if nHardwareFlag belongs to any systems in gamehw_config
2006 for (INT32 i = 0; gamehw_cfg[i].ini[0] != '\0'; i++) {
2007 for (INT32 hw = 0; gamehw_cfg[i].hw[hw] != 0; hw++) {
2008 if (gamehw_cfg[i].hw[hw] == nHardwareFlag)
2009 {
2010 szFileName = gamehw_cfg[i].ini;
2011 nApplyHardwareDefaults = 1;
2012 break;
2013 }
2014 }
2015 }
2016
2017 if (nApplyHardwareDefaults) {
2018 for (INT32 nPlayer = 0; nPlayer < nMaxPlayers; nPlayer++) {
2019 GameInputAutoIni(nPlayer, szFileName, true);
2020 }
2021 }
2022
2023 return 0;
2024 }
2025
2026 // Auto-configure any undefined inputs to defaults
GameInpDefault()2027 INT32 GameInpDefault()
2028 {
2029 struct GameInp* pgi;
2030 struct BurnInputInfo bii;
2031 UINT32 i;
2032
2033 for (INT32 nPlayer = 0; nPlayer < nMaxPlayers; nPlayer++) {
2034
2035 if ((nPlayerDefaultControls[nPlayer] & 0x0F) != 0x0F) {
2036 continue;
2037 }
2038
2039 GameInputAutoIni(nPlayer, szPlayerDefaultIni[nPlayer], false);
2040 }
2041
2042 // Fill all inputs still undefined
2043 for (i = 0, pgi = GameInp; i < nGameInpCount; i++, pgi++) {
2044 if (pgi->nInput) { // Already defined - leave it alone
2045 continue;
2046 }
2047
2048 // Get the extra info about the input
2049 bii.szInfo = NULL;
2050 BurnDrvGetInputInfo(&bii, i);
2051 if (bii.pVal == NULL) {
2052 continue;
2053 }
2054 if (bii.szInfo == NULL) {
2055 bii.szInfo = "";
2056 }
2057
2058 // Dip switches - set to constant
2059 if (bii.nType & BIT_GROUP_CONSTANT) {
2060 pgi->nInput = GIT_CONSTANT;
2061 continue;
2062 }
2063 #ifdef BUILD_MACOS
2064 if (MacOSinpInitControls(pgi, bii.szInfo) == 0) {
2065 continue; // NOTE: prevents 'GameInpAutoOne' from being called
2066 }
2067 #endif
2068 GameInpAutoOne(pgi, bii.szInfo);
2069 }
2070
2071 #ifndef BUILD_MACOS
2072 // Fill in macros still undefined
2073 for (i = 0; i < nMacroCount; i++, pgi++) {
2074 if (pgi->nInput != GIT_MACRO_AUTO || pgi->Macro.nMode) { // Already defined - leave it alone
2075 continue;
2076 }
2077
2078 GameInpAutoOne(pgi, pgi->Macro.szName);
2079 }
2080 #endif
2081
2082 return 0;
2083 }
2084
2085 // ---------------------------------------------------------------------------
2086 // Write all the GameInps out to config file 'h'
2087
GameInpWrite(FILE * h)2088 INT32 GameInpWrite(FILE* h)
2089 {
2090 // Write input types
2091 for (UINT32 i = 0; i < nGameInpCount; i++) {
2092 TCHAR* szName = NULL;
2093 INT32 nPad = 0;
2094 szName = InputNumToName(i);
2095 _ftprintf(h, _T("input \"%s\" "), szName);
2096 nPad = 16 - _tcslen(szName);
2097 for (INT32 j = 0; j < nPad; j++) {
2098 _ftprintf(h, _T(" "));
2099 }
2100 _ftprintf(h, _T("%s\n"), InpToString(GameInp + i));
2101 }
2102
2103 _ftprintf(h, _T("\n"));
2104
2105 struct GameInp* pgi = GameInp + nGameInpCount;
2106 for (UINT32 i = 0; i < nMacroCount; i++, pgi++) {
2107 INT32 nPad = 0;
2108
2109 if (pgi->nInput & GIT_GROUP_MACRO) {
2110 switch (pgi->nInput) {
2111 case GIT_MACRO_AUTO: // Auto-assigned macros
2112 if (pgi->Macro.nSysMacro == 15) _ftprintf(h, _T("afire \"%hs\"\n"), pgi->Macro.szName); // Create autofire (afire) tag
2113 _ftprintf(h, _T("macro \"%hs\" "), pgi->Macro.szName);
2114 break;
2115 case GIT_MACRO_CUSTOM: // Custom macros
2116 _ftprintf(h, _T("custom \"%hs\" "), pgi->Macro.szName);
2117 break;
2118 default: // Unknown -- ignore
2119 continue;
2120 }
2121
2122 nPad = 16 - strlen(pgi->Macro.szName);
2123 for (INT32 j = 0; j < nPad; j++) {
2124 _ftprintf(h, _T(" "));
2125 }
2126 _ftprintf(h, _T("%s\n"), InpMacroToString(pgi));
2127 }
2128 }
2129
2130 return 0;
2131 }
2132
2133 // ---------------------------------------------------------------------------
2134
2135 // Read a GameInp in
GameInpRead(TCHAR * szVal,bool bOverWrite)2136 INT32 GameInpRead(TCHAR* szVal, bool bOverWrite)
2137 {
2138 INT32 nRet;
2139 TCHAR* szQuote = NULL;
2140 TCHAR* szEnd = NULL;
2141 UINT32 i = 0;
2142
2143 nRet = QuoteRead(&szQuote, &szEnd, szVal);
2144 if (nRet) {
2145 return 1;
2146 }
2147
2148 // Find which input number this refers to
2149 i = InputNameToNum(szQuote);
2150 if (i == ~0U) {
2151 return 1;
2152 }
2153
2154 if (bOverWrite || GameInp[i].nInput == 0) {
2155 // Parse the input description into the GameInp structure
2156 StringToInp(GameInp + i, szEnd);
2157 }
2158
2159 return 0;
2160 }
2161
GameInpMacroRead(TCHAR * szVal,bool bOverWrite)2162 INT32 GameInpMacroRead(TCHAR* szVal, bool bOverWrite)
2163 {
2164 INT32 nRet;
2165 TCHAR* szQuote = NULL;
2166 TCHAR* szEnd = NULL;
2167 UINT32 i = 0;
2168
2169 nRet = QuoteRead(&szQuote, &szEnd, szVal);
2170 if (nRet) {
2171 return 1;
2172 }
2173
2174 i = MacroNameToNum(szQuote);
2175 if (i != ~0U) {
2176 i += nGameInpCount;
2177 if (GameInp[i].Macro.nMode == 0 || bOverWrite) {
2178 StringToMacro(GameInp + i, szEnd);
2179 }
2180 }
2181
2182 return 0;
2183 }
2184
GameMacroAutofireRead(TCHAR * szVal,bool bOverWrite)2185 INT32 GameMacroAutofireRead(TCHAR* szVal, bool bOverWrite)
2186 {
2187 INT32 nRet;
2188 TCHAR* szQuote = NULL;
2189 TCHAR* szEnd = NULL;
2190 UINT32 i = 0;
2191
2192 nRet = QuoteRead(&szQuote, &szEnd, szVal);
2193 if (nRet) {
2194 return 1;
2195 }
2196
2197 i = MacroNameToNum(szQuote);
2198 if (i != ~0U) {
2199 i += nGameInpCount;
2200 if (GameInp[i].Macro.nMode == 0 || bOverWrite) {
2201 (GameInp + i)->Macro.nSysMacro = 15;
2202 }
2203 }
2204
2205 return 0;
2206 }
2207
GameInpCustomRead(TCHAR * szVal,bool bOverWrite)2208 INT32 GameInpCustomRead(TCHAR* szVal, bool bOverWrite)
2209 {
2210 return AddCustomMacro(szVal, bOverWrite);
2211 }
2212