diff src/win32/VBA.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/win32/VBA.cpp	Sat Mar 03 10:31:27 2012 -0600
     1.3 @@ -0,0 +1,2272 @@
     1.4 +// VBA.cpp : Defines the class behaviors for the application.
     1.5 +//
     1.6 +#include "stdafx.h"
     1.7 +#include <mmsystem.h>
     1.8 +#include <cassert>
     1.9 +
    1.10 +#include "resource.h"
    1.11 +#include "VBA.h"
    1.12 +#include "AVIWrite.h"
    1.13 +#include "Input.h"
    1.14 +#include "IUpdate.h"
    1.15 +#include "LangSelect.h"
    1.16 +#include "MainWnd.h"
    1.17 +#include "Reg.h"
    1.18 +#include "WavWriter.h"
    1.19 +#include "WinResUtil.h"
    1.20 +#include "WinMiscUtil.h"
    1.21 +#include "ramwatch.h"
    1.22 +
    1.23 +#include "../gba/GBA.h"
    1.24 +#include "../gba/GBAGlobals.h"
    1.25 +#include "../gba/agbprint.h"
    1.26 +#include "../gb/GB.h"
    1.27 +#include "../gb/gbGlobals.h"
    1.28 +#include "../gb/gbPrinter.h"
    1.29 +#include "../common/CheatSearch.h"
    1.30 +#include "../gba/RTC.h"
    1.31 +#include "../gba/GBASound.h"
    1.32 +#include "../common/Util.h"
    1.33 +#include "../common/Text.h"
    1.34 +#include "../common/movie.h"
    1.35 +#include "../common/nesvideos-piece.h"
    1.36 +#include "../common/vbalua.h"
    1.37 +#include "../filters/filters.h"
    1.38 +#include "../version.h"
    1.39 +
    1.40 +extern IDisplay *newGDIDisplay();
    1.41 +extern IDisplay *newDirectDrawDisplay();
    1.42 +extern IDisplay *newDirect3DDisplay();
    1.43 +extern IDisplay *newOpenGLDisplay();
    1.44 +
    1.45 +extern Input *newDirectInput();
    1.46 +
    1.47 +extern void remoteStubSignal(int, int);
    1.48 +extern void remoteOutput(char *, u32);
    1.49 +extern void remoteStubMain();
    1.50 +extern void remoteSetProtocol(int);
    1.51 +extern void remoteCleanUp();
    1.52 +extern int remoteSocket;
    1.53 +
    1.54 +void winlog(const char *msg, ...);
    1.55 +
    1.56 +bool debugger = false;
    1.57 +
    1.58 +char movieFileToPlay[1024];
    1.59 +bool playMovieFile		   = false;
    1.60 +bool playMovieFileReadOnly = false;
    1.61 +char wavFileToOutput [1024];
    1.62 +bool outputWavFile	= false;
    1.63 +bool outputAVIFile	= false;
    1.64 +bool flagHideMenu	= false;
    1.65 +int	 quitAfterTime	= -1;
    1.66 +int	 pauseAfterTime = -1;
    1.67 +
    1.68 +void winSignal(int, int);
    1.69 +void winOutput(char *, u32);
    1.70 +
    1.71 +void (*dbgSignal)(int, int)	   = winSignal;
    1.72 +void (*dbgOutput)(char *, u32) = winOutput;
    1.73 +
    1.74 +#ifdef MMX
    1.75 +extern "C" bool cpu_mmx;
    1.76 +#endif
    1.77 +
    1.78 +// nowhere good to put them to
    1.79 +
    1.80 +void DrawTextMessages(u8 *dest, int pitch, int left, int bottom)
    1.81 +{
    1.82 +	for (int slot = 0; slot < SCREEN_MESSAGE_SLOTS; slot++)
    1.83 +	{
    1.84 +		if (theApp.screenMessage[slot])
    1.85 +		{
    1.86 +			if ((theApp.screenMessageDuration[slot] < 0 ||
    1.87 +			     (int)(GetTickCount() - theApp.screenMessageTime[slot]) < theApp.screenMessageDuration[slot]) &&
    1.88 +			    (!theApp.disableStatusMessage || slot == 1 || slot == 2))
    1.89 +			{
    1.90 +				drawText(dest,
    1.91 +				         pitch,
    1.92 +				         left,
    1.93 +				         bottom - 10 * (slot + 1),
    1.94 +				         theApp.screenMessageBuffer[slot],
    1.95 +				         theApp.screenMessageColorBuffer[slot]);
    1.96 +			}
    1.97 +			else
    1.98 +			{
    1.99 +				theApp.screenMessage[slot] = false;
   1.100 +			}
   1.101 +		}
   1.102 +	}
   1.103 +}
   1.104 +
   1.105 +// draw Lua graphics in game screen
   1.106 +void DrawLuaGui()
   1.107 +{
   1.108 +	int copyX		= 240, copyY       = 160;
   1.109 +	int screenX		= 240, screenY     = 160;
   1.110 +	int copyOffsetX = 0,   copyOffsetY = 0;
   1.111 +	if (systemCartridgeType == 1)
   1.112 +	{
   1.113 +		if (gbBorderOn)
   1.114 +		{
   1.115 +			copyX		= 256, copyY       = 224;
   1.116 +			screenX		= 256, screenY     = 224;
   1.117 +		}
   1.118 +		else
   1.119 +		{
   1.120 +			copyX = 160, copyY = 144;
   1.121 +			screenX = 160, screenY = 144;
   1.122 +		}
   1.123 +	}
   1.124 +	int pitch = copyX * (systemColorDepth / 8) + (systemColorDepth == 24 ? 0 : 4);
   1.125 +
   1.126 +	++copyOffsetY; // don't know why it's needed
   1.127 +
   1.128 +	VBALuaGui(&pix[copyOffsetY * pitch + copyOffsetX * (systemColorDepth / 8)], copyX, screenX, screenY);
   1.129 +	VBALuaClearGui();
   1.130 +}
   1.131 +
   1.132 +void directXMessage(const char *msg)
   1.133 +{
   1.134 +	systemMessage(
   1.135 +	    IDS_DIRECTX_7_REQUIRED,
   1.136 +	    "DirectX 7.0 or greater is required to run.\nDownload at http://www.microsoft.com/directx.\n\nError found at: %s",
   1.137 +	    msg);
   1.138 +}
   1.139 +
   1.140 +void winlog(const char *msg, ...)
   1.141 +{
   1.142 +	CString buffer;
   1.143 +	va_list valist;
   1.144 +
   1.145 +	va_start(valist, msg);
   1.146 +	buffer.FormatV(msg, valist);
   1.147 +
   1.148 +	FILE *winout = fopen("vba-trace.log", "w");
   1.149 +
   1.150 +	fputs(buffer, winout);
   1.151 +
   1.152 +	fclose(winout);
   1.153 +
   1.154 +	va_end(valist);
   1.155 +}
   1.156 +
   1.157 +// code from SDL_main.c for Windows
   1.158 +/* Parse a command line buffer into arguments */
   1.159 +
   1.160 +static int parseCommandLine(char *cmdline, char * *argv)
   1.161 +{
   1.162 +	char *bufp;
   1.163 +	int	  argc;
   1.164 +
   1.165 +	argc = 0;
   1.166 +	for (bufp = cmdline; *bufp; )
   1.167 +	{
   1.168 +		/* Skip leading whitespace */
   1.169 +		while (isspace(*bufp))
   1.170 +		{
   1.171 +			++bufp;
   1.172 +		}
   1.173 +		/* Skip over argument */
   1.174 +		if (*bufp == '"')
   1.175 +		{
   1.176 +			++bufp;
   1.177 +			if (*bufp)
   1.178 +			{
   1.179 +				if (argv)
   1.180 +				{
   1.181 +					argv[argc] = bufp;
   1.182 +				}
   1.183 +				++argc;
   1.184 +			}
   1.185 +			/* Skip over word */
   1.186 +			while (*bufp && (*bufp != '"'))
   1.187 +			{
   1.188 +				++bufp;
   1.189 +			}
   1.190 +		}
   1.191 +		else
   1.192 +		{
   1.193 +			if (*bufp)
   1.194 +			{
   1.195 +				if (argv)
   1.196 +				{
   1.197 +					argv[argc] = bufp;
   1.198 +				}
   1.199 +				++argc;
   1.200 +			}
   1.201 +			/* Skip over word */
   1.202 +			while (*bufp && !isspace(*bufp))
   1.203 +			{
   1.204 +				++bufp;
   1.205 +			}
   1.206 +		}
   1.207 +		if (*bufp)
   1.208 +		{
   1.209 +			if (argv)
   1.210 +			{
   1.211 +				*bufp = '\0';
   1.212 +			}
   1.213 +			++bufp;
   1.214 +		}
   1.215 +	}
   1.216 +	if (argv)
   1.217 +	{
   1.218 +		argv[argc] = NULL;
   1.219 +	}
   1.220 +	return(argc);
   1.221 +}
   1.222 +
   1.223 +static void debugSystemScreenMessage1(const char *msg)
   1.224 +{
   1.225 +	systemScreenMessage(msg, 3);
   1.226 +}
   1.227 +
   1.228 +static void debugSystemScreenMessage2(const char *msg)
   1.229 +{
   1.230 +	systemScreenMessage(msg, 4);
   1.231 +}
   1.232 +
   1.233 +static void winSignal(int, int)
   1.234 +{}
   1.235 +
   1.236 +#define CPUReadByteQuick(addr) \
   1.237 +    map[(addr) >> 24].address[(addr) & map[(addr) >> 24].mask]
   1.238 +
   1.239 +static void winOutput(char *s, u32 addr)
   1.240 +{
   1.241 +	if (s)
   1.242 +	{
   1.243 +		log(s);
   1.244 +	}
   1.245 +	else
   1.246 +	{
   1.247 +		CString str;
   1.248 +		char	c;
   1.249 +
   1.250 +		c = CPUReadByteQuick(addr);
   1.251 +		addr++;
   1.252 +		while (c)
   1.253 +		{
   1.254 +			str += c;
   1.255 +			c	 = CPUReadByteQuick(addr);
   1.256 +			addr++;
   1.257 +		}
   1.258 +		log(str);
   1.259 +	}
   1.260 +}
   1.261 +
   1.262 +typedef BOOL (WINAPI * GETMENUBARINFO)(HWND, LONG, LONG, PMENUBARINFO);
   1.263 +
   1.264 +static int winGetMenuBarHeight()
   1.265 +{
   1.266 +	HINSTANCE hinstDll = /**/ ::LoadLibrary("USER32.DLL");
   1.267 +
   1.268 +	if (hinstDll)
   1.269 +	{
   1.270 +		GETMENUBARINFO func = (GETMENUBARINFO)GetProcAddress(hinstDll, "GetMenuBarInfo");
   1.271 +
   1.272 +		if (func)
   1.273 +		{
   1.274 +			MENUBARINFO info;
   1.275 +			info.cbSize = sizeof(info);
   1.276 +
   1.277 +			func(AfxGetMainWnd()->GetSafeHwnd(), OBJID_MENU, 0, &info);
   1.278 +
   1.279 +			/**/ ::FreeLibrary(hinstDll);
   1.280 +
   1.281 +			return info.rcBar.bottom - info.rcBar.top + 1;
   1.282 +		}
   1.283 +	}
   1.284 +
   1.285 +	return GetSystemMetrics(SM_CYMENU);
   1.286 +}
   1.287 +
   1.288 +/////////////////////////////////////////////////////////////////////////////
   1.289 +// VBA
   1.290 +
   1.291 +BEGIN_MESSAGE_MAP(VBA, CWinApp)
   1.292 +//{{AFX_MSG_MAP(VBA)
   1.293 +// NOTE - the ClassWizard will add and remove mapping macros here.
   1.294 +//    DO NOT EDIT what you see in these blocks of generated code!
   1.295 +//}}AFX_MSG_MAP
   1.296 +END_MESSAGE_MAP()
   1.297 +
   1.298 +/////////////////////////////////////////////////////////////////////////////
   1.299 +// The one and only VBA object
   1.300 +
   1.301 +VBA theApp;
   1.302 +
   1.303 +/////////////////////////////////////////////////////////////////////////////
   1.304 +// VBA construction
   1.305 +
   1.306 +VBA::VBA() : emulator(::theEmulator)
   1.307 +{
   1.308 +	// important
   1.309 +	{
   1.310 +#ifdef MULTITHREAD_STDLOCALE_WORKAROUND
   1.311 +		// Note: there's a known threading bug regarding std::locale with MSVC according to
   1.312 +		// http://connect.microsoft.com/VisualStudio/feedback/details/492128/std-locale-constructor-modifies-global-locale-via-setlocale
   1.313 +		int iPreviousFlag = ::_configthreadlocale(_ENABLE_PER_THREAD_LOCALE);
   1.314 +#endif
   1.315 +		using std::locale;
   1.316 +		locale::global(locale(locale::classic(), "", locale::collate | locale::ctype));
   1.317 +
   1.318 +#ifdef MULTITHREAD_STDLOCALE_WORKAROUND
   1.319 +		if (iPreviousFlag > 0 )
   1.320 +			::_configthreadlocale(iPreviousFlag);
   1.321 +#endif
   1.322 +	}
   1.323 +
   1.324 +	mode320Available	 = false;
   1.325 +	mode640Available	 = false;
   1.326 +	mode800Available	 = false;
   1.327 +	windowPositionX		 = 0;
   1.328 +	windowPositionY		 = 0;
   1.329 +	filterFunction		 = NULL;
   1.330 +	ifbFunction			 = NULL;
   1.331 +	ifbType				 = 0;
   1.332 +	filterType			 = 0;
   1.333 +	filterWidth			 = 0;
   1.334 +	filterHeight		 = 0;
   1.335 +	fsWidth				 = 0;
   1.336 +	fsHeight			 = 0;
   1.337 +	fsColorDepth		 = 0;
   1.338 +	fsForceChange		 = false;
   1.339 +	surfaceSizeX		 = 0;
   1.340 +	surfaceSizeY		 = 0;
   1.341 +	sizeX				 = 0;
   1.342 +	sizeY				 = 0;
   1.343 +	videoOption			 = 0;
   1.344 +	fullScreenStretch	 = false;
   1.345 +	disableStatusMessage = false;
   1.346 +	showSpeed			 = 1;
   1.347 +	showSpeedTransparent = true;
   1.348 +	showRenderedFrames	 = 0;
   1.349 +	for (int j = 0; j < SCREEN_MESSAGE_SLOTS; j++)
   1.350 +	{
   1.351 +		screenMessage[j]		 = false;
   1.352 +		screenMessageTime[j]	 = 0;
   1.353 +		screenMessageDuration[j] = 0;
   1.354 +	}
   1.355 +	menuToggle		 = true;
   1.356 +	display			 = NULL;
   1.357 +	menu			 = NULL;
   1.358 +	popup			 = NULL;
   1.359 +	soundInitialized = false;
   1.360 +	useBiosFile		 = false;
   1.361 +	skipBiosFile	 = false;
   1.362 +	active			 = true;
   1.363 +	paused			 = false;
   1.364 +	recentFreeze	 = false;
   1.365 +	autoSaveLoadCheatList	  = false;
   1.366 +	pauseDuringCheatSearch	  = false;
   1.367 +	modelessCheatDialogIsOpen = false;
   1.368 +//	winout						= NULL;
   1.369 +//	removeIntros				= false;
   1.370 +	autoIPS = true;
   1.371 +	winGbBorderOn	  = 0;
   1.372 +	hideMovieBorder	  = false;
   1.373 +	winFlashSize	  = 0x10000;
   1.374 +	winRtcEnable	  = false;
   1.375 +	winSaveType		  = 0;
   1.376 +	rewindMemory	  = NULL;
   1.377 +	frameSearchMemory = NULL;
   1.378 +	rewindPos		  = 0;
   1.379 +	rewindTopPos	  = 0;
   1.380 +	rewindCounter	  = 0;
   1.381 +	rewindCount		  = 0;
   1.382 +	rewindSaveNeeded  = false;
   1.383 +	rewindTimer		  = 0;
   1.384 +	captureFormat	  = 0;
   1.385 +	tripleBuffering	  = true;
   1.386 +	autoHideMenu	  = false;
   1.387 +	throttle		  = 100;
   1.388 +	throttleLastTime  = 0;
   1.389 +///  autoFrameSkipLastTime		= 0;
   1.390 +///  autoFrameSkip				= false;
   1.391 +	vsync = false;
   1.392 +	changingVideoSize = false;
   1.393 +	pVideoDriverGUID  = NULL;
   1.394 +	renderMethod	  = DIRECT_DRAW;
   1.395 +	iconic = false;
   1.396 +	ddrawEmulationOnly		= false;
   1.397 +	ddrawUsingEmulationOnly = false;
   1.398 +	ddrawDebug				= false;
   1.399 +	ddrawUseVideoMemory		= false;
   1.400 +	d3dFilter				= 0;
   1.401 +	glFilter				= 0;
   1.402 +	glType					= 0;
   1.403 +	regEnabled				= false;
   1.404 +	pauseWhenInactive		= true;
   1.405 +	muteWhenInactive		= true;
   1.406 +	enableBackgroundInput	= false;
   1.407 +	alwaysOnTop				= false;
   1.408 +	filenamePreference		= true;
   1.409 +	frameCounter			= false;
   1.410 +	lagCounter				= false;
   1.411 +	extraCounter			= false;
   1.412 +	inputDisplay			= false;
   1.413 +	speedupToggle			= false;
   1.414 +	useOldSync				= false;
   1.415 +	allowLeftRight			= false;
   1.416 +	autofireAccountForLag	= false;
   1.417 +	nextframeAccountForLag	= false;
   1.418 +	muteFrameAdvance		= false;
   1.419 +	muteWhenInactive		= false;
   1.420 +	winMuteForNow		= false;
   1.421 +	winGbPrinterEnabled		= false;
   1.422 +	threadPriority			= 2;
   1.423 +	disableMMX				= false;
   1.424 +	languageOption			= 0;
   1.425 +	languageModule			= NULL;
   1.426 +	languageName			= "";
   1.427 +	renderedFrames			= 0;
   1.428 +	input					= NULL;
   1.429 +	joypadDefault			= 0;
   1.430 +	autoFire				= 0;
   1.431 +	autoFire2				= 0;
   1.432 +	autoHold				= 0;
   1.433 +	autoFireToggle			= false;
   1.434 +	winPauseNextFrame		= false;
   1.435 +	soundRecording			= false;
   1.436 +	soundRecorder			= NULL;
   1.437 +	sound					= NULL;
   1.438 +	aviRecording			= false;
   1.439 +	aviRecorder				= NULL;
   1.440 +	painting				= false;
   1.441 +	mouseCounter			= 0;
   1.442 +	movieReadOnly			= true;
   1.443 +	movieOnEndPause			= false;
   1.444 +	movieOnEndBehavior		= 0;
   1.445 +	wasPaused				= false;
   1.446 +	fsMaxScale				= 0;
   1.447 +	romSize					= 0;
   1.448 +	autoLoadMostRecent		= false;
   1.449 +	loadMakesRecent			= false;
   1.450 +	loadMakesCurrent		= false;
   1.451 +	saveMakesCurrent		= false;
   1.452 +	currentSlot				= 0;
   1.453 +	showSlotTime			= false;
   1.454 +	frameSearchLoadValid	= false;
   1.455 +	frameSearching			= false;
   1.456 +	frameSearchSkipping		= false;
   1.457 +	nvVideoLog				= false;
   1.458 +	nvAudioLog				= false;
   1.459 +	LoggingEnabled			= 0;
   1.460 +///  FPS = 60;
   1.461 +
   1.462 +	updateCount = 0;
   1.463 +
   1.464 +	systemSaveUpdateCounter = SYSTEM_SAVE_NOT_UPDATED;
   1.465 +
   1.466 +	ZeroMemory(&emulator, sizeof(emulator));
   1.467 +
   1.468 +	hAccel = NULL;
   1.469 +
   1.470 +	for (int i = 0; i < 24; )
   1.471 +	{
   1.472 +		systemGbPalette[i++] = (0x1f) | (0x1f << 5) | (0x1f << 10);
   1.473 +		systemGbPalette[i++] = (0x15) | (0x15 << 5) | (0x15 << 10);
   1.474 +		systemGbPalette[i++] = (0x0c) | (0x0c << 5) | (0x0c << 10);
   1.475 +		systemGbPalette[i++] = 0;
   1.476 +	}
   1.477 +
   1.478 +	VBAMovieInit();
   1.479 +
   1.480 +	TIMECAPS tc;
   1.481 +	if (timeGetDevCaps(&tc, sizeof(TIMECAPS)) == TIMERR_NOERROR)
   1.482 +	{
   1.483 +		wmTimerRes = min(max(tc.wPeriodMin, 1), tc.wPeriodMax);
   1.484 +		timeBeginPeriod(wmTimerRes);
   1.485 +	}
   1.486 +	else
   1.487 +	{
   1.488 +		wmTimerRes = 5;
   1.489 +		timeBeginPeriod(wmTimerRes);
   1.490 +	}
   1.491 +}
   1.492 +
   1.493 +VBA::~VBA()
   1.494 +{
   1.495 +	if (VBAMovieActive())
   1.496 +		VBAMovieStop(true);
   1.497 +
   1.498 +	saveSettings();
   1.499 +
   1.500 +	InterframeCleanup();
   1.501 +
   1.502 +	if (aviRecorder)
   1.503 +	{
   1.504 +		delete aviRecorder;
   1.505 +		aviRecorder	 = NULL;
   1.506 +		aviRecording = false;
   1.507 +	}
   1.508 +
   1.509 +	if (soundRecorder)
   1.510 +	{
   1.511 +		delete soundRecorder;
   1.512 +		soundRecorder = NULL;
   1.513 +	}
   1.514 +	soundRecording = false;
   1.515 +	soundPause();
   1.516 +	soundShutdown();
   1.517 +
   1.518 +	((MainWnd *)(m_pMainWnd))->winFileClose();
   1.519 +
   1.520 +	if (input)
   1.521 +		delete input;
   1.522 +
   1.523 +	shutdownDisplay();
   1.524 +
   1.525 +	if (rewindMemory)
   1.526 +		free(rewindMemory);
   1.527 +
   1.528 +	if (frameSearchMemory)
   1.529 +		free(frameSearchMemory);
   1.530 +
   1.531 +	timeEndPeriod(wmTimerRes);
   1.532 +}
   1.533 +
   1.534 +/////////////////////////////////////////////////////////////////////////////
   1.535 +// VBA initialization
   1.536 +
   1.537 +#include <afxdisp.h>
   1.538 +
   1.539 +BOOL VBA::InitInstance()
   1.540 +{
   1.541 +	AfxEnableControlContainer();
   1.542 +	// Standard initialization
   1.543 +	// If you are not using these features and wish to reduce the size
   1.544 +	//  of your final executable, you should remove from the following
   1.545 +	//  the specific initialization routines you do not need.
   1.546 +
   1.547 +//#ifdef _AFXDLL
   1.548 +//  Enable3dControls();      // Call this when using MFC in a shared DLL
   1.549 +//#else
   1.550 +//  Enable3dControlsStatic();  // Call this when linking to MFC statically
   1.551 +//#endif
   1.552 +
   1.553 +	SetRegistryKey(_T("VBA"));
   1.554 +
   1.555 +	remoteSetProtocol(0);
   1.556 +
   1.557 +	systemVerbose = GetPrivateProfileInt("config", "verbose", 0, "VBA.ini");
   1.558 +	systemDebug = GetPrivateProfileInt("config", "debug", 0, "VBA.ini");
   1.559 +	ddrawDebug = GetPrivateProfileInt("config", "ddrawDebug", 0, "VBA.ini") ? true : false;
   1.560 +
   1.561 +	wndClass = AfxRegisterWndClass(0, LoadCursor(IDC_ARROW), (HBRUSH)GetStockObject(BLACK_BRUSH), LoadIcon(IDI_ICON));
   1.562 +
   1.563 +	char winBuffer[2048];
   1.564 +	GetModuleFileName(NULL, winBuffer, 2048);
   1.565 +	char *p = strrchr(winBuffer, '\\');
   1.566 +	if (p)
   1.567 +		*p = 0;
   1.568 +	exeDir = winBuffer;
   1.569 +
   1.570 +	regInit(winBuffer);
   1.571 +
   1.572 +	loadSettings();
   1.573 +	theApp.LuaFastForward = -1;
   1.574 +	if (!initInput())
   1.575 +		return FALSE;
   1.576 +
   1.577 +	if (!initDisplay())
   1.578 +	{
   1.579 +		if (videoOption >= VIDEO_320x240)
   1.580 +		{
   1.581 +			regSetDwordValue("video", VIDEO_1X);
   1.582 +			if (pVideoDriverGUID)
   1.583 +				regSetDwordValue("defaultVideoDriver", TRUE);
   1.584 +		}
   1.585 +		return FALSE;
   1.586 +	}
   1.587 +
   1.588 +	hAccel = LoadAccelerators(AfxGetInstanceHandle(), MAKEINTRESOURCE(IDR_ACCELERATOR));
   1.589 +
   1.590 +	winAccelMgr.Connect((MainWnd *)m_pMainWnd);
   1.591 +
   1.592 +	extern void winAccelAddCommandsFromMenu(CAcceleratorManager & mgr, CMenu * pMenu, const CString &parentStr);
   1.593 +	extern void winAccelAddCommandsFromTable(CAcceleratorManager & mgr);
   1.594 +
   1.595 +	winAccelAddCommandsFromMenu(winAccelMgr, &m_menu, CString());
   1.596 +	winAccelAddCommandsFromTable(winAccelMgr);
   1.597 +
   1.598 +	winAccelMgr.CreateDefaultTable();
   1.599 +	winAccelMgr.Load();
   1.600 +	winAccelMgr.UpdateWndTable();
   1.601 +	winAccelMgr.UpdateMenu(menu);
   1.602 +
   1.603 +	if (m_lpCmdLine[0])
   1.604 +	{
   1.605 +		int		argc = parseCommandLine(m_lpCmdLine, NULL);
   1.606 +		char * *argv = (char * *)malloc((argc + 1) * sizeof(char *));
   1.607 +		parseCommandLine(m_lpCmdLine, argv);
   1.608 +
   1.609 +		bool gotFlag = false, enoughArgs = false;
   1.610 +		for (int i = 0; i < argc; i++)
   1.611 +		{
   1.612 +			if (argv[i][0] == '-' || gotFlag)
   1.613 +			{
   1.614 +				if (!gotFlag)
   1.615 +					loadSettings();
   1.616 +				gotFlag = true;
   1.617 +				if (_stricmp(argv[i], "-rom") == 0)
   1.618 +				{
   1.619 +					if (i + 1 >= argc || argv[i + 1][0] == '-')
   1.620 +						goto invalidArgument;
   1.621 +					romFilename = argv[++i];
   1.622 +					winCorrectPath(romFilename);
   1.623 +					gameFilename = romFilename;
   1.624 +				}
   1.625 +				else if (_stricmp(argv[i], "-bios") == 0)
   1.626 +				{
   1.627 +					if (i + 1 >= argc || argv[i + 1][0] == '-')
   1.628 +						goto invalidArgument;
   1.629 +					biosFileName = argv[++i];
   1.630 +					winCorrectPath(biosFileName);
   1.631 +
   1.632 +					//systemLoadBIOS();
   1.633 +				}
   1.634 +				else if (_stricmp(argv[i], "-frameskip") == 0)
   1.635 +				{
   1.636 +					if (i + 1 >= argc || argv[i + 1][0] == '-')
   1.637 +						goto invalidArgument;
   1.638 +					frameSkip = atoi(argv[++i]);
   1.639 +					if (frameSkip < 0)
   1.640 +						frameSkip = 0;
   1.641 +					if (frameSkip > 9)
   1.642 +						frameSkip = 9;
   1.643 +					gbFrameSkip = frameSkip;
   1.644 +				}
   1.645 +				else if (_stricmp(argv[i], "-throttle") == 0)
   1.646 +				{
   1.647 +					if (i + 1 >= argc || argv[i + 1][0] == '-')
   1.648 +						goto invalidArgument;
   1.649 +					throttle = atoi(argv[++i]);
   1.650 +					if (throttle < 5)
   1.651 +						throttle = 5;
   1.652 +					if (throttle > 1000)
   1.653 +						throttle = 1000;
   1.654 +				}
   1.655 +				else if (_stricmp(argv[i], "-throttleKeepPitch") == 0)
   1.656 +				{
   1.657 +					if (i + 1 >= argc || argv[i + 1][0] == '-')
   1.658 +						goto invalidArgument;
   1.659 +					accuratePitchThrottle = atoi(argv[++i]) != 0;
   1.660 +				}
   1.661 +				else if (_stricmp(argv[i], "-synchronize") == 0)
   1.662 +				{
   1.663 +					if (i + 1 >= argc || argv[i + 1][0] == '-')
   1.664 +						goto invalidArgument;
   1.665 +					synchronize = atoi(argv[++i]) != 0;
   1.666 +				}
   1.667 +				else if (_stricmp(argv[i], "-hideborder") == 0)
   1.668 +				{
   1.669 +					if (i + 1 >= argc || argv[i + 1][0] == '-')
   1.670 +						goto invalidArgument;
   1.671 +					hideMovieBorder = atoi(argv[++i]) != 0;
   1.672 +				}
   1.673 +				else if (_stricmp(argv[i], "-play") == 0)
   1.674 +				{
   1.675 +					playMovieFile = true;
   1.676 +					if (i + 1 >= argc || argv[i + 1][0] == '-')
   1.677 +						goto invalidArgument;
   1.678 +					strcpy(movieFileToPlay, argv[++i]);
   1.679 +					winCorrectPath(movieFileToPlay);
   1.680 +					if (i + 1 >= argc || argv[i + 1][0] == '-') { --i; goto invalidArgument; }
   1.681 +					playMovieFileReadOnly = atoi(argv[++i]) != 0;
   1.682 +				}
   1.683 +				else if (_stricmp(argv[i], "-videoLog") == 0)
   1.684 +				{
   1.685 +					nvVideoLog	   = true;
   1.686 +					nvAudioLog	   = true;
   1.687 +					LoggingEnabled = 2;
   1.688 +					if (i + 1 >= argc || argv[i + 1][0] == '-') {}
   1.689 +					else
   1.690 +						NESVideoSetVideoCmd(argv[++i]);
   1.691 +				}
   1.692 +				else if (_stricmp(argv[i], "-logDebug") == 0)
   1.693 +				{
   1.694 +					NESVideoEnableDebugging(debugSystemScreenMessage1, debugSystemScreenMessage2);
   1.695 +				}
   1.696 +				else if (_stricmp(argv[i], "-logToFile") == 0)
   1.697 +				{
   1.698 +					NESVideoSetFileFuncs(fopen, fclose);
   1.699 +				}
   1.700 +				else if (_stricmp(argv[i], "-outputWAV") == 0)
   1.701 +				{
   1.702 +					outputWavFile = true;
   1.703 +					if (i + 1 >= argc || argv[i + 1][0] == '-')
   1.704 +						goto invalidArgument;
   1.705 +					strcpy(wavFileToOutput, argv[++i]);
   1.706 +				}
   1.707 +				else if (_stricmp(argv[i], "-outputAVI") == 0)
   1.708 +				{
   1.709 +					outputAVIFile = true;
   1.710 +				}
   1.711 +				else if (_stricmp(argv[i], "-quitAfter") == 0)
   1.712 +				{
   1.713 +					if (i + 1 >= argc || argv[i + 1][0] == '-')
   1.714 +						goto invalidArgument;
   1.715 +					quitAfterTime = atoi(argv[++i]);
   1.716 +				}
   1.717 +				else if (_stricmp(argv[i], "-pauseAt") == 0)
   1.718 +				{
   1.719 +					if (i + 1 >= argc || argv[i + 1][0] == '-')
   1.720 +						goto invalidArgument;
   1.721 +					pauseAfterTime = atoi(argv[++i]);
   1.722 +				}
   1.723 +				else if (_stricmp(argv[i], "-videoScale") == 0)
   1.724 +				{
   1.725 +					if (i + 1 >= argc || argv[i + 1][0] == '-')
   1.726 +						goto invalidArgument;
   1.727 +					int size = atoi(argv[++i]);
   1.728 +					if (size < 1)
   1.729 +						size = 1;
   1.730 +					if (size > 4)
   1.731 +						size = 4;
   1.732 +					switch (size)
   1.733 +					{
   1.734 +					case 1:
   1.735 +						videoOption = VIDEO_1X; break;
   1.736 +					case 2:
   1.737 +						videoOption = VIDEO_2X; break;
   1.738 +					case 3:
   1.739 +						videoOption = VIDEO_3X; break;
   1.740 +					case 4:
   1.741 +						videoOption = VIDEO_4X; break;
   1.742 +					}
   1.743 +				}
   1.744 +				else if (_stricmp(argv[i], "-hideMenu") == 0)
   1.745 +				{
   1.746 +					flagHideMenu = true;
   1.747 +				}
   1.748 +				else
   1.749 +				{
   1.750 +					enoughArgs = true;
   1.751 +invalidArgument:
   1.752 +					char str [2048];    // the string is larger than 1024 bytes
   1.753 +					strcpy(str, "");
   1.754 +					if (_stricmp(argv[i], "-h") != 0)
   1.755 +						if (enoughArgs)
   1.756 +							sprintf(str, "Invalid commandline argument %d: %s\n", i, argv[i]);
   1.757 +						else
   1.758 +							sprintf(str, "Not enough arguments for arg %d: %s\n", i, argv[i]);
   1.759 +					strcat(str, "Valid commands:\n"
   1.760 +					            "-h \t\t\t displays this help\n"
   1.761 +					            "-rom filename \t\t opens the given ROM\n"
   1.762 +					            "-bios filename \t\t use the given GBA BIOS\n"
   1.763 +					            "-play filename val \t\t plays the given VBM movie (val: 1 = read-only, 0 = editable)\n"
   1.764 +					            "-outputWAV filename \t outputs WAV audio to the given file\n"
   1.765 +					            "-outputAVI \t\t outputs an AVI (you are prompted for location and codec)\n"
   1.766 +					            "-frameskip val \t\t sets the frameskip amount to the given value\n"
   1.767 +					            "-synchronize val \t\t limits running speed to sound playing speed, (0 = off, 1 = on)\n"
   1.768 +					            "-throttle val \t\t sets the throttle speed to the given percentage\n"
   1.769 +					            "-hideborder val \t\t hides SGB border, if any (0 = show, 1 = hide)\n"
   1.770 +					            "-throttleKeepPitch val \t if throttle and synch, don't change sound freq (0 = off, 1 = on)\n"
   1.771 +					            "-quitAfter val \t\t close program when frame counter == val\n"
   1.772 +					            "-pauseAt val \t\t pause (movie) once when frame counter == val\n"
   1.773 +					            "-videoScale val \t\t sets the video size (val = 1 for 1X, 2 for 2X, 3 for 3X, or 4 for 4X)\n"
   1.774 +					            "-hideMenu \t\t hides the menu until program exit\n"
   1.775 +					            "\n"
   1.776 +					            "-videoLog args \t does (nesvideos) video+audio logging with the given arguments\n"
   1.777 +					            "-logToFile \t tells logging to use fopen/fclose of args, if logging is enabled\n"
   1.778 +					            "-logDebug  \t tells logging to output debug info to screen, if logging is enabled\n"
   1.779 +					       );
   1.780 +					theApp.winCheckFullscreen();
   1.781 +					AfxGetApp()->m_pMainWnd->MessageBox(str, "Commandline Help", MB_OK | MB_ICONINFORMATION);
   1.782 +					exit(0);
   1.783 +				}
   1.784 +			}
   1.785 +			else
   1.786 +			{
   1.787 +				// assume anything else is a ROM, for backward compatibility
   1.788 +				romFilename	 = argv[i++];
   1.789 +				gameFilename = romFilename;
   1.790 +				loadSettings();
   1.791 +			}
   1.792 +		}
   1.793 +
   1.794 +/*
   1.795 +        int index = filename.ReverseFind('.');
   1.796 +
   1.797 +        if (index != -1)
   1.798 +            filename = filename.Left(index);
   1.799 + */
   1.800 +		if (romFilename.GetLength() > 0)
   1.801 +		{
   1.802 +			((MainWnd *)theApp.m_pMainWnd)->winFileRun();
   1.803 +		}
   1.804 +		free(argv);
   1.805 +	}
   1.806 +
   1.807 +	return TRUE;
   1.808 +}
   1.809 +
   1.810 +void VBA::adjustDestRect()
   1.811 +{
   1.812 +	POINT point;
   1.813 +
   1.814 +	point.x = 0;
   1.815 +	point.y = 0;
   1.816 +
   1.817 +	m_pMainWnd->ClientToScreen(&point);
   1.818 +	dest.top  = point.y;
   1.819 +	dest.left = point.x;
   1.820 +
   1.821 +	point.x = surfaceSizeX;
   1.822 +	point.y = surfaceSizeY;
   1.823 +
   1.824 +	m_pMainWnd->ClientToScreen(&point);
   1.825 +	dest.bottom = point.y;
   1.826 +	dest.right	= point.x;
   1.827 +
   1.828 +	if (videoOption > VIDEO_4X)
   1.829 +	{
   1.830 +		int menuSkip = 0;
   1.831 +		if (menuToggle)
   1.832 +		{
   1.833 +			menuSkip = winGetMenuBarHeight();
   1.834 +		}
   1.835 +
   1.836 +		if (fullScreenStretch)
   1.837 +		{
   1.838 +			dest.top	= menuSkip;
   1.839 +			dest.left	= 0;
   1.840 +			dest.right	= fsWidth;
   1.841 +			dest.bottom = fsHeight;
   1.842 +		}
   1.843 +		else
   1.844 +		{
   1.845 +			int top	 = (fsHeight - surfaceSizeY) / 2;
   1.846 +			int left = (fsWidth - surfaceSizeX) / 2;
   1.847 +			dest.top	+= top - menuSkip * 2;
   1.848 +			dest.bottom += top;
   1.849 +			dest.left	+= left;
   1.850 +			dest.right	+= left;
   1.851 +		}
   1.852 +	}
   1.853 +}
   1.854 +
   1.855 +void VBA::updateIFB()
   1.856 +{
   1.857 +	if (systemColorDepth == 16)
   1.858 +	{
   1.859 +		switch (ifbType)
   1.860 +		{
   1.861 +		case 0:
   1.862 +		default:
   1.863 +			ifbFunction = NULL;
   1.864 +			break;
   1.865 +		case 1:
   1.866 +			ifbFunction = MotionBlurIB;
   1.867 +			break;
   1.868 +		case 2:
   1.869 +			ifbFunction = SmartIB;
   1.870 +			break;
   1.871 +		}
   1.872 +	}
   1.873 +	else if (systemColorDepth == 32)
   1.874 +	{
   1.875 +		switch (ifbType)
   1.876 +		{
   1.877 +		case 0:
   1.878 +		default:
   1.879 +			ifbFunction = NULL;
   1.880 +			break;
   1.881 +		case 1:
   1.882 +			ifbFunction = MotionBlurIB32;
   1.883 +			break;
   1.884 +		case 2:
   1.885 +			ifbFunction = SmartIB32;
   1.886 +			break;
   1.887 +		}
   1.888 +	}
   1.889 +	else
   1.890 +		ifbFunction = NULL;
   1.891 +}
   1.892 +
   1.893 +void VBA::updateFilter()
   1.894 +{
   1.895 +	filterWidth	 = sizeX;
   1.896 +	filterHeight = sizeY;
   1.897 +
   1.898 +	if (systemColorDepth == 16 && (videoOption > VIDEO_1X &&
   1.899 +	                               videoOption != VIDEO_320x240))
   1.900 +	{
   1.901 +		switch (filterType)
   1.902 +		{
   1.903 +		default:
   1.904 +		case 0:
   1.905 +			filterFunction = NULL;
   1.906 +			break;
   1.907 +		case 1:
   1.908 +			filterFunction = ScanlinesTV;
   1.909 +			break;
   1.910 +		case 2:
   1.911 +			filterFunction = _2xSaI;
   1.912 +			break;
   1.913 +		case 3:
   1.914 +			filterFunction = Super2xSaI;
   1.915 +			break;
   1.916 +		case 4:
   1.917 +			filterFunction = SuperEagle;
   1.918 +			break;
   1.919 +		case 5:
   1.920 +			filterFunction = Pixelate2x16;
   1.921 +			break;
   1.922 +		case 6:
   1.923 +			filterFunction = MotionBlur;
   1.924 +			break;
   1.925 +		case 7:
   1.926 +			filterFunction = AdMame2x;
   1.927 +			break;
   1.928 +		case 8:
   1.929 +			filterFunction = Simple2x16;
   1.930 +			break;
   1.931 +		case 9:
   1.932 +			filterFunction = Bilinear;
   1.933 +			break;
   1.934 +		case 10:
   1.935 +			filterFunction = BilinearPlus;
   1.936 +			break;
   1.937 +		case 11:
   1.938 +			filterFunction = Scanlines;
   1.939 +			break;
   1.940 +		case 12:
   1.941 +			filterFunction = hq2xS;
   1.942 +			break;
   1.943 +		case 13:
   1.944 +			filterFunction = hq2x;
   1.945 +			break;
   1.946 +		case 14:
   1.947 +			filterFunction = lq2x;
   1.948 +			break;
   1.949 +		case 15:
   1.950 +			filterFunction = hq3xS;
   1.951 +			break;
   1.952 +		case 16:
   1.953 +			filterFunction = hq3x;
   1.954 +			break;
   1.955 +		case 17:
   1.956 +			filterFunction = Simple3x16;
   1.957 +			break;
   1.958 +		case 18:
   1.959 +			filterFunction = Simple4x16;
   1.960 +			break;
   1.961 +		case 19:
   1.962 +			filterFunction = Pixelate3x16;
   1.963 +			break;
   1.964 +		case 20:
   1.965 +			filterFunction = Pixelate4x16;
   1.966 +			break;
   1.967 +		}
   1.968 +		switch (filterType)
   1.969 +		{
   1.970 +		case 0: // normal -> 1x texture
   1.971 +			rect.right	= sizeX;
   1.972 +			rect.bottom = sizeY;
   1.973 +			break;
   1.974 +		default: // other -> 2x texture
   1.975 +			rect.right	= sizeX * 2;
   1.976 +			rect.bottom = sizeY * 2;
   1.977 +			memset(delta, 255, sizeof(delta));
   1.978 +			break;
   1.979 +		case 15: // hq3x -> 3x texture
   1.980 +		case 16:
   1.981 +		case 17:
   1.982 +		case 19:
   1.983 +			rect.right	= sizeX * 3;
   1.984 +			rect.bottom = sizeY * 3;
   1.985 +			memset(delta, 255, sizeof(delta));
   1.986 +			break;
   1.987 +		case 18: // Simple4x -> 4x texture
   1.988 +		case 20:
   1.989 +			rect.right	= sizeX * 4;
   1.990 +			rect.bottom = sizeY * 4;
   1.991 +			memset(delta, 255, sizeof(delta));
   1.992 +			break;
   1.993 +		}
   1.994 +	}
   1.995 +	else
   1.996 +	{
   1.997 +		if (systemColorDepth == 32 && videoOption > VIDEO_1X &&
   1.998 +		    videoOption != VIDEO_320x240)
   1.999 +		{
  1.1000 +			switch (filterType)
  1.1001 +			{
  1.1002 +			default:
  1.1003 +			case 0:
  1.1004 +				filterFunction = NULL;
  1.1005 +				break;
  1.1006 +			case 1:
  1.1007 +				filterFunction = ScanlinesTV32;
  1.1008 +				break;
  1.1009 +			case 2:
  1.1010 +				filterFunction = _2xSaI32;
  1.1011 +				break;
  1.1012 +			case 3:
  1.1013 +				filterFunction = Super2xSaI32;
  1.1014 +				break;
  1.1015 +			case 4:
  1.1016 +				filterFunction = SuperEagle32;
  1.1017 +				break;
  1.1018 +			case 5:
  1.1019 +				filterFunction = Pixelate2x32;
  1.1020 +				break;
  1.1021 +			case 6:
  1.1022 +				filterFunction = MotionBlur32;
  1.1023 +				break;
  1.1024 +			case 7:
  1.1025 +				filterFunction = AdMame2x32;
  1.1026 +				break;
  1.1027 +			case 8:
  1.1028 +				filterFunction = Simple2x32;
  1.1029 +				break;
  1.1030 +			case 9:
  1.1031 +				filterFunction = Bilinear32;
  1.1032 +				break;
  1.1033 +			case 10:
  1.1034 +				filterFunction = BilinearPlus32;
  1.1035 +				break;
  1.1036 +			case 11:
  1.1037 +				filterFunction = Scanlines32;
  1.1038 +				break;
  1.1039 +			case 12:
  1.1040 +				filterFunction = hq2xS32;
  1.1041 +				break;
  1.1042 +			case 13:
  1.1043 +				filterFunction = hq2x32;
  1.1044 +				break;
  1.1045 +			case 14:
  1.1046 +				filterFunction = lq2x32;
  1.1047 +				break;
  1.1048 +			case 15:
  1.1049 +				filterFunction = hq3xS32;
  1.1050 +				break;
  1.1051 +			case 16:
  1.1052 +				filterFunction = hq3x32;
  1.1053 +				break;
  1.1054 +			case 17:
  1.1055 +				filterFunction = Simple3x32;
  1.1056 +				break;
  1.1057 +			case 18:
  1.1058 +				filterFunction = Simple4x32;
  1.1059 +				break;
  1.1060 +			case 19:
  1.1061 +				filterFunction = Pixelate3x32;
  1.1062 +				break;
  1.1063 +			case 20:
  1.1064 +				filterFunction = Pixelate4x32;
  1.1065 +				break;
  1.1066 +			}
  1.1067 +			switch (filterType)
  1.1068 +			{
  1.1069 +			case 0: // normal -> 1x texture
  1.1070 +				rect.right	= sizeX;
  1.1071 +				rect.bottom = sizeY;
  1.1072 +				break;
  1.1073 +			default: // other -> 2x texture
  1.1074 +				rect.right	= sizeX * 2;
  1.1075 +				rect.bottom = sizeY * 2;
  1.1076 +				memset(delta, 255, sizeof(delta));
  1.1077 +				break;
  1.1078 +			case 15: // hq3x -> 3x texture
  1.1079 +			case 16:
  1.1080 +			case 17:
  1.1081 +			case 19:
  1.1082 +				rect.right	= sizeX * 3;
  1.1083 +				rect.bottom = sizeY * 3;
  1.1084 +				memset(delta, 255, sizeof(delta));
  1.1085 +				break;
  1.1086 +			case 18: // Simple4x -> 4x texture
  1.1087 +			case 20:
  1.1088 +				rect.right	= sizeX * 4;
  1.1089 +				rect.bottom = sizeY * 4;
  1.1090 +				memset(delta, 255, sizeof(delta));
  1.1091 +				break;
  1.1092 +			}
  1.1093 +		}
  1.1094 +		else
  1.1095 +			filterFunction = NULL;
  1.1096 +	}
  1.1097 +
  1.1098 +	if (display)
  1.1099 +		display->changeRenderSize(rect.right, rect.bottom);
  1.1100 +}
  1.1101 +
  1.1102 +void VBA::recreateMenuBar()
  1.1103 +{
  1.1104 +	m_menu.Detach();
  1.1105 +	m_menu.Attach(winResLoadMenu(MAKEINTRESOURCE(IDR_MENU)));
  1.1106 +
  1.1107 +	if (m_pMainWnd && menuToggle)   // assuming that whether the menu has been set is always kept tracked
  1.1108 +	{
  1.1109 +		m_pMainWnd->SetMenu(&m_menu);
  1.1110 +	}
  1.1111 +
  1.1112 +	if (menu != NULL)
  1.1113 +	{
  1.1114 +		DestroyMenu(menu);
  1.1115 +	}
  1.1116 +
  1.1117 +	menu = m_menu.GetSafeHmenu();
  1.1118 +}
  1.1119 +
  1.1120 +void VBA::updateMenuBar()
  1.1121 +{
  1.1122 +	if (flagHideMenu)
  1.1123 +		return;
  1.1124 +
  1.1125 +	recreateMenuBar();
  1.1126 +
  1.1127 +	if (popup != NULL)
  1.1128 +	{
  1.1129 +		// force popup recreation if language changed
  1.1130 +		DestroyMenu(popup);
  1.1131 +		popup = NULL;
  1.1132 +	}
  1.1133 +}
  1.1134 +
  1.1135 +void VBA::saveRewindStateIfNecessary()
  1.1136 +{
  1.1137 +	if (rewindSaveNeeded && rewindMemory && emulator.emuWriteMemState)
  1.1138 +	{
  1.1139 +		rewindCount++;
  1.1140 +		if (rewindCount > rewindSlots)
  1.1141 +			rewindCount = rewindSlots;
  1.1142 +		assert(rewindPos >= 0 && rewindPos < rewindSlots);
  1.1143 +		if (emulator.emuWriteMemState(&rewindMemory[rewindPos * REWIND_SIZE], REWIND_SIZE))
  1.1144 +		{
  1.1145 +			rewindPos = ++rewindPos % rewindSlots;
  1.1146 +			assert(rewindPos >= 0 && rewindPos < rewindSlots);
  1.1147 +			if (rewindCount == rewindSlots)
  1.1148 +				rewindTopPos = ++rewindTopPos % rewindSlots;
  1.1149 +		}
  1.1150 +	}
  1.1151 +
  1.1152 +	// also update/cache some frame search stuff
  1.1153 +	if (frameSearching)
  1.1154 +	{
  1.1155 +		extern SMovie Movie;
  1.1156 +		int curFrame = (Movie.state == MOVIE_STATE_NONE) ? systemCounters.frameCount : Movie.currentFrame;
  1.1157 +		int endFrame = theApp.frameSearchStart + theApp.frameSearchLength;
  1.1158 +		frameSearchSkipping	 = (curFrame < endFrame);
  1.1159 +		frameSearchFirstStep = false;
  1.1160 +
  1.1161 +		if (curFrame == endFrame)
  1.1162 +		{
  1.1163 +			// cache intermediate state to speed up searching forward
  1.1164 +			emulator.emuWriteMemState(&frameSearchMemory[REWIND_SIZE * 1], REWIND_SIZE);
  1.1165 +		}
  1.1166 +
  1.1167 +		if (curFrame == endFrame + 1)
  1.1168 +		{
  1.1169 +			emulator.emuWriteMemState(&frameSearchMemory[REWIND_SIZE * 2], REWIND_SIZE);
  1.1170 +			frameSearchLoadValid = true;
  1.1171 +		}
  1.1172 +	}
  1.1173 +	else
  1.1174 +	{
  1.1175 +		frameSearchFirstStep = false;
  1.1176 +
  1.1177 +		assert(!frameSearchSkipping);
  1.1178 +		// just in case
  1.1179 +		frameSearchSkipping = false;
  1.1180 +	}
  1.1181 +}
  1.1182 +
  1.1183 +BOOL VBA::OnIdle(LONG lCount)
  1.1184 +{
  1.1185 +	if (emulating && debugger)
  1.1186 +	{
  1.1187 +		MSG msg;
  1.1188 +		remoteStubMain();
  1.1189 +		if (debugger)
  1.1190 +			return TRUE;  // continue loop
  1.1191 +		return !::PeekMessage(&msg, NULL, NULL, NULL, PM_NOREMOVE);
  1.1192 +	}
  1.1193 +	else if (emulating && active && !paused)
  1.1194 +	{
  1.1195 +///    for(int i = 0; i < 2; i++)
  1.1196 +		{
  1.1197 +			emulator.emuMain(emulator.emuCount);
  1.1198 +
  1.1199 +			// save the state for rewinding, if necessary
  1.1200 +			saveRewindStateIfNecessary();
  1.1201 +
  1.1202 +			rewindSaveNeeded = false;
  1.1203 +		}
  1.1204 +
  1.1205 +		if (mouseCounter)
  1.1206 +		{
  1.1207 +			if (--mouseCounter == 0)
  1.1208 +			{
  1.1209 +				SetCursor(NULL);
  1.1210 +			}
  1.1211 +		}
  1.1212 +		return TRUE;
  1.1213 +	}
  1.1214 +	else if (emulating) // this fixes display if resetting while paused
  1.1215 +	{
  1.1216 +//		VBAUpdateButtonPressDisplay();
  1.1217 +		VBAUpdateFrameCountDisplay();
  1.1218 +		systemRefreshScreen();
  1.1219 +	}
  1.1220 +
  1.1221 +	return FALSE;
  1.1222 +
  1.1223 +	//  return CWinApp::OnIdle(lCount);
  1.1224 +}
  1.1225 +
  1.1226 +void VBA::addRecentFile(const CString &file)
  1.1227 +{
  1.1228 +	// Do not change recent list if frozen
  1.1229 +	if (recentFreeze)
  1.1230 +		return;
  1.1231 +	int i = 0;
  1.1232 +	for (i = 0; i < 10; ++i)
  1.1233 +	{
  1.1234 +		if (recentFiles[i].GetLength() == 0)
  1.1235 +			break;
  1.1236 +
  1.1237 +		if (recentFiles[i].Compare(file) == 0)
  1.1238 +		{
  1.1239 +			if (i == 0)
  1.1240 +				return;
  1.1241 +			CString p = recentFiles[i];
  1.1242 +			for (int j = i; j > 0; --j)
  1.1243 +			{
  1.1244 +				recentFiles[j] = recentFiles[j - 1];
  1.1245 +			}
  1.1246 +			recentFiles[0] = p;
  1.1247 +			return;
  1.1248 +		}
  1.1249 +	}
  1.1250 +	int num = 0;
  1.1251 +	for (i = 0; i < 10; ++i)
  1.1252 +	{
  1.1253 +		if (recentFiles[i].GetLength() != 0)
  1.1254 +			++num;
  1.1255 +	}
  1.1256 +	if (num == 10)
  1.1257 +	{
  1.1258 +		--num;
  1.1259 +	}
  1.1260 +
  1.1261 +	for (i = num; i >= 1; --i)
  1.1262 +	{
  1.1263 +		recentFiles[i] = recentFiles[i - 1];
  1.1264 +	}
  1.1265 +	recentFiles[0] = file;
  1.1266 +}
  1.1267 +
  1.1268 +void VBA::updateFrameSkip()
  1.1269 +{
  1.1270 +	switch (systemCartridgeType)
  1.1271 +	{
  1.1272 +	case 0:
  1.1273 +		systemFrameSkip = frameSkip;
  1.1274 +		break;
  1.1275 +	case 1:
  1.1276 +		systemFrameSkip = gbFrameSkip;
  1.1277 +		break;
  1.1278 +	}
  1.1279 +}
  1.1280 +
  1.1281 +void VBA::updateVideoSize(UINT id)
  1.1282 +{
  1.1283 +	int	 value		 = 0;
  1.1284 +	bool forceUpdate = false;
  1.1285 +
  1.1286 +	switch (id)
  1.1287 +	{
  1.1288 +	case ID_OPTIONS_VIDEO_X1:
  1.1289 +		value		= VIDEO_1X;
  1.1290 +		forceUpdate = true;
  1.1291 +		break;
  1.1292 +	case ID_OPTIONS_VIDEO_X2:
  1.1293 +		value		= VIDEO_2X;
  1.1294 +		forceUpdate = true;
  1.1295 +		break;
  1.1296 +	case ID_OPTIONS_VIDEO_X3:
  1.1297 +		value		= VIDEO_3X;
  1.1298 +		forceUpdate = true;
  1.1299 +		break;
  1.1300 +	case ID_OPTIONS_VIDEO_X4:
  1.1301 +		value		= VIDEO_4X;
  1.1302 +		forceUpdate = true;
  1.1303 +		break;
  1.1304 +	case ID_OPTIONS_VIDEO_FULLSCREEN320X240:
  1.1305 +		value		 = VIDEO_320x240;
  1.1306 +		fsWidth		 = 320;
  1.1307 +		fsHeight	 = 240;
  1.1308 +		fsColorDepth = 16;
  1.1309 +		break;
  1.1310 +	case ID_OPTIONS_VIDEO_FULLSCREEN640X480:
  1.1311 +		value		 = VIDEO_640x480;
  1.1312 +		fsWidth		 = 640;
  1.1313 +		fsHeight	 = 480;
  1.1314 +		fsColorDepth = 16;
  1.1315 +		break;
  1.1316 +	case ID_OPTIONS_VIDEO_FULLSCREEN800X600:
  1.1317 +		value		 = VIDEO_800x600;
  1.1318 +		fsWidth		 = 800;
  1.1319 +		fsHeight	 = 600;
  1.1320 +		fsColorDepth = 16;
  1.1321 +		break;
  1.1322 +	case ID_OPTIONS_VIDEO_FULLSCREEN:
  1.1323 +		value		= VIDEO_OTHER;
  1.1324 +		forceUpdate = true;
  1.1325 +		break;
  1.1326 +	}
  1.1327 +
  1.1328 +	if (videoOption != value || forceUpdate)
  1.1329 +		updateWindowSize(value);
  1.1330 +}
  1.1331 +
  1.1332 +void VBA::updateWindowSize(int value)
  1.1333 +{
  1.1334 +	regSetDwordValue("video", value);
  1.1335 +
  1.1336 +	if (value == VIDEO_OTHER)
  1.1337 +	{
  1.1338 +		regSetDwordValue("fsWidth", fsWidth);
  1.1339 +		regSetDwordValue("fsHeight", fsHeight);
  1.1340 +		regSetDwordValue("fsColorDepth", fsColorDepth);
  1.1341 +	}
  1.1342 +
  1.1343 +	if (display &&
  1.1344 +	    (((value >= VIDEO_320x240 || videoOption >= VIDEO_320x240) && videoOption != value) ||
  1.1345 +	     fsForceChange))
  1.1346 +	{
  1.1347 +		fsForceChange = false;
  1.1348 +		videoOption	  = value;
  1.1349 +		initDisplay();
  1.1350 +	}
  1.1351 +
  1.1352 +	videoOption = value;
  1.1353 +
  1.1354 +	if (systemCartridgeType == 1)
  1.1355 +	{
  1.1356 +		if (gbBorderOn)
  1.1357 +		{
  1.1358 +			sizeX = 256;
  1.1359 +			sizeY = 224;
  1.1360 +			gbBorderLineSkip   = 256;
  1.1361 +			gbBorderColumnSkip = 48;
  1.1362 +			gbBorderRowSkip	   = 40;
  1.1363 +		}
  1.1364 +		else
  1.1365 +		{
  1.1366 +			sizeX = 160;
  1.1367 +			sizeY = 144;
  1.1368 +			gbBorderLineSkip   = 160;
  1.1369 +			gbBorderColumnSkip = 0;
  1.1370 +			gbBorderRowSkip	   = 0;
  1.1371 +		}
  1.1372 +	}
  1.1373 +	else
  1.1374 +	{
  1.1375 +		sizeX = 240;
  1.1376 +		sizeY = 160;
  1.1377 +	}
  1.1378 +
  1.1379 +	switch (videoOption)
  1.1380 +	{
  1.1381 +	case VIDEO_1X:
  1.1382 +		surfaceSizeX = sizeX;
  1.1383 +		surfaceSizeY = sizeY;
  1.1384 +		break;
  1.1385 +	case VIDEO_2X:
  1.1386 +		surfaceSizeX = sizeX * 2;
  1.1387 +		surfaceSizeY = sizeY * 2;
  1.1388 +		break;
  1.1389 +	case VIDEO_3X:
  1.1390 +		surfaceSizeX = sizeX * 3;
  1.1391 +		surfaceSizeY = sizeY * 3;
  1.1392 +		break;
  1.1393 +	case VIDEO_4X:
  1.1394 +		surfaceSizeX = sizeX * 4;
  1.1395 +		surfaceSizeY = sizeY * 4;
  1.1396 +		break;
  1.1397 +	case VIDEO_320x240:
  1.1398 +	case VIDEO_640x480:
  1.1399 +	case VIDEO_800x600:
  1.1400 +	case VIDEO_OTHER:
  1.1401 +		// Need to fix this code later. For now, Fullscreen takes the whole screen.
  1.1402 +		if (fullScreenStretch)
  1.1403 +		{
  1.1404 +			surfaceSizeX = fsWidth;
  1.1405 +			surfaceSizeY = fsHeight;
  1.1406 +		}
  1.1407 +		else
  1.1408 +		{
  1.1409 +			double scaleX	= (double)fsWidth / (double)sizeX;
  1.1410 +			double scaleY	= (double)fsHeight / (double)sizeY;
  1.1411 +			double scaleMin = scaleX < scaleY ? scaleX : scaleY;
  1.1412 +			if (fsMaxScale)
  1.1413 +				scaleMin = scaleMin > fsMaxScale ? fsMaxScale : scaleMin;
  1.1414 +			surfaceSizeX = (int)(scaleMin * sizeX);
  1.1415 +			surfaceSizeY = (int)(scaleMin * sizeY);
  1.1416 +		}
  1.1417 +		break;
  1.1418 +	}
  1.1419 +
  1.1420 +	rect.left	= 0;
  1.1421 +	rect.top	= 0;
  1.1422 +	rect.right	= sizeX;
  1.1423 +	rect.bottom = sizeY;
  1.1424 +
  1.1425 +	int winSizeX = 0;
  1.1426 +	int winSizeY = 0;
  1.1427 +	int x		 = 0;
  1.1428 +	int y		 = 0;
  1.1429 +
  1.1430 +	DWORD style	  = WS_POPUP | WS_VISIBLE;
  1.1431 +	DWORD styleEx = alwaysOnTop ? WS_EX_TOPMOST : 0;
  1.1432 +
  1.1433 +	if (videoOption <= VIDEO_4X)
  1.1434 +	{
  1.1435 +		style |= WS_OVERLAPPEDWINDOW;
  1.1436 +
  1.1437 +		dest.left	= 0;
  1.1438 +		dest.top	= 0;
  1.1439 +		dest.right	= surfaceSizeX;
  1.1440 +		dest.bottom = surfaceSizeY;
  1.1441 +
  1.1442 +		x = windowPositionX;
  1.1443 +		y = windowPositionY;
  1.1444 +	}
  1.1445 +	else
  1.1446 +	{
  1.1447 +		dest.left	= 0;
  1.1448 +		dest.top	= 0;
  1.1449 +		dest.right	= fsWidth;
  1.1450 +		dest.bottom = fsHeight;
  1.1451 +	}
  1.1452 +
  1.1453 +	AdjustWindowRectEx(&dest, style, flagHideMenu ? FALSE : TRUE, styleEx);
  1.1454 +	winSizeX = dest.right  - dest.left;
  1.1455 +	winSizeY = dest.bottom - dest.top;
  1.1456 +
  1.1457 +	if (m_pMainWnd == NULL)
  1.1458 +	{
  1.1459 +		// Create a new window
  1.1460 +		m_pMainWnd = new MainWnd;
  1.1461 +		m_pMainWnd->CreateEx(styleEx,
  1.1462 +		                     theApp.wndClass,
  1.1463 +		                     VBA_NAME_AND_VERSION,
  1.1464 +		                     style,
  1.1465 +		                     x, y, winSizeX, winSizeY,
  1.1466 +		                     NULL,
  1.1467 +		                     0);
  1.1468 +
  1.1469 +		if (!(HWND)*m_pMainWnd)
  1.1470 +		{
  1.1471 +			winlog("Error creating Window %08x\n", GetLastError());
  1.1472 +			AfxPostQuitMessage(0);
  1.1473 +			return;
  1.1474 +		}
  1.1475 +	}
  1.1476 +	else
  1.1477 +	{
  1.1478 +		m_pMainWnd->SetWindowPos(0, //HWND_TOPMOST,
  1.1479 +		                         x,
  1.1480 +		                         y,
  1.1481 +		                         winSizeX,
  1.1482 +		                         winSizeY,
  1.1483 +		                         SWP_NOMOVE | SWP_SHOWWINDOW);
  1.1484 +	}
  1.1485 +
  1.1486 +	updateMenuBar(); // add menubar first of all, or winGetMenuBarHeight() will get random height.
  1.1487 +	winAccelMgr.UpdateMenu(menu);
  1.1488 +	adjustDestRect();
  1.1489 +
  1.1490 +	updateIFB();
  1.1491 +	updateFilter();
  1.1492 +
  1.1493 +	m_pMainWnd->RedrawWindow(NULL, NULL, RDW_INVALIDATE | RDW_ERASE | RDW_ALLCHILDREN);
  1.1494 +}
  1.1495 +
  1.1496 +bool VBA::initDisplay()
  1.1497 +{
  1.1498 +	if (display)
  1.1499 +	{
  1.1500 +		changingVideoSize = true;
  1.1501 +		shutdownDisplay();
  1.1502 +		if (input)
  1.1503 +		{
  1.1504 +			delete input;
  1.1505 +			input = NULL;
  1.1506 +		}
  1.1507 +		CWnd *pWnd = m_pMainWnd;
  1.1508 +
  1.1509 +		m_pMainWnd = NULL;
  1.1510 +		pWnd->DragAcceptFiles(FALSE);
  1.1511 +		pWnd->DestroyWindow();
  1.1512 +		delete pWnd;
  1.1513 +
  1.1514 +		display = NULL;
  1.1515 +	}
  1.1516 +
  1.1517 +	if (display == NULL)
  1.1518 +	{
  1.1519 +		updateWindowSize(videoOption);
  1.1520 +
  1.1521 +		switch (renderMethod)
  1.1522 +		{
  1.1523 +		case GDI:
  1.1524 +			display = newGDIDisplay();
  1.1525 +			break;
  1.1526 +		case DIRECT_DRAW:
  1.1527 +			display = newDirectDrawDisplay();
  1.1528 +			break;
  1.1529 +		case DIRECT_3D:
  1.1530 +			display = newDirect3DDisplay();
  1.1531 +			break;
  1.1532 +		case OPENGL:
  1.1533 +			display = newOpenGLDisplay();
  1.1534 +			break;
  1.1535 +		}
  1.1536 +
  1.1537 +		if (display->initialize())
  1.1538 +		{
  1.1539 +			if (input == NULL)
  1.1540 +			{
  1.1541 +				if (!initInput())
  1.1542 +				{
  1.1543 +					changingVideoSize = false;
  1.1544 +					AfxPostQuitMessage(0);
  1.1545 +					return false;
  1.1546 +				}
  1.1547 +			}
  1.1548 +
  1.1549 +			input->checkKeys();
  1.1550 +
  1.1551 +			changingVideoSize = false;
  1.1552 +		}
  1.1553 +		else
  1.1554 +		{
  1.1555 +			if (videoOption == VIDEO_320x240 ||
  1.1556 +			    videoOption == VIDEO_640x480 ||
  1.1557 +			    videoOption == VIDEO_800x600 ||
  1.1558 +			    videoOption == VIDEO_OTHER)
  1.1559 +			{
  1.1560 +				regSetDwordValue("video", VIDEO_1X);
  1.1561 +				if (pVideoDriverGUID)
  1.1562 +					regSetDwordValue("defaultVideoDriver", TRUE);
  1.1563 +			}
  1.1564 +			changingVideoSize = false;
  1.1565 +			return false;
  1.1566 +		}
  1.1567 +	}
  1.1568 +	changingVideoSize = false;
  1.1569 +	return true;
  1.1570 +}
  1.1571 +
  1.1572 +bool VBA::updateRenderMethod(bool force)
  1.1573 +{
  1.1574 +	bool res = true;
  1.1575 +	if (force || (display && display->getType() != renderMethod))
  1.1576 +	{
  1.1577 +		res = initDisplay();
  1.1578 +
  1.1579 +		while (!res && renderMethod > 0)
  1.1580 +		{
  1.1581 +			if (renderMethod == OPENGL)
  1.1582 +				renderMethod = DIRECT_3D;
  1.1583 +			else if (renderMethod == DIRECT_3D)
  1.1584 +				renderMethod = DIRECT_DRAW;
  1.1585 +			else if (renderMethod == DIRECT_DRAW)
  1.1586 +				renderMethod = GDI;
  1.1587 +
  1.1588 +			res = initDisplay();
  1.1589 +		}
  1.1590 +	}
  1.1591 +
  1.1592 +	updateIFB();
  1.1593 +	updateFilter();
  1.1594 +
  1.1595 +	m_pMainWnd->RedrawWindow(NULL, NULL, RDW_INVALIDATE | RDW_ERASE | RDW_ALLCHILDREN);
  1.1596 +
  1.1597 +	regSetDwordValue("renderMethod", renderMethod);
  1.1598 +
  1.1599 +	return res;
  1.1600 +}
  1.1601 +
  1.1602 +void VBA::winCheckFullscreen()
  1.1603 +{
  1.1604 +	if (videoOption > VIDEO_4X && tripleBuffering)
  1.1605 +	{
  1.1606 +		if (display)
  1.1607 +			display->checkFullScreen();
  1.1608 +	}
  1.1609 +}
  1.1610 +
  1.1611 +void VBA::shutdownDisplay()
  1.1612 +{
  1.1613 +	if (display != NULL)
  1.1614 +	{
  1.1615 +		display->cleanup();
  1.1616 +		delete display;
  1.1617 +		display = NULL;
  1.1618 +	}
  1.1619 +}
  1.1620 +
  1.1621 +void VBA::updatePriority()
  1.1622 +{
  1.1623 +	switch (threadPriority)
  1.1624 +	{
  1.1625 +	case 0:
  1.1626 +		SetThreadPriority(THREAD_PRIORITY_HIGHEST);
  1.1627 +		break;
  1.1628 +	case 1:
  1.1629 +		SetThreadPriority(THREAD_PRIORITY_ABOVE_NORMAL);
  1.1630 +		break;
  1.1631 +	case 3:
  1.1632 +		SetThreadPriority(THREAD_PRIORITY_BELOW_NORMAL);
  1.1633 +		break;
  1.1634 +	default:
  1.1635 +		SetThreadPriority(THREAD_PRIORITY_NORMAL);
  1.1636 +	}
  1.1637 +}
  1.1638 +
  1.1639 +#ifdef MMX
  1.1640 +bool VBA::detectMMX()
  1.1641 +{
  1.1642 +	bool support = false;
  1.1643 +	char brand[13];
  1.1644 +
  1.1645 +	// check for Intel chip
  1.1646 +	__try {
  1.1647 +		__asm {
  1.1648 +			mov eax, 0;
  1.1649 +			cpuid;
  1.1650 +			mov [dword ptr brand + 0], ebx;
  1.1651 +			mov [dword ptr brand + 4], edx;
  1.1652 +			mov [dword ptr brand + 8], ecx;
  1.1653 +		}
  1.1654 +	}
  1.1655 +	__except(EXCEPTION_EXECUTE_HANDLER) {
  1.1656 +		if (_exception_code() == STATUS_ILLEGAL_INSTRUCTION)
  1.1657 +		{
  1.1658 +			return false;
  1.1659 +		}
  1.1660 +		return false;
  1.1661 +	}
  1.1662 +	// Check for Intel or AMD CPUs
  1.1663 +	if (strncmp(brand, "GenuineIntel", 12))
  1.1664 +	{
  1.1665 +		if (strncmp(brand, "AuthenticAMD", 12))
  1.1666 +		{
  1.1667 +			return false;
  1.1668 +		}
  1.1669 +	}
  1.1670 +
  1.1671 +	__asm {
  1.1672 +		mov eax, 1;
  1.1673 +		cpuid;
  1.1674 +		test edx, 00800000h;
  1.1675 +		jz	 NotFound;
  1.1676 +		mov [support], 1;
  1.1677 +NotFound:
  1.1678 +	}
  1.1679 +	return support;
  1.1680 +}
  1.1681 +
  1.1682 +#endif
  1.1683 +
  1.1684 +void VBA::winSetLanguageOption(int option, bool force)
  1.1685 +{
  1.1686 +	if (((option == languageOption) && option != 2) && !force)
  1.1687 +		return;
  1.1688 +	switch (option)
  1.1689 +	{
  1.1690 +	case 0:
  1.1691 +	{
  1.1692 +		char lbuffer[10];
  1.1693 +
  1.1694 +		if (GetLocaleInfo(LOCALE_SYSTEM_DEFAULT, LOCALE_SABBREVLANGNAME,
  1.1695 +		                  lbuffer, 10))
  1.1696 +		{
  1.1697 +			HINSTANCE l = winLoadLanguage(lbuffer);
  1.1698 +			if (l == NULL)
  1.1699 +			{
  1.1700 +				LCID locIdBase = MAKELCID(MAKELANGID(PRIMARYLANGID(GetSystemDefaultLangID()), SUBLANG_NEUTRAL), SORT_DEFAULT);
  1.1701 +				if (GetLocaleInfo(locIdBase, LOCALE_SABBREVLANGNAME,
  1.1702 +				                  lbuffer, 10))
  1.1703 +				{
  1.1704 +					l = winLoadLanguage(lbuffer);
  1.1705 +					if (l == NULL)
  1.1706 +					{
  1.1707 +						systemMessage(IDS_FAILED_TO_LOAD_LIBRARY,
  1.1708 +						              "Failed to load library %s",
  1.1709 +						              lbuffer);
  1.1710 +						return;
  1.1711 +					}
  1.1712 +				}
  1.1713 +			}
  1.1714 +			AfxSetResourceHandle(l);
  1.1715 +			if (languageModule != NULL)
  1.1716 +				/**/ ::FreeLibrary(languageModule);
  1.1717 +			languageModule = l;
  1.1718 +		}
  1.1719 +		else
  1.1720 +		{
  1.1721 +			systemMessage(IDS_FAILED_TO_GET_LOCINFO,
  1.1722 +			              "Failed to get locale information");
  1.1723 +			return;
  1.1724 +		}
  1.1725 +		break;
  1.1726 +	}
  1.1727 +	case 1:
  1.1728 +		if (languageModule != NULL)
  1.1729 +			/**/ ::FreeLibrary(languageModule);
  1.1730 +		languageModule = NULL;
  1.1731 +		AfxSetResourceHandle(AfxGetInstanceHandle());
  1.1732 +		break;
  1.1733 +	case 2:
  1.1734 +	{
  1.1735 +		if (!force)
  1.1736 +		{
  1.1737 +			LangSelect dlg;
  1.1738 +			if (dlg.DoModal())
  1.1739 +			{
  1.1740 +				HINSTANCE l = winLoadLanguage(languageName);
  1.1741 +				if (l == NULL)
  1.1742 +				{
  1.1743 +					systemMessage(IDS_FAILED_TO_LOAD_LIBRARY,
  1.1744 +					              "Failed to load library %s",
  1.1745 +					              languageName);
  1.1746 +					return;
  1.1747 +				}
  1.1748 +				AfxSetResourceHandle(l);
  1.1749 +				if (languageModule != NULL)
  1.1750 +					/**/ ::FreeLibrary(languageModule);
  1.1751 +				languageModule = l;
  1.1752 +			}
  1.1753 +		}
  1.1754 +		else
  1.1755 +		{
  1.1756 +			if (languageName.IsEmpty())
  1.1757 +				return;
  1.1758 +			HINSTANCE l = winLoadLanguage(languageName);
  1.1759 +			if (l == NULL)
  1.1760 +			{
  1.1761 +				systemMessage(IDS_FAILED_TO_LOAD_LIBRARY,
  1.1762 +				              "Failed to load library %s",
  1.1763 +				              languageName);
  1.1764 +				return;
  1.1765 +			}
  1.1766 +			AfxSetResourceHandle(l);
  1.1767 +			if (languageModule != NULL)
  1.1768 +				FreeLibrary(languageModule);
  1.1769 +			languageModule = l;
  1.1770 +		}
  1.1771 +		break;
  1.1772 +	}
  1.1773 +	}
  1.1774 +	languageOption = option;
  1.1775 +	updateMenuBar();
  1.1776 +	theApp.winAccelMgr.UpdateMenu(theApp.menu);
  1.1777 +}
  1.1778 +
  1.1779 +HINSTANCE VBA::winLoadLanguage(const char *name)
  1.1780 +{
  1.1781 +	CString buffer;
  1.1782 +
  1.1783 +	buffer.Format("vba_%s.dll", name);
  1.1784 +
  1.1785 +	HINSTANCE l = /**/ ::LoadLibrary(buffer);
  1.1786 +
  1.1787 +	if (l == NULL)
  1.1788 +	{
  1.1789 +		if (strlen(name) == 3)
  1.1790 +		{
  1.1791 +			char buffer2[3];
  1.1792 +			buffer2[0] = name[0];
  1.1793 +			buffer2[1] = name[1];
  1.1794 +			buffer2[2] = 0;
  1.1795 +			buffer.Format("vba_%s.dll", buffer2);
  1.1796 +
  1.1797 +			return /**/ ::LoadLibrary(buffer);
  1.1798 +		}
  1.1799 +	}
  1.1800 +	return l;
  1.1801 +}
  1.1802 +
  1.1803 +bool VBA::initInput()
  1.1804 +{
  1.1805 +	if (input)
  1.1806 +		delete input;
  1.1807 +	input = newDirectInput();
  1.1808 +	if (input->initialize())
  1.1809 +	{
  1.1810 +		input->loadSettings();
  1.1811 +		input->checkKeys();
  1.1812 +		return true;
  1.1813 +	}
  1.1814 +	delete input;
  1.1815 +	return false;
  1.1816 +}
  1.1817 +
  1.1818 +void VBA::winAddUpdateListener(IUpdateListener *l)
  1.1819 +{
  1.1820 +	updateList.AddTail(l);
  1.1821 +	updateCount++;
  1.1822 +}
  1.1823 +
  1.1824 +void VBA::winRemoveUpdateListener(IUpdateListener *l)
  1.1825 +{
  1.1826 +	POSITION pos = updateList.Find(l);
  1.1827 +	if (pos)
  1.1828 +	{
  1.1829 +		updateList.RemoveAt(pos);
  1.1830 +		updateCount--;
  1.1831 +		if (updateCount < 0)
  1.1832 +			updateCount = 0;
  1.1833 +	}
  1.1834 +}
  1.1835 +
  1.1836 +void VBA::loadSettings()
  1.1837 +{
  1.1838 +	CString	buffer;
  1.1839 +	// video
  1.1840 +	bool defaultVideoDriver = regQueryDwordValue("defaultVideoDriver", true) ? true : false;
  1.1841 +	if (!regQueryBinaryValue("videoDriverGUID", (char *)&videoDriverGUID, sizeof(GUID)))
  1.1842 +	{
  1.1843 +		defaultVideoDriver = TRUE;
  1.1844 +	}
  1.1845 +	if (defaultVideoDriver)
  1.1846 +		pVideoDriverGUID = NULL;
  1.1847 +	else
  1.1848 +		pVideoDriverGUID = &videoDriverGUID;
  1.1849 +
  1.1850 +	videoOption = regQueryDwordValue("video", 0);
  1.1851 +	if (videoOption < 0 || videoOption > VIDEO_OTHER)
  1.1852 +		videoOption = 0;
  1.1853 +	switch (videoOption)
  1.1854 +	{
  1.1855 +	case VIDEO_320x240:
  1.1856 +		fsWidth		 = 320;
  1.1857 +		fsHeight	 = 240;
  1.1858 +		fsColorDepth = 16;
  1.1859 +		break;
  1.1860 +	case VIDEO_640x480:
  1.1861 +		fsWidth		 = 640;
  1.1862 +		fsHeight	 = 480;
  1.1863 +		fsColorDepth = 16;
  1.1864 +		break;
  1.1865 +	case VIDEO_800x600:
  1.1866 +		fsWidth		 = 800;
  1.1867 +		fsHeight	 = 600;
  1.1868 +		fsColorDepth = 16;
  1.1869 +		break;
  1.1870 +	}
  1.1871 +	if (videoOption == VIDEO_OTHER)
  1.1872 +	{
  1.1873 +		if (fsWidth < 0 || fsWidth > 4095 || fsHeight < 0 || fsHeight > 4095)
  1.1874 +			videoOption = 0;
  1.1875 +		if (fsColorDepth != 16 && fsColorDepth != 24 && fsColorDepth != 32)
  1.1876 +			videoOption = 0;
  1.1877 +	}
  1.1878 +
  1.1879 +	fsWidth = regQueryDwordValue("fsWidth", 0);
  1.1880 +	fsHeight = regQueryDwordValue("fsHeight", 0);
  1.1881 +	fsColorDepth	  = regQueryDwordValue("fsColorDepth", 0);
  1.1882 +	fsMaxScale		  = regQueryDwordValue("fsMaxScale", 0);
  1.1883 +	fullScreenStretch = regQueryDwordValue("stretch", 0) ? true : false;
  1.1884 +
  1.1885 +	renderMethod = (DISPLAY_TYPE)regQueryDwordValue("renderMethod", DIRECT_DRAW);
  1.1886 +	if (renderMethod < GDI || renderMethod > OPENGL)
  1.1887 +		renderMethod = DIRECT_DRAW;
  1.1888 +
  1.1889 +	ddrawEmulationOnly	= regQueryDwordValue("ddrawEmulationOnly", false) ? true : false;
  1.1890 +	ddrawUseVideoMemory = regQueryDwordValue("ddrawUseVideoMemory", false) ? true : false;
  1.1891 +	tripleBuffering		= regQueryDwordValue("tripleBuffering", true) ? true : false;
  1.1892 +	vsync = regQueryDwordValue("vsync", false) ? true : false;
  1.1893 +
  1.1894 +	d3dFilter = regQueryDwordValue("d3dFilter", 0);
  1.1895 +	if (d3dFilter < 0 || d3dFilter > 1)
  1.1896 +		d3dFilter = 0;
  1.1897 +	glFilter = regQueryDwordValue("glFilter", 0);
  1.1898 +	if (glFilter < 0 || glFilter > 1)
  1.1899 +		glFilter = 0;
  1.1900 +	glType = regQueryDwordValue("glType", 0);
  1.1901 +	if (glType < 0 || glType > 1)
  1.1902 +		glType = 0;
  1.1903 +
  1.1904 +	// pixel filter & ifb
  1.1905 +	filterType = regQueryDwordValue("filter", 0);
  1.1906 +	if (filterType < 0 || filterType > 20)
  1.1907 +		filterType = 0;
  1.1908 +	disableMMX = regQueryDwordValue("disableMMX", 0) ? true : false;
  1.1909 +	ifbType	   = regQueryDwordValue("ifbType", 0);
  1.1910 +	if (ifbType < 0 || ifbType > 2)
  1.1911 +		ifbType = 0;
  1.1912 +
  1.1913 +	// frame skipping
  1.1914 +	frameSkip = regQueryDwordValue("frameSkip", /*2*/ 0);
  1.1915 +	if (frameSkip < 0 || frameSkip > 9)
  1.1916 +		frameSkip = 1;
  1.1917 +	gbFrameSkip = regQueryDwordValue("gbFrameSkip", 0);
  1.1918 +	if (gbFrameSkip < 0 || gbFrameSkip > 9)
  1.1919 +		gbFrameSkip = 0;
  1.1920 +///  autoFrameSkip = regQueryDwordValue("autoFrameSkip", FALSE) ? TRUE : FALSE;
  1.1921 +
  1.1922 +	// input
  1.1923 +	joypadDefault = regQueryDwordValue("joypadDefault", 0);
  1.1924 +	if (joypadDefault < 0 || joypadDefault > 3)
  1.1925 +		joypadDefault = 0;
  1.1926 +	allowLeftRight		   = regQueryDwordValue("allowLeftRight", false) ? true : false;
  1.1927 +	autofireAccountForLag  = regQueryDwordValue("autofireAccountForLag", false) ? true : false;
  1.1928 +	nextframeAccountForLag = regQueryDwordValue("nextframeAccountForLag", false) ? true : false;
  1.1929 +	theApp.AsscWithSaveState = regQueryDwordValue("AsscWithSaveState", false) ? true : false;
  1.1930 +
  1.1931 +	// speed
  1.1932 +	throttle = regQueryDwordValue("throttle", 0);
  1.1933 +	if (throttle < 5 || throttle > 1000)
  1.1934 +		throttle = 100;
  1.1935 +
  1.1936 +	synchronize = regQueryDwordValue("synchronize", 1) ? true : false;
  1.1937 +	accuratePitchThrottle = regQueryDwordValue("accuratePitchThrottle", FALSE) ? TRUE : FALSE;
  1.1938 +
  1.1939 +	// sound
  1.1940 +	int resChannels = regQueryDwordValue("soundEnable", 0x30f);
  1.1941 +	soundEnableChannels(resChannels);
  1.1942 +	soundDisableChannels(~resChannels);
  1.1943 +	soundOffFlag = (regQueryDwordValue("soundOff", 0)) ? true : false;
  1.1944 +	soundQuality = regQueryDwordValue("soundQuality", 2);
  1.1945 +	soundEcho	 = regQueryDwordValue("soundEcho", 0) ? true : false;
  1.1946 +	soundLowPass = regQueryDwordValue("soundLowPass", 0) ? true : false;
  1.1947 +	soundReverse = regQueryDwordValue("soundReverse", 0) ? true : false;
  1.1948 +	soundVolume	 = regQueryDwordValue("soundVolume", 0);
  1.1949 +	if (soundVolume < 0 || soundVolume > 5)
  1.1950 +		soundVolume = 0;
  1.1951 +	muteFrameAdvance = regQueryDwordValue("muteFrameAdvance", 0) ? TRUE : FALSE;
  1.1952 +	muteWhenInactive = regQueryDwordValue("muteWhenInactive", 0) ? TRUE : FALSE;
  1.1953 +
  1.1954 +	// emulation
  1.1955 +	memLagEnabled	  = regQueryDwordValue("memLagEnabled", false) ? true : false;
  1.1956 +	memLagTempEnabled = memLagEnabled;
  1.1957 +	gbNullInputHackEnabled	   = regQueryDwordValue("gbNullInputHackEnabled", false) ? true : false;
  1.1958 +	gbNullInputHackTempEnabled = gbNullInputHackEnabled;
  1.1959 +	useOldSync		  = regQueryDwordValue("useOldSync", 0) ? TRUE : FALSE;
  1.1960 +	useOldFrameTiming = regQueryDwordValue("useOldGBTiming", false) ? true : false;
  1.1961 +
  1.1962 +	useBiosFile	 = regQueryDwordValue("useBios", 0) ? true : false;
  1.1963 +	skipBiosFile = regQueryDwordValue("skipBios", 0) ? true : false;
  1.1964 +	buffer		 = regQueryStringValue("biosFile", "");
  1.1965 +	if (!buffer.IsEmpty())
  1.1966 +	{
  1.1967 +		biosFileName = buffer;
  1.1968 +	}
  1.1969 +//	removeIntros = regQueryDwordValue("removeIntros", false) ? true : false;
  1.1970 +
  1.1971 +	autoIPS = regQueryDwordValue("autoIPS", true) ? true : false;
  1.1972 +
  1.1973 +	agbPrintEnable(regQueryDwordValue("agbPrint", 0) ? true : false);
  1.1974 +	winRtcEnable = regQueryDwordValue("rtcEnabled", 0) ? true : false;
  1.1975 +	rtcEnable(winRtcEnable);
  1.1976 +
  1.1977 +	winSaveType = regQueryDwordValue("saveType", 0);
  1.1978 +	if (winSaveType < 0 || winSaveType > 5)
  1.1979 +		winSaveType = 0;
  1.1980 +	cpuEnhancedDetection = regQueryDwordValue("enhancedDetection", 1) ? true : false;
  1.1981 +	winFlashSize		 = regQueryDwordValue("flashSize", 0x10000);
  1.1982 +	if (winFlashSize != 0x10000 && winFlashSize != 0x20000)
  1.1983 +		winFlashSize = 0x10000;
  1.1984 +
  1.1985 +	cpuDisableSfx = regQueryDwordValue("disableSfx", 0) ? true : false;
  1.1986 +
  1.1987 +	// GBx
  1.1988 +	winGbPrinterEnabled = regQueryDwordValue("gbPrinter", false) ? true : false;
  1.1989 +	if (winGbPrinterEnabled)
  1.1990 +		gbSerialFunction = gbPrinterSend;
  1.1991 +	else
  1.1992 +		gbSerialFunction = NULL;
  1.1993 +	gbEmulatorType = regQueryDwordValue("emulatorType", 0);
  1.1994 +	if (gbEmulatorType < 0 || gbEmulatorType > 5)
  1.1995 +		gbEmulatorType = 1;
  1.1996 +	winGbBorderOn	  = regQueryDwordValue("borderOn", 0);
  1.1997 +	gbBorderAutomatic = regQueryDwordValue("borderAutomatic", 0);
  1.1998 +
  1.1999 +	gbColorOption	= regQueryDwordValue("colorOption", 0);
  1.2000 +	gbPaletteOption = regQueryDwordValue("gbPaletteOption", 0);
  1.2001 +	if (gbPaletteOption < 0)
  1.2002 +		gbPaletteOption = 0;
  1.2003 +	if (gbPaletteOption > 2)
  1.2004 +		gbPaletteOption = 2;
  1.2005 +	regQueryBinaryValue("gbPalette", (char *)systemGbPalette, 24 * sizeof(u16));
  1.2006 +
  1.2007 +	// head-up display
  1.2008 +	showSpeed = regQueryDwordValue("showSpeed", 1);
  1.2009 +	if (showSpeed < 0 || showSpeed > 2)
  1.2010 +		showSpeed = 1;
  1.2011 +	showSpeedTransparent = regQueryDwordValue("showSpeedTransparent", TRUE) ? TRUE : FALSE;
  1.2012 +	outlinedText		 = regQueryDwordValue("outlinedText", TRUE) != 0;
  1.2013 +	transparentText		 = regQueryDwordValue("transparentText", FALSE) != 0;
  1.2014 +	textColor			 = regQueryDwordValue("textColor", 0);
  1.2015 +	textMethod			 = regQueryDwordValue("textMethod", 1);
  1.2016 +	frameCounter		 = regQueryDwordValue("frameCounter", false) ? true : false;
  1.2017 +	lagCounter			 = regQueryDwordValue("lagCounter", false) ? true : false;
  1.2018 +	extraCounter		 = regQueryDwordValue("extraCounter", false) ? true : false;
  1.2019 +	inputDisplay		 = regQueryDwordValue("inputDisplay", false) ? true : false;
  1.2020 +	disableStatusMessage = regQueryDwordValue("disableStatus", 0) ? true : false;
  1.2021 +
  1.2022 +	// UI
  1.2023 +	windowPositionX = regQueryDwordValue("windowX", 0);
  1.2024 +	if (windowPositionX < 0)
  1.2025 +		windowPositionX = 0;
  1.2026 +	windowPositionY = regQueryDwordValue("windowY", 0);
  1.2027 +	if (windowPositionY < 0)
  1.2028 +		windowPositionY = 0;
  1.2029 +
  1.2030 +	autoHideMenu = regQueryDwordValue("autoHideMenu", 0) ? true : false;
  1.2031 +
  1.2032 +	languageOption = regQueryDwordValue("language", 1);
  1.2033 +	if (languageOption < 0 || languageOption > 2)
  1.2034 +		languageOption = 1;
  1.2035 +	buffer = regQueryStringValue("languageName", "");
  1.2036 +	if (!buffer.IsEmpty())
  1.2037 +	{
  1.2038 +		languageName = buffer.Left(3);
  1.2039 +	}
  1.2040 +	else
  1.2041 +		languageName = "";
  1.2042 +	winSetLanguageOption(languageOption, true);
  1.2043 +
  1.2044 +	// preferences
  1.2045 +	alwaysOnTop = regQueryDwordValue("alwaysOnTop", false) ? true : false;
  1.2046 +	pauseWhenInactive	  = regQueryDwordValue("pauseWhenInactive", 1) ? true : false;
  1.2047 +	enableBackgroundInput = regQueryDwordValue("enableBackgroundInput", 0) ? true : false;
  1.2048 +	threadPriority		  = regQueryDwordValue("priority", 2);
  1.2049 +	if (threadPriority < 0 || threadPriority > 3)
  1.2050 +		threadPriority = 2;
  1.2051 +	updatePriority();
  1.2052 +
  1.2053 +	filenamePreference = regQueryDwordValue("filenamePreference", 0);
  1.2054 +	altAviRecordMethod = regQueryDwordValue("altAviRecordMethod", false) ? true : false;
  1.2055 +	captureFormat	   = regQueryDwordValue("captureFormat", 0);
  1.2056 +
  1.2057 +	rewindTimer = regQueryDwordValue("rewindTimer", 0);
  1.2058 +	rewindSlots = regQueryDwordValue("rewindSlots", 64);
  1.2059 +	if (rewindTimer < 0 || rewindTimer > 600)
  1.2060 +		rewindTimer = 0;
  1.2061 +	if (rewindSlots <= 0)
  1.2062 +		rewindTimer = rewindSlots = 0;
  1.2063 +	if (rewindSlots > MAX_REWIND_SLOTS)
  1.2064 +		rewindSlots = MAX_REWIND_SLOTS;
  1.2065 +	if (rewindTimer != 0)
  1.2066 +	{
  1.2067 +		if (rewindMemory == NULL)
  1.2068 +			rewindMemory = (char *)malloc(rewindSlots * REWIND_SIZE);
  1.2069 +	}
  1.2070 +
  1.2071 +	if (frameSearchMemory == NULL)
  1.2072 +		frameSearchMemory = (char *)malloc(3 * REWIND_SIZE);
  1.2073 +
  1.2074 +	recentFreeze = regQueryDwordValue("recentFreeze", false) ? true : false;
  1.2075 +	for (int i = 0, j = 0; i < 10; ++i)
  1.2076 +	{
  1.2077 +		buffer.Format("recent%d", i);
  1.2078 +		const char *s = regQueryStringValue(buffer, NULL);
  1.2079 +		if (s == NULL)
  1.2080 +			continue;
  1.2081 +		recentFiles[j] = s;
  1.2082 +		++j;
  1.2083 +	}
  1.2084 +
  1.2085 +	autoLoadMostRecent = regQueryDwordValue("autoLoadMostRecent", false) ? true : false;
  1.2086 +	loadMakesRecent	   = regQueryDwordValue("loadMakesRecent", false) ? true : false;
  1.2087 +	loadMakesCurrent   = regQueryDwordValue("loadMakesCurrent", false) ? true : false;
  1.2088 +	saveMakesCurrent   = regQueryDwordValue("saveMakesCurrent", false) ? true : false;
  1.2089 +	currentSlot		   = regQueryDwordValue("currentSlot", 0);
  1.2090 +	showSlotTime	   = regQueryDwordValue("showSlotTime", 0) ? true : false;
  1.2091 +
  1.2092 +	cheatsEnabled = regQueryDwordValue("cheatsEnabled", true) ? true : false;
  1.2093 +	autoSaveLoadCheatList  = regQueryDwordValue("autoSaveCheatList", 0) ? true : false;
  1.2094 +	pauseDuringCheatSearch = regQueryDwordValue("pauseDuringCheatSearch2", 0) ? true : false;
  1.2095 +
  1.2096 +	movieOnEndBehavior = regQueryDwordValue("movieOnEndBehavior", 0);
  1.2097 +	movieOnEndPause	   = regQueryDwordValue("movieOnEndPause", 0) ? true : false;
  1.2098 +
  1.2099 +	extern bool autoConvertMovieWhenPlaying;    // from movie.cpp
  1.2100 +	autoConvertMovieWhenPlaying = regQueryDwordValue("autoConvertMovieWhenPlaying", 0) ? true : false;
  1.2101 +
  1.2102 +	// RamWatch Settings
  1.2103 +	AutoRWLoad		= regQueryDwordValue(AUTORWLOAD, false);
  1.2104 +	RWSaveWindowPos = regQueryDwordValue(RWSAVEPOS, false);
  1.2105 +	ramw_x = regQueryDwordValue(RAMWX, 0);
  1.2106 +	ramw_y = regQueryDwordValue(RAMWY, 0);
  1.2107 +
  1.2108 +	// this is FILO
  1.2109 +	for (int i = MAX_RECENT_WATCHES; i > 0; --i)
  1.2110 +	{
  1.2111 +		buffer.Format("recentWatch%d", i);
  1.2112 +		const char *s = regQueryStringValue(buffer, NULL);
  1.2113 +		if (s == NULL)
  1.2114 +			continue;
  1.2115 +		RWAddRecentFile(s);
  1.2116 +	}
  1.2117 +}
  1.2118 +
  1.2119 +void VBA::saveSettings()
  1.2120 +{
  1.2121 +	regSetDwordValue("defaultVideoDriver", pVideoDriverGUID == NULL);
  1.2122 +	if (pVideoDriverGUID)
  1.2123 +	{
  1.2124 +		regSetBinaryValue("videoDriverGUID", (char *)&videoDriverGUID,
  1.2125 +		                  sizeof(GUID));
  1.2126 +	}
  1.2127 +	regSetDwordValue("video", videoOption);
  1.2128 +
  1.2129 +	regSetDwordValue("fsWidth", fsWidth);
  1.2130 +	regSetDwordValue("fsHeight", fsHeight);
  1.2131 +	regSetDwordValue("fsColorDepth", fsColorDepth);
  1.2132 +	regSetDwordValue("fsMaxScale", fsMaxScale);
  1.2133 +
  1.2134 +	regSetDwordValue("stretch", fullScreenStretch);
  1.2135 +
  1.2136 +	regSetDwordValue("renderMethod", renderMethod);
  1.2137 +
  1.2138 +	regSetDwordValue("ddrawEmulationOnly", ddrawEmulationOnly);
  1.2139 +	regSetDwordValue("ddrawUseVideoMemory", ddrawUseVideoMemory);
  1.2140 +	regSetDwordValue("tripleBuffering", tripleBuffering);
  1.2141 +	regSetDwordValue("vsync", vsync);
  1.2142 +
  1.2143 +	regSetDwordValue("d3dFilter", d3dFilter);
  1.2144 +	regSetDwordValue("glFilter", glFilter);
  1.2145 +	regSetDwordValue("glType", glType);
  1.2146 +
  1.2147 +	// pixel filter & ifb
  1.2148 +	regSetDwordValue("filter", filterType);
  1.2149 +	regSetDwordValue("ifbType", ifbType);
  1.2150 +	regSetDwordValue("disableMMX", disableMMX);
  1.2151 +
  1.2152 +	// frame skipping
  1.2153 +	regSetDwordValue("frameSkip", frameSkip);
  1.2154 +	regSetDwordValue("gbFrameSkip", gbFrameSkip);
  1.2155 +///  regSetDwordValue("autoFrameSkip", autoFrameSkip);
  1.2156 +
  1.2157 +	// input
  1.2158 +	regSetDwordValue("joypadDefault", joypadDefault);
  1.2159 +	regSetDwordValue("allowLeftRight", allowLeftRight);
  1.2160 +	regSetDwordValue("autofireAccountforLag", autofireAccountForLag);
  1.2161 +	regSetDwordValue("nextframeAccountforLag", nextframeAccountForLag);
  1.2162 +	regSetDwordValue("AsscWithSaveState", theApp.AsscWithSaveState);
  1.2163 +
  1.2164 +
  1.2165 +	// speed
  1.2166 +	regSetDwordValue("throttle", throttle);
  1.2167 +	regSetDwordValue("synchronize", synchronize);
  1.2168 +	regSetDwordValue("accuratePitchThrottle", accuratePitchThrottle);
  1.2169 +
  1.2170 +	// sound
  1.2171 +	regSetDwordValue("soundEnable", soundGetEnabledChannels() & 0x030f);
  1.2172 +	regSetDwordValue("soundOff", soundOffFlag);
  1.2173 +	regSetDwordValue("soundQuality", soundQuality);
  1.2174 +	regSetDwordValue("soundEcho", soundEcho);
  1.2175 +	regSetDwordValue("soundLowPass", soundLowPass);
  1.2176 +	regSetDwordValue("soundReverse", soundReverse);
  1.2177 +	regSetDwordValue("soundVolume", soundVolume);
  1.2178 +	regSetDwordValue("muteFrameAdvance", muteFrameAdvance);
  1.2179 +	regSetDwordValue("muteWhenInactive", muteWhenInactive);
  1.2180 +
  1.2181 +	// emulation
  1.2182 +	regSetDwordValue("useBios", useBiosFile);
  1.2183 +	regSetDwordValue("skipBios", skipBiosFile);
  1.2184 +	if (!biosFileName.IsEmpty())
  1.2185 +		regSetStringValue("biosFile", biosFileName);
  1.2186 +//	regSetDwordValue("removeIntros", removeIntros);
  1.2187 +
  1.2188 +	regSetDwordValue("autoIPS", autoIPS);
  1.2189 +
  1.2190 +	regSetDwordValue("memLagEnabled", memLagEnabled);
  1.2191 +	regSetDwordValue("gbNullInputHackEnabled", gbNullInputHackEnabled);
  1.2192 +	regSetDwordValue("useOldGBTiming", useOldFrameTiming);
  1.2193 +	regSetDwordValue("useOldSync", useOldSync);
  1.2194 +
  1.2195 +	regSetDwordValue("agbPrint", agbPrintIsEnabled());
  1.2196 +	regSetDwordValue("rtcEnabled", winRtcEnable);
  1.2197 +
  1.2198 +	regSetDwordValue("saveType", winSaveType);
  1.2199 +	regSetDwordValue("enhancedDetection", cpuEnhancedDetection);
  1.2200 +	regSetDwordValue("flashSize", winFlashSize);
  1.2201 +
  1.2202 +	regSetDwordValue("disableSfx", cpuDisableSfx);
  1.2203 +
  1.2204 +	// GBx
  1.2205 +	regSetDwordValue("emulatorType", gbEmulatorType);
  1.2206 +	regSetDwordValue("gbPrinter", winGbPrinterEnabled);
  1.2207 +	regSetDwordValue("borderOn", winGbBorderOn);
  1.2208 +	regSetDwordValue("borderAutomatic", gbBorderAutomatic);
  1.2209 +
  1.2210 +	regSetDwordValue("colorOption", gbColorOption);
  1.2211 +	regSetDwordValue("gbPaletteOption", gbPaletteOption);
  1.2212 +	regSetBinaryValue("gbPalette", (char *)systemGbPalette, 24 * sizeof(u16));
  1.2213 +
  1.2214 +	// head-up display
  1.2215 +	regSetDwordValue("showSpeed", showSpeed);
  1.2216 +	regSetDwordValue("showSpeedTransparent", showSpeedTransparent);
  1.2217 +
  1.2218 +	regSetDwordValue("outlinedText", outlinedText);
  1.2219 +	regSetDwordValue("transparentText", transparentText);
  1.2220 +	regSetDwordValue("textColor", textColor);
  1.2221 +	regSetDwordValue("textMethod", textMethod);
  1.2222 +	regSetDwordValue("frameCounter", frameCounter);
  1.2223 +	regSetDwordValue("lagCounter", lagCounter);
  1.2224 +	regSetDwordValue("extraCounter", extraCounter);
  1.2225 +	regSetDwordValue("inputDisplay", inputDisplay);
  1.2226 +	regSetDwordValue("disableStatus", disableStatusMessage);
  1.2227 +
  1.2228 +	// UI
  1.2229 +	regSetDwordValue("windowX", windowPositionX);
  1.2230 +	regSetDwordValue("windowY", windowPositionY);
  1.2231 +
  1.2232 +	regSetDwordValue("autoHideMenu", autoHideMenu);
  1.2233 +
  1.2234 +	regSetDwordValue("language", languageOption);
  1.2235 +	regSetStringValue("languageName", languageName);
  1.2236 +
  1.2237 +	// preferences
  1.2238 +	regSetDwordValue("alwaysOnTop", alwaysOnTop);
  1.2239 +	regSetDwordValue("pauseWhenInactive", pauseWhenInactive);
  1.2240 +	regSetDwordValue("enableBackgroundInput", enableBackgroundInput);
  1.2241 +	regSetDwordValue("priority", threadPriority);
  1.2242 +
  1.2243 +	regSetDwordValue("filenamePreference", filenamePreference);
  1.2244 +	regSetDwordValue("altAviRecordMethod", altAviRecordMethod);
  1.2245 +	regSetDwordValue("captureFormat", captureFormat);
  1.2246 +
  1.2247 +	regSetDwordValue("cheatsEnabled", cheatsEnabled);
  1.2248 +	regSetDwordValue("autoSaveCheatList", autoSaveLoadCheatList);
  1.2249 +	regSetDwordValue("pauseDuringCheatSearch2", pauseDuringCheatSearch);
  1.2250 +
  1.2251 +	regSetDwordValue("rewindTimer", rewindTimer);
  1.2252 +	regSetDwordValue("rewindSlots", rewindSlots);
  1.2253 +
  1.2254 +	regSetDwordValue("recentFreeze", recentFreeze);
  1.2255 +	CString buffer;
  1.2256 +	for (int i = 0; i < 10; i++)
  1.2257 +	{
  1.2258 +		buffer.Format("recent%d", i);
  1.2259 +		regSetStringValue(buffer, recentFiles[i]);
  1.2260 +	}
  1.2261 +
  1.2262 +	regSetDwordValue("autoLoadMostRecent", autoLoadMostRecent);
  1.2263 +	regSetDwordValue("loadMakesRecent", loadMakesRecent);
  1.2264 +	regSetDwordValue("loadMakesCurrent", loadMakesCurrent);
  1.2265 +	regSetDwordValue("saveMakesCurrent", saveMakesCurrent);
  1.2266 +	regSetDwordValue("currentSlot", currentSlot);
  1.2267 +	regSetDwordValue("showSlotTime", showSlotTime);
  1.2268 +
  1.2269 +	regSetDwordValue("movieOnEndBehavior", movieOnEndBehavior);
  1.2270 +	regSetDwordValue("movieOnEndPause", movieOnEndPause);
  1.2271 +
  1.2272 +	extern bool autoConvertMovieWhenPlaying;    // from movie.cpp
  1.2273 +	regSetDwordValue("autoConvertMovieWhenPlaying", autoConvertMovieWhenPlaying);
  1.2274 +}
  1.2275 +