rlm@1: // VBA.cpp : Defines the class behaviors for the application. rlm@1: // rlm@1: #include "stdafx.h" rlm@1: #include rlm@1: #include rlm@1: rlm@1: #include "resource.h" rlm@1: #include "VBA.h" rlm@1: #include "AVIWrite.h" rlm@1: #include "Input.h" rlm@1: #include "IUpdate.h" rlm@1: #include "LangSelect.h" rlm@1: #include "MainWnd.h" rlm@1: #include "Reg.h" rlm@1: #include "WavWriter.h" rlm@1: #include "WinResUtil.h" rlm@1: #include "WinMiscUtil.h" rlm@1: #include "ramwatch.h" rlm@1: rlm@1: #include "../gba/GBA.h" rlm@1: #include "../gba/GBAGlobals.h" rlm@1: #include "../gba/agbprint.h" rlm@1: #include "../gb/GB.h" rlm@1: #include "../gb/gbGlobals.h" rlm@1: #include "../gb/gbPrinter.h" rlm@1: #include "../common/CheatSearch.h" rlm@1: #include "../gba/RTC.h" rlm@1: #include "../gba/GBASound.h" rlm@1: #include "../common/Util.h" rlm@1: #include "../common/Text.h" rlm@1: #include "../common/movie.h" rlm@1: #include "../common/nesvideos-piece.h" rlm@1: #include "../common/vbalua.h" rlm@1: #include "../filters/filters.h" rlm@1: #include "../version.h" rlm@1: rlm@1: extern IDisplay *newGDIDisplay(); rlm@1: extern IDisplay *newDirectDrawDisplay(); rlm@1: extern IDisplay *newDirect3DDisplay(); rlm@1: extern IDisplay *newOpenGLDisplay(); rlm@1: rlm@1: extern Input *newDirectInput(); rlm@1: rlm@1: extern void remoteStubSignal(int, int); rlm@1: extern void remoteOutput(char *, u32); rlm@1: extern void remoteStubMain(); rlm@1: extern void remoteSetProtocol(int); rlm@1: extern void remoteCleanUp(); rlm@1: extern int remoteSocket; rlm@1: rlm@1: void winlog(const char *msg, ...); rlm@1: rlm@1: bool debugger = false; rlm@1: rlm@1: char movieFileToPlay[1024]; rlm@1: bool playMovieFile = false; rlm@1: bool playMovieFileReadOnly = false; rlm@1: char wavFileToOutput [1024]; rlm@1: bool outputWavFile = false; rlm@1: bool outputAVIFile = false; rlm@1: bool flagHideMenu = false; rlm@1: int quitAfterTime = -1; rlm@1: int pauseAfterTime = -1; rlm@1: rlm@1: void winSignal(int, int); rlm@1: void winOutput(char *, u32); rlm@1: rlm@1: void (*dbgSignal)(int, int) = winSignal; rlm@1: void (*dbgOutput)(char *, u32) = winOutput; rlm@1: rlm@1: #ifdef MMX rlm@1: extern "C" bool cpu_mmx; rlm@1: #endif rlm@1: rlm@1: // nowhere good to put them to rlm@1: rlm@1: void DrawTextMessages(u8 *dest, int pitch, int left, int bottom) rlm@1: { rlm@1: for (int slot = 0; slot < SCREEN_MESSAGE_SLOTS; slot++) rlm@1: { rlm@1: if (theApp.screenMessage[slot]) rlm@1: { rlm@1: if ((theApp.screenMessageDuration[slot] < 0 || rlm@1: (int)(GetTickCount() - theApp.screenMessageTime[slot]) < theApp.screenMessageDuration[slot]) && rlm@1: (!theApp.disableStatusMessage || slot == 1 || slot == 2)) rlm@1: { rlm@1: drawText(dest, rlm@1: pitch, rlm@1: left, rlm@1: bottom - 10 * (slot + 1), rlm@1: theApp.screenMessageBuffer[slot], rlm@1: theApp.screenMessageColorBuffer[slot]); rlm@1: } rlm@1: else rlm@1: { rlm@1: theApp.screenMessage[slot] = false; rlm@1: } rlm@1: } rlm@1: } rlm@1: } rlm@1: rlm@1: // draw Lua graphics in game screen rlm@1: void DrawLuaGui() rlm@1: { rlm@1: int copyX = 240, copyY = 160; rlm@1: int screenX = 240, screenY = 160; rlm@1: int copyOffsetX = 0, copyOffsetY = 0; rlm@1: if (systemCartridgeType == 1) rlm@1: { rlm@1: if (gbBorderOn) rlm@1: { rlm@1: copyX = 256, copyY = 224; rlm@1: screenX = 256, screenY = 224; rlm@1: } rlm@1: else rlm@1: { rlm@1: copyX = 160, copyY = 144; rlm@1: screenX = 160, screenY = 144; rlm@1: } rlm@1: } rlm@1: int pitch = copyX * (systemColorDepth / 8) + (systemColorDepth == 24 ? 0 : 4); rlm@1: rlm@1: ++copyOffsetY; // don't know why it's needed rlm@1: rlm@1: VBALuaGui(&pix[copyOffsetY * pitch + copyOffsetX * (systemColorDepth / 8)], copyX, screenX, screenY); rlm@1: VBALuaClearGui(); rlm@1: } rlm@1: rlm@1: void directXMessage(const char *msg) rlm@1: { rlm@1: systemMessage( rlm@1: IDS_DIRECTX_7_REQUIRED, rlm@1: "DirectX 7.0 or greater is required to run.\nDownload at http://www.microsoft.com/directx.\n\nError found at: %s", rlm@1: msg); rlm@1: } rlm@1: rlm@1: void winlog(const char *msg, ...) rlm@1: { rlm@1: CString buffer; rlm@1: va_list valist; rlm@1: rlm@1: va_start(valist, msg); rlm@1: buffer.FormatV(msg, valist); rlm@1: rlm@1: FILE *winout = fopen("vba-trace.log", "w"); rlm@1: rlm@1: fputs(buffer, winout); rlm@1: rlm@1: fclose(winout); rlm@1: rlm@1: va_end(valist); rlm@1: } rlm@1: rlm@1: // code from SDL_main.c for Windows rlm@1: /* Parse a command line buffer into arguments */ rlm@1: rlm@1: static int parseCommandLine(char *cmdline, char * *argv) rlm@1: { rlm@1: char *bufp; rlm@1: int argc; rlm@1: rlm@1: argc = 0; rlm@1: for (bufp = cmdline; *bufp; ) rlm@1: { rlm@1: /* Skip leading whitespace */ rlm@1: while (isspace(*bufp)) rlm@1: { rlm@1: ++bufp; rlm@1: } rlm@1: /* Skip over argument */ rlm@1: if (*bufp == '"') rlm@1: { rlm@1: ++bufp; rlm@1: if (*bufp) rlm@1: { rlm@1: if (argv) rlm@1: { rlm@1: argv[argc] = bufp; rlm@1: } rlm@1: ++argc; rlm@1: } rlm@1: /* Skip over word */ rlm@1: while (*bufp && (*bufp != '"')) rlm@1: { rlm@1: ++bufp; rlm@1: } rlm@1: } rlm@1: else rlm@1: { rlm@1: if (*bufp) rlm@1: { rlm@1: if (argv) rlm@1: { rlm@1: argv[argc] = bufp; rlm@1: } rlm@1: ++argc; rlm@1: } rlm@1: /* Skip over word */ rlm@1: while (*bufp && !isspace(*bufp)) rlm@1: { rlm@1: ++bufp; rlm@1: } rlm@1: } rlm@1: if (*bufp) rlm@1: { rlm@1: if (argv) rlm@1: { rlm@1: *bufp = '\0'; rlm@1: } rlm@1: ++bufp; rlm@1: } rlm@1: } rlm@1: if (argv) rlm@1: { rlm@1: argv[argc] = NULL; rlm@1: } rlm@1: return(argc); rlm@1: } rlm@1: rlm@1: static void debugSystemScreenMessage1(const char *msg) rlm@1: { rlm@1: systemScreenMessage(msg, 3); rlm@1: } rlm@1: rlm@1: static void debugSystemScreenMessage2(const char *msg) rlm@1: { rlm@1: systemScreenMessage(msg, 4); rlm@1: } rlm@1: rlm@1: static void winSignal(int, int) rlm@1: {} rlm@1: rlm@1: #define CPUReadByteQuick(addr) \ rlm@1: map[(addr) >> 24].address[(addr) & map[(addr) >> 24].mask] rlm@1: rlm@1: static void winOutput(char *s, u32 addr) rlm@1: { rlm@1: if (s) rlm@1: { rlm@1: log(s); rlm@1: } rlm@1: else rlm@1: { rlm@1: CString str; rlm@1: char c; rlm@1: rlm@1: c = CPUReadByteQuick(addr); rlm@1: addr++; rlm@1: while (c) rlm@1: { rlm@1: str += c; rlm@1: c = CPUReadByteQuick(addr); rlm@1: addr++; rlm@1: } rlm@1: log(str); rlm@1: } rlm@1: } rlm@1: rlm@1: typedef BOOL (WINAPI * GETMENUBARINFO)(HWND, LONG, LONG, PMENUBARINFO); rlm@1: rlm@1: static int winGetMenuBarHeight() rlm@1: { rlm@1: HINSTANCE hinstDll = /**/ ::LoadLibrary("USER32.DLL"); rlm@1: rlm@1: if (hinstDll) rlm@1: { rlm@1: GETMENUBARINFO func = (GETMENUBARINFO)GetProcAddress(hinstDll, "GetMenuBarInfo"); rlm@1: rlm@1: if (func) rlm@1: { rlm@1: MENUBARINFO info; rlm@1: info.cbSize = sizeof(info); rlm@1: rlm@1: func(AfxGetMainWnd()->GetSafeHwnd(), OBJID_MENU, 0, &info); rlm@1: rlm@1: /**/ ::FreeLibrary(hinstDll); rlm@1: rlm@1: return info.rcBar.bottom - info.rcBar.top + 1; rlm@1: } rlm@1: } rlm@1: rlm@1: return GetSystemMetrics(SM_CYMENU); rlm@1: } rlm@1: rlm@1: ///////////////////////////////////////////////////////////////////////////// rlm@1: // VBA rlm@1: rlm@1: BEGIN_MESSAGE_MAP(VBA, CWinApp) rlm@1: //{{AFX_MSG_MAP(VBA) rlm@1: // NOTE - the ClassWizard will add and remove mapping macros here. rlm@1: // DO NOT EDIT what you see in these blocks of generated code! rlm@1: //}}AFX_MSG_MAP rlm@1: END_MESSAGE_MAP() rlm@1: rlm@1: ///////////////////////////////////////////////////////////////////////////// rlm@1: // The one and only VBA object rlm@1: rlm@1: VBA theApp; rlm@1: rlm@1: ///////////////////////////////////////////////////////////////////////////// rlm@1: // VBA construction rlm@1: rlm@1: VBA::VBA() : emulator(::theEmulator) rlm@1: { rlm@1: // important rlm@1: { rlm@1: #ifdef MULTITHREAD_STDLOCALE_WORKAROUND rlm@1: // Note: there's a known threading bug regarding std::locale with MSVC according to rlm@1: // http://connect.microsoft.com/VisualStudio/feedback/details/492128/std-locale-constructor-modifies-global-locale-via-setlocale rlm@1: int iPreviousFlag = ::_configthreadlocale(_ENABLE_PER_THREAD_LOCALE); rlm@1: #endif rlm@1: using std::locale; rlm@1: locale::global(locale(locale::classic(), "", locale::collate | locale::ctype)); rlm@1: rlm@1: #ifdef MULTITHREAD_STDLOCALE_WORKAROUND rlm@1: if (iPreviousFlag > 0 ) rlm@1: ::_configthreadlocale(iPreviousFlag); rlm@1: #endif rlm@1: } rlm@1: rlm@1: mode320Available = false; rlm@1: mode640Available = false; rlm@1: mode800Available = false; rlm@1: windowPositionX = 0; rlm@1: windowPositionY = 0; rlm@1: filterFunction = NULL; rlm@1: ifbFunction = NULL; rlm@1: ifbType = 0; rlm@1: filterType = 0; rlm@1: filterWidth = 0; rlm@1: filterHeight = 0; rlm@1: fsWidth = 0; rlm@1: fsHeight = 0; rlm@1: fsColorDepth = 0; rlm@1: fsForceChange = false; rlm@1: surfaceSizeX = 0; rlm@1: surfaceSizeY = 0; rlm@1: sizeX = 0; rlm@1: sizeY = 0; rlm@1: videoOption = 0; rlm@1: fullScreenStretch = false; rlm@1: disableStatusMessage = false; rlm@1: showSpeed = 1; rlm@1: showSpeedTransparent = true; rlm@1: showRenderedFrames = 0; rlm@1: for (int j = 0; j < SCREEN_MESSAGE_SLOTS; j++) rlm@1: { rlm@1: screenMessage[j] = false; rlm@1: screenMessageTime[j] = 0; rlm@1: screenMessageDuration[j] = 0; rlm@1: } rlm@1: menuToggle = true; rlm@1: display = NULL; rlm@1: menu = NULL; rlm@1: popup = NULL; rlm@1: soundInitialized = false; rlm@1: useBiosFile = false; rlm@1: skipBiosFile = false; rlm@1: active = true; rlm@1: paused = false; rlm@1: recentFreeze = false; rlm@1: autoSaveLoadCheatList = false; rlm@1: pauseDuringCheatSearch = false; rlm@1: modelessCheatDialogIsOpen = false; rlm@1: // winout = NULL; rlm@1: // removeIntros = false; rlm@1: autoIPS = true; rlm@1: winGbBorderOn = 0; rlm@1: hideMovieBorder = false; rlm@1: winFlashSize = 0x10000; rlm@1: winRtcEnable = false; rlm@1: winSaveType = 0; rlm@1: rewindMemory = NULL; rlm@1: frameSearchMemory = NULL; rlm@1: rewindPos = 0; rlm@1: rewindTopPos = 0; rlm@1: rewindCounter = 0; rlm@1: rewindCount = 0; rlm@1: rewindSaveNeeded = false; rlm@1: rewindTimer = 0; rlm@1: captureFormat = 0; rlm@1: tripleBuffering = true; rlm@1: autoHideMenu = false; rlm@1: throttle = 100; rlm@1: throttleLastTime = 0; rlm@1: /// autoFrameSkipLastTime = 0; rlm@1: /// autoFrameSkip = false; rlm@1: vsync = false; rlm@1: changingVideoSize = false; rlm@1: pVideoDriverGUID = NULL; rlm@1: renderMethod = DIRECT_DRAW; rlm@1: iconic = false; rlm@1: ddrawEmulationOnly = false; rlm@1: ddrawUsingEmulationOnly = false; rlm@1: ddrawDebug = false; rlm@1: ddrawUseVideoMemory = false; rlm@1: d3dFilter = 0; rlm@1: glFilter = 0; rlm@1: glType = 0; rlm@1: regEnabled = false; rlm@1: pauseWhenInactive = true; rlm@1: muteWhenInactive = true; rlm@1: enableBackgroundInput = false; rlm@1: alwaysOnTop = false; rlm@1: filenamePreference = true; rlm@1: frameCounter = false; rlm@1: lagCounter = false; rlm@1: extraCounter = false; rlm@1: inputDisplay = false; rlm@1: speedupToggle = false; rlm@1: useOldSync = false; rlm@1: allowLeftRight = false; rlm@1: autofireAccountForLag = false; rlm@1: nextframeAccountForLag = false; rlm@1: muteFrameAdvance = false; rlm@1: muteWhenInactive = false; rlm@1: winMuteForNow = false; rlm@1: winGbPrinterEnabled = false; rlm@1: threadPriority = 2; rlm@1: disableMMX = false; rlm@1: languageOption = 0; rlm@1: languageModule = NULL; rlm@1: languageName = ""; rlm@1: renderedFrames = 0; rlm@1: input = NULL; rlm@1: joypadDefault = 0; rlm@1: autoFire = 0; rlm@1: autoFire2 = 0; rlm@1: autoHold = 0; rlm@1: autoFireToggle = false; rlm@1: winPauseNextFrame = false; rlm@1: soundRecording = false; rlm@1: soundRecorder = NULL; rlm@1: sound = NULL; rlm@1: aviRecording = false; rlm@1: aviRecorder = NULL; rlm@1: painting = false; rlm@1: mouseCounter = 0; rlm@1: movieReadOnly = true; rlm@1: movieOnEndPause = false; rlm@1: movieOnEndBehavior = 0; rlm@1: wasPaused = false; rlm@1: fsMaxScale = 0; rlm@1: romSize = 0; rlm@1: autoLoadMostRecent = false; rlm@1: loadMakesRecent = false; rlm@1: loadMakesCurrent = false; rlm@1: saveMakesCurrent = false; rlm@1: currentSlot = 0; rlm@1: showSlotTime = false; rlm@1: frameSearchLoadValid = false; rlm@1: frameSearching = false; rlm@1: frameSearchSkipping = false; rlm@1: nvVideoLog = false; rlm@1: nvAudioLog = false; rlm@1: LoggingEnabled = 0; rlm@1: /// FPS = 60; rlm@1: rlm@1: updateCount = 0; rlm@1: rlm@1: systemSaveUpdateCounter = SYSTEM_SAVE_NOT_UPDATED; rlm@1: rlm@1: ZeroMemory(&emulator, sizeof(emulator)); rlm@1: rlm@1: hAccel = NULL; rlm@1: rlm@1: for (int i = 0; i < 24; ) rlm@1: { rlm@1: systemGbPalette[i++] = (0x1f) | (0x1f << 5) | (0x1f << 10); rlm@1: systemGbPalette[i++] = (0x15) | (0x15 << 5) | (0x15 << 10); rlm@1: systemGbPalette[i++] = (0x0c) | (0x0c << 5) | (0x0c << 10); rlm@1: systemGbPalette[i++] = 0; rlm@1: } rlm@1: rlm@1: VBAMovieInit(); rlm@1: rlm@1: TIMECAPS tc; rlm@1: if (timeGetDevCaps(&tc, sizeof(TIMECAPS)) == TIMERR_NOERROR) rlm@1: { rlm@1: wmTimerRes = min(max(tc.wPeriodMin, 1), tc.wPeriodMax); rlm@1: timeBeginPeriod(wmTimerRes); rlm@1: } rlm@1: else rlm@1: { rlm@1: wmTimerRes = 5; rlm@1: timeBeginPeriod(wmTimerRes); rlm@1: } rlm@1: } rlm@1: rlm@1: VBA::~VBA() rlm@1: { rlm@1: if (VBAMovieActive()) rlm@1: VBAMovieStop(true); rlm@1: rlm@1: saveSettings(); rlm@1: rlm@1: InterframeCleanup(); rlm@1: rlm@1: if (aviRecorder) rlm@1: { rlm@1: delete aviRecorder; rlm@1: aviRecorder = NULL; rlm@1: aviRecording = false; rlm@1: } rlm@1: rlm@1: if (soundRecorder) rlm@1: { rlm@1: delete soundRecorder; rlm@1: soundRecorder = NULL; rlm@1: } rlm@1: soundRecording = false; rlm@1: soundPause(); rlm@1: soundShutdown(); rlm@1: rlm@1: ((MainWnd *)(m_pMainWnd))->winFileClose(); rlm@1: rlm@1: if (input) rlm@1: delete input; rlm@1: rlm@1: shutdownDisplay(); rlm@1: rlm@1: if (rewindMemory) rlm@1: free(rewindMemory); rlm@1: rlm@1: if (frameSearchMemory) rlm@1: free(frameSearchMemory); rlm@1: rlm@1: timeEndPeriod(wmTimerRes); rlm@1: } rlm@1: rlm@1: ///////////////////////////////////////////////////////////////////////////// rlm@1: // VBA initialization rlm@1: rlm@1: #include rlm@1: rlm@1: BOOL VBA::InitInstance() rlm@1: { rlm@1: AfxEnableControlContainer(); rlm@1: // Standard initialization rlm@1: // If you are not using these features and wish to reduce the size rlm@1: // of your final executable, you should remove from the following rlm@1: // the specific initialization routines you do not need. rlm@1: rlm@1: //#ifdef _AFXDLL rlm@1: // Enable3dControls(); // Call this when using MFC in a shared DLL rlm@1: //#else rlm@1: // Enable3dControlsStatic(); // Call this when linking to MFC statically rlm@1: //#endif rlm@1: rlm@1: SetRegistryKey(_T("VBA")); rlm@1: rlm@1: remoteSetProtocol(0); rlm@1: rlm@1: systemVerbose = GetPrivateProfileInt("config", "verbose", 0, "VBA.ini"); rlm@1: systemDebug = GetPrivateProfileInt("config", "debug", 0, "VBA.ini"); rlm@1: ddrawDebug = GetPrivateProfileInt("config", "ddrawDebug", 0, "VBA.ini") ? true : false; rlm@1: rlm@1: wndClass = AfxRegisterWndClass(0, LoadCursor(IDC_ARROW), (HBRUSH)GetStockObject(BLACK_BRUSH), LoadIcon(IDI_ICON)); rlm@1: rlm@1: char winBuffer[2048]; rlm@1: GetModuleFileName(NULL, winBuffer, 2048); rlm@1: char *p = strrchr(winBuffer, '\\'); rlm@1: if (p) rlm@1: *p = 0; rlm@1: exeDir = winBuffer; rlm@1: rlm@1: regInit(winBuffer); rlm@1: rlm@1: loadSettings(); rlm@1: theApp.LuaFastForward = -1; rlm@1: if (!initInput()) rlm@1: return FALSE; rlm@1: rlm@1: if (!initDisplay()) rlm@1: { rlm@1: if (videoOption >= VIDEO_320x240) rlm@1: { rlm@1: regSetDwordValue("video", VIDEO_1X); rlm@1: if (pVideoDriverGUID) rlm@1: regSetDwordValue("defaultVideoDriver", TRUE); rlm@1: } rlm@1: return FALSE; rlm@1: } rlm@1: rlm@1: hAccel = LoadAccelerators(AfxGetInstanceHandle(), MAKEINTRESOURCE(IDR_ACCELERATOR)); rlm@1: rlm@1: winAccelMgr.Connect((MainWnd *)m_pMainWnd); rlm@1: rlm@1: extern void winAccelAddCommandsFromMenu(CAcceleratorManager & mgr, CMenu * pMenu, const CString &parentStr); rlm@1: extern void winAccelAddCommandsFromTable(CAcceleratorManager & mgr); rlm@1: rlm@1: winAccelAddCommandsFromMenu(winAccelMgr, &m_menu, CString()); rlm@1: winAccelAddCommandsFromTable(winAccelMgr); rlm@1: rlm@1: winAccelMgr.CreateDefaultTable(); rlm@1: winAccelMgr.Load(); rlm@1: winAccelMgr.UpdateWndTable(); rlm@1: winAccelMgr.UpdateMenu(menu); rlm@1: rlm@1: if (m_lpCmdLine[0]) rlm@1: { rlm@1: int argc = parseCommandLine(m_lpCmdLine, NULL); rlm@1: char * *argv = (char * *)malloc((argc + 1) * sizeof(char *)); rlm@1: parseCommandLine(m_lpCmdLine, argv); rlm@1: rlm@1: bool gotFlag = false, enoughArgs = false; rlm@1: for (int i = 0; i < argc; i++) rlm@1: { rlm@1: if (argv[i][0] == '-' || gotFlag) rlm@1: { rlm@1: if (!gotFlag) rlm@1: loadSettings(); rlm@1: gotFlag = true; rlm@1: if (_stricmp(argv[i], "-rom") == 0) rlm@1: { rlm@1: if (i + 1 >= argc || argv[i + 1][0] == '-') rlm@1: goto invalidArgument; rlm@1: romFilename = argv[++i]; rlm@1: winCorrectPath(romFilename); rlm@1: gameFilename = romFilename; rlm@1: } rlm@1: else if (_stricmp(argv[i], "-bios") == 0) rlm@1: { rlm@1: if (i + 1 >= argc || argv[i + 1][0] == '-') rlm@1: goto invalidArgument; rlm@1: biosFileName = argv[++i]; rlm@1: winCorrectPath(biosFileName); rlm@1: rlm@1: //systemLoadBIOS(); rlm@1: } rlm@1: else if (_stricmp(argv[i], "-frameskip") == 0) rlm@1: { rlm@1: if (i + 1 >= argc || argv[i + 1][0] == '-') rlm@1: goto invalidArgument; rlm@1: frameSkip = atoi(argv[++i]); rlm@1: if (frameSkip < 0) rlm@1: frameSkip = 0; rlm@1: if (frameSkip > 9) rlm@1: frameSkip = 9; rlm@1: gbFrameSkip = frameSkip; rlm@1: } rlm@1: else if (_stricmp(argv[i], "-throttle") == 0) rlm@1: { rlm@1: if (i + 1 >= argc || argv[i + 1][0] == '-') rlm@1: goto invalidArgument; rlm@1: throttle = atoi(argv[++i]); rlm@1: if (throttle < 5) rlm@1: throttle = 5; rlm@1: if (throttle > 1000) rlm@1: throttle = 1000; rlm@1: } rlm@1: else if (_stricmp(argv[i], "-throttleKeepPitch") == 0) rlm@1: { rlm@1: if (i + 1 >= argc || argv[i + 1][0] == '-') rlm@1: goto invalidArgument; rlm@1: accuratePitchThrottle = atoi(argv[++i]) != 0; rlm@1: } rlm@1: else if (_stricmp(argv[i], "-synchronize") == 0) rlm@1: { rlm@1: if (i + 1 >= argc || argv[i + 1][0] == '-') rlm@1: goto invalidArgument; rlm@1: synchronize = atoi(argv[++i]) != 0; rlm@1: } rlm@1: else if (_stricmp(argv[i], "-hideborder") == 0) rlm@1: { rlm@1: if (i + 1 >= argc || argv[i + 1][0] == '-') rlm@1: goto invalidArgument; rlm@1: hideMovieBorder = atoi(argv[++i]) != 0; rlm@1: } rlm@1: else if (_stricmp(argv[i], "-play") == 0) rlm@1: { rlm@1: playMovieFile = true; rlm@1: if (i + 1 >= argc || argv[i + 1][0] == '-') rlm@1: goto invalidArgument; rlm@1: strcpy(movieFileToPlay, argv[++i]); rlm@1: winCorrectPath(movieFileToPlay); rlm@1: if (i + 1 >= argc || argv[i + 1][0] == '-') { --i; goto invalidArgument; } rlm@1: playMovieFileReadOnly = atoi(argv[++i]) != 0; rlm@1: } rlm@1: else if (_stricmp(argv[i], "-videoLog") == 0) rlm@1: { rlm@1: nvVideoLog = true; rlm@1: nvAudioLog = true; rlm@1: LoggingEnabled = 2; rlm@1: if (i + 1 >= argc || argv[i + 1][0] == '-') {} rlm@1: else rlm@1: NESVideoSetVideoCmd(argv[++i]); rlm@1: } rlm@1: else if (_stricmp(argv[i], "-logDebug") == 0) rlm@1: { rlm@1: NESVideoEnableDebugging(debugSystemScreenMessage1, debugSystemScreenMessage2); rlm@1: } rlm@1: else if (_stricmp(argv[i], "-logToFile") == 0) rlm@1: { rlm@1: NESVideoSetFileFuncs(fopen, fclose); rlm@1: } rlm@1: else if (_stricmp(argv[i], "-outputWAV") == 0) rlm@1: { rlm@1: outputWavFile = true; rlm@1: if (i + 1 >= argc || argv[i + 1][0] == '-') rlm@1: goto invalidArgument; rlm@1: strcpy(wavFileToOutput, argv[++i]); rlm@1: } rlm@1: else if (_stricmp(argv[i], "-outputAVI") == 0) rlm@1: { rlm@1: outputAVIFile = true; rlm@1: } rlm@1: else if (_stricmp(argv[i], "-quitAfter") == 0) rlm@1: { rlm@1: if (i + 1 >= argc || argv[i + 1][0] == '-') rlm@1: goto invalidArgument; rlm@1: quitAfterTime = atoi(argv[++i]); rlm@1: } rlm@1: else if (_stricmp(argv[i], "-pauseAt") == 0) rlm@1: { rlm@1: if (i + 1 >= argc || argv[i + 1][0] == '-') rlm@1: goto invalidArgument; rlm@1: pauseAfterTime = atoi(argv[++i]); rlm@1: } rlm@1: else if (_stricmp(argv[i], "-videoScale") == 0) rlm@1: { rlm@1: if (i + 1 >= argc || argv[i + 1][0] == '-') rlm@1: goto invalidArgument; rlm@1: int size = atoi(argv[++i]); rlm@1: if (size < 1) rlm@1: size = 1; rlm@1: if (size > 4) rlm@1: size = 4; rlm@1: switch (size) rlm@1: { rlm@1: case 1: rlm@1: videoOption = VIDEO_1X; break; rlm@1: case 2: rlm@1: videoOption = VIDEO_2X; break; rlm@1: case 3: rlm@1: videoOption = VIDEO_3X; break; rlm@1: case 4: rlm@1: videoOption = VIDEO_4X; break; rlm@1: } rlm@1: } rlm@1: else if (_stricmp(argv[i], "-hideMenu") == 0) rlm@1: { rlm@1: flagHideMenu = true; rlm@1: } rlm@1: else rlm@1: { rlm@1: enoughArgs = true; rlm@1: invalidArgument: rlm@1: char str [2048]; // the string is larger than 1024 bytes rlm@1: strcpy(str, ""); rlm@1: if (_stricmp(argv[i], "-h") != 0) rlm@1: if (enoughArgs) rlm@1: sprintf(str, "Invalid commandline argument %d: %s\n", i, argv[i]); rlm@1: else rlm@1: sprintf(str, "Not enough arguments for arg %d: %s\n", i, argv[i]); rlm@1: strcat(str, "Valid commands:\n" rlm@1: "-h \t\t\t displays this help\n" rlm@1: "-rom filename \t\t opens the given ROM\n" rlm@1: "-bios filename \t\t use the given GBA BIOS\n" rlm@1: "-play filename val \t\t plays the given VBM movie (val: 1 = read-only, 0 = editable)\n" rlm@1: "-outputWAV filename \t outputs WAV audio to the given file\n" rlm@1: "-outputAVI \t\t outputs an AVI (you are prompted for location and codec)\n" rlm@1: "-frameskip val \t\t sets the frameskip amount to the given value\n" rlm@1: "-synchronize val \t\t limits running speed to sound playing speed, (0 = off, 1 = on)\n" rlm@1: "-throttle val \t\t sets the throttle speed to the given percentage\n" rlm@1: "-hideborder val \t\t hides SGB border, if any (0 = show, 1 = hide)\n" rlm@1: "-throttleKeepPitch val \t if throttle and synch, don't change sound freq (0 = off, 1 = on)\n" rlm@1: "-quitAfter val \t\t close program when frame counter == val\n" rlm@1: "-pauseAt val \t\t pause (movie) once when frame counter == val\n" rlm@1: "-videoScale val \t\t sets the video size (val = 1 for 1X, 2 for 2X, 3 for 3X, or 4 for 4X)\n" rlm@1: "-hideMenu \t\t hides the menu until program exit\n" rlm@1: "\n" rlm@1: "-videoLog args \t does (nesvideos) video+audio logging with the given arguments\n" rlm@1: "-logToFile \t tells logging to use fopen/fclose of args, if logging is enabled\n" rlm@1: "-logDebug \t tells logging to output debug info to screen, if logging is enabled\n" rlm@1: ); rlm@1: theApp.winCheckFullscreen(); rlm@1: AfxGetApp()->m_pMainWnd->MessageBox(str, "Commandline Help", MB_OK | MB_ICONINFORMATION); rlm@1: exit(0); rlm@1: } rlm@1: } rlm@1: else rlm@1: { rlm@1: // assume anything else is a ROM, for backward compatibility rlm@1: romFilename = argv[i++]; rlm@1: gameFilename = romFilename; rlm@1: loadSettings(); rlm@1: } rlm@1: } rlm@1: rlm@1: /* rlm@1: int index = filename.ReverseFind('.'); rlm@1: rlm@1: if (index != -1) rlm@1: filename = filename.Left(index); rlm@1: */ rlm@1: if (romFilename.GetLength() > 0) rlm@1: { rlm@1: ((MainWnd *)theApp.m_pMainWnd)->winFileRun(); rlm@1: } rlm@1: free(argv); rlm@1: } rlm@1: rlm@1: return TRUE; rlm@1: } rlm@1: rlm@1: void VBA::adjustDestRect() rlm@1: { rlm@1: POINT point; rlm@1: rlm@1: point.x = 0; rlm@1: point.y = 0; rlm@1: rlm@1: m_pMainWnd->ClientToScreen(&point); rlm@1: dest.top = point.y; rlm@1: dest.left = point.x; rlm@1: rlm@1: point.x = surfaceSizeX; rlm@1: point.y = surfaceSizeY; rlm@1: rlm@1: m_pMainWnd->ClientToScreen(&point); rlm@1: dest.bottom = point.y; rlm@1: dest.right = point.x; rlm@1: rlm@1: if (videoOption > VIDEO_4X) rlm@1: { rlm@1: int menuSkip = 0; rlm@1: if (menuToggle) rlm@1: { rlm@1: menuSkip = winGetMenuBarHeight(); rlm@1: } rlm@1: rlm@1: if (fullScreenStretch) rlm@1: { rlm@1: dest.top = menuSkip; rlm@1: dest.left = 0; rlm@1: dest.right = fsWidth; rlm@1: dest.bottom = fsHeight; rlm@1: } rlm@1: else rlm@1: { rlm@1: int top = (fsHeight - surfaceSizeY) / 2; rlm@1: int left = (fsWidth - surfaceSizeX) / 2; rlm@1: dest.top += top - menuSkip * 2; rlm@1: dest.bottom += top; rlm@1: dest.left += left; rlm@1: dest.right += left; rlm@1: } rlm@1: } rlm@1: } rlm@1: rlm@1: void VBA::updateIFB() rlm@1: { rlm@1: if (systemColorDepth == 16) rlm@1: { rlm@1: switch (ifbType) rlm@1: { rlm@1: case 0: rlm@1: default: rlm@1: ifbFunction = NULL; rlm@1: break; rlm@1: case 1: rlm@1: ifbFunction = MotionBlurIB; rlm@1: break; rlm@1: case 2: rlm@1: ifbFunction = SmartIB; rlm@1: break; rlm@1: } rlm@1: } rlm@1: else if (systemColorDepth == 32) rlm@1: { rlm@1: switch (ifbType) rlm@1: { rlm@1: case 0: rlm@1: default: rlm@1: ifbFunction = NULL; rlm@1: break; rlm@1: case 1: rlm@1: ifbFunction = MotionBlurIB32; rlm@1: break; rlm@1: case 2: rlm@1: ifbFunction = SmartIB32; rlm@1: break; rlm@1: } rlm@1: } rlm@1: else rlm@1: ifbFunction = NULL; rlm@1: } rlm@1: rlm@1: void VBA::updateFilter() rlm@1: { rlm@1: filterWidth = sizeX; rlm@1: filterHeight = sizeY; rlm@1: rlm@1: if (systemColorDepth == 16 && (videoOption > VIDEO_1X && rlm@1: videoOption != VIDEO_320x240)) rlm@1: { rlm@1: switch (filterType) rlm@1: { rlm@1: default: rlm@1: case 0: rlm@1: filterFunction = NULL; rlm@1: break; rlm@1: case 1: rlm@1: filterFunction = ScanlinesTV; rlm@1: break; rlm@1: case 2: rlm@1: filterFunction = _2xSaI; rlm@1: break; rlm@1: case 3: rlm@1: filterFunction = Super2xSaI; rlm@1: break; rlm@1: case 4: rlm@1: filterFunction = SuperEagle; rlm@1: break; rlm@1: case 5: rlm@1: filterFunction = Pixelate2x16; rlm@1: break; rlm@1: case 6: rlm@1: filterFunction = MotionBlur; rlm@1: break; rlm@1: case 7: rlm@1: filterFunction = AdMame2x; rlm@1: break; rlm@1: case 8: rlm@1: filterFunction = Simple2x16; rlm@1: break; rlm@1: case 9: rlm@1: filterFunction = Bilinear; rlm@1: break; rlm@1: case 10: rlm@1: filterFunction = BilinearPlus; rlm@1: break; rlm@1: case 11: rlm@1: filterFunction = Scanlines; rlm@1: break; rlm@1: case 12: rlm@1: filterFunction = hq2xS; rlm@1: break; rlm@1: case 13: rlm@1: filterFunction = hq2x; rlm@1: break; rlm@1: case 14: rlm@1: filterFunction = lq2x; rlm@1: break; rlm@1: case 15: rlm@1: filterFunction = hq3xS; rlm@1: break; rlm@1: case 16: rlm@1: filterFunction = hq3x; rlm@1: break; rlm@1: case 17: rlm@1: filterFunction = Simple3x16; rlm@1: break; rlm@1: case 18: rlm@1: filterFunction = Simple4x16; rlm@1: break; rlm@1: case 19: rlm@1: filterFunction = Pixelate3x16; rlm@1: break; rlm@1: case 20: rlm@1: filterFunction = Pixelate4x16; rlm@1: break; rlm@1: } rlm@1: switch (filterType) rlm@1: { rlm@1: case 0: // normal -> 1x texture rlm@1: rect.right = sizeX; rlm@1: rect.bottom = sizeY; rlm@1: break; rlm@1: default: // other -> 2x texture rlm@1: rect.right = sizeX * 2; rlm@1: rect.bottom = sizeY * 2; rlm@1: memset(delta, 255, sizeof(delta)); rlm@1: break; rlm@1: case 15: // hq3x -> 3x texture rlm@1: case 16: rlm@1: case 17: rlm@1: case 19: rlm@1: rect.right = sizeX * 3; rlm@1: rect.bottom = sizeY * 3; rlm@1: memset(delta, 255, sizeof(delta)); rlm@1: break; rlm@1: case 18: // Simple4x -> 4x texture rlm@1: case 20: rlm@1: rect.right = sizeX * 4; rlm@1: rect.bottom = sizeY * 4; rlm@1: memset(delta, 255, sizeof(delta)); rlm@1: break; rlm@1: } rlm@1: } rlm@1: else rlm@1: { rlm@1: if (systemColorDepth == 32 && videoOption > VIDEO_1X && rlm@1: videoOption != VIDEO_320x240) rlm@1: { rlm@1: switch (filterType) rlm@1: { rlm@1: default: rlm@1: case 0: rlm@1: filterFunction = NULL; rlm@1: break; rlm@1: case 1: rlm@1: filterFunction = ScanlinesTV32; rlm@1: break; rlm@1: case 2: rlm@1: filterFunction = _2xSaI32; rlm@1: break; rlm@1: case 3: rlm@1: filterFunction = Super2xSaI32; rlm@1: break; rlm@1: case 4: rlm@1: filterFunction = SuperEagle32; rlm@1: break; rlm@1: case 5: rlm@1: filterFunction = Pixelate2x32; rlm@1: break; rlm@1: case 6: rlm@1: filterFunction = MotionBlur32; rlm@1: break; rlm@1: case 7: rlm@1: filterFunction = AdMame2x32; rlm@1: break; rlm@1: case 8: rlm@1: filterFunction = Simple2x32; rlm@1: break; rlm@1: case 9: rlm@1: filterFunction = Bilinear32; rlm@1: break; rlm@1: case 10: rlm@1: filterFunction = BilinearPlus32; rlm@1: break; rlm@1: case 11: rlm@1: filterFunction = Scanlines32; rlm@1: break; rlm@1: case 12: rlm@1: filterFunction = hq2xS32; rlm@1: break; rlm@1: case 13: rlm@1: filterFunction = hq2x32; rlm@1: break; rlm@1: case 14: rlm@1: filterFunction = lq2x32; rlm@1: break; rlm@1: case 15: rlm@1: filterFunction = hq3xS32; rlm@1: break; rlm@1: case 16: rlm@1: filterFunction = hq3x32; rlm@1: break; rlm@1: case 17: rlm@1: filterFunction = Simple3x32; rlm@1: break; rlm@1: case 18: rlm@1: filterFunction = Simple4x32; rlm@1: break; rlm@1: case 19: rlm@1: filterFunction = Pixelate3x32; rlm@1: break; rlm@1: case 20: rlm@1: filterFunction = Pixelate4x32; rlm@1: break; rlm@1: } rlm@1: switch (filterType) rlm@1: { rlm@1: case 0: // normal -> 1x texture rlm@1: rect.right = sizeX; rlm@1: rect.bottom = sizeY; rlm@1: break; rlm@1: default: // other -> 2x texture rlm@1: rect.right = sizeX * 2; rlm@1: rect.bottom = sizeY * 2; rlm@1: memset(delta, 255, sizeof(delta)); rlm@1: break; rlm@1: case 15: // hq3x -> 3x texture rlm@1: case 16: rlm@1: case 17: rlm@1: case 19: rlm@1: rect.right = sizeX * 3; rlm@1: rect.bottom = sizeY * 3; rlm@1: memset(delta, 255, sizeof(delta)); rlm@1: break; rlm@1: case 18: // Simple4x -> 4x texture rlm@1: case 20: rlm@1: rect.right = sizeX * 4; rlm@1: rect.bottom = sizeY * 4; rlm@1: memset(delta, 255, sizeof(delta)); rlm@1: break; rlm@1: } rlm@1: } rlm@1: else rlm@1: filterFunction = NULL; rlm@1: } rlm@1: rlm@1: if (display) rlm@1: display->changeRenderSize(rect.right, rect.bottom); rlm@1: } rlm@1: rlm@1: void VBA::recreateMenuBar() rlm@1: { rlm@1: m_menu.Detach(); rlm@1: m_menu.Attach(winResLoadMenu(MAKEINTRESOURCE(IDR_MENU))); rlm@1: rlm@1: if (m_pMainWnd && menuToggle) // assuming that whether the menu has been set is always kept tracked rlm@1: { rlm@1: m_pMainWnd->SetMenu(&m_menu); rlm@1: } rlm@1: rlm@1: if (menu != NULL) rlm@1: { rlm@1: DestroyMenu(menu); rlm@1: } rlm@1: rlm@1: menu = m_menu.GetSafeHmenu(); rlm@1: } rlm@1: rlm@1: void VBA::updateMenuBar() rlm@1: { rlm@1: if (flagHideMenu) rlm@1: return; rlm@1: rlm@1: recreateMenuBar(); rlm@1: rlm@1: if (popup != NULL) rlm@1: { rlm@1: // force popup recreation if language changed rlm@1: DestroyMenu(popup); rlm@1: popup = NULL; rlm@1: } rlm@1: } rlm@1: rlm@1: void VBA::saveRewindStateIfNecessary() rlm@1: { rlm@1: if (rewindSaveNeeded && rewindMemory && emulator.emuWriteMemState) rlm@1: { rlm@1: rewindCount++; rlm@1: if (rewindCount > rewindSlots) rlm@1: rewindCount = rewindSlots; rlm@1: assert(rewindPos >= 0 && rewindPos < rewindSlots); rlm@1: if (emulator.emuWriteMemState(&rewindMemory[rewindPos * REWIND_SIZE], REWIND_SIZE)) rlm@1: { rlm@1: rewindPos = ++rewindPos % rewindSlots; rlm@1: assert(rewindPos >= 0 && rewindPos < rewindSlots); rlm@1: if (rewindCount == rewindSlots) rlm@1: rewindTopPos = ++rewindTopPos % rewindSlots; rlm@1: } rlm@1: } rlm@1: rlm@1: // also update/cache some frame search stuff rlm@1: if (frameSearching) rlm@1: { rlm@1: extern SMovie Movie; rlm@1: int curFrame = (Movie.state == MOVIE_STATE_NONE) ? systemCounters.frameCount : Movie.currentFrame; rlm@1: int endFrame = theApp.frameSearchStart + theApp.frameSearchLength; rlm@1: frameSearchSkipping = (curFrame < endFrame); rlm@1: frameSearchFirstStep = false; rlm@1: rlm@1: if (curFrame == endFrame) rlm@1: { rlm@1: // cache intermediate state to speed up searching forward rlm@1: emulator.emuWriteMemState(&frameSearchMemory[REWIND_SIZE * 1], REWIND_SIZE); rlm@1: } rlm@1: rlm@1: if (curFrame == endFrame + 1) rlm@1: { rlm@1: emulator.emuWriteMemState(&frameSearchMemory[REWIND_SIZE * 2], REWIND_SIZE); rlm@1: frameSearchLoadValid = true; rlm@1: } rlm@1: } rlm@1: else rlm@1: { rlm@1: frameSearchFirstStep = false; rlm@1: rlm@1: assert(!frameSearchSkipping); rlm@1: // just in case rlm@1: frameSearchSkipping = false; rlm@1: } rlm@1: } rlm@1: rlm@1: BOOL VBA::OnIdle(LONG lCount) rlm@1: { rlm@1: if (emulating && debugger) rlm@1: { rlm@1: MSG msg; rlm@1: remoteStubMain(); rlm@1: if (debugger) rlm@1: return TRUE; // continue loop rlm@1: return !::PeekMessage(&msg, NULL, NULL, NULL, PM_NOREMOVE); rlm@1: } rlm@1: else if (emulating && active && !paused) rlm@1: { rlm@1: /// for(int i = 0; i < 2; i++) rlm@1: { rlm@1: emulator.emuMain(emulator.emuCount); rlm@1: rlm@1: // save the state for rewinding, if necessary rlm@1: saveRewindStateIfNecessary(); rlm@1: rlm@1: rewindSaveNeeded = false; rlm@1: } rlm@1: rlm@1: if (mouseCounter) rlm@1: { rlm@1: if (--mouseCounter == 0) rlm@1: { rlm@1: SetCursor(NULL); rlm@1: } rlm@1: } rlm@1: return TRUE; rlm@1: } rlm@1: else if (emulating) // this fixes display if resetting while paused rlm@1: { rlm@1: // VBAUpdateButtonPressDisplay(); rlm@1: VBAUpdateFrameCountDisplay(); rlm@1: systemRefreshScreen(); rlm@1: } rlm@1: rlm@1: return FALSE; rlm@1: rlm@1: // return CWinApp::OnIdle(lCount); rlm@1: } rlm@1: rlm@1: void VBA::addRecentFile(const CString &file) rlm@1: { rlm@1: // Do not change recent list if frozen rlm@1: if (recentFreeze) rlm@1: return; rlm@1: int i = 0; rlm@1: for (i = 0; i < 10; ++i) rlm@1: { rlm@1: if (recentFiles[i].GetLength() == 0) rlm@1: break; rlm@1: rlm@1: if (recentFiles[i].Compare(file) == 0) rlm@1: { rlm@1: if (i == 0) rlm@1: return; rlm@1: CString p = recentFiles[i]; rlm@1: for (int j = i; j > 0; --j) rlm@1: { rlm@1: recentFiles[j] = recentFiles[j - 1]; rlm@1: } rlm@1: recentFiles[0] = p; rlm@1: return; rlm@1: } rlm@1: } rlm@1: int num = 0; rlm@1: for (i = 0; i < 10; ++i) rlm@1: { rlm@1: if (recentFiles[i].GetLength() != 0) rlm@1: ++num; rlm@1: } rlm@1: if (num == 10) rlm@1: { rlm@1: --num; rlm@1: } rlm@1: rlm@1: for (i = num; i >= 1; --i) rlm@1: { rlm@1: recentFiles[i] = recentFiles[i - 1]; rlm@1: } rlm@1: recentFiles[0] = file; rlm@1: } rlm@1: rlm@1: void VBA::updateFrameSkip() rlm@1: { rlm@1: switch (systemCartridgeType) rlm@1: { rlm@1: case 0: rlm@1: systemFrameSkip = frameSkip; rlm@1: break; rlm@1: case 1: rlm@1: systemFrameSkip = gbFrameSkip; rlm@1: break; rlm@1: } rlm@1: } rlm@1: rlm@1: void VBA::updateVideoSize(UINT id) rlm@1: { rlm@1: int value = 0; rlm@1: bool forceUpdate = false; rlm@1: rlm@1: switch (id) rlm@1: { rlm@1: case ID_OPTIONS_VIDEO_X1: rlm@1: value = VIDEO_1X; rlm@1: forceUpdate = true; rlm@1: break; rlm@1: case ID_OPTIONS_VIDEO_X2: rlm@1: value = VIDEO_2X; rlm@1: forceUpdate = true; rlm@1: break; rlm@1: case ID_OPTIONS_VIDEO_X3: rlm@1: value = VIDEO_3X; rlm@1: forceUpdate = true; rlm@1: break; rlm@1: case ID_OPTIONS_VIDEO_X4: rlm@1: value = VIDEO_4X; rlm@1: forceUpdate = true; rlm@1: break; rlm@1: case ID_OPTIONS_VIDEO_FULLSCREEN320X240: rlm@1: value = VIDEO_320x240; rlm@1: fsWidth = 320; rlm@1: fsHeight = 240; rlm@1: fsColorDepth = 16; rlm@1: break; rlm@1: case ID_OPTIONS_VIDEO_FULLSCREEN640X480: rlm@1: value = VIDEO_640x480; rlm@1: fsWidth = 640; rlm@1: fsHeight = 480; rlm@1: fsColorDepth = 16; rlm@1: break; rlm@1: case ID_OPTIONS_VIDEO_FULLSCREEN800X600: rlm@1: value = VIDEO_800x600; rlm@1: fsWidth = 800; rlm@1: fsHeight = 600; rlm@1: fsColorDepth = 16; rlm@1: break; rlm@1: case ID_OPTIONS_VIDEO_FULLSCREEN: rlm@1: value = VIDEO_OTHER; rlm@1: forceUpdate = true; rlm@1: break; rlm@1: } rlm@1: rlm@1: if (videoOption != value || forceUpdate) rlm@1: updateWindowSize(value); rlm@1: } rlm@1: rlm@1: void VBA::updateWindowSize(int value) rlm@1: { rlm@1: regSetDwordValue("video", value); rlm@1: rlm@1: if (value == VIDEO_OTHER) rlm@1: { rlm@1: regSetDwordValue("fsWidth", fsWidth); rlm@1: regSetDwordValue("fsHeight", fsHeight); rlm@1: regSetDwordValue("fsColorDepth", fsColorDepth); rlm@1: } rlm@1: rlm@1: if (display && rlm@1: (((value >= VIDEO_320x240 || videoOption >= VIDEO_320x240) && videoOption != value) || rlm@1: fsForceChange)) rlm@1: { rlm@1: fsForceChange = false; rlm@1: videoOption = value; rlm@1: initDisplay(); rlm@1: } rlm@1: rlm@1: videoOption = value; rlm@1: rlm@1: if (systemCartridgeType == 1) rlm@1: { rlm@1: if (gbBorderOn) rlm@1: { rlm@1: sizeX = 256; rlm@1: sizeY = 224; rlm@1: gbBorderLineSkip = 256; rlm@1: gbBorderColumnSkip = 48; rlm@1: gbBorderRowSkip = 40; rlm@1: } rlm@1: else rlm@1: { rlm@1: sizeX = 160; rlm@1: sizeY = 144; rlm@1: gbBorderLineSkip = 160; rlm@1: gbBorderColumnSkip = 0; rlm@1: gbBorderRowSkip = 0; rlm@1: } rlm@1: } rlm@1: else rlm@1: { rlm@1: sizeX = 240; rlm@1: sizeY = 160; rlm@1: } rlm@1: rlm@1: switch (videoOption) rlm@1: { rlm@1: case VIDEO_1X: rlm@1: surfaceSizeX = sizeX; rlm@1: surfaceSizeY = sizeY; rlm@1: break; rlm@1: case VIDEO_2X: rlm@1: surfaceSizeX = sizeX * 2; rlm@1: surfaceSizeY = sizeY * 2; rlm@1: break; rlm@1: case VIDEO_3X: rlm@1: surfaceSizeX = sizeX * 3; rlm@1: surfaceSizeY = sizeY * 3; rlm@1: break; rlm@1: case VIDEO_4X: rlm@1: surfaceSizeX = sizeX * 4; rlm@1: surfaceSizeY = sizeY * 4; rlm@1: break; rlm@1: case VIDEO_320x240: rlm@1: case VIDEO_640x480: rlm@1: case VIDEO_800x600: rlm@1: case VIDEO_OTHER: rlm@1: // Need to fix this code later. For now, Fullscreen takes the whole screen. rlm@1: if (fullScreenStretch) rlm@1: { rlm@1: surfaceSizeX = fsWidth; rlm@1: surfaceSizeY = fsHeight; rlm@1: } rlm@1: else rlm@1: { rlm@1: double scaleX = (double)fsWidth / (double)sizeX; rlm@1: double scaleY = (double)fsHeight / (double)sizeY; rlm@1: double scaleMin = scaleX < scaleY ? scaleX : scaleY; rlm@1: if (fsMaxScale) rlm@1: scaleMin = scaleMin > fsMaxScale ? fsMaxScale : scaleMin; rlm@1: surfaceSizeX = (int)(scaleMin * sizeX); rlm@1: surfaceSizeY = (int)(scaleMin * sizeY); rlm@1: } rlm@1: break; rlm@1: } rlm@1: rlm@1: rect.left = 0; rlm@1: rect.top = 0; rlm@1: rect.right = sizeX; rlm@1: rect.bottom = sizeY; rlm@1: rlm@1: int winSizeX = 0; rlm@1: int winSizeY = 0; rlm@1: int x = 0; rlm@1: int y = 0; rlm@1: rlm@1: DWORD style = WS_POPUP | WS_VISIBLE; rlm@1: DWORD styleEx = alwaysOnTop ? WS_EX_TOPMOST : 0; rlm@1: rlm@1: if (videoOption <= VIDEO_4X) rlm@1: { rlm@1: style |= WS_OVERLAPPEDWINDOW; rlm@1: rlm@1: dest.left = 0; rlm@1: dest.top = 0; rlm@1: dest.right = surfaceSizeX; rlm@1: dest.bottom = surfaceSizeY; rlm@1: rlm@1: x = windowPositionX; rlm@1: y = windowPositionY; rlm@1: } rlm@1: else rlm@1: { rlm@1: dest.left = 0; rlm@1: dest.top = 0; rlm@1: dest.right = fsWidth; rlm@1: dest.bottom = fsHeight; rlm@1: } rlm@1: rlm@1: AdjustWindowRectEx(&dest, style, flagHideMenu ? FALSE : TRUE, styleEx); rlm@1: winSizeX = dest.right - dest.left; rlm@1: winSizeY = dest.bottom - dest.top; rlm@1: rlm@1: if (m_pMainWnd == NULL) rlm@1: { rlm@1: // Create a new window rlm@1: m_pMainWnd = new MainWnd; rlm@1: m_pMainWnd->CreateEx(styleEx, rlm@1: theApp.wndClass, rlm@1: VBA_NAME_AND_VERSION, rlm@1: style, rlm@1: x, y, winSizeX, winSizeY, rlm@1: NULL, rlm@1: 0); rlm@1: rlm@1: if (!(HWND)*m_pMainWnd) rlm@1: { rlm@1: winlog("Error creating Window %08x\n", GetLastError()); rlm@1: AfxPostQuitMessage(0); rlm@1: return; rlm@1: } rlm@1: } rlm@1: else rlm@1: { rlm@1: m_pMainWnd->SetWindowPos(0, //HWND_TOPMOST, rlm@1: x, rlm@1: y, rlm@1: winSizeX, rlm@1: winSizeY, rlm@1: SWP_NOMOVE | SWP_SHOWWINDOW); rlm@1: } rlm@1: rlm@1: updateMenuBar(); // add menubar first of all, or winGetMenuBarHeight() will get random height. rlm@1: winAccelMgr.UpdateMenu(menu); rlm@1: adjustDestRect(); rlm@1: rlm@1: updateIFB(); rlm@1: updateFilter(); rlm@1: rlm@1: m_pMainWnd->RedrawWindow(NULL, NULL, RDW_INVALIDATE | RDW_ERASE | RDW_ALLCHILDREN); rlm@1: } rlm@1: rlm@1: bool VBA::initDisplay() rlm@1: { rlm@1: if (display) rlm@1: { rlm@1: changingVideoSize = true; rlm@1: shutdownDisplay(); rlm@1: if (input) rlm@1: { rlm@1: delete input; rlm@1: input = NULL; rlm@1: } rlm@1: CWnd *pWnd = m_pMainWnd; rlm@1: rlm@1: m_pMainWnd = NULL; rlm@1: pWnd->DragAcceptFiles(FALSE); rlm@1: pWnd->DestroyWindow(); rlm@1: delete pWnd; rlm@1: rlm@1: display = NULL; rlm@1: } rlm@1: rlm@1: if (display == NULL) rlm@1: { rlm@1: updateWindowSize(videoOption); rlm@1: rlm@1: switch (renderMethod) rlm@1: { rlm@1: case GDI: rlm@1: display = newGDIDisplay(); rlm@1: break; rlm@1: case DIRECT_DRAW: rlm@1: display = newDirectDrawDisplay(); rlm@1: break; rlm@1: case DIRECT_3D: rlm@1: display = newDirect3DDisplay(); rlm@1: break; rlm@1: case OPENGL: rlm@1: display = newOpenGLDisplay(); rlm@1: break; rlm@1: } rlm@1: rlm@1: if (display->initialize()) rlm@1: { rlm@1: if (input == NULL) rlm@1: { rlm@1: if (!initInput()) rlm@1: { rlm@1: changingVideoSize = false; rlm@1: AfxPostQuitMessage(0); rlm@1: return false; rlm@1: } rlm@1: } rlm@1: rlm@1: input->checkKeys(); rlm@1: rlm@1: changingVideoSize = false; rlm@1: } rlm@1: else rlm@1: { rlm@1: if (videoOption == VIDEO_320x240 || rlm@1: videoOption == VIDEO_640x480 || rlm@1: videoOption == VIDEO_800x600 || rlm@1: videoOption == VIDEO_OTHER) rlm@1: { rlm@1: regSetDwordValue("video", VIDEO_1X); rlm@1: if (pVideoDriverGUID) rlm@1: regSetDwordValue("defaultVideoDriver", TRUE); rlm@1: } rlm@1: changingVideoSize = false; rlm@1: return false; rlm@1: } rlm@1: } rlm@1: changingVideoSize = false; rlm@1: return true; rlm@1: } rlm@1: rlm@1: bool VBA::updateRenderMethod(bool force) rlm@1: { rlm@1: bool res = true; rlm@1: if (force || (display && display->getType() != renderMethod)) rlm@1: { rlm@1: res = initDisplay(); rlm@1: rlm@1: while (!res && renderMethod > 0) rlm@1: { rlm@1: if (renderMethod == OPENGL) rlm@1: renderMethod = DIRECT_3D; rlm@1: else if (renderMethod == DIRECT_3D) rlm@1: renderMethod = DIRECT_DRAW; rlm@1: else if (renderMethod == DIRECT_DRAW) rlm@1: renderMethod = GDI; rlm@1: rlm@1: res = initDisplay(); rlm@1: } rlm@1: } rlm@1: rlm@1: updateIFB(); rlm@1: updateFilter(); rlm@1: rlm@1: m_pMainWnd->RedrawWindow(NULL, NULL, RDW_INVALIDATE | RDW_ERASE | RDW_ALLCHILDREN); rlm@1: rlm@1: regSetDwordValue("renderMethod", renderMethod); rlm@1: rlm@1: return res; rlm@1: } rlm@1: rlm@1: void VBA::winCheckFullscreen() rlm@1: { rlm@1: if (videoOption > VIDEO_4X && tripleBuffering) rlm@1: { rlm@1: if (display) rlm@1: display->checkFullScreen(); rlm@1: } rlm@1: } rlm@1: rlm@1: void VBA::shutdownDisplay() rlm@1: { rlm@1: if (display != NULL) rlm@1: { rlm@1: display->cleanup(); rlm@1: delete display; rlm@1: display = NULL; rlm@1: } rlm@1: } rlm@1: rlm@1: void VBA::updatePriority() rlm@1: { rlm@1: switch (threadPriority) rlm@1: { rlm@1: case 0: rlm@1: SetThreadPriority(THREAD_PRIORITY_HIGHEST); rlm@1: break; rlm@1: case 1: rlm@1: SetThreadPriority(THREAD_PRIORITY_ABOVE_NORMAL); rlm@1: break; rlm@1: case 3: rlm@1: SetThreadPriority(THREAD_PRIORITY_BELOW_NORMAL); rlm@1: break; rlm@1: default: rlm@1: SetThreadPriority(THREAD_PRIORITY_NORMAL); rlm@1: } rlm@1: } rlm@1: rlm@1: #ifdef MMX rlm@1: bool VBA::detectMMX() rlm@1: { rlm@1: bool support = false; rlm@1: char brand[13]; rlm@1: rlm@1: // check for Intel chip rlm@1: __try { rlm@1: __asm { rlm@1: mov eax, 0; rlm@1: cpuid; rlm@1: mov [dword ptr brand + 0], ebx; rlm@1: mov [dword ptr brand + 4], edx; rlm@1: mov [dword ptr brand + 8], ecx; rlm@1: } rlm@1: } rlm@1: __except(EXCEPTION_EXECUTE_HANDLER) { rlm@1: if (_exception_code() == STATUS_ILLEGAL_INSTRUCTION) rlm@1: { rlm@1: return false; rlm@1: } rlm@1: return false; rlm@1: } rlm@1: // Check for Intel or AMD CPUs rlm@1: if (strncmp(brand, "GenuineIntel", 12)) rlm@1: { rlm@1: if (strncmp(brand, "AuthenticAMD", 12)) rlm@1: { rlm@1: return false; rlm@1: } rlm@1: } rlm@1: rlm@1: __asm { rlm@1: mov eax, 1; rlm@1: cpuid; rlm@1: test edx, 00800000h; rlm@1: jz NotFound; rlm@1: mov [support], 1; rlm@1: NotFound: rlm@1: } rlm@1: return support; rlm@1: } rlm@1: rlm@1: #endif rlm@1: rlm@1: void VBA::winSetLanguageOption(int option, bool force) rlm@1: { rlm@1: if (((option == languageOption) && option != 2) && !force) rlm@1: return; rlm@1: switch (option) rlm@1: { rlm@1: case 0: rlm@1: { rlm@1: char lbuffer[10]; rlm@1: rlm@1: if (GetLocaleInfo(LOCALE_SYSTEM_DEFAULT, LOCALE_SABBREVLANGNAME, rlm@1: lbuffer, 10)) rlm@1: { rlm@1: HINSTANCE l = winLoadLanguage(lbuffer); rlm@1: if (l == NULL) rlm@1: { rlm@1: LCID locIdBase = MAKELCID(MAKELANGID(PRIMARYLANGID(GetSystemDefaultLangID()), SUBLANG_NEUTRAL), SORT_DEFAULT); rlm@1: if (GetLocaleInfo(locIdBase, LOCALE_SABBREVLANGNAME, rlm@1: lbuffer, 10)) rlm@1: { rlm@1: l = winLoadLanguage(lbuffer); rlm@1: if (l == NULL) rlm@1: { rlm@1: systemMessage(IDS_FAILED_TO_LOAD_LIBRARY, rlm@1: "Failed to load library %s", rlm@1: lbuffer); rlm@1: return; rlm@1: } rlm@1: } rlm@1: } rlm@1: AfxSetResourceHandle(l); rlm@1: if (languageModule != NULL) rlm@1: /**/ ::FreeLibrary(languageModule); rlm@1: languageModule = l; rlm@1: } rlm@1: else rlm@1: { rlm@1: systemMessage(IDS_FAILED_TO_GET_LOCINFO, rlm@1: "Failed to get locale information"); rlm@1: return; rlm@1: } rlm@1: break; rlm@1: } rlm@1: case 1: rlm@1: if (languageModule != NULL) rlm@1: /**/ ::FreeLibrary(languageModule); rlm@1: languageModule = NULL; rlm@1: AfxSetResourceHandle(AfxGetInstanceHandle()); rlm@1: break; rlm@1: case 2: rlm@1: { rlm@1: if (!force) rlm@1: { rlm@1: LangSelect dlg; rlm@1: if (dlg.DoModal()) rlm@1: { rlm@1: HINSTANCE l = winLoadLanguage(languageName); rlm@1: if (l == NULL) rlm@1: { rlm@1: systemMessage(IDS_FAILED_TO_LOAD_LIBRARY, rlm@1: "Failed to load library %s", rlm@1: languageName); rlm@1: return; rlm@1: } rlm@1: AfxSetResourceHandle(l); rlm@1: if (languageModule != NULL) rlm@1: /**/ ::FreeLibrary(languageModule); rlm@1: languageModule = l; rlm@1: } rlm@1: } rlm@1: else rlm@1: { rlm@1: if (languageName.IsEmpty()) rlm@1: return; rlm@1: HINSTANCE l = winLoadLanguage(languageName); rlm@1: if (l == NULL) rlm@1: { rlm@1: systemMessage(IDS_FAILED_TO_LOAD_LIBRARY, rlm@1: "Failed to load library %s", rlm@1: languageName); rlm@1: return; rlm@1: } rlm@1: AfxSetResourceHandle(l); rlm@1: if (languageModule != NULL) rlm@1: FreeLibrary(languageModule); rlm@1: languageModule = l; rlm@1: } rlm@1: break; rlm@1: } rlm@1: } rlm@1: languageOption = option; rlm@1: updateMenuBar(); rlm@1: theApp.winAccelMgr.UpdateMenu(theApp.menu); rlm@1: } rlm@1: rlm@1: HINSTANCE VBA::winLoadLanguage(const char *name) rlm@1: { rlm@1: CString buffer; rlm@1: rlm@1: buffer.Format("vba_%s.dll", name); rlm@1: rlm@1: HINSTANCE l = /**/ ::LoadLibrary(buffer); rlm@1: rlm@1: if (l == NULL) rlm@1: { rlm@1: if (strlen(name) == 3) rlm@1: { rlm@1: char buffer2[3]; rlm@1: buffer2[0] = name[0]; rlm@1: buffer2[1] = name[1]; rlm@1: buffer2[2] = 0; rlm@1: buffer.Format("vba_%s.dll", buffer2); rlm@1: rlm@1: return /**/ ::LoadLibrary(buffer); rlm@1: } rlm@1: } rlm@1: return l; rlm@1: } rlm@1: rlm@1: bool VBA::initInput() rlm@1: { rlm@1: if (input) rlm@1: delete input; rlm@1: input = newDirectInput(); rlm@1: if (input->initialize()) rlm@1: { rlm@1: input->loadSettings(); rlm@1: input->checkKeys(); rlm@1: return true; rlm@1: } rlm@1: delete input; rlm@1: return false; rlm@1: } rlm@1: rlm@1: void VBA::winAddUpdateListener(IUpdateListener *l) rlm@1: { rlm@1: updateList.AddTail(l); rlm@1: updateCount++; rlm@1: } rlm@1: rlm@1: void VBA::winRemoveUpdateListener(IUpdateListener *l) rlm@1: { rlm@1: POSITION pos = updateList.Find(l); rlm@1: if (pos) rlm@1: { rlm@1: updateList.RemoveAt(pos); rlm@1: updateCount--; rlm@1: if (updateCount < 0) rlm@1: updateCount = 0; rlm@1: } rlm@1: } rlm@1: rlm@1: void VBA::loadSettings() rlm@1: { rlm@1: CString buffer; rlm@1: // video rlm@1: bool defaultVideoDriver = regQueryDwordValue("defaultVideoDriver", true) ? true : false; rlm@1: if (!regQueryBinaryValue("videoDriverGUID", (char *)&videoDriverGUID, sizeof(GUID))) rlm@1: { rlm@1: defaultVideoDriver = TRUE; rlm@1: } rlm@1: if (defaultVideoDriver) rlm@1: pVideoDriverGUID = NULL; rlm@1: else rlm@1: pVideoDriverGUID = &videoDriverGUID; rlm@1: rlm@1: videoOption = regQueryDwordValue("video", 0); rlm@1: if (videoOption < 0 || videoOption > VIDEO_OTHER) rlm@1: videoOption = 0; rlm@1: switch (videoOption) rlm@1: { rlm@1: case VIDEO_320x240: rlm@1: fsWidth = 320; rlm@1: fsHeight = 240; rlm@1: fsColorDepth = 16; rlm@1: break; rlm@1: case VIDEO_640x480: rlm@1: fsWidth = 640; rlm@1: fsHeight = 480; rlm@1: fsColorDepth = 16; rlm@1: break; rlm@1: case VIDEO_800x600: rlm@1: fsWidth = 800; rlm@1: fsHeight = 600; rlm@1: fsColorDepth = 16; rlm@1: break; rlm@1: } rlm@1: if (videoOption == VIDEO_OTHER) rlm@1: { rlm@1: if (fsWidth < 0 || fsWidth > 4095 || fsHeight < 0 || fsHeight > 4095) rlm@1: videoOption = 0; rlm@1: if (fsColorDepth != 16 && fsColorDepth != 24 && fsColorDepth != 32) rlm@1: videoOption = 0; rlm@1: } rlm@1: rlm@1: fsWidth = regQueryDwordValue("fsWidth", 0); rlm@1: fsHeight = regQueryDwordValue("fsHeight", 0); rlm@1: fsColorDepth = regQueryDwordValue("fsColorDepth", 0); rlm@1: fsMaxScale = regQueryDwordValue("fsMaxScale", 0); rlm@1: fullScreenStretch = regQueryDwordValue("stretch", 0) ? true : false; rlm@1: rlm@1: renderMethod = (DISPLAY_TYPE)regQueryDwordValue("renderMethod", DIRECT_DRAW); rlm@1: if (renderMethod < GDI || renderMethod > OPENGL) rlm@1: renderMethod = DIRECT_DRAW; rlm@1: rlm@1: ddrawEmulationOnly = regQueryDwordValue("ddrawEmulationOnly", false) ? true : false; rlm@1: ddrawUseVideoMemory = regQueryDwordValue("ddrawUseVideoMemory", false) ? true : false; rlm@1: tripleBuffering = regQueryDwordValue("tripleBuffering", true) ? true : false; rlm@1: vsync = regQueryDwordValue("vsync", false) ? true : false; rlm@1: rlm@1: d3dFilter = regQueryDwordValue("d3dFilter", 0); rlm@1: if (d3dFilter < 0 || d3dFilter > 1) rlm@1: d3dFilter = 0; rlm@1: glFilter = regQueryDwordValue("glFilter", 0); rlm@1: if (glFilter < 0 || glFilter > 1) rlm@1: glFilter = 0; rlm@1: glType = regQueryDwordValue("glType", 0); rlm@1: if (glType < 0 || glType > 1) rlm@1: glType = 0; rlm@1: rlm@1: // pixel filter & ifb rlm@1: filterType = regQueryDwordValue("filter", 0); rlm@1: if (filterType < 0 || filterType > 20) rlm@1: filterType = 0; rlm@1: disableMMX = regQueryDwordValue("disableMMX", 0) ? true : false; rlm@1: ifbType = regQueryDwordValue("ifbType", 0); rlm@1: if (ifbType < 0 || ifbType > 2) rlm@1: ifbType = 0; rlm@1: rlm@1: // frame skipping rlm@1: frameSkip = regQueryDwordValue("frameSkip", /*2*/ 0); rlm@1: if (frameSkip < 0 || frameSkip > 9) rlm@1: frameSkip = 1; rlm@1: gbFrameSkip = regQueryDwordValue("gbFrameSkip", 0); rlm@1: if (gbFrameSkip < 0 || gbFrameSkip > 9) rlm@1: gbFrameSkip = 0; rlm@1: /// autoFrameSkip = regQueryDwordValue("autoFrameSkip", FALSE) ? TRUE : FALSE; rlm@1: rlm@1: // input rlm@1: joypadDefault = regQueryDwordValue("joypadDefault", 0); rlm@1: if (joypadDefault < 0 || joypadDefault > 3) rlm@1: joypadDefault = 0; rlm@1: allowLeftRight = regQueryDwordValue("allowLeftRight", false) ? true : false; rlm@1: autofireAccountForLag = regQueryDwordValue("autofireAccountForLag", false) ? true : false; rlm@1: nextframeAccountForLag = regQueryDwordValue("nextframeAccountForLag", false) ? true : false; rlm@1: theApp.AsscWithSaveState = regQueryDwordValue("AsscWithSaveState", false) ? true : false; rlm@1: rlm@1: // speed rlm@1: throttle = regQueryDwordValue("throttle", 0); rlm@1: if (throttle < 5 || throttle > 1000) rlm@1: throttle = 100; rlm@1: rlm@1: synchronize = regQueryDwordValue("synchronize", 1) ? true : false; rlm@1: accuratePitchThrottle = regQueryDwordValue("accuratePitchThrottle", FALSE) ? TRUE : FALSE; rlm@1: rlm@1: // sound rlm@1: int resChannels = regQueryDwordValue("soundEnable", 0x30f); rlm@1: soundEnableChannels(resChannels); rlm@1: soundDisableChannels(~resChannels); rlm@1: soundOffFlag = (regQueryDwordValue("soundOff", 0)) ? true : false; rlm@1: soundQuality = regQueryDwordValue("soundQuality", 2); rlm@1: soundEcho = regQueryDwordValue("soundEcho", 0) ? true : false; rlm@1: soundLowPass = regQueryDwordValue("soundLowPass", 0) ? true : false; rlm@1: soundReverse = regQueryDwordValue("soundReverse", 0) ? true : false; rlm@1: soundVolume = regQueryDwordValue("soundVolume", 0); rlm@1: if (soundVolume < 0 || soundVolume > 5) rlm@1: soundVolume = 0; rlm@1: muteFrameAdvance = regQueryDwordValue("muteFrameAdvance", 0) ? TRUE : FALSE; rlm@1: muteWhenInactive = regQueryDwordValue("muteWhenInactive", 0) ? TRUE : FALSE; rlm@1: rlm@1: // emulation rlm@1: memLagEnabled = regQueryDwordValue("memLagEnabled", false) ? true : false; rlm@1: memLagTempEnabled = memLagEnabled; rlm@1: gbNullInputHackEnabled = regQueryDwordValue("gbNullInputHackEnabled", false) ? true : false; rlm@1: gbNullInputHackTempEnabled = gbNullInputHackEnabled; rlm@1: useOldSync = regQueryDwordValue("useOldSync", 0) ? TRUE : FALSE; rlm@1: useOldFrameTiming = regQueryDwordValue("useOldGBTiming", false) ? true : false; rlm@1: rlm@1: useBiosFile = regQueryDwordValue("useBios", 0) ? true : false; rlm@1: skipBiosFile = regQueryDwordValue("skipBios", 0) ? true : false; rlm@1: buffer = regQueryStringValue("biosFile", ""); rlm@1: if (!buffer.IsEmpty()) rlm@1: { rlm@1: biosFileName = buffer; rlm@1: } rlm@1: // removeIntros = regQueryDwordValue("removeIntros", false) ? true : false; rlm@1: rlm@1: autoIPS = regQueryDwordValue("autoIPS", true) ? true : false; rlm@1: rlm@1: agbPrintEnable(regQueryDwordValue("agbPrint", 0) ? true : false); rlm@1: winRtcEnable = regQueryDwordValue("rtcEnabled", 0) ? true : false; rlm@1: rtcEnable(winRtcEnable); rlm@1: rlm@1: winSaveType = regQueryDwordValue("saveType", 0); rlm@1: if (winSaveType < 0 || winSaveType > 5) rlm@1: winSaveType = 0; rlm@1: cpuEnhancedDetection = regQueryDwordValue("enhancedDetection", 1) ? true : false; rlm@1: winFlashSize = regQueryDwordValue("flashSize", 0x10000); rlm@1: if (winFlashSize != 0x10000 && winFlashSize != 0x20000) rlm@1: winFlashSize = 0x10000; rlm@1: rlm@1: cpuDisableSfx = regQueryDwordValue("disableSfx", 0) ? true : false; rlm@1: rlm@1: // GBx rlm@1: winGbPrinterEnabled = regQueryDwordValue("gbPrinter", false) ? true : false; rlm@1: if (winGbPrinterEnabled) rlm@1: gbSerialFunction = gbPrinterSend; rlm@1: else rlm@1: gbSerialFunction = NULL; rlm@1: gbEmulatorType = regQueryDwordValue("emulatorType", 0); rlm@1: if (gbEmulatorType < 0 || gbEmulatorType > 5) rlm@1: gbEmulatorType = 1; rlm@1: winGbBorderOn = regQueryDwordValue("borderOn", 0); rlm@1: gbBorderAutomatic = regQueryDwordValue("borderAutomatic", 0); rlm@1: rlm@1: gbColorOption = regQueryDwordValue("colorOption", 0); rlm@1: gbPaletteOption = regQueryDwordValue("gbPaletteOption", 0); rlm@1: if (gbPaletteOption < 0) rlm@1: gbPaletteOption = 0; rlm@1: if (gbPaletteOption > 2) rlm@1: gbPaletteOption = 2; rlm@1: regQueryBinaryValue("gbPalette", (char *)systemGbPalette, 24 * sizeof(u16)); rlm@1: rlm@1: // head-up display rlm@1: showSpeed = regQueryDwordValue("showSpeed", 1); rlm@1: if (showSpeed < 0 || showSpeed > 2) rlm@1: showSpeed = 1; rlm@1: showSpeedTransparent = regQueryDwordValue("showSpeedTransparent", TRUE) ? TRUE : FALSE; rlm@1: outlinedText = regQueryDwordValue("outlinedText", TRUE) != 0; rlm@1: transparentText = regQueryDwordValue("transparentText", FALSE) != 0; rlm@1: textColor = regQueryDwordValue("textColor", 0); rlm@1: textMethod = regQueryDwordValue("textMethod", 1); rlm@1: frameCounter = regQueryDwordValue("frameCounter", false) ? true : false; rlm@1: lagCounter = regQueryDwordValue("lagCounter", false) ? true : false; rlm@1: extraCounter = regQueryDwordValue("extraCounter", false) ? true : false; rlm@1: inputDisplay = regQueryDwordValue("inputDisplay", false) ? true : false; rlm@1: disableStatusMessage = regQueryDwordValue("disableStatus", 0) ? true : false; rlm@1: rlm@1: // UI rlm@1: windowPositionX = regQueryDwordValue("windowX", 0); rlm@1: if (windowPositionX < 0) rlm@1: windowPositionX = 0; rlm@1: windowPositionY = regQueryDwordValue("windowY", 0); rlm@1: if (windowPositionY < 0) rlm@1: windowPositionY = 0; rlm@1: rlm@1: autoHideMenu = regQueryDwordValue("autoHideMenu", 0) ? true : false; rlm@1: rlm@1: languageOption = regQueryDwordValue("language", 1); rlm@1: if (languageOption < 0 || languageOption > 2) rlm@1: languageOption = 1; rlm@1: buffer = regQueryStringValue("languageName", ""); rlm@1: if (!buffer.IsEmpty()) rlm@1: { rlm@1: languageName = buffer.Left(3); rlm@1: } rlm@1: else rlm@1: languageName = ""; rlm@1: winSetLanguageOption(languageOption, true); rlm@1: rlm@1: // preferences rlm@1: alwaysOnTop = regQueryDwordValue("alwaysOnTop", false) ? true : false; rlm@1: pauseWhenInactive = regQueryDwordValue("pauseWhenInactive", 1) ? true : false; rlm@1: enableBackgroundInput = regQueryDwordValue("enableBackgroundInput", 0) ? true : false; rlm@1: threadPriority = regQueryDwordValue("priority", 2); rlm@1: if (threadPriority < 0 || threadPriority > 3) rlm@1: threadPriority = 2; rlm@1: updatePriority(); rlm@1: rlm@1: filenamePreference = regQueryDwordValue("filenamePreference", 0); rlm@1: altAviRecordMethod = regQueryDwordValue("altAviRecordMethod", false) ? true : false; rlm@1: captureFormat = regQueryDwordValue("captureFormat", 0); rlm@1: rlm@1: rewindTimer = regQueryDwordValue("rewindTimer", 0); rlm@1: rewindSlots = regQueryDwordValue("rewindSlots", 64); rlm@1: if (rewindTimer < 0 || rewindTimer > 600) rlm@1: rewindTimer = 0; rlm@1: if (rewindSlots <= 0) rlm@1: rewindTimer = rewindSlots = 0; rlm@1: if (rewindSlots > MAX_REWIND_SLOTS) rlm@1: rewindSlots = MAX_REWIND_SLOTS; rlm@1: if (rewindTimer != 0) rlm@1: { rlm@1: if (rewindMemory == NULL) rlm@1: rewindMemory = (char *)malloc(rewindSlots * REWIND_SIZE); rlm@1: } rlm@1: rlm@1: if (frameSearchMemory == NULL) rlm@1: frameSearchMemory = (char *)malloc(3 * REWIND_SIZE); rlm@1: rlm@1: recentFreeze = regQueryDwordValue("recentFreeze", false) ? true : false; rlm@1: for (int i = 0, j = 0; i < 10; ++i) rlm@1: { rlm@1: buffer.Format("recent%d", i); rlm@1: const char *s = regQueryStringValue(buffer, NULL); rlm@1: if (s == NULL) rlm@1: continue; rlm@1: recentFiles[j] = s; rlm@1: ++j; rlm@1: } rlm@1: rlm@1: autoLoadMostRecent = regQueryDwordValue("autoLoadMostRecent", false) ? true : false; rlm@1: loadMakesRecent = regQueryDwordValue("loadMakesRecent", false) ? true : false; rlm@1: loadMakesCurrent = regQueryDwordValue("loadMakesCurrent", false) ? true : false; rlm@1: saveMakesCurrent = regQueryDwordValue("saveMakesCurrent", false) ? true : false; rlm@1: currentSlot = regQueryDwordValue("currentSlot", 0); rlm@1: showSlotTime = regQueryDwordValue("showSlotTime", 0) ? true : false; rlm@1: rlm@1: cheatsEnabled = regQueryDwordValue("cheatsEnabled", true) ? true : false; rlm@1: autoSaveLoadCheatList = regQueryDwordValue("autoSaveCheatList", 0) ? true : false; rlm@1: pauseDuringCheatSearch = regQueryDwordValue("pauseDuringCheatSearch2", 0) ? true : false; rlm@1: rlm@1: movieOnEndBehavior = regQueryDwordValue("movieOnEndBehavior", 0); rlm@1: movieOnEndPause = regQueryDwordValue("movieOnEndPause", 0) ? true : false; rlm@1: rlm@1: extern bool autoConvertMovieWhenPlaying; // from movie.cpp rlm@1: autoConvertMovieWhenPlaying = regQueryDwordValue("autoConvertMovieWhenPlaying", 0) ? true : false; rlm@1: rlm@1: // RamWatch Settings rlm@1: AutoRWLoad = regQueryDwordValue(AUTORWLOAD, false); rlm@1: RWSaveWindowPos = regQueryDwordValue(RWSAVEPOS, false); rlm@1: ramw_x = regQueryDwordValue(RAMWX, 0); rlm@1: ramw_y = regQueryDwordValue(RAMWY, 0); rlm@1: rlm@1: // this is FILO rlm@1: for (int i = MAX_RECENT_WATCHES; i > 0; --i) rlm@1: { rlm@1: buffer.Format("recentWatch%d", i); rlm@1: const char *s = regQueryStringValue(buffer, NULL); rlm@1: if (s == NULL) rlm@1: continue; rlm@1: RWAddRecentFile(s); rlm@1: } rlm@1: } rlm@1: rlm@1: void VBA::saveSettings() rlm@1: { rlm@1: regSetDwordValue("defaultVideoDriver", pVideoDriverGUID == NULL); rlm@1: if (pVideoDriverGUID) rlm@1: { rlm@1: regSetBinaryValue("videoDriverGUID", (char *)&videoDriverGUID, rlm@1: sizeof(GUID)); rlm@1: } rlm@1: regSetDwordValue("video", videoOption); rlm@1: rlm@1: regSetDwordValue("fsWidth", fsWidth); rlm@1: regSetDwordValue("fsHeight", fsHeight); rlm@1: regSetDwordValue("fsColorDepth", fsColorDepth); rlm@1: regSetDwordValue("fsMaxScale", fsMaxScale); rlm@1: rlm@1: regSetDwordValue("stretch", fullScreenStretch); rlm@1: rlm@1: regSetDwordValue("renderMethod", renderMethod); rlm@1: rlm@1: regSetDwordValue("ddrawEmulationOnly", ddrawEmulationOnly); rlm@1: regSetDwordValue("ddrawUseVideoMemory", ddrawUseVideoMemory); rlm@1: regSetDwordValue("tripleBuffering", tripleBuffering); rlm@1: regSetDwordValue("vsync", vsync); rlm@1: rlm@1: regSetDwordValue("d3dFilter", d3dFilter); rlm@1: regSetDwordValue("glFilter", glFilter); rlm@1: regSetDwordValue("glType", glType); rlm@1: rlm@1: // pixel filter & ifb rlm@1: regSetDwordValue("filter", filterType); rlm@1: regSetDwordValue("ifbType", ifbType); rlm@1: regSetDwordValue("disableMMX", disableMMX); rlm@1: rlm@1: // frame skipping rlm@1: regSetDwordValue("frameSkip", frameSkip); rlm@1: regSetDwordValue("gbFrameSkip", gbFrameSkip); rlm@1: /// regSetDwordValue("autoFrameSkip", autoFrameSkip); rlm@1: rlm@1: // input rlm@1: regSetDwordValue("joypadDefault", joypadDefault); rlm@1: regSetDwordValue("allowLeftRight", allowLeftRight); rlm@1: regSetDwordValue("autofireAccountforLag", autofireAccountForLag); rlm@1: regSetDwordValue("nextframeAccountforLag", nextframeAccountForLag); rlm@1: regSetDwordValue("AsscWithSaveState", theApp.AsscWithSaveState); rlm@1: rlm@1: rlm@1: // speed rlm@1: regSetDwordValue("throttle", throttle); rlm@1: regSetDwordValue("synchronize", synchronize); rlm@1: regSetDwordValue("accuratePitchThrottle", accuratePitchThrottle); rlm@1: rlm@1: // sound rlm@1: regSetDwordValue("soundEnable", soundGetEnabledChannels() & 0x030f); rlm@1: regSetDwordValue("soundOff", soundOffFlag); rlm@1: regSetDwordValue("soundQuality", soundQuality); rlm@1: regSetDwordValue("soundEcho", soundEcho); rlm@1: regSetDwordValue("soundLowPass", soundLowPass); rlm@1: regSetDwordValue("soundReverse", soundReverse); rlm@1: regSetDwordValue("soundVolume", soundVolume); rlm@1: regSetDwordValue("muteFrameAdvance", muteFrameAdvance); rlm@1: regSetDwordValue("muteWhenInactive", muteWhenInactive); rlm@1: rlm@1: // emulation rlm@1: regSetDwordValue("useBios", useBiosFile); rlm@1: regSetDwordValue("skipBios", skipBiosFile); rlm@1: if (!biosFileName.IsEmpty()) rlm@1: regSetStringValue("biosFile", biosFileName); rlm@1: // regSetDwordValue("removeIntros", removeIntros); rlm@1: rlm@1: regSetDwordValue("autoIPS", autoIPS); rlm@1: rlm@1: regSetDwordValue("memLagEnabled", memLagEnabled); rlm@1: regSetDwordValue("gbNullInputHackEnabled", gbNullInputHackEnabled); rlm@1: regSetDwordValue("useOldGBTiming", useOldFrameTiming); rlm@1: regSetDwordValue("useOldSync", useOldSync); rlm@1: rlm@1: regSetDwordValue("agbPrint", agbPrintIsEnabled()); rlm@1: regSetDwordValue("rtcEnabled", winRtcEnable); rlm@1: rlm@1: regSetDwordValue("saveType", winSaveType); rlm@1: regSetDwordValue("enhancedDetection", cpuEnhancedDetection); rlm@1: regSetDwordValue("flashSize", winFlashSize); rlm@1: rlm@1: regSetDwordValue("disableSfx", cpuDisableSfx); rlm@1: rlm@1: // GBx rlm@1: regSetDwordValue("emulatorType", gbEmulatorType); rlm@1: regSetDwordValue("gbPrinter", winGbPrinterEnabled); rlm@1: regSetDwordValue("borderOn", winGbBorderOn); rlm@1: regSetDwordValue("borderAutomatic", gbBorderAutomatic); rlm@1: rlm@1: regSetDwordValue("colorOption", gbColorOption); rlm@1: regSetDwordValue("gbPaletteOption", gbPaletteOption); rlm@1: regSetBinaryValue("gbPalette", (char *)systemGbPalette, 24 * sizeof(u16)); rlm@1: rlm@1: // head-up display rlm@1: regSetDwordValue("showSpeed", showSpeed); rlm@1: regSetDwordValue("showSpeedTransparent", showSpeedTransparent); rlm@1: rlm@1: regSetDwordValue("outlinedText", outlinedText); rlm@1: regSetDwordValue("transparentText", transparentText); rlm@1: regSetDwordValue("textColor", textColor); rlm@1: regSetDwordValue("textMethod", textMethod); rlm@1: regSetDwordValue("frameCounter", frameCounter); rlm@1: regSetDwordValue("lagCounter", lagCounter); rlm@1: regSetDwordValue("extraCounter", extraCounter); rlm@1: regSetDwordValue("inputDisplay", inputDisplay); rlm@1: regSetDwordValue("disableStatus", disableStatusMessage); rlm@1: rlm@1: // UI rlm@1: regSetDwordValue("windowX", windowPositionX); rlm@1: regSetDwordValue("windowY", windowPositionY); rlm@1: rlm@1: regSetDwordValue("autoHideMenu", autoHideMenu); rlm@1: rlm@1: regSetDwordValue("language", languageOption); rlm@1: regSetStringValue("languageName", languageName); rlm@1: rlm@1: // preferences rlm@1: regSetDwordValue("alwaysOnTop", alwaysOnTop); rlm@1: regSetDwordValue("pauseWhenInactive", pauseWhenInactive); rlm@1: regSetDwordValue("enableBackgroundInput", enableBackgroundInput); rlm@1: regSetDwordValue("priority", threadPriority); rlm@1: rlm@1: regSetDwordValue("filenamePreference", filenamePreference); rlm@1: regSetDwordValue("altAviRecordMethod", altAviRecordMethod); rlm@1: regSetDwordValue("captureFormat", captureFormat); rlm@1: rlm@1: regSetDwordValue("cheatsEnabled", cheatsEnabled); rlm@1: regSetDwordValue("autoSaveCheatList", autoSaveLoadCheatList); rlm@1: regSetDwordValue("pauseDuringCheatSearch2", pauseDuringCheatSearch); rlm@1: rlm@1: regSetDwordValue("rewindTimer", rewindTimer); rlm@1: regSetDwordValue("rewindSlots", rewindSlots); rlm@1: rlm@1: regSetDwordValue("recentFreeze", recentFreeze); rlm@1: CString buffer; rlm@1: for (int i = 0; i < 10; i++) rlm@1: { rlm@1: buffer.Format("recent%d", i); rlm@1: regSetStringValue(buffer, recentFiles[i]); rlm@1: } rlm@1: rlm@1: regSetDwordValue("autoLoadMostRecent", autoLoadMostRecent); rlm@1: regSetDwordValue("loadMakesRecent", loadMakesRecent); rlm@1: regSetDwordValue("loadMakesCurrent", loadMakesCurrent); rlm@1: regSetDwordValue("saveMakesCurrent", saveMakesCurrent); rlm@1: regSetDwordValue("currentSlot", currentSlot); rlm@1: regSetDwordValue("showSlotTime", showSlotTime); rlm@1: rlm@1: regSetDwordValue("movieOnEndBehavior", movieOnEndBehavior); rlm@1: regSetDwordValue("movieOnEndPause", movieOnEndPause); rlm@1: rlm@1: extern bool autoConvertMovieWhenPlaying; // from movie.cpp rlm@1: regSetDwordValue("autoConvertMovieWhenPlaying", autoConvertMovieWhenPlaying); rlm@1: } rlm@1: