snes9xgx/source/ngc/preferences.cpp

434 lines
13 KiB
C++
Raw Normal View History

/****************************************************************************
* Snes9x 1.51 Nintendo Wii/Gamecube Port
*
* Tantric September 2008
*
* preferences.cpp
*
* Preferences save/load to XML file
***************************************************************************/
#include <gccore.h>
#include <stdio.h>
#include <string.h>
#include <ogcsys.h>
2008-08-22 22:23:32 +02:00
#include <mxml.h>
#include "snes9xGX.h"
2008-08-12 05:25:16 +02:00
#include "images/saveicon.h"
2008-08-07 07:19:17 +02:00
#include "menudraw.h"
2008-08-12 05:25:16 +02:00
#include "memcardop.h"
2008-08-07 07:19:17 +02:00
#include "fileop.h"
#include "smbop.h"
#include "filesel.h"
2008-09-27 09:13:52 +02:00
#include "input.h"
extern int currconfig[4];
2008-08-20 09:58:55 +02:00
#define PREFS_FILE_NAME "SNES9xGX.xml"
char prefscomment[2][32];
/****************************************************************************
* Prepare Preferences Data
*
* This sets up the save buffer for saving.
***************************************************************************/
2008-08-20 09:58:55 +02:00
mxml_node_t *xml;
mxml_node_t *data;
mxml_node_t *section;
mxml_node_t *item;
mxml_node_t *elem;
2008-09-27 09:13:52 +02:00
char temp[20];
2008-08-20 09:58:55 +02:00
const char * toStr(int i)
{
sprintf(temp, "%d", i);
return temp;
}
2008-10-24 07:11:01 +02:00
const char * FtoStr(float i)
{
sprintf(temp, "%.2f", i);
return temp;
}
2008-08-20 09:58:55 +02:00
void createXMLSection(const char * name, const char * description)
{
section = mxmlNewElement(data, "section");
mxmlElementSetAttr(section, "name", name);
mxmlElementSetAttr(section, "description", description);
}
void createXMLSetting(const char * name, const char * description, const char * value)
{
item = mxmlNewElement(section, "setting");
mxmlElementSetAttr(item, "name", name);
mxmlElementSetAttr(item, "value", value);
mxmlElementSetAttr(item, "description", description);
}
void createXMLController(unsigned int controller[], const char * name, const char * description)
{
item = mxmlNewElement(section, "controller");
mxmlElementSetAttr(item, "name", name);
mxmlElementSetAttr(item, "description", description);
// create buttons
2008-09-27 09:13:52 +02:00
for(int i=0; i < MAXJP; i++)
2008-08-20 09:58:55 +02:00
{
elem = mxmlNewElement(item, "button");
mxmlElementSetAttr(elem, "number", toStr(i));
mxmlElementSetAttr(elem, "assignment", toStr(controller[i]));
}
}
const char * XMLSaveCallback(mxml_node_t *node, int where)
{
const char *name;
name = node->value.element.name;
if(where == MXML_WS_BEFORE_CLOSE)
{
if(!strcmp(name, "file") || !strcmp(name, "section"))
return ("\n");
else if(!strcmp(name, "controller"))
return ("\n\t");
}
if (where == MXML_WS_BEFORE_OPEN)
{
if(!strcmp(name, "file"))
return ("\n");
else if(!strcmp(name, "section"))
return ("\n\n");
else if(!strcmp(name, "setting") || !strcmp(name, "controller"))
return ("\n\t");
else if(!strcmp(name, "button"))
return ("\n\t\t");
}
return (NULL);
}
int
2008-08-20 09:58:55 +02:00
preparePrefsData (int method)
{
2008-08-20 09:58:55 +02:00
int offset = 0;
// add save icon and comments for Memory Card saves
if(method == METHOD_MC_SLOTA || method == METHOD_MC_SLOTB)
{
offset = sizeof (saveicon);
// Copy in save icon
memcpy (savebuffer, saveicon, offset);
// And the comments
sprintf (prefscomment[0], "%s Prefs", VERSIONSTR);
sprintf (prefscomment[1], "Preferences");
2008-08-20 09:58:55 +02:00
memcpy (savebuffer + offset, prefscomment, 64);
offset += 64;
}
xml = mxmlNewXML("1.0");
mxmlSetWrapMargin(0); // disable line wrapping
2008-08-20 09:58:55 +02:00
data = mxmlNewElement(xml, "file");
mxmlElementSetAttr(data, "version",VERSIONSTR);
2008-08-20 09:58:55 +02:00
createXMLSection("File", "File Settings");
createXMLSetting("AutoLoad", "Auto Load", toStr(GCSettings.AutoLoad));
createXMLSetting("AutoSave", "Auto Save", toStr(GCSettings.AutoSave));
createXMLSetting("LoadMethod", "Load Method", toStr(GCSettings.LoadMethod));
createXMLSetting("SaveMethod", "Save Method", toStr(GCSettings.SaveMethod));
createXMLSetting("LoadFolder", "Load Folder", GCSettings.LoadFolder);
createXMLSetting("SaveFolder", "Save Folder", GCSettings.SaveFolder);
createXMLSetting("CheatFolder", "Cheats Folder", GCSettings.CheatFolder);
createXMLSetting("VerifySaves", "Verify Memory Card Saves", toStr(GCSettings.VerifySaves));
createXMLSection("Network", "Network Settings");
createXMLSetting("smbip", "Share Computer IP", GCSettings.smbip);
createXMLSetting("smbshare", "Share Name", GCSettings.smbshare);
createXMLSetting("smbuser", "Share Username", GCSettings.smbuser);
createXMLSetting("smbpwd", "Share Password", GCSettings.smbpwd);
createXMLSection("Emulation", "Emulation Settings");
createXMLSetting("Transparency", "Transparency", toStr(Settings.Transparency));
createXMLSetting("DisplayFrameRate", "Display Frame Rate", toStr(Settings.DisplayFrameRate));
2008-10-24 07:11:01 +02:00
createXMLSetting("Zoom", "Zoom On/Off", toStr(GCSettings.Zoom));
createXMLSetting("ZoomLevel", "Zoom Level", FtoStr(GCSettings.ZoomLevel));
2008-08-20 09:58:55 +02:00
createXMLSetting("render", "Video Filtering", toStr(GCSettings.render));
createXMLSetting("widescreen", "Aspect Ratio Correction", toStr(GCSettings.widescreen));
createXMLSetting("xshift", "Horizontal Video Shift", toStr(GCSettings.xshift));
createXMLSetting("yshift", "Vertical Video Shift", toStr(GCSettings.yshift));
2008-08-20 09:58:55 +02:00
createXMLSection("Controller", "Controller Settings");
createXMLSetting("MultiTap", "MultiTap", toStr(Settings.MultiPlayer5Master));
createXMLSetting("Superscope", "Superscope", toStr(GCSettings.Superscope));
createXMLSetting("Mice", "Mice", toStr(GCSettings.Mouse));
createXMLSetting("Justifiers", "Justifiers", toStr(GCSettings.Justifier));
createXMLController(gcpadmap, "gcpadmap", "GameCube Pad");
createXMLController(wmpadmap, "wmpadmap", "Wiimote");
createXMLController(ccpadmap, "ccpadmap", "Classic Controller");
createXMLController(ncpadmap, "ncpadmap", "Nunchuk");
int datasize = mxmlSaveString(xml, (char *)savebuffer+offset, (SAVEBUFFERSIZE-offset), XMLSaveCallback);
2008-08-20 09:58:55 +02:00
mxmlDelete(xml);
return datasize;
}
/****************************************************************************
* loadXMLSetting
*
* Load XML elements into variables for an individual variable
***************************************************************************/
2008-08-20 09:58:55 +02:00
void loadXMLSetting(char * var, const char * name)
{
item = mxmlFindElement(xml, xml, "setting", "name", name, MXML_DESCEND);
if(item)
sprintf(var, "%s", mxmlElementGetAttr(item, "value"));
}
void loadXMLSetting(int * var, const char * name)
{
item = mxmlFindElement(xml, xml, "setting", "name", name, MXML_DESCEND);
if(item)
*var = atoi(mxmlElementGetAttr(item, "value"));
}
2008-10-24 07:11:01 +02:00
void loadXMLSetting(float * var, const char * name)
{
item = mxmlFindElement(xml, xml, "setting", "name", name, MXML_DESCEND);
if(item)
*var = atof(mxmlElementGetAttr(item, "value"));
}
2008-08-20 09:58:55 +02:00
void loadXMLSetting(bool8 * var, const char * name)
{
item = mxmlFindElement(xml, xml, "setting", "name", name, MXML_DESCEND);
if(item)
*var = atoi(mxmlElementGetAttr(item, "value"));
}
/****************************************************************************
* loadXMLController
*
* Load XML elements into variables for a controller mapping
***************************************************************************/
2008-08-20 09:58:55 +02:00
void loadXMLController(unsigned int controller[], const char * name)
{
item = mxmlFindElement(xml, xml, "controller", "name", name, MXML_DESCEND);
if(item)
{
// populate buttons
2008-09-27 09:13:52 +02:00
for(int i=0; i < MAXJP; i++)
2008-08-20 09:58:55 +02:00
{
elem = mxmlFindElement(item, xml, "button", "number", toStr(i), MXML_DESCEND);
if(elem)
controller[i] = atoi(mxmlElementGetAttr(elem, "assignment"));
}
}
}
/****************************************************************************
* decodePrefsData
*
* Decodes preferences - parses XML and loads preferences into the variables
***************************************************************************/
bool
2008-08-20 09:58:55 +02:00
decodePrefsData (int method)
{
2008-08-20 09:58:55 +02:00
int offset = 0;
// skip save icon and comments for Memory Card saves
if(method == METHOD_MC_SLOTA || method == METHOD_MC_SLOTB)
{
offset = sizeof (saveicon);
offset += 64; // sizeof prefscomment
}
xml = mxmlLoadString(NULL, (char *)savebuffer+offset, MXML_TEXT_CALLBACK);
// check settings version
// we don't do anything with the version #, but we'll store it anyway
char * version;
item = mxmlFindElement(xml, xml, "file", "version", NULL, MXML_DESCEND);
if(item) // a version entry exists
version = (char *)mxmlElementGetAttr(item, "version");
else // version # not found, must be invalid
return false;
// File Settings
loadXMLSetting(&GCSettings.AutoLoad, "AutoLoad");
loadXMLSetting(&GCSettings.AutoSave, "AutoSave");
loadXMLSetting(&GCSettings.LoadMethod, "LoadMethod");
loadXMLSetting(&GCSettings.SaveMethod, "SaveMethod");
loadXMLSetting(GCSettings.LoadFolder, "LoadFolder");
loadXMLSetting(GCSettings.SaveFolder, "SaveFolder");
loadXMLSetting(GCSettings.CheatFolder, "CheatFolder");
loadXMLSetting(&GCSettings.VerifySaves, "VerifySaves");
// Network Settings
loadXMLSetting(GCSettings.smbip, "smbip");
loadXMLSetting(GCSettings.smbshare, "smbshare");
loadXMLSetting(GCSettings.smbuser, "smbuser");
loadXMLSetting(GCSettings.smbpwd, "smbpwd");
// Emulation Settings
loadXMLSetting(&Settings.Transparency, "Transparency");
loadXMLSetting(&Settings.DisplayFrameRate, "DisplayFrameRate");
2008-10-24 07:11:01 +02:00
loadXMLSetting(&GCSettings.Zoom, "Zoom");
loadXMLSetting(&GCSettings.ZoomLevel, "ZoomLevel");
2008-08-20 09:58:55 +02:00
loadXMLSetting(&GCSettings.render, "render");
loadXMLSetting(&GCSettings.widescreen, "widescreen");
loadXMLSetting(&GCSettings.xshift, "xshift");
loadXMLSetting(&GCSettings.yshift, "yshift");
2008-08-20 09:58:55 +02:00
// Controller Settings
loadXMLSetting(&Settings.MultiPlayer5Master, "MultiTap");
loadXMLSetting(&GCSettings.Superscope, "Superscope");
loadXMLSetting(&GCSettings.Mouse, "Mice");
loadXMLSetting(&GCSettings.Justifier, "Justifiers");
loadXMLController(gcpadmap, "gcpadmap");
loadXMLController(wmpadmap, "wmpadmap");
loadXMLController(ccpadmap, "ccpadmap");
loadXMLController(ncpadmap, "ncpadmap");
mxmlDelete(xml);
return true;
}
/****************************************************************************
* Save Preferences
***************************************************************************/
bool
SavePrefs (int method, bool silent)
{
2008-10-03 23:19:45 +02:00
// there's no point in saving SMB settings TO SMB, because then we'll have no way to load them the next time!
// so instead we'll save using whatever other method is available (eg: SD)
if(method == METHOD_AUTO || method == METHOD_SMB)
method = autoSaveMethod();
char filepath[1024];
int datasize;
int offset = 0;
2008-09-27 09:13:52 +02:00
AllocSaveBuffer ();
2008-08-20 09:58:55 +02:00
datasize = preparePrefsData (method);
if (!silent)
ShowAction ((char*) "Saving preferences...");
if(method == METHOD_SD || method == METHOD_USB)
{
2008-08-12 05:25:16 +02:00
if(ChangeFATInterface(method, NOTSILENT))
{
sprintf (filepath, "%s/%s/%s", ROOTFATDIR, GCSettings.SaveFolder, PREFS_FILE_NAME);
offset = SaveBufferToFAT (filepath, datasize, silent);
}
}
else if(method == METHOD_SMB)
{
sprintf (filepath, "%s/%s", GCSettings.SaveFolder, PREFS_FILE_NAME);
offset = SaveBufferToSMB (filepath, datasize, silent);
}
else if(method == METHOD_MC_SLOTA)
{
2008-08-12 05:25:16 +02:00
offset = SaveBufferToMC (savebuffer, CARD_SLOTA, (char *)PREFS_FILE_NAME, datasize, silent);
}
else if(method == METHOD_MC_SLOTB)
{
2008-08-12 05:25:16 +02:00
offset = SaveBufferToMC (savebuffer, CARD_SLOTB, (char *)PREFS_FILE_NAME, datasize, silent);
}
2008-09-27 09:13:52 +02:00
FreeSaveBuffer ();
if (offset > 0)
{
2008-08-20 09:58:55 +02:00
if (!silent)
2008-08-12 05:25:16 +02:00
WaitPrompt ((char *)"Preferences saved");
2008-08-20 09:58:55 +02:00
return true;
}
2008-08-20 09:58:55 +02:00
return false;
}
/****************************************************************************
2008-09-04 04:42:27 +02:00
* Load Preferences from specified method
***************************************************************************/
bool
2008-09-04 05:02:29 +02:00
LoadPrefsFromMethod (int method)
{
bool retval = false;
char filepath[1024];
int offset = 0;
2008-09-27 09:13:52 +02:00
AllocSaveBuffer ();
if(method == METHOD_SD || method == METHOD_USB)
{
2008-08-12 05:25:16 +02:00
if(ChangeFATInterface(method, NOTSILENT))
{
sprintf (filepath, "%s/%s/%s", ROOTFATDIR, GCSettings.SaveFolder, PREFS_FILE_NAME);
2008-09-04 04:42:27 +02:00
offset = LoadBufferFromFAT (filepath, SILENT);
2008-08-12 05:25:16 +02:00
}
}
else if(method == METHOD_SMB)
{
sprintf (filepath, "%s/%s", GCSettings.SaveFolder, PREFS_FILE_NAME);
2008-09-04 05:02:29 +02:00
offset = LoadBufferFromSMB (filepath, SILENT);
}
else if(method == METHOD_MC_SLOTA)
{
2008-09-04 04:42:27 +02:00
offset = LoadBufferFromMC (savebuffer, CARD_SLOTA, (char *)PREFS_FILE_NAME, SILENT);
}
else if(method == METHOD_MC_SLOTB)
{
2008-09-04 04:42:27 +02:00
offset = LoadBufferFromMC (savebuffer, CARD_SLOTB, (char *)PREFS_FILE_NAME, SILENT);
}
if (offset > 0)
2008-08-20 09:58:55 +02:00
retval = decodePrefsData (method);
2008-09-04 04:42:27 +02:00
2008-09-27 09:13:52 +02:00
FreeSaveBuffer ();
return retval;
}
2008-09-04 04:42:27 +02:00
/****************************************************************************
* Load Preferences
* Checks sources consecutively until we find a preference file
***************************************************************************/
2008-09-04 04:42:27 +02:00
bool LoadPrefs()
{
ShowAction ((char*) "Loading preferences...");
bool prefFound = false;
if(ChangeFATInterface(METHOD_SD, SILENT))
prefFound = LoadPrefsFromMethod(METHOD_SD);
if(!prefFound && ChangeFATInterface(METHOD_USB, SILENT))
prefFound = LoadPrefsFromMethod(METHOD_USB);
if(!prefFound && TestCard(CARD_SLOTA, SILENT))
prefFound = LoadPrefsFromMethod(METHOD_MC_SLOTA);
if(!prefFound && TestCard(CARD_SLOTB, SILENT))
prefFound = LoadPrefsFromMethod(METHOD_MC_SLOTB);
if(!prefFound && ConnectShare (SILENT))
prefFound = LoadPrefsFromMethod(METHOD_SMB);
return prefFound;
}