snes9xgx/source/ngc/menu.cpp
dborth fb27030208 [Whats Was New 002 - July 21, 2008]
- added: classic and nunchuk support
- added: all controllers can now be configured
- added: GC version (untested)
- changed: mappings are no longer stored in SRAM, but in config file. 
           This means no per-game configurations, but one global 
           config per controller.
- one makefile to make all versions. (thanks to snes9x143 SVN)
2008-10-16 01:49:58 +00:00

843 lines
20 KiB
C++

/****************************************************************************
* Snes9x 1.50
*
* Nintendo Gamecube Menu
*
* softdev July 2006
* crunchy2 May-June 2007
****************************************************************************/
#include <gccore.h>
#include <ogcsys.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <wiiuse/wpad.h>
#include "snes9x.h"
#include "snes9xGx.h"
#include "memmap.h"
#include "debug.h"
#include "cpuexec.h"
#include "ppu.h"
#include "apu.h"
#include "display.h"
#include "gfx.h"
#include "soundux.h"
#include "spc700.h"
#include "spc7110.h"
#include "controls.h"
#include "aram.h"
#include "ftfont.h"
#include "video.h"
#include "mcsave.h"
#include "filesel.h"
#include "ngcunzip.h"
#include "smbload.h"
#include "mcsave.h"
#include "sdload.h"
#include "memfile.h"
#include "dvd.h"
#include "s9xconfig.h"
#include "sram.h"
#include "preferences.h"
#include "button_mapping.h"
#include "ftfont.h"
extern void DrawMenu (char items[][20], char *title, int maxitems, int selected);
#define PSOSDLOADID 0x7c6000a6
extern int menu;
extern unsigned long ARAM_ROMSIZE;
#define SOFTRESET_ADR ((volatile u32*)0xCC003024)
void Reboot() {
#ifdef __wii__
SYS_ResetSystem(SYS_RETURNTOMENU, 0, 0);
#else
#define SOFTRESET_ADR ((volatile u32*)0xCC003024)
*SOFTRESET_ADR = 0x00000000;
#endif
}
/****************************************************************************
* Freeze Manager
****************************************************************************/
int freezecountwii = 7;
char freezemenuwii[][20] = { "Freeze to SD", "Thaw from SD",
"Freeze to MC Slot A", "Thaw from MC Slot A",
"Freeze to MC Slot B", "Thaw from MC Slot B",
"Return to previous"
};
int freezecount = 9;
char freezemenu[][20] = { "Freeze to SD", "Thaw from SD",
"Freeze to MC Slot A", "Thaw from MC Slot A",
"Freeze to MC Slot B", "Thaw from MC Slot B",
"Freeze to SMB", "Thaw from SMB",
"Return to previous"
};
int
FreezeManager ()
{
int ret;
int loaded = 0;
int quit = 0;
int oldmenu = menu;
menu = 0;
while (quit == 0)
{
if ( isWii ) /* Wii menu */
{
ret = RunMenu (freezemenuwii, freezecountwii, (char*)"Freeze Manager");
if (ret >= freezecountwii-1)
ret = freezecount-1;
}
else /* Gamecube menu */
ret = RunMenu (freezemenu, freezecount, (char*)"Freeze Manager");
switch (ret)
{
case 0:/*** Freeze to SDCard ***/
NGCFreezeGame (2, NOTSILENT);
break;
case 1:/*** Thaw from SDCard***/
quit = loaded = NGCUnfreezeGame (2, NOTSILENT);
break;
case 2:/*** Freeze to MC in slot A ***/
NGCFreezeGame (0, NOTSILENT);
break;
case 3:/*** Thaw from MC in slot A ***/
quit = loaded = NGCUnfreezeGame (0, NOTSILENT);
break;
case 4:/*** Freeze to MC in slot B ***/
NGCFreezeGame (1, NOTSILENT);
break;
case 5:/*** Thaw from MC in slot B ***/
quit = loaded = NGCUnfreezeGame (1, NOTSILENT);
break;
case 6:/*** Freeze to SMB ***/
if ( !isWii )
NGCFreezeGame (4, NOTSILENT);
break;
case 7:/*** Thaw from SMB ***/
if ( !isWii )
quit = loaded = NGCUnfreezeGame (4, NOTSILENT);
break;
case -1: /*** Button B ***/
case 8:
quit = 1;
break;
}
}
menu = oldmenu;
return loaded;
}
/****************************************************************************
* Load Manager
****************************************************************************/
int loadmancountwii = 2;
char loadmanwii[][20] = { "Load from SD",
"Return to previous"
};
int loadmancount = 4;
char loadman[][20] = { "Load from SD",
"Load from DVD", "Load from SMB", "Return to previous"
};
int
LoadManager ()
{
int ret;
int quit = 0;
int oldmenu = menu;
int retval = 1;
menu = 0;
while (quit == 0)
{
if ( isWii ) /* Wii menu */
{
ret = RunMenu (loadmanwii, loadmancountwii, (char*)"Load Manager");
if (ret >= loadmancountwii-1)
ret = loadmancount-1;
}
else /* Gamecube menu */
ret = RunMenu (loadman, loadmancount, (char*)"Load Manager");
switch (ret)
{
case 0:
/*** Load from SD ***/
quit = OpenSD (0);
break;
case 1:
/*** Load from DVD ***/
quit = OpenDVD ();
break;
case 2:
/*** Load from SMB ***/ //(gamecube option)
quit = OpenSMB ();
break;
case -1: /*** Button B ***/
case 3:
retval = 0;
quit = 1;
break;
}
}
/***
* check for autoloadsram / freeze
***/
if ( retval == 1 ) // if ROM was loaded, load the SRAM & settings
{
if ( GCSettings.AutoLoad == 1 )
quickLoadSRAM ( SILENT );
else if ( GCSettings.AutoLoad == 2 )
{
/*** load SRAM first in order to get joypad config ***/
quickLoadSRAM ( SILENT );
quickLoadFreeze ( SILENT );
}
S9xSoftReset(); // reset after loading sram
}
menu = oldmenu;
return retval;
}
/****************************************************************************
* Save Manager
****************************************************************************/
int savecountwii = 7;
char savemenuwii[][20] = { "Save to SD", "Load from SD",
"Save to MC SLOT A", "Load from MC SLOT A",
"Save to MC SLOT B", "Load from MC SLOT B",
"Return to previous"
};
int savecount = 9;
char savemenu[][20] = { "Save to SD", "Load from SD",
"Save to MC SLOT A", "Load from MC SLOT A",
"Save to MC SLOT B", "Load from MC SLOT B",
"Save to SMB", "Load from SMB",
"Return to previous"
};
void
SaveManager ()
{
int ret;
int quit = 0;
int oldmenu = menu;
menu = 0;
while (quit == 0)
{
if ( isWii ) /* Wii menu */
{
ret = RunMenu (savemenuwii, savecountwii, (char*)"Save Manager");
if (ret >= savecountwii-1)
ret = savecount-1;
}
else /* Gamecube menu */
ret = RunMenu (savemenu, savecount, (char*)"Save Manager");
switch (ret)
{
case 0:
/*** Save to SD***/
SaveSRAMToSD (0, NOTSILENT);
break;
case 1:
/*** Load from SD***/
LoadSRAMFromSD (0, NOTSILENT);
break;
case 2:
/*** Save to MC slot A ***/
SaveSRAMToMC (CARD_SLOTA, NOTSILENT);
break;
case 3:
/*** Load from MC slot A ***/
LoadSRAMFromMC (CARD_SLOTA, NOTSILENT);
break;
case 4:
/*** Save to MC slot B ***/
SaveSRAMToMC (CARD_SLOTB, NOTSILENT);
break;
case 5:
/*** Load from MC slot B ***/
LoadSRAMFromMC (CARD_SLOTB, NOTSILENT);
break;
case 6:
/*** Save to SMB **/
SaveSRAMToSMB (NOTSILENT);
break;
case 7:
/*** Load from SMB ***/
LoadSRAMFromSMB (NOTSILENT);
break;
case -1: /*** Button B ***/
case 8:
/*** Return ***/
quit = 1;
break;
}
}
menu = oldmenu;
}
/****************************************************************************
* Emulator Options
****************************************************************************/
static int emuCount = 11;
static char emulatorOptions[][20] = { "Reverse Stereo OFF",
"Interp. Sound ON", "Transparency ON", "FPS Display OFF",
"MultiTap 5 OFF", "C-Stick Zoom OFF",
"Auto Load OFF", "Auto Save OFF", "Verify MC Saves OFF",
"Save Prefs Now", "Return to previous"
};
void
EmulatorOptions ()
{
int ret = 0;
int quit = 0;
int oldmenu = menu;
menu = 0;
while (quit == 0)
{
sprintf (emulatorOptions[0], "Reverse Stereo %s",
Settings.ReverseStereo == true ? " ON" : "OFF");
sprintf (emulatorOptions[1], "Interp. Sound %s",
Settings.InterpolatedSound == true ? " ON" : "OFF");
sprintf (emulatorOptions[2], "Transparency %s",
Settings.Transparency == true ? " ON" : "OFF");
sprintf (emulatorOptions[3], "FPS Display %s",
Settings.DisplayFrameRate == true ? " ON" : "OFF");
sprintf (emulatorOptions[4], "MultiTap 5 %s",
Settings.MultiPlayer5Master == true ? " ON" : "OFF");
sprintf (emulatorOptions[5], "C-Stick Zoom %s",
GCSettings.NGCZoom == true ? " ON" : "OFF");
if (GCSettings.AutoLoad == 0) sprintf (emulatorOptions[6],"Auto Load OFF");
else if (GCSettings.AutoLoad == 1) sprintf (emulatorOptions[6],"Auto Load SRAM");
else if (GCSettings.AutoLoad == 2) sprintf (emulatorOptions[6],"Auto Load FREEZE");
if (GCSettings.AutoSave == 0) sprintf (emulatorOptions[7],"Auto Save OFF");
else if (GCSettings.AutoSave == 1) sprintf (emulatorOptions[7],"Auto Save SRAM");
else if (GCSettings.AutoSave == 2) sprintf (emulatorOptions[7],"Auto Save FREEZE");
else if (GCSettings.AutoSave == 3) sprintf (emulatorOptions[7],"Auto Save BOTH");
sprintf (emulatorOptions[8], "Verify MC Saves %s",
GCSettings.VerifySaves == true ? " ON" : "OFF");
ret = RunMenu (emulatorOptions, emuCount, (char*)"Emulator Options");
switch (ret)
{
case 0:
Settings.ReverseStereo =
(Settings.ReverseStereo == false ? true : false);
break;
case 1:
Settings.InterpolatedSound =
(Settings.InterpolatedSound == false ? true : false);
break;
case 2:
Settings.Transparency =
(Settings.Transparency == false ? true : false);
break;
case 3:
Settings.DisplayFrameRate =
(Settings.DisplayFrameRate == false ? true : false);
break;
case 4:
Settings.MultiPlayer5Master =
(Settings.MultiPlayer5Master == false ? true : false);
if (Settings.MultiPlayer5Master)
{
S9xSetController (1, CTL_MP5, 1, 2, 3, -1);
}
else
{
S9xSetController (1, CTL_JOYPAD, 1, 0, 0, 0);
}
break;
case 5:
GCSettings.NGCZoom =
(GCSettings.NGCZoom == false ? true : false);
break;
case 6:
GCSettings.AutoLoad ++;
if (GCSettings.AutoLoad > 2)
GCSettings.AutoLoad = 0;
break;
case 7:
GCSettings.AutoSave ++;
if (GCSettings.AutoSave > 3)
GCSettings.AutoSave = 0;
break;
case 8:
GCSettings.VerifySaves =
(GCSettings.VerifySaves == false ? true : false);
break;
case 9:
quickSavePrefs(NOTSILENT);
break;
case -1: /*** Button B ***/
case 10:
quit = 1;
break;
}
}
menu = oldmenu;
}
/****************************************************************************
* Controller Configuration
*
* Snes9x 1.50 uses a cmd system to work out which button has been pressed.
* Here, I simply move the designated value to the gcpadmaps array, which saves
* on updating the cmd sequences.
****************************************************************************/
u32
GetInput (u16 ctrlr_type)
{
u32 exp_type, pressed;
pressed=0;
while( PAD_ButtonsHeld(0)
#ifdef HW_RVL
| WPAD_ButtonsHeld(0)
#endif
) VIDEO_WaitVSync(); // button 'debounce'
while (pressed == 0)
{
VIDEO_WaitVSync();
// get input based on controller type
//if (ctrlr_type == CTRLR_GCPAD)
//{
pressed = PAD_ButtonsHeld (0);
//}
#ifdef HW_RVL
//else
//{
// if ( WPAD_Probe( 0, &exp_type) == 0) // check wiimote and expansion status (first if wiimote is connected & no errors)
// {
pressed = WPAD_ButtonsHeld (0);
// if (ctrlr_type != CTRLR_WIIMOTE && exp_type != ctrlr_type+1) // if we need input from an expansion, and its not connected...
// pressed = 0;
// }
//}
#endif
} // end while
while( pressed == (PAD_ButtonsHeld(0)
#ifdef HW_RVL
| WPAD_ButtonsHeld(0)
#endif
) ) VIDEO_WaitVSync();
return pressed;
} // end GetInput()
int cfg_text_count = 4;
char cfg_text[][20] = {
" ",
"Press Any Button",
"on the",
" " // identify controller
};
u32
GetButtonMap(u16 ctrlr_type, char* btn_name)
{
u32 pressed, previous;
char title[20];
pressed = 0; previous = 1;
switch (ctrlr_type) {
case CTRLR_NUNCHUK:
strncpy (cfg_text[3], (char*)"NUNCHUK", 7);
break;
case CTRLR_CLASSIC:
strncpy (cfg_text[3], (char*)"CLASSIC", 7);
break;
case CTRLR_GCPAD:
strncpy (cfg_text[3], (char*)"GC PAD", 7);
break;
case CTRLR_WIIMOTE:
strncpy (cfg_text[3], (char*)"WIIMOTE", 7);
break;
};
sprintf (cfg_text[0], "Remapping %s", btn_name); // note which button we are remapping
DrawMenu(&cfg_text[0], title, cfg_text_count, 1); // display text
// while (previous != pressed && pressed == 0); // get two consecutive button presses (which are the same)
// {
// previous = pressed;
// VIDEO_WaitVSync(); // slow things down a bit so we don't overread the pads
pressed = GetInput(ctrlr_type);
// }
return pressed;
} // end getButtonMap()
int cfg_btns_count = 13;
char cfg_btns_menu[][20] = {
"A - ",
"B - ",
"X - ",
"Y - ",
"L TRIG - ",
"R TRIG - ",
"SELECT - ",
"START - ",
"UP - ",
"DOWN - ",
"LEFT - ",
"RIGHT - ",
"Return to previous"
};
extern unsigned int gcpadmap[];
extern unsigned int wmpadmap[];
extern unsigned int ccpadmap[];
extern unsigned int ncpadmap[];
void
ConfigureButtons (u16 ctrlr_type)
{
int quit = 0;
int ret = 0;
int oldmenu = menu;
menu = 0;
char* menu_title;
u32 pressed;
unsigned int* currentpadmap;
char temp[20] = "";
int i, j;
/*** Update Menu Title (based on controller we're configuring) ***/
switch (ctrlr_type) {
case CTRLR_NUNCHUK:
menu_title = (char*)"SNES - NUNCHUK";
currentpadmap = ncpadmap;
break;
case CTRLR_CLASSIC:
menu_title = (char*)"SNES - CLASSIC";
currentpadmap = ccpadmap;
break;
case CTRLR_GCPAD:
menu_title = (char*)"SNES - GC PAD";
currentpadmap = gcpadmap;
break;
case CTRLR_WIIMOTE:
menu_title = (char*)"SNES - WIIMOTE";
currentpadmap = wmpadmap;
break;
};
while (quit == 0)
{
/*** Update Menu with Current ButtonMap ***/
for (i=0; i<12; i++) // snes pad has 12 buttons to config (go thru them)
{
// get current padmap button name to display
for ( j=0;
currentpadmap[i] != ctrlr_def[ctrlr_type].map[j].btn // match padmap button press with button names
&& j < ctrlr_def[ctrlr_type].num_btns
; j++ );
memset (temp, 0, sizeof(temp));
strncpy (temp, cfg_btns_menu[i], 12); // copy snes button information
if (currentpadmap[i] == ctrlr_def[ctrlr_type].map[j].btn) // check if a match was made
strncat (temp, ctrlr_def[ctrlr_type].map[j].name, 6); // update button map display
else
strcat (temp, (char*)"---"); // otherwise, button is 'unmapped'
strncpy (cfg_btns_menu[i], temp, 19); // move back updated information
}
ret = RunMenu (cfg_btns_menu, cfg_btns_count, menu_title);
switch (ret)
{
case 0:
case 1:
case 2:
case 3:
case 4:
case 5:
case 6:
case 7:
case 8:
case 9:
case 10:
case 11:
/*** Change button map ***/
// wait for input
memset (temp, 0, sizeof(temp));
strncpy(temp, cfg_btns_menu[ret], 6); // get the name of the snes button we're changing
pressed = GetButtonMap(ctrlr_type, temp); // get a button selection from user
// FIX: check if input is valid for this controller
currentpadmap[ret] = pressed; // update mapping
break;
case -1: /*** Button B ***/
case 12:
/*** Return ***/
quit = 1;
break;
}
}
menu = oldmenu;
} // end configurebuttons()
int cfg_ctrlr_count_wii = 6;
char cfg_ctrlr_menu_wii[][20] = { "Nunchuk",
"Classic Controller",
"Gamecube Pad",
"Wiimote",
"Save Prefs Now",
"Return to previous"
};
int cfg_ctrlr_count_gc = 3;
char cfg_ctrlr_menu_gc[][20] = { "Gamecube Pad",
"Save Prefs Now",
"Return to previous"
};
void
ConfigureControllers ()
{
int quit = 0;
int ret = 0;
int oldmenu = menu;
menu = 0;
while (quit == 0)
{
#ifdef HW_RVL
/*** Wii Controller Config Menu ***/
ret = RunMenu (cfg_ctrlr_menu_wii, cfg_ctrlr_count_wii, (char*)"Configure Controllers");
switch (ret)
{
case 0:
/*** Configure Nunchuk ***/
ConfigureButtons (CTRLR_NUNCHUK);
break;
case 1:
/*** Configure Classic ***/
ConfigureButtons (CTRLR_CLASSIC);
break;
case 2:
/*** Configure GC Pad ***/
ConfigureButtons (CTRLR_GCPAD);
break;
case 3:
/*** Configure Wiimote ***/
ConfigureButtons (CTRLR_WIIMOTE);
break;
case 4:
/*** Save Preferences Now ***/
quickSavePrefs(NOTSILENT);
break;
case -1: /*** Button B ***/
case 5:
/*** Return ***/
quit = 1;
break;
}
#else
/*** Gamecube Controller Config Menu ***/
ret = RunMenu (cfg_ctrlr_menu_gc, cfg_ctrlr_count_gc, (char*)"Configure Controllers");
switch (ret)
{
case 0:
/*** Configure Nunchuk ***/
ConfigureButtons (CTRLR_GCPAD);
break;
case 1:
/*** Save Preferences Now ***/
quickSavePrefs(NOTSILENT);
break;
case -1: /*** Button B ***/
case 2:
/*** Return ***/
quit = 1;
break;
}
#endif
}
menu = oldmenu;
}
/****************************************************************************
* Main Menu
****************************************************************************/
int menucount = 10;
char menuitems[][20] = { "Choose Game",
"SRAM Manager", "Freeze Manager",
"Config Controllers", "Emulator Options",
"Reset Game", "Stop DVD Drive", "Exit to Loader",
"Reboot System", "Return to Game"
};
void
mainmenu ()
{
int quit = 0;
int ret;
int *psoid = (int *) 0x80001800;
void (*PSOReload) () = (void (*)()) 0x80001800;
if ( isWii )
sprintf (menuitems[8],"Reset Wii");
else
sprintf (menuitems[8],"Reset Gamecube");
VIDEO_WaitVSync ();
while (quit == 0)
{
ret = RunMenu (menuitems, menucount, (char*)"Main Menu");
switch (ret)
{
case 0:
/*** Load ROM Menu ***/
quit = LoadManager ();
break;
case 1:
/*** SRAM Manager Menu ***/
if ( ARAM_ROMSIZE > 0 )
SaveManager ();
else
WaitPrompt((char*) "No ROM is loaded!");
break;
case 2:
/*** Do Freeze / Thaw Menu ***/
if ( ARAM_ROMSIZE > 0 )
quit = FreezeManager ();
else
WaitPrompt((char*) "No ROM is loaded!");
break;
case 3:
/*** Configure Controllers ***/
ConfigureControllers ();
break;
case 4:
/*** Emulator Options ***/
EmulatorOptions ();
break;
case 5:
/*** Soft reset ***/
S9xSoftReset ();
quit = 1;
break;
case 6:
/*** Turn off DVD motor ***/
dvd_motor_off();
break;
case 7:
/*** Exit to Loader ***/
#ifdef __wii__
exit(0);
#else // gamecube
if (psoid[0] == PSOSDLOADID)
PSOReload ();
#endif
break;
case 8:
/*** Reset the Gamecube/Wii ***/
Reboot();
break;
case -1: /*** Button B ***/
case 9:
/*** Return to Game ***/
quit = 1;
break;
}
}
/*** Remove any still held buttons ***/
#ifdef HW_RVL
while( PAD_ButtonsHeld(0) || WPAD_ButtonsHeld(0) )
VIDEO_WaitVSync();
#else
while( PAD_ButtonsHeld(0) )
VIDEO_WaitVSync();
#endif
}