annotate src/gtk/window.cpp @ 1:f9f4f1b99eed

importing src directory
author Robert McIntyre <rlm@mit.edu>
date Sat, 03 Mar 2012 10:31:27 -0600
parents
children
rev   line source
rlm@1 1 // VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
rlm@1 2 // Copyright (C) 1999-2003 Forgotten
rlm@1 3 // Copyright (C) 2004 Forgotten and the VBA development team
rlm@1 4
rlm@1 5 // This program is free software; you can redistribute it and/or modify
rlm@1 6 // it under the terms of the GNU General Public License as published by
rlm@1 7 // the Free Software Foundation; either version 2, or(at your option)
rlm@1 8 // any later version.
rlm@1 9 //
rlm@1 10 // This program is distributed in the hope that it will be useful,
rlm@1 11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
rlm@1 12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
rlm@1 13 // GNU General Public License for more details.
rlm@1 14 //
rlm@1 15 // You should have received a copy of the GNU General Public License
rlm@1 16 // along with this program; if not, write to the Free Software Foundation,
rlm@1 17 // Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
rlm@1 18
rlm@1 19 #include "window.h"
rlm@1 20
rlm@1 21 #include <sys/stat.h>
rlm@1 22
rlm@1 23 #include <stdio.h>
rlm@1 24 #include <time.h>
rlm@1 25
rlm@1 26 #include <SDL.h>
rlm@1 27
rlm@1 28 #include "../gba/GBA.h"
rlm@1 29 #include "../gba/GBAGlobals.h"
rlm@1 30 #include "../gba/GBASound.h"
rlm@1 31 #include "../gb/GB.h"
rlm@1 32 #include "../gb/gbGlobals.h"
rlm@1 33 #include "../gb/gbPrinter.h"
rlm@1 34 #include "../common/Util.h"
rlm@1 35
rlm@1 36 #include "menuitem.h"
rlm@1 37 #include "tools.h"
rlm@1 38 #include "intl.h"
rlm@1 39
rlm@1 40 extern int systemRenderedFrames;
rlm@1 41 extern int systemFPS;
rlm@1 42 extern bool debugger;
rlm@1 43 extern int RGB_LOW_BITS_MASK;
rlm@1 44 extern void (*dbgMain)();
rlm@1 45 extern void (*dbgSignal)(int, int);
rlm@1 46 extern void (*dbgOutput)(char *, u32);
rlm@1 47 extern void remoteInit();
rlm@1 48 extern void remoteCleanUp();
rlm@1 49 extern void remoteStubMain();
rlm@1 50 extern void remoteStubSignal(int, int);
rlm@1 51 extern void remoteOutput(char *, u32);
rlm@1 52 extern void remoteSetProtocol(int);
rlm@1 53 extern void remoteSetPort(int);
rlm@1 54
rlm@1 55 #ifdef MMX
rlm@1 56 extern "C" bool cpu_mmx;
rlm@1 57 #endif // MMX
rlm@1 58
rlm@1 59 namespace VBA
rlm@1 60 {
rlm@1 61
rlm@1 62 using Gnome::Glade::Xml;
rlm@1 63
rlm@1 64 Window * Window::m_poInstance = NULL;
rlm@1 65
rlm@1 66 Window::Window(GtkWindow * _pstWindow, const Glib::RefPtr<Xml> & _poXml) :
rlm@1 67 Gtk::Window (_pstWindow),
rlm@1 68 m_iGBScreenWidth (160),
rlm@1 69 m_iGBScreenHeight (144),
rlm@1 70 m_iSGBScreenWidth (256),
rlm@1 71 m_iSGBScreenHeight(224),
rlm@1 72 m_iGBAScreenWidth (240),
rlm@1 73 m_iGBAScreenHeight(160),
rlm@1 74 m_iFrameskipMin (0),
rlm@1 75 m_iFrameskipMax (9),
rlm@1 76 m_iThrottleMin (5),
rlm@1 77 m_iThrottleMax (1000),
rlm@1 78 m_iScaleMin (1),
rlm@1 79 m_iScaleMax (6),
rlm@1 80 m_iShowSpeedMin (ShowNone),
rlm@1 81 m_iShowSpeedMax (ShowDetailed),
rlm@1 82 m_iSaveTypeMin (SaveAuto),
rlm@1 83 m_iSaveTypeMax (SaveNone),
rlm@1 84 m_iSoundQualityMin(Sound44K),
rlm@1 85 m_iSoundQualityMax(Sound11K),
rlm@1 86 m_iSoundVolumeMin (Sound100),
rlm@1 87 m_iSoundVolumeMax (Sound50),
rlm@1 88 m_iEmulatorTypeMin(EmulatorAuto),
rlm@1 89 m_iEmulatorTypeMax(EmulatorSGB2),
rlm@1 90 m_iFilter2xMin (FirstFilter),
rlm@1 91 m_iFilter2xMax (LastFilter),
rlm@1 92 m_iFilterIBMin (FirstFilterIB),
rlm@1 93 m_iFilterIBMax (LastFilterIB),
rlm@1 94 m_iJoypadMin (1),
rlm@1 95 m_iJoypadMax (4)
rlm@1 96 {
rlm@1 97 m_poXml = _poXml;
rlm@1 98 m_poFileOpenDialog = NULL;
rlm@1 99 m_iScreenWidth = m_iGBAScreenWidth;
rlm@1 100 m_iScreenHeight = m_iGBAScreenHeight;
rlm@1 101 m_eCartridge = CartridgeNone;
rlm@1 102 m_uiJoypadState = 0;
rlm@1 103
rlm@1 104 vInitSystem();
rlm@1 105 vInitSDL();
rlm@1 106
rlm@1 107 Gtk::Container * poC;
rlm@1 108 poC = dynamic_cast<Gtk::Container *>(_poXml->get_widget("ScreenContainer"));
rlm@1 109 m_poScreenArea = Gtk::manage(new ScreenArea(m_iScreenWidth, m_iScreenHeight));
rlm@1 110 poC->add(*m_poScreenArea);
rlm@1 111 vDrawDefaultScreen();
rlm@1 112 m_poScreenArea->show();
rlm@1 113
rlm@1 114 // Get config
rlm@1 115 //
rlm@1 116 vInitConfig();
rlm@1 117
rlm@1 118 m_sUserDataDir = Glib::get_home_dir() + "/.gvba";
rlm@1 119 m_sConfigFile = m_sUserDataDir + "/config";
rlm@1 120
rlm@1 121 if (! Glib::file_test(m_sUserDataDir, Glib::FILE_TEST_EXISTS))
rlm@1 122 {
rlm@1 123 mkdir(m_sUserDataDir.c_str(), 0777);
rlm@1 124 }
rlm@1 125 if (Glib::file_test(m_sConfigFile, Glib::FILE_TEST_EXISTS))
rlm@1 126 {
rlm@1 127 vLoadConfig(m_sConfigFile);
rlm@1 128 vCheckConfig();
rlm@1 129 }
rlm@1 130 else
rlm@1 131 {
rlm@1 132 vSaveConfig(m_sConfigFile);
rlm@1 133 }
rlm@1 134
rlm@1 135 vCreateFileOpenDialog();
rlm@1 136 vLoadHistoryFromConfig();
rlm@1 137 vLoadJoypadsFromConfig();
rlm@1 138
rlm@1 139 Gtk::MenuItem * poMI;
rlm@1 140 Gtk::CheckMenuItem * poCMI;
rlm@1 141
rlm@1 142 // File menu
rlm@1 143 //
rlm@1 144 poMI = dynamic_cast<Gtk::MenuItem *>(_poXml->get_widget("FileOpen"));
rlm@1 145 poMI->signal_activate().connect(SigC::slot(*this, &Window::vOnFileOpen));
rlm@1 146
rlm@1 147 poMI = dynamic_cast<Gtk::MenuItem *>(_poXml->get_widget("FileLoad"));
rlm@1 148 poMI->signal_activate().connect(SigC::slot(*this, &Window::vOnFileLoad));
rlm@1 149 m_listSensitiveWhenPlaying.push_back(poMI);
rlm@1 150
rlm@1 151 poMI = dynamic_cast<Gtk::MenuItem *>(_poXml->get_widget("FileSave"));
rlm@1 152 poMI->signal_activate().connect(SigC::slot(*this, &Window::vOnFileSave));
rlm@1 153 m_listSensitiveWhenPlaying.push_back(poMI);
rlm@1 154
rlm@1 155 for (int i = 0; i < 10; i++)
rlm@1 156 {
rlm@1 157 char csName[20];
rlm@1 158 snprintf(csName, 20, "LoadGameSlot%d", i + 1);
rlm@1 159 m_apoLoadGameItem[i] = dynamic_cast<Gtk::MenuItem *>(_poXml->get_widget(csName));
rlm@1 160 snprintf(csName, 20, "SaveGameSlot%d", i + 1);
rlm@1 161 m_apoSaveGameItem[i] = dynamic_cast<Gtk::MenuItem *>(_poXml->get_widget(csName));
rlm@1 162
rlm@1 163 m_apoLoadGameItem[i]->signal_activate().connect(SigC::bind<int>(
rlm@1 164 SigC::slot(*this, &Window::vOnLoadGame),
rlm@1 165 i + 1));
rlm@1 166 m_apoSaveGameItem[i]->signal_activate().connect(SigC::bind<int>(
rlm@1 167 SigC::slot(*this, &Window::vOnSaveGame),
rlm@1 168 i + 1));
rlm@1 169 }
rlm@1 170 vUpdateGameSlots();
rlm@1 171
rlm@1 172 poMI = dynamic_cast<Gtk::MenuItem *>(_poXml->get_widget("LoadGameMostRecent"));
rlm@1 173 poMI->signal_activate().connect(SigC::slot(*this, &Window::vOnLoadGameMostRecent));
rlm@1 174 m_listSensitiveWhenPlaying.push_back(poMI);
rlm@1 175
rlm@1 176 poCMI = dynamic_cast<Gtk::CheckMenuItem *>(_poXml->get_widget("LoadGameAuto"));
rlm@1 177 poCMI->set_active(m_poCoreConfig->oGetKey<bool>("load_game_auto"));
rlm@1 178 vOnLoadGameAutoToggled(poCMI);
rlm@1 179 poCMI->signal_toggled().connect(SigC::bind<Gtk::CheckMenuItem *>(
rlm@1 180 SigC::slot(*this, &Window::vOnLoadGameAutoToggled),
rlm@1 181 poCMI));
rlm@1 182
rlm@1 183 poMI = dynamic_cast<Gtk::MenuItem *>(_poXml->get_widget("SaveGameOldest"));
rlm@1 184 poMI->signal_activate().connect(SigC::slot(*this, &Window::vOnSaveGameOldest));
rlm@1 185 m_listSensitiveWhenPlaying.push_back(poMI);
rlm@1 186
rlm@1 187 m_poFilePauseItem = dynamic_cast<Gtk::CheckMenuItem *>(_poXml->get_widget("FilePause"));
rlm@1 188 m_poFilePauseItem->set_active(false);
rlm@1 189 vOnFilePauseToggled(m_poFilePauseItem);
rlm@1 190 m_poFilePauseItem->signal_toggled().connect(SigC::bind<Gtk::CheckMenuItem *>(
rlm@1 191 SigC::slot(*this, &Window::vOnFilePauseToggled),
rlm@1 192 m_poFilePauseItem));
rlm@1 193 m_listSensitiveWhenPlaying.push_back(m_poFilePauseItem);
rlm@1 194
rlm@1 195 poMI = dynamic_cast<Gtk::MenuItem *>(_poXml->get_widget("FileReset"));
rlm@1 196 poMI->signal_activate().connect(SigC::slot(*this, &Window::vOnFileReset));
rlm@1 197 m_listSensitiveWhenPlaying.push_back(poMI);
rlm@1 198
rlm@1 199 poMI = dynamic_cast<Gtk::MenuItem *>(_poXml->get_widget("FileScreenCapture"));
rlm@1 200 poMI->signal_activate().connect(SigC::slot(*this, &Window::vOnFileScreenCapture));
rlm@1 201 m_listSensitiveWhenPlaying.push_back(poMI);
rlm@1 202
rlm@1 203 poMI = dynamic_cast<Gtk::MenuItem *>(_poXml->get_widget("FileClose"));
rlm@1 204 poMI->signal_activate().connect(SigC::slot(*this, &Window::vOnFileClose));
rlm@1 205 m_listSensitiveWhenPlaying.push_back(poMI);
rlm@1 206
rlm@1 207 poMI = dynamic_cast<Gtk::MenuItem *>(_poXml->get_widget("FileExit"));
rlm@1 208 poMI->signal_activate().connect(SigC::slot(*this, &Window::vOnFileExit));
rlm@1 209
rlm@1 210 // Recent menu
rlm@1 211 //
rlm@1 212 m_poRecentMenu = dynamic_cast<Gtk::Menu *>(_poXml->get_widget("RecentMenu_menu"));
rlm@1 213 vUpdateHistoryMenu();
rlm@1 214
rlm@1 215 m_poRecentResetItem = dynamic_cast<Gtk::MenuItem *>(_poXml->get_widget("RecentReset"));
rlm@1 216 m_poRecentResetItem->signal_activate().connect(SigC::slot(*this, &Window::vOnRecentReset));
rlm@1 217
rlm@1 218 poCMI = dynamic_cast<Gtk::CheckMenuItem *>(_poXml->get_widget("RecentFreeze"));
rlm@1 219 poCMI->set_active(m_poHistoryConfig->oGetKey<bool>("freeze"));
rlm@1 220 vOnRecentFreezeToggled(poCMI);
rlm@1 221 poCMI->signal_toggled().connect(SigC::bind<Gtk::CheckMenuItem *>(
rlm@1 222 SigC::slot(*this, &Window::vOnRecentFreezeToggled),
rlm@1 223 poCMI));
rlm@1 224
rlm@1 225 // Import menu
rlm@1 226 //
rlm@1 227 poMI = dynamic_cast<Gtk::MenuItem *>(_poXml->get_widget("ImportBatteryFile"));
rlm@1 228 poMI->signal_activate().connect(SigC::slot(*this, &Window::vOnImportBatteryFile));
rlm@1 229 m_listSensitiveWhenPlaying.push_back(poMI);
rlm@1 230
rlm@1 231 // Export menu
rlm@1 232 //
rlm@1 233 poMI = dynamic_cast<Gtk::MenuItem *>(_poXml->get_widget("ExportBatteryFile"));
rlm@1 234 poMI->signal_activate().connect(SigC::slot(*this, &Window::vOnExportBatteryFile));
rlm@1 235 m_listSensitiveWhenPlaying.push_back(poMI);
rlm@1 236
rlm@1 237 // Frameskip menu
rlm@1 238 //
rlm@1 239 struct
rlm@1 240 {
rlm@1 241 const char * m_csName;
rlm@1 242 const int m_iFrameskip;
rlm@1 243 }
rlm@1 244 astFrameskip[] =
rlm@1 245 {
rlm@1 246 { "FrameskipAutomatic", -1 },
rlm@1 247 { "Frameskip0", 0 },
rlm@1 248 { "Frameskip1", 1 },
rlm@1 249 { "Frameskip2", 2 },
rlm@1 250 { "Frameskip3", 3 },
rlm@1 251 { "Frameskip4", 4 },
rlm@1 252 { "Frameskip5", 5 },
rlm@1 253 { "Frameskip6", 6 },
rlm@1 254 { "Frameskip7", 7 },
rlm@1 255 { "Frameskip8", 8 },
rlm@1 256 { "Frameskip9", 9 }
rlm@1 257 };
rlm@1 258 int iDefaultFrameskip;
rlm@1 259 if (m_poCoreConfig->sGetKey("frameskip") == "auto")
rlm@1 260 {
rlm@1 261 iDefaultFrameskip = -1;
rlm@1 262 }
rlm@1 263 else
rlm@1 264 {
rlm@1 265 iDefaultFrameskip = m_poCoreConfig->oGetKey<int>("frameskip");
rlm@1 266 }
rlm@1 267 for (guint i = 0; i < G_N_ELEMENTS(astFrameskip); i++)
rlm@1 268 {
rlm@1 269 poCMI = dynamic_cast<Gtk::CheckMenuItem *>(_poXml->get_widget(astFrameskip[i].m_csName));
rlm@1 270 if (astFrameskip[i].m_iFrameskip == iDefaultFrameskip)
rlm@1 271 {
rlm@1 272 poCMI->set_active();
rlm@1 273 vOnFrameskipToggled(poCMI, iDefaultFrameskip);
rlm@1 274 }
rlm@1 275 poCMI->signal_toggled().connect(SigC::bind<Gtk::CheckMenuItem *, int>(
rlm@1 276 SigC::slot(*this, &Window::vOnFrameskipToggled),
rlm@1 277 poCMI, astFrameskip[i].m_iFrameskip));
rlm@1 278 }
rlm@1 279
rlm@1 280 // Throttle menu
rlm@1 281 //
rlm@1 282 struct
rlm@1 283 {
rlm@1 284 const char * m_csName;
rlm@1 285 const int m_iThrottle;
rlm@1 286 }
rlm@1 287 astThrottle[] =
rlm@1 288 {
rlm@1 289 { "ThrottleNoThrottle", 0 },
rlm@1 290 { "Throttle25", 25 },
rlm@1 291 { "Throttle50", 50 },
rlm@1 292 { "Throttle100", 100 },
rlm@1 293 { "Throttle150", 150 },
rlm@1 294 { "Throttle200", 200 }
rlm@1 295 };
rlm@1 296 poCMI = dynamic_cast<Gtk::CheckMenuItem *>(_poXml->get_widget("ThrottleOther"));
rlm@1 297 poCMI->set_active();
rlm@1 298 poCMI->signal_activate().connect(SigC::bind<Gtk::CheckMenuItem *>(
rlm@1 299 SigC::slot(*this, &Window::vOnThrottleOther),
rlm@1 300 poCMI));
rlm@1 301
rlm@1 302 int iDefaultThrottle = m_poCoreConfig->oGetKey<int>("throttle");
rlm@1 303 for (guint i = 0; i < G_N_ELEMENTS(astThrottle); i++)
rlm@1 304 {
rlm@1 305 poCMI = dynamic_cast<Gtk::CheckMenuItem *>(_poXml->get_widget(astThrottle[i].m_csName));
rlm@1 306 if (astThrottle[i].m_iThrottle == iDefaultThrottle)
rlm@1 307 {
rlm@1 308 poCMI->set_active();
rlm@1 309 }
rlm@1 310 poCMI->signal_toggled().connect(SigC::bind<Gtk::CheckMenuItem *, int>(
rlm@1 311 SigC::slot(*this, &Window::vOnThrottleToggled),
rlm@1 312 poCMI, astThrottle[i].m_iThrottle));
rlm@1 313 }
rlm@1 314 vSetThrottle(iDefaultThrottle);
rlm@1 315
rlm@1 316 // Video menu
rlm@1 317 //
rlm@1 318 struct
rlm@1 319 {
rlm@1 320 const char * m_csName;
rlm@1 321 const int m_iScale;
rlm@1 322 }
rlm@1 323 astVideoScale[] =
rlm@1 324 {
rlm@1 325 { "Video1x", 1 },
rlm@1 326 { "Video2x", 2 },
rlm@1 327 { "Video3x", 3 },
rlm@1 328 { "Video4x", 4 },
rlm@1 329 { "Video5x", 5 },
rlm@1 330 { "Video6x", 6 }
rlm@1 331 };
rlm@1 332 int iDefaultScale = m_poDisplayConfig->oGetKey<int>("scale");
rlm@1 333 for (guint i = 0; i < G_N_ELEMENTS(astVideoScale); i++)
rlm@1 334 {
rlm@1 335 poCMI = dynamic_cast<Gtk::CheckMenuItem *>(_poXml->get_widget(astVideoScale[i].m_csName));
rlm@1 336 if (astVideoScale[i].m_iScale == iDefaultScale)
rlm@1 337 {
rlm@1 338 poCMI->set_active();
rlm@1 339 vOnVideoScaleToggled(poCMI, iDefaultScale);
rlm@1 340 }
rlm@1 341 poCMI->signal_toggled().connect(SigC::bind<Gtk::CheckMenuItem *, int>(
rlm@1 342 SigC::slot(*this, &Window::vOnVideoScaleToggled),
rlm@1 343 poCMI, astVideoScale[i].m_iScale));
rlm@1 344 }
rlm@1 345
rlm@1 346 // Layers menu
rlm@1 347 //
rlm@1 348 struct
rlm@1 349 {
rlm@1 350 const char * m_csName;
rlm@1 351 const char * m_csKey;
rlm@1 352 const int m_iLayer;
rlm@1 353 }
rlm@1 354 astLayer[] =
rlm@1 355 {
rlm@1 356 { "LayersBg0", "layer_bg0", 0 },
rlm@1 357 { "LayersBg1", "layer_bg1", 1 },
rlm@1 358 { "LayersBg2", "layer_bg2", 2 },
rlm@1 359 { "LayersBg3", "layer_bg3", 3 },
rlm@1 360 { "LayersObj", "layer_obj", 4 },
rlm@1 361 { "LayersWin0", "layer_win0", 5 },
rlm@1 362 { "LayersWin1", "layer_win1", 6 },
rlm@1 363 { "LayersObjWin", "layer_objwin", 7 }
rlm@1 364 };
rlm@1 365 for (guint i = 0; i < G_N_ELEMENTS(astLayer); i++)
rlm@1 366 {
rlm@1 367 poCMI = dynamic_cast<Gtk::CheckMenuItem *>(_poXml->get_widget(astLayer[i].m_csName));
rlm@1 368 poCMI->set_active(m_poCoreConfig->oGetKey<bool>(astLayer[i].m_csKey));
rlm@1 369 vOnLayerToggled(poCMI, astLayer[i].m_iLayer);
rlm@1 370 poCMI->signal_toggled().connect(SigC::bind<Gtk::CheckMenuItem *, int>(
rlm@1 371 SigC::slot(*this, &Window::vOnLayerToggled),
rlm@1 372 poCMI, astLayer[i].m_iLayer));
rlm@1 373 }
rlm@1 374
rlm@1 375 // Emulator menu
rlm@1 376 //
rlm@1 377 poMI = dynamic_cast<Gtk::MenuItem *>(_poXml->get_widget("EmulatorDirectories"));
rlm@1 378 poMI->signal_activate().connect(SigC::slot(*this, &Window::vOnDirectories));
rlm@1 379
rlm@1 380 poCMI = dynamic_cast<Gtk::CheckMenuItem *>(_poXml->get_widget("EmulatorPauseWhenInactive"));
rlm@1 381 poCMI->set_active(m_poDisplayConfig->oGetKey<bool>("pause_when_inactive"));
rlm@1 382 vOnPauseWhenInactiveToggled(poCMI);
rlm@1 383 poCMI->signal_toggled().connect(SigC::bind<Gtk::CheckMenuItem *>(
rlm@1 384 SigC::slot(*this, &Window::vOnPauseWhenInactiveToggled),
rlm@1 385 poCMI));
rlm@1 386
rlm@1 387 m_poUseBiosItem = dynamic_cast<Gtk::CheckMenuItem *>(_poXml->get_widget("EmulatorUseBios"));
rlm@1 388 m_poUseBiosItem->set_active(m_poCoreConfig->oGetKey<bool>("use_bios_file"));
rlm@1 389 if (m_poCoreConfig->sGetKey("bios_file") == "")
rlm@1 390 {
rlm@1 391 m_poUseBiosItem->set_sensitive(false);
rlm@1 392 }
rlm@1 393 m_poUseBiosItem->signal_toggled().connect(SigC::bind<Gtk::CheckMenuItem *>(
rlm@1 394 SigC::slot(*this, &Window::vOnUseBiosToggled),
rlm@1 395 m_poUseBiosItem));
rlm@1 396
rlm@1 397 poMI = dynamic_cast<Gtk::MenuItem *>(_poXml->get_widget("EmulatorSelectBios"));
rlm@1 398 poMI->signal_activate().connect(SigC::slot(*this, &Window::vOnSelectBios));
rlm@1 399
rlm@1 400 // Show speed menu
rlm@1 401 //
rlm@1 402 struct
rlm@1 403 {
rlm@1 404 const char * m_csName;
rlm@1 405 const EShowSpeed m_eShowSpeed;
rlm@1 406 }
rlm@1 407 astShowSpeed[] =
rlm@1 408 {
rlm@1 409 { "ShowSpeedNone", ShowNone },
rlm@1 410 { "ShowSpeedPercentage", ShowPercentage },
rlm@1 411 { "ShowSpeedDetailed", ShowDetailed }
rlm@1 412 };
rlm@1 413 EShowSpeed eDefaultShowSpeed = (EShowSpeed)m_poDisplayConfig->oGetKey<int>("show_speed");
rlm@1 414 for (guint i = 0; i < G_N_ELEMENTS(astShowSpeed); i++)
rlm@1 415 {
rlm@1 416 poCMI = dynamic_cast<Gtk::CheckMenuItem *>(_poXml->get_widget(astShowSpeed[i].m_csName));
rlm@1 417 if (astShowSpeed[i].m_eShowSpeed == eDefaultShowSpeed)
rlm@1 418 {
rlm@1 419 poCMI->set_active();
rlm@1 420 vOnShowSpeedToggled(poCMI, eDefaultShowSpeed);
rlm@1 421 }
rlm@1 422 poCMI->signal_toggled().connect(SigC::bind<Gtk::CheckMenuItem *, int>(
rlm@1 423 SigC::slot(*this, &Window::vOnShowSpeedToggled),
rlm@1 424 poCMI, astShowSpeed[i].m_eShowSpeed));
rlm@1 425 }
rlm@1 426
rlm@1 427 // Save type menu
rlm@1 428 //
rlm@1 429 struct
rlm@1 430 {
rlm@1 431 const char * m_csName;
rlm@1 432 const ESaveType m_eSaveType;
rlm@1 433 }
rlm@1 434 astSaveType[] =
rlm@1 435 {
rlm@1 436 { "SaveTypeAutomatic", SaveAuto },
rlm@1 437 { "SaveTypeEeprom", SaveEEPROM },
rlm@1 438 { "SaveTypeSram", SaveSRAM },
rlm@1 439 { "SaveTypeFlash", SaveFlash },
rlm@1 440 { "SaveTypeEepromSensor", SaveEEPROMSensor },
rlm@1 441 { "SaveTypeNone", SaveNone }
rlm@1 442 };
rlm@1 443 ESaveType eDefaultSaveType = (ESaveType)m_poCoreConfig->oGetKey<int>("save_type");
rlm@1 444 for (guint i = 0; i < G_N_ELEMENTS(astSaveType); i++)
rlm@1 445 {
rlm@1 446 poCMI = dynamic_cast<Gtk::CheckMenuItem *>(_poXml->get_widget(astSaveType[i].m_csName));
rlm@1 447 if (astSaveType[i].m_eSaveType == eDefaultSaveType)
rlm@1 448 {
rlm@1 449 poCMI->set_active();
rlm@1 450 vOnSaveTypeToggled(poCMI, eDefaultSaveType);
rlm@1 451 }
rlm@1 452 poCMI->signal_toggled().connect(SigC::bind<Gtk::CheckMenuItem *, int>(
rlm@1 453 SigC::slot(*this, &Window::vOnSaveTypeToggled),
rlm@1 454 poCMI, astSaveType[i].m_eSaveType));
rlm@1 455 }
rlm@1 456
rlm@1 457 // Flash size menu
rlm@1 458 //
rlm@1 459 struct
rlm@1 460 {
rlm@1 461 const char * m_csName;
rlm@1 462 const int m_iFlashSize;
rlm@1 463 }
rlm@1 464 astFlashSize[] =
rlm@1 465 {
rlm@1 466 { "SaveTypeFlash64K", 64 },
rlm@1 467 { "SaveTypeFlash128K", 128 }
rlm@1 468 };
rlm@1 469 int iDefaultFlashSize = m_poCoreConfig->oGetKey<int>("flash_size");
rlm@1 470 for (guint i = 0; i < G_N_ELEMENTS(astFlashSize); i++)
rlm@1 471 {
rlm@1 472 poCMI = dynamic_cast<Gtk::CheckMenuItem *>(_poXml->get_widget(astFlashSize[i].m_csName));
rlm@1 473 if (astFlashSize[i].m_iFlashSize == iDefaultFlashSize)
rlm@1 474 {
rlm@1 475 poCMI->set_active();
rlm@1 476 vOnFlashSizeToggled(poCMI, iDefaultFlashSize);
rlm@1 477 }
rlm@1 478 poCMI->signal_toggled().connect(SigC::bind<Gtk::CheckMenuItem *, int>(
rlm@1 479 SigC::slot(*this, &Window::vOnFlashSizeToggled),
rlm@1 480 poCMI, astFlashSize[i].m_iFlashSize));
rlm@1 481 }
rlm@1 482
rlm@1 483 // Screenshot format menu
rlm@1 484 //
rlm@1 485 struct
rlm@1 486 {
rlm@1 487 const char * m_csName;
rlm@1 488 const char * m_csScreenshotFormat;
rlm@1 489 }
rlm@1 490 astScreenshotFormat[] =
rlm@1 491 {
rlm@1 492 { "ScreenshotFormatPNG", "png" },
rlm@1 493 { "ScreenshotFormatBMP", "bmp" }
rlm@1 494 };
rlm@1 495 std::string sDefaultScreenshotFormat = m_poCoreConfig->sGetKey("screenshot_format");
rlm@1 496 for (guint i = 0; i < G_N_ELEMENTS(astScreenshotFormat); i++)
rlm@1 497 {
rlm@1 498 poCMI = dynamic_cast<Gtk::CheckMenuItem *>(_poXml->get_widget(astScreenshotFormat[i].m_csName));
rlm@1 499 if (astScreenshotFormat[i].m_csScreenshotFormat == sDefaultScreenshotFormat)
rlm@1 500 {
rlm@1 501 poCMI->set_active();
rlm@1 502 vOnScreenshotFormatToggled(poCMI, sDefaultScreenshotFormat);
rlm@1 503 }
rlm@1 504 poCMI->signal_toggled().connect(SigC::bind<Gtk::CheckMenuItem *, std::string>(
rlm@1 505 SigC::slot(*this, &Window::vOnScreenshotFormatToggled),
rlm@1 506 poCMI, std::string(astScreenshotFormat[i].m_csScreenshotFormat)));
rlm@1 507 }
rlm@1 508
rlm@1 509 // Sound menu
rlm@1 510 //
rlm@1 511 std::string sDefaultSoundStatus = m_poSoundConfig->sGetKey("status");
rlm@1 512
rlm@1 513 poCMI = dynamic_cast<Gtk::CheckMenuItem *>(_poXml->get_widget("SoundOff"));
rlm@1 514 if (sDefaultSoundStatus == "off")
rlm@1 515 {
rlm@1 516 poCMI->set_active();
rlm@1 517 vOnSoundStatusToggled(poCMI, SoundOff);
rlm@1 518 }
rlm@1 519 poCMI->signal_toggled().connect(SigC::bind<Gtk::CheckMenuItem *, int>(
rlm@1 520 SigC::slot(*this, &Window::vOnSoundStatusToggled),
rlm@1 521 poCMI, SoundOff));
rlm@1 522 m_poSoundOffItem = poCMI;
rlm@1 523
rlm@1 524 poCMI = dynamic_cast<Gtk::CheckMenuItem *>(_poXml->get_widget("SoundMute"));
rlm@1 525 if (sDefaultSoundStatus == "mute")
rlm@1 526 {
rlm@1 527 poCMI->set_active();
rlm@1 528 vOnSoundStatusToggled(poCMI, SoundMute);
rlm@1 529 }
rlm@1 530 poCMI->signal_toggled().connect(SigC::bind<Gtk::CheckMenuItem *, int>(
rlm@1 531 SigC::slot(*this, &Window::vOnSoundStatusToggled),
rlm@1 532 poCMI, SoundMute));
rlm@1 533
rlm@1 534 poCMI = dynamic_cast<Gtk::CheckMenuItem *>(_poXml->get_widget("SoundOn"));
rlm@1 535 if (sDefaultSoundStatus == "on")
rlm@1 536 {
rlm@1 537 poCMI->set_active();
rlm@1 538 vOnSoundStatusToggled(poCMI, SoundOn);
rlm@1 539 }
rlm@1 540 poCMI->signal_toggled().connect(SigC::bind<Gtk::CheckMenuItem *, int>(
rlm@1 541 SigC::slot(*this, &Window::vOnSoundStatusToggled),
rlm@1 542 poCMI, SoundOn));
rlm@1 543
rlm@1 544 poCMI = dynamic_cast<Gtk::CheckMenuItem *>(_poXml->get_widget("SoundEcho"));
rlm@1 545 poCMI->set_active(m_poSoundConfig->oGetKey<bool>("echo"));
rlm@1 546 vOnSoundEchoToggled(poCMI);
rlm@1 547 poCMI->signal_toggled().connect(SigC::bind<Gtk::CheckMenuItem *>(
rlm@1 548 SigC::slot(*this, &Window::vOnSoundEchoToggled),
rlm@1 549 poCMI));
rlm@1 550
rlm@1 551 poCMI = dynamic_cast<Gtk::CheckMenuItem *>(_poXml->get_widget("SoundLowPass"));
rlm@1 552 poCMI->set_active(m_poSoundConfig->oGetKey<bool>("low_pass"));
rlm@1 553 vOnSoundLowPassToggled(poCMI);
rlm@1 554 poCMI->signal_toggled().connect(SigC::bind<Gtk::CheckMenuItem *>(
rlm@1 555 SigC::slot(*this, &Window::vOnSoundLowPassToggled),
rlm@1 556 poCMI));
rlm@1 557
rlm@1 558 poCMI = dynamic_cast<Gtk::CheckMenuItem *>(_poXml->get_widget("SoundReverseStereo"));
rlm@1 559 poCMI->set_active(m_poSoundConfig->oGetKey<bool>("reverse_stereo"));
rlm@1 560 vOnSoundReverseToggled(poCMI);
rlm@1 561 poCMI->signal_toggled().connect(SigC::bind<Gtk::CheckMenuItem *>(
rlm@1 562 SigC::slot(*this, &Window::vOnSoundReverseToggled),
rlm@1 563 poCMI));
rlm@1 564
rlm@1 565 struct
rlm@1 566 {
rlm@1 567 const char * m_csName;
rlm@1 568 const char * m_csKey;
rlm@1 569 const int m_iSoundChannel;
rlm@1 570 }
rlm@1 571 astSoundChannel[] =
rlm@1 572 {
rlm@1 573 { "SoundChannel1", "channel_1", 0 },
rlm@1 574 { "SoundChannel2", "channel_2", 1 },
rlm@1 575 { "SoundChannel3", "channel_3", 2 },
rlm@1 576 { "SoundChannel4", "channel_4", 3 },
rlm@1 577 { "SoundChannelA", "channel_A", 4 },
rlm@1 578 { "SoundChannelB", "channel_B", 5 }
rlm@1 579 };
rlm@1 580 for (guint i = 0; i < G_N_ELEMENTS(astSoundChannel); i++)
rlm@1 581 {
rlm@1 582 poCMI = dynamic_cast<Gtk::CheckMenuItem *>(_poXml->get_widget(astSoundChannel[i].m_csName));
rlm@1 583 poCMI->set_active(m_poSoundConfig->oGetKey<bool>(astSoundChannel[i].m_csKey));
rlm@1 584 vOnSoundChannelToggled(poCMI, astSoundChannel[i].m_iSoundChannel);
rlm@1 585 poCMI->signal_toggled().connect(SigC::bind<Gtk::CheckMenuItem *, int>(
rlm@1 586 SigC::slot(*this, &Window::vOnSoundChannelToggled),
rlm@1 587 poCMI, astSoundChannel[i].m_iSoundChannel));
rlm@1 588 }
rlm@1 589
rlm@1 590 struct
rlm@1 591 {
rlm@1 592 const char * m_csName;
rlm@1 593 const ESoundQuality m_eSoundQuality;
rlm@1 594 }
rlm@1 595 astSoundQuality[] =
rlm@1 596 {
rlm@1 597 { "Sound11Khz", Sound11K },
rlm@1 598 { "Sound22Khz", Sound22K },
rlm@1 599 { "Sound44Khz", Sound44K }
rlm@1 600 };
rlm@1 601 ESoundQuality eDefaultSoundQuality = (ESoundQuality)m_poSoundConfig->oGetKey<int>("quality");
rlm@1 602 for (guint i = 0; i < G_N_ELEMENTS(astSoundQuality); i++)
rlm@1 603 {
rlm@1 604 poCMI = dynamic_cast<Gtk::CheckMenuItem *>(_poXml->get_widget(astSoundQuality[i].m_csName));
rlm@1 605 if (astSoundQuality[i].m_eSoundQuality == eDefaultSoundQuality)
rlm@1 606 {
rlm@1 607 poCMI->set_active();
rlm@1 608 vOnSoundQualityToggled(poCMI, eDefaultSoundQuality);
rlm@1 609 }
rlm@1 610 poCMI->signal_toggled().connect(SigC::bind<Gtk::CheckMenuItem *, int>(
rlm@1 611 SigC::slot(*this, &Window::vOnSoundQualityToggled),
rlm@1 612 poCMI, astSoundQuality[i].m_eSoundQuality));
rlm@1 613 }
rlm@1 614
rlm@1 615 // Volume menu
rlm@1 616 //
rlm@1 617 struct
rlm@1 618 {
rlm@1 619 const char * m_csName;
rlm@1 620 const ESoundVolume m_eSoundVolume;
rlm@1 621 }
rlm@1 622 astSoundVolume[] =
rlm@1 623 {
rlm@1 624 { "Volume25", Sound25 },
rlm@1 625 { "Volume50", Sound50 },
rlm@1 626 { "Volume100", Sound100 },
rlm@1 627 { "Volume200", Sound200 },
rlm@1 628 { "Volume300", Sound300 },
rlm@1 629 { "Volume400", Sound400 }
rlm@1 630 };
rlm@1 631 ESoundVolume eDefaultSoundVolume = (ESoundVolume)m_poSoundConfig->oGetKey<int>("volume");
rlm@1 632 for (guint i = 0; i < G_N_ELEMENTS(astSoundVolume); i++)
rlm@1 633 {
rlm@1 634 poCMI = dynamic_cast<Gtk::CheckMenuItem *>(_poXml->get_widget(astSoundVolume[i].m_csName));
rlm@1 635 if (astSoundVolume[i].m_eSoundVolume == eDefaultSoundVolume)
rlm@1 636 {
rlm@1 637 poCMI->set_active();
rlm@1 638 vOnSoundVolumeToggled(poCMI, eDefaultSoundVolume);
rlm@1 639 }
rlm@1 640 poCMI->signal_toggled().connect(SigC::bind<Gtk::CheckMenuItem *, int>(
rlm@1 641 SigC::slot(*this, &Window::vOnSoundVolumeToggled),
rlm@1 642 poCMI, astSoundVolume[i].m_eSoundVolume));
rlm@1 643 }
rlm@1 644
rlm@1 645 // Gameboy menu
rlm@1 646 //
rlm@1 647 poCMI = dynamic_cast<Gtk::CheckMenuItem *>(_poXml->get_widget("GameboyBorder"));
rlm@1 648 poCMI->set_active(m_poCoreConfig->oGetKey<bool>("gb_border"));
rlm@1 649 vOnGBBorderToggled(poCMI);
rlm@1 650 poCMI->signal_toggled().connect(SigC::bind<Gtk::CheckMenuItem *>(
rlm@1 651 SigC::slot(*this, &Window::vOnGBBorderToggled),
rlm@1 652 poCMI));
rlm@1 653
rlm@1 654 poCMI = dynamic_cast<Gtk::CheckMenuItem *>(_poXml->get_widget("GameboyPrinter"));
rlm@1 655 poCMI->set_active(m_poCoreConfig->oGetKey<bool>("gb_printer"));
rlm@1 656 vOnGBPrinterToggled(poCMI);
rlm@1 657 poCMI->signal_toggled().connect(SigC::bind<Gtk::CheckMenuItem *>(
rlm@1 658 SigC::slot(*this, &Window::vOnGBPrinterToggled),
rlm@1 659 poCMI));
rlm@1 660
rlm@1 661 struct
rlm@1 662 {
rlm@1 663 const char * m_csName;
rlm@1 664 const EEmulatorType m_eEmulatorType;
rlm@1 665 }
rlm@1 666 astEmulatorType[] =
rlm@1 667 {
rlm@1 668 { "GameboyAutomatic", EmulatorAuto },
rlm@1 669 { "GameboyGba", EmulatorGBA },
rlm@1 670 { "GameboyCgb", EmulatorCGB },
rlm@1 671 { "GameboySgb", EmulatorSGB },
rlm@1 672 { "GameboySgb2", EmulatorSGB2 },
rlm@1 673 { "GameboyGb", EmulatorGB }
rlm@1 674 };
rlm@1 675 EEmulatorType eDefaultEmulatorType = (EEmulatorType)m_poCoreConfig->oGetKey<int>("emulator_type");
rlm@1 676 for (guint i = 0; i < G_N_ELEMENTS(astEmulatorType); i++)
rlm@1 677 {
rlm@1 678 poCMI = dynamic_cast<Gtk::CheckMenuItem *>(_poXml->get_widget(astEmulatorType[i].m_csName));
rlm@1 679 if (astEmulatorType[i].m_eEmulatorType == eDefaultEmulatorType)
rlm@1 680 {
rlm@1 681 poCMI->set_active();
rlm@1 682 vOnEmulatorTypeToggled(poCMI, eDefaultEmulatorType);
rlm@1 683 }
rlm@1 684 poCMI->signal_toggled().connect(SigC::bind<Gtk::CheckMenuItem *, int>(
rlm@1 685 SigC::slot(*this, &Window::vOnEmulatorTypeToggled),
rlm@1 686 poCMI, astEmulatorType[i].m_eEmulatorType));
rlm@1 687 }
rlm@1 688
rlm@1 689 // Filter menu
rlm@1 690 //
rlm@1 691 struct
rlm@1 692 {
rlm@1 693 const char * m_csName;
rlm@1 694 const EFilter2x m_eFilter2x;
rlm@1 695 }
rlm@1 696 astFilter2x[] =
rlm@1 697 {
rlm@1 698 { "FilterNone", FilterNone },
rlm@1 699 { "FilterTVMode", FilterScanlinesTV },
rlm@1 700 { "Filter2xSaI", Filter2xSaI },
rlm@1 701 { "FilterSuper2xSaI", FilterSuper2xSaI },
rlm@1 702 { "FilterSuperEagle", FilterSuperEagle },
rlm@1 703 { "FilterPixelate", FilterPixelate },
rlm@1 704 { "FilterMotionBlur", FilterMotionBlur },
rlm@1 705 { "FilterAdvanceMame2x", FilterAdMame2x },
rlm@1 706 { "FilterSimple2x", FilterSimple2x },
rlm@1 707 { "FilterBilinear", FilterBilinear },
rlm@1 708 { "FilterBilinearPlus", FilterBilinearPlus },
rlm@1 709 { "FilterScanlines", FilterScanlines },
rlm@1 710 { "FilterHq2x", FilterHq2x },
rlm@1 711 { "FilterLq2x", FilterLq2x }
rlm@1 712 };
rlm@1 713 EFilter2x eDefaultFilter2x = (EFilter2x)m_poDisplayConfig->oGetKey<int>("filter2x");
rlm@1 714 for (guint i = 0; i < G_N_ELEMENTS(astFilter2x); i++)
rlm@1 715 {
rlm@1 716 poCMI = dynamic_cast<Gtk::CheckMenuItem *>(_poXml->get_widget(astFilter2x[i].m_csName));
rlm@1 717 if (astFilter2x[i].m_eFilter2x == eDefaultFilter2x)
rlm@1 718 {
rlm@1 719 poCMI->set_active();
rlm@1 720 vOnFilter2xToggled(poCMI, eDefaultFilter2x);
rlm@1 721 }
rlm@1 722 poCMI->signal_toggled().connect(SigC::bind<Gtk::CheckMenuItem *, int>(
rlm@1 723 SigC::slot(*this, &Window::vOnFilter2xToggled),
rlm@1 724 poCMI, astFilter2x[i].m_eFilter2x));
rlm@1 725 }
rlm@1 726
rlm@1 727 poCMI = dynamic_cast<Gtk::CheckMenuItem *>(_poXml->get_widget("FilterDisableMmx"));
rlm@1 728 #ifdef MMX
rlm@1 729 poCMI->set_active(m_poDisplayConfig->oGetKey<bool>("filter_disable_mmx"));
rlm@1 730 vOnDisableMMXToggled(poCMI);
rlm@1 731 poCMI->signal_toggled().connect(SigC::bind<Gtk::CheckMenuItem *>(
rlm@1 732 SigC::slot(*this, &Window::vOnDisableMMXToggled),
rlm@1 733 poCMI));
rlm@1 734 #else // ! MMX
rlm@1 735 poCMI->set_active();
rlm@1 736 poCMI->set_sensitive(false);
rlm@1 737 #endif // ! MMX
rlm@1 738
rlm@1 739 // Interframe blending menu
rlm@1 740 //
rlm@1 741 struct
rlm@1 742 {
rlm@1 743 const char * m_csName;
rlm@1 744 const EFilterIB m_eFilterIB;
rlm@1 745 }
rlm@1 746 astFilterIB[] =
rlm@1 747 {
rlm@1 748 { "IFBNone", FilterIBNone },
rlm@1 749 { "IFBSmart", FilterIBSmart },
rlm@1 750 { "IFBMotionBlur", FilterIBMotionBlur }
rlm@1 751 };
rlm@1 752 EFilterIB eDefaultFilterIB = (EFilterIB)m_poDisplayConfig->oGetKey<int>("filterIB");
rlm@1 753 for (guint i = 0; i < G_N_ELEMENTS(astFilterIB); i++)
rlm@1 754 {
rlm@1 755 poCMI = dynamic_cast<Gtk::CheckMenuItem *>(_poXml->get_widget(astFilterIB[i].m_csName));
rlm@1 756 if (astFilterIB[i].m_eFilterIB == eDefaultFilterIB)
rlm@1 757 {
rlm@1 758 poCMI->set_active();
rlm@1 759 vOnFilterIBToggled(poCMI, eDefaultFilterIB);
rlm@1 760 }
rlm@1 761 poCMI->signal_toggled().connect(SigC::bind<Gtk::CheckMenuItem *, int>(
rlm@1 762 SigC::slot(*this, &Window::vOnFilterIBToggled),
rlm@1 763 poCMI, astFilterIB[i].m_eFilterIB));
rlm@1 764 }
rlm@1 765
rlm@1 766 // Joypad menu
rlm@1 767 //
rlm@1 768 poMI = dynamic_cast<Gtk::MenuItem *>(_poXml->get_widget("JoypadConfigure1"));
rlm@1 769 poMI->signal_activate().connect(SigC::bind<int>(
rlm@1 770 SigC::slot(*this, &Window::vOnJoypadConfigure), 1));
rlm@1 771
rlm@1 772 poMI = dynamic_cast<Gtk::MenuItem *>(_poXml->get_widget("JoypadConfigure2"));
rlm@1 773 poMI->signal_activate().connect(SigC::bind<int>(
rlm@1 774 SigC::slot(*this, &Window::vOnJoypadConfigure), 2));
rlm@1 775
rlm@1 776 poMI = dynamic_cast<Gtk::MenuItem *>(_poXml->get_widget("JoypadConfigure3"));
rlm@1 777 poMI->signal_activate().connect(SigC::bind<int>(
rlm@1 778 SigC::slot(*this, &Window::vOnJoypadConfigure), 3));
rlm@1 779
rlm@1 780 poMI = dynamic_cast<Gtk::MenuItem *>(_poXml->get_widget("JoypadConfigure4"));
rlm@1 781 poMI->signal_activate().connect(SigC::bind<int>(
rlm@1 782 SigC::slot(*this, &Window::vOnJoypadConfigure), 4));
rlm@1 783
rlm@1 784 int iDefaultJoypad = m_poInputConfig->oGetKey<int>("active_joypad");
rlm@1 785 for (int i = m_iJoypadMin; i <= m_iJoypadMax; i++)
rlm@1 786 {
rlm@1 787 char csName[20];
rlm@1 788 snprintf(csName, sizeof(csName), "Joypad%d", i);
rlm@1 789
rlm@1 790 poCMI = dynamic_cast<Gtk::CheckMenuItem *>(_poXml->get_widget(csName));
rlm@1 791 if (i == iDefaultJoypad)
rlm@1 792 {
rlm@1 793 poCMI->set_active();
rlm@1 794 vOnJoypadToggled(poCMI, iDefaultJoypad);
rlm@1 795 }
rlm@1 796 poCMI->signal_toggled().connect(SigC::bind<Gtk::CheckMenuItem *, int>(
rlm@1 797 SigC::slot(*this, &Window::vOnJoypadToggled),
rlm@1 798 poCMI, i));
rlm@1 799 }
rlm@1 800
rlm@1 801 // Autofire menu
rlm@1 802 //
rlm@1 803 struct
rlm@1 804 {
rlm@1 805 const char * m_csName;
rlm@1 806 const char * m_csKey;
rlm@1 807 const EKeyFlag m_eKeyFlag;
rlm@1 808 }
rlm@1 809 astAutofire[] =
rlm@1 810 {
rlm@1 811 { "AutofireA", "autofire_A", KeyFlagA },
rlm@1 812 { "AutofireB", "autofire_B", KeyFlagB },
rlm@1 813 { "AutofireL", "autofire_L", KeyFlagL },
rlm@1 814 { "AutofireR", "autofire_R", KeyFlagR }
rlm@1 815 };
rlm@1 816 for (guint i = 0; i < G_N_ELEMENTS(astAutofire); i++)
rlm@1 817 {
rlm@1 818 poCMI = dynamic_cast<Gtk::CheckMenuItem *>(_poXml->get_widget(astAutofire[i].m_csName));
rlm@1 819 poCMI->set_active(m_poInputConfig->oGetKey<bool>(astAutofire[i].m_csKey));
rlm@1 820 vOnAutofireToggled(poCMI, astAutofire[i].m_eKeyFlag);
rlm@1 821 poCMI->signal_toggled().connect(SigC::bind<Gtk::CheckMenuItem *, u32>(
rlm@1 822 SigC::slot(*this, &Window::vOnAutofireToggled),
rlm@1 823 poCMI, astAutofire[i].m_eKeyFlag));
rlm@1 824 }
rlm@1 825
rlm@1 826 // GDB menu
rlm@1 827 //
rlm@1 828 poMI = dynamic_cast<Gtk::MenuItem *>(_poXml->get_widget("GdbWait"));
rlm@1 829 poMI->signal_activate().connect(SigC::slot(*this, &Window::vOnGDBWait));
rlm@1 830
rlm@1 831 poMI = dynamic_cast<Gtk::MenuItem *>(_poXml->get_widget("GdbLoadAndWait"));
rlm@1 832 poMI->signal_activate().connect(SigC::slot(*this, &Window::vOnGDBLoadAndWait));
rlm@1 833
rlm@1 834 poMI = dynamic_cast<Gtk::MenuItem *>(_poXml->get_widget("GdbBreak"));
rlm@1 835 poMI->signal_activate().connect(SigC::slot(*this, &Window::vOnGDBBreak));
rlm@1 836
rlm@1 837 poMI = dynamic_cast<Gtk::MenuItem *>(_poXml->get_widget("GdbDisconnect"));
rlm@1 838 poMI->signal_activate().connect(SigC::slot(*this, &Window::vOnGDBDisconnect));
rlm@1 839
rlm@1 840 // Help menu
rlm@1 841 //
rlm@1 842 poMI = dynamic_cast<Gtk::MenuItem *>(_poXml->get_widget("HelpAbout"));
rlm@1 843 poMI->signal_activate().connect(SigC::slot(*this, &Window::vOnHelpAbout));
rlm@1 844
rlm@1 845 // Init widgets sensitivity
rlm@1 846 for (std::list<Gtk::Widget *>::iterator it = m_listSensitiveWhenPlaying.begin();
rlm@1 847 it != m_listSensitiveWhenPlaying.end();
rlm@1 848 it++)
rlm@1 849 {
rlm@1 850 (*it)->set_sensitive(false);
rlm@1 851 }
rlm@1 852
rlm@1 853 if (m_poInstance == NULL)
rlm@1 854 {
rlm@1 855 m_poInstance = this;
rlm@1 856 }
rlm@1 857 else
rlm@1 858 {
rlm@1 859 abort();
rlm@1 860 }
rlm@1 861 }
rlm@1 862
rlm@1 863 Window::~Window()
rlm@1 864 {
rlm@1 865 vOnFileClose();
rlm@1 866 vSaveHistoryToConfig();
rlm@1 867 vSaveJoypadsToConfig();
rlm@1 868 vSaveConfig(m_sConfigFile);
rlm@1 869
rlm@1 870 if (m_poFileOpenDialog != NULL)
rlm@1 871 {
rlm@1 872 delete m_poFileOpenDialog;
rlm@1 873 }
rlm@1 874
rlm@1 875 if (m_poKeymap != NULL)
rlm@1 876 {
rlm@1 877 delete m_poKeymap;
rlm@1 878 }
rlm@1 879
rlm@1 880 m_poInstance = NULL;
rlm@1 881 }
rlm@1 882
rlm@1 883 void Window::vInitSystem()
rlm@1 884 {
rlm@1 885 #if G_BYTE_ORDER == G_LITTLE_ENDIAN
rlm@1 886 systemRedShift = 3;
rlm@1 887 systemGreenShift = 11;
rlm@1 888 systemBlueShift = 19;
rlm@1 889 RGB_LOW_BITS_MASK = 0x00010101;
rlm@1 890 #else
rlm@1 891 systemRedShift = 27;
rlm@1 892 systemGreenShift = 19;
rlm@1 893 systemBlueShift = 11;
rlm@1 894 RGB_LOW_BITS_MASK = 0x01010100;
rlm@1 895 #endif
rlm@1 896
rlm@1 897 systemColorDepth = 32;
rlm@1 898 systemDebug = 0;
rlm@1 899 systemVerbose = 0;
rlm@1 900 systemSaveUpdateCounter = SYSTEM_SAVE_NOT_UPDATED;
rlm@1 901 systemFrameSkip = 0;
rlm@1 902 systemSoundOn = false;
rlm@1 903 soundOffFlag = true;
rlm@1 904
rlm@1 905 systemRenderedFrames = 0;
rlm@1 906 systemFPS = 0;
rlm@1 907
rlm@1 908 emulating = 0;
rlm@1 909 debugger = false;
rlm@1 910
rlm@1 911 for (int i = 0; i < 0x10000; i++)
rlm@1 912 {
rlm@1 913 #if G_BYTE_ORDER == G_LITTLE_ENDIAN
rlm@1 914 systemColorMap32[i] = (((i & 0x1f) << systemRedShift)
rlm@1 915 | (((i & 0x3e0) >> 5) << systemGreenShift)
rlm@1 916 | (((i & 0x7c00) >> 10) << systemBlueShift));
rlm@1 917 #else
rlm@1 918 systemColorMap32[i] = (((i & 0x1f) << systemRedShift)
rlm@1 919 | (((i & 0x3e0) >> 5) << systemGreenShift)
rlm@1 920 | (((i & 0x7c00) >> 10) << systemBlueShift));
rlm@1 921 #endif
rlm@1 922 }
rlm@1 923
rlm@1 924 gbFrameSkip = 0;
rlm@1 925
rlm@1 926 for (int i = 0; i < 24; )
rlm@1 927 {
rlm@1 928 systemGbPalette[i++] = (0x1f) | (0x1f << 5) | (0x1f << 10);
rlm@1 929 systemGbPalette[i++] = (0x15) | (0x15 << 5) | (0x15 << 10);
rlm@1 930 systemGbPalette[i++] = (0x0c) | (0x0c << 5) | (0x0c << 10);
rlm@1 931 systemGbPalette[i++] = 0;
rlm@1 932 }
rlm@1 933
rlm@1 934 Init_2xSaI(32);
rlm@1 935 }
rlm@1 936
rlm@1 937 void Window::vInitSDL()
rlm@1 938 {
rlm@1 939 static bool bDone = false;
rlm@1 940
rlm@1 941 if (bDone)
rlm@1 942 return;
rlm@1 943
rlm@1 944 int iFlags = (SDL_INIT_AUDIO | SDL_INIT_NOPARACHUTE);
rlm@1 945
rlm@1 946 if (SDL_Init(iFlags) < 0)
rlm@1 947 {
rlm@1 948 fprintf(stderr, "Failed to init SDL: %s", SDL_GetError());
rlm@1 949 abort();
rlm@1 950 }
rlm@1 951
rlm@1 952 bDone = true;
rlm@1 953 }
rlm@1 954
rlm@1 955 void Window::vInitConfig()
rlm@1 956 {
rlm@1 957 m_oConfig.vClear();
rlm@1 958
rlm@1 959 // History section
rlm@1 960 //
rlm@1 961 m_poHistoryConfig = m_oConfig.poAddSection("History");
rlm@1 962 m_poHistoryConfig->vSetKey("freeze", false );
rlm@1 963 m_poHistoryConfig->vSetKey("0", "" );
rlm@1 964 m_poHistoryConfig->vSetKey("1", "" );
rlm@1 965 m_poHistoryConfig->vSetKey("2", "" );
rlm@1 966 m_poHistoryConfig->vSetKey("3", "" );
rlm@1 967 m_poHistoryConfig->vSetKey("4", "" );
rlm@1 968 m_poHistoryConfig->vSetKey("5", "" );
rlm@1 969 m_poHistoryConfig->vSetKey("6", "" );
rlm@1 970 m_poHistoryConfig->vSetKey("7", "" );
rlm@1 971 m_poHistoryConfig->vSetKey("8", "" );
rlm@1 972 m_poHistoryConfig->vSetKey("9", "" );
rlm@1 973
rlm@1 974 // Directories section
rlm@1 975 //
rlm@1 976 m_poDirConfig = m_oConfig.poAddSection("Directories");
rlm@1 977 m_poDirConfig->vSetKey("gb_roms", "" );
rlm@1 978 m_poDirConfig->vSetKey("gba_roms", "" );
rlm@1 979 m_poDirConfig->vSetKey("batteries", "" );
rlm@1 980 m_poDirConfig->vSetKey("saves", "" );
rlm@1 981 m_poDirConfig->vSetKey("captures", "" );
rlm@1 982
rlm@1 983 // Core section
rlm@1 984 //
rlm@1 985 m_poCoreConfig = m_oConfig.poAddSection("Core");
rlm@1 986 m_poCoreConfig->vSetKey("load_game_auto", false );
rlm@1 987 m_poCoreConfig->vSetKey("frameskip", "auto" );
rlm@1 988 m_poCoreConfig->vSetKey("throttle", 0 );
rlm@1 989 m_poCoreConfig->vSetKey("layer_bg0", true );
rlm@1 990 m_poCoreConfig->vSetKey("layer_bg1", true );
rlm@1 991 m_poCoreConfig->vSetKey("layer_bg2", true );
rlm@1 992 m_poCoreConfig->vSetKey("layer_bg3", true );
rlm@1 993 m_poCoreConfig->vSetKey("layer_obj", true );
rlm@1 994 m_poCoreConfig->vSetKey("layer_win0", true );
rlm@1 995 m_poCoreConfig->vSetKey("layer_win1", true );
rlm@1 996 m_poCoreConfig->vSetKey("layer_objwin", true );
rlm@1 997 m_poCoreConfig->vSetKey("use_bios_file", false );
rlm@1 998 m_poCoreConfig->vSetKey("bios_file", "" );
rlm@1 999 m_poCoreConfig->vSetKey("save_type", SaveAuto );
rlm@1 1000 m_poCoreConfig->vSetKey("flash_size", 64 );
rlm@1 1001 m_poCoreConfig->vSetKey("gb_border", true );
rlm@1 1002 m_poCoreConfig->vSetKey("gb_printer", false );
rlm@1 1003 m_poCoreConfig->vSetKey("emulator_type", EmulatorAuto );
rlm@1 1004 m_poCoreConfig->vSetKey("screenshot_format", "png" );
rlm@1 1005
rlm@1 1006 // Display section
rlm@1 1007 //
rlm@1 1008 m_poDisplayConfig = m_oConfig.poAddSection("Display");
rlm@1 1009 m_poDisplayConfig->vSetKey("scale", 1 );
rlm@1 1010 m_poDisplayConfig->vSetKey("show_speed", ShowPercentage );
rlm@1 1011 m_poDisplayConfig->vSetKey("pause_when_inactive", true );
rlm@1 1012 m_poDisplayConfig->vSetKey("filter2x", FilterNone );
rlm@1 1013 m_poDisplayConfig->vSetKey("filterIB", FilterIBNone );
rlm@1 1014 #ifdef MMX
rlm@1 1015 m_poDisplayConfig->vSetKey("filter_disable_mmx", false );
rlm@1 1016 #endif // MMX
rlm@1 1017
rlm@1 1018 // Sound section
rlm@1 1019 //
rlm@1 1020 m_poSoundConfig = m_oConfig.poAddSection("Sound");
rlm@1 1021 m_poSoundConfig->vSetKey("status", "on" );
rlm@1 1022 m_poSoundConfig->vSetKey("echo", false );
rlm@1 1023 m_poSoundConfig->vSetKey("low_pass", false );
rlm@1 1024 m_poSoundConfig->vSetKey("reverse_stereo", false );
rlm@1 1025 m_poSoundConfig->vSetKey("channel_1", true );
rlm@1 1026 m_poSoundConfig->vSetKey("channel_2", true );
rlm@1 1027 m_poSoundConfig->vSetKey("channel_3", true );
rlm@1 1028 m_poSoundConfig->vSetKey("channel_4", true );
rlm@1 1029 m_poSoundConfig->vSetKey("channel_A", true );
rlm@1 1030 m_poSoundConfig->vSetKey("channel_B", true );
rlm@1 1031 m_poSoundConfig->vSetKey("quality", Sound22K );
rlm@1 1032 m_poSoundConfig->vSetKey("volume", Sound100 );
rlm@1 1033
rlm@1 1034 // Input section
rlm@1 1035 //
rlm@1 1036 JoypadConfig oJoypadConfig;
rlm@1 1037 oJoypadConfig.vSetDefault();
rlm@1 1038 m_poInputConfig = m_oConfig.poAddSection("Input");
rlm@1 1039 m_poInputConfig->vSetKey("active_joypad", m_iJoypadMin );
rlm@1 1040 for (int i = m_iJoypadMin; i <= m_iJoypadMax; i++)
rlm@1 1041 {
rlm@1 1042 char csPrefix[20];
rlm@1 1043 snprintf(csPrefix, sizeof(csPrefix), "joypad%d_", i);
rlm@1 1044 std::string sPrefix(csPrefix);
rlm@1 1045 m_poInputConfig->vSetKey(sPrefix + "up", oJoypadConfig.m_uiUp );
rlm@1 1046 m_poInputConfig->vSetKey(sPrefix + "down", oJoypadConfig.m_uiDown );
rlm@1 1047 m_poInputConfig->vSetKey(sPrefix + "left", oJoypadConfig.m_uiLeft );
rlm@1 1048 m_poInputConfig->vSetKey(sPrefix + "right", oJoypadConfig.m_uiRight );
rlm@1 1049 m_poInputConfig->vSetKey(sPrefix + "A", oJoypadConfig.m_uiA );
rlm@1 1050 m_poInputConfig->vSetKey(sPrefix + "B", oJoypadConfig.m_uiB );
rlm@1 1051 m_poInputConfig->vSetKey(sPrefix + "L", oJoypadConfig.m_uiL );
rlm@1 1052 m_poInputConfig->vSetKey(sPrefix + "R", oJoypadConfig.m_uiR );
rlm@1 1053 m_poInputConfig->vSetKey(sPrefix + "select", oJoypadConfig.m_uiSelect );
rlm@1 1054 m_poInputConfig->vSetKey(sPrefix + "start", oJoypadConfig.m_uiStart );
rlm@1 1055 m_poInputConfig->vSetKey(sPrefix + "speed", oJoypadConfig.m_uiSpeed );
rlm@1 1056 m_poInputConfig->vSetKey(sPrefix + "capture", oJoypadConfig.m_uiCapture );
rlm@1 1057 }
rlm@1 1058 m_poInputConfig->vSetKey("autofire_A", false );
rlm@1 1059 m_poInputConfig->vSetKey("autofire_B", false );
rlm@1 1060 m_poInputConfig->vSetKey("autofire_L", false );
rlm@1 1061 m_poInputConfig->vSetKey("autofire_R", false );
rlm@1 1062 }
rlm@1 1063
rlm@1 1064 void Window::vCheckConfig()
rlm@1 1065 {
rlm@1 1066 int iValue;
rlm@1 1067 int iAdjusted;
rlm@1 1068 std::string sValue;
rlm@1 1069
rlm@1 1070 // Directories section
rlm@1 1071 //
rlm@1 1072 sValue = m_poDirConfig->sGetKey("gb_roms");
rlm@1 1073 if (sValue != "" && ! Glib::file_test(sValue, Glib::FILE_TEST_IS_DIR))
rlm@1 1074 {
rlm@1 1075 m_poDirConfig->vSetKey("gb_roms", "");
rlm@1 1076 }
rlm@1 1077 sValue = m_poDirConfig->sGetKey("gba_roms");
rlm@1 1078 if (sValue != "" && ! Glib::file_test(sValue, Glib::FILE_TEST_IS_DIR))
rlm@1 1079 {
rlm@1 1080 m_poDirConfig->vSetKey("gba_roms", "");
rlm@1 1081 }
rlm@1 1082 sValue = m_poDirConfig->sGetKey("batteries");
rlm@1 1083 if (sValue != "" && ! Glib::file_test(sValue, Glib::FILE_TEST_IS_DIR))
rlm@1 1084 {
rlm@1 1085 m_poDirConfig->vSetKey("batteries", "");
rlm@1 1086 }
rlm@1 1087 sValue = m_poDirConfig->sGetKey("saves");
rlm@1 1088 if (sValue != "" && ! Glib::file_test(sValue, Glib::FILE_TEST_IS_DIR))
rlm@1 1089 {
rlm@1 1090 m_poDirConfig->vSetKey("saves", "");
rlm@1 1091 }
rlm@1 1092 sValue = m_poDirConfig->sGetKey("captures");
rlm@1 1093 if (sValue != "" && ! Glib::file_test(sValue, Glib::FILE_TEST_IS_DIR))
rlm@1 1094 {
rlm@1 1095 m_poDirConfig->vSetKey("captures", "");
rlm@1 1096 }
rlm@1 1097
rlm@1 1098 // Core section
rlm@1 1099 //
rlm@1 1100 if (m_poCoreConfig->sGetKey("frameskip") != "auto")
rlm@1 1101 {
rlm@1 1102 iValue = m_poCoreConfig->oGetKey<int>("frameskip");
rlm@1 1103 iAdjusted = CLAMP(iValue, m_iFrameskipMin, m_iFrameskipMax);
rlm@1 1104 if (iValue != iAdjusted)
rlm@1 1105 {
rlm@1 1106 m_poCoreConfig->vSetKey("frameskip", iAdjusted);
rlm@1 1107 }
rlm@1 1108 }
rlm@1 1109
rlm@1 1110 iValue = m_poCoreConfig->oGetKey<int>("throttle");
rlm@1 1111 if (iValue != 0)
rlm@1 1112 {
rlm@1 1113 iAdjusted = CLAMP(iValue, m_iThrottleMin, m_iThrottleMax);
rlm@1 1114 if (iValue != iAdjusted)
rlm@1 1115 {
rlm@1 1116 m_poCoreConfig->vSetKey("throttle", iAdjusted);
rlm@1 1117 }
rlm@1 1118 }
rlm@1 1119
rlm@1 1120 sValue = m_poCoreConfig->sGetKey("bios_file");
rlm@1 1121 if (sValue != "" && ! Glib::file_test(sValue, Glib::FILE_TEST_IS_REGULAR))
rlm@1 1122 {
rlm@1 1123 m_poCoreConfig->vSetKey("bios_file", "");
rlm@1 1124 }
rlm@1 1125 if (m_poCoreConfig->sGetKey("bios_file") == "")
rlm@1 1126 {
rlm@1 1127 m_poCoreConfig->vSetKey("use_bios_file", false);
rlm@1 1128 }
rlm@1 1129
rlm@1 1130 iValue = m_poCoreConfig->oGetKey<int>("save_type");
rlm@1 1131 if (iValue != 0)
rlm@1 1132 {
rlm@1 1133 iAdjusted = CLAMP(iValue, m_iSaveTypeMin, m_iSaveTypeMax);
rlm@1 1134 if (iValue != iAdjusted)
rlm@1 1135 {
rlm@1 1136 m_poCoreConfig->vSetKey("save_type", iAdjusted);
rlm@1 1137 }
rlm@1 1138 }
rlm@1 1139
rlm@1 1140 iValue = m_poCoreConfig->oGetKey<int>("flash_size");
rlm@1 1141 if (iValue != 64 && iValue != 128)
rlm@1 1142 {
rlm@1 1143 m_poCoreConfig->vSetKey("flash_size", 64);
rlm@1 1144 }
rlm@1 1145
rlm@1 1146 iValue = m_poCoreConfig->oGetKey<int>("emulator_type");
rlm@1 1147 iAdjusted = CLAMP(iValue, m_iEmulatorTypeMin, m_iEmulatorTypeMax);
rlm@1 1148 if (iValue != iAdjusted)
rlm@1 1149 {
rlm@1 1150 m_poCoreConfig->vSetKey("emulator_type", iAdjusted);
rlm@1 1151 }
rlm@1 1152
rlm@1 1153 sValue = m_poCoreConfig->sGetKey("screenshot_format");
rlm@1 1154 if (sValue != "png" && sValue != "bmp")
rlm@1 1155 {
rlm@1 1156 sValue = "png";
rlm@1 1157 }
rlm@1 1158
rlm@1 1159 // Display section
rlm@1 1160 //
rlm@1 1161 iValue = m_poDisplayConfig->oGetKey<int>("scale");
rlm@1 1162 iAdjusted = CLAMP(iValue, m_iScaleMin, m_iScaleMax);
rlm@1 1163 if (iValue != iAdjusted)
rlm@1 1164 {
rlm@1 1165 m_poDisplayConfig->vSetKey("scale", iAdjusted);
rlm@1 1166 }
rlm@1 1167
rlm@1 1168 iValue = m_poDisplayConfig->oGetKey<int>("show_speed");
rlm@1 1169 iAdjusted = CLAMP(iValue, m_iShowSpeedMin, m_iShowSpeedMax);
rlm@1 1170 if (iValue != iAdjusted)
rlm@1 1171 {
rlm@1 1172 m_poDisplayConfig->vSetKey("show_speed", iAdjusted);
rlm@1 1173 }
rlm@1 1174
rlm@1 1175 iValue = m_poDisplayConfig->oGetKey<int>("filter2x");
rlm@1 1176 iAdjusted = CLAMP(iValue, m_iFilter2xMin, m_iFilter2xMax);
rlm@1 1177 if (iValue != iAdjusted)
rlm@1 1178 {
rlm@1 1179 m_poDisplayConfig->vSetKey("filter2x", iAdjusted);
rlm@1 1180 }
rlm@1 1181
rlm@1 1182 iValue = m_poDisplayConfig->oGetKey<int>("filterIB");
rlm@1 1183 iAdjusted = CLAMP(iValue, m_iFilterIBMin, m_iFilterIBMax);
rlm@1 1184 if (iValue != iAdjusted)
rlm@1 1185 {
rlm@1 1186 m_poDisplayConfig->vSetKey("filterIB", iAdjusted);
rlm@1 1187 }
rlm@1 1188
rlm@1 1189 // Sound section
rlm@1 1190 //
rlm@1 1191 sValue = m_poSoundConfig->sGetKey("status");
rlm@1 1192 if (sValue != "off" && sValue != "on" && sValue != "mute")
rlm@1 1193 {
rlm@1 1194 m_poSoundConfig->vSetKey("status", "on");
rlm@1 1195 }
rlm@1 1196
rlm@1 1197 iValue = m_poSoundConfig->oGetKey<int>("quality");
rlm@1 1198 iAdjusted = CLAMP(iValue, m_iSoundQualityMin, m_iSoundQualityMax);
rlm@1 1199 if (iValue != iAdjusted)
rlm@1 1200 {
rlm@1 1201 m_poSoundConfig->vSetKey("quality", iAdjusted);
rlm@1 1202 }
rlm@1 1203
rlm@1 1204 iValue = m_poSoundConfig->oGetKey<int>("volume");
rlm@1 1205 iAdjusted = CLAMP(iValue, m_iSoundVolumeMin, m_iSoundVolumeMax);
rlm@1 1206 if (iValue != iAdjusted)
rlm@1 1207 {
rlm@1 1208 m_poSoundConfig->vSetKey("volume", iAdjusted);
rlm@1 1209 }
rlm@1 1210
rlm@1 1211 // Input section
rlm@1 1212 //
rlm@1 1213 iValue = m_poInputConfig->oGetKey<int>("active_joypad");
rlm@1 1214 iAdjusted = CLAMP(iValue, m_iJoypadMin, m_iJoypadMax);
rlm@1 1215 if (iValue != iAdjusted)
rlm@1 1216 {
rlm@1 1217 m_poInputConfig->vSetKey("active_joypad", iAdjusted);
rlm@1 1218 }
rlm@1 1219 }
rlm@1 1220
rlm@1 1221 void Window::vLoadConfig(const std::string & _rsFile)
rlm@1 1222 {
rlm@1 1223 try
rlm@1 1224 {
rlm@1 1225 m_oConfig.vLoad(_rsFile, false, false);
rlm@1 1226 }
rlm@1 1227 catch (const Glib::Error & e)
rlm@1 1228 {
rlm@1 1229 vPopupError(e.what().c_str());
rlm@1 1230 }
rlm@1 1231 }
rlm@1 1232
rlm@1 1233 void Window::vSaveConfig(const std::string & _rsFile)
rlm@1 1234 {
rlm@1 1235 try
rlm@1 1236 {
rlm@1 1237 m_oConfig.vSave(_rsFile);
rlm@1 1238 }
rlm@1 1239 catch (const Glib::Error & e)
rlm@1 1240 {
rlm@1 1241 vPopupError(e.what().c_str());
rlm@1 1242 }
rlm@1 1243 }
rlm@1 1244
rlm@1 1245 void Window::vLoadHistoryFromConfig()
rlm@1 1246 {
rlm@1 1247 char csKey[] = "0";
rlm@1 1248 for (int i = 0; i < 10; i++, csKey[0]++)
rlm@1 1249 {
rlm@1 1250 std::string sFile = m_poHistoryConfig->sGetKey(csKey);
rlm@1 1251 if (sFile == "")
rlm@1 1252 {
rlm@1 1253 break;
rlm@1 1254 }
rlm@1 1255 m_listHistory.push_back(sFile);
rlm@1 1256 }
rlm@1 1257 }
rlm@1 1258
rlm@1 1259 void Window::vSaveHistoryToConfig()
rlm@1 1260 {
rlm@1 1261 char csKey[] = "0";
rlm@1 1262 for (std::list<std::string>::const_iterator it = m_listHistory.begin();
rlm@1 1263 it != m_listHistory.end();
rlm@1 1264 it++, csKey[0]++)
rlm@1 1265 {
rlm@1 1266 m_poHistoryConfig->vSetKey(csKey, *it);
rlm@1 1267 }
rlm@1 1268 }
rlm@1 1269
rlm@1 1270 void Window::vHistoryAdd(const std::string & _rsFile)
rlm@1 1271 {
rlm@1 1272 if (m_poHistoryConfig->oGetKey<bool>("freeze"))
rlm@1 1273 {
rlm@1 1274 return;
rlm@1 1275 }
rlm@1 1276
rlm@1 1277 m_listHistory.remove(_rsFile);
rlm@1 1278 m_listHistory.push_front(_rsFile);
rlm@1 1279 if (m_listHistory.size() > 10)
rlm@1 1280 {
rlm@1 1281 m_listHistory.pop_back();
rlm@1 1282 }
rlm@1 1283
rlm@1 1284 vUpdateHistoryMenu();
rlm@1 1285 }
rlm@1 1286
rlm@1 1287 void Window::vClearHistoryMenu()
rlm@1 1288 {
rlm@1 1289 Gtk::Menu_Helpers::MenuList::iterator it = m_poRecentMenu->items().begin();
rlm@1 1290 for (int i = 0; i < 3; i++, it++)
rlm@1 1291 ;
rlm@1 1292
rlm@1 1293 m_poRecentMenu->items().erase(it, m_poRecentMenu->items().end());
rlm@1 1294 }
rlm@1 1295
rlm@1 1296 void Window::vUpdateHistoryMenu()
rlm@1 1297 {
rlm@1 1298 vClearHistoryMenu();
rlm@1 1299
rlm@1 1300 guint uiAccelKey = GDK_F1;
rlm@1 1301 for (std::list<std::string>::const_iterator it = m_listHistory.begin();
rlm@1 1302 it != m_listHistory.end();
rlm@1 1303 it++, uiAccelKey++)
rlm@1 1304 {
rlm@1 1305 Gtk::Image * poImage = Gtk::manage(new Gtk::Image(Gtk::Stock::OPEN, Gtk::ICON_SIZE_MENU));
rlm@1 1306 Glib::ustring sLabel = Glib::path_get_basename(*it);
rlm@1 1307 VBA::ImageMenuItem * poIMI = Gtk::manage(new VBA::ImageMenuItem(*poImage, sLabel));
rlm@1 1308
rlm@1 1309 m_oTooltips.set_tip(*poIMI, *it);
rlm@1 1310
rlm@1 1311 poIMI->signal_activate().connect(SigC::bind<std::string>(
rlm@1 1312 SigC::slot(*this, &Window::vOnRecentFile),
rlm@1 1313 *it));
rlm@1 1314
rlm@1 1315 poIMI->set_accel_key(Gtk::AccelKey(uiAccelKey, Gdk::CONTROL_MASK));
rlm@1 1316 poIMI->accelerate(*this);
rlm@1 1317
rlm@1 1318 poIMI->show();
rlm@1 1319 m_poRecentMenu->items().push_back(*poIMI);
rlm@1 1320 }
rlm@1 1321 }
rlm@1 1322
rlm@1 1323 void Window::vLoadJoypadsFromConfig()
rlm@1 1324 {
rlm@1 1325 m_oJoypads.clear();
rlm@1 1326
rlm@1 1327 for (int i = m_iJoypadMin; i <= m_iJoypadMax; i++)
rlm@1 1328 {
rlm@1 1329 char csPrefix[20];
rlm@1 1330 snprintf(csPrefix, sizeof(csPrefix), "joypad%d_", i);
rlm@1 1331 std::string sPrefix(csPrefix);
rlm@1 1332
rlm@1 1333 JoypadConfig oJoypadConfig;
rlm@1 1334 oJoypadConfig.m_uiUp = m_poInputConfig->oGetKey<guint>(sPrefix + "up");
rlm@1 1335 oJoypadConfig.m_uiDown = m_poInputConfig->oGetKey<guint>(sPrefix + "down");
rlm@1 1336 oJoypadConfig.m_uiLeft = m_poInputConfig->oGetKey<guint>(sPrefix + "left");
rlm@1 1337 oJoypadConfig.m_uiRight = m_poInputConfig->oGetKey<guint>(sPrefix + "right");
rlm@1 1338 oJoypadConfig.m_uiA = m_poInputConfig->oGetKey<guint>(sPrefix + "A");
rlm@1 1339 oJoypadConfig.m_uiB = m_poInputConfig->oGetKey<guint>(sPrefix + "B");
rlm@1 1340 oJoypadConfig.m_uiL = m_poInputConfig->oGetKey<guint>(sPrefix + "L");
rlm@1 1341 oJoypadConfig.m_uiR = m_poInputConfig->oGetKey<guint>(sPrefix + "R");
rlm@1 1342 oJoypadConfig.m_uiSelect = m_poInputConfig->oGetKey<guint>(sPrefix + "select");
rlm@1 1343 oJoypadConfig.m_uiStart = m_poInputConfig->oGetKey<guint>(sPrefix + "start");
rlm@1 1344 oJoypadConfig.m_uiSpeed = m_poInputConfig->oGetKey<guint>(sPrefix + "speed");
rlm@1 1345 oJoypadConfig.m_uiCapture = m_poInputConfig->oGetKey<guint>(sPrefix + "capture");
rlm@1 1346
rlm@1 1347 m_oJoypads.push_back(oJoypadConfig);
rlm@1 1348 }
rlm@1 1349 }
rlm@1 1350
rlm@1 1351 void Window::vSaveJoypadsToConfig()
rlm@1 1352 {
rlm@1 1353 for (int i = m_iJoypadMin; i <= m_iJoypadMax; i++)
rlm@1 1354 {
rlm@1 1355 char csPrefix[20];
rlm@1 1356 snprintf(csPrefix, sizeof(csPrefix), "joypad%d_", i);
rlm@1 1357 std::string sPrefix(csPrefix);
rlm@1 1358
rlm@1 1359 m_poInputConfig->vSetKey(sPrefix + "up", m_oJoypads[i - 1].m_uiUp );
rlm@1 1360 m_poInputConfig->vSetKey(sPrefix + "down", m_oJoypads[i - 1].m_uiDown );
rlm@1 1361 m_poInputConfig->vSetKey(sPrefix + "left", m_oJoypads[i - 1].m_uiLeft );
rlm@1 1362 m_poInputConfig->vSetKey(sPrefix + "right", m_oJoypads[i - 1].m_uiRight );
rlm@1 1363 m_poInputConfig->vSetKey(sPrefix + "A", m_oJoypads[i - 1].m_uiA );
rlm@1 1364 m_poInputConfig->vSetKey(sPrefix + "B", m_oJoypads[i - 1].m_uiB );
rlm@1 1365 m_poInputConfig->vSetKey(sPrefix + "L", m_oJoypads[i - 1].m_uiL );
rlm@1 1366 m_poInputConfig->vSetKey(sPrefix + "R", m_oJoypads[i - 1].m_uiR );
rlm@1 1367 m_poInputConfig->vSetKey(sPrefix + "select", m_oJoypads[i - 1].m_uiSelect );
rlm@1 1368 m_poInputConfig->vSetKey(sPrefix + "start", m_oJoypads[i - 1].m_uiStart );
rlm@1 1369 m_poInputConfig->vSetKey(sPrefix + "speed", m_oJoypads[i - 1].m_uiSpeed );
rlm@1 1370 m_poInputConfig->vSetKey(sPrefix + "capture", m_oJoypads[i - 1].m_uiCapture );
rlm@1 1371 }
rlm@1 1372 }
rlm@1 1373
rlm@1 1374 void Window::vUpdateScreen()
rlm@1 1375 {
rlm@1 1376 if (m_eCartridge == CartridgeGB)
rlm@1 1377 {
rlm@1 1378 if (gbBorderOn)
rlm@1 1379 {
rlm@1 1380 m_iScreenWidth = m_iSGBScreenWidth;
rlm@1 1381 m_iScreenHeight = m_iSGBScreenHeight;
rlm@1 1382 gbBorderLineSkip = m_iSGBScreenWidth;
rlm@1 1383 gbBorderColumnSkip = (m_iSGBScreenWidth - m_iGBScreenWidth) / 2;
rlm@1 1384 gbBorderRowSkip = (m_iSGBScreenHeight - m_iGBScreenHeight) / 2;
rlm@1 1385 }
rlm@1 1386 else
rlm@1 1387 {
rlm@1 1388 m_iScreenWidth = m_iGBScreenWidth;
rlm@1 1389 m_iScreenHeight = m_iGBScreenHeight;
rlm@1 1390 gbBorderLineSkip = m_iGBScreenWidth;
rlm@1 1391 gbBorderColumnSkip = 0;
rlm@1 1392 gbBorderRowSkip = 0;
rlm@1 1393 }
rlm@1 1394 }
rlm@1 1395 else if (m_eCartridge == CartridgeGBA)
rlm@1 1396 {
rlm@1 1397 m_iScreenWidth = m_iGBAScreenWidth;
rlm@1 1398 m_iScreenHeight = m_iGBAScreenHeight;
rlm@1 1399 }
rlm@1 1400
rlm@1 1401 g_return_if_fail(m_iScreenWidth >= 1 && m_iScreenHeight >= 1);
rlm@1 1402
rlm@1 1403 m_poScreenArea->vSetSize(m_iScreenWidth, m_iScreenHeight);
rlm@1 1404 m_poScreenArea->vSetScale(m_poDisplayConfig->oGetKey<int>("scale"));
rlm@1 1405
rlm@1 1406 resize(1, 1);
rlm@1 1407
rlm@1 1408 if (emulating)
rlm@1 1409 {
rlm@1 1410 vDrawScreen();
rlm@1 1411 }
rlm@1 1412 else
rlm@1 1413 {
rlm@1 1414 vDrawDefaultScreen();
rlm@1 1415 }
rlm@1 1416 }
rlm@1 1417
rlm@1 1418 bool Window::bLoadROM(const std::string & _rsFile)
rlm@1 1419 {
rlm@1 1420 vOnFileClose();
rlm@1 1421
rlm@1 1422 m_sRomFile = _rsFile;
rlm@1 1423 const char * csFile = _rsFile.c_str();
rlm@1 1424
rlm@1 1425 IMAGE_TYPE eType = utilFindType(csFile);
rlm@1 1426 if (eType == IMAGE_UNKNOWN)
rlm@1 1427 {
rlm@1 1428 vPopupError(_("Unknown file type %s"), csFile);
rlm@1 1429 return false;
rlm@1 1430 }
rlm@1 1431
rlm@1 1432 bool bLoaded = false;
rlm@1 1433 if (eType == IMAGE_GB)
rlm@1 1434 {
rlm@1 1435 bLoaded = gbLoadRom(csFile);
rlm@1 1436 if (bLoaded)
rlm@1 1437 {
rlm@1 1438 m_eCartridge = CartridgeGB;
rlm@1 1439 m_stEmulator = GBSystem;
rlm@1 1440 }
rlm@1 1441 }
rlm@1 1442 else if (eType == IMAGE_GBA)
rlm@1 1443 {
rlm@1 1444 int iSize = CPULoadRom(csFile);
rlm@1 1445 bLoaded = (iSize > 0);
rlm@1 1446 if (bLoaded)
rlm@1 1447 {
rlm@1 1448 m_eCartridge = CartridgeGBA;
rlm@1 1449 m_stEmulator = GBASystem;
rlm@1 1450
rlm@1 1451 useBios = m_poCoreConfig->oGetKey<bool>("use_bios_file");
rlm@1 1452 //CPUInit(m_poCoreConfig->sGetKey("bios_file").c_str(), useBios);
rlm@1 1453 CPUInit();
rlm@1 1454 CPUReset();
rlm@1 1455
rlm@1 1456 // If the bios file was rejected by CPUInit
rlm@1 1457 if (m_poCoreConfig->oGetKey<bool>("use_bios_file") && ! useBios)
rlm@1 1458 {
rlm@1 1459 m_poUseBiosItem->set_active(false);
rlm@1 1460 m_poUseBiosItem->set_sensitive(false);
rlm@1 1461 m_poCoreConfig->vSetKey("bios_file", "");
rlm@1 1462 }
rlm@1 1463 }
rlm@1 1464 }
rlm@1 1465
rlm@1 1466 if (! bLoaded)
rlm@1 1467 {
rlm@1 1468 return false;
rlm@1 1469 }
rlm@1 1470
rlm@1 1471 vLoadBattery();
rlm@1 1472 vUpdateScreen();
rlm@1 1473
rlm@1 1474 debugger = false; // May cause conflicts
rlm@1 1475 emulating = 1;
rlm@1 1476 m_bWasEmulating = false;
rlm@1 1477 m_uiThrottleDelay = 0;
rlm@1 1478
rlm@1 1479 if (m_eCartridge == CartridgeGBA)
rlm@1 1480 {
rlm@1 1481 soundSetQuality(m_eSoundQuality);
rlm@1 1482 }
rlm@1 1483 else
rlm@1 1484 {
rlm@1 1485 gbSoundSetQuality(m_eSoundQuality);
rlm@1 1486 }
rlm@1 1487
rlm@1 1488 vUpdateGameSlots();
rlm@1 1489 vHistoryAdd(_rsFile);
rlm@1 1490
rlm@1 1491 for (std::list<Gtk::Widget *>::iterator it = m_listSensitiveWhenPlaying.begin();
rlm@1 1492 it != m_listSensitiveWhenPlaying.end();
rlm@1 1493 it++)
rlm@1 1494 {
rlm@1 1495 (*it)->set_sensitive();
rlm@1 1496 }
rlm@1 1497
rlm@1 1498 if (m_poCoreConfig->oGetKey<bool>("load_game_auto"))
rlm@1 1499 {
rlm@1 1500 vOnLoadGameMostRecent();
rlm@1 1501 }
rlm@1 1502
rlm@1 1503 vStartEmu();
rlm@1 1504
rlm@1 1505 return true;
rlm@1 1506 }
rlm@1 1507
rlm@1 1508 void Window::vPopupError(const char * _csFormat, ...)
rlm@1 1509 {
rlm@1 1510 va_list args;
rlm@1 1511 va_start(args, _csFormat);
rlm@1 1512 char * csMsg = g_strdup_vprintf(_csFormat, args);
rlm@1 1513 va_end(args);
rlm@1 1514
rlm@1 1515 Gtk::MessageDialog oDialog(*this,
rlm@1 1516 csMsg,
rlm@1 1517 #ifndef GTKMM20
rlm@1 1518 false,
rlm@1 1519 #endif // ! GTKMM20
rlm@1 1520 Gtk::MESSAGE_ERROR,
rlm@1 1521 Gtk::BUTTONS_OK);
rlm@1 1522 oDialog.run();
rlm@1 1523 g_free(csMsg);
rlm@1 1524 }
rlm@1 1525
rlm@1 1526 void Window::vPopupErrorV(const char * _csFormat, va_list _args)
rlm@1 1527 {
rlm@1 1528 char * csMsg = g_strdup_vprintf(_csFormat, _args);
rlm@1 1529
rlm@1 1530 Gtk::MessageDialog oDialog(*this,
rlm@1 1531 csMsg,
rlm@1 1532 #ifndef GTKMM20
rlm@1 1533 false,
rlm@1 1534 #endif // ! GTKMM20
rlm@1 1535 Gtk::MESSAGE_ERROR,
rlm@1 1536 Gtk::BUTTONS_OK);
rlm@1 1537 oDialog.run();
rlm@1 1538 g_free(csMsg);
rlm@1 1539 }
rlm@1 1540
rlm@1 1541 void Window::vDrawScreen()
rlm@1 1542 {
rlm@1 1543 m_poScreenArea->vDrawPixels(pix);
rlm@1 1544 }
rlm@1 1545
rlm@1 1546 void Window::vDrawDefaultScreen()
rlm@1 1547 {
rlm@1 1548 m_poScreenArea->vDrawColor(0x000000); // Black
rlm@1 1549 }
rlm@1 1550
rlm@1 1551 void Window::vSetDefaultTitle()
rlm@1 1552 {
rlm@1 1553 set_title("VBA");
rlm@1 1554 }
rlm@1 1555
rlm@1 1556 void Window::vShowSpeed(int _iSpeed)
rlm@1 1557 {
rlm@1 1558 char csTitle[50];
rlm@1 1559
rlm@1 1560 if (m_eShowSpeed == ShowPercentage)
rlm@1 1561 {
rlm@1 1562 snprintf(csTitle, 50, "VBA - %d%%", _iSpeed);
rlm@1 1563 set_title(csTitle);
rlm@1 1564 }
rlm@1 1565 else if (m_eShowSpeed == ShowDetailed)
rlm@1 1566 {
rlm@1 1567 snprintf(csTitle, 50, "VBA - %d%% (%d, %d fps)",
rlm@1 1568 _iSpeed, systemFrameSkip, systemFPS);
rlm@1 1569 set_title(csTitle);
rlm@1 1570 }
rlm@1 1571 }
rlm@1 1572
rlm@1 1573 void Window::vComputeFrameskip(int _iRate)
rlm@1 1574 {
rlm@1 1575 static u32 uiLastTime = 0;
rlm@1 1576 static int iFrameskipAdjust = 0;
rlm@1 1577
rlm@1 1578 u32 uiTime = SDL_GetTicks();
rlm@1 1579
rlm@1 1580 if (m_bWasEmulating)
rlm@1 1581 {
rlm@1 1582 int iWantedSpeed = 100;
rlm@1 1583
rlm@1 1584 if (m_iThrottle > 0)
rlm@1 1585 {
rlm@1 1586 if (! speedup)
rlm@1 1587 {
rlm@1 1588 u32 uiDiff = uiTime - m_uiThrottleLastTime;
rlm@1 1589 int iTarget = 1000000 / (_iRate * m_iThrottle);
rlm@1 1590 int iDelay = iTarget - uiDiff;
rlm@1 1591 if (iDelay > 0)
rlm@1 1592 {
rlm@1 1593 m_uiThrottleDelay = iDelay;
rlm@1 1594 }
rlm@1 1595 }
rlm@1 1596 iWantedSpeed = m_iThrottle;
rlm@1 1597 }
rlm@1 1598
rlm@1 1599 if (m_bAutoFrameskip)
rlm@1 1600 {
rlm@1 1601 u32 uiDiff = uiTime - uiLastTime;
rlm@1 1602 int iSpeed = iWantedSpeed;
rlm@1 1603
rlm@1 1604 if (uiDiff != 0)
rlm@1 1605 {
rlm@1 1606 iSpeed = (1000000 / _iRate) / uiDiff;
rlm@1 1607 }
rlm@1 1608
rlm@1 1609 if (iSpeed >= iWantedSpeed - 2)
rlm@1 1610 {
rlm@1 1611 iFrameskipAdjust++;
rlm@1 1612 if (iFrameskipAdjust >= 3)
rlm@1 1613 {
rlm@1 1614 iFrameskipAdjust = 0;
rlm@1 1615 if (systemFrameSkip > 0)
rlm@1 1616 {
rlm@1 1617 systemFrameSkip--;
rlm@1 1618 }
rlm@1 1619 }
rlm@1 1620 }
rlm@1 1621 else
rlm@1 1622 {
rlm@1 1623 if (iSpeed < iWantedSpeed - 20)
rlm@1 1624 {
rlm@1 1625 iFrameskipAdjust -= ((iWantedSpeed - 10) - iSpeed) / 5;
rlm@1 1626 }
rlm@1 1627 else if (systemFrameSkip < 9)
rlm@1 1628 {
rlm@1 1629 iFrameskipAdjust--;
rlm@1 1630 }
rlm@1 1631
rlm@1 1632 if (iFrameskipAdjust <= -2)
rlm@1 1633 {
rlm@1 1634 iFrameskipAdjust += 2;
rlm@1 1635 if (systemFrameSkip < 9)
rlm@1 1636 {
rlm@1 1637 systemFrameSkip++;
rlm@1 1638 }
rlm@1 1639 }
rlm@1 1640 }
rlm@1 1641 }
rlm@1 1642 }
rlm@1 1643 else
rlm@1 1644 {
rlm@1 1645 m_bWasEmulating = true;
rlm@1 1646 }
rlm@1 1647
rlm@1 1648 uiLastTime = uiTime;
rlm@1 1649 m_uiThrottleLastTime = uiTime;
rlm@1 1650 }
rlm@1 1651
rlm@1 1652 void Window::vCaptureScreen(int _iNum)
rlm@1 1653 {
rlm@1 1654 std::string sBaseName;
rlm@1 1655 std::string sCaptureDir = m_poDirConfig->sGetKey("captures");
rlm@1 1656 if (sCaptureDir == "")
rlm@1 1657 {
rlm@1 1658 sBaseName = sCutSuffix(m_sRomFile);
rlm@1 1659 }
rlm@1 1660 else
rlm@1 1661 {
rlm@1 1662 sBaseName = sCaptureDir + "/" + sCutSuffix(Glib::path_get_basename(m_sRomFile));
rlm@1 1663 }
rlm@1 1664 std::string sFormat = m_poCoreConfig->sGetKey("screenshot_format");
rlm@1 1665
rlm@1 1666 char * csFile = g_strdup_printf("%s_%02d.%s",
rlm@1 1667 sBaseName.c_str(),
rlm@1 1668 _iNum,
rlm@1 1669 sFormat.c_str());
rlm@1 1670 if (sFormat == "png")
rlm@1 1671 {
rlm@1 1672 m_stEmulator.emuWritePNG(csFile);
rlm@1 1673 }
rlm@1 1674 else
rlm@1 1675 {
rlm@1 1676 m_stEmulator.emuWriteBMP(csFile);
rlm@1 1677 }
rlm@1 1678 g_free(csFile);
rlm@1 1679 }
rlm@1 1680
rlm@1 1681 u32 Window::uiReadJoypad()
rlm@1 1682 {
rlm@1 1683 u32 uiJoypad = m_uiJoypadState;
rlm@1 1684
rlm@1 1685 if (m_uiAutofireState != 0)
rlm@1 1686 {
rlm@1 1687 uiJoypad &= ~m_uiAutofireState;
rlm@1 1688 if (m_bAutofireToggle)
rlm@1 1689 {
rlm@1 1690 uiJoypad |= m_uiAutofireState;
rlm@1 1691 }
rlm@1 1692 m_bAutofireToggle = ! m_bAutofireToggle;
rlm@1 1693 }
rlm@1 1694
rlm@1 1695 return uiJoypad;
rlm@1 1696 }
rlm@1 1697
rlm@1 1698 void Window::vCreateFileOpenDialog()
rlm@1 1699 {
rlm@1 1700 if (m_poFileOpenDialog != NULL)
rlm@1 1701 {
rlm@1 1702 return;
rlm@1 1703 }
rlm@1 1704
rlm@1 1705 std::string sGBDir = m_poDirConfig->sGetKey("gb_roms");
rlm@1 1706 std::string sGBADir = m_poDirConfig->sGetKey("gba_roms");
rlm@1 1707
rlm@1 1708 #ifdef GTKMM20
rlm@1 1709
rlm@1 1710 Gtk::FileSelection * poDialog = new Gtk::FileSelection(_("Open"));
rlm@1 1711 poDialog->set_transient_for(*this);
rlm@1 1712
rlm@1 1713 if (sGBADir != "")
rlm@1 1714 {
rlm@1 1715 poDialog->set_filename(sGBADir + "/");
rlm@1 1716 }
rlm@1 1717 else if (sGBDir != "")
rlm@1 1718 {
rlm@1 1719 poDialog->set_filename(sGBDir + "/");
rlm@1 1720 }
rlm@1 1721
rlm@1 1722 #else // ! GTKMM20
rlm@1 1723
rlm@1 1724 Gtk::FileChooserDialog * poDialog = new Gtk::FileChooserDialog(*this, _("Open"));
rlm@1 1725 poDialog->add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
rlm@1 1726 poDialog->add_button(Gtk::Stock::OPEN, Gtk::RESPONSE_OK);
rlm@1 1727
rlm@1 1728 if (sGBDir != "")
rlm@1 1729 {
rlm@1 1730 poDialog->add_shortcut_folder(sGBDir);
rlm@1 1731 poDialog->set_current_folder(sGBDir);
rlm@1 1732 }
rlm@1 1733
rlm@1 1734 if (sGBADir != "" && sGBADir != sGBDir)
rlm@1 1735 {
rlm@1 1736 poDialog->add_shortcut_folder(sGBADir);
rlm@1 1737 poDialog->set_current_folder(sGBADir);
rlm@1 1738 }
rlm@1 1739
rlm@1 1740 const char * acsPattern[] =
rlm@1 1741 {
rlm@1 1742 // GBA
rlm@1 1743 "*.[bB][iI][nN]", "*.[aA][gG][bB]", "*.[gG][bB][aA]",
rlm@1 1744 // GB
rlm@1 1745 "*.[gG][bB]", "*.[sS][gG][bB]", "*.[cC][gG][bB]", "*.[gG][bB][cC]",
rlm@1 1746 // Both
rlm@1 1747 "*.[mM][bB]", "*.[eE][lL][fF]", "*.[zZ][iI][pP]", "*.[zZ]", "*.[gG][zZ]"
rlm@1 1748 };
rlm@1 1749
rlm@1 1750 Gtk::FileFilter oAllGBAFilter;
rlm@1 1751 oAllGBAFilter.set_name(_("All Gameboy Advance files"));
rlm@1 1752 for (guint i = 0; i < G_N_ELEMENTS(acsPattern); i++)
rlm@1 1753 {
rlm@1 1754 oAllGBAFilter.add_pattern(acsPattern[i]);
rlm@1 1755 }
rlm@1 1756
rlm@1 1757 Gtk::FileFilter oGBAFilter;
rlm@1 1758 oGBAFilter.set_name(_("Gameboy Advance files"));
rlm@1 1759 for (int i = 0; i < 3; i++)
rlm@1 1760 {
rlm@1 1761 oGBAFilter.add_pattern(acsPattern[i]);
rlm@1 1762 }
rlm@1 1763
rlm@1 1764 Gtk::FileFilter oGBFilter;
rlm@1 1765 oGBFilter.set_name(_("Gameboy files"));
rlm@1 1766 for (int i = 3; i < 7; i++)
rlm@1 1767 {
rlm@1 1768 oGBFilter.add_pattern(acsPattern[i]);
rlm@1 1769 }
rlm@1 1770
rlm@1 1771 poDialog->add_filter(oAllGBAFilter);
rlm@1 1772 poDialog->add_filter(oGBAFilter);
rlm@1 1773 poDialog->add_filter(oGBFilter);
rlm@1 1774
rlm@1 1775 #endif // ! GTKMM20
rlm@1 1776
rlm@1 1777 m_poFileOpenDialog = poDialog;
rlm@1 1778 }
rlm@1 1779
rlm@1 1780 void Window::vLoadBattery()
rlm@1 1781 {
rlm@1 1782 std::string sBattery;
rlm@1 1783 std::string sDir = m_poDirConfig->sGetKey("batteries");
rlm@1 1784 if (sDir == "")
rlm@1 1785 {
rlm@1 1786 sBattery = sCutSuffix(m_sRomFile) + ".sav";
rlm@1 1787 }
rlm@1 1788 else
rlm@1 1789 {
rlm@1 1790 sBattery = sDir + "/" + sCutSuffix(Glib::path_get_basename(m_sRomFile)) + ".sav";
rlm@1 1791 }
rlm@1 1792
rlm@1 1793 if (m_stEmulator.emuReadBattery(sBattery.c_str()))
rlm@1 1794 {
rlm@1 1795 systemScreenMessage(_("Loaded battery"));
rlm@1 1796 }
rlm@1 1797 }
rlm@1 1798
rlm@1 1799 void Window::vSaveBattery()
rlm@1 1800 {
rlm@1 1801 std::string sBattery;
rlm@1 1802 std::string sDir = m_poDirConfig->sGetKey("batteries");
rlm@1 1803 if (sDir == "")
rlm@1 1804 {
rlm@1 1805 sBattery = sCutSuffix(m_sRomFile) + ".sav";
rlm@1 1806 }
rlm@1 1807 else
rlm@1 1808 {
rlm@1 1809 sBattery = sDir + "/" + sCutSuffix(Glib::path_get_basename(m_sRomFile)) + ".sav";
rlm@1 1810 }
rlm@1 1811
rlm@1 1812 if (m_stEmulator.emuWriteBattery(sBattery.c_str()))
rlm@1 1813 {
rlm@1 1814 systemScreenMessage(_("Saved battery"));
rlm@1 1815 }
rlm@1 1816 }
rlm@1 1817
rlm@1 1818 void Window::vStartEmu()
rlm@1 1819 {
rlm@1 1820 if (m_oEmuSig.connected())
rlm@1 1821 {
rlm@1 1822 return;
rlm@1 1823 }
rlm@1 1824
rlm@1 1825 m_oEmuSig = Glib::signal_idle().connect(SigC::slot(*this, &Window::bOnEmuIdle),
rlm@1 1826 Glib::PRIORITY_DEFAULT_IDLE);
rlm@1 1827 }
rlm@1 1828
rlm@1 1829 void Window::vStopEmu()
rlm@1 1830 {
rlm@1 1831 m_oEmuSig.disconnect();
rlm@1 1832 m_bWasEmulating = false;
rlm@1 1833 }
rlm@1 1834
rlm@1 1835 void Window::vSetThrottle(int _iPercent)
rlm@1 1836 {
rlm@1 1837 m_iThrottle = _iPercent;
rlm@1 1838 m_poCoreConfig->vSetKey("throttle", _iPercent);
rlm@1 1839 }
rlm@1 1840
rlm@1 1841 void Window::vSelectBestThrottleItem()
rlm@1 1842 {
rlm@1 1843 struct
rlm@1 1844 {
rlm@1 1845 const char * m_csName;
rlm@1 1846 const int m_iThrottle;
rlm@1 1847 }
rlm@1 1848 astThrottle[] =
rlm@1 1849 {
rlm@1 1850 { "ThrottleNoThrottle", 0 },
rlm@1 1851 { "Throttle25", 25 },
rlm@1 1852 { "Throttle50", 50 },
rlm@1 1853 { "Throttle100", 100 },
rlm@1 1854 { "Throttle150", 150 },
rlm@1 1855 { "Throttle200", 200 }
rlm@1 1856 };
rlm@1 1857 for (guint i = 0; i < G_N_ELEMENTS(astThrottle); i++)
rlm@1 1858 {
rlm@1 1859 Gtk::CheckMenuItem * poCMI;
rlm@1 1860 poCMI = dynamic_cast<Gtk::CheckMenuItem *>(m_poXml->get_widget(astThrottle[i].m_csName));
rlm@1 1861 if (astThrottle[i].m_iThrottle == m_iThrottle)
rlm@1 1862 {
rlm@1 1863 poCMI->set_active();
rlm@1 1864 }
rlm@1 1865 }
rlm@1 1866 }
rlm@1 1867
rlm@1 1868 void Window::vUpdateGameSlots()
rlm@1 1869 {
rlm@1 1870 if (m_eCartridge == CartridgeNone)
rlm@1 1871 {
rlm@1 1872 std::string sDateTime = _("----/--/-- --:--:--");
rlm@1 1873
rlm@1 1874 for (int i = 0; i < 10; i++)
rlm@1 1875 {
rlm@1 1876 char csPrefix[10];
rlm@1 1877 snprintf(csPrefix, sizeof(csPrefix), "%2d ", i + 1);
rlm@1 1878
rlm@1 1879 Gtk::Label * poLabel;
rlm@1 1880 poLabel = dynamic_cast<Gtk::Label *>(m_apoLoadGameItem[i]->get_child());
rlm@1 1881 poLabel->set_text(csPrefix + sDateTime);
rlm@1 1882 m_apoLoadGameItem[i]->set_sensitive(false);
rlm@1 1883
rlm@1 1884 poLabel = dynamic_cast<Gtk::Label *>(m_apoSaveGameItem[i]->get_child());
rlm@1 1885 poLabel->set_text(csPrefix + sDateTime);
rlm@1 1886 m_apoSaveGameItem[i]->set_sensitive(false);
rlm@1 1887
rlm@1 1888 m_astGameSlot[i].m_bEmpty = true;
rlm@1 1889 }
rlm@1 1890 }
rlm@1 1891 else
rlm@1 1892 {
rlm@1 1893 std::string sFileBase;
rlm@1 1894 std::string sDir = m_poDirConfig->sGetKey("saves");
rlm@1 1895 if (sDir == "")
rlm@1 1896 {
rlm@1 1897 sFileBase = sCutSuffix(m_sRomFile);
rlm@1 1898 }
rlm@1 1899 else
rlm@1 1900 {
rlm@1 1901 sFileBase = sDir + "/" + sCutSuffix(Glib::path_get_basename(m_sRomFile));
rlm@1 1902 }
rlm@1 1903
rlm@1 1904 const char * csDateFormat = _("%Y/%m/%d %H:%M:%S");
rlm@1 1905
rlm@1 1906 for (int i = 0; i < 10; i++)
rlm@1 1907 {
rlm@1 1908 char csPrefix[10];
rlm@1 1909 snprintf(csPrefix, sizeof(csPrefix), "%2d ", i + 1);
rlm@1 1910
rlm@1 1911 char csSlot[10];
rlm@1 1912 snprintf(csSlot, sizeof(csSlot), "%d", i + 1);
rlm@1 1913 m_astGameSlot[i].m_sFile = sFileBase + csSlot + ".sgm";
rlm@1 1914
rlm@1 1915 std::string sDateTime;
rlm@1 1916 struct stat stStat;
rlm@1 1917 if (stat(m_astGameSlot[i].m_sFile.c_str(), &stStat) == -1)
rlm@1 1918 {
rlm@1 1919 sDateTime = _("----/--/-- --:--:--");
rlm@1 1920 m_astGameSlot[i].m_bEmpty = true;
rlm@1 1921 }
rlm@1 1922 else
rlm@1 1923 {
rlm@1 1924 char csDateTime[30];
rlm@1 1925 strftime(csDateTime, sizeof(csDateTime), csDateFormat,
rlm@1 1926 localtime(&stStat.st_mtime));
rlm@1 1927 sDateTime = csDateTime;
rlm@1 1928 m_astGameSlot[i].m_bEmpty = false;
rlm@1 1929 m_astGameSlot[i].m_uiTime = stStat.st_mtime;
rlm@1 1930 }
rlm@1 1931
rlm@1 1932 Gtk::Label * poLabel;
rlm@1 1933 poLabel = dynamic_cast<Gtk::Label *>(m_apoLoadGameItem[i]->get_child());
rlm@1 1934 poLabel->set_text(csPrefix + sDateTime);
rlm@1 1935 m_apoLoadGameItem[i]->set_sensitive(! m_astGameSlot[i].m_bEmpty);
rlm@1 1936
rlm@1 1937 poLabel = dynamic_cast<Gtk::Label *>(m_apoSaveGameItem[i]->get_child());
rlm@1 1938 poLabel->set_text(csPrefix + sDateTime);
rlm@1 1939 m_apoSaveGameItem[i]->set_sensitive();
rlm@1 1940 }
rlm@1 1941 }
rlm@1 1942 }
rlm@1 1943
rlm@1 1944 } // VBA namespace