1 // Burner Input Dialog module
2 #include "burner.h"
3
4 HWND hInpdDlg = NULL; // Handle to the Input Dialog
5 static HWND hInpdList = NULL;
6 static unsigned char *LastVal = NULL; // Last input values/defined
7 static int bLastValDefined = 0; //
8
9 static HWND hInpdGi = NULL, hInpdPci = NULL, hInpdAnalog = NULL; // Combo boxes
10
11 // Update which input is using which PC input
InpdUseUpdate()12 static int InpdUseUpdate()
13 {
14 unsigned int i, j = 0;
15 struct GameInp* pgi = NULL;
16 if (hInpdList == NULL) {
17 return 1;
18 }
19
20 // Update the values of all the inputs
21 for (i = 0, pgi = GameInp; i < nGameInpCount; i++, pgi++) {
22 LVITEM LvItem;
23 TCHAR* pszVal = NULL;
24
25 if (pgi->Input.pVal == NULL) {
26 continue;
27 }
28
29 pszVal = InpToDesc(pgi);
30
31 if (_tcscmp(pszVal, _T("code 0x00")) == 0)
32 pszVal = _T("Unassigned (locked)");
33
34 memset(&LvItem, 0, sizeof(LvItem));
35 LvItem.mask = LVIF_TEXT;
36 LvItem.iItem = j;
37 LvItem.iSubItem = 1;
38 LvItem.pszText = pszVal;
39
40 SendMessage(hInpdList, LVM_SETITEM, 0, (LPARAM)&LvItem);
41
42 j++;
43 }
44
45 for (i = 0, pgi = GameInp + nGameInpCount; i < nMacroCount; i++, pgi++) {
46 LVITEM LvItem;
47 TCHAR* pszVal = NULL;
48
49 if (pgi->nInput & GIT_GROUP_MACRO) {
50 pszVal = InpMacroToDesc(pgi);
51
52 if (_tcscmp(pszVal, _T("code 0x00")) == 0)
53 pszVal = _T("Unassigned (locked)");
54
55 memset(&LvItem, 0, sizeof(LvItem));
56 LvItem.mask = LVIF_TEXT;
57 LvItem.iItem = j;
58 LvItem.iSubItem = 1;
59 LvItem.pszText = pszVal;
60
61 SendMessage(hInpdList, LVM_SETITEM, 0, (LPARAM)&LvItem);
62 }
63
64 j++;
65 }
66
67 return 0;
68 }
69
InpdUpdate()70 int InpdUpdate()
71 {
72 unsigned int i, j = 0;
73 struct GameInp* pgi = NULL;
74 unsigned char* plv = NULL;
75 unsigned short nThisVal;
76 if (hInpdList == NULL) {
77 return 1;
78 }
79 if (LastVal == NULL) {
80 return 1;
81 }
82
83 // Update the values of all the inputs
84 for (i = 0, pgi = GameInp, plv = LastVal; i < nGameInpCount; i++, pgi++, plv++) {
85 LVITEM LvItem;
86 TCHAR szVal[16];
87
88 if (pgi->nType == 0) {
89 continue;
90 }
91
92 if (pgi->nType & BIT_GROUP_ANALOG) {
93 if (bRunPause) { // Update LastVal
94 nThisVal = pgi->Input.nVal;
95 } else {
96 nThisVal = *pgi->Input.pShortVal;
97 }
98
99 if (bLastValDefined && (pgi->nType != BIT_ANALOG_REL || nThisVal) && pgi->Input.nVal == *((unsigned short*)plv)) {
100 j++;
101 continue;
102 }
103
104 *((unsigned short*)plv) = nThisVal;
105 } else {
106 if (bRunPause) { // Update LastVal
107 nThisVal = pgi->Input.nVal;
108 } else {
109 nThisVal = *pgi->Input.pVal;
110 }
111
112 if (bLastValDefined && pgi->Input.nVal == *plv) { // hasn't changed
113 j++;
114 continue;
115 }
116
117 *plv = nThisVal;
118 }
119
120 switch (pgi->nType) {
121 case BIT_DIGITAL: {
122 if (nThisVal == 0) {
123 szVal[0] = 0;
124 } else {
125 if (nThisVal == 1) {
126 _tcscpy(szVal, _T("ON"));
127 } else {
128 _stprintf(szVal, _T("0x%02X"), nThisVal);
129 }
130 }
131 break;
132 }
133 case BIT_ANALOG_ABS: {
134 _stprintf(szVal, _T("0x%02X"), nThisVal >> 8);
135 break;
136 }
137 case BIT_ANALOG_REL: {
138 if (nThisVal == 0) {
139 szVal[0] = 0;
140 }
141 if ((short)nThisVal < 0) {
142 _stprintf(szVal, _T("%d"), ((short)nThisVal) >> 8);
143 }
144 if ((short)nThisVal > 0) {
145 _stprintf(szVal, _T("+%d"), ((short)nThisVal) >> 8);
146 }
147 break;
148 }
149 default: {
150 _stprintf(szVal, _T("0x%02X"), nThisVal);
151 }
152 }
153
154 memset(&LvItem, 0, sizeof(LvItem));
155 LvItem.mask = LVIF_TEXT;
156 LvItem.iItem = j;
157 LvItem.iSubItem = 2;
158 LvItem.pszText = szVal;
159
160 SendMessage(hInpdList, LVM_SETITEM, 0, (LPARAM)&LvItem);
161
162 j++;
163 }
164
165 bLastValDefined = 1; // LastVal is now defined
166
167 return 0;
168 }
169
InpdListBegin()170 static int InpdListBegin()
171 {
172 LVCOLUMN LvCol;
173 if (hInpdList == NULL) {
174 return 1;
175 }
176
177 // Full row select style:
178 SendMessage(hInpdList, LVM_SETEXTENDEDLISTVIEWSTYLE, 0, LVS_EX_FULLROWSELECT);
179
180 // Make column headers
181 memset(&LvCol, 0, sizeof(LvCol));
182 LvCol.mask = LVCF_TEXT | LVCF_WIDTH | LVCF_SUBITEM;
183
184 LvCol.cx = 0xa0;
185 LvCol.pszText = FBALoadStringEx(hAppInst, IDS_INPUT_INPUT, true);
186 SendMessage(hInpdList, LVM_INSERTCOLUMN, 0, (LPARAM)&LvCol);
187
188 LvCol.cx = 0xa0;
189 LvCol.pszText = FBALoadStringEx(hAppInst, IDS_INPUT_MAPPING, true);
190 SendMessage(hInpdList, LVM_INSERTCOLUMN, 1, (LPARAM)&LvCol);
191
192 LvCol.cx = 0x38;
193 LvCol.pszText = FBALoadStringEx(hAppInst, IDS_INPUT_STATE, true);
194 SendMessage(hInpdList, LVM_INSERTCOLUMN, 2, (LPARAM)&LvCol);
195
196 return 0;
197 }
198
199 // Make a list view of the game inputs
InpdListMake(int bBuild)200 int InpdListMake(int bBuild)
201 {
202 unsigned int j = 0;
203
204 if (hInpdList == NULL) {
205 return 1;
206 }
207
208 bLastValDefined = 0;
209 if (bBuild) {
210 SendMessage(hInpdList, LVM_DELETEALLITEMS, 0, 0);
211 }
212
213 // Add all the input names to the list
214 for (unsigned int i = 0; i < nGameInpCount; i++) {
215 struct BurnInputInfo bii;
216 LVITEM LvItem;
217
218 // Get the name of the input
219 bii.szName = NULL;
220 BurnDrvGetInputInfo(&bii, i);
221
222 // skip unused inputs
223 if (bii.pVal == NULL) {
224 continue;
225 }
226 if (bii.szName == NULL) {
227 bii.szName = "";
228 }
229
230 memset(&LvItem, 0, sizeof(LvItem));
231 LvItem.mask = LVIF_TEXT | LVIF_PARAM;
232 LvItem.iItem = j;
233 LvItem.iSubItem = 0;
234 LvItem.pszText = ANSIToTCHAR(bii.szName, NULL, 0);
235 LvItem.lParam = (LPARAM)i;
236
237 SendMessage(hInpdList, bBuild ? LVM_INSERTITEM : LVM_SETITEM, 0, (LPARAM)&LvItem);
238
239 j++;
240 }
241
242 struct GameInp* pgi = GameInp + nGameInpCount;
243 for (unsigned int i = 0; i < nMacroCount; i++, pgi++) {
244 LVITEM LvItem;
245
246 if (pgi->nInput & GIT_GROUP_MACRO) {
247 memset(&LvItem, 0, sizeof(LvItem));
248 LvItem.mask = LVIF_TEXT | LVIF_PARAM;
249 LvItem.iItem = j;
250 LvItem.iSubItem = 0;
251 LvItem.pszText = ANSIToTCHAR(pgi->Macro.szName, NULL, 0);
252 LvItem.lParam = (LPARAM)j;
253
254 SendMessage(hInpdList, bBuild ? LVM_INSERTITEM : LVM_SETITEM, 0, (LPARAM)&LvItem);
255 }
256
257 j++;
258 }
259
260 InpdUseUpdate();
261
262 return 0;
263 }
264
DisablePresets()265 static void DisablePresets()
266 {
267 EnableWindow(hInpdPci, FALSE);
268 EnableWindow(hInpdAnalog, FALSE);
269 EnableWindow(GetDlgItem(hInpdDlg, IDC_INPD_DEFAULT), FALSE);
270 EnableWindow(GetDlgItem(hInpdDlg, IDC_INPD_USE), FALSE);
271 }
272
InitComboboxes()273 static void InitComboboxes()
274 {
275 TCHAR szLabel[1024];
276 HANDLE search;
277 WIN32_FIND_DATA findData;
278
279 for (int i = 0; i < 4; i++) {
280 _stprintf(szLabel, FBALoadStringEx(hAppInst, IDS_INPUT_INP_PLAYER, true), i + 1);
281 SendMessage(hInpdGi, CB_ADDSTRING, 0, (LPARAM)szLabel);
282 }
283
284 SendMessage(hInpdPci, CB_ADDSTRING, 0, (LPARAM)FBALoadStringEx(hAppInst, IDS_INPUT_INP_KEYBOARD, true));
285 for (int i = 0; i < 3; i++) {
286 _stprintf(szLabel, FBALoadStringEx(hAppInst, IDS_INPUT_INP_JOYSTICK, true), i);
287 SendMessage(hInpdPci, CB_ADDSTRING, 0, (LPARAM)szLabel);
288 }
289 SendMessage(hInpdPci, CB_ADDSTRING, 0, (LPARAM)FBALoadStringEx(hAppInst, IDS_INPUT_INP_XARCADEL, true));
290 SendMessage(hInpdPci, CB_ADDSTRING, 0, (LPARAM)FBALoadStringEx(hAppInst, IDS_INPUT_INP_XARCADER, true));
291 SendMessage(hInpdPci, CB_ADDSTRING, 0, (LPARAM)FBALoadStringEx(hAppInst, IDS_INPUT_INP_HOTRODL, true));
292 SendMessage(hInpdPci, CB_ADDSTRING, 0, (LPARAM)FBALoadStringEx(hAppInst, IDS_INPUT_INP_HOTRODR, true));
293
294 // Scan presets directory for .ini files and add them to the list
295 if ((search = FindFirstFile(_T("config/presets/*.ini"), &findData)) != INVALID_HANDLE_VALUE) {
296 do {
297 findData.cFileName[_tcslen(findData.cFileName) - 4] = 0;
298 SendMessage(hInpdPci, CB_ADDSTRING, 0, (LPARAM)findData.cFileName);
299 } while (FindNextFile(search, &findData) != 0);
300
301 FindClose(search);
302 }
303 }
304
InpdInit()305 static int InpdInit()
306 {
307 int nMemLen;
308
309 hInpdList = GetDlgItem(hInpdDlg, IDC_INPD_LIST);
310
311 // Allocate a last val array for the last input values
312 nMemLen = nGameInpCount * sizeof(char);
313 LastVal = (unsigned char*)malloc(nMemLen);
314 if (LastVal == NULL) {
315 return 1;
316 }
317 memset(LastVal, 0, nMemLen);
318
319 InpdListBegin();
320 InpdListMake(1);
321
322 // Init the Combo boxes
323 hInpdGi = GetDlgItem(hInpdDlg, IDC_INPD_GI);
324 hInpdPci = GetDlgItem(hInpdDlg, IDC_INPD_PCI);
325 hInpdAnalog = GetDlgItem(hInpdDlg, IDC_INPD_ANALOG);
326 InitComboboxes();
327
328 DisablePresets();
329
330 return 0;
331 }
332
InpdExit()333 static int InpdExit()
334 {
335 // Exit the Combo boxes
336 hInpdPci = NULL;
337 hInpdGi = NULL;
338 hInpdAnalog = NULL;
339
340 if (LastVal != NULL) {
341 free(LastVal);
342 LastVal = NULL;
343 }
344 hInpdList = NULL;
345 hInpdDlg = NULL;
346 if (!bAltPause && bRunPause) {
347 bRunPause=0;
348 }
349 GameInpCheckMouse();
350
351 return 0;
352 }
353
GameInpConfigOne(int nPlayer,int nPcDev,int nAnalog,struct GameInp * pgi,char * szi)354 static void GameInpConfigOne(int nPlayer, int nPcDev, int nAnalog, struct GameInp* pgi, char* szi)
355 {
356 switch (nPcDev) {
357 case 0:
358 GamcPlayer(pgi, szi, nPlayer, -1); // Keyboard
359 GamcAnalogKey(pgi, szi, nPlayer, nAnalog);
360 GamcMisc(pgi, szi, nPlayer);
361 break;
362 case 1:
363 GamcPlayer(pgi, szi, nPlayer, 0); // Joystick 1
364 GamcAnalogJoy(pgi, szi, nPlayer, 0, nAnalog);
365 GamcMisc(pgi, szi, nPlayer);
366 break;
367 case 2:
368 GamcPlayer(pgi, szi, nPlayer, 1); // Joystick 2
369 GamcAnalogJoy(pgi, szi, nPlayer, 1, nAnalog);
370 GamcMisc(pgi, szi, nPlayer);
371 break;
372 case 3:
373 GamcPlayer(pgi, szi, nPlayer, 2); // Joystick 3
374 GamcAnalogJoy(pgi, szi, nPlayer, 2, nAnalog);
375 GamcMisc(pgi, szi, nPlayer);
376 break;
377 case 4:
378 GamcPlayerHotRod(pgi, szi, nPlayer, 0x10, nAnalog); // X-Arcade left side
379 GamcMisc(pgi, szi, -1);
380 break;
381 case 5:
382 GamcPlayerHotRod(pgi, szi, nPlayer, 0x11, nAnalog); // X-Arcade right side
383 GamcMisc(pgi, szi, -1);
384 break;
385 case 6:
386 GamcPlayerHotRod(pgi, szi, nPlayer, 0x00, nAnalog); // HotRod left side
387 GamcMisc(pgi, szi, -1);
388 break;
389 case 7:
390 GamcPlayerHotRod(pgi, szi, nPlayer, 0x01, nAnalog); // HotRod right size
391 GamcMisc(pgi, szi, -1);
392 break;
393 }
394 }
395
396 // Configure some of the game input
GameInpConfig(int nPlayer,int nPcDev,int nAnalog)397 static int GameInpConfig(int nPlayer, int nPcDev, int nAnalog)
398 {
399 struct GameInp* pgi = NULL;
400 unsigned int i;
401
402 for (i = 0, pgi = GameInp; i < nGameInpCount; i++, pgi++) {
403 struct BurnInputInfo bii;
404
405 // Get the extra info about the input
406 bii.szInfo = NULL;
407 BurnDrvGetInputInfo(&bii, i);
408 if (bii.pVal == NULL) {
409 continue;
410 }
411 if (bii.szInfo == NULL) {
412 bii.szInfo = "";
413 }
414 GameInpConfigOne(nPlayer, nPcDev, nAnalog, pgi, bii.szInfo);
415 }
416
417 for (i = 0; i < nMacroCount; i++, pgi++) {
418 GameInpConfigOne(nPlayer, nPcDev, nAnalog, pgi, pgi->Macro.szName);
419 }
420
421 GameInpCheckLeftAlt();
422
423 return 0;
424 }
425
426 // List item activated; find out which one
ListItemActivate()427 static int ListItemActivate()
428 {
429 struct BurnInputInfo bii;
430 LVITEM LvItem;
431
432 memset(&LvItem, 0, sizeof(LvItem));
433 int nSel = SendMessage(hInpdList, LVM_GETNEXTITEM, (WPARAM)-1, LVNI_SELECTED);
434 if (nSel < 0) {
435 return 1;
436 }
437
438 // Get the corresponding input
439 LvItem.mask = LVIF_PARAM;
440 LvItem.iItem = nSel;
441 LvItem.iSubItem = 0;
442 SendMessage(hInpdList, LVM_GETITEM, 0, (LPARAM)&LvItem);
443 nSel = LvItem.lParam;
444
445 if (nSel >= (int)(nGameInpCount + nMacroCount)) { // out of range
446 return 1;
447 }
448
449 memset(&bii, 0, sizeof(bii));
450 bii.nType = 0;
451 int rc = BurnDrvGetInputInfo(&bii, nSel);
452 if (bii.pVal == NULL && rc != 1) { // rc == 1 for a macro or system macro.
453 return 1;
454 }
455
456 DestroyWindow(hInpsDlg); // Make sure any existing dialogs are gone
457 DestroyWindow(hInpcDlg); //
458
459 if (bii.nType & BIT_GROUP_CONSTANT) {
460 // Dip switch is a constant - change it
461 nInpcInput = nSel;
462 InpcCreate();
463 } else {
464 if (GameInp[nSel].nInput == GIT_MACRO_CUSTOM) {
465 #if 0
466 InpMacroCreate(nSel);
467 #endif
468 } else {
469 // Assign to a key
470 nInpsInput = nSel;
471 InpsCreate();
472 }
473 }
474
475 GameInpCheckLeftAlt();
476
477 return 0;
478 }
479
480 #if 0
481 static int NewMacroButton()
482 {
483 LVITEM LvItem;
484 int nSel;
485
486 DestroyWindow(hInpsDlg); // Make sure any existing dialogs are gone
487 DestroyWindow(hInpcDlg); //
488
489 nSel = SendMessage(hInpdList, LVM_GETNEXTITEM, (WPARAM)-1, LVNI_SELECTED);
490 if (nSel < 0) {
491 nSel = -1;
492 }
493
494 // Get the corresponding input
495 LvItem.mask = LVIF_PARAM;
496 LvItem.iItem = nSel;
497 LvItem.iSubItem = 0;
498 SendMessage(hInpdList, LVM_GETITEM, 0, (LPARAM)&LvItem);
499 nSel = LvItem.lParam;
500
501 if (nSel >= (int)nGameInpCount && nSel < (int)(nGameInpCount + nMacroCount)) {
502 if (GameInp[nSel].nInput != GIT_MACRO_CUSTOM) {
503 nSel = -1;
504 }
505 } else {
506 nSel = -1;
507 }
508
509 InpMacroCreate(nSel);
510
511 return 0;
512 }
513 #endif
514
DeleteInput(unsigned int i)515 static int DeleteInput(unsigned int i)
516 {
517 struct BurnInputInfo bii;
518
519 if (i >= nGameInpCount) {
520
521 if (i < nGameInpCount + nMacroCount) { // Macro
522 GameInp[i].Macro.nMode = 0;
523 } else { // out of range
524 return 1;
525 }
526 } else { // "True" input
527 bii.nType = BIT_DIGITAL;
528 BurnDrvGetInputInfo(&bii, i);
529 if (bii.pVal == NULL) {
530 return 1;
531 }
532 if (bii.nType & BIT_GROUP_CONSTANT) { // Don't delete dip switches
533 return 1;
534 }
535
536 GameInp[i].nInput = 0;
537 }
538
539 GameInpCheckLeftAlt();
540
541 return 0;
542 }
543
544 // List item(s) deleted; find out which one(s)
ListItemDelete()545 static int ListItemDelete()
546 {
547 int nStart = -1;
548 LVITEM LvItem;
549 int nRet;
550
551 while ((nRet = SendMessage(hInpdList, LVM_GETNEXTITEM, (WPARAM)nStart, LVNI_SELECTED)) != -1) {
552 nStart = nRet;
553
554 // Get the corresponding input
555 LvItem.mask = LVIF_PARAM;
556 LvItem.iItem = nRet;
557 LvItem.iSubItem = 0;
558 SendMessage(hInpdList, LVM_GETITEM, 0, (LPARAM)&LvItem);
559 nRet = LvItem.lParam;
560
561 DeleteInput(nRet);
562 }
563
564 InpdListMake(0); // refresh view
565 return 0;
566 }
567
InitAnalogOptions(int nGi,int nPci)568 static int InitAnalogOptions(int nGi, int nPci)
569 {
570 // init analog options dialog
571 int nAnalog = -1;
572 if (nPci == (nPlayerDefaultControls[nGi] & 0x0F)) {
573 nAnalog = nPlayerDefaultControls[nGi] >> 4;
574 }
575
576 SendMessage(hInpdAnalog, CB_RESETCONTENT, 0, 0);
577 if (nPci >= 1 && nPci <= 3) {
578 // Absolute mode only for joysticks
579 SendMessage(hInpdAnalog, CB_ADDSTRING, 0, (LPARAM)(LPARAM)FBALoadStringEx(hAppInst, IDS_INPUT_ANALOG_ABS, true));
580 } else {
581 if (nAnalog > 0) {
582 nAnalog--;
583 }
584 }
585 SendMessage(hInpdAnalog, CB_ADDSTRING, 0, (LPARAM)(LPARAM)FBALoadStringEx(hAppInst, IDS_INPUT_ANALOG_AUTO, true));
586 SendMessage(hInpdAnalog, CB_ADDSTRING, 0, (LPARAM)(LPARAM)FBALoadStringEx(hAppInst, IDS_INPUT_ANALOG_NORMAL, true));
587
588 SendMessage(hInpdAnalog, CB_SETCURSEL, (WPARAM)nAnalog, 0);
589
590 return 0;
591 }
592
SaveHardwarePreset()593 static void SaveHardwarePreset()
594 {
595 TCHAR *szDefaultCpsFile = _T("config\\presets\\cps.ini");
596 TCHAR *szDefaultNeogeoFile = _T("config\\presets\\neogeo.ini");
597 TCHAR *szDefaultPgmFile = _T("config\\presets\\pgm.ini");
598 TCHAR *szFileName = _T("config\\presets\\preset.ini");
599 TCHAR *szHardwareString = _T("Generic hardware");
600
601 int nHardwareFlag = (BurnDrvGetHardwareCode() & HARDWARE_PUBLIC_MASK);
602
603 if (nHardwareFlag == HARDWARE_CAPCOM_CPS1 || nHardwareFlag == HARDWARE_CAPCOM_CPS1_QSOUND || nHardwareFlag == HARDWARE_CAPCOM_CPS1_GENERIC || nHardwareFlag == HARDWARE_CAPCOM_CPSCHANGER || nHardwareFlag == HARDWARE_CAPCOM_CPS2 || nHardwareFlag == HARDWARE_CAPCOM_CPS3) {
604 szFileName = szDefaultCpsFile;
605 szHardwareString = _T("CPS-1/CPS-2/CPS-3 hardware");
606 }
607
608 if (nHardwareFlag == HARDWARE_SNK_NEOGEO) {
609 szFileName = szDefaultNeogeoFile;
610 szHardwareString = _T("Neo-Geo hardware");
611 }
612
613 if (nHardwareFlag == HARDWARE_IGS_PGM) {
614 szFileName = szDefaultPgmFile;
615 szHardwareString = _T("PGM hardware");
616 }
617
618 FILE *fp = _tfopen(szFileName, _T("wt"));
619 if (fp) {
620 _ftprintf(fp, _T(APP_TITLE) _T(" - Hardware Default Preset\n\n"));
621 _ftprintf(fp, _T("%s\n\n"), szHardwareString);
622 _ftprintf(fp, _T("version 0x%06X\n\n"), nBurnVer);
623 GameInpWrite(fp);
624 fclose(fp);
625 }
626
627 // add to dropdown (if not already there)
628 TCHAR szPresetName[MAX_PATH] = _T("");
629 int iCBItem = 0;
630
631 memcpy(szPresetName, szFileName + 15, (_tcslen(szFileName) - 19) * sizeof(TCHAR));
632 iCBItem = SendMessage(hInpdPci, CB_FINDSTRING, -1, (LPARAM)szPresetName);
633 if (iCBItem == -1) SendMessage(hInpdPci, CB_ADDSTRING, 0, (LPARAM)szPresetName);
634
635 // confirm to user
636 FBAPopupAddText(PUF_TEXT_DEFAULT, MAKEINTRESOURCE(IDS_PRESET_SAVED), szFileName);
637 FBAPopupDisplay(PUF_TYPE_INFO);
638 }
639
UsePreset(bool bMakeDefault)640 int UsePreset(bool bMakeDefault)
641 {
642 int nGi, nPci, nAnalog = 0;
643 TCHAR szFilename[MAX_PATH] = _T("config\\presets\\");
644
645 nGi = SendMessage(hInpdGi, CB_GETCURSEL, 0, 0);
646 if (nGi == CB_ERR) {
647 return 1;
648 }
649 nPci = SendMessage(hInpdPci, CB_GETCURSEL, 0, 0);
650 if (nPci == CB_ERR) {
651 return 1;
652 }
653 if (nPci <= 7) {
654 // Determine analog option
655 nAnalog = SendMessage(hInpdAnalog, CB_GETCURSEL, 0, 0);
656 if (nAnalog == CB_ERR) {
657 return 1;
658 }
659
660 if (nPci == 0 || nPci > 3) { // No "Absolute" option for keyboard or X-Arcade/HotRod controls
661 nAnalog++;
662 }
663
664 GameInpConfig(nGi, nPci, nAnalog); // Re-configure inputs
665 } else {
666 // Find out the filename of the preset ini
667 SendMessage(hInpdPci, CB_GETLBTEXT, nPci, (LPARAM)(szFilename + _tcslen(szFilename)));
668 _tcscat(szFilename, _T(".ini"));
669
670 GameInputAutoIni(nGi, szFilename, true); // Read inputs from file
671
672 // Make sure all inputs are defined
673 for (unsigned int i = 0, j = 0; i < nGameInpCount; i++) {
674 if (GameInp[i].Input.pVal == NULL) {
675 continue;
676 }
677
678 if (GameInp[i].nInput == 0) {
679 DeleteInput(j);
680 }
681
682 j++;
683 }
684
685 nPci = 0x0F;
686 }
687
688 SendMessage(hInpdAnalog, CB_SETCURSEL, (WPARAM)-1, 0);
689 SendMessage(hInpdPci, CB_SETCURSEL, (WPARAM)-1, 0);
690 SendMessage(hInpdGi, CB_SETCURSEL, (WPARAM)-1, 0);
691
692 DisablePresets();
693
694 if (bMakeDefault) {
695 nPlayerDefaultControls[nGi] = nPci | (nAnalog << 4);
696 _tcscpy(szPlayerDefaultIni[nGi], szFilename);
697 }
698
699 GameInpCheckLeftAlt();
700
701 return 0;
702 }
703
DialogProc(HWND hDlg,UINT Msg,WPARAM wParam,LPARAM lParam)704 static INT_PTR CALLBACK DialogProc(HWND hDlg, UINT Msg, WPARAM wParam, LPARAM lParam)
705 {
706 if (Msg == WM_INITDIALOG) {
707 hInpdDlg = hDlg;
708 InpdInit();
709 if (!kNetGame && bAutoPause) {
710 bRunPause = 1;
711 }
712
713 return TRUE;
714 }
715
716 if (Msg == WM_CLOSE) {
717 EnableWindow(hScrnWnd, TRUE);
718 DestroyWindow(hInpdDlg);
719 return 0;
720 }
721
722 if (Msg == WM_DESTROY) {
723 InpdExit();
724 return 0;
725 }
726
727 if (Msg == WM_COMMAND) {
728 int Id = LOWORD(wParam);
729 int Notify = HIWORD(wParam);
730
731 if (Id == IDOK && Notify == BN_CLICKED) {
732 ListItemActivate();
733 return 0;
734 }
735 if (Id == IDCANCEL && Notify == BN_CLICKED) {
736 SendMessage(hDlg, WM_CLOSE, 0, 0);
737 return 0;
738 }
739
740 if (Id == IDC_INPD_NEWMACRO && Notify == BN_CLICKED) {
741
742 // NewMacroButton();
743
744 return 0;
745 }
746
747 if (Id == IDC_INPD_SAVE_AS_PRESET && Notify == BN_CLICKED) {
748 SaveHardwarePreset();
749 return 0;
750 }
751
752 if (Id == IDC_INPD_USE && Notify == BN_CLICKED) {
753
754 UsePreset(false);
755
756 InpdListMake(0); // refresh view
757
758 return 0;
759 }
760
761 if (Id == IDC_INPD_DEFAULT && Notify == BN_CLICKED) {
762
763 UsePreset(true);
764
765 InpdListMake(0); // refresh view
766
767 return 0;
768 }
769
770 if (Id == IDC_INPD_GI && Notify == CBN_SELCHANGE) {
771 int nGi;
772 nGi = SendMessage(hInpdGi, CB_GETCURSEL, 0, 0);
773 if (nGi == CB_ERR) {
774 SendMessage(hInpdPci, CB_SETCURSEL, (WPARAM)-1, 0);
775 SendMessage(hInpdAnalog, CB_SETCURSEL, (WPARAM)-1, 0);
776
777 DisablePresets();
778
779 return 0;
780 }
781 int nPci = nPlayerDefaultControls[nGi] & 0x0F;
782 SendMessage(hInpdPci, CB_SETCURSEL, nPci, 0);
783 EnableWindow(hInpdPci, TRUE);
784
785 if (nPci > 5) {
786 SendMessage(hInpdAnalog, CB_SETCURSEL, (WPARAM)-1, 0);
787 EnableWindow(hInpdAnalog, FALSE);
788 } else {
789 InitAnalogOptions(nGi, nPci);
790 EnableWindow(hInpdAnalog, TRUE);
791 }
792
793 EnableWindow(GetDlgItem(hInpdDlg, IDC_INPD_DEFAULT), TRUE);
794 EnableWindow(GetDlgItem(hInpdDlg, IDC_INPD_USE), TRUE);
795
796 return 0;
797 }
798
799 if (Id == IDC_INPD_PCI && Notify == CBN_SELCHANGE) {
800 int nGi, nPci;
801 nGi = SendMessage(hInpdGi, CB_GETCURSEL, 0, 0);
802 if (nGi == CB_ERR) {
803 return 0;
804 }
805 nPci = SendMessage(hInpdPci, CB_GETCURSEL, 0, 0);
806 if (nPci == CB_ERR) {
807 return 0;
808 }
809
810 if (nPci > 7) {
811 EnableWindow(GetDlgItem(hInpdDlg, IDC_INPD_DEFAULT), TRUE);
812 EnableWindow(GetDlgItem(hInpdDlg, IDC_INPD_USE), TRUE);
813
814 SendMessage(hInpdAnalog, CB_SETCURSEL, (WPARAM)-1, 0);
815 EnableWindow(hInpdAnalog, FALSE);
816 } else {
817 EnableWindow(hInpdAnalog, TRUE);
818 InitAnalogOptions(nGi, nPci);
819
820 if (SendMessage(hInpdAnalog, CB_GETCURSEL, 0, 0) != CB_ERR) {
821 EnableWindow(GetDlgItem(hInpdDlg, IDC_INPD_DEFAULT), TRUE);
822 EnableWindow(GetDlgItem(hInpdDlg, IDC_INPD_USE), TRUE);
823 } else {
824 EnableWindow(GetDlgItem(hInpdDlg, IDC_INPD_DEFAULT), FALSE);
825 EnableWindow(GetDlgItem(hInpdDlg, IDC_INPD_USE), FALSE);
826 }
827 }
828
829 return 0;
830 }
831
832 if (Id == IDC_INPD_ANALOG && Notify == CBN_SELCHANGE) {
833 if (SendMessage(hInpdAnalog, CB_GETCURSEL, 0, 0) != CB_ERR) {
834 EnableWindow(GetDlgItem(hInpdDlg, IDC_INPD_DEFAULT), TRUE);
835 EnableWindow(GetDlgItem(hInpdDlg, IDC_INPD_USE), TRUE);
836 }
837
838 return 0;
839 }
840
841 }
842
843 if (Msg == WM_NOTIFY && lParam != 0) {
844 int Id = LOWORD(wParam);
845 NMHDR* pnm = (NMHDR*)lParam;
846
847 if (Id == IDC_INPD_LIST && pnm->code == LVN_ITEMACTIVATE) {
848 ListItemActivate();
849 }
850 if (Id == IDC_INPD_LIST && pnm->code == LVN_KEYDOWN) {
851 NMLVKEYDOWN *pnmkd = (NMLVKEYDOWN*)lParam;
852 if (pnmkd->wVKey == VK_DELETE) {
853 ListItemDelete();
854 }
855 }
856
857 if (Id == IDC_INPD_LIST && pnm->code == NM_CUSTOMDRAW) {
858 NMLVCUSTOMDRAW* plvcd = (NMLVCUSTOMDRAW*)lParam;
859
860 switch (plvcd->nmcd.dwDrawStage) {
861 case CDDS_PREPAINT:
862 SetWindowLongPtr(hInpdDlg, DWLP_MSGRESULT, CDRF_NOTIFYITEMDRAW);
863 return 1;
864 case CDDS_ITEMPREPAINT:
865 if (plvcd->nmcd.dwItemSpec < nGameInpCount) {
866 if (GameInp[plvcd->nmcd.dwItemSpec].nType & BIT_GROUP_CONSTANT) {
867
868 if (GameInp[plvcd->nmcd.dwItemSpec].nInput == 0) {
869 plvcd->clrTextBk = RGB(0xDF, 0xDF, 0xDF);
870
871 SetWindowLongPtr(hInpdDlg, DWLP_MSGRESULT, CDRF_NEWFONT);
872 return 1;
873 }
874
875 if (GameInp[plvcd->nmcd.dwItemSpec].nType == BIT_DIPSWITCH) {
876 plvcd->clrTextBk = RGB(0xFF, 0xEF, 0xD7);
877
878 SetWindowLongPtr(hInpdDlg, DWLP_MSGRESULT, CDRF_NEWFONT);
879 return 1;
880 }
881 }
882 }
883
884 if (plvcd->nmcd.dwItemSpec >= nGameInpCount) {
885 if (GameInp[plvcd->nmcd.dwItemSpec].Macro.nMode) {
886 plvcd->clrTextBk = RGB(0xFF, 0xCF, 0xCF);
887 } else {
888 plvcd->clrTextBk = RGB(0xFF, 0xEF, 0xEF);
889 }
890
891 SetWindowLongPtr(hInpdDlg, DWLP_MSGRESULT, CDRF_NEWFONT);
892 return 1;
893 }
894 return 1;
895 }
896 }
897 return 0;
898 }
899
900 return 0;
901 }
902
InpdCreate()903 int InpdCreate()
904 {
905 if (bDrvOkay == 0) {
906 return 1;
907 }
908
909 DestroyWindow(hInpdDlg); // Make sure exitted
910
911 hInpdDlg = FBACreateDialog(hAppInst, MAKEINTRESOURCE(IDD_INPD), hScrnWnd, (DLGPROC)DialogProc);
912 if (hInpdDlg == NULL) {
913 return 1;
914 }
915
916 WndInMid(hInpdDlg, hScrnWnd);
917 ShowWindow(hInpdDlg, SW_NORMAL);
918
919 return 0;
920 }
921
922
923