home *** CD-ROM | disk | FTP | other *** search
/ Chip 2004 July / CMCD0704.ISO / Software / Freeware / Utilitare / VisualBoyAdvance-1.7.2 / src / gtk / windowcallbacks.cpp < prev   
Encoding:
C/C++ Source or Header  |  2004-05-11  |  34.5 KB  |  1,580 lines

  1. // VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
  2. // Copyright (C) 1999-2003 Forgotten
  3. // Copyright (C) 2004 Forgotten and the VBA development team
  4.  
  5. // This program is free software; you can redistribute it and/or modify
  6. // it under the terms of the GNU General Public License as published by
  7. // the Free Software Foundation; either version 2, or(at your option)
  8. // any later version.
  9. //
  10. // This program is distributed in the hope that it will be useful,
  11. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13. // GNU General Public License for more details.
  14. //
  15. // You should have received a copy of the GNU General Public License
  16. // along with this program; if not, write to the Free Software Foundation,
  17. // Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  18.  
  19. #include "window.h"
  20.  
  21. #include <sys/stat.h>
  22.  
  23. #include <stdio.h>
  24. #include <time.h>
  25.  
  26. #include <SDL.h>
  27.  
  28. #include "../GBA.h"
  29. #include "../gb/GB.h"
  30. #include "../gb/gbGlobals.h"
  31. #include "../gb/gbPrinter.h"
  32. #include "../Sound.h"
  33. #include "../Util.h"
  34.  
  35. #include "tools.h"
  36. #include "intl.h"
  37.  
  38. extern int systemRenderedFrames;
  39. extern int systemFPS;
  40. extern bool debugger;
  41. extern int RGB_LOW_BITS_MASK;
  42. extern void (*dbgMain)();
  43. extern void (*dbgSignal)(int, int);
  44. extern void (*dbgOutput)(char *, u32);
  45. extern void remoteInit();
  46. extern void remoteCleanUp();
  47. extern void remoteStubMain();
  48. extern void remoteStubSignal(int, int);
  49. extern void remoteOutput(char *, u32);
  50. extern void remoteSetProtocol(int);
  51. extern void remoteSetPort(int);
  52.  
  53. #ifdef MMX
  54. extern "C" bool cpu_mmx;
  55. #endif // MMX
  56.  
  57. namespace VBA
  58. {
  59.  
  60. using Gnome::Glade::Xml;
  61.  
  62. void Window::vOnFileOpen()
  63. {
  64.   while (m_poFileOpenDialog->run() == Gtk::RESPONSE_OK)
  65.   {
  66.     if (bLoadROM(m_poFileOpenDialog->get_filename()))
  67.     {
  68.       break;
  69.     }
  70.   }
  71.   m_poFileOpenDialog->hide();
  72. }
  73.  
  74. void Window::vOnFileLoad()
  75. {
  76.   std::string sSaveDir = m_poDirConfig->sGetKey("saves");
  77.  
  78. #ifdef GTKMM20
  79.  
  80.   Gtk::FileSelection oDialog(_("Load game"));
  81.   oDialog.set_transient_for(*this);
  82.  
  83.   if (sSaveDir == "")
  84.   {
  85.     oDialog.set_filename(Glib::path_get_dirname(m_sRomFile) + "/");
  86.   }
  87.   else
  88.   {
  89.     oDialog.set_filename(sSaveDir + "/");
  90.   }
  91.  
  92. #else // ! GTKMM20
  93.  
  94.   Gtk::FileChooserDialog oDialog(*this, _("Load game"));
  95.   oDialog.add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
  96.   oDialog.add_button(Gtk::Stock::OPEN,   Gtk::RESPONSE_OK);
  97.  
  98.   if (sSaveDir == "")
  99.   {
  100.     oDialog.set_current_folder(Glib::path_get_dirname(m_sRomFile));
  101.   }
  102.   else
  103.   {
  104.     oDialog.set_current_folder(sSaveDir);
  105.     oDialog.add_shortcut_folder(sSaveDir);
  106.   }
  107.  
  108.   Gtk::FileFilter oSaveFilter;
  109.   oSaveFilter.set_name(_("VisualBoyAdvance save game"));
  110.   oSaveFilter.add_pattern("*.[sS][gG][mM]");
  111.  
  112.   oDialog.add_filter(oSaveFilter);
  113.  
  114. #endif // ! GTKMM20
  115.  
  116.   while (oDialog.run() == Gtk::RESPONSE_OK)
  117.   {
  118.     if (m_stEmulator.emuReadState(oDialog.get_filename().c_str()))
  119.     {
  120.       break;
  121.     }
  122.   }
  123. }
  124.  
  125. void Window::vOnFileSave()
  126. {
  127.   Glib::ustring sSaveDir = m_poDirConfig->sGetKey("saves");
  128.  
  129. #ifdef GTKMM20
  130.  
  131.   Gtk::FileSelection oDialog(_("Save game"));
  132.   oDialog.set_transient_for(*this);
  133.  
  134.   if (sSaveDir == "")
  135.   {
  136.     oDialog.set_filename(sCutSuffix(m_sRomFile));
  137.   }
  138.   else
  139.   {
  140.     oDialog.set_filename(sSaveDir + "/" +
  141.                          sCutSuffix(Glib::path_get_basename(m_sRomFile)));
  142.   }
  143.  
  144. #else // ! GTKMM20
  145.  
  146.   Gtk::FileChooserDialog oDialog(*this, _("Save game"),
  147.                                  Gtk::FILE_CHOOSER_ACTION_SAVE);
  148.   oDialog.add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
  149.   oDialog.add_button(Gtk::Stock::SAVE,   Gtk::RESPONSE_OK);
  150.  
  151.   if (sSaveDir == "")
  152.   {
  153.     oDialog.set_current_folder(Glib::path_get_dirname(m_sRomFile));
  154.   }
  155.   else
  156.   {
  157.     oDialog.set_current_folder(sSaveDir);
  158.     oDialog.add_shortcut_folder(sSaveDir);
  159.   }
  160.   oDialog.set_current_name(sCutSuffix(Glib::path_get_basename(m_sRomFile)));
  161.  
  162.   Gtk::FileFilter oSaveFilter;
  163.   oSaveFilter.set_name(_("VisualBoyAdvance save game"));
  164.   oSaveFilter.add_pattern("*.[sS][gG][mM]");
  165.  
  166.   oDialog.add_filter(oSaveFilter);
  167.  
  168. #endif // ! GTKMM20
  169.  
  170.   while (oDialog.run() == Gtk::RESPONSE_OK)
  171.   {
  172.     Glib::ustring sFile = oDialog.get_filename();
  173.     if (! bHasSuffix(sFile, ".sgm", false))
  174.     {
  175.       sFile += ".sgm";
  176.     }
  177.  
  178.     if (Glib::file_test(sFile, Glib::FILE_TEST_EXISTS))
  179.     {
  180.       Gtk::MessageDialog oConfirmDialog(*this,
  181.                                         _("File already exists. Overwrite it?"),
  182. #ifndef GTKMM20
  183.                                         false,
  184. #endif // ! GTKMM20
  185.                                         Gtk::MESSAGE_QUESTION,
  186.                                         Gtk::BUTTONS_YES_NO);
  187.       if (oConfirmDialog.run() != Gtk::RESPONSE_YES)
  188.       {
  189.         continue;
  190.       }
  191.     }
  192.  
  193.     if (m_stEmulator.emuWriteState(sFile.c_str()))
  194.     {
  195.       break;
  196.     }
  197.   }
  198. }
  199.  
  200. void Window::vOnLoadGameMostRecent()
  201. {
  202.   int    iMostRecent = -1;
  203.   time_t uiTimeMax;
  204.  
  205.   for (int i = 0; i < 10; i++)
  206.   {
  207.     if (! m_astGameSlot[i].m_bEmpty
  208.         && (iMostRecent < 0 || m_astGameSlot[i].m_uiTime > uiTimeMax))
  209.     {
  210.       iMostRecent = i;
  211.       uiTimeMax = m_astGameSlot[i].m_uiTime;
  212.     }
  213.   }
  214.  
  215.   if (iMostRecent >= 0)
  216.   {
  217.     vOnLoadGame(iMostRecent + 1);
  218.   }
  219. }
  220.  
  221. void Window::vOnLoadGameAutoToggled(Gtk::CheckMenuItem * _poCMI)
  222. {
  223.   m_poCoreConfig->vSetKey("load_game_auto", _poCMI->get_active());
  224. }
  225.  
  226. void Window::vOnLoadGame(int _iSlot)
  227. {
  228.   int i = _iSlot - 1;
  229.   if (! m_astGameSlot[i].m_bEmpty)
  230.   {
  231.     m_stEmulator.emuReadState(m_astGameSlot[i].m_sFile.c_str());
  232.     m_poFilePauseItem->set_active(false);
  233.   }
  234. }
  235.  
  236. void Window::vOnSaveGameOldest()
  237. {
  238.   int    iOldest = -1;
  239.   time_t uiTimeMin;
  240.  
  241.   for (int i = 0; i < 10; i++)
  242.   {
  243.     if (! m_astGameSlot[i].m_bEmpty
  244.         && (iOldest < 0 || m_astGameSlot[i].m_uiTime < uiTimeMin))
  245.     {
  246.       iOldest = i;
  247.       uiTimeMin = m_astGameSlot[i].m_uiTime;
  248.     }
  249.   }
  250.  
  251.   if (iOldest >= 0)
  252.   {
  253.     vOnSaveGame(iOldest + 1);
  254.   }
  255.   else
  256.   {
  257.     vOnSaveGame(1);
  258.   }
  259. }
  260.  
  261. void Window::vOnSaveGame(int _iSlot)
  262. {
  263.   int i = _iSlot - 1;
  264.   m_stEmulator.emuWriteState(m_astGameSlot[i].m_sFile.c_str());
  265.   vUpdateGameSlots();
  266. }
  267.  
  268. void Window::vOnFilePauseToggled(Gtk::CheckMenuItem * _poCMI)
  269. {
  270.   m_bPaused = _poCMI->get_active();
  271.   if (emulating)
  272.   {
  273.     if (m_bPaused)
  274.     {
  275.       vStopEmu();
  276.       soundPause();
  277.     }
  278.     else
  279.     {
  280.       vStartEmu();
  281.       soundResume();
  282.     }
  283.   }
  284. }
  285.  
  286. void Window::vOnFileReset()
  287. {
  288.   if (emulating)
  289.   {
  290.     m_stEmulator.emuReset();
  291.     m_poFilePauseItem->set_active(false);
  292.   }
  293. }
  294.  
  295. void Window::vOnRecentReset()
  296. {
  297.   m_listHistory.clear();
  298.   vClearHistoryMenu();
  299. }
  300.  
  301. void Window::vOnRecentFreezeToggled(Gtk::CheckMenuItem * _poCMI)
  302. {
  303.   m_poRecentResetItem->set_sensitive(! _poCMI->get_active());
  304.   m_poHistoryConfig->vSetKey("freeze", _poCMI->get_active());
  305. }
  306.  
  307. void Window::vOnRecentFile(std::string _sFile)
  308. {
  309.   bLoadROM(_sFile);
  310. }
  311.  
  312. void Window::vOnImportBatteryFile()
  313. {
  314.   std::string BatteryDir = m_poDirConfig->sGetKey("batteries");
  315.  
  316. #ifdef GTKMM20
  317.  
  318.   Gtk::FileSelection oDialog(_("Import battery file"));
  319.   oDialog.set_transient_for(*this);
  320.  
  321.   if (BatteryDir == "")
  322.   {
  323.     oDialog.set_filename(Glib::path_get_dirname(m_sRomFile) + "/");
  324.   }
  325.   else
  326.   {
  327.     oDialog.set_filename(BatteryDir + "/");
  328.   }
  329.  
  330. #else // ! GTKMM20
  331.  
  332.   Gtk::FileChooserDialog oDialog(*this, _("Import battery file"));
  333.   oDialog.add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
  334.   oDialog.add_button(Gtk::Stock::OPEN,   Gtk::RESPONSE_OK);
  335.  
  336.   if (BatteryDir == "")
  337.   {
  338.     oDialog.set_current_folder(Glib::path_get_dirname(m_sRomFile));
  339.   }
  340.   else
  341.   {
  342.     oDialog.set_current_folder(BatteryDir);
  343.     oDialog.add_shortcut_folder(BatteryDir);
  344.   }
  345.  
  346.   Gtk::FileFilter oBatteryFilter;
  347.   oBatteryFilter.set_name(_("Battery file"));
  348.   oBatteryFilter.add_pattern("*.[sS][aA][vV]");
  349.  
  350.   Gtk::FileFilter oFlashFilter;
  351.   oFlashFilter.set_name(_("Flash save"));
  352.   oFlashFilter.add_pattern("*.[dD][aA][tT]");
  353.  
  354.   oDialog.add_filter(oBatteryFilter);
  355.   oDialog.add_filter(oFlashFilter);
  356.  
  357. #endif // ! GTKMM20
  358.  
  359.   while (oDialog.run() == Gtk::RESPONSE_OK)
  360.   {
  361.     Gtk::MessageDialog oConfirmDialog(*this,
  362.                                       _("Importing a battery file will erase any saved games and reset the emulator. Do you want to continue?"),
  363. #ifndef GTKMM20
  364.                                       false,
  365. #endif // ! GTKMM20
  366.                                       Gtk::MESSAGE_QUESTION,
  367.                                       Gtk::BUTTONS_YES_NO);
  368.     if (oConfirmDialog.run() != Gtk::RESPONSE_YES)
  369.     {
  370.       continue;
  371.     }
  372.  
  373.     if (m_stEmulator.emuReadBattery(oDialog.get_filename().c_str()))
  374.     {
  375.       m_stEmulator.emuReset();
  376.       break;
  377.     }
  378.     else
  379.     {
  380.       vPopupError(_("Failed to import battery file %s."),
  381.                   oDialog.get_filename().c_str());
  382.     }
  383.   }
  384. }
  385.  
  386. void Window::vOnExportBatteryFile()
  387. {
  388.   std::string sBatteryDir = m_poDirConfig->sGetKey("batteries");
  389.  
  390. #ifdef GTKMM20
  391.  
  392.   Gtk::FileSelection oDialog(_("Export battery file"));
  393.   oDialog.set_transient_for(*this);
  394.  
  395.   if (sBatteryDir == "")
  396.   {
  397.     oDialog.set_filename(sCutSuffix(m_sRomFile));
  398.   }
  399.   else
  400.   {
  401.     oDialog.set_filename(sBatteryDir + "/" +
  402.                          sCutSuffix(Glib::path_get_basename(m_sRomFile)));
  403.   }
  404.  
  405. #else // ! GTKMM20
  406.  
  407.   Gtk::FileChooserDialog oDialog(*this, _("Export battery file"),
  408.                                  Gtk::FILE_CHOOSER_ACTION_SAVE);
  409.   oDialog.add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
  410.   oDialog.add_button(Gtk::Stock::SAVE,   Gtk::RESPONSE_OK);
  411.  
  412.   if (sBatteryDir == "")
  413.   {
  414.     oDialog.set_current_folder(Glib::path_get_dirname(m_sRomFile));
  415.   }
  416.   else
  417.   {
  418.     oDialog.set_current_folder(sBatteryDir);
  419.     oDialog.add_shortcut_folder(sBatteryDir);
  420.   }
  421.   oDialog.set_current_name(sCutSuffix(Glib::path_get_basename(m_sRomFile)));
  422.  
  423.   Gtk::FileFilter oBatteryFilter;
  424.   oBatteryFilter.set_name(_("Battery file"));
  425.   oBatteryFilter.add_pattern("*.[sS][aA][vV]");
  426.  
  427.   Gtk::FileFilter oFlashFilter;
  428.   oFlashFilter.set_name(_("Flash save"));
  429.   oFlashFilter.add_pattern("*.[dD][aA][tT]");
  430.  
  431.   oDialog.add_filter(oBatteryFilter);
  432.   oDialog.add_filter(oFlashFilter);
  433.  
  434. #endif // ! GTKMM20
  435.  
  436.   while (oDialog.run() == Gtk::RESPONSE_OK)
  437.   {
  438.     Glib::ustring sFile = oDialog.get_filename();
  439.     Glib::ustring sExt;
  440.  
  441. #ifdef GTKMM20
  442.  
  443.     sExt = ".sav";
  444.  
  445. #else // ! GTKMM20
  446.  
  447.     if (oDialog.get_filter() == &oBatteryFilter)
  448.     {
  449.       sExt = ".sav";
  450.     }
  451.     else
  452.     {
  453.       sExt = ".dat";
  454.     }
  455.  
  456. #endif // ! GTKMM20
  457.  
  458.     if (! bHasSuffix(sFile, sExt, false))
  459.     {
  460.       sFile += sExt;
  461.     }
  462.  
  463.     if (Glib::file_test(sFile, Glib::FILE_TEST_EXISTS))
  464.     {
  465.       Gtk::MessageDialog oConfirmDialog(*this,
  466.                                         _("File already exists. Overwrite it?"),
  467. #ifndef GTKMM20
  468.                                         false,
  469. #endif // ! GTKMM20
  470.                                         Gtk::MESSAGE_QUESTION,
  471.                                         Gtk::BUTTONS_YES_NO);
  472.       if (oConfirmDialog.run() != Gtk::RESPONSE_YES)
  473.       {
  474.         continue;
  475.       }
  476.     }
  477.  
  478.     bool bResult;
  479.     if (m_eCartridge == CartridgeGB)
  480.     {
  481.       bResult = gbWriteBatteryFile(sFile.c_str(), false);
  482.     }
  483.     else
  484.     {
  485.       bResult = m_stEmulator.emuWriteBattery(sFile.c_str());
  486.     }
  487.  
  488.     if (bResult)
  489.     {
  490.       break;
  491.     }
  492.     else
  493.     {
  494.       vPopupError(_("Failed to export battery file %s."),
  495.                   sFile.c_str());
  496.     }
  497.   }
  498. }
  499.  
  500. void Window::vOnFileScreenCapture()
  501. {
  502.   std::string sCaptureDir = m_poDirConfig->sGetKey("captures");
  503.  
  504. #ifdef GTKMM20
  505.  
  506.   Gtk::FileSelection oDialog(_("Save screenshot"));
  507.   oDialog.set_transient_for(*this);
  508.  
  509.   if (sCaptureDir == "")
  510.   {
  511.     oDialog.set_filename(sCutSuffix(m_sRomFile));
  512.   }
  513.   else
  514.   {
  515.     oDialog.set_filename(sCaptureDir + "/" +
  516.                          sCutSuffix(Glib::path_get_basename(m_sRomFile)));
  517.   }
  518.  
  519. #else // ! GTKMM20
  520.  
  521.   Gtk::FileChooserDialog oDialog(*this, _("Save screenshot"),
  522.                                  Gtk::FILE_CHOOSER_ACTION_SAVE);
  523.   oDialog.add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
  524.   oDialog.add_button(Gtk::Stock::SAVE,   Gtk::RESPONSE_OK);
  525.  
  526.   if (sCaptureDir == "")
  527.   {
  528.     oDialog.set_current_folder(Glib::path_get_dirname(m_sRomFile));
  529.   }
  530.   else
  531.   {
  532.     oDialog.set_current_folder(sCaptureDir);
  533.     oDialog.add_shortcut_folder(sCaptureDir);
  534.   }
  535.   oDialog.set_current_name(sCutSuffix(Glib::path_get_basename(m_sRomFile)));
  536.  
  537.   Gtk::FileFilter oPngFilter;
  538.   oPngFilter.set_name(_("PNG image"));
  539.   oPngFilter.add_pattern("*.[pP][nN][gG]");
  540.  
  541.   Gtk::FileFilter oBmpFilter;
  542.   oBmpFilter.set_name(_("BMP image"));
  543.   oBmpFilter.add_pattern("*.[bB][mM][pP]");
  544.  
  545.   oDialog.add_filter(oPngFilter);
  546.   oDialog.add_filter(oBmpFilter);
  547.  
  548.   if (m_poCoreConfig->sGetKey("screenshot_format") == "bmp")
  549.   {
  550.     oDialog.set_filter(oBmpFilter);
  551.   }
  552.  
  553. #endif // ! GTKMM20
  554.  
  555.   while (oDialog.run() == Gtk::RESPONSE_OK)
  556.   {
  557.     Glib::ustring sFile = oDialog.get_filename();
  558.     Glib::ustring sExt;
  559.  
  560. #ifdef GTKMM20
  561.  
  562.     sExt = "." + m_poCoreConfig->sGetKey("screenshot_format");
  563.  
  564. #else // ! GTKMM20
  565.  
  566.     if (oDialog.get_filter() == &oPngFilter)
  567.     {
  568.       sExt = ".png";
  569.     }
  570.     else
  571.     {
  572.       sExt = ".bmp";
  573.     }
  574.  
  575. #endif // ! GTKMM20
  576.  
  577.     if (! bHasSuffix(sFile, sExt, false))
  578.     {
  579.       sFile += sExt;
  580.     }
  581.  
  582.     if (Glib::file_test(sFile, Glib::FILE_TEST_EXISTS))
  583.     {
  584.       Gtk::MessageDialog oConfirmDialog(*this,
  585.                                         _("File already exists. Overwrite it?"),
  586. #ifndef GTKMM20
  587.                                         false,
  588. #endif // ! GTKMM20
  589.                                         Gtk::MESSAGE_QUESTION,
  590.                                         Gtk::BUTTONS_YES_NO);
  591.       if (oConfirmDialog.run() != Gtk::RESPONSE_YES)
  592.       {
  593.         continue;
  594.       }
  595.     }
  596.  
  597.     bool bResult;
  598.     if (sExt == ".png")
  599.     {
  600.       bResult = m_stEmulator.emuWritePNG(sFile.c_str());
  601.     }
  602.     else
  603.     {
  604.       bResult = m_stEmulator.emuWriteBMP(sFile.c_str());
  605.     }
  606.  
  607.     if (bResult)
  608.     {
  609.       break;
  610.     }
  611.   }
  612. }
  613.  
  614. void Window::vOnFileClose()
  615. {
  616.   if (m_eCartridge != CartridgeNone)
  617.   {
  618.     soundPause();
  619.     vStopEmu();
  620.     vSetDefaultTitle();
  621.     vDrawDefaultScreen();
  622.     vSaveBattery();
  623.     m_stEmulator.emuCleanUp();
  624.     m_eCartridge = CartridgeNone;
  625.     emulating = 0;
  626.  
  627.     vUpdateGameSlots();
  628.  
  629.     for (std::list<Gtk::Widget *>::iterator it = m_listSensitiveWhenPlaying.begin();
  630.          it != m_listSensitiveWhenPlaying.end();
  631.          it++)
  632.     {
  633.       (*it)->set_sensitive(false);
  634.     }
  635.  
  636.     m_poFilePauseItem->set_active(false);
  637.   }
  638. }
  639.  
  640. void Window::vOnFileExit()
  641. {
  642.   hide();
  643. }
  644.  
  645. void Window::vOnFrameskipToggled(Gtk::CheckMenuItem * _poCMI, int _iValue)
  646. {
  647.   if (! _poCMI->get_active())
  648.   {
  649.     return;
  650.   }
  651.  
  652.   if (_iValue >= 0 && _iValue <= 9)
  653.   {
  654.     m_poCoreConfig->vSetKey("frameskip", _iValue);
  655.     gbFrameSkip      = _iValue;
  656.     systemFrameSkip  = _iValue;
  657.     m_bAutoFrameskip = false;
  658.   }
  659.   else
  660.   {
  661.     m_poCoreConfig->vSetKey("frameskip", "auto");
  662.     gbFrameSkip      = 0;
  663.     systemFrameSkip  = 0;
  664.     m_bAutoFrameskip = true;
  665.   }
  666. }
  667.  
  668. void Window::vOnThrottleToggled(Gtk::CheckMenuItem * _poCMI, int _iPercent)
  669. {
  670.   if (! _poCMI->get_active())
  671.   {
  672.     return;
  673.   }
  674.  
  675.   vSetThrottle(_iPercent);
  676.  
  677.   // Initialize the frameskip adjustment each time throttle is changed
  678.   if (m_bAutoFrameskip)
  679.   {
  680.     systemFrameSkip = 0;
  681.   }
  682. }
  683.  
  684. void Window::vOnThrottleOther(Gtk::CheckMenuItem * _poCMI)
  685. {
  686.   if (! _poCMI->get_active())
  687.   {
  688.     return;
  689.   }
  690.  
  691.   Glib::RefPtr<Xml> poXml;
  692.   poXml = Xml::create(PKGDATADIR "/vba.glade", "ThrottleDialog");
  693.  
  694.   Gtk::Dialog * poDialog = dynamic_cast<Gtk::Dialog *>(poXml->get_widget("ThrottleDialog"));
  695.   Gtk::SpinButton * poSpin = dynamic_cast<Gtk::SpinButton *>(poXml->get_widget("ThrottleSpin"));
  696.  
  697.   poDialog->set_transient_for(*this);
  698.  
  699.   if (m_iThrottle != 0)
  700.   {
  701.     poSpin->set_value(m_iThrottle);
  702.   }
  703.   else
  704.   {
  705.     poSpin->set_value(100);
  706.   }
  707.  
  708.   if (poDialog->run() == Gtk::RESPONSE_OK)
  709.   {
  710.     vSetThrottle(poSpin->get_value_as_int());
  711.   }
  712.  
  713.   delete poDialog;
  714.   vSelectBestThrottleItem();
  715. }
  716.  
  717. void Window::vOnVideoScaleToggled(Gtk::CheckMenuItem * _poCMI, int _iScale)
  718. {
  719.   if (! _poCMI->get_active())
  720.   {
  721.     return;
  722.   }
  723.  
  724.   m_poDisplayConfig->vSetKey("scale", _iScale);
  725.   vUpdateScreen();
  726. }
  727.  
  728. void Window::vOnLayerToggled(Gtk::CheckMenuItem * _poCMI, int _iLayer)
  729. {
  730.   int iMask = (0x0100 << _iLayer);
  731.   if (_poCMI->get_active())
  732.   {
  733.     layerSettings |= iMask;
  734.   }
  735.   else
  736.   {
  737.     layerSettings &= ~iMask;
  738.   }
  739.   layerEnable = DISPCNT & layerSettings;
  740.  
  741.   const char * acsLayers[] =
  742.   {
  743.     "layer_bg0",
  744.     "layer_bg1",
  745.     "layer_bg2",
  746.     "layer_bg3",
  747.     "layer_obj",
  748.     "layer_win0",
  749.     "layer_win1",
  750.     "layer_objwin"
  751.   };
  752.   m_poCoreConfig->vSetKey(acsLayers[_iLayer], _poCMI->get_active());
  753. }
  754.  
  755. void Window::vOnDirectories()
  756. {
  757.   Glib::RefPtr<Xml> poXml;
  758.   poXml = Xml::create(PKGDATADIR "/vba.glade", "DirectoriesDialog");
  759.  
  760.   struct
  761.   {
  762.     const char * m_csKey;
  763.     const char * m_csEntry;
  764.     const char * m_csResetButton;
  765.     const char * m_csSelectButton;
  766.   }
  767.   astRow[] =
  768.   {
  769.     { "gba_roms",  "GBARomsDirEntry",   "GBARomsDirResetButton",   "GBARomsDirSelectButton"   },
  770.     { "gb_roms",   "GBRomsDirEntry",    "GBRomsDirResetButton",    "GBRomsDirSelectButton"    },
  771.     { "batteries", "BatteriesDirEntry", "BatteriesDirResetButton", "BatteriesDirSelectButton" },
  772.     { "saves",     "SavesDirEntry",     "SavesDirResetButton",     "SavesDirSelectButton"     },
  773.     { "captures",  "CapturesDirEntry",  "CapturesDirResetButton",  "CapturesDirSelectButton"  }
  774.   };
  775.  
  776.   for (guint i = 0; i < G_N_ELEMENTS(astRow); i++)
  777.   {
  778.     Gtk::Entry *  poEntry  = dynamic_cast<Gtk::Entry *>(poXml->get_widget(astRow[i].m_csEntry));
  779.     Gtk::Button * poReset  = dynamic_cast<Gtk::Button *>(poXml->get_widget(astRow[i].m_csResetButton));
  780.     Gtk::Button * poSelect = dynamic_cast<Gtk::Button *>(poXml->get_widget(astRow[i].m_csSelectButton));
  781.  
  782.     poEntry->set_text(m_poDirConfig->sGetKey(astRow[i].m_csKey));
  783.  
  784.     poReset->signal_clicked().connect(SigC::bind<Gtk::Entry *>(
  785.                                         SigC::slot(*this, &Window::vOnDirectoryReset),
  786.                                         poEntry));
  787.     poSelect->signal_clicked().connect(SigC::bind<Gtk::Entry *>(
  788.                                          SigC::slot(*this, &Window::vOnDirectorySelect),
  789.                                          poEntry));
  790.   }
  791.  
  792.   Gtk::Dialog * poDialog = dynamic_cast<Gtk::Dialog *>(poXml->get_widget("DirectoriesDialog"));
  793.   poDialog->set_transient_for(*this);
  794.  
  795.   if (poDialog->run() == Gtk::RESPONSE_OK)
  796.   {
  797.     for (guint i = 0; i < G_N_ELEMENTS(astRow); i++)
  798.     {
  799.       Gtk::Entry * poEntry = dynamic_cast<Gtk::Entry *>(poXml->get_widget(astRow[i].m_csEntry));
  800.       Glib::ustring sDir = poEntry->get_text();
  801.       if (! Glib::file_test(sDir, Glib::FILE_TEST_IS_DIR))
  802.       {
  803.         sDir = "";
  804.       }
  805.       m_poDirConfig->vSetKey(astRow[i].m_csKey, sDir);
  806.     }
  807.  
  808.     // Needed if saves dir changed
  809.     vUpdateGameSlots();
  810.   }
  811.  
  812.   delete poDialog;
  813. }
  814.  
  815. void Window::vOnDirectoryReset(Gtk::Entry * _poEntry)
  816. {
  817.   _poEntry->set_text("");
  818. }
  819.  
  820. void Window::vOnDirectorySelect(Gtk::Entry * _poEntry)
  821. {
  822. #ifdef GTKMM20
  823.  
  824.   Gtk::FileSelection oDialog(_("Select directory"));
  825.   oDialog.set_transient_for(*this);
  826.  
  827.   if (_poEntry->get_text() != "")
  828.   {
  829.     oDialog.set_filename(_poEntry->get_text() + "/");
  830.   }
  831.  
  832.   if (oDialog.run() == Gtk::RESPONSE_OK)
  833.   {
  834.     std::string sFile = oDialog.get_filename();
  835.     if (! Glib::file_test(sFile, Glib::FILE_TEST_IS_DIR))
  836.     {
  837.       sFile = Glib::path_get_dirname(sFile);
  838.     }
  839.     _poEntry->set_text(sFile);
  840.   }
  841.  
  842. #else // ! GTKMM20
  843.  
  844.   Gtk::FileChooserDialog oDialog(*this, _("Select directory"),
  845.                                  Gtk::FILE_CHOOSER_ACTION_SELECT_FOLDER);
  846.   oDialog.add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
  847.   oDialog.add_button(Gtk::Stock::OK,     Gtk::RESPONSE_OK);
  848.  
  849.   if (_poEntry->get_text() != "")
  850.   {
  851.     oDialog.add_shortcut_folder(_poEntry->get_text());
  852.     oDialog.set_current_folder(_poEntry->get_text());
  853.   }
  854.  
  855.   if (oDialog.run() == Gtk::RESPONSE_OK)
  856.   {
  857.     _poEntry->set_text(oDialog.get_filename());
  858.   }
  859.  
  860. #endif // ! GTKMM20
  861. }
  862.  
  863. void Window::vOnPauseWhenInactiveToggled(Gtk::CheckMenuItem * _poCMI)
  864. {
  865.   m_poDisplayConfig->vSetKey("pause_when_inactive", _poCMI->get_active());
  866. }
  867.  
  868. void Window::vOnSelectBios()
  869. {
  870. #ifdef GTKMM20
  871.  
  872.   Gtk::FileSelection oDialog(_("Select BIOS file"));
  873.   oDialog.set_transient_for(*this);
  874.  
  875.   if (m_poCoreConfig->sGetKey("bios_file") != "")
  876.   {
  877.     oDialog.set_filename(m_poCoreConfig->sGetKey("bios_file"));
  878.   }
  879.  
  880. #else // ! GTKMM20
  881.  
  882.   Gtk::FileChooserDialog oDialog(*this, _("Select BIOS file"));
  883.   oDialog.add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
  884.   oDialog.add_button(Gtk::Stock::OPEN,   Gtk::RESPONSE_OK);
  885.  
  886.   if (m_poCoreConfig->sGetKey("bios_file") != "")
  887.   {
  888.     oDialog.set_filename(m_poCoreConfig->sGetKey("bios_file"));
  889.   }
  890.  
  891.   const char * acsPattern[] =
  892.   {
  893.     "*.[bB][iI][nN]", "*.[aA][gG][bB]", "*.[gG][bB][aA]",
  894.     "*.[bB][iI][oO][sS]", "*.[zZ][iI][pP]", "*.[zZ]", "*.[gG][zZ]"
  895.   };
  896.  
  897.   Gtk::FileFilter oAllFilter;
  898.   oAllFilter.set_name(_("All files"));
  899.   oAllFilter.add_pattern("*");
  900.  
  901.   Gtk::FileFilter oBiosFilter;
  902.   oBiosFilter.set_name(_("Gameboy Advance BIOS"));
  903.   for (guint i = 0; i < G_N_ELEMENTS(acsPattern); i++)
  904.   {
  905.     oBiosFilter.add_pattern(acsPattern[i]);
  906.   }
  907.  
  908.   oDialog.add_filter(oAllFilter);
  909.   oDialog.add_filter(oBiosFilter);
  910.  
  911.   oDialog.set_filter(oBiosFilter);
  912.  
  913. #endif // ! GTKMM20
  914.  
  915.   while (oDialog.run() == Gtk::RESPONSE_OK)
  916.   {
  917.     if (Glib::file_test(oDialog.get_filename(), Glib::FILE_TEST_IS_REGULAR))
  918.     {
  919.       m_poCoreConfig->vSetKey("bios_file", oDialog.get_filename());
  920.       m_poUseBiosItem->set_sensitive();
  921.       break;
  922.     }
  923.   }
  924. }
  925.  
  926. void Window::vOnUseBiosToggled(Gtk::CheckMenuItem * _poCMI)
  927. {
  928.   m_poCoreConfig->vSetKey("use_bios_file", _poCMI->get_active());
  929. }
  930.  
  931. void Window::vOnShowSpeedToggled(Gtk::CheckMenuItem * _poCMI, int _iShowSpeed)
  932. {
  933.   if (! _poCMI->get_active())
  934.   {
  935.     return;
  936.   }
  937.  
  938.   m_eShowSpeed = (EShowSpeed)_iShowSpeed;
  939.   if (m_eShowSpeed == ShowNone)
  940.   {
  941.     vSetDefaultTitle();
  942.   }
  943.   m_poDisplayConfig->vSetKey("show_speed", _iShowSpeed);
  944. }
  945.  
  946. void Window::vOnSaveTypeToggled(Gtk::CheckMenuItem * _poCMI, int _iSaveType)
  947. {
  948.   if (! _poCMI->get_active())
  949.   {
  950.     return;
  951.   }
  952.  
  953.   cpuSaveType = _iSaveType;
  954.   m_poCoreConfig->vSetKey("save_type", _iSaveType);
  955. }
  956.  
  957. void Window::vOnFlashSizeToggled(Gtk::CheckMenuItem * _poCMI, int _iFlashSize)
  958. {
  959.   if (! _poCMI->get_active())
  960.   {
  961.     return;
  962.   }
  963.  
  964.   if (_iFlashSize == 64)
  965.   {
  966.     flashSetSize(0x10000);
  967.   }
  968.   else
  969.   {
  970.     flashSetSize(0x20000);
  971.   }
  972.   m_poCoreConfig->vSetKey("flash_size", _iFlashSize);
  973. }
  974.  
  975. void Window::vOnScreenshotFormatToggled(Gtk::CheckMenuItem * _poCMI, std::string _sFormat)
  976. {
  977.   if (! _poCMI->get_active())
  978.   {
  979.     return;
  980.   }
  981.  
  982.   m_poCoreConfig->vSetKey("screenshot_format", _sFormat);
  983. }
  984.  
  985. void Window::vOnSoundStatusToggled(Gtk::CheckMenuItem * _poCMI, int _iSoundStatus)
  986. {
  987.   if (! _poCMI->get_active())
  988.   {
  989.     return;
  990.   }
  991.  
  992.   std::string sSoundStatus;
  993.   switch (_iSoundStatus)
  994.   {
  995.   case SoundOff:
  996.     soundOffFlag = true;
  997.     if (systemSoundOn)
  998.     {
  999.       soundShutdown();
  1000.     }
  1001.     sSoundStatus = "off";
  1002.     break;
  1003.   case SoundMute:
  1004.     soundDisable(0x30f);
  1005.     sSoundStatus = "mute";
  1006.     break;
  1007.   case SoundOn:
  1008.     if (soundOffFlag)
  1009.     {
  1010.       soundOffFlag = false;
  1011.       if (! soundInit())
  1012.       {
  1013.         m_poSoundOffItem->set_active();
  1014.         return;
  1015.       }
  1016.     }
  1017.     soundEnable(0x30f);
  1018.     sSoundStatus = "on";
  1019.     break;
  1020.   }
  1021.   m_poSoundConfig->vSetKey("status", sSoundStatus);
  1022. }
  1023.  
  1024. void Window::vOnSoundEchoToggled(Gtk::CheckMenuItem * _poCMI)
  1025. {
  1026.   soundEcho = _poCMI->get_active();
  1027.   m_poSoundConfig->vSetKey("echo", soundEcho);
  1028. }
  1029.  
  1030. void Window::vOnSoundLowPassToggled(Gtk::CheckMenuItem * _poCMI)
  1031. {
  1032.   soundLowPass = _poCMI->get_active();
  1033.   m_poSoundConfig->vSetKey("low_pass", soundLowPass);
  1034. }
  1035.  
  1036. void Window::vOnSoundReverseToggled(Gtk::CheckMenuItem * _poCMI)
  1037. {
  1038.   soundReverse = _poCMI->get_active();
  1039.   m_poSoundConfig->vSetKey("reverse_stereo", soundReverse);
  1040. }
  1041.  
  1042. void Window::vOnSoundChannelToggled(Gtk::CheckMenuItem * _poCMI, int _iSoundChannel)
  1043. {
  1044.   int iShift = _iSoundChannel;
  1045.   if (_iSoundChannel > 3)
  1046.   {
  1047.     iShift += 4;
  1048.   }
  1049.   int iFlag = 1 << iShift;
  1050.   int iActive = soundGetEnable() & 0x30f;
  1051.   if (_poCMI->get_active())
  1052.   {
  1053.     iActive |= iFlag;
  1054.   }
  1055.   else
  1056.   {
  1057.     iActive &= ~iFlag;
  1058.   }
  1059.   soundEnable(iActive);
  1060.   soundDisable(~iActive & 0x30f);
  1061.  
  1062.   const char * acsChannels[] =
  1063.   {
  1064.     "channel_1",
  1065.     "channel_2",
  1066.     "channel_3",
  1067.     "channel_4",
  1068.     "channel_A",
  1069.     "channel_B"
  1070.   };
  1071.   m_poSoundConfig->vSetKey(acsChannels[_iSoundChannel], _poCMI->get_active());
  1072. }
  1073.  
  1074. void Window::vOnSoundQualityToggled(Gtk::CheckMenuItem * _poCMI, int _iSoundQuality)
  1075. {
  1076.   if (! _poCMI->get_active())
  1077.   {
  1078.     return;
  1079.   }
  1080.  
  1081.   m_eSoundQuality = (ESoundQuality)_iSoundQuality;
  1082.   if (m_eCartridge == CartridgeGBA)
  1083.   {
  1084.     soundSetQuality(_iSoundQuality);
  1085.   }
  1086.   else if (m_eCartridge == CartridgeGB)
  1087.   {
  1088.     gbSoundSetQuality(_iSoundQuality);
  1089.   }
  1090.   m_poSoundConfig->vSetKey("quality", _iSoundQuality);
  1091. }
  1092.  
  1093. void Window::vOnSoundVolumeToggled(Gtk::CheckMenuItem * _poCMI, int _iSoundVolume)
  1094. {
  1095.   if (! _poCMI->get_active())
  1096.   {
  1097.     return;
  1098.   }
  1099.  
  1100.   soundVolume = _iSoundVolume;
  1101.   m_poSoundConfig->vSetKey("volume", _iSoundVolume);
  1102. }
  1103.  
  1104. void Window::vOnGBBorderToggled(Gtk::CheckMenuItem * _poCMI)
  1105. {
  1106.   gbBorderOn = _poCMI->get_active();
  1107.   if (emulating && m_eCartridge == CartridgeGB && _poCMI->get_active())
  1108.   {
  1109.     gbSgbRenderBorder();
  1110.   }
  1111.   vUpdateScreen();
  1112.   m_poCoreConfig->vSetKey("gb_border", _poCMI->get_active());
  1113. }
  1114.  
  1115. void Window::vOnGBPrinterToggled(Gtk::CheckMenuItem * _poCMI)
  1116. {
  1117.   if (_poCMI->get_active())
  1118.   {
  1119.     gbSerialFunction = gbPrinterSend;
  1120.   }
  1121.   else
  1122.   {
  1123.     gbSerialFunction = NULL;
  1124.   }
  1125.   m_poCoreConfig->vSetKey("gb_printer", _poCMI->get_active());
  1126. }
  1127.  
  1128. void Window::vOnEmulatorTypeToggled(Gtk::CheckMenuItem * _poCMI, int _iEmulatorType)
  1129. {
  1130.   gbEmulatorType = _iEmulatorType;
  1131.   m_poCoreConfig->vSetKey("emulator_type", _iEmulatorType);
  1132. }
  1133.  
  1134. void Window::vOnFilter2xToggled(Gtk::CheckMenuItem * _poCMI, int _iFilter2x)
  1135. {
  1136.   if (! _poCMI->get_active())
  1137.   {
  1138.     return;
  1139.   }
  1140.  
  1141.   m_poScreenArea->vSetFilter2x((EFilter2x)_iFilter2x);
  1142.   if (emulating)
  1143.   {
  1144.     vDrawScreen();
  1145.   }
  1146.   m_poDisplayConfig->vSetKey("filter2x", _iFilter2x);
  1147. }
  1148.  
  1149. void Window::vOnFilterIBToggled(Gtk::CheckMenuItem * _poCMI, int _iFilterIB)
  1150. {
  1151.   if (! _poCMI->get_active())
  1152.   {
  1153.     return;
  1154.   }
  1155.  
  1156.   m_poScreenArea->vSetFilterIB((EFilterIB)_iFilterIB);
  1157.   if (emulating)
  1158.   {
  1159.     vDrawScreen();
  1160.   }
  1161.   m_poDisplayConfig->vSetKey("filterIB", _iFilterIB);
  1162. }
  1163.  
  1164. #ifdef MMX
  1165. void Window::vOnDisableMMXToggled(Gtk::CheckMenuItem * _poCMI)
  1166. {
  1167.   cpu_mmx = ! _poCMI->get_active();
  1168.   m_poDisplayConfig->vSetKey("filter_disable_mmx", _poCMI->get_active());
  1169. }
  1170. #endif // MMX
  1171.  
  1172. void Window::vOnJoypadConfigure(int _iJoypad)
  1173. {
  1174.   Glib::RefPtr<Xml> poXml;
  1175.   poXml = Xml::create(PKGDATADIR "/vba.glade", "JoypadConfigDialog");
  1176.  
  1177.   JoypadConfigDialog * poDialog = NULL;
  1178.   poXml->get_widget_derived<JoypadConfigDialog>("JoypadConfigDialog", poDialog);
  1179.   poDialog->set_transient_for(*this);
  1180.   poDialog->vSetConfig(m_oJoypads[_iJoypad - 1]);
  1181.  
  1182.   if (poDialog->run() == Gtk::RESPONSE_OK)
  1183.   {
  1184.     m_oJoypads[_iJoypad - 1] = poDialog->stGetConfig();
  1185.     if (_iJoypad == m_poInputConfig->oGetKey<int>("active_joypad"))
  1186.     {
  1187.       if (m_poKeymap != NULL)
  1188.       {
  1189.         delete m_poKeymap;
  1190.       }
  1191.       m_poKeymap = m_oJoypads[_iJoypad - 1].poCreateKeymap();
  1192.     }
  1193.   }
  1194.  
  1195.   delete poDialog;
  1196. }
  1197.  
  1198. void Window::vOnJoypadToggled(Gtk::CheckMenuItem * _poCMI, int _iJoypad)
  1199. {
  1200.   if (! _poCMI->get_active())
  1201.   {
  1202.     return;
  1203.   }
  1204.  
  1205.   if (m_poKeymap != NULL)
  1206.   {
  1207.     delete m_poKeymap;
  1208.   }
  1209.   m_poKeymap = m_oJoypads[_iJoypad - 1].poCreateKeymap();
  1210.  
  1211.   m_poInputConfig->vSetKey("active_joypad", _iJoypad);
  1212. }
  1213.  
  1214. void Window::vOnAutofireToggled(Gtk::CheckMenuItem * _poCMI, u32 _uiKeyFlag)
  1215. {
  1216.   if (_poCMI->get_active())
  1217.   {
  1218.     m_uiAutofireState |= _uiKeyFlag;
  1219.   }
  1220.   else
  1221.   {
  1222.     m_uiAutofireState &= ~_uiKeyFlag;
  1223.   }
  1224.  
  1225.   std::string sKey;
  1226.   if (_uiKeyFlag == KeyFlagA)
  1227.   {
  1228.     sKey = "autofire_A";
  1229.   }
  1230.   else if (_uiKeyFlag == KeyFlagB)
  1231.   {
  1232.     sKey = "autofire_B";
  1233.   }
  1234.   else if (_uiKeyFlag == KeyFlagL)
  1235.   {
  1236.     sKey = "autofire_L";
  1237.   }
  1238.   else if (_uiKeyFlag == KeyFlagR)
  1239.   {
  1240.     sKey = "autofire_R";
  1241.   }
  1242.   m_poInputConfig->vSetKey(sKey, _poCMI->get_active());
  1243. }
  1244.  
  1245. void Window::vOnGDBWait()
  1246. {
  1247.   Glib::RefPtr<Xml> poXml;
  1248.   poXml = Xml::create(PKGDATADIR "/vba.glade", "TcpPortDialog");
  1249.  
  1250.   Gtk::Dialog * poDialog = dynamic_cast<Gtk::Dialog *>(poXml->get_widget("TcpPortDialog"));
  1251.   Gtk::SpinButton * poSpin = dynamic_cast<Gtk::SpinButton *>(poXml->get_widget("TcpPortSpin"));
  1252.  
  1253.   poDialog->set_transient_for(*this);
  1254.  
  1255.   int iPort = 55555;
  1256.   poSpin->set_value(iPort);  
  1257.  
  1258.   bool bOk = false;
  1259.   if (poDialog->run() == Gtk::RESPONSE_OK)
  1260.   {
  1261.     bOk = true;
  1262.     iPort = poSpin->get_value_as_int();
  1263.   }
  1264.   delete poDialog;
  1265.  
  1266.   if (! bOk)
  1267.   {
  1268.     return;
  1269.   }
  1270.  
  1271.   m_eCartridge = CartridgeGBA;
  1272.   m_sRomFile   = "gnu_stub";
  1273.   m_stEmulator = GBASystem;
  1274.  
  1275.   rom         = (u8 *) malloc(0x2000000);
  1276.   workRAM     = (u8 *) calloc(1, 0x40000);
  1277.   bios        = (u8 *) calloc(1, 0x4000);
  1278.   internalRAM = (u8 *) calloc(1, 0x8000);
  1279.   paletteRAM  = (u8 *) calloc(1, 0x400);
  1280.   vram        = (u8 *) calloc(1, 0x20000);
  1281.   oam         = (u8 *) calloc(1, 0x400);
  1282.   pix         = (u8 *) calloc(1, 4 * m_iGBAScreenWidth * m_iGBAScreenHeight);
  1283.   ioMem       = (u8 *) calloc(1, 0x400);
  1284.  
  1285.   useBios = m_poCoreConfig->oGetKey<bool>("use_bios_file");
  1286.   CPUInit(m_poCoreConfig->sGetKey("bios_file").c_str(), useBios);
  1287.   CPUReset();
  1288.  
  1289.   for (std::list<Gtk::Widget *>::iterator it = m_listSensitiveWhenPlaying.begin();
  1290.        it != m_listSensitiveWhenPlaying.end();
  1291.        it++)
  1292.   {
  1293.     (*it)->set_sensitive();
  1294.   }
  1295.  
  1296.   if (m_poCoreConfig->oGetKey<bool>("load_game_auto"))
  1297.   {
  1298.     vOnLoadGameMostRecent();
  1299.   }
  1300.  
  1301.   vStartEmu();
  1302.  
  1303.   emulating = 1;
  1304.  
  1305.   dbgMain   = remoteStubMain;
  1306.   dbgSignal = remoteStubSignal;
  1307.   dbgOutput = remoteOutput;
  1308.   debugger  = true;
  1309.  
  1310.   remoteSetProtocol(0);
  1311.   remoteSetPort(iPort);
  1312.   remoteInit();
  1313. }
  1314.  
  1315. void Window::vOnGDBLoadAndWait()
  1316. {
  1317.   bool bLoaded = false;
  1318.  
  1319.   while (m_poFileOpenDialog->run() == Gtk::RESPONSE_OK)
  1320.   {
  1321.     if (bLoadROM(m_poFileOpenDialog->get_filename()))
  1322.     {
  1323.       bLoaded = true;
  1324.       break;
  1325.     }
  1326.   }
  1327.   m_poFileOpenDialog->hide();
  1328.  
  1329.   if (! bLoaded)
  1330.   {
  1331.     return;
  1332.   }
  1333.  
  1334.   if (m_eCartridge != CartridgeGBA)
  1335.   {
  1336.     vPopupError(_("Only GBA images are supported."));
  1337.     vOnFileClose();
  1338.     return;
  1339.   }
  1340.  
  1341.   Glib::RefPtr<Xml> poXml;
  1342.   poXml = Xml::create(PKGDATADIR "/vba.glade", "TcpPortDialog");
  1343.  
  1344.   Gtk::Dialog * poDialog = dynamic_cast<Gtk::Dialog *>(poXml->get_widget("TcpPortDialog"));
  1345.   Gtk::SpinButton * poSpin = dynamic_cast<Gtk::SpinButton *>(poXml->get_widget("TcpPortSpin"));
  1346.  
  1347.   poDialog->set_transient_for(*this);
  1348.  
  1349.   int iPort = 55555;
  1350.   poSpin->set_value(iPort);  
  1351.  
  1352.   bool bOk = false;
  1353.   if (poDialog->run() == Gtk::RESPONSE_OK)
  1354.   {
  1355.     bOk = true;
  1356.     iPort = poSpin->get_value_as_int();
  1357.   }
  1358.   delete poDialog;
  1359.  
  1360.   if (! bOk)
  1361.   {
  1362.     return;
  1363.   }
  1364.  
  1365.   dbgMain   = remoteStubMain;
  1366.   dbgSignal = remoteStubSignal;
  1367.   dbgOutput = remoteOutput;
  1368.   debugger  = true;
  1369.  
  1370.   remoteSetProtocol(0);
  1371.   remoteSetPort(iPort);
  1372.   remoteInit();
  1373. }
  1374.  
  1375. void Window::vOnGDBBreak()
  1376. {
  1377.   if (armState)
  1378.   {
  1379.     armNextPC -= 4;
  1380.     reg[15].I -= 4;
  1381.   }
  1382.   else
  1383.   {
  1384.     armNextPC -= 2;
  1385.     reg[15].I -= 2;
  1386.   }
  1387.  
  1388.   debugger = true;
  1389. }
  1390.  
  1391. void Window::vOnGDBDisconnect()
  1392. {
  1393.   remoteCleanUp();
  1394.   debugger = false;
  1395. }
  1396.  
  1397. void Window::vOnHelpAbout()
  1398. {
  1399.   Glib::RefPtr<Xml> poXml;
  1400.   poXml = Xml::create(PKGDATADIR "/vba.glade", "AboutDialog");
  1401.  
  1402.   Gtk::Dialog * poDialog = dynamic_cast<Gtk::Dialog *>(poXml->get_widget("AboutDialog"));
  1403.   poDialog->set_transient_for(*this);
  1404.  
  1405.   Gtk::Image oIcon(PKGDATADIR "/vba-64.png");
  1406.   oIcon.show();
  1407.   Gtk::Container * poIconContainer = dynamic_cast<Gtk::Container *>(poXml->get_widget("AboutIconContainer"));
  1408.   poIconContainer->add(oIcon);
  1409.  
  1410.   Gtk::Label * poLabel  = dynamic_cast<Gtk::Label *>(poXml->get_widget("VersionLabel"));
  1411.   poLabel->set_markup("<b><big>" PACKAGE " " VERSION "</big></b>");
  1412.  
  1413.   poDialog->run();
  1414.   delete poDialog;
  1415. }
  1416.  
  1417. bool Window::bOnEmuIdle()
  1418. {
  1419.   if (debugger && m_stEmulator.emuHasDebugger)
  1420.   {
  1421.     dbgMain();
  1422.     return true;
  1423.   }
  1424.  
  1425.   if (m_uiThrottleDelay != 0)
  1426.   {
  1427.     u32 uiTime = SDL_GetTicks();
  1428.     if (uiTime - m_uiThrottleLastTime >= m_uiThrottleDelay)
  1429.     {
  1430.       m_uiThrottleDelay = 0;
  1431.       m_uiThrottleLastTime = uiTime;
  1432.     }
  1433.     else
  1434.     {
  1435.       return true;
  1436.     }
  1437.   }
  1438.  
  1439.   m_stEmulator.emuMain(m_stEmulator.emuCount);
  1440.   return true;
  1441. }
  1442.  
  1443. bool Window::on_focus_in_event(GdkEventFocus * _pstEvent)
  1444. {
  1445.   if (emulating
  1446.       && ! m_bPaused
  1447.       && m_poDisplayConfig->oGetKey<bool>("pause_when_inactive"))
  1448.   {
  1449.     vStartEmu();
  1450.     soundResume();
  1451.   }
  1452.   return false;
  1453. }
  1454.  
  1455. bool Window::on_focus_out_event(GdkEventFocus * _pstEvent)
  1456. {
  1457.   if (emulating
  1458.       && ! m_bPaused
  1459.       && m_poDisplayConfig->oGetKey<bool>("pause_when_inactive"))
  1460.   {
  1461.     vStopEmu();
  1462.     soundPause();
  1463.   }
  1464.   return false;
  1465. }
  1466.  
  1467. bool Window::on_key_press_event(GdkEventKey * _pstEvent)
  1468. {
  1469.   EKey eKey;
  1470.  
  1471.   if ((_pstEvent->state & Gtk::AccelGroup::get_default_mod_mask())
  1472.       || (eKey = m_poKeymap->eGetKey(_pstEvent->hardware_keycode)) == KeyNone)
  1473.   {
  1474.     return Gtk::Window::on_key_press_event(_pstEvent);
  1475.   }
  1476.  
  1477.   switch (eKey)
  1478.   {
  1479.   case KeyA:
  1480.     m_uiJoypadState |= KeyFlagA;
  1481.     break;
  1482.   case KeyB:
  1483.     m_uiJoypadState |= KeyFlagB;
  1484.     break;
  1485.   case KeySelect:
  1486.     m_uiJoypadState |= KeyFlagSelect;
  1487.     break;
  1488.   case KeyStart:
  1489.     m_uiJoypadState |= KeyFlagStart;
  1490.     break;
  1491.   case KeyRight:
  1492.     m_uiJoypadState |= KeyFlagRight;
  1493.     m_uiJoypadState &= ~KeyFlagLeft;
  1494.     break;
  1495.   case KeyLeft:
  1496.     m_uiJoypadState |= KeyFlagLeft;
  1497.     m_uiJoypadState &= ~KeyFlagRight;
  1498.     break;
  1499.   case KeyUp:
  1500.     m_uiJoypadState |= KeyFlagUp;
  1501.     m_uiJoypadState &= ~KeyFlagDown;
  1502.     break;
  1503.   case KeyDown:
  1504.     m_uiJoypadState |= KeyFlagDown;
  1505.     m_uiJoypadState &= ~KeyFlagUp;
  1506.     break;
  1507.   case KeyR:
  1508.     m_uiJoypadState |= KeyFlagR;
  1509.     break;
  1510.   case KeyL:
  1511.     m_uiJoypadState |= KeyFlagL;
  1512.     break;
  1513.   case KeySpeed:
  1514.     m_uiJoypadState |= KeyFlagSpeed;
  1515.     break;
  1516.   case KeyCapture:
  1517.     m_uiJoypadState |= KeyFlagCapture;
  1518.     break;
  1519.   case KeyNone:
  1520.     break;
  1521.   }
  1522.   return true;
  1523. }
  1524.  
  1525. bool Window::on_key_release_event(GdkEventKey * _pstEvent)
  1526. {
  1527.   EKey eKey;
  1528.  
  1529.   if ((_pstEvent->state & Gtk::AccelGroup::get_default_mod_mask())
  1530.       || (eKey = m_poKeymap->eGetKey(_pstEvent->hardware_keycode)) == KeyNone)
  1531.   {
  1532.     return Gtk::Window::on_key_release_event(_pstEvent);
  1533.   }
  1534.  
  1535.   switch (eKey)
  1536.   {
  1537.   case KeyA:
  1538.     m_uiJoypadState &= ~KeyFlagA;
  1539.     break;
  1540.   case KeyB:
  1541.     m_uiJoypadState &= ~KeyFlagB;
  1542.     break;
  1543.   case KeySelect:
  1544.     m_uiJoypadState &= ~KeyFlagSelect;
  1545.     break;
  1546.   case KeyStart:
  1547.     m_uiJoypadState &= ~KeyFlagStart;
  1548.     break;
  1549.   case KeyRight:
  1550.     m_uiJoypadState &= ~KeyFlagRight;
  1551.     break;
  1552.   case KeyLeft:
  1553.     m_uiJoypadState &= ~KeyFlagLeft;
  1554.     break;
  1555.   case KeyUp:
  1556.     m_uiJoypadState &= ~KeyFlagUp;
  1557.     break;
  1558.   case KeyDown:
  1559.     m_uiJoypadState &= ~KeyFlagDown;
  1560.     break;
  1561.   case KeyR:
  1562.     m_uiJoypadState &= ~KeyFlagR;
  1563.     break;
  1564.   case KeyL:
  1565.     m_uiJoypadState &= ~KeyFlagL;
  1566.     break;
  1567.   case KeySpeed:
  1568.     m_uiJoypadState &= ~KeyFlagSpeed;
  1569.     break;
  1570.   case KeyCapture:
  1571.     m_uiJoypadState &= ~KeyFlagCapture;
  1572.     break;
  1573.   case KeyNone:
  1574.     break;
  1575.   }
  1576.   return true;
  1577. }
  1578.  
  1579. } // namespace VBA
  1580.