/* * snes9express * prefs.cc * Copyright (C) 1998-2004 David Nordlund * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * For further details, please read the included COPYING file, * or go to http://www.gnu.org/copyleft/gpl.html */ #include #include #include #include #include #include "interface.h" #include "skins.h" #include "misc.h" /** Set up the preferences GUI */ s9x_Prefs::s9x_Prefs(fr_Element*parent): fr_Window(parent, PROG " Preferences"), Banner(0), Notebook(this), PgAppear(&Notebook, "Appearance"), PgPaths(&Notebook, "Paths"), PgReset(&Notebook, "Reset"), PgPower(&Notebook, "Power"), VideoDriver(this, "Video Driver", false), UseX11(&VideoDriver, "X11 snes9x"), UseGL(&VideoDriver, "OpenGL snes9x"), UseGlide(&VideoDriver, "Glide snes9x"), Start2Prof(this, "Default Profile", true), Start2Last(this, "Last run options", false), Reset2Prof(this, "Default Profile", true), Reset2Last(this, "Last run options", false), Reset2Args(this, "Command-line", false), Snes9xVersion(this, "", SNES9X_VERSION, 1.00, SNES9X_VERSION, 2), ROMdir(this, "Default ROM dir", S9X_ROMENV, S9X_ROMDIR, true), snes9xDir(this, "snes9x directory", "SNES9X_DIR", "", true), BtnApply(this, FR_STOCK_APPLY), BtnSave(this, FR_STOCK_SAVE), BtnClose(this, FR_STOCK_CLOSE), BtnOK(this, FR_STOCK_OK), PrefsFile("prefs"), SkinSelector(this) { fr_ButtonBox BtnBox(this); SetGridSize(1, 4, false); SetPadding(3, 3); // SetStretch(Fill, Shrink); AddListener(this); Notebook.SetPadding(3, 3); Pack(Notebook, 0, 1, 1, 2); CreatePgAppear(); CreatePgPaths(); CreatePgPower(); CreatePgReset(); Notebook.AddPage(PgPaths); Notebook.AddPage(PgAppear); Notebook.AddPage(PgPower); Notebook.AddPage(PgReset); BtnApply.AddListener(this); BtnSave.AddListener(this); BtnClose.AddListener(this); BtnOK.AddListener(this); BtnApply.SetTooltip("Apply these settings (does not Save)"); BtnSave.SetTooltip("Save these settings (does not Apply)"); BtnClose.SetTooltip("Close this window (does not Apply or Save)"); BtnOK.SetTooltip("Apply, Save, & Close"); BtnBox.AddButton(BtnApply); BtnBox.AddButton(BtnSave); BtnBox.AddButton(BtnClose); BtnBox.AddButton(BtnOK, true); SetStretch(Normal, Normal); Pack(BtnBox); BtnOK.GrabFocus(); SetToDefaults(); Load(); } void s9x_Prefs::CreatePgAppear() { PgAppear.SetGridSize(1, 2, false); fr_Box SkinBox(this); SkinBox.SetName("Skin"); SkinBox.SetGridSize(1, 1, true); SkinBox.SetPadding(3, 3); SkinBox.SetStretch(Fill, Fill); SkinBox.Pack(SkinSelector); SkinBox.Frame(); PgAppear.Pack(SkinBox); addOption(SkinSelector); fr_Box Box(this); Box.SetName("snes9x version"); Box.SetGridSize(3, 1, false); fr_Label lbl(this, "snes9x version:"); Box.Pack(lbl); Snes9xVersion.SetName("snes9x version:"); Snes9xVersion.Args << fr_CaseInsensitive << "--snes9xversion"; Snes9xVersion.SetTooltip("Set the version of snes9x you are using. " "The appropraite options will be available " "in the interface."); addOption(Snes9xVersion); Box.Pack(Snes9xVersion); Box.Frame(); PgAppear.Pack(Box); } void s9x_Prefs::CreatePgPaths() { PgPaths.SetGridSize(1, 1, false); ROMdir.Args << fr_CaseInsensitive << "--romdir"; ROMdir.AddLabel("ROMs:"); ROMdir.SetTooltip("Enter the path of the default directory for ROMs"); addOption(ROMdir); std::string Home(fr_HomeDir()); std::string DefSnapDir = Home + '/' + S9X_SNAPSHOTDIR; SnapDir = new fr_File(this, "Default Snapshot dir", S9X_SNAPSHOTENV, DefSnapDir, true); SnapDir->Args << fr_CaseInsensitive << "--snapshotdir"; SnapDir->AddLabel("Snapshots:"); SnapDir->SetTooltip("Enter the path of the default directory for Snapshots"); addOption(*SnapDir); snes9xDir.Args << fr_CaseInsensitive << "--snes9xdir" << "--snes9x"; snes9xDir.AddLabel("snes9x:"); snes9xDir.SetTooltip("Enter the directory where the snes9x executables are.\n" "If this is blank, $PATH will be searched."); addOption(snes9xDir); fr_Box Box1(this); Box1.SetName("Directories"); Box1.SetGridSize(1, 3, true); Box1.Frame(); Box1.Pack(ROMdir); Box1.Pack(*SnapDir); Box1.Pack(snes9xDir); PgPaths.Pack(Box1); } void s9x_Prefs::CreatePgReset() { PgReset.SetGridSize(1, 2, true); fr_Box Box1(this); Box1.SetName("Reset Button loads ..."); Box1.SetGridSize(2, 1, true); Reset2Prof.Args << fr_CaseInsensitive << "--reset+profile"; Reset2Prof.NotArgs << "--reset-profile"; Reset2Prof.SetTooltip("Load the Default Profile"); addOption(Reset2Prof); Box1.Pack(Reset2Prof); Reset2Last.Args << fr_CaseInsensitive << "--reset+last"; Reset2Last.SetTooltip("Set the options to those that were used" " the last time you ran snes9x"); addOption(Reset2Last); Box1.Pack(Reset2Last); Reset2Args.Args << fr_CaseInsensitive << "--reset+args"; Reset2Args.SetTooltip("Re-read the " PROG " command line options\n (if any" " were issued. This is always done at start up)"); addOption(Reset2Args); Box1.Pack(Reset2Args); Box1.Frame(); fr_Box Box2(this); Box2.SetName("Start-Up loads ..."); Box2.SetGridSize(2, 1, true); Start2Prof.Args << fr_CaseInsensitive << "--start+profile"; Start2Prof.NotArgs << "--start-profile"; Start2Prof.SetTooltip("Load the Default Profile"); addOption(Start2Prof); Box2.Pack(Start2Prof); Start2Last.Args << fr_CaseInsensitive << "--start+last"; Start2Last.SetTooltip("Set the options to those that were used" " the last time you ran snes9x"); addOption(Start2Last); Box2.Pack(Start2Last); Box2.Frame(); PgReset.Pack(Box1); PgReset.Pack(Box2); } void s9x_Prefs::CreatePgPower() { PgPower.SetGridSize(1, 1, true); fr_Box BoxRun(this); BoxRun.SetName("Power button runs..."); BoxRun.SetGridSize(1, 3, false); BoxRun.SetPadding(3, 3); UseX11.Args << fr_CaseInsensitive << "--driver=x11"; UseX11.SetTooltip("Use the regular X11 snes9x executable"); UseGL.Args << fr_CaseInsensitive << "--driver=opengl"; UseGL.SetTooltip("Use the OpenGL snes9x executable"); UseGlide.Args << fr_CaseInsensitive << "--driver=glide"; UseGlide.SetTooltip("Use the Glide snes9x executable"); addOption(VideoDriver); BoxRun.Pack(UseX11); BoxRun.Pack(UseGL); BoxRun.Pack(UseGlide); BoxRun.Frame(); PgPower.Pack(BoxRun); } s9x_Prefs::~s9x_Prefs() { } void s9x_Prefs::SetToDefaults() { s9x_OptionManager::SetToDefaults(); } void s9x_Prefs::SiftArgs(fr_ArgList& L) { s9x_OptionManager::SiftArgs(L); snes9xDir.SetFileName(GetSnes9xDir()); //fr_ArgList tmpL(25); //CompileArgs(tmpL); } std::string s9x_Prefs::GetROMdir() { return ROMdir.GetFileName(); } std::string s9x_Prefs::GetSnapDir() { return SnapDir->GetFileName(); } std::string s9x_Prefs::GetSnes9xDir() { std::string s = snes9xDir.GetFileName(); if(s.size()==0) return ""; if(fr_DirExists(s)) return s; //std::cerr << "converting from old file path to directory path" << std::endl; // the following is for backwards compatibilty with older // versions of snes9express that have paths to executables. std::string s9xdir = fr_Dirname(s); if(fr_DirExists(s9xdir)) return s9xdir; return ""; } void s9x_Prefs::Load() { s9x_Interface*I = (s9x_Interface*)Parent; std::ifstream infile; std::string errmsg(""); bool resave = false; if(PrefsFile.exists()) { try { PrefsFile.open(infile); fr_ArgList ArgList(25); std::string buf; ArgList << fr_CaseInsensitive; if(!(infile >> buf)||(buf != PROG)) // old prefs format { ArgList << buf; while(std::getline(infile, buf)) ArgList << buf; resave = true; } else { // not so old prefs format if(!std::getline(infile, buf) || (buf != " prefs")) throw "invalid format or file corrupt"; infile >> ArgList; } SiftArgs(ArgList); } catch(const char*e) { errmsg = e; } catch(const std::string& e) { errmsg = e; } catch(...) { errmsg = "unidentified exception"; } PrefsFile.close(infile); if(resave && errmsg.size()==0) Save(); } if(errmsg.size()) I->Mesg("Error loading preferences file:\n" + errmsg, true); } void s9x_Prefs::Save() { std::ofstream outfile; try { fr_ArgList ArgList(25); CompileArgs(ArgList); int c = ArgList.CountArgs(); if(c<1) { PrefsFile.remove(); return; } PrefsFile.open(outfile); outfile << PROG " prefs" << std::endl << ArgList << std::endl; } catch(const std::string& errmsg) { Mesg(std::string("Error saving preferences:\n") + errmsg, true); } catch(...) { Mesg("Error saving preferences file! :(", true); } PrefsFile.close(outfile); } void s9x_Prefs::Apply() { static char RomDirEnv[FR_PATH_MAX], SnapDirEnv[FR_PATH_MAX]; int l; s9x_Interface*I = (s9x_Interface*)Parent; I->ApplySkin(SkinSelector.GetSelectedSkinPath()); std::string rd = ROMdir.GetFileName(); std::string sd = SnapDir->GetFileName(); snprintf(RomDirEnv, sizeof(RomDirEnv), "%s=%s", S9X_ROMENV, rd.c_str()); snprintf(SnapDirEnv, sizeof(SnapDirEnv), "%s=%s", S9X_SNAPSHOTENV, sd.c_str()); //putenv(RomDirEnv); putenv(SnapDirEnv); fr_ToggleInGroup* SelectedExecutable = VideoDriver.GetSelected(); std::string executable = GetSnes9xDir(); l = executable.size(); if(l && (executable[l-1] != '/')) executable += '/'; if(SelectedExecutable == &UseGL) executable += "osnes9x"; else if(SelectedExecutable == &UseGlide) executable += "gsnes9x"; else executable += "snes9x"; I->setExecutable(executable); I->setROMdir(GetROMdir()); I->Set9xVersion(Snes9xVersion.GetValue()); } void s9x_Prefs::ApplySkin(s9x_Skin*S) { #ifdef S9X_SKINABLE s9x_SkinSection* section = S?S->getSection("icons"):NULL; fr_Image* icon = section?section->getImage("logo"):NULL; fr_Image* label = section?section->getImage("label"):NULL; setIcon(icon); if(Banner) { Remove(*Banner); delete Banner; Banner = 0; } if(label) { Banner = new fr_Element(this, *label); Pack(*Banner, 0, 0, 1, 1); } #endif } bool s9x_Prefs::ResetToProfile() { return Reset2Prof.GetState(); } bool s9x_Prefs::ResetToArgs() { return Reset2Args.GetState(); } bool s9x_Prefs::ResetToLast() { return Reset2Last.GetState(); } bool s9x_Prefs::StartToProfile() { return Start2Prof.GetState(); } bool s9x_Prefs::StartToLast() { return Start2Last.GetState(); } void s9x_Prefs::EventOccurred(fr_Event*e) { if(e->Is(BtnApply)||e->Is(BtnOK)) Apply(); if(e->Is(BtnSave)||e->Is(BtnOK)) Save(); if(e->Is(BtnClose)||e->Is(BtnOK)) SetVisibility(false); else if(e->Is(BtnApply)) { fr_Flush(); SetVisibility(true); } else if(e->Is(this, fr_Destroy)) SetVisibility(false); else if(e->Is(this, fr_MenuClick)) SetVisibility(true); }