@@ -39,9 +39,6 @@ void *ConsoleUI::fileTextures[2];
39
39
void *ConsoleUI::folderTextures[2 ];
40
40
void *ConsoleUI::fontTexture;
41
41
42
- int ConsoleUI::showFpsCounter = 0 ;
43
- int ConsoleUI::menuTheme = 0 ;
44
-
45
42
const uint32_t *ConsoleUI::palette;
46
43
uint32_t ConsoleUI::uiWidth, ConsoleUI::uiHeight;
47
44
uint32_t ConsoleUI::lineHeight;
@@ -61,6 +58,10 @@ std::thread *ConsoleUI::coreThread, *ConsoleUI::saveThread;
61
58
std::condition_variable ConsoleUI::cond;
62
59
std::mutex ConsoleUI::mutex;
63
60
61
+ int ConsoleUI::showFpsCounter = 0 ;
62
+ int ConsoleUI::menuTheme = 0 ;
63
+ int ConsoleUI::keyBinds[] = {};
64
+
64
65
const uint32_t ConsoleUI::themeColors[] =
65
66
{
66
67
0xFF2D2D2D , 0xFFFFFFFF , 0xFF4B4B4B , 0xFF232323 , 0xFFE1B955 , 0xFFC8FF00 , // Dark
@@ -179,11 +180,27 @@ void ConsoleUI::initialize(int width, int height, std::string root, std::string
179
180
// Create the settings folder if it doesn't exist
180
181
mkdir (prefix.c_str (), 0777 );
181
182
183
+ // Set the default input bindings
184
+ for (int i = 0 ; i < INPUT_MAX; i++)
185
+ keyBinds[i] = defaultKeys[i];
186
+
182
187
// Define the platform settings
183
188
std::vector<Setting> platformSettings =
184
189
{
185
190
Setting (" showFpsCounter" , &showFpsCounter, false ),
186
- Setting (" menuTheme" , &menuTheme, false )
191
+ Setting (" menuTheme" , &menuTheme, false ),
192
+ Setting (" keyA" , &keyBinds[INPUT_A], false ),
193
+ Setting (" keyB" , &keyBinds[INPUT_B], false ),
194
+ Setting (" keySelect" , &keyBinds[INPUT_SELECT], false ),
195
+ Setting (" keyStart" , &keyBinds[INPUT_START], false ),
196
+ Setting (" keyRight" , &keyBinds[INPUT_RIGHT], false ),
197
+ Setting (" keyLeft" , &keyBinds[INPUT_LEFT], false ),
198
+ Setting (" keyUp" , &keyBinds[INPUT_UP], false ),
199
+ Setting (" keyDown" , &keyBinds[INPUT_DOWN], false ),
200
+ Setting (" keyR" , &keyBinds[INPUT_R], false ),
201
+ Setting (" keyL" , &keyBinds[INPUT_L], false ),
202
+ Setting (" keyX" , &keyBinds[INPUT_X], false ),
203
+ Setting (" keyY" , &keyBinds[INPUT_Y], false ),
187
204
};
188
205
189
206
// Add the platform settings
@@ -274,9 +291,9 @@ void ConsoleUI::mainLoop(MenuTouch (*specialTouch)(), ScreenLayout *touchLayout)
274
291
// Send input to the core
275
292
for (int i = 0 ; i < 12 ; i++)
276
293
{
277
- if (pressed & BIT (i) )
294
+ if (pressed & keyBinds[i] )
278
295
core->input .pressKey (i);
279
- else if (~ held & BIT (i ))
296
+ else if (!( held & keyBinds[i] ))
280
297
core->input .releaseKey (i);
281
298
}
282
299
@@ -310,7 +327,7 @@ void ConsoleUI::mainLoop(MenuTouch (*specialTouch)(), ScreenLayout *touchLayout)
310
327
if (botTexture) destroyTexture (botTexture);
311
328
312
329
// Open the pause menu if requested
313
- if (held & INPUT_PAUSE)
330
+ if (held & keyBinds[ INPUT_PAUSE] )
314
331
pauseMenu ();
315
332
}
316
333
}
@@ -323,7 +340,7 @@ int ConsoleUI::setPath(std::string path)
323
340
// If a GBA path is set, allow clearing it
324
341
if (gbaPath != " " )
325
342
{
326
- if (!message (" Loading NDS ROM" , " Load the previous GBA ROM alongside this ROM?" , true ))
343
+ if (!message (" Loading NDS ROM" , " Load the previous GBA ROM alongside this ROM?" , 1 ))
327
344
gbaPath = " " ;
328
345
}
329
346
@@ -346,7 +363,7 @@ int ConsoleUI::setPath(std::string path)
346
363
// If an NDS path is set, allow clearing it
347
364
if (ndsPath != " " )
348
365
{
349
- if (!message (" Loading GBA ROM" , " Load the previous NDS ROM alongside this ROM?" , true ))
366
+ if (!message (" Loading GBA ROM" , " Load the previous NDS ROM alongside this ROM?" , 1 ))
350
367
ndsPath = " " ;
351
368
}
352
369
@@ -408,7 +425,7 @@ uint32_t ConsoleUI::menu(std::string title, std::vector<MenuItem> &items,
408
425
uint32_t held = getInputHeld ();
409
426
410
427
// Handle up input presses
411
- if ((pressed & INPUT_UP) && !(pressed & INPUT_DOWN))
428
+ if ((pressed & defaultKeys[ INPUT_UP] ) && !(pressed & defaultKeys[ INPUT_DOWN] ))
412
429
{
413
430
// Disable touch mode or move the selection box up
414
431
if (touchMode)
@@ -422,7 +439,7 @@ uint32_t ConsoleUI::menu(std::string title, std::vector<MenuItem> &items,
422
439
}
423
440
424
441
// Handle down input presses
425
- if ((pressed & INPUT_DOWN) && !(pressed & INPUT_UP))
442
+ if ((pressed & defaultKeys[ INPUT_DOWN] ) && !(pressed & defaultKeys[ INPUT_UP] ))
426
443
{
427
444
// Disable touch mode or move the selection box down
428
445
if (touchMode)
@@ -436,26 +453,26 @@ uint32_t ConsoleUI::menu(std::string title, std::vector<MenuItem> &items,
436
453
}
437
454
438
455
// Return button presses so they can be handled externally
439
- if (((pressed & INPUT_A) && !touchMode) || (pressed & INPUT_B) || (actionX != " "
440
- && (pressed & INPUT_X)) || (actionPlus != " " && (pressed & INPUT_START)))
456
+ if (((pressed & defaultKeys[ INPUT_A] ) && !touchMode) || (pressed & defaultKeys[ INPUT_B] ) || (actionX != " "
457
+ && (pressed & defaultKeys[ INPUT_X] )) || (actionPlus != " " && (pressed & defaultKeys[ INPUT_START] )))
441
458
{
442
459
touchMode = false ;
443
460
return pressed;
444
461
}
445
462
446
463
// Disable touch mode before allowing A presses so the selector is visible
447
- if ((pressed & INPUT_A) && touchMode)
464
+ if ((pressed & defaultKeys[ INPUT_A] ) && touchMode)
448
465
touchMode = false ;
449
466
450
467
// Cancel up input if it was released
451
- if (upHeld && !(held & INPUT_UP))
468
+ if (upHeld && !(held & defaultKeys[ INPUT_UP] ))
452
469
{
453
470
upHeld = false ;
454
471
scroll = false ;
455
472
}
456
473
457
474
// Cancel down input if it was released
458
- if (downHeld && !(held & INPUT_DOWN))
475
+ if (downHeld && !(held & defaultKeys[ INPUT_DOWN] ))
459
476
{
460
477
downHeld = false ;
461
478
scroll = false ;
@@ -514,11 +531,11 @@ uint32_t ConsoleUI::menu(std::string title, std::vector<MenuItem> &items,
514
531
if (!touchScroll && touchStart.y >= 650 )
515
532
{
516
533
if (touchStart.x >= boundsBX && touchStart.x < boundsAB)
517
- return INPUT_B;
534
+ return defaultKeys[ INPUT_B] ;
518
535
else if (touchStart.x >= boundsXPlus && touchStart.x < boundsBX)
519
- return INPUT_X;
536
+ return defaultKeys[ INPUT_X] ;
520
537
else if (touchStart.x >= boundsPlus && touchStart.x < boundsXPlus)
521
- return INPUT_START;
538
+ return defaultKeys[ INPUT_START] ;
522
539
}
523
540
touchStarted = false ;
524
541
}
@@ -544,7 +561,7 @@ uint32_t ConsoleUI::menu(std::string title, std::vector<MenuItem> &items,
544
561
1190 && touchStart.y >= 124 + i * 70 && touchStart.y < 194 + i * 70 )
545
562
{
546
563
index = offset;
547
- return INPUT_A;
564
+ return defaultKeys[ INPUT_A] ;
548
565
}
549
566
550
567
// Draw UI elements around the list items
@@ -582,7 +599,7 @@ uint32_t ConsoleUI::menu(std::string title, std::vector<MenuItem> &items,
582
599
}
583
600
}
584
601
585
- bool ConsoleUI::message (std::string title, std::string text, bool cancel )
602
+ uint32_t ConsoleUI::message (std::string title, std::string text, int type )
586
603
{
587
604
// Define the action strings
588
605
std::string actionB = " \x81 Back " ;
@@ -605,7 +622,7 @@ bool ConsoleUI::message(std::string title, std::string text, bool cancel)
605
622
drawString (title, SCALE (72 ), SCALE (30 ), SCALE (42 ), palette[1 ]);
606
623
drawRectangle (SCALE (30 ), SCALE (88 ), SCALE (1220 ), lineHeight, palette[1 ]);
607
624
drawRectangle (SCALE (30 ), SCALE (648 ), SCALE (1220 ), lineHeight, palette[1 ]);
608
- drawString ((cancel ? actionB : " " ) + actionA, SCALE (1218 ), SCALE (667 ), SCALE (34 ), palette[1 ], true );
625
+ if (type < 2 ) drawString ((type ? actionB : " " ) + actionA, SCALE (1218 ), SCALE (667 ), SCALE (34 ), palette[1 ], true );
609
626
610
627
// Draw each line of text, separated by newline characters
611
628
for (int i = 0 , j = 0 , y = 0 ; j != std::string::npos; y += 38 )
@@ -619,10 +636,12 @@ bool ConsoleUI::message(std::string title, std::string text, bool cancel)
619
636
uint32_t pressed = getInputPress ();
620
637
621
638
// Dismiss the message and return the result if an action is pressed
622
- if (pressed & INPUT_A)
623
- return true ;
624
- else if ((pressed & INPUT_B) && cancel)
625
- return false ;
639
+ if (pressed && type == 2 ) // Input
640
+ return pressed;
641
+ else if (pressed & defaultKeys[INPUT_A]) // Default
642
+ return 1 ;
643
+ else if ((pressed & defaultKeys[INPUT_B]) && type == 1 ) // Cancel
644
+ return 0 ;
626
645
627
646
// Scan for touch input
628
647
MenuTouch touch = getInputTouch ();
@@ -649,10 +668,10 @@ bool ConsoleUI::message(std::string title, std::string text, bool cancel)
649
668
// Simulate a button press if its action text was tapped
650
669
if (!touchScroll && touchStart.y >= 650 )
651
670
{
652
- if (touchStart.x >= boundsAB && touchStart.x < boundsA)
653
- return true ;
654
- else if (touchStart.x >= boundsB && touchStart.x < boundsAB && cancel )
655
- return false ;
671
+ if (touchStart.x >= boundsAB && touchStart.x < boundsA && type < 2 )
672
+ return 1 ;
673
+ else if (touchStart.x >= boundsB && touchStart.x < boundsAB && type == 1 )
674
+ return 0 ;
656
675
}
657
676
touchStarted = false ;
658
677
}
@@ -708,7 +727,7 @@ void ConsoleUI::fileBrowser()
708
727
uint32_t pressed = menu (" NooDS" , files, index , " Settings" , " Exit" );
709
728
710
729
// Handle menu input
711
- if (pressed & INPUT_A)
730
+ if (pressed & defaultKeys[ INPUT_A] )
712
731
{
713
732
// Navigate to the selected file if any exist
714
733
if (files.empty ()) continue ;
@@ -731,7 +750,7 @@ void ConsoleUI::fileBrowser()
731
750
return ;
732
751
}
733
752
}
734
- else if (pressed & INPUT_B)
753
+ else if (pressed & defaultKeys[ INPUT_B] )
735
754
{
736
755
// Navigate to the previous directory
737
756
if (curPath != basePath)
@@ -740,12 +759,12 @@ void ConsoleUI::fileBrowser()
740
759
index = 0 ;
741
760
}
742
761
}
743
- else if (pressed & INPUT_X)
762
+ else if (pressed & defaultKeys[ INPUT_X] )
744
763
{
745
764
// Open the settings menu
746
765
settingsMenu ();
747
766
}
748
- else if (pressed & INPUT_START)
767
+ else if (pressed & defaultKeys[ INPUT_START] )
749
768
{
750
769
// Close the file browser
751
770
return ;
@@ -790,10 +809,10 @@ void ConsoleUI::settingsMenu()
790
809
};
791
810
792
811
// Create the settings menu
793
- uint32_t pressed = menu (" Settings" , settings, index );
812
+ uint32_t pressed = menu (" Settings" , settings, index , " Controls " );
794
813
795
814
// Handle menu input
796
- if (pressed & INPUT_A)
815
+ if (pressed & defaultKeys[ INPUT_A] )
797
816
{
798
817
// Change the chosen setting to its next value
799
818
switch (index )
@@ -821,13 +840,89 @@ void ConsoleUI::settingsMenu()
821
840
break ;
822
841
}
823
842
}
824
- else if (pressed & INPUT_B)
843
+ else if (pressed & defaultKeys[ INPUT_B] )
825
844
{
826
845
// Close the settings menu
827
846
changed = true ;
828
847
Settings::save ();
829
848
return ;
830
849
}
850
+ else if (pressed & defaultKeys[INPUT_X])
851
+ {
852
+ // Open the controls menu
853
+ controlsMenu ();
854
+ }
855
+ }
856
+ }
857
+
858
+ void ConsoleUI::controlsMenu ()
859
+ {
860
+ int index = 0 ;
861
+ while (true )
862
+ {
863
+ // Define names for the bindable inputs
864
+ const char *names[] =
865
+ {
866
+ " A Button" , " B Button" , " Select Button" , " Start Button" ,
867
+ " Right Button" , " Left Button" , " Up Button" , " Down Button" ,
868
+ " R Button" , " L Button" , " X Button" , " Y Button" , " Menu Button"
869
+ };
870
+
871
+ // Build strings for the input bindings
872
+ std::string bindings[INPUT_MAX];
873
+ for (int i = 0 ; i < INPUT_MAX; i++)
874
+ {
875
+ // Add the input name with a comma (up to 8 entries)
876
+ for (int j = 0 , k = -1 ; j < 32 && k < 8 ; j++)
877
+ {
878
+ if (!(keyBinds[i] & (1 << j))) continue ;
879
+ if (bindings[i] != " " ) bindings[i] += " , " ;
880
+ bindings[i] += (++k < 8 ) ? keyNames[j] : " ..." ;
881
+ }
882
+
883
+ // Replace empty strings with the word none
884
+ if (bindings[i] == " " )
885
+ bindings[i] = " None" ;
886
+ }
887
+
888
+ // Create a list of inputs and current bindings
889
+ std::vector<MenuItem> controls =
890
+ {
891
+ MenuItem (names[INPUT_A], bindings[INPUT_A]),
892
+ MenuItem (names[INPUT_B], bindings[INPUT_B]),
893
+ MenuItem (names[INPUT_SELECT], bindings[INPUT_SELECT]),
894
+ MenuItem (names[INPUT_START], bindings[INPUT_START]),
895
+ MenuItem (names[INPUT_RIGHT], bindings[INPUT_RIGHT]),
896
+ MenuItem (names[INPUT_LEFT], bindings[INPUT_LEFT]),
897
+ MenuItem (names[INPUT_UP], bindings[INPUT_UP]),
898
+ MenuItem (names[INPUT_DOWN], bindings[INPUT_DOWN]),
899
+ MenuItem (names[INPUT_R], bindings[INPUT_R]),
900
+ MenuItem (names[INPUT_L], bindings[INPUT_L]),
901
+ MenuItem (names[INPUT_X], bindings[INPUT_X]),
902
+ MenuItem (names[INPUT_Y], bindings[INPUT_Y]),
903
+ MenuItem (names[INPUT_PAUSE], bindings[INPUT_PAUSE]),
904
+ };
905
+
906
+ // Create the controls menu
907
+ uint32_t pressed = menu (" Controls" , controls, index , " Clear" );
908
+
909
+ // Handle menu input
910
+ if (pressed & defaultKeys[INPUT_A])
911
+ {
912
+ // Show a binding message and bind the pressed input
913
+ keyBinds[index ] |= message (std::string (" Remap " ) + names[index ],
914
+ " Press an input to add it as a binding." , 2 );
915
+ }
916
+ else if (pressed & defaultKeys[INPUT_B])
917
+ {
918
+ // Close the controls menu
919
+ return ;
920
+ }
921
+ else if (pressed & defaultKeys[INPUT_X])
922
+ {
923
+ // Clear an input binding
924
+ keyBinds[index ] = 0 ;
925
+ }
831
926
}
832
927
}
833
928
@@ -855,7 +950,7 @@ void ConsoleUI::pauseMenu()
855
950
uint32_t pressed = menu (" NooDS" , items, index );
856
951
857
952
// Handle menu input
858
- if (pressed & INPUT_A)
953
+ if (pressed & defaultKeys[ INPUT_A] )
859
954
{
860
955
// Handle the selected item
861
956
switch (index )
@@ -876,7 +971,7 @@ void ConsoleUI::pauseMenu()
876
971
" loading states is dangerous and can lead to data loss.\n States are also not guaranteed to "
877
972
" be compatible across emulator versions.\n Please rely on in-game saving to keep your progress, "
878
973
" and back up .sav files\n before using this feature. Do you want to save the current state?" :
879
- " Do you want to overwrite the saved state with the current state? This can't be undone!" , true ))
974
+ " Do you want to overwrite the saved state with the current state? This can't be undone!" , 1 ))
880
975
break ;
881
976
882
977
// Save the state and return to emulation if confirmed
@@ -938,7 +1033,7 @@ void ConsoleUI::pauseMenu()
938
1033
return ;
939
1034
}
940
1035
}
941
- else if (pressed & INPUT_B)
1036
+ else if (pressed & defaultKeys[ INPUT_B] )
942
1037
{
943
1038
// Return to the emulator
944
1039
startCore ();
@@ -983,10 +1078,10 @@ bool ConsoleUI::saveTypeMenu()
983
1078
uint32_t pressed = menu (" Change Save Type" , items, index );
984
1079
985
1080
// Handle menu input
986
- if (pressed & INPUT_A)
1081
+ if (pressed & defaultKeys[ INPUT_A] )
987
1082
{
988
1083
// Confirm the change because doing this accidentally could be bad
989
- if (!message (" Changing Save Type" , " Are you sure? This may result in data loss!" , true ))
1084
+ if (!message (" Changing Save Type" , " Are you sure? This may result in data loss!" , 1 ))
990
1085
continue ;
991
1086
992
1087
// Apply the change for the current mode
@@ -1022,7 +1117,7 @@ bool ConsoleUI::saveTypeMenu()
1022
1117
}
1023
1118
return true ;
1024
1119
}
1025
- else if (pressed & INPUT_B)
1120
+ else if (pressed & defaultKeys[ INPUT_B] )
1026
1121
{
1027
1122
// Close the save type menu
1028
1123
return false ;
0 commit comments