diff src/gtk/windowcallbacks.cpp @ 1:f9f4f1b99eed

importing src directory
author Robert McIntyre <rlm@mit.edu>
date Sat, 03 Mar 2012 10:31:27 -0600
parents
children
line wrap: on
line diff
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/src/gtk/windowcallbacks.cpp	Sat Mar 03 10:31:27 2012 -0600
     1.3 @@ -0,0 +1,1582 @@
     1.4 +// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
     1.5 +// Copyright (C) 1999-2003 Forgotten
     1.6 +// Copyright (C) 2004 Forgotten and the VBA development team
     1.7 +
     1.8 +// This program is free software; you can redistribute it and/or modify
     1.9 +// it under the terms of the GNU General Public License as published by
    1.10 +// the Free Software Foundation; either version 2, or(at your option)
    1.11 +// any later version.
    1.12 +//
    1.13 +// This program is distributed in the hope that it will be useful,
    1.14 +// but WITHOUT ANY WARRANTY; without even the implied warranty of
    1.15 +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    1.16 +// GNU General Public License for more details.
    1.17 +//
    1.18 +// You should have received a copy of the GNU General Public License
    1.19 +// along with this program; if not, write to the Free Software Foundation,
    1.20 +// Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
    1.21 +
    1.22 +#include "window.h"
    1.23 +
    1.24 +#include <sys/stat.h>
    1.25 +
    1.26 +#include <stdio.h>
    1.27 +#include <time.h>
    1.28 +
    1.29 +#include <SDL.h>
    1.30 +
    1.31 +#include "../gba/GBA.h"
    1.32 +#include "../gba/GBAGlobals.h"
    1.33 +#include "../gba/Flash.h"
    1.34 +#include "../gba/GBASound.h"
    1.35 +#include "../gb/GB.h"
    1.36 +#include "../gb/gbGlobals.h"
    1.37 +#include "../gb/gbPrinter.h"
    1.38 +#include "../common/Util.h"
    1.39 +
    1.40 +#include "tools.h"
    1.41 +#include "intl.h"
    1.42 +
    1.43 +extern int systemRenderedFrames;
    1.44 +extern int systemFPS;
    1.45 +extern bool debugger;
    1.46 +extern int RGB_LOW_BITS_MASK;
    1.47 +extern void (*dbgMain)();
    1.48 +extern void (*dbgSignal)(int, int);
    1.49 +extern void (*dbgOutput)(char *, u32);
    1.50 +extern void remoteInit();
    1.51 +extern void remoteCleanUp();
    1.52 +extern void remoteStubMain();
    1.53 +extern void remoteStubSignal(int, int);
    1.54 +extern void remoteOutput(char *, u32);
    1.55 +extern void remoteSetProtocol(int);
    1.56 +extern void remoteSetPort(int);
    1.57 +
    1.58 +#ifdef MMX
    1.59 +extern "C" bool cpu_mmx;
    1.60 +#endif // MMX
    1.61 +
    1.62 +namespace VBA
    1.63 +{
    1.64 +
    1.65 +using Gnome::Glade::Xml;
    1.66 +
    1.67 +void Window::vOnFileOpen()
    1.68 +{
    1.69 +  while (m_poFileOpenDialog->run() == Gtk::RESPONSE_OK)
    1.70 +  {
    1.71 +    if (bLoadROM(m_poFileOpenDialog->get_filename()))
    1.72 +    {
    1.73 +      break;
    1.74 +    }
    1.75 +  }
    1.76 +  m_poFileOpenDialog->hide();
    1.77 +}
    1.78 +
    1.79 +void Window::vOnFileLoad()
    1.80 +{
    1.81 +  std::string sSaveDir = m_poDirConfig->sGetKey("saves");
    1.82 +
    1.83 +#ifdef GTKMM20
    1.84 +
    1.85 +  Gtk::FileSelection oDialog(_("Load game"));
    1.86 +  oDialog.set_transient_for(*this);
    1.87 +
    1.88 +  if (sSaveDir == "")
    1.89 +  {
    1.90 +    oDialog.set_filename(Glib::path_get_dirname(m_sRomFile) + "/");
    1.91 +  }
    1.92 +  else
    1.93 +  {
    1.94 +    oDialog.set_filename(sSaveDir + "/");
    1.95 +  }
    1.96 +
    1.97 +#else // ! GTKMM20
    1.98 +
    1.99 +  Gtk::FileChooserDialog oDialog(*this, _("Load game"));
   1.100 +  oDialog.add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
   1.101 +  oDialog.add_button(Gtk::Stock::OPEN,   Gtk::RESPONSE_OK);
   1.102 +
   1.103 +  if (sSaveDir == "")
   1.104 +  {
   1.105 +    oDialog.set_current_folder(Glib::path_get_dirname(m_sRomFile));
   1.106 +  }
   1.107 +  else
   1.108 +  {
   1.109 +    oDialog.set_current_folder(sSaveDir);
   1.110 +    oDialog.add_shortcut_folder(sSaveDir);
   1.111 +  }
   1.112 +
   1.113 +  Gtk::FileFilter oSaveFilter;
   1.114 +  oSaveFilter.set_name(_("VisualBoyAdvance save game"));
   1.115 +  oSaveFilter.add_pattern("*.[sS][gG][mM]");
   1.116 +
   1.117 +  oDialog.add_filter(oSaveFilter);
   1.118 +
   1.119 +#endif // ! GTKMM20
   1.120 +
   1.121 +  while (oDialog.run() == Gtk::RESPONSE_OK)
   1.122 +  {
   1.123 +    if (m_stEmulator.emuReadState(oDialog.get_filename().c_str()))
   1.124 +    {
   1.125 +      break;
   1.126 +    }
   1.127 +  }
   1.128 +}
   1.129 +
   1.130 +void Window::vOnFileSave()
   1.131 +{
   1.132 +  Glib::ustring sSaveDir = m_poDirConfig->sGetKey("saves");
   1.133 +
   1.134 +#ifdef GTKMM20
   1.135 +
   1.136 +  Gtk::FileSelection oDialog(_("Save game"));
   1.137 +  oDialog.set_transient_for(*this);
   1.138 +
   1.139 +  if (sSaveDir == "")
   1.140 +  {
   1.141 +    oDialog.set_filename(sCutSuffix(m_sRomFile));
   1.142 +  }
   1.143 +  else
   1.144 +  {
   1.145 +    oDialog.set_filename(sSaveDir + "/" +
   1.146 +                         sCutSuffix(Glib::path_get_basename(m_sRomFile)));
   1.147 +  }
   1.148 +
   1.149 +#else // ! GTKMM20
   1.150 +
   1.151 +  Gtk::FileChooserDialog oDialog(*this, _("Save game"),
   1.152 +                                 Gtk::FILE_CHOOSER_ACTION_SAVE);
   1.153 +  oDialog.add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
   1.154 +  oDialog.add_button(Gtk::Stock::SAVE,   Gtk::RESPONSE_OK);
   1.155 +
   1.156 +  if (sSaveDir == "")
   1.157 +  {
   1.158 +    oDialog.set_current_folder(Glib::path_get_dirname(m_sRomFile));
   1.159 +  }
   1.160 +  else
   1.161 +  {
   1.162 +    oDialog.set_current_folder(sSaveDir);
   1.163 +    oDialog.add_shortcut_folder(sSaveDir);
   1.164 +  }
   1.165 +  oDialog.set_current_name(sCutSuffix(Glib::path_get_basename(m_sRomFile)));
   1.166 +
   1.167 +  Gtk::FileFilter oSaveFilter;
   1.168 +  oSaveFilter.set_name(_("VisualBoyAdvance save game"));
   1.169 +  oSaveFilter.add_pattern("*.[sS][gG][mM]");
   1.170 +
   1.171 +  oDialog.add_filter(oSaveFilter);
   1.172 +
   1.173 +#endif // ! GTKMM20
   1.174 +
   1.175 +  while (oDialog.run() == Gtk::RESPONSE_OK)
   1.176 +  {
   1.177 +    Glib::ustring sFile = oDialog.get_filename();
   1.178 +    if (! bHasSuffix(sFile, ".sgm", false))
   1.179 +    {
   1.180 +      sFile += ".sgm";
   1.181 +    }
   1.182 +
   1.183 +    if (Glib::file_test(sFile, Glib::FILE_TEST_EXISTS))
   1.184 +    {
   1.185 +      Gtk::MessageDialog oConfirmDialog(*this,
   1.186 +                                        _("File already exists. Overwrite it?"),
   1.187 +#ifndef GTKMM20
   1.188 +                                        false,
   1.189 +#endif // ! GTKMM20
   1.190 +                                        Gtk::MESSAGE_QUESTION,
   1.191 +                                        Gtk::BUTTONS_YES_NO);
   1.192 +      if (oConfirmDialog.run() != Gtk::RESPONSE_YES)
   1.193 +      {
   1.194 +        continue;
   1.195 +      }
   1.196 +    }
   1.197 +
   1.198 +    if (m_stEmulator.emuWriteState(sFile.c_str()))
   1.199 +    {
   1.200 +      break;
   1.201 +    }
   1.202 +  }
   1.203 +}
   1.204 +
   1.205 +void Window::vOnLoadGameMostRecent()
   1.206 +{
   1.207 +  int    iMostRecent = -1;
   1.208 +  time_t uiTimeMax;
   1.209 +
   1.210 +  for (int i = 0; i < 10; i++)
   1.211 +  {
   1.212 +    if (! m_astGameSlot[i].m_bEmpty
   1.213 +        && (iMostRecent < 0 || m_astGameSlot[i].m_uiTime > uiTimeMax))
   1.214 +    {
   1.215 +      iMostRecent = i;
   1.216 +      uiTimeMax = m_astGameSlot[i].m_uiTime;
   1.217 +    }
   1.218 +  }
   1.219 +
   1.220 +  if (iMostRecent >= 0)
   1.221 +  {
   1.222 +    vOnLoadGame(iMostRecent + 1);
   1.223 +  }
   1.224 +}
   1.225 +
   1.226 +void Window::vOnLoadGameAutoToggled(Gtk::CheckMenuItem * _poCMI)
   1.227 +{
   1.228 +  m_poCoreConfig->vSetKey("load_game_auto", _poCMI->get_active());
   1.229 +}
   1.230 +
   1.231 +void Window::vOnLoadGame(int _iSlot)
   1.232 +{
   1.233 +  int i = _iSlot - 1;
   1.234 +  if (! m_astGameSlot[i].m_bEmpty)
   1.235 +  {
   1.236 +    m_stEmulator.emuReadState(m_astGameSlot[i].m_sFile.c_str());
   1.237 +    m_poFilePauseItem->set_active(false);
   1.238 +  }
   1.239 +}
   1.240 +
   1.241 +void Window::vOnSaveGameOldest()
   1.242 +{
   1.243 +  int    iOldest = -1;
   1.244 +  time_t uiTimeMin;
   1.245 +
   1.246 +  for (int i = 0; i < 10; i++)
   1.247 +  {
   1.248 +    if (! m_astGameSlot[i].m_bEmpty
   1.249 +        && (iOldest < 0 || m_astGameSlot[i].m_uiTime < uiTimeMin))
   1.250 +    {
   1.251 +      iOldest = i;
   1.252 +      uiTimeMin = m_astGameSlot[i].m_uiTime;
   1.253 +    }
   1.254 +  }
   1.255 +
   1.256 +  if (iOldest >= 0)
   1.257 +  {
   1.258 +    vOnSaveGame(iOldest + 1);
   1.259 +  }
   1.260 +  else
   1.261 +  {
   1.262 +    vOnSaveGame(1);
   1.263 +  }
   1.264 +}
   1.265 +
   1.266 +void Window::vOnSaveGame(int _iSlot)
   1.267 +{
   1.268 +  int i = _iSlot - 1;
   1.269 +  m_stEmulator.emuWriteState(m_astGameSlot[i].m_sFile.c_str());
   1.270 +  vUpdateGameSlots();
   1.271 +}
   1.272 +
   1.273 +void Window::vOnFilePauseToggled(Gtk::CheckMenuItem * _poCMI)
   1.274 +{
   1.275 +  m_bPaused = _poCMI->get_active();
   1.276 +  if (emulating)
   1.277 +  {
   1.278 +    if (m_bPaused)
   1.279 +    {
   1.280 +      vStopEmu();
   1.281 +      soundPause();
   1.282 +    }
   1.283 +    else
   1.284 +    {
   1.285 +      vStartEmu();
   1.286 +      soundResume();
   1.287 +    }
   1.288 +  }
   1.289 +}
   1.290 +
   1.291 +void Window::vOnFileReset()
   1.292 +{
   1.293 +  if (emulating)
   1.294 +  {
   1.295 +    m_stEmulator.emuReset(true);
   1.296 +    m_poFilePauseItem->set_active(false);
   1.297 +  }
   1.298 +}
   1.299 +
   1.300 +void Window::vOnRecentReset()
   1.301 +{
   1.302 +  m_listHistory.clear();
   1.303 +  vClearHistoryMenu();
   1.304 +}
   1.305 +
   1.306 +void Window::vOnRecentFreezeToggled(Gtk::CheckMenuItem * _poCMI)
   1.307 +{
   1.308 +  m_poRecentResetItem->set_sensitive(! _poCMI->get_active());
   1.309 +  m_poHistoryConfig->vSetKey("freeze", _poCMI->get_active());
   1.310 +}
   1.311 +
   1.312 +void Window::vOnRecentFile(std::string _sFile)
   1.313 +{
   1.314 +  bLoadROM(_sFile);
   1.315 +}
   1.316 +
   1.317 +void Window::vOnImportBatteryFile()
   1.318 +{
   1.319 +  std::string BatteryDir = m_poDirConfig->sGetKey("batteries");
   1.320 +
   1.321 +#ifdef GTKMM20
   1.322 +
   1.323 +  Gtk::FileSelection oDialog(_("Import battery file"));
   1.324 +  oDialog.set_transient_for(*this);
   1.325 +
   1.326 +  if (BatteryDir == "")
   1.327 +  {
   1.328 +    oDialog.set_filename(Glib::path_get_dirname(m_sRomFile) + "/");
   1.329 +  }
   1.330 +  else
   1.331 +  {
   1.332 +    oDialog.set_filename(BatteryDir + "/");
   1.333 +  }
   1.334 +
   1.335 +#else // ! GTKMM20
   1.336 +
   1.337 +  Gtk::FileChooserDialog oDialog(*this, _("Import battery file"));
   1.338 +  oDialog.add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
   1.339 +  oDialog.add_button(Gtk::Stock::OPEN,   Gtk::RESPONSE_OK);
   1.340 +
   1.341 +  if (BatteryDir == "")
   1.342 +  {
   1.343 +    oDialog.set_current_folder(Glib::path_get_dirname(m_sRomFile));
   1.344 +  }
   1.345 +  else
   1.346 +  {
   1.347 +    oDialog.set_current_folder(BatteryDir);
   1.348 +    oDialog.add_shortcut_folder(BatteryDir);
   1.349 +  }
   1.350 +
   1.351 +  Gtk::FileFilter oBatteryFilter;
   1.352 +  oBatteryFilter.set_name(_("Battery file"));
   1.353 +  oBatteryFilter.add_pattern("*.[sS][aA][vV]");
   1.354 +
   1.355 +  Gtk::FileFilter oFlashFilter;
   1.356 +  oFlashFilter.set_name(_("Flash save"));
   1.357 +  oFlashFilter.add_pattern("*.[dD][aA][tT]");
   1.358 +
   1.359 +  oDialog.add_filter(oBatteryFilter);
   1.360 +  oDialog.add_filter(oFlashFilter);
   1.361 +
   1.362 +#endif // ! GTKMM20
   1.363 +
   1.364 +  while (oDialog.run() == Gtk::RESPONSE_OK)
   1.365 +  {
   1.366 +    Gtk::MessageDialog oConfirmDialog(*this,
   1.367 +                                      _("Importing a battery file will erase any saved games and reset the emulator. Do you want to continue?"),
   1.368 +#ifndef GTKMM20
   1.369 +                                      false,
   1.370 +#endif // ! GTKMM20
   1.371 +                                      Gtk::MESSAGE_QUESTION,
   1.372 +                                      Gtk::BUTTONS_YES_NO);
   1.373 +    if (oConfirmDialog.run() != Gtk::RESPONSE_YES)
   1.374 +    {
   1.375 +      continue;
   1.376 +    }
   1.377 +
   1.378 +    if (m_stEmulator.emuReadBattery(oDialog.get_filename().c_str()))
   1.379 +    {
   1.380 +      m_stEmulator.emuReset(false);
   1.381 +      break;
   1.382 +    }
   1.383 +    else
   1.384 +    {
   1.385 +      vPopupError(_("Failed to import battery file %s."),
   1.386 +                  oDialog.get_filename().c_str());
   1.387 +    }
   1.388 +  }
   1.389 +}
   1.390 +
   1.391 +void Window::vOnExportBatteryFile()
   1.392 +{
   1.393 +  std::string sBatteryDir = m_poDirConfig->sGetKey("batteries");
   1.394 +
   1.395 +#ifdef GTKMM20
   1.396 +
   1.397 +  Gtk::FileSelection oDialog(_("Export battery file"));
   1.398 +  oDialog.set_transient_for(*this);
   1.399 +
   1.400 +  if (sBatteryDir == "")
   1.401 +  {
   1.402 +    oDialog.set_filename(sCutSuffix(m_sRomFile));
   1.403 +  }
   1.404 +  else
   1.405 +  {
   1.406 +    oDialog.set_filename(sBatteryDir + "/" +
   1.407 +                         sCutSuffix(Glib::path_get_basename(m_sRomFile)));
   1.408 +  }
   1.409 +
   1.410 +#else // ! GTKMM20
   1.411 +
   1.412 +  Gtk::FileChooserDialog oDialog(*this, _("Export battery file"),
   1.413 +                                 Gtk::FILE_CHOOSER_ACTION_SAVE);
   1.414 +  oDialog.add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
   1.415 +  oDialog.add_button(Gtk::Stock::SAVE,   Gtk::RESPONSE_OK);
   1.416 +
   1.417 +  if (sBatteryDir == "")
   1.418 +  {
   1.419 +    oDialog.set_current_folder(Glib::path_get_dirname(m_sRomFile));
   1.420 +  }
   1.421 +  else
   1.422 +  {
   1.423 +    oDialog.set_current_folder(sBatteryDir);
   1.424 +    oDialog.add_shortcut_folder(sBatteryDir);
   1.425 +  }
   1.426 +  oDialog.set_current_name(sCutSuffix(Glib::path_get_basename(m_sRomFile)));
   1.427 +
   1.428 +  Gtk::FileFilter oBatteryFilter;
   1.429 +  oBatteryFilter.set_name(_("Battery file"));
   1.430 +  oBatteryFilter.add_pattern("*.[sS][aA][vV]");
   1.431 +
   1.432 +  Gtk::FileFilter oFlashFilter;
   1.433 +  oFlashFilter.set_name(_("Flash save"));
   1.434 +  oFlashFilter.add_pattern("*.[dD][aA][tT]");
   1.435 +
   1.436 +  oDialog.add_filter(oBatteryFilter);
   1.437 +  oDialog.add_filter(oFlashFilter);
   1.438 +
   1.439 +#endif // ! GTKMM20
   1.440 +
   1.441 +  while (oDialog.run() == Gtk::RESPONSE_OK)
   1.442 +  {
   1.443 +    Glib::ustring sFile = oDialog.get_filename();
   1.444 +    Glib::ustring sExt;
   1.445 +
   1.446 +#ifdef GTKMM20
   1.447 +
   1.448 +    sExt = ".sav";
   1.449 +
   1.450 +#else // ! GTKMM20
   1.451 +
   1.452 +    if (oDialog.get_filter() == &oBatteryFilter)
   1.453 +    {
   1.454 +      sExt = ".sav";
   1.455 +    }
   1.456 +    else
   1.457 +    {
   1.458 +      sExt = ".dat";
   1.459 +    }
   1.460 +
   1.461 +#endif // ! GTKMM20
   1.462 +
   1.463 +    if (! bHasSuffix(sFile, sExt, false))
   1.464 +    {
   1.465 +      sFile += sExt;
   1.466 +    }
   1.467 +
   1.468 +    if (Glib::file_test(sFile, Glib::FILE_TEST_EXISTS))
   1.469 +    {
   1.470 +      Gtk::MessageDialog oConfirmDialog(*this,
   1.471 +                                        _("File already exists. Overwrite it?"),
   1.472 +#ifndef GTKMM20
   1.473 +                                        false,
   1.474 +#endif // ! GTKMM20
   1.475 +                                        Gtk::MESSAGE_QUESTION,
   1.476 +                                        Gtk::BUTTONS_YES_NO);
   1.477 +      if (oConfirmDialog.run() != Gtk::RESPONSE_YES)
   1.478 +      {
   1.479 +        continue;
   1.480 +      }
   1.481 +    }
   1.482 +
   1.483 +    bool bResult;
   1.484 +    if (m_eCartridge == CartridgeGB)
   1.485 +    {
   1.486 +      bResult = gbWriteBatteryFile(sFile.c_str(), false);
   1.487 +    }
   1.488 +    else
   1.489 +    {
   1.490 +      bResult = m_stEmulator.emuWriteBattery(sFile.c_str());
   1.491 +    }
   1.492 +
   1.493 +    if (bResult)
   1.494 +    {
   1.495 +      break;
   1.496 +    }
   1.497 +    else
   1.498 +    {
   1.499 +      vPopupError(_("Failed to export battery file %s."),
   1.500 +                  sFile.c_str());
   1.501 +    }
   1.502 +  }
   1.503 +}
   1.504 +
   1.505 +void Window::vOnFileScreenCapture()
   1.506 +{
   1.507 +  std::string sCaptureDir = m_poDirConfig->sGetKey("captures");
   1.508 +
   1.509 +#ifdef GTKMM20
   1.510 +
   1.511 +  Gtk::FileSelection oDialog(_("Save screenshot"));
   1.512 +  oDialog.set_transient_for(*this);
   1.513 +
   1.514 +  if (sCaptureDir == "")
   1.515 +  {
   1.516 +    oDialog.set_filename(sCutSuffix(m_sRomFile));
   1.517 +  }
   1.518 +  else
   1.519 +  {
   1.520 +    oDialog.set_filename(sCaptureDir + "/" +
   1.521 +                         sCutSuffix(Glib::path_get_basename(m_sRomFile)));
   1.522 +  }
   1.523 +
   1.524 +#else // ! GTKMM20
   1.525 +
   1.526 +  Gtk::FileChooserDialog oDialog(*this, _("Save screenshot"),
   1.527 +                                 Gtk::FILE_CHOOSER_ACTION_SAVE);
   1.528 +  oDialog.add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
   1.529 +  oDialog.add_button(Gtk::Stock::SAVE,   Gtk::RESPONSE_OK);
   1.530 +
   1.531 +  if (sCaptureDir == "")
   1.532 +  {
   1.533 +    oDialog.set_current_folder(Glib::path_get_dirname(m_sRomFile));
   1.534 +  }
   1.535 +  else
   1.536 +  {
   1.537 +    oDialog.set_current_folder(sCaptureDir);
   1.538 +    oDialog.add_shortcut_folder(sCaptureDir);
   1.539 +  }
   1.540 +  oDialog.set_current_name(sCutSuffix(Glib::path_get_basename(m_sRomFile)));
   1.541 +
   1.542 +  Gtk::FileFilter oPngFilter;
   1.543 +  oPngFilter.set_name(_("PNG image"));
   1.544 +  oPngFilter.add_pattern("*.[pP][nN][gG]");
   1.545 +
   1.546 +  Gtk::FileFilter oBmpFilter;
   1.547 +  oBmpFilter.set_name(_("BMP image"));
   1.548 +  oBmpFilter.add_pattern("*.[bB][mM][pP]");
   1.549 +
   1.550 +  oDialog.add_filter(oPngFilter);
   1.551 +  oDialog.add_filter(oBmpFilter);
   1.552 +
   1.553 +  if (m_poCoreConfig->sGetKey("screenshot_format") == "bmp")
   1.554 +  {
   1.555 +    oDialog.set_filter(oBmpFilter);
   1.556 +  }
   1.557 +
   1.558 +#endif // ! GTKMM20
   1.559 +
   1.560 +  while (oDialog.run() == Gtk::RESPONSE_OK)
   1.561 +  {
   1.562 +    Glib::ustring sFile = oDialog.get_filename();
   1.563 +    Glib::ustring sExt;
   1.564 +
   1.565 +#ifdef GTKMM20
   1.566 +
   1.567 +    sExt = "." + m_poCoreConfig->sGetKey("screenshot_format");
   1.568 +
   1.569 +#else // ! GTKMM20
   1.570 +
   1.571 +    if (oDialog.get_filter() == &oPngFilter)
   1.572 +    {
   1.573 +      sExt = ".png";
   1.574 +    }
   1.575 +    else
   1.576 +    {
   1.577 +      sExt = ".bmp";
   1.578 +    }
   1.579 +
   1.580 +#endif // ! GTKMM20
   1.581 +
   1.582 +    if (! bHasSuffix(sFile, sExt, false))
   1.583 +    {
   1.584 +      sFile += sExt;
   1.585 +    }
   1.586 +
   1.587 +    if (Glib::file_test(sFile, Glib::FILE_TEST_EXISTS))
   1.588 +    {
   1.589 +      Gtk::MessageDialog oConfirmDialog(*this,
   1.590 +                                        _("File already exists. Overwrite it?"),
   1.591 +#ifndef GTKMM20
   1.592 +                                        false,
   1.593 +#endif // ! GTKMM20
   1.594 +                                        Gtk::MESSAGE_QUESTION,
   1.595 +                                        Gtk::BUTTONS_YES_NO);
   1.596 +      if (oConfirmDialog.run() != Gtk::RESPONSE_YES)
   1.597 +      {
   1.598 +        continue;
   1.599 +      }
   1.600 +    }
   1.601 +
   1.602 +    bool bResult;
   1.603 +    if (sExt == ".png")
   1.604 +    {
   1.605 +      bResult = m_stEmulator.emuWritePNG(sFile.c_str());
   1.606 +    }
   1.607 +    else
   1.608 +    {
   1.609 +      bResult = m_stEmulator.emuWriteBMP(sFile.c_str());
   1.610 +    }
   1.611 +
   1.612 +    if (bResult)
   1.613 +    {
   1.614 +      break;
   1.615 +    }
   1.616 +  }
   1.617 +}
   1.618 +
   1.619 +void Window::vOnFileClose()
   1.620 +{
   1.621 +  if (m_eCartridge != CartridgeNone)
   1.622 +  {
   1.623 +    soundPause();
   1.624 +    vStopEmu();
   1.625 +    vSetDefaultTitle();
   1.626 +    vDrawDefaultScreen();
   1.627 +    vSaveBattery();
   1.628 +    m_stEmulator.emuCleanUp();
   1.629 +    m_eCartridge = CartridgeNone;
   1.630 +    emulating = 0;
   1.631 +
   1.632 +    vUpdateGameSlots();
   1.633 +
   1.634 +    for (std::list<Gtk::Widget *>::iterator it = m_listSensitiveWhenPlaying.begin();
   1.635 +         it != m_listSensitiveWhenPlaying.end();
   1.636 +         it++)
   1.637 +    {
   1.638 +      (*it)->set_sensitive(false);
   1.639 +    }
   1.640 +
   1.641 +    m_poFilePauseItem->set_active(false);
   1.642 +  }
   1.643 +}
   1.644 +
   1.645 +void Window::vOnFileExit()
   1.646 +{
   1.647 +  hide();
   1.648 +}
   1.649 +
   1.650 +void Window::vOnFrameskipToggled(Gtk::CheckMenuItem * _poCMI, int _iValue)
   1.651 +{
   1.652 +  if (! _poCMI->get_active())
   1.653 +  {
   1.654 +    return;
   1.655 +  }
   1.656 +
   1.657 +  if (_iValue >= 0 && _iValue <= 9)
   1.658 +  {
   1.659 +    m_poCoreConfig->vSetKey("frameskip", _iValue);
   1.660 +    gbFrameSkip      = _iValue;
   1.661 +    systemFrameSkip  = _iValue;
   1.662 +    m_bAutoFrameskip = false;
   1.663 +  }
   1.664 +  else
   1.665 +  {
   1.666 +    m_poCoreConfig->vSetKey("frameskip", "auto");
   1.667 +    gbFrameSkip      = 0;
   1.668 +    systemFrameSkip  = 0;
   1.669 +    m_bAutoFrameskip = true;
   1.670 +  }
   1.671 +}
   1.672 +
   1.673 +void Window::vOnThrottleToggled(Gtk::CheckMenuItem * _poCMI, int _iPercent)
   1.674 +{
   1.675 +  if (! _poCMI->get_active())
   1.676 +  {
   1.677 +    return;
   1.678 +  }
   1.679 +
   1.680 +  vSetThrottle(_iPercent);
   1.681 +
   1.682 +  // Initialize the frameskip adjustment each time throttle is changed
   1.683 +  if (m_bAutoFrameskip)
   1.684 +  {
   1.685 +    systemFrameSkip = 0;
   1.686 +  }
   1.687 +}
   1.688 +
   1.689 +void Window::vOnThrottleOther(Gtk::CheckMenuItem * _poCMI)
   1.690 +{
   1.691 +  if (! _poCMI->get_active())
   1.692 +  {
   1.693 +    return;
   1.694 +  }
   1.695 +
   1.696 +  Glib::RefPtr<Xml> poXml;
   1.697 +  poXml = Xml::create(PKGDATADIR "/vba.glade", "ThrottleDialog");
   1.698 +
   1.699 +  Gtk::Dialog * poDialog = dynamic_cast<Gtk::Dialog *>(poXml->get_widget("ThrottleDialog"));
   1.700 +  Gtk::SpinButton * poSpin = dynamic_cast<Gtk::SpinButton *>(poXml->get_widget("ThrottleSpin"));
   1.701 +
   1.702 +  poDialog->set_transient_for(*this);
   1.703 +
   1.704 +  if (m_iThrottle != 0)
   1.705 +  {
   1.706 +    poSpin->set_value(m_iThrottle);
   1.707 +  }
   1.708 +  else
   1.709 +  {
   1.710 +    poSpin->set_value(100);
   1.711 +  }
   1.712 +
   1.713 +  if (poDialog->run() == Gtk::RESPONSE_OK)
   1.714 +  {
   1.715 +    vSetThrottle(poSpin->get_value_as_int());
   1.716 +  }
   1.717 +
   1.718 +  delete poDialog;
   1.719 +  vSelectBestThrottleItem();
   1.720 +}
   1.721 +
   1.722 +void Window::vOnVideoScaleToggled(Gtk::CheckMenuItem * _poCMI, int _iScale)
   1.723 +{
   1.724 +  if (! _poCMI->get_active())
   1.725 +  {
   1.726 +    return;
   1.727 +  }
   1.728 +
   1.729 +  m_poDisplayConfig->vSetKey("scale", _iScale);
   1.730 +  vUpdateScreen();
   1.731 +}
   1.732 +
   1.733 +void Window::vOnLayerToggled(Gtk::CheckMenuItem * _poCMI, int _iLayer)
   1.734 +{
   1.735 +  int iMask = (0x0100 << _iLayer);
   1.736 +  if (_poCMI->get_active())
   1.737 +  {
   1.738 +    layerSettings |= iMask;
   1.739 +  }
   1.740 +  else
   1.741 +  {
   1.742 +    layerSettings &= ~iMask;
   1.743 +  }
   1.744 +  layerEnable = DISPCNT & layerSettings;
   1.745 +
   1.746 +  const char * acsLayers[] =
   1.747 +  {
   1.748 +    "layer_bg0",
   1.749 +    "layer_bg1",
   1.750 +    "layer_bg2",
   1.751 +    "layer_bg3",
   1.752 +    "layer_obj",
   1.753 +    "layer_win0",
   1.754 +    "layer_win1",
   1.755 +    "layer_objwin"
   1.756 +  };
   1.757 +  m_poCoreConfig->vSetKey(acsLayers[_iLayer], _poCMI->get_active());
   1.758 +}
   1.759 +
   1.760 +void Window::vOnDirectories()
   1.761 +{
   1.762 +  Glib::RefPtr<Xml> poXml;
   1.763 +  poXml = Xml::create(PKGDATADIR "/vba.glade", "DirectoriesDialog");
   1.764 +
   1.765 +  struct
   1.766 +  {
   1.767 +    const char * m_csKey;
   1.768 +    const char * m_csEntry;
   1.769 +    const char * m_csResetButton;
   1.770 +    const char * m_csSelectButton;
   1.771 +  }
   1.772 +  astRow[] =
   1.773 +  {
   1.774 +    { "gba_roms",  "GBARomsDirEntry",   "GBARomsDirResetButton",   "GBARomsDirSelectButton"   },
   1.775 +    { "gb_roms",   "GBRomsDirEntry",    "GBRomsDirResetButton",    "GBRomsDirSelectButton"    },
   1.776 +    { "batteries", "BatteriesDirEntry", "BatteriesDirResetButton", "BatteriesDirSelectButton" },
   1.777 +    { "saves",     "SavesDirEntry",     "SavesDirResetButton",     "SavesDirSelectButton"     },
   1.778 +    { "captures",  "CapturesDirEntry",  "CapturesDirResetButton",  "CapturesDirSelectButton"  }
   1.779 +  };
   1.780 +
   1.781 +  for (guint i = 0; i < G_N_ELEMENTS(astRow); i++)
   1.782 +  {
   1.783 +    Gtk::Entry *  poEntry  = dynamic_cast<Gtk::Entry *>(poXml->get_widget(astRow[i].m_csEntry));
   1.784 +    Gtk::Button * poReset  = dynamic_cast<Gtk::Button *>(poXml->get_widget(astRow[i].m_csResetButton));
   1.785 +    Gtk::Button * poSelect = dynamic_cast<Gtk::Button *>(poXml->get_widget(astRow[i].m_csSelectButton));
   1.786 +
   1.787 +    poEntry->set_text(m_poDirConfig->sGetKey(astRow[i].m_csKey));
   1.788 +
   1.789 +    poReset->signal_clicked().connect(SigC::bind<Gtk::Entry *>(
   1.790 +                                        SigC::slot(*this, &Window::vOnDirectoryReset),
   1.791 +                                        poEntry));
   1.792 +    poSelect->signal_clicked().connect(SigC::bind<Gtk::Entry *>(
   1.793 +                                         SigC::slot(*this, &Window::vOnDirectorySelect),
   1.794 +                                         poEntry));
   1.795 +  }
   1.796 +
   1.797 +  Gtk::Dialog * poDialog = dynamic_cast<Gtk::Dialog *>(poXml->get_widget("DirectoriesDialog"));
   1.798 +  poDialog->set_transient_for(*this);
   1.799 +
   1.800 +  if (poDialog->run() == Gtk::RESPONSE_OK)
   1.801 +  {
   1.802 +    for (guint i = 0; i < G_N_ELEMENTS(astRow); i++)
   1.803 +    {
   1.804 +      Gtk::Entry * poEntry = dynamic_cast<Gtk::Entry *>(poXml->get_widget(astRow[i].m_csEntry));
   1.805 +      Glib::ustring sDir = poEntry->get_text();
   1.806 +      if (! Glib::file_test(sDir, Glib::FILE_TEST_IS_DIR))
   1.807 +      {
   1.808 +        sDir = "";
   1.809 +      }
   1.810 +      m_poDirConfig->vSetKey(astRow[i].m_csKey, sDir);
   1.811 +    }
   1.812 +
   1.813 +    // Needed if saves dir changed
   1.814 +    vUpdateGameSlots();
   1.815 +  }
   1.816 +
   1.817 +  delete poDialog;
   1.818 +}
   1.819 +
   1.820 +void Window::vOnDirectoryReset(Gtk::Entry * _poEntry)
   1.821 +{
   1.822 +  _poEntry->set_text("");
   1.823 +}
   1.824 +
   1.825 +void Window::vOnDirectorySelect(Gtk::Entry * _poEntry)
   1.826 +{
   1.827 +#ifdef GTKMM20
   1.828 +
   1.829 +  Gtk::FileSelection oDialog(_("Select directory"));
   1.830 +  oDialog.set_transient_for(*this);
   1.831 +
   1.832 +  if (_poEntry->get_text() != "")
   1.833 +  {
   1.834 +    oDialog.set_filename(_poEntry->get_text() + "/");
   1.835 +  }
   1.836 +
   1.837 +  if (oDialog.run() == Gtk::RESPONSE_OK)
   1.838 +  {
   1.839 +    std::string sFile = oDialog.get_filename();
   1.840 +    if (! Glib::file_test(sFile, Glib::FILE_TEST_IS_DIR))
   1.841 +    {
   1.842 +      sFile = Glib::path_get_dirname(sFile);
   1.843 +    }
   1.844 +    _poEntry->set_text(sFile);
   1.845 +  }
   1.846 +
   1.847 +#else // ! GTKMM20
   1.848 +
   1.849 +  Gtk::FileChooserDialog oDialog(*this, _("Select directory"),
   1.850 +                                 Gtk::FILE_CHOOSER_ACTION_SELECT_FOLDER);
   1.851 +  oDialog.add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
   1.852 +  oDialog.add_button(Gtk::Stock::OK,     Gtk::RESPONSE_OK);
   1.853 +
   1.854 +  if (_poEntry->get_text() != "")
   1.855 +  {
   1.856 +    oDialog.add_shortcut_folder(_poEntry->get_text());
   1.857 +    oDialog.set_current_folder(_poEntry->get_text());
   1.858 +  }
   1.859 +
   1.860 +  if (oDialog.run() == Gtk::RESPONSE_OK)
   1.861 +  {
   1.862 +    _poEntry->set_text(oDialog.get_filename());
   1.863 +  }
   1.864 +
   1.865 +#endif // ! GTKMM20
   1.866 +}
   1.867 +
   1.868 +void Window::vOnPauseWhenInactiveToggled(Gtk::CheckMenuItem * _poCMI)
   1.869 +{
   1.870 +  m_poDisplayConfig->vSetKey("pause_when_inactive", _poCMI->get_active());
   1.871 +}
   1.872 +
   1.873 +void Window::vOnSelectBios()
   1.874 +{
   1.875 +#ifdef GTKMM20
   1.876 +
   1.877 +  Gtk::FileSelection oDialog(_("Select BIOS file"));
   1.878 +  oDialog.set_transient_for(*this);
   1.879 +
   1.880 +  if (m_poCoreConfig->sGetKey("bios_file") != "")
   1.881 +  {
   1.882 +    oDialog.set_filename(m_poCoreConfig->sGetKey("bios_file"));
   1.883 +  }
   1.884 +
   1.885 +#else // ! GTKMM20
   1.886 +
   1.887 +  Gtk::FileChooserDialog oDialog(*this, _("Select BIOS file"));
   1.888 +  oDialog.add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
   1.889 +  oDialog.add_button(Gtk::Stock::OPEN,   Gtk::RESPONSE_OK);
   1.890 +
   1.891 +  if (m_poCoreConfig->sGetKey("bios_file") != "")
   1.892 +  {
   1.893 +    oDialog.set_filename(m_poCoreConfig->sGetKey("bios_file"));
   1.894 +  }
   1.895 +
   1.896 +  const char * acsPattern[] =
   1.897 +  {
   1.898 +    "*.[bB][iI][nN]", "*.[aA][gG][bB]", "*.[gG][bB][aA]",
   1.899 +    "*.[bB][iI][oO][sS]", "*.[zZ][iI][pP]", "*.[zZ]", "*.[gG][zZ]"
   1.900 +  };
   1.901 +
   1.902 +  Gtk::FileFilter oAllFilter;
   1.903 +  oAllFilter.set_name(_("All files"));
   1.904 +  oAllFilter.add_pattern("*");
   1.905 +
   1.906 +  Gtk::FileFilter oBiosFilter;
   1.907 +  oBiosFilter.set_name(_("Gameboy Advance BIOS"));
   1.908 +  for (guint i = 0; i < G_N_ELEMENTS(acsPattern); i++)
   1.909 +  {
   1.910 +    oBiosFilter.add_pattern(acsPattern[i]);
   1.911 +  }
   1.912 +
   1.913 +  oDialog.add_filter(oAllFilter);
   1.914 +  oDialog.add_filter(oBiosFilter);
   1.915 +
   1.916 +  oDialog.set_filter(oBiosFilter);
   1.917 +
   1.918 +#endif // ! GTKMM20
   1.919 +
   1.920 +  while (oDialog.run() == Gtk::RESPONSE_OK)
   1.921 +  {
   1.922 +    if (Glib::file_test(oDialog.get_filename(), Glib::FILE_TEST_IS_REGULAR))
   1.923 +    {
   1.924 +      m_poCoreConfig->vSetKey("bios_file", oDialog.get_filename());
   1.925 +      m_poUseBiosItem->set_sensitive();
   1.926 +      break;
   1.927 +    }
   1.928 +  }
   1.929 +}
   1.930 +
   1.931 +void Window::vOnUseBiosToggled(Gtk::CheckMenuItem * _poCMI)
   1.932 +{
   1.933 +  m_poCoreConfig->vSetKey("use_bios_file", _poCMI->get_active());
   1.934 +}
   1.935 +
   1.936 +void Window::vOnShowSpeedToggled(Gtk::CheckMenuItem * _poCMI, int _iShowSpeed)
   1.937 +{
   1.938 +  if (! _poCMI->get_active())
   1.939 +  {
   1.940 +    return;
   1.941 +  }
   1.942 +
   1.943 +  m_eShowSpeed = (EShowSpeed)_iShowSpeed;
   1.944 +  if (m_eShowSpeed == ShowNone)
   1.945 +  {
   1.946 +    vSetDefaultTitle();
   1.947 +  }
   1.948 +  m_poDisplayConfig->vSetKey("show_speed", _iShowSpeed);
   1.949 +}
   1.950 +
   1.951 +void Window::vOnSaveTypeToggled(Gtk::CheckMenuItem * _poCMI, int _iSaveType)
   1.952 +{
   1.953 +  if (! _poCMI->get_active())
   1.954 +  {
   1.955 +    return;
   1.956 +  }
   1.957 +
   1.958 +  cpuSaveType = _iSaveType;
   1.959 +  m_poCoreConfig->vSetKey("save_type", _iSaveType);
   1.960 +}
   1.961 +
   1.962 +void Window::vOnFlashSizeToggled(Gtk::CheckMenuItem * _poCMI, int _iFlashSize)
   1.963 +{
   1.964 +  if (! _poCMI->get_active())
   1.965 +  {
   1.966 +    return;
   1.967 +  }
   1.968 +
   1.969 +  if (_iFlashSize == 64)
   1.970 +  {
   1.971 +    flashSetSize(0x10000);
   1.972 +  }
   1.973 +  else
   1.974 +  {
   1.975 +    flashSetSize(0x20000);
   1.976 +  }
   1.977 +  m_poCoreConfig->vSetKey("flash_size", _iFlashSize);
   1.978 +}
   1.979 +
   1.980 +void Window::vOnScreenshotFormatToggled(Gtk::CheckMenuItem * _poCMI, std::string _sFormat)
   1.981 +{
   1.982 +  if (! _poCMI->get_active())
   1.983 +  {
   1.984 +    return;
   1.985 +  }
   1.986 +
   1.987 +  m_poCoreConfig->vSetKey("screenshot_format", _sFormat);
   1.988 +}
   1.989 +
   1.990 +void Window::vOnSoundStatusToggled(Gtk::CheckMenuItem * _poCMI, int _iSoundStatus)
   1.991 +{
   1.992 +  if (! _poCMI->get_active())
   1.993 +  {
   1.994 +    return;
   1.995 +  }
   1.996 +
   1.997 +  std::string sSoundStatus;
   1.998 +  switch (_iSoundStatus)
   1.999 +  {
  1.1000 +  case SoundOff:
  1.1001 +    soundOffFlag = true;
  1.1002 +    if (systemSoundOn)
  1.1003 +    {
  1.1004 +      soundShutdown();
  1.1005 +    }
  1.1006 +    sSoundStatus = "off";
  1.1007 +    break;
  1.1008 +  case SoundMute:
  1.1009 +    soundDisableChannels(0x30f);
  1.1010 +    sSoundStatus = "mute";
  1.1011 +    break;
  1.1012 +  case SoundOn:
  1.1013 +    if (soundOffFlag)
  1.1014 +    {
  1.1015 +      soundOffFlag = false;
  1.1016 +      if (! soundInit())
  1.1017 +      {
  1.1018 +        m_poSoundOffItem->set_active();
  1.1019 +        return;
  1.1020 +      }
  1.1021 +    }
  1.1022 +    soundEnableChannels(0x30f);
  1.1023 +    sSoundStatus = "on";
  1.1024 +    break;
  1.1025 +  }
  1.1026 +  m_poSoundConfig->vSetKey("status", sSoundStatus);
  1.1027 +}
  1.1028 +
  1.1029 +void Window::vOnSoundEchoToggled(Gtk::CheckMenuItem * _poCMI)
  1.1030 +{
  1.1031 +  soundEcho = _poCMI->get_active();
  1.1032 +  m_poSoundConfig->vSetKey("echo", soundEcho);
  1.1033 +}
  1.1034 +
  1.1035 +void Window::vOnSoundLowPassToggled(Gtk::CheckMenuItem * _poCMI)
  1.1036 +{
  1.1037 +  soundLowPass = _poCMI->get_active();
  1.1038 +  m_poSoundConfig->vSetKey("low_pass", soundLowPass);
  1.1039 +}
  1.1040 +
  1.1041 +void Window::vOnSoundReverseToggled(Gtk::CheckMenuItem * _poCMI)
  1.1042 +{
  1.1043 +  soundReverse = _poCMI->get_active();
  1.1044 +  m_poSoundConfig->vSetKey("reverse_stereo", soundReverse);
  1.1045 +}
  1.1046 +
  1.1047 +void Window::vOnSoundChannelToggled(Gtk::CheckMenuItem * _poCMI, int _iSoundChannel)
  1.1048 +{
  1.1049 +  int iShift = _iSoundChannel;
  1.1050 +  if (_iSoundChannel > 3)
  1.1051 +  {
  1.1052 +    iShift += 4;
  1.1053 +  }
  1.1054 +  int iFlag = 1 << iShift;
  1.1055 +  int iActive = soundGetEnabledChannels() & 0x30f;
  1.1056 +  if (_poCMI->get_active())
  1.1057 +  {
  1.1058 +    iActive |= iFlag;
  1.1059 +  }
  1.1060 +  else
  1.1061 +  {
  1.1062 +    iActive &= ~iFlag;
  1.1063 +  }
  1.1064 +  soundEnableChannels(iActive);
  1.1065 +  soundDisableChannels(~iActive & 0x30f);
  1.1066 +
  1.1067 +  const char * acsChannels[] =
  1.1068 +  {
  1.1069 +    "channel_1",
  1.1070 +    "channel_2",
  1.1071 +    "channel_3",
  1.1072 +    "channel_4",
  1.1073 +    "channel_A",
  1.1074 +    "channel_B"
  1.1075 +  };
  1.1076 +  m_poSoundConfig->vSetKey(acsChannels[_iSoundChannel], _poCMI->get_active());
  1.1077 +}
  1.1078 +
  1.1079 +void Window::vOnSoundQualityToggled(Gtk::CheckMenuItem * _poCMI, int _iSoundQuality)
  1.1080 +{
  1.1081 +  if (! _poCMI->get_active())
  1.1082 +  {
  1.1083 +    return;
  1.1084 +  }
  1.1085 +
  1.1086 +  m_eSoundQuality = (ESoundQuality)_iSoundQuality;
  1.1087 +  if (m_eCartridge == CartridgeGBA)
  1.1088 +  {
  1.1089 +    soundSetQuality(_iSoundQuality);
  1.1090 +  }
  1.1091 +  else if (m_eCartridge == CartridgeGB)
  1.1092 +  {
  1.1093 +    gbSoundSetQuality(_iSoundQuality);
  1.1094 +  }
  1.1095 +  m_poSoundConfig->vSetKey("quality", _iSoundQuality);
  1.1096 +}
  1.1097 +
  1.1098 +void Window::vOnSoundVolumeToggled(Gtk::CheckMenuItem * _poCMI, int _iSoundVolume)
  1.1099 +{
  1.1100 +  if (! _poCMI->get_active())
  1.1101 +  {
  1.1102 +    return;
  1.1103 +  }
  1.1104 +
  1.1105 +  soundVolume = _iSoundVolume;
  1.1106 +  m_poSoundConfig->vSetKey("volume", _iSoundVolume);
  1.1107 +}
  1.1108 +
  1.1109 +void Window::vOnGBBorderToggled(Gtk::CheckMenuItem * _poCMI)
  1.1110 +{
  1.1111 +  gbBorderOn = _poCMI->get_active();
  1.1112 +  if (emulating && m_eCartridge == CartridgeGB && _poCMI->get_active())
  1.1113 +  {
  1.1114 +    gbSgbRenderBorder();
  1.1115 +  }
  1.1116 +  vUpdateScreen();
  1.1117 +  m_poCoreConfig->vSetKey("gb_border", _poCMI->get_active());
  1.1118 +}
  1.1119 +
  1.1120 +void Window::vOnGBPrinterToggled(Gtk::CheckMenuItem * _poCMI)
  1.1121 +{
  1.1122 +  if (_poCMI->get_active())
  1.1123 +  {
  1.1124 +    gbSerialFunction = gbPrinterSend;
  1.1125 +  }
  1.1126 +  else
  1.1127 +  {
  1.1128 +    gbSerialFunction = NULL;
  1.1129 +  }
  1.1130 +  m_poCoreConfig->vSetKey("gb_printer", _poCMI->get_active());
  1.1131 +}
  1.1132 +
  1.1133 +void Window::vOnEmulatorTypeToggled(Gtk::CheckMenuItem * _poCMI, int _iEmulatorType)
  1.1134 +{
  1.1135 +  gbEmulatorType = _iEmulatorType;
  1.1136 +  m_poCoreConfig->vSetKey("emulator_type", _iEmulatorType);
  1.1137 +}
  1.1138 +
  1.1139 +void Window::vOnFilter2xToggled(Gtk::CheckMenuItem * _poCMI, int _iFilter2x)
  1.1140 +{
  1.1141 +  if (! _poCMI->get_active())
  1.1142 +  {
  1.1143 +    return;
  1.1144 +  }
  1.1145 +
  1.1146 +  m_poScreenArea->vSetFilter2x((EFilter2x)_iFilter2x);
  1.1147 +  if (emulating)
  1.1148 +  {
  1.1149 +    vDrawScreen();
  1.1150 +  }
  1.1151 +  m_poDisplayConfig->vSetKey("filter2x", _iFilter2x);
  1.1152 +}
  1.1153 +
  1.1154 +void Window::vOnFilterIBToggled(Gtk::CheckMenuItem * _poCMI, int _iFilterIB)
  1.1155 +{
  1.1156 +  if (! _poCMI->get_active())
  1.1157 +  {
  1.1158 +    return;
  1.1159 +  }
  1.1160 +
  1.1161 +  m_poScreenArea->vSetFilterIB((EFilterIB)_iFilterIB);
  1.1162 +  if (emulating)
  1.1163 +  {
  1.1164 +    vDrawScreen();
  1.1165 +  }
  1.1166 +  m_poDisplayConfig->vSetKey("filterIB", _iFilterIB);
  1.1167 +}
  1.1168 +
  1.1169 +#ifdef MMX
  1.1170 +void Window::vOnDisableMMXToggled(Gtk::CheckMenuItem * _poCMI)
  1.1171 +{
  1.1172 +  cpu_mmx = ! _poCMI->get_active();
  1.1173 +  m_poDisplayConfig->vSetKey("filter_disable_mmx", _poCMI->get_active());
  1.1174 +}
  1.1175 +#endif // MMX
  1.1176 +
  1.1177 +void Window::vOnJoypadConfigure(int _iJoypad)
  1.1178 +{
  1.1179 +  Glib::RefPtr<Xml> poXml;
  1.1180 +  poXml = Xml::create(PKGDATADIR "/vba.glade", "JoypadConfigDialog");
  1.1181 +
  1.1182 +  JoypadConfigDialog * poDialog = NULL;
  1.1183 +  poXml->get_widget_derived<JoypadConfigDialog>("JoypadConfigDialog", poDialog);
  1.1184 +  poDialog->set_transient_for(*this);
  1.1185 +  poDialog->vSetConfig(m_oJoypads[_iJoypad - 1]);
  1.1186 +
  1.1187 +  if (poDialog->run() == Gtk::RESPONSE_OK)
  1.1188 +  {
  1.1189 +    m_oJoypads[_iJoypad - 1] = poDialog->stGetConfig();
  1.1190 +    if (_iJoypad == m_poInputConfig->oGetKey<int>("active_joypad"))
  1.1191 +    {
  1.1192 +      if (m_poKeymap != NULL)
  1.1193 +      {
  1.1194 +        delete m_poKeymap;
  1.1195 +      }
  1.1196 +      m_poKeymap = m_oJoypads[_iJoypad - 1].poCreateKeymap();
  1.1197 +    }
  1.1198 +  }
  1.1199 +
  1.1200 +  delete poDialog;
  1.1201 +}
  1.1202 +
  1.1203 +void Window::vOnJoypadToggled(Gtk::CheckMenuItem * _poCMI, int _iJoypad)
  1.1204 +{
  1.1205 +  if (! _poCMI->get_active())
  1.1206 +  {
  1.1207 +    return;
  1.1208 +  }
  1.1209 +
  1.1210 +  if (m_poKeymap != NULL)
  1.1211 +  {
  1.1212 +    delete m_poKeymap;
  1.1213 +  }
  1.1214 +  m_poKeymap = m_oJoypads[_iJoypad - 1].poCreateKeymap();
  1.1215 +
  1.1216 +  m_poInputConfig->vSetKey("active_joypad", _iJoypad);
  1.1217 +}
  1.1218 +
  1.1219 +void Window::vOnAutofireToggled(Gtk::CheckMenuItem * _poCMI, u32 _uiKeyFlag)
  1.1220 +{
  1.1221 +  if (_poCMI->get_active())
  1.1222 +  {
  1.1223 +    m_uiAutofireState |= _uiKeyFlag;
  1.1224 +  }
  1.1225 +  else
  1.1226 +  {
  1.1227 +    m_uiAutofireState &= ~_uiKeyFlag;
  1.1228 +  }
  1.1229 +
  1.1230 +  std::string sKey;
  1.1231 +  if (_uiKeyFlag == KeyFlagA)
  1.1232 +  {
  1.1233 +    sKey = "autofire_A";
  1.1234 +  }
  1.1235 +  else if (_uiKeyFlag == KeyFlagB)
  1.1236 +  {
  1.1237 +    sKey = "autofire_B";
  1.1238 +  }
  1.1239 +  else if (_uiKeyFlag == KeyFlagL)
  1.1240 +  {
  1.1241 +    sKey = "autofire_L";
  1.1242 +  }
  1.1243 +  else if (_uiKeyFlag == KeyFlagR)
  1.1244 +  {
  1.1245 +    sKey = "autofire_R";
  1.1246 +  }
  1.1247 +  m_poInputConfig->vSetKey(sKey, _poCMI->get_active());
  1.1248 +}
  1.1249 +
  1.1250 +void Window::vOnGDBWait()
  1.1251 +{
  1.1252 +  Glib::RefPtr<Xml> poXml;
  1.1253 +  poXml = Xml::create(PKGDATADIR "/vba.glade", "TcpPortDialog");
  1.1254 +
  1.1255 +  Gtk::Dialog * poDialog = dynamic_cast<Gtk::Dialog *>(poXml->get_widget("TcpPortDialog"));
  1.1256 +  Gtk::SpinButton * poSpin = dynamic_cast<Gtk::SpinButton *>(poXml->get_widget("TcpPortSpin"));
  1.1257 +
  1.1258 +  poDialog->set_transient_for(*this);
  1.1259 +
  1.1260 +  int iPort = 55555;
  1.1261 +  poSpin->set_value(iPort);  
  1.1262 +
  1.1263 +  bool bOk = false;
  1.1264 +  if (poDialog->run() == Gtk::RESPONSE_OK)
  1.1265 +  {
  1.1266 +    bOk = true;
  1.1267 +    iPort = poSpin->get_value_as_int();
  1.1268 +  }
  1.1269 +  delete poDialog;
  1.1270 +
  1.1271 +  if (! bOk)
  1.1272 +  {
  1.1273 +    return;
  1.1274 +  }
  1.1275 +
  1.1276 +  m_eCartridge = CartridgeGBA;
  1.1277 +  m_sRomFile   = "gnu_stub";
  1.1278 +  m_stEmulator = GBASystem;
  1.1279 +
  1.1280 +  rom         = (u8 *) malloc(0x2000000);
  1.1281 +  workRAM     = (u8 *) calloc(1, 0x40000);
  1.1282 +  bios        = (u8 *) calloc(1, 0x4000);
  1.1283 +  internalRAM = (u8 *) calloc(1, 0x8000);
  1.1284 +  paletteRAM  = (u8 *) calloc(1, 0x400);
  1.1285 +  vram        = (u8 *) calloc(1, 0x20000);
  1.1286 +  oam         = (u8 *) calloc(1, 0x400);
  1.1287 +  pix         = (u8 *) calloc(1, 4 * m_iGBAScreenWidth * m_iGBAScreenHeight);
  1.1288 +  ioMem       = (u8 *) calloc(1, 0x400);
  1.1289 +
  1.1290 +  useBios = m_poCoreConfig->oGetKey<bool>("use_bios_file");
  1.1291 +  //CPUInit(m_poCoreConfig->sGetKey("bios_file").c_str(), useBios);
  1.1292 +  CPUInit();
  1.1293 +  CPUReset();
  1.1294 +
  1.1295 +  for (std::list<Gtk::Widget *>::iterator it = m_listSensitiveWhenPlaying.begin();
  1.1296 +       it != m_listSensitiveWhenPlaying.end();
  1.1297 +       it++)
  1.1298 +  {
  1.1299 +    (*it)->set_sensitive();
  1.1300 +  }
  1.1301 +
  1.1302 +  if (m_poCoreConfig->oGetKey<bool>("load_game_auto"))
  1.1303 +  {
  1.1304 +    vOnLoadGameMostRecent();
  1.1305 +  }
  1.1306 +
  1.1307 +  vStartEmu();
  1.1308 +
  1.1309 +  emulating = 1;
  1.1310 +
  1.1311 +  dbgMain   = remoteStubMain;
  1.1312 +  dbgSignal = remoteStubSignal;
  1.1313 +  dbgOutput = remoteOutput;
  1.1314 +  debugger  = true;
  1.1315 +
  1.1316 +  remoteSetProtocol(0);
  1.1317 +  remoteSetPort(iPort);
  1.1318 +  remoteInit();
  1.1319 +}
  1.1320 +
  1.1321 +void Window::vOnGDBLoadAndWait()
  1.1322 +{
  1.1323 +  bool bLoaded = false;
  1.1324 +
  1.1325 +  while (m_poFileOpenDialog->run() == Gtk::RESPONSE_OK)
  1.1326 +  {
  1.1327 +    if (bLoadROM(m_poFileOpenDialog->get_filename()))
  1.1328 +    {
  1.1329 +      bLoaded = true;
  1.1330 +      break;
  1.1331 +    }
  1.1332 +  }
  1.1333 +  m_poFileOpenDialog->hide();
  1.1334 +
  1.1335 +  if (! bLoaded)
  1.1336 +  {
  1.1337 +    return;
  1.1338 +  }
  1.1339 +
  1.1340 +  if (m_eCartridge != CartridgeGBA)
  1.1341 +  {
  1.1342 +    vPopupError(_("Only GBA images are supported."));
  1.1343 +    vOnFileClose();
  1.1344 +    return;
  1.1345 +  }
  1.1346 +
  1.1347 +  Glib::RefPtr<Xml> poXml;
  1.1348 +  poXml = Xml::create(PKGDATADIR "/vba.glade", "TcpPortDialog");
  1.1349 +
  1.1350 +  Gtk::Dialog * poDialog = dynamic_cast<Gtk::Dialog *>(poXml->get_widget("TcpPortDialog"));
  1.1351 +  Gtk::SpinButton * poSpin = dynamic_cast<Gtk::SpinButton *>(poXml->get_widget("TcpPortSpin"));
  1.1352 +
  1.1353 +  poDialog->set_transient_for(*this);
  1.1354 +
  1.1355 +  int iPort = 55555;
  1.1356 +  poSpin->set_value(iPort);  
  1.1357 +
  1.1358 +  bool bOk = false;
  1.1359 +  if (poDialog->run() == Gtk::RESPONSE_OK)
  1.1360 +  {
  1.1361 +    bOk = true;
  1.1362 +    iPort = poSpin->get_value_as_int();
  1.1363 +  }
  1.1364 +  delete poDialog;
  1.1365 +
  1.1366 +  if (! bOk)
  1.1367 +  {
  1.1368 +    return;
  1.1369 +  }
  1.1370 +
  1.1371 +  dbgMain   = remoteStubMain;
  1.1372 +  dbgSignal = remoteStubSignal;
  1.1373 +  dbgOutput = remoteOutput;
  1.1374 +  debugger  = true;
  1.1375 +
  1.1376 +  remoteSetProtocol(0);
  1.1377 +  remoteSetPort(iPort);
  1.1378 +  remoteInit();
  1.1379 +}
  1.1380 +
  1.1381 +void Window::vOnGDBBreak()
  1.1382 +{
  1.1383 +  if (armState)
  1.1384 +  {
  1.1385 +    armNextPC -= 4;
  1.1386 +    reg[15].I -= 4;
  1.1387 +  }
  1.1388 +  else
  1.1389 +  {
  1.1390 +    armNextPC -= 2;
  1.1391 +    reg[15].I -= 2;
  1.1392 +  }
  1.1393 +
  1.1394 +  debugger = true;
  1.1395 +}
  1.1396 +
  1.1397 +void Window::vOnGDBDisconnect()
  1.1398 +{
  1.1399 +  remoteCleanUp();
  1.1400 +  debugger = false;
  1.1401 +}
  1.1402 +
  1.1403 +void Window::vOnHelpAbout()
  1.1404 +{
  1.1405 +  Glib::RefPtr<Xml> poXml;
  1.1406 +  poXml = Xml::create(PKGDATADIR "/vba.glade", "AboutDialog");
  1.1407 +
  1.1408 +  Gtk::Dialog * poDialog = dynamic_cast<Gtk::Dialog *>(poXml->get_widget("AboutDialog"));
  1.1409 +  poDialog->set_transient_for(*this);
  1.1410 +
  1.1411 +  Gtk::Image oIcon(PKGDATADIR "/vba-64.png");
  1.1412 +  oIcon.show();
  1.1413 +  Gtk::Container * poIconContainer = dynamic_cast<Gtk::Container *>(poXml->get_widget("AboutIconContainer"));
  1.1414 +  poIconContainer->add(oIcon);
  1.1415 +
  1.1416 +  Gtk::Label * poLabel  = dynamic_cast<Gtk::Label *>(poXml->get_widget("VersionLabel"));
  1.1417 +  poLabel->set_markup("<b><big>" PACKAGE " " VERSION "</big></b>");
  1.1418 +
  1.1419 +  poDialog->run();
  1.1420 +  delete poDialog;
  1.1421 +}
  1.1422 +
  1.1423 +bool Window::bOnEmuIdle()
  1.1424 +{
  1.1425 +  if (debugger && m_stEmulator.emuHasDebugger)
  1.1426 +  {
  1.1427 +    dbgMain();
  1.1428 +    return true;
  1.1429 +  }
  1.1430 +
  1.1431 +  if (m_uiThrottleDelay != 0)
  1.1432 +  {
  1.1433 +    u32 uiTime = SDL_GetTicks();
  1.1434 +    if (uiTime - m_uiThrottleLastTime >= m_uiThrottleDelay)
  1.1435 +    {
  1.1436 +      m_uiThrottleDelay = 0;
  1.1437 +      m_uiThrottleLastTime = uiTime;
  1.1438 +    }
  1.1439 +    else
  1.1440 +    {
  1.1441 +      return true;
  1.1442 +    }
  1.1443 +  }
  1.1444 +
  1.1445 +  m_stEmulator.emuMain(m_stEmulator.emuCount);
  1.1446 +  return true;
  1.1447 +}
  1.1448 +
  1.1449 +bool Window::on_focus_in_event(GdkEventFocus * _pstEvent)
  1.1450 +{
  1.1451 +  if (emulating
  1.1452 +      && ! m_bPaused
  1.1453 +      && m_poDisplayConfig->oGetKey<bool>("pause_when_inactive"))
  1.1454 +  {
  1.1455 +    vStartEmu();
  1.1456 +    soundResume();
  1.1457 +  }
  1.1458 +  return false;
  1.1459 +}
  1.1460 +
  1.1461 +bool Window::on_focus_out_event(GdkEventFocus * _pstEvent)
  1.1462 +{
  1.1463 +  if (emulating
  1.1464 +      && ! m_bPaused
  1.1465 +      && m_poDisplayConfig->oGetKey<bool>("pause_when_inactive"))
  1.1466 +  {
  1.1467 +    vStopEmu();
  1.1468 +    soundPause();
  1.1469 +  }
  1.1470 +  return false;
  1.1471 +}
  1.1472 +
  1.1473 +bool Window::on_key_press_event(GdkEventKey * _pstEvent)
  1.1474 +{
  1.1475 +  EKey eKey;
  1.1476 +
  1.1477 +  if ((_pstEvent->state & Gtk::AccelGroup::get_default_mod_mask())
  1.1478 +      || (eKey = m_poKeymap->eGetKey(_pstEvent->hardware_keycode)) == KeyNone)
  1.1479 +  {
  1.1480 +    return Gtk::Window::on_key_press_event(_pstEvent);
  1.1481 +  }
  1.1482 +
  1.1483 +  switch (eKey)
  1.1484 +  {
  1.1485 +  case KeyA:
  1.1486 +    m_uiJoypadState |= KeyFlagA;
  1.1487 +    break;
  1.1488 +  case KeyB:
  1.1489 +    m_uiJoypadState |= KeyFlagB;
  1.1490 +    break;
  1.1491 +  case KeySelect:
  1.1492 +    m_uiJoypadState |= KeyFlagSelect;
  1.1493 +    break;
  1.1494 +  case KeyStart:
  1.1495 +    m_uiJoypadState |= KeyFlagStart;
  1.1496 +    break;
  1.1497 +  case KeyRight:
  1.1498 +    m_uiJoypadState |= KeyFlagRight;
  1.1499 +    m_uiJoypadState &= ~KeyFlagLeft;
  1.1500 +    break;
  1.1501 +  case KeyLeft:
  1.1502 +    m_uiJoypadState |= KeyFlagLeft;
  1.1503 +    m_uiJoypadState &= ~KeyFlagRight;
  1.1504 +    break;
  1.1505 +  case KeyUp:
  1.1506 +    m_uiJoypadState |= KeyFlagUp;
  1.1507 +    m_uiJoypadState &= ~KeyFlagDown;
  1.1508 +    break;
  1.1509 +  case KeyDown:
  1.1510 +    m_uiJoypadState |= KeyFlagDown;
  1.1511 +    m_uiJoypadState &= ~KeyFlagUp;
  1.1512 +    break;
  1.1513 +  case KeyR:
  1.1514 +    m_uiJoypadState |= KeyFlagR;
  1.1515 +    break;
  1.1516 +  case KeyL:
  1.1517 +    m_uiJoypadState |= KeyFlagL;
  1.1518 +    break;
  1.1519 +  case KeySpeed:
  1.1520 +    m_uiJoypadState |= KeyFlagSpeed;
  1.1521 +    break;
  1.1522 +  case KeyCapture:
  1.1523 +    m_uiJoypadState |= KeyFlagCapture;
  1.1524 +    break;
  1.1525 +  case KeyNone:
  1.1526 +    break;
  1.1527 +  }
  1.1528 +  return true;
  1.1529 +}
  1.1530 +
  1.1531 +bool Window::on_key_release_event(GdkEventKey * _pstEvent)
  1.1532 +{
  1.1533 +  EKey eKey;
  1.1534 +
  1.1535 +  if ((_pstEvent->state & Gtk::AccelGroup::get_default_mod_mask())
  1.1536 +      || (eKey = m_poKeymap->eGetKey(_pstEvent->hardware_keycode)) == KeyNone)
  1.1537 +  {
  1.1538 +    return Gtk::Window::on_key_release_event(_pstEvent);
  1.1539 +  }
  1.1540 +
  1.1541 +  switch (eKey)
  1.1542 +  {
  1.1543 +  case KeyA:
  1.1544 +    m_uiJoypadState &= ~KeyFlagA;
  1.1545 +    break;
  1.1546 +  case KeyB:
  1.1547 +    m_uiJoypadState &= ~KeyFlagB;
  1.1548 +    break;
  1.1549 +  case KeySelect:
  1.1550 +    m_uiJoypadState &= ~KeyFlagSelect;
  1.1551 +    break;
  1.1552 +  case KeyStart:
  1.1553 +    m_uiJoypadState &= ~KeyFlagStart;
  1.1554 +    break;
  1.1555 +  case KeyRight:
  1.1556 +    m_uiJoypadState &= ~KeyFlagRight;
  1.1557 +    break;
  1.1558 +  case KeyLeft:
  1.1559 +    m_uiJoypadState &= ~KeyFlagLeft;
  1.1560 +    break;
  1.1561 +  case KeyUp:
  1.1562 +    m_uiJoypadState &= ~KeyFlagUp;
  1.1563 +    break;
  1.1564 +  case KeyDown:
  1.1565 +    m_uiJoypadState &= ~KeyFlagDown;
  1.1566 +    break;
  1.1567 +  case KeyR:
  1.1568 +    m_uiJoypadState &= ~KeyFlagR;
  1.1569 +    break;
  1.1570 +  case KeyL:
  1.1571 +    m_uiJoypadState &= ~KeyFlagL;
  1.1572 +    break;
  1.1573 +  case KeySpeed:
  1.1574 +    m_uiJoypadState &= ~KeyFlagSpeed;
  1.1575 +    break;
  1.1576 +  case KeyCapture:
  1.1577 +    m_uiJoypadState &= ~KeyFlagCapture;
  1.1578 +    break;
  1.1579 +  case KeyNone:
  1.1580 +    break;
  1.1581 +  }
  1.1582 +  return true;
  1.1583 +}
  1.1584 +
  1.1585 +} // namespace VBA