rlm@1: // VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator. rlm@1: // Copyright (C) 1999-2003 Forgotten rlm@1: // Copyright (C) 2004 Forgotten and the VBA development team rlm@1: rlm@1: // This program is free software; you can redistribute it and/or modify rlm@1: // it under the terms of the GNU General Public License as published by rlm@1: // the Free Software Foundation; either version 2, or(at your option) rlm@1: // any later version. rlm@1: // rlm@1: // This program is distributed in the hope that it will be useful, rlm@1: // but WITHOUT ANY WARRANTY; without even the implied warranty of rlm@1: // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the rlm@1: // GNU General Public License for more details. rlm@1: // rlm@1: // You should have received a copy of the GNU General Public License rlm@1: // along with this program; if not, write to the Free Software Foundation, rlm@1: // Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. rlm@1: rlm@1: #include "window.h" rlm@1: rlm@1: #include rlm@1: rlm@1: #include rlm@1: #include rlm@1: rlm@1: #include rlm@1: rlm@1: #include "../gba/GBA.h" rlm@1: #include "../gba/GBAGlobals.h" rlm@1: #include "../gba/GBASound.h" rlm@1: #include "../gb/GB.h" rlm@1: #include "../gb/gbGlobals.h" rlm@1: #include "../gb/gbPrinter.h" rlm@1: #include "../common/Util.h" rlm@1: rlm@1: #include "menuitem.h" rlm@1: #include "tools.h" rlm@1: #include "intl.h" rlm@1: rlm@1: extern int systemRenderedFrames; rlm@1: extern int systemFPS; rlm@1: extern bool debugger; rlm@1: extern int RGB_LOW_BITS_MASK; rlm@1: extern void (*dbgMain)(); rlm@1: extern void (*dbgSignal)(int, int); rlm@1: extern void (*dbgOutput)(char *, u32); rlm@1: extern void remoteInit(); rlm@1: extern void remoteCleanUp(); rlm@1: extern void remoteStubMain(); rlm@1: extern void remoteStubSignal(int, int); rlm@1: extern void remoteOutput(char *, u32); rlm@1: extern void remoteSetProtocol(int); rlm@1: extern void remoteSetPort(int); rlm@1: rlm@1: #ifdef MMX rlm@1: extern "C" bool cpu_mmx; rlm@1: #endif // MMX rlm@1: rlm@1: namespace VBA rlm@1: { rlm@1: rlm@1: using Gnome::Glade::Xml; rlm@1: rlm@1: Window * Window::m_poInstance = NULL; rlm@1: rlm@1: Window::Window(GtkWindow * _pstWindow, const Glib::RefPtr & _poXml) : rlm@1: Gtk::Window (_pstWindow), rlm@1: m_iGBScreenWidth (160), rlm@1: m_iGBScreenHeight (144), rlm@1: m_iSGBScreenWidth (256), rlm@1: m_iSGBScreenHeight(224), rlm@1: m_iGBAScreenWidth (240), rlm@1: m_iGBAScreenHeight(160), rlm@1: m_iFrameskipMin (0), rlm@1: m_iFrameskipMax (9), rlm@1: m_iThrottleMin (5), rlm@1: m_iThrottleMax (1000), rlm@1: m_iScaleMin (1), rlm@1: m_iScaleMax (6), rlm@1: m_iShowSpeedMin (ShowNone), rlm@1: m_iShowSpeedMax (ShowDetailed), rlm@1: m_iSaveTypeMin (SaveAuto), rlm@1: m_iSaveTypeMax (SaveNone), rlm@1: m_iSoundQualityMin(Sound44K), rlm@1: m_iSoundQualityMax(Sound11K), rlm@1: m_iSoundVolumeMin (Sound100), rlm@1: m_iSoundVolumeMax (Sound50), rlm@1: m_iEmulatorTypeMin(EmulatorAuto), rlm@1: m_iEmulatorTypeMax(EmulatorSGB2), rlm@1: m_iFilter2xMin (FirstFilter), rlm@1: m_iFilter2xMax (LastFilter), rlm@1: m_iFilterIBMin (FirstFilterIB), rlm@1: m_iFilterIBMax (LastFilterIB), rlm@1: m_iJoypadMin (1), rlm@1: m_iJoypadMax (4) rlm@1: { rlm@1: m_poXml = _poXml; rlm@1: m_poFileOpenDialog = NULL; rlm@1: m_iScreenWidth = m_iGBAScreenWidth; rlm@1: m_iScreenHeight = m_iGBAScreenHeight; rlm@1: m_eCartridge = CartridgeNone; rlm@1: m_uiJoypadState = 0; rlm@1: rlm@1: vInitSystem(); rlm@1: vInitSDL(); rlm@1: rlm@1: Gtk::Container * poC; rlm@1: poC = dynamic_cast(_poXml->get_widget("ScreenContainer")); rlm@1: m_poScreenArea = Gtk::manage(new ScreenArea(m_iScreenWidth, m_iScreenHeight)); rlm@1: poC->add(*m_poScreenArea); rlm@1: vDrawDefaultScreen(); rlm@1: m_poScreenArea->show(); rlm@1: rlm@1: // Get config rlm@1: // rlm@1: vInitConfig(); rlm@1: rlm@1: m_sUserDataDir = Glib::get_home_dir() + "/.gvba"; rlm@1: m_sConfigFile = m_sUserDataDir + "/config"; rlm@1: rlm@1: if (! Glib::file_test(m_sUserDataDir, Glib::FILE_TEST_EXISTS)) rlm@1: { rlm@1: mkdir(m_sUserDataDir.c_str(), 0777); rlm@1: } rlm@1: if (Glib::file_test(m_sConfigFile, Glib::FILE_TEST_EXISTS)) rlm@1: { rlm@1: vLoadConfig(m_sConfigFile); rlm@1: vCheckConfig(); rlm@1: } rlm@1: else rlm@1: { rlm@1: vSaveConfig(m_sConfigFile); rlm@1: } rlm@1: rlm@1: vCreateFileOpenDialog(); rlm@1: vLoadHistoryFromConfig(); rlm@1: vLoadJoypadsFromConfig(); rlm@1: rlm@1: Gtk::MenuItem * poMI; rlm@1: Gtk::CheckMenuItem * poCMI; rlm@1: rlm@1: // File menu rlm@1: // rlm@1: poMI = dynamic_cast(_poXml->get_widget("FileOpen")); rlm@1: poMI->signal_activate().connect(SigC::slot(*this, &Window::vOnFileOpen)); rlm@1: rlm@1: poMI = dynamic_cast(_poXml->get_widget("FileLoad")); rlm@1: poMI->signal_activate().connect(SigC::slot(*this, &Window::vOnFileLoad)); rlm@1: m_listSensitiveWhenPlaying.push_back(poMI); rlm@1: rlm@1: poMI = dynamic_cast(_poXml->get_widget("FileSave")); rlm@1: poMI->signal_activate().connect(SigC::slot(*this, &Window::vOnFileSave)); rlm@1: m_listSensitiveWhenPlaying.push_back(poMI); rlm@1: rlm@1: for (int i = 0; i < 10; i++) rlm@1: { rlm@1: char csName[20]; rlm@1: snprintf(csName, 20, "LoadGameSlot%d", i + 1); rlm@1: m_apoLoadGameItem[i] = dynamic_cast(_poXml->get_widget(csName)); rlm@1: snprintf(csName, 20, "SaveGameSlot%d", i + 1); rlm@1: m_apoSaveGameItem[i] = dynamic_cast(_poXml->get_widget(csName)); rlm@1: rlm@1: m_apoLoadGameItem[i]->signal_activate().connect(SigC::bind( rlm@1: SigC::slot(*this, &Window::vOnLoadGame), rlm@1: i + 1)); rlm@1: m_apoSaveGameItem[i]->signal_activate().connect(SigC::bind( rlm@1: SigC::slot(*this, &Window::vOnSaveGame), rlm@1: i + 1)); rlm@1: } rlm@1: vUpdateGameSlots(); rlm@1: rlm@1: poMI = dynamic_cast(_poXml->get_widget("LoadGameMostRecent")); rlm@1: poMI->signal_activate().connect(SigC::slot(*this, &Window::vOnLoadGameMostRecent)); rlm@1: m_listSensitiveWhenPlaying.push_back(poMI); rlm@1: rlm@1: poCMI = dynamic_cast(_poXml->get_widget("LoadGameAuto")); rlm@1: poCMI->set_active(m_poCoreConfig->oGetKey("load_game_auto")); rlm@1: vOnLoadGameAutoToggled(poCMI); rlm@1: poCMI->signal_toggled().connect(SigC::bind( rlm@1: SigC::slot(*this, &Window::vOnLoadGameAutoToggled), rlm@1: poCMI)); rlm@1: rlm@1: poMI = dynamic_cast(_poXml->get_widget("SaveGameOldest")); rlm@1: poMI->signal_activate().connect(SigC::slot(*this, &Window::vOnSaveGameOldest)); rlm@1: m_listSensitiveWhenPlaying.push_back(poMI); rlm@1: rlm@1: m_poFilePauseItem = dynamic_cast(_poXml->get_widget("FilePause")); rlm@1: m_poFilePauseItem->set_active(false); rlm@1: vOnFilePauseToggled(m_poFilePauseItem); rlm@1: m_poFilePauseItem->signal_toggled().connect(SigC::bind( rlm@1: SigC::slot(*this, &Window::vOnFilePauseToggled), rlm@1: m_poFilePauseItem)); rlm@1: m_listSensitiveWhenPlaying.push_back(m_poFilePauseItem); rlm@1: rlm@1: poMI = dynamic_cast(_poXml->get_widget("FileReset")); rlm@1: poMI->signal_activate().connect(SigC::slot(*this, &Window::vOnFileReset)); rlm@1: m_listSensitiveWhenPlaying.push_back(poMI); rlm@1: rlm@1: poMI = dynamic_cast(_poXml->get_widget("FileScreenCapture")); rlm@1: poMI->signal_activate().connect(SigC::slot(*this, &Window::vOnFileScreenCapture)); rlm@1: m_listSensitiveWhenPlaying.push_back(poMI); rlm@1: rlm@1: poMI = dynamic_cast(_poXml->get_widget("FileClose")); rlm@1: poMI->signal_activate().connect(SigC::slot(*this, &Window::vOnFileClose)); rlm@1: m_listSensitiveWhenPlaying.push_back(poMI); rlm@1: rlm@1: poMI = dynamic_cast(_poXml->get_widget("FileExit")); rlm@1: poMI->signal_activate().connect(SigC::slot(*this, &Window::vOnFileExit)); rlm@1: rlm@1: // Recent menu rlm@1: // rlm@1: m_poRecentMenu = dynamic_cast(_poXml->get_widget("RecentMenu_menu")); rlm@1: vUpdateHistoryMenu(); rlm@1: rlm@1: m_poRecentResetItem = dynamic_cast(_poXml->get_widget("RecentReset")); rlm@1: m_poRecentResetItem->signal_activate().connect(SigC::slot(*this, &Window::vOnRecentReset)); rlm@1: rlm@1: poCMI = dynamic_cast(_poXml->get_widget("RecentFreeze")); rlm@1: poCMI->set_active(m_poHistoryConfig->oGetKey("freeze")); rlm@1: vOnRecentFreezeToggled(poCMI); rlm@1: poCMI->signal_toggled().connect(SigC::bind( rlm@1: SigC::slot(*this, &Window::vOnRecentFreezeToggled), rlm@1: poCMI)); rlm@1: rlm@1: // Import menu rlm@1: // rlm@1: poMI = dynamic_cast(_poXml->get_widget("ImportBatteryFile")); rlm@1: poMI->signal_activate().connect(SigC::slot(*this, &Window::vOnImportBatteryFile)); rlm@1: m_listSensitiveWhenPlaying.push_back(poMI); rlm@1: rlm@1: // Export menu rlm@1: // rlm@1: poMI = dynamic_cast(_poXml->get_widget("ExportBatteryFile")); rlm@1: poMI->signal_activate().connect(SigC::slot(*this, &Window::vOnExportBatteryFile)); rlm@1: m_listSensitiveWhenPlaying.push_back(poMI); rlm@1: rlm@1: // Frameskip menu rlm@1: // rlm@1: struct rlm@1: { rlm@1: const char * m_csName; rlm@1: const int m_iFrameskip; rlm@1: } rlm@1: astFrameskip[] = rlm@1: { rlm@1: { "FrameskipAutomatic", -1 }, rlm@1: { "Frameskip0", 0 }, rlm@1: { "Frameskip1", 1 }, rlm@1: { "Frameskip2", 2 }, rlm@1: { "Frameskip3", 3 }, rlm@1: { "Frameskip4", 4 }, rlm@1: { "Frameskip5", 5 }, rlm@1: { "Frameskip6", 6 }, rlm@1: { "Frameskip7", 7 }, rlm@1: { "Frameskip8", 8 }, rlm@1: { "Frameskip9", 9 } rlm@1: }; rlm@1: int iDefaultFrameskip; rlm@1: if (m_poCoreConfig->sGetKey("frameskip") == "auto") rlm@1: { rlm@1: iDefaultFrameskip = -1; rlm@1: } rlm@1: else rlm@1: { rlm@1: iDefaultFrameskip = m_poCoreConfig->oGetKey("frameskip"); rlm@1: } rlm@1: for (guint i = 0; i < G_N_ELEMENTS(astFrameskip); i++) rlm@1: { rlm@1: poCMI = dynamic_cast(_poXml->get_widget(astFrameskip[i].m_csName)); rlm@1: if (astFrameskip[i].m_iFrameskip == iDefaultFrameskip) rlm@1: { rlm@1: poCMI->set_active(); rlm@1: vOnFrameskipToggled(poCMI, iDefaultFrameskip); rlm@1: } rlm@1: poCMI->signal_toggled().connect(SigC::bind( rlm@1: SigC::slot(*this, &Window::vOnFrameskipToggled), rlm@1: poCMI, astFrameskip[i].m_iFrameskip)); rlm@1: } rlm@1: rlm@1: // Throttle menu rlm@1: // rlm@1: struct rlm@1: { rlm@1: const char * m_csName; rlm@1: const int m_iThrottle; rlm@1: } rlm@1: astThrottle[] = rlm@1: { rlm@1: { "ThrottleNoThrottle", 0 }, rlm@1: { "Throttle25", 25 }, rlm@1: { "Throttle50", 50 }, rlm@1: { "Throttle100", 100 }, rlm@1: { "Throttle150", 150 }, rlm@1: { "Throttle200", 200 } rlm@1: }; rlm@1: poCMI = dynamic_cast(_poXml->get_widget("ThrottleOther")); rlm@1: poCMI->set_active(); rlm@1: poCMI->signal_activate().connect(SigC::bind( rlm@1: SigC::slot(*this, &Window::vOnThrottleOther), rlm@1: poCMI)); rlm@1: rlm@1: int iDefaultThrottle = m_poCoreConfig->oGetKey("throttle"); rlm@1: for (guint i = 0; i < G_N_ELEMENTS(astThrottle); i++) rlm@1: { rlm@1: poCMI = dynamic_cast(_poXml->get_widget(astThrottle[i].m_csName)); rlm@1: if (astThrottle[i].m_iThrottle == iDefaultThrottle) rlm@1: { rlm@1: poCMI->set_active(); rlm@1: } rlm@1: poCMI->signal_toggled().connect(SigC::bind( rlm@1: SigC::slot(*this, &Window::vOnThrottleToggled), rlm@1: poCMI, astThrottle[i].m_iThrottle)); rlm@1: } rlm@1: vSetThrottle(iDefaultThrottle); rlm@1: rlm@1: // Video menu rlm@1: // rlm@1: struct rlm@1: { rlm@1: const char * m_csName; rlm@1: const int m_iScale; rlm@1: } rlm@1: astVideoScale[] = rlm@1: { rlm@1: { "Video1x", 1 }, rlm@1: { "Video2x", 2 }, rlm@1: { "Video3x", 3 }, rlm@1: { "Video4x", 4 }, rlm@1: { "Video5x", 5 }, rlm@1: { "Video6x", 6 } rlm@1: }; rlm@1: int iDefaultScale = m_poDisplayConfig->oGetKey("scale"); rlm@1: for (guint i = 0; i < G_N_ELEMENTS(astVideoScale); i++) rlm@1: { rlm@1: poCMI = dynamic_cast(_poXml->get_widget(astVideoScale[i].m_csName)); rlm@1: if (astVideoScale[i].m_iScale == iDefaultScale) rlm@1: { rlm@1: poCMI->set_active(); rlm@1: vOnVideoScaleToggled(poCMI, iDefaultScale); rlm@1: } rlm@1: poCMI->signal_toggled().connect(SigC::bind( rlm@1: SigC::slot(*this, &Window::vOnVideoScaleToggled), rlm@1: poCMI, astVideoScale[i].m_iScale)); rlm@1: } rlm@1: rlm@1: // Layers menu rlm@1: // rlm@1: struct rlm@1: { rlm@1: const char * m_csName; rlm@1: const char * m_csKey; rlm@1: const int m_iLayer; rlm@1: } rlm@1: astLayer[] = rlm@1: { rlm@1: { "LayersBg0", "layer_bg0", 0 }, rlm@1: { "LayersBg1", "layer_bg1", 1 }, rlm@1: { "LayersBg2", "layer_bg2", 2 }, rlm@1: { "LayersBg3", "layer_bg3", 3 }, rlm@1: { "LayersObj", "layer_obj", 4 }, rlm@1: { "LayersWin0", "layer_win0", 5 }, rlm@1: { "LayersWin1", "layer_win1", 6 }, rlm@1: { "LayersObjWin", "layer_objwin", 7 } rlm@1: }; rlm@1: for (guint i = 0; i < G_N_ELEMENTS(astLayer); i++) rlm@1: { rlm@1: poCMI = dynamic_cast(_poXml->get_widget(astLayer[i].m_csName)); rlm@1: poCMI->set_active(m_poCoreConfig->oGetKey(astLayer[i].m_csKey)); rlm@1: vOnLayerToggled(poCMI, astLayer[i].m_iLayer); rlm@1: poCMI->signal_toggled().connect(SigC::bind( rlm@1: SigC::slot(*this, &Window::vOnLayerToggled), rlm@1: poCMI, astLayer[i].m_iLayer)); rlm@1: } rlm@1: rlm@1: // Emulator menu rlm@1: // rlm@1: poMI = dynamic_cast(_poXml->get_widget("EmulatorDirectories")); rlm@1: poMI->signal_activate().connect(SigC::slot(*this, &Window::vOnDirectories)); rlm@1: rlm@1: poCMI = dynamic_cast(_poXml->get_widget("EmulatorPauseWhenInactive")); rlm@1: poCMI->set_active(m_poDisplayConfig->oGetKey("pause_when_inactive")); rlm@1: vOnPauseWhenInactiveToggled(poCMI); rlm@1: poCMI->signal_toggled().connect(SigC::bind( rlm@1: SigC::slot(*this, &Window::vOnPauseWhenInactiveToggled), rlm@1: poCMI)); rlm@1: rlm@1: m_poUseBiosItem = dynamic_cast(_poXml->get_widget("EmulatorUseBios")); rlm@1: m_poUseBiosItem->set_active(m_poCoreConfig->oGetKey("use_bios_file")); rlm@1: if (m_poCoreConfig->sGetKey("bios_file") == "") rlm@1: { rlm@1: m_poUseBiosItem->set_sensitive(false); rlm@1: } rlm@1: m_poUseBiosItem->signal_toggled().connect(SigC::bind( rlm@1: SigC::slot(*this, &Window::vOnUseBiosToggled), rlm@1: m_poUseBiosItem)); rlm@1: rlm@1: poMI = dynamic_cast(_poXml->get_widget("EmulatorSelectBios")); rlm@1: poMI->signal_activate().connect(SigC::slot(*this, &Window::vOnSelectBios)); rlm@1: rlm@1: // Show speed menu rlm@1: // rlm@1: struct rlm@1: { rlm@1: const char * m_csName; rlm@1: const EShowSpeed m_eShowSpeed; rlm@1: } rlm@1: astShowSpeed[] = rlm@1: { rlm@1: { "ShowSpeedNone", ShowNone }, rlm@1: { "ShowSpeedPercentage", ShowPercentage }, rlm@1: { "ShowSpeedDetailed", ShowDetailed } rlm@1: }; rlm@1: EShowSpeed eDefaultShowSpeed = (EShowSpeed)m_poDisplayConfig->oGetKey("show_speed"); rlm@1: for (guint i = 0; i < G_N_ELEMENTS(astShowSpeed); i++) rlm@1: { rlm@1: poCMI = dynamic_cast(_poXml->get_widget(astShowSpeed[i].m_csName)); rlm@1: if (astShowSpeed[i].m_eShowSpeed == eDefaultShowSpeed) rlm@1: { rlm@1: poCMI->set_active(); rlm@1: vOnShowSpeedToggled(poCMI, eDefaultShowSpeed); rlm@1: } rlm@1: poCMI->signal_toggled().connect(SigC::bind( rlm@1: SigC::slot(*this, &Window::vOnShowSpeedToggled), rlm@1: poCMI, astShowSpeed[i].m_eShowSpeed)); rlm@1: } rlm@1: rlm@1: // Save type menu rlm@1: // rlm@1: struct rlm@1: { rlm@1: const char * m_csName; rlm@1: const ESaveType m_eSaveType; rlm@1: } rlm@1: astSaveType[] = rlm@1: { rlm@1: { "SaveTypeAutomatic", SaveAuto }, rlm@1: { "SaveTypeEeprom", SaveEEPROM }, rlm@1: { "SaveTypeSram", SaveSRAM }, rlm@1: { "SaveTypeFlash", SaveFlash }, rlm@1: { "SaveTypeEepromSensor", SaveEEPROMSensor }, rlm@1: { "SaveTypeNone", SaveNone } rlm@1: }; rlm@1: ESaveType eDefaultSaveType = (ESaveType)m_poCoreConfig->oGetKey("save_type"); rlm@1: for (guint i = 0; i < G_N_ELEMENTS(astSaveType); i++) rlm@1: { rlm@1: poCMI = dynamic_cast(_poXml->get_widget(astSaveType[i].m_csName)); rlm@1: if (astSaveType[i].m_eSaveType == eDefaultSaveType) rlm@1: { rlm@1: poCMI->set_active(); rlm@1: vOnSaveTypeToggled(poCMI, eDefaultSaveType); rlm@1: } rlm@1: poCMI->signal_toggled().connect(SigC::bind( rlm@1: SigC::slot(*this, &Window::vOnSaveTypeToggled), rlm@1: poCMI, astSaveType[i].m_eSaveType)); rlm@1: } rlm@1: rlm@1: // Flash size menu rlm@1: // rlm@1: struct rlm@1: { rlm@1: const char * m_csName; rlm@1: const int m_iFlashSize; rlm@1: } rlm@1: astFlashSize[] = rlm@1: { rlm@1: { "SaveTypeFlash64K", 64 }, rlm@1: { "SaveTypeFlash128K", 128 } rlm@1: }; rlm@1: int iDefaultFlashSize = m_poCoreConfig->oGetKey("flash_size"); rlm@1: for (guint i = 0; i < G_N_ELEMENTS(astFlashSize); i++) rlm@1: { rlm@1: poCMI = dynamic_cast(_poXml->get_widget(astFlashSize[i].m_csName)); rlm@1: if (astFlashSize[i].m_iFlashSize == iDefaultFlashSize) rlm@1: { rlm@1: poCMI->set_active(); rlm@1: vOnFlashSizeToggled(poCMI, iDefaultFlashSize); rlm@1: } rlm@1: poCMI->signal_toggled().connect(SigC::bind( rlm@1: SigC::slot(*this, &Window::vOnFlashSizeToggled), rlm@1: poCMI, astFlashSize[i].m_iFlashSize)); rlm@1: } rlm@1: rlm@1: // Screenshot format menu rlm@1: // rlm@1: struct rlm@1: { rlm@1: const char * m_csName; rlm@1: const char * m_csScreenshotFormat; rlm@1: } rlm@1: astScreenshotFormat[] = rlm@1: { rlm@1: { "ScreenshotFormatPNG", "png" }, rlm@1: { "ScreenshotFormatBMP", "bmp" } rlm@1: }; rlm@1: std::string sDefaultScreenshotFormat = m_poCoreConfig->sGetKey("screenshot_format"); rlm@1: for (guint i = 0; i < G_N_ELEMENTS(astScreenshotFormat); i++) rlm@1: { rlm@1: poCMI = dynamic_cast(_poXml->get_widget(astScreenshotFormat[i].m_csName)); rlm@1: if (astScreenshotFormat[i].m_csScreenshotFormat == sDefaultScreenshotFormat) rlm@1: { rlm@1: poCMI->set_active(); rlm@1: vOnScreenshotFormatToggled(poCMI, sDefaultScreenshotFormat); rlm@1: } rlm@1: poCMI->signal_toggled().connect(SigC::bind( rlm@1: SigC::slot(*this, &Window::vOnScreenshotFormatToggled), rlm@1: poCMI, std::string(astScreenshotFormat[i].m_csScreenshotFormat))); rlm@1: } rlm@1: rlm@1: // Sound menu rlm@1: // rlm@1: std::string sDefaultSoundStatus = m_poSoundConfig->sGetKey("status"); rlm@1: rlm@1: poCMI = dynamic_cast(_poXml->get_widget("SoundOff")); rlm@1: if (sDefaultSoundStatus == "off") rlm@1: { rlm@1: poCMI->set_active(); rlm@1: vOnSoundStatusToggled(poCMI, SoundOff); rlm@1: } rlm@1: poCMI->signal_toggled().connect(SigC::bind( rlm@1: SigC::slot(*this, &Window::vOnSoundStatusToggled), rlm@1: poCMI, SoundOff)); rlm@1: m_poSoundOffItem = poCMI; rlm@1: rlm@1: poCMI = dynamic_cast(_poXml->get_widget("SoundMute")); rlm@1: if (sDefaultSoundStatus == "mute") rlm@1: { rlm@1: poCMI->set_active(); rlm@1: vOnSoundStatusToggled(poCMI, SoundMute); rlm@1: } rlm@1: poCMI->signal_toggled().connect(SigC::bind( rlm@1: SigC::slot(*this, &Window::vOnSoundStatusToggled), rlm@1: poCMI, SoundMute)); rlm@1: rlm@1: poCMI = dynamic_cast(_poXml->get_widget("SoundOn")); rlm@1: if (sDefaultSoundStatus == "on") rlm@1: { rlm@1: poCMI->set_active(); rlm@1: vOnSoundStatusToggled(poCMI, SoundOn); rlm@1: } rlm@1: poCMI->signal_toggled().connect(SigC::bind( rlm@1: SigC::slot(*this, &Window::vOnSoundStatusToggled), rlm@1: poCMI, SoundOn)); rlm@1: rlm@1: poCMI = dynamic_cast(_poXml->get_widget("SoundEcho")); rlm@1: poCMI->set_active(m_poSoundConfig->oGetKey("echo")); rlm@1: vOnSoundEchoToggled(poCMI); rlm@1: poCMI->signal_toggled().connect(SigC::bind( rlm@1: SigC::slot(*this, &Window::vOnSoundEchoToggled), rlm@1: poCMI)); rlm@1: rlm@1: poCMI = dynamic_cast(_poXml->get_widget("SoundLowPass")); rlm@1: poCMI->set_active(m_poSoundConfig->oGetKey("low_pass")); rlm@1: vOnSoundLowPassToggled(poCMI); rlm@1: poCMI->signal_toggled().connect(SigC::bind( rlm@1: SigC::slot(*this, &Window::vOnSoundLowPassToggled), rlm@1: poCMI)); rlm@1: rlm@1: poCMI = dynamic_cast(_poXml->get_widget("SoundReverseStereo")); rlm@1: poCMI->set_active(m_poSoundConfig->oGetKey("reverse_stereo")); rlm@1: vOnSoundReverseToggled(poCMI); rlm@1: poCMI->signal_toggled().connect(SigC::bind( rlm@1: SigC::slot(*this, &Window::vOnSoundReverseToggled), rlm@1: poCMI)); rlm@1: rlm@1: struct rlm@1: { rlm@1: const char * m_csName; rlm@1: const char * m_csKey; rlm@1: const int m_iSoundChannel; rlm@1: } rlm@1: astSoundChannel[] = rlm@1: { rlm@1: { "SoundChannel1", "channel_1", 0 }, rlm@1: { "SoundChannel2", "channel_2", 1 }, rlm@1: { "SoundChannel3", "channel_3", 2 }, rlm@1: { "SoundChannel4", "channel_4", 3 }, rlm@1: { "SoundChannelA", "channel_A", 4 }, rlm@1: { "SoundChannelB", "channel_B", 5 } rlm@1: }; rlm@1: for (guint i = 0; i < G_N_ELEMENTS(astSoundChannel); i++) rlm@1: { rlm@1: poCMI = dynamic_cast(_poXml->get_widget(astSoundChannel[i].m_csName)); rlm@1: poCMI->set_active(m_poSoundConfig->oGetKey(astSoundChannel[i].m_csKey)); rlm@1: vOnSoundChannelToggled(poCMI, astSoundChannel[i].m_iSoundChannel); rlm@1: poCMI->signal_toggled().connect(SigC::bind( rlm@1: SigC::slot(*this, &Window::vOnSoundChannelToggled), rlm@1: poCMI, astSoundChannel[i].m_iSoundChannel)); rlm@1: } rlm@1: rlm@1: struct rlm@1: { rlm@1: const char * m_csName; rlm@1: const ESoundQuality m_eSoundQuality; rlm@1: } rlm@1: astSoundQuality[] = rlm@1: { rlm@1: { "Sound11Khz", Sound11K }, rlm@1: { "Sound22Khz", Sound22K }, rlm@1: { "Sound44Khz", Sound44K } rlm@1: }; rlm@1: ESoundQuality eDefaultSoundQuality = (ESoundQuality)m_poSoundConfig->oGetKey("quality"); rlm@1: for (guint i = 0; i < G_N_ELEMENTS(astSoundQuality); i++) rlm@1: { rlm@1: poCMI = dynamic_cast(_poXml->get_widget(astSoundQuality[i].m_csName)); rlm@1: if (astSoundQuality[i].m_eSoundQuality == eDefaultSoundQuality) rlm@1: { rlm@1: poCMI->set_active(); rlm@1: vOnSoundQualityToggled(poCMI, eDefaultSoundQuality); rlm@1: } rlm@1: poCMI->signal_toggled().connect(SigC::bind( rlm@1: SigC::slot(*this, &Window::vOnSoundQualityToggled), rlm@1: poCMI, astSoundQuality[i].m_eSoundQuality)); rlm@1: } rlm@1: rlm@1: // Volume menu rlm@1: // rlm@1: struct rlm@1: { rlm@1: const char * m_csName; rlm@1: const ESoundVolume m_eSoundVolume; rlm@1: } rlm@1: astSoundVolume[] = rlm@1: { rlm@1: { "Volume25", Sound25 }, rlm@1: { "Volume50", Sound50 }, rlm@1: { "Volume100", Sound100 }, rlm@1: { "Volume200", Sound200 }, rlm@1: { "Volume300", Sound300 }, rlm@1: { "Volume400", Sound400 } rlm@1: }; rlm@1: ESoundVolume eDefaultSoundVolume = (ESoundVolume)m_poSoundConfig->oGetKey("volume"); rlm@1: for (guint i = 0; i < G_N_ELEMENTS(astSoundVolume); i++) rlm@1: { rlm@1: poCMI = dynamic_cast(_poXml->get_widget(astSoundVolume[i].m_csName)); rlm@1: if (astSoundVolume[i].m_eSoundVolume == eDefaultSoundVolume) rlm@1: { rlm@1: poCMI->set_active(); rlm@1: vOnSoundVolumeToggled(poCMI, eDefaultSoundVolume); rlm@1: } rlm@1: poCMI->signal_toggled().connect(SigC::bind( rlm@1: SigC::slot(*this, &Window::vOnSoundVolumeToggled), rlm@1: poCMI, astSoundVolume[i].m_eSoundVolume)); rlm@1: } rlm@1: rlm@1: // Gameboy menu rlm@1: // rlm@1: poCMI = dynamic_cast(_poXml->get_widget("GameboyBorder")); rlm@1: poCMI->set_active(m_poCoreConfig->oGetKey("gb_border")); rlm@1: vOnGBBorderToggled(poCMI); rlm@1: poCMI->signal_toggled().connect(SigC::bind( rlm@1: SigC::slot(*this, &Window::vOnGBBorderToggled), rlm@1: poCMI)); rlm@1: rlm@1: poCMI = dynamic_cast(_poXml->get_widget("GameboyPrinter")); rlm@1: poCMI->set_active(m_poCoreConfig->oGetKey("gb_printer")); rlm@1: vOnGBPrinterToggled(poCMI); rlm@1: poCMI->signal_toggled().connect(SigC::bind( rlm@1: SigC::slot(*this, &Window::vOnGBPrinterToggled), rlm@1: poCMI)); rlm@1: rlm@1: struct rlm@1: { rlm@1: const char * m_csName; rlm@1: const EEmulatorType m_eEmulatorType; rlm@1: } rlm@1: astEmulatorType[] = rlm@1: { rlm@1: { "GameboyAutomatic", EmulatorAuto }, rlm@1: { "GameboyGba", EmulatorGBA }, rlm@1: { "GameboyCgb", EmulatorCGB }, rlm@1: { "GameboySgb", EmulatorSGB }, rlm@1: { "GameboySgb2", EmulatorSGB2 }, rlm@1: { "GameboyGb", EmulatorGB } rlm@1: }; rlm@1: EEmulatorType eDefaultEmulatorType = (EEmulatorType)m_poCoreConfig->oGetKey("emulator_type"); rlm@1: for (guint i = 0; i < G_N_ELEMENTS(astEmulatorType); i++) rlm@1: { rlm@1: poCMI = dynamic_cast(_poXml->get_widget(astEmulatorType[i].m_csName)); rlm@1: if (astEmulatorType[i].m_eEmulatorType == eDefaultEmulatorType) rlm@1: { rlm@1: poCMI->set_active(); rlm@1: vOnEmulatorTypeToggled(poCMI, eDefaultEmulatorType); rlm@1: } rlm@1: poCMI->signal_toggled().connect(SigC::bind( rlm@1: SigC::slot(*this, &Window::vOnEmulatorTypeToggled), rlm@1: poCMI, astEmulatorType[i].m_eEmulatorType)); rlm@1: } rlm@1: rlm@1: // Filter menu rlm@1: // rlm@1: struct rlm@1: { rlm@1: const char * m_csName; rlm@1: const EFilter2x m_eFilter2x; rlm@1: } rlm@1: astFilter2x[] = rlm@1: { rlm@1: { "FilterNone", FilterNone }, rlm@1: { "FilterTVMode", FilterScanlinesTV }, rlm@1: { "Filter2xSaI", Filter2xSaI }, rlm@1: { "FilterSuper2xSaI", FilterSuper2xSaI }, rlm@1: { "FilterSuperEagle", FilterSuperEagle }, rlm@1: { "FilterPixelate", FilterPixelate }, rlm@1: { "FilterMotionBlur", FilterMotionBlur }, rlm@1: { "FilterAdvanceMame2x", FilterAdMame2x }, rlm@1: { "FilterSimple2x", FilterSimple2x }, rlm@1: { "FilterBilinear", FilterBilinear }, rlm@1: { "FilterBilinearPlus", FilterBilinearPlus }, rlm@1: { "FilterScanlines", FilterScanlines }, rlm@1: { "FilterHq2x", FilterHq2x }, rlm@1: { "FilterLq2x", FilterLq2x } rlm@1: }; rlm@1: EFilter2x eDefaultFilter2x = (EFilter2x)m_poDisplayConfig->oGetKey("filter2x"); rlm@1: for (guint i = 0; i < G_N_ELEMENTS(astFilter2x); i++) rlm@1: { rlm@1: poCMI = dynamic_cast(_poXml->get_widget(astFilter2x[i].m_csName)); rlm@1: if (astFilter2x[i].m_eFilter2x == eDefaultFilter2x) rlm@1: { rlm@1: poCMI->set_active(); rlm@1: vOnFilter2xToggled(poCMI, eDefaultFilter2x); rlm@1: } rlm@1: poCMI->signal_toggled().connect(SigC::bind( rlm@1: SigC::slot(*this, &Window::vOnFilter2xToggled), rlm@1: poCMI, astFilter2x[i].m_eFilter2x)); rlm@1: } rlm@1: rlm@1: poCMI = dynamic_cast(_poXml->get_widget("FilterDisableMmx")); rlm@1: #ifdef MMX rlm@1: poCMI->set_active(m_poDisplayConfig->oGetKey("filter_disable_mmx")); rlm@1: vOnDisableMMXToggled(poCMI); rlm@1: poCMI->signal_toggled().connect(SigC::bind( rlm@1: SigC::slot(*this, &Window::vOnDisableMMXToggled), rlm@1: poCMI)); rlm@1: #else // ! MMX rlm@1: poCMI->set_active(); rlm@1: poCMI->set_sensitive(false); rlm@1: #endif // ! MMX rlm@1: rlm@1: // Interframe blending menu rlm@1: // rlm@1: struct rlm@1: { rlm@1: const char * m_csName; rlm@1: const EFilterIB m_eFilterIB; rlm@1: } rlm@1: astFilterIB[] = rlm@1: { rlm@1: { "IFBNone", FilterIBNone }, rlm@1: { "IFBSmart", FilterIBSmart }, rlm@1: { "IFBMotionBlur", FilterIBMotionBlur } rlm@1: }; rlm@1: EFilterIB eDefaultFilterIB = (EFilterIB)m_poDisplayConfig->oGetKey("filterIB"); rlm@1: for (guint i = 0; i < G_N_ELEMENTS(astFilterIB); i++) rlm@1: { rlm@1: poCMI = dynamic_cast(_poXml->get_widget(astFilterIB[i].m_csName)); rlm@1: if (astFilterIB[i].m_eFilterIB == eDefaultFilterIB) rlm@1: { rlm@1: poCMI->set_active(); rlm@1: vOnFilterIBToggled(poCMI, eDefaultFilterIB); rlm@1: } rlm@1: poCMI->signal_toggled().connect(SigC::bind( rlm@1: SigC::slot(*this, &Window::vOnFilterIBToggled), rlm@1: poCMI, astFilterIB[i].m_eFilterIB)); rlm@1: } rlm@1: rlm@1: // Joypad menu rlm@1: // rlm@1: poMI = dynamic_cast(_poXml->get_widget("JoypadConfigure1")); rlm@1: poMI->signal_activate().connect(SigC::bind( rlm@1: SigC::slot(*this, &Window::vOnJoypadConfigure), 1)); rlm@1: rlm@1: poMI = dynamic_cast(_poXml->get_widget("JoypadConfigure2")); rlm@1: poMI->signal_activate().connect(SigC::bind( rlm@1: SigC::slot(*this, &Window::vOnJoypadConfigure), 2)); rlm@1: rlm@1: poMI = dynamic_cast(_poXml->get_widget("JoypadConfigure3")); rlm@1: poMI->signal_activate().connect(SigC::bind( rlm@1: SigC::slot(*this, &Window::vOnJoypadConfigure), 3)); rlm@1: rlm@1: poMI = dynamic_cast(_poXml->get_widget("JoypadConfigure4")); rlm@1: poMI->signal_activate().connect(SigC::bind( rlm@1: SigC::slot(*this, &Window::vOnJoypadConfigure), 4)); rlm@1: rlm@1: int iDefaultJoypad = m_poInputConfig->oGetKey("active_joypad"); rlm@1: for (int i = m_iJoypadMin; i <= m_iJoypadMax; i++) rlm@1: { rlm@1: char csName[20]; rlm@1: snprintf(csName, sizeof(csName), "Joypad%d", i); rlm@1: rlm@1: poCMI = dynamic_cast(_poXml->get_widget(csName)); rlm@1: if (i == iDefaultJoypad) rlm@1: { rlm@1: poCMI->set_active(); rlm@1: vOnJoypadToggled(poCMI, iDefaultJoypad); rlm@1: } rlm@1: poCMI->signal_toggled().connect(SigC::bind( rlm@1: SigC::slot(*this, &Window::vOnJoypadToggled), rlm@1: poCMI, i)); rlm@1: } rlm@1: rlm@1: // Autofire menu rlm@1: // rlm@1: struct rlm@1: { rlm@1: const char * m_csName; rlm@1: const char * m_csKey; rlm@1: const EKeyFlag m_eKeyFlag; rlm@1: } rlm@1: astAutofire[] = rlm@1: { rlm@1: { "AutofireA", "autofire_A", KeyFlagA }, rlm@1: { "AutofireB", "autofire_B", KeyFlagB }, rlm@1: { "AutofireL", "autofire_L", KeyFlagL }, rlm@1: { "AutofireR", "autofire_R", KeyFlagR } rlm@1: }; rlm@1: for (guint i = 0; i < G_N_ELEMENTS(astAutofire); i++) rlm@1: { rlm@1: poCMI = dynamic_cast(_poXml->get_widget(astAutofire[i].m_csName)); rlm@1: poCMI->set_active(m_poInputConfig->oGetKey(astAutofire[i].m_csKey)); rlm@1: vOnAutofireToggled(poCMI, astAutofire[i].m_eKeyFlag); rlm@1: poCMI->signal_toggled().connect(SigC::bind( rlm@1: SigC::slot(*this, &Window::vOnAutofireToggled), rlm@1: poCMI, astAutofire[i].m_eKeyFlag)); rlm@1: } rlm@1: rlm@1: // GDB menu rlm@1: // rlm@1: poMI = dynamic_cast(_poXml->get_widget("GdbWait")); rlm@1: poMI->signal_activate().connect(SigC::slot(*this, &Window::vOnGDBWait)); rlm@1: rlm@1: poMI = dynamic_cast(_poXml->get_widget("GdbLoadAndWait")); rlm@1: poMI->signal_activate().connect(SigC::slot(*this, &Window::vOnGDBLoadAndWait)); rlm@1: rlm@1: poMI = dynamic_cast(_poXml->get_widget("GdbBreak")); rlm@1: poMI->signal_activate().connect(SigC::slot(*this, &Window::vOnGDBBreak)); rlm@1: rlm@1: poMI = dynamic_cast(_poXml->get_widget("GdbDisconnect")); rlm@1: poMI->signal_activate().connect(SigC::slot(*this, &Window::vOnGDBDisconnect)); rlm@1: rlm@1: // Help menu rlm@1: // rlm@1: poMI = dynamic_cast(_poXml->get_widget("HelpAbout")); rlm@1: poMI->signal_activate().connect(SigC::slot(*this, &Window::vOnHelpAbout)); rlm@1: rlm@1: // Init widgets sensitivity rlm@1: for (std::list::iterator it = m_listSensitiveWhenPlaying.begin(); rlm@1: it != m_listSensitiveWhenPlaying.end(); rlm@1: it++) rlm@1: { rlm@1: (*it)->set_sensitive(false); rlm@1: } rlm@1: rlm@1: if (m_poInstance == NULL) rlm@1: { rlm@1: m_poInstance = this; rlm@1: } rlm@1: else rlm@1: { rlm@1: abort(); rlm@1: } rlm@1: } rlm@1: rlm@1: Window::~Window() rlm@1: { rlm@1: vOnFileClose(); rlm@1: vSaveHistoryToConfig(); rlm@1: vSaveJoypadsToConfig(); rlm@1: vSaveConfig(m_sConfigFile); rlm@1: rlm@1: if (m_poFileOpenDialog != NULL) rlm@1: { rlm@1: delete m_poFileOpenDialog; rlm@1: } rlm@1: rlm@1: if (m_poKeymap != NULL) rlm@1: { rlm@1: delete m_poKeymap; rlm@1: } rlm@1: rlm@1: m_poInstance = NULL; rlm@1: } rlm@1: rlm@1: void Window::vInitSystem() rlm@1: { rlm@1: #if G_BYTE_ORDER == G_LITTLE_ENDIAN rlm@1: systemRedShift = 3; rlm@1: systemGreenShift = 11; rlm@1: systemBlueShift = 19; rlm@1: RGB_LOW_BITS_MASK = 0x00010101; rlm@1: #else rlm@1: systemRedShift = 27; rlm@1: systemGreenShift = 19; rlm@1: systemBlueShift = 11; rlm@1: RGB_LOW_BITS_MASK = 0x01010100; rlm@1: #endif rlm@1: rlm@1: systemColorDepth = 32; rlm@1: systemDebug = 0; rlm@1: systemVerbose = 0; rlm@1: systemSaveUpdateCounter = SYSTEM_SAVE_NOT_UPDATED; rlm@1: systemFrameSkip = 0; rlm@1: systemSoundOn = false; rlm@1: soundOffFlag = true; rlm@1: rlm@1: systemRenderedFrames = 0; rlm@1: systemFPS = 0; rlm@1: rlm@1: emulating = 0; rlm@1: debugger = false; rlm@1: rlm@1: for (int i = 0; i < 0x10000; i++) rlm@1: { rlm@1: #if G_BYTE_ORDER == G_LITTLE_ENDIAN rlm@1: systemColorMap32[i] = (((i & 0x1f) << systemRedShift) rlm@1: | (((i & 0x3e0) >> 5) << systemGreenShift) rlm@1: | (((i & 0x7c00) >> 10) << systemBlueShift)); rlm@1: #else rlm@1: systemColorMap32[i] = (((i & 0x1f) << systemRedShift) rlm@1: | (((i & 0x3e0) >> 5) << systemGreenShift) rlm@1: | (((i & 0x7c00) >> 10) << systemBlueShift)); rlm@1: #endif rlm@1: } rlm@1: rlm@1: gbFrameSkip = 0; rlm@1: rlm@1: for (int i = 0; i < 24; ) rlm@1: { rlm@1: systemGbPalette[i++] = (0x1f) | (0x1f << 5) | (0x1f << 10); rlm@1: systemGbPalette[i++] = (0x15) | (0x15 << 5) | (0x15 << 10); rlm@1: systemGbPalette[i++] = (0x0c) | (0x0c << 5) | (0x0c << 10); rlm@1: systemGbPalette[i++] = 0; rlm@1: } rlm@1: rlm@1: Init_2xSaI(32); rlm@1: } rlm@1: rlm@1: void Window::vInitSDL() rlm@1: { rlm@1: static bool bDone = false; rlm@1: rlm@1: if (bDone) rlm@1: return; rlm@1: rlm@1: int iFlags = (SDL_INIT_AUDIO | SDL_INIT_NOPARACHUTE); rlm@1: rlm@1: if (SDL_Init(iFlags) < 0) rlm@1: { rlm@1: fprintf(stderr, "Failed to init SDL: %s", SDL_GetError()); rlm@1: abort(); rlm@1: } rlm@1: rlm@1: bDone = true; rlm@1: } rlm@1: rlm@1: void Window::vInitConfig() rlm@1: { rlm@1: m_oConfig.vClear(); rlm@1: rlm@1: // History section rlm@1: // rlm@1: m_poHistoryConfig = m_oConfig.poAddSection("History"); rlm@1: m_poHistoryConfig->vSetKey("freeze", false ); rlm@1: m_poHistoryConfig->vSetKey("0", "" ); rlm@1: m_poHistoryConfig->vSetKey("1", "" ); rlm@1: m_poHistoryConfig->vSetKey("2", "" ); rlm@1: m_poHistoryConfig->vSetKey("3", "" ); rlm@1: m_poHistoryConfig->vSetKey("4", "" ); rlm@1: m_poHistoryConfig->vSetKey("5", "" ); rlm@1: m_poHistoryConfig->vSetKey("6", "" ); rlm@1: m_poHistoryConfig->vSetKey("7", "" ); rlm@1: m_poHistoryConfig->vSetKey("8", "" ); rlm@1: m_poHistoryConfig->vSetKey("9", "" ); rlm@1: rlm@1: // Directories section rlm@1: // rlm@1: m_poDirConfig = m_oConfig.poAddSection("Directories"); rlm@1: m_poDirConfig->vSetKey("gb_roms", "" ); rlm@1: m_poDirConfig->vSetKey("gba_roms", "" ); rlm@1: m_poDirConfig->vSetKey("batteries", "" ); rlm@1: m_poDirConfig->vSetKey("saves", "" ); rlm@1: m_poDirConfig->vSetKey("captures", "" ); rlm@1: rlm@1: // Core section rlm@1: // rlm@1: m_poCoreConfig = m_oConfig.poAddSection("Core"); rlm@1: m_poCoreConfig->vSetKey("load_game_auto", false ); rlm@1: m_poCoreConfig->vSetKey("frameskip", "auto" ); rlm@1: m_poCoreConfig->vSetKey("throttle", 0 ); rlm@1: m_poCoreConfig->vSetKey("layer_bg0", true ); rlm@1: m_poCoreConfig->vSetKey("layer_bg1", true ); rlm@1: m_poCoreConfig->vSetKey("layer_bg2", true ); rlm@1: m_poCoreConfig->vSetKey("layer_bg3", true ); rlm@1: m_poCoreConfig->vSetKey("layer_obj", true ); rlm@1: m_poCoreConfig->vSetKey("layer_win0", true ); rlm@1: m_poCoreConfig->vSetKey("layer_win1", true ); rlm@1: m_poCoreConfig->vSetKey("layer_objwin", true ); rlm@1: m_poCoreConfig->vSetKey("use_bios_file", false ); rlm@1: m_poCoreConfig->vSetKey("bios_file", "" ); rlm@1: m_poCoreConfig->vSetKey("save_type", SaveAuto ); rlm@1: m_poCoreConfig->vSetKey("flash_size", 64 ); rlm@1: m_poCoreConfig->vSetKey("gb_border", true ); rlm@1: m_poCoreConfig->vSetKey("gb_printer", false ); rlm@1: m_poCoreConfig->vSetKey("emulator_type", EmulatorAuto ); rlm@1: m_poCoreConfig->vSetKey("screenshot_format", "png" ); rlm@1: rlm@1: // Display section rlm@1: // rlm@1: m_poDisplayConfig = m_oConfig.poAddSection("Display"); rlm@1: m_poDisplayConfig->vSetKey("scale", 1 ); rlm@1: m_poDisplayConfig->vSetKey("show_speed", ShowPercentage ); rlm@1: m_poDisplayConfig->vSetKey("pause_when_inactive", true ); rlm@1: m_poDisplayConfig->vSetKey("filter2x", FilterNone ); rlm@1: m_poDisplayConfig->vSetKey("filterIB", FilterIBNone ); rlm@1: #ifdef MMX rlm@1: m_poDisplayConfig->vSetKey("filter_disable_mmx", false ); rlm@1: #endif // MMX rlm@1: rlm@1: // Sound section rlm@1: // rlm@1: m_poSoundConfig = m_oConfig.poAddSection("Sound"); rlm@1: m_poSoundConfig->vSetKey("status", "on" ); rlm@1: m_poSoundConfig->vSetKey("echo", false ); rlm@1: m_poSoundConfig->vSetKey("low_pass", false ); rlm@1: m_poSoundConfig->vSetKey("reverse_stereo", false ); rlm@1: m_poSoundConfig->vSetKey("channel_1", true ); rlm@1: m_poSoundConfig->vSetKey("channel_2", true ); rlm@1: m_poSoundConfig->vSetKey("channel_3", true ); rlm@1: m_poSoundConfig->vSetKey("channel_4", true ); rlm@1: m_poSoundConfig->vSetKey("channel_A", true ); rlm@1: m_poSoundConfig->vSetKey("channel_B", true ); rlm@1: m_poSoundConfig->vSetKey("quality", Sound22K ); rlm@1: m_poSoundConfig->vSetKey("volume", Sound100 ); rlm@1: rlm@1: // Input section rlm@1: // rlm@1: JoypadConfig oJoypadConfig; rlm@1: oJoypadConfig.vSetDefault(); rlm@1: m_poInputConfig = m_oConfig.poAddSection("Input"); rlm@1: m_poInputConfig->vSetKey("active_joypad", m_iJoypadMin ); rlm@1: for (int i = m_iJoypadMin; i <= m_iJoypadMax; i++) rlm@1: { rlm@1: char csPrefix[20]; rlm@1: snprintf(csPrefix, sizeof(csPrefix), "joypad%d_", i); rlm@1: std::string sPrefix(csPrefix); rlm@1: m_poInputConfig->vSetKey(sPrefix + "up", oJoypadConfig.m_uiUp ); rlm@1: m_poInputConfig->vSetKey(sPrefix + "down", oJoypadConfig.m_uiDown ); rlm@1: m_poInputConfig->vSetKey(sPrefix + "left", oJoypadConfig.m_uiLeft ); rlm@1: m_poInputConfig->vSetKey(sPrefix + "right", oJoypadConfig.m_uiRight ); rlm@1: m_poInputConfig->vSetKey(sPrefix + "A", oJoypadConfig.m_uiA ); rlm@1: m_poInputConfig->vSetKey(sPrefix + "B", oJoypadConfig.m_uiB ); rlm@1: m_poInputConfig->vSetKey(sPrefix + "L", oJoypadConfig.m_uiL ); rlm@1: m_poInputConfig->vSetKey(sPrefix + "R", oJoypadConfig.m_uiR ); rlm@1: m_poInputConfig->vSetKey(sPrefix + "select", oJoypadConfig.m_uiSelect ); rlm@1: m_poInputConfig->vSetKey(sPrefix + "start", oJoypadConfig.m_uiStart ); rlm@1: m_poInputConfig->vSetKey(sPrefix + "speed", oJoypadConfig.m_uiSpeed ); rlm@1: m_poInputConfig->vSetKey(sPrefix + "capture", oJoypadConfig.m_uiCapture ); rlm@1: } rlm@1: m_poInputConfig->vSetKey("autofire_A", false ); rlm@1: m_poInputConfig->vSetKey("autofire_B", false ); rlm@1: m_poInputConfig->vSetKey("autofire_L", false ); rlm@1: m_poInputConfig->vSetKey("autofire_R", false ); rlm@1: } rlm@1: rlm@1: void Window::vCheckConfig() rlm@1: { rlm@1: int iValue; rlm@1: int iAdjusted; rlm@1: std::string sValue; rlm@1: rlm@1: // Directories section rlm@1: // rlm@1: sValue = m_poDirConfig->sGetKey("gb_roms"); rlm@1: if (sValue != "" && ! Glib::file_test(sValue, Glib::FILE_TEST_IS_DIR)) rlm@1: { rlm@1: m_poDirConfig->vSetKey("gb_roms", ""); rlm@1: } rlm@1: sValue = m_poDirConfig->sGetKey("gba_roms"); rlm@1: if (sValue != "" && ! Glib::file_test(sValue, Glib::FILE_TEST_IS_DIR)) rlm@1: { rlm@1: m_poDirConfig->vSetKey("gba_roms", ""); rlm@1: } rlm@1: sValue = m_poDirConfig->sGetKey("batteries"); rlm@1: if (sValue != "" && ! Glib::file_test(sValue, Glib::FILE_TEST_IS_DIR)) rlm@1: { rlm@1: m_poDirConfig->vSetKey("batteries", ""); rlm@1: } rlm@1: sValue = m_poDirConfig->sGetKey("saves"); rlm@1: if (sValue != "" && ! Glib::file_test(sValue, Glib::FILE_TEST_IS_DIR)) rlm@1: { rlm@1: m_poDirConfig->vSetKey("saves", ""); rlm@1: } rlm@1: sValue = m_poDirConfig->sGetKey("captures"); rlm@1: if (sValue != "" && ! Glib::file_test(sValue, Glib::FILE_TEST_IS_DIR)) rlm@1: { rlm@1: m_poDirConfig->vSetKey("captures", ""); rlm@1: } rlm@1: rlm@1: // Core section rlm@1: // rlm@1: if (m_poCoreConfig->sGetKey("frameskip") != "auto") rlm@1: { rlm@1: iValue = m_poCoreConfig->oGetKey("frameskip"); rlm@1: iAdjusted = CLAMP(iValue, m_iFrameskipMin, m_iFrameskipMax); rlm@1: if (iValue != iAdjusted) rlm@1: { rlm@1: m_poCoreConfig->vSetKey("frameskip", iAdjusted); rlm@1: } rlm@1: } rlm@1: rlm@1: iValue = m_poCoreConfig->oGetKey("throttle"); rlm@1: if (iValue != 0) rlm@1: { rlm@1: iAdjusted = CLAMP(iValue, m_iThrottleMin, m_iThrottleMax); rlm@1: if (iValue != iAdjusted) rlm@1: { rlm@1: m_poCoreConfig->vSetKey("throttle", iAdjusted); rlm@1: } rlm@1: } rlm@1: rlm@1: sValue = m_poCoreConfig->sGetKey("bios_file"); rlm@1: if (sValue != "" && ! Glib::file_test(sValue, Glib::FILE_TEST_IS_REGULAR)) rlm@1: { rlm@1: m_poCoreConfig->vSetKey("bios_file", ""); rlm@1: } rlm@1: if (m_poCoreConfig->sGetKey("bios_file") == "") rlm@1: { rlm@1: m_poCoreConfig->vSetKey("use_bios_file", false); rlm@1: } rlm@1: rlm@1: iValue = m_poCoreConfig->oGetKey("save_type"); rlm@1: if (iValue != 0) rlm@1: { rlm@1: iAdjusted = CLAMP(iValue, m_iSaveTypeMin, m_iSaveTypeMax); rlm@1: if (iValue != iAdjusted) rlm@1: { rlm@1: m_poCoreConfig->vSetKey("save_type", iAdjusted); rlm@1: } rlm@1: } rlm@1: rlm@1: iValue = m_poCoreConfig->oGetKey("flash_size"); rlm@1: if (iValue != 64 && iValue != 128) rlm@1: { rlm@1: m_poCoreConfig->vSetKey("flash_size", 64); rlm@1: } rlm@1: rlm@1: iValue = m_poCoreConfig->oGetKey("emulator_type"); rlm@1: iAdjusted = CLAMP(iValue, m_iEmulatorTypeMin, m_iEmulatorTypeMax); rlm@1: if (iValue != iAdjusted) rlm@1: { rlm@1: m_poCoreConfig->vSetKey("emulator_type", iAdjusted); rlm@1: } rlm@1: rlm@1: sValue = m_poCoreConfig->sGetKey("screenshot_format"); rlm@1: if (sValue != "png" && sValue != "bmp") rlm@1: { rlm@1: sValue = "png"; rlm@1: } rlm@1: rlm@1: // Display section rlm@1: // rlm@1: iValue = m_poDisplayConfig->oGetKey("scale"); rlm@1: iAdjusted = CLAMP(iValue, m_iScaleMin, m_iScaleMax); rlm@1: if (iValue != iAdjusted) rlm@1: { rlm@1: m_poDisplayConfig->vSetKey("scale", iAdjusted); rlm@1: } rlm@1: rlm@1: iValue = m_poDisplayConfig->oGetKey("show_speed"); rlm@1: iAdjusted = CLAMP(iValue, m_iShowSpeedMin, m_iShowSpeedMax); rlm@1: if (iValue != iAdjusted) rlm@1: { rlm@1: m_poDisplayConfig->vSetKey("show_speed", iAdjusted); rlm@1: } rlm@1: rlm@1: iValue = m_poDisplayConfig->oGetKey("filter2x"); rlm@1: iAdjusted = CLAMP(iValue, m_iFilter2xMin, m_iFilter2xMax); rlm@1: if (iValue != iAdjusted) rlm@1: { rlm@1: m_poDisplayConfig->vSetKey("filter2x", iAdjusted); rlm@1: } rlm@1: rlm@1: iValue = m_poDisplayConfig->oGetKey("filterIB"); rlm@1: iAdjusted = CLAMP(iValue, m_iFilterIBMin, m_iFilterIBMax); rlm@1: if (iValue != iAdjusted) rlm@1: { rlm@1: m_poDisplayConfig->vSetKey("filterIB", iAdjusted); rlm@1: } rlm@1: rlm@1: // Sound section rlm@1: // rlm@1: sValue = m_poSoundConfig->sGetKey("status"); rlm@1: if (sValue != "off" && sValue != "on" && sValue != "mute") rlm@1: { rlm@1: m_poSoundConfig->vSetKey("status", "on"); rlm@1: } rlm@1: rlm@1: iValue = m_poSoundConfig->oGetKey("quality"); rlm@1: iAdjusted = CLAMP(iValue, m_iSoundQualityMin, m_iSoundQualityMax); rlm@1: if (iValue != iAdjusted) rlm@1: { rlm@1: m_poSoundConfig->vSetKey("quality", iAdjusted); rlm@1: } rlm@1: rlm@1: iValue = m_poSoundConfig->oGetKey("volume"); rlm@1: iAdjusted = CLAMP(iValue, m_iSoundVolumeMin, m_iSoundVolumeMax); rlm@1: if (iValue != iAdjusted) rlm@1: { rlm@1: m_poSoundConfig->vSetKey("volume", iAdjusted); rlm@1: } rlm@1: rlm@1: // Input section rlm@1: // rlm@1: iValue = m_poInputConfig->oGetKey("active_joypad"); rlm@1: iAdjusted = CLAMP(iValue, m_iJoypadMin, m_iJoypadMax); rlm@1: if (iValue != iAdjusted) rlm@1: { rlm@1: m_poInputConfig->vSetKey("active_joypad", iAdjusted); rlm@1: } rlm@1: } rlm@1: rlm@1: void Window::vLoadConfig(const std::string & _rsFile) rlm@1: { rlm@1: try rlm@1: { rlm@1: m_oConfig.vLoad(_rsFile, false, false); rlm@1: } rlm@1: catch (const Glib::Error & e) rlm@1: { rlm@1: vPopupError(e.what().c_str()); rlm@1: } rlm@1: } rlm@1: rlm@1: void Window::vSaveConfig(const std::string & _rsFile) rlm@1: { rlm@1: try rlm@1: { rlm@1: m_oConfig.vSave(_rsFile); rlm@1: } rlm@1: catch (const Glib::Error & e) rlm@1: { rlm@1: vPopupError(e.what().c_str()); rlm@1: } rlm@1: } rlm@1: rlm@1: void Window::vLoadHistoryFromConfig() rlm@1: { rlm@1: char csKey[] = "0"; rlm@1: for (int i = 0; i < 10; i++, csKey[0]++) rlm@1: { rlm@1: std::string sFile = m_poHistoryConfig->sGetKey(csKey); rlm@1: if (sFile == "") rlm@1: { rlm@1: break; rlm@1: } rlm@1: m_listHistory.push_back(sFile); rlm@1: } rlm@1: } rlm@1: rlm@1: void Window::vSaveHistoryToConfig() rlm@1: { rlm@1: char csKey[] = "0"; rlm@1: for (std::list::const_iterator it = m_listHistory.begin(); rlm@1: it != m_listHistory.end(); rlm@1: it++, csKey[0]++) rlm@1: { rlm@1: m_poHistoryConfig->vSetKey(csKey, *it); rlm@1: } rlm@1: } rlm@1: rlm@1: void Window::vHistoryAdd(const std::string & _rsFile) rlm@1: { rlm@1: if (m_poHistoryConfig->oGetKey("freeze")) rlm@1: { rlm@1: return; rlm@1: } rlm@1: rlm@1: m_listHistory.remove(_rsFile); rlm@1: m_listHistory.push_front(_rsFile); rlm@1: if (m_listHistory.size() > 10) rlm@1: { rlm@1: m_listHistory.pop_back(); rlm@1: } rlm@1: rlm@1: vUpdateHistoryMenu(); rlm@1: } rlm@1: rlm@1: void Window::vClearHistoryMenu() rlm@1: { rlm@1: Gtk::Menu_Helpers::MenuList::iterator it = m_poRecentMenu->items().begin(); rlm@1: for (int i = 0; i < 3; i++, it++) rlm@1: ; rlm@1: rlm@1: m_poRecentMenu->items().erase(it, m_poRecentMenu->items().end()); rlm@1: } rlm@1: rlm@1: void Window::vUpdateHistoryMenu() rlm@1: { rlm@1: vClearHistoryMenu(); rlm@1: rlm@1: guint uiAccelKey = GDK_F1; rlm@1: for (std::list::const_iterator it = m_listHistory.begin(); rlm@1: it != m_listHistory.end(); rlm@1: it++, uiAccelKey++) rlm@1: { rlm@1: Gtk::Image * poImage = Gtk::manage(new Gtk::Image(Gtk::Stock::OPEN, Gtk::ICON_SIZE_MENU)); rlm@1: Glib::ustring sLabel = Glib::path_get_basename(*it); rlm@1: VBA::ImageMenuItem * poIMI = Gtk::manage(new VBA::ImageMenuItem(*poImage, sLabel)); rlm@1: rlm@1: m_oTooltips.set_tip(*poIMI, *it); rlm@1: rlm@1: poIMI->signal_activate().connect(SigC::bind( rlm@1: SigC::slot(*this, &Window::vOnRecentFile), rlm@1: *it)); rlm@1: rlm@1: poIMI->set_accel_key(Gtk::AccelKey(uiAccelKey, Gdk::CONTROL_MASK)); rlm@1: poIMI->accelerate(*this); rlm@1: rlm@1: poIMI->show(); rlm@1: m_poRecentMenu->items().push_back(*poIMI); rlm@1: } rlm@1: } rlm@1: rlm@1: void Window::vLoadJoypadsFromConfig() rlm@1: { rlm@1: m_oJoypads.clear(); rlm@1: rlm@1: for (int i = m_iJoypadMin; i <= m_iJoypadMax; i++) rlm@1: { rlm@1: char csPrefix[20]; rlm@1: snprintf(csPrefix, sizeof(csPrefix), "joypad%d_", i); rlm@1: std::string sPrefix(csPrefix); rlm@1: rlm@1: JoypadConfig oJoypadConfig; rlm@1: oJoypadConfig.m_uiUp = m_poInputConfig->oGetKey(sPrefix + "up"); rlm@1: oJoypadConfig.m_uiDown = m_poInputConfig->oGetKey(sPrefix + "down"); rlm@1: oJoypadConfig.m_uiLeft = m_poInputConfig->oGetKey(sPrefix + "left"); rlm@1: oJoypadConfig.m_uiRight = m_poInputConfig->oGetKey(sPrefix + "right"); rlm@1: oJoypadConfig.m_uiA = m_poInputConfig->oGetKey(sPrefix + "A"); rlm@1: oJoypadConfig.m_uiB = m_poInputConfig->oGetKey(sPrefix + "B"); rlm@1: oJoypadConfig.m_uiL = m_poInputConfig->oGetKey(sPrefix + "L"); rlm@1: oJoypadConfig.m_uiR = m_poInputConfig->oGetKey(sPrefix + "R"); rlm@1: oJoypadConfig.m_uiSelect = m_poInputConfig->oGetKey(sPrefix + "select"); rlm@1: oJoypadConfig.m_uiStart = m_poInputConfig->oGetKey(sPrefix + "start"); rlm@1: oJoypadConfig.m_uiSpeed = m_poInputConfig->oGetKey(sPrefix + "speed"); rlm@1: oJoypadConfig.m_uiCapture = m_poInputConfig->oGetKey(sPrefix + "capture"); rlm@1: rlm@1: m_oJoypads.push_back(oJoypadConfig); rlm@1: } rlm@1: } rlm@1: rlm@1: void Window::vSaveJoypadsToConfig() rlm@1: { rlm@1: for (int i = m_iJoypadMin; i <= m_iJoypadMax; i++) rlm@1: { rlm@1: char csPrefix[20]; rlm@1: snprintf(csPrefix, sizeof(csPrefix), "joypad%d_", i); rlm@1: std::string sPrefix(csPrefix); rlm@1: rlm@1: m_poInputConfig->vSetKey(sPrefix + "up", m_oJoypads[i - 1].m_uiUp ); rlm@1: m_poInputConfig->vSetKey(sPrefix + "down", m_oJoypads[i - 1].m_uiDown ); rlm@1: m_poInputConfig->vSetKey(sPrefix + "left", m_oJoypads[i - 1].m_uiLeft ); rlm@1: m_poInputConfig->vSetKey(sPrefix + "right", m_oJoypads[i - 1].m_uiRight ); rlm@1: m_poInputConfig->vSetKey(sPrefix + "A", m_oJoypads[i - 1].m_uiA ); rlm@1: m_poInputConfig->vSetKey(sPrefix + "B", m_oJoypads[i - 1].m_uiB ); rlm@1: m_poInputConfig->vSetKey(sPrefix + "L", m_oJoypads[i - 1].m_uiL ); rlm@1: m_poInputConfig->vSetKey(sPrefix + "R", m_oJoypads[i - 1].m_uiR ); rlm@1: m_poInputConfig->vSetKey(sPrefix + "select", m_oJoypads[i - 1].m_uiSelect ); rlm@1: m_poInputConfig->vSetKey(sPrefix + "start", m_oJoypads[i - 1].m_uiStart ); rlm@1: m_poInputConfig->vSetKey(sPrefix + "speed", m_oJoypads[i - 1].m_uiSpeed ); rlm@1: m_poInputConfig->vSetKey(sPrefix + "capture", m_oJoypads[i - 1].m_uiCapture ); rlm@1: } rlm@1: } rlm@1: rlm@1: void Window::vUpdateScreen() rlm@1: { rlm@1: if (m_eCartridge == CartridgeGB) rlm@1: { rlm@1: if (gbBorderOn) rlm@1: { rlm@1: m_iScreenWidth = m_iSGBScreenWidth; rlm@1: m_iScreenHeight = m_iSGBScreenHeight; rlm@1: gbBorderLineSkip = m_iSGBScreenWidth; rlm@1: gbBorderColumnSkip = (m_iSGBScreenWidth - m_iGBScreenWidth) / 2; rlm@1: gbBorderRowSkip = (m_iSGBScreenHeight - m_iGBScreenHeight) / 2; rlm@1: } rlm@1: else rlm@1: { rlm@1: m_iScreenWidth = m_iGBScreenWidth; rlm@1: m_iScreenHeight = m_iGBScreenHeight; rlm@1: gbBorderLineSkip = m_iGBScreenWidth; rlm@1: gbBorderColumnSkip = 0; rlm@1: gbBorderRowSkip = 0; rlm@1: } rlm@1: } rlm@1: else if (m_eCartridge == CartridgeGBA) rlm@1: { rlm@1: m_iScreenWidth = m_iGBAScreenWidth; rlm@1: m_iScreenHeight = m_iGBAScreenHeight; rlm@1: } rlm@1: rlm@1: g_return_if_fail(m_iScreenWidth >= 1 && m_iScreenHeight >= 1); rlm@1: rlm@1: m_poScreenArea->vSetSize(m_iScreenWidth, m_iScreenHeight); rlm@1: m_poScreenArea->vSetScale(m_poDisplayConfig->oGetKey("scale")); rlm@1: rlm@1: resize(1, 1); rlm@1: rlm@1: if (emulating) rlm@1: { rlm@1: vDrawScreen(); rlm@1: } rlm@1: else rlm@1: { rlm@1: vDrawDefaultScreen(); rlm@1: } rlm@1: } rlm@1: rlm@1: bool Window::bLoadROM(const std::string & _rsFile) rlm@1: { rlm@1: vOnFileClose(); rlm@1: rlm@1: m_sRomFile = _rsFile; rlm@1: const char * csFile = _rsFile.c_str(); rlm@1: rlm@1: IMAGE_TYPE eType = utilFindType(csFile); rlm@1: if (eType == IMAGE_UNKNOWN) rlm@1: { rlm@1: vPopupError(_("Unknown file type %s"), csFile); rlm@1: return false; rlm@1: } rlm@1: rlm@1: bool bLoaded = false; rlm@1: if (eType == IMAGE_GB) rlm@1: { rlm@1: bLoaded = gbLoadRom(csFile); rlm@1: if (bLoaded) rlm@1: { rlm@1: m_eCartridge = CartridgeGB; rlm@1: m_stEmulator = GBSystem; rlm@1: } rlm@1: } rlm@1: else if (eType == IMAGE_GBA) rlm@1: { rlm@1: int iSize = CPULoadRom(csFile); rlm@1: bLoaded = (iSize > 0); rlm@1: if (bLoaded) rlm@1: { rlm@1: m_eCartridge = CartridgeGBA; rlm@1: m_stEmulator = GBASystem; rlm@1: rlm@1: useBios = m_poCoreConfig->oGetKey("use_bios_file"); rlm@1: //CPUInit(m_poCoreConfig->sGetKey("bios_file").c_str(), useBios); rlm@1: CPUInit(); rlm@1: CPUReset(); rlm@1: rlm@1: // If the bios file was rejected by CPUInit rlm@1: if (m_poCoreConfig->oGetKey("use_bios_file") && ! useBios) rlm@1: { rlm@1: m_poUseBiosItem->set_active(false); rlm@1: m_poUseBiosItem->set_sensitive(false); rlm@1: m_poCoreConfig->vSetKey("bios_file", ""); rlm@1: } rlm@1: } rlm@1: } rlm@1: rlm@1: if (! bLoaded) rlm@1: { rlm@1: return false; rlm@1: } rlm@1: rlm@1: vLoadBattery(); rlm@1: vUpdateScreen(); rlm@1: rlm@1: debugger = false; // May cause conflicts rlm@1: emulating = 1; rlm@1: m_bWasEmulating = false; rlm@1: m_uiThrottleDelay = 0; rlm@1: rlm@1: if (m_eCartridge == CartridgeGBA) rlm@1: { rlm@1: soundSetQuality(m_eSoundQuality); rlm@1: } rlm@1: else rlm@1: { rlm@1: gbSoundSetQuality(m_eSoundQuality); rlm@1: } rlm@1: rlm@1: vUpdateGameSlots(); rlm@1: vHistoryAdd(_rsFile); rlm@1: rlm@1: for (std::list::iterator it = m_listSensitiveWhenPlaying.begin(); rlm@1: it != m_listSensitiveWhenPlaying.end(); rlm@1: it++) rlm@1: { rlm@1: (*it)->set_sensitive(); rlm@1: } rlm@1: rlm@1: if (m_poCoreConfig->oGetKey("load_game_auto")) rlm@1: { rlm@1: vOnLoadGameMostRecent(); rlm@1: } rlm@1: rlm@1: vStartEmu(); rlm@1: rlm@1: return true; rlm@1: } rlm@1: rlm@1: void Window::vPopupError(const char * _csFormat, ...) rlm@1: { rlm@1: va_list args; rlm@1: va_start(args, _csFormat); rlm@1: char * csMsg = g_strdup_vprintf(_csFormat, args); rlm@1: va_end(args); rlm@1: rlm@1: Gtk::MessageDialog oDialog(*this, rlm@1: csMsg, rlm@1: #ifndef GTKMM20 rlm@1: false, rlm@1: #endif // ! GTKMM20 rlm@1: Gtk::MESSAGE_ERROR, rlm@1: Gtk::BUTTONS_OK); rlm@1: oDialog.run(); rlm@1: g_free(csMsg); rlm@1: } rlm@1: rlm@1: void Window::vPopupErrorV(const char * _csFormat, va_list _args) rlm@1: { rlm@1: char * csMsg = g_strdup_vprintf(_csFormat, _args); rlm@1: rlm@1: Gtk::MessageDialog oDialog(*this, rlm@1: csMsg, rlm@1: #ifndef GTKMM20 rlm@1: false, rlm@1: #endif // ! GTKMM20 rlm@1: Gtk::MESSAGE_ERROR, rlm@1: Gtk::BUTTONS_OK); rlm@1: oDialog.run(); rlm@1: g_free(csMsg); rlm@1: } rlm@1: rlm@1: void Window::vDrawScreen() rlm@1: { rlm@1: m_poScreenArea->vDrawPixels(pix); rlm@1: } rlm@1: rlm@1: void Window::vDrawDefaultScreen() rlm@1: { rlm@1: m_poScreenArea->vDrawColor(0x000000); // Black rlm@1: } rlm@1: rlm@1: void Window::vSetDefaultTitle() rlm@1: { rlm@1: set_title("VBA"); rlm@1: } rlm@1: rlm@1: void Window::vShowSpeed(int _iSpeed) rlm@1: { rlm@1: char csTitle[50]; rlm@1: rlm@1: if (m_eShowSpeed == ShowPercentage) rlm@1: { rlm@1: snprintf(csTitle, 50, "VBA - %d%%", _iSpeed); rlm@1: set_title(csTitle); rlm@1: } rlm@1: else if (m_eShowSpeed == ShowDetailed) rlm@1: { rlm@1: snprintf(csTitle, 50, "VBA - %d%% (%d, %d fps)", rlm@1: _iSpeed, systemFrameSkip, systemFPS); rlm@1: set_title(csTitle); rlm@1: } rlm@1: } rlm@1: rlm@1: void Window::vComputeFrameskip(int _iRate) rlm@1: { rlm@1: static u32 uiLastTime = 0; rlm@1: static int iFrameskipAdjust = 0; rlm@1: rlm@1: u32 uiTime = SDL_GetTicks(); rlm@1: rlm@1: if (m_bWasEmulating) rlm@1: { rlm@1: int iWantedSpeed = 100; rlm@1: rlm@1: if (m_iThrottle > 0) rlm@1: { rlm@1: if (! speedup) rlm@1: { rlm@1: u32 uiDiff = uiTime - m_uiThrottleLastTime; rlm@1: int iTarget = 1000000 / (_iRate * m_iThrottle); rlm@1: int iDelay = iTarget - uiDiff; rlm@1: if (iDelay > 0) rlm@1: { rlm@1: m_uiThrottleDelay = iDelay; rlm@1: } rlm@1: } rlm@1: iWantedSpeed = m_iThrottle; rlm@1: } rlm@1: rlm@1: if (m_bAutoFrameskip) rlm@1: { rlm@1: u32 uiDiff = uiTime - uiLastTime; rlm@1: int iSpeed = iWantedSpeed; rlm@1: rlm@1: if (uiDiff != 0) rlm@1: { rlm@1: iSpeed = (1000000 / _iRate) / uiDiff; rlm@1: } rlm@1: rlm@1: if (iSpeed >= iWantedSpeed - 2) rlm@1: { rlm@1: iFrameskipAdjust++; rlm@1: if (iFrameskipAdjust >= 3) rlm@1: { rlm@1: iFrameskipAdjust = 0; rlm@1: if (systemFrameSkip > 0) rlm@1: { rlm@1: systemFrameSkip--; rlm@1: } rlm@1: } rlm@1: } rlm@1: else rlm@1: { rlm@1: if (iSpeed < iWantedSpeed - 20) rlm@1: { rlm@1: iFrameskipAdjust -= ((iWantedSpeed - 10) - iSpeed) / 5; rlm@1: } rlm@1: else if (systemFrameSkip < 9) rlm@1: { rlm@1: iFrameskipAdjust--; rlm@1: } rlm@1: rlm@1: if (iFrameskipAdjust <= -2) rlm@1: { rlm@1: iFrameskipAdjust += 2; rlm@1: if (systemFrameSkip < 9) rlm@1: { rlm@1: systemFrameSkip++; rlm@1: } rlm@1: } rlm@1: } rlm@1: } rlm@1: } rlm@1: else rlm@1: { rlm@1: m_bWasEmulating = true; rlm@1: } rlm@1: rlm@1: uiLastTime = uiTime; rlm@1: m_uiThrottleLastTime = uiTime; rlm@1: } rlm@1: rlm@1: void Window::vCaptureScreen(int _iNum) rlm@1: { rlm@1: std::string sBaseName; rlm@1: std::string sCaptureDir = m_poDirConfig->sGetKey("captures"); rlm@1: if (sCaptureDir == "") rlm@1: { rlm@1: sBaseName = sCutSuffix(m_sRomFile); rlm@1: } rlm@1: else rlm@1: { rlm@1: sBaseName = sCaptureDir + "/" + sCutSuffix(Glib::path_get_basename(m_sRomFile)); rlm@1: } rlm@1: std::string sFormat = m_poCoreConfig->sGetKey("screenshot_format"); rlm@1: rlm@1: char * csFile = g_strdup_printf("%s_%02d.%s", rlm@1: sBaseName.c_str(), rlm@1: _iNum, rlm@1: sFormat.c_str()); rlm@1: if (sFormat == "png") rlm@1: { rlm@1: m_stEmulator.emuWritePNG(csFile); rlm@1: } rlm@1: else rlm@1: { rlm@1: m_stEmulator.emuWriteBMP(csFile); rlm@1: } rlm@1: g_free(csFile); rlm@1: } rlm@1: rlm@1: u32 Window::uiReadJoypad() rlm@1: { rlm@1: u32 uiJoypad = m_uiJoypadState; rlm@1: rlm@1: if (m_uiAutofireState != 0) rlm@1: { rlm@1: uiJoypad &= ~m_uiAutofireState; rlm@1: if (m_bAutofireToggle) rlm@1: { rlm@1: uiJoypad |= m_uiAutofireState; rlm@1: } rlm@1: m_bAutofireToggle = ! m_bAutofireToggle; rlm@1: } rlm@1: rlm@1: return uiJoypad; rlm@1: } rlm@1: rlm@1: void Window::vCreateFileOpenDialog() rlm@1: { rlm@1: if (m_poFileOpenDialog != NULL) rlm@1: { rlm@1: return; rlm@1: } rlm@1: rlm@1: std::string sGBDir = m_poDirConfig->sGetKey("gb_roms"); rlm@1: std::string sGBADir = m_poDirConfig->sGetKey("gba_roms"); rlm@1: rlm@1: #ifdef GTKMM20 rlm@1: rlm@1: Gtk::FileSelection * poDialog = new Gtk::FileSelection(_("Open")); rlm@1: poDialog->set_transient_for(*this); rlm@1: rlm@1: if (sGBADir != "") rlm@1: { rlm@1: poDialog->set_filename(sGBADir + "/"); rlm@1: } rlm@1: else if (sGBDir != "") rlm@1: { rlm@1: poDialog->set_filename(sGBDir + "/"); rlm@1: } rlm@1: rlm@1: #else // ! GTKMM20 rlm@1: rlm@1: Gtk::FileChooserDialog * poDialog = new Gtk::FileChooserDialog(*this, _("Open")); rlm@1: poDialog->add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL); rlm@1: poDialog->add_button(Gtk::Stock::OPEN, Gtk::RESPONSE_OK); rlm@1: rlm@1: if (sGBDir != "") rlm@1: { rlm@1: poDialog->add_shortcut_folder(sGBDir); rlm@1: poDialog->set_current_folder(sGBDir); rlm@1: } rlm@1: rlm@1: if (sGBADir != "" && sGBADir != sGBDir) rlm@1: { rlm@1: poDialog->add_shortcut_folder(sGBADir); rlm@1: poDialog->set_current_folder(sGBADir); rlm@1: } rlm@1: rlm@1: const char * acsPattern[] = rlm@1: { rlm@1: // GBA rlm@1: "*.[bB][iI][nN]", "*.[aA][gG][bB]", "*.[gG][bB][aA]", rlm@1: // GB rlm@1: "*.[gG][bB]", "*.[sS][gG][bB]", "*.[cC][gG][bB]", "*.[gG][bB][cC]", rlm@1: // Both rlm@1: "*.[mM][bB]", "*.[eE][lL][fF]", "*.[zZ][iI][pP]", "*.[zZ]", "*.[gG][zZ]" rlm@1: }; rlm@1: rlm@1: Gtk::FileFilter oAllGBAFilter; rlm@1: oAllGBAFilter.set_name(_("All Gameboy Advance files")); rlm@1: for (guint i = 0; i < G_N_ELEMENTS(acsPattern); i++) rlm@1: { rlm@1: oAllGBAFilter.add_pattern(acsPattern[i]); rlm@1: } rlm@1: rlm@1: Gtk::FileFilter oGBAFilter; rlm@1: oGBAFilter.set_name(_("Gameboy Advance files")); rlm@1: for (int i = 0; i < 3; i++) rlm@1: { rlm@1: oGBAFilter.add_pattern(acsPattern[i]); rlm@1: } rlm@1: rlm@1: Gtk::FileFilter oGBFilter; rlm@1: oGBFilter.set_name(_("Gameboy files")); rlm@1: for (int i = 3; i < 7; i++) rlm@1: { rlm@1: oGBFilter.add_pattern(acsPattern[i]); rlm@1: } rlm@1: rlm@1: poDialog->add_filter(oAllGBAFilter); rlm@1: poDialog->add_filter(oGBAFilter); rlm@1: poDialog->add_filter(oGBFilter); rlm@1: rlm@1: #endif // ! GTKMM20 rlm@1: rlm@1: m_poFileOpenDialog = poDialog; rlm@1: } rlm@1: rlm@1: void Window::vLoadBattery() rlm@1: { rlm@1: std::string sBattery; rlm@1: std::string sDir = m_poDirConfig->sGetKey("batteries"); rlm@1: if (sDir == "") rlm@1: { rlm@1: sBattery = sCutSuffix(m_sRomFile) + ".sav"; rlm@1: } rlm@1: else rlm@1: { rlm@1: sBattery = sDir + "/" + sCutSuffix(Glib::path_get_basename(m_sRomFile)) + ".sav"; rlm@1: } rlm@1: rlm@1: if (m_stEmulator.emuReadBattery(sBattery.c_str())) rlm@1: { rlm@1: systemScreenMessage(_("Loaded battery")); rlm@1: } rlm@1: } rlm@1: rlm@1: void Window::vSaveBattery() rlm@1: { rlm@1: std::string sBattery; rlm@1: std::string sDir = m_poDirConfig->sGetKey("batteries"); rlm@1: if (sDir == "") rlm@1: { rlm@1: sBattery = sCutSuffix(m_sRomFile) + ".sav"; rlm@1: } rlm@1: else rlm@1: { rlm@1: sBattery = sDir + "/" + sCutSuffix(Glib::path_get_basename(m_sRomFile)) + ".sav"; rlm@1: } rlm@1: rlm@1: if (m_stEmulator.emuWriteBattery(sBattery.c_str())) rlm@1: { rlm@1: systemScreenMessage(_("Saved battery")); rlm@1: } rlm@1: } rlm@1: rlm@1: void Window::vStartEmu() rlm@1: { rlm@1: if (m_oEmuSig.connected()) rlm@1: { rlm@1: return; rlm@1: } rlm@1: rlm@1: m_oEmuSig = Glib::signal_idle().connect(SigC::slot(*this, &Window::bOnEmuIdle), rlm@1: Glib::PRIORITY_DEFAULT_IDLE); rlm@1: } rlm@1: rlm@1: void Window::vStopEmu() rlm@1: { rlm@1: m_oEmuSig.disconnect(); rlm@1: m_bWasEmulating = false; rlm@1: } rlm@1: rlm@1: void Window::vSetThrottle(int _iPercent) rlm@1: { rlm@1: m_iThrottle = _iPercent; rlm@1: m_poCoreConfig->vSetKey("throttle", _iPercent); rlm@1: } rlm@1: rlm@1: void Window::vSelectBestThrottleItem() rlm@1: { rlm@1: struct rlm@1: { rlm@1: const char * m_csName; rlm@1: const int m_iThrottle; rlm@1: } rlm@1: astThrottle[] = rlm@1: { rlm@1: { "ThrottleNoThrottle", 0 }, rlm@1: { "Throttle25", 25 }, rlm@1: { "Throttle50", 50 }, rlm@1: { "Throttle100", 100 }, rlm@1: { "Throttle150", 150 }, rlm@1: { "Throttle200", 200 } rlm@1: }; rlm@1: for (guint i = 0; i < G_N_ELEMENTS(astThrottle); i++) rlm@1: { rlm@1: Gtk::CheckMenuItem * poCMI; rlm@1: poCMI = dynamic_cast(m_poXml->get_widget(astThrottle[i].m_csName)); rlm@1: if (astThrottle[i].m_iThrottle == m_iThrottle) rlm@1: { rlm@1: poCMI->set_active(); rlm@1: } rlm@1: } rlm@1: } rlm@1: rlm@1: void Window::vUpdateGameSlots() rlm@1: { rlm@1: if (m_eCartridge == CartridgeNone) rlm@1: { rlm@1: std::string sDateTime = _("----/--/-- --:--:--"); rlm@1: rlm@1: for (int i = 0; i < 10; i++) rlm@1: { rlm@1: char csPrefix[10]; rlm@1: snprintf(csPrefix, sizeof(csPrefix), "%2d ", i + 1); rlm@1: rlm@1: Gtk::Label * poLabel; rlm@1: poLabel = dynamic_cast(m_apoLoadGameItem[i]->get_child()); rlm@1: poLabel->set_text(csPrefix + sDateTime); rlm@1: m_apoLoadGameItem[i]->set_sensitive(false); rlm@1: rlm@1: poLabel = dynamic_cast(m_apoSaveGameItem[i]->get_child()); rlm@1: poLabel->set_text(csPrefix + sDateTime); rlm@1: m_apoSaveGameItem[i]->set_sensitive(false); rlm@1: rlm@1: m_astGameSlot[i].m_bEmpty = true; rlm@1: } rlm@1: } rlm@1: else rlm@1: { rlm@1: std::string sFileBase; rlm@1: std::string sDir = m_poDirConfig->sGetKey("saves"); rlm@1: if (sDir == "") rlm@1: { rlm@1: sFileBase = sCutSuffix(m_sRomFile); rlm@1: } rlm@1: else rlm@1: { rlm@1: sFileBase = sDir + "/" + sCutSuffix(Glib::path_get_basename(m_sRomFile)); rlm@1: } rlm@1: rlm@1: const char * csDateFormat = _("%Y/%m/%d %H:%M:%S"); rlm@1: rlm@1: for (int i = 0; i < 10; i++) rlm@1: { rlm@1: char csPrefix[10]; rlm@1: snprintf(csPrefix, sizeof(csPrefix), "%2d ", i + 1); rlm@1: rlm@1: char csSlot[10]; rlm@1: snprintf(csSlot, sizeof(csSlot), "%d", i + 1); rlm@1: m_astGameSlot[i].m_sFile = sFileBase + csSlot + ".sgm"; rlm@1: rlm@1: std::string sDateTime; rlm@1: struct stat stStat; rlm@1: if (stat(m_astGameSlot[i].m_sFile.c_str(), &stStat) == -1) rlm@1: { rlm@1: sDateTime = _("----/--/-- --:--:--"); rlm@1: m_astGameSlot[i].m_bEmpty = true; rlm@1: } rlm@1: else rlm@1: { rlm@1: char csDateTime[30]; rlm@1: strftime(csDateTime, sizeof(csDateTime), csDateFormat, rlm@1: localtime(&stStat.st_mtime)); rlm@1: sDateTime = csDateTime; rlm@1: m_astGameSlot[i].m_bEmpty = false; rlm@1: m_astGameSlot[i].m_uiTime = stStat.st_mtime; rlm@1: } rlm@1: rlm@1: Gtk::Label * poLabel; rlm@1: poLabel = dynamic_cast(m_apoLoadGameItem[i]->get_child()); rlm@1: poLabel->set_text(csPrefix + sDateTime); rlm@1: m_apoLoadGameItem[i]->set_sensitive(! m_astGameSlot[i].m_bEmpty); rlm@1: rlm@1: poLabel = dynamic_cast(m_apoSaveGameItem[i]->get_child()); rlm@1: poLabel->set_text(csPrefix + sDateTime); rlm@1: m_apoSaveGameItem[i]->set_sensitive(); rlm@1: } rlm@1: } rlm@1: } rlm@1: rlm@1: } // VBA namespace