Mercurial > vba-linux
view src/win32/VBA.cpp @ 2:3549bbe597ed
adding makefile.am
author | Robert McIntyre <rlm@mit.edu> |
---|---|
date | Sat, 03 Mar 2012 10:31:47 -0600 |
parents | f9f4f1b99eed |
children |
line wrap: on
line source
1 // VBA.cpp : Defines the class behaviors for the application.2 //3 #include "stdafx.h"4 #include <mmsystem.h>5 #include <cassert>7 #include "resource.h"8 #include "VBA.h"9 #include "AVIWrite.h"10 #include "Input.h"11 #include "IUpdate.h"12 #include "LangSelect.h"13 #include "MainWnd.h"14 #include "Reg.h"15 #include "WavWriter.h"16 #include "WinResUtil.h"17 #include "WinMiscUtil.h"18 #include "ramwatch.h"20 #include "../gba/GBA.h"21 #include "../gba/GBAGlobals.h"22 #include "../gba/agbprint.h"23 #include "../gb/GB.h"24 #include "../gb/gbGlobals.h"25 #include "../gb/gbPrinter.h"26 #include "../common/CheatSearch.h"27 #include "../gba/RTC.h"28 #include "../gba/GBASound.h"29 #include "../common/Util.h"30 #include "../common/Text.h"31 #include "../common/movie.h"32 #include "../common/nesvideos-piece.h"33 #include "../common/vbalua.h"34 #include "../filters/filters.h"35 #include "../version.h"37 extern IDisplay *newGDIDisplay();38 extern IDisplay *newDirectDrawDisplay();39 extern IDisplay *newDirect3DDisplay();40 extern IDisplay *newOpenGLDisplay();42 extern Input *newDirectInput();44 extern void remoteStubSignal(int, int);45 extern void remoteOutput(char *, u32);46 extern void remoteStubMain();47 extern void remoteSetProtocol(int);48 extern void remoteCleanUp();49 extern int remoteSocket;51 void winlog(const char *msg, ...);53 bool debugger = false;55 char movieFileToPlay[1024];56 bool playMovieFile = false;57 bool playMovieFileReadOnly = false;58 char wavFileToOutput [1024];59 bool outputWavFile = false;60 bool outputAVIFile = false;61 bool flagHideMenu = false;62 int quitAfterTime = -1;63 int pauseAfterTime = -1;65 void winSignal(int, int);66 void winOutput(char *, u32);68 void (*dbgSignal)(int, int) = winSignal;69 void (*dbgOutput)(char *, u32) = winOutput;71 #ifdef MMX72 extern "C" bool cpu_mmx;73 #endif75 // nowhere good to put them to77 void DrawTextMessages(u8 *dest, int pitch, int left, int bottom)78 {79 for (int slot = 0; slot < SCREEN_MESSAGE_SLOTS; slot++)80 {81 if (theApp.screenMessage[slot])82 {83 if ((theApp.screenMessageDuration[slot] < 0 ||84 (int)(GetTickCount() - theApp.screenMessageTime[slot]) < theApp.screenMessageDuration[slot]) &&85 (!theApp.disableStatusMessage || slot == 1 || slot == 2))86 {87 drawText(dest,88 pitch,89 left,90 bottom - 10 * (slot + 1),91 theApp.screenMessageBuffer[slot],92 theApp.screenMessageColorBuffer[slot]);93 }94 else95 {96 theApp.screenMessage[slot] = false;97 }98 }99 }100 }102 // draw Lua graphics in game screen103 void DrawLuaGui()104 {105 int copyX = 240, copyY = 160;106 int screenX = 240, screenY = 160;107 int copyOffsetX = 0, copyOffsetY = 0;108 if (systemCartridgeType == 1)109 {110 if (gbBorderOn)111 {112 copyX = 256, copyY = 224;113 screenX = 256, screenY = 224;114 }115 else116 {117 copyX = 160, copyY = 144;118 screenX = 160, screenY = 144;119 }120 }121 int pitch = copyX * (systemColorDepth / 8) + (systemColorDepth == 24 ? 0 : 4);123 ++copyOffsetY; // don't know why it's needed125 VBALuaGui(&pix[copyOffsetY * pitch + copyOffsetX * (systemColorDepth / 8)], copyX, screenX, screenY);126 VBALuaClearGui();127 }129 void directXMessage(const char *msg)130 {131 systemMessage(132 IDS_DIRECTX_7_REQUIRED,133 "DirectX 7.0 or greater is required to run.\nDownload at http://www.microsoft.com/directx.\n\nError found at: %s",134 msg);135 }137 void winlog(const char *msg, ...)138 {139 CString buffer;140 va_list valist;142 va_start(valist, msg);143 buffer.FormatV(msg, valist);145 FILE *winout = fopen("vba-trace.log", "w");147 fputs(buffer, winout);149 fclose(winout);151 va_end(valist);152 }154 // code from SDL_main.c for Windows155 /* Parse a command line buffer into arguments */157 static int parseCommandLine(char *cmdline, char * *argv)158 {159 char *bufp;160 int argc;162 argc = 0;163 for (bufp = cmdline; *bufp; )164 {165 /* Skip leading whitespace */166 while (isspace(*bufp))167 {168 ++bufp;169 }170 /* Skip over argument */171 if (*bufp == '"')172 {173 ++bufp;174 if (*bufp)175 {176 if (argv)177 {178 argv[argc] = bufp;179 }180 ++argc;181 }182 /* Skip over word */183 while (*bufp && (*bufp != '"'))184 {185 ++bufp;186 }187 }188 else189 {190 if (*bufp)191 {192 if (argv)193 {194 argv[argc] = bufp;195 }196 ++argc;197 }198 /* Skip over word */199 while (*bufp && !isspace(*bufp))200 {201 ++bufp;202 }203 }204 if (*bufp)205 {206 if (argv)207 {208 *bufp = '\0';209 }210 ++bufp;211 }212 }213 if (argv)214 {215 argv[argc] = NULL;216 }217 return(argc);218 }220 static void debugSystemScreenMessage1(const char *msg)221 {222 systemScreenMessage(msg, 3);223 }225 static void debugSystemScreenMessage2(const char *msg)226 {227 systemScreenMessage(msg, 4);228 }230 static void winSignal(int, int)231 {}233 #define CPUReadByteQuick(addr) \234 map[(addr) >> 24].address[(addr) & map[(addr) >> 24].mask]236 static void winOutput(char *s, u32 addr)237 {238 if (s)239 {240 log(s);241 }242 else243 {244 CString str;245 char c;247 c = CPUReadByteQuick(addr);248 addr++;249 while (c)250 {251 str += c;252 c = CPUReadByteQuick(addr);253 addr++;254 }255 log(str);256 }257 }259 typedef BOOL (WINAPI * GETMENUBARINFO)(HWND, LONG, LONG, PMENUBARINFO);261 static int winGetMenuBarHeight()262 {263 HINSTANCE hinstDll = /**/ ::LoadLibrary("USER32.DLL");265 if (hinstDll)266 {267 GETMENUBARINFO func = (GETMENUBARINFO)GetProcAddress(hinstDll, "GetMenuBarInfo");269 if (func)270 {271 MENUBARINFO info;272 info.cbSize = sizeof(info);274 func(AfxGetMainWnd()->GetSafeHwnd(), OBJID_MENU, 0, &info);276 /**/ ::FreeLibrary(hinstDll);278 return info.rcBar.bottom - info.rcBar.top + 1;279 }280 }282 return GetSystemMetrics(SM_CYMENU);283 }285 /////////////////////////////////////////////////////////////////////////////286 // VBA288 BEGIN_MESSAGE_MAP(VBA, CWinApp)289 //{{AFX_MSG_MAP(VBA)290 // NOTE - the ClassWizard will add and remove mapping macros here.291 // DO NOT EDIT what you see in these blocks of generated code!292 //}}AFX_MSG_MAP293 END_MESSAGE_MAP()295 /////////////////////////////////////////////////////////////////////////////296 // The one and only VBA object298 VBA theApp;300 /////////////////////////////////////////////////////////////////////////////301 // VBA construction303 VBA::VBA() : emulator(::theEmulator)304 {305 // important306 {307 #ifdef MULTITHREAD_STDLOCALE_WORKAROUND308 // Note: there's a known threading bug regarding std::locale with MSVC according to309 // http://connect.microsoft.com/VisualStudio/feedback/details/492128/std-locale-constructor-modifies-global-locale-via-setlocale310 int iPreviousFlag = ::_configthreadlocale(_ENABLE_PER_THREAD_LOCALE);311 #endif312 using std::locale;313 locale::global(locale(locale::classic(), "", locale::collate | locale::ctype));315 #ifdef MULTITHREAD_STDLOCALE_WORKAROUND316 if (iPreviousFlag > 0 )317 ::_configthreadlocale(iPreviousFlag);318 #endif319 }321 mode320Available = false;322 mode640Available = false;323 mode800Available = false;324 windowPositionX = 0;325 windowPositionY = 0;326 filterFunction = NULL;327 ifbFunction = NULL;328 ifbType = 0;329 filterType = 0;330 filterWidth = 0;331 filterHeight = 0;332 fsWidth = 0;333 fsHeight = 0;334 fsColorDepth = 0;335 fsForceChange = false;336 surfaceSizeX = 0;337 surfaceSizeY = 0;338 sizeX = 0;339 sizeY = 0;340 videoOption = 0;341 fullScreenStretch = false;342 disableStatusMessage = false;343 showSpeed = 1;344 showSpeedTransparent = true;345 showRenderedFrames = 0;346 for (int j = 0; j < SCREEN_MESSAGE_SLOTS; j++)347 {348 screenMessage[j] = false;349 screenMessageTime[j] = 0;350 screenMessageDuration[j] = 0;351 }352 menuToggle = true;353 display = NULL;354 menu = NULL;355 popup = NULL;356 soundInitialized = false;357 useBiosFile = false;358 skipBiosFile = false;359 active = true;360 paused = false;361 recentFreeze = false;362 autoSaveLoadCheatList = false;363 pauseDuringCheatSearch = false;364 modelessCheatDialogIsOpen = false;365 // winout = NULL;366 // removeIntros = false;367 autoIPS = true;368 winGbBorderOn = 0;369 hideMovieBorder = false;370 winFlashSize = 0x10000;371 winRtcEnable = false;372 winSaveType = 0;373 rewindMemory = NULL;374 frameSearchMemory = NULL;375 rewindPos = 0;376 rewindTopPos = 0;377 rewindCounter = 0;378 rewindCount = 0;379 rewindSaveNeeded = false;380 rewindTimer = 0;381 captureFormat = 0;382 tripleBuffering = true;383 autoHideMenu = false;384 throttle = 100;385 throttleLastTime = 0;386 /// autoFrameSkipLastTime = 0;387 /// autoFrameSkip = false;388 vsync = false;389 changingVideoSize = false;390 pVideoDriverGUID = NULL;391 renderMethod = DIRECT_DRAW;392 iconic = false;393 ddrawEmulationOnly = false;394 ddrawUsingEmulationOnly = false;395 ddrawDebug = false;396 ddrawUseVideoMemory = false;397 d3dFilter = 0;398 glFilter = 0;399 glType = 0;400 regEnabled = false;401 pauseWhenInactive = true;402 muteWhenInactive = true;403 enableBackgroundInput = false;404 alwaysOnTop = false;405 filenamePreference = true;406 frameCounter = false;407 lagCounter = false;408 extraCounter = false;409 inputDisplay = false;410 speedupToggle = false;411 useOldSync = false;412 allowLeftRight = false;413 autofireAccountForLag = false;414 nextframeAccountForLag = false;415 muteFrameAdvance = false;416 muteWhenInactive = false;417 winMuteForNow = false;418 winGbPrinterEnabled = false;419 threadPriority = 2;420 disableMMX = false;421 languageOption = 0;422 languageModule = NULL;423 languageName = "";424 renderedFrames = 0;425 input = NULL;426 joypadDefault = 0;427 autoFire = 0;428 autoFire2 = 0;429 autoHold = 0;430 autoFireToggle = false;431 winPauseNextFrame = false;432 soundRecording = false;433 soundRecorder = NULL;434 sound = NULL;435 aviRecording = false;436 aviRecorder = NULL;437 painting = false;438 mouseCounter = 0;439 movieReadOnly = true;440 movieOnEndPause = false;441 movieOnEndBehavior = 0;442 wasPaused = false;443 fsMaxScale = 0;444 romSize = 0;445 autoLoadMostRecent = false;446 loadMakesRecent = false;447 loadMakesCurrent = false;448 saveMakesCurrent = false;449 currentSlot = 0;450 showSlotTime = false;451 frameSearchLoadValid = false;452 frameSearching = false;453 frameSearchSkipping = false;454 nvVideoLog = false;455 nvAudioLog = false;456 LoggingEnabled = 0;457 /// FPS = 60;459 updateCount = 0;461 systemSaveUpdateCounter = SYSTEM_SAVE_NOT_UPDATED;463 ZeroMemory(&emulator, sizeof(emulator));465 hAccel = NULL;467 for (int i = 0; i < 24; )468 {469 systemGbPalette[i++] = (0x1f) | (0x1f << 5) | (0x1f << 10);470 systemGbPalette[i++] = (0x15) | (0x15 << 5) | (0x15 << 10);471 systemGbPalette[i++] = (0x0c) | (0x0c << 5) | (0x0c << 10);472 systemGbPalette[i++] = 0;473 }475 VBAMovieInit();477 TIMECAPS tc;478 if (timeGetDevCaps(&tc, sizeof(TIMECAPS)) == TIMERR_NOERROR)479 {480 wmTimerRes = min(max(tc.wPeriodMin, 1), tc.wPeriodMax);481 timeBeginPeriod(wmTimerRes);482 }483 else484 {485 wmTimerRes = 5;486 timeBeginPeriod(wmTimerRes);487 }488 }490 VBA::~VBA()491 {492 if (VBAMovieActive())493 VBAMovieStop(true);495 saveSettings();497 InterframeCleanup();499 if (aviRecorder)500 {501 delete aviRecorder;502 aviRecorder = NULL;503 aviRecording = false;504 }506 if (soundRecorder)507 {508 delete soundRecorder;509 soundRecorder = NULL;510 }511 soundRecording = false;512 soundPause();513 soundShutdown();515 ((MainWnd *)(m_pMainWnd))->winFileClose();517 if (input)518 delete input;520 shutdownDisplay();522 if (rewindMemory)523 free(rewindMemory);525 if (frameSearchMemory)526 free(frameSearchMemory);528 timeEndPeriod(wmTimerRes);529 }531 /////////////////////////////////////////////////////////////////////////////532 // VBA initialization534 #include <afxdisp.h>536 BOOL VBA::InitInstance()537 {538 AfxEnableControlContainer();539 // Standard initialization540 // If you are not using these features and wish to reduce the size541 // of your final executable, you should remove from the following542 // the specific initialization routines you do not need.544 //#ifdef _AFXDLL545 // Enable3dControls(); // Call this when using MFC in a shared DLL546 //#else547 // Enable3dControlsStatic(); // Call this when linking to MFC statically548 //#endif550 SetRegistryKey(_T("VBA"));552 remoteSetProtocol(0);554 systemVerbose = GetPrivateProfileInt("config", "verbose", 0, "VBA.ini");555 systemDebug = GetPrivateProfileInt("config", "debug", 0, "VBA.ini");556 ddrawDebug = GetPrivateProfileInt("config", "ddrawDebug", 0, "VBA.ini") ? true : false;558 wndClass = AfxRegisterWndClass(0, LoadCursor(IDC_ARROW), (HBRUSH)GetStockObject(BLACK_BRUSH), LoadIcon(IDI_ICON));560 char winBuffer[2048];561 GetModuleFileName(NULL, winBuffer, 2048);562 char *p = strrchr(winBuffer, '\\');563 if (p)564 *p = 0;565 exeDir = winBuffer;567 regInit(winBuffer);569 loadSettings();570 theApp.LuaFastForward = -1;571 if (!initInput())572 return FALSE;574 if (!initDisplay())575 {576 if (videoOption >= VIDEO_320x240)577 {578 regSetDwordValue("video", VIDEO_1X);579 if (pVideoDriverGUID)580 regSetDwordValue("defaultVideoDriver", TRUE);581 }582 return FALSE;583 }585 hAccel = LoadAccelerators(AfxGetInstanceHandle(), MAKEINTRESOURCE(IDR_ACCELERATOR));587 winAccelMgr.Connect((MainWnd *)m_pMainWnd);589 extern void winAccelAddCommandsFromMenu(CAcceleratorManager & mgr, CMenu * pMenu, const CString &parentStr);590 extern void winAccelAddCommandsFromTable(CAcceleratorManager & mgr);592 winAccelAddCommandsFromMenu(winAccelMgr, &m_menu, CString());593 winAccelAddCommandsFromTable(winAccelMgr);595 winAccelMgr.CreateDefaultTable();596 winAccelMgr.Load();597 winAccelMgr.UpdateWndTable();598 winAccelMgr.UpdateMenu(menu);600 if (m_lpCmdLine[0])601 {602 int argc = parseCommandLine(m_lpCmdLine, NULL);603 char * *argv = (char * *)malloc((argc + 1) * sizeof(char *));604 parseCommandLine(m_lpCmdLine, argv);606 bool gotFlag = false, enoughArgs = false;607 for (int i = 0; i < argc; i++)608 {609 if (argv[i][0] == '-' || gotFlag)610 {611 if (!gotFlag)612 loadSettings();613 gotFlag = true;614 if (_stricmp(argv[i], "-rom") == 0)615 {616 if (i + 1 >= argc || argv[i + 1][0] == '-')617 goto invalidArgument;618 romFilename = argv[++i];619 winCorrectPath(romFilename);620 gameFilename = romFilename;621 }622 else if (_stricmp(argv[i], "-bios") == 0)623 {624 if (i + 1 >= argc || argv[i + 1][0] == '-')625 goto invalidArgument;626 biosFileName = argv[++i];627 winCorrectPath(biosFileName);629 //systemLoadBIOS();630 }631 else if (_stricmp(argv[i], "-frameskip") == 0)632 {633 if (i + 1 >= argc || argv[i + 1][0] == '-')634 goto invalidArgument;635 frameSkip = atoi(argv[++i]);636 if (frameSkip < 0)637 frameSkip = 0;638 if (frameSkip > 9)639 frameSkip = 9;640 gbFrameSkip = frameSkip;641 }642 else if (_stricmp(argv[i], "-throttle") == 0)643 {644 if (i + 1 >= argc || argv[i + 1][0] == '-')645 goto invalidArgument;646 throttle = atoi(argv[++i]);647 if (throttle < 5)648 throttle = 5;649 if (throttle > 1000)650 throttle = 1000;651 }652 else if (_stricmp(argv[i], "-throttleKeepPitch") == 0)653 {654 if (i + 1 >= argc || argv[i + 1][0] == '-')655 goto invalidArgument;656 accuratePitchThrottle = atoi(argv[++i]) != 0;657 }658 else if (_stricmp(argv[i], "-synchronize") == 0)659 {660 if (i + 1 >= argc || argv[i + 1][0] == '-')661 goto invalidArgument;662 synchronize = atoi(argv[++i]) != 0;663 }664 else if (_stricmp(argv[i], "-hideborder") == 0)665 {666 if (i + 1 >= argc || argv[i + 1][0] == '-')667 goto invalidArgument;668 hideMovieBorder = atoi(argv[++i]) != 0;669 }670 else if (_stricmp(argv[i], "-play") == 0)671 {672 playMovieFile = true;673 if (i + 1 >= argc || argv[i + 1][0] == '-')674 goto invalidArgument;675 strcpy(movieFileToPlay, argv[++i]);676 winCorrectPath(movieFileToPlay);677 if (i + 1 >= argc || argv[i + 1][0] == '-') { --i; goto invalidArgument; }678 playMovieFileReadOnly = atoi(argv[++i]) != 0;679 }680 else if (_stricmp(argv[i], "-videoLog") == 0)681 {682 nvVideoLog = true;683 nvAudioLog = true;684 LoggingEnabled = 2;685 if (i + 1 >= argc || argv[i + 1][0] == '-') {}686 else687 NESVideoSetVideoCmd(argv[++i]);688 }689 else if (_stricmp(argv[i], "-logDebug") == 0)690 {691 NESVideoEnableDebugging(debugSystemScreenMessage1, debugSystemScreenMessage2);692 }693 else if (_stricmp(argv[i], "-logToFile") == 0)694 {695 NESVideoSetFileFuncs(fopen, fclose);696 }697 else if (_stricmp(argv[i], "-outputWAV") == 0)698 {699 outputWavFile = true;700 if (i + 1 >= argc || argv[i + 1][0] == '-')701 goto invalidArgument;702 strcpy(wavFileToOutput, argv[++i]);703 }704 else if (_stricmp(argv[i], "-outputAVI") == 0)705 {706 outputAVIFile = true;707 }708 else if (_stricmp(argv[i], "-quitAfter") == 0)709 {710 if (i + 1 >= argc || argv[i + 1][0] == '-')711 goto invalidArgument;712 quitAfterTime = atoi(argv[++i]);713 }714 else if (_stricmp(argv[i], "-pauseAt") == 0)715 {716 if (i + 1 >= argc || argv[i + 1][0] == '-')717 goto invalidArgument;718 pauseAfterTime = atoi(argv[++i]);719 }720 else if (_stricmp(argv[i], "-videoScale") == 0)721 {722 if (i + 1 >= argc || argv[i + 1][0] == '-')723 goto invalidArgument;724 int size = atoi(argv[++i]);725 if (size < 1)726 size = 1;727 if (size > 4)728 size = 4;729 switch (size)730 {731 case 1:732 videoOption = VIDEO_1X; break;733 case 2:734 videoOption = VIDEO_2X; break;735 case 3:736 videoOption = VIDEO_3X; break;737 case 4:738 videoOption = VIDEO_4X; break;739 }740 }741 else if (_stricmp(argv[i], "-hideMenu") == 0)742 {743 flagHideMenu = true;744 }745 else746 {747 enoughArgs = true;748 invalidArgument:749 char str [2048]; // the string is larger than 1024 bytes750 strcpy(str, "");751 if (_stricmp(argv[i], "-h") != 0)752 if (enoughArgs)753 sprintf(str, "Invalid commandline argument %d: %s\n", i, argv[i]);754 else755 sprintf(str, "Not enough arguments for arg %d: %s\n", i, argv[i]);756 strcat(str, "Valid commands:\n"757 "-h \t\t\t displays this help\n"758 "-rom filename \t\t opens the given ROM\n"759 "-bios filename \t\t use the given GBA BIOS\n"760 "-play filename val \t\t plays the given VBM movie (val: 1 = read-only, 0 = editable)\n"761 "-outputWAV filename \t outputs WAV audio to the given file\n"762 "-outputAVI \t\t outputs an AVI (you are prompted for location and codec)\n"763 "-frameskip val \t\t sets the frameskip amount to the given value\n"764 "-synchronize val \t\t limits running speed to sound playing speed, (0 = off, 1 = on)\n"765 "-throttle val \t\t sets the throttle speed to the given percentage\n"766 "-hideborder val \t\t hides SGB border, if any (0 = show, 1 = hide)\n"767 "-throttleKeepPitch val \t if throttle and synch, don't change sound freq (0 = off, 1 = on)\n"768 "-quitAfter val \t\t close program when frame counter == val\n"769 "-pauseAt val \t\t pause (movie) once when frame counter == val\n"770 "-videoScale val \t\t sets the video size (val = 1 for 1X, 2 for 2X, 3 for 3X, or 4 for 4X)\n"771 "-hideMenu \t\t hides the menu until program exit\n"772 "\n"773 "-videoLog args \t does (nesvideos) video+audio logging with the given arguments\n"774 "-logToFile \t tells logging to use fopen/fclose of args, if logging is enabled\n"775 "-logDebug \t tells logging to output debug info to screen, if logging is enabled\n"776 );777 theApp.winCheckFullscreen();778 AfxGetApp()->m_pMainWnd->MessageBox(str, "Commandline Help", MB_OK | MB_ICONINFORMATION);779 exit(0);780 }781 }782 else783 {784 // assume anything else is a ROM, for backward compatibility785 romFilename = argv[i++];786 gameFilename = romFilename;787 loadSettings();788 }789 }791 /*792 int index = filename.ReverseFind('.');794 if (index != -1)795 filename = filename.Left(index);796 */797 if (romFilename.GetLength() > 0)798 {799 ((MainWnd *)theApp.m_pMainWnd)->winFileRun();800 }801 free(argv);802 }804 return TRUE;805 }807 void VBA::adjustDestRect()808 {809 POINT point;811 point.x = 0;812 point.y = 0;814 m_pMainWnd->ClientToScreen(&point);815 dest.top = point.y;816 dest.left = point.x;818 point.x = surfaceSizeX;819 point.y = surfaceSizeY;821 m_pMainWnd->ClientToScreen(&point);822 dest.bottom = point.y;823 dest.right = point.x;825 if (videoOption > VIDEO_4X)826 {827 int menuSkip = 0;828 if (menuToggle)829 {830 menuSkip = winGetMenuBarHeight();831 }833 if (fullScreenStretch)834 {835 dest.top = menuSkip;836 dest.left = 0;837 dest.right = fsWidth;838 dest.bottom = fsHeight;839 }840 else841 {842 int top = (fsHeight - surfaceSizeY) / 2;843 int left = (fsWidth - surfaceSizeX) / 2;844 dest.top += top - menuSkip * 2;845 dest.bottom += top;846 dest.left += left;847 dest.right += left;848 }849 }850 }852 void VBA::updateIFB()853 {854 if (systemColorDepth == 16)855 {856 switch (ifbType)857 {858 case 0:859 default:860 ifbFunction = NULL;861 break;862 case 1:863 ifbFunction = MotionBlurIB;864 break;865 case 2:866 ifbFunction = SmartIB;867 break;868 }869 }870 else if (systemColorDepth == 32)871 {872 switch (ifbType)873 {874 case 0:875 default:876 ifbFunction = NULL;877 break;878 case 1:879 ifbFunction = MotionBlurIB32;880 break;881 case 2:882 ifbFunction = SmartIB32;883 break;884 }885 }886 else887 ifbFunction = NULL;888 }890 void VBA::updateFilter()891 {892 filterWidth = sizeX;893 filterHeight = sizeY;895 if (systemColorDepth == 16 && (videoOption > VIDEO_1X &&896 videoOption != VIDEO_320x240))897 {898 switch (filterType)899 {900 default:901 case 0:902 filterFunction = NULL;903 break;904 case 1:905 filterFunction = ScanlinesTV;906 break;907 case 2:908 filterFunction = _2xSaI;909 break;910 case 3:911 filterFunction = Super2xSaI;912 break;913 case 4:914 filterFunction = SuperEagle;915 break;916 case 5:917 filterFunction = Pixelate2x16;918 break;919 case 6:920 filterFunction = MotionBlur;921 break;922 case 7:923 filterFunction = AdMame2x;924 break;925 case 8:926 filterFunction = Simple2x16;927 break;928 case 9:929 filterFunction = Bilinear;930 break;931 case 10:932 filterFunction = BilinearPlus;933 break;934 case 11:935 filterFunction = Scanlines;936 break;937 case 12:938 filterFunction = hq2xS;939 break;940 case 13:941 filterFunction = hq2x;942 break;943 case 14:944 filterFunction = lq2x;945 break;946 case 15:947 filterFunction = hq3xS;948 break;949 case 16:950 filterFunction = hq3x;951 break;952 case 17:953 filterFunction = Simple3x16;954 break;955 case 18:956 filterFunction = Simple4x16;957 break;958 case 19:959 filterFunction = Pixelate3x16;960 break;961 case 20:962 filterFunction = Pixelate4x16;963 break;964 }965 switch (filterType)966 {967 case 0: // normal -> 1x texture968 rect.right = sizeX;969 rect.bottom = sizeY;970 break;971 default: // other -> 2x texture972 rect.right = sizeX * 2;973 rect.bottom = sizeY * 2;974 memset(delta, 255, sizeof(delta));975 break;976 case 15: // hq3x -> 3x texture977 case 16:978 case 17:979 case 19:980 rect.right = sizeX * 3;981 rect.bottom = sizeY * 3;982 memset(delta, 255, sizeof(delta));983 break;984 case 18: // Simple4x -> 4x texture985 case 20:986 rect.right = sizeX * 4;987 rect.bottom = sizeY * 4;988 memset(delta, 255, sizeof(delta));989 break;990 }991 }992 else993 {994 if (systemColorDepth == 32 && videoOption > VIDEO_1X &&995 videoOption != VIDEO_320x240)996 {997 switch (filterType)998 {999 default:1000 case 0:1001 filterFunction = NULL;1002 break;1003 case 1:1004 filterFunction = ScanlinesTV32;1005 break;1006 case 2:1007 filterFunction = _2xSaI32;1008 break;1009 case 3:1010 filterFunction = Super2xSaI32;1011 break;1012 case 4:1013 filterFunction = SuperEagle32;1014 break;1015 case 5:1016 filterFunction = Pixelate2x32;1017 break;1018 case 6:1019 filterFunction = MotionBlur32;1020 break;1021 case 7:1022 filterFunction = AdMame2x32;1023 break;1024 case 8:1025 filterFunction = Simple2x32;1026 break;1027 case 9:1028 filterFunction = Bilinear32;1029 break;1030 case 10:1031 filterFunction = BilinearPlus32;1032 break;1033 case 11:1034 filterFunction = Scanlines32;1035 break;1036 case 12:1037 filterFunction = hq2xS32;1038 break;1039 case 13:1040 filterFunction = hq2x32;1041 break;1042 case 14:1043 filterFunction = lq2x32;1044 break;1045 case 15:1046 filterFunction = hq3xS32;1047 break;1048 case 16:1049 filterFunction = hq3x32;1050 break;1051 case 17:1052 filterFunction = Simple3x32;1053 break;1054 case 18:1055 filterFunction = Simple4x32;1056 break;1057 case 19:1058 filterFunction = Pixelate3x32;1059 break;1060 case 20:1061 filterFunction = Pixelate4x32;1062 break;1063 }1064 switch (filterType)1065 {1066 case 0: // normal -> 1x texture1067 rect.right = sizeX;1068 rect.bottom = sizeY;1069 break;1070 default: // other -> 2x texture1071 rect.right = sizeX * 2;1072 rect.bottom = sizeY * 2;1073 memset(delta, 255, sizeof(delta));1074 break;1075 case 15: // hq3x -> 3x texture1076 case 16:1077 case 17:1078 case 19:1079 rect.right = sizeX * 3;1080 rect.bottom = sizeY * 3;1081 memset(delta, 255, sizeof(delta));1082 break;1083 case 18: // Simple4x -> 4x texture1084 case 20:1085 rect.right = sizeX * 4;1086 rect.bottom = sizeY * 4;1087 memset(delta, 255, sizeof(delta));1088 break;1089 }1090 }1091 else1092 filterFunction = NULL;1093 }1095 if (display)1096 display->changeRenderSize(rect.right, rect.bottom);1097 }1099 void VBA::recreateMenuBar()1100 {1101 m_menu.Detach();1102 m_menu.Attach(winResLoadMenu(MAKEINTRESOURCE(IDR_MENU)));1104 if (m_pMainWnd && menuToggle) // assuming that whether the menu has been set is always kept tracked1105 {1106 m_pMainWnd->SetMenu(&m_menu);1107 }1109 if (menu != NULL)1110 {1111 DestroyMenu(menu);1112 }1114 menu = m_menu.GetSafeHmenu();1115 }1117 void VBA::updateMenuBar()1118 {1119 if (flagHideMenu)1120 return;1122 recreateMenuBar();1124 if (popup != NULL)1125 {1126 // force popup recreation if language changed1127 DestroyMenu(popup);1128 popup = NULL;1129 }1130 }1132 void VBA::saveRewindStateIfNecessary()1133 {1134 if (rewindSaveNeeded && rewindMemory && emulator.emuWriteMemState)1135 {1136 rewindCount++;1137 if (rewindCount > rewindSlots)1138 rewindCount = rewindSlots;1139 assert(rewindPos >= 0 && rewindPos < rewindSlots);1140 if (emulator.emuWriteMemState(&rewindMemory[rewindPos * REWIND_SIZE], REWIND_SIZE))1141 {1142 rewindPos = ++rewindPos % rewindSlots;1143 assert(rewindPos >= 0 && rewindPos < rewindSlots);1144 if (rewindCount == rewindSlots)1145 rewindTopPos = ++rewindTopPos % rewindSlots;1146 }1147 }1149 // also update/cache some frame search stuff1150 if (frameSearching)1151 {1152 extern SMovie Movie;1153 int curFrame = (Movie.state == MOVIE_STATE_NONE) ? systemCounters.frameCount : Movie.currentFrame;1154 int endFrame = theApp.frameSearchStart + theApp.frameSearchLength;1155 frameSearchSkipping = (curFrame < endFrame);1156 frameSearchFirstStep = false;1158 if (curFrame == endFrame)1159 {1160 // cache intermediate state to speed up searching forward1161 emulator.emuWriteMemState(&frameSearchMemory[REWIND_SIZE * 1], REWIND_SIZE);1162 }1164 if (curFrame == endFrame + 1)1165 {1166 emulator.emuWriteMemState(&frameSearchMemory[REWIND_SIZE * 2], REWIND_SIZE);1167 frameSearchLoadValid = true;1168 }1169 }1170 else1171 {1172 frameSearchFirstStep = false;1174 assert(!frameSearchSkipping);1175 // just in case1176 frameSearchSkipping = false;1177 }1178 }1180 BOOL VBA::OnIdle(LONG lCount)1181 {1182 if (emulating && debugger)1183 {1184 MSG msg;1185 remoteStubMain();1186 if (debugger)1187 return TRUE; // continue loop1188 return !::PeekMessage(&msg, NULL, NULL, NULL, PM_NOREMOVE);1189 }1190 else if (emulating && active && !paused)1191 {1192 /// for(int i = 0; i < 2; i++)1193 {1194 emulator.emuMain(emulator.emuCount);1196 // save the state for rewinding, if necessary1197 saveRewindStateIfNecessary();1199 rewindSaveNeeded = false;1200 }1202 if (mouseCounter)1203 {1204 if (--mouseCounter == 0)1205 {1206 SetCursor(NULL);1207 }1208 }1209 return TRUE;1210 }1211 else if (emulating) // this fixes display if resetting while paused1212 {1213 // VBAUpdateButtonPressDisplay();1214 VBAUpdateFrameCountDisplay();1215 systemRefreshScreen();1216 }1218 return FALSE;1220 // return CWinApp::OnIdle(lCount);1221 }1223 void VBA::addRecentFile(const CString &file)1224 {1225 // Do not change recent list if frozen1226 if (recentFreeze)1227 return;1228 int i = 0;1229 for (i = 0; i < 10; ++i)1230 {1231 if (recentFiles[i].GetLength() == 0)1232 break;1234 if (recentFiles[i].Compare(file) == 0)1235 {1236 if (i == 0)1237 return;1238 CString p = recentFiles[i];1239 for (int j = i; j > 0; --j)1240 {1241 recentFiles[j] = recentFiles[j - 1];1242 }1243 recentFiles[0] = p;1244 return;1245 }1246 }1247 int num = 0;1248 for (i = 0; i < 10; ++i)1249 {1250 if (recentFiles[i].GetLength() != 0)1251 ++num;1252 }1253 if (num == 10)1254 {1255 --num;1256 }1258 for (i = num; i >= 1; --i)1259 {1260 recentFiles[i] = recentFiles[i - 1];1261 }1262 recentFiles[0] = file;1263 }1265 void VBA::updateFrameSkip()1266 {1267 switch (systemCartridgeType)1268 {1269 case 0:1270 systemFrameSkip = frameSkip;1271 break;1272 case 1:1273 systemFrameSkip = gbFrameSkip;1274 break;1275 }1276 }1278 void VBA::updateVideoSize(UINT id)1279 {1280 int value = 0;1281 bool forceUpdate = false;1283 switch (id)1284 {1285 case ID_OPTIONS_VIDEO_X1:1286 value = VIDEO_1X;1287 forceUpdate = true;1288 break;1289 case ID_OPTIONS_VIDEO_X2:1290 value = VIDEO_2X;1291 forceUpdate = true;1292 break;1293 case ID_OPTIONS_VIDEO_X3:1294 value = VIDEO_3X;1295 forceUpdate = true;1296 break;1297 case ID_OPTIONS_VIDEO_X4:1298 value = VIDEO_4X;1299 forceUpdate = true;1300 break;1301 case ID_OPTIONS_VIDEO_FULLSCREEN320X240:1302 value = VIDEO_320x240;1303 fsWidth = 320;1304 fsHeight = 240;1305 fsColorDepth = 16;1306 break;1307 case ID_OPTIONS_VIDEO_FULLSCREEN640X480:1308 value = VIDEO_640x480;1309 fsWidth = 640;1310 fsHeight = 480;1311 fsColorDepth = 16;1312 break;1313 case ID_OPTIONS_VIDEO_FULLSCREEN800X600:1314 value = VIDEO_800x600;1315 fsWidth = 800;1316 fsHeight = 600;1317 fsColorDepth = 16;1318 break;1319 case ID_OPTIONS_VIDEO_FULLSCREEN:1320 value = VIDEO_OTHER;1321 forceUpdate = true;1322 break;1323 }1325 if (videoOption != value || forceUpdate)1326 updateWindowSize(value);1327 }1329 void VBA::updateWindowSize(int value)1330 {1331 regSetDwordValue("video", value);1333 if (value == VIDEO_OTHER)1334 {1335 regSetDwordValue("fsWidth", fsWidth);1336 regSetDwordValue("fsHeight", fsHeight);1337 regSetDwordValue("fsColorDepth", fsColorDepth);1338 }1340 if (display &&1341 (((value >= VIDEO_320x240 || videoOption >= VIDEO_320x240) && videoOption != value) ||1342 fsForceChange))1343 {1344 fsForceChange = false;1345 videoOption = value;1346 initDisplay();1347 }1349 videoOption = value;1351 if (systemCartridgeType == 1)1352 {1353 if (gbBorderOn)1354 {1355 sizeX = 256;1356 sizeY = 224;1357 gbBorderLineSkip = 256;1358 gbBorderColumnSkip = 48;1359 gbBorderRowSkip = 40;1360 }1361 else1362 {1363 sizeX = 160;1364 sizeY = 144;1365 gbBorderLineSkip = 160;1366 gbBorderColumnSkip = 0;1367 gbBorderRowSkip = 0;1368 }1369 }1370 else1371 {1372 sizeX = 240;1373 sizeY = 160;1374 }1376 switch (videoOption)1377 {1378 case VIDEO_1X:1379 surfaceSizeX = sizeX;1380 surfaceSizeY = sizeY;1381 break;1382 case VIDEO_2X:1383 surfaceSizeX = sizeX * 2;1384 surfaceSizeY = sizeY * 2;1385 break;1386 case VIDEO_3X:1387 surfaceSizeX = sizeX * 3;1388 surfaceSizeY = sizeY * 3;1389 break;1390 case VIDEO_4X:1391 surfaceSizeX = sizeX * 4;1392 surfaceSizeY = sizeY * 4;1393 break;1394 case VIDEO_320x240:1395 case VIDEO_640x480:1396 case VIDEO_800x600:1397 case VIDEO_OTHER:1398 // Need to fix this code later. For now, Fullscreen takes the whole screen.1399 if (fullScreenStretch)1400 {1401 surfaceSizeX = fsWidth;1402 surfaceSizeY = fsHeight;1403 }1404 else1405 {1406 double scaleX = (double)fsWidth / (double)sizeX;1407 double scaleY = (double)fsHeight / (double)sizeY;1408 double scaleMin = scaleX < scaleY ? scaleX : scaleY;1409 if (fsMaxScale)1410 scaleMin = scaleMin > fsMaxScale ? fsMaxScale : scaleMin;1411 surfaceSizeX = (int)(scaleMin * sizeX);1412 surfaceSizeY = (int)(scaleMin * sizeY);1413 }1414 break;1415 }1417 rect.left = 0;1418 rect.top = 0;1419 rect.right = sizeX;1420 rect.bottom = sizeY;1422 int winSizeX = 0;1423 int winSizeY = 0;1424 int x = 0;1425 int y = 0;1427 DWORD style = WS_POPUP | WS_VISIBLE;1428 DWORD styleEx = alwaysOnTop ? WS_EX_TOPMOST : 0;1430 if (videoOption <= VIDEO_4X)1431 {1432 style |= WS_OVERLAPPEDWINDOW;1434 dest.left = 0;1435 dest.top = 0;1436 dest.right = surfaceSizeX;1437 dest.bottom = surfaceSizeY;1439 x = windowPositionX;1440 y = windowPositionY;1441 }1442 else1443 {1444 dest.left = 0;1445 dest.top = 0;1446 dest.right = fsWidth;1447 dest.bottom = fsHeight;1448 }1450 AdjustWindowRectEx(&dest, style, flagHideMenu ? FALSE : TRUE, styleEx);1451 winSizeX = dest.right - dest.left;1452 winSizeY = dest.bottom - dest.top;1454 if (m_pMainWnd == NULL)1455 {1456 // Create a new window1457 m_pMainWnd = new MainWnd;1458 m_pMainWnd->CreateEx(styleEx,1459 theApp.wndClass,1460 VBA_NAME_AND_VERSION,1461 style,1462 x, y, winSizeX, winSizeY,1463 NULL,1464 0);1466 if (!(HWND)*m_pMainWnd)1467 {1468 winlog("Error creating Window %08x\n", GetLastError());1469 AfxPostQuitMessage(0);1470 return;1471 }1472 }1473 else1474 {1475 m_pMainWnd->SetWindowPos(0, //HWND_TOPMOST,1476 x,1477 y,1478 winSizeX,1479 winSizeY,1480 SWP_NOMOVE | SWP_SHOWWINDOW);1481 }1483 updateMenuBar(); // add menubar first of all, or winGetMenuBarHeight() will get random height.1484 winAccelMgr.UpdateMenu(menu);1485 adjustDestRect();1487 updateIFB();1488 updateFilter();1490 m_pMainWnd->RedrawWindow(NULL, NULL, RDW_INVALIDATE | RDW_ERASE | RDW_ALLCHILDREN);1491 }1493 bool VBA::initDisplay()1494 {1495 if (display)1496 {1497 changingVideoSize = true;1498 shutdownDisplay();1499 if (input)1500 {1501 delete input;1502 input = NULL;1503 }1504 CWnd *pWnd = m_pMainWnd;1506 m_pMainWnd = NULL;1507 pWnd->DragAcceptFiles(FALSE);1508 pWnd->DestroyWindow();1509 delete pWnd;1511 display = NULL;1512 }1514 if (display == NULL)1515 {1516 updateWindowSize(videoOption);1518 switch (renderMethod)1519 {1520 case GDI:1521 display = newGDIDisplay();1522 break;1523 case DIRECT_DRAW:1524 display = newDirectDrawDisplay();1525 break;1526 case DIRECT_3D:1527 display = newDirect3DDisplay();1528 break;1529 case OPENGL:1530 display = newOpenGLDisplay();1531 break;1532 }1534 if (display->initialize())1535 {1536 if (input == NULL)1537 {1538 if (!initInput())1539 {1540 changingVideoSize = false;1541 AfxPostQuitMessage(0);1542 return false;1543 }1544 }1546 input->checkKeys();1548 changingVideoSize = false;1549 }1550 else1551 {1552 if (videoOption == VIDEO_320x240 ||1553 videoOption == VIDEO_640x480 ||1554 videoOption == VIDEO_800x600 ||1555 videoOption == VIDEO_OTHER)1556 {1557 regSetDwordValue("video", VIDEO_1X);1558 if (pVideoDriverGUID)1559 regSetDwordValue("defaultVideoDriver", TRUE);1560 }1561 changingVideoSize = false;1562 return false;1563 }1564 }1565 changingVideoSize = false;1566 return true;1567 }1569 bool VBA::updateRenderMethod(bool force)1570 {1571 bool res = true;1572 if (force || (display && display->getType() != renderMethod))1573 {1574 res = initDisplay();1576 while (!res && renderMethod > 0)1577 {1578 if (renderMethod == OPENGL)1579 renderMethod = DIRECT_3D;1580 else if (renderMethod == DIRECT_3D)1581 renderMethod = DIRECT_DRAW;1582 else if (renderMethod == DIRECT_DRAW)1583 renderMethod = GDI;1585 res = initDisplay();1586 }1587 }1589 updateIFB();1590 updateFilter();1592 m_pMainWnd->RedrawWindow(NULL, NULL, RDW_INVALIDATE | RDW_ERASE | RDW_ALLCHILDREN);1594 regSetDwordValue("renderMethod", renderMethod);1596 return res;1597 }1599 void VBA::winCheckFullscreen()1600 {1601 if (videoOption > VIDEO_4X && tripleBuffering)1602 {1603 if (display)1604 display->checkFullScreen();1605 }1606 }1608 void VBA::shutdownDisplay()1609 {1610 if (display != NULL)1611 {1612 display->cleanup();1613 delete display;1614 display = NULL;1615 }1616 }1618 void VBA::updatePriority()1619 {1620 switch (threadPriority)1621 {1622 case 0:1623 SetThreadPriority(THREAD_PRIORITY_HIGHEST);1624 break;1625 case 1:1626 SetThreadPriority(THREAD_PRIORITY_ABOVE_NORMAL);1627 break;1628 case 3:1629 SetThreadPriority(THREAD_PRIORITY_BELOW_NORMAL);1630 break;1631 default:1632 SetThreadPriority(THREAD_PRIORITY_NORMAL);1633 }1634 }1636 #ifdef MMX1637 bool VBA::detectMMX()1638 {1639 bool support = false;1640 char brand[13];1642 // check for Intel chip1643 __try {1644 __asm {1645 mov eax, 0;1646 cpuid;1647 mov [dword ptr brand + 0], ebx;1648 mov [dword ptr brand + 4], edx;1649 mov [dword ptr brand + 8], ecx;1650 }1651 }1652 __except(EXCEPTION_EXECUTE_HANDLER) {1653 if (_exception_code() == STATUS_ILLEGAL_INSTRUCTION)1654 {1655 return false;1656 }1657 return false;1658 }1659 // Check for Intel or AMD CPUs1660 if (strncmp(brand, "GenuineIntel", 12))1661 {1662 if (strncmp(brand, "AuthenticAMD", 12))1663 {1664 return false;1665 }1666 }1668 __asm {1669 mov eax, 1;1670 cpuid;1671 test edx, 00800000h;1672 jz NotFound;1673 mov [support], 1;1674 NotFound:1675 }1676 return support;1677 }1679 #endif1681 void VBA::winSetLanguageOption(int option, bool force)1682 {1683 if (((option == languageOption) && option != 2) && !force)1684 return;1685 switch (option)1686 {1687 case 0:1688 {1689 char lbuffer[10];1691 if (GetLocaleInfo(LOCALE_SYSTEM_DEFAULT, LOCALE_SABBREVLANGNAME,1692 lbuffer, 10))1693 {1694 HINSTANCE l = winLoadLanguage(lbuffer);1695 if (l == NULL)1696 {1697 LCID locIdBase = MAKELCID(MAKELANGID(PRIMARYLANGID(GetSystemDefaultLangID()), SUBLANG_NEUTRAL), SORT_DEFAULT);1698 if (GetLocaleInfo(locIdBase, LOCALE_SABBREVLANGNAME,1699 lbuffer, 10))1700 {1701 l = winLoadLanguage(lbuffer);1702 if (l == NULL)1703 {1704 systemMessage(IDS_FAILED_TO_LOAD_LIBRARY,1705 "Failed to load library %s",1706 lbuffer);1707 return;1708 }1709 }1710 }1711 AfxSetResourceHandle(l);1712 if (languageModule != NULL)1713 /**/ ::FreeLibrary(languageModule);1714 languageModule = l;1715 }1716 else1717 {1718 systemMessage(IDS_FAILED_TO_GET_LOCINFO,1719 "Failed to get locale information");1720 return;1721 }1722 break;1723 }1724 case 1:1725 if (languageModule != NULL)1726 /**/ ::FreeLibrary(languageModule);1727 languageModule = NULL;1728 AfxSetResourceHandle(AfxGetInstanceHandle());1729 break;1730 case 2:1731 {1732 if (!force)1733 {1734 LangSelect dlg;1735 if (dlg.DoModal())1736 {1737 HINSTANCE l = winLoadLanguage(languageName);1738 if (l == NULL)1739 {1740 systemMessage(IDS_FAILED_TO_LOAD_LIBRARY,1741 "Failed to load library %s",1742 languageName);1743 return;1744 }1745 AfxSetResourceHandle(l);1746 if (languageModule != NULL)1747 /**/ ::FreeLibrary(languageModule);1748 languageModule = l;1749 }1750 }1751 else1752 {1753 if (languageName.IsEmpty())1754 return;1755 HINSTANCE l = winLoadLanguage(languageName);1756 if (l == NULL)1757 {1758 systemMessage(IDS_FAILED_TO_LOAD_LIBRARY,1759 "Failed to load library %s",1760 languageName);1761 return;1762 }1763 AfxSetResourceHandle(l);1764 if (languageModule != NULL)1765 FreeLibrary(languageModule);1766 languageModule = l;1767 }1768 break;1769 }1770 }1771 languageOption = option;1772 updateMenuBar();1773 theApp.winAccelMgr.UpdateMenu(theApp.menu);1774 }1776 HINSTANCE VBA::winLoadLanguage(const char *name)1777 {1778 CString buffer;1780 buffer.Format("vba_%s.dll", name);1782 HINSTANCE l = /**/ ::LoadLibrary(buffer);1784 if (l == NULL)1785 {1786 if (strlen(name) == 3)1787 {1788 char buffer2[3];1789 buffer2[0] = name[0];1790 buffer2[1] = name[1];1791 buffer2[2] = 0;1792 buffer.Format("vba_%s.dll", buffer2);1794 return /**/ ::LoadLibrary(buffer);1795 }1796 }1797 return l;1798 }1800 bool VBA::initInput()1801 {1802 if (input)1803 delete input;1804 input = newDirectInput();1805 if (input->initialize())1806 {1807 input->loadSettings();1808 input->checkKeys();1809 return true;1810 }1811 delete input;1812 return false;1813 }1815 void VBA::winAddUpdateListener(IUpdateListener *l)1816 {1817 updateList.AddTail(l);1818 updateCount++;1819 }1821 void VBA::winRemoveUpdateListener(IUpdateListener *l)1822 {1823 POSITION pos = updateList.Find(l);1824 if (pos)1825 {1826 updateList.RemoveAt(pos);1827 updateCount--;1828 if (updateCount < 0)1829 updateCount = 0;1830 }1831 }1833 void VBA::loadSettings()1834 {1835 CString buffer;1836 // video1837 bool defaultVideoDriver = regQueryDwordValue("defaultVideoDriver", true) ? true : false;1838 if (!regQueryBinaryValue("videoDriverGUID", (char *)&videoDriverGUID, sizeof(GUID)))1839 {1840 defaultVideoDriver = TRUE;1841 }1842 if (defaultVideoDriver)1843 pVideoDriverGUID = NULL;1844 else1845 pVideoDriverGUID = &videoDriverGUID;1847 videoOption = regQueryDwordValue("video", 0);1848 if (videoOption < 0 || videoOption > VIDEO_OTHER)1849 videoOption = 0;1850 switch (videoOption)1851 {1852 case VIDEO_320x240:1853 fsWidth = 320;1854 fsHeight = 240;1855 fsColorDepth = 16;1856 break;1857 case VIDEO_640x480:1858 fsWidth = 640;1859 fsHeight = 480;1860 fsColorDepth = 16;1861 break;1862 case VIDEO_800x600:1863 fsWidth = 800;1864 fsHeight = 600;1865 fsColorDepth = 16;1866 break;1867 }1868 if (videoOption == VIDEO_OTHER)1869 {1870 if (fsWidth < 0 || fsWidth > 4095 || fsHeight < 0 || fsHeight > 4095)1871 videoOption = 0;1872 if (fsColorDepth != 16 && fsColorDepth != 24 && fsColorDepth != 32)1873 videoOption = 0;1874 }1876 fsWidth = regQueryDwordValue("fsWidth", 0);1877 fsHeight = regQueryDwordValue("fsHeight", 0);1878 fsColorDepth = regQueryDwordValue("fsColorDepth", 0);1879 fsMaxScale = regQueryDwordValue("fsMaxScale", 0);1880 fullScreenStretch = regQueryDwordValue("stretch", 0) ? true : false;1882 renderMethod = (DISPLAY_TYPE)regQueryDwordValue("renderMethod", DIRECT_DRAW);1883 if (renderMethod < GDI || renderMethod > OPENGL)1884 renderMethod = DIRECT_DRAW;1886 ddrawEmulationOnly = regQueryDwordValue("ddrawEmulationOnly", false) ? true : false;1887 ddrawUseVideoMemory = regQueryDwordValue("ddrawUseVideoMemory", false) ? true : false;1888 tripleBuffering = regQueryDwordValue("tripleBuffering", true) ? true : false;1889 vsync = regQueryDwordValue("vsync", false) ? true : false;1891 d3dFilter = regQueryDwordValue("d3dFilter", 0);1892 if (d3dFilter < 0 || d3dFilter > 1)1893 d3dFilter = 0;1894 glFilter = regQueryDwordValue("glFilter", 0);1895 if (glFilter < 0 || glFilter > 1)1896 glFilter = 0;1897 glType = regQueryDwordValue("glType", 0);1898 if (glType < 0 || glType > 1)1899 glType = 0;1901 // pixel filter & ifb1902 filterType = regQueryDwordValue("filter", 0);1903 if (filterType < 0 || filterType > 20)1904 filterType = 0;1905 disableMMX = regQueryDwordValue("disableMMX", 0) ? true : false;1906 ifbType = regQueryDwordValue("ifbType", 0);1907 if (ifbType < 0 || ifbType > 2)1908 ifbType = 0;1910 // frame skipping1911 frameSkip = regQueryDwordValue("frameSkip", /*2*/ 0);1912 if (frameSkip < 0 || frameSkip > 9)1913 frameSkip = 1;1914 gbFrameSkip = regQueryDwordValue("gbFrameSkip", 0);1915 if (gbFrameSkip < 0 || gbFrameSkip > 9)1916 gbFrameSkip = 0;1917 /// autoFrameSkip = regQueryDwordValue("autoFrameSkip", FALSE) ? TRUE : FALSE;1919 // input1920 joypadDefault = regQueryDwordValue("joypadDefault", 0);1921 if (joypadDefault < 0 || joypadDefault > 3)1922 joypadDefault = 0;1923 allowLeftRight = regQueryDwordValue("allowLeftRight", false) ? true : false;1924 autofireAccountForLag = regQueryDwordValue("autofireAccountForLag", false) ? true : false;1925 nextframeAccountForLag = regQueryDwordValue("nextframeAccountForLag", false) ? true : false;1926 theApp.AsscWithSaveState = regQueryDwordValue("AsscWithSaveState", false) ? true : false;1928 // speed1929 throttle = regQueryDwordValue("throttle", 0);1930 if (throttle < 5 || throttle > 1000)1931 throttle = 100;1933 synchronize = regQueryDwordValue("synchronize", 1) ? true : false;1934 accuratePitchThrottle = regQueryDwordValue("accuratePitchThrottle", FALSE) ? TRUE : FALSE;1936 // sound1937 int resChannels = regQueryDwordValue("soundEnable", 0x30f);1938 soundEnableChannels(resChannels);1939 soundDisableChannels(~resChannels);1940 soundOffFlag = (regQueryDwordValue("soundOff", 0)) ? true : false;1941 soundQuality = regQueryDwordValue("soundQuality", 2);1942 soundEcho = regQueryDwordValue("soundEcho", 0) ? true : false;1943 soundLowPass = regQueryDwordValue("soundLowPass", 0) ? true : false;1944 soundReverse = regQueryDwordValue("soundReverse", 0) ? true : false;1945 soundVolume = regQueryDwordValue("soundVolume", 0);1946 if (soundVolume < 0 || soundVolume > 5)1947 soundVolume = 0;1948 muteFrameAdvance = regQueryDwordValue("muteFrameAdvance", 0) ? TRUE : FALSE;1949 muteWhenInactive = regQueryDwordValue("muteWhenInactive", 0) ? TRUE : FALSE;1951 // emulation1952 memLagEnabled = regQueryDwordValue("memLagEnabled", false) ? true : false;1953 memLagTempEnabled = memLagEnabled;1954 gbNullInputHackEnabled = regQueryDwordValue("gbNullInputHackEnabled", false) ? true : false;1955 gbNullInputHackTempEnabled = gbNullInputHackEnabled;1956 useOldSync = regQueryDwordValue("useOldSync", 0) ? TRUE : FALSE;1957 useOldFrameTiming = regQueryDwordValue("useOldGBTiming", false) ? true : false;1959 useBiosFile = regQueryDwordValue("useBios", 0) ? true : false;1960 skipBiosFile = regQueryDwordValue("skipBios", 0) ? true : false;1961 buffer = regQueryStringValue("biosFile", "");1962 if (!buffer.IsEmpty())1963 {1964 biosFileName = buffer;1965 }1966 // removeIntros = regQueryDwordValue("removeIntros", false) ? true : false;1968 autoIPS = regQueryDwordValue("autoIPS", true) ? true : false;1970 agbPrintEnable(regQueryDwordValue("agbPrint", 0) ? true : false);1971 winRtcEnable = regQueryDwordValue("rtcEnabled", 0) ? true : false;1972 rtcEnable(winRtcEnable);1974 winSaveType = regQueryDwordValue("saveType", 0);1975 if (winSaveType < 0 || winSaveType > 5)1976 winSaveType = 0;1977 cpuEnhancedDetection = regQueryDwordValue("enhancedDetection", 1) ? true : false;1978 winFlashSize = regQueryDwordValue("flashSize", 0x10000);1979 if (winFlashSize != 0x10000 && winFlashSize != 0x20000)1980 winFlashSize = 0x10000;1982 cpuDisableSfx = regQueryDwordValue("disableSfx", 0) ? true : false;1984 // GBx1985 winGbPrinterEnabled = regQueryDwordValue("gbPrinter", false) ? true : false;1986 if (winGbPrinterEnabled)1987 gbSerialFunction = gbPrinterSend;1988 else1989 gbSerialFunction = NULL;1990 gbEmulatorType = regQueryDwordValue("emulatorType", 0);1991 if (gbEmulatorType < 0 || gbEmulatorType > 5)1992 gbEmulatorType = 1;1993 winGbBorderOn = regQueryDwordValue("borderOn", 0);1994 gbBorderAutomatic = regQueryDwordValue("borderAutomatic", 0);1996 gbColorOption = regQueryDwordValue("colorOption", 0);1997 gbPaletteOption = regQueryDwordValue("gbPaletteOption", 0);1998 if (gbPaletteOption < 0)1999 gbPaletteOption = 0;2000 if (gbPaletteOption > 2)2001 gbPaletteOption = 2;2002 regQueryBinaryValue("gbPalette", (char *)systemGbPalette, 24 * sizeof(u16));2004 // head-up display2005 showSpeed = regQueryDwordValue("showSpeed", 1);2006 if (showSpeed < 0 || showSpeed > 2)2007 showSpeed = 1;2008 showSpeedTransparent = regQueryDwordValue("showSpeedTransparent", TRUE) ? TRUE : FALSE;2009 outlinedText = regQueryDwordValue("outlinedText", TRUE) != 0;2010 transparentText = regQueryDwordValue("transparentText", FALSE) != 0;2011 textColor = regQueryDwordValue("textColor", 0);2012 textMethod = regQueryDwordValue("textMethod", 1);2013 frameCounter = regQueryDwordValue("frameCounter", false) ? true : false;2014 lagCounter = regQueryDwordValue("lagCounter", false) ? true : false;2015 extraCounter = regQueryDwordValue("extraCounter", false) ? true : false;2016 inputDisplay = regQueryDwordValue("inputDisplay", false) ? true : false;2017 disableStatusMessage = regQueryDwordValue("disableStatus", 0) ? true : false;2019 // UI2020 windowPositionX = regQueryDwordValue("windowX", 0);2021 if (windowPositionX < 0)2022 windowPositionX = 0;2023 windowPositionY = regQueryDwordValue("windowY", 0);2024 if (windowPositionY < 0)2025 windowPositionY = 0;2027 autoHideMenu = regQueryDwordValue("autoHideMenu", 0) ? true : false;2029 languageOption = regQueryDwordValue("language", 1);2030 if (languageOption < 0 || languageOption > 2)2031 languageOption = 1;2032 buffer = regQueryStringValue("languageName", "");2033 if (!buffer.IsEmpty())2034 {2035 languageName = buffer.Left(3);2036 }2037 else2038 languageName = "";2039 winSetLanguageOption(languageOption, true);2041 // preferences2042 alwaysOnTop = regQueryDwordValue("alwaysOnTop", false) ? true : false;2043 pauseWhenInactive = regQueryDwordValue("pauseWhenInactive", 1) ? true : false;2044 enableBackgroundInput = regQueryDwordValue("enableBackgroundInput", 0) ? true : false;2045 threadPriority = regQueryDwordValue("priority", 2);2046 if (threadPriority < 0 || threadPriority > 3)2047 threadPriority = 2;2048 updatePriority();2050 filenamePreference = regQueryDwordValue("filenamePreference", 0);2051 altAviRecordMethod = regQueryDwordValue("altAviRecordMethod", false) ? true : false;2052 captureFormat = regQueryDwordValue("captureFormat", 0);2054 rewindTimer = regQueryDwordValue("rewindTimer", 0);2055 rewindSlots = regQueryDwordValue("rewindSlots", 64);2056 if (rewindTimer < 0 || rewindTimer > 600)2057 rewindTimer = 0;2058 if (rewindSlots <= 0)2059 rewindTimer = rewindSlots = 0;2060 if (rewindSlots > MAX_REWIND_SLOTS)2061 rewindSlots = MAX_REWIND_SLOTS;2062 if (rewindTimer != 0)2063 {2064 if (rewindMemory == NULL)2065 rewindMemory = (char *)malloc(rewindSlots * REWIND_SIZE);2066 }2068 if (frameSearchMemory == NULL)2069 frameSearchMemory = (char *)malloc(3 * REWIND_SIZE);2071 recentFreeze = regQueryDwordValue("recentFreeze", false) ? true : false;2072 for (int i = 0, j = 0; i < 10; ++i)2073 {2074 buffer.Format("recent%d", i);2075 const char *s = regQueryStringValue(buffer, NULL);2076 if (s == NULL)2077 continue;2078 recentFiles[j] = s;2079 ++j;2080 }2082 autoLoadMostRecent = regQueryDwordValue("autoLoadMostRecent", false) ? true : false;2083 loadMakesRecent = regQueryDwordValue("loadMakesRecent", false) ? true : false;2084 loadMakesCurrent = regQueryDwordValue("loadMakesCurrent", false) ? true : false;2085 saveMakesCurrent = regQueryDwordValue("saveMakesCurrent", false) ? true : false;2086 currentSlot = regQueryDwordValue("currentSlot", 0);2087 showSlotTime = regQueryDwordValue("showSlotTime", 0) ? true : false;2089 cheatsEnabled = regQueryDwordValue("cheatsEnabled", true) ? true : false;2090 autoSaveLoadCheatList = regQueryDwordValue("autoSaveCheatList", 0) ? true : false;2091 pauseDuringCheatSearch = regQueryDwordValue("pauseDuringCheatSearch2", 0) ? true : false;2093 movieOnEndBehavior = regQueryDwordValue("movieOnEndBehavior", 0);2094 movieOnEndPause = regQueryDwordValue("movieOnEndPause", 0) ? true : false;2096 extern bool autoConvertMovieWhenPlaying; // from movie.cpp2097 autoConvertMovieWhenPlaying = regQueryDwordValue("autoConvertMovieWhenPlaying", 0) ? true : false;2099 // RamWatch Settings2100 AutoRWLoad = regQueryDwordValue(AUTORWLOAD, false);2101 RWSaveWindowPos = regQueryDwordValue(RWSAVEPOS, false);2102 ramw_x = regQueryDwordValue(RAMWX, 0);2103 ramw_y = regQueryDwordValue(RAMWY, 0);2105 // this is FILO2106 for (int i = MAX_RECENT_WATCHES; i > 0; --i)2107 {2108 buffer.Format("recentWatch%d", i);2109 const char *s = regQueryStringValue(buffer, NULL);2110 if (s == NULL)2111 continue;2112 RWAddRecentFile(s);2113 }2114 }2116 void VBA::saveSettings()2117 {2118 regSetDwordValue("defaultVideoDriver", pVideoDriverGUID == NULL);2119 if (pVideoDriverGUID)2120 {2121 regSetBinaryValue("videoDriverGUID", (char *)&videoDriverGUID,2122 sizeof(GUID));2123 }2124 regSetDwordValue("video", videoOption);2126 regSetDwordValue("fsWidth", fsWidth);2127 regSetDwordValue("fsHeight", fsHeight);2128 regSetDwordValue("fsColorDepth", fsColorDepth);2129 regSetDwordValue("fsMaxScale", fsMaxScale);2131 regSetDwordValue("stretch", fullScreenStretch);2133 regSetDwordValue("renderMethod", renderMethod);2135 regSetDwordValue("ddrawEmulationOnly", ddrawEmulationOnly);2136 regSetDwordValue("ddrawUseVideoMemory", ddrawUseVideoMemory);2137 regSetDwordValue("tripleBuffering", tripleBuffering);2138 regSetDwordValue("vsync", vsync);2140 regSetDwordValue("d3dFilter", d3dFilter);2141 regSetDwordValue("glFilter", glFilter);2142 regSetDwordValue("glType", glType);2144 // pixel filter & ifb2145 regSetDwordValue("filter", filterType);2146 regSetDwordValue("ifbType", ifbType);2147 regSetDwordValue("disableMMX", disableMMX);2149 // frame skipping2150 regSetDwordValue("frameSkip", frameSkip);2151 regSetDwordValue("gbFrameSkip", gbFrameSkip);2152 /// regSetDwordValue("autoFrameSkip", autoFrameSkip);2154 // input2155 regSetDwordValue("joypadDefault", joypadDefault);2156 regSetDwordValue("allowLeftRight", allowLeftRight);2157 regSetDwordValue("autofireAccountforLag", autofireAccountForLag);2158 regSetDwordValue("nextframeAccountforLag", nextframeAccountForLag);2159 regSetDwordValue("AsscWithSaveState", theApp.AsscWithSaveState);2162 // speed2163 regSetDwordValue("throttle", throttle);2164 regSetDwordValue("synchronize", synchronize);2165 regSetDwordValue("accuratePitchThrottle", accuratePitchThrottle);2167 // sound2168 regSetDwordValue("soundEnable", soundGetEnabledChannels() & 0x030f);2169 regSetDwordValue("soundOff", soundOffFlag);2170 regSetDwordValue("soundQuality", soundQuality);2171 regSetDwordValue("soundEcho", soundEcho);2172 regSetDwordValue("soundLowPass", soundLowPass);2173 regSetDwordValue("soundReverse", soundReverse);2174 regSetDwordValue("soundVolume", soundVolume);2175 regSetDwordValue("muteFrameAdvance", muteFrameAdvance);2176 regSetDwordValue("muteWhenInactive", muteWhenInactive);2178 // emulation2179 regSetDwordValue("useBios", useBiosFile);2180 regSetDwordValue("skipBios", skipBiosFile);2181 if (!biosFileName.IsEmpty())2182 regSetStringValue("biosFile", biosFileName);2183 // regSetDwordValue("removeIntros", removeIntros);2185 regSetDwordValue("autoIPS", autoIPS);2187 regSetDwordValue("memLagEnabled", memLagEnabled);2188 regSetDwordValue("gbNullInputHackEnabled", gbNullInputHackEnabled);2189 regSetDwordValue("useOldGBTiming", useOldFrameTiming);2190 regSetDwordValue("useOldSync", useOldSync);2192 regSetDwordValue("agbPrint", agbPrintIsEnabled());2193 regSetDwordValue("rtcEnabled", winRtcEnable);2195 regSetDwordValue("saveType", winSaveType);2196 regSetDwordValue("enhancedDetection", cpuEnhancedDetection);2197 regSetDwordValue("flashSize", winFlashSize);2199 regSetDwordValue("disableSfx", cpuDisableSfx);2201 // GBx2202 regSetDwordValue("emulatorType", gbEmulatorType);2203 regSetDwordValue("gbPrinter", winGbPrinterEnabled);2204 regSetDwordValue("borderOn", winGbBorderOn);2205 regSetDwordValue("borderAutomatic", gbBorderAutomatic);2207 regSetDwordValue("colorOption", gbColorOption);2208 regSetDwordValue("gbPaletteOption", gbPaletteOption);2209 regSetBinaryValue("gbPalette", (char *)systemGbPalette, 24 * sizeof(u16));2211 // head-up display2212 regSetDwordValue("showSpeed", showSpeed);2213 regSetDwordValue("showSpeedTransparent", showSpeedTransparent);2215 regSetDwordValue("outlinedText", outlinedText);2216 regSetDwordValue("transparentText", transparentText);2217 regSetDwordValue("textColor", textColor);2218 regSetDwordValue("textMethod", textMethod);2219 regSetDwordValue("frameCounter", frameCounter);2220 regSetDwordValue("lagCounter", lagCounter);2221 regSetDwordValue("extraCounter", extraCounter);2222 regSetDwordValue("inputDisplay", inputDisplay);2223 regSetDwordValue("disableStatus", disableStatusMessage);2225 // UI2226 regSetDwordValue("windowX", windowPositionX);2227 regSetDwordValue("windowY", windowPositionY);2229 regSetDwordValue("autoHideMenu", autoHideMenu);2231 regSetDwordValue("language", languageOption);2232 regSetStringValue("languageName", languageName);2234 // preferences2235 regSetDwordValue("alwaysOnTop", alwaysOnTop);2236 regSetDwordValue("pauseWhenInactive", pauseWhenInactive);2237 regSetDwordValue("enableBackgroundInput", enableBackgroundInput);2238 regSetDwordValue("priority", threadPriority);2240 regSetDwordValue("filenamePreference", filenamePreference);2241 regSetDwordValue("altAviRecordMethod", altAviRecordMethod);2242 regSetDwordValue("captureFormat", captureFormat);2244 regSetDwordValue("cheatsEnabled", cheatsEnabled);2245 regSetDwordValue("autoSaveCheatList", autoSaveLoadCheatList);2246 regSetDwordValue("pauseDuringCheatSearch2", pauseDuringCheatSearch);2248 regSetDwordValue("rewindTimer", rewindTimer);2249 regSetDwordValue("rewindSlots", rewindSlots);2251 regSetDwordValue("recentFreeze", recentFreeze);2252 CString buffer;2253 for (int i = 0; i < 10; i++)2254 {2255 buffer.Format("recent%d", i);2256 regSetStringValue(buffer, recentFiles[i]);2257 }2259 regSetDwordValue("autoLoadMostRecent", autoLoadMostRecent);2260 regSetDwordValue("loadMakesRecent", loadMakesRecent);2261 regSetDwordValue("loadMakesCurrent", loadMakesCurrent);2262 regSetDwordValue("saveMakesCurrent", saveMakesCurrent);2263 regSetDwordValue("currentSlot", currentSlot);2264 regSetDwordValue("showSlotTime", showSlotTime);2266 regSetDwordValue("movieOnEndBehavior", movieOnEndBehavior);2267 regSetDwordValue("movieOnEndPause", movieOnEndPause);2269 extern bool autoConvertMovieWhenPlaying; // from movie.cpp2270 regSetDwordValue("autoConvertMovieWhenPlaying", autoConvertMovieWhenPlaying);2271 }