/********************************************************************************** Snes9x - Portable Super Nintendo Entertainment System (TM) emulator. (c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com), Jerremy Koot (jkoot@snes9x.com) (c) Copyright 2002 - 2004 Matthew Kendora (c) Copyright 2002 - 2005 Peter Bortas (peter@bortas.org) (c) Copyright 2004 - 2005 Joel Yliluoma (http://iki.fi/bisqwit/) (c) Copyright 2001 - 2006 John Weidman (jweidman@slip.net) (c) Copyright 2002 - 2006 funkyass (funkyass@spam.shaw.ca), Kris Bleakley (codeviolation@hotmail.com) (c) Copyright 2002 - 2007 Brad Jorsch (anomie@users.sourceforge.net), Nach (n-a-c-h@users.sourceforge.net), zones (kasumitokoduck@yahoo.com) (c) Copyright 2006 - 2007 nitsuja BS-X C emulator code (c) Copyright 2005 - 2006 Dreamer Nom, zones C4 x86 assembler and some C emulation code (c) Copyright 2000 - 2003 _Demo_ (_demo_@zsnes.com), Nach, zsKnight (zsknight@zsnes.com) C4 C++ code (c) Copyright 2003 - 2006 Brad Jorsch, Nach DSP-1 emulator code (c) Copyright 1998 - 2006 _Demo_, Andreas Naive (andreasnaive@gmail.com) Gary Henderson, Ivar (ivar@snes9x.com), John Weidman, Kris Bleakley, Matthew Kendora, Nach, neviksti (neviksti@hotmail.com) DSP-2 emulator code (c) Copyright 2003 John Weidman, Kris Bleakley, Lord Nightmare (lord_nightmare@users.sourceforge.net), Matthew Kendora, neviksti DSP-3 emulator code (c) Copyright 2003 - 2006 John Weidman, Kris Bleakley, Lancer, z80 gaiden DSP-4 emulator code (c) Copyright 2004 - 2006 Dreamer Nom, John Weidman, Kris Bleakley, Nach, z80 gaiden OBC1 emulator code (c) Copyright 2001 - 2004 zsKnight, pagefault (pagefault@zsnes.com), Kris Bleakley, Ported from x86 assembler to C by sanmaiwashi SPC7110 and RTC C++ emulator code (c) Copyright 2002 Matthew Kendora with research by zsKnight, John Weidman, Dark Force S-DD1 C emulator code (c) Copyright 2003 Brad Jorsch with research by Andreas Naive, John Weidman S-RTC C emulator code (c) Copyright 2001-2006 byuu, John Weidman ST010 C++ emulator code (c) Copyright 2003 Feather, John Weidman, Kris Bleakley, Matthew Kendora Super FX x86 assembler emulator code (c) Copyright 1998 - 2003 _Demo_, pagefault, zsKnight, Super FX C emulator code (c) Copyright 1997 - 1999 Ivar, Gary Henderson, John Weidman Sound DSP emulator code is derived from SNEeSe and OpenSPC: (c) Copyright 1998 - 2003 Brad Martin (c) Copyright 1998 - 2006 Charles Bilyue' SH assembler code partly based on x86 assembler code (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se) 2xSaI filter (c) Copyright 1999 - 2001 Derek Liauw Kie Fa HQ2x, HQ3x, HQ4x filters (c) Copyright 2003 Maxim Stepin (maxim@hiend3d.com) Win32 GUI code (c) Copyright 2003 - 2006 blip, funkyass, Matthew Kendora, Nach, nitsuja Mac OS GUI code (c) Copyright 1998 - 2001 John Stiles (c) Copyright 2001 - 2007 zones Specific ports contains the works of other authors. See headers in individual files. Snes9x homepage: http://www.snes9x.com Permission to use, copy, modify and/or distribute Snes9x in both binary and source form, for non-commercial purposes, is hereby granted without fee, providing that this license information and copyright notice appear with all copies and any derived work. This software is provided 'as-is', without any express or implied warranty. In no event shall the authors be held liable for any damages arising from the use of this software or it's derivatives. Snes9x is freeware for PERSONAL USE only. Commercial users should seek permission of the copyright holders first. Commercial use includes, but is not limited to, charging money for Snes9x or software derived from Snes9x, including Snes9x or derivatives in commercial game bundles, and/or using Snes9x as a promotion for your commercial product. The copyright holders request that bug fixes and improvements to the code should be forwarded to them so everyone can benefit from the modifications in future versions. Super NES and Super Nintendo Entertainment System are trademarks of Nintendo Co., Limited and its subsidiary companies. **********************************************************************************/ // Win32 GUI code // (c) Copyright 2003-2006 blip, Nach, Matthew Kendora, funkyass and nitsuja #ifdef __MINGW32__ #define _WIN32_IE 0x0501 #define _WIN32_WINNT 0x0501 #endif #include #include #include "wsnes9x.h" #include "directx.h" #include "../snes9x.h" #include "../memmap.h" #include "../cpuexec.h" #include "../display.h" #include "../3d.h" #include "../cheats.h" #include "../netplay.h" #include "../apu.h" #include "../movie.h" #include "../controls.h" #include "../conffile.h" #include "../soundux.h" #include "AVIOutput.h" #include "InputCustom.h" #include #include #if (((defined(_MSC_VER) && _MSC_VER >= 1300)) || defined(__MINGW32__)) // both MINGW and VS.NET use fstream instead of fstream.h which is deprecated #include using namespace std; #else // for VC++ 6 #include #endif #include //#include "string_cache.h" #include "wlanguage.h" #include "../language.h" //uncomment to find memory leaks, with a line in WinMain //#define CHECK_MEMORY_LEAKS #ifdef CHECK_MEMORY_LEAKS #include #endif #include #include #include #include extern SNPServer NPServer; #ifdef USE_OPENGL OpenGLData OpenGL; #endif #include #ifdef FMOD_SUPPORT #include "fmod.h" #endif #ifdef _MSC_VER #define F_OK 0 #define X_OK 1 #define W_OK 2 #define R_OK 4 #endif __int64 PCBase, PCFrameTime, PCFrameTimeNTSC, PCFrameTimePAL, PCStart, PCEnd; DWORD PCStartTicks, PCEndTicks; #ifdef RTC_DEBUGGER int CALLBACK SPC7110rtc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam); #endif int CALLBACK DlgSP7PackConfig(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam); int CALLBACK DlgSoundConf(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam); int CALLBACK DlgInfoProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam); int CALLBACK DlgAboutProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam); int CALLBACK DlgEmulatorProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam); int CALLBACK DlgOpenROMProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam); int CALLBACK DlgMultiROMProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam); LRESULT CALLBACK DlgChildSplitProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam); int CALLBACK DlgNPProgress(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam); int CALLBACK DlgPackConfigProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam); int CALLBACK DlgNetConnect(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam); int CALLBACK DlgNPOptions(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam); int CALLBACK DlgFunky(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam); int CALLBACK DlgInputConfig(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam); int CALLBACK DlgHotkeyConfig(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam); int CALLBACK DlgCheater(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam); int CALLBACK DlgCheatSearch(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam); int CALLBACK DlgCheatSearchAdd(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam); int CALLBACK DlgCreateMovie(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam); int CALLBACK DlgOpenMovie(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam); HRESULT CALLBACK EnumModesCallback( LPDDSURFACEDESC lpDDSurfaceDesc, LPVOID lpContext); int CALLBACK test(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam); #ifdef RTC_DEBUGGER //Messages for sliders (for some reason they don't get included during the build) #define TBM_GETPOS (WM_USER) #define TBM_GETRANGEMIN (WM_USER+1) #define TBM_GETRANGEMAX (WM_USER+2) #define TBM_GETTIC (WM_USER+3) #define TBM_SETTIC (WM_USER+4) #define TBM_SETPOS (WM_USER+5) #define TBM_SETRANGE (WM_USER+6) #define TBM_SETRANGEMIN (WM_USER+7) #define TBM_SETRANGEMAX (WM_USER+8) #define TBM_CLEARTICS (WM_USER+9) #define TBM_SETSEL (WM_USER+10) #define TBM_SETSELSTART (WM_USER+11) #define TBM_SETSELEND (WM_USER+12) #define TBM_GETPTICS (WM_USER+14) #define TBM_GETTICPOS (WM_USER+15) #define TBM_GETNUMTICS (WM_USER+16) #define TBM_GETSELSTART (WM_USER+17) #define TBM_GETSELEND (WM_USER+18) #define TBM_CLEARSEL (WM_USER+19) #define TBM_SETTICFREQ (WM_USER+20) #define TBM_SETPAGESIZE (WM_USER+21) #define TBM_GETPAGESIZE (WM_USER+22) #define TBM_SETLINESIZE (WM_USER+23) #define TBM_GETLINESIZE (WM_USER+24) #define TBM_GETTHUMBRECT (WM_USER+25) #define TBM_GETCHANNELRECT (WM_USER+26) #define TBM_SETTHUMBLENGTH (WM_USER+27) #define TBM_GETTHUMBLENGTH (WM_USER+28) #endif #define NOTKNOWN "Unknown Company " #define HEADER_SIZE 512 #define INFO_LEN (0xFF - 0xC0) #define WM_CUSTKEYDOWN (WM_USER+50) #define WM_CUSTKEYUP (WM_USER+51) /*****************************************************************************/ /* Global variables */ /*****************************************************************************/ struct sGUI GUI; typedef struct sExtList { TCHAR* extension; bool compressed; struct sExtList* next; } ExtList; ExtList* valid_ext=NULL; void MakeExtFile(void); void LoadExts(void); extern FILE *trace_fs; extern SCheatData Cheat; extern bool8 do_frame_adjust; HINSTANCE g_hInst; #ifdef DEBUGGER extern "C" void Trace (); #endif static const char *rom_filename = NULL; CDirectX DirectX; struct SJoypad Joypad[16] = { { true, /* Joypad 1 enabled */ VK_LEFT, VK_RIGHT, VK_UP, VK_DOWN, /* Left, Right, Up, Down */ 0, 0, 0, 0, /* Left_Up, Left_Down, Right_Up, Right_Down */ VK_SPACE, VK_RETURN, /* Start, Select */ 'V', 'C', /* A B */ 'D', 'X', /* X Y */ 'A', 'S' /* L R */ }, { true, /* Joypad 2 enabled */ 'J', 'L', 'I', 'K', /* Left, Right, Up, Down */ 0, 0, 0, 0, /* Left_Up, Left_Down, Right_Up, Right_Down */ 'P', 'O', /* Start, Select */ 'H', 'G', /* A B */ 'T', 'F', /* X Y */ 'Y', 'U' /* L R */ }, { false, /* Joypad 3 disabled */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { false, /* Joypad 4 disabled */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { false, /* Joypad 5 disabled */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { false, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },/* Joypad 6 disabled */ { false, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },/* Joypad 7 disabled */ { false, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },/* Joypad 8 disabled */ { false, /* Joypad 1 Turbo disabled */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { false, /* Joypad 2 Turbo disabled */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { false, /* Joypad 3 Turbo disabled */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { false, /* Joypad 4 Turbo disabled */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { false, /* Joypad 5 Turbo disabled */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { false, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },/* Joypad 6 Turbo disabled */ { false, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },/* Joypad 7 Turbo disabled */ { false, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },/* Joypad 8 Turbo disabled */ }; // stores on/off toggle info for each key of each controller SJoypad ToggleJoypadStorage [8] = { { false, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { false, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { false, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { false, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { false, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { false, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { false, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { false, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, }; SJoypad TurboToggleJoypadStorage [8] = { { false, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { false, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { false, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { false, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { false, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { false, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { false, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { false, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, }; struct SCustomKeys CustomKeys = { {/*VK_OEM_PLUS*/0xBB,0}, // speed+ (=) {/*VK_OEM_MINUS*/0xBD,0}, // speed- (-) {VK_PAUSE,0}, // pause (PAUSE) {/*VK_OEM_5*/0xDC,0}, // frame advance (\) {/*VK_OEM_PLUS*/0xBB,CUSTKEY_SHIFT_MASK}, // skip+ (_) {/*VK_OEM_MINUS*/0xBD,CUSTKEY_SHIFT_MASK}, // skip- (+) {/*VK_OEM_3*/0xC0,0}, // superscope turbo (`) {/*VK_OEM_2*/0xBF,0}, // superscope pause (/) {/*VK_OEM_PERIOD*/0xBE,0}, // frame counter (.) {'8',CUSTKEY_SHIFT_MASK}, // movie read-only (*) {{VK_F1,CUSTKEY_SHIFT_MASK}, // save keys {VK_F2,CUSTKEY_SHIFT_MASK}, {VK_F3,CUSTKEY_SHIFT_MASK}, {VK_F4,CUSTKEY_SHIFT_MASK}, {VK_F5,CUSTKEY_SHIFT_MASK}, {VK_F6,CUSTKEY_SHIFT_MASK}, {VK_F7,CUSTKEY_SHIFT_MASK}, {VK_F8,CUSTKEY_SHIFT_MASK}, {VK_F9,CUSTKEY_SHIFT_MASK}, {VK_F10,CUSTKEY_SHIFT_MASK}}, {{VK_F1,0}, // load keys {VK_F2,0}, {VK_F3,0}, {VK_F4,0}, {VK_F5,0}, {VK_F6,0}, {VK_F7,0}, {VK_F8,0}, {VK_F9,0}, {VK_F10,0}}, {VK_TAB,0}, // fast forward (TAB) {/*VK_OEM_COMMA*/0xBC,0}, // show pressed keys/buttons (,) {VK_F12,0}, // save screenshot (F12) {0,0}, // slot plus (disabled by default) {0,0}, // slot minus (disabled by default) {0,0}, // slot save (disabled by default) {0,0}, // slot load (disabled by default) {'1',0}, // background layer 1 {'2',0}, // background layer 2 {'3',0}, // background layer 3 {'4',0}, // background layer 4 {'5',0}, // sprite layer {'8',0}, // Clipping Windows // {'8',0}, // BG Layering hack {'9',0}, // Transparency {'0',0}, // HDMA Emulation {'6',CUSTKEY_SHIFT_MASK}, // GLCube Mode // {'9',CUSTKEY_SHIFT_MASK}, // Interpolate Mode 7 {'6',0}, // Joypad Swap {'7',0}, // Switch Controllers {VK_NEXT,CUSTKEY_SHIFT_MASK}, // Turbo A {VK_END,CUSTKEY_SHIFT_MASK}, // Turbo B {VK_HOME,CUSTKEY_SHIFT_MASK}, // Turbo Y {VK_PRIOR,CUSTKEY_SHIFT_MASK}, // Turbo X {VK_INSERT,CUSTKEY_SHIFT_MASK}, // Turbo L {VK_DELETE,CUSTKEY_SHIFT_MASK}, // Turbo R {0,0}, // Turbo Start {0,0}, // Turbo Select {0,0}, // Turbo Left {0,0}, // Turbo Up {0,0}, // Turbo Right {0,0}, // Turbo Down {{0,0}, // Select save slot 0 {0,0}, // Select save slot 1 {0,0}, // Select save slot 2 {0,0}, // Select save slot 3 {0,0}, // Select save slot 4 {0,0}, // Select save slot 5 {0,0}, // Select save slot 6 {0,0}, // Select save slot 7 {0,0}, // Select save slot 8 {0,0}}, // Select save slot 9 {'R',CUSTKEY_CTRL_MASK|CUSTKEY_SHIFT_MASK}, // Reset Game {0,0}, // Toggle Cheats }; struct SSoundRates { uint32 rate; int ident; } SoundRates[9] = { { 8000, ID_SOUND_8000HZ}, {11025, ID_SOUND_11025HZ}, {16000, ID_SOUND_16000HZ}, {22050, ID_SOUND_22050HZ}, {30000, ID_SOUND_30000HZ}, {32000, ID_SOUND_32000HZ}, {35000, ID_SOUND_35000HZ}, {44100, ID_SOUND_44100HZ}, {48000, ID_SOUND_48000HZ} }; static uint32 FrameTimings[] = { 4000, 4000, 8333, 11667, 16667, 20000, 33333, 66667, 133333, 300000, 500000, 1000000, 1000000 }; // Languages supported by Snes9X: Windows // 0 - English [Default] // 1 - Dutch/Nederlands struct sLanguages Languages[] = { { IDR_MENU_US, TEXT("DirectX failed to initialize!"), TEXT("DirectDraw failed to set the selected display mode!"), TEXT("DirectSound failed to initialize; no sound will be played."), TEXT("These settings won't take effect until you restart the emulator."), TEXT("The frame timer failed to initialize, please do NOT select the automatic framerate option or Snes9X will crash!")}, { IDR_MENU_NL, TEXT("Er is een fout opgetreden tijdens het initalizeren van DirectX!"), TEXT("Er is een fout opgetreden tijdens het verander van scherm modus!"), TEXT("Er is een fout opgetreden tijdens het initializeren van DirectSound, er zal geen geluid worden afgespeeld."), TEXT("Deze opties worden pas toegepast als de emulator opnieuw is opgestart."), TEXT("Er is een fout opgetreden tijdens het initializeren van de frame timer, kies NIET de automatische framerate optie want dan zal Snes9X crashen!")} }; struct OpenMovieParams { char Path[_MAX_PATH]; bool8 ReadOnly; bool8 DisplayInput; uint8 ControllersMask; uint8 Opts; uint8 SyncFlags; wchar_t Metadata[MOVIE_MAX_METADATA]; }; struct dMode { long height; long width; long depth; long rate; int status; }; std::vector dm; /*****************************************************************************/ /* WinProc */ /*****************************************************************************/ void DoAVIOpen(const char* filename); void DoAVIClose(int reason); bool8 SetupSound( long rate, bool8 sixteen_bit, bool8 stereo); void RestoreGUIDisplay (); void RestoreSNESDisplay (); void FreezeUnfreeze (int slot, bool8 freeze); void CheckDirectoryIsWritable (const char *filename); static void CheckMenuStates (); static void ResetFrameTimer (); bool8 LoadROM (const char *filename); bool8 LoadMultiROM (const char *filename, const char *filename2); #ifdef NETPLAY_SUPPORT static void EnableServer (bool8 enable); #endif void WinDeleteRecentGamesList (); const char* WinParseCommandLineAndLoadConfigFile (char *line); void WinRegisterConfigItems (); void WinSaveConfigFile (); void WinSetDefaultValues (); void WinLockConfigFile (); void WinUnlockConfigFile (); void WinCleanupConfigData (); #ifdef USE_DIRECTX3D void D3DMove (HWND, LPARAM); void D3DSizeChange (HWND, WPARAM); #endif #include "../ppu.h" #include "../snapshot.h" extern "C" const char *S9xGetFilename (const char *, enum s9x_getdirtype dirtype); const char *S9xGetFilenameInc (const char *); void S9xSetRecentGames (); void S9xAddToRecentGames (const char *filename); void S9xRemoveFromRecentGames (int i); extern void S9xReRefresh(); static void absToRel(char* relPath, const char* absPath, const char* baseDir) { strcpy(relPath, absPath); if(!strncasecmp(absPath, baseDir, strlen(baseDir))) { char temp [MAX_PATH]; temp[MAX_PATH-3]='\0'; const char* relative = absPath+strlen(baseDir); while(relative[0]=='\\' || relative[0]=='/') relative++; relPath[0]='.'; relPath[1]='\\'; strcpy(relPath+2, relative); } } void S9xMouseOn () { if(Settings.StopEmulation) return; if (GUI.ControllerOption==SNES_MOUSE || GUI.ControllerOption==SNES_MOUSE_SWAPPED) { if(Settings.Paused) SetCursor (GUI.Arrow); else SetCursor (NULL); } else if (GUI.ControllerOption!=SNES_SUPERSCOPE && GUI.ControllerOption!=SNES_JUSTIFIER && GUI.ControllerOption!=SNES_JUSTIFIER_2) { SetCursor (GUI.Arrow); GUI.CursorTimer = 60; } else { if(Settings.Paused) SetCursor (GUI.GunSight); else SetCursor (NULL); } } void ChangeInputDevice(void) { Settings.MouseMaster = false; Settings.JustifierMaster = false; Settings.SuperScopeMaster = false; Settings.MultiPlayer5Master = false; CheckMenuItem(GUI.hMenu, IDM_ENABLE_MULTITAP, MFS_UNCHECKED); CheckMenuItem(GUI.hMenu, IDM_JUSTIFIER, MFS_UNCHECKED); CheckMenuItem(GUI.hMenu, IDM_MOUSE_TOGGLE, MFS_UNCHECKED); CheckMenuItem(GUI.hMenu, IDM_SCOPE_TOGGLE, MFS_UNCHECKED); CheckMenuItem(GUI.hMenu, IDM_MOUSE_SWAPPED, MFS_UNCHECKED); CheckMenuItem(GUI.hMenu, IDM_JUSTIFIERS, MFS_UNCHECKED); CheckMenuItem(GUI.hMenu, IDM_MULTITAP8, MFS_UNCHECKED); CheckMenuItem(GUI.hMenu, IDM_SNES_JOYPAD, MFS_UNCHECKED); switch(GUI.ControllerOption) { case SNES_MOUSE: Settings.MouseMaster = true; S9xSetController(0, CTL_MOUSE, 0, 0, 0, 0); S9xSetController(1, CTL_JOYPAD, 1, 0, 0, 0); CheckMenuItem(GUI.hMenu, IDM_MOUSE_TOGGLE, MFS_CHECKED); break; case SNES_MOUSE_SWAPPED: Settings.MouseMaster = true; S9xSetController(0, CTL_JOYPAD, 0, 0, 0, 0); S9xSetController(1, CTL_MOUSE, 1, 0, 0, 0); CheckMenuItem(GUI.hMenu, IDM_MOUSE_SWAPPED, MFS_CHECKED); break; case SNES_SUPERSCOPE: Settings.SuperScopeMaster = true; S9xSetController(0, CTL_JOYPAD, 0, 0, 0, 0); S9xSetController(1, CTL_SUPERSCOPE, 0, 0, 0, 0); CheckMenuItem(GUI.hMenu, IDM_SCOPE_TOGGLE, MFS_CHECKED); break; case SNES_MULTIPLAYER5: Settings.MultiPlayer5Master = true; S9xSetController(0, CTL_JOYPAD, 0, 0, 0, 0); S9xSetController(1, CTL_MP5, 1, 2, 3, 4); CheckMenuItem(GUI.hMenu, IDM_ENABLE_MULTITAP, MFS_CHECKED); break; case SNES_MULTIPLAYER8: Settings.MultiPlayer5Master = true; S9xSetController(0, CTL_MP5, 0, 1, 2, 3); S9xSetController(1, CTL_MP5, 4, 5, 6, 7); CheckMenuItem(GUI.hMenu, IDM_ENABLE_MULTITAP, MFS_CHECKED); break; case SNES_JUSTIFIER: Settings.JustifierMaster = true; S9xSetController(0, CTL_JOYPAD, 0, 0, 0, 0); S9xSetController(1, CTL_JUSTIFIER, 0, 0, 0, 0); CheckMenuItem(GUI.hMenu, IDM_JUSTIFIER, MFS_CHECKED); break; case SNES_JUSTIFIER_2: Settings.JustifierMaster = true; S9xSetController(0, CTL_JOYPAD, 0, 0, 0, 0); S9xSetController(1, CTL_JUSTIFIER, 1, 0, 0, 0); CheckMenuItem(GUI.hMenu, IDM_JUSTIFIERS, MFS_CHECKED); break; default: case SNES_JOYPAD: S9xSetController(0, CTL_JOYPAD, 0, 0, 0, 0); S9xSetController(1, CTL_JOYPAD, 1, 0, 0, 0); CheckMenuItem(GUI.hMenu, IDM_SNES_JOYPAD, MFS_CHECKED); break; } GUI.ControlForced = 0xff; } static void CenterCursor() { if(GUI.ControllerOption==SNES_MOUSE || GUI.ControllerOption==SNES_MOUSE_SWAPPED) { if(GUI.hWnd == GetActiveWindow() && !S9xMoviePlaying()) { POINT cur, middle; RECT size; GetClientRect (GUI.hWnd, &size); middle.x = (size.right - size.left) >> 1; middle.y = (size.bottom - size.top) >> 1; ClientToScreen (GUI.hWnd, &middle); GetCursorPos (&cur); int dX = middle.x-cur.x; int dY = middle.y-cur.y; if(dX || dY) { GUI.MouseX -= dX; GUI.MouseY -= dY; SetCursorPos (middle.x, middle.y); // GUI.IgnoreNextMouseMove = true; } } } } void S9xRestoreWindowTitle () { TCHAR buf [100]; sprintf (buf, TEXT(WINDOW_TITLE), VERSION); SetWindowText (GUI.hWnd, buf); } void SwitchToGDI() { if (!VOODOO_MODE && !OPENGL_MODE) { IPPU.ColorsChanged = true; DirectX.lpDD->FlipToGDISurface(); GUI.FlipCounter = 0; DirectX.lpDDSPrimary2->SetPalette (NULL); } } static void S9xClearSurface (LPDIRECTDRAWSURFACE2 lpDDSurface) { DDBLTFX fx; memset (&fx, 0, sizeof (fx)); fx.dwSize = sizeof (fx); while (lpDDSurface->Blt (NULL, DirectX.lpDDSPrimary2, NULL, DDBLT_WAIT, NULL) == DDERR_SURFACELOST) lpDDSurface->Restore (); } void UpdateBackBuffer() { GUI.ScreenCleared = true; if (!VOODOO_MODE && !OPENGL_MODE && GUI.FullScreen) { SwitchToGDI(); DDBLTFX fx; memset (&fx, 0, sizeof (fx)); fx.dwSize = sizeof (fx); while (DirectX.lpDDSPrimary2->Blt (NULL, NULL, NULL, DDBLT_WAIT | DDBLT_COLORFILL, &fx) == DDERR_SURFACELOST) DirectX.lpDDSPrimary2->Restore (); if (GetMenu (GUI.hWnd) != NULL) DrawMenuBar (GUI.hWnd); GUI.FlipCounter = 0; DDSCAPS caps; caps.dwCaps = DDSCAPS_BACKBUFFER; LPDIRECTDRAWSURFACE2 pDDSurface; if (DirectX.lpDDSPrimary2->GetAttachedSurface (&caps, &pDDSurface) == DD_OK && pDDSurface != NULL) { S9xClearSurface (pDDSurface); DirectX.lpDDSPrimary2->Flip (NULL, DDFLIP_WAIT); while (DirectX.lpDDSPrimary2->GetFlipStatus (DDGFS_ISFLIPDONE) != DD_OK) Sleep (0); if(DirectX.DoubleBuffered) S9xClearSurface (pDDSurface); } } else { if (GetMenu( GUI.hWnd) != NULL) DrawMenuBar (GUI.hWnd); } } void ToggleFullScreen () { S9xSetPause (PAUSE_TOGGLE_FULL_SCREEN); #ifdef USE_GLIDE if (VOODOO_MODE) { // S9xGlideEnable (FALSE); // GUI.Scale = 0; // MoveWindow (GUI.hWnd, GUI.window_size.left, // GUI.window_size.top, // GUI.window_size.right - GUI.window_size.left, // GUI.window_size.bottom - GUI.window_size.top, TRUE); } else #endif #ifdef USE_OPENGL if (OPENGL_MODE) { if (!GUI.FullScreen) { DEVMODE dmScreenSettings; memset (&dmScreenSettings, 0, sizeof(dmScreenSettings)); dmScreenSettings.dmSize = sizeof(dmScreenSettings); dmScreenSettings.dmPelsWidth = GUI.Width; dmScreenSettings.dmPelsHeight = GUI.Height; dmScreenSettings.dmBitsPerPel = 16; //bits; dmScreenSettings.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT; if (ChangeDisplaySettings (&dmScreenSettings, CDS_FULLSCREEN) == DISP_CHANGE_SUCCESSFUL) { GUI.FullScreen = TRUE; SetWindowLong (GUI.hWnd, GWL_STYLE, WS_POPUP | WS_VISIBLE); SetWindowPos (GUI.hWnd, HWND_TOP, 0, 0, GUI.Width, GUI.Height, SWP_DRAWFRAME|SWP_FRAMECHANGED); } } else { bool maximized = GUI.window_maximized; SetWindowLong (GUI.hWnd, GWL_STYLE, WS_POPUPWINDOW|WS_CAPTION| WS_THICKFRAME|WS_VISIBLE|WS_MINIMIZEBOX|WS_MAXIMIZEBOX); SetWindowPos (GUI.hWnd, HWND_TOP, GUI.window_size.left, GUI.window_size.top, GUI.window_size.right - GUI.window_size.left, GUI.window_size.bottom - GUI.window_size.top, SWP_DRAWFRAME|SWP_FRAMECHANGED); if(maximized) ShowWindow(GUI.hWnd, SW_MAXIMIZE); ChangeDisplaySettings (NULL, 0); GUI.FullScreen = FALSE; } } else { #endif //if (!VOODOO_MODE && !GUI.FullScreen) // GetWindowRect (GUI.hWnd, &GUI.window_size); if (!DirectX.SetDisplayMode (GUI.Width, GUI.Height, max(GetFilterScale(GUI.Scale), GetFilterScale(GUI.ScaleHiRes)), GUI.Depth, GUI.RefreshRate, GUI.FullScreen, GUI.DoubleBuffered)) { MessageBox( GUI.hWnd, Languages[ GUI.Language].errModeDD, TEXT("Snes9X - DirectDraw(2)"), MB_OK | MB_ICONSTOP); S9xClearPause (PAUSE_TOGGLE_FULL_SCREEN); return; } GUI.FullScreen = !GUI.FullScreen; if (!GUI.FullScreen) { SwitchToGDI(); bool maximized = GUI.window_maximized; MoveWindow (GUI.hWnd, GUI.window_size.left, GUI.window_size.top, GUI.window_size.right - GUI.window_size.left, GUI.window_size.bottom - GUI.window_size.top, TRUE); if(maximized) ShowWindow(GUI.hWnd, SW_MAXIMIZE); } #if defined(USE_GLIDE) || defined (USE_OPENGL) } #endif S9xGraphicsDeinit(); S9xSetWinPixelFormat (); S9xInitUpdate(); S9xGraphicsInit(); IPPU.RenderThisFrame = true; UpdateBackBuffer(); S9xClearPause (PAUSE_TOGGLE_FULL_SCREEN); } void S9xDisplayStateChange (const char *str, bool8 on) { static char string [100]; sprintf (string, "%s %s", str, on ? "on" : "off"); S9xSetInfoString (string); } static void UpdateScale(RenderFilter & Scale, RenderFilter & NextScale) { if (IS_GL_OR_GLIDE(Scale) == IS_GL_OR_GLIDE(NextScale)) Scale = NextScale; else { if (IS_GLIDE_MODE(NextScale) || (IS_GL_MODE(NextScale) && !S9xOpenGLInit ()) || (!IS_GL_OR_GLIDE(NextScale) && !DirectX.InitDirectX())) { Scale = FILTER_NONE; NextScale = FILTER_NONE; MessageBox (GUI.hWnd, TEXT(WINPROC_FILTER_RESTART), TEXT(SNES9X_INFO), MB_OK | MB_ICONINFORMATION); } else { S9xGraphicsDeinit(); Scale = NextScale; Settings.OpenGLEnable = IS_GL_MODE(Scale); Settings.GlideEnable = IS_GLIDE_MODE(Scale); S9xSetWinPixelFormat (); S9xInitUpdate(); S9xGraphicsInit(); } } } static char InfoString [100]; static uint32 prevPadReadFrame = (uint32)-1; static bool skipNextFrameStop = false; int HandleKeyMessage(WPARAM wParam, LPARAM lParam) { // update toggles for (int J = 0; J < 5; J++) { extern bool S9xGetState (WORD KeyIdent); if(Joypad[J].Enabled && (!S9xGetState(Joypad[J+8].Left))) // enabled and Togglify { SJoypad & p = ToggleJoypadStorage[J]; if(wParam == Joypad[J].L) p.L = !p.L; if(wParam == Joypad[J].R) p.R = !p.R; if(wParam == Joypad[J].A) p.A = !p.A; if(wParam == Joypad[J].B) p.B = !p.B; if(wParam == Joypad[J].Y) p.Y = !p.Y; if(wParam == Joypad[J].X) p.X = !p.X; if(wParam == Joypad[J].Start) p.Start = !p.Start; if(wParam == Joypad[J].Select) p.Select = !p.Select; if(wParam == Joypad[J].Left) p.Left = !p.Left; if(wParam == Joypad[J].Right) p.Right = !p.Right; if(wParam == Joypad[J].Up) p.Up = !p.Up; if(wParam == Joypad[J].Down) p.Down = !p.Down; /// if(wParam == Joypad[J].Left_Down) p.Left_Down = !p.Left_Down; /// if(wParam == Joypad[J].Left_Up) p.Left_Up = !p.Left_Up; /// if(wParam == Joypad[J].Right_Down) p.Right_Down = !p.Right_Down; /// if(wParam == Joypad[J].Right_Up) p.Right_Up = !p.Right_Up; if(!Settings.UpAndDown) { if(p.Left && p.Right) p.Left = p.Right = false; if(p.Up && p.Down) p.Up = p.Down = false; } } if(Joypad[J].Enabled && (!S9xGetState(Joypad[J+8].Down))) // enabled and turbo-togglify (TurboTog) { SJoypad & p = TurboToggleJoypadStorage[J]; if(wParam == Joypad[J].L) p.L = !p.L; if(wParam == Joypad[J].R) p.R = !p.R; if(wParam == Joypad[J].A) p.A = !p.A; if(wParam == Joypad[J].B) p.B = !p.B; if(wParam == Joypad[J].Y) p.Y = !p.Y; if(wParam == Joypad[J].X) p.X = !p.X; if(wParam == Joypad[J].Start) p.Start = !p.Start; if(wParam == Joypad[J].Select) p.Select = !p.Select; /// if(wParam == Joypad[J].Left) p.Left = !p.Left; /// if(wParam == Joypad[J].Right) p.Right = !p.Right; /// if(wParam == Joypad[J].Up) p.Up = !p.Up; /// if(wParam == Joypad[J].Down) p.Down = !p.Down; /// if(wParam == Joypad[J].Left_Down) p.Left_Down = !p.Left_Down; /// if(wParam == Joypad[J].Left_Up) p.Left_Up = !p.Left_Up; /// if(wParam == Joypad[J].Right_Down) p.Right_Down = !p.Right_Down; /// if(wParam == Joypad[J].Right_Up) p.Right_Up = !p.Right_Up; /* if(!Settings.UpAndDown) { if(p.Left && p.Right && ) p.Left = p.Right = false; if(p.Up && p.Down) p.Up = p.Down = false; }*/ } if(wParam == Joypad[J+8].Right) // clear all { { SJoypad & p = ToggleJoypadStorage[J]; p.L = false; p.R = false; p.A = false; p.B = false; p.Y = false; p.X = false; p.Start = false; p.Select = false; p.Left = false; p.Right = false; p.Up = false; p.Down = false; } { SJoypad & p = TurboToggleJoypadStorage[J]; p.L = false; p.R = false; p.A = false; p.B = false; p.Y = false; p.X = false; p.Start = false; p.Select = false; p.Left = false; p.Right = false; p.Up = false; p.Down = false; } } } bool hitHotKey = false; if(!(wParam == 0 || wParam == VK_ESCAPE)) // if it's the 'disabled' key, it's never pressed as a hotkey { int modifiers = 0; if(GetAsyncKeyState(VK_MENU)) modifiers |= CUSTKEY_ALT_MASK; if(GetAsyncKeyState(VK_CONTROL)) modifiers |= CUSTKEY_CTRL_MASK; if(GetAsyncKeyState(VK_SHIFT)) modifiers |= CUSTKEY_SHIFT_MASK; { for(int i = 0 ; i < 10 ; i++) { if(wParam == CustomKeys.Save[i].key && modifiers == CustomKeys.Save[i].modifiers) { FreezeUnfreeze (i, true); hitHotKey = true; } if(wParam == CustomKeys.Load[i].key && modifiers == CustomKeys.Load[i].modifiers) { FreezeUnfreeze (i, false); hitHotKey = true; } } if(wParam == CustomKeys.SlotSave.key && modifiers == CustomKeys.SlotSave.modifiers) { FreezeUnfreeze (GUI.CurrentSaveSlot, true); hitHotKey = true; } if(wParam == CustomKeys.SlotLoad.key && modifiers == CustomKeys.SlotLoad.modifiers) { FreezeUnfreeze (GUI.CurrentSaveSlot, false); hitHotKey = true; } if(wParam == CustomKeys.SlotPlus.key && modifiers == CustomKeys.SlotPlus.modifiers) { GUI.CurrentSaveSlot++; if(GUI.CurrentSaveSlot > 9) GUI.CurrentSaveSlot = 0; static char str [64]; sprintf(str, FREEZE_INFO_SET_SLOT_N, GUI.CurrentSaveSlot); S9xSetInfoString(str); hitHotKey = true; } if(wParam == CustomKeys.SlotMinus.key && modifiers == CustomKeys.SlotMinus.modifiers) { GUI.CurrentSaveSlot--; if(GUI.CurrentSaveSlot < 0) GUI.CurrentSaveSlot = 9; static char str [64]; sprintf(str, FREEZE_INFO_SET_SLOT_N, GUI.CurrentSaveSlot); S9xSetInfoString(str); hitHotKey = true; } } if(wParam == CustomKeys.FrameAdvance.key && modifiers == CustomKeys.FrameAdvance.modifiers) { static DWORD lastTime = 0; if((int)(timeGetTime() - lastTime) > 20 && (!ICPU.SavedAtOp || prevPadReadFrame == IPPU.TotalEmulatedFrames)) { lastTime = timeGetTime(); if(Settings.Paused || GUI.FASkipsNonInput) { if(!ICPU.SavedAtOp) prevPadReadFrame = (uint32)-1; Settings.Paused = false; S9xMouseOn(); GUI.IgnoreNextMouseMove = true; Settings.Paused = true; Settings.FrameAdvance = true; GUI.FrameAdvanceJustPressed = 2; // kick the main thread out of GetMessage (just in case) if(!ICPU.SavedAtOp) SendMessage(GUI.hWnd, WM_NULL, 0, 0); } else { Settings.Paused = true; } CenterCursor(); } hitHotKey = true; } if(wParam == CustomKeys.FrameCount.key && modifiers == CustomKeys.FrameCount.modifiers) { if (S9xMovieActive() #ifdef NETPLAY_SUPPORT || Settings.NetPlay #endif ) S9xMovieToggleFrameDisplay (); else S9xMessage(S9X_INFO, S9X_MOVIE_INFO, MOVIE_ERR_NOFRAMETOGGLE); hitHotKey = true; } if(wParam == CustomKeys.Pause.key && modifiers == CustomKeys.Pause.modifiers) { Settings.Paused = Settings.Paused ^ true; Settings.FrameAdvance = false; GUI.FrameAdvanceJustPressed = 0; CenterCursor(); if(!Settings.Paused) S9xMouseOn(); hitHotKey = true; } if(wParam == CustomKeys.ReadOnly.key && modifiers == CustomKeys.ReadOnly.modifiers) { if (S9xMovieActive()) S9xMovieToggleRecState(); else S9xMessage(S9X_INFO, S9X_MOVIE_INFO, MOVIE_ERR_NOREADONLYTOGGLE); hitHotKey = true; } if(wParam == CustomKeys.FastForward.key && modifiers == CustomKeys.FastForward.modifiers) { if(Settings.SPC7110RTC) return 1; if (GUI.TurboModeToggle) { Settings.TurboMode ^= TRUE; if (Settings.TurboMode) S9xMessage (S9X_INFO, S9X_TURBO_MODE, WINPROC_TURBOMODE_ON); else S9xMessage (S9X_INFO, S9X_TURBO_MODE, WINPROC_TURBOMODE_OFF); } else { if(!Settings.TurboMode) S9xMessage (S9X_INFO, S9X_TURBO_MODE, WINPROC_TURBOMODE_TEXT); Settings.TurboMode = TRUE; } hitHotKey = true; } if(wParam == CustomKeys.ShowPressed.key && modifiers == CustomKeys.ShowPressed.modifiers) { Settings.DisplayPressedKeys = Settings.DisplayPressedKeys?0:2; if(Settings.DisplayPressedKeys==2) S9xMessage(S9X_INFO, S9X_MOVIE_INFO, INPUT_INFO_DISPLAY_ENABLED); else S9xMessage(S9X_INFO, S9X_MOVIE_INFO, INPUT_INFO_DISPLAY_DISABLED); hitHotKey = true; } if(wParam == CustomKeys.SaveScreenShot.key && modifiers == CustomKeys.SaveScreenShot.modifiers) { Settings.TakeScreenshot=true; } if(wParam == CustomKeys.ScopePause.key && modifiers == CustomKeys.ScopePause.modifiers) { GUI.superscope_pause = 1; hitHotKey = true; } if(wParam == CustomKeys.ScopeTurbo.key && modifiers == CustomKeys.ScopeTurbo.modifiers) { GUI.superscope_turbo = 1; hitHotKey = true; } if(wParam == CustomKeys.SkipDown.key && modifiers == CustomKeys.SkipDown.modifiers) { if (Settings.SkipFrames <= 1) Settings.SkipFrames = AUTO_FRAMERATE; else if (Settings.SkipFrames != AUTO_FRAMERATE) Settings.SkipFrames--; if (Settings.SkipFrames == AUTO_FRAMERATE) S9xSetInfoString (WINPROC_AUTOSKIP); else { sprintf (InfoString, WINPROC_FRAMESKIP, Settings.SkipFrames - 1); S9xSetInfoString (InfoString); } hitHotKey = true; } if(wParam == CustomKeys.SkipUp.key && modifiers == CustomKeys.SkipUp.modifiers) { if (Settings.SkipFrames == AUTO_FRAMERATE) Settings.SkipFrames = 1; else if (Settings.SkipFrames < 10) Settings.SkipFrames++; if (Settings.SkipFrames == AUTO_FRAMERATE) S9xSetInfoString (WINPROC_AUTOSKIP); else { sprintf (InfoString, WINPROC_FRAMESKIP, Settings.SkipFrames - 1); S9xSetInfoString (InfoString); } hitHotKey = true; } if(wParam == CustomKeys.SpeedDown.key && modifiers == CustomKeys.SpeedDown.modifiers) { // Increase emulated frame time int i; for(i=1; FrameTimings[i]compressed) && ext->extension && strlen(ext->extension) < 256) { if(!first) strcat(lpfilterptr, ";*."); else { strcat(lpfilterptr, "*."); first = false; } strcat(lpfilterptr, ext->extension); extlen_approx += strlen(ext->extension) + 3; } ext = ext->next; } lpfilterptr += strlen(lpfilterptr); } else strcat0(lpfilterptr, "*.smc"); strcat0(lpfilterptr, "\0"); } strcat0(lpfilterptr, FILE_INFO_ANY_FILE_TYPE); strcat0(lpfilterptr, "\0*.*\0\0"); ZeroMemory((LPVOID)&ofn, sizeof(OPENFILENAME)); ofn.lStructSize = sizeof(OPENFILENAME); ofn.hwndOwner = GUI.hWnd; ofn.lpstrFilter = lpfilter; ofn.lpstrFile = szFileName; ofn.lpstrDefExt = "smc"; ofn.nMaxFile = MAX_PATH; ofn.Flags = OFN_HIDEREADONLY | OFN_FILEMUSTEXIST; ofn.lpstrInitialDir = szPathName; if(GetOpenFileName(&ofn)) { strncpy(filename, ofn.lpstrFile, _MAX_PATH); return true; } return false; } } char multiRomA [MAX_PATH] = {0}; // lazy, should put in sGUI and add init to {0} somewhere char multiRomB [MAX_PATH] = {0}; static bool startingMovie = false; HWND cheatSearchHWND = NULL; #define MOVIE_LOCKED_SETTING if(S9xMovieActive()) {MessageBox(GUI.hWnd,TEXT("That setting is locked while a movie is active."),TEXT("Notice"),MB_OK|MB_ICONEXCLAMATION); break;} LRESULT CALLBACK WinProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { unsigned int i; //bool showFPS; #ifdef NETPLAY_SUPPORT char hostname [100]; #endif switch (uMsg) { case WM_CREATE: g_hInst = ((LPCREATESTRUCT)lParam)->hInstance; #ifndef MK_APU DeleteMenu(GUI.hMenu,IDM_CATCH_UP_SOUND,MF_BYCOMMAND); #endif return 0; case WM_KEYDOWN: if(GUI.BackgroundKeyHotkeys) break; case WM_CUSTKEYDOWN: case WM_SYSKEYDOWN: { if(!HandleKeyMessage(wParam,lParam)) return 0; break; } case WM_KEYUP: { int modifiers = 0; if(GetAsyncKeyState(VK_MENU)) modifiers |= CUSTKEY_ALT_MASK; if(GetAsyncKeyState(VK_CONTROL)) modifiers |= CUSTKEY_CTRL_MASK; if(GetAsyncKeyState(VK_SHIFT)) modifiers |= CUSTKEY_SHIFT_MASK; if(wParam == CustomKeys.FastForward.key && modifiers == CustomKeys.FastForward.modifiers) { if (!GUI.TurboModeToggle) Settings.TurboMode = FALSE; } if(wParam == CustomKeys.ScopePause.key && modifiers == CustomKeys.ScopePause.modifiers) { GUI.superscope_pause = 0; } } break; case WM_COMMAND: switch (wParam & 0xffff) { case ID_FILE_WRITE_AVI: { RestoreGUIDisplay (); //exit DirectX OPENFILENAME ofn; char szFileName[MAX_PATH]; char szPathName[MAX_PATH]; SetCurrentDirectory(S9xGetDirectory(DEFAULT_DIR)); _fullpath(szPathName, GUI.MovieDir, MAX_PATH); mkdir(szPathName); szFileName[0] = '\0'; ZeroMemory( (LPVOID)&ofn, sizeof(OPENFILENAME) ); ofn.lStructSize = sizeof(OPENFILENAME); ofn.hwndOwner = GUI.hWnd; ofn.lpstrFilter = FILE_INFO_AVI_FILE_TYPE "\0*.avi\0" FILE_INFO_ANY_FILE_TYPE "\0*.*\0\0"; ofn.lpstrFile = szFileName; ofn.lpstrDefExt = "avi"; ofn.nMaxFile = MAX_PATH; ofn.Flags = OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT; ofn.lpstrInitialDir = szPathName; if(GetSaveFileName( &ofn )) { DoAVIOpen(szFileName); } RestoreSNESDisplay ();// re-enter after dialog } break; case ID_FILE_STOP_AVI: DoAVIClose(0); break; case ID_FILE_MOVIE_STOP: S9xMovieStop(FALSE); break; case ID_FILE_MOVIE_PLAY: { RestoreGUIDisplay (); //exit DirectX OpenMovieParams op; memset(&op, 0, sizeof(op)); if(DialogBoxParam(g_hInst, MAKEINTRESOURCE(IDD_OPENMOVIE), hWnd, DlgOpenMovie, (LPARAM)&op) && op.Path[0]!='\0') { int err=S9xMovieOpen (op.Path, op.ReadOnly); if(err!=SUCCESS) { _TCHAR* err_string=TEXT(MOVIE_ERR_COULD_NOT_OPEN); switch(err) { case FILE_NOT_FOUND: err_string=TEXT(MOVIE_ERR_NOT_FOUND); break; case WRONG_FORMAT: err_string=TEXT(MOVIE_ERR_WRONG_FORMAT); break; case WRONG_VERSION: err_string=TEXT(MOVIE_ERR_WRONG_VERSION); break; } MessageBox( hWnd, err_string, TEXT(SNES9X_INFO), MB_OK); } } RestoreSNESDisplay ();// re-enter after dialog } break; case ID_FILE_MOVIE_RECORD: { RestoreGUIDisplay (); //exit DirectX OpenMovieParams op; memset(&op, 0, sizeof(op)); if(DialogBoxParam(g_hInst, MAKEINTRESOURCE(IDD_CREATEMOVIE), hWnd, DlgCreateMovie, (LPARAM)&op) && op.Path[0]!='\0') { if(Settings.ShutdownMaster) { static bool seenItOnce = false; if(!seenItOnce) { seenItOnce = true; MessageBox(hWnd, MOVIE_SHUTDOWNMASTER_WARNING, SNES9X_WARN, MB_OK); } } startingMovie = true; int err=S9xMovieCreate (op.Path, op.ControllersMask, op.Opts, op.Metadata, wcslen(op.Metadata)); startingMovie = false; if(err!=SUCCESS) { _TCHAR* err_string=TEXT(MOVIE_ERR_COULD_NOT_OPEN); switch(err) { case FILE_NOT_FOUND: err_string=TEXT(MOVIE_ERR_NOT_FOUND); break; case WRONG_FORMAT: err_string=TEXT(MOVIE_ERR_WRONG_FORMAT); break; case WRONG_VERSION: err_string=TEXT(MOVIE_ERR_WRONG_VERSION); break; } MessageBox( hWnd, err_string, TEXT(SNES9X_INFO), MB_OK); } } RestoreSNESDisplay ();// re-enter after dialog } break; case IDM_GFX_PACKS: RestoreGUIDisplay (); //exit DirectX DialogBox(g_hInst, MAKEINTRESOURCE(IDD_GFX_PACK), hWnd, DlgPackConfigProc); RestoreSNESDisplay ();// re-enter after dialog break; case IDM_CATCH_UP_SOUND: Settings.SampleCatchup=!Settings.SampleCatchup; if(Settings.SampleCatchup) CheckMenuItem(GUI.hMenu, IDM_CATCH_UP_SOUND, MFS_CHECKED); else CheckMenuItem(GUI.hMenu, IDM_CATCH_UP_SOUND, MFS_UNCHECKED); break; case IDM_SNES_JOYPAD: MOVIE_LOCKED_SETTING GUI.ControllerOption = SNES_JOYPAD; ChangeInputDevice(); break; case IDM_ENABLE_MULTITAP: MOVIE_LOCKED_SETTING GUI.ControllerOption = SNES_MULTIPLAYER5; ChangeInputDevice(); break; case IDM_SCOPE_TOGGLE: MOVIE_LOCKED_SETTING GUI.ControllerOption = SNES_SUPERSCOPE; ChangeInputDevice(); break; case IDM_JUSTIFIER: MOVIE_LOCKED_SETTING GUI.ControllerOption = SNES_JUSTIFIER; ChangeInputDevice(); break; case IDM_MOUSE_TOGGLE: MOVIE_LOCKED_SETTING GUI.ControllerOption = SNES_MOUSE; ChangeInputDevice(); break; case IDM_MOUSE_SWAPPED: MOVIE_LOCKED_SETTING GUI.ControllerOption = SNES_MOUSE_SWAPPED; ChangeInputDevice(); break; case IDM_MULTITAP8: MOVIE_LOCKED_SETTING GUI.ControllerOption = SNES_MULTIPLAYER8; ChangeInputDevice(); break; case IDM_JUSTIFIERS: MOVIE_LOCKED_SETTING GUI.ControllerOption = SNES_JUSTIFIER_2; ChangeInputDevice(); break; //start turbo case ID_TURBO_R: GUI.TurboMask^=TURBO_R_MASK; if(GUI.TurboMask&TURBO_R_MASK) S9xSetInfoString (WINPROC_TURBO_R_ON); else S9xSetInfoString (WINPROC_TURBO_R_OFF); break; case ID_TURBO_L: GUI.TurboMask^=TURBO_L_MASK; if(GUI.TurboMask&TURBO_L_MASK) S9xSetInfoString (WINPROC_TURBO_L_ON); else S9xSetInfoString (WINPROC_TURBO_L_OFF); break; case ID_TURBO_A: GUI.TurboMask^=TURBO_A_MASK; if(GUI.TurboMask&TURBO_A_MASK) S9xSetInfoString (WINPROC_TURBO_A_ON); else S9xSetInfoString (WINPROC_TURBO_A_OFF); break; case ID_TURBO_B: GUI.TurboMask^=TURBO_B_MASK; if(GUI.TurboMask&TURBO_B_MASK) S9xSetInfoString (WINPROC_TURBO_B_ON); else S9xSetInfoString (WINPROC_TURBO_B_OFF); break; case ID_TURBO_Y: GUI.TurboMask^=TURBO_Y_MASK; if(GUI.TurboMask&TURBO_Y_MASK) S9xSetInfoString (WINPROC_TURBO_Y_ON); else S9xSetInfoString (WINPROC_TURBO_Y_OFF); break; case ID_TURBO_X: GUI.TurboMask^=TURBO_X_MASK; if(GUI.TurboMask&TURBO_X_MASK) S9xSetInfoString (WINPROC_TURBO_X_ON); else S9xSetInfoString (WINPROC_TURBO_X_OFF); break; case ID_TURBO_START: GUI.TurboMask^=TURBO_STA_MASK; if(GUI.TurboMask&TURBO_STA_MASK) S9xSetInfoString (WINPROC_TURBO_START_ON); else S9xSetInfoString (WINPROC_TURBO_START_OFF); break; case ID_TURBO_SELECT: GUI.TurboMask^=TURBO_SEL_MASK; if(GUI.TurboMask&TURBO_SEL_MASK) S9xSetInfoString (WINPROC_TURBO_SEL_ON); else S9xSetInfoString (WINPROC_TURBO_SEL_OFF); break; case ID_TURBO_LEFT: GUI.TurboMask^=TURBO_LEFT_MASK; if(GUI.TurboMask&TURBO_LEFT_MASK) S9xSetInfoString (WINPROC_TURBO_LEFT_ON); else S9xSetInfoString (WINPROC_TURBO_LEFT_OFF); break; case ID_TURBO_UP: GUI.TurboMask^=TURBO_UP_MASK; if(GUI.TurboMask&TURBO_UP_MASK) S9xSetInfoString (WINPROC_TURBO_UP_ON); else S9xSetInfoString (WINPROC_TURBO_UP_OFF); break; case ID_TURBO_RIGHT: GUI.TurboMask^=TURBO_RIGHT_MASK; if(GUI.TurboMask&TURBO_RIGHT_MASK) S9xSetInfoString (WINPROC_TURBO_RIGHT_ON); else S9xSetInfoString (WINPROC_TURBO_RIGHT_OFF); break; case ID_TURBO_DOWN: GUI.TurboMask^=TURBO_DOWN_MASK; if(GUI.TurboMask&TURBO_DOWN_MASK) S9xSetInfoString (WINPROC_TURBO_DOWN_ON); else S9xSetInfoString (WINPROC_TURBO_DOWN_OFF); break; //end turbo case ID_OPTIONS_DISPLAY: { int old_scale = GUI.NextScale; // bool old_stretch = GUI.Stretch; bool wasFullScreen = GUI.FullScreen; RestoreGUIDisplay (); //showFPS = Settings.DisplayFrameRate ? true : false; //if (!VOODOO_MODE && !GUI.FullScreen) // GetWindowRect (GUI.hWnd, &GUI.window_size); DialogBox(g_hInst, MAKEINTRESOURCE(IDD_NEWDISPLAY), hWnd, DlgFunky); //_DirectXConfig (DirectX.lpDD, &Settings, &GUI, &showFPS); //Settings.DisplayFrameRate = showFPS; SwitchToGDI(); if (GUI.NextScale != old_scale) { UpdateScale(GUI.Scale, GUI.NextScale); } GUI.ScaleHiRes = GUI.NextScaleHiRes; RestoreSNESDisplay (); if (!GUI.FullScreen && wasFullScreen) { MoveWindow (GUI.hWnd, GUI.window_size.left, GUI.window_size.top, GUI.window_size.right - GUI.window_size.left, GUI.window_size.bottom - GUI.window_size.top, TRUE); } S9xGraphicsDeinit(); // S9xDeinitUpdate(); S9xSetWinPixelFormat (); S9xInitUpdate(); S9xGraphicsInit(); IPPU.RenderThisFrame = false; // if (old_stretch != GUI.Stretch || old_scale != GUI.Scale) { RECT rect; GetClientRect (GUI.hWnd, &rect); InvalidateRect (GUI.hWnd, &rect, true); } break; } case ID_OPTIONS_JOYPAD: RestoreGUIDisplay (); DialogBox(g_hInst, MAKEINTRESOURCE(IDD_INPUTCONFIG), hWnd, DlgInputConfig); RestoreSNESDisplay (); break; case ID_OPTIONS_KEYCUSTOM: RestoreGUIDisplay (); DialogBox(g_hInst, MAKEINTRESOURCE(IDD_KEYCUSTOM), hWnd, DlgHotkeyConfig); RestoreSNESDisplay (); break; case ID_FILE_LOADMULTICART: { #ifdef NETPLAY_SUPPORT if (Settings.NetPlay && !Settings.NetPlayServer) { S9xMessage (S9X_INFO, S9X_NETPLAY_NOT_SERVER, WINPROC_DISCONNECT); break; } #endif RestoreGUIDisplay (); const bool ok = (1 <= DialogBoxParam(g_hInst, MAKEINTRESOURCE(IDD_MULTICART), GUI.hWnd, DlgMultiROMProc, (LPARAM)NULL)); if(ok) { if (!Settings.StopEmulation) { Memory.SaveSRAM (S9xGetFilename (".srm", SRAM_DIR)); S9xSaveCheatFile (S9xGetFilename (".cht", CHEAT_DIR)); } Settings.StopEmulation = !LoadMultiROM (multiRomA, multiRomB); if (!Settings.StopEmulation) { bool8 loadedSRAM = Memory.LoadSRAM (S9xGetFilename (".srm", SRAM_DIR)); if(!loadedSRAM) // help migration from earlier Snes9x versions by checking ROM directory for savestates Memory.LoadSRAM (S9xGetFilename (".srm", ROMFILENAME_DIR)); S9xLoadCheatFile (S9xGetFilename (".cht", CHEAT_DIR)); // S9xAddToRecentGames (multiRomA, multiRomB); CheckDirectoryIsWritable (S9xGetFilename (".---", SNAPSHOT_DIR)); CheckMenuStates (); #ifdef NETPLAY_SUPPORT // still valid with multicart ??? if (NPServer.SendROMImageOnConnect) S9xNPServerQueueSendingROMImage (); else S9xNPServerQueueSendingLoadROMRequest (Memory.ROMName); #endif } if(GUI.ControllerOption == SNES_SUPERSCOPE) SetCursor (GUI.GunSight); else { SetCursor (GUI.Arrow); GUI.CursorTimer = 60; } Settings.Paused = false; } RestoreSNESDisplay (); GUI.ScreenCleared = true; } break; case ID_FILE_LOAD_GAME: { char filename [_MAX_PATH]; #ifdef NETPLAY_SUPPORT if (Settings.NetPlay && !Settings.NetPlayServer) { S9xMessage (S9X_INFO, S9X_NETPLAY_NOT_SERVER, WINPROC_DISCONNECT); break; } #endif RestoreGUIDisplay (); if(DoOpenRomDialog(filename)) { if (!Settings.StopEmulation) { Memory.SaveSRAM (S9xGetFilename (".srm", SRAM_DIR)); S9xSaveCheatFile (S9xGetFilename (".cht", CHEAT_DIR)); } Settings.StopEmulation = !LoadROM (filename); if (!Settings.StopEmulation) { bool8 loadedSRAM = Memory.LoadSRAM (S9xGetFilename (".srm", SRAM_DIR)); if(!loadedSRAM) // help migration from earlier Snes9x versions by checking ROM directory for savestates Memory.LoadSRAM (S9xGetFilename (".srm", ROMFILENAME_DIR)); S9xLoadCheatFile (S9xGetFilename (".cht", CHEAT_DIR)); S9xAddToRecentGames (filename); CheckDirectoryIsWritable (S9xGetFilename (".---", SNAPSHOT_DIR)); CheckMenuStates (); #ifdef NETPLAY_SUPPORT if (NPServer.SendROMImageOnConnect) S9xNPServerQueueSendingROMImage (); else S9xNPServerQueueSendingLoadROMRequest (Memory.ROMName); #endif } if(GUI.ControllerOption == SNES_SUPERSCOPE) SetCursor (GUI.GunSight); else { SetCursor (GUI.Arrow); GUI.CursorTimer = 60; } Settings.Paused = false; } RestoreSNESDisplay (); GUI.ScreenCleared = true; } break; case ID_FILE_EXIT: S9xSetPause (PAUSE_EXIT); #ifdef USE_GLIDE S9xGlideEnable (FALSE); #endif PostMessage (hWnd, WM_DESTROY, 0, 0); break; case ID_WINDOW_HIDEMENUBAR: if( GetMenu( GUI.hWnd) == NULL) SetMenu( GUI.hWnd, GUI.hMenu); else SetMenu( GUI.hWnd, NULL); GUI.ScreenCleared = true; break; case ID_LANGUAGE_ENGLISH: GUI.Language = 0; SetMenu( GUI.hWnd, LoadMenu( GUI.hInstance, MAKEINTRESOURCE( Languages[ GUI.Language].idMenu))); DestroyMenu( GUI.hMenu); GUI.hMenu = GetMenu( GUI.hWnd); break; case ID_LANGUAGE_NEDERLANDS: GUI.Language = 1; SetMenu( GUI.hWnd, LoadMenu( GUI.hInstance, MAKEINTRESOURCE( Languages[ GUI.Language].idMenu))); DestroyMenu( GUI.hMenu); GUI.hMenu = GetMenu( GUI.hWnd); break; #ifdef NETPLAY_SUPPORT case ID_NETPLAY_SERVER: S9xRestoreWindowTitle (); EnableServer (!Settings.NetPlayServer); if(Settings.NetPlayServer) { char localhostmsg [512]; // FIXME: need winsock2.h for this, don't know how to include it //struct addrinfo *aiList = NULL; //if(getaddrinfo("localhost", Settings.Port, NULL, &aiList) == 0) //{ // sprintf(localhostmsg, "Your server address is: %s", aiList->ai_canonname); // MessageBox(GUI.hWnd,localhostmsg,"Note",MB_OK); //} //else { char localhostname [256]; gethostname(localhostname,256); sprintf(localhostmsg, "Your host name is: %s\nYour port number is: %d", localhostname, Settings.Port); MessageBox(GUI.hWnd,localhostmsg,"Note",MB_OK); } } break; case ID_NETPLAY_CONNECT: RestoreGUIDisplay (); if(1<=DialogBoxParam(g_hInst, MAKEINTRESOURCE(IDD_NETCONNECT), hWnd, DlgNetConnect,(LPARAM)&hostname)) { S9xSetPause (PAUSE_NETPLAY_CONNECT); if (!S9xNPConnectToServer (hostname, Settings.Port, Memory.ROMName)) { S9xClearPause (PAUSE_NETPLAY_CONNECT); } } RestoreSNESDisplay (); break; case ID_NETPLAY_DISCONNECT: if (Settings.NetPlay) { Settings.NetPlay = FALSE; S9xNPDisconnect (); } if (Settings.NetPlayServer) { Settings.NetPlayServer = FALSE; S9xNPStopServer (); } break; case ID_NETPLAY_OPTIONS: { bool8 old_netplay_server = Settings.NetPlayServer; RestoreGUIDisplay (); if(1<=DialogBox(g_hInst, MAKEINTRESOURCE(IDD_NPOPTIONS), hWnd, DlgNPOptions)) { if (old_netplay_server != Settings.NetPlayServer) { Settings.NetPlayServer = old_netplay_server; S9xRestoreWindowTitle (); EnableServer (!Settings.NetPlayServer); } } RestoreSNESDisplay (); break; } case ID_NETPLAY_SYNC: S9xNPServerQueueSyncAll (); break; case ID_NETPLAY_ROM: if (NPServer.SyncByReset) { if (MessageBox (GUI.hWnd, TEXT(WINPROC_NET_RESTART), TEXT(SNES9X_WARN), MB_OKCANCEL | MB_ICONWARNING) == IDCANCEL) break; } S9xNPServerQueueSendingROMImage (); break; case ID_NETPLAY_SEND_ROM_ON_CONNECT: NPServer.SendROMImageOnConnect ^= TRUE; break; case ID_NETPLAY_SYNC_BY_RESET: NPServer.SyncByReset ^= TRUE; break; #endif case ID_SOUND_8000HZ: case ID_SOUND_11025HZ: case ID_SOUND_16000HZ: case ID_SOUND_22050HZ: case ID_SOUND_30000HZ: case ID_SOUND_35000HZ: case ID_SOUND_44100HZ: case ID_SOUND_48000HZ: case ID_SOUND_32000HZ: Settings.Mute = FALSE; for( i = 0; i < COUNT(SoundRates); i ++) if (SoundRates[i].ident == (int) wParam) { Settings.SoundPlaybackRate = SoundRates [i].rate; if (!SetupSound (Settings.SoundPlaybackRate, Settings.SixteenBitSound, Settings.Stereo)) { MessageBox( GUI.hWnd, Languages[ GUI.Language].errInitDS, TEXT(SNES9X_DXS), MB_OK | MB_ICONINFORMATION); } break; } break; case ID_CHANNELS_CHANNEL1: S9xToggleSoundChannel(0); break; case ID_CHANNELS_CHANNEL2: S9xToggleSoundChannel(1); break; case ID_CHANNELS_CHANNEL3: S9xToggleSoundChannel(2); break; case ID_CHANNELS_CHANNEL4: S9xToggleSoundChannel(3); break; case ID_CHANNELS_CHANNEL5: S9xToggleSoundChannel(4); break; case ID_CHANNELS_CHANNEL6: S9xToggleSoundChannel(5); break; case ID_CHANNELS_CHANNEL7: S9xToggleSoundChannel(6); break; case ID_CHANNELS_CHANNEL8: S9xToggleSoundChannel(7); break; case ID_CHANNELS_ENABLEALL: S9xToggleSoundChannel(8); break; case ID_SOUND_NOSOUND: Settings.Mute = TRUE; Settings.SoundPlaybackRate = 32000; SetupSound (Settings.SoundPlaybackRate, Settings.SixteenBitSound, Settings.Stereo); break; case ID_SOUND_25MS: Settings.SoundBufferSize = 1; SetupSound (Settings.SoundPlaybackRate, Settings.SixteenBitSound, Settings.Stereo); break; case ID_SOUND_50MS: Settings.SoundBufferSize = 2; SetupSound (Settings.SoundPlaybackRate, Settings.SixteenBitSound, Settings.Stereo); break; case ID_SOUND_100MS: Settings.SoundBufferSize = 4; SetupSound (Settings.SoundPlaybackRate, Settings.SixteenBitSound, Settings.Stereo); break; case ID_SOUND_200MS: Settings.SoundBufferSize = 8; SetupSound (Settings.SoundPlaybackRate, Settings.SixteenBitSound, Settings.Stereo); break; case ID_SOUND_500MS: Settings.SoundBufferSize = 16; SetupSound (Settings.SoundPlaybackRate, Settings.SixteenBitSound, Settings.Stereo); break; case ID_SOUND_1S: Settings.SoundBufferSize = 32; SetupSound (Settings.SoundPlaybackRate, Settings.SixteenBitSound, Settings.Stereo); break; case ID_SOUND_2S: Settings.SoundBufferSize = 64; SetupSound (Settings.SoundPlaybackRate, Settings.SixteenBitSound, Settings.Stereo); break; case ID_SOUND_STEREO: Settings.Stereo = !Settings.Stereo; SetupSound (Settings.SoundPlaybackRate, Settings.SixteenBitSound, Settings.Stereo); break; case ID_SOUND_REVERSE_STEREO: Settings.ReverseStereo = !Settings.ReverseStereo; break; case ID_SOUND_16BIT: Settings.SixteenBitSound = !Settings.SixteenBitSound; SetupSound (Settings.SoundPlaybackRate, Settings.SixteenBitSound, Settings.Stereo); break; case ID_SOUND_INTERPOLATED: Settings.InterpolatedSound = !Settings.InterpolatedSound; S9xDisplayStateChange (WINPROC_INTERPOLATED_SND, Settings.InterpolatedSound); break; case ID_SOUND_SYNC: Settings.SoundSync = !Settings.SoundSync; S9xDisplayStateChange (WINPROC_SYNC_SND, Settings.SoundSync); break; case ID_SOUND_OPTIONS: { struct SSettings orig = Settings; RestoreGUIDisplay (); if(1<=DialogBoxParam(g_hInst,MAKEINTRESOURCE(IDD_SOUND_OPTS),hWnd,DlgSoundConf, (LPARAM)&Settings)) { if (orig.NextAPUEnabled != Settings.NextAPUEnabled) { if (!Settings.NextAPUEnabled) { if (MessageBox (GUI.hWnd, TEXT(WINPROC_SND_OFF), TEXT(SNES9X_SNDQ), MB_YESNO | MB_ICONQUESTION) == IDNO) { Settings.NextAPUEnabled = orig.NextAPUEnabled; } else { Settings.APUEnabled = FALSE; SetupSound (0, FALSE, FALSE); } } else { if (!Settings.StopEmulation) { MessageBox (GUI.hWnd, TEXT(WINPROC_SND_RESTART), TEXT(SNES9X_SNDQ), MB_OK | MB_ICONINFORMATION); } else Settings.APUEnabled = Settings.NextAPUEnabled; } } else if (orig.SixteenBitSound != Settings.SixteenBitSound || orig.Stereo != Settings.Stereo || orig.SoundPlaybackRate != Settings.SoundPlaybackRate || orig.SoundBufferSize != Settings.SoundBufferSize || orig.SoundDriver != Settings.SoundDriver || orig.SoundMixInterval != Settings.SoundMixInterval) { SetupSound (Settings.SoundPlaybackRate, Settings.SixteenBitSound, Settings.Stereo); } } RestoreSNESDisplay (); break; } #ifdef RTC_DEBUGGER case IDM_7110_RTC: { struct SPC7110RTC origrtc = s7r.rtc; RestoreGUIDisplay (); if(1<=DialogBoxParam(g_hInst,MAKEINTRESOURCE(IDD_7110_RTC),hWnd,SPC7110rtc, (LPARAM)&origrtc)) { rtc_f9.reg[0x00]=origrtc.reg[0x00]; rtc_f9.reg[0x01]=origrtc.reg[0x01]; rtc_f9.reg[0x02]=origrtc.reg[0x02]; rtc_f9.reg[0x03]=origrtc.reg[0x03]; rtc_f9.reg[0x04]=origrtc.reg[0x04]; rtc_f9.reg[0x05]=origrtc.reg[0x05]; rtc_f9.reg[0x06]=origrtc.reg[0x06]; rtc_f9.reg[0x07]=origrtc.reg[0x07]; rtc_f9.reg[0x08]=origrtc.reg[0x08]; rtc_f9.reg[0x09]=origrtc.reg[0x09]; rtc_f9.reg[0x0A]=origrtc.reg[0x0A]; rtc_f9.reg[0x0B]=origrtc.reg[0x0B]; rtc_f9.reg[0x0C]=origrtc.reg[0x0C]; rtc_f9.reg[0x0D]=origrtc.reg[0x0D]; rtc_f9.reg[0x0E]=origrtc.reg[0x0E]; rtc_f9.reg[0x0F]=origrtc.reg[0x0F]; rtc_f9.last_used=time(NULL); } RestoreSNESDisplay (); break; } #endif case ID_WINDOW_FULLSCREEN: ToggleFullScreen (); break; case ID_WINDOW_STRETCH: { GUI.Stretch = !GUI.Stretch; if(!GUI.Stretch != !GUI.VideoMemory) { GUI.VideoMemory = !GUI.VideoMemory; RestoreSNESDisplay (); } RECT rect; GetClientRect (GUI.hWnd, &rect); InvalidateRect (GUI.hWnd, &rect, true); } break; case ID_WINDOW_ASPECTRATIO: { GUI.AspectRatio = !GUI.AspectRatio; RECT rect; GetClientRect (GUI.hWnd, &rect); InvalidateRect (GUI.hWnd, &rect, true); } break; case ID_WINDOW_VIDMEM: { GUI.VideoMemory = !GUI.VideoMemory; RestoreSNESDisplay (); RECT rect; GetClientRect (GUI.hWnd, &rect); InvalidateRect (GUI.hWnd, &rect, true); } break; case ID_FILE_SAVE_SPC_DATA: spc_is_dumping = 1; // S9xSPCDump (S9xGetFilenameInc (".spc")); break; case ID_SAVESCREENSHOT: Settings.TakeScreenshot=true; break; case ID_FILE_SAVE_SRAM_DATA: { bool8 success = Memory.SaveSRAM (S9xGetFilename (".srm", SRAM_DIR)); if(!success) S9xMessage(S9X_ERROR, S9X_FREEZE_FILE_INFO, SRM_SAVE_FAILED); } break; case ID_FILE_RESET: #ifdef NETPLAY_SUPPORT if (Settings.NetPlayServer) { S9xNPReset (); SetupSound (Settings.SoundPlaybackRate, Settings.SixteenBitSound, Settings.Stereo); } else if (!Settings.NetPlay) #endif { S9xMovieUpdateOnReset (); if(S9xMoviePlaying()) S9xMovieStop (TRUE); S9xSoftReset (); SetupSound (Settings.SoundPlaybackRate, Settings.SixteenBitSound, Settings.Stereo); } if(!S9xMovieRecording()) Settings.Paused = false; break; case ID_FILE_PAUSE: Settings.Paused = !Settings.Paused; Settings.FrameAdvance = false; GUI.FrameAdvanceJustPressed = 0; break; case ID_FILE_LOAD1: FreezeUnfreeze (0, FALSE); break; case ID_FILE_LOAD2: FreezeUnfreeze (1, FALSE); break; case ID_FILE_LOAD3: FreezeUnfreeze (2, FALSE); break; case ID_FILE_LOAD4: FreezeUnfreeze (3, FALSE); break; case ID_FILE_LOAD5: FreezeUnfreeze (4, FALSE); break; case ID_FILE_LOAD6: FreezeUnfreeze (5, FALSE); break; case ID_FILE_LOAD7: FreezeUnfreeze (6, FALSE); break; case ID_FILE_LOAD8: FreezeUnfreeze (7, FALSE); break; case ID_FILE_LOAD9: FreezeUnfreeze (8, FALSE); break; case ID_FILE_SAVE1: FreezeUnfreeze (0, TRUE); break; case ID_FILE_SAVE2: FreezeUnfreeze (1, TRUE); break; case ID_FILE_SAVE3: FreezeUnfreeze (2, TRUE); break; case ID_FILE_SAVE4: FreezeUnfreeze (3, TRUE); break; case ID_FILE_SAVE5: FreezeUnfreeze (4, TRUE); break; case ID_FILE_SAVE6: FreezeUnfreeze (5, TRUE); break; case ID_FILE_SAVE7: FreezeUnfreeze (6, TRUE); break; case ID_FILE_SAVE8: FreezeUnfreeze (7, TRUE); break; case ID_FILE_SAVE9: FreezeUnfreeze (8, TRUE); break; case ID_CHEAT_ENTER: RestoreGUIDisplay (); S9xRemoveCheats (); DialogBox(g_hInst, MAKEINTRESOURCE(IDD_CHEATER), hWnd, DlgCheater); S9xSaveCheatFile (S9xGetFilename (".cht", CHEAT_DIR)); S9xApplyCheats (); RestoreSNESDisplay (); break; case ID_CHEAT_SEARCH: RestoreGUIDisplay (); if(!cheatSearchHWND) // create and show non-modal cheat search window { cheatSearchHWND = CreateDialog(g_hInst, MAKEINTRESOURCE(IDD_CHEAT_SEARCH), hWnd, DlgCheatSearch); // non-modal/modeless ShowWindow(cheatSearchHWND, SW_SHOW); } else // already open so just reactivate the window { SetActiveWindow(cheatSearchHWND); } RestoreSNESDisplay (); break; case ID_CHEAT_SEARCH_MODAL: RestoreGUIDisplay (); DialogBox(g_hInst, MAKEINTRESOURCE(IDD_CHEAT_SEARCH), hWnd, DlgCheatSearch); // modal S9xSaveCheatFile (S9xGetFilename (".cht", CHEAT_DIR)); RestoreSNESDisplay (); break; case ID_CHEAT_APPLY: Settings.ApplyCheats = !Settings.ApplyCheats; if (!Settings.ApplyCheats){ S9xRemoveCheats (); S9xMessage (S9X_INFO, S9X_GAME_GENIE_CODE_ERROR, CHEATS_INFO_DISABLED); }else{ S9xApplyCheats (); bool on = false; extern struct SCheatData Cheat; for (uint32 i = 0; i < Cheat.num_cheats && !on; i++) if (Cheat.c [i].enabled) on = true; S9xMessage (S9X_INFO, S9X_GAME_GENIE_CODE_ERROR, on ? CHEATS_INFO_ENABLED : CHEATS_INFO_ENABLED_NONE); } break; case ID_OPTIONS_SETTINGS: RestoreGUIDisplay (); DialogBox(g_hInst, MAKEINTRESOURCE(IDD_EMU_SETTINGS), hWnd, DlgEmulatorProc); RestoreSNESDisplay (); break; case ID_HELP_ABOUT: RestoreGUIDisplay (); DialogBox(g_hInst, MAKEINTRESOURCE(IDD_ABOUT), hWnd, DlgAboutProc); RestoreSNESDisplay (); break; #ifdef DEBUGGER case ID_DEBUG_TRACE: { Trace (); break; } case ID_DEBUG_FRAME_ADVANCE: CPU.Flags |= FRAME_ADVANCE_FLAG; ICPU.FrameAdvanceCount = 1; Settings.Paused = FALSE; break; #endif case IDM_7110_CACHE: RestoreGUIDisplay (); DialogBox(g_hInst, MAKEINTRESOURCE(IDD_SPC7110_CACHE), hWnd, DlgSP7PackConfig); RestoreSNESDisplay (); break; case IDM_LOG_7110: Do7110Logging(); break; case IDM_ROM_INFO: RestoreGUIDisplay (); DialogBox(g_hInst, MAKEINTRESOURCE(IDD_ROM_INFO), hWnd, DlgInfoProc); RestoreSNESDisplay (); break; default: if ((wParam & 0xffff) >= 0xFF00) { int i = (wParam & 0xffff) - 0xFF00; int j = 0; { while (j < MAX_RECENT_GAMES_LIST_SIZE && j != i) j++; if (i == j) { #ifdef NETPLAY_SUPPORT if (Settings.NetPlay && !Settings.NetPlayServer) { S9xMessage (S9X_INFO, S9X_NETPLAY_NOT_SERVER, WINPROC_DISCONNECT); break; } #endif if (!Settings.StopEmulation) { Memory.SaveSRAM (S9xGetFilename (".srm", SRAM_DIR)); S9xSaveCheatFile (S9xGetFilename (".cht", CHEAT_DIR)); } Settings.StopEmulation = !LoadROM (GUI.RecentGames [i]); if (!Settings.StopEmulation) { bool8 loadedSRAM = Memory.LoadSRAM (S9xGetFilename (".srm", SRAM_DIR)); if(!loadedSRAM) // help migration from earlier Snes9x versions by checking ROM directory for savestates Memory.LoadSRAM (S9xGetFilename (".srm", ROMFILENAME_DIR)); S9xLoadCheatFile (S9xGetFilename (".cht", CHEAT_DIR)); S9xAddToRecentGames (GUI.RecentGames [i]); CheckDirectoryIsWritable (S9xGetFilename (".---", SNAPSHOT_DIR)); CheckMenuStates (); #ifdef NETPLAY_SUPPORT if (NPServer.SendROMImageOnConnect) S9xNPServerQueueSendingROMImage (); else S9xNPServerQueueSendingLoadROMRequest (Memory.ROMName); #endif Settings.Paused = false; } else { sprintf (String, ERR_ROM_NOT_FOUND, GUI.RecentGames [i]); S9xMessage (S9X_ERROR, S9X_ROM_NOT_FOUND, String); S9xRemoveFromRecentGames(i); } } } } break; } break; case WM_EXITMENULOOP: UpdateBackBuffer(); S9xClearPause (PAUSE_MENU); break; case WM_ENTERMENULOOP: S9xSetPause (PAUSE_MENU); #ifdef USE_GLIDE S9xGlideEnable (FALSE); #endif CheckMenuStates (); SwitchToGDI(); DrawMenuBar( GUI.hWnd); break; case WM_CLOSE: { bool maximized = GUI.window_maximized; ShowWindow(GUI.hWnd, SW_RESTORE); GUI.window_maximized = maximized; if (!VOODOO_MODE && !GUI.FullScreen) GetWindowRect (GUI.hWnd, &GUI.window_size); } break; case WM_DESTROY: Memory.SaveSRAM(S9xGetFilename(".srm", SRAM_DIR)); if(CleanUp7110) (*CleanUp7110)(); GUI.hWnd = NULL; PostQuitMessage (0); return (0); case WM_PAINT: { PAINTSTRUCT paint; BeginPaint (GUI.hWnd, &paint); // refresh screen if(DirectX.Clipped) S9xReRefresh(); EndPaint (GUI.hWnd, &paint); break; } case WM_SYSCOMMAND: { // Prevent screen saver from starting if not paused //kode54 says add the ! to fix the screensaver pevention. if (!(Settings.ForcedPause || Settings.StopEmulation || (Settings.Paused && !Settings.FrameAdvance)) && (wParam == SC_SCREENSAVE || wParam == SC_MONITORPOWER)) return (0); break; } case WM_ACTIVATE: if (LOWORD(wParam) == WA_INACTIVE) { #ifdef USE_GLIDE if (VOODOO_MODE) { S9xGlideEnable (FALSE); #if 0 MoveWindow (GUI.hWnd, GUI.window_size.left, GUI.window_size.top, GUI.window_size.right - GUI.window_size.left, GUI.window_size.bottom - GUI.window_size.top, TRUE); #endif } #endif if(GUI.InactivePause) { S9xSetPause (PAUSE_INACTIVE_WINDOW); } } else { Settings.TurboMode = false; /// if(GUI.InactivePause) { S9xClearPause (PAUSE_INACTIVE_WINDOW); } IPPU.ColorsChanged = TRUE; } break; case WM_QUERYNEWPALETTE: // if (!GUI.FullScreen && GUI.ScreenDepth == 8) // RealizePalette (GUI.WindowDC); break; case WM_SIZE: if (wParam == SIZE_MAXIMIZED) { GUI.window_maximized = true; } if (wParam == SIZE_RESTORED) { GUI.window_maximized = false; if(GUI.InactivePause) { S9xClearPause (PAUSE_WINDOW_ICONISED); } } if (wParam == SIZE_MINIMIZED || wParam == SIZE_MAXHIDE) { #ifdef USE_GLIDE S9xGlideEnable (FALSE); #endif /// if(GUI.InactivePause) { S9xClearPause (PAUSE_WINDOW_ICONISED); } } #ifdef USE_DIRECTX3D D3DSizeChange (GUI.hWnd, wParam); #endif break; case WM_MOVE: //if (!VOODOO_MODE && !GUI.FullScreen && !Settings.ForcedPause) //{ // GetWindowRect (GUI.hWnd, &GUI.window_size); //} #ifdef USE_DIRECTX3D D3DMove (GUI.hWnd, lParam); #endif break; case WM_DISPLAYCHANGE: if (!GUI.FullScreen) { if (!VOODOO_MODE && !OPENGL_MODE && DirectX.SetDisplayMode (GUI.Width, GUI.Height, max(GetFilterScale(GUI.Scale), GetFilterScale(GUI.ScaleHiRes)), GUI.Depth, GUI.RefreshRate, !GUI.FullScreen, GUI.DoubleBuffered)) { S9xGraphicsDeinit(); S9xSetWinPixelFormat (); S9xInitUpdate(); S9xGraphicsInit(); } } break; case WM_MOUSEMOVE: if(Settings.StopEmulation) { SetCursor (GUI.Arrow); break; } // Lo-word of lparam is xpos, hi-word is ypos // if (!GUI.IgnoreNextMouseMove) { //POINT p; //p.x = GET_X_LPARAM(lParam); //p.y = GET_Y_LPARAM(lParam); //ClientToScreen (GUI.hWnd, &p); if ((!Settings.ForcedPause && !Settings.StopEmulation && !(Settings.Paused && !Settings.FrameAdvance)) && (GUI.ControllerOption==SNES_MOUSE || GUI.ControllerOption==SNES_MOUSE_SWAPPED) ) { CenterCursor(); } else if (GUI.ControllerOption==SNES_SUPERSCOPE || GUI.ControllerOption==SNES_JUSTIFIER || GUI.ControllerOption==SNES_JUSTIFIER_2) { RECT size; GetClientRect (GUI.hWnd, &size); if(!(GUI.Scale)&&!(GUI.Stretch)) { int x,y, startx, starty; x=GET_X_LPARAM(lParam); y=GET_Y_LPARAM(lParam); // int theight; // (IPPU.RenderedScreenHeight> 256)? theight= SNES_HEIGHT_EXTENDED<<1: theight = SNES_HEIGHT_EXTENDED; int theight = GUI.HeightExtend ? SNES_HEIGHT_EXTENDED : SNES_HEIGHT; if(IPPU.RenderedScreenHeight > SNES_HEIGHT_EXTENDED) theight <<= 1; startx= size.right-IPPU.RenderedScreenWidth; startx/=2; starty= size.bottom-theight; starty/=2; if(x(startx+IPPU.RenderedScreenWidth)) GUI.MouseX=IPPU.RenderedScreenWidth; else GUI.MouseX=x-startx; if(y(starty+theight)) GUI.MouseY=theight; else GUI.MouseY=y-starty; } else if(!(GUI.Stretch)&&!VOODOO_MODE && !OPENGL_MODE) { int x,y, startx, starty, sizex, sizey; x=GET_X_LPARAM(lParam); y=GET_Y_LPARAM(lParam); if (IPPU.RenderedScreenWidth>256) sizex=IPPU.RenderedScreenWidth; else sizex=IPPU.RenderedScreenWidth*2; int theight = GUI.HeightExtend ? SNES_HEIGHT_EXTENDED : SNES_HEIGHT; sizey = (IPPU.RenderedScreenHeight > SNES_HEIGHT_EXTENDED) ? theight : (theight << 1); startx= size.right-sizex; startx/=2; starty= size.bottom-sizey; starty/=2; if(x(startx+sizex)) GUI.MouseX=sizex; else GUI.MouseX=x-startx; if(y(starty+sizey)) GUI.MouseY=sizey; else GUI.MouseY=y-starty; GUI.MouseX=(GUI.MouseX*IPPU.RenderedScreenWidth)/sizex; GUI.MouseY=(GUI.MouseY*IPPU.RenderedScreenHeight)/sizey; } else { int sizex = IPPU.RenderedScreenWidth; int sizey = GUI.HeightExtend ? SNES_HEIGHT_EXTENDED : SNES_HEIGHT; sizey = (IPPU.RenderedScreenHeight > SNES_HEIGHT_EXTENDED) ? (sizey << 1) : sizey; int width = size.right, height = size.bottom, xdiff = 0, ydiff = 0; if(GUI.AspectRatio) { if(width > sizex*height/sizey) { xdiff = width - sizex*height/sizey; width -= xdiff; xdiff >>= 1; } else if(height > sizey*width/sizex) { ydiff = height - sizey*width/sizex; height -= ydiff; ydiff >>= 1; } } GUI.MouseX=(GET_X_LPARAM(lParam)-xdiff)*sizex/width; GUI.MouseY=(GET_Y_LPARAM(lParam)-ydiff)*sizey/height; } } else { // GUI.MouseX = p.x; // GUI.MouseY = p.y; } } // else // GUI.IgnoreNextMouseMove = false; if(!GUI.IgnoreNextMouseMove) S9xMouseOn (); else GUI.IgnoreNextMouseMove = false; return 0; case WM_LBUTTONDOWN: S9xMouseOn (); GUI.MouseButtons |= 1; break; case WM_LBUTTONUP: S9xMouseOn (); GUI.MouseButtons &= ~1; break; case WM_RBUTTONDOWN: S9xMouseOn (); GUI.MouseButtons |= 2; break; case WM_RBUTTONUP: S9xMouseOn (); GUI.MouseButtons &= ~2; if(GUI.ControllerOption==SNES_JUSTIFIER || GUI.ControllerOption==SNES_JUSTIFIER_2) { RECT size; GetClientRect (GUI.hWnd, &size); GUI.MouseButtons&=~1; GUI.MouseX=(IPPU.RenderedScreenWidth*(lParam & 0xffff))/(size.right-size.left); GUI.MouseY=(((lParam >> 16) & 0xffff)*IPPU.RenderedScreenHeight)/(size.bottom-size.top); } break; case WM_MBUTTONDOWN: S9xMouseOn (); GUI.MouseButtons |= 4; break; case WM_MBUTTONUP: S9xMouseOn (); GUI.MouseButtons &= ~4; break; #ifdef NETPLAY_SUPPORT case WM_USER + 3: NetPlay.Answer = S9xLoadROMImage ((const char *) lParam); SetEvent (NetPlay.ReplyEvent); break; case WM_USER + 2: S9xMessage (0, 0, NetPlay.WarningMsg); break; case WM_USER + 1: RestoreGUIDisplay (); S9xRestoreWindowTitle (); MessageBox (GUI.hWnd, NetPlay.ErrorMsg, TEXT(SNES9X_NP_ERROR), MB_OK | MB_ICONSTOP); RestoreSNESDisplay (); break; case WM_USER: if (NetPlay.ActionMsg [0] == 0) S9xRestoreWindowTitle (); else { TCHAR buf [NP_MAX_ACTION_LEN + 10]; sprintf (buf, TEXT("%s %3d%%"), NetPlay.ActionMsg, (int) lParam); SetWindowText (GUI.hWnd, buf); } #if 0 if ((int) lParam >= 0) { RestoreGUIDisplay (); DialogBox(g_hInst, MAKEINTRESOURCE(IDD_NETPLAYPROGRESS), hWnd, DlgNPProgress); } else { DialogBox(g_hInst, MAKEINTRESOURCE(IDD_NETPLAYPROGRESS), hWnd, DlgNPProgress); RestoreSNESDisplay (); } #endif break; #endif } return DefWindowProc (hWnd, uMsg, wParam, lParam); } /*****************************************************************************/ /* WinInit */ /*****************************************************************************/ BOOL WinInit( HINSTANCE hInstance) { WNDCLASSEX wndclass; ZeroMemory(&wndclass, sizeof(wndclass)); wndclass.cbSize = sizeof(wndclass); wndclass.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC; wndclass.lpfnWndProc = WinProc; wndclass.cbClsExtra = 0; wndclass.cbWndExtra = 0; wndclass.hInstance = hInstance; wndclass.hIcon = LoadIcon (hInstance, MAKEINTRESOURCE(IDI_ICON1)); wndclass.hIconSm = (HICON)LoadImage(hInstance, MAKEINTRESOURCE(IDI_ICON1), IMAGE_ICON, 16, 16, 0); wndclass.hCursor = NULL; //LoadCursor (NULL, IDC_ARROW); wndclass.lpszMenuName = NULL; wndclass.lpszClassName = TEXT("Snes9X: WndClass"); wndclass.hbrBackground=(HBRUSH)GetStockObject(BLACK_BRUSH); //// Initialize the struct to zero //ZeroMemory(&wcx,sizeof(WNDCLASSEX)); //wcx.cbSize = sizeof(WNDCLASSEX); // Must always be sizeof(WNDCLASSEX) //wcx.style = CS_HREDRAW|CS_VREDRAW |CS_DBLCLKS ; // Class styles //wcx.lpfnWndProc = (WNDPROC)MainWndProc; // Pointer to the callback procedure //wcx.cbClsExtra = 0; // Extra byte to allocate following the wndclassex structure //wcx.cbWndExtra = 0; // Extra byte to allocate following an instance of the structure //wcx.hInstance = hInstance; // Instance of the application //wcx.hIcon = NULL; // Class Icon //wcx.hCursor = LoadCursor(NULL, IDC_ARROW); // Class Cursor //wcx.hbrBackground = (HBRUSH)(COLOR_WINDOW); // Background brush //wcx.lpszMenuName = NULL; // Menu resource //wcx.lpszClassName = "Lesson2"; // Name of this class //wcx.hIconSm = NULL; // Small icon for this class GUI.hInstance = hInstance; if (!RegisterClassEx (&wndclass)) { MessageBox (NULL, "Failed to register windows class", "Internal Error", MB_OK | MB_ICONSTOP); return FALSE; } GUI.hMenu = LoadMenu (hInstance, MAKEINTRESOURCE( Languages[ GUI.Language].idMenu)); if (GUI.hMenu == NULL) { MessageBox (NULL, "Failed to initialize the menu.\nThis could indicate a failure of your operating system;\ntry closing some other windows or programs, or restart your computer, before opening Snes9x again.\nOr, if you compiled this program yourself, ensure that Snes9x was built with the proper resource files.", "Snes9X - Menu Initialization Failure", MB_OK | MB_ICONSTOP); // return FALSE; // disabled: try to function without the menu } TCHAR buf [100]; sprintf (buf, TEXT(WINDOW_TITLE), VERSION); DWORD dwExStyle; DWORD dwStyle; RECT rect; rect.left = rect.top = 0; rect.right = MAX_SNES_WIDTH; rect.bottom = MAX_SNES_HEIGHT; dwExStyle = WS_EX_APPWINDOW | WS_EX_WINDOWEDGE; dwStyle = WS_OVERLAPPEDWINDOW; AdjustWindowRectEx (&rect, dwStyle, FALSE, dwExStyle); if ((GUI.hWnd = CreateWindowEx ( dwExStyle, TEXT("Snes9X: WndClass"), buf, WS_CLIPSIBLINGS | WS_CLIPCHILDREN | dwStyle, 0, 0, rect.right - rect.left, rect.bottom - rect.top, NULL, GUI.hMenu, hInstance, NULL)) == NULL) return FALSE; GUI.hDC = GetDC (GUI.hWnd); LoadExts(); GUI.GunSight = LoadCursor (hInstance, MAKEINTRESOURCE (IDC_CURSOR_SCOPE)); GUI.Arrow = LoadCursor (NULL, IDC_ARROW); GUI.Accelerators = LoadAccelerators (hInstance, MAKEINTRESOURCE (IDR_SNES9X_ACCELERATORS)); Settings.ForcedPause = 0; Settings.StopEmulation = TRUE; Settings.Paused = FALSE; GUI.AVIOut = NULL; return TRUE; } void S9xExtraUsage () { } extern long _rate; extern bool _sixteen_bit; extern bool _stereo; extern long _buffernos; extern long _buffersize; extern long _samplecount; extern long _bytecount; extern unsigned long _interval; volatile unsigned long LastSound = 0; uint32 next_frame_time = 0; VOID CALLBACK SoundTimer (UINT idEvent, UINT uMsg, DWORD dwUser, DWORD dw1, DWORD dw2) { void ProcessSound (void); if (Settings.SoundDriver == WIN_SNES9X_DIRECT_SOUND_DRIVER) ProcessSound (); } // handles joystick hotkey presses VOID CALLBACK HotkeyTimer( UINT idEvent, UINT uMsg, DWORD dwUser, DWORD dw1, DWORD dw2) { // static int lastTime = timeGetTime(); // if(timeGetTime() - lastTime > 5) { bool S9xGetState (WORD KeyIdent); if(GUI.JoystickHotkeys) { static int counter = 0; static uint32 joyState [256]; for(int i = 0 ; i < 255 ; i++) { if(counter%2 && !joyState[i]) continue; bool active = !S9xGetState(0x8000|i); if(active) { if(joyState[i] < ULONG_MAX) // 0xffffffffUL joyState[i]++; if(joyState[i] == 1 || joyState[i] >= 12) PostMessage(GUI.hWnd, WM_CUSTKEYDOWN, (WPARAM)(0x8000|i),(LPARAM)(NULL)); } else joyState[i] = 0; } counter++; } if(GUI.BackgroundKeyHotkeys) { static int counter = 0; static uint32 joyState [256]; for(int i = 0 ; i < 255 ; i++) { if(counter%2 && !joyState[i]) continue; bool active = !S9xGetState(i); if(active) { if(joyState[i] < ULONG_MAX) // 0xffffffffUL joyState[i]++; if(joyState[i] == 1 || joyState[i] >= 12) PostMessage(GUI.hWnd, WM_CUSTKEYDOWN, (WPARAM)(i),(LPARAM)(NULL)); } else joyState[i] = 0; } counter++; } // lastTime = timeGetTime(); } } VOID CALLBACK FrameTimer( UINT idEvent, UINT uMsg, DWORD dwUser, DWORD dw1, DWORD dw2) { // QueryPerformanceCounter is unreliable on newfangled frequency-switching computers, // yet is absolutely necessary for best performance on somewhat older computers (even ones that are capable of frequency switching but don't do it very often). // Thus, we keep two timers and use the QueryPerformanceCounter one unless the other (more accurate but less precise) // one differs from it by more than a few milliseconds. QueryPerformanceCounter((LARGE_INTEGER*)&PCEnd); PCEndTicks = timeGetTime()*1000; const __int64 PCElapsedPrecise = PCEnd - PCStart; const __int64 PCElapsedAccurate = (__int64)(PCEndTicks - PCStartTicks) * PCBase / 1000000; const bool useTicksTimer = (abs((int)(PCElapsedPrecise - PCElapsedAccurate)) > (PCBase >> 7)); // if > 7.8 ms difference, settle for accuracy at the sacrifice of precision while ((!useTicksTimer && (PCEnd - PCStart ) >= PCFrameTime) || ( useTicksTimer && (PCEndTicks - PCStartTicks) >= PCFrameTime * 1000000 / PCBase)) { if (DirectX.FrameCount == DirectX.LastFrameCount) DirectX.IdleCount++; else { DirectX.IdleCount = 0; DirectX.LastFrameCount = DirectX.FrameCount; } #ifdef NETPLAY_SUPPORT // if (Settings.NetPlay && !Settings.NetPlayServer) // return; if (Settings.NetPlay && !Settings.NetPlayServer) return; //- if (Settings.NetPlayServer) //- { //- if (Settings.Paused || Settings.StopEmulation || Settings.ForcedPause) if (Settings.NetPlayServer) { //- WaitForSingleObject (GUI.ServerTimerSemaphore, 0); if ((Settings.Paused && !Settings.FrameAdvance) || Settings.StopEmulation || Settings.ForcedPause) { WaitForSingleObject (GUI.ServerTimerSemaphore, 0); return; } ReleaseSemaphore (GUI.ServerTimerSemaphore, 1, NULL); if (Settings.NetPlay) return; } else #endif { if (Settings.SkipFrames != AUTO_FRAMERATE || Settings.TurboMode || (Settings.Paused /*&& !Settings.FrameAdvance*/) || Settings.StopEmulation || Settings.ForcedPause) { WaitForSingleObject (GUI.FrameTimerSemaphore, 0); PCStart = PCEnd; PCStartTicks = PCEndTicks; return; } // ReleaseSemaphore (GUI.ServerTimerSemaphore, 1, NULL); ReleaseSemaphore (GUI.FrameTimerSemaphore, 1, NULL); // if (Settings.NetPlay) // return; // } // else //#endif // if (Settings.SkipFrames != AUTO_FRAMERATE || Settings.TurboMode || // Settings.Paused || Settings.StopEmulation || Settings.ForcedPause) // { // WaitForSingleObject (GUI.FrameTimerSemaphore, 0); // return; // } // ReleaseSemaphore (GUI.FrameTimerSemaphore, 1, NULL); PCStart += PCFrameTime; PCStartTicks += (DWORD)(PCFrameTime * 1000000 / PCBase); } } } static void EnsureInputDisplayUpdated() { if(GUI.FrameAdvanceJustPressed==1 && Settings.Paused && Settings.DisplayPressedKeys==2 && GUI.ControllerOption != SNES_JOYPAD && GUI.ControllerOption != SNES_MULTIPLAYER5 && GUI.ControllerOption != SNES_MULTIPLAYER8) S9xReRefresh(); } // for "frame advance skips non-input frames" feature void S9xOnSNESPadRead() { if(!GUI.FASkipsNonInput) return; if(prevPadReadFrame != IPPU.TotalEmulatedFrames) // we want <= 1 calls per frame { prevPadReadFrame = IPPU.TotalEmulatedFrames; if(Settings.FrameAdvance && Settings.Paused && !skipNextFrameStop) { Settings.FrameAdvance = false; ICPU.SavedAtOp = TRUE; EnsureInputDisplayUpdated(); // wait until either unpause or next frame advance // note: using GUI.hWnd instead of NULL for PeekMessage/GetMessage breaks some non-modal dialogs MSG msg; while (Settings.StopEmulation || (Settings.Paused && !Settings.FrameAdvance) || Settings.ForcedPause || PeekMessage (&msg, NULL, 0, 0, PM_NOREMOVE)) { if (!GetMessage (&msg, NULL, 0, 0)) { PostMessage(GUI.hWnd, WM_QUIT, 0,0); return; } if (!TranslateAccelerator (GUI.hWnd, GUI.Accelerators, &msg)) { TranslateMessage (&msg); DispatchMessage (&msg); } } ICPU.SavedAtOp = !ICPU.SavedAtOp; } else { skipNextFrameStop = false; } } } enum { k_HD = 0x80000000, k_JP = 0x01000000, k_MO = 0x02000000, k_SS = 0x04000000, k_LG = 0x08000000, k_BT = 0x00100000, k_PT = 0x00200000, k_PS = 0x00400000, k_C1 = 0x00000100, k_C2 = 0x00000200, k_C3 = 0x00000400, k_C4 = 0x00000800, k_C5 = 0x00001000, k_C6 = 0x00002000, k_C7 = 0x00004000, k_C8 = 0x00008000 }; enum { kWinCMapPad1PX = k_HD | k_BT | k_JP | k_C1, kWinCMapPad1PA, kWinCMapPad1PB, kWinCMapPad1PY, kWinCMapPad1PL, kWinCMapPad1PR, kWinCMapPad1PSelect, kWinCMapPad1PStart, kWinCMapPad1PUp, kWinCMapPad1PDown, kWinCMapPad1PLeft, kWinCMapPad1PRight, kWinCMapPad2PX = k_HD | k_BT | k_JP | k_C2, kWinCMapPad2PA, kWinCMapPad2PB, kWinCMapPad2PY, kWinCMapPad2PL, kWinCMapPad2PR, kWinCMapPad2PSelect, kWinCMapPad2PStart, kWinCMapPad2PUp, kWinCMapPad2PDown, kWinCMapPad2PLeft, kWinCMapPad2PRight, kWinCMapPad3PX = k_HD | k_BT | k_JP | k_C3, kWinCMapPad3PA, kWinCMapPad3PB, kWinCMapPad3PY, kWinCMapPad3PL, kWinCMapPad3PR, kWinCMapPad3PSelect, kWinCMapPad3PStart, kWinCMapPad3PUp, kWinCMapPad3PDown, kWinCMapPad3PLeft, kWinCMapPad3PRight, kWinCMapPad4PX = k_HD | k_BT | k_JP | k_C4, kWinCMapPad4PA, kWinCMapPad4PB, kWinCMapPad4PY, kWinCMapPad4PL, kWinCMapPad4PR, kWinCMapPad4PSelect, kWinCMapPad4PStart, kWinCMapPad4PUp, kWinCMapPad4PDown, kWinCMapPad4PLeft, kWinCMapPad4PRight, kWinCMapPad5PX = k_HD | k_BT | k_JP | k_C5, kWinCMapPad5PA, kWinCMapPad5PB, kWinCMapPad5PY, kWinCMapPad5PL, kWinCMapPad5PR, kWinCMapPad5PSelect, kWinCMapPad5PStart, kWinCMapPad5PUp, kWinCMapPad5PDown, kWinCMapPad5PLeft, kWinCMapPad5PRight, kWinCMapPad6PX = k_HD | k_BT | k_JP | k_C6, kWinCMapPad6PA, kWinCMapPad6PB, kWinCMapPad6PY, kWinCMapPad6PL, kWinCMapPad6PR, kWinCMapPad6PSelect, kWinCMapPad6PStart, kWinCMapPad6PUp, kWinCMapPad6PDown, kWinCMapPad6PLeft, kWinCMapPad6PRight, kWinCMapPad7PX = k_HD | k_BT | k_JP | k_C7, kWinCMapPad7PA, kWinCMapPad7PB, kWinCMapPad7PY, kWinCMapPad7PL, kWinCMapPad7PR, kWinCMapPad7PSelect, kWinCMapPad7PStart, kWinCMapPad7PUp, kWinCMapPad7PDown, kWinCMapPad7PLeft, kWinCMapPad7PRight, kWinCMapPad8PX = k_HD | k_BT | k_JP | k_C8, kWinCMapPad8PA, kWinCMapPad8PB, kWinCMapPad8PY, kWinCMapPad8PL, kWinCMapPad8PR, kWinCMapPad8PSelect, kWinCMapPad8PStart, kWinCMapPad8PUp, kWinCMapPad8PDown, kWinCMapPad8PLeft, kWinCMapPad8PRight, kWinCMapMouse1PL = k_HD | k_BT | k_MO | k_C1, kWinCMapMouse1PR, kWinCMapMouse2PL = k_HD | k_BT | k_MO | k_C2, kWinCMapMouse2PR, kWinCMapScopeOffscreen = k_HD | k_BT | k_SS | k_C1, kWinCMapScopeFire, kWinCMapScopeCursor, kWinCMapScopeTurbo, kWinCMapScopePause, kWinCMapLGun1Offscreen = k_HD | k_BT | k_LG | k_C1, kWinCMapLGun1Trigger, kWinCMapLGun1Start, kWinCMapLGun2Offscreen = k_HD | k_BT | k_LG | k_C2, kWinCMapLGun2Trigger, kWinCMapLGun2Start, kWinCMapMouse1Pointer = k_HD | k_PT | k_MO | k_C1, kWinCMapMouse2Pointer = k_HD | k_PT | k_MO | k_C2, kWinCMapSuperscopePointer = k_HD | k_PT | k_SS | k_C1, kWinCMapJustifier1Pointer = k_HD | k_PT | k_LG | k_C1, kWinCMapPseudoPtrBase = k_HD | k_PS | k_LG | k_C2 // for Justifier 2P }; #define ASSIGN_BUTTONf(n, s) S9xMapButton (n, cmd = S9xGetCommandT(s), false) #define ASSIGN_BUTTONt(n, s) S9xMapButton (n, cmd = S9xGetCommandT(s), true) #define ASSIGN_POINTRf(n, s) S9xMapPointer(n, cmd = S9xGetCommandT(s), false) #define ASSIGN_POINTRt(n, s) S9xMapPointer(n, cmd = S9xGetCommandT(s), true) #define KeyIsPressed(km, k) (1 & (((unsigned char *) km) [(k) >> 3] >> ((k) & 7))) void S9xSetupDefaultKeymap(void) { s9xcommand_t cmd; ASSIGN_BUTTONf(kWinCMapPad1PX, "Joypad1 X"); ASSIGN_BUTTONf(kWinCMapPad1PA, "Joypad1 A"); ASSIGN_BUTTONf(kWinCMapPad1PB, "Joypad1 B"); ASSIGN_BUTTONf(kWinCMapPad1PY, "Joypad1 Y"); ASSIGN_BUTTONf(kWinCMapPad1PL, "Joypad1 L"); ASSIGN_BUTTONf(kWinCMapPad1PR, "Joypad1 R"); ASSIGN_BUTTONf(kWinCMapPad1PSelect, "Joypad1 Select"); ASSIGN_BUTTONf(kWinCMapPad1PStart, "Joypad1 Start"); ASSIGN_BUTTONf(kWinCMapPad1PUp, "Joypad1 Up"); ASSIGN_BUTTONf(kWinCMapPad1PDown, "Joypad1 Down"); ASSIGN_BUTTONf(kWinCMapPad1PLeft, "Joypad1 Left"); ASSIGN_BUTTONf(kWinCMapPad1PRight, "Joypad1 Right"); ASSIGN_BUTTONf(kWinCMapPad2PX, "Joypad2 X"); ASSIGN_BUTTONf(kWinCMapPad2PA, "Joypad2 A"); ASSIGN_BUTTONf(kWinCMapPad2PB, "Joypad2 B"); ASSIGN_BUTTONf(kWinCMapPad2PY, "Joypad2 Y"); ASSIGN_BUTTONf(kWinCMapPad2PL, "Joypad2 L"); ASSIGN_BUTTONf(kWinCMapPad2PR, "Joypad2 R"); ASSIGN_BUTTONf(kWinCMapPad2PSelect, "Joypad2 Select"); ASSIGN_BUTTONf(kWinCMapPad2PStart, "Joypad2 Start"); ASSIGN_BUTTONf(kWinCMapPad2PUp, "Joypad2 Up"); ASSIGN_BUTTONf(kWinCMapPad2PDown, "Joypad2 Down"); ASSIGN_BUTTONf(kWinCMapPad2PLeft, "Joypad2 Left"); ASSIGN_BUTTONf(kWinCMapPad2PRight, "Joypad2 Right"); ASSIGN_BUTTONf(kWinCMapPad3PX, "Joypad3 X"); ASSIGN_BUTTONf(kWinCMapPad3PA, "Joypad3 A"); ASSIGN_BUTTONf(kWinCMapPad3PB, "Joypad3 B"); ASSIGN_BUTTONf(kWinCMapPad3PY, "Joypad3 Y"); ASSIGN_BUTTONf(kWinCMapPad3PL, "Joypad3 L"); ASSIGN_BUTTONf(kWinCMapPad3PR, "Joypad3 R"); ASSIGN_BUTTONf(kWinCMapPad3PSelect, "Joypad3 Select"); ASSIGN_BUTTONf(kWinCMapPad3PStart, "Joypad3 Start"); ASSIGN_BUTTONf(kWinCMapPad3PUp, "Joypad3 Up"); ASSIGN_BUTTONf(kWinCMapPad3PDown, "Joypad3 Down"); ASSIGN_BUTTONf(kWinCMapPad3PLeft, "Joypad3 Left"); ASSIGN_BUTTONf(kWinCMapPad3PRight, "Joypad3 Right"); ASSIGN_BUTTONf(kWinCMapPad4PX, "Joypad4 X"); ASSIGN_BUTTONf(kWinCMapPad4PA, "Joypad4 A"); ASSIGN_BUTTONf(kWinCMapPad4PB, "Joypad4 B"); ASSIGN_BUTTONf(kWinCMapPad4PY, "Joypad4 Y"); ASSIGN_BUTTONf(kWinCMapPad4PL, "Joypad4 L"); ASSIGN_BUTTONf(kWinCMapPad4PR, "Joypad4 R"); ASSIGN_BUTTONf(kWinCMapPad4PSelect, "Joypad4 Select"); ASSIGN_BUTTONf(kWinCMapPad4PStart, "Joypad4 Start"); ASSIGN_BUTTONf(kWinCMapPad4PUp, "Joypad4 Up"); ASSIGN_BUTTONf(kWinCMapPad4PDown, "Joypad4 Down"); ASSIGN_BUTTONf(kWinCMapPad4PLeft, "Joypad4 Left"); ASSIGN_BUTTONf(kWinCMapPad4PRight, "Joypad4 Right"); ASSIGN_BUTTONf(kWinCMapPad5PX, "Joypad5 X"); ASSIGN_BUTTONf(kWinCMapPad5PA, "Joypad5 A"); ASSIGN_BUTTONf(kWinCMapPad5PB, "Joypad5 B"); ASSIGN_BUTTONf(kWinCMapPad5PY, "Joypad5 Y"); ASSIGN_BUTTONf(kWinCMapPad5PL, "Joypad5 L"); ASSIGN_BUTTONf(kWinCMapPad5PR, "Joypad5 R"); ASSIGN_BUTTONf(kWinCMapPad5PSelect, "Joypad5 Select"); ASSIGN_BUTTONf(kWinCMapPad5PStart, "Joypad5 Start"); ASSIGN_BUTTONf(kWinCMapPad5PUp, "Joypad5 Up"); ASSIGN_BUTTONf(kWinCMapPad5PDown, "Joypad5 Down"); ASSIGN_BUTTONf(kWinCMapPad5PLeft, "Joypad5 Left"); ASSIGN_BUTTONf(kWinCMapPad5PRight, "Joypad5 Right"); ASSIGN_BUTTONf(kWinCMapPad6PX, "Joypad6 X"); ASSIGN_BUTTONf(kWinCMapPad6PA, "Joypad6 A"); ASSIGN_BUTTONf(kWinCMapPad6PB, "Joypad6 B"); ASSIGN_BUTTONf(kWinCMapPad6PY, "Joypad6 Y"); ASSIGN_BUTTONf(kWinCMapPad6PL, "Joypad6 L"); ASSIGN_BUTTONf(kWinCMapPad6PR, "Joypad6 R"); ASSIGN_BUTTONf(kWinCMapPad6PSelect, "Joypad6 Select"); ASSIGN_BUTTONf(kWinCMapPad6PStart, "Joypad6 Start"); ASSIGN_BUTTONf(kWinCMapPad6PUp, "Joypad6 Up"); ASSIGN_BUTTONf(kWinCMapPad6PDown, "Joypad6 Down"); ASSIGN_BUTTONf(kWinCMapPad6PLeft, "Joypad6 Left"); ASSIGN_BUTTONf(kWinCMapPad6PRight, "Joypad6 Right"); ASSIGN_BUTTONf(kWinCMapPad7PX, "Joypad7 X"); ASSIGN_BUTTONf(kWinCMapPad7PA, "Joypad7 A"); ASSIGN_BUTTONf(kWinCMapPad7PB, "Joypad7 B"); ASSIGN_BUTTONf(kWinCMapPad7PY, "Joypad7 Y"); ASSIGN_BUTTONf(kWinCMapPad7PL, "Joypad7 L"); ASSIGN_BUTTONf(kWinCMapPad7PR, "Joypad7 R"); ASSIGN_BUTTONf(kWinCMapPad7PSelect, "Joypad7 Select"); ASSIGN_BUTTONf(kWinCMapPad7PStart, "Joypad7 Start"); ASSIGN_BUTTONf(kWinCMapPad7PUp, "Joypad7 Up"); ASSIGN_BUTTONf(kWinCMapPad7PDown, "Joypad7 Down"); ASSIGN_BUTTONf(kWinCMapPad7PLeft, "Joypad7 Left"); ASSIGN_BUTTONf(kWinCMapPad7PRight, "Joypad7 Right"); ASSIGN_BUTTONf(kWinCMapPad8PX, "Joypad8 X"); ASSIGN_BUTTONf(kWinCMapPad8PA, "Joypad8 A"); ASSIGN_BUTTONf(kWinCMapPad8PB, "Joypad8 B"); ASSIGN_BUTTONf(kWinCMapPad8PY, "Joypad8 Y"); ASSIGN_BUTTONf(kWinCMapPad8PL, "Joypad8 L"); ASSIGN_BUTTONf(kWinCMapPad8PR, "Joypad8 R"); ASSIGN_BUTTONf(kWinCMapPad8PSelect, "Joypad8 Select"); ASSIGN_BUTTONf(kWinCMapPad8PStart, "Joypad8 Start"); ASSIGN_BUTTONf(kWinCMapPad8PUp, "Joypad8 Up"); ASSIGN_BUTTONf(kWinCMapPad8PDown, "Joypad8 Down"); ASSIGN_BUTTONf(kWinCMapPad8PLeft, "Joypad8 Left"); ASSIGN_BUTTONf(kWinCMapPad8PRight, "Joypad8 Right"); ASSIGN_BUTTONt(kWinCMapMouse1PL, "Mouse1 L"); ASSIGN_BUTTONt(kWinCMapMouse1PR, "Mouse1 R"); ASSIGN_BUTTONt(kWinCMapMouse2PL, "Mouse2 L"); ASSIGN_BUTTONt(kWinCMapMouse2PR, "Mouse2 R"); ASSIGN_BUTTONt(kWinCMapScopeOffscreen, "Superscope AimOffscreen"); ASSIGN_BUTTONt(kWinCMapScopeFire, "Superscope Fire"); ASSIGN_BUTTONt(kWinCMapScopeCursor, "Superscope Cursor"); ASSIGN_BUTTONt(kWinCMapScopeTurbo, "Superscope ToggleTurbo"); ASSIGN_BUTTONt(kWinCMapScopePause, "Superscope Pause"); ASSIGN_BUTTONt(kWinCMapLGun1Offscreen, "Justifier1 AimOffscreen"); ASSIGN_BUTTONt(kWinCMapLGun1Trigger, "Justifier1 Trigger"); ASSIGN_BUTTONt(kWinCMapLGun1Start, "Justifier1 Start"); ASSIGN_BUTTONt(kWinCMapLGun2Offscreen, "Justifier2 AimOffscreen"); ASSIGN_BUTTONt(kWinCMapLGun2Trigger, "Justifier2 Trigger"); ASSIGN_BUTTONt(kWinCMapLGun2Start, "Justifier2 Start"); ASSIGN_POINTRt(kWinCMapMouse1Pointer, "Pointer Mouse1"); ASSIGN_POINTRt(kWinCMapMouse2Pointer, "Pointer Mouse2"); ASSIGN_POINTRt(kWinCMapSuperscopePointer, "Pointer Superscope"); ASSIGN_POINTRt(kWinCMapJustifier1Pointer, "Pointer Justifier1"); ASSIGN_POINTRf(PseudoPointerBase, "Pointer Justifier2"); ASSIGN_BUTTONf(kWinCMapPseudoPtrBase + 0, "ButtonToPointer 1u Med"); ASSIGN_BUTTONf(kWinCMapPseudoPtrBase + 1, "ButtonToPointer 1d Med"); ASSIGN_BUTTONf(kWinCMapPseudoPtrBase + 2, "ButtonToPointer 1l Med"); ASSIGN_BUTTONf(kWinCMapPseudoPtrBase + 3, "ButtonToPointer 1r Med"); } void ControlPadFlagsToS9xReportButtons(int n, uint32 p) { uint32 base = k_HD | k_BT | k_JP | (0x100 << n); S9xReportButton(base + 0, (p & 0x0040) != 0); S9xReportButton(base + 1, (p & 0x0080) != 0); S9xReportButton(base + 2, (p & 0x8000) != 0); S9xReportButton(base + 3, (p & 0x4000) != 0); S9xReportButton(base + 4, (p & 0x0020) != 0); S9xReportButton(base + 5, (p & 0x0010) != 0); S9xReportButton(base + 6, (p & 0x2000) != 0); S9xReportButton(base + 7, (p & 0x1000) != 0); S9xReportButton(base + 8, (p & 0x0800) != 0); S9xReportButton(base + 9, (p & 0x0400) != 0); S9xReportButton(base + 10, (p & 0x0200) != 0); S9xReportButton(base + 11, (p & 0x0100) != 0); } void ControlPadFlagsToS9xPseudoPointer(uint32 p) { // prevent screwiness caused by trying to move the pointer left+right or up+down if((p & 0x0c00) == 0x0c00) p &= ~0x0c00; if((p & 0x0300) == 0x0300) p &= ~0x0300; // checks added to prevent a lack of right/down movement from breaking left/up movement if(!(p & 0x0400)) S9xReportButton(kWinCMapPseudoPtrBase + 0, (p & 0x0800) != 0); if(!(p & 0x0800)) S9xReportButton(kWinCMapPseudoPtrBase + 1, (p & 0x0400) != 0); if(!(p & 0x0100)) S9xReportButton(kWinCMapPseudoPtrBase + 2, (p & 0x0200) != 0); if(!(p & 0x0200)) S9xReportButton(kWinCMapPseudoPtrBase + 3, (p & 0x0100) != 0); } static void ProcessInput(void) { extern void S9xWinScanJoypads (); #ifdef NETPLAY_SUPPORT if (!Settings.NetPlay) #endif S9xWinScanJoypads (); extern uint32 joypads [8]; for(int i = 0 ; i < 8 ; i++) ControlPadFlagsToS9xReportButtons(i, joypads[i]); if (GUI.ControllerOption==SNES_JUSTIFIER_2) ControlPadFlagsToS9xPseudoPointer(joypads[1]); } static void WinDisplayString (const char *string, int linesFromBottom, int pixelsFromLeft, bool allowWrap); /*****************************************************************************/ /* WinMain */ /*****************************************************************************/ extern "C" void S9xMainLoop(void); int Init3d (HWND); extern "C" void DeinitS9x(void); int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { Settings.StopEmulation = TRUE; // Redirect stderr and stdout to file. It wouldn't go to any commandline anyway. FILE* fout = freopen("stdout.txt", "w", stdout); if(fout) setvbuf(fout, NULL, _IONBF, 0); FILE* ferr = freopen("stderr.txt", "w", stderr); if(ferr) setvbuf(ferr, NULL, _IONBF, 0); DWORD wSoundTimerRes; WinRegisterConfigItems (); ConfigFile::SetAlphaSort(false); ConfigFile::SetTimeSort(false); rom_filename = WinParseCommandLineAndLoadConfigFile (lpCmdLine); WinSaveConfigFile (); WinLockConfigFile (); bool maximized = GUI.window_maximized; WinInit (hInstance); if(GUI.HideMenu) { SetMenu (GUI.hWnd, NULL); } // GUI.hWnd = _MainWindow (); // SetMenu (GUI.hWnd, GUI.hMenu); //_InitDLL (GUI.hWnd); /* if (_GUIVersion () != GUI_VERSION) { MessageBox (GUI.hWnd, "Incorrect version of Snes9XW.dll dynamic-link library file found.\n\nPlease check you extracted both the Snes9XW.exe and Snes9XW.dll\nfiles into the same directory from the Snes9XW distribution\nzip file.", "Snes9X - Incorrect Snes9XW.dll Version", MB_OK | MB_ICONSTOP); return false; } */ DirectX.InitDirectSound (); if (!SetupSound (Settings.SoundPlaybackRate, Settings.SixteenBitSound, Settings.Stereo)) { MessageBox( GUI.hWnd, Languages[ GUI.Language].errInitDS, TEXT("Snes9X - DirectSound"), MB_OK | MB_ICONINFORMATION); } #ifdef USE_GLIDE if (VOODOO_MODE) { if (!S9xVoodooInitialise ()) { GUI.Scale = 0; GUI.NextScale = 0; } else { GUI.FullScreen = FALSE; Settings.SixteenBit = TRUE; } } #endif #ifdef USE_OPENGL OpenGL.initialized = false; if (OPENGL_MODE) { if (!S9xOpenGLInit ()) { GUI.Scale = FILTER_NONE; GUI.NextScale = FILTER_NONE; } } #endif extern void InitLUTs(); // init hq2x InitLUTs(); S9xCustomDisplayString = WinDisplayString; if (!VOODOO_MODE && !OPENGL_MODE && !DirectX.InitDirectX ()) { MessageBox (GUI.hWnd, Languages[ GUI.Language].errInitDD, TEXT("Snes9X - DirectX"), MB_OK | MB_ICONSTOP); return false; } if (!GUI.FullScreen) { MoveWindow (GUI.hWnd, GUI.window_size.left, GUI.window_size.top, GUI.window_size.right - GUI.window_size.left, GUI.window_size.bottom - GUI.window_size.top, TRUE); } if (!VOODOO_MODE && !OPENGL_MODE && !DirectX.SetDisplayMode (GUI.Width, GUI.Height, max(GetFilterScale(GUI.Scale), GetFilterScale(GUI.ScaleHiRes)), GUI.Depth, GUI.RefreshRate, !GUI.FullScreen, GUI.DoubleBuffered)) { MessageBox( GUI.hWnd, Languages[ GUI.Language].errModeDD, TEXT("Snes9X - DirectDraw(7)"), MB_OK | MB_ICONSTOP); GUI.FullScreen = FALSE; if (!DirectX.SetDisplayMode (GUI.Width, GUI.Height, max(GetFilterScale(GUI.Scale), GetFilterScale(GUI.ScaleHiRes)), GUI.Depth, GUI.RefreshRate, !GUI.FullScreen, GUI.DoubleBuffered)) return (false); } if (!GUI.FullScreen) { RECT rect; GetClientRect (GUI.hWnd, &rect); InvalidateRect (GUI.hWnd, &rect, true); } GUI.ControlForced = 0xff; S9xSetRecentGames (); ShowWindow (GUI.hWnd, maximized ? SW_MAXIMIZE : SW_SHOWNORMAL); SetForegroundWindow (GUI.hWnd); SetFocus (GUI.hWnd); #ifdef USE_DIRECTX3D if (Init3d (GUI.hWnd) != -100) { MessageBox (GUI.hWnd, TEXT("InitD3D failed."), TEXT("InitD3D Error"), MB_OK | MB_ICONINFORMATION); exit (1); } #endif // hack for borders-not-shown bug (Windows bug?) on startup if(!maximized) { ShowWindow (GUI.hWnd, SW_HIDE); ShowWindow (GUI.hWnd, SW_SHOWNORMAL); } void InitSnes9X (void); InitSnes9X (); TIMECAPS tc; if (timeGetDevCaps(&tc, sizeof(TIMECAPS))== TIMERR_NOERROR) { #ifdef __MINGW32__ wSoundTimerRes = min(max(tc.wPeriodMin, 1), tc.wPeriodMax); #else wSoundTimerRes = min(max(tc.wPeriodMin, 1), tc.wPeriodMax); #endif timeBeginPeriod (wSoundTimerRes); } else { wSoundTimerRes = 5; timeBeginPeriod (wSoundTimerRes); } QueryPerformanceFrequency((LARGE_INTEGER*)&PCBase); QueryPerformanceCounter((LARGE_INTEGER*)&PCStart); PCEnd = PCStart; PCEndTicks = timeGetTime()*1000; PCStartTicks = timeGetTime()*1000; PCFrameTime = PCFrameTimeNTSC = (__int64)((float)PCBase / 59.948743718592964824120603015098f); PCFrameTimePAL = PCBase / 50; Settings.StopEmulation = TRUE; GUI.hFrameTimer = timeSetEvent (20, 0, FrameTimer, 0, TIME_PERIODIC); GUI.hSoundTimer = timeSetEvent (5, 0, SoundTimer, 0, TIME_PERIODIC); if(GUI.JoystickHotkeys || GUI.BackgroundKeyHotkeys) GUI.hHotkeyTimer = timeSetEvent (32, 0, HotkeyTimer, 0, TIME_PERIODIC); else GUI.hHotkeyTimer = 0; GUI.FrameTimerSemaphore = CreateSemaphore (NULL, 0, 10, NULL); GUI.ServerTimerSemaphore = CreateSemaphore (NULL, 0, 10, NULL); if (GUI.hFrameTimer == 0) { MessageBox( GUI.hWnd, Languages[ GUI.Language].errFrameTimer, TEXT("Snes9X - Frame Timer"), MB_OK | MB_ICONINFORMATION); } Settings.StopEmulation = !LoadROM (rom_filename); if (!Settings.StopEmulation) { bool8 loaded = Memory.LoadSRAM (S9xGetFilename (".srm", SRAM_DIR)); if(!loaded) // help migration from earlier Snes9x versions by checking ROM directory for savestates Memory.LoadSRAM (S9xGetFilename (".srm", ROMFILENAME_DIR)); S9xLoadCheatFile (S9xGetFilename (".cht", CHEAT_DIR)); CheckDirectoryIsWritable (S9xGetFilename (".---", SNAPSHOT_DIR)); CheckMenuStates (); } if (!Settings.StopEmulation) { if (GUI.ControllerOption == SNES_SUPERSCOPE) SetCursor (GUI.GunSight); else { SetCursor (GUI.Arrow); GUI.CursorTimer = 60; } } S9xUnmapAllControls(); S9xSetupDefaultKeymap(); ChangeInputDevice(); DWORD lastTime = timeGetTime(); MSG msg; while (TRUE) { EnsureInputDisplayUpdated(); // note: using GUI.hWnd instead of NULL for PeekMessage/GetMessage breaks some non-modal dialogs while (Settings.StopEmulation || (Settings.Paused && !Settings.FrameAdvance) || Settings.ForcedPause || PeekMessage (&msg, NULL, 0, 0, PM_NOREMOVE)) { if (!GetMessage (&msg, NULL, 0, 0)) goto loop_exit; // got WM_QUIT if (!TranslateAccelerator (GUI.hWnd, GUI.Accelerators, &msg)) { TranslateMessage (&msg); DispatchMessage (&msg); } } #ifdef NETPLAY_SUPPORT if (!Settings.NetPlay || !NetPlay.PendingWait4Sync || WaitForSingleObject (GUI.ClientSemaphore, 100) != WAIT_TIMEOUT) { if (NetPlay.PendingWait4Sync) { NetPlay.PendingWait4Sync = FALSE; NetPlay.FrameCount++; S9xNPStepJoypadHistory (); } #endif if(watches[0].on) { // copy the memory used by each active watch for(unsigned int i = 0 ; i < sizeof(watches)/sizeof(*watches) ; i++) { if(watches[i].on) { int address = watches[i].address - 0x7E0000; const uint8* source; if(address < 0x20000) source = Memory.RAM + address ; else if(address < 0x30000) source = Memory.SRAM + address - 0x20000; else source = Memory.FillRAM + address - 0x30000; CopyMemory(Cheat.CWatchRAM + address, source, watches[i].size); } } } if(cheatSearchHWND) { if(timeGetTime() - lastTime >= 100) { SendMessage(cheatSearchHWND, WM_COMMAND, (WPARAM)(IDC_REFRESHLIST),(LPARAM)(NULL)); lastTime = timeGetTime(); } } // the following is a hack to allow frametimes greater than 100ms, // without affecting the responsiveness of the GUI BOOL run_loop=false; do_frame_adjust=false; if (Settings.TurboMode || Settings.FrameAdvance || Settings.SkipFrames != AUTO_FRAMERATE #ifdef NETPLAY_SUPPORT || Settings.NetPlay #endif ) { run_loop=true; } else { LONG prev; BOOL success; if ((success = ReleaseSemaphore (GUI.FrameTimerSemaphore, 1, &prev)) && prev == 0) { WaitForSingleObject (GUI.FrameTimerSemaphore, 0); if (WaitForSingleObject (GUI.FrameTimerSemaphore, 100) == WAIT_OBJECT_0) { run_loop=true; } } else { if (success) WaitForSingleObject (GUI.FrameTimerSemaphore, 0); WaitForSingleObject (GUI.FrameTimerSemaphore, 0); run_loop=true; do_frame_adjust=true; } } if(Settings.FrameAdvance) { if(GFX.InfoStringTimeout > 4) GFX.InfoStringTimeout = 4; if(!GUI.FASkipsNonInput) Settings.FrameAdvance = false; } if(GUI.FrameAdvanceJustPressed) GUI.FrameAdvanceJustPressed--; if(run_loop) { ProcessInput(); S9xMainLoop(); DirectX.FrameCount++; } #ifdef NETPLAY_SUPPORT } #endif if (CPU.Flags & DEBUG_MODE_FLAG) { Settings.Paused = TRUE; Settings.FrameAdvance = false; CPU.Flags &= ~DEBUG_MODE_FLAG; } if (GUI.CursorTimer) { if (--GUI.CursorTimer == 0) { if(!Settings.SuperScopeMaster) SetCursor (NULL); } } } loop_exit: #ifdef USE_GLIDE S9xGlideEnable (FALSE); #endif Settings.StopEmulation = TRUE; if (GUI.hHotkeyTimer) timeKillEvent (GUI.hHotkeyTimer); if (GUI.hSoundTimer) timeKillEvent (GUI.hSoundTimer); if( GUI.hFrameTimer) { timeKillEvent (GUI.hFrameTimer); timeEndPeriod (wSoundTimerRes); } if (!Settings.StopEmulation) { Memory.SaveSRAM (S9xGetFilename (".srm", SRAM_DIR)); S9xSaveCheatFile (S9xGetFilename (".cht", CHEAT_DIR)); } //if (!VOODOO_MODE && !GUI.FullScreen) // GetWindowRect (GUI.hWnd, &GUI.window_size); #ifdef USE_OPENGL if (OPENGL_MODE) S9xOpenGLDeinit (); #endif // this goes here, because the avi // recording might have messed with // the auto frame skip setting // (it needs to come before WinSave) DoAVIClose(0); S9xMovieShutdown (); // must happen before saving config WinUnlockConfigFile (); WinSaveConfigFile (); WinCleanupConfigData(); Memory.Deinit(); #ifdef USE_GLIDE if(Settings.GlideEnable) S9xGlideDeinit(); else if (Settings.OpenGLEnable) #else if (Settings.OpenGLEnable) #endif #ifdef USE_OPENGL S9xOpenGLDeinit(); #endif S9xGraphicsDeinit(); S9xDeinitAPU(); WinDeleteRecentGamesList (); DeinitS9x(); #ifdef CHECK_MEMORY_LEAKS _CrtDumpMemoryLeaks(); #endif return msg.wParam; } void RestoreGUIDisplay () { S9xSetPause (PAUSE_RESTORE_GUI); #ifdef USE_GLIDE S9xGlideEnable (FALSE); #endif if (!VOODOO_MODE && !OPENGL_MODE && GUI.FullScreen && (GUI.Width < 640 || GUI.Height < 400) && !DirectX.SetDisplayMode (640, 480, 1, 0, 60, !GUI.FullScreen, false)) { MessageBox (GUI.hWnd, Languages[ GUI.Language].errModeDD, TEXT("Snes9X - DirectDraw(1)"), MB_OK | MB_ICONSTOP); S9xClearPause (PAUSE_RESTORE_GUI); return; } SwitchToGDI(); S9xClearPause (PAUSE_RESTORE_GUI); } void RestoreSNESDisplay () { if (!VOODOO_MODE && !OPENGL_MODE && !DirectX.SetDisplayMode (GUI.Width, GUI.Height, max(GetFilterScale(GUI.Scale), GetFilterScale(GUI.ScaleHiRes)), GUI.Depth, GUI.RefreshRate, !GUI.FullScreen, GUI.DoubleBuffered)) { MessageBox (GUI.hWnd, Languages[ GUI.Language].errModeDD, TEXT("Snes9X - DirectDraw(4)"), MB_OK | MB_ICONSTOP); return; } // S9xInitUpdate(); #ifdef USE_GLIDE if (VOODOO_MODE && Glide.voodoo_present) { //S9xGlideEnable (TRUE); } #endif UpdateBackBuffer(); } void FreezeUnfreeze (int slot, bool8 freeze) { static TCHAR filename [_MAX_PATH + 1]; TCHAR drive [_MAX_DRIVE + 1]; TCHAR dir [_MAX_DIR + 1]; TCHAR fname [_MAX_FNAME + 1]; TCHAR ext [_MAX_EXT + 1]; #ifdef NETPLAY_SUPPORT if (!freeze && Settings.NetPlay && !Settings.NetPlayServer) { S9xMessage (S9X_INFO, S9X_NETPLAY_NOT_SERVER, "Only the server is allowed to load freeze files."); return; } #endif _splitpath (Memory.ROMFilename, drive, dir, fname, ext); static char *digits = "t123456789"; for(int oldDir = 0; oldDir <= 1; oldDir++) { for(int zmv = 0; zmv <= 1; zmv++) { if((!oldDir && !zmv) || (!freeze && _access (filename, 0) != 0 && slot < 10)) { if(!zmv) sprintf (ext, TEXT(".%03d"), slot); else sprintf (ext, TEXT(".zs%c"), digits [slot]); if (GUI.FreezeFileDir [0]) { strcpy (filename, oldDir ? S9xGetDirectory(ROMFILENAME_DIR) : S9xGetDirectory(SNAPSHOT_DIR)); strcat (filename, TEXT("\\")); strcat (filename, fname); strcat (filename, ext); } else _makepath (filename, drive, dir, fname, ext); } } } S9xSetPause (PAUSE_FREEZE_FILE); if (freeze) { // extern bool diagnostic_freezing; // if(GetAsyncKeyState('Q') && GetAsyncKeyState('W') && GetAsyncKeyState('E') && GetAsyncKeyState('R')) // { // diagnostic_freezing = true; // } S9xFreezeGame (filename); // // diagnostic_freezing = false; } else { const int prevSavedAtOp = ICPU.SavedAtOp; if (S9xUnfreezeGame (filename)) { // S9xMessage (S9X_INFO, S9X_FREEZE_FILE_INFO, S9xBasename (filename)); #ifdef NETPLAY_SUPPORT S9xNPServerQueueSendingFreezeFile (filename); #endif // UpdateBackBuffer(); } // fix next frame advance after loading non-skipping state from a skipping state if(prevSavedAtOp && !ICPU.SavedAtOp) skipNextFrameStop = true; } S9xClearPause (PAUSE_FREEZE_FILE); } void CheckDirectoryIsWritable (const char *filename) { FILE *fs = fopen (filename, "w+"); if (fs == NULL) MessageBox (GUI.hWnd, TEXT("The folder where Snes9X saves emulated save RAM files and\ngame save positions (freeze files) is currently set to a\nread-only folder.\n\nIf you do not change the game save folder, Snes9X will be\nunable to save your progress in this game. Change the folder\nfrom the Settings Dialog available from the Options menu.\n\nThe default save folder is called Saves, if no value is set.\n"), TEXT("Snes9X: Unable to save file warning"), MB_OK | MB_ICONINFORMATION); else { fclose (fs); remove (filename); } } static void CheckMenuStates () { MENUITEMINFO mii; unsigned int i; ZeroMemory( &mii, sizeof( mii)); mii.cbSize = sizeof( mii); mii.fMask = MIIM_STATE; mii.fState = GUI.FullScreen ? MFS_CHECKED : MFS_UNCHECKED; SetMenuItemInfo (GUI.hMenu, ID_WINDOW_FULLSCREEN, FALSE, &mii); mii.fState = GUI.Stretch ? MFS_CHECKED : MFS_UNCHECKED; SetMenuItemInfo (GUI.hMenu, ID_WINDOW_STRETCH, FALSE, &mii); mii.fState = GUI.Stretch ? (GUI.AspectRatio ? MFS_CHECKED : MFS_UNCHECKED) : MFS_CHECKED|MFS_DISABLED; SetMenuItemInfo (GUI.hMenu, ID_WINDOW_ASPECTRATIO, FALSE, &mii); mii.fState = GUI.VideoMemory ? MFS_CHECKED : MFS_UNCHECKED; if(!GUI.Stretch) mii.fState |= MFS_DISABLED; SetMenuItemInfo (GUI.hMenu, ID_WINDOW_VIDMEM, FALSE, &mii); mii.fState = (Settings.Paused && !Settings.StopEmulation) ? MFS_CHECKED : MFS_UNCHECKED; SetMenuItemInfo (GUI.hMenu, ID_FILE_PAUSE, FALSE, &mii); mii.fState = MFS_UNCHECKED; if (Settings.StopEmulation) mii.fState |= MFS_DISABLED; SetMenuItemInfo (GUI.hMenu, ID_FILE_SAVE_SPC_DATA, FALSE, &mii); SetMenuItemInfo (GUI.hMenu, ID_FILE_SAVE_SRAM_DATA, FALSE, &mii); SetMenuItemInfo (GUI.hMenu, ID_FILE_SAVE1, FALSE, &mii); SetMenuItemInfo (GUI.hMenu, ID_FILE_SAVE2, FALSE, &mii); SetMenuItemInfo (GUI.hMenu, ID_FILE_SAVE3, FALSE, &mii); SetMenuItemInfo (GUI.hMenu, ID_FILE_SAVE4, FALSE, &mii); SetMenuItemInfo (GUI.hMenu, ID_FILE_SAVE5, FALSE, &mii); SetMenuItemInfo (GUI.hMenu, ID_FILE_SAVE6, FALSE, &mii); SetMenuItemInfo (GUI.hMenu, ID_FILE_SAVE7, FALSE, &mii); SetMenuItemInfo (GUI.hMenu, ID_FILE_SAVE8, FALSE, &mii); SetMenuItemInfo (GUI.hMenu, ID_FILE_SAVE9, FALSE, &mii); SetMenuItemInfo (GUI.hMenu, ID_FILE_LOAD1, FALSE, &mii); SetMenuItemInfo (GUI.hMenu, ID_FILE_LOAD2, FALSE, &mii); SetMenuItemInfo (GUI.hMenu, ID_FILE_LOAD3, FALSE, &mii); SetMenuItemInfo (GUI.hMenu, ID_FILE_LOAD4, FALSE, &mii); SetMenuItemInfo (GUI.hMenu, ID_FILE_LOAD5, FALSE, &mii); SetMenuItemInfo (GUI.hMenu, ID_FILE_LOAD6, FALSE, &mii); SetMenuItemInfo (GUI.hMenu, ID_FILE_LOAD7, FALSE, &mii); SetMenuItemInfo (GUI.hMenu, ID_FILE_LOAD8, FALSE, &mii); SetMenuItemInfo (GUI.hMenu, ID_FILE_LOAD9, FALSE, &mii); SetMenuItemInfo (GUI.hMenu, ID_FILE_RESET, FALSE, &mii); SetMenuItemInfo (GUI.hMenu, ID_CHEAT_ENTER, FALSE, &mii); SetMenuItemInfo (GUI.hMenu, ID_CHEAT_SEARCH_MODAL, FALSE, &mii); if (GUI.FullScreen) mii.fState |= MFS_DISABLED; SetMenuItemInfo (GUI.hMenu, ID_CHEAT_SEARCH, FALSE, &mii); #ifdef NETPLAY_SUPPORT if (Settings.NetPlay && !Settings.NetPlayServer) mii.fState = MFS_DISABLED; else mii.fState = Settings.NetPlayServer ? MFS_CHECKED : MFS_UNCHECKED; SetMenuItemInfo (GUI.hMenu, ID_NETPLAY_SERVER, FALSE, &mii); mii.fState = Settings.NetPlay && !Settings.NetPlayServer ? 0 : MFS_DISABLED; SetMenuItemInfo (GUI.hMenu, ID_NETPLAY_DISCONNECT, FALSE, &mii); mii.fState = Settings.NetPlay || Settings.NetPlayServer ? MFS_DISABLED : 0; SetMenuItemInfo (GUI.hMenu, ID_NETPLAY_CONNECT, FALSE, &mii); mii.fState = NPServer.SendROMImageOnConnect ? MFS_CHECKED : MFS_UNCHECKED; SetMenuItemInfo (GUI.hMenu, ID_NETPLAY_SEND_ROM_ON_CONNECT, FALSE, &mii); mii.fState = NPServer.SyncByReset ? MFS_CHECKED : MFS_UNCHECKED; SetMenuItemInfo (GUI.hMenu, ID_NETPLAY_SYNC_BY_RESET, FALSE, &mii); mii.fState = Settings.NetPlayServer ? 0 : MFS_DISABLED; SetMenuItemInfo (GUI.hMenu, ID_NETPLAY_SYNC, FALSE, &mii); SetMenuItemInfo (GUI.hMenu, ID_NETPLAY_ROM, FALSE, &mii); #endif mii.fState = Settings.ApplyCheats ? MFS_CHECKED : MFS_UNCHECKED; if (Settings.StopEmulation) mii.fState |= MFS_DISABLED; SetMenuItemInfo( GUI.hMenu, ID_CHEAT_APPLY, FALSE, &mii); mii.fState = MFS_UNCHECKED; SetMenuItemInfo (GUI.hMenu, ID_SOUND_OPTIONS, FALSE, &mii); if (!Settings.APUEnabled) mii.fState |= MFS_DISABLED; SetMenuItemInfo (GUI.hMenu, ID_SOUND_NOSOUND, FALSE, &mii); for (i = 0; i < COUNT(SoundRates); i++) SetMenuItemInfo (GUI.hMenu, SoundRates[i].ident, FALSE, &mii); if (Settings.SoundPlaybackRate == 0 || Settings.Mute) mii.fState |= MFS_DISABLED; SetMenuItemInfo (GUI.hMenu, ID_SOUND_16BIT, FALSE, &mii); SetMenuItemInfo (GUI.hMenu, ID_SOUND_STEREO, FALSE, &mii); SetMenuItemInfo (GUI.hMenu, ID_SOUND_SYNC, FALSE, &mii); SetMenuItemInfo (GUI.hMenu, ID_SOUND_INTERPOLATED, FALSE, &mii); SetMenuItemInfo (GUI.hMenu, ID_SOUND_25MS, FALSE, &mii); SetMenuItemInfo (GUI.hMenu, ID_SOUND_50MS, FALSE, &mii); SetMenuItemInfo (GUI.hMenu, ID_SOUND_100MS, FALSE, &mii); SetMenuItemInfo (GUI.hMenu, ID_SOUND_200MS, FALSE, &mii); SetMenuItemInfo (GUI.hMenu, ID_SOUND_500MS, FALSE, &mii); SetMenuItemInfo (GUI.hMenu, ID_SOUND_1S, FALSE, &mii); SetMenuItemInfo (GUI.hMenu, ID_SOUND_2S, FALSE, &mii); if (!Settings.Stereo) mii.fState |= MFS_DISABLED; SetMenuItemInfo (GUI.hMenu, ID_SOUND_REVERSE_STEREO, FALSE, &mii); mii.fState = !Settings.APUEnabled ? MFS_CHECKED | MFS_DISABLED : MFS_CHECKED; if (!DirectX.DSAvailable || Settings.SoundPlaybackRate == 0 || Settings.Mute || !Settings.APUEnabled) SetMenuItemInfo (GUI.hMenu, ID_SOUND_NOSOUND, FALSE, &mii); else { for (i = 0; i < COUNT(SoundRates); i++) { if (SoundRates [i].rate == Settings.SoundPlaybackRate) { SetMenuItemInfo (GUI.hMenu, SoundRates[i].ident, FALSE, &mii); break; } } } if (Settings.SoundPlaybackRate == 0 || Settings.Mute) mii.fState |= MFS_DISABLED; int id; switch (Settings.SoundBufferSize) { case 1: id = ID_SOUND_25MS; break; case 2: id = ID_SOUND_50MS; break; default: case 4: id = ID_SOUND_100MS; break; case 8: id = ID_SOUND_200MS; break; case 16: id = ID_SOUND_500MS; break; case 32: id = ID_SOUND_1S; break; case 64: id = ID_SOUND_2S; break; } SetMenuItemInfo (GUI.hMenu, id, FALSE, &mii); if (Settings.SixteenBitSound) SetMenuItemInfo (GUI.hMenu, ID_SOUND_16BIT, FALSE, &mii); if (Settings.Stereo) SetMenuItemInfo (GUI.hMenu, ID_SOUND_STEREO, FALSE, &mii); if (Settings.InterpolatedSound) SetMenuItemInfo (GUI.hMenu, ID_SOUND_INTERPOLATED, FALSE,&mii); if (Settings.SoundSync) SetMenuItemInfo (GUI.hMenu, ID_SOUND_SYNC, FALSE, &mii); if (!Settings.Stereo) mii.fState |= MFS_DISABLED; if (Settings.ReverseStereo) SetMenuItemInfo (GUI.hMenu, ID_SOUND_REVERSE_STEREO, FALSE, &mii); #ifndef DEBUGGER mii.fState = MFS_DISABLED; #else mii.fState = MFS_UNCHECKED; #endif SetMenuItemInfo (GUI.hMenu, ID_DEBUG_TRACE, FALSE, &mii); SetMenuItemInfo (GUI.hMenu, ID_DEBUG_TRACE_SPC, FALSE, &mii); SetMenuItemInfo (GUI.hMenu, ID_DEBUG_TRACE_SA1, FALSE, &mii); SetMenuItemInfo (GUI.hMenu, ID_DEBUG_TRACE_DSP1, FALSE, &mii); SetMenuItemInfo (GUI.hMenu, ID_DEBUG_FRAME_ADVANCE, FALSE, &mii); SetMenuItemInfo (GUI.hMenu, ID_DEBUG_SNES_STATUS, FALSE, &mii); mii.fState = (!Settings.StopEmulation) ? MFS_ENABLED : MFS_DISABLED; SetMenuItemInfo (GUI.hMenu, ID_FILE_MOVIE_PLAY, FALSE, &mii); SetMenuItemInfo (GUI.hMenu, ID_FILE_MOVIE_RECORD, FALSE, &mii); mii.fState = (S9xMovieActive () && !Settings.StopEmulation) ? MFS_ENABLED : MFS_DISABLED; SetMenuItemInfo (GUI.hMenu, ID_FILE_MOVIE_STOP, FALSE, &mii); mii.fState = (!Settings.StopEmulation) ? MFS_ENABLED : MFS_DISABLED; SetMenuItemInfo (GUI.hMenu, ID_FILE_WRITE_AVI, FALSE, &mii); mii.fState = (!Settings.StopEmulation && (GUI.AVIOut)) ? MFS_ENABLED : MFS_DISABLED; SetMenuItemInfo (GUI.hMenu, ID_FILE_STOP_AVI, FALSE, &mii); mii.fState = (GUI.SoundChannelEnable & (1 << 0)) ? MFS_CHECKED : MFS_UNCHECKED; SetMenuItemInfo (GUI.hMenu, ID_CHANNELS_CHANNEL1, FALSE, &mii); mii.fState = (GUI.SoundChannelEnable & (1 << 1)) ? MFS_CHECKED : MFS_UNCHECKED; SetMenuItemInfo (GUI.hMenu, ID_CHANNELS_CHANNEL2, FALSE, &mii); mii.fState = (GUI.SoundChannelEnable & (1 << 2)) ? MFS_CHECKED : MFS_UNCHECKED; SetMenuItemInfo (GUI.hMenu, ID_CHANNELS_CHANNEL3, FALSE, &mii); mii.fState = (GUI.SoundChannelEnable & (1 << 3)) ? MFS_CHECKED : MFS_UNCHECKED; SetMenuItemInfo (GUI.hMenu, ID_CHANNELS_CHANNEL4, FALSE, &mii); mii.fState = (GUI.SoundChannelEnable & (1 << 4)) ? MFS_CHECKED : MFS_UNCHECKED; SetMenuItemInfo (GUI.hMenu, ID_CHANNELS_CHANNEL5, FALSE, &mii); mii.fState = (GUI.SoundChannelEnable & (1 << 5)) ? MFS_CHECKED : MFS_UNCHECKED; SetMenuItemInfo (GUI.hMenu, ID_CHANNELS_CHANNEL6, FALSE, &mii); mii.fState = (GUI.SoundChannelEnable & (1 << 6)) ? MFS_CHECKED : MFS_UNCHECKED; SetMenuItemInfo (GUI.hMenu, ID_CHANNELS_CHANNEL7, FALSE, &mii); mii.fState = (GUI.SoundChannelEnable & (1 << 7)) ? MFS_CHECKED : MFS_UNCHECKED; SetMenuItemInfo (GUI.hMenu, ID_CHANNELS_CHANNEL8, FALSE, &mii); UINT validFlag; enum controllers controller[2]; int8 ids[4]; S9xGetController(0, &controller[0], &ids[0],&ids[1],&ids[2],&ids[3]); S9xGetController(1, &controller[1], &ids[0],&ids[1],&ids[2],&ids[3]); validFlag = (((1<= 512) { OpenGL.texture_size = 512; OpenGL.num_textures = 2; } else { OpenGL.texture_size = OpenGL.max_texture_size; OpenGL.num_textures = 1; } Settings.OpenGLEnable = TRUE; const char *ext = (const char *) glGetString (GL_EXTENSIONS); if (ext && strstr (ext, "EXT_packed_pixels") != NULL) OpenGL.packed_pixels_extension_present = TRUE; const char *version = (const char *) glGetString (GL_VERSION); if (version && strlen (version) < 100) { char ver [100]; strcpy (ver, version); // Strip dots from the version string char *ptr; while (ptr = strchr (ver, '.')) memmove (ptr, ptr + 1, strlen (ptr + 1) + 1); // Pad the string with zeros to 4 digits while (strlen (ver) < 4) strcat (ver, "0"); OpenGL.version = atoi (ver); } else OpenGL.version = 1100; #ifndef GL_UNSIGNED_SHORT_5_5_5_1_EXT #define GL_UNSIGNED_SHORT_5_5_5_1_EXT 0x8034 #endif if (OpenGL.version >= 1200) { OpenGL.internal_format = GL_RGB5_A1; OpenGL.format = GL_RGBA; OpenGL.type = GL_UNSIGNED_SHORT_5_5_5_1_EXT; } else if (OpenGL.packed_pixels_extension_present) { OpenGL.internal_format = GL_RGB5_A1; OpenGL.format = GL_RGBA; OpenGL.type = GL_UNSIGNED_SHORT_5_5_5_1_EXT; } else { OpenGL.internal_format = GL_RGB; OpenGL.format = GL_RGB; OpenGL.type = GL_UNSIGNED_BYTE; } glGenTextures (OpenGL.num_textures, OpenGL.textures); if (OpenGL.num_textures == 2) { glBindTexture (GL_TEXTURE_2D, OpenGL.textures [1]); glTexImage2D (GL_TEXTURE_2D, 0, OpenGL.internal_format, 256, 256, 0, OpenGL.format, OpenGL.type, NULL); glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexEnvf (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); } glBindTexture (GL_TEXTURE_2D, OpenGL.textures [0]); glTexImage2D (GL_TEXTURE_2D, 0, OpenGL.internal_format, OpenGL.texture_size, OpenGL.texture_size, 0, OpenGL.format, OpenGL.type, NULL); glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexEnvf (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); glPolygonMode (GL_FRONT, GL_FILL); glEnable (GL_CULL_FACE); glCullFace (GL_BACK); glEnable (GL_DITHER); glEnable (GL_LIGHTING); glEnable (GL_LIGHT0); glEnable (GL_POINT_SMOOTH); glHint (GL_POINT_SMOOTH_HINT, GL_NICEST); glEnable (GL_TEXTURE_2D); glShadeModel (GL_SMOOTH); glClearColor (0.0f, 0.0f, 0.0f, 1.0f); glClearDepth (1.0f); glDisable (GL_DEPTH_TEST); glDepthFunc (GL_LESS); glHint (GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); GLfloat LightAmbient[] = { 0.2f, 0.2f, 0.2f, 1.0f }; GLfloat LightDiffuse[] = { 1.0f, 1.0f, 1.0f, 1.0f }; GLfloat LightSpecular[] = { 0.5f, 0.5f, 0.5f, 1.0f }; GLfloat LightPosition[] = { 0.0f, 0.0f, 2.0f, 1.0f }; glLightfv (GL_LIGHT0, GL_AMBIENT, LightAmbient); glLightfv (GL_LIGHT0, GL_DIFFUSE, LightDiffuse); glLightfv (GL_LIGHT0, GL_SPECULAR, LightSpecular); glLightfv (GL_LIGHT0, GL_POSITION, LightPosition); //Set common material properties GLfloat MatSpecular[] = { 1.0f, 1.0f, 1.0f, 1.1f }; GLfloat WhMat[] = { 1.0f, 1.0f, 1.0f, 1.0f }; glMaterialf (GL_FRONT_AND_BACK, GL_SHININESS, 128.0f); glMaterialfv (GL_FRONT_AND_BACK, GL_SPECULAR, MatSpecular); glMaterialfv (GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, WhMat); glMatrixMode (GL_PROJECTION); glLoadIdentity (); glMatrixMode (GL_MODELVIEW); glDisable (GL_DEPTH_TEST); glDisable (GL_LIGHTING); glEnable (GL_TEXTURE_2D); glTexEnvf (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL); glDisable (GL_BLEND); OpenGL.initialized = TRUE; return (TRUE); } void S9xOpenGLDeinit () { if (GUI.FullScreen) ChangeDisplaySettings (NULL, 0); if (GUI.hRC) { wglMakeCurrent (NULL, NULL); wglDeleteContext (GUI.hRC); GUI.hRC = NULL; } } void S9xOpenGLResize (int width, int height) { if (height == 0) height = 1; glViewport (0, 0, width, height); glMatrixMode (GL_PROJECTION); glLoadIdentity(); gluPerspective (45.0f, (GLfloat)width / (GLfloat)height, 0.1f, 100.0f); glMatrixMode (GL_MODELVIEW); } #endif void S9xAddToRecentGames (const char *filename) { // Make sure its not in the list already int i; for(i = 0; i < MAX_RECENT_GAMES_LIST_SIZE; i++) if (!*GUI.RecentGames[i] || strcmp (filename, GUI.RecentGames[i]) == 0) break; const bool underMax = (i < MAX_RECENT_GAMES_LIST_SIZE); if(underMax && *GUI.RecentGames[i]) { // It is in the list, move it to the head of the list. char temp [MAX_PATH]; strcpy(temp, GUI.RecentGames[i]); for(int j = i; j > 0; j--) strcpy(GUI.RecentGames[j], GUI.RecentGames[j-1]); strcpy(GUI.RecentGames[0], temp); } else { // Not in the list, add it. if(underMax) // Extend the recent game list length by 1. memmove(&GUI.RecentGames[1], &GUI.RecentGames[0], MAX_PATH*i); else // Throw the last item off the end of the list memmove(&GUI.RecentGames[1], &GUI.RecentGames[0], MAX_PATH*(i-1)); strcpy(GUI.RecentGames[0], filename); WinSaveConfigFile(); } S9xSetRecentGames(); } void S9xRemoveFromRecentGames (int i) { if (*GUI.RecentGames [i]) { for (int j = i; j < MAX_RECENT_GAMES_LIST_SIZE-1; j++) strcpy(GUI.RecentGames [j], GUI.RecentGames [j + 1]); *GUI.RecentGames [MAX_RECENT_GAMES_LIST_SIZE-1] = '\0'; S9xSetRecentGames (); } } void S9xSetRecentGames () { HMENU file = GetSubMenu (GUI.hMenu, 0); if (file) { HMENU recent = GetSubMenu (file, 1); if (recent) { MENUITEMINFO mii; TCHAR name [256 + 10]; int i; // Clear out the menu first for (i = GetMenuItemCount (recent) - 1; i >= 0; i--) RemoveMenu (recent, i, MF_BYPOSITION); mii.cbSize = sizeof (mii); mii.fMask = MIIM_TYPE | MIIM_DATA | MIIM_STATE | MIIM_ID; mii.fType = MFT_STRING; mii.fState = MFS_UNCHECKED; for (i = 0; i < MAX_RECENT_GAMES_LIST_SIZE && i < GUI.MaxRecentGames && *GUI.RecentGames [i]; i++) { // Build up a menu item string in the form: // 1. sprintf (name, TEXT("&%c. "), i < 9 ? '1' + i : 'A' + i - 9); // append the game title to name, with formatting modifications as necessary { TCHAR baseName [256]; strcpy (baseName, S9xBasename (GUI.RecentGames [i])); int pos = strlen (name), baseNameLen = strlen (baseName); for (int j = 0; j < baseNameLen ; j++) { char c = baseName [j]; name [pos++] = c; // & is a special character in Windows menus, // so we have to change & to && when copying over the game title // otherwise "Pocky & Rocky (U).smc" will show up as "Pocky _Rocky (U).smc", for example if(c == '&') name [pos++] = '&'; } name [pos] = '\0'; } mii.dwTypeData = name; mii.cch = strlen (name) + 1; mii.wID = 0xFF00 + i; InsertMenuItem (recent, 0xFF00 + i, FALSE, &mii); } } } } void WinDeleteRecentGamesList () { for(int i=0;iSoundDriver,0); SendDlgItemMessage(hDlg, IDC_SKIP_TYPE, CB_INSERTSTRING,0,(LPARAM)TEXT("Skip style #1")); SendDlgItemMessage(hDlg, IDC_SKIP_TYPE, CB_INSERTSTRING,1,(LPARAM)TEXT("Skip style #2")); SendDlgItemMessage(hDlg, IDC_SKIP_TYPE, CB_INSERTSTRING,2,(LPARAM)TEXT("Skip style #3")); SendDlgItemMessage(hDlg, IDC_SKIP_TYPE, CB_INSERTSTRING,3,(LPARAM)TEXT("Skip style #4")); SendDlgItemMessage(hDlg, IDC_SKIP_TYPE, CB_INSERTSTRING,4,(LPARAM)TEXT("Skip style #5")); SendDlgItemMessage(hDlg,IDC_SKIP_TYPE,CB_SETCURSEL,set->SoundSkipMethod,0); SendDlgItemMessage(hDlg, IDC_RATE, CB_INSERTSTRING,0,(LPARAM)TEXT("8 KHz")); SendDlgItemMessage(hDlg, IDC_RATE, CB_INSERTSTRING,1,(LPARAM)TEXT("11 KHz")); SendDlgItemMessage(hDlg, IDC_RATE, CB_INSERTSTRING,2,(LPARAM)TEXT("16 KHz")); SendDlgItemMessage(hDlg, IDC_RATE, CB_INSERTSTRING,3,(LPARAM)TEXT("22 KHz")); SendDlgItemMessage(hDlg, IDC_RATE, CB_INSERTSTRING,4,(LPARAM)TEXT("30 KHz")); SendDlgItemMessage(hDlg, IDC_RATE, CB_INSERTSTRING,5,(LPARAM)TEXT("32 KHz")); SendDlgItemMessage(hDlg, IDC_RATE, CB_INSERTSTRING,6,(LPARAM)TEXT("35 KHz")); SendDlgItemMessage(hDlg, IDC_RATE, CB_INSERTSTRING,7,(LPARAM)TEXT("44 KHz")); SendDlgItemMessage(hDlg, IDC_RATE, CB_INSERTSTRING,8,(LPARAM)TEXT("48 KHz")); int temp; switch(set->SoundPlaybackRate) { case 8000:temp=0;break; case 11025:temp=1;break; case 16000:temp=2;break; case 22050:temp=3;break; case 30000:temp=4;break; case 0: default: case 32000:temp=5;break; case 35000:temp=6;break; case 44000: case 44100:temp=7;break; case 48000:temp=8;break; } SendDlgItemMessage(hDlg,IDC_RATE,CB_SETCURSEL,temp,0); SendDlgItemMessage(hDlg, IDC_MIX, CB_INSERTSTRING,0,(LPARAM)TEXT("10 ms")); SendDlgItemMessage(hDlg, IDC_MIX, CB_INSERTSTRING,1,(LPARAM)TEXT("20 ms")); SendDlgItemMessage(hDlg, IDC_MIX, CB_INSERTSTRING,2,(LPARAM)TEXT("30 ms")); SendDlgItemMessage(hDlg, IDC_MIX, CB_INSERTSTRING,3,(LPARAM)TEXT("40 ms")); SendDlgItemMessage(hDlg, IDC_MIX, CB_INSERTSTRING,4,(LPARAM)TEXT("50 ms")); SendDlgItemMessage(hDlg, IDC_MIX, CB_INSERTSTRING,5,(LPARAM)TEXT("60 ms")); SendDlgItemMessage(hDlg, IDC_MIX, CB_INSERTSTRING,6,(LPARAM)TEXT("70 ms")); SendDlgItemMessage(hDlg, IDC_MIX, CB_INSERTSTRING,7,(LPARAM)TEXT("80 ms")); SendDlgItemMessage(hDlg, IDC_MIX, CB_INSERTSTRING,8,(LPARAM)TEXT("90 ms")); SendDlgItemMessage(hDlg, IDC_MIX, CB_INSERTSTRING,9,(LPARAM)TEXT("100 ms")); SendDlgItemMessage(hDlg, IDC_MIX, CB_INSERTSTRING,10,(LPARAM)TEXT("110 ms")); SendDlgItemMessage(hDlg, IDC_MIX, CB_INSERTSTRING,11,(LPARAM)TEXT("120 ms")); SendDlgItemMessage(hDlg, IDC_MIX, CB_INSERTSTRING,12,(LPARAM)TEXT("130 ms")); SendDlgItemMessage(hDlg, IDC_MIX, CB_INSERTSTRING,13,(LPARAM)TEXT("140 ms")); SendDlgItemMessage(hDlg, IDC_MIX, CB_INSERTSTRING,14,(LPARAM)TEXT("150 ms")); SendDlgItemMessage(hDlg,IDC_MIX,CB_SETCURSEL,((set->SoundMixInterval/10)-1),0); SendDlgItemMessage(hDlg, IDC_BUFLEN, CB_INSERTSTRING,0,(LPARAM)TEXT("10 ms")); SendDlgItemMessage(hDlg, IDC_BUFLEN, CB_INSERTSTRING,1,(LPARAM)TEXT("20 ms")); SendDlgItemMessage(hDlg, IDC_BUFLEN, CB_INSERTSTRING,2,(LPARAM)TEXT("40 ms")); SendDlgItemMessage(hDlg, IDC_BUFLEN, CB_INSERTSTRING,3,(LPARAM)TEXT("80 ms")); SendDlgItemMessage(hDlg, IDC_BUFLEN, CB_INSERTSTRING,4,(LPARAM)TEXT("160 ms")); SendDlgItemMessage(hDlg, IDC_BUFLEN, CB_INSERTSTRING,5,(LPARAM)TEXT("320 ms")); SendDlgItemMessage(hDlg, IDC_BUFLEN, CB_INSERTSTRING,6,(LPARAM)TEXT("640 ms")); switch(set->SoundBufferSize) { case 2:temp=1; break; case 4:temp=2; break; case 8:temp=3; break; case 16:temp=4; break; case 32:temp=5; break; case 64: temp=6;break; case 1: default:temp=0;break; } SendDlgItemMessage(hDlg,IDC_BUFLEN,CB_SETCURSEL,temp,0); if(set->SixteenBitSound) SendDlgItemMessage(hDlg,IDC_16BIT,BM_SETCHECK,BST_CHECKED,0); if(set->Stereo) SendDlgItemMessage(hDlg,IDC_STEREO,BM_SETCHECK,BST_CHECKED,0); else EnableWindow(GetDlgItem(hDlg, IDC_REV_STEREO), FALSE); if(set->ReverseStereo) SendDlgItemMessage(hDlg,IDC_REV_STEREO,BM_SETCHECK,BST_CHECKED,0); if(set->AltSampleDecode) { EnableWindow(GetDlgItem(hDlg, IDC_CACHING), FALSE); SendDlgItemMessage(hDlg,IDC_ANTIRES,BM_SETCHECK,BST_CHECKED,0); } if(set->Mute) SendDlgItemMessage(hDlg,IDC_MUTE,BM_SETCHECK,BST_CHECKED,0); if(GUI.FAMute) SendDlgItemMessage(hDlg,IDC_FAMT,BM_SETCHECK,BST_CHECKED,0); if(set->NextAPUEnabled) { EnableWindow(GetDlgItem(hDlg, IDC_SKIP_TYPE), FALSE); SendDlgItemMessage(hDlg,IDC_SPC700ON,BM_SETCHECK,BST_CHECKED,0); //Gray out the skip feature! } if(set->InterpolatedSound) SendDlgItemMessage(hDlg,IDC_LINEAR_INTER,BM_SETCHECK,BST_CHECKED,0); if(set->SoundSync) SendDlgItemMessage(hDlg,IDC_SYNC_TO_SOUND_CPU,BM_SETCHECK,BST_CHECKED,0); if(set->SoundEnvelopeHeightReading) SendDlgItemMessage(hDlg,IDC_ENVX,BM_SETCHECK,BST_CHECKED,0); if(set->FakeMuteFix) SendDlgItemMessage(hDlg,IDC_FMUT,BM_SETCHECK,BST_CHECKED,0); //if(set->UseWIPAPUTiming) // SendDlgItemMessage(hDlg,IDC_WIP1,BM_SETCHECK,BST_CHECKED,0); if(!set->DisableSoundEcho) SendDlgItemMessage(hDlg,IDC_ECHO,BM_SETCHECK,BST_CHECKED,0); // if(!set->DisableSampleCaching) // SendDlgItemMessage(hDlg,IDC_CACHING,BM_SETCHECK,BST_CHECKED,0); if(!set->DisableMasterVolume) SendDlgItemMessage(hDlg,IDC_MASTER_VOL,BM_SETCHECK,BST_CHECKED,0); if(set->SoundDriver) { EnableWindow(GetDlgItem(hDlg, IDC_MIX), false); EnableWindow(GetDlgItem(hDlg, IDC_BUFLEN), false); EnableWindow(GetDlgItem(hDlg, IDC_SYNC_TO_SOUND_CPU), false); } if(!IsDlgButtonChecked(hDlg,IDC_SPC700ON)) { EnableWindow(GetDlgItem(hDlg, IDC_CACHING), FALSE); EnableWindow(GetDlgItem(hDlg, IDC_MUTE), FALSE); EnableWindow(GetDlgItem(hDlg, IDC_FAMT), FALSE); EnableWindow(GetDlgItem(hDlg, IDC_ANTIRES), FALSE); EnableWindow(GetDlgItem(hDlg, IDC_SKIP_TYPE), TRUE); EnableWindow(GetDlgItem(hDlg, IDC_DRIVER), FALSE); EnableWindow(GetDlgItem(hDlg, IDC_16BIT), FALSE); EnableWindow(GetDlgItem(hDlg, IDC_ENVX), FALSE); EnableWindow(GetDlgItem(hDlg, IDC_STEREO), FALSE); EnableWindow(GetDlgItem(hDlg, IDC_MASTER_VOL), FALSE); EnableWindow(GetDlgItem(hDlg, IDC_RATE), FALSE); EnableWindow(GetDlgItem(hDlg, IDC_ECHO), FALSE); EnableWindow(GetDlgItem(hDlg, IDC_LINEAR_INTER), FALSE); EnableWindow(GetDlgItem(hDlg, IDC_REV_STEREO), FALSE); EnableWindow(GetDlgItem(hDlg, IDC_BUFLEN), FALSE); EnableWindow(GetDlgItem(hDlg, IDC_MIX), FALSE); EnableWindow(GetDlgItem(hDlg, IDC_SYNC_TO_SOUND_CPU), FALSE); EnableWindow(GetDlgItem(hDlg, IDC_FMUT), FALSE); } return true; case WM_PAINT: { PAINTSTRUCT ps; BeginPaint (hDlg, &ps); if(hBmp) { BITMAP bmp; ZeroMemory(&bmp, sizeof(BITMAP)); RECT r; GetClientRect(hDlg, &r); HDC hdc=GetDC(hDlg); HDC hDCbmp=CreateCompatibleDC(hdc); GetObject(hBmp, sizeof(BITMAP), &bmp); HBITMAP hOldBmp=(HBITMAP)SelectObject(hDCbmp, hBmp); StretchBlt(hdc, 0,0,r.right,r.bottom,hDCbmp,0,0,bmp.bmWidth,bmp.bmHeight,SRCCOPY); SelectObject(hDCbmp, hOldBmp); DeleteDC(hDCbmp); ReleaseDC(hDlg, hdc); }; EndPaint (hDlg, &ps); } return true; case WM_COMMAND: switch(LOWORD(wParam)) { case IDOK: { set->SoundDriver=SendDlgItemMessage(hDlg, IDC_DRIVER,CB_GETCURSEL,0,0); set->SoundSkipMethod=(unsigned char)SendDlgItemMessage(hDlg,IDC_SKIP_TYPE,CB_GETCURSEL,0,0); set->SixteenBitSound=IsDlgButtonChecked(hDlg, IDC_16BIT); set->AltSampleDecode=IsDlgButtonChecked(hDlg, IDC_ANTIRES); set->SoundSync=IsDlgButtonChecked(hDlg, IDC_SYNC_TO_SOUND_CPU); set->InterpolatedSound=IsDlgButtonChecked(hDlg, IDC_LINEAR_INTER); set->Stereo=IsDlgButtonChecked(hDlg, IDC_STEREO); set->ReverseStereo=IsDlgButtonChecked(hDlg, IDC_REV_STEREO); set->Mute=IsDlgButtonChecked(hDlg, IDC_MUTE); GUI.FAMute=IsDlgButtonChecked(hDlg, IDC_FAMT)!=0; set->NextAPUEnabled=IsDlgButtonChecked(hDlg, IDC_SPC700ON); set->SoundEnvelopeHeightReading=IsDlgButtonChecked(hDlg, IDC_ENVX); set->FakeMuteFix=IsDlgButtonChecked(hDlg, IDC_FMUT); set->DisableSoundEcho=(!IsDlgButtonChecked(hDlg, IDC_ECHO)); set->DisableSampleCaching=(!IsDlgButtonChecked(hDlg, IDC_CACHING)); set->DisableMasterVolume=(!IsDlgButtonChecked(hDlg, IDC_MASTER_VOL)); switch(SendDlgItemMessage(hDlg, IDC_RATE,CB_GETCURSEL,0,0)) { case 0: set->SoundPlaybackRate=8000; break; case 1: set->SoundPlaybackRate=11025; break; case 2: set->SoundPlaybackRate=16000; break; case 3: set->SoundPlaybackRate=22050; break; case 4: set->SoundPlaybackRate=30000; break; case 5: set->SoundPlaybackRate=32000; break; case 6: set->SoundPlaybackRate=35000; break; case 7: set->SoundPlaybackRate=44100; break; case 8: set->SoundPlaybackRate=48000; break; } set->SoundMixInterval=(10*(1+(SendDlgItemMessage(hDlg,IDC_MIX,CB_GETCURSEL,0,0)))); set->SoundBufferSize=1<APUEnabled; set->APUEnabled = set->NextAPUEnabled; WinSaveConfigFile(); set->APUEnabled = wasEnabled; } SetupSound (Settings.SoundPlaybackRate, Settings.SixteenBitSound, Settings.Stereo); } /* FALL THROUGH */ case IDCANCEL: EndDialog(hDlg, 1); if(hBmp) { DeleteObject(hBmp); hBmp=NULL; } return true; case IDC_SPC700ON: if(BN_CLICKED==HIWORD(wParam)||BN_DBLCLK==HIWORD(wParam)) { if(!IsDlgButtonChecked(hDlg,IDC_SPC700ON)) { EnableWindow(GetDlgItem(hDlg, IDC_CACHING), FALSE); EnableWindow(GetDlgItem(hDlg, IDC_MUTE), FALSE); EnableWindow(GetDlgItem(hDlg, IDC_FAMT), FALSE); EnableWindow(GetDlgItem(hDlg, IDC_ANTIRES), FALSE); EnableWindow(GetDlgItem(hDlg, IDC_SKIP_TYPE), TRUE); EnableWindow(GetDlgItem(hDlg, IDC_DRIVER), FALSE); EnableWindow(GetDlgItem(hDlg, IDC_16BIT), FALSE); EnableWindow(GetDlgItem(hDlg, IDC_ENVX), FALSE); EnableWindow(GetDlgItem(hDlg, IDC_STEREO), FALSE); EnableWindow(GetDlgItem(hDlg, IDC_MASTER_VOL), FALSE); EnableWindow(GetDlgItem(hDlg, IDC_RATE), FALSE); EnableWindow(GetDlgItem(hDlg, IDC_ECHO), FALSE); EnableWindow(GetDlgItem(hDlg, IDC_LINEAR_INTER), FALSE); EnableWindow(GetDlgItem(hDlg, IDC_REV_STEREO), FALSE); EnableWindow(GetDlgItem(hDlg, IDC_BUFLEN), FALSE); EnableWindow(GetDlgItem(hDlg, IDC_MIX), FALSE); EnableWindow(GetDlgItem(hDlg, IDC_SYNC_TO_SOUND_CPU), FALSE); EnableWindow(GetDlgItem(hDlg, IDC_FMUT), FALSE); } else { EnableWindow(GetDlgItem(hDlg, IDC_LINEAR_INTER), TRUE); EnableWindow(GetDlgItem(hDlg, IDC_ECHO), TRUE); EnableWindow(GetDlgItem(hDlg, IDC_RATE), TRUE); EnableWindow(GetDlgItem(hDlg, IDC_MASTER_VOL), TRUE); EnableWindow(GetDlgItem(hDlg, IDC_STEREO), TRUE); EnableWindow(GetDlgItem(hDlg, IDC_DRIVER), TRUE); EnableWindow(GetDlgItem(hDlg, IDC_16BIT), TRUE); EnableWindow(GetDlgItem(hDlg, IDC_ENVX), TRUE); EnableWindow(GetDlgItem(hDlg, IDC_SKIP_TYPE), FALSE); EnableWindow(GetDlgItem(hDlg, IDC_ANTIRES), TRUE); EnableWindow(GetDlgItem(hDlg, IDC_MUTE), TRUE); EnableWindow(GetDlgItem(hDlg, IDC_FAMT), TRUE); EnableWindow(GetDlgItem(hDlg, IDC_FMUT), TRUE); if(!IsDlgButtonChecked(hDlg,IDC_ANTIRES)) EnableWindow(GetDlgItem(hDlg, IDC_CACHING), TRUE); if(IsDlgButtonChecked(hDlg,IDC_STEREO)) EnableWindow(GetDlgItem(hDlg, IDC_REV_STEREO), TRUE); if(0==SendDlgItemMessage(hDlg, IDC_DRIVER, CB_GETCURSEL, 0,0)) { //enable stuff. EnableWindow(GetDlgItem(hDlg, IDC_MIX), true); EnableWindow(GetDlgItem(hDlg, IDC_BUFLEN), true); EnableWindow(GetDlgItem(hDlg, IDC_SYNC_TO_SOUND_CPU), true); } return true; //Check Driver States for other options. } return true; } else return false; case IDC_DRIVER: if(CBN_SELCHANGE==HIWORD(wParam)) { //get index int i; i=SendDlgItemMessage(hDlg, IDC_DRIVER, CB_GETCURSEL, 0,0); if(i) { EnableWindow(GetDlgItem(hDlg, IDC_MIX), false); EnableWindow(GetDlgItem(hDlg, IDC_BUFLEN), false); EnableWindow(GetDlgItem(hDlg, IDC_SYNC_TO_SOUND_CPU), false); } //disable if index... else { //enable stuff. EnableWindow(GetDlgItem(hDlg, IDC_MIX), true); EnableWindow(GetDlgItem(hDlg, IDC_BUFLEN), true); EnableWindow(GetDlgItem(hDlg, IDC_SYNC_TO_SOUND_CPU), true); } return true; } else return false; case IDC_ANTIRES: { if(BN_CLICKED==HIWORD(wParam)||BN_DBLCLK==HIWORD(wParam)) { if(!IsDlgButtonChecked(hDlg,IDC_ANTIRES)) { // EnableWindow(GetDlgItem(hDlg, IDC_CACHING), TRUE); } else EnableWindow(GetDlgItem(hDlg, IDC_CACHING), FALSE); return true; } else return false; } case IDC_STEREO: { if(BN_CLICKED==HIWORD(wParam)||BN_DBLCLK==HIWORD(wParam)) { if(IsDlgButtonChecked(hDlg,IDC_STEREO)) { EnableWindow(GetDlgItem(hDlg, IDC_REV_STEREO), TRUE); } else EnableWindow(GetDlgItem(hDlg, IDC_REV_STEREO), FALSE); return true; } else return false; } default: return false; } } return false; } int CALLBACK DlgSP7PackConfig(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam) { static HBITMAP hBmp; switch(msg) { case WM_INITDIALOG: if(DirectX.Clipped) S9xReRefresh(); { hBmp=(HBITMAP)LoadImage(NULL, TEXT("Gogo.bmp"), IMAGE_BITMAP, 0,0, LR_CREATEDIBSECTION | LR_LOADFROMFILE); if(LoadUp7110==&SPC7110Grab) SendDlgItemMessage(hDlg, IDC_SPC7110_SOME, BM_SETCHECK, (WPARAM)BST_CHECKED, 0); else if(LoadUp7110==&SPC7110Open) SendDlgItemMessage(hDlg, IDC_SPC7110_FILE, BM_SETCHECK, (WPARAM)BST_CHECKED, 0); else SendDlgItemMessage(hDlg, IDC_SPC7110_ALL, BM_SETCHECK, (WPARAM)BST_CHECKED, 0); SendDlgItemMessage(hDlg, IDC_SPIN_CACHE, UDM_SETRANGE, 0, MAKELONG(20,1)); SendDlgItemMessage(hDlg, IDC_SPIN_CACHE, UDM_SETPOS, 0, MAKELONG(cacheMegs,0)); return true; } case WM_PAINT: { PAINTSTRUCT ps; BeginPaint (hDlg, &ps); if(hBmp) { BITMAP bmp; ZeroMemory(&bmp, sizeof(BITMAP)); RECT r; GetClientRect(hDlg, &r); HDC hdc=GetDC(hDlg); HDC hDCbmp=CreateCompatibleDC(hdc); GetObject(hBmp, sizeof(BITMAP), &bmp); HBITMAP hOldBmp=(HBITMAP)SelectObject(hDCbmp, hBmp); StretchBlt(hdc, 0,0,r.right,r.bottom,hDCbmp,0,0,bmp.bmWidth,bmp.bmHeight,SRCCOPY); SelectObject(hDCbmp, hOldBmp); DeleteDC(hDCbmp); ReleaseDC(hDlg, hdc); } EndPaint (hDlg, &ps); } return true; case WM_COMMAND: { switch(LOWORD(wParam)) { case IDOK: if(BST_CHECKED==SendDlgItemMessage(hDlg, IDC_SPC7110_ALL, BM_GETCHECK,0,0)) { LoadUp7110=&SPC7110Load; } else if(BST_CHECKED==SendDlgItemMessage(hDlg, IDC_SPC7110_FILE, BM_GETCHECK,0,0)) { LoadUp7110=&SPC7110Open; } else { LoadUp7110=&SPC7110Grab; cacheMegs=(uint16)SendDlgItemMessage(hDlg,IDC_SPIN_CACHE,UDM_GETPOS,0,0); } WinSaveConfigFile(); case IDCANCEL: EndDialog(hDlg,0); if(hBmp) { DeleteObject(hBmp); hBmp=NULL; } default: return false; } } default: return false; } } #ifdef RTC_DEBUGGER int CALLBACK SPC7110rtc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam) { static int month; static int day; static int year; static int hour; static int minutes; static int seconds; static int dayinmonth; static struct SPC7110RTC* rtc; switch(msg) { case WM_INITDIALOG: if(DirectX.Clipped) S9xReRefresh(); rtc= (struct SPC7110RTC *)lParam; seconds=rtc->reg[0]+rtc->reg[1]*10; minutes=rtc->reg[2]+rtc->reg[3]*10; hour=rtc->reg[4]+rtc->reg[5]*10; day=rtc->reg[6]+rtc->reg[7]*10; month=rtc->reg[8]+rtc->reg[9]*10; year=rtc->reg[10]+rtc->reg[11]*10; dayinmonth=S9xRTCDaysInMonth(month,year); SendDlgItemMessage(hDlg,IDC_MONTH, TBM_SETRANGE,(WPARAM)1,(LPARAM)MAKELONG(0,11)); SendDlgItemMessage(hDlg,IDC_MONTH, TBM_SETTICFREQ,(WPARAM)5,0); SendDlgItemMessage(hDlg,IDC_MONTH, TBM_SETPOS,(WPARAM)(BOOL)TRUE,(LPARAM)month-1); SetDlgItemInt(hDlg,IDC_LBLMONTH,month,0); SendDlgItemMessage(hDlg,IDC_DAY, TBM_SETRANGE,(WPARAM)1,(LPARAM)MAKELONG(0,dayinmonth-1)); SendDlgItemMessage(hDlg,IDC_DAY, TBM_SETTICFREQ,(WPARAM)5,0); SendDlgItemMessage(hDlg,IDC_DAY, TBM_SETPOS,(WPARAM)(BOOL)TRUE,(LPARAM)day-1); SetDlgItemInt(hDlg,IDC_LBLDAY,day,0); SendDlgItemMessage(hDlg,IDC_YEAR, TBM_SETRANGE,(WPARAM)1,(LPARAM)MAKELONG(0,99)); SendDlgItemMessage(hDlg,IDC_YEAR, TBM_SETTICFREQ,(WPARAM)5,0); if(year<95) { SendDlgItemMessage(hDlg,IDC_YEAR, TBM_SETPOS,(WPARAM)(BOOL)TRUE,(LPARAM)year+5); SetDlgItemInt(hDlg,IDC_LBLYEAR,year+2000,0); } else { SendDlgItemMessage(hDlg,IDC_YEAR, TBM_SETPOS,(WPARAM)(BOOL)TRUE,(LPARAM)year-95); SetDlgItemInt(hDlg,IDC_LBLYEAR,year+1900,0); } SendDlgItemMessage(hDlg, IDC_HOUR, TBM_SETRANGE,(WPARAM)1,(LPARAM)MAKELONG(0,23)); SendDlgItemMessage(hDlg,IDC_HOUR, TBM_SETTICFREQ,(WPARAM)5,0); SendDlgItemMessage(hDlg,IDC_HOUR, TBM_SETPOS,(WPARAM)(BOOL)TRUE,(LPARAM)hour); SetDlgItemInt(hDlg,IDC_LBLHOUR,hour,0); SendDlgItemMessage(hDlg, IDC_MINUTE, TBM_SETRANGE,(WPARAM)1,(LPARAM)MAKELONG(0,59)); SendDlgItemMessage(hDlg,IDC_MINUTE, TBM_SETTICFREQ,(WPARAM)5,0); SendDlgItemMessage(hDlg,IDC_MINUTE, TBM_SETPOS,(WPARAM)(BOOL)TRUE,(LPARAM)minutes); SetDlgItemInt(hDlg,IDC_LBLMINUTE,minutes,0); SendDlgItemMessage(hDlg, IDC_SECOND, TBM_SETRANGE,(WPARAM)1,(LPARAM)MAKELONG(0,59)); SendDlgItemMessage(hDlg,IDC_SECOND, TBM_SETTICFREQ,(WPARAM)5,0); SendDlgItemMessage(hDlg,IDC_SECOND, TBM_SETPOS,(WPARAM)(BOOL)TRUE,(LPARAM)seconds); SetDlgItemInt(hDlg,IDC_LBLSECOND,seconds,0); if(rtc->reg[0x0D]&0x01) SendDlgItemMessage(hDlg,IDC_RTC_D1,BM_SETCHECK,BST_CHECKED,0); if(rtc->reg[0x0D]&0x02) SendDlgItemMessage(hDlg,IDC_RTC_D2,BM_SETCHECK,BST_CHECKED,0); if(rtc->reg[0x0D]&0x04) SendDlgItemMessage(hDlg,IDC_RTC_D4,BM_SETCHECK,BST_CHECKED,0); if(rtc->reg[0x0D]&0x08) SendDlgItemMessage(hDlg,IDC_RTC_D8,BM_SETCHECK,BST_CHECKED,0); if(rtc->reg[0x0E]&0x01) SendDlgItemMessage(hDlg,IDC_RTC_E1,BM_SETCHECK,BST_CHECKED,0); if(rtc->reg[0x0E]&0x02) SendDlgItemMessage(hDlg,IDC_RTC_E2,BM_SETCHECK,BST_CHECKED,0); if(rtc->reg[0x0E]&0x04) SendDlgItemMessage(hDlg,IDC_RTC_E4,BM_SETCHECK,BST_CHECKED,0); if(rtc->reg[0x0E]&0x08) SendDlgItemMessage(hDlg,IDC_RTC_E8,BM_SETCHECK,BST_CHECKED,0); if(rtc->reg[0x0F]&0x01) SendDlgItemMessage(hDlg,IDC_RTC_F1,BM_SETCHECK,BST_CHECKED,0); if(rtc->reg[0x0F]&0x02) SendDlgItemMessage(hDlg,IDC_RTC_F2,BM_SETCHECK,BST_CHECKED,0); if(rtc->reg[0x0F]&0x04) SendDlgItemMessage(hDlg,IDC_RTC_F4,BM_SETCHECK,BST_CHECKED,0); if(rtc->reg[0x0F]&0x08) SendDlgItemMessage(hDlg,IDC_RTC_F8,BM_SETCHECK,BST_CHECKED,0); return true; case WM_COMMAND: switch(LOWORD(wParam)) { case IDOK: rtc->reg[0x0]=seconds%10; rtc->reg[0x1]=seconds/10; rtc->reg[0x2]=minutes%10; rtc->reg[0x3]=minutes/10; rtc->reg[0x4]=hour%10; rtc->reg[0x5]=hour/10; rtc->reg[0x6]=day%10; rtc->reg[0x7]=day/10; rtc->reg[0x8]=month%10; rtc->reg[0x9]=month/10; rtc->reg[0xA]=year%10; rtc->reg[0xB]=year/10; if(IsDlgButtonChecked(hDlg, IDC_RTC_D1)) rtc->reg[0x0D]|=0x01; else rtc->reg[0x0D]&=0x0E; if(IsDlgButtonChecked(hDlg, IDC_RTC_D2)) rtc->reg[0x0D]|=0x02; else rtc->reg[0x0D]&=0x0D; if(IsDlgButtonChecked(hDlg, IDC_RTC_D4)) rtc->reg[0x0D]|=0x04; else rtc->reg[0x0D]&=0x0B; if(IsDlgButtonChecked(hDlg, IDC_RTC_D8)) rtc->reg[0x0D]|=0x08; else rtc->reg[0x0D]&=0x07; if(IsDlgButtonChecked(hDlg, IDC_RTC_E1)) rtc->reg[0x0E]|=0x01; else rtc->reg[0x0E]&=0x0E; if(IsDlgButtonChecked(hDlg, IDC_RTC_E2)) rtc->reg[0x0E]|=0x02; else rtc->reg[0x0E]&=0x0D; if(IsDlgButtonChecked(hDlg, IDC_RTC_E4)) rtc->reg[0x0E]|=0x04; else rtc->reg[0x0E]&=0x0B; if(IsDlgButtonChecked(hDlg, IDC_RTC_E8)) rtc->reg[0x0E]|=0x08; else rtc->reg[0x0E]&=0x07; if(IsDlgButtonChecked(hDlg, IDC_RTC_F1)) rtc->reg[0x0F]|=0x01; else rtc->reg[0x0F]&=0x0E; if(IsDlgButtonChecked(hDlg, IDC_RTC_F2)) rtc->reg[0x0F]|=0x02; else rtc->reg[0x0F]&=0x0D; if(IsDlgButtonChecked(hDlg, IDC_RTC_F4)) rtc->reg[0x0F]|=0x04; else rtc->reg[0x0F]&=0x0B; if(IsDlgButtonChecked(hDlg, IDC_RTC_F8)) rtc->reg[0x0F]|=0x08; else rtc->reg[0x0F]&=0x07; WinSaveConfigFile(); case IDCANCEL: EndDialog(hDlg, 1); return true; /*case IDC_MONTH: int dinmonth; dinmonth = S9xRTCDaysInMonth( */ default: return false; } case WM_HSCROLL: month=1+SendDlgItemMessage(hDlg,IDC_MONTH,TBM_GETPOS,0,0); SetDlgItemInt(hDlg,IDC_LBLMONTH,month,0); day=1+SendDlgItemMessage(hDlg,IDC_DAY,TBM_GETPOS,0,0); year=SendDlgItemMessage(hDlg,IDC_YEAR,TBM_GETPOS,0,0); hour=SendDlgItemMessage(hDlg,IDC_HOUR,TBM_GETPOS,0,0); minutes=SendDlgItemMessage(hDlg,IDC_MINUTE,TBM_GETPOS,0,0); seconds=SendDlgItemMessage(hDlg,IDC_SECOND,TBM_GETPOS,0,0); SetDlgItemInt(hDlg,IDC_LBLHOUR,hour,0); SetDlgItemInt(hDlg,IDC_LBLMINUTE,minutes,0); SetDlgItemInt(hDlg,IDC_LBLSECOND,seconds,0); if(year<5) { year+=95; SetDlgItemInt(hDlg,IDC_LBLYEAR,year+1900,0); } else { year-=5; SetDlgItemInt(hDlg,IDC_LBLYEAR,year+2000,0); } dayinmonth=S9xRTCDaysInMonth(month,year); if(day>dayinmonth) { day=dayinmonth; SendDlgItemMessage(hDlg,IDC_DAY, TBM_SETPOS,(WPARAM)(BOOL)TRUE,(LPARAM)day-1); } SendDlgItemMessage(hDlg,IDC_DAY, TBM_SETRANGE,(WPARAM)1,(LPARAM)MAKELONG(0,dayinmonth-1)); SetDlgItemInt(hDlg,IDC_LBLDAY,day,0); return true; default: return false; } } #endif // SetSelProc // Callback procedure to set the initial selection of the (folder) browser. int CALLBACK SetSelProc( HWND hWnd, UINT uMsg, LPARAM lParam, LPARAM lpData ) { if (uMsg==BFFM_INITIALIZED) { ::SendMessage(hWnd, BFFM_SETSELECTION, TRUE, lpData ); } return 0; } const char *StaticRAMBitSize () { static char tmp [20]; sprintf (tmp, " (%dKbit)", 8*(Memory.SRAMMask + 1) / 1024); return (tmp); } int CALLBACK DlgInfoProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam) { static HBITMAP hBmp; switch(msg) { case WM_INITDIALOG: if(DirectX.Clipped) S9xReRefresh(); { hBmp=(HBITMAP)LoadImage(NULL, TEXT("anomie.bmp"), IMAGE_BITMAP, 0,0, LR_CREATEDIBSECTION | LR_LOADFROMFILE); char temp[100]; char romtext[4096]; sprintf(romtext, "File: %s\r\nName: %s\r\n", Memory.ROMFilename, Memory.ROMName); sprintf(temp, "Speed: %02X/%s\r\nROM Map: %s\r\nType: %02x\r\n", Memory.ROMSpeed, ((Memory.ROMSpeed&0x10)!=0)?"FastROM":"SlowROM",(Memory.HiROM)?"HiROM":"LoROM",Memory.ROMType); strcat(romtext, temp); strcat(romtext, "Kart contents: "); strcat(romtext, Memory.KartContents ()); strcat(romtext, "\r\nHeader ROM Size: "); strcat(romtext, Memory.Size()); sprintf(temp, "\r\nCalculated ROM Size: %d Mbits", Memory.CalculatedSize/0x20000); strcat(romtext, temp); strcat(romtext, "\r\nSRAM size: "); strcat(romtext, Memory.StaticRAMSize ()); strcat(romtext, StaticRAMBitSize()); strcat(romtext, "\r\nActual Checksum: "); sprintf(temp, "%04X", Memory.CalculatedChecksum); strcat(romtext, temp); strcat(romtext, "\r\nHeader Checksum: "); sprintf(temp, "%04X", Memory.ROMChecksum); strcat(romtext, temp); strcat(romtext, "\r\nHeader Checksum Compliment: "); sprintf(temp, "%04X", Memory.ROMComplementChecksum); strcat(romtext, temp); strcat(romtext, "\r\nOutput: "); if(Memory.ROMRegion>12||Memory.ROMRegion<2) strcat(romtext, "NTSC 60Hz"); else strcat(romtext, "PAL 50Hz"); sprintf(temp, "\r\nCRC32:\t%08X", Memory.ROMCRC32); strcat(romtext, temp); strcat(romtext, "\r\nLicensee: "); int tmp=-1; // sscanf(Memory.CompanyId, "%02X", &tmp); if(Memory.CompanyId[0]=='0') tmp=0; if(Memory.CompanyId[0]=='1') tmp=16; if(Memory.CompanyId[0]=='2') tmp=32; if(Memory.CompanyId[0]=='3') tmp=48; if(Memory.CompanyId[0]=='4') tmp=64; if(Memory.CompanyId[0]=='5') tmp=80; if(Memory.CompanyId[0]=='6') tmp=96; if(Memory.CompanyId[0]=='7') tmp=112; if(Memory.CompanyId[0]=='8') tmp=128; if(Memory.CompanyId[0]=='9') tmp=144; if(Memory.CompanyId[0]=='A') tmp=160; if(Memory.CompanyId[0]=='B') tmp=176; if(Memory.CompanyId[0]=='C') tmp=192; if(Memory.CompanyId[0]=='D') tmp=208; if(Memory.CompanyId[0]=='E') tmp=224; if(Memory.CompanyId[0]=='F') tmp=240; if(tmp!=-1) { if(Memory.CompanyId[1]=='0') tmp+=0; else if(Memory.CompanyId[1]=='1') tmp+=1; else if(Memory.CompanyId[1]=='2') tmp+=2; else if(Memory.CompanyId[1]=='3') tmp+=3; else if(Memory.CompanyId[1]=='4') tmp+=4; else if(Memory.CompanyId[1]=='5') tmp+=5; else if(Memory.CompanyId[1]=='6') tmp+=6; else if(Memory.CompanyId[1]=='7') tmp+=7; else if(Memory.CompanyId[1]=='8') tmp+=8; else if(Memory.CompanyId[1]=='9') tmp+=9; else if(Memory.CompanyId[1]=='A') tmp+=10; else if(Memory.CompanyId[1]=='B') tmp+=11; else if(Memory.CompanyId[1]=='C') tmp+=12; else if(Memory.CompanyId[1]=='D') tmp+=13; else if(Memory.CompanyId[1]=='E') tmp+=14; else if(Memory.CompanyId[1]=='F') tmp+=15; else tmp=0; } else tmp=0; if(tmp==0) tmp=(Memory.HiROM)?Memory.ROM[0x0FFDA]:Memory.ROM[0x7FDA]; switch(tmp) // switch(((Memory.ROMSpeed&0x0F)!=0)?Memory.ROM[0x0FFDA]:Memory.ROM[0x7FDA]) // switch(atoi(Memory.CompanyId)) // switch(((Memory.CompanyId[0]-'0')*16)+(Memory.CompanyId[1]-'0')) { case 0:strcat(romtext, "INVALID COMPANY");break; case 1:strcat(romtext, "Nintendo");break; case 2:strcat(romtext, "Ajinomoto");break; case 3:strcat(romtext, "Imagineer-Zoom");break; case 4:strcat(romtext, "Chris Gray Enterprises Inc.");break; case 5:strcat(romtext, "Zamuse");break; case 6:strcat(romtext, "Falcom");break; case 7:strcat(romtext, NOTKNOWN "7");break; case 8:strcat(romtext, "Capcom");break; case 9:strcat(romtext, "HOT-B");break; case 10:strcat(romtext, "Jaleco");break; case 11:strcat(romtext, "Coconuts");break; case 12:strcat(romtext, "Rage Software");break; case 13:strcat(romtext, "Micronet"); break; //Acc. ZFE case 14:strcat(romtext, "Technos");break; case 15:strcat(romtext, "Mebio Software");break; case 16:strcat(romtext, "SHOUEi System"); break; //Acc. ZFE case 17:strcat(romtext, "Starfish");break; //UCON 64 case 18:strcat(romtext, "Gremlin Graphics");break; case 19:strcat(romtext, "Electronic Arts");break; case 20:strcat(romtext, "NCS / Masaya"); break; //Acc. ZFE case 21:strcat(romtext, "COBRA Team");break; case 22:strcat(romtext, "Human/Field");break; case 23:strcat(romtext, "KOEI");break; case 24:strcat(romtext, "Hudson Soft");break; case 25:strcat(romtext, "Game Village");break;//uCON64 case 26:strcat(romtext, "Yanoman");break; case 27:strcat(romtext, NOTKNOWN "27");break; case 28:strcat(romtext, "Tecmo");break; case 29:strcat(romtext, NOTKNOWN "29");break; case 30:strcat(romtext, "Open System");break; case 31:strcat(romtext, "Virgin Games");break; case 32:strcat(romtext, "KSS");break; case 33:strcat(romtext, "Sunsoft");break; case 34:strcat(romtext, "POW");break; case 35:strcat(romtext, "Micro World");break; case 36:strcat(romtext, NOTKNOWN "36");break; case 37:strcat(romtext, NOTKNOWN "37");break; case 38:strcat(romtext, "Enix");break; case 39:strcat(romtext, "Loriciel/Electro Brain");break;//uCON64 case 40:strcat(romtext, "Kemco");break; case 41:strcat(romtext, "Seta Co.,Ltd.");break; case 42:strcat(romtext, "Culture Brain"); break; //Acc. ZFE case 43:strcat(romtext, "Irem Japan");break;//Irem? Gun Force J case 44:strcat(romtext, "Pal Soft"); break; //Acc. ZFE case 45:strcat(romtext, "Visit Co.,Ltd.");break; case 46:strcat(romtext, "INTEC Inc."); break; //Acc. ZFE case 47:strcat(romtext, "System Sacom Corp."); break; //Acc. ZFE case 48:strcat(romtext, "Viacom New Media");break; //Zoop! case 49:strcat(romtext, "Carrozzeria");break; case 50:strcat(romtext, "Dynamic");break; case 51:strcat(romtext, "Nintendo");break; case 52:strcat(romtext, "Magifact");break; case 53:strcat(romtext, "Hect");break; case 54:strcat(romtext, NOTKNOWN "54");break; case 55:strcat(romtext, NOTKNOWN "55");break; case 56:strcat(romtext, "Capcom Europe");break;//Capcom? BOF2(E) MM7 (E) case 57:strcat(romtext, "Accolade Europe");break;//Accolade?Bubsy 2 (E) case 58:strcat(romtext, NOTKNOWN "58");break; case 59:strcat(romtext, "Arcade Zone");break;//uCON64 case 60:strcat(romtext, "Empire Software");break; case 61:strcat(romtext, "Loriciel");break; case 62:strcat(romtext, "Gremlin Graphics"); break; //Acc. ZFE case 63:strcat(romtext, NOTKNOWN "63");break; case 64:strcat(romtext, "Seika Corp.");break; case 65:strcat(romtext, "UBI Soft");break; case 66:strcat(romtext, NOTKNOWN "66");break; case 67:strcat(romtext, NOTKNOWN "67");break; case 68:strcat(romtext, "LifeFitness Exertainment");break;//?? Exertainment Mountain Bike Rally (U).zip case 69:strcat(romtext, NOTKNOWN "69");break; case 70:strcat(romtext, "System 3");break; case 71:strcat(romtext, "Spectrum Holobyte");break; case 72:strcat(romtext, NOTKNOWN "72");break; case 73:strcat(romtext, "Irem");break; case 74:strcat(romtext, NOTKNOWN "74");break; case 75:strcat(romtext, "Raya Systems/Sculptured Software");break; case 76:strcat(romtext, "Renovation Products");break; case 77:strcat(romtext, "Malibu Games/Black Pearl");break; case 78:strcat(romtext, NOTKNOWN "78");break; case 79:strcat(romtext, "U.S. Gold");break; case 80:strcat(romtext, "Absolute Entertainment");break; case 81:strcat(romtext, "Acclaim");break; case 82:strcat(romtext, "Activision");break; case 83:strcat(romtext, "American Sammy");break; case 84:strcat(romtext, "GameTek");break; case 85:strcat(romtext, "Hi Tech Expressions");break; case 86:strcat(romtext, "LJN Toys");break; case 87:strcat(romtext, NOTKNOWN "87");break; case 88:strcat(romtext, NOTKNOWN "88");break; case 89:strcat(romtext, NOTKNOWN "89");break; case 90:strcat(romtext, "Mindscape");break; case 91:strcat(romtext, "Romstar, Inc."); break; //Acc. ZFE case 92:strcat(romtext, NOTKNOWN "92");break; case 93:strcat(romtext, "Tradewest");break; case 94:strcat(romtext, NOTKNOWN "94");break; case 95:strcat(romtext, "American Softworks Corp.");break; case 96:strcat(romtext, "Titus");break; case 97:strcat(romtext, "Virgin Interactive Entertainment");break; case 98:strcat(romtext, "Maxis");break; case 99:strcat(romtext, "Origin/FCI/Pony Canyon");break;//uCON64 case 100:strcat(romtext, NOTKNOWN "100");break; case 101:strcat(romtext, NOTKNOWN "101");break; case 102:strcat(romtext, NOTKNOWN "102");break; case 103:strcat(romtext, "Ocean");break; case 104:strcat(romtext, NOTKNOWN "104");break; case 105:strcat(romtext, "Electronic Arts");break; case 106:strcat(romtext, NOTKNOWN "106");break; case 107:strcat(romtext, "Laser Beam");break; case 108:strcat(romtext, NOTKNOWN "108");break; case 109:strcat(romtext, NOTKNOWN "109");break; case 110:strcat(romtext, "Elite");break; case 111:strcat(romtext, "Electro Brain");break; case 112:strcat(romtext, "Infogrames");break; case 113:strcat(romtext, "Interplay");break; case 114:strcat(romtext, "LucasArts");break; case 115:strcat(romtext, "Parker Brothers");break; case 116:strcat(romtext, "Konami");break;//uCON64 case 117:strcat(romtext, "STORM");break; case 118:strcat(romtext, NOTKNOWN "118");break; case 119:strcat(romtext, NOTKNOWN "119");break; case 120:strcat(romtext, "THQ Software");break; case 121:strcat(romtext, "Accolade Inc.");break; case 122:strcat(romtext, "Triffix Entertainment");break; case 123:strcat(romtext, NOTKNOWN "123");break; case 124:strcat(romtext, "Microprose");break; case 125:strcat(romtext, NOTKNOWN "125");break; case 126:strcat(romtext, NOTKNOWN "126");break; case 127:strcat(romtext, "Kemco");break; case 128:strcat(romtext, "Misawa");break; case 129:strcat(romtext, "Teichio");break; case 130:strcat(romtext, "Namco Ltd.");break; case 131:strcat(romtext, "Lozc");break; case 132:strcat(romtext, "Koei");break; case 133:strcat(romtext, NOTKNOWN "133");break; case 134:strcat(romtext, "Tokuma Shoten Intermedia");break; case 135:strcat(romtext, "Tsukuda Original"); break; //Acc. ZFE case 136:strcat(romtext, "DATAM-Polystar");break; case 137:strcat(romtext, NOTKNOWN "137");break; case 138:strcat(romtext, NOTKNOWN "138");break; case 139:strcat(romtext, "Bullet-Proof Software");break; case 140:strcat(romtext, "Vic Tokai");break; case 141:strcat(romtext, NOTKNOWN "141");break; case 142:strcat(romtext, "Character Soft");break; case 143:strcat(romtext, "I\'\'Max");break; case 144:strcat(romtext, "Takara");break; case 145:strcat(romtext, "CHUN Soft");break; case 146:strcat(romtext, "Video System Co., Ltd.");break; case 147:strcat(romtext, "BEC");break; case 148:strcat(romtext, NOTKNOWN "148");break; case 149:strcat(romtext, "Varie");break; case 150:strcat(romtext, "Yonezawa / S'Pal Corp."); break; //Acc. ZFE case 151:strcat(romtext, "Kaneco");break; case 152:strcat(romtext, NOTKNOWN "152");break; case 153:strcat(romtext, "Pack in Video");break; case 154:strcat(romtext, "Nichibutsu");break; case 155:strcat(romtext, "TECMO");break; case 156:strcat(romtext, "Imagineer Co.");break; case 157:strcat(romtext, NOTKNOWN "157");break; case 158:strcat(romtext, NOTKNOWN "158");break; case 159:strcat(romtext, NOTKNOWN "159");break; case 160:strcat(romtext, "Telenet");break; case 161:strcat(romtext, "Hori"); break; //Acc. uCON64 case 162:strcat(romtext, NOTKNOWN "162");break; case 163:strcat(romtext, NOTKNOWN "163");break; case 164:strcat(romtext, "Konami");break; case 165:strcat(romtext, "K.Amusement Leasing Co.");break; case 166:strcat(romtext, NOTKNOWN "166");break; case 167:strcat(romtext, "Takara");break; case 168:strcat(romtext, NOTKNOWN "168");break; case 169:strcat(romtext, "Technos Jap.");break; case 170:strcat(romtext, "JVC");break; case 171:strcat(romtext, NOTKNOWN "171");break; case 172:strcat(romtext, "Toei Animation");break; case 173:strcat(romtext, "Toho");break; case 174:strcat(romtext, NOTKNOWN "174");break; case 175:strcat(romtext, "Namco Ltd.");break; case 176:strcat(romtext, "Media Rings Corp."); break; //Acc. ZFE case 177:strcat(romtext, "ASCII Co. Activison");break; case 178:strcat(romtext, "Bandai");break; case 179:strcat(romtext, NOTKNOWN "179");break; case 180:strcat(romtext, "Enix America");break; case 181:strcat(romtext, NOTKNOWN "181");break; case 182:strcat(romtext, "Halken");break; case 183:strcat(romtext, NOTKNOWN "183");break; case 184:strcat(romtext, NOTKNOWN "184");break; case 185:strcat(romtext, NOTKNOWN "185");break; case 186:strcat(romtext, "Culture Brain");break; case 187:strcat(romtext, "Sunsoft");break; case 188:strcat(romtext, "Toshiba EMI");break; case 189:strcat(romtext, "Sony Imagesoft");break; case 190:strcat(romtext, NOTKNOWN "190");break; case 191:strcat(romtext, "Sammy");break; case 192:strcat(romtext, "Taito");break; case 193:strcat(romtext, NOTKNOWN "193");break; case 194:strcat(romtext, "Kemco");break; case 195:strcat(romtext, "Square");break; case 196:strcat(romtext, "Tokuma Soft");break; case 197:strcat(romtext, "Data East");break; case 198:strcat(romtext, "Tonkin House");break; case 199:strcat(romtext, NOTKNOWN "199");break; case 200:strcat(romtext, "KOEI");break; case 201:strcat(romtext, NOTKNOWN "201");break; case 202:strcat(romtext, "Konami USA");break; case 203:strcat(romtext, "NTVIC");break; case 204:strcat(romtext, NOTKNOWN "204");break; case 205:strcat(romtext, "Meldac");break; case 206:strcat(romtext, "Pony Canyon");break; case 207:strcat(romtext, "Sotsu Agency/Sunrise");break; case 208:strcat(romtext, "Disco/Taito");break; case 209:strcat(romtext, "Sofel");break; case 210:strcat(romtext, "Quest Corp.");break; case 211:strcat(romtext, "Sigma");break; case 212:strcat(romtext, "Ask Kodansha Co., Ltd."); break; //Acc. ZFE case 213:strcat(romtext, NOTKNOWN "213");break; case 214:strcat(romtext, "Naxat");break; case 215:strcat(romtext, NOTKNOWN "215");break; case 216:strcat(romtext, "Capcom Co., Ltd.");break; case 217:strcat(romtext, "Banpresto");break; case 218:strcat(romtext, "Tomy");break; case 219:strcat(romtext, "Acclaim");break; case 220:strcat(romtext, NOTKNOWN "220");break; case 221:strcat(romtext, "NCS");break; case 222:strcat(romtext, "Human Entertainment");break; case 223:strcat(romtext, "Altron");break; case 224:strcat(romtext, "Jaleco");break; case 225:strcat(romtext, NOTKNOWN "225");break; case 226:strcat(romtext, "Yutaka");break; case 227:strcat(romtext, NOTKNOWN "227");break; case 228:strcat(romtext, "T&ESoft");break; case 229:strcat(romtext, "EPOCH Co.,Ltd.");break; case 230:strcat(romtext, NOTKNOWN "230");break; case 231:strcat(romtext, "Athena");break; case 232:strcat(romtext, "Asmik");break; case 233:strcat(romtext, "Natsume");break; case 234:strcat(romtext, "King Records");break; case 235:strcat(romtext, "Atlus");break; case 236:strcat(romtext, "Sony Music Entertainment");break; case 237:strcat(romtext, NOTKNOWN "237");break; case 238:strcat(romtext, "IGS");break; case 239:strcat(romtext, NOTKNOWN "239");break; case 240:strcat(romtext, NOTKNOWN "240");break; case 241:strcat(romtext, "Motown Software");break; case 242:strcat(romtext, "Left Field Entertainment");break; case 243:strcat(romtext, "Beam Software");break; case 244:strcat(romtext, "Tec Magik");break; case 245:strcat(romtext, NOTKNOWN "245");break; case 246:strcat(romtext, NOTKNOWN "246");break; case 247:strcat(romtext, NOTKNOWN "247");break; case 248:strcat(romtext, NOTKNOWN "248");break; case 249:strcat(romtext, "Cybersoft");break; case 250:strcat(romtext, NOTKNOWN "250");break; case 251:strcat(romtext, "Psygnosis"); break; //Acc. ZFE case 252:strcat(romtext, NOTKNOWN "252");break; case 253:strcat(romtext, NOTKNOWN "253");break; case 254:strcat(romtext, "Davidson"); break; //Acc. uCON64 case 255:strcat(romtext, NOTKNOWN "255");break; default:strcat(romtext, NOTKNOWN);break; } strcat(romtext, "\r\nROM Version: "); sprintf(temp, "1.%d", (Memory.HiROM)?Memory.ROM[0x0FFDB]:Memory.ROM[0x7FDB]); strcat(romtext, temp); strcat(romtext, "\r\nRegion: "); switch(Memory.ROMRegion) { case 0: strcat(romtext, "Japan"); break; case 1: strcat(romtext, "USA/Canada"); break; case 2: strcat(romtext, "Oceania, Europe, and Asia"); break; case 3: strcat(romtext, "Sweden"); break; case 4: strcat(romtext, "Finland"); break; case 5: strcat(romtext, "Denmark"); break; case 6: strcat(romtext, "France"); break; case 7: strcat(romtext, "Holland"); break; case 8: strcat(romtext, "Spain"); break; case 9: strcat(romtext, "Germany, Austria, and Switzerland"); break; case 10: strcat(romtext, "Italy"); break; case 11: strcat(romtext, "Hong Kong and China"); break; case 12: strcat(romtext, "Indonesia"); break; case 13: strcat(romtext, "South Korea"); break; case 14:strcat(romtext, "Unknown region 14");break; default:strcat(romtext, "Unknown region 15");break; } SendDlgItemMessage(hDlg, IDC_ROM_DATA, WM_SETTEXT, 0, (LPARAM)romtext); return true; break; } case WM_CTLCOLORSTATIC: if(GUI.InfoColor!=WIN32_WHITE) { SetTextColor((HDC)wParam, GUI.InfoColor); SetBkColor((HDC)wParam, RGB(0,0,0)); } return true;break; case WM_PAINT: { PAINTSTRUCT ps; BeginPaint (hDlg, &ps); if(hBmp) { BITMAP bmp; ZeroMemory(&bmp, sizeof(BITMAP)); RECT r; GetClientRect(hDlg, &r); HDC hdc=GetDC(hDlg); HDC hDCbmp=CreateCompatibleDC(hdc); GetObject(hBmp, sizeof(BITMAP), &bmp); HBITMAP hOldBmp=(HBITMAP)SelectObject(hDCbmp, hBmp); StretchBlt(hdc, 0,0,r.right,r.bottom,hDCbmp,0,0,bmp.bmWidth,bmp.bmHeight,SRCCOPY); SelectObject(hDCbmp, hOldBmp); DeleteDC(hDCbmp); ReleaseDC(hDlg, hdc); } EndPaint (hDlg, &ps); } return true; case WM_COMMAND: { switch(LOWORD(wParam)) { case IDOK: case IDCANCEL: EndDialog(hDlg, 0); if(hBmp) { DeleteObject(hBmp); hBmp=NULL; } return true; break; default: return false; break; } } default:return false; } } int CALLBACK DlgAboutProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam) { static HBITMAP hBmp; switch(msg) { case WM_INITDIALOG: if(DirectX.Clipped) S9xReRefresh(); { TCHAR buf[2048];//find better way of dealing. sprintf(buf,TEXT(DISCLAIMER_TEXT),VERSION); hBmp=(HBITMAP)LoadImage(NULL, TEXT("RedChaos1.bmp"), IMAGE_BITMAP, 0,0, LR_CREATEDIBSECTION | LR_LOADFROMFILE); SetDlgItemText(hDlg, IDC_DISCLAIMER, buf); SetWindowText(hDlg, TEXT(ABOUT_DIALOG_TITLE) TEXT(APP_NAME)); } return true; case WM_PAINT: { PAINTSTRUCT ps; BeginPaint (hDlg, &ps); if(hBmp) { BITMAP bmp; ZeroMemory(&bmp, sizeof(BITMAP)); RECT r; GetClientRect(hDlg, &r); HDC hdc=GetDC(hDlg); HDC hDCbmp=CreateCompatibleDC(hdc); GetObject(hBmp, sizeof(BITMAP), &bmp); HBITMAP hOldBmp=(HBITMAP)SelectObject(hDCbmp, hBmp); StretchBlt(hdc, 0,0,r.right,r.bottom,hDCbmp,0,0,bmp.bmWidth,bmp.bmHeight,SRCCOPY); SelectObject(hDCbmp, hOldBmp); DeleteDC(hDCbmp); ReleaseDC(hDlg, hdc); } EndPaint (hDlg, &ps); } return true; case WM_COMMAND: { switch(LOWORD(wParam)) { case IDOK: case IDCANCEL: EndDialog(hDlg, 0); if(hBmp) { DeleteObject(hBmp); hBmp=NULL; } return true; break; default: return false; break; } } default:return false; } } int CALLBACK DlgEmulatorProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam) { static char paths[8][MAX_PATH]; static int which = 0; static HBITMAP hBmp; switch(msg) { case WM_INITDIALOG: if(DirectX.Clipped) S9xReRefresh(); { hBmp=(HBITMAP)LoadImage(NULL, TEXT("MKendora.bmp"), IMAGE_BITMAP, 0,0, LR_CREATEDIBSECTION | LR_LOADFROMFILE); SetWindowText(hDlg, TEXT(EMUSET_TITLE)); SetDlgItemText(hDlg, IDC_TOGGLE_TURBO, EMUSET_TOGGLE_TURBO); SetDlgItemText(hDlg, IDC_LABEL_FREEZE, EMUSET_LABEL_DIRECTORY); SetDlgItemText(hDlg, IDOK, BUTTON_OK); SetDlgItemText(hDlg, IDCANCEL, BUTTON_CANCEL); SetDlgItemText(hDlg, IDC_LABEL_ASRAM, EMUSET_LABEL_ASRAM); SetDlgItemText(hDlg, IDC_LABEL_ASRAM_TEXT, EMUSET_LABEL_ASRAM_TEXT); SetDlgItemText(hDlg, IDC_LABEL_SMAX, EMUSET_LABEL_SMAX); SetDlgItemText(hDlg, IDC_LABEL_SMAX_TEXT, EMUSET_LABEL_SMAX_TEXT); SetDlgItemText(hDlg, IDC_LABEL_STURBO_TEXT, EMUSET_LABEL_STURBO_TEXT); SetDlgItemText(hDlg, IDC_LABEL_STURBO, EMUSET_LABEL_STURBO); SetDlgItemText(hDlg, IDC_BROWSE, EMUSET_BROWSE); SetDlgItemText(hDlg, IDC_CUSTOM_FOLDER_FIELD, GUI.FreezeFileDir); extern bool using_conf_not_cfg; SetDlgItemText(hDlg, IDC_CONFIG_NAME_BOX, using_conf_not_cfg ? "snes9x.conf" : "snes9x.cfg"); SendDlgItemMessage(hDlg, IDC_SRAM_SPIN, UDM_SETRANGE, 0, MAKELPARAM((short)99, (short)0)); SendDlgItemMessage(hDlg, IDC_SRAM_SPIN,UDM_SETPOS,0, Settings.AutoSaveDelay); SendDlgItemMessage(hDlg, IDC_SPIN_MAX_SKIP, UDM_SETRANGE, 0, MAKELPARAM((short)59, (short)0)); SendDlgItemMessage(hDlg, IDC_SPIN_MAX_SKIP,UDM_SETPOS,0, Settings.AutoMaxSkipFrames); SendDlgItemMessage(hDlg, IDC_SPIN_TURBO_SKIP, UDM_SETRANGE, 0, MAKELPARAM((short)600, (short)0)); SendDlgItemMessage(hDlg, IDC_SPIN_TURBO_SKIP,UDM_SETPOS,0, Settings.TurboSkipFrames); CheckDlgButton(hDlg,IDC_TOGGLE_TURBO,GUI.TurboModeToggle ? BST_CHECKED : BST_UNCHECKED); CheckDlgButton(hDlg,IDC_INACTIVE_PAUSE,GUI.InactivePause ? BST_CHECKED : BST_UNCHECKED); CheckDlgButton(hDlg,IDC_CUSTOMROMOPEN,GUI.CustomRomOpen ? BST_CHECKED : BST_UNCHECKED); int inum = 0; strcpy(paths[inum++],GUI.RomDir); SendDlgItemMessage(hDlg,IDC_DIRCOMBO,CB_ADDSTRING,0,(LPARAM)(LPCTSTR)SETTINGS_OPTION_DIRECTORY_ROMS); strcpy(paths[inum++],GUI.ScreensDir); SendDlgItemMessage(hDlg,IDC_DIRCOMBO,CB_ADDSTRING,0,(LPARAM)(LPCTSTR)SETTINGS_OPTION_DIRECTORY_SCREENS); strcpy(paths[inum++],GUI.MovieDir); SendDlgItemMessage(hDlg,IDC_DIRCOMBO,CB_ADDSTRING,0,(LPARAM)(LPCTSTR)SETTINGS_OPTION_DIRECTORY_MOVIES); strcpy(paths[inum++],GUI.SPCDir); SendDlgItemMessage(hDlg,IDC_DIRCOMBO,CB_ADDSTRING,0,(LPARAM)(LPCTSTR)SETTINGS_OPTION_DIRECTORY_SPCS); strcpy(paths[inum++],GUI.FreezeFileDir); SendDlgItemMessage(hDlg,IDC_DIRCOMBO,CB_ADDSTRING,0,(LPARAM)(LPCTSTR)SETTINGS_OPTION_DIRECTORY_SAVES); strcpy(paths[inum++],GUI.SRAMFileDir); SendDlgItemMessage(hDlg,IDC_DIRCOMBO,CB_ADDSTRING,0,(LPARAM)(LPCTSTR)SETTINGS_OPTION_DIRECTORY_SRAM); strcpy(paths[inum++],GUI.PatchDir); SendDlgItemMessage(hDlg,IDC_DIRCOMBO,CB_ADDSTRING,0,(LPARAM)(LPCTSTR)SETTINGS_OPTION_DIRECTORY_PATCHESANDCHEATS); strcpy(paths[inum++],GUI.BiosDir); SendDlgItemMessage(hDlg,IDC_DIRCOMBO,CB_ADDSTRING,0,(LPARAM)(LPCTSTR)SETTINGS_OPTION_DIRECTORY_BIOS); SendDlgItemMessage(hDlg,IDC_DIRCOMBO,CB_SETCURSEL,(WPARAM)0,0); SetDlgItemText(hDlg, IDC_CUSTOM_FOLDER_FIELD, paths[0]); which = 0; SetCurrentDirectory(S9xGetDirectory(DEFAULT_DIR)); } case WM_PAINT: { PAINTSTRUCT ps; BeginPaint (hDlg, &ps); if(hBmp) { BITMAP bmp; ZeroMemory(&bmp, sizeof(BITMAP)); RECT r; GetClientRect(hDlg, &r); HDC hdc=GetDC(hDlg); HDC hDCbmp=CreateCompatibleDC(hdc); GetObject(hBmp, sizeof(BITMAP), &bmp); HBITMAP hOldBmp=(HBITMAP)SelectObject(hDCbmp, hBmp); StretchBlt(hdc, 0,0,r.right,r.bottom,hDCbmp,0,0,bmp.bmWidth,bmp.bmHeight,SRCCOPY); SelectObject(hDCbmp, hOldBmp); DeleteDC(hDCbmp); ReleaseDC(hDlg, hdc); } EndPaint (hDlg, &ps); } return true; case WM_COMMAND: { switch(LOWORD(wParam)) { case IDC_BROWSE: { LPMALLOC lpm=NULL; LPITEMIDLIST iidl=NULL; BROWSEINFO bi; ZeroMemory(&bi, sizeof(BROWSEINFO)); TCHAR path[MAX_PATH]; _fullpath(path, paths[which], MAX_PATH); TCHAR title[]=TEXT(SETTINGS_TITLE_SELECTFOLDER); CoInitialize(NULL); bi.hwndOwner=hDlg; bi.pszDisplayName=path; bi.lpszTitle=title; bi.lpfn = SetSelProc; bi.lParam = (LPARAM)(LPCSTR) path; iidl=SHBrowseForFolder(&bi); if(iidl) SHGetPathFromIDList(iidl, path); SHGetMalloc(&lpm); lpm->Free(iidl); CoUninitialize(); absToRel(paths[which], path, S9xGetDirectory(DEFAULT_DIR)); SetDlgItemText(hDlg, IDC_CUSTOM_FOLDER_FIELD, paths[which]); } break; case IDC_CUSTOM_FOLDER_FIELD: which = SendDlgItemMessage(hDlg,IDC_DIRCOMBO,CB_GETCURSEL,0,0); GetDlgItemText(hDlg, IDC_CUSTOM_FOLDER_FIELD, paths[which], MAX_PATH); break; case IDC_DIRCOMBO: which = SendDlgItemMessage(hDlg,IDC_DIRCOMBO,CB_GETCURSEL,0,0); SetDlgItemText(hDlg, IDC_CUSTOM_FOLDER_FIELD, paths[which]); break; case IDOK: { int inum = 0; strcpy(GUI.RomDir,paths[inum++]); strcpy(GUI.ScreensDir,paths[inum++]); strcpy(GUI.MovieDir,paths[inum++]); strcpy(GUI.SPCDir,paths[inum++]); strcpy(GUI.FreezeFileDir,paths[inum++]); strcpy(GUI.SRAMFileDir,paths[inum++]); strcpy(GUI.PatchDir,paths[inum++]); strcpy(GUI.BiosDir,paths[inum++]); GUI.TurboModeToggle = (BST_CHECKED==IsDlgButtonChecked(hDlg, IDC_TOGGLE_TURBO)); GUI.InactivePause = (BST_CHECKED==IsDlgButtonChecked(hDlg, IDC_INACTIVE_PAUSE)); GUI.CustomRomOpen = (BST_CHECKED==IsDlgButtonChecked(hDlg, IDC_CUSTOMROMOPEN)); Settings.TurboSkipFrames=SendDlgItemMessage(hDlg, IDC_SPIN_TURBO_SKIP, UDM_GETPOS, 0,0); Settings.AutoMaxSkipFrames=SendDlgItemMessage(hDlg, IDC_SPIN_MAX_SKIP, UDM_GETPOS, 0,0); Settings.AutoSaveDelay=SendDlgItemMessage(hDlg, IDC_SRAM_SPIN, UDM_GETPOS, 0,0); WinSaveConfigFile(); } /* fall through */ case IDCANCEL: EndDialog(hDlg, 0); if(hBmp) { DeleteObject(hBmp); hBmp=NULL; } return true; break; default: return false; break; } } default:return false; } } #define SKIP_FLOPPY bool ExtensionIsValid(const TCHAR * filename) { ExtList* curr=valid_ext; while(curr!=NULL) { if(curr->extension==NULL) { if(NULL==strstr(filename, TEXT("."))) return true; } else if(filename[(strlen(filename)-1)-strlen(curr->extension)]=='.') { if(0==_strnicmp(&filename[(strlen(filename))-strlen(curr->extension)], curr->extension, strlen(curr->extension))) return true; } curr=curr->next; } return false; } bool IsCompressed(const TCHAR* filename) { ExtList* curr=valid_ext; while(curr!=NULL) { if(curr->extension==NULL) { if(NULL==strstr(filename, TEXT("."))) return curr->compressed; } else if(filename[(strlen(filename)-1)-strlen(curr->extension)]=='.') { if(0==_strnicmp(&filename[(strlen(filename))-strlen(curr->extension)], curr->extension, strlen(curr->extension))) return curr->compressed; } curr=curr->next; } return false; } inline bool AllASCII(char *b, int size) { for (int i = 0; i < size; i++) { if (b[i] < 32 || b[i] > 126) { return(false); } } return(true); } inline int InfoScore(char *Buffer) { int score = 0; if (Buffer[28] + (Buffer[29] << 8) + Buffer[30] + (Buffer[31] << 8) == 0xFFFF) { score += 3; } if (Buffer[26] == 0x33) { score += 2; } if ((Buffer[21] & 0xf) < 4) { score += 2; } if (!(Buffer[61] & 0x80)) { score -= 4; } if ((1 << (Buffer[23] - 7)) > 48) { score -= 1; } if (Buffer[25] < 14) { score += 1; } if (!AllASCII(Buffer, 20)) { score -= 1; } return (score); } inline unsigned short sum(unsigned char *array, unsigned int size = HEADER_SIZE) { register unsigned short theSum = 0; for (register unsigned int i = 0; i < size; i++) { theSum += array[i]; } return(theSum); } void rominfo(const TCHAR *filename, TCHAR *namebuffer, TCHAR *sizebuffer) { strcpy(namebuffer, ROM_ITEM_DESCNOTAVAILABLE); strcpy(sizebuffer, "? Mbits"); if(IsCompressed(filename)) { unzFile uf = unzOpen(filename); if(uf) { unz_file_info info; if(UNZ_OK == unzGetCurrentFileInfo(uf, &info, 0,0,0,0,0,0)) { if (info.uncompressed_size < 0x8000) // Smaller than a block strcpy(namebuffer, ROM_ITEM_NOTAROM); else strcpy(namebuffer, ROM_ITEM_COMPRESSEDROMDESCRIPTION); // should subtract header size, so this may be slightly off, but it's better than "? MBits" double MBitD = (double)(info.uncompressed_size - 0) / 0x100000 * 8; int MBitI = (int)MBitD; int sizeIndex; if(0!=(MBitI / 10)) { sizebuffer[0] = MBitI / 10 + '0'; sizeIndex = 1; } else sizeIndex = 0; sizebuffer[sizeIndex+0] = MBitI % 10 + '0'; sizebuffer[sizeIndex+1] = '.'; sizebuffer[sizeIndex+2] = (char)((MBitD - MBitI) * 10) + '0'; sizebuffer[sizeIndex+3] = (char)((int)((MBitD - MBitI) * 100) % 10) + '0'; sizebuffer[sizeIndex+4] = ' '; sizebuffer[sizeIndex+5] = 'M'; sizebuffer[sizeIndex+6] = 'b'; sizebuffer[sizeIndex+7] = 'i'; sizebuffer[sizeIndex+8] = 't'; sizebuffer[sizeIndex+9] = '\0'; } unzClose(uf); } return; } struct stat filestats; stat(filename, &filestats); int HeaderSize = 0; if (filestats.st_size >= 0x8000) { ifstream ROMFile(filename, ios::in | ios::binary); if (ROMFile) { int HasHeadScore = 0, NoHeadScore = 0, HeadRemain = filestats.st_size & 0x7FFF; switch(HeadRemain) { case 0: NoHeadScore += 3; break; case HEADER_SIZE: HasHeadScore += 2; break; } unsigned char HeaderBuffer[HEADER_SIZE]; ROMFile.read((char *)HeaderBuffer, HEADER_SIZE); if (sum(HeaderBuffer) < 2500) { HasHeadScore += 2; } //SMC/SWC Header if (HeaderBuffer[8] == 0xAA && HeaderBuffer[9] == 0xBB && HeaderBuffer[10]== 4) { HasHeadScore += 3; } //FIG Header else if ((HeaderBuffer[4] == 0x77 && HeaderBuffer[5] == 0x83) || (HeaderBuffer[4] == 0xDD && HeaderBuffer[5] == 0x82) || (HeaderBuffer[4] == 0xDD && HeaderBuffer[5] == 2) || (HeaderBuffer[4] == 0xF7 && HeaderBuffer[5] == 0x83) || (HeaderBuffer[4] == 0xFD && HeaderBuffer[5] == 0x82) || (HeaderBuffer[4] == 0x00 && HeaderBuffer[5] == 0x80) || (HeaderBuffer[4] == 0x47 && HeaderBuffer[5] == 0x83) || (HeaderBuffer[4] == 0x11 && HeaderBuffer[5] == 2)) { HasHeadScore += 2; } else if (!strncmp("GAME DOCTOR SF 3", (char *)HeaderBuffer, 16)) { HasHeadScore += 5; } HeaderSize = HasHeadScore > NoHeadScore ? HEADER_SIZE : 0; bool EHi = false; if (filestats.st_size - HeaderSize >= 0x500000) { ROMFile.seekg(0x40FFC0 + HeaderSize, ios::beg); ROMFile.read((char *)HeaderBuffer, INFO_LEN); if (InfoScore((char *)HeaderBuffer) > 1) { EHi = true; strncpy(namebuffer, (char *)HeaderBuffer, 21); } } if (!EHi) { if (filestats.st_size - HeaderSize >= 0x10000) { char LoHead[INFO_LEN], HiHead[INFO_LEN]; ROMFile.seekg(0x7FC0 + HeaderSize, ios::beg); ROMFile.read(LoHead, INFO_LEN); int LoScore = InfoScore(LoHead); ROMFile.seekg(0xFFC0 + HeaderSize, ios::beg); ROMFile.read(HiHead, INFO_LEN); int HiScore = InfoScore(HiHead); strncpy(namebuffer, LoScore > HiScore ? LoHead : HiHead, 21); if (filestats.st_size - HeaderSize >= 0x20000) { ROMFile.seekg((filestats.st_size - HeaderSize) / 2 + 0x7FC0 + HeaderSize, ios::beg); ROMFile.read(LoHead, INFO_LEN); int IntLScore = InfoScore(LoHead) / 2; if (IntLScore > LoScore && IntLScore > HiScore) { strncpy(namebuffer, LoHead, 21); } } } else //ROM only has one block { ROMFile.seekg(0x7FC0 + HeaderSize, ios::beg); ROMFile.read(namebuffer, 21); } } ROMFile.close(); } else //Couldn't open file { strcpy(namebuffer, ROM_ITEM_CANTOPEN); } } else //Smaller than a block { strcpy(namebuffer, ROM_ITEM_NOTAROM); } double MBitD = (double)(filestats.st_size - HeaderSize) / 0x100000 * 8; int MBitI = (int)MBitD; int sizeIndex; if(0!=(MBitI / 10)) { sizebuffer[0] = MBitI / 10 + '0'; sizeIndex = 1; } else sizeIndex = 0; sizebuffer[sizeIndex+0] = MBitI % 10 + '0'; sizebuffer[sizeIndex+1] = '.'; sizebuffer[sizeIndex+2] = (char)((MBitD - MBitI) * 10) + '0'; sizebuffer[sizeIndex+3] = (char)((int)((MBitD - MBitI) * 100) % 10) + '0'; sizebuffer[sizeIndex+4] = ' '; sizebuffer[sizeIndex+5] = 'M'; sizebuffer[sizeIndex+6] = 'b'; sizebuffer[sizeIndex+7] = 'i'; sizebuffer[sizeIndex+8] = 't'; sizebuffer[sizeIndex+9] = '\0'; namebuffer[21] = '\0'; } void GetPathFromTree( HWND hDlg, UINT tree, TCHAR* selected, HTREEITEM hItem) { TVITEM tv; TCHAR temp[MAX_PATH]; temp[0]='\0'; ZeroMemory(&tv, sizeof(TVITEM)); HTREEITEM hTreeTemp=hItem; if(tv.iImage==7) { tv.mask=TVIF_HANDLE|TVIF_IMAGE; tv.hItem=hTreeTemp; tv.iImage=6; TreeView_SetItem(GetDlgItem(hDlg, tree),&tv); ZeroMemory(&tv, sizeof(TVITEM)); } tv.mask=TVIF_HANDLE|TVIF_TEXT; tv.hItem=hTreeTemp; tv.pszText=temp; tv.cchTextMax =MAX_PATH; TreeView_GetItem(GetDlgItem(hDlg, tree), &tv); sprintf(selected, TEXT("%s"), temp); while(TreeView_GetParent(GetDlgItem(hDlg, tree), hTreeTemp)) { temp[0]='\0'; hTreeTemp=TreeView_GetParent(GetDlgItem(hDlg, tree), hTreeTemp); tv.mask=TVIF_HANDLE|TVIF_TEXT; tv.hItem=hTreeTemp; tv.pszText=temp; tv.cchTextMax =MAX_PATH; TreeView_GetItem(GetDlgItem(hDlg, tree), &tv); sprintf(temp, TEXT("%s\\%s"),temp, selected); strcpy(selected, temp); } } typedef struct RomDataCacheNode { char* fname; char* rname; char* rmbits; struct RomDataCacheNode* next; } RomDataList; void ClearCacheList(RomDataList* rdl) { RomDataList* temp=rdl; RomDataList* temp2=NULL; if(rdl==NULL) return; do { temp2=temp->next; if(temp->fname) delete [] temp->fname; if(temp->rmbits) delete [] temp->rmbits; if(temp->rname) delete [] temp->rname; delete temp; temp=temp2; } while(temp!=NULL); } void ExpandDir(char * selected, HTREEITEM hParent, HWND hDlg) { TCHAR temp[MAX_PATH]; WIN32_FIND_DATA wfd; ZeroMemory(&wfd, sizeof(WIN32_FIND_DATA)); strcat(selected, TEXT("\\*")); HANDLE hFind=FindFirstFile(selected,&wfd); selected[(strlen(selected)-1)]='\0'; do { if(wfd.dwFileAttributes&FILE_ATTRIBUTE_DIRECTORY) { if(strcmp(wfd.cFileName, TEXT("."))&&strcmp(wfd.cFileName, TEXT(".."))) { //skip these, add the rest. TV_INSERTSTRUCT tvis; ZeroMemory(&tvis, sizeof(TV_INSERTSTRUCT)); tvis.hParent=hParent; tvis.hInsertAfter=TVI_SORT; tvis.item.mask = TVIF_STATE | TVIF_TEXT | TVIF_IMAGE | TVIF_SELECTEDIMAGE; tvis.item.pszText=wfd.cFileName; tvis.item.cchTextMax=MAX_PATH; const bool locked = (wfd.dwFileAttributes&(FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_ENCRYPTED|FILE_ATTRIBUTE_OFFLINE))!=0; const bool hidden = (wfd.dwFileAttributes&(FILE_ATTRIBUTE_HIDDEN))!=0; tvis.item.iImage=hidden?9:(locked?8:7); tvis.item.iSelectedImage=locked?8:6; HTREEITEM hNewTree=TreeView_InsertItem(GetDlgItem(hDlg, IDC_ROM_DIR),&tvis); strcpy(temp, selected); strcat(temp, wfd.cFileName); strcat(temp, TEXT("\\*")); bool subdir=false; WIN32_FIND_DATA wfd2; ZeroMemory(&wfd2, sizeof(WIN32_FIND_DATA)); HANDLE hFind2=FindFirstFile(temp,&wfd2); do { if(wfd2.dwFileAttributes&FILE_ATTRIBUTE_DIRECTORY) { if(strcmp(wfd2.cFileName, TEXT("."))&&strcmp(wfd2.cFileName, TEXT(".."))) { subdir=true; } } } while(FindNextFile(hFind2, &wfd2)&&!subdir); if(subdir) { TV_INSERTSTRUCT tvis; ZeroMemory(&tvis, sizeof(TV_INSERTSTRUCT)); tvis.hParent=hNewTree; tvis.hInsertAfter=TVI_SORT; TreeView_InsertItem(GetDlgItem(hDlg, IDC_ROM_DIR),&tvis); } FindClose(hFind2); } } } while(FindNextFile(hFind, &wfd)); FindClose(hFind); //scan for folders } void ListFilesFromFolder(HWND hDlg, RomDataList** prdl) { RomDataList* rdl= *prdl; RomDataList* current=NULL; int count=0; TVITEM tv; TCHAR temp[MAX_PATH]; TCHAR selected[MAX_PATH]; // directory path temp[0]='\0'; ZeroMemory(&tv, sizeof(TVITEM)); HTREEITEM hTreeItem=TreeView_GetSelection(GetDlgItem(hDlg, IDC_ROM_DIR)); GetPathFromTree(hDlg, IDC_ROM_DIR, selected, hTreeItem); SendDlgItemMessage(hDlg, IDC_ROMLIST, WM_SETREDRAW, FALSE, 0); ListView_DeleteAllItems(GetDlgItem(hDlg, IDC_ROMLIST)); ClearCacheList(rdl); rdl=NULL; //Add items here. WIN32_FIND_DATA wfd; ZeroMemory(&wfd, sizeof(WIN32_FIND_DATA)); strcat(selected, TEXT("\\*")); HANDLE hFind=FindFirstFile(selected, &wfd); selected[(strlen(selected)-1)]='\0'; do { if(wfd.dwFileAttributes&FILE_ATTRIBUTE_DIRECTORY) continue; if(ExtensionIsValid(wfd.cFileName)) { RomDataList* newitem=new RomDataList; ZeroMemory(newitem, sizeof(RomDataList)); newitem->fname=new char[1+strlen(wfd.cFileName)]; strcpy(newitem->fname, wfd.cFileName); // hide ntldr and no-name files if(!newitem->fname || !*newitem->fname || (!strcmp(newitem->fname, "ntldr") && strlen(selected)<4)) continue; // too small to be a ROM if (wfd.nFileSizeLow < 0x8000 && !IsCompressed(wfd.cFileName)) continue; count++; if(!rdl) rdl=newitem; else { if(0>stricmp(newitem->fname,rdl->fname)) { newitem->next=rdl; rdl=newitem; } else { RomDataList* trail=rdl; current=rdl->next; while(current!=NULL&&0fname,current->fname)) { trail=current; current=current->next; } newitem->next=current; trail->next=newitem; } } } } while(FindNextFile(hFind, &wfd)); FindClose(hFind); SendDlgItemMessage(hDlg, IDC_ROMLIST, WM_SETREDRAW, TRUE, 0); *prdl=rdl; ListView_SetItemCountEx (GetDlgItem(hDlg, IDC_ROMLIST), count, 0); ListView_SetItemState (GetDlgItem(hDlg,IDC_ROMLIST), 0, LVIS_SELECTED|LVIS_FOCUSED,LVIS_SELECTED|LVIS_FOCUSED); } // load multicart rom dialog int CALLBACK DlgMultiROMProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam) { switch(msg) { case WM_INITDIALOG:{ if(DirectX.Clipped) S9xReRefresh(); TCHAR path[MAX_PATH]; SetCurrentDirectory(S9xGetDirectory(BIOS_DIR)); _fullpath(path, "stbios.bin", MAX_PATH); SetDlgItemText(hDlg, IDC_MULTICART_BIOSEDIT, path); FILE* ftemp = fopen(path, "rb"); if(ftemp) { fclose(ftemp); SetDlgItemText(hDlg, IDC_MULTICART_BIOSNOTFOUND, MULTICART_BIOS_FOUND); } else SetDlgItemText(hDlg, IDC_MULTICART_BIOSNOTFOUND, MULTICART_BIOS_NOT_FOUND); SetDlgItemText(hDlg, IDC_MULTICART_EDITA, multiRomA); SetDlgItemText(hDlg, IDC_MULTICART_EDITB, multiRomB); break;} case WM_COMMAND: { char rom1[MAX_PATH]={0}, rom2[MAX_PATH]={0}; SetCurrentDirectory(S9xGetDirectory(ROM_DIR)); switch(LOWORD(wParam)) { case IDOK: GetDlgItemText(hDlg, IDC_MULTICART_EDITA, multiRomA, MAX_PATH); GetDlgItemText(hDlg, IDC_MULTICART_EDITB, multiRomB, MAX_PATH); if(*multiRomA) _fullpath(multiRomA, multiRomA, MAX_PATH); if(*multiRomB) _fullpath(multiRomB, multiRomB, MAX_PATH); EndDialog(hDlg, 1); return true; case IDCANCEL: EndDialog(hDlg, 0); return true; case IDC_MULTICART_SWAP: GetDlgItemText(hDlg, IDC_MULTICART_EDITA, rom2, MAX_PATH); GetDlgItemText(hDlg, IDC_MULTICART_EDITB, rom1, MAX_PATH); if(*rom1) _fullpath(rom1, rom1, MAX_PATH); if(*rom2) _fullpath(rom2, rom2, MAX_PATH); SetDlgItemText(hDlg, IDC_MULTICART_EDITA, rom1); SetDlgItemText(hDlg, IDC_MULTICART_EDITB, rom2); break; case IDC_MULTICART_BROWSEA: if(!DoOpenRomDialog(rom1, true)) break; _fullpath(rom1, rom1, MAX_PATH); SetDlgItemText(hDlg, IDC_MULTICART_EDITA, rom1); break; case IDC_MULTICART_BROWSEB: if(!DoOpenRomDialog(rom2, true)) break; _fullpath(rom2, rom2, MAX_PATH); SetDlgItemText(hDlg, IDC_MULTICART_EDITB, rom2); break; case IDC_MULTICART_CLEARA: rom1[0] = '\0'; SetDlgItemText(hDlg, IDC_MULTICART_EDITA, rom1); break; case IDC_MULTICART_CLEARB: rom1[1] = '\0'; SetDlgItemText(hDlg, IDC_MULTICART_EDITB, rom2); break; } } } return false; } int CALLBACK DlgOpenROMProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam) { static HBITMAP hBmp; int rv=0; static HWND hSplit; static HIMAGELIST hIcons; static TCHAR *filename; static RomDataList* rdl; static int selectionMarkOverride = -1; static bool initDone = false; static RomDataList* nextInvalidatedROM = NULL; static int nextInvalidatedROMCounter = 0; static HWND romList = NULL; static HWND dirList = NULL; switch(msg) { case WM_INITDIALOG: if(DirectX.Clipped) S9xReRefresh(); { initDone = false; // suppress annoying "no disk in drive" errors SetErrorMode(SEM_FAILCRITICALERRORS); romList = GetDlgItem(hDlg,IDC_ROMLIST); dirList = GetDlgItem(hDlg,IDC_ROM_DIR); hBmp=(HBITMAP)LoadImage(NULL, TEXT("Koji.bmp"), IMAGE_BITMAP, 0,0, LR_CREATEDIBSECTION | LR_LOADFROMFILE); filename=(TCHAR*)lParam; RECT treeRect; RECT listRect; WNDCLASSEX wcex; TCHAR tempclassname[]=TEXT("S9xSplitter"); ZeroMemory(&wcex, sizeof(WNDCLASSEX)); wcex.cbSize=sizeof(WNDCLASSEX); wcex.hInstance=g_hInst; wcex.lpfnWndProc=DlgChildSplitProc; wcex.lpszClassName=tempclassname; wcex.hbrBackground=(HBRUSH)GetStockObject(LTGRAY_BRUSH); wcex.hCursor=LoadCursor(NULL, IDC_SIZEWE); /// wcex.hCursor=LoadCursor(NULL, MAKEINTRESOURCE(IDC_SIZEWE)); /// ATOM aSplitter=RegisterClassEx(&wcex); GetWindowRect(dirList, &treeRect); GetWindowRect(romList, &listRect); POINT p; ListView_SetExtendedListViewStyle(romList, LVS_EX_FULLROWSELECT); p.x=treeRect.right; p.y=treeRect.top; ScreenToClient(hDlg, &p); hSplit=CreateWindow(TEXT("S9xSplitter"), TEXT(""),WS_CHILD|WS_VISIBLE , p.x, p.y, listRect.left-treeRect.right , listRect.bottom-listRect.top, hDlg,NULL, g_hInst,0); LVCOLUMN col; static const LPSTR temp1 = TEXT(ROM_COLUMN_FILENAME); ZeroMemory(&col, sizeof(LVCOLUMN)); col.mask=LVCF_FMT|LVCF_ORDER|LVCF_TEXT|LVCF_WIDTH; col.fmt=LVCFMT_LEFT; col.iOrder=0; col.cx=196; col.cchTextMax=5; col.pszText=temp1; ListView_InsertColumn(romList, 0, &col); static const LPSTR temp2 = TEXT(ROM_COLUMN_DESCRIPTION); ZeroMemory(&col, sizeof(LVCOLUMN)); col.mask=LVCF_FMT|LVCF_ORDER|LVCF_TEXT|LVCF_WIDTH|LVCF_SUBITEM; col.fmt=LVCFMT_LEFT; col.iOrder=1; col.cx=112; col.cchTextMax=32; col.pszText=temp2; col.iSubItem=1; ListView_InsertColumn(romList, 1, &col); static const LPSTR temp3 = TEXT(ROM_COLUMN_SIZE); ZeroMemory(&col, sizeof(LVCOLUMN)); col.mask=LVCF_FMT|LVCF_ORDER|LVCF_TEXT|LVCF_WIDTH|LVCF_SUBITEM; col.fmt=LVCFMT_LEFT; col.iOrder=2; col.cx=67; col.cchTextMax=32; col.pszText=temp3; col.iSubItem=2; ListView_InsertColumn(romList, 2, &col); SendDlgItemMessage(hDlg, IDC_MEM_TYPE,CB_INSERTSTRING,0,(LPARAM)TEXT(ROM_OPTION_AUTODETECT)); SendDlgItemMessage(hDlg, IDC_MEM_TYPE,CB_INSERTSTRING,1,(LPARAM)TEXT(ROM_OPTION_FORCEHIROM)); SendDlgItemMessage(hDlg, IDC_MEM_TYPE,CB_INSERTSTRING,2,(LPARAM)TEXT(ROM_OPTION_FORCELOROM)); SendDlgItemMessage(hDlg, IDC_MEM_TYPE,CB_SETCURSEL,0,0); SendDlgItemMessage(hDlg, IDC_VIDEO_MODE,CB_INSERTSTRING,0,(LPARAM)TEXT(ROM_OPTION_AUTODETECT)); SendDlgItemMessage(hDlg, IDC_VIDEO_MODE,CB_INSERTSTRING,1,(LPARAM)TEXT(ROM_OPTION_FORCEPAL)); SendDlgItemMessage(hDlg, IDC_VIDEO_MODE,CB_INSERTSTRING,2,(LPARAM)TEXT(ROM_OPTION_FORCENTSC)); SendDlgItemMessage(hDlg, IDC_VIDEO_MODE,CB_SETCURSEL,0,0); SendDlgItemMessage(hDlg, IDC_HEADER,CB_INSERTSTRING,0,(LPARAM)TEXT(ROM_OPTION_AUTODETECT)); SendDlgItemMessage(hDlg, IDC_HEADER,CB_INSERTSTRING,1,(LPARAM)TEXT(ROM_OPTION_FORCEHEADER)); SendDlgItemMessage(hDlg, IDC_HEADER,CB_INSERTSTRING,2,(LPARAM)TEXT(ROM_OPTION_FORCENOHEADER)); SendDlgItemMessage(hDlg, IDC_HEADER,CB_SETCURSEL,0,0); SendDlgItemMessage(hDlg, IDC_INTERLEAVE,CB_INSERTSTRING,0,(LPARAM)TEXT(ROM_OPTION_AUTODETECT)); SendDlgItemMessage(hDlg, IDC_INTERLEAVE,CB_INSERTSTRING,1,(LPARAM)TEXT(ROM_OPTION_NONINTERLEAVED)); SendDlgItemMessage(hDlg, IDC_INTERLEAVE,CB_INSERTSTRING,2,(LPARAM)TEXT(ROM_OPTION_MODE1)); SendDlgItemMessage(hDlg, IDC_INTERLEAVE,CB_INSERTSTRING,3,(LPARAM)TEXT(ROM_OPTION_MODE2)); SendDlgItemMessage(hDlg, IDC_INTERLEAVE,CB_INSERTSTRING,4,(LPARAM)TEXT(ROM_OPTION_GD24)); SendDlgItemMessage(hDlg, IDC_INTERLEAVE,CB_SETCURSEL,0,0); hIcons=ImageList_Create(16,16,ILC_COLOR24,10,10); HANDLE hBitmap; #define ADD_IMAGE(IDB_NAME) \ hBitmap=LoadImage(g_hInst, MAKEINTRESOURCE(IDB_NAME), IMAGE_BITMAP, 0,0, LR_DEFAULTCOLOR|LR_CREATEDIBSECTION); \ ImageList_Add(hIcons, (HBITMAP)hBitmap, NULL); \ DeleteObject(hBitmap); ADD_IMAGE(IDB_HARDDRIVE); // 0 ADD_IMAGE(IDB_CDDRIVE); // 1 ADD_IMAGE(IDB_NETDRIVE); // 2 ADD_IMAGE(IDB_REMOVABLE); // 3 ADD_IMAGE(IDB_RAMDISK); // 4 ADD_IMAGE(IDB_UNKNOWN); // 5 ADD_IMAGE(IDB_OPENFOLDER); // 6 ADD_IMAGE(IDB_CLOSEDFOLDER); // 7 ADD_IMAGE(IDB_LOCKEDFOLDER); // 8 ADD_IMAGE(IDB_HIDDENFOLDER); // 9 TreeView_SetImageList(dirList, hIcons, TVSIL_NORMAL); // DWORD dw; TCHAR buffer[MAX_PATH]; TCHAR blah[MAX_PATH]; long result=ERROR_SUCCESS/*-1*/; HTREEITEM hTreeDrive=NULL; char drive [_MAX_DRIVE + 1]; strcpy (drive,"C:\\"); _fullpath (buffer, S9xGetDirectory(ROM_DIR), MAX_PATH); _splitpath (buffer, drive, NULL, NULL, NULL); DWORD driveMask=GetLogicalDrives(); #ifndef SKIP_FLOPPY for (int i=0;i<26;i++) #else for (int i=2;i<26;i++) #endif { if(driveMask&(1<=0) { RomDataList* curr=rdl; for(int i=0;inext; if(curr && !curr->rname) { nextInvalidatedROM = curr; nextInvalidatedROMCounter = selected; } } LVHITTESTINFO lvhi; lvhi.flags = LVHT_ONITEM; lvhi.iItem = 0; lvhi.iSubItem = 0; lvhi.pt.x = 0; lvhi.pt.y = 0; ListView_HitTest(romList, &lvhi); int firstVisibleItem = lvhi.iItem+1; int lastVisibleItem = firstVisibleItem+20; // skip up to 100 things that don't need updating bool enteredValid = false; if(nextInvalidatedROM->rname || nextInvalidatedROMCounterlastVisibleItem) for(int i = 0 ; i < 100 ; i++) if(nextInvalidatedROM->rname || (!enteredValid && (nextInvalidatedROMCounterlastVisibleItem))) { if(!enteredValid && nextInvalidatedROMCounter>=firstVisibleItem && nextInvalidatedROMCounternext; if(nextInvalidatedROM) nextInvalidatedROMCounter++; else { nextInvalidatedROM = rdl; nextInvalidatedROMCounter = 0; } } // update 1 item, if it needs updating if(!nextInvalidatedROM->rname) { TCHAR path[MAX_PATH]; TCHAR buffer[32]; TCHAR buffer2[32]; GetPathFromTree(hDlg, IDC_ROM_DIR, path, TreeView_GetSelection(dirList)); strcat(path, "\\"); strcat(path, nextInvalidatedROM->fname); rominfo(path, buffer, buffer2); nextInvalidatedROM->rname=new char[strlen(buffer)+1]; strcpy(nextInvalidatedROM->rname, buffer); nextInvalidatedROM->rmbits=new char[strlen(buffer2)+1]; strcpy(nextInvalidatedROM->rmbits, buffer2); ListView_RedrawItems(romList,nextInvalidatedROMCounter,nextInvalidatedROMCounter); } // next timer nextInvalidatedROM = nextInvalidatedROM->next; if(nextInvalidatedROM) nextInvalidatedROMCounter++; else { nextInvalidatedROM = rdl; nextInvalidatedROMCounter = 0; } SetTimer(hDlg,42,600,NULL); return true; } case WM_PAINT: { PAINTSTRUCT ps; BeginPaint (hDlg, &ps); if(hBmp) { BITMAP bmp; ZeroMemory(&bmp, sizeof(BITMAP)); RECT r; GetClientRect(hDlg, &r); HDC hdc=GetDC(hDlg); HDC hDCbmp=CreateCompatibleDC(hdc); GetObject(hBmp, sizeof(BITMAP), &bmp); HBITMAP hOldBmp=(HBITMAP)SelectObject(hDCbmp, hBmp); StretchBlt(hdc, 0,0,r.right,r.bottom,hDCbmp,0,0,bmp.bmWidth,bmp.bmHeight,SRCCOPY); SelectObject(hDCbmp, hOldBmp); DeleteDC(hDCbmp); ReleaseDC(hDlg, hdc); } EndPaint (hDlg, &ps); } return true; case WM_COMMAND: { switch(LOWORD(wParam)) { case IDOK: { LVITEM lvi; ZeroMemory(&lvi, sizeof(LVITEM)); //get selections int list_index = selectionMarkOverride == -1 ? ListView_GetSelectionMark(romList) : selectionMarkOverride; if(list_index!=-1 && (int)SendMessage(romList, LVM_GETNEXTITEM, (WPARAM)-1, LVNI_SELECTED)!=-1) { rv=1; TCHAR temp[MAX_PATH]; temp[0]='\0'; lvi.iItem=list_index; lvi.mask=LVIF_TEXT; lvi.pszText=filename; lvi.cchTextMax=MAX_PATH; ListView_GetItem(romList, &lvi); strcpy(temp, filename); HTREEITEM hTreeTemp=TreeView_GetSelection(dirList); TVITEM tv; ZeroMemory(&tv, sizeof(TVITEM)); tv.mask=TVIF_HANDLE|TVIF_TEXT; tv.hItem=hTreeTemp; tv.pszText=temp; tv.cchTextMax =MAX_PATH; TreeView_GetItem(dirList, &tv); sprintf(temp, TEXT("%s\\%s"), temp, filename); strcpy(filename, temp); while(TreeView_GetParent(dirList, hTreeTemp)!=NULL) { temp[0]='\0'; hTreeTemp=TreeView_GetParent(dirList, hTreeTemp); tv.mask=TVIF_HANDLE|TVIF_TEXT; tv.hItem=hTreeTemp; tv.pszText=temp; tv.cchTextMax =MAX_PATH; TreeView_GetItem(dirList, &tv); sprintf(temp, TEXT("%s\\%s"),temp, filename); strcpy(filename, temp); } int iTemp=SendDlgItemMessage(hDlg, IDC_MEM_TYPE,CB_GETCURSEL,0,0); Settings.ForceHiROM=Settings.ForceLoROM=FALSE; if(iTemp==1) Settings.ForceHiROM=TRUE; else if(iTemp==2) Settings.ForceLoROM=TRUE; iTemp=SendDlgItemMessage(hDlg, IDC_INTERLEAVE,CB_GETCURSEL,0,0); Settings.ForceNotInterleaved=Settings.ForceInterleaved=Settings.ForceInterleaved2=Settings.ForceInterleaveGD24=FALSE; if(iTemp==1) Settings.ForceNotInterleaved=TRUE; else if(iTemp==2) Settings.ForceInterleaved=TRUE; else if(iTemp==3) Settings.ForceInterleaved2=TRUE; else if(iTemp==4) Settings.ForceInterleaveGD24=TRUE; iTemp=SendDlgItemMessage(hDlg, IDC_VIDEO_MODE,CB_GETCURSEL,0,0); Settings.ForceNTSC=Settings.ForcePAL=FALSE; if(iTemp==1) Settings.ForcePAL=TRUE; else if(iTemp==2) Settings.ForceNTSC=TRUE; iTemp=SendDlgItemMessage(hDlg, IDC_HEADER,CB_GETCURSEL,0,0); Settings.ForceNoHeader=Settings.ForceHeader=FALSE; if(iTemp==1) Settings.ForceHeader=TRUE; else if(iTemp==2) Settings.ForceNoHeader=TRUE; strcpy(temp, filename); int i=strlen(temp); while(temp[i]!='\\' && temp[i]!='/') { temp[i]='\0'; i--; } temp[i]='\0'; if(!GUI.LockDirectories) absToRel(GUI.RomDir, temp, S9xGetDirectory(DEFAULT_DIR)); } else { return false; } } case IDCANCEL: EndDialog(hDlg, rv); if(hBmp) { DeleteObject(hBmp); hBmp=NULL; } ClearCacheList(rdl); rdl=NULL; DestroyWindow(hSplit); UnregisterClass(TEXT("S9xSplitter"), g_hInst); TreeView_DeleteAllItems(dirList); ListView_DeleteAllItems(romList); return true; break; default: return false; break; } } case WM_NOTIFY: { if(lParam == 0) return false; NMHDR* pNmh=(NMHDR*)lParam; static int foundItemOverride = -1; switch(pNmh->idFrom) { case IDC_ROMLIST: { switch(pNmh->code) { // allow typing in a ROM filename (or part of it) to jump to it // necessary to implement ourselves because Windows doesn't provide // this functionality for virtual (owner data) lists such as this case LVN_ODFINDITEM: { LRESULT pResult; // pNMHDR has information about the item we should find // In pResult we should save which item that should be selected NMLVFINDITEM* pFindInfo = (NMLVFINDITEM*)lParam; /* pFindInfo->iStart is from which item we should search. We search to bottom, and then restart at top and will stop at pFindInfo->iStart, unless we find an item that match */ // Set the default return value to -1 // That means we didn't find any match. pResult = -1; //Is search NOT based on string? if( (pFindInfo->lvfi.flags & LVFI_STRING) == 0 ) { //This will probably never happend... return pResult; } //This is the string we search for LPCSTR searchstr = pFindInfo->lvfi.psz; int startPos = pFindInfo->iStart; //Is startPos outside the list (happens if last item is selected) if(startPos >= ListView_GetItemCount(romList)) startPos = 0; if(rdl==NULL) return pResult; RomDataList* curr=rdl; for(int i=0;inext; int currentPos=startPos; pResult=startPos; bool looped = false; // perform search do { // does this word begin with all characters in searchstr? if( _tcsnicmp(curr->fname, searchstr, strlen(searchstr)) == 0) { // select this item and stop search pResult = currentPos; break; } else if( _tcsnicmp(curr->fname, searchstr, strlen(searchstr)) > 0) { if(looped) { pResult = currentPos; break; } // optimization: the items are ordered alphabetically, so go back to the top since we know it can't be anything further down curr=rdl; currentPos = 0; looped = true; continue; } //Go to next item currentPos++; curr=curr->next; //Need to restart at top? if(currentPos >= ListView_GetItemCount(romList)) { currentPos = 0; curr = rdl; } //Stop if back to start }while(currentPos != startPos); foundItemOverride = pResult; // in case previously-selected item is 0 ListView_SetItemState (romList, 1, LVIS_SELECTED|LVIS_FOCUSED,LVIS_SELECTED|LVIS_FOCUSED); return pResult; // HACK: for some reason this selects the first item instead of what it's returning... current workaround is to manually re-select this return value upon the next changed event } break; case LVN_ITEMCHANGED: { // hack - see note directly above LPNMLISTVIEW lpnmlv = (LPNMLISTVIEW)lParam; if(lpnmlv->uNewState & (LVIS_SELECTED|LVIS_FOCUSED)) { if(foundItemOverride != -1 && lpnmlv->iItem == 0) { ListView_SetItemState (romList, foundItemOverride, LVIS_SELECTED|LVIS_FOCUSED,LVIS_SELECTED|LVIS_FOCUSED); ListView_EnsureVisible (romList, foundItemOverride, FALSE); selectionMarkOverride = foundItemOverride; foundItemOverride = -1; } else { selectionMarkOverride = lpnmlv->iItem; } } } break; case LVN_GETDISPINFO: { if(!initDone) return false; int i, j; RomDataList* curr=rdl; if(rdl==NULL) return false; NMLVDISPINFO * nmlvdi=(NMLVDISPINFO*)lParam; j=nmlvdi->item.iItem; for(i=0;inext; if(curr==NULL) return false; //if(curr->rname==NULL && j==(int)SendMessage(romList, LVM_GETNEXTITEM, -1, LVNI_SELECTED)) //{ // TCHAR path[MAX_PATH]; // TCHAR buffer[32]; // TCHAR buffer2[32]; // GetPathFromTree(hDlg, IDC_ROM_DIR, path, TreeView_GetSelection(dirList)); // strcat(path, "\\"); // strcat(path, curr->fname); // rominfo(path, buffer, buffer2); // curr->rname=new char[strlen(buffer)+1]; // strcpy(curr->rname, buffer); // curr->rmbits=new char[strlen(buffer2)+1]; // strcpy(curr->rmbits, buffer2); //} if(nmlvdi->item.iSubItem==0) { nmlvdi->item.pszText=curr->fname?curr->fname:(char*)""; nmlvdi->item.cchTextMax=MAX_PATH; } if(nmlvdi->item.iSubItem==1) { nmlvdi->item.pszText=curr->rname?curr->rname:(char*)""; nmlvdi->item.cchTextMax=24; } if(nmlvdi->item.iSubItem==2) { nmlvdi->item.pszText=curr->rmbits?curr->rmbits:(char*)""; nmlvdi->item.cchTextMax=11; } // nmlvdi->item.mask=LVIF_TEXT; // This is bad as wine relies on this to not change. } break; case NM_DBLCLK: { PostMessage(hDlg, WM_COMMAND, (WPARAM)(IDOK),(LPARAM)(NULL)); } default:break; } } break; case IDC_ROM_DIR: { switch(pNmh->code) { case TVN_ITEMEXPANDING: { TCHAR selected[MAX_PATH]; NMTREEVIEW* nmTv=(NMTREEVIEW*)lParam; while(TreeView_GetChild(dirList,nmTv->itemNew.hItem)) { TreeView_DeleteItem(dirList, TreeView_GetChild(dirList,nmTv->itemNew.hItem)); } if(nmTv->action&TVE_EXPAND) { GetPathFromTree(hDlg, IDC_ROM_DIR, selected,nmTv->itemNew.hItem); ExpandDir(selected, nmTv->itemNew.hItem, hDlg); } else { TVITEM tv; ZeroMemory(&tv, sizeof(TVITEM)); HTREEITEM hTreeTemp=nmTv->itemNew.hItem; if(tv.iImage==6) { tv.mask=TVIF_HANDLE|TVIF_IMAGE; tv.hItem=hTreeTemp; tv.iImage=7; TreeView_SetItem(dirList,&tv); } TV_INSERTSTRUCT tvis; ZeroMemory(&tvis, sizeof(TV_INSERTSTRUCT)); tvis.hParent=nmTv->itemNew.hItem; tvis.hInsertAfter=TVI_SORT; TreeView_InsertItem(dirList,&tvis); } } return false; break; case TVN_SELCHANGED: { ListFilesFromFolder(hDlg, &rdl); nextInvalidatedROM = rdl; nextInvalidatedROMCounter = 0; } default:return false; } } default:return false; } } default:return false; } } LRESULT CALLBACK DlgChildSplitProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) { static bool PaintSpecial; static short drag_x; short temp_x; switch(msg) { case WM_CREATE: return 0; case WM_SIZE: return 0; case WM_PAINT: PAINTSTRUCT ps; GetUpdateRect (hWnd, &ps.rcPaint, true); ps.hdc=GetDC(hWnd); ps.fErase=true; BeginPaint(hWnd, &ps); EndPaint(hWnd, &ps); ReleaseDC(hWnd, ps.hdc); return 0; case WM_LBUTTONDOWN: PaintSpecial=true; drag_x=GET_X_LPARAM(lParam); SetCapture(hWnd); return 0; case WM_LBUTTONUP: PaintSpecial=false; temp_x=(GET_X_LPARAM(lParam)-drag_x); HWND hDlg,hTree,hList; RECT treeRect; RECT listRect; hDlg=GetParent(hWnd); hTree=GetDlgItem(hDlg, IDC_ROM_DIR); hList=GetDlgItem(hDlg, IDC_ROMLIST); GetWindowRect(hTree, &treeRect); POINT p; p.x=temp_x+treeRect.right; p.y=treeRect.top; GetWindowRect(hList, &listRect); if(p.x>(listRect.right-50)) { temp_x-=(short)(p.x-(listRect.right-50)); p.x=listRect.right-50; } ScreenToClient(hDlg, &p); if(p.x<50) { temp_x+=(short)(50-p.x); p.x=50; } MoveWindow( hWnd, p.x, p.y, listRect.left-treeRect.right, listRect.bottom-listRect.top, FALSE); MoveWindow(hList, p.x+(listRect.left-treeRect.right), p.y,listRect.right-listRect.left-temp_x, listRect.bottom-listRect.top, TRUE); p.x=treeRect.left; p.y=treeRect.top; ScreenToClient(hDlg, &p); MoveWindow(hTree, p.x, p.y,treeRect.right-treeRect.left+temp_x,treeRect.bottom-treeRect.top, true); InvalidateRect(hWnd,NULL, true); ReleaseCapture(); return 0; case WM_MOUSEMOVE: if (wParam & MK_LBUTTON) { //move paint location PaintSpecial=true; temp_x=(GET_X_LPARAM(lParam)-drag_x); hDlg=GetParent(hWnd); hTree=GetDlgItem(hDlg, IDC_ROM_DIR); hList=GetDlgItem(hDlg, IDC_ROMLIST); GetWindowRect(hTree, &treeRect); p.x=temp_x+treeRect.right; p.y=treeRect.top; GetWindowRect(hList, &listRect); if(p.x>(listRect.right-50)) { temp_x-=(short)(p.x-(listRect.right-50)); p.x=listRect.right-50; } ScreenToClient(hDlg, &p); if(p.x<50) { temp_x+=(short)(50-p.x); p.x=50; } MoveWindow(hWnd, p.x, p.y, listRect.left-treeRect.right, listRect.bottom-listRect.top, FALSE); MoveWindow(hList, p.x+(listRect.left-treeRect.right), p.y,listRect.right-listRect.left-temp_x, listRect.bottom-listRect.top, TRUE); p.x=treeRect.left; p.y=treeRect.top; ScreenToClient(hDlg, &p); MoveWindow(hTree, p.x, p.y,treeRect.right-treeRect.left+temp_x,treeRect.bottom-treeRect.top, true); InvalidateRect(hWnd,NULL, true); } return 0; case WM_CAPTURECHANGED: PaintSpecial=false; ReleaseCapture(); return 0; case WM_DESTROY: return 0; default:return DefWindowProc(hWnd, msg, wParam, lParam); } } int CALLBACK DlgPackConfigProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam) { static HBITMAP hBmp; switch(msg) { case WM_INITDIALOG: if(DirectX.Clipped) S9xReRefresh(); { hBmp=(HBITMAP)LoadImage(NULL, TEXT("LinkHylia.bmp"), IMAGE_BITMAP, 0,0, LR_CREATEDIBSECTION | LR_LOADFROMFILE); SetDlgItemText(hDlg, IDC_STAR_OCEAN, GUI.StarOceanPack); SetDlgItemText(hDlg, IDC_SFA2, GUI.SFA2NTSCPack); SetDlgItemText(hDlg, IDC_SFA2E, GUI.SFA2PALPack); SetDlgItemText(hDlg, IDC_SJNS, GUI.SJNSPack); SetDlgItemText(hDlg, IDC_SFZ2, GUI.SFZ2Pack); SetDlgItemText(hDlg, IDC_MDH, GUI.MDHPack); SetDlgItemText(hDlg, IDC_SPL4, GUI.SPL4Pack); SetDlgItemText(hDlg, IDC_FEOEZ, GUI.FEOEZPack); } return true; case WM_PAINT: { PAINTSTRUCT ps; BeginPaint (hDlg, &ps); if(hBmp) { BITMAP bmp; ZeroMemory(&bmp, sizeof(BITMAP)); RECT r; GetClientRect(hDlg, &r); HDC hdc=GetDC(hDlg); HDC hDCbmp=CreateCompatibleDC(hdc); GetObject(hBmp, sizeof(BITMAP), &bmp); HBITMAP hOldBmp=(HBITMAP)SelectObject(hDCbmp, hBmp); StretchBlt(hdc, 0,0,r.right,r.bottom,hDCbmp,0,0,bmp.bmWidth,bmp.bmHeight,SRCCOPY); SelectObject(hDCbmp, hOldBmp); DeleteDC(hDCbmp); ReleaseDC(hDlg, hdc); } EndPaint (hDlg, &ps); } return true; case WM_COMMAND: { switch(LOWORD(wParam)) { case IDC_SO_BROWSE: { LPMALLOC lpm=NULL; LPITEMIDLIST iidl=NULL; BROWSEINFO bi; ZeroMemory(&bi, sizeof(BROWSEINFO)); char path[MAX_PATH]; char title[]="Star Ocean Graphics Pack"; CoInitialize(NULL); bi.hwndOwner=hDlg; bi.pszDisplayName=path; bi.lpszTitle=title; iidl=SHBrowseForFolder(&bi); SHGetPathFromIDList(iidl, path); SHGetMalloc(&lpm); lpm->Free(iidl); CoUninitialize(); SetDlgItemText(hDlg, IDC_STAR_OCEAN, path); } break; case IDC_SFA2_BROWSE: { LPMALLOC lpm=NULL; LPITEMIDLIST iidl=NULL; BROWSEINFO bi; ZeroMemory(&bi, sizeof(BROWSEINFO)); char path[MAX_PATH]; char title[]="Street Fighter Alpha 2 Graphics Pack"; CoInitialize(NULL); bi.hwndOwner=hDlg; bi.pszDisplayName=path; bi.lpszTitle=title; iidl=SHBrowseForFolder(&bi); SHGetPathFromIDList(iidl, path); SHGetMalloc(&lpm); lpm->Free(iidl); CoUninitialize(); SetDlgItemText(hDlg, IDC_SFA2, path); } break; case IDC_SFA2E_BROWSE: { LPMALLOC lpm=NULL; LPITEMIDLIST iidl=NULL; BROWSEINFO bi; ZeroMemory(&bi, sizeof(BROWSEINFO)); char path[MAX_PATH]; char title[]="Street Fighter Alpha 2 Graphics Pack"; CoInitialize(NULL); bi.hwndOwner=hDlg; bi.pszDisplayName=path; bi.lpszTitle=title; iidl=SHBrowseForFolder(&bi); SHGetPathFromIDList(iidl, path); SHGetMalloc(&lpm); lpm->Free(iidl); CoUninitialize(); SetDlgItemText(hDlg, IDC_SFA2E, path); } break; case IDC_SFZ2_BROWSE: { LPMALLOC lpm=NULL; LPITEMIDLIST iidl=NULL; BROWSEINFO bi; ZeroMemory(&bi, sizeof(BROWSEINFO)); char path[MAX_PATH]; char title[]="Street Fighter Zero 2 Graphics Pack"; CoInitialize(NULL); bi.hwndOwner=hDlg; bi.pszDisplayName=path; bi.lpszTitle=title; iidl=SHBrowseForFolder(&bi); SHGetPathFromIDList(iidl, path); SHGetMalloc(&lpm); lpm->Free(iidl); CoUninitialize(); SetDlgItemText(hDlg, IDC_SFZ2, path); } break; case IDC_FEOEZ_BROWSE: { LPMALLOC lpm=NULL; LPITEMIDLIST iidl=NULL; BROWSEINFO bi; ZeroMemory(&bi, sizeof(BROWSEINFO)); char path[MAX_PATH]; char title[]="Far East of Eden Zero Graphics Pack"; CoInitialize(NULL); bi.hwndOwner=hDlg; bi.pszDisplayName=path; bi.lpszTitle=title; iidl=SHBrowseForFolder(&bi); SHGetPathFromIDList(iidl, path); SHGetMalloc(&lpm); lpm->Free(iidl); CoUninitialize(); SetDlgItemText(hDlg, IDC_FEOEZ, path); } break; case IDC_MDH_BROWSE: { LPMALLOC lpm=NULL; LPITEMIDLIST iidl=NULL; BROWSEINFO bi; ZeroMemory(&bi, sizeof(BROWSEINFO)); char path[MAX_PATH]; char title[]="Momotarou Densetsu Happy Graphics Pack"; CoInitialize(NULL); bi.hwndOwner=hDlg; bi.pszDisplayName=path; bi.lpszTitle=title; iidl=SHBrowseForFolder(&bi); SHGetPathFromIDList(iidl, path); SHGetMalloc(&lpm); lpm->Free(iidl); CoUninitialize(); SetDlgItemText(hDlg, IDC_MDH, path); } break; case IDC_FEOEZ_SJNS_BROWSE: { LPMALLOC lpm=NULL; LPITEMIDLIST iidl=NULL; BROWSEINFO bi; ZeroMemory(&bi, sizeof(BROWSEINFO)); char path[MAX_PATH]; char title[]="FEOEZ - Shounen Jump no Shou Graphics Pack"; CoInitialize(NULL); bi.hwndOwner=hDlg; bi.pszDisplayName=path; bi.lpszTitle=title; iidl=SHBrowseForFolder(&bi); SHGetPathFromIDList(iidl, path); SHGetMalloc(&lpm); lpm->Free(iidl); CoUninitialize(); SetDlgItemText(hDlg, IDC_SJNS, path); } break; case IDC_SPL4_BROWSE: { LPMALLOC lpm=NULL; LPITEMIDLIST iidl=NULL; BROWSEINFO bi; ZeroMemory(&bi, sizeof(BROWSEINFO)); char path[MAX_PATH]; char title[]="FEOEZ - Shounen Jump no Shou Graphics Pack"; CoInitialize(NULL); bi.hwndOwner=hDlg; bi.pszDisplayName=path; bi.lpszTitle=title; iidl=SHBrowseForFolder(&bi); SHGetPathFromIDList(iidl, path); SHGetMalloc(&lpm); lpm->Free(iidl); CoUninitialize(); SetDlgItemText(hDlg, IDC_SPL4, path); } break; case IDOK: GetDlgItemText(hDlg, IDC_STAR_OCEAN, GUI.StarOceanPack, MAX_PATH); GetDlgItemText(hDlg, IDC_SFA2, GUI.SFA2NTSCPack, MAX_PATH); GetDlgItemText(hDlg, IDC_SPL4, GUI.SPL4Pack, MAX_PATH); GetDlgItemText(hDlg, IDC_SJNS, GUI.SJNSPack, MAX_PATH); GetDlgItemText(hDlg, IDC_SFZ2, GUI.SFZ2Pack, MAX_PATH); GetDlgItemText(hDlg, IDC_SFA2E, GUI.SFA2PALPack, MAX_PATH); GetDlgItemText(hDlg, IDC_MDH, GUI.MDHPack, MAX_PATH); GetDlgItemText(hDlg, IDC_FEOEZ, GUI.FEOEZPack, MAX_PATH); WinSaveConfigFile(); case IDCANCEL: if(hBmp) { DeleteObject(hBmp); hBmp=NULL; } EndDialog(hDlg, 0); return true; break; default: return false; break; } } default:return false; } } extern "C" { char*osd_GetPackDir() { static char filename[MAX_PATH]; memset(filename, 0, MAX_PATH); if(strlen(GUI.FreezeFileDir)!=0) strcpy (filename, GUI.FreezeFileDir); else { char dir [_MAX_DIR + 1]; char drive [_MAX_DRIVE + 1]; char name [_MAX_FNAME + 1]; char ext [_MAX_EXT + 1]; _splitpath(Memory.ROMFilename,drive, dir, name, ext); _makepath(filename,drive, dir, NULL, NULL); } if(!strncmp((char*)&Memory.ROM [0xffc0], "SUPER POWER LEAG 4 ", 21)) { if(strlen(GUI.SPL4Pack)) return GUI.SPL4Pack; else strcat(filename, "\\SPL4-SP7"); } else if(!strncmp((char*)&Memory.ROM [0xffc0], "MOMOTETSU HAPPY ",21)) { if(strlen(GUI.MDHPack)) return GUI.MDHPack; else strcat(filename, "\\SMHT-SP7"); } else if(!strncmp((char*)&Memory.ROM [0xffc0], "HU TENGAI MAKYO ZERO ", 21)) { if(strlen(GUI.FEOEZPack)) return GUI.FEOEZPack; else strcat(filename, "\\FEOEZSP7"); } else if(!strncmp((char*)&Memory.ROM [0xffc0], "JUMP TENGAIMAKYO ZERO",21)) { if(strlen(GUI.SJNSPack)) return GUI.SJNSPack; else strcat(filename, "\\SJUMPSP7"); } else strcat(filename, "\\MISC-SP7"); return filename; } } #ifdef NETPLAY_SUPPORT int CALLBACK DlgNetConnect(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam) { static HBITMAP hBmp; // HKEY hKey; char defPort[5]; char portTemp[5]; char temp[100]; // char temp2[5]; static char* hostname; // unsigned long cbData; // static int i; if(Settings.Port==0) { _itoa(1996,defPort,10); } else { _itoa(Settings.Port,defPort,10); } WORD chkLength; // if(RegCreateKeyEx(HKEY_CURRENT_USER,MY_REG_KEY "\\1.x\\NetPlayServerHistory",0,NULL,REG_OPTION_NON_VOLATILE,KEY_ALL_ACCESS, NULL, &hKey,NULL) == ERROR_SUCCESS){} switch (msg) { case WM_INITDIALOG: if(DirectX.Clipped) S9xReRefresh(); SetWindowText(hDlg,NPCON_TITLE); SetDlgItemText(hDlg,IDC_LABEL_SERVERADDY,NPCON_LABEL_SERVERADDY); SetDlgItemText(hDlg,IDC_LABEL_PORTNUM,NPCON_LABEL_PORTNUM); SetDlgItemText(hDlg,IDC_CLEARHISTORY, NPCON_CLEARHISTORY); SetDlgItemText(hDlg,IDOK,BUTTON_OK); SetDlgItemText(hDlg,IDCANCEL,BUTTON_CANCEL); hBmp=(HBITMAP)LoadImage(NULL, TEXT("Overload.bmp"), IMAGE_BITMAP, 0,0, LR_CREATEDIBSECTION | LR_LOADFROMFILE); hostname = (char *)lParam; { for(int i=0; i65535||atoi(portTemp)<1024) { MessageBox(hDlg,"Port Number needs to be between 1024 and 65535","Error",MB_OK); break; } else { Settings.Port = atoi(portTemp); } //chkLength = (WORD) SendDlgItemMessage(hDlg,IDC_HOSTNAME,EM_LINELENGTH,0,0); //if(chkLength > 0) //{ //SendDlgItemMessage(hDlg,IDC_HOSTNAME,EM_GETLINE,0,(LPARAM)hostname); SendDlgItemMessage(hDlg,IDC_HOSTNAME,WM_GETTEXT,100,(LPARAM)temp); if(!strcmp(temp, NPCON_ENTERHOST)) { MessageBox(hDlg,NPCON_PLEASE_ENTERHOST,"Error",MB_OK); break; } strcpy(hostname,temp); //MessageBox(hDlg,temp,"hola",MB_OK); // save hostname in recent list { int i; for(i=0; i 0) { EndDialog(hDlg,1); if(hBmp) { DeleteObject(hBmp); hBmp=NULL; } return TRUE; } else { EndDialog(hDlg,0); if(hBmp) { DeleteObject(hBmp); hBmp=NULL; } return TRUE; } break; //} } case IDCANCEL: { EndDialog(hDlg, 0); if(hBmp) { DeleteObject(hBmp); hBmp=NULL; } return TRUE; } default:break; } } return FALSE; } #endif void SetInfoDlgColor(unsigned char r, unsigned char g, unsigned char b) { GUI.InfoColor=RGB(r,g,b); } void ClearExts(void) { ExtList* temp; ExtList* curr=valid_ext; while(curr!=NULL) { temp=curr->next; if(curr->extension) delete [] curr->extension; delete curr; curr=temp; } valid_ext=NULL; } void LoadExts(void) { char buffer[MAX_PATH+2]; if(valid_ext!=NULL) { ClearExts(); } ExtList* curr; valid_ext=new ExtList; curr=valid_ext; ZeroMemory(curr, sizeof(ExtList)); ifstream in; #if (((defined(_MSC_VER) && _MSC_VER >= 1300)) || defined(__MINGW32__)) in.open("Valid.Ext", ios::in); #else in.open("Valid.Ext", ios::in|ios::nocreate); #endif if (!in.is_open()) { in.clear(); MakeExtFile(); #if (((defined(_MSC_VER) && _MSC_VER >= 1300)) || defined(__MINGW32__)) in.open("Valid.Ext", ios::in); #else in.open("Valid.Ext", ios::in|ios::nocreate); #endif if(!in.is_open()) { MessageBox(GUI.hWnd, "Fatal Error: The File \"Valid.Ext\" could not be found or created.", "Error", MB_ICONERROR|MB_OK); PostQuitMessage(-1); } } do { buffer[0]='\0'; in.getline(buffer,MAX_PATH+2); if((*buffer)!='\0') { curr->next=new ExtList; curr=curr->next; ZeroMemory(curr, sizeof(ExtList)); if(_strnicmp(buffer+strlen(buffer)-1, "Y", 1)==0) curr->compressed=true; if(strlen(buffer)>1) { curr->extension=new char[strlen(buffer)-1]; strncpy(curr->extension, buffer, strlen(buffer)-1); curr->extension[strlen(buffer)-1]='\0'; } else curr->extension=NULL; } } while(!in.eof()); in.close(); curr=valid_ext; valid_ext=valid_ext->next; delete curr; } void MakeExtFile(void) { ofstream out; out.open("Valid.Ext"); out<<"N" <65535) { MessageBox(hDlg,"Port Number needs to be betweeb 1024 and 65535","Error",MB_OK); break; } else { Settings.Port = atoi(defPort); } //MessageBox(hDlg,defPort,defPort,MB_OK); Settings.NetPlayServer = IsDlgButtonChecked(hDlg,IDC_ACTASSERVER); NPServer.SendROMImageOnConnect = IsDlgButtonChecked(hDlg,IDC_SENDROM); NPServer.SyncByReset = IsDlgButtonChecked(hDlg,IDC_SYNCBYRESET); EndDialog(hDlg,0); if(hBmp) { DeleteObject(hBmp); hBmp=NULL; } WinSaveConfigFile(); return TRUE; } case IDCANCEL: { EndDialog(hDlg,0); if(hBmp) { DeleteObject(hBmp); hBmp=NULL; } return TRUE; } } } return FALSE; } #endif HRESULT CALLBACK EnumModesCallback( LPDDSURFACEDESC lpDDSurfaceDesc, LPVOID lpContext) { char depmode[80]; char s[80]; dMode curmode; HWND hDlg = (HWND)lpContext; int index; // HKEY hKey; DWORD type; // BYTE val[4]; // DWORD nuv=4; type=REG_DWORD; if((lpDDSurfaceDesc->ddpfPixelFormat.dwRGBBitCount != 15 && lpDDSurfaceDesc->ddpfPixelFormat.dwRGBBitCount != 16) || (lpDDSurfaceDesc->dwWidth < SNES_WIDTH || lpDDSurfaceDesc->dwHeight < SNES_HEIGHT_EXTENDED)) { // let them muck with the .cfg file if they really want to set such a poor display mode return DDENUMRET_OK; // keep going without adding mode to list } sprintf( depmode, "%dx%d %dbit %dHz", (int)lpDDSurfaceDesc->dwWidth, (int)lpDDSurfaceDesc->dwHeight, (int)lpDDSurfaceDesc->ddpfPixelFormat.dwRGBBitCount, (int)lpDDSurfaceDesc->dwRefreshRate); // RegOpenKeyEx(HKEY_CURRENT_USER,MY_REG_KEY "\\1.x\\DisplayModes",0,KEY_ALL_ACCESS, &hKey); curmode.width=lpDDSurfaceDesc->dwWidth; curmode.height=lpDDSurfaceDesc->dwHeight; curmode.depth=lpDDSurfaceDesc->ddpfPixelFormat.dwRGBBitCount; curmode.rate=lpDDSurfaceDesc->dwRefreshRate; // NYI: loading which display modes have been tested // if(RegQueryValueEx(hKey,depmode,0,&type,val,&nuv)==ERROR_SUCCESS) // { // //sprintf(s,"%d %d %d %d",val[0],val[1],val[2],val[3]); // //MessageBox(hDlg,s,temp,MB_OK); // switch(val[0]) // { // case 1: // strcpy(s,"Failed"); // curmode.status=1; // break; // case 3: // strcpy(s,"Works"); // curmode.status=3; // break; // default: // strcpy(s,"Untested"); // curmode.status=0; // } // } // else { strcpy(s,"Untested"); curmode.status=0; //MessageBox(hDlg,s,temp,MB_OK); } dm.push_back(curmode); LVITEM lvi; ZeroMemory(&lvi, sizeof(LVITEM)); lvi.iItem=dm.size(); lvi.mask=LVIF_TEXT; lvi.pszText=depmode; lvi.cchTextMax=80; //lvi.lParam=dmindex; index=ListView_InsertItem(hDlg, &lvi); //dmindex++; ZeroMemory(&lvi, sizeof(LVITEM)); lvi.mask=LVIF_TEXT; lvi.iItem=index; lvi.iSubItem=1; lvi.pszText=s; lvi.cchTextMax=10; ListView_SetItem(hDlg, &lvi); // RegCloseKey(hKey); return DDENUMRET_OK; } void EnableDisableKeyFields (int index, HWND hDlg) { bool enableUnTurboable; if(index < 5) { SetDlgItemText(hDlg,IDC_LABEL_RIGHT,INPUTCONFIG_LABEL_RIGHT); SetDlgItemText(hDlg,IDC_LABEL_UPLEFT,INPUTCONFIG_LABEL_UPLEFT); SetDlgItemText(hDlg,IDC_LABEL_UPRIGHT,INPUTCONFIG_LABEL_UPRIGHT); SetDlgItemText(hDlg,IDC_LABEL_DOWNRIGHT,INPUTCONFIG_LABEL_DOWNRIGHT); SetDlgItemText(hDlg,IDC_LABEL_UP,INPUTCONFIG_LABEL_UP); SetDlgItemText(hDlg,IDC_LABEL_LEFT,INPUTCONFIG_LABEL_LEFT); SetDlgItemText(hDlg,IDC_LABEL_DOWN,INPUTCONFIG_LABEL_DOWN); SetDlgItemText(hDlg,IDC_LABEL_DOWNLEFT,INPUTCONFIG_LABEL_DOWNLEFT); enableUnTurboable = true; } else { SetDlgItemText(hDlg,IDC_LABEL_UP,INPUTCONFIG_LABEL_MAKE_TURBO); SetDlgItemText(hDlg,IDC_LABEL_LEFT,INPUTCONFIG_LABEL_MAKE_HELD); SetDlgItemText(hDlg,IDC_LABEL_DOWN,INPUTCONFIG_LABEL_MAKE_TURBO_HELD); SetDlgItemText(hDlg,IDC_LABEL_RIGHT,INPUTCONFIG_LABEL_CLEAR_TOGGLES_AND_TURBO); SetDlgItemText(hDlg,IDC_LABEL_UPLEFT,INPUTCONFIG_LABEL_UNUSED); SetDlgItemText(hDlg,IDC_LABEL_UPRIGHT,INPUTCONFIG_LABEL_UNUSED); SetDlgItemText(hDlg,IDC_LABEL_DOWNLEFT,INPUTCONFIG_LABEL_UNUSED); SetDlgItemText(hDlg,IDC_LABEL_DOWNRIGHT,INPUTCONFIG_LABEL_UNUSED); SetDlgItemText(hDlg,IDC_UPLEFT,INPUTCONFIG_LABEL_UNUSED); SetDlgItemText(hDlg,IDC_UPRIGHT,INPUTCONFIG_LABEL_UNUSED); SetDlgItemText(hDlg,IDC_DWNLEFT,INPUTCONFIG_LABEL_UNUSED); SetDlgItemText(hDlg,IDC_DWNRIGHT,INPUTCONFIG_LABEL_UNUSED); enableUnTurboable = false; } EnableWindow(GetDlgItem(hDlg,IDC_UPLEFT), enableUnTurboable); EnableWindow(GetDlgItem(hDlg,IDC_UPRIGHT), enableUnTurboable); EnableWindow(GetDlgItem(hDlg,IDC_DWNRIGHT), enableUnTurboable); EnableWindow(GetDlgItem(hDlg,IDC_DWNLEFT), enableUnTurboable); } bool in_display_dlg = false; int CALLBACK DlgFunky(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam) { static HBITMAP hBmp; // HKEY hKey; int index; // static bool state = false; char s[80],temp[80]; // temporary GUI state for restoring after previewing while selecting options static int prevScale, prevScaleHiRes, prevPPL; static bool prevStretch, prevAspectRatio, prevHeightExtend, prevAutoDisplayMessages;//, prevVideoMemory; //if(RegCreateKeyEx(HKEY_CURRENT_USER,MY_REG_KEY "\\1.x\\DisplayModes",0,NULL,REG_OPTION_NON_VOLATILE,KEY_ALL_ACCESS, NULL, &hKey,NULL) == ERROR_SUCCESS) //{ // RegCloseKey(hKey); // //} switch(msg) { case WM_PAINT: { PAINTSTRUCT ps; BeginPaint (hDlg, &ps); if(hBmp) { BITMAP bmp; ZeroMemory(&bmp, sizeof(BITMAP)); RECT r; GetClientRect(hDlg, &r); HDC hdc=GetDC(hDlg); HDC hDCbmp=CreateCompatibleDC(hdc); GetObject(hBmp, sizeof(BITMAP), &bmp); HBITMAP hOldBmp=(HBITMAP)SelectObject(hDCbmp, hBmp); StretchBlt(hdc, 0,0,r.right,r.bottom,hDCbmp,0,0,bmp.bmWidth,bmp.bmHeight,SRCCOPY); SelectObject(hDCbmp, hOldBmp); DeleteDC(hDCbmp); ReleaseDC(hDlg, hdc); } EndPaint (hDlg, &ps); } return true; case WM_INITDIALOG: in_display_dlg = true; if(DirectX.Clipped) S9xReRefresh(); prevScale = GUI.Scale; prevScaleHiRes = GUI.ScaleHiRes; prevPPL = GFX.RealPPL; prevStretch = GUI.Stretch; // prevVideoMemory = GUI.VideoMemory; prevAspectRatio = GUI.AspectRatio; prevHeightExtend = GUI.HeightExtend; prevAutoDisplayMessages = Settings.AutoDisplayMessages != 0; hBmp=(HBITMAP)LoadImage(NULL, TEXT("lantus.bmp"), IMAGE_BITMAP, 0,0, LR_CREATEDIBSECTION | LR_LOADFROMFILE); sprintf(s,"Current Mode: %dx%d %dbit %dHz",GUI.Width,GUI.Height,GUI.Depth,GUI.RefreshRate); SendDlgItemMessage(hDlg,IDC_CURRMODE,WM_SETTEXT,0,(LPARAM)s); if(DirectX.lpDD==NULL) DirectDrawCreate( NULL, &DirectX.lpDD, NULL); if(GUI.DoubleBuffered) SendDlgItemMessage(hDlg, IDC_DBLBUFFER, BM_SETCHECK, (WPARAM)BST_CHECKED, 0); SendDlgItemMessage(hDlg,IDC_FRAMERATESKIPSLIDER,TBM_SETRANGE,(WPARAM)true,(LPARAM)MAKELONG(0,9)); if(Settings.SkipFrames!=AUTO_FRAMERATE) SendDlgItemMessage(hDlg,IDC_FRAMERATESKIPSLIDER,TBM_SETPOS,(WPARAM)true,(LPARAM)Settings.SkipFrames); // EnableWindow(GetDlgItem(hDlg, IDC_RENDER16BIT), FALSE); // EnableWindow(GetDlgItem(hDlg, IDC_TRANS), FALSE); // if(Settings.SixteenBit) { // SendDlgItemMessage(hDlg, IDC_RENDER16BIT, BM_SETCHECK, (WPARAM)BST_CHECKED, 0); EnableWindow(GetDlgItem(hDlg, IDC_TRANS), TRUE); } if(Settings.Transparency) SendDlgItemMessage(hDlg, IDC_TRANS, BM_SETCHECK, (WPARAM)BST_CHECKED, 0); if(Settings.SupportHiRes) SendDlgItemMessage(hDlg, IDC_HIRES, BM_SETCHECK, (WPARAM)BST_CHECKED, 0); if(GUI.HeightExtend) SendDlgItemMessage(hDlg, IDC_HEIGHT_EXTEND, BM_SETCHECK, (WPARAM)BST_CHECKED, 0); //// if(Settings.Mode7Interpolate) // EnableWindow(GetDlgItem(hDlg, IDC_BILINEARMD7), FALSE); // { //// SendDlgItemMessage(hDlg, IDC_BILINEARMD7, BM_SETCHECK, (WPARAM)BST_CHECKED, 0); // SendDlgItemMessage(hDlg, IDC_BILINEARMD7, BM_SETCHECK, (WPARAM)BST_UNCHECKED, 0); // } if(Settings.AutoDisplayMessages) SendDlgItemMessage(hDlg, IDC_MESSAGES_IN_IMAGE, BM_SETCHECK, (WPARAM)BST_CHECKED, 0); if(Settings.SkipFrames==AUTO_FRAMERATE) SendDlgItemMessage(hDlg, IDC_AUTOFRAME, BM_SETCHECK, (WPARAM)BST_CHECKED, 0); if(GUI.Stretch) { SendDlgItemMessage(hDlg, IDC_STRETCH, BM_SETCHECK, (WPARAM)BST_CHECKED, 0); SendDlgItemMessage(hDlg,IDC_VIDEOCARD,WM_SETTEXT,0,(LPARAM)"Bi-linear Filtering"); } else SendDlgItemMessage(hDlg,IDC_VIDEOCARD,WM_SETTEXT,0,(LPARAM)"Use Video Memory"); if(GUI.AspectRatio) SendDlgItemMessage(hDlg, IDC_ASPECT, BM_SETCHECK, (WPARAM)BST_CHECKED, 0); if(GUI.FullScreen) SendDlgItemMessage(hDlg, IDC_FULLSCREEN, BM_SETCHECK, (WPARAM)BST_CHECKED, 0); if(GUI.VideoMemory) SendDlgItemMessage(hDlg,IDC_VIDEOCARD, BM_SETCHECK, (WPARAM)BST_CHECKED,0); EnableWindow(GetDlgItem(hDlg, IDC_LOCALVIDMEM), GUI.VideoMemory); if(GUI.LocalVidMem) SendDlgItemMessage(hDlg,IDC_LOCALVIDMEM, BM_SETCHECK, (WPARAM)BST_CHECKED,0); if(Settings.DisplayFrameRate) SendDlgItemMessage(hDlg, IDC_SHOWFPS, BM_SETCHECK, (WPARAM)BST_CHECKED, 0); if(Settings.AutoMaxSkipFrames==0) SendDlgItemMessage(hDlg, IDC_LIMITFRAMES, BM_SETCHECK, (WPARAM)BST_CHECKED, 0); if(IsDlgButtonChecked(hDlg,IDC_AUTOFRAME)) EnableWindow(GetDlgItem(hDlg, IDC_LIMITFRAMES), TRUE); EnableWindow(GetDlgItem(hDlg, IDC_ASPECT), GUI.Stretch); // add all the GUI.Scale filters to the combo box for(int filter = 0 ; filter < (int)NUM_FILTERS ; filter++) { #ifdef USE_OPENGL // hide OpenGL Bilinear from the dialog. It can still be set in the .cfg file, but right now OpenGL mode is a little too buggy (some black things render as white) to be in the GUI's display menu. if(filter == (int)FILTER_OPENGL && (int)FILTER_OPENGL+1 == (int)NUM_FILTERS && GUI.Scale != (int)FILTER_OPENGL) break; #endif strcpy(temp,GetFilterName((RenderFilter)filter)); SendDlgItemMessage(hDlg,IDC_FILTERBOX,CB_ADDSTRING,0,(LPARAM) (LPCTSTR)temp); } for(int filter = 0 ; filter < (int)NUM_FILTERS ; filter++) { #ifdef USE_OPENGL if(filter == (int)FILTER_OPENGL && (int)FILTER_OPENGL+1 == (int)NUM_FILTERS && GUI.Scale != (int)FILTER_OPENGL) continue; #endif if(GetFilterHiResSupport((RenderFilter)filter)) { strcpy(temp,GetFilterName((RenderFilter)filter)); SendDlgItemMessage(hDlg,IDC_FILTERBOX2,CB_ADDSTRING,0,(LPARAM) (LPCTSTR)temp); } } // SendDlgItemMessage(hDlg,IDC_FILTERBOX2,CB_SETCURSEL,(WPARAM)GUI.NextScaleHiRes,0); SendDlgItemMessage(hDlg,IDC_FILTERBOX,CB_SETCURSEL,(WPARAM)GUI.NextScale,0); //if(!GUI.FullScreen || (GUI.Width >= 512 && GUI.Height >= 478) || GUI.Stretch) //{ // EnableWindow(GetDlgItem(hDlg,IDC_FILTERBOX),true); // EnableWindow(GetDlgItem(hDlg,IDC_HIRES),true); //} //else //{ // EnableWindow(GetDlgItem(hDlg,IDC_FILTERBOX),false); // EnableWindow(GetDlgItem(hDlg,IDC_HIRES),false); //} LVCOLUMN col; strcpy(s,"Status"); ZeroMemory(&col, sizeof(LVCOLUMN)); col.mask=LVCF_FMT|LVCF_TEXT|LVCF_WIDTH; col.fmt=LVCFMT_LEFT; col.iOrder=0; col.cx=60; col.cchTextMax=80; col.pszText=s; ListView_InsertColumn(GetDlgItem(hDlg,IDC_VIDMODELIST), 1, &col); strcpy(s,"Video Mode"); ZeroMemory(&col, sizeof(LVCOLUMN)); col.mask=LVCF_FMT|LVCF_ORDER|LVCF_TEXT|LVCF_WIDTH; col.fmt=LVCFMT_LEFT; col.iOrder=0; col.cx=125; col.cchTextMax=80; col.pszText=s; ListView_InsertColumn(GetDlgItem(hDlg,IDC_VIDMODELIST), 0, &col); DirectX.lpDD->EnumDisplayModes(DDEDM_REFRESHRATES,NULL,GetDlgItem(hDlg,IDC_VIDMODELIST),(LPDDENUMMODESCALLBACK)EnumModesCallback); // have to start focus on something like this or Escape won't exit the dialog SetFocus(GetDlgItem(hDlg,IDC_FILTERBOX)); goto checkUpdateFilterBox2; break; case WM_CLOSE: case WM_DESTROY: // dmindex=0; break; case WM_COMMAND: switch(LOWORD(wParam)) { case IDC_STRETCH: if(!in_display_dlg) break; // for some reason this screws up the fullscreen mode clipper if it happens before the refresh if(IsDlgButtonChecked(hDlg, IDC_STRETCH)==BST_CHECKED) { EnableWindow(GetDlgItem(hDlg, IDC_ASPECT), TRUE); SendDlgItemMessage(hDlg,IDC_VIDEOCARD,WM_SETTEXT,0,(LPARAM)"Bi-linear Filtering"); } else { EnableWindow(GetDlgItem(hDlg, IDC_ASPECT), FALSE); SendDlgItemMessage(hDlg,IDC_VIDEOCARD,WM_SETTEXT,0,(LPARAM)"Use Video Memory"); } GUI.Stretch = (bool)(IsDlgButtonChecked(hDlg,IDC_STRETCH)==BST_CHECKED); // refresh screen, so the user can see the new mode // (assuming the dialog box isn't completely covering the game window) if(DirectX.Clipped) S9xReRefresh(); // make video memory option match stretching option, but allow it to be changed via the other checkbox CheckDlgButton(hDlg,IDC_VIDEOCARD,GUI.Stretch); /* fall through */ case IDC_VIDEOCARD: EnableWindow(GetDlgItem(hDlg, IDC_LOCALVIDMEM), (bool)(IsDlgButtonChecked(hDlg,IDC_VIDEOCARD)==BST_CHECKED)); //GUI.VideoMemory = (bool)(IsDlgButtonChecked(hDlg,IDC_VIDEOCARD)==BST_CHECKED); //RestoreSNESDisplay (); //// refresh screen, so the user can see the new stretch mode //if(DirectX.Clipped) S9xReRefresh(); break; case IDC_MESSAGES_IN_IMAGE: if(!in_display_dlg) break; Settings.AutoDisplayMessages = (bool)(IsDlgButtonChecked(hDlg,IDC_MESSAGES_IN_IMAGE)==BST_CHECKED); if(Settings.AutoDisplayMessages || Settings.OpenGLEnable || Settings.GlideEnable) { if(!GFX.InfoString || !*GFX.InfoString){ GFX.InfoString = "Test message!"; GFX.InfoStringTimeout = 1; } S9xDisplayMessages(GFX.Screen, GFX.RealPPL, IPPU.RenderedScreenWidth, IPPU.RenderedScreenHeight, 1); } // refresh screen, so the user can see the new mode if(DirectX.Clipped) S9xReRefresh(); break; case IDC_ASPECT: if(!in_display_dlg) break; GUI.AspectRatio = (bool)(IsDlgButtonChecked(hDlg,IDC_ASPECT)==BST_CHECKED); // refresh screen, so the user can see the new mode if(DirectX.Clipped) S9xReRefresh(); break; case IDC_HEIGHT_EXTEND: if(!in_display_dlg) break; GUI.HeightExtend = (bool)(IsDlgButtonChecked(hDlg,IDC_HEIGHT_EXTEND)==BST_CHECKED); // refresh screen, so the user can see the new mode if(DirectX.Clipped) S9xReRefresh(); break; case IDC_AUTOFRAME: if(!in_display_dlg) break; if(BN_CLICKED==HIWORD(wParam)||BN_DBLCLK==HIWORD(wParam)) { if(IsDlgButtonChecked(hDlg,IDC_AUTOFRAME)) { EnableWindow(GetDlgItem(hDlg, IDC_LIMITFRAMES), TRUE); } else EnableWindow(GetDlgItem(hDlg, IDC_LIMITFRAMES), FALSE); return true; } else return false; break; case IDC_FILTERBOX: if(!in_display_dlg) break; { int scale = (int)SendDlgItemMessage(hDlg,IDC_FILTERBOX,CB_GETCURSEL,0,0); if(scale == GUI.Scale) break; const int oldScaleScale = max(GetFilterScale(GUI.Scale), GetFilterScale(GUI.ScaleHiRes)); // UpdateScale(GUI.Scale, scale); if (IS_GL_OR_GLIDE(GUI.Scale) == IS_GL_OR_GLIDE(scale)) GUI.Scale = (RenderFilter)scale; else if(!IS_GL_OR_GLIDE(GUI.Scale) && IS_GL_OR_GLIDE(scale)) GUI.Scale = FILTER_NONE; const int newScaleScale = max(GetFilterScale(GUI.Scale), GetFilterScale(GUI.ScaleHiRes)); if(oldScaleScale != newScaleScale) RestoreSNESDisplay(); // refresh screen, so the user can see the new filter // (assuming the dialog box isn't completely covering the game window) if(DirectX.Clipped) S9xReRefresh(); // set hi-res combo box to match the lo-res output filter as best as possible // if(GetFilterHiResSupport(GUI.Scale)) checkUpdateFilterBox2: { char textOriginal [256]; SendMessage(GetDlgItem(hDlg, IDC_FILTERBOX), WM_GETTEXT, 256,(LPARAM)textOriginal); int count = SendDlgItemMessage(hDlg,IDC_FILTERBOX2,CB_GETCOUNT,0,0); // int scale = GUI.Scale; bool switched = false; for(int j=0; j<2 && !switched; j++){ if(j){ RenderFilter filter; // no match, set default for chosen scale switch(GetFilterScale(GUI.Scale)){ case 1: filter = FILTER_SIMPLE1X; break; default: case 2: filter = FILTER_SIMPLE2X; break; case 3: filter = FILTER_SIMPLE3X; break; } strcpy(textOriginal, GetFilterName(filter)); } for(int i=0; i<=count && !switched; i++){ int textLen = SendDlgItemMessage(hDlg,IDC_FILTERBOX2,CB_GETLBTEXTLEN,(WPARAM)i,0); char* text = new char[textLen+1]; SendDlgItemMessage(hDlg,IDC_FILTERBOX2,CB_GETLBTEXT,(WPARAM)i,(LPARAM)text); if(!stricmp(textOriginal, text)){ SendDlgItemMessage(hDlg,IDC_FILTERBOX2,CB_SETCURSEL,(WPARAM)i,0); switched = true; } delete[] text; } } goto updateFilterBox2; } } break; case IDC_FILTERBOX2: // hi-res updateFilterBox2: if(!in_display_dlg) break; { char text [256]; text[0] = '\0'; SendMessage(GetDlgItem(hDlg, IDC_FILTERBOX2), WM_GETTEXT, 256,(LPARAM)text); int scale = GUI.Scale; for(int i=0; i= 512 && GUI.Height >= 478) || GUI.Stretch) Settings.SupportHiRes = IsDlgButtonChecked(hDlg, IDC_HIRES); else Settings.SupportHiRes = false; GUI.HeightExtend = IsDlgButtonChecked(hDlg, IDC_HEIGHT_EXTEND)!=0; Settings.AutoDisplayMessages = IsDlgButtonChecked(hDlg, IDC_MESSAGES_IN_IMAGE); // Settings.Mode7Interpolate = IsDlgButtonChecked(hDlg, IDC_BILINEARMD7); GUI.DoubleBuffered = (bool)(IsDlgButtonChecked(hDlg, IDC_DBLBUFFER)==BST_CHECKED); if(IsDlgButtonChecked(hDlg, IDC_AUTOFRAME)) { Settings.SkipFrames=AUTO_FRAMERATE; } else { Settings.SkipFrames=(uint32)SendDlgItemMessage(hDlg,IDC_FRAMERATESKIPSLIDER,TBM_GETPOS,0,0); } if(IsDlgButtonChecked(hDlg, IDC_AUTOFRAME)&&IsDlgButtonChecked(hDlg, IDC_LIMITFRAMES)) { Settings.AutoMaxSkipFrames=0; } else { if(Settings.AutoMaxSkipFrames==0) { Settings.AutoMaxSkipFrames=1; } } GUI.Stretch = (bool)(IsDlgButtonChecked(hDlg, IDC_STRETCH)==BST_CHECKED); GUI.AspectRatio = (bool)(IsDlgButtonChecked(hDlg, IDC_ASPECT)==BST_CHECKED); GUI.FullScreen = (bool)(IsDlgButtonChecked(hDlg, IDC_FULLSCREEN)==BST_CHECKED); Settings.DisplayFrameRate = IsDlgButtonChecked(hDlg, IDC_SHOWFPS); // we might've changed the region that the game draws over // (by turning on "maintain aspect ratio", or turning on "extend height" when "maintain aspect ratio" is already on), // so we must invalidate the window to redraw black // behind the possibly-newly-revealed areas of the window RedrawWindow((HWND)GetParent(hDlg),NULL,NULL, RDW_INVALIDATE | RDW_INTERNALPAINT | RDW_ERASENOW); WinSaveConfigFile(); if(!GUI.FullScreen || (GUI.Width >= 512 && GUI.Height >= 478)) GUI.NextScale = (RenderFilter)SendDlgItemMessage(hDlg,IDC_FILTERBOX,CB_GETCURSEL,0,0); else GUI.NextScale = FILTER_NONE; if(!GUI.FullScreen || (GUI.Width >= 512 && GUI.Height >= 478)) GUI.NextScaleHiRes = GUI.ScaleHiRes; else GUI.NextScaleHiRes = FILTER_SIMPLE1X; // dmindex=0; EndDialog(hDlg,0); if(hBmp) { DeleteObject(hBmp); hBmp=NULL; } return false; case IDCANCEL: // dmindex=0; in_display_dlg = false; { //UpdateScale(GUI.Scale, prevScale); GUI.Scale = GUI.NextScale = (RenderFilter)prevScale; GUI.ScaleHiRes = GUI.NextScaleHiRes = (RenderFilter)prevScaleHiRes; GFX.RealPPL = prevPPL; GUI.Stretch = prevStretch; Settings.AutoDisplayMessages = prevAutoDisplayMessages; // GUI.VideoMemory = prevVideoMemory; GUI.AspectRatio = prevAspectRatio; GUI.HeightExtend = prevHeightExtend; // if(DirectX.Clipped) S9xReRefresh(); } EndDialog(hDlg,0); if(hBmp) { DeleteObject(hBmp); hBmp=NULL; } return false; case IDC_TESTMODE: //DirectX.lpDD->SetCooperativeLevel(hDlg,DDSCL_FULLSCREEN|DDSCL_ALLOWMODEX|DDSCL_EXCLUSIVE|DDSCL_ALLOWREBOOT); index=ListView_GetSelectionMark(GetDlgItem(hDlg,IDC_VIDMODELIST)); if(index != -1) { sprintf(temp,"%dx%d %dbit %dHz",(int)dm.at(index).width,(int)dm.at(index).height,(int)dm.at(index).depth,(int)dm.at(index).rate); // XXX: TODO: set the selected refresh rate too! (this defaults to highest possible rate instead) if(DirectX.lpDD->SetDisplayMode(dm.at(index).width,dm.at(index).height,dm.at(index).depth)!=DD_OK) { MessageBox(hDlg,"There was an error testing the selected mode","DD_NOTOK",MB_OK); LVITEM lvi; dm.at(index).status=1; strcpy(s,"Failed"); ZeroMemory(&lvi, sizeof(LVITEM)); lvi.mask=LVIF_TEXT; lvi.iItem=index; lvi.iSubItem=1; lvi.pszText=s; lvi.cchTextMax=10; ListView_SetItem(GetDlgItem(hDlg,IDC_VIDMODELIST), &lvi); // NYI: saving which display modes have been tested //if(RegOpenKeyEx(HKEY_CURRENT_USER,MY_REG_KEY "\\1.x\\DisplayModes",0,KEY_ALL_ACCESS, &hKey)==ERROR_SUCCESS) //{ // // RegSetValueEx(hKey,temp,0,REG_DWORD,(LPBYTE)&dm.at(index).status,sizeof(DWORD)); // // RegCloseKey(hKey); // //} } else { if(MessageBox(hDlg,"Did it Work?","Test Display Mode",MB_YESNO)==IDYES) { dm.at(index).status=3; LVITEM lvi; strcpy(s,"Works"); ZeroMemory(&lvi, sizeof(LVITEM)); lvi.mask=LVIF_TEXT; lvi.iItem=index; lvi.iSubItem=1; lvi.pszText=s; lvi.cchTextMax=10; ListView_SetItem(GetDlgItem(hDlg,IDC_VIDMODELIST), &lvi); // NYI: saving which display modes have been tested //if(RegOpenKeyEx(HKEY_CURRENT_USER,MY_REG_KEY "\\1.x\\DisplayModes",0,KEY_ALL_ACCESS, &hKey)==ERROR_SUCCESS) //{ // // if(RegSetValueEx(hKey,temp,0,REG_DWORD,(LPBYTE)&dm.at(index).status,sizeof(DWORD))==ERROR_SUCCESS) // { // // } // // RegCloseKey(hKey); // //} } else { dm.at(index).status=1; LVITEM lvi; strcpy(s,"Failed"); ZeroMemory(&lvi, sizeof(LVITEM)); lvi.mask=LVIF_TEXT; lvi.iItem=index; lvi.iSubItem=1; lvi.pszText=s; lvi.cchTextMax=10; ListView_SetItem(GetDlgItem(hDlg,IDC_VIDMODELIST), &lvi); // NYI: saving which display modes have been tested //if(RegOpenKeyEx(HKEY_CURRENT_USER, // MY_REG_KEY "\\1.x\\DisplayModes", // 0,KEY_ALL_ACCESS, &hKey)==ERROR_SUCCESS) //{ // RegSetValueEx(hKey,temp,0,REG_DWORD,(LPBYTE)&dm.at(index).status,sizeof(DWORD)); // // RegCloseKey(hKey); // //} } } // XXX: TODO: set the selected refresh rate too! (this defaults to highest possible rate instead) DirectX.lpDD->SetDisplayMode(GUI.Width,GUI.Height,GUI.Depth); } else { MessageBox(hDlg,"Please select a mode to test","No Mode Selected",MB_OK); } return false; case IDC_SETDMODE: bool go; index=ListView_GetSelectionMark(GetDlgItem(hDlg,IDC_VIDMODELIST)); switch (dm.at(index).status) { case 3: if(MessageBox(hDlg,"Are you sure?","Confirm Set Display Mode",MB_YESNO)==IDYES) { go=true; } else { go=false; } break; case 1: if(MessageBox(hDlg,"This mode failed in testing, are you sure?","Confirm Set Display Mode",MB_YESNO)==IDYES) { go=true; } else { go=false; } break; case 0: if(MessageBox(hDlg,"This Mode Hasn't been tested, are you sure?","Confirm Set Display Mode",MB_YESNO)==IDYES) { go=true; } else { go=false; } break; } if(go) { GUI.Width=dm.at(index).width; GUI.Height=dm.at(index).height; GUI.Depth=dm.at(index).depth; GUI.RefreshRate=dm.at(index).depth; } if(!GUI.FullScreen || (GUI.Width >= 512 && GUI.Height >= 478) || GUI.Stretch) { EnableWindow(GetDlgItem(hDlg,IDC_FILTERBOX),true); EnableWindow(GetDlgItem(hDlg,IDC_HIRES),true); } else { EnableWindow(GetDlgItem(hDlg,IDC_FILTERBOX),false); EnableWindow(GetDlgItem(hDlg,IDC_HIRES),false); } sprintf(s,"Current Mode: %dx%d %dbit %dHz",GUI.Width,GUI.Height,GUI.Depth,GUI.RefreshRate); SendDlgItemMessage(hDlg,IDC_CURRMODE,WM_SETTEXT,0,(LPARAM)s); return false; } } return false; } static void set_buttoninfo(int index, HWND hDlg) { SendDlgItemMessage(hDlg,IDC_UP,WM_USER+44,Joypad[index].Up,0); SendDlgItemMessage(hDlg,IDC_LEFT,WM_USER+44,Joypad[index].Left,0); SendDlgItemMessage(hDlg,IDC_DOWN,WM_USER+44,Joypad[index].Down,0); SendDlgItemMessage(hDlg,IDC_RIGHT,WM_USER+44,Joypad[index].Right,0); SendDlgItemMessage(hDlg,IDC_A,WM_USER+44,Joypad[index].A,0); SendDlgItemMessage(hDlg,IDC_B,WM_USER+44,Joypad[index].B,0); SendDlgItemMessage(hDlg,IDC_X,WM_USER+44,Joypad[index].X,0); SendDlgItemMessage(hDlg,IDC_Y,WM_USER+44,Joypad[index].Y,0); SendDlgItemMessage(hDlg,IDC_L,WM_USER+44,Joypad[index].L,0); SendDlgItemMessage(hDlg,IDC_R,WM_USER+44,Joypad[index].R,0); SendDlgItemMessage(hDlg,IDC_START,WM_USER+44,Joypad[index].Start,0); SendDlgItemMessage(hDlg,IDC_SELECT,WM_USER+44,Joypad[index].Select,0); if(index < 5) { SendDlgItemMessage(hDlg,IDC_UPLEFT,WM_USER+44,Joypad[index].Left_Up,0); SendDlgItemMessage(hDlg,IDC_UPRIGHT,WM_USER+44,Joypad[index].Right_Up,0); SendDlgItemMessage(hDlg,IDC_DWNLEFT,WM_USER+44,Joypad[index].Left_Down,0); SendDlgItemMessage(hDlg,IDC_DWNRIGHT,WM_USER+44,Joypad[index].Right_Down,0); } } void TranslateKey(WORD keyz,char *out); //HWND funky; SJoyState JoystickF [16]; #ifdef NETPLAY_SUPPORT int CALLBACK DlgNPProgress(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam) { SendDlgItemMessage(hDlg,IDC_NPPROGRESS,PBM_SETRANGE,0,(LPARAM)MAKELPARAM (0, 100)); SendDlgItemMessage(hDlg,IDC_NPPROGRESS,PBM_SETPOS,(WPARAM)(int)NetPlay.PercentageComplete,0); return false; } #endif int CALLBACK DlgInputConfig(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam) { static HBITMAP hBmp; char temp[256]; short C; int i, which; static int index=0; static SJoypad pads[10]; //HBRUSH g_hbrBackground; InitInputCustomControl(); switch(msg) { case WM_PAINT: { PAINTSTRUCT ps; BeginPaint (hDlg, &ps); if(hBmp) { BITMAP bmp; ZeroMemory(&bmp, sizeof(BITMAP)); RECT r; GetClientRect(hDlg, &r); HDC hdc=GetDC(hDlg); HDC hDCbmp=CreateCompatibleDC(hdc); GetObject(hBmp, sizeof(BITMAP), &bmp); HBITMAP hOldBmp=(HBITMAP)SelectObject(hDCbmp, hBmp); StretchBlt(hdc, 0,0,r.right,r.bottom,hDCbmp,0,0,bmp.bmWidth,bmp.bmHeight,SRCCOPY); SelectObject(hDCbmp, hOldBmp); DeleteDC(hDCbmp); ReleaseDC(hDlg, hdc); } EndPaint (hDlg, &ps); } return true; case WM_INITDIALOG: if(DirectX.Clipped) S9xReRefresh(); SetWindowText(hDlg,INPUTCONFIG_TITLE); SetDlgItemText(hDlg,IDC_JPTOGGLE,INPUTCONFIG_JPTOGGLE); SetDlgItemText(hDlg,IDC_OK,BUTTON_OK); SetDlgItemText(hDlg,IDC_CANCEL,BUTTON_CANCEL); /// SetDlgItemText(hDlg,IDC_DIAGTOGGLE,INPUTCONFIG_DIAGTOGGLE); SetDlgItemText(hDlg,IDC_LABEL_UP,INPUTCONFIG_LABEL_UP); SetDlgItemText(hDlg,IDC_LABEL_DOWN,INPUTCONFIG_LABEL_DOWN); SetDlgItemText(hDlg,IDC_LABEL_LEFT,INPUTCONFIG_LABEL_LEFT); SetDlgItemText(hDlg,IDC_LABEL_A,INPUTCONFIG_LABEL_A); SetDlgItemText(hDlg,IDC_LABEL_B,INPUTCONFIG_LABEL_B); SetDlgItemText(hDlg,IDC_LABEL_X,INPUTCONFIG_LABEL_X); SetDlgItemText(hDlg,IDC_LABEL_Y,INPUTCONFIG_LABEL_Y); SetDlgItemText(hDlg,IDC_LABEL_L,INPUTCONFIG_LABEL_L); SetDlgItemText(hDlg,IDC_LABEL_R,INPUTCONFIG_LABEL_R); SetDlgItemText(hDlg,IDC_LABEL_START,INPUTCONFIG_LABEL_START); SetDlgItemText(hDlg,IDC_LABEL_SELECT,INPUTCONFIG_LABEL_SELECT); SetDlgItemText(hDlg,IDC_LABEL_UPRIGHT,INPUTCONFIG_LABEL_UPRIGHT); SetDlgItemText(hDlg,IDC_LABEL_UPLEFT,INPUTCONFIG_LABEL_UPLEFT); SetDlgItemText(hDlg,IDC_LABEL_DOWNRIGHT,INPUTCONFIG_LABEL_DOWNRIGHT); SetDlgItemText(hDlg,IDC_LABEL_DOWNLEFT,INPUTCONFIG_LABEL_DOWNLEFT); SetDlgItemText(hDlg,IDC_LABEL_BLUE,INPUTCONFIG_LABEL_BLUE); for(i=5;i<10;i++) Joypad[i].Left_Up = Joypad[i].Right_Up = Joypad[i].Left_Down = Joypad[i].Right_Down = 0; hBmp=(HBITMAP)LoadImage(NULL, TEXT("PBortas.bmp"), IMAGE_BITMAP, 0,0, LR_CREATEDIBSECTION | LR_LOADFROMFILE); memcpy(pads, Joypad, 10*sizeof(SJoypad)); for( i=0;i<256;i++) GetAsyncKeyState(i); for( C = 0; C != 16; C ++) JoystickF[C].Attached = joyGetDevCaps( JOYSTICKID1+C, &JoystickF[C].Caps, sizeof( JOYCAPS)) == JOYERR_NOERROR; for(i=1;i<6;i++) { sprintf(temp,INPUTCONFIG_JPCOMBO,i); SendDlgItemMessage(hDlg,IDC_JPCOMBO,CB_ADDSTRING,0,(LPARAM)(LPCTSTR)temp); } for(i=6;i<11;i++) { sprintf(temp,INPUTCONFIG_JPCOMBO INPUTCONFIG_LABEL_CONTROLLER_TURBO_PANEL_MOD,i-5); SendDlgItemMessage(hDlg,IDC_JPCOMBO,CB_ADDSTRING,0,(LPARAM)(LPCTSTR)temp); } SendDlgItemMessage(hDlg,IDC_JPCOMBO,CB_SETCURSEL,(WPARAM)0,0); SendDlgItemMessage(hDlg,IDC_JPTOGGLE,BM_SETCHECK, Joypad[index].Enabled ? (WPARAM)BST_CHECKED : (WPARAM)BST_UNCHECKED, 0); SendDlgItemMessage(hDlg,IDC_ALLOWLEFTRIGHT,BM_SETCHECK, Settings.UpAndDown ? (WPARAM)BST_CHECKED : (WPARAM)BST_UNCHECKED, 0); set_buttoninfo(index,hDlg); EnableDisableKeyFields(index,hDlg); PostMessage(hDlg,WM_COMMAND, CBN_SELCHANGE<<16, 0); SetFocus(GetDlgItem(hDlg,IDC_JPCOMBO)); return true; break; case WM_CLOSE: EndDialog(hDlg, 0); return TRUE; case WM_USER+46: // refresh command, for clicking away from a selected field index = SendDlgItemMessage(hDlg,IDC_JPCOMBO,CB_GETCURSEL,0,0); if(index > 4) index += 3; // skip controllers 6, 7, and 8 in the input dialog set_buttoninfo(index,hDlg); return TRUE; case WM_USER+43: //MessageBox(hDlg,"USER+43 CAUGHT","moo",MB_OK); which = GetDlgCtrlID((HWND)lParam); switch(which) { case IDC_UP: Joypad[index].Up = wParam; break; case IDC_DOWN: Joypad[index].Down = wParam; break; case IDC_LEFT: Joypad[index].Left = wParam; break; case IDC_RIGHT: Joypad[index].Right = wParam; break; case IDC_A: Joypad[index].A = wParam; break; case IDC_B: Joypad[index].B = wParam; break; case IDC_X: Joypad[index].X = wParam; break; case IDC_Y: Joypad[index].Y = wParam; break; case IDC_L: Joypad[index].L = wParam; break; case IDC_R: Joypad[index].R = wParam; break; case IDC_SELECT: Joypad[index].Select = wParam; break; case IDC_START: Joypad[index].Start = wParam; break; case IDC_UPLEFT: Joypad[index].Left_Up = wParam; break; case IDC_UPRIGHT: Joypad[index].Right_Up = wParam; break; case IDC_DWNLEFT: Joypad[index].Left_Down = wParam; case IDC_DWNRIGHT: Joypad[index].Right_Down = wParam; break; } set_buttoninfo(index,hDlg); PostMessage(hDlg,WM_NEXTDLGCTL,0,0); return true; case WM_COMMAND: switch(LOWORD(wParam)) { case IDCANCEL: memcpy(Joypad, pads, 10*sizeof(SJoypad)); EndDialog(hDlg,0); if(hBmp) { DeleteObject(hBmp); hBmp=NULL; } break; case IDOK: Settings.UpAndDown = IsDlgButtonChecked(hDlg, IDC_ALLOWLEFTRIGHT); WinSaveConfigFile(); EndDialog(hDlg,0); if(hBmp) { DeleteObject(hBmp); hBmp=NULL; } break; case IDC_JPTOGGLE: // joypad Enable toggle index = SendDlgItemMessage(hDlg,IDC_JPCOMBO,CB_GETCURSEL,0,0); if(index > 4) index += 3; // skip controllers 6, 7, and 8 in the input dialog Joypad[index].Enabled=IsDlgButtonChecked(hDlg,IDC_JPTOGGLE); set_buttoninfo(index, hDlg); // update display of conflicts break; } switch(HIWORD(wParam)) { case CBN_SELCHANGE: index = SendDlgItemMessage(hDlg,IDC_JPCOMBO,CB_GETCURSEL,0,0); SendDlgItemMessage(hDlg,IDC_JPCOMBO,CB_SETCURSEL,(WPARAM)index,0); if(index > 4) index += 3; // skip controllers 6, 7, and 8 in the input dialog if(index < 8) { SendDlgItemMessage(hDlg,IDC_JPTOGGLE,BM_SETCHECK, Joypad[index].Enabled ? (WPARAM)BST_CHECKED : (WPARAM)BST_UNCHECKED, 0); EnableWindow(GetDlgItem(hDlg,IDC_JPTOGGLE),TRUE); } else { SendDlgItemMessage(hDlg,IDC_JPTOGGLE,BM_SETCHECK, Joypad[index-8].Enabled ? (WPARAM)BST_CHECKED : (WPARAM)BST_UNCHECKED, 0); EnableWindow(GetDlgItem(hDlg,IDC_JPTOGGLE),FALSE); } set_buttoninfo(index,hDlg); EnableDisableKeyFields(index,hDlg); break; } return FALSE; } return FALSE; } static void set_hotkeyinfo(HWND hDlg) { int index = SendDlgItemMessage(hDlg,IDC_HKCOMBO,CB_GETCURSEL,0,0); switch(index) { case 0: // set page 1 fields SendDlgItemMessage(hDlg,IDC_HOTKEY1,WM_USER+44,CustomKeys.SpeedUp.key,CustomKeys.SpeedUp.modifiers); SendDlgItemMessage(hDlg,IDC_HOTKEY2,WM_USER+44,CustomKeys.SpeedDown.key,CustomKeys.SpeedDown.modifiers); SendDlgItemMessage(hDlg,IDC_HOTKEY3,WM_USER+44,CustomKeys.Pause.key,CustomKeys.Pause.modifiers); SendDlgItemMessage(hDlg,IDC_HOTKEY4,WM_USER+44,CustomKeys.FrameAdvance.key,CustomKeys.FrameAdvance.modifiers); SendDlgItemMessage(hDlg,IDC_HOTKEY5,WM_USER+44,CustomKeys.FastForward.key,CustomKeys.FastForward.modifiers); SendDlgItemMessage(hDlg,IDC_HOTKEY6,WM_USER+44,CustomKeys.SkipUp.key,CustomKeys.SkipUp.modifiers); SendDlgItemMessage(hDlg,IDC_HOTKEY7,WM_USER+44,CustomKeys.SkipDown.key,CustomKeys.SkipDown.modifiers); SendDlgItemMessage(hDlg,IDC_HOTKEY8,WM_USER+44,CustomKeys.ScopeTurbo.key,CustomKeys.ScopeTurbo.modifiers); SendDlgItemMessage(hDlg,IDC_HOTKEY9,WM_USER+44,CustomKeys.ScopePause.key,CustomKeys.ScopePause.modifiers); SendDlgItemMessage(hDlg,IDC_HOTKEY10,WM_USER+44,CustomKeys.ShowPressed.key,CustomKeys.ShowPressed.modifiers); SendDlgItemMessage(hDlg,IDC_HOTKEY11,WM_USER+44,CustomKeys.FrameCount.key,CustomKeys.FrameCount.modifiers); SendDlgItemMessage(hDlg,IDC_HOTKEY12,WM_USER+44,CustomKeys.ReadOnly.key,CustomKeys.ReadOnly.modifiers); SendDlgItemMessage(hDlg,IDC_HOTKEY13,WM_USER+44,CustomKeys.SaveScreenShot.key,CustomKeys.SaveScreenShot.modifiers); break; case 1: SendDlgItemMessage(hDlg,IDC_HOTKEY1,WM_USER+44,CustomKeys.BGL1.key,CustomKeys.BGL1.modifiers); SendDlgItemMessage(hDlg,IDC_HOTKEY2,WM_USER+44,CustomKeys.BGL2.key,CustomKeys.BGL2.modifiers); SendDlgItemMessage(hDlg,IDC_HOTKEY3,WM_USER+44,CustomKeys.BGL3.key,CustomKeys.BGL3.modifiers); SendDlgItemMessage(hDlg,IDC_HOTKEY4,WM_USER+44,CustomKeys.BGL4.key,CustomKeys.BGL4.modifiers); SendDlgItemMessage(hDlg,IDC_HOTKEY5,WM_USER+44,CustomKeys.BGL5.key,CustomKeys.BGL5.modifiers); SendDlgItemMessage(hDlg,IDC_HOTKEY6,WM_USER+44,CustomKeys.ClippingWindows.key,CustomKeys.ClippingWindows.modifiers); SendDlgItemMessage(hDlg,IDC_HOTKEY7,WM_USER+44,CustomKeys.Transparency.key,CustomKeys.Transparency.modifiers); SendDlgItemMessage(hDlg,IDC_HOTKEY8,WM_USER+44,CustomKeys.HDMA.key,CustomKeys.HDMA.modifiers); SendDlgItemMessage(hDlg,IDC_HOTKEY9,WM_USER+44,CustomKeys.GLCube.key,CustomKeys.GLCube.modifiers); SendDlgItemMessage(hDlg,IDC_HOTKEY10,WM_USER+44,CustomKeys.SwitchControllers.key,CustomKeys.SwitchControllers.modifiers); SendDlgItemMessage(hDlg,IDC_HOTKEY11,WM_USER+44,CustomKeys.JoypadSwap.key,CustomKeys.JoypadSwap.modifiers); SendDlgItemMessage(hDlg,IDC_HOTKEY12,WM_USER+44,CustomKeys.ResetGame.key,CustomKeys.ResetGame.modifiers); SendDlgItemMessage(hDlg,IDC_HOTKEY13,WM_USER+44,CustomKeys.ToggleCheats.key,CustomKeys.ToggleCheats.modifiers); // SendDlgItemMessage(hDlg,IDC_HOTKEY12,WM_USER+44,CustomKeys.InterpMode7.key,CustomKeys.InterpMode7.modifiers); // SendDlgItemMessage(hDlg,IDC_HOTKEY13,WM_USER+44,CustomKeys.BGLHack.key,CustomKeys.BGLHack.modifiers); break; case 2: SendDlgItemMessage(hDlg,IDC_HOTKEY1,WM_USER+44,CustomKeys.TurboA.key,CustomKeys.TurboA.modifiers); SendDlgItemMessage(hDlg,IDC_HOTKEY2,WM_USER+44,CustomKeys.TurboB.key,CustomKeys.TurboB.modifiers); SendDlgItemMessage(hDlg,IDC_HOTKEY3,WM_USER+44,CustomKeys.TurboY.key,CustomKeys.TurboY.modifiers); SendDlgItemMessage(hDlg,IDC_HOTKEY4,WM_USER+44,CustomKeys.TurboX.key,CustomKeys.TurboX.modifiers); SendDlgItemMessage(hDlg,IDC_HOTKEY5,WM_USER+44,CustomKeys.TurboL.key,CustomKeys.TurboL.modifiers); SendDlgItemMessage(hDlg,IDC_HOTKEY6,WM_USER+44,CustomKeys.TurboR.key,CustomKeys.TurboR.modifiers); SendDlgItemMessage(hDlg,IDC_HOTKEY7,WM_USER+44,CustomKeys.TurboStart.key,CustomKeys.TurboStart.modifiers); SendDlgItemMessage(hDlg,IDC_HOTKEY8,WM_USER+44,CustomKeys.TurboSelect.key,CustomKeys.TurboSelect.modifiers); SendDlgItemMessage(hDlg,IDC_HOTKEY9,WM_USER+44,CustomKeys.TurboLeft.key,CustomKeys.TurboLeft.modifiers); SendDlgItemMessage(hDlg,IDC_HOTKEY10,WM_USER+44,CustomKeys.TurboUp.key,CustomKeys.TurboUp.modifiers); SendDlgItemMessage(hDlg,IDC_HOTKEY11,WM_USER+44,CustomKeys.TurboRight.key,CustomKeys.TurboRight.modifiers); SendDlgItemMessage(hDlg,IDC_HOTKEY12,WM_USER+44,CustomKeys.TurboDown.key,CustomKeys.TurboDown.modifiers); SendDlgItemMessage(hDlg,IDC_HOTKEY12,WM_USER+44,0,0); break; case 3: for(int i = 0 ; i < 10 ; i++) SendDlgItemMessage(hDlg,IDC_HOTKEY1+i,WM_USER+44,CustomKeys.SelectSave[i].key,CustomKeys.SelectSave[i].modifiers); SendDlgItemMessage(hDlg,IDC_HOTKEY11,WM_USER+44,0,0); SendDlgItemMessage(hDlg,IDC_HOTKEY12,WM_USER+44,0,0); SendDlgItemMessage(hDlg,IDC_HOTKEY13,WM_USER+44,0,0); break; } SendDlgItemMessage(hDlg,IDC_SLOTPLUS,WM_USER+44,CustomKeys.SlotPlus.key,CustomKeys.SlotPlus.modifiers); SendDlgItemMessage(hDlg,IDC_SLOTMINUS,WM_USER+44,CustomKeys.SlotMinus.key,CustomKeys.SlotMinus.modifiers); SendDlgItemMessage(hDlg,IDC_SLOTSAVE,WM_USER+44,CustomKeys.SlotSave.key,CustomKeys.SlotSave.modifiers); SendDlgItemMessage(hDlg,IDC_SLOTLOAD,WM_USER+44,CustomKeys.SlotLoad.key,CustomKeys.SlotLoad.modifiers); int i; for(i = 0 ; i < 10 ; i++) SendDlgItemMessage(hDlg,IDC_SAVE1+i,WM_USER+44,CustomKeys.Save[i].key,CustomKeys.Save[i].modifiers); for(i = 0 ; i < 10 ; i++) SendDlgItemMessage(hDlg,IDC_SAVE11+i,WM_USER+44,CustomKeys.Load[i].key,CustomKeys.Load[i].modifiers); switch(index) { case 0: // set page 1 label text SetDlgItemText(hDlg,IDC_LABEL_HK1,HOTKEYS_LABEL_1_1); SetDlgItemText(hDlg,IDC_LABEL_HK2,HOTKEYS_LABEL_1_2); SetDlgItemText(hDlg,IDC_LABEL_HK3,HOTKEYS_LABEL_1_3); SetDlgItemText(hDlg,IDC_LABEL_HK4,HOTKEYS_LABEL_1_4); SetDlgItemText(hDlg,IDC_LABEL_HK5,HOTKEYS_LABEL_1_5); SetDlgItemText(hDlg,IDC_LABEL_HK6,HOTKEYS_LABEL_1_6); SetDlgItemText(hDlg,IDC_LABEL_HK7,HOTKEYS_LABEL_1_7); SetDlgItemText(hDlg,IDC_LABEL_HK8,HOTKEYS_LABEL_1_8); SetDlgItemText(hDlg,IDC_LABEL_HK9,HOTKEYS_LABEL_1_9); SetDlgItemText(hDlg,IDC_LABEL_HK10,HOTKEYS_LABEL_1_10); SetDlgItemText(hDlg,IDC_LABEL_HK11,HOTKEYS_LABEL_1_11); SetDlgItemText(hDlg,IDC_LABEL_HK12,HOTKEYS_LABEL_1_12); SetDlgItemText(hDlg,IDC_LABEL_HK13,HOTKEYS_LABEL_1_13); break; case 1: SetDlgItemText(hDlg,IDC_LABEL_HK1,HOTKEYS_LABEL_2_1); SetDlgItemText(hDlg,IDC_LABEL_HK2,HOTKEYS_LABEL_2_2); SetDlgItemText(hDlg,IDC_LABEL_HK3,HOTKEYS_LABEL_2_3); SetDlgItemText(hDlg,IDC_LABEL_HK4,HOTKEYS_LABEL_2_4); SetDlgItemText(hDlg,IDC_LABEL_HK5,HOTKEYS_LABEL_2_5); SetDlgItemText(hDlg,IDC_LABEL_HK6,HOTKEYS_LABEL_2_6); SetDlgItemText(hDlg,IDC_LABEL_HK7,HOTKEYS_LABEL_2_7); SetDlgItemText(hDlg,IDC_LABEL_HK8,HOTKEYS_LABEL_2_8); SetDlgItemText(hDlg,IDC_LABEL_HK9,HOTKEYS_LABEL_2_9); SetDlgItemText(hDlg,IDC_LABEL_HK10,HOTKEYS_LABEL_2_10); SetDlgItemText(hDlg,IDC_LABEL_HK11,HOTKEYS_LABEL_2_11); SetDlgItemText(hDlg,IDC_LABEL_HK12,HOTKEYS_LABEL_2_12); SetDlgItemText(hDlg,IDC_LABEL_HK13,HOTKEYS_LABEL_2_13); break; case 2: SetDlgItemText(hDlg,IDC_LABEL_HK1,HOTKEYS_LABEL_3_1); SetDlgItemText(hDlg,IDC_LABEL_HK2,HOTKEYS_LABEL_3_2); SetDlgItemText(hDlg,IDC_LABEL_HK3,HOTKEYS_LABEL_3_3); SetDlgItemText(hDlg,IDC_LABEL_HK4,HOTKEYS_LABEL_3_4); SetDlgItemText(hDlg,IDC_LABEL_HK5,HOTKEYS_LABEL_3_5); SetDlgItemText(hDlg,IDC_LABEL_HK6,HOTKEYS_LABEL_3_6); SetDlgItemText(hDlg,IDC_LABEL_HK7,HOTKEYS_LABEL_3_7); SetDlgItemText(hDlg,IDC_LABEL_HK8,HOTKEYS_LABEL_3_8); SetDlgItemText(hDlg,IDC_LABEL_HK8,HOTKEYS_LABEL_3_8); SetDlgItemText(hDlg,IDC_LABEL_HK9,HOTKEYS_LABEL_3_9); SetDlgItemText(hDlg,IDC_LABEL_HK10,HOTKEYS_LABEL_3_10); SetDlgItemText(hDlg,IDC_LABEL_HK11,HOTKEYS_LABEL_3_11); SetDlgItemText(hDlg,IDC_LABEL_HK12,HOTKEYS_LABEL_3_12); SetDlgItemText(hDlg,IDC_LABEL_HK13,INPUTCONFIG_LABEL_UNUSED); break; case 3: for(int i = 0 ; i < 10 ; i++) { char temp [64]; sprintf(temp, "Select Slot %d", i); SetDlgItemText(hDlg,IDC_LABEL_HK1+i,temp); } for(int i = 10 ; i < 13 ; i++) SetDlgItemText(hDlg,IDC_LABEL_HK1+i,INPUTCONFIG_LABEL_UNUSED); break; } } // DlgHotkeyConfig int CALLBACK DlgHotkeyConfig(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam) { int i, which; static int index=0; static SCustomKeys keys; //HBRUSH g_hbrBackground; InitKeyCustomControl(); switch(msg) { case WM_PAINT: { PAINTSTRUCT ps; BeginPaint (hDlg, &ps); EndPaint (hDlg, &ps); } return true; case WM_INITDIALOG: if(DirectX.Clipped) S9xReRefresh(); SetWindowText(hDlg,HOTKEYS_TITLE); // insert hotkey page list items for(i=1 ; i <= 4 ; i++) { char temp[256]; sprintf(temp,HOTKEYS_HKCOMBO,i); SendDlgItemMessage(hDlg,IDC_HKCOMBO,CB_ADDSTRING,0,(LPARAM)(LPCTSTR)temp); } SendDlgItemMessage(hDlg,IDC_HKCOMBO,CB_SETCURSEL,(WPARAM)0,0); memcpy(&keys, &CustomKeys, sizeof(SCustomKeys)); for( i=0;i<256;i++) { GetAsyncKeyState(i); } SetDlgItemText(hDlg,IDC_LABEL_BLUE,HOTKEYS_LABEL_BLUE); set_hotkeyinfo(hDlg); PostMessage(hDlg,WM_COMMAND, CBN_SELCHANGE<<16, 0); SetFocus(GetDlgItem(hDlg,IDC_HKCOMBO)); return true; break; case WM_CLOSE: EndDialog(hDlg, 0); return TRUE; case WM_USER+46: // refresh command, for clicking away from a selected field index = SendDlgItemMessage(hDlg,IDC_HKCOMBO,CB_GETCURSEL,0,0); set_hotkeyinfo(hDlg); return TRUE; case WM_USER+43: { //MessageBox(hDlg,"USER+43 CAUGHT","moo",MB_OK); int modifiers = 0; if(GetAsyncKeyState(VK_MENU) || wParam == VK_MENU) modifiers |= CUSTKEY_ALT_MASK; if(GetAsyncKeyState(VK_CONTROL) || wParam == VK_CONTROL) modifiers |= CUSTKEY_CTRL_MASK; if(GetAsyncKeyState(VK_SHIFT) || wParam == VK_SHIFT) modifiers |= CUSTKEY_SHIFT_MASK; int index = SendDlgItemMessage(hDlg,IDC_HKCOMBO,CB_GETCURSEL,0,0); which = GetDlgCtrlID((HWND)lParam); switch(which) { case IDC_HOTKEY1: if(index == 0) CustomKeys.SpeedUp.key = wParam, CustomKeys.SpeedUp.modifiers = modifiers; if(index == 1) CustomKeys.BGL1.key = wParam, CustomKeys.BGL1.modifiers = modifiers; if(index == 2) CustomKeys.TurboA.key = wParam, CustomKeys.TurboA.modifiers = modifiers; if(index == 3) CustomKeys.SelectSave[0].key = wParam, CustomKeys.SelectSave[0].modifiers = modifiers; break; case IDC_HOTKEY2: if(index == 0) CustomKeys.SpeedDown.key = wParam, CustomKeys.SpeedDown.modifiers = modifiers; if(index == 1) CustomKeys.BGL2.key = wParam, CustomKeys.BGL2.modifiers = modifiers; if(index == 2) CustomKeys.TurboB.key = wParam, CustomKeys.TurboB.modifiers = modifiers; if(index == 3) CustomKeys.SelectSave[1].key = wParam, CustomKeys.SelectSave[1].modifiers = modifiers; break; case IDC_HOTKEY3: if(index == 0) CustomKeys.Pause.key = wParam, CustomKeys.Pause.modifiers = modifiers; if(index == 1) CustomKeys.BGL3.key = wParam, CustomKeys.BGL3.modifiers = modifiers; if(index == 2) CustomKeys.TurboY.key = wParam, CustomKeys.TurboY.modifiers = modifiers; if(index == 3) CustomKeys.SelectSave[2].key = wParam, CustomKeys.SelectSave[2].modifiers = modifiers; break; case IDC_HOTKEY4: if(index == 0) CustomKeys.FrameAdvance.key = wParam, CustomKeys.FrameAdvance.modifiers = modifiers; if(index == 1) CustomKeys.BGL4.key = wParam, CustomKeys.BGL4.modifiers = modifiers; if(index == 2) CustomKeys.TurboX.key = wParam, CustomKeys.TurboX.modifiers = modifiers; if(index == 3) CustomKeys.SelectSave[3].key = wParam, CustomKeys.SelectSave[3].modifiers = modifiers; break; case IDC_HOTKEY5: if(index == 0) CustomKeys.FastForward.key = wParam, CustomKeys.FastForward.modifiers = modifiers; if(index == 1) CustomKeys.BGL5.key = wParam, CustomKeys.BGL5.modifiers = modifiers; if(index == 2) CustomKeys.TurboL.key = wParam, CustomKeys.TurboL.modifiers = modifiers; if(index == 3) CustomKeys.SelectSave[4].key = wParam, CustomKeys.SelectSave[4].modifiers = modifiers; break; case IDC_HOTKEY6: if(index == 0) CustomKeys.SkipUp.key = wParam, CustomKeys.SkipUp.modifiers = modifiers; if(index == 1) CustomKeys.ClippingWindows.key = wParam, CustomKeys.ClippingWindows.modifiers = modifiers; if(index == 2) CustomKeys.TurboR.key = wParam, CustomKeys.TurboR.modifiers = modifiers; if(index == 3) CustomKeys.SelectSave[5].key = wParam, CustomKeys.SelectSave[5].modifiers = modifiers; break; case IDC_HOTKEY7: if(index == 0) CustomKeys.SkipDown.key = wParam, CustomKeys.SkipDown.modifiers = modifiers; if(index == 1) CustomKeys.Transparency.key = wParam, CustomKeys.Transparency.modifiers = modifiers; if(index == 2) CustomKeys.TurboStart.key = wParam, CustomKeys.TurboStart.modifiers = modifiers; if(index == 3) CustomKeys.SelectSave[6].key = wParam, CustomKeys.SelectSave[6].modifiers = modifiers; break; case IDC_HOTKEY8: if(index == 0) CustomKeys.ScopeTurbo.key = wParam, CustomKeys.ScopeTurbo.modifiers = modifiers; if(index == 1) CustomKeys.HDMA.key = wParam, CustomKeys.HDMA.modifiers = modifiers; if(index == 2) CustomKeys.TurboSelect.key = wParam, CustomKeys.TurboSelect.modifiers = modifiers; if(index == 3) CustomKeys.SelectSave[7].key = wParam, CustomKeys.SelectSave[7].modifiers = modifiers; break; case IDC_HOTKEY9: if(index == 0) CustomKeys.ScopePause.key = wParam, CustomKeys.ScopePause.modifiers = modifiers; if(index == 1) CustomKeys.GLCube.key = wParam, CustomKeys.GLCube.modifiers = modifiers; if(index == 2) CustomKeys.TurboLeft.key = wParam, CustomKeys.TurboLeft.modifiers = modifiers; if(index == 3) CustomKeys.SelectSave[8].key = wParam, CustomKeys.SelectSave[8].modifiers = modifiers; break; case IDC_HOTKEY10: if(index == 0) CustomKeys.ShowPressed.key = wParam, CustomKeys.ShowPressed.modifiers = modifiers; if(index == 1) CustomKeys.SwitchControllers.key = wParam, CustomKeys.SwitchControllers.modifiers = modifiers; if(index == 2) CustomKeys.TurboUp.key = wParam, CustomKeys.TurboUp.modifiers = modifiers; if(index == 3) CustomKeys.SelectSave[9].key = wParam, CustomKeys.SelectSave[9].modifiers = modifiers; break; case IDC_HOTKEY11: if(index == 0) CustomKeys.FrameCount.key = wParam, CustomKeys.FrameCount.modifiers = modifiers; if(index == 1) CustomKeys.JoypadSwap.key = wParam, CustomKeys.JoypadSwap.modifiers = modifiers; if(index == 2) CustomKeys.TurboRight.key = wParam, CustomKeys.TurboRight.modifiers = modifiers; break; case IDC_HOTKEY12: if(index == 0) CustomKeys.ReadOnly.key = wParam, CustomKeys.ReadOnly.modifiers = modifiers; if(index == 1) CustomKeys.ResetGame.key = wParam, CustomKeys.ResetGame.modifiers = modifiers; if(index == 2) CustomKeys.TurboDown.key = wParam, CustomKeys.TurboDown.modifiers = modifiers; // if(index == 3) CustomKeys.InterpMode7.key = wParam, CustomKeys.InterpMode7.modifiers = modifiers; break; case IDC_HOTKEY13: if(index == 0) CustomKeys.SaveScreenShot.key = wParam, CustomKeys.SaveScreenShot.modifiers = modifiers; if(index == 1) CustomKeys.ToggleCheats.key = wParam, CustomKeys.ToggleCheats.modifiers = modifiers; // if(index == 3) CustomKeys.BGLHack.key = wParam, CustomKeys.BGLHack.modifiers = modifiers; break; case IDC_SLOTPLUS: CustomKeys.SlotPlus.key = wParam; CustomKeys.SlotPlus.modifiers = modifiers; break; case IDC_SLOTMINUS: CustomKeys.SlotMinus.key = wParam; CustomKeys.SlotMinus.modifiers = modifiers; break; case IDC_SLOTLOAD: CustomKeys.SlotLoad.key = wParam; CustomKeys.SlotLoad.modifiers = modifiers; break; case IDC_SLOTSAVE: CustomKeys.SlotSave.key = wParam; CustomKeys.SlotSave.modifiers = modifiers; break; } if(which >= IDC_SAVE1 && which <= IDC_SAVE10) { CustomKeys.Save[which-IDC_SAVE1].key = wParam; CustomKeys.Save[which-IDC_SAVE1].modifiers = modifiers; } if(which >= IDC_SAVE11 && which <= IDC_SAVE20) { CustomKeys.Load[which-IDC_SAVE11].key = wParam; CustomKeys.Load[which-IDC_SAVE11].modifiers = modifiers; } set_hotkeyinfo(hDlg); PostMessage(hDlg,WM_NEXTDLGCTL,0,0); // PostMessage(hDlg,WM_KILLFOCUS,0,0); } return true; case WM_COMMAND: switch(LOWORD(wParam)) { case IDCANCEL: memcpy(&CustomKeys, &keys, sizeof(SCustomKeys)); EndDialog(hDlg,0); break; case IDOK: WinSaveConfigFile(); EndDialog(hDlg,0); break; } switch(HIWORD(wParam)) { case CBN_SELCHANGE: index = SendDlgItemMessage(hDlg,IDC_HKCOMBO,CB_GETCURSEL,0,0); SendDlgItemMessage(hDlg,IDC_HKCOMBO,CB_SETCURSEL,(WPARAM)index,0); set_hotkeyinfo(hDlg); SetFocus(GetDlgItem(hDlg,IDC_HKCOMBO)); break; } return FALSE; } return FALSE; } template int ScanAddress(const char* str, IntType& value) { int ret = 0; if(tolower(*str) == 's') { ret = sscanf(str+1, "%x", &value); value += 0x7E0000 + 0x20000; } else if(tolower(*str) == 'i') { ret = sscanf(str+1, "%x", &value); value += 0x7E0000 + 0x30000; } else { int plus = (*str == '0' && tolower(str[1]) == 'x') ? 2 : 0; ret = sscanf(str+plus, "%x", &value); } return ret; } enum CheatStatus{ Untouched, Deleted, Modified }; typedef struct{ int* index; DWORD* state; }CheatTracker; #define ITEM_QUERY(a, b, c, d, e) ZeroMemory(&a, sizeof(LV_ITEM)); \ a.iItem= ListView_GetSelectionMark(GetDlgItem(hDlg, b)); \ a.iSubItem=c; \ a.mask=LVIF_TEXT; \ a.pszText=d; \ a.cchTextMax=e; \ ListView_GetItem(GetDlgItem(hDlg, b), &a); int CALLBACK DlgCheater(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam) { static HBITMAP hBmp; static bool internal_change; static bool has_sel; static int sel_idx; static uint8 new_sel; static CheatTracker ct; switch(msg) { case WM_INITDIALOG: if(DirectX.Clipped) S9xReRefresh(); hBmp=(HBITMAP)LoadImage(NULL, TEXT("funkyass.bmp"), IMAGE_BITMAP, 0,0, LR_CREATEDIBSECTION | LR_LOADFROMFILE); ListView_SetExtendedListViewStyle(GetDlgItem(hDlg, IDC_CHEAT_LIST), LVS_EX_FULLROWSELECT|LVS_EX_CHECKBOXES); SendDlgItemMessage(hDlg, IDC_CHEAT_CODE, EM_LIMITTEXT, 14, 0); SendDlgItemMessage(hDlg, IDC_CHEAT_DESCRIPTION, EM_LIMITTEXT, 22, 0); SendDlgItemMessage(hDlg, IDC_CHEAT_ADDRESS, EM_LIMITTEXT, 6, 0); SendDlgItemMessage(hDlg, IDC_CHEAT_BYTE, EM_LIMITTEXT, 3, 0); LVCOLUMN col; char temp[32]; strcpy(temp,SEARCH_COLUMN_ADDRESS); ZeroMemory(&col, sizeof(LVCOLUMN)); col.mask=LVCF_FMT|LVCF_ORDER|LVCF_TEXT|LVCF_WIDTH; col.fmt=LVCFMT_LEFT; col.iOrder=0; col.cx=70; col.cchTextMax=7; col.pszText=temp; ListView_InsertColumn(GetDlgItem(hDlg,IDC_CHEAT_LIST), 0, &col); strcpy(temp,SEARCH_COLUMN_VALUE); ZeroMemory(&col, sizeof(LVCOLUMN)); col.mask=LVCF_FMT|LVCF_ORDER|LVCF_TEXT|LVCF_WIDTH|LVCF_SUBITEM; col.fmt=LVCFMT_LEFT; col.iOrder=1; col.cx=43; col.cchTextMax=3; col.pszText=temp; col.iSubItem=1; ListView_InsertColumn(GetDlgItem(hDlg,IDC_CHEAT_LIST), 1, &col); strcpy(temp,SEARCH_COLUMN_DESCRIPTION); ZeroMemory(&col, sizeof(LVCOLUMN)); col.mask=LVCF_FMT|LVCF_ORDER|LVCF_TEXT|LVCF_WIDTH|LVCF_SUBITEM; col.fmt=LVCFMT_LEFT; col.iOrder=2; col.cx=165; col.cchTextMax=32; col.pszText=temp; col.iSubItem=2; ListView_InsertColumn(GetDlgItem(hDlg,IDC_CHEAT_LIST), 2, &col); ct.index=new int[Cheat.num_cheats]; ct.state=new DWORD[Cheat.num_cheats]; uint32 counter; for(counter=0; counter=curr_idx) ct.index[k]++; } ct.index[counter]=curr_idx; ct.state[counter]=Untouched; sprintf(buffer, "%02X", Cheat.c[counter].byte); ZeroMemory(&lvi, sizeof(LVITEM)); lvi.iItem=curr_idx; lvi.iSubItem=1; lvi.mask=LVIF_TEXT; lvi.pszText=buffer; lvi.cchTextMax=3; SendDlgItemMessage(hDlg,IDC_CHEAT_LIST, LVM_SETITEM, 0, (LPARAM)&lvi); ZeroMemory(&lvi, sizeof(LVITEM)); lvi.iItem=curr_idx; lvi.iSubItem=2; lvi.mask=LVIF_TEXT; lvi.pszText=Cheat.c[counter].name; lvi.cchTextMax=23; SendDlgItemMessage(hDlg,IDC_CHEAT_LIST, LVM_SETITEM, 0, (LPARAM)&lvi); ListView_SetCheckState(GetDlgItem(hDlg,IDC_CHEAT_LIST), curr_idx, Cheat.c[counter].enabled); } return true; case WM_PAINT: { PAINTSTRUCT ps; BeginPaint (hDlg, &ps); if(hBmp) { BITMAP bmp; ZeroMemory(&bmp, sizeof(BITMAP)); RECT r; GetClientRect(hDlg, &r); HDC hdc=GetDC(hDlg); HDC hDCbmp=CreateCompatibleDC(hdc); GetObject(hBmp, sizeof(BITMAP), &bmp); HBITMAP hOldBmp=(HBITMAP)SelectObject(hDCbmp, hBmp); StretchBlt(hdc, 0,0,r.right,r.bottom,hDCbmp,0,0,bmp.bmWidth,bmp.bmHeight,SRCCOPY); SelectObject(hDCbmp, hOldBmp); DeleteDC(hDCbmp); ReleaseDC(hDlg, hdc); } EndPaint (hDlg, &ps); } return true; case WM_NOTIFY: { switch(LOWORD(wParam)) { case IDC_CHEAT_LIST: if(0==ListView_GetSelectedCount(GetDlgItem(hDlg, IDC_CHEAT_LIST))) { EnableWindow(GetDlgItem(hDlg, IDC_DELETE_CHEAT), false); EnableWindow(GetDlgItem(hDlg, IDC_UPDATE_CHEAT), false); has_sel=false; sel_idx=-1; } else { EnableWindow(GetDlgItem(hDlg, IDC_DELETE_CHEAT), true); if(!has_sel||sel_idx!=ListView_GetSelectionMark(GetDlgItem(hDlg, IDC_CHEAT_LIST))) { new_sel=3; //change char buf[25]; LV_ITEM lvi; ITEM_QUERY (lvi, IDC_CHEAT_LIST, 0, buf, 7); SetDlgItemText(hDlg, IDC_CHEAT_ADDRESS, lvi.pszText); ITEM_QUERY (lvi, IDC_CHEAT_LIST, 1, &buf[strlen(buf)], 3); SetDlgItemText(hDlg, IDC_CHEAT_CODE, buf); char temp[4]; int q; sscanf(lvi.pszText, "%02X", &q); sprintf(temp, "%d", q); SetDlgItemText(hDlg, IDC_CHEAT_BYTE, temp); ITEM_QUERY (lvi, IDC_CHEAT_LIST, 2, buf, 24); internal_change=true; SetDlgItemText(hDlg, IDC_CHEAT_DESCRIPTION, lvi.pszText); } sel_idx=ListView_GetSelectionMark(GetDlgItem(hDlg, IDC_CHEAT_LIST)); has_sel=true; } return true; default: return false; } } case WM_COMMAND: { switch(LOWORD(wParam)) { case IDC_CHEAT_DESCRIPTION: { switch(HIWORD(wParam)) { case EN_CHANGE: if(internal_change) { internal_change=!internal_change; return false; } if(!has_sel) return true; EnableWindow(GetDlgItem(hDlg, IDC_UPDATE_CHEAT), true); return true; } break; } case IDC_ADD_CHEAT: { char temp[24]; GetDlgItemText(hDlg, IDC_CHEAT_CODE, temp, 23); if(strcmp(temp, "")) { int j; bool skip=false; int count=1; uint32 addy; uint8 byte[3]; //test game genie if (NULL==S9xGameGenieToRaw (temp, addy, byte[0])) skip=true; //test goldfinger // if(!skip //test PAR if(!skip) { if(NULL==S9xProActionReplayToRaw(temp, addy, byte[0])) skip=true; } if(!skip) return 0; for(j=0; j=curr_idx) ct.index[k]++; } sprintf(buffer, "%02X", byte[j]); ZeroMemory(&lvi, sizeof(LVITEM)); lvi.iItem=curr_idx; lvi.iSubItem=1; lvi.mask=LVIF_TEXT; lvi.pszText=buffer; lvi.cchTextMax=2; SendDlgItemMessage(hDlg,IDC_CHEAT_LIST, LVM_SETITEM, 0, (LPARAM)&lvi); GetDlgItemText(hDlg, IDC_CHEAT_DESCRIPTION, temp, 23); ZeroMemory(&lvi, sizeof(LVITEM)); lvi.iItem=curr_idx; lvi.iSubItem=2; lvi.mask=LVIF_TEXT; lvi.pszText=temp; lvi.cchTextMax=23; SendDlgItemMessage(hDlg,IDC_CHEAT_LIST, LVM_SETITEM, 0, (LPARAM)&lvi); addy++; } } else { uint8 byte; char buffer[7]; char buffer2[7]; GetDlgItemText(hDlg, IDC_CHEAT_ADDRESS, buffer, 7); GetDlgItemText(hDlg, IDC_CHEAT_BYTE, buffer2, 7); int curr_idx=-1; LVITEM lvi; ZeroMemory(&lvi, sizeof(LVITEM)); lvi.mask=LVIF_TEXT; lvi.pszText=buffer; lvi.cchTextMax=6; lvi.iItem=0; curr_idx=ListView_InsertItem(GetDlgItem(hDlg,IDC_CHEAT_LIST), &lvi); int scanres; if(buffer2[0]=='$') sscanf(buffer2,"$%2X", (unsigned int*)&scanres); else sscanf(buffer2,"%d", &scanres); byte = (uint8)(scanres & 0xff); sprintf(buffer2, "%02X", byte); ZeroMemory(&lvi, sizeof(LVITEM)); lvi.iItem=curr_idx; lvi.iSubItem=1; lvi.mask=LVIF_TEXT; lvi.pszText=buffer2; lvi.cchTextMax=2; SendDlgItemMessage(hDlg,IDC_CHEAT_LIST, LVM_SETITEM, 0, (LPARAM)&lvi); GetDlgItemText(hDlg, IDC_CHEAT_DESCRIPTION, temp, 23); ZeroMemory(&lvi, sizeof(LVITEM)); lvi.iItem=curr_idx; lvi.iSubItem=2; lvi.mask=LVIF_TEXT; lvi.pszText=temp; lvi.cchTextMax=23; SendDlgItemMessage(hDlg,IDC_CHEAT_LIST, LVM_SETITEM, 0, (LPARAM)&lvi); } } break; case IDC_UPDATE_CHEAT: { char temp[24]; GetDlgItemText(hDlg, IDC_CHEAT_CODE, temp, 23); if(strcmp(temp, "")) { int j; bool skip=false; int count=1; uint32 addy; uint8 byte[3]; //test game genie if (NULL==S9xGameGenieToRaw (temp, addy, byte[0])) skip=true; //test goldfinger // if(!skip //test PAR if(!skip) { if(NULL==S9xProActionReplayToRaw(temp, addy, byte[0])) skip=true; } if(!skip) return 0; for(j=0;j<(int)Cheat.num_cheats;j++) { if(ct.index[j]==sel_idx) ct.state[j]=Modified; } for(j=0; jsel_idx) ct.index[j]--; } } ListView_DeleteItem(GetDlgItem(hDlg, IDC_CHEAT_LIST), sel_idx); break; case IDC_CLEAR_CHEATS: internal_change = true; SetDlgItemText(hDlg,IDC_CHEAT_CODE,""); SetDlgItemText(hDlg,IDC_CHEAT_ADDRESS,""); SetDlgItemText(hDlg,IDC_CHEAT_BYTE,""); SetDlgItemText(hDlg,IDC_CHEAT_DESCRIPTION,""); ListView_SetItemState(GetDlgItem(hDlg, IDC_CHEAT_LIST),sel_idx, 0, LVIS_SELECTED|LVIS_FOCUSED); ListView_SetSelectionMark(GetDlgItem(hDlg, IDC_CHEAT_LIST), -1); sel_idx=-1; has_sel=false; break; case IDC_CHEAT_CODE: { uint32 j, k; long index; char buffer[15]; char buffer2[15]; POINT point; switch(HIWORD(wParam)) { case EN_CHANGE: if(internal_change) { internal_change=false; return true; } SendMessage((HWND)lParam, WM_GETTEXT, 15,(LPARAM)buffer); GetCaretPos(&point); index = SendMessage((HWND)lParam,(UINT) EM_CHARFROMPOS, 0, (LPARAM) ((point.x&0x0000FFFF) | (((point.y&0x0000FFFF))<<16))); k=0; for(j=0; j='0' && buffer[j]<='9') || (buffer[j]>='A' && buffer[j]<='F') || buffer[j]=='-' || buffer[j]=='X') { buffer2[k]=buffer[j]; k++; } else index --; } buffer2[k]='\0'; if(has_sel&&!new_sel&&strlen(buffer2)!=0) { SetDlgItemText(hDlg, IDC_CHEAT_ADDRESS, ""); SetDlgItemText(hDlg, IDC_CHEAT_BYTE, ""); } if(new_sel!=0) new_sel--; internal_change=true; SendMessage((HWND)lParam, WM_SETTEXT, 0,(LPARAM)buffer2); SendMessage((HWND)lParam, (UINT) EM_SETSEL, (WPARAM) (index), index); uint32 addy; uint8 val; bool8 sram; uint8 bytes[3]; if(NULL==S9xGameGenieToRaw(buffer2, addy, val)||NULL==S9xProActionReplayToRaw(buffer2, addy, val)||NULL==S9xGoldFingerToRaw(buffer2, addy, sram, val, bytes)) { if(has_sel) EnableWindow(GetDlgItem(hDlg, IDC_UPDATE_CHEAT), true); else EnableWindow(GetDlgItem(hDlg, IDC_UPDATE_CHEAT), false); EnableWindow(GetDlgItem(hDlg, IDC_ADD_CHEAT), true); } else { EnableWindow(GetDlgItem(hDlg, IDC_ADD_CHEAT), false); EnableWindow(GetDlgItem(hDlg, IDC_UPDATE_CHEAT), false); } // SetDlgItemText(hDlg, IDC_CHEAT_ADDRESS, ""); // SetDlgItemText(hDlg, IDC_CHEAT_BYTE, ""); break; } break; } case IDC_CHEAT_ADDRESS: { uint32 j, k; long index; char buffer[7]; char buffer2[7]; POINT point; switch(HIWORD(wParam)) { case EN_CHANGE: if(internal_change) { internal_change=false; return true; } SendMessage((HWND)lParam, WM_GETTEXT, 7,(LPARAM)buffer); GetCaretPos(&point); index = SendMessage((HWND)lParam,(UINT) EM_CHARFROMPOS, 0, (LPARAM) ((point.x&0x0000FFFF) | (((point.y&0x0000FFFF))<<16))); k=0; for(j=0; j='0' && buffer[j]<='9') || (buffer[j]>='A' && buffer[j]<='F')) { buffer2[k]=buffer[j]; k++; } else index --; } buffer2[k]='\0'; internal_change=true; SendMessage((HWND)lParam, WM_SETTEXT, 0,(LPARAM)buffer2); SendMessage((HWND)lParam, (UINT) EM_SETSEL, (WPARAM) (index), index); SendMessage(GetDlgItem(hDlg, IDC_CHEAT_BYTE), WM_GETTEXT, 4,(LPARAM)buffer); if(has_sel&&!new_sel&&0!=strlen(buffer2)) SetDlgItemText(hDlg, IDC_CHEAT_CODE, ""); if(new_sel!=0) new_sel--; if(strlen(buffer2)!=0 && strlen(buffer) !=0) { if(has_sel) EnableWindow(GetDlgItem(hDlg, IDC_UPDATE_CHEAT), true); else EnableWindow(GetDlgItem(hDlg, IDC_UPDATE_CHEAT), false); EnableWindow(GetDlgItem(hDlg, IDC_ADD_CHEAT), true); } else { EnableWindow(GetDlgItem(hDlg, IDC_ADD_CHEAT), false); EnableWindow(GetDlgItem(hDlg, IDC_UPDATE_CHEAT), false); } break; } break; } case IDC_CHEAT_BYTE: { uint32 j, k; long index; char buffer[4]; char buffer2[4]; POINT point; switch(HIWORD(wParam)) { case EN_CHANGE: if(internal_change) { internal_change=false; return true; } SendMessage((HWND)lParam, WM_GETTEXT, 4,(LPARAM)buffer); GetCaretPos(&point); index = SendMessage((HWND)lParam,(UINT) EM_CHARFROMPOS, 0, (LPARAM) ((point.x&0x0000FFFF) | (((point.y&0x0000FFFF))<<16))); k=0; for(j=0; j='0' && buffer[j]<='9') || (buffer[j]>='A' && buffer[j]<='F') || buffer[j]=='$') { buffer2[k]=buffer[j]; k++; } else index --; } buffer2[k]='\0'; if(has_sel&&!new_sel&&0!=strlen(buffer2)) SetDlgItemText(hDlg, IDC_CHEAT_CODE, ""); if(new_sel!=0) new_sel--; internal_change=true; SendMessage((HWND)lParam, WM_SETTEXT, 0,(LPARAM)buffer2); SendMessage((HWND)lParam, (UINT) EM_SETSEL, (WPARAM) (index), index); SendMessage(GetDlgItem(hDlg, IDC_CHEAT_ADDRESS), WM_GETTEXT, 7,(LPARAM)buffer); if(strlen(buffer2)!=0 && strlen(buffer) !=0) { if(has_sel) EnableWindow(GetDlgItem(hDlg, IDC_UPDATE_CHEAT), true); else EnableWindow(GetDlgItem(hDlg, IDC_UPDATE_CHEAT), false); EnableWindow(GetDlgItem(hDlg, IDC_ADD_CHEAT), true); } else { EnableWindow(GetDlgItem(hDlg, IDC_ADD_CHEAT), false); EnableWindow(GetDlgItem(hDlg, IDC_UPDATE_CHEAT), false); } //SetDlgItemText(hDlg, IDC_CHEAT_CODE, ""); break; } break; } case IDOK: { int k,l; bool hit; unsigned int scanned; for(k=0;k=0;l--) { if(ct.state[l]==Deleted) { S9xDeleteCheat(l); } } } case IDCANCEL: delete [] ct.index; delete [] ct.state; EndDialog(hDlg, 0); if(hBmp) { DeleteObject(hBmp); hBmp=NULL; } return true; default:return false; } } default: return false; } } #define TEST_BIT(a,v) \ ((a)[(v) >> 5] & (1 << ((v) & 31))) static inline int CheatCount(int byteSub) { int a, b=0; // for(a=0;a<0x32000-byteSub;a++) for(a=0;a<0x30000-byteSub;a++) // hide IRAM from cheat dialog (it seems not to be searhed correctly) { if(TEST_BIT(Cheat.ALL_BITS, a)) b++; } return b; } struct ICheat { uint32 address; uint32 new_val; uint32 saved_val; int size; bool8 enabled; bool8 saved; char name [22]; int format; }; bool TestRange(int val_type, S9xCheatDataSize bytes, uint32 value) { if(val_type!=2) { if(bytes==S9X_8_BITS) { if(value<256) return true; else return false; } if(bytes==S9X_16_BITS) { if(value<65536) return true; else return false; } if(bytes==S9X_24_BITS) { if(value<16777216) return true; else return false; } //if it reads in, it's a valid 32-bit unsigned! return true; } else { if(bytes==S9X_8_BITS) { if((int32)value<128 && (int32)value >= -128) return true; else return false; } if(bytes==S9X_16_BITS) { if((int32)value<32768 && (int32)value >= -32768) return true; else return false; } if(bytes==S9X_24_BITS) { if((int32)value<8388608 && (int32)value >= -8388608) return true; else return false; } //should be handled by sscanf return true; } } int CALLBACK DlgCheatSearch(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam) { static HBITMAP hBmp; static S9xCheatDataSize bytes; static int val_type; static int use_entered; static S9xCheatComparisonType comp_type; switch(msg) { case WM_INITDIALOG: { if(DirectX.Clipped) S9xReRefresh(); if(val_type==0) val_type=1; hBmp=(HBITMAP)LoadImage(NULL, TEXT("Raptor.bmp"), IMAGE_BITMAP, 0,0, LR_CREATEDIBSECTION | LR_LOADFROMFILE); ListView_SetExtendedListViewStyle(GetDlgItem(hDlg, IDC_ADDYS), LVS_EX_FULLROWSELECT); //defaults SendDlgItemMessage(hDlg, IDC_LESS_THAN, BM_SETCHECK, BST_CHECKED, 0); if(!use_entered) SendDlgItemMessage(hDlg, IDC_PREV, BM_SETCHECK, BST_CHECKED, 0); else if(use_entered==1) { SendDlgItemMessage(hDlg, IDC_ENTERED, BM_SETCHECK, BST_CHECKED, 0); EnableWindow(GetDlgItem(hDlg, IDC_VALUE_ENTER), true); EnableWindow(GetDlgItem(hDlg, IDC_ENTER_LABEL), true); } else if(use_entered==2) { SendDlgItemMessage(hDlg, IDC_ENTEREDADDRESS, BM_SETCHECK, BST_CHECKED, 0); EnableWindow(GetDlgItem(hDlg, IDC_VALUE_ENTER), true); EnableWindow(GetDlgItem(hDlg, IDC_ENTER_LABEL), true); } SendDlgItemMessage(hDlg, IDC_UNSIGNED, BM_SETCHECK, BST_CHECKED, 0); SendDlgItemMessage(hDlg, IDC_1_BYTE, BM_SETCHECK, BST_CHECKED, 0); if(comp_type==S9X_GREATER_THAN) { SendDlgItemMessage(hDlg, IDC_LESS_THAN, BM_SETCHECK, BST_UNCHECKED, 0); SendDlgItemMessage(hDlg, IDC_GREATER_THAN, BM_SETCHECK, BST_CHECKED, 0); } else if(comp_type==S9X_LESS_THAN_OR_EQUAL) { SendDlgItemMessage(hDlg, IDC_LESS_THAN, BM_SETCHECK, BST_UNCHECKED, 0); SendDlgItemMessage(hDlg, IDC_LESS_THAN_EQUAL, BM_SETCHECK, BST_CHECKED, 0); } else if(comp_type==S9X_GREATER_THAN_OR_EQUAL) { SendDlgItemMessage(hDlg, IDC_LESS_THAN, BM_SETCHECK, BST_UNCHECKED, 0); SendDlgItemMessage(hDlg, IDC_GREATER_THAN_EQUAL, BM_SETCHECK, BST_CHECKED, 0); } else if(comp_type==S9X_EQUAL) { SendDlgItemMessage(hDlg, IDC_LESS_THAN, BM_SETCHECK, BST_UNCHECKED, 0); SendDlgItemMessage(hDlg, IDC_EQUAL, BM_SETCHECK, BST_CHECKED, 0); } else if(comp_type==S9X_NOT_EQUAL) { SendDlgItemMessage(hDlg, IDC_LESS_THAN, BM_SETCHECK, BST_UNCHECKED, 0); SendDlgItemMessage(hDlg, IDC_NOT_EQUAL, BM_SETCHECK, BST_CHECKED, 0); } if(val_type==2) { SendDlgItemMessage(hDlg, IDC_UNSIGNED, BM_SETCHECK, BST_UNCHECKED, 0); SendDlgItemMessage(hDlg, IDC_SIGNED, BM_SETCHECK, BST_CHECKED, 0); } else if(val_type==3) { SendDlgItemMessage(hDlg, IDC_UNSIGNED, BM_SETCHECK, BST_UNCHECKED, 0); SendDlgItemMessage(hDlg, IDC_HEX, BM_SETCHECK, BST_CHECKED, 0); } if(bytes==S9X_16_BITS) { SendDlgItemMessage(hDlg, IDC_1_BYTE, BM_SETCHECK, BST_UNCHECKED, 0); SendDlgItemMessage(hDlg, IDC_2_BYTE, BM_SETCHECK, BST_CHECKED, 0); } else if(bytes==S9X_24_BITS) { SendDlgItemMessage(hDlg, IDC_1_BYTE, BM_SETCHECK, BST_UNCHECKED, 0); SendDlgItemMessage(hDlg, IDC_3_BYTE, BM_SETCHECK, BST_CHECKED, 0); } else if(bytes==S9X_32_BITS) { SendDlgItemMessage(hDlg, IDC_1_BYTE, BM_SETCHECK, BST_UNCHECKED, 0); SendDlgItemMessage(hDlg, IDC_4_BYTE, BM_SETCHECK, BST_CHECKED, 0); } LVCOLUMN col; char temp[32]; strcpy(temp,"Address"); ZeroMemory(&col, sizeof(LVCOLUMN)); col.mask=LVCF_FMT|LVCF_ORDER|LVCF_TEXT|LVCF_WIDTH; col.fmt=LVCFMT_LEFT; col.iOrder=0; col.cx=70; col.cchTextMax=7; col.pszText=temp; ListView_InsertColumn(GetDlgItem(hDlg,IDC_ADDYS), 0, &col); strcpy(temp,"Curr. Value"); ZeroMemory(&col, sizeof(LVCOLUMN)); col.mask=LVCF_FMT|LVCF_ORDER|LVCF_TEXT|LVCF_WIDTH|LVCF_SUBITEM; col.fmt=LVCFMT_LEFT; col.iOrder=1; col.cx=104; col.cchTextMax=3; col.pszText=temp; col.iSubItem=1; ListView_InsertColumn(GetDlgItem(hDlg,IDC_ADDYS), 1, &col); strcpy(temp,"Prev. Value"); ZeroMemory(&col, sizeof(LVCOLUMN)); col.mask=LVCF_FMT|LVCF_ORDER|LVCF_TEXT|LVCF_WIDTH|LVCF_SUBITEM; col.fmt=LVCFMT_LEFT; col.iOrder=2; col.cx=104; col.cchTextMax=32; col.pszText=temp; col.iSubItem=2; ListView_InsertColumn(GetDlgItem(hDlg,IDC_ADDYS), 2, &col); { int l = CheatCount(bytes); ListView_SetItemCount (GetDlgItem(hDlg, IDC_ADDYS), l); } } return true; case WM_DESTROY: { cheatSearchHWND = NULL; S9xSaveCheatFile (S9xGetFilename (".cht", CHEAT_DIR)); break; } case WM_PAINT: { PAINTSTRUCT ps; BeginPaint (hDlg, &ps); if(hBmp) { BITMAP bmp; ZeroMemory(&bmp, sizeof(BITMAP)); RECT r; GetClientRect(hDlg, &r); HDC hdc=GetDC(hDlg); HDC hDCbmp=CreateCompatibleDC(hdc); GetObject(hBmp, sizeof(BITMAP), &bmp); HBITMAP hOldBmp=(HBITMAP)SelectObject(hDCbmp, hBmp); StretchBlt(hdc, 0,0,r.right,r.bottom,hDCbmp,0,0,bmp.bmWidth,bmp.bmHeight,SRCCOPY); SelectObject(hDCbmp, hOldBmp); DeleteDC(hDCbmp); ReleaseDC(hDlg, hdc); } EndPaint (hDlg, &ps); } return true; case WM_NOTIFY: { static int selectionMarkOverride = -1; static int foundItemOverride = -1; if(wParam == IDC_ADDYS) { NMHDR * nmh=(NMHDR*)lParam; if(nmh->hwndFrom == GetDlgItem(hDlg, IDC_ADDYS) && nmh->code == LVN_GETDISPINFO) { static TCHAR buf[12]; // the following code assumes this variable is static int i, j; NMLVDISPINFO * nmlvdi=(NMLVDISPINFO*)lParam; j=nmlvdi->item.iItem; j++; for(i=0;i<(0x32000-bytes)&& j>0;i++) { if(TEST_BIT(Cheat.ALL_BITS, i)) j--; } if (i>=0x32000 && j!=0) { return false; } i--; if(j=nmlvdi->item.iSubItem==0) { if(i < 0x20000) sprintf(buf, "%06X", i+0x7E0000); else if(i < 0x30000) sprintf(buf, "s%05X", i-0x20000); else sprintf(buf, "i%05X", i-0x30000); nmlvdi->item.pszText=buf; nmlvdi->item.cchTextMax=8; } if(j=nmlvdi->item.iSubItem==1) { int q=0, r=0; if(i < 0x20000) for(r=0;r<=bytes;r++) q+=(Cheat.RAM[i+r])<<(8*r); else if(i < 0x30000) for(r=0;r<=bytes;r++) q+=(Cheat.SRAM[(i-0x20000)+r])<<(8*r); else for(r=0;r<=bytes;r++) q+=(Cheat.FillRAM[(i-0x30000)+r])<<(8*r); //needs to account for size switch(val_type) { case 1: sprintf(buf, "%u", q); break; case 3: { switch(bytes) { default: case S9X_8_BITS:sprintf(buf, "%02X", q&0xFF);break; case S9X_16_BITS: sprintf(buf, "%04X", q&0xFFFF); break; case S9X_24_BITS: sprintf(buf, "%06X", q&0xFFFFFF);break; case S9X_32_BITS: sprintf(buf, "%08X", q);break; } } break; case 2: default: switch(bytes) { default: case S9X_8_BITS: if((q-128)<0) sprintf(buf, "%d", q&0xFF); else sprintf(buf, "%d", q-256); break; case S9X_16_BITS: if((q-32768)<0) sprintf(buf, "%d", q&0xFFFF); else sprintf(buf, "%d", q-65536); break; case S9X_24_BITS: if((q-0x800000)<0) sprintf(buf, "%d", q&0xFFFFFF); else sprintf(buf, "%d", q-0x1000000); break; case S9X_32_BITS: sprintf(buf, "%d", q);break; } break; } nmlvdi->item.pszText=buf; nmlvdi->item.cchTextMax=4; } if(j=nmlvdi->item.iSubItem==2) { int q=0, r=0; if(i < 0x20000) for(r=0;r<=bytes;r++) q+=(Cheat.CWRAM[i+r])<<(8*r); else if(i < 0x30000) for(r=0;r<=bytes;r++) q+=(Cheat.CSRAM[(i-0x20000)+r])<<(8*r); else for(r=0;r<=bytes;r++) q+=(Cheat.CIRAM[(i-0x30000)+r])<<(8*r); //needs to account for size switch(val_type) { case 1: sprintf(buf, "%u", q); break; case 3: { switch(bytes) { default: case S9X_8_BITS:sprintf(buf, "%02X", q&0xFF);break; case S9X_16_BITS: sprintf(buf, "%04X", q&0xFFFF); break; case S9X_24_BITS: sprintf(buf, "%06X", q&0xFFFFFF);break; case S9X_32_BITS: sprintf(buf, "%08X", q);break; } break; } case 2: default: switch(bytes) { default: case S9X_8_BITS: if((q-128)<0) sprintf(buf, "%d", q&0xFF); else sprintf(buf, "%d", q-256); break; case S9X_16_BITS: if((q-32768)<0) sprintf(buf, "%d", q&0xFFFF); else sprintf(buf, "%d", q-65536); break; case S9X_24_BITS: if((q-0x800000)<0) sprintf(buf, "%d", q&0xFFFFFF); else sprintf(buf, "%d", q-0x1000000); break; case S9X_32_BITS: sprintf(buf, "%d", q);break; } break; } nmlvdi->item.pszText=buf; nmlvdi->item.cchTextMax=4; } // nmlvdi->item.mask=LVIF_TEXT; // This is bad as wine relies on this to not change. } else if(nmh->hwndFrom == GetDlgItem(hDlg, IDC_ADDYS) && (nmh->code == (UINT)LVN_ITEMACTIVATE||nmh->code == (UINT)NM_CLICK)) { bool enable=true; if(-1==ListView_GetSelectionMark(nmh->hwndFrom)) { enable=false; } EnableWindow(GetDlgItem(hDlg, IDC_C_ADD), enable); } // allow typing in an address to jump to it else if(nmh->hwndFrom == GetDlgItem(hDlg, IDC_ADDYS) && nmh->code == (UINT)LVN_ODFINDITEM) { LRESULT pResult; // pNMHDR has information about the item we should find // In pResult we should save which item that should be selected NMLVFINDITEM* pFindInfo = (NMLVFINDITEM*)lParam; /* pFindInfo->iStart is from which item we should search. We search to bottom, and then restart at top and will stop at pFindInfo->iStart, unless we find an item that match */ // Set the default return value to -1 // That means we didn't find any match. pResult = -1; //Is search NOT based on string? if( (pFindInfo->lvfi.flags & LVFI_STRING) == 0 ) { //This will probably never happend... return pResult; } //This is the string we search for LPCSTR searchstr = pFindInfo->lvfi.psz; int startPos = pFindInfo->iStart; //Is startPos outside the list (happens if last item is selected) if(startPos >= ListView_GetItemCount(GetDlgItem(hDlg,IDC_ADDYS))) startPos = 0; int currentPos, addrPos; for(addrPos=0,currentPos=0;addrPos<(0x32000-bytes)&¤tPos=0x32000 && addrPos!=0) break; // ignore leading 0's while(searchstr[0] == '0' && searchstr[1] != '\0') searchstr++; int searchNum = 0; ScanAddress(searchstr, searchNum); // if (searchstr[0] != '7') // break; // all searchable addresses begin with a 7 bool looped = false; // perform search do { if(addrPos == searchNum) { // select this item and stop search pResult = currentPos; break; } else if(addrPos > searchNum) { if(looped) { pResult = currentPos; break; } // optimization: the items are ordered alphabetically, so go back to the top since we know it can't be anything further down currentPos = 0; addrPos = 0; while(!TEST_BIT(Cheat.ALL_BITS, addrPos)) addrPos++; looped = true; continue; } //Go to next item addrPos++; while(!TEST_BIT(Cheat.ALL_BITS, addrPos)) addrPos++; currentPos++; //Need to restart at top? if(currentPos >= ListView_GetItemCount(GetDlgItem(hDlg,IDC_ADDYS))) { currentPos = 0; addrPos = 0; while(!TEST_BIT(Cheat.ALL_BITS, addrPos)) addrPos++; } //Stop if back to start }while(currentPos != startPos); foundItemOverride = pResult; // in case previously-selected item is 0 ListView_SetItemState (GetDlgItem(hDlg,IDC_ADDYS), 1, LVIS_SELECTED|LVIS_FOCUSED,LVIS_SELECTED|LVIS_FOCUSED); return pResult; // HACK: for some reason this selects the first item instead of what it's returning... current workaround is to manually re-select this return value upon the next changed event } else if(nmh->hwndFrom == GetDlgItem(hDlg, IDC_ADDYS) && nmh->code == LVN_ITEMCHANGED) { // hack - see note directly above LPNMLISTVIEW lpnmlv = (LPNMLISTVIEW)lParam; if(lpnmlv->uNewState & (LVIS_SELECTED|LVIS_FOCUSED)) { if(foundItemOverride != -1 && lpnmlv->iItem == 0) { ListView_SetItemState (GetDlgItem(hDlg,IDC_ADDYS), foundItemOverride, LVIS_SELECTED|LVIS_FOCUSED,LVIS_SELECTED|LVIS_FOCUSED); ListView_EnsureVisible (GetDlgItem(hDlg,IDC_ADDYS), foundItemOverride, FALSE); selectionMarkOverride = foundItemOverride; foundItemOverride = -1; } else { selectionMarkOverride = lpnmlv->iItem; } } } } } break; case WM_ACTIVATE: ListView_RedrawItems(GetDlgItem(hDlg, IDC_ADDYS),0, 0x32000); break; case WM_COMMAND: { switch(LOWORD(wParam)) { case IDC_LESS_THAN: case IDC_GREATER_THAN: case IDC_LESS_THAN_EQUAL: case IDC_GREATER_THAN_EQUAL: case IDC_EQUAL: case IDC_NOT_EQUAL: if(BST_CHECKED==IsDlgButtonChecked(hDlg, IDC_LESS_THAN)) comp_type=S9X_LESS_THAN; else if(BST_CHECKED==IsDlgButtonChecked(hDlg, IDC_GREATER_THAN)) comp_type=S9X_GREATER_THAN; else if(BST_CHECKED==IsDlgButtonChecked(hDlg, IDC_LESS_THAN_EQUAL)) comp_type=S9X_LESS_THAN_OR_EQUAL; else if(BST_CHECKED==IsDlgButtonChecked(hDlg, IDC_GREATER_THAN_EQUAL)) comp_type=S9X_GREATER_THAN_OR_EQUAL; else if(BST_CHECKED==IsDlgButtonChecked(hDlg, IDC_EQUAL)) comp_type=S9X_EQUAL; else if(BST_CHECKED==IsDlgButtonChecked(hDlg, IDC_NOT_EQUAL)) comp_type=S9X_NOT_EQUAL; break; case IDC_1_BYTE: case IDC_2_BYTE: case IDC_3_BYTE: case IDC_4_BYTE: if(BST_CHECKED==IsDlgButtonChecked(hDlg, IDC_1_BYTE)) bytes=S9X_8_BITS; else if(BST_CHECKED==IsDlgButtonChecked(hDlg, IDC_2_BYTE)) bytes=S9X_16_BITS; else if(BST_CHECKED==IsDlgButtonChecked(hDlg, IDC_3_BYTE)) bytes=S9X_24_BITS; else bytes=S9X_32_BITS; { int l = CheatCount(bytes); ListView_SetItemCount (GetDlgItem(hDlg, IDC_ADDYS), l); } break; case IDC_SIGNED: case IDC_UNSIGNED: case IDC_HEX: if(BST_CHECKED==IsDlgButtonChecked(hDlg, IDC_UNSIGNED)) val_type=1; else if(BST_CHECKED==IsDlgButtonChecked(hDlg, IDC_SIGNED)) val_type=2; else val_type=3; ListView_RedrawItems(GetDlgItem(hDlg, IDC_ADDYS),0, 0x32000); break; case IDC_C_ADD: { // account for size struct ICheat cht; // int idx=-1; LVITEM lvi; static TCHAR buf[12]; // the following code assumes this variable is static, I think ZeroMemory(&cht, sizeof(struct SCheat)); //retrieve and convert to SCheat if(bytes==S9X_8_BITS) cht.size=1; else if (bytes==S9X_16_BITS) cht.size=2; else if (bytes==S9X_24_BITS) cht.size=3; else if (bytes==S9X_32_BITS) cht.size=4; ITEM_QUERY(lvi, IDC_ADDYS, 0, buf, 7); ScanAddress(buf, cht.address); memset(buf, 0, 7); if(val_type==1) { ITEM_QUERY(lvi, IDC_ADDYS, 1, buf, 12); sscanf(buf, "%u", &cht.new_val); memset(buf, 0, 7); ITEM_QUERY(lvi, IDC_ADDYS, 2, buf, 12); sscanf(buf, "%u", &cht.saved_val); } else if(val_type==3) { ITEM_QUERY(lvi, IDC_ADDYS, 1, buf, 12); sscanf(buf, "%x", &cht.new_val); memset(buf, 0, 7); ITEM_QUERY(lvi, IDC_ADDYS, 2, buf, 12); sscanf(buf, "%x", &cht.saved_val); } else { ITEM_QUERY(lvi, IDC_ADDYS, 1, buf, 12); sscanf(buf, "%d", &cht.new_val); memset(buf, 0, 7); ITEM_QUERY(lvi, IDC_ADDYS, 2, buf, 12); sscanf(buf, "%d", &cht.saved_val); } cht.format=val_type; //invoke dialog if(!DialogBoxParam(g_hInst, MAKEINTRESOURCE(IDD_CHEAT_FROM_SEARCH), hDlg, DlgCheatSearchAdd, (LPARAM)&cht)) { int p; for(p=0; p>(8*p))&0xFF)); //add cheat strcpy(Cheat.c[Cheat.num_cheats-1].name, cht.name); } } } break; case IDC_C_RESET: S9xStartCheatSearch(&Cheat); { int l = CheatCount(bytes); ListView_SetItemCount (GetDlgItem(hDlg, IDC_ADDYS), l); } ListView_RedrawItems(GetDlgItem(hDlg, IDC_ADDYS),0, 0x32000); //val_type=1; //SendDlgItemMessage(hDlg, IDC_UNSIGNED, BM_SETCHECK, BST_CHECKED, 0); //SendDlgItemMessage(hDlg, IDC_SIGNED, BM_SETCHECK, BST_UNCHECKED, 0); //SendDlgItemMessage(hDlg, IDC_HEX, BM_SETCHECK, BST_UNCHECKED, 0); //bytes=S9X_8_BITS; //SendDlgItemMessage(hDlg, IDC_1_BYTE, BM_SETCHECK, BST_CHECKED, 0); //SendDlgItemMessage(hDlg, IDC_2_BYTE, BM_SETCHECK, BST_UNCHECKED, 0); //SendDlgItemMessage(hDlg, IDC_3_BYTE, BM_SETCHECK, BST_UNCHECKED, 0); //SendDlgItemMessage(hDlg, IDC_4_BYTE, BM_SETCHECK, BST_UNCHECKED, 0); //use_entered=0; //SendDlgItemMessage(hDlg, IDC_PREV, BM_SETCHECK, BST_CHECKED, 0); //SendDlgItemMessage(hDlg, IDC_ENTERED, BM_SETCHECK, BST_UNCHECKED, 0); //SendDlgItemMessage(hDlg, IDC_ENTEREDADDRESS, BM_SETCHECK, BST_UNCHECKED, 0); //EnableWindow(GetDlgItem(hDlg, IDC_VALUE_ENTER), false); //EnableWindow(GetDlgItem(hDlg, IDC_ENTER_LABEL), false); //comp_type=S9X_LESS_THAN; //SendDlgItemMessage(hDlg, IDC_LESS_THAN, BM_SETCHECK, BST_CHECKED, 0); //SendDlgItemMessage(hDlg, IDC_GREATER_THAN, BM_SETCHECK, BST_UNCHECKED, 0); //SendDlgItemMessage(hDlg, IDC_LESS_THAN_EQUAL, BM_SETCHECK, BST_UNCHECKED, 0); //SendDlgItemMessage(hDlg, IDC_GREATER_THAN_EQUAL, BM_SETCHECK, BST_UNCHECKED, 0); //SendDlgItemMessage(hDlg, IDC_EQUAL, BM_SETCHECK, BST_UNCHECKED, 0); //SendDlgItemMessage(hDlg, IDC_NOT_EQUAL, BM_SETCHECK, BST_UNCHECKED, 0); return true; case IDC_C_WATCH: { uint32 address = (uint32)-1; char buf [12]; LVITEM lvi; ITEM_QUERY(lvi, IDC_ADDYS, 0, buf, 7); ScanAddress(buf, address); { memset(buf, 0, 7); unsigned int i; for(i = 0 ; i < sizeof(watches)/sizeof(*watches) ; i++) if(!watches[i].on || watches[i].address == address) break; if(i >= sizeof(watches)/sizeof(*watches)) i = (unsigned int)(sizeof(watches)/sizeof(*watches)-1); watches[i].on = true; // account for size if(bytes==S9X_8_BITS) watches[i].size=1; else if (bytes==S9X_16_BITS) watches[i].size=2; else if (bytes==S9X_24_BITS) watches[i].size=3; else if (bytes==S9X_32_BITS) watches[i].size=4; watches[i].format=val_type; watches[i].address=address; strncpy(watches[i].buf,buf,12); if(address < 0x7E0000 + 0x20000) sprintf(watches[i].desc, "%6X", address); else if(address < 0x7E0000 + 0x30000) sprintf(watches[i].desc, "s%05X", address - 0x7E0000 - 0x20000); else sprintf(watches[i].desc, "i%05X", address - 0x7E0000 - 0x30000); } { RECT rect; GetClientRect (GUI.hWnd, &rect); InvalidateRect (GUI.hWnd, &rect, true); } } break; case IDC_C_CLEARWATCH: { for(unsigned int i = 0 ; i < sizeof(watches)/sizeof(*watches) ; i++) watches[i].on = false; { RECT rect; GetClientRect (GUI.hWnd, &rect); InvalidateRect (GUI.hWnd, &rect, true); } } break; case IDC_C_LOADWATCH: { OPENFILENAME ofn; char szFileName[MAX_PATH]; char szPathName[MAX_PATH]; strcpy(szFileName, "watches"); _fullpath(szPathName, S9xGetDirectory(CHEAT_DIR), MAX_PATH); ZeroMemory( (LPVOID)&ofn, sizeof(OPENFILENAME) ); ofn.lStructSize = sizeof(OPENFILENAME); ofn.hwndOwner = GUI.hWnd; ofn.lpstrFilter = FILE_INFO_TXT_FILE_TYPE "\0*.txt\0" FILE_INFO_ANY_FILE_TYPE "\0*.*\0\0"; ofn.lpstrFile = szFileName; ofn.lpstrDefExt = "txt"; ofn.nMaxFile = MAX_PATH; ofn.Flags = OFN_HIDEREADONLY | OFN_FILEMUSTEXIST; ofn.lpstrInitialDir = szPathName; if(GetOpenFileName( &ofn )) { FILE *file = fopen(szFileName, "r"); if(file) { unsigned int i; for(i = 0 ; i < sizeof(watches)/sizeof(*watches) ; i++) watches[i].on = false; for(i = 0 ; i < sizeof(watches)/sizeof(*watches) ; i++) { char nameStr [32]; nameStr[0]='?'; nameStr[1]='\0'; fscanf(file, " address = 0x%x, name = \"%31[^\"]\", size = %d, format = %d\n", &watches[i].address, nameStr, &watches[i].size, &watches[i].format); if(nameStr[0] == '\0' || nameStr[0] == '?') { if(watches[i].address < 0x7E0000 + 0x20000) sprintf(nameStr, "%06X", watches[i].address); else if(watches[i].address < 0x7E0000 + 0x30000) sprintf(nameStr, "s%05X", watches[i].address - 0x7E0000 - 0x20000); else sprintf(nameStr, "i%05X", watches[i].address - 0x7E0000 - 0x30000); } nameStr[31] = '\0'; if(!ferror(file)) { watches[i].on = true; watches[i].buf[0] = '\0'; strncpy(watches[i].desc, nameStr, sizeof(watches[i].desc)); watches[i].desc[sizeof(watches[i].desc)-1]='\0'; } if(ferror(file) || feof(file)) break; } fclose(file); } } { RECT rect; GetClientRect (GUI.hWnd, &rect); InvalidateRect (GUI.hWnd, &rect, true); } } break; case IDC_C_SAVEWATCH: { OPENFILENAME ofn; char szFileName[MAX_PATH]; char szPathName[MAX_PATH]; strcpy(szFileName, "watches"); _fullpath(szPathName, S9xGetDirectory(CHEAT_DIR), MAX_PATH); ZeroMemory( (LPVOID)&ofn, sizeof(OPENFILENAME) ); ofn.lStructSize = sizeof(OPENFILENAME); ofn.hwndOwner = GUI.hWnd; ofn.lpstrFilter = FILE_INFO_TXT_FILE_TYPE "\0*.txt\0" FILE_INFO_ANY_FILE_TYPE "\0*.*\0\0"; ofn.lpstrFile = szFileName; ofn.lpstrDefExt = "txt"; ofn.nMaxFile = MAX_PATH; ofn.Flags = OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT; ofn.lpstrInitialDir = szPathName; if(GetSaveFileName( &ofn )) { FILE *file = fopen(szFileName, "w"); if(file) { for(unsigned int i = 0 ; i < sizeof(watches)/sizeof(*watches) ; i++) if(watches[i].on) // fprintf(file, "address = 0x%x, name = \"%6X\", size = %d, format = %d\n", watches[i].address, watches[i].address, watches[i].size, watches[i].format); fprintf(file, "address = 0x%x, name = \"?\", size = %d, format = %d\n", watches[i].address, watches[i].size, watches[i].format); fclose(file); } } { RECT rect; GetClientRect (GUI.hWnd, &rect); InvalidateRect (GUI.hWnd, &rect, true); } } break; case IDC_REFRESHLIST: ListView_RedrawItems(GetDlgItem(hDlg, IDC_ADDYS),0, 0x32000); break; case IDC_ENTERED: case IDC_ENTEREDADDRESS: case IDC_PREV: if(BST_CHECKED==IsDlgButtonChecked(hDlg, IDC_ENTERED)) { use_entered=1; EnableWindow(GetDlgItem(hDlg, IDC_VALUE_ENTER), true); EnableWindow(GetDlgItem(hDlg, IDC_ENTER_LABEL), true); } else if(BST_CHECKED==IsDlgButtonChecked(hDlg, IDC_ENTEREDADDRESS)) { use_entered=2; EnableWindow(GetDlgItem(hDlg, IDC_VALUE_ENTER), true); EnableWindow(GetDlgItem(hDlg, IDC_ENTER_LABEL), true); } else { use_entered=0; EnableWindow(GetDlgItem(hDlg, IDC_VALUE_ENTER), false); EnableWindow(GetDlgItem(hDlg, IDC_ENTER_LABEL), false); } return true; break; case IDC_C_SEARCH: { val_type=0; if(BST_CHECKED==IsDlgButtonChecked(hDlg, IDC_LESS_THAN)) comp_type=S9X_LESS_THAN; else if(BST_CHECKED==IsDlgButtonChecked(hDlg, IDC_GREATER_THAN)) comp_type=S9X_GREATER_THAN; else if(BST_CHECKED==IsDlgButtonChecked(hDlg, IDC_LESS_THAN_EQUAL)) comp_type=S9X_LESS_THAN_OR_EQUAL; else if(BST_CHECKED==IsDlgButtonChecked(hDlg, IDC_GREATER_THAN_EQUAL)) comp_type=S9X_GREATER_THAN_OR_EQUAL; else if(BST_CHECKED==IsDlgButtonChecked(hDlg, IDC_EQUAL)) comp_type=S9X_EQUAL; else comp_type=S9X_NOT_EQUAL; if(BST_CHECKED==IsDlgButtonChecked(hDlg, IDC_UNSIGNED)) val_type=1; else if(BST_CHECKED==IsDlgButtonChecked(hDlg, IDC_SIGNED)) val_type=2; else val_type=3; if(BST_CHECKED==IsDlgButtonChecked(hDlg, IDC_1_BYTE)) bytes=S9X_8_BITS; else if(BST_CHECKED==IsDlgButtonChecked(hDlg, IDC_2_BYTE)) bytes=S9X_16_BITS; else if(BST_CHECKED==IsDlgButtonChecked(hDlg, IDC_3_BYTE)) bytes=S9X_24_BITS; else bytes=S9X_32_BITS; if(BST_CHECKED==IsDlgButtonChecked(hDlg, IDC_ENTERED) || BST_CHECKED==IsDlgButtonChecked(hDlg, IDC_ENTEREDADDRESS)) { TCHAR buf[20]; GetDlgItemText(hDlg, IDC_VALUE_ENTER, buf, 20); uint32 value; int ret; if(use_entered==2) { ret = ScanAddress(buf, value); value -= 0x7E0000; S9xSearchForAddress (&Cheat, comp_type, bytes, value, FALSE); } else { if(val_type==1) ret=_stscanf(buf, "%ul", &value); else if (val_type==2) ret=_stscanf(buf, "%d", &value); else ret=_stscanf(buf, "%x", &value); if(ret!=1||!TestRange(val_type, bytes, value)) { MessageBox(hDlg, TEXT(SEARCH_ERR_INVALIDSEARCHVALUE), TEXT(SEARCH_TITLE_CHEATERROR), MB_OK); return true; } S9xSearchForValue (&Cheat, comp_type, bytes, value, (val_type==2), FALSE); } } else { S9xSearchForChange (&Cheat, comp_type, bytes, (val_type==2), FALSE); } int l = CheatCount(bytes); ListView_SetItemCount (GetDlgItem(hDlg, IDC_ADDYS), l); } // if non-modal, update "Prev. Value" column after Search if(cheatSearchHWND) { CopyMemory(Cheat.CWRAM, Cheat.RAM, 0x20000); CopyMemory(Cheat.CSRAM, Cheat.SRAM, 0x10000); CopyMemory(Cheat.CIRAM, Cheat.FillRAM, 0x2000); } ListView_RedrawItems(GetDlgItem(hDlg, IDC_ADDYS),0, 0x32000); return true; break; case IDOK: CopyMemory(Cheat.CWRAM, Cheat.RAM, 0x20000); CopyMemory(Cheat.CSRAM, Cheat.SRAM, 0x10000); CopyMemory(Cheat.CIRAM, Cheat.FillRAM, 0x2000); /* fall through */ case IDCANCEL: if(cheatSearchHWND) DestroyWindow(hDlg); else EndDialog(hDlg, 0); if(hBmp) { DeleteObject(hBmp); hBmp=NULL; }; return true; default: break; } } default: return false; } return false; } int CALLBACK DlgCheatSearchAdd(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam) { static struct ICheat* new_cheat; int ret=-1; static HBITMAP hBmp; switch(msg) { case WM_INITDIALOG: if(DirectX.Clipped) S9xReRefresh(); { TCHAR buf [12]; new_cheat=(struct ICheat*)lParam; hBmp=(HBITMAP)LoadImage(NULL, TEXT("Gary.bmp"), IMAGE_BITMAP, 0,0, LR_CREATEDIBSECTION | LR_LOADFROMFILE); sprintf(buf, "%06X", new_cheat->address); SetDlgItemText(hDlg, IDC_NC_ADDRESS, buf); switch(new_cheat->format) { default: case 1://UNSIGNED memset(buf,0,12); sprintf(buf, "%u", new_cheat->new_val); SetDlgItemText(hDlg, IDC_NC_CURRVAL, buf); memset(buf,0,12); sprintf(buf, "%u", new_cheat->saved_val); SetDlgItemText(hDlg, IDC_NC_PREVVAL, buf); SetWindowLong(GetDlgItem(hDlg, IDC_NC_NEWVAL), GWL_STYLE, ES_NUMBER |GetWindowLong(GetDlgItem(hDlg, IDC_NC_NEWVAL),GWL_STYLE)); SetWindowLong(GetDlgItem(hDlg, IDC_NC_CURRVAL), GWL_STYLE, ES_NUMBER |GetWindowLong(GetDlgItem(hDlg, IDC_NC_CURRVAL),GWL_STYLE)); SetWindowLong(GetDlgItem(hDlg, IDC_NC_PREVVAL), GWL_STYLE, ES_NUMBER |GetWindowLong(GetDlgItem(hDlg, IDC_NC_PREVVAL),GWL_STYLE)); if(new_cheat->size==1) { SendDlgItemMessage(hDlg, IDC_NC_CURRVAL,EM_SETLIMITTEXT, 3, 0); SendDlgItemMessage(hDlg, IDC_NC_PREVVAL,EM_SETLIMITTEXT, 3, 0); SendDlgItemMessage(hDlg, IDC_NC_NEWVAL,EM_SETLIMITTEXT, 3, 0); } if(new_cheat->size==2) { SendDlgItemMessage(hDlg, IDC_NC_CURRVAL,EM_SETLIMITTEXT, 5, 0); SendDlgItemMessage(hDlg, IDC_NC_PREVVAL,EM_SETLIMITTEXT, 5, 0); SendDlgItemMessage(hDlg, IDC_NC_NEWVAL,EM_SETLIMITTEXT, 5, 0); } if(new_cheat->size==3) { SendDlgItemMessage(hDlg, IDC_NC_CURRVAL,EM_SETLIMITTEXT, 8, 0); SendDlgItemMessage(hDlg, IDC_NC_PREVVAL,EM_SETLIMITTEXT, 8, 0); SendDlgItemMessage(hDlg, IDC_NC_NEWVAL,EM_SETLIMITTEXT, 8, 0); } if(new_cheat->size==4) { SendDlgItemMessage(hDlg, IDC_NC_CURRVAL,EM_SETLIMITTEXT, 10, 0); SendDlgItemMessage(hDlg, IDC_NC_PREVVAL,EM_SETLIMITTEXT, 10, 0); SendDlgItemMessage(hDlg, IDC_NC_NEWVAL,EM_SETLIMITTEXT, 10, 0); } break; case 3: { char formatstring[10]; sprintf(formatstring, "%%%02dX",new_cheat->size*2); memset(buf,0,12); sprintf(buf, formatstring, new_cheat->new_val); SetDlgItemText(hDlg, IDC_NC_CURRVAL, buf); memset(buf,0,12); sprintf(buf, formatstring, new_cheat->saved_val); SetDlgItemText(hDlg, IDC_NC_PREVVAL, buf); SendDlgItemMessage(hDlg, IDC_NC_CURRVAL,EM_SETLIMITTEXT, new_cheat->size*2, 0); SendDlgItemMessage(hDlg, IDC_NC_PREVVAL,EM_SETLIMITTEXT, new_cheat->size*2, 0); SendDlgItemMessage(hDlg, IDC_NC_NEWVAL,EM_SETLIMITTEXT, new_cheat->size*2, 0); } break; //HEX case 2: memset(buf,0,12); sprintf(buf, "%d", new_cheat->new_val); SetDlgItemText(hDlg, IDC_NC_CURRVAL, buf); memset(buf,0,12); sprintf(buf, "%d", new_cheat->saved_val); SetDlgItemText(hDlg, IDC_NC_PREVVAL, buf); if(new_cheat->size==1) { //-128 SendDlgItemMessage(hDlg, IDC_NC_CURRVAL,EM_SETLIMITTEXT, 4, 0); SendDlgItemMessage(hDlg, IDC_NC_PREVVAL,EM_SETLIMITTEXT, 4, 0); SendDlgItemMessage(hDlg, IDC_NC_NEWVAL,EM_SETLIMITTEXT, 4, 0); } if(new_cheat->size==2) { //-32768 SendDlgItemMessage(hDlg, IDC_NC_CURRVAL,EM_SETLIMITTEXT, 6, 0); SendDlgItemMessage(hDlg, IDC_NC_PREVVAL,EM_SETLIMITTEXT, 6, 0); SendDlgItemMessage(hDlg, IDC_NC_NEWVAL,EM_SETLIMITTEXT, 6, 0); } if(new_cheat->size==3) { //-8388608 SendDlgItemMessage(hDlg, IDC_NC_CURRVAL,EM_SETLIMITTEXT, 8, 0); SendDlgItemMessage(hDlg, IDC_NC_PREVVAL,EM_SETLIMITTEXT, 8, 0); SendDlgItemMessage(hDlg, IDC_NC_NEWVAL,EM_SETLIMITTEXT, 8, 0); } if(new_cheat->size==4) { //-2147483648 SendDlgItemMessage(hDlg, IDC_NC_CURRVAL,EM_SETLIMITTEXT, 11, 0); SendDlgItemMessage(hDlg, IDC_NC_PREVVAL,EM_SETLIMITTEXT, 11, 0); SendDlgItemMessage(hDlg, IDC_NC_NEWVAL,EM_SETLIMITTEXT, 11, 0); } break; } } return true; case WM_PAINT: { PAINTSTRUCT ps; BeginPaint (hDlg, &ps); if(hBmp) { BITMAP bmp; ZeroMemory(&bmp, sizeof(BITMAP)); RECT r; GetClientRect(hDlg, &r); HDC hdc=GetDC(hDlg); HDC hDCbmp=CreateCompatibleDC(hdc); GetObject(hBmp, sizeof(BITMAP), &bmp); HBITMAP hOldBmp=(HBITMAP)SelectObject(hDCbmp, hBmp); StretchBlt(hdc, 0,0,r.right,r.bottom,hDCbmp,0,0,bmp.bmWidth,bmp.bmHeight,SRCCOPY); SelectObject(hDCbmp, hOldBmp); DeleteDC(hDCbmp); ReleaseDC(hDlg, hdc); } EndPaint (hDlg, &ps); } return true; case WM_COMMAND: { switch(LOWORD(wParam)) { case IDOK: { int ret = 0; TCHAR buf[23]; int temp=new_cheat->size; S9xCheatDataSize tmp = S9X_8_BITS; ZeroMemory(new_cheat, sizeof(struct SCheat)); new_cheat->size=temp; GetDlgItemText(hDlg, IDC_NC_ADDRESS, buf, 7); ScanAddress(buf, new_cheat->address); if(temp==1) tmp=S9X_8_BITS; if(temp==2) tmp=S9X_16_BITS; if(temp==3) tmp=S9X_24_BITS; if(temp==4) tmp=S9X_32_BITS; if(0!=GetDlgItemText(hDlg, IDC_NC_NEWVAL, buf, 12)) { if(new_cheat->format==2) ret=sscanf(buf, "%d", &new_cheat->new_val); else if(new_cheat->format==1) ret=sscanf(buf, "%u", &new_cheat->new_val); else if(new_cheat->format==3) ret=sscanf(buf, "%x", &new_cheat->new_val); if(ret!=1 || !TestRange(new_cheat->format, tmp, new_cheat->new_val)) { MessageBox(hDlg, SEARCH_ERR_INVALIDNEWVALUE, SEARCH_TITLE_RANGEERROR, MB_OK); return true; } if(0==GetDlgItemText(hDlg, IDC_NC_CURRVAL, buf, 12)) new_cheat->saved=FALSE; else { int i; if(new_cheat->format==2) ret=sscanf(buf, "%d", &i); else if(new_cheat->format==1) ret=sscanf(buf, "%u", &i); else if(new_cheat->format==3) ret=sscanf(buf, "%x", &i); if(ret!=1 || !TestRange(new_cheat->format, tmp, i)) { MessageBox(hDlg, SEARCH_ERR_INVALIDCURVALUE, SEARCH_TITLE_RANGEERROR, MB_OK); return true; } new_cheat->saved_val=i; new_cheat->saved=TRUE; } GetDlgItemText(hDlg, IDC_NC_DESC, new_cheat->name, 23); new_cheat->enabled=TRUE; S9xAddCheat(new_cheat->enabled,new_cheat->saved_val,new_cheat->address,new_cheat->new_val); strcpy(Cheat.c[Cheat.num_cheats-1].name,new_cheat->name); ret=0; } } case IDCANCEL: EndDialog(hDlg, ret); if(hBmp) { DeleteObject(hBmp); hBmp=NULL; } return true; default: break; } } default: return false; } } static void set_movieinfo(const char* path, HWND hDlg) { MovieInfo m; int i; int getInfoResult=FILE_NOT_FOUND; if(strlen(path)) getInfoResult = S9xMovieGetInfo(path, &m); if(getInfoResult!=FILE_NOT_FOUND) { char* p; char tmpstr[128]; strncpy(tmpstr, ctime(&m.TimeCreated), 127); tmpstr[127]='\0'; if((p=strrchr(tmpstr, '\n'))) *p='\0'; SetWindowTextA(GetDlgItem(hDlg, IDC_MOVIE_DATE), tmpstr); uint32 div = Memory.ROMFramesPerSecond; if(!div) div = 60; uint32 l=(m.LengthFrames+(div>>1))/div; uint32 seconds=l%60; l/=60; uint32 minutes=l%60; l/=60; uint32 hours=l%60; sprintf(tmpstr, "%02d:%02d:%02d", hours, minutes, seconds); SetWindowTextA(GetDlgItem(hDlg, IDC_MOVIE_LENGTH), tmpstr); sprintf(tmpstr, "%u", m.LengthFrames); SetWindowTextA(GetDlgItem(hDlg, IDC_MOVIE_FRAMES), tmpstr); sprintf(tmpstr, "%u", m.RerecordCount); SetWindowTextA(GetDlgItem(hDlg, IDC_MOVIE_RERECORD), tmpstr); } else { SetWindowText(GetDlgItem(hDlg, IDC_MOVIE_DATE), _T("")); SetWindowText(GetDlgItem(hDlg, IDC_MOVIE_LENGTH), _T("")); SetWindowText(GetDlgItem(hDlg, IDC_MOVIE_FRAMES), _T("")); SetWindowText(GetDlgItem(hDlg, IDC_MOVIE_RERECORD), _T("")); } if(getInfoResult==SUCCESS) { // set author comment: { /// SetWindowTextW(GetDlgItem(hDlg, IDC_MOVIE_METADATA), m.Metadata); // won't work, because of & symbol wchar_t metadata [MOVIE_MAX_METADATA]; int j, pos = 0, len = wcslen(m.Metadata); for (j = 0; j < len ; j++) { wchar_t c = m.Metadata [j]; metadata [pos++] = c; // & is a special character in Windows fields, // so we have to change & to && when copying over the game title // otherwise "Pocky & Rocky" will show up as "Pocky Rocky", for example if(c == (wchar_t)'&') metadata [pos++] = (wchar_t)'&'; } metadata [pos] = (wchar_t)'\0'; SetWindowTextW(GetDlgItem(hDlg, IDC_MOVIE_METADATA), metadata); } SetWindowText(GetDlgItem(hDlg, IDC_LABEL_MOVIEINFOBOX), _T(MOVIE_LABEL_AUTHORINFO)); if(m.ReadOnly) { EnableWindow(GetDlgItem(hDlg, IDC_READONLY), FALSE); SendDlgItemMessage(hDlg,IDC_READONLY,BM_SETCHECK,BST_CHECKED,0); } else { EnableWindow(GetDlgItem(hDlg, IDC_READONLY), TRUE); /// SendDlgItemMessage(hDlg,IDC_READONLY,BM_SETCHECK,BST_UNCHECKED,0); } EnableWindow(GetDlgItem(hDlg, IDC_DISPLAY_INPUT), TRUE); for(i=0; i<5; ++i) { SendDlgItemMessage(hDlg,IDC_JOY1+i,BM_SETCHECK,(m.ControllersMask & (1<ReadOnly=TRUE; GUI.MovieReadOnly=TRUE; } else GUI.MovieReadOnly=FALSE; if(BST_CHECKED==SendDlgItemMessage(hDlg, IDC_DISPLAY_INPUT, BM_GETCHECK,0,0)) op->DisplayInput=TRUE; GetDlgItemText(hDlg, IDC_MOVIE_PATH, op->Path, MAX_PATH); SetCurrentDirectory(movieDirectory); } Settings.UpAndDown = IsDlgButtonChecked(hDlg, IDC_ALLOWLEFTRIGHT); // Settings.SoundEnvelopeHeightReading = IsDlgButtonChecked(hDlg, IDC_ENVX); // set in movie.cpp on playback // Settings.FakeMuteFix = IsDlgButtonChecked(hDlg, IDC_FMUT); // set in movie.cpp on playbacks Settings.SoundSync = IsDlgButtonChecked(hDlg, IDC_SYNC_TO_SOUND_CPU); EndDialog(hDlg, 1); return true; case IDCANCEL: EndDialog(hDlg, 0); return true; default: break; } } default: return false; } } // checks if the currently loaded ROM has an SRAM file in the saves directory that we have write access to static bool existsSRAM () { return(!access(S9xGetFilename(".srm", SRAM_DIR), R_OK|W_OK)); } int CALLBACK DlgCreateMovie(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam) { static OpenMovieParams* op=NULL; static char movieDirectory [MAX_PATH]; switch(msg) { case WM_INITDIALOG: { if(DirectX.Clipped) S9xReRefresh(); SetCurrentDirectory(S9xGetDirectory(DEFAULT_DIR)); _fullpath (movieDirectory, GUI.MovieDir, MAX_PATH); mkdir(movieDirectory); SetCurrentDirectory(movieDirectory); // have to save here or the SRAM file might not exist when we check for it // (which would cause clear SRAM option to not work) Memory.SaveSRAM(S9xGetFilename (".srm", SRAM_DIR)); op=(OpenMovieParams*)lParam; SendDlgItemMessage(hDlg,IDC_RECORD_RESET,BM_SETCHECK,BST_UNCHECKED,0); int i; for(i=1; i<5; ++i) { SendDlgItemMessage(hDlg,IDC_JOY1+i,BM_SETCHECK,BST_UNCHECKED,0); } SendDlgItemMessage(hDlg,IDC_JOY1,BM_SETCHECK,BST_CHECKED,0); // get default filename if(Memory.ROMFilename[0]!='\0') { static TCHAR filename [_MAX_PATH + 1]; TCHAR drive [_MAX_DRIVE + 1]; TCHAR dir [_MAX_DIR + 1]; TCHAR fname [_MAX_FNAME + 1]; TCHAR ext [_MAX_EXT + 1]; _splitpath (Memory.ROMFilename, drive, dir, fname, ext); _makepath (filename, "", "", fname, "smv"); SetWindowText(GetDlgItem(hDlg, IDC_MOVIE_PATH), filename); } SendDlgItemMessage(hDlg,IDC_ALLOWLEFTRIGHT,BM_SETCHECK, Settings.UpAndDown ? (WPARAM)BST_CHECKED : (WPARAM)BST_UNCHECKED, 0); // SendDlgItemMessage(hDlg,IDC_ENVX,BM_SETCHECK, Settings.SoundEnvelopeHeightReading ? (WPARAM)BST_CHECKED : (WPARAM)BST_UNCHECKED, 0); // SendDlgItemMessage(hDlg,IDC_FMUT,BM_SETCHECK, Settings.FakeMuteFix ? (WPARAM)BST_CHECKED : (WPARAM)BST_UNCHECKED, 0); SendDlgItemMessage(hDlg,IDC_ENVX,BM_SETCHECK, (WPARAM)BST_UNCHECKED, 0); // I realized that this should almost *always* be off when recording, because whenever it makes any difference to have it off, it prevents desyncs. Let the user turn it on each time if they really want it on when recording. SendDlgItemMessage(hDlg,IDC_FMUT,BM_SETCHECK, (WPARAM)BST_CHECKED, 0); // I realized that this should almost *always* be on when recording, because whenever it makes any difference to have it on, it prevents desyncs. Let the user turn it off each time if they really want it off when recording. SendDlgItemMessage(hDlg,IDC_SYNC_TO_SOUND_CPU,BM_SETCHECK, Settings.SoundSync ? (WPARAM)BST_CHECKED : (WPARAM)BST_UNCHECKED, 0); SetWindowText(GetDlgItem(hDlg, IDC_LOADEDFROMMOVIE), _T("")); EnableWindow(GetDlgItem(hDlg, IDC_SYNC_TO_SOUND_CPU), 0==Settings.SoundDriver); // can't sync sound to CPU unless using "Snes9x DirectSound" driver SendDlgItemMessage(hDlg,IDC_RECORD_RESET,BM_SETCHECK, (WPARAM)(GUI.MovieStartFromReset ? BST_CHECKED : BST_UNCHECKED), 0); SendDlgItemMessage(hDlg,IDC_RECORD_NOW,BM_SETCHECK, (WPARAM)(GUI.MovieStartFromReset ? BST_UNCHECKED : BST_CHECKED), 0); if(existsSRAM()) { EnableWindow(GetDlgItem(hDlg, IDC_CLEARSRAM), GUI.MovieStartFromReset); SendDlgItemMessage(hDlg,IDC_CLEARSRAM,BM_SETCHECK, (WPARAM)(GUI.MovieClearSRAM ? BST_CHECKED : BST_UNCHECKED), 0); } else { EnableWindow(GetDlgItem(hDlg, IDC_CLEARSRAM), false); SendDlgItemMessage(hDlg,IDC_CLEARSRAM,BM_SETCHECK, (WPARAM)BST_CHECKED, 0); } SetDlgItemText(hDlg,IDC_LABEL_STARTSETTINGS, MOVIE_LABEL_STARTSETTINGS); SetDlgItemText(hDlg,IDC_LABEL_CONTROLLERSETTINGS, MOVIE_LABEL_CONTSETTINGS); SetDlgItemText(hDlg,IDC_LABEL_SYNCSETTINGS, MOVIE_LABEL_SYNCSETTINGS); } return true; case WM_COMMAND: { switch(LOWORD(wParam)) { case IDC_BROWSE_MOVIE: { OPENFILENAME ofn; char szFileName[MAX_PATH]; szFileName[0] = '\0'; ZeroMemory( (LPVOID)&ofn, sizeof(OPENFILENAME) ); ofn.lStructSize = sizeof(OPENFILENAME); ofn.hwndOwner = hDlg; ofn.lpstrFilter = MOVIE_FILETYPE_DESCRIPTION "\0*.smv\0" FILE_INFO_ANY_FILE_TYPE "\0*.*\0\0"; ofn.lpstrFile = szFileName; ofn.lpstrDefExt = "smv"; ofn.nMaxFile = MAX_PATH; ofn.Flags = OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT; ofn.lpstrInitialDir = movieDirectory; if(GetSaveFileName( &ofn )) { SetWindowText(GetDlgItem(hDlg, IDC_MOVIE_PATH), szFileName); if(!GUI.LockDirectories) { char temp [256]; GetCurrentDirectory(MAX_PATH, temp); absToRel(GUI.MovieDir, temp, S9xGetDirectory(DEFAULT_DIR)); } } SetCurrentDirectory(movieDirectory); } return true; case IDOK: { GetDlgItemText(hDlg, IDC_MOVIE_PATH, op->Path, MAX_PATH); GetDlgItemTextW(hDlg, IDC_MOVIE_METADATA, op->Metadata, MOVIE_MAX_METADATA); int i; for(i=wcslen(op->Metadata); i<32; i++) wcscat(op->Metadata, L" "); op->ControllersMask=0; op->Opts=0; for(i=0; i<5; ++i) // TODO: should we even bother with 8-controller recording? right now there are only 5 controller buttons in the dialog, so... { if(BST_CHECKED==SendDlgItemMessage(hDlg, IDC_JOY1+i, BM_GETCHECK,0,0)) op->ControllersMask |= (1<Opts |= MOVIE_OPT_FROM_RESET; GUI.MovieStartFromReset = TRUE; } else GUI.MovieStartFromReset = FALSE; Settings.UpAndDown = IsDlgButtonChecked(hDlg, IDC_ALLOWLEFTRIGHT); Settings.SoundEnvelopeHeightReading = IsDlgButtonChecked(hDlg, IDC_ENVX); Settings.FakeMuteFix = IsDlgButtonChecked(hDlg, IDC_FMUT); Settings.SoundSync = IsDlgButtonChecked(hDlg, IDC_SYNC_TO_SOUND_CPU); op->SyncFlags = MOVIE_SYNC_DATA_EXISTS | MOVIE_SYNC_HASROMINFO; if(Settings.UpAndDown) op->SyncFlags |= MOVIE_SYNC_LEFTRIGHT; if(Settings.SoundEnvelopeHeightReading) op->SyncFlags |= MOVIE_SYNC_VOLUMEENVX; if(Settings.FakeMuteFix) op->SyncFlags |= MOVIE_SYNC_FAKEMUTE; if(Settings.SoundSync) op->SyncFlags |= MOVIE_SYNC_SYNCSOUND; if(IsDlgButtonChecked(hDlg, IDC_CLEARSRAM) && IsDlgButtonChecked(hDlg, IDC_RECORD_RESET) && existsSRAM()) { GUI.MovieClearSRAM = TRUE; remove(S9xGetFilename (".srm", SRAM_DIR)); // delete SRAM if it exists (maybe unnecessary?) remove(S9xGetFilename (".srm", ROMFILENAME_DIR)); Memory.LoadSRAM(S9xGetFilename (".srm", SRAM_DIR)); // refresh memory (hard reset) } else if(!IsDlgButtonChecked(hDlg, IDC_CLEARSRAM) && IsDlgButtonChecked(hDlg, IDC_RECORD_RESET) && existsSRAM()) { GUI.MovieClearSRAM = FALSE; } SetCurrentDirectory(movieDirectory); } EndDialog(hDlg, 1); return true; case IDCANCEL: EndDialog(hDlg, 0); return true; case IDC_RECORD_NOW: if(existsSRAM()) { EnableWindow(GetDlgItem(hDlg, IDC_CLEARSRAM), false); } break; case IDC_RECORD_RESET: if(existsSRAM()) { EnableWindow(GetDlgItem(hDlg, IDC_CLEARSRAM), true); } break; default: break; } } default: return false; } } // MYO void S9xHandlePortCommand(s9xcommand_t cmd, int16 data1, int16 data2) { return; } // NYI const char *S9xChooseFilename (bool8 read_only) { return NULL; } // NYI const char *S9xChooseMovieFilename (bool8 read_only) { return NULL; } const char * S9xStringInput(const char *msg) { return NULL; } void S9xToggleSoundChannel (int c) { if (c == 8) GUI.SoundChannelEnable = 255; else GUI.SoundChannelEnable ^= 1 << c; S9xSetSoundControl(GUI.SoundChannelEnable); } bool S9xPollButton(uint32 id, bool *pressed){ if(S9xMoviePlaying()) return false; *pressed = false; #define CHECK_KEY(controller, button) (!S9xGetState(Joypad[controller].button) || (ToggleJoypadStorage[controller].button && !TurboToggleJoypadStorage[controller].button) || (IPPU.TotalEmulatedFrames%2 == ToggleJoypadStorage[controller].button && TurboToggleJoypadStorage[controller].button)) extern bool S9xGetState (WORD KeyIdent); if (id & k_MO) // mouse { switch (id & 0xFF) { case 0: *pressed = GUI.MouseButtons & 1 /* Left */ || ((id & k_C1) && (CHECK_KEY(0,A) || CHECK_KEY(0,L))) || ((id & k_C2) && (CHECK_KEY(1,A) || CHECK_KEY(1,L))); break; case 1: *pressed = GUI.MouseButtons & 2 /* Right */ || ((id & k_C1) && (CHECK_KEY(0,B) || CHECK_KEY(0,R))) || ((id & k_C2) && (CHECK_KEY(1,B) || CHECK_KEY(1,R))); break; } } else if (id & k_SS) // superscope { switch (id & 0xFF) { case 0: *pressed = GUI.MouseX <= 0 || GUI.MouseY <= 0 || GUI.MouseX >= IPPU.RenderedScreenWidth || GUI.MouseY >= ((IPPU.RenderedScreenHeight> 256) ? SNES_HEIGHT_EXTENDED<<1 : SNES_HEIGHT_EXTENDED) || CHECK_KEY(1,X); break; case 2: *pressed = (GUI.MouseButtons & 2) /* Right */ || CHECK_KEY(1,B) || CHECK_KEY(1,R) ; break; case 3: *pressed = (GUI.MouseButtons & 4) /* Middle */ || GUI.superscope_turbo || CHECK_KEY(1,Y); GUI.superscope_turbo=0; GUI.MouseButtons &= ~4; break; case 4: *pressed = GUI.superscope_pause || CHECK_KEY(1,Start) || CHECK_KEY(1,Select); break; case 1: *pressed = (GUI.MouseButtons & 1) /* Left */ || CHECK_KEY(1,A) || CHECK_KEY(1,L); break; } } else if (id & k_LG) // justifier { if (id & k_C1) { switch (id & 0xFF) { case 0: *pressed = GUI.MouseX <= 0 || GUI.MouseY <= 0 || GUI.MouseX >= IPPU.RenderedScreenWidth || GUI.MouseY >= ((IPPU.RenderedScreenHeight> 256) ? SNES_HEIGHT_EXTENDED<<1 : SNES_HEIGHT_EXTENDED) || CHECK_KEY(0,X) || CHECK_KEY(0,Start); break; case 1: *pressed = GUI.MouseButtons & 1 /* Left */ || CHECK_KEY(0,A) || CHECK_KEY(0,L); break; case 2: *pressed = GUI.MouseButtons & 2 /* Right */ || CHECK_KEY(1,B) || CHECK_KEY(1,R); break; } } else { switch (id & 0xFF) { case 0: *pressed = CHECK_KEY(1,Start) /* 2p Start */ || CHECK_KEY(1,X); break; case 1: *pressed = CHECK_KEY(1,A) /* 2p A */ || CHECK_KEY(1,L); break; case 2: *pressed = CHECK_KEY(1,B) /* 2p B */ || CHECK_KEY(1,R); break; } } } return (true); } // ??? NYI bool S9xPollAxis(uint32 id, int16 *value){ return false; } bool S9xPollPointer(uint32 id, int16 *x, int16 *y){ if(S9xMoviePlaying()) return false; if (id & k_PT) { *x = GUI.MouseX; *y = GUI.MouseY; } else *x = *y = 0; return (true); } // adjusts settings based on ROM that was just loaded void S9xPostRomInit() { // "Cheats are on" message if cheats are on and active, // to make it less likely that someone will think there is some bug because of // a lingering cheat they don't realize is on if (Settings.ApplyCheats) { extern struct SCheatData Cheat; for (uint32 i = 0; i < Cheat.num_cheats; i++) { if (Cheat.c [i].enabled) { char String2 [1024]; sprintf(String2, "(CHEATS ARE ON!) %s", String); strncpy(String, String2, 512); break; } } } if(!S9xMovieActive() && !startingMovie) { // revert previously forced control if(GUI.ControlForced!=0xff) GUI.ControllerOption = GUI.ControlForced; int prevController = GUI.ControllerOption; GUI.ValidControllerOptions = 0xFFFF; // NSRT controller settings if (!strncmp((const char *)Memory.NSRTHeader+24, "NSRT", 4)) { switch(Memory.NSRTHeader[29]) { default: // unknown or unsupported break; case 0x00: // Gamepad / Gamepad GUI.ControllerOption = SNES_JOYPAD; GUI.ValidControllerOptions = (1< static inline void FontPixToScreen(char p, screenPtrType *s) { if(p == '#') { *s = Settings.DisplayColor; } else if(p == '.') { static const screenPtrType black = BUILD_PIXEL(0,0,0); *s = black; } } template<> static inline void FontPixToScreen(char p, uint32 *s) { #define CONVERT_16_TO_32(pixel) \ (((((pixel) >> 11) ) << /*RedShift+3*/ 19) | \ ((((pixel) >> 6) & 0x1f) << /*GreenShift+3*/11) | \ (((pixel) & 0x1f) << /*BlueShift+3*/ 3)) if(p == '#') { *s = CONVERT_16_TO_32(Settings.DisplayColor); } else if(p == '.') { static const uint32 black = CONVERT_16_TO_32(BUILD_PIXEL(0,0,0)); *s = black; } } #define CHOOSE(c1) ((c1=='#'||X=='#') ? '#' : ((c1=='.'||X=='.') ? '.' : c1)) template static inline void FontPixToScreenEPX(int x, int y, screenPtrType *s) { const char X = font[y][x]; // E D H const char A = x>0 ?font[y][x-1]:' '; // A X C const char C = x<143?font[y][x+1]:' '; // F B G if (A != C) { const char D = y>0 ?font[y-1][x]:' '; const char B = y<125?font[y+1][x]:' '; if (B != D) { FontPixToScreen((D == A) ? CHOOSE(D) : X, s); FontPixToScreen((C == D) ? CHOOSE(C) : X, s+1); FontPixToScreen((A == B) ? CHOOSE(A) : X, s+display_ppl); FontPixToScreen((B == C) ? CHOOSE(B) : X, s+display_ppl+1); return; } } FontPixToScreen(X, s); FontPixToScreen(X, s+1); FontPixToScreen(X, s+display_ppl); FontPixToScreen(X, s+display_ppl+1); } #undef CHOOSE #define CHOOSE(c1) ((X=='#') ? '#' : c1) template inline void FontPixToScreenEPXSimple3(int x, int y, screenPtrType *s) { const char X = font[y][x]; // E D H const char A = x>0 ?font[y][x-1]:' '; // A X C const char C = x<143?font[y][x+1]:' '; // F B G const char D = y>0 ?font[y-1][x]:' '; const char B = y<125?font[y+1][x]:' '; const bool XnE = y>0 &&x>0 ?(X != font[y-1][x-1]):X!=' '; const bool XnF = y<125&&x<143?(X != font[y+1][x-1]):X!=' '; const bool XnG = y<125&&x>0 ?(X != font[y+1][x+1]):X!=' '; const bool XnH = y>0 &&x<143?(X != font[y-1][x+1]):X!=' '; const bool DA = D == A && (XnE || CHOOSE(D)!=X); const bool AB = A == B && (XnF || CHOOSE(A)!=X); const bool BC = B == C && (XnG || CHOOSE(B)!=X); const bool CD = C == D && (XnH || CHOOSE(C)!=X); FontPixToScreen(DA ? A : X, s); FontPixToScreen(X, s+1); FontPixToScreen(CD ? C : X, s+2); FontPixToScreen(X, s+display_ppl); FontPixToScreen(X, s+display_ppl+1); FontPixToScreen(X, s+display_ppl+2); FontPixToScreen(AB ? A : X, s+display_ppl+display_ppl); FontPixToScreen(X, s+display_ppl+display_ppl+1); FontPixToScreen(BC ? C : X, s+display_ppl+display_ppl+2); } #undef CHOOSE template void WinDisplayChar(screenPtrType *s, uint8 c) { if(c <= 32) return; int line = ((c - 32) >> 4) * display_fontheight; int offset = ((c - 32) & 15) * display_fontwidth; int h, w; if(!display_paramsinited) display_ppl = Settings.OpenGLEnable ? IPPU.RenderedScreenWidth : GFX.RealPPL; if(display_hfontaccessscale == 1 && display_vfontaccessscale == 1) { for(h=0; h static void WinDisplayStringI (const char *string, int linesFromBottom, int pixelsFromLeft, bool allowWrap) { if(linesFromBottom <= 0) linesFromBottom = 1; display_ppl /= (sizeof(screenPtrType)>>1); screenPtrType *Screen = (screenPtrType*)display_screen // text draw position, starting on the screen + pixelsFromLeft // with this much horizontal offset // * (Settings.SixteenBit ? 2 : 1) + (display_height - display_fontheight * linesFromBottom) // and this much vertical offset * display_ppl; int len = strlen(string); int max_chars = display_width / (display_fontwidth-display_hfontaccessscale); int char_count = 0; int prev_hfont_access_scale = display_hfontaccessscale; // squash if it won't fit on 1 line and we're drawing greater than 1x scale and we're not allowing wrapping while(len > max_chars && !allowWrap && display_hfontaccessscale > 1) { display_fontwidth /= display_hfontaccessscale; display_hfontaccessscale--; display_fontwidth *= display_hfontaccessscale; max_chars = display_width / (display_fontwidth-display_hfontaccessscale); } // loop through and draw the characters for(int i = 0 ; i < len ; i++, char_count++) { if(char_count >= max_chars || (unsigned char)string[i] < 32) { if(!allowWrap) break; Screen -= /*Settings.SixteenBit ? (display_fontwidth-display_hfontaccessscale)*sizeof(uint16)*max_chars :*/ (display_fontwidth-display_hfontaccessscale)*max_chars; Screen += display_fontheight * display_ppl; if(Screen >= (screenPtrType*)display_screen + display_ppl * display_height) break; char_count -= max_chars; } if((unsigned char) string[i]<32) continue; WinDisplayChar(Screen, string[i]); Screen += /*Settings.SixteenBit ? (display_fontwidth-display_hfontaccessscale)*sizeof(uint16) :*/ (display_fontwidth-display_hfontaccessscale); } // revert temporary change to font scale, if any if(display_hfontaccessscale != prev_hfont_access_scale) { display_hfontaccessscale = prev_hfont_access_scale; display_fontwidth *= display_hfontaccessscale; } display_ppl *= (sizeof(screenPtrType)>>1); } static void WinDisplayString (const char *string, int linesFromBottom, int pixelsFromLeft, bool allowWrap) { if(GUI.ScreenDepth == 32 && GUI.DepthConverted) { WinDisplayStringI(string, linesFromBottom, pixelsFromLeft, allowWrap); } else { WinDisplayStringI(string, linesFromBottom, pixelsFromLeft, allowWrap); } }