diff --git a/README.md b/README.md index 3f363ccc..1aa6d15a 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,4 @@ +### ![#f03c15](https://via.placeholder.com/15/f03c15/000000?text=+) **Experimental - Expect instability** # Mupen64 Lua [![Release](https://img.shields.io/github/v/release/mkdasher/mupen64-rr-lua-?label=Release)](https://github.com/mkdasher/mupen64-rr-lua-/releases) @@ -8,7 +9,7 @@ [comment]: <> (Second image has to be inline so another approach is used) [**__\>\> Latest Release \<\<__**](https://github.com/mkdasher/mupen64-rr-lua-/releases/latest/)
-This repository contains source code for continued development of Mupen64 - Nintendo 64 emulator with TAS support, and TASinput plugin. +This repository contains the latest source code for continued development of Mupen64 - Nintendo 64 emulator with TAS support, and TASInput plugin. This version includes new Features such as: AVISplit, Reset recording, WiiVC and Backwards Compatibility options all in one. diff --git a/lua/LuaConsole.cpp b/lua/LuaConsole.cpp index 9ce7a5ff..2d454d82 100644 --- a/lua/LuaConsole.cpp +++ b/lua/LuaConsole.cpp @@ -22,12 +22,13 @@ #include "../main/savestates.h" #include "../main/win/Config.h" #include - +#include #ifdef LUA_CONSOLE //nice msvc pragma smh #pragma comment(lib, "lua54.lib") +#pragma comment (lib,"Gdiplus.lib") extern unsigned long op; @@ -49,6 +50,8 @@ bool traceLogMode; bool enablePCBreak; bool maximumSpeedMode; bool anyLuaRunning = false; +bool gdiPlusInitialized = false; +ULONG_PTR gdiPlusToken; #define DEBUG_GETLASTERROR 0//if(GetLastError()){ShowInfo("Line:%d GetLastError:%d",__LINE__,GetLastError());SetLastError(0);} @@ -150,7 +153,6 @@ struct EmulationLock{ } }; -void runLUA(HWND wnd, char path[]); // bad solution void ConsoleWrite(HWND, const char*); void SetWindowLua(HWND wnd, Lua *lua); void SetButtonState(HWND wnd, bool state); @@ -205,8 +207,12 @@ class Lua { hMutex = CreateMutex(0, 0, 0); newLuaState(); runFile(path); - if(isrunning()) + if (isrunning()) + { SetButtonState(ownWnd, true); + AddToRecentScripts(path); + strcpy(Config.LuaScriptPath, path); + } ShowInfo("Lua run"); } void stop() { @@ -335,7 +341,6 @@ class Lua { void runFile(char *path) { //int GetErrorMessage(lua_State *L); int result; - SetButtonState(ownWnd, true); //lua_pushcfunction(L, GetErrorMessage); result = luaL_dofile(L, path); if(result) { @@ -636,11 +641,14 @@ INT_PTR CALLBACK DialogProc(HWND wnd, UINT msg, WPARAM wParam, LPARAM lParam) { return TRUE; } case WM_CLOSE: + + if (Config.LuaWarnOnClose + && (MessageBox(0, "Are you sure you want to close this dialog and terminate this lua script instance?", "Confirm closing", MB_TASKMODAL | MB_TOPMOST | MB_YESNO | MB_ICONQUESTION) == IDNO)) + return TRUE; + DestroyWindow(wnd); return TRUE; case WM_DESTROY:{ - GetWindowText(GetDlgItem(wnd, IDC_TEXTBOX_LUASCRIPTPATH), - Config.LuaScriptPath, MAX_PATH); LuaMessage::Msg *msg = new LuaMessage::Msg(); msg->type = LuaMessage::DestroyLua; msg->destroyLua.wnd = wnd; @@ -657,8 +665,10 @@ INT_PTR CALLBACK DialogProc(HWND wnd, UINT msg, WPARAM wParam, LPARAM lParam) { return FALSE; } std::string OpenLuaFileDialog() { - EmulationLock lock; - + + int storePaused = emu_paused; + pauseEmu(1); + OPENFILENAME ofn; char filename[MAX_PATH] = ""; @@ -676,8 +686,13 @@ std::string OpenLuaFileDialog() { ofn.Flags = OFN_NOCHANGEDIR | OFN_HIDEREADONLY | OFN_FILEMUSTEXIST; ofn.lpstrInitialDir = NULL; - if(!GetOpenFileName(&ofn)) + if (!GetOpenFileName(&ofn)) { + if (!storePaused) resumeEmu(1); return ""; + } + + if (!storePaused) resumeEmu(1); + return ofn.lpstrFile; } void SetButtonState(HWND wnd, bool state) { @@ -710,6 +725,7 @@ BOOL WmCommand(HWND wnd, WORD id, WORD code, HWND control){ //strcpy(Config.LuaScriptPath, msg->runPath.path); anyLuaRunning = true; luaMessage.post(msg); + shouldSave = true; return TRUE; } case IDC_BUTTON_LUASTOP: { @@ -755,9 +771,13 @@ void CreateLuaWindow(void(*callback)()) { if(!luaDC) { InitializeLuaDC(mainHWND); } + + int LuaWndId = Config.LuaSimpleDialog ? IDD_LUAWINDOW_SIMPLIFIED : IDD_LUAWINDOW; + HWND wnd = CreateDialogParam(app_hInstance, - MAKEINTRESOURCE(IDD_LUAWINDOW), mainHWND, DialogProc, + MAKEINTRESOURCE(LuaWndId), mainHWND, DialogProc, (LPARAM)callback); + ShowWindow(wnd, SW_SHOW); //タブストップ利かないのと同じ原因だと思う } void ConsoleWrite(HWND wnd, const char *str) { @@ -2067,6 +2087,102 @@ int DrawRect(lua_State *L) { luaL_checknumber(L, 3), luaL_checknumber(L, 4)); return 0; } + +VOID checkGDIPlusInitialized() { + // will be inlined by compiler + if (!gdiPlusInitialized) { + printf("lua initialize gdiplus\n"); + Gdiplus::GdiplusStartupInput gdiplusStartupInput; + Gdiplus::GdiplusStartup(&gdiPlusToken, &gdiplusStartupInput, NULL); + gdiPlusInitialized = true; + } +} + +int FillPolygonAlpha(lua_State* L) { + + checkGDIPlusInitialized(); + Lua* lua = GetLuaClass(L); + + Gdiplus::PointF pt1; + Gdiplus::PointF pt2; + Gdiplus::PointF pt3; + byte a, r, g, b; + + pt1.X = luaL_checknumber(L, 1); + pt1.Y = luaL_checknumber(L, 2); + + pt2.X = luaL_checknumber(L, 3); + pt2.Y = luaL_checknumber(L, 4); + + pt3.X = luaL_checknumber(L, 5); + pt3.Y = luaL_checknumber(L, 6); + + a = luaL_checknumber(L, 7); + r = luaL_checknumber(L, 8); + g = luaL_checknumber(L, 9); + b = luaL_checknumber(L, 10); + + Gdiplus::Graphics gfx(luaDC); + Gdiplus::SolidBrush brush(Gdiplus::Color(a, r, g, b)); + + Gdiplus::PointF pts[3] = {pt1,pt2,pt3}; + gfx.FillPolygon(&brush, pts, 1); + + + return 0; +} + + +int FillEllipseAlpha(lua_State* L) { + checkGDIPlusInitialized(); + Lua* lua = GetLuaClass(L); + + int left, top, right, bottom; + byte a, r, g, b; + + bottom = luaL_checknumber(L, 1); + left = luaL_checknumber(L, 2); + right = luaL_checknumber(L, 3); + top = luaL_checknumber(L, 4); + + a = luaL_checknumber(L, 5); + r = luaL_checknumber(L, 6); + g = luaL_checknumber(L, 7); + b = luaL_checknumber(L, 8); + + Gdiplus::Graphics gfx(luaDC); + Gdiplus::SolidBrush brush(Gdiplus::Color(a, r, g, b)); + + gfx.FillEllipse(&brush, left, top, right, bottom); + + return 0; +} +int FillRectAlpha(lua_State* L) +{ + checkGDIPlusInitialized(); + + Lua* lua = GetLuaClass(L); + + int left, top, right, bottom; + byte a, r, g, b; + + bottom = luaL_checknumber(L, 1); + left = luaL_checknumber(L, 2); + right = luaL_checknumber(L, 3); + top = luaL_checknumber(L, 4); + + a = luaL_checknumber(L, 5); + r = luaL_checknumber(L, 6); + g = luaL_checknumber(L, 7); + b = luaL_checknumber(L, 8); + + Gdiplus::Graphics gfx(luaDC); + Gdiplus::SolidBrush brush(Gdiplus::Color(a, r, g, b)); + + gfx.FillRectangle(&brush, left, top, right, bottom); + + return 0; +} int FillRect(lua_State* L) { /* (Info) @@ -2994,7 +3110,13 @@ const luaL_Reg wguiFuncs[] = { {"text", TextOut}, {"drawtext", DrawText}, {"rect", DrawRect}, - {"fillrect", FillRect}, // Experimental + {"fillrect", FillRect}, + /**/ + // GDIPlus functions marked with "a" suffix + {"fillrecta", FillRectAlpha}, + {"fillellipsea", FillEllipseAlpha}, + {"fillpolygona", FillPolygonAlpha}, + /* +#include "win/main_win.h" +#include "../winproject/resource.h" //for menu id +#endif + +BOOL freezeRecentScript; + +//takes config and puts the entries to menu +void BuildRecentScriptsMenu(HWND hwnd) { + int i; + bool empty = false; + MENUITEMINFO menuinfo = { 0 }; + HMENU hMenu = GetMenu(hwnd); + HMENU hSubMenu = GetSubMenu(hMenu, 5); + hSubMenu = GetSubMenu(hSubMenu, 2); + //DeleteMenu(hSubMenu, ID_LUA_RECENT, MF_BYCOMMAND); //remove the "no recent scripts" entry, add later if in fact no recent + + menuinfo.cbSize = sizeof(MENUITEMINFO); + menuinfo.fMask = MIIM_TYPE | MIIM_ID; + menuinfo.fType = MFT_STRING; + menuinfo.fState = MFS_ENABLED; + for (i = 0; i < LUA_MAX_RECENT; i++) { + if (strcmp(Config.RecentScripts[i], "") == 0) + { + if (i == 0) + { + menuinfo.dwTypeData = "No recent scripts"; + empty = true; + } + else break; + } + else + menuinfo.dwTypeData = Config.RecentScripts[i]; + + + menuinfo.cch = strlen(menuinfo.dwTypeData); + menuinfo.wID = ID_LUA_RECENT + i; + InsertMenuItem(hSubMenu, i+3, TRUE, &menuinfo); + if (empty) EnableMenuItem(hSubMenu, ID_LUA_RECENT, MF_DISABLED); + } +} + +void ClearRecent(BOOL clear_array) { + int i; + HMENU hMenu; + + hMenu = GetMenu(mainHWND); + for (i = 0; i < LUA_MAX_RECENT; i++) { + DeleteMenu(hMenu, ID_LUA_RECENT + i, MF_BYCOMMAND); + } + if (clear_array) { + memset(Config.RecentScripts, 0, LUA_MAX_RECENT * sizeof(Config.RecentScripts[0])); + } + +} + +void RefreshRecent() +{ + //nuke the menu + ClearRecent(FALSE); + //rebuild + BuildRecentScriptsMenu(mainHWND); + + +} + + +//Adds path to recent paths, if already in list then just moves things around +//newer scripts are earlier in array +void AddToRecentScripts(char* path) +{ + if (Config.RecentScriptsFreeze) return; // fuck off? + + int i = 0; + //Either finds index of path in recent list, or stops at last one + //notice how it doesn't matter if last==path or not, we do same swapping later + for (; i0; --j) + { + strcpy(Config.RecentScripts[j], Config.RecentScripts[j-1]); + } + //now write to top + strcpy(Config.RecentScripts[0], path); + //rebuild menu + RefreshRecent(); +} + +void RunRecentScript(WORD menuItem) +{ + char path[MAX_PATH]; + int index = menuItem - ID_LUA_RECENT; + sprintf(path, Config.RecentScripts[index]); + LuaOpenAndRun(path); +} \ No newline at end of file diff --git a/lua/Recent.h b/lua/Recent.h new file mode 100644 index 00000000..127b07fc --- /dev/null +++ b/lua/Recent.h @@ -0,0 +1,12 @@ +#pragma once +#ifdef _WIN32 +#include //linux trolled + // lol +#endif +#define LUA_MAX_RECENT 5 + +//functions +void AddToRecentScripts(char* path); +void BuildRecentScriptsMenu(HWND); +void RunRecentScript(WORD); +void ClearRecent(BOOL); diff --git a/main/debughook.c b/main/debughook.c new file mode 100644 index 00000000..c37a4c27 --- /dev/null +++ b/main/debughook.c @@ -0,0 +1,12 @@ +//MSVC ONLY +#include "debughook.h" +#undef fwrite +size_t fwrite2(const void* ptr, size_t size, size_t count, FILE* stream){ + printf("Writing %d bytes: " ,size*count); + for (int i = 0; i < size * count; i++) + { + printf("%hhx", ((const char*)ptr)[i]); + } + printf("\n"); + return fwrite(ptr, size, count, stream); +} \ No newline at end of file diff --git a/main/debughook.h b/main/debughook.h new file mode 100644 index 00000000..9570d716 --- /dev/null +++ b/main/debughook.h @@ -0,0 +1,10 @@ +//MSVC ONLY, included with /FI option in debug target settings +#pragma once +#include + +size_t fwrite2(const void* ptr, size_t size, size_t count, FILE* stream); + +// Only use debug (much slower) fwrite on debug target +#ifdef _DEBUG +#define fwrite(a,b,c,d) fwrite2(a,b,c,d) +#endif \ No newline at end of file diff --git a/main/mupenIniApi.c b/main/mupenIniApi.c index f0904a13..5b71f8f2 100755 --- a/main/mupenIniApi.c +++ b/main/mupenIniApi.c @@ -132,6 +132,7 @@ void ini_openFile() { cur->next_entry = (iniElem*)malloc(sizeof(iniElem)); cur = cur->next_entry; + cur->next_entry = NULL; cur->next_crc = NULL; cur->next_MD5 = NULL; } diff --git a/main/plugin.c b/main/plugin.c index d4b46930..1d3b0958 100755 --- a/main/plugin.c +++ b/main/plugin.c @@ -60,11 +60,16 @@ AUDIO_INFO audio_info; static CONTROL_INFO control_info; static RSP_INFO rsp_info; + void (__cdecl*getDllInfo)(PLUGIN_INFO *PluginInfo); void (__cdecl*dllConfig)(HWND hParent); void (__cdecl*dllTest)(HWND hParent); void (__cdecl*dllAbout)(HWND hParent); + + + + /* dummy functions to prevent mupen from crashing if a plugin is missing */ static void __cdecl dummy_void() {} static BOOL __cdecl dummy_initiateGFX(GFX_INFO Gfx_Info) { return TRUE; } diff --git a/main/plugin.h b/main/plugin.h index e74a3a4b..031a1f2f 100755 --- a/main/plugin.h +++ b/main/plugin.h @@ -1,3 +1,4 @@ +#pragma once /** * Mupen64 - plugin.h * Copyright (C) 2002 Hacktarux @@ -51,6 +52,7 @@ void plugin_exec_config(const char *name); void plugin_exec_test(const char *name); void plugin_exec_about(const char *name); + /* Plugin types */ #define PLUGIN_TYPE_RSP 1 #define PLUGIN_TYPE_GFX 2 diff --git a/main/rom.c b/main/rom.c index aded8b49..3858f4ba 100755 --- a/main/rom.c +++ b/main/rom.c @@ -45,7 +45,9 @@ #include "md5.h" #include "mupenIniApi.h" #include "guifuncs.h" +#include "../main/win/Config.h" #include +#include static FILE *rom_file; static gzFile z_rom_file; @@ -90,14 +92,25 @@ static int findsize() // divide through 131072 works too but im sure compiler is smart enough } -bool validRomExt(std::string str) { +const char* getExt(const char* filename) { + const char* dot = strrchr(filename, '.'); + if (!dot || dot == filename) return ""; + return dot + 1; +} + +bool validRomExt(const char* filename) { +//#ifdef _DEBUG +// printf("%s\n", filename); +//#endif + const char* str = getExt(filename); + if (str == "\0" || str == "0") return 0; // z64,n64,v64,rom - const char* cstr = str.c_str(); - return stricmp(cstr, "z64") || - stricmp(cstr, "n64") || - stricmp(cstr, "v64") || - stricmp(cstr, "rom"); + return !stricmp(str, "z64") || + !stricmp(str, "n64") || + !stricmp(str, "v64") || + !stricmp(str, "rom"); } + static int find_file(char *argv) { z=0; @@ -165,10 +178,9 @@ int rom_read(const char *argv) char buf[1024], arg[1024], *s; strncpy(arg, argv, 1000); - std::string strfileName = argv; - if (strfileName.find_last_of(".") != std::string::npos - && !validRomExt(strfileName.substr(strfileName.find_last_of(".") + 1)) - && !ask_extension()) {goto killRom;} + + if (!validRomExt(argv) && !ask_extension()) + goto killRom; if (find_file(arg)) { @@ -187,9 +199,12 @@ int rom_read(const char *argv) } } } + + printf ("file found\n"); /*------------------------------------------------------------------------*/ - if (findsize() > 64 && !ask_hack())goto killRom; + if (findsize() > 64 && !ask_hack()) goto killRom; + if (rom) free(rom); rom = (unsigned char*)malloc(taille_rom); @@ -394,7 +409,7 @@ int fill_header(const char *argv) { char arg[1024]; strncpy(arg, argv, 1000); - if (find_file(arg)) + if (find_file(arg)/* || !validRomExt(argv) && Config.alertBAD */) { printf ("file not found or wrong path\n"); return 0; diff --git a/main/rom.h b/main/rom.h index 1c5d72ea..85b14402 100755 --- a/main/rom.h +++ b/main/rom.h @@ -34,7 +34,7 @@ int rom_read(const char *argv); int fill_header(const char *argv); bool iequals(const std::string& a, const std::string& b); -bool validRomExt(std::string str); +bool validRomExt(const char* filename); void calculateMD5(const char *argv, unsigned char digest[16]); extern unsigned char *rom; extern int taille_rom; diff --git a/main/savestates.c b/main/savestates.c index aab0cbb6..6bc3f423 100755 --- a/main/savestates.c +++ b/main/savestates.c @@ -253,8 +253,10 @@ void savestates_load(bool silenceNotFoundError) { if (f == NULL) { - if (silenceNotFoundError) return; - + if (silenceNotFoundError) { + printf("Silent st fail: Savestate \"%s\" not found.\n", filename); + return; + } if (slot > 9) { //print .st not .savestate because @@ -283,7 +285,7 @@ void savestates_load(bool silenceNotFoundError) gzclose(f); savestates_job_success = FALSE; - if (VCR_isRecording()) VCR_stopRecord(); + if (VCR_isRecording()) VCR_stopRecord(1); else VCR_stopPlayback(); return; } @@ -405,7 +407,7 @@ void savestates_load(bool silenceNotFoundError) } else { printWarning(errStr); - if (stop && VCR_isRecording()) VCR_stopRecord(); + if (stop && VCR_isRecording()) VCR_stopRecord(1); else if (stop) VCR_stopPlayback(); savestates_job_success = FALSE; goto failedLoad; @@ -424,7 +426,7 @@ void savestates_load(bool silenceNotFoundError) if (VCR_isPlaying()) VCR_stopPlayback(); else - VCR_stopRecord(); + VCR_stopRecord(1); } lockNoStWarn = false; //reset } diff --git a/main/vcr.c b/main/vcr.c index c100bd3e..1fa7870a 100644 --- a/main/vcr.c +++ b/main/vcr.c @@ -55,12 +55,14 @@ #define MUP_HEADER_SIZE_OLD (512) // bytes #define MUP_HEADER_SIZE (sizeof(SMovieHeader)) #define MUP_HEADER_SIZE_CUR (m_header.version <= 2 ? MUP_HEADER_SIZE_OLD : MUP_HEADER_SIZE) +#define MAX_AVI_SIZE 0x7B9ACA00 extern CONFIG Config; //stop AVI at m64 end, set by command line avi bool gStopAVI = false; bool captureMarkedStop; +BOOL dontPlay = false; #define BUFFER_GROWTH_SIZE (4096) @@ -128,11 +130,11 @@ static int soundBufPos = 0; long lastSound = 0; volatile BOOL captureFrameValid = FALSE; static int AVIBreakMovie = 0; - +int AVIIncrement = 0; int titleLength; extern void resetEmu(); -void SetActiveMovie(char* buf, int maxlen); +void SetActiveMovie(char* buf); static int startPlayback(const char *filename, const char *authorUTF8, const char *descriptionUTF8, const bool restarting); static int restartPlayback(); @@ -352,7 +354,7 @@ static void truncateMovie() { // truncate movie controller data to header.length_samples length - long truncLen = MUP_HEADER_SIZE + sizeof(BUTTONS)*(m_header.length_samples+1); + long truncLen = MUP_HEADER_SIZE + sizeof(BUTTONS)*(m_header.length_samples); #ifdef __WIN32__ HANDLE fileHandle = CreateFile(m_filename, GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, 0); @@ -478,7 +480,7 @@ void flush_movie() // (over-)write the controller data fseek(m_file, MUP_HEADER_SIZE, SEEK_SET); - fwrite(m_inputBuffer, 1, sizeof(BUTTONS)*(m_header.length_samples+1), m_file); + fwrite(m_inputBuffer, 1, sizeof(BUTTONS)*(m_header.length_samples), m_file); fflush(m_file); } @@ -868,6 +870,7 @@ VCR_getKeys( int Control, BUTTONS *Keys ) if (m_task == Idle) return; + if (m_task == StartRecording) { if(!continue_vcr_on_restart_mode) @@ -941,11 +944,12 @@ VCR_getKeys( int Control, BUTTONS *Keys ) //sprintf(str, "Couldn't find or load this movie's snapshot,\n\"%s\".\nMake sure that file is where Mupen64 can find it.", savestates_get_selected_filename()); //printError(str); m_task = Idle; - extern HWND mainHWND; - char title[MAX_PATH]; - GetWindowText(mainHWND, title, MAX_PATH); - title[titleLength] = '\0'; //remove movie being played part - SetWindowText(mainHWND, title); + if (!dontPlay) { + char title[MAX_PATH]; + GetWindowText(mainHWND, title, MAX_PATH); + title[titleLength] = '\0'; //remove movie being played part + SetWindowText(mainHWND, title); + } getKeys( Control, Keys ); return; } @@ -1073,7 +1077,7 @@ VCR_getKeys( int Control, BUTTONS *Keys ) int -VCR_startRecord( const char *filename, unsigned short flags, const char *authorUTF8, const char *descriptionUTF8 ) +VCR_startRecord( const char *filename, unsigned short flags, const char *authorUTF8, const char *descriptionUTF8, int defExt ) { VCR_coreStopped(); @@ -1135,14 +1139,18 @@ VCR_startRecord( const char *filename, unsigned short flags, const char *authorU break; } - strncat( buf, ".st", PATH_MAX ); + if(defExt) + strncat(buf,".st",PATH_MAX); + else + strncat(buf, ".savestate", PATH_MAX); + savestates_select_filename( buf ); savestates_job |= SAVESTATE; m_task = StartRecordingFromSnapshot; } else{ m_task = StartRecording; } - SetActiveMovie(buf, MAX_PATH); + SetActiveMovie(buf); setROMInfo(&m_header); // utf8 strings are also null-terminated so this method still works @@ -1170,7 +1178,7 @@ VCR_startRecord( const char *filename, unsigned short flags, const char *authorU int -VCR_stopRecord() +VCR_stopRecord(int defExt) { int retVal = -1; @@ -1187,7 +1195,12 @@ VCR_stopRecord() printf( "[VCR]: Removing files (nothing recorded)\n" ); strcpy( buf, m_filename ); - strncat( m_filename, ".st", PATH_MAX ); + + if (defExt) + strncat(m_filename, ".st", PATH_MAX); + else + strncat(m_filename, ".savestate", PATH_MAX); + if (_unlink( buf ) < 0) fprintf( stderr, "[VCR]: Couldn't remove save state: %s\n", strerror( errno ) ); @@ -1247,33 +1260,26 @@ VCR_stopRecord() //on titlebar, modifies passed buffer!! //if buffer == NULL, remove current active -void SetActiveMovie(char* buf,int maxlen) +void SetActiveMovie(char* buf) { static bool active = false; char title[MAX_PATH]; - if (buf == NULL && titleLength) + + if (!buf) { - GetWindowText(mainHWND, title, MAX_PATH); - title[titleLength] = '\0'; //remove movie being played part - SetWindowText(mainHWND, title); + sprintf(title, MUPEN_VERSION " - %s", ROM_HEADER->nom); } - else if(buf != NULL) + else if (buf) { - if (!buf) return; - //original length - titleLength = GetWindowText(mainHWND, title, MAX_PATH); + _splitpath(buf, 0, 0, buf, 0); - //trim trailing spaces because it looks weird - while (title[--titleLength] == ' '); - title[++titleLength] = '\0'; - - strcat(title, " | "); - strcat(title, buf); - strcat(title, ".m64"); - SetWindowText(mainHWND, title); + sprintf(title, MUPEN_VERSION " - %s | %s.m64", ROM_HEADER->nom, buf); } + printf("title %s\n", title); + SetWindowText(mainHWND, title); } + int VCR_startPlayback(const char *filename, const char *authorUTF8, const char *descriptionUTF8) { return startPlayback(filename, authorUTF8, descriptionUTF8, false); @@ -1311,10 +1317,15 @@ startPlayback( const char *filename, const char *authorUTF8, const char *descrip if (m_file == 0 && (m_file = fopen( buf, "rb" )) == 0) { fprintf( stderr, "[VCR]: Cannot start playback, could not open .m64 file '%s': %s\n", filename, strerror( errno ) ); - return -1; + RESET_TITLEBAR + if (m_file != NULL) + fclose(m_file); + return -1; } } - if (!restarting) SetActiveMovie(buf, MAX_PATH); // can crash when looping + fast forward, no need to change this + SetActiveMovie(buf); + // can crash when looping + fast forward, no need to change this + // this creates a bug, so i changed it -auru { int code = read_movie_header(m_file, &m_header); @@ -1325,7 +1336,7 @@ startPlayback( const char *filename, const char *authorUTF8, const char *descrip char warningStr [8092]; warningStr[0] = '\0'; - BOOL dontPlay = FALSE; + dontPlay = FALSE; if(!Controls[0].Present && (m_header.controllerFlags & CONTROLLER_1_PRESENT)) { @@ -1401,6 +1412,7 @@ startPlayback( const char *filename, const char *authorUTF8, const char *descrip { sprintf(str, "The movie was recorded with the ROM \"%s\",\nbut you are using the ROM \"%s\",\nso the movie probably won't play properly.\n", m_header.romNom, ROM_HEADER->nom); strcat(warningStr, str); + dontPlay = TRUE; } else { @@ -1408,22 +1420,24 @@ startPlayback( const char *filename, const char *authorUTF8, const char *descrip { sprintf(str, "The movie was recorded with a ROM with country code \"%d\",\nbut you are using a ROM with country code \"%d\",\nso the movie may not play properly.\n", m_header.romCountry, ROM_HEADER->Country_code); strcat(warningStr, str); + dontPlay = TRUE; } else if(ROM_HEADER && m_header.romCRC != ROM_HEADER->CRC1) { - sprintf(str, "The movie was recorded with a ROM that has CRC \"0x%x\",\nbut you are using a ROM with CRC \"0x%x\",\nso the movie may not play properly.\n", (unsigned int)m_header.romCRC, (unsigned int)ROM_HEADER->CRC1); + sprintf(str, "The movie was recorded with a ROM that has CRC \"0x%X\",\nbut you are using a ROM with CRC \"0x%X\",\nso the movie may not play properly.\n", (unsigned int)m_header.romCRC, (unsigned int)ROM_HEADER->CRC1); strcat(warningStr, str); + dontPlay = TRUE; } } if(strlen(warningStr) > 0) { - if(dontPlay) printError(warningStr); else printWarning(warningStr); } + extern char gfx_name[255]; extern char input_name[255]; extern char sound_name[255]; @@ -1466,7 +1480,9 @@ startPlayback( const char *filename, const char *authorUTF8, const char *descrip if (dontPlay) { - SetWindowText(mainHWND, MUPEN_VERSION); + RESET_TITLEBAR + if(m_file != NULL) + fclose(m_file); return -1; } @@ -1491,7 +1507,7 @@ startPlayback( const char *filename, const char *authorUTF8, const char *descrip #ifdef _WIN32 char buf[50]; sprintf(buf, "%d rr", m_header.rerecord_count); - + extern HWND hStatus; SendMessage(hStatus, SB_SETTEXT, 1, (LPARAM)buf); #endif @@ -1500,6 +1516,7 @@ startPlayback( const char *filename, const char *authorUTF8, const char *descrip char buf[100]; sprintf(buf, "[VCR]: Error playing movie: %s.\n", m_errCodeName[code]); printError(buf); + dontPlay = code != 0; // should be stable enough break; } @@ -1508,6 +1525,9 @@ startPlayback( const char *filename, const char *authorUTF8, const char *descrip if(m_header.startFlags & MOVIE_START_FROM_SNAPSHOT) { + // we cant wait for this function to return and then get check in emu(?) thread (savestates_load) + + // load state printf( "[VCR]: Loading state...\n" ); strcpy( buf, m_filename ); @@ -1522,7 +1542,34 @@ startPlayback( const char *filename, const char *authorUTF8, const char *descrip break; } + // TODO: FIXME: One should never fear threats. It's like with a dog. + // A dog senses when somebody wrote bad code, and bites. + char* bufnExt = (char*)malloc(strlen(buf)+11); + strcpy(bufnExt, buf); + strncat( buf, ".st", 4); + + FILE* stBuf; + + if ((stBuf = fopen(buf, "r"))) fclose(stBuf); + else + { + // try .savestate + strncat(bufnExt, ".savestate", 11); + + if ((stBuf = fopen(bufnExt, "r"))) fclose(stBuf); + else { + printf("[VCR]: Early Savestate exist check failed. No .savestate or .st found for movie!\n"); + RESET_TITLEBAR; + if (m_file != NULL) + fclose(m_file); + free(bufnExt); + return -1; + } + } + + free(bufnExt); + savestates_select_filename( buf ); savestates_job |= LOADSTATE; m_task = StartPlaybackFromSnapshot; @@ -1552,6 +1599,7 @@ int VCR_restartPlayback() { int restartPlayback() { + VCR_setReadOnly(true); // force read only int ret = startPlayback(m_filename, "", "", true); @@ -1594,7 +1642,8 @@ stopPlayback(bool bypassLoopSetting) } #ifdef __WIN32__ extern HWND mainHWND; - SetActiveMovie(NULL, 0); //remove from title + //SetActiveMovie(NULL); //remove from title + RESET_TITLEBAR // maybe #endif if (m_file && m_task != StartRecording && m_task != Recording) { @@ -1704,34 +1753,16 @@ VCR_updateScreen() return; } - if(VCRComp_GetSize() > 0x7B9ACA00) + + + if(VCRComp_GetSize() > MAX_AVI_SIZE) { - if(AVIBreakMovie) - { - VCRComp_finishFile(1); - AVIBreakMovie=2; - } - else - { - VCRComp_finishFile(1); - AVIBreakMovie=1; - } - int fnlen=strlen(AVIFileName); - if(AVIBreakMovie==2) - { - AVIFileName[fnlen-5]++; - if(AVIFileName[fnlen-5]==90) - AVIBreakMovie=1; - } - else - { - AVIFileName[fnlen+1]=AVIFileName[fnlen]; - AVIFileName[fnlen]=AVIFileName[fnlen-1]; - AVIFileName[fnlen-1]=AVIFileName[fnlen-2]; - AVIFileName[fnlen-2]=AVIFileName[fnlen-3]; - AVIFileName[fnlen-3]=AVIFileName[fnlen-4]; - AVIFileName[fnlen-4]=65; - } + static char* endptr; + VCRComp_finishFile(1); + if (!AVIIncrement) + endptr = AVIFileName + strlen(AVIFileName) -4; + //AVIIncrement + sprintf(endptr, "%d.avi", ++AVIIncrement); VCRComp_startFile( AVIFileName, width, height, visByCountrycode(), 0); } @@ -1868,7 +1899,7 @@ void VCR_aiLenChanged() short *p = (short *)((char*)rdram + (ai_register.ai_dram_addr & 0xFFFFFF)); char* buf = (char*)p; int aiLen = ai_register.ai_len; - + //printf("ailenchanged %p %d\n", p, aiLen); aiLenChanged(); if (m_capture == 0) return; @@ -1957,6 +1988,14 @@ int VCR_startCapture( const char *recFilename, const char *aviFilename, bool cod } init_readScreen(); #endif + + FILE* tmpf = fopen(aviFilename, "ab+"); + + if (!tmpf && MessageBox(0, "AVI capture might break because the file is inaccessible. Try anyway?", "File inaccessible", MB_TASKMODAL | MB_ICONERROR | MB_YESNO) == IDNO) + return -1; + + fclose(tmpf); + if (readScreen == 0) { printError("AVI capture failed because the active video plugin does not support ReadScreen()!"); @@ -2025,6 +2064,8 @@ void VCR_toggleLoopMovie() { m_loopMovie = !m_loopMovie; + extern bool lockNoStWarn; + lockNoStWarn = m_loopMovie; #ifdef __WIN32__ extern HWND mainHWND; @@ -2057,7 +2098,7 @@ VCR_stopCapture() #endif // VCR_stopPlayback(); VCRComp_finishFile(0); - AVIBreakMovie = 0; + AVIIncrement = 0; printf( "[VCR]: Capture finished.\n" ); // ShowInfo("VCR_stopCapture() done"); return 0; @@ -2078,7 +2119,7 @@ VCR_coreStopped() case StartRecording: case StartRecordingFromSnapshot: case Recording: - VCR_stopRecord(); + VCR_stopRecord(1); break; case StartPlayback: case StartPlaybackFromSnapshot: @@ -2159,7 +2200,10 @@ void VCR_updateFrameCounter () char rr[50]; if (VCR_isRecording()) { - sprintf(str, "%d (%d) %s", (int)m_currentVI, (int)m_currentSample, inputDisplay); + if (Config.zeroIndex) + sprintf(str, "%d (%d) %s", (int)m_currentVI-2, (int)m_currentSample-1, inputDisplay); + else + sprintf(str, "%d (%d) %s", (int)m_currentVI, (int)m_currentSample, inputDisplay); if (m_header.rerecord_count == 0) sprintf(rr, "%d rr", m_header.rerecord_count); else @@ -2167,7 +2211,10 @@ void VCR_updateFrameCounter () } else if (VCR_isPlaying()) { - sprintf(str, "%d/%d (%d/%d) %s", (int)m_currentVI, (int)VCR_getLengthVIs(), (int)m_currentSample, (int)VCR_getLengthSamples(), inputDisplay); + if (Config.zeroIndex) + sprintf(str, "%d/%d (%d/%d) %s", (int)m_currentVI-2, (int)VCR_getLengthVIs()-2, (int)m_currentSample-1, (int)VCR_getLengthSamples()-1, inputDisplay); + else + sprintf(str, "%d/%d (%d/%d) %s", (int)m_currentVI, (int)VCR_getLengthVIs(), (int)m_currentSample, (int)VCR_getLengthSamples(), inputDisplay); if (m_header.rerecord_count == 0) sprintf(rr, "%d rr", m_header.rerecord_count); else diff --git a/main/vcr.h b/main/vcr.h index 623a27da..384bba64 100755 --- a/main/vcr.h +++ b/main/vcr.h @@ -91,8 +91,8 @@ extern void VCR_movieFreeze (char** buf, unsigned long* size); extern int VCR_movieUnfreeze (const char* buf, unsigned long size); extern void VCR_clearAllSaveData(); -extern int VCR_startRecord( const char *filename, unsigned short flags, const char *authorUTF8, const char *descriptionUTF8 ); -extern int VCR_stopRecord(); +extern int VCR_startRecord( const char *filename, unsigned short flags, const char *authorUTF8, const char *descriptionUTF8, int defExt); +extern int VCR_stopRecord(int defExt); extern int VCR_startPlayback( const char *filename, const char *authorUTF8, const char *descriptionUTF8 ); extern int VCR_restartPlayback(); extern int VCR_stopPlayback(); diff --git a/main/win/Config.c b/main/win/Config.c index 8a226090..8981f788 100755 --- a/main/win/Config.c +++ b/main/win/Config.c @@ -29,6 +29,8 @@ #include "commandline.h" #include "../../winproject/resource.h" +#include "../lua/Recent.h" + #define CfgFileName "mupen64.cfg" extern int no_audio_delay; @@ -87,7 +89,7 @@ int ReadCfgInt(char* Section, char* Key, int DefaultValue) void LoadRecentRoms() { int i; - char tempStr[50]; + char tempStr[32]; Config.RecentRomsFreeze = ReadCfgInt("Recent Roms", "Freeze", 0); for (i = 0; i < MAX_RECENT_ROMS; i++) @@ -102,6 +104,20 @@ void LoadRecentRoms() } +//Loads recent scripts from .cfg +void LoadRecentScripts() +{ + char tempStr[32]; + Config.RecentScriptsFreeze = ReadCfgInt("Recent Scripts", "Freeze", 0); + for (unsigned i = 0; i < LUA_MAX_RECENT; i++) + { + + sprintf(tempStr, "RecentLua%d", i); + ReadCfgString("Recent Scripts", tempStr, "", Config.RecentScripts[i]); + } + +} + void ReadHotkeyConfig(int n, char* name, int cmd, int def) { HOTKEY* h; char t[128]; @@ -133,6 +149,7 @@ void WriteHotkeyConfig(int n, char* name) { void LoadConfig() { LoadRecentRoms(); + LoadRecentScripts(); // Language ReadCfgString("Language", "Default", "English", Config.DefaultLanguage); @@ -143,8 +160,8 @@ void LoadConfig() Config.WindowPosX = ReadCfgInt("Window", "X", (GetSystemMetrics(SM_CXSCREEN) - Config.WindowWidth) / 2); Config.WindowPosY = ReadCfgInt("Window", "Y", (GetSystemMetrics(SM_CYSCREEN) - Config.WindowHeight) / 2); //if mupen was closed by minimising - if (Config.WindowPosX < 0 || Config.WindowWidth < 0) { - printf("\nWindow size too small"); + if (Config.WindowPosX < MIN_WINDOW_W-1 || Config.WindowWidth < MIN_WINDOW_H-1) { + printf("window too small. attempting to fix\n"); Config.WindowWidth = 800; Config.WindowHeight = 600; Config.WindowPosX = (GetSystemMetrics(SM_CXSCREEN) - Config.WindowWidth) / 2; @@ -163,6 +180,7 @@ void LoadConfig() Config.FPSmodifier = ReadCfgInt("General", "Fps Modifier", 100); Config.skipFrequency = ReadCfgInt("General", "Skip Frequency", 8); Config.loopMovie = ReadCfgInt("General", "Loop Movie", 0); + Config.zeroIndex = ReadCfgInt("General", "Zero index", 0); Config.guiDynacore = ReadCfgInt("CPU", "Core", 1); @@ -315,6 +333,17 @@ void SaveRecentRoms() } } +void SaveRecentScripts() +{ + char tempStr[32]; + WriteCfgInt("Recent Scripts", "Freeze", Config.RecentScriptsFreeze); + for (unsigned i = 0; i < LUA_MAX_RECENT; i++) + { + sprintf(tempStr, "RecentLua%d", i); + WriteCfgString("Recent Scripts", tempStr, Config.RecentScripts[i]); + } +} + void SaveConfig() { saveWindowSettings(); @@ -322,6 +351,7 @@ void SaveConfig() if (!cmdlineNoGui) { saveBrowserSettings(); SaveRecentRoms(); + SaveRecentScripts(); } //Language @@ -339,6 +369,7 @@ void SaveConfig() WriteCfgInt("General", "Use Fps Modifier", Config.UseFPSmodifier); WriteCfgInt("General", "Skip Frequency", Config.skipFrequency); WriteCfgInt("General", "Loop Movie", Config.loopMovie); + WriteCfgInt("General", "Zero Index", Config.zeroIndex); //Advanced Vars WriteCfgInt("Advanced", "Start Full Screen", Config.StartFullScreen); diff --git a/main/win/CrashHandler.cpp b/main/win/CrashHandler.cpp new file mode 100644 index 00000000..3131b7f6 --- /dev/null +++ b/main/win/CrashHandler.cpp @@ -0,0 +1,66 @@ +#include "CrashHandler.h" +#include "main_win.h" +#include +#include +#include "../../winproject/resource.h" //MUPEN_VERSION +#include "vcr.h" + +//Attempt to find crashing module, finds closest base address to crash point which should be the module (right?) +//error - points to the error msg buffer +//addr - where did it crash +//len - current error length so it can append properly +//returns length of appended text +int FindModuleName(char *error, void* addr, int len) +{ + HMODULE hMods[1024]; + HANDLE hProcess = GetCurrentProcess(); + DWORD cbNeeded; + printf("addr: %p\n", addr); + if (EnumProcessModules(hProcess, hMods, sizeof(hMods), &cbNeeded)) + { + HMODULE maxbase = 0; + for (int i = 0; i < (cbNeeded / sizeof(HMODULE)); i++) + { + //find closest addr + if (hMods[i] > maxbase && hMods[i] < addr){ + maxbase = hMods[i]; + char modname[MAX_PATH]; + GetModuleBaseName(hProcess, maxbase, modname, sizeof(modname) / sizeof(char)); + printf("%s: %p\n", modname, maxbase);} + } + // Get the full path to the module's file. + char modname[MAX_PATH]; + if (GetModuleBaseName(hProcess, maxbase, modname,sizeof(modname) / sizeof(char))) + // write the address with module + return sprintf(error+len,"Addr:0x%p (%s 0x%p)\n", addr,modname,maxbase); + } + return 0; //what +} + +//builds da error message +LONG WINAPI ExceptionReleaseTarget(_EXCEPTION_POINTERS* ExceptionInfo) +{ + int len = 0; + char error[2048]; + void* addr = ExceptionInfo->ExceptionRecord->ExceptionAddress; + len += FindModuleName(error, addr, len); //appends to error as well + + //emu info + len += sprintf(error + len, "Version:" MUPEN_VERSION "\n"); + len += sprintf(error + len, "Gfx:%s\n", gfx_name); + len += sprintf(error + len, "Input:%s\n", input_name); + len += sprintf(error + len, "Audio:%s\n", sound_name); + len += sprintf(error + len, "rsp:%s\n", rsp_name); + extern int m_task; + //some flags + len += sprintf(error + len, "m_task:%d\n", m_task); + len += sprintf(error + len, "emu_launched:%d\n", emu_launched); + len += sprintf(error + len, "is_capturing_avi:%d\n", VCR_isCapturing()); + + FILE* f = fopen(CRASH_LOG, "w+"); //overwrite + fprintf(f, error); + fclose(f); + + int code = MessageBox(0, "Emulator crashed, press OK to try to continue\nCrash log saved to " CRASH_LOG, "Exception", MB_OKCANCEL | MB_ICONERROR); + return code == IDOK ? EXCEPTION_CONTINUE_EXECUTION : EXCEPTION_EXECUTE_HANDLER; +} \ No newline at end of file diff --git a/main/win/CrashHandler.h b/main/win/CrashHandler.h new file mode 100644 index 00000000..77be5cec --- /dev/null +++ b/main/win/CrashHandler.h @@ -0,0 +1,6 @@ +#pragma once +#include + +#define CRASH_LOG "crash.log" + +LONG WINAPI ExceptionReleaseTarget(_EXCEPTION_POINTERS* ExceptionInfo); \ No newline at end of file diff --git a/main/win/GUI_LogWindow.c b/main/win/GUI_LogWindow.c index 03a69617..83455283 100755 --- a/main/win/GUI_LogWindow.c +++ b/main/win/GUI_LogWindow.c @@ -20,13 +20,14 @@ #include "DebugView.h" #include "main_win.h" -int extLogger ; - +int extLogger; +//HINSTANCE dv_hInst; +HMODULE DVHandle; ///////////////// External Logger DLL ////////////////////////////////////////// int CreateExtLogger() { - HMODULE DVHandle; + char TempStr[MAX_PATH]; sprintf(TempStr,"%s%s",AppPath,"debugview.dll") ; @@ -36,23 +37,16 @@ int CreateExtLogger() if (DVHandle) { FileLog = (void (__cdecl *)(char *, ...)) GetProcAddress(DVHandle, "FileLog"); - OpenDV = (HWND (__cdecl *)(HINSTANCE, int)) GetProcAddress(DVHandle, "OpenDV"); - DVMsg = (void (__cdecl *)(int, char *, ...)) GetProcAddress(DVHandle, "DVMsg"); - CloseDV = (void (__cdecl *)(void)) GetProcAddress(DVHandle, "CloseDV"); - ShowDV = (void (__cdecl *)(int)) GetProcAddress(DVHandle, "ShowDV"); - SetUserIcon = (void (__cdecl *)(int, HICON)) GetProcAddress(DVHandle, "SetUserIcon"); - SetUserIconName = (void (__cdecl *)(int, char*)) GetProcAddress(DVHandle, "SetUserIconName"); - DVClear = (void (__cdecl*)( void )) GetProcAddress(DVHandle, "DVClear");; - OpenDV( DVHandle, DV_SHOW ); + OpenDV(DVHandle, DV_HIDE); // ShowDV( DV_HIDE ) ; return 1; @@ -63,24 +57,18 @@ int CreateExtLogger() } /* Show / Hide Management */ -void ShowLogWindow() { - if (extLogger) { - if (ShowDV) ShowDV( DV_SHOW ) ; - } +void ShowLogWindow() { + if (extLogger) ShowDV(DV_SHOW); } -void HideLogWindow() { - if (extLogger) { - if (ShowDV) ShowDV( DV_HIDE ) ; - } +void HideLogWindow() { + if (extLogger) ShowDV(DV_HIDE); } void ShowHideLogWindow() { - if (extLogger) { - if (ShowDV) ShowDV( DV_AUTO ) ; - } + if (extLogger) ShowDV(DV_AUTO); } @@ -162,13 +150,15 @@ void ClearLogWindow() int GUI_CreateLogWindow( HWND hwnd ) { - extLogger = CreateExtLogger() ; - return 0; + extLogger = CreateExtLogger(); + return extLogger; } void CloseLogWindow() { + // if this closes once you can never open it again + // probably this is just shitty programming because debugview source code isnt available if (extLogger) { - if (CloseDV) CloseDV() ; + if (CloseDV) CloseDV(); } } diff --git a/main/win/configdialog.c b/main/win/configdialog.c index 2d109102..f2f6cd3c 100755 --- a/main/win/configdialog.c +++ b/main/win/configdialog.c @@ -53,6 +53,37 @@ HWND hwndTrack ; extern int no_audio_delay; extern int no_compiled_jump; +BOOL CALLBACK OtherOptionsProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam) +{ + switch (Message) { + case WM_INITDIALOG: + WriteCheckBoxValue(hwnd, IDC_LUA_SIMPLEDIALOG, Config.LuaSimpleDialog); + WriteCheckBoxValue(hwnd, IDC_LUA_WARNONCLOSE, Config.LuaWarnOnClose); + return TRUE; + case WM_COMMAND: + switch (LOWORD(wParam)) + { + + } + break; + + case WM_NOTIFY: + if (((NMHDR FAR*) lParam)->code == PSN_APPLY) { + Config.LuaSimpleDialog = ReadCheckBoxValue(hwnd, IDC_LUA_SIMPLEDIALOG); + Config.LuaWarnOnClose = ReadCheckBoxValue(hwnd, IDC_LUA_WARNONCLOSE); + EnableToolbar(); + EnableStatusbar(); + FastRefreshBrowser(); + LoadConfigExternals(); + } + break; + + default: + return FALSE; + } + return TRUE; +} + void WriteCheckBoxValue( HWND hwnd, int resourceID , int value) { if (value) { @@ -90,10 +121,10 @@ void ReadComboBoxValue(HWND hwnd,int ResourceID,char *ret) } void ChangeSettings(HWND hwndOwner) { - PROPSHEETPAGE psp[5]; + PROPSHEETPAGE psp[6]; PROPSHEETHEADER psh; char ConfigStr[200],DirectoriesStr[200],titleStr[200],settingsStr[200]; - char AdvSettingsStr[200], HotkeysStr[200]; + char AdvSettingsStr[200], HotkeysStr[200], OtherStr[200]; psp[0].dwSize = sizeof(PROPSHEETPAGE); psp[0].dwFlags = PSP_USETITLE; psp[0].hInstance = app_hInstance; @@ -144,6 +175,16 @@ void ChangeSettings(HWND hwndOwner) { psp[4].lParam = 0; psp[4].pfnCallback = NULL; + psp[5].dwSize = sizeof(PROPSHEETPAGE); + psp[5].dwFlags = PSP_USETITLE; + psp[5].hInstance = app_hInstance; + psp[5].pszTemplate = MAKEINTRESOURCE(IDD_OTHER_OPTIONS_DIALOG); + psp[5].pfnDlgProc = OtherOptionsProc; + TranslateDefault("Other", "Other", OtherStr); + psp[5].pszTitle = OtherStr; + psp[5].lParam = 0; + psp[5].pfnCallback = NULL; + psh.dwSize = sizeof(PROPSHEETHEADER); psh.dwFlags = PSH_PROPSHEETPAGE | PSH_NOAPPLYNOW | PSH_NOCONTEXTHELP; psh.hwndParent = hwndOwner; @@ -685,6 +726,7 @@ BOOL CALLBACK GeneralCfg(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam) WriteCheckBoxValue( hwnd, IDC_LIMITFPS, Config.limitFps); WriteCheckBoxValue( hwnd, IDC_INI_COMPRESSED, Config.compressedIni); WriteCheckBoxValue( hwnd, IDC_SPEEDMODIFIER, Config.UseFPSmodifier ); + WriteCheckBoxValue(hwnd, IDC_0INDEX, Config.zeroIndex); SetDlgItemInt(hwnd, IDC_SKIPFREQ, Config.skipFrequency,0); CreateToolTip(IDC_SKIPFREQ, hwnd, "0 = Skip all frames, 1 = Show all frames, n = show every nth frame"); @@ -758,6 +800,7 @@ BOOL CALLBACK GeneralCfg(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam) Config.FPSmodifier = SendMessage( hwndTrack , TBM_GETPOS, 0, 0); Config.UseFPSmodifier = ReadCheckBoxValue( hwnd , IDC_SPEEDMODIFIER ); Config.skipFrequency = GetDlgItemInt(hwnd, IDC_SKIPFREQ,0,0); + Config.zeroIndex = ReadCheckBoxValue(hwnd, IDC_0INDEX); if (emu_launched) SetStatusMode( 2 ); else SetStatusMode( 0 ); InitTimer(); @@ -1269,6 +1312,8 @@ BOOL CALLBACK HotkeysProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam) return TRUE; } + + HWND WINAPI CreateTrackbar( HWND hwndDlg, // handle of dialog box (parent window) UINT iMin, // minimum value in trackbar range diff --git a/main/win/main_win.cpp b/main/win/main_win.cpp index a25675ec..07b2db38 100644 --- a/main/win/main_win.cpp +++ b/main/win/main_win.cpp @@ -17,6 +17,7 @@ #include "LuaConsole.h" +#include "Recent.h" #include "win/DebugInfo.hpp" #if defined(__cplusplus) && !defined(_MSC_VER) @@ -52,6 +53,7 @@ extern "C" { #include "RomSettings.h" #include "GUI_logwindow.h" #include "commandline.h" +#include "CrashHandler.h" #include "../vcr.h" #include "../../r4300/recomph.h" @@ -61,6 +63,9 @@ extern "C" { #include "../../memory/pif.h" #undef EMULATOR_MAIN_CPP_DEF +#include +#pragma comment (lib,"Gdiplus.lib") + extern void CountryCodeToCountryName(int countrycode,char *countryname); void StartMovies(); @@ -214,6 +219,7 @@ int recording; HWND hTool, mainHWND, hStatus, hRomList, hStatusProgress; HINSTANCE app_hInstance; BOOL manualFPSLimit = TRUE; +BOOL ignoreErrorEmulation = FALSE; char statusmsg[800]; char gfx_name[255]; @@ -221,6 +227,10 @@ char input_name[255]; char sound_name[255]; char rsp_name[255]; +char stroopConfigLine[150] = {0}; +#define INCOMPATIBLE_PLUGINS_AMOUNT 1 // this is so bad +const char pluginBlacklist[INCOMPATIBLE_PLUGINS_AMOUNT][256] = { "Azimer\'s Audio v0.7" }; + enum EThreadFuncState { TFS_INITMEM, @@ -493,11 +503,35 @@ static plugins *liste_plugins = NULL, *current; void insert_plugin(plugins *p, char *file_name, char *plugin_name, void *handle, int type,int num) { + + + + if (p->next) insert_plugin(p->next, file_name, plugin_name, handle, type, (p->type == type) ? num+1 : num); else { + for (int i = 0; i < INCOMPATIBLE_PLUGINS_AMOUNT; i++) + { + if (strstr(plugin_name, pluginBlacklist[i])) { + char* msg = (char*)malloc(sizeof(pluginBlacklist[i])); + + sprintf(msg, "A incompatible plugin with the name \"%s\" was detected.\ + \nIt is highly recommended to skip loading this plugin as not doing so might cause instability.\ + \nAre you sure you want to load this plugin?", plugin_name); + + int res = MessageBox(0, msg, "Incompatible plugin", MB_YESNO | MB_TOPMOST | MB_ICONWARNING); + + free(msg); + + if (res == IDNO) + return; + else + ; // todo: punch user in the face + + } + } p->next = (plugins*)malloc(sizeof(plugins)); p->next->type = type; p->next->handle = (HMODULE)handle; @@ -1257,7 +1291,7 @@ void pauseEmu(BOOL quiet) BOOL StartRom(char *fullRomPath) { - if (romBrowserbusy) { + if (romBrowserBusy) { display_status("Rom browser busy!"); return TRUE; } @@ -1501,8 +1535,8 @@ void CreateToolBarWindow(HWND hwnd) }; hTool = CreateToolbarEx (hwnd, - WS_CHILD | WS_VISIBLE | TBSTYLE_TOOLTIPS | TBSTYLE_FLAT | TBSTYLE_TRANSPARENT | - /*WS_CLIPCHILDREN | WS_CLIPSIBLINGS | CCS_NODIVIDER | CCS_NORESIZE |*/ CCS_ADJUSTABLE, + WS_CHILD | WS_VISIBLE | TBSTYLE_TOOLTIPS /* | */ + /*CS_ADJUSTABLE no this causes a bug...*/, IDC_TOOLBAR, 10, app_hInstance, IDB_TOOLBAR, (LPCTBBUTTON)&tbButtons, 13, 16, 16, 200, 25, sizeof (TBBUTTON)); @@ -1990,7 +2024,9 @@ LRESULT CALLBACK RecordMovieProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM if(Controls[3].Present && Controls[3].Plugin == PLUGIN_RUMBLE_PAK) strcat(tempbuf, " with rumble pak"); SetDlgItemText(hwnd,IDC_MOVIE_CONTROLLER4_TEXT2,tempbuf); - + + EnableWindow(GetDlgItem(hwnd, IDC_EXTSAVESTATE), 0); // workaround because initial selected button is "Start" + SetFocus(GetDlgItem(hwnd,IDC_INI_AUTHOR)); return FALSE; @@ -2026,7 +2062,10 @@ LRESULT CALLBACK RecordMovieProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM GetDlgItemText(hwnd,IDC_INI_MOVIEFILE,tempbuf,MAX_PATH); unsigned short flag = IsDlgButtonChecked(hwnd, IDC_FROMSNAPSHOT_RADIO) ? MOVIE_START_FROM_SNAPSHOT : IsDlgButtonChecked(hwnd, IDC_FROMSTART_RADIO) ? MOVIE_START_FROM_NOTHING : MOVIE_START_FROM_EEPROM; - if (strlen(tempbuf) == 0 || VCR_startRecord( tempbuf, flag, authorUTF8, descriptionUTF8 ) < 0) + + + + if (strlen(tempbuf) == 0 || VCR_startRecord( tempbuf, flag, authorUTF8, descriptionUTF8, !IsDlgButtonChecked(hwnd, IDC_EXTSAVESTATE)) < 0) { sprintf(tempbuf2, "Couldn't start recording\nof \"%s\".", tempbuf); MessageBox(hwnd, tempbuf2, "VCR", MB_OK); @@ -2080,7 +2119,18 @@ LRESULT CALLBACK RecordMovieProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM strcat(path_buffer, ".m64"); SetDlgItemText(hwnd,IDC_INI_MOVIEFILE,path_buffer); } - } break; + } + break; + + case IDC_FROMEEPROM_RADIO: + EnableWindow(GetDlgItem(hwnd, IDC_EXTSAVESTATE), 0); + break; + case IDC_FROMSNAPSHOT_RADIO: + EnableWindow(GetDlgItem(hwnd, IDC_EXTSAVESTATE), 1); + break; + case IDC_FROMSTART_RADIO: + EnableWindow(GetDlgItem(hwnd, IDC_EXTSAVESTATE), 0); + break; } break; } @@ -2105,7 +2155,7 @@ void OpenMovieRecordDialog() if (emu_launched&&!emu_paused) pauseEmu(FALSE) ; - DialogBox(GetModuleHandle(NULL), + DialogBox(GetModuleHandle(NULL), MAKEINTRESOURCE(IDD_MOVIE_RECORD_DIALOG), mainHWND, (DLGPROC)RecordMovieProc); if (emu_launched&&emu_paused&&!wasPaused) @@ -2382,10 +2432,17 @@ if(!continue_vcr_on_restart_mode) static DWORD WINAPI SoundThread(LPVOID lpParam) { - while (emu_launched) aiUpdate(1); + while (emu_launched) + aiUpdate(1); ExitThread(0); } +static DWORD WINAPI StartMoviesThread(LPVOID lpParam) +{ + Sleep(2000); + StartMovies(); + ExitThread(0); +} static DWORD WINAPI ThreadFunc(LPVOID lpParam) { @@ -2425,7 +2482,8 @@ static DWORD WINAPI ThreadFunc(LPVOID lpParam) SoundThreadHandle = CreateThread(NULL, 0, SoundThread, NULL, 0, &SOUNDTHREADID); ThreadFuncState = TFS_EMULATING; ShowInfo("Emu thread: Emulation started...."); - StartMovies(); // check commandline args + CreateThread(NULL, 0, StartMoviesThread, NULL, 0, NULL); + //StartMovies(); // check commandline args StartLuaScripts(); StartSavestate(); AtResetCallback(); @@ -2481,6 +2539,8 @@ void exit_emu(int postquit) freeRomDirList(); freeRomList(); freeLanguages(); + Gdiplus::GdiplusShutdown(gdiPlusToken); + //printf("free gdiplus\n"); PostQuitMessage (0); } } @@ -2531,7 +2591,15 @@ void ProcessToolTips(LPARAM lParam, HWND hWnd) lpttt->lpszText = TempMessage; break; case EMU_PLAY: - TranslateDefault("Start/Resume Emulation", "Start/Resume Emulation", TempMessage); + if (!emu_launched) { + TranslateDefault("Start Emulation", "Start Emulation", TempMessage); + } + else if (emu_paused) { + TranslateDefault("Resume Emulation", "Resume Emulation", TempMessage); + } + else { + TranslateDefault("Emulating", "Emulating", TempMessage); + } lpttt->lpszText = TempMessage; break; case EMU_PAUSE: @@ -2689,9 +2757,24 @@ LRESULT CALLBACK WndProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam) else if (lstrcmp(fext, ".M64") == 0) { if (rom) { if (!VCR_getReadOnly()) VCR_toggleReadOnly(); - VCR_startPlayback(fname, 0, 0); - EnableMenuItem(hMenu, ID_STOP_RECORD, MF_GRAYED); - EnableMenuItem(hMenu, ID_STOP_PLAYBACK, MF_ENABLED); + + if (VCR_startPlayback(fname, 0, 0) < 0) { + //sprintf(fname2, "Couldn't start playback\nof \"%s\".", fname); + //MessageBox(hwnd, fname2, "VCR", MB_OK|MB_ICONERROR); + printf("[VCR]: Drag drop Failed to start playback of %s", fname); + break; + } + else { + HMENU hMenu = GetMenu(mainHWND); + EnableMenuItem(hMenu, ID_STOP_RECORD, MF_GRAYED); + EnableMenuItem(hMenu, ID_STOP_PLAYBACK, MF_ENABLED); + if (!emu_paused || !emu_launched) + SetStatusTranslatedString(hStatus, 0, "Playback started..."); + else + SetStatusTranslatedString(hStatus, 0, "Playback started. (Paused)"); + + } + } } else if (strcmp(fext, ".ST") ==0 || strcmp(fext, ".SAVESTATE") == 0) { @@ -2703,7 +2786,8 @@ LRESULT CALLBACK WndProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam) else if (strcmp(fext, ".LUA")==0) { if (rom) { for (; *fext; ++fext) *fext = tolower(*fext); // Deep in the code, lua will access file with that path (uppercase extension because stupid, useless programming at line 2677 converts it), see it doesnt exist and fail. - LuaOpenAndRun(fname); + // even this hack will fail under special circumstances + LuaOpenAndRun(fname); } } @@ -2789,6 +2873,7 @@ LRESULT CALLBACK WndProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam) TranslateMenu(GetMenu( hwnd), hwnd); CreateRomListControl( hwnd); SetRecentList( hwnd); + BuildRecentScriptsMenu(hwnd); EnableToolbar(); EnableStatusbar(); //////////////////////////// @@ -2825,6 +2910,14 @@ LRESULT CALLBACK WndProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam) // return 0; case WM_WINDOWPOSCHANGING: //allow gfx plugin to set arbitrary size return 0; + case WM_GETMINMAXINFO: + { + LPMINMAXINFO lpMMI = (LPMINMAXINFO)lParam; + lpMMI->ptMinTrackSize.x = MIN_WINDOW_W; + lpMMI->ptMinTrackSize.y = MIN_WINDOW_H; + // this might break small res with gfx plugin!!! + } + break; case WM_ENTERMENULOOP: AutoPause = emu_paused; if (!emu_paused) @@ -2874,6 +2967,18 @@ LRESULT CALLBACK WndProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam) ::NewLuaScript((void(*)())lParam); #endif } break; + case ID_LUA_RECENT_FREEZE: { + HMENU hMenu; + hMenu = GetMenu(mainHWND); + CheckMenuItem(hMenu, ID_LUA_RECENT_FREEZE, (Config.RecentScriptsFreeze ^= 1) ? MF_CHECKED : MF_UNCHECKED); + shouldSave = TRUE; + break; + } + case ID_LUA_RECENT_RESET: { + ClearRecent(TRUE); + BuildRecentScriptsMenu(hwnd); + break; + } case ID_MENU_LUASCRIPT_CLOSEALL: { #ifdef LUA_CONSOLE @@ -3048,23 +3153,32 @@ LRESULT CALLBACK WndProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam) { BOOL temppaused = !emu_paused; pauseEmu(TRUE); - char buf[31]; - char res; + + // todo: simplify + + // maybe pack formatted and buffer and result into one long char array where you only read necessary part + + char buf[12]; // ram start sprintf(buf, "0x%#08p", rdram); - std::string stdstr_buf = buf; - FILE* file = fopen("ramstart.txt", "w"); - fputs(buf, file); - fflush(file); fclose(file); -#ifdef _WIN32 // This will only work on windows - res = MessageBoxA(0, stdstr_buf.c_str(), "RAM Start (Click Yes to Copy)", MB_ICONINFORMATION | MB_TASKMODAL | MB_YESNO); - printf("Buffer size: %d\n", stdstr_buf.size()); - printf("Buffer length: %d\n", stdstr_buf.length()); - if (res == IDYES) { + + if (!stroopConfigLine[0]) { + TCHAR procName[MAX_PATH]; + GetModuleFileName(NULL, procName, MAX_PATH); + _splitpath(procName, 0, 0, procName, 0); + + sprintf(stroopConfigLine, "", procName, buf); + + + + } + std::string stdstr_buf = stroopConfigLine; +#ifdef _WIN32 + if (MessageBoxA(0, buf, "RAM Start (Click Yes to Copy STROOP config line)", MB_ICONINFORMATION | MB_TASKMODAL | MB_YESNO) == IDYES) { OpenClipboard(mainHWND); EmptyClipboard(); - HGLOBAL hg = GlobalAlloc(GMEM_MOVEABLE, stdstr_buf.size()+1); + HGLOBAL hg = GlobalAlloc(GMEM_MOVEABLE, stdstr_buf.size() + 1); if (hg) { - memcpy(GlobalLock(hg), stdstr_buf.c_str(), stdstr_buf.size()+1); + memcpy(GlobalLock(hg), stdstr_buf.c_str(), stdstr_buf.size() + 1); GlobalUnlock(hg); SetClipboardData(CF_TEXT, hg); CloseClipboard(); @@ -3072,10 +3186,11 @@ LRESULT CALLBACK WndProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam) } else { printf("Failed to copy"); CloseClipboard(); } } - + #endif + if (temppaused) { resumeEmu(TRUE); CheckMenuItem(GetMenu(mainHWND), EMU_PAUSE, MF_BYCOMMAND | MFS_UNCHECKED); @@ -3191,7 +3306,7 @@ LRESULT CALLBACK WndProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam) strcpy(path_buffer,""); oifn.lpstrFile = path_buffer, oifn.nMaxFile = sizeof(path_buffer); - oifn.lpstrFilter = "Mupen 64 Saves(*.st)\0*.st;*.st?\0All Files\0*.*\0"; + oifn.lpstrFilter = "Mupen 64 Saves(*.st;*.savestate)\0*.st;*.st?;*.savestate\0All Files\0*.*\0"; oifn.lpstrFileTitle = ""; oifn.nMaxFileTitle = 0; oifn.lpstrInitialDir = ""; @@ -3209,7 +3324,7 @@ LRESULT CALLBACK WndProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam) break; case ID_STOP_RECORD: - if (VCR_stopRecord() < 0) + if (VCR_stopRecord(1) < 0) // seems ok (no) ; // fail quietly // MessageBox(NULL, "Couldn't stop recording.", "VCR", MB_OK); else { @@ -3392,6 +3507,10 @@ LRESULT CALLBACK WndProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam) } else if (LOWORD(wParam) >= ID_RECENTROMS_FIRST && LOWORD(wParam) < (ID_RECENTROMS_FIRST + MAX_RECENT_ROMS)) { RunRecentRom(LOWORD(wParam)); + } + else if (LOWORD(wParam) >= ID_LUA_RECENT && LOWORD(wParam) < (ID_LUA_RECENT + LUA_MAX_RECENT)) { + printf("run recent script\n"); + RunRecentScript(LOWORD(wParam)); } break; } @@ -3493,6 +3612,7 @@ void LoadConfigExternals() { savestates_ignore_nonmovie_warnings = Config.IgnoreStWarnings; } + int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { @@ -3521,7 +3641,6 @@ int WINAPI WinMain( CreateDirectory((path + "ScreenShots").c_str(), NULL); CreateDirectory((path + "plugin").c_str(), NULL); } - emu_launched = 0; emu_paused = 1; /************ Loading Config *******/ @@ -3624,16 +3743,17 @@ int WINAPI WinMain( ShowWindow(hwnd, nCmdShow); // This fixes offscreen recording issue SetWindowLong(hwnd, GWL_EXSTYLE, WS_EX_ACCEPTFILES | WS_EX_LAYERED); //this can't be applied before ShowWindow(), otherwise you must use some fancy function - UpdateWindow(hwnd); + BringWindowToTop(hRomList); + ListView_SetExtendedListViewStyleEx(hRomList, LVS_EX_DOUBLEBUFFER, LVS_EX_DOUBLEBUFFER); + UpdateWindow(hwnd); #endif + EnableMenuItem(GetMenu(hwnd), ID_LOG_WINDOW, MF_DISABLED); #ifdef _DEBUG - GUI_CreateLogWindow(hwnd); + if(GUI_CreateLogWindow(mainHWND)) EnableMenuItem(GetMenu(hwnd), ID_LOG_WINDOW, MF_ENABLED); #endif - if (!extLogger) - { - //DeleteMenu( GetMenu(hwnd), ID_LOG_WINDOW, MF_BYCOMMAND); - EnableMenuItem(GetMenu(hwnd), ID_LOG_WINDOW, MF_GRAYED); - } + + + if (!isKailleraExist()) { @@ -3652,6 +3772,10 @@ int WINAPI WinMain( LoadConfigExternals(); + //warning, this is ignored when debugger is attached (like visual studio) + SetUnhandledExceptionFilter(ExceptionReleaseTarget); + //example + //RaiseException(1, 0, 0, 0); //shows messagebox from wntdll while(GetMessage(&Msg, NULL, 0, 0) > 0) { if (!TranslateAccelerator(mainHWND,Accel,&Msg) diff --git a/main/win/main_win.h b/main/win/main_win.h index eec12792..258ca068 100755 --- a/main/win/main_win.h +++ b/main/win/main_win.h @@ -14,6 +14,9 @@ * * ***************************************************************************/ + //for max recent +#include "../lua/Recent.h" + #ifndef MAIN_WIN_H #define MAIN_WIN_H @@ -94,6 +97,7 @@ typedef struct _CONFIG { int FPSmodifier; int skipFrequency; BOOL loopMovie; + BOOL zeroIndex; // Advanced vars BOOL StartFullScreen; @@ -149,14 +153,21 @@ typedef struct _CONFIG { bool captureOtherWindows; HOTKEY hotkey [NUM_HOTKEYS]; - //Lua - char LuaScriptPath[MAX_PATH]; + //Lua + char LuaScriptPath[MAX_PATH]; + char RecentScripts[LUA_MAX_RECENT][MAX_PATH]; + BOOL RecentScriptsFreeze; + BOOL LuaSimpleDialog; + BOOL LuaWarnOnClose; } CONFIG; extern "C" CONFIG Config; extern BOOL forceIgnoreRSP; extern BOOL continue_vcr_on_restart_mode; +extern BOOL ignoreErrorEmulation; #define IGNORE_RSP (((!Config.limitFps || !manualFPSLimit) && (!Config.skipFrequency || (frame++ % Config.skipFrequency)))) //if frame advancing and either skipfreq is 0 or modulo is 0 +#define RESET_TITLEBAR char tmpwndtitle[200]; sprintf(tmpwndtitle, MUPEN_VERSION " - %s", ROM_HEADER->nom); SetWindowText(mainHWND, tmpwndtitle); + #endif diff --git a/main/win/rombrowser.c b/main/win/rombrowser.c index 2ffca837..aee4ced4 100755 --- a/main/win/rombrowser.c +++ b/main/win/rombrowser.c @@ -14,6 +14,7 @@ * * ***************************************************************************/ + #include #include #include @@ -52,8 +53,8 @@ int RomBrowserFieldsWidth[ROM_COLUMN_FIELDS] = {250,150,70,70,200,100,100}; int RealColumn[ROM_COLUMN_FIELDS] = {0,2,3,4,-1,-1,-1}; static DWORD Id; -HANDLE romBrowserRefreshThread; -bool romBrowserbusy; +HANDLE romBrowserRefreshThread = NULL; +int romBrowserBusy = 0; char *getFieldName(int col) { @@ -876,11 +877,9 @@ void AddDirToList(char RomBrowserDir[MAX_PATH],BOOL sortflag) strcpy(FullPath,RomBrowserDir); if (FullPath[strlen(RomBrowserDir) - 1] != '\\') { strcat(FullPath,"\\"); } strcat(FullPath,fd.cFileName); - std::string strfileName = FullPath; - if (strfileName.find_last_of(".") != std::string::npos - && !validRomExt(strfileName.substr(strfileName.find_last_of(".") + 1)) && Config.alertBAD) { - continue; - } + + if ((Config.alertBAD||Config.alertHACK) && !validRomExt(FullPath)) continue; + if ((fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0) { if (Config.RomBrowserRecursion) { AddDirToList(FullPath,FALSE); } @@ -990,6 +989,7 @@ void FastRefreshBrowser() ListViewSort(); } DWORD WINAPI RefreshRomBrowserInternal(LPVOID tParam) { + romBrowserBusy = TRUE; remove(get_cachepath()); SaveRomBrowserDirs(); TOTAL_ROMS_NUMBER = 0; @@ -997,15 +997,13 @@ DWORD WINAPI RefreshRomBrowserInternal(LPVOID tParam) { ListView_DeleteAllItems(hRomList); freeRomList(); LoadRomList(); - romBrowserbusy = false; - TerminateThread(romBrowserRefreshThread,0); // is it a good idea for thread to kill itself - // vs is warning too about this... better way? + romBrowserBusy = FALSE; + ExitThread(0); return 0; } void RefreshRomBrowser() { - romBrowserbusy = true; romBrowserRefreshThread = CreateThread(NULL, 0, RefreshRomBrowserInternal, NULL, 0, &Id); } @@ -1157,6 +1155,9 @@ void ClearRecentList (HWND hwnd,BOOL clear_array) { HMENU hMenu; hMenu = GetMenu(hwnd); + //apparently not needed because windows still is able to find the correct items + //hMenu = GetSubMenu(hMenu, 0); + //hMenu = GetSubMenu(hMenu, 5); for (i = 0; i < MAX_RECENT_ROMS; i ++ ) { DeleteMenu(hMenu, ID_RECENTROMS_FIRST + i, MF_BYCOMMAND); } @@ -1168,22 +1169,21 @@ void ClearRecentList (HWND hwnd,BOOL clear_array) { void SetRecentList(HWND hwnd) { int i; - HMENU hMenu, hSubMenu ; MENUITEMINFO menuinfo; FreezeRecentRoms( hwnd, FALSE ) ; + HMENU hMenu = GetMenu(hwnd); + HMENU hSubMenu = GetSubMenu(hMenu, 0); + hSubMenu = GetSubMenu(hSubMenu, 5); + + menuinfo.cbSize = sizeof(MENUITEMINFO); + menuinfo.fMask = MIIM_TYPE | MIIM_ID; + menuinfo.fType = MFT_STRING; + menuinfo.fState = MFS_ENABLED; for ( i = 0 ; i < MAX_RECENT_ROMS ; i++) { if ( strcmp( Config.RecentRoms[i], "")==0 ) continue; - hMenu = GetMenu(hwnd) ; - hSubMenu = GetSubMenu(hMenu,0); - hSubMenu = GetSubMenu(hSubMenu,5); - - menuinfo.cbSize = sizeof(MENUITEMINFO); - menuinfo.fMask = MIIM_TYPE|MIIM_ID; - menuinfo.fType = MFT_STRING; - menuinfo.fState = MFS_ENABLED; menuinfo.dwTypeData = ParseName( Config.RecentRoms[i]); - menuinfo.cch = sizeof( hSubMenu); + menuinfo.cch = strlen(menuinfo.dwTypeData); menuinfo.wID = ID_RECENTROMS_FIRST + i; InsertMenuItem( hSubMenu, 3 + i, TRUE, &menuinfo); diff --git a/main/win/rombrowser.h b/main/win/rombrowser.h index eb6aba63..6fc5b916 100755 --- a/main/win/rombrowser.h +++ b/main/win/rombrowser.h @@ -105,7 +105,8 @@ ROM_INFO *getSelectedRom(); extern HWND romInfoHWND ; extern ITEM_LIST ItemList; -extern bool romBrowserbusy; +extern HANDLE romBrowserRefreshThread; +extern int romBrowserBusy; #define ROM_COLUMN_FIELDS 7 #define MAX_RECENT_ROMS 10 diff --git a/main/win/timers.c b/main/win/timers.c index fc16cc6f..50ad5948 100755 --- a/main/win/timers.c +++ b/main/win/timers.c @@ -107,9 +107,22 @@ void new_vi() { // fps wont update when emu is stuck so we must check vi/s // vi/s shouldn't go over 300 in normal gameplay while holding down fast forward unless you have repeat speed at uzi speed - if (emu_launched && frame_advancing && VIs > 300 && MessageBox(NULL, "Emulation problem detected, close rom?", "Warning", MB_ICONWARNING | MB_YESNO | MB_TOPMOST | MB_TASKMODAL) == IDYES) { - frame_advancing = false; //don't pause at next open - CreateThread(NULL, 0, closeRom, (LPVOID)1, 0, 0); + if (!ignoreErrorEmulation && emu_launched && frame_advancing && VIs > 300) { + int res = MessageBox(NULL, "Emulation problem detected\nPress Abort to close the rom\nPress Retry to continue emulation\nPress ignore to not show this again", "Error", MB_ICONERROR | MB_ABORTRETRYIGNORE | MB_TOPMOST | MB_TASKMODAL); + switch (res) + { + case IDABORT: + frame_advancing = false; //don't pause at next open + CreateThread(NULL, 0, closeRom, (LPVOID)1, 0, 0); + break; + case IDIGNORE: + ignoreErrorEmulation = TRUE; + break; + default: + // dame tu cosita uh ay + break; + } + } //#endif diff --git a/memory/pif.c b/memory/pif.c index 66626321..15065c1f 100755 --- a/memory/pif.c +++ b/memory/pif.c @@ -548,17 +548,14 @@ void update_pif_read(bool stcheck) } } } - if (stcheck) { - if (!input_delay) { - if (savestates_job & SAVESTATE && stAllowed) - { - savestates_save(); - savestates_job &= ~SAVESTATE; - } + if (stcheck && !input_delay) { + if (savestates_job & SAVESTATE && stAllowed) + { + savestates_save(); + savestates_job &= ~SAVESTATE; } } - if (savestates_job & LOADSTATE && stAllowed) - { + if (savestates_job & LOADSTATE && stAllowed) { savestates_load(false); savestates_job &= ~LOADSTATE; } @@ -610,4 +607,4 @@ void update_pif_read(bool stcheck) printf("---------------------------------\n"); #endif //printf("pif exit\n"); -} \ No newline at end of file +} diff --git a/memory/tlb.c b/memory/tlb.c index eda59621..0633f45e 100755 --- a/memory/tlb.c +++ b/memory/tlb.c @@ -38,7 +38,7 @@ unsigned long tlb_LUT_w[0x100000]; extern unsigned long interp_addr; unsigned long virtual_to_physical_address(unsigned long addresse, int w) { - if (addresse >= 0x7f000000 && addresse < 0x80000000) // golden eye hack + if (addresse >= 0x7f000000 && addresse < 0x80000000) // golden eye hack (it uses TLB a lot) { if (ROM_HEADER->CRC1 == sl(0xDCBC50D1)) // US return 0xb0034b30 + (addresse & 0xFFFFFF); diff --git a/r4300/exception.c b/r4300/exception.c index 29d8d760..2fbf586d 100755 --- a/r4300/exception.c +++ b/r4300/exception.c @@ -35,12 +35,14 @@ extern unsigned long interp_addr; +//Unused, this seems to be handled in pure_interp.c prefetch() void address_error_exception() { printf("address_error_exception\n"); stop=1; } +//Unused, an TLB entry is marked as invalid void TLB_invalid_exception() { if (delay_slot) @@ -53,12 +55,14 @@ void TLB_invalid_exception() stop=1; } +//Unused, 64-bit miss (is this even used on n64?) void XTLB_refill_exception(unsigned long long int addresse) { printf("XTLB refill exception\n"); stop=1; } +//Means no such virtual->physical translation exists void TLB_refill_exception(unsigned long address, int w) { int usual_handler = 0, i; @@ -144,32 +148,43 @@ void TLB_refill_exception(unsigned long address, int w) } } +//Unused, aka TLB modified Exception, entry is not writable void TLB_mod_exception() { printf("TLB mod exception\n"); stop=1; } +//Unused void integer_overflow_exception() { printf("integer overflow exception\n"); stop=1; } +//Unused, handled somewhere else void coprocessor_unusable_exception() { printf("coprocessor_unusable_exception\n"); stop=1; } +//General handler, passes execution to default n64 handler void exception_general() { update_count(); + //EXL bit, 1 = exception level Status |= 2; + //Exception return address if (!interpcore) EPC = PC->addr; else EPC = interp_addr; + //printf("exception, Cause: %x EPC: %x \n", Cause, EPC); + + //Highest bit of Cause tells if exception has been executed in branch delay slot + //delay_slot seems to always be 0 or 1, why is there reference to 3 ? + //if delay_slot, arrange the registers as it should be on n64 (emu uses a variable) if(delay_slot==1 || delay_slot==3) { Cause |= 0x80000000; @@ -177,8 +192,10 @@ void exception_general() } else { - Cause &= 0x7FFFFFFF; + Cause &= 0x7FFFFFFF; //make sure its cleared? } + + //exception handler is always at 0x80000180, continue there if (interpcore) { interp_addr = 0x80000180; diff --git a/r4300/pure_interp.c b/r4300/pure_interp.c index c2f851e6..35cfce3a 100755 --- a/r4300/pure_interp.c +++ b/r4300/pure_interp.c @@ -3104,6 +3104,7 @@ void (*interp_ops[64])(void) = SC , SWC1 , NI , NI , NI , SDC1, NI , SD }; +//Get opcode from address (interp_address) void prefetch() { //static FILE *f = NULL; @@ -3151,7 +3152,8 @@ void prefetch() } else { - printf("execution ・l'addresse :%x\n", (int)interp_addr); + //unmapped memory exception + printf("Exception, attempt to prefetch unmapped memory at: %x\n", (int)interp_addr); stop=1; } } diff --git a/r4300/r4300.c b/r4300/r4300.c index 435d5df6..435ae617 100755 --- a/r4300/r4300.c +++ b/r4300/r4300.c @@ -1409,6 +1409,9 @@ static inline unsigned long update_invalid_addr(unsigned long addr) unsigned long jump_to_address; inline void jump_to_func() { +//#ifdef _DEBUG +// printf("dyna jump: %p\n", addr); +//#endif unsigned long paddr; if (skip_jump) return; paddr = update_invalid_addr(addr); diff --git a/tasinput_plugin/src/DI.cpp b/tasinput_plugin/src/DI.cpp index 00e50f8c..7a161039 100755 --- a/tasinput_plugin/src/DI.cpp +++ b/tasinput_plugin/src/DI.cpp @@ -98,6 +98,11 @@ BOOL CALLBACK DIEnumDevicesCallback( LPCDIDEVICEINSTANCE lpddi, LPVOID pvRef) { bOK = FALSE; } } + if (DInputDev[nCurrentDevices].lpDIDevice == NULL) + { + MessageBox(0, "Fatal device error, please report issue on github", "error", MB_ICONERROR); + return DIENUM_CONTINUE; + } if (bOK == TRUE) { DInputDev[nCurrentDevices].lpDIDevice->Acquire(); diff --git a/tasinput_plugin/src/DefDI.cpp b/tasinput_plugin/src/DefDI.cpp old mode 100755 new mode 100644 index 258f0627..5e2dde00 --- a/tasinput_plugin/src/DefDI.cpp +++ b/tasinput_plugin/src/DefDI.cpp @@ -44,6 +44,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #define PI 3.14159265358979f #define BUFFER_CHUNK 128 +#undef List // look at line 32 for cause #define aCombo ComboList.at(activeCombo) //so it's a bit cleaner HINSTANCE g_hInstance; @@ -61,6 +62,8 @@ bool romIsOpen = false; HMENU hMenu; HANDLE fakeStatusThread = NULL; // fake! used for testing plugin +bool validatedhTxtbox = FALSE; +UINT systemDPI; bool lock; //don't focus mupen FILE* cFile; /*combo file conains list of combos in format: @@ -185,6 +188,7 @@ struct Status BUTTONS buttonOverride, buttonAutofire, buttonAutofire2; BUTTONS buttonDisplayed; BUTTONS LastControllerInput; + BUTTONS LastPureControllerInput; //without overrides/combo HWND statusDlg; HWND prevHWnd; HWND lBox; @@ -211,6 +215,7 @@ struct Status bool IsWindowFromEmulatorProcessActive (); static bool IsAnyStatusDialogActive (); LRESULT StatusDlgMethod (UINT msg, WPARAM wParam, LPARAM lParam); + void UpdateVisuals(BUTTONS ControllerInput); void GetKeys(BUTTONS * Keys); void SetKeys(BUTTONS ControllerInput); }; @@ -219,11 +224,14 @@ int Status::frameCounter = 0; Status status [NUMBER_OF_CONTROLS]; +//#define STICKPIC_SIZE (131) -#define STICKPIC_SIZE (131) +// todo split into x y +UINT STICKPIC_SIZE = 131; int WINAPI DllMain ( HINSTANCE hInstance, DWORD fdwReason, PVOID pvReserved) -{ +{ + switch (fdwReason) { case DLL_PROCESS_ATTACH: @@ -796,19 +804,27 @@ void Status::GetKeys(BUTTONS * Keys) } else if (comboTask == C_PAUSE) comboStart++; - continue_controller: +continue_controller: + //Allow unpressing with real controller low iq: + //1. realChanged has 1 where something changed + //2. mask out presses, leave releases + //3. remove the releases from override + DWORD realChanged = ControllerInput.Value ^ LastPureControllerInput.Value; + buttonOverride.Value &= ~(realChanged&LastPureControllerInput.Value); + + LastPureControllerInput.Value = ControllerInput.Value; ControllerInput.Value |= buttonOverride.Value; //if((frameCounter/2)%2 == 0) if (frameCounter % 2 == 0) //autofire stuff ControllerInput.Value ^= buttonAutofire.Value; else ControllerInput.Value ^= buttonAutofire2.Value; - + bool prevOverrideAllowed = overrideAllowed; overrideAllowed = true; if (comboTask != C_PAUSE) { - if (!copyButtons) SetKeys(ControllerInput); //don't overwrite after switching to read write + if (!copyButtons && !fakeInput) SetKeys(ControllerInput); //don't overwrite after switching to read write else LastControllerInput = ControllerInput; copyButtons = false; } @@ -816,7 +832,7 @@ void Status::GetKeys(BUTTONS * Keys) ControllerInput.Y_AXIS = overrideY; //Pass Button Info to Emulator Keys->Value = ControllerInput.Value; - buttonOverride.Value = oldOverride; + //buttonOverride.Value = oldOverride; //copy fetched data to combo too if (comboTask == C_RECORD && !fakeInput) { @@ -831,17 +847,75 @@ void Status::GetKeys(BUTTONS * Keys) gettingKeys = false; } + VOID SetXYTextFast(HWND parent, BOOL x, char* str) { // Optimized setdlgitemtext: explanation: // GetDlgItem is very slow because of the many controls and this may limit the speed of emulator in some cases(?) // Instead of using SetDlgItemText every time and (internally) calling GetDlgItem, we precompute the handles to x and y textboxes the first time and re-use them - // NOTE: this may break when extending dialogs because handle changes (will fix in future) - if (!textXHWND) textXHWND = GetDlgItem(parent, IDC_EDITX); - if (!textYHWND) textYHWND = GetDlgItem(parent, IDC_EDITY); + if (!textXHWND || !validatedhTxtbox) textXHWND = GetDlgItem(parent, IDC_EDITX); + if (!textYHWND || !validatedhTxtbox) textYHWND = GetDlgItem(parent, IDC_EDITY); + + if (x) SetWindowText(textXHWND, str); + else SetWindowText(textYHWND, str); +} + +BOOL AdjustForDPI(HWND parent, UINT dpi) { + + // Adjust for system scaling + // todo: more scaling checks + // 96 - 100% + // 120 - 125% + + RECT ctl_pos, ctl_gp_pos; + GetWindowRect(GetDlgItem(parent, IDC_STICKPIC), &ctl_pos); + GetWindowRect(GetDlgItem(parent, IDC_STATICX), &ctl_gp_pos); + + ctl_gp_pos.left -= 3; // adjust for border + + if (STICKPIC_SIZE == 131) { + // prevent infinitely increasing size - if (x) SetWindowText(textXHWND, str); // Is there implicit char* -> long pointer string happening? - else SetWindowText(textYHWND, str); + if (dpi == 120) { + STICKPIC_SIZE = STICKPIC_SIZE*125/100; // * 1.25 works too + } + + + // check for overlap with gpbox and try to fix it + if (ctl_pos.right+1 > ctl_gp_pos.left) { + printf("overlap with groupbox (%d/%d)", ctl_pos.right, ctl_gp_pos.left); + STICKPIC_SIZE = ctl_gp_pos.left-2; + } + } + + STICKPIC_SIZE -= 1; + + //STICKPIC_SIZE = (UINT)STICKPIC_SIZE; // ensure no double + printf("stickpic size: %d\ndpi: %d", STICKPIC_SIZE, dpi); + return dpi != 96; + +} + +//updates buttons +void Status::UpdateVisuals(BUTTONS ControllerInput) +{ +#define UPDATECHECK(idc,field) {if(buttonDisplayed.field != ControllerInput.field) CheckDlgButton(statusDlg, idc, ControllerInput.field);} + UPDATECHECK(IDC_CHECK_A, A_BUTTON); + UPDATECHECK(IDC_CHECK_B, B_BUTTON); + UPDATECHECK(IDC_CHECK_START, START_BUTTON); + UPDATECHECK(IDC_CHECK_L, L_TRIG); + UPDATECHECK(IDC_CHECK_R, R_TRIG); + UPDATECHECK(IDC_CHECK_Z, Z_TRIG); + UPDATECHECK(IDC_CHECK_CUP, U_CBUTTON); + UPDATECHECK(IDC_CHECK_CLEFT, L_CBUTTON); + UPDATECHECK(IDC_CHECK_CRIGHT, R_CBUTTON); + UPDATECHECK(IDC_CHECK_CDOWN, D_CBUTTON); + UPDATECHECK(IDC_CHECK_DUP, U_DPAD); + UPDATECHECK(IDC_CHECK_DLEFT, L_DPAD); + UPDATECHECK(IDC_CHECK_DRIGHT, R_DPAD); + UPDATECHECK(IDC_CHECK_DDOWN, D_DPAD); + buttonDisplayed.Value = ControllerInput.Value&0xFFFF; //fuck off } + void Status::SetKeys(BUTTONS ControllerInput) { if (copyButtons) //copy m64 data to current input @@ -856,22 +930,7 @@ void Status::SetKeys(BUTTONS ControllerInput) //true if physical controller state is changed (because logical is handled in GetKeys) if (buttonDisplayed.Value != ControllerInput.Value && HasPanel(2)) { -#define UPDATECHECK(idc,field) {if(buttonDisplayed.field != ControllerInput.field) CheckDlgButton(statusDlg, idc, ControllerInput.field^(buttonAutofire2.field|buttonAutofire.field));} - UPDATECHECK(IDC_CHECK_A, A_BUTTON); - UPDATECHECK(IDC_CHECK_B, B_BUTTON); - UPDATECHECK(IDC_CHECK_START, START_BUTTON); - UPDATECHECK(IDC_CHECK_L, L_TRIG); - UPDATECHECK(IDC_CHECK_R, R_TRIG); - UPDATECHECK(IDC_CHECK_Z, Z_TRIG); - UPDATECHECK(IDC_CHECK_CUP, U_CBUTTON); - UPDATECHECK(IDC_CHECK_CLEFT, L_CBUTTON); - UPDATECHECK(IDC_CHECK_CRIGHT, R_CBUTTON); - UPDATECHECK(IDC_CHECK_CDOWN, D_CBUTTON); - UPDATECHECK(IDC_CHECK_DUP, U_DPAD); - UPDATECHECK(IDC_CHECK_DLEFT, L_DPAD); - UPDATECHECK(IDC_CHECK_DRIGHT, R_DPAD); - UPDATECHECK(IDC_CHECK_DDOWN, D_DPAD); -#undef UPDATECHECK + UpdateVisuals(ControllerInput); buttonDisplayed.Value = ControllerInput.Value; } if(relativeXOn == 3 && radialRecalc) @@ -1307,9 +1366,9 @@ EXPORT void CALL ReadController ( int Control, BYTE * Command ) // (The frame counter is used only for autofire and combo progression.) if(Control == -1) Status::frameCounter++; -// for(Control = 0; Control < NUMBER_OF_CONTROLS; Control++) -// if(Controller[Control].bActive) -// status[Control].frameCounter++; + + //for (char i = 0; i < 4; i++) + // SendMessage(status[i].statusDlg, WM_SETCURSOR, 0, 0); } EXPORT void CALL RomClosed (void) { @@ -1329,7 +1388,9 @@ EXPORT void CALL RomClosed (void) { } void StartFake() { if (fakeStatusThread) { - MessageBox(0, "You can only have 1 testing TASInput running at a time", "Too many instances", MB_TOPMOST); + if (MessageBox(0, "You can only have 1 testing TASInput running at a time. Do you want to kill current TASInput instance?", "Too many instances", MB_TOPMOST | MB_YESNO) == IDNO)return; + // kill tasinput + RomClosed(); return; } @@ -1530,7 +1591,6 @@ void Status::RefreshAnalogPicture () } } - DWORD WINAPI StatusDlgThreadProc (LPVOID lpParameter) { int Control = LOBYTE(*(int*)lpParameter); @@ -1565,14 +1625,19 @@ static bool IsMouseOverControl (HWND hDlg, int dialogItemID) RECT rect; GetCursorPos(&pt); - GetWindowRect(GetDlgItem(hDlg, dialogItemID), &rect); - - return (pt.x <= rect.right && pt.x >= rect.left && pt.y <= rect.bottom && pt.y >= rect.top); + if(GetWindowRect(GetDlgItem(hDlg, dialogItemID), &rect)) //failed to get the dimensions + return (pt.x <= rect.right && pt.x >= rect.left && pt.y <= rect.bottom && pt.y >= rect.top); + return FALSE; } void Status::ActivateEmulatorWindow () { if (lock) return; + if (prevHWnd) + { + SetForegroundWindow(prevHWnd); + return; + } SetFocus(NULL); SetActiveWindow(NULL); // activates whatever the previous window was @@ -1641,12 +1706,13 @@ void RefreshChanges(HWND hwnd) bool ShowContextMenu(HWND hwnd,HWND hitwnd, int x, int y) { - if (hitwnd != hwnd || IsMouseOverControl(hwnd, IDC_STICKPIC) || (GetKeyState(VK_LBUTTON) & 0x8000) != 0) return TRUE; + if (hitwnd != hwnd || IsMouseOverControl(hwnd, IDC_STICKPIC) || (GetKeyState(VK_LBUTTON) & 0x8000)) return TRUE; RefreshChanges(hwnd); SetWindowPos(hwnd, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW); //disable topmost for a second hMenu = CreatePopupMenu(); AppendMenu(hMenu, menuConfig.onTop ? MF_CHECKED : 0, OnTop, "Stay on Top"); AppendMenu(hMenu, menuConfig.floatFromParent ? MF_CHECKED : 0, Float, "Show in Taskbar"); + AppendMenu(hMenu, menuConfig.movable ? MF_CHECKED : 0, Movable, "Movable"); lock = true; int res = TrackPopupMenuEx(hMenu, TPM_RETURNCMD | TPM_NONOTIFY, x, y, hwnd, 0); lock = false; @@ -1658,6 +1724,9 @@ bool ShowContextMenu(HWND hwnd,HWND hitwnd, int x, int y) case Float: menuConfig.floatFromParent ^= 1; break; + case Movable: + menuConfig.movable ^= 1; + break; } RefreshChanges(hwnd); DestroyMenu(hMenu); @@ -1716,8 +1785,14 @@ LRESULT Status::StatusDlgMethod (UINT msg, WPARAM wParam, LPARAM lParam) return TRUE; case WM_INITDIALOG: { + //SetProcessDpiAwarenessContext(DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE); + // sure... did i think it is that easy + + systemDPI = GetDpiForSystem(); + + AdjustForDPI(statusDlg, systemDPI); + // reset some dialog state - dragging = false; lastXDrag = 0; lastYDrag = 0; dragging = false, draggingStick = false, draggingPermaStick = false; @@ -1831,7 +1906,7 @@ LRESULT Status::StatusDlgMethod (UINT msg, WPARAM wParam, LPARAM lParam) // initial x/y text field values sprintf(str, "%d", initialStickX); - SetDlgItemText(statusDlg, IDC_EDITX, str); + SetDlgItemText(statusDlg, IDC_EDITX, str); // no need for "fast" version here this only happens one time sprintf(str, "%d", -initialStickY); SetDlgItemText(statusDlg, IDC_EDITY, str); @@ -1871,115 +1946,44 @@ LRESULT Status::StatusDlgMethod (UINT msg, WPARAM wParam, LPARAM lParam) // too bad we don't get useful events like WM_MOUSEMOVE or WM_LBUTTONDOWN... case WM_SETCURSOR: +#ifdef _DEBUG + //printf("tasinput setcursor message!\n"); +#endif + + //is any mouse button pressed? nextClick = ((GetAsyncKeyState(VK_LBUTTON) & 0x8000) || (GetAsyncKeyState(VK_RBUTTON) & 0x8000)); - lastWasRight = 0!=(GetAsyncKeyState(VK_RBUTTON) & 0x8000); - if(!dragging && !lastClick && nextClick) + + //used for sliders (rightclick reset), remembers if rightclick was pressed + //!! turns it into bool + lastWasRight = !!(GetAsyncKeyState(VK_RBUTTON) & 0x8000); + //if we are over buttons area and right is clicked, look for autofire candidates + //sadly wm_rbuttondown doesnt work here + if (IsMouseOverControl(statusDlg, IDC_BUTTONSLABEL) && lastWasRight) { - if(IsMouseOverControl(statusDlg,IDC_STICKPIC)) + overrideOn = true; //clicking on buttons counts as override + if (GetAsyncKeyState(VK_RBUTTON) & 0x8000) // right click on a button to autofire it { - if(draggingPermaStick || GetAsyncKeyState(VK_RBUTTON) & 0x8000) - { - draggingPermaStick = !draggingPermaStick; - draggingStick = draggingPermaStick; - } - else - draggingStick = true; - } - else if((!HasPanel(1) || // Any non-control area of the window is draggable. - (!IsMouseOverControl(statusDlg,IDC_XABS) && // This is done partly out of necessity, - !IsMouseOverControl(statusDlg,IDC_XSEM) && // because normal automatic window movement - !IsMouseOverControl(statusDlg,IDC_XREL) && // would not work (don't get messages for it), - !IsMouseOverControl(statusDlg,IDC_XRAD) && // and partly because the result occupies - !IsMouseOverControl(statusDlg,IDC_YABS) && // less space and is more convenient - !IsMouseOverControl(statusDlg,IDC_YSEM) && - !IsMouseOverControl(statusDlg,IDC_YREL) && - !IsMouseOverControl(statusDlg,IDC_EDITX) && - !IsMouseOverControl(statusDlg,IDC_EDITY) && - !IsMouseOverControl(statusDlg, IDC_CLEARJOY) && - !IsMouseOverControl(statusDlg,IDC_SPINX) && - !IsMouseOverControl(statusDlg,IDC_SPINY) && - !IsMouseOverControl(statusDlg,IDC_SLIDERX) && - !IsMouseOverControl(statusDlg,IDC_SLIDERY) && - !IsMouseOverControl(statusDlg, IDC_CHECK_ANGDISP) && - !IsMouseOverControl(statusDlg,IDC_MOREBUTTON0) && - !IsMouseOverControl(statusDlg,IDC_MOREBUTTON1))) && - (!HasPanel(2) || - (!IsMouseOverControl(statusDlg,IDC_CLEARBUTTONS) && - !IsMouseOverControl(statusDlg,IDC_MOREBUTTON2) && - !IsMouseOverControl(statusDlg,IDC_MOREBUTTON3) && - !IsMouseOverControl(statusDlg,IDC_MOREBUTTON4))) && - (!HasPanel(3) || - (!IsMouseOverControl(statusDlg,IDC_MACROBOX) && - !IsMouseOverControl(statusDlg,IDC_MACROLIST) && - !IsMouseOverControl(statusDlg,IDC_MOREBUTTON5) && - !IsMouseOverControl(statusDlg,IDC_MOREBUTTON6)))) - { - if(HasPanel(2) && - (IsMouseOverControl(statusDlg,IDC_CHECK_A) || - IsMouseOverControl(statusDlg,IDC_CHECK_B) || - IsMouseOverControl(statusDlg,IDC_CHECK_L) || - IsMouseOverControl(statusDlg,IDC_CHECK_R) || - IsMouseOverControl(statusDlg,IDC_CHECK_Z) || - IsMouseOverControl(statusDlg,IDC_CHECK_START) || - IsMouseOverControl(statusDlg,IDC_CHECK_CUP) || - IsMouseOverControl(statusDlg,IDC_CHECK_CDOWN) || - IsMouseOverControl(statusDlg,IDC_CHECK_CLEFT) || - IsMouseOverControl(statusDlg,IDC_CHECK_CRIGHT) || - IsMouseOverControl(statusDlg,IDC_CHECK_DUP) || - IsMouseOverControl(statusDlg,IDC_CHECK_DDOWN) || - IsMouseOverControl(statusDlg,IDC_CHECK_DLEFT) || - IsMouseOverControl(statusDlg,IDC_CHECK_DRIGHT))) - { - overrideOn = true; //clicking on buttons counts as override - if(GetAsyncKeyState(VK_RBUTTON) & 0x8000) // right click on a button to autofire it - { -#define UPDATEAUTO(idc,field) \ -{ \ - if(IsMouseOverControl(statusDlg,idc)) \ - { \ - CheckDlgButton(statusDlg,idc,buttonAutofire.field|buttonAutofire2.field ? 0 : 1); \ - BUTTONS &autoFire1 = (frameCounter%2 == 0) ? buttonAutofire : buttonAutofire2; \ - BUTTONS &autoFire2 = (frameCounter%2 == 0) ? buttonAutofire2 : buttonAutofire; \ - autoFire1.field = !(autoFire1.field|autoFire2.field); \ - autoFire2.field = 0; \ - buttonOverride.field = 0; \ - } \ -} - UPDATEAUTO(IDC_CHECK_A, A_BUTTON); - UPDATEAUTO(IDC_CHECK_B, B_BUTTON); - UPDATEAUTO(IDC_CHECK_START, START_BUTTON); - UPDATEAUTO(IDC_CHECK_L, L_TRIG); - UPDATEAUTO(IDC_CHECK_R, R_TRIG); - UPDATEAUTO(IDC_CHECK_Z, Z_TRIG); - UPDATEAUTO(IDC_CHECK_CUP, U_CBUTTON); - UPDATEAUTO(IDC_CHECK_CLEFT, L_CBUTTON); - UPDATEAUTO(IDC_CHECK_CRIGHT, R_CBUTTON); - UPDATEAUTO(IDC_CHECK_CDOWN, D_CBUTTON); - UPDATEAUTO(IDC_CHECK_DUP, U_DPAD); - UPDATEAUTO(IDC_CHECK_DLEFT, L_DPAD); - UPDATEAUTO(IDC_CHECK_DRIGHT, R_DPAD); - UPDATEAUTO(IDC_CHECK_DDOWN, D_DPAD); -#undef UPDATEAUTO - ActivateEmulatorWindow(); - } - } - else - { - dragging = true; - POINT pt; - GetCursorPos(&pt); - dragXStart = pt.x; - dragYStart = pt.y; - - RECT rect; - GetWindowRect(statusDlg, &rect); - dragXStart -= rect.left; - dragYStart -= rect.top; - } + UPDATEAUTO(IDC_CHECK_A, A_BUTTON); + UPDATEAUTO(IDC_CHECK_B, B_BUTTON); + UPDATEAUTO(IDC_CHECK_START, START_BUTTON); + UPDATEAUTO(IDC_CHECK_L, L_TRIG); + UPDATEAUTO(IDC_CHECK_R, R_TRIG); + UPDATEAUTO(IDC_CHECK_Z, Z_TRIG); + UPDATEAUTO(IDC_CHECK_CUP, U_CBUTTON); + UPDATEAUTO(IDC_CHECK_CLEFT, L_CBUTTON); + UPDATEAUTO(IDC_CHECK_CRIGHT, R_CBUTTON); + UPDATEAUTO(IDC_CHECK_CDOWN, D_CBUTTON); + UPDATEAUTO(IDC_CHECK_DUP, U_DPAD); + UPDATEAUTO(IDC_CHECK_DLEFT, L_DPAD); + UPDATEAUTO(IDC_CHECK_DRIGHT, R_DPAD); + UPDATEAUTO(IDC_CHECK_DDOWN, D_DPAD); + + ActivateEmulatorWindow(); } } lastClick = nextClick; /* fall through */ + case WM_MOUSEMOVE: case WM_NCHITTEST: case WM_TIMER: skipEditX = false; @@ -1988,29 +1992,18 @@ LRESULT Status::StatusDlgMethod (UINT msg, WPARAM wParam, LPARAM lParam) resetXScale = false, SendDlgItemMessage(statusDlg, IDC_SLIDERX, TBM_SETPOS, TRUE, (LPARAM)(LONG)(1000)); if(resetYScale) resetYScale = false, SendDlgItemMessage(statusDlg, IDC_SLIDERY, TBM_SETPOS, TRUE, (LPARAM)(LONG)(1000)); - if(dragging && !nextClick) - { - dragging = false; - ActivateEmulatorWindow(); - } - if(draggingStick && ((!nextClick && !draggingPermaStick ) || !IsWindowFromEmulatorProcessActive())) - { - draggingStick = false; - draggingPermaStick = false; - if(IsWindowFromEmulatorProcessActive()) - ActivateEmulatorWindow(); - } - if(dragging) + if (dragging) { POINT pt; GetCursorPos(&pt); int newDragX = pt.x; int newDragY = pt.y; - if(lastXDrag != newDragX-dragXStart || lastYDrag != newDragY-dragYStart) + if (lastXDrag != newDragX - dragXStart || lastYDrag != newDragY - dragYStart) { - lastXDrag = newDragX-dragXStart; - lastYDrag = newDragY-dragYStart; - SetWindowPos(statusDlg,0, lastXDrag, lastYDrag, 0,0, SWP_NOZORDER|SWP_NOSIZE|SWP_SHOWWINDOW); + lastXDrag = newDragX - dragXStart; + lastYDrag = newDragY - dragYStart; + // do not + SetWindowPos(statusDlg, 0, lastXDrag, lastYDrag, 0, 0,/*SWP_NOZORDER|*/SWP_NOSIZE | SWP_SHOWWINDOW); } } else if(draggingStick) @@ -2018,8 +2011,8 @@ LRESULT Status::StatusDlgMethod (UINT msg, WPARAM wParam, LPARAM lParam) POINT pt; GetCursorPos(&pt); ScreenToClient(GetDlgItem(statusDlg, IDC_STICKPIC), &pt); - overrideX = (pt.x*256/STICKPIC_SIZE - 128 + 1); - overrideY = -(pt.y*256/STICKPIC_SIZE - 128 + 1); + overrideX = (pt.x*256/(signed)STICKPIC_SIZE - 128 + 1); + overrideY = -(pt.y*256/(signed)STICKPIC_SIZE - 128 + 1); // normalize out-of-bounds clicks if(overrideX > 127 || overrideY > 127 || overrideX < -128 || overrideY < -129) @@ -2045,7 +2038,7 @@ LRESULT Status::StatusDlgMethod (UINT msg, WPARAM wParam, LPARAM lParam) sprintf(str, "%d", (int)(angle2 + (angle2>0 ? 0.5f : -0.5f))); skipEditX = true; } - SetDlgItemText(statusDlg, IDC_EDITX, str); + SetXYTextFast(statusDlg, true, str); if(!AngDisp) sprintf(str, "%d", -overrideY); else @@ -2054,20 +2047,18 @@ LRESULT Status::StatusDlgMethod (UINT msg, WPARAM wParam, LPARAM lParam) sprintf(str, "%d", (int)(0.5f + radialDistance)); skipEditY = true; } - SetDlgItemText(statusDlg, IDC_EDITY, str); - + SetXYTextFast(statusDlg, false, str); radialRecalc = true; overrideOn = true; //joystick dragged with mouse RefreshAnalogPicture(); - ActivateEmulatorWindow(); } else if(IsWindowFromEmulatorProcessActive() &&!lock) { if(!IsAnyStatusDialogActive()) { - if(gettingKeys) + if (gettingKeys) Sleep(0); - ActivateEmulatorWindow(); + //ActivateEmulatorWindow(); if(!gettingKeys && !(comboTask & (C_RUNNING | C_LOOP)) && !copyButtons) { BUTTONS Keys; @@ -2076,7 +2067,7 @@ LRESULT Status::StatusDlgMethod (UINT msg, WPARAM wParam, LPARAM lParam) GetKeys(&Keys); //used in radial mode I think fakeInput = false; relativeControlNow = false; - ActivateEmulatorWindow(); + //ActivateEmulatorWindow(); } } else @@ -2090,6 +2081,7 @@ LRESULT Status::StatusDlgMethod (UINT msg, WPARAM wParam, LPARAM lParam) SetWindowPos(statusDlg, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW); } break; + case WM_PAINT: { PAINTSTRUCT ps; @@ -2187,6 +2179,69 @@ LRESULT Status::StatusDlgMethod (UINT msg, WPARAM wParam, LPARAM lParam) } } break; + case WM_LBUTTONUP: + if (dragging) + { + printf("drag end\n"); + dragging = false; + ReleaseCapture(); + ActivateEmulatorWindow(); + } + if (draggingStick) + { + draggingStick = false; + ReleaseCapture(); + if (IsWindowFromEmulatorProcessActive()) + ActivateEmulatorWindow(); + } + if (draggingPermaStick) + { + draggingPermaStick = false; + KillTimer(statusDlg, IDT_TIMER3); + } + break; + + case WM_LBUTTONDOWN: //this message is only sent when clicking on non-controls, which is perfect for dragging right + printf("ld\n"); + if (!IsMouseOverControl(statusDlg,IDC_STICKPIC)) { + if (menuConfig.movable) + { + POINT pt; + printf("drag start\n"); + dragging = true; + GetCursorPos(&pt); + dragXStart = pt.x; + dragYStart = pt.y; + + RECT rect; + GetWindowRect(statusDlg, &rect); + dragXStart -= rect.left; + dragYStart -= rect.top; + } + } + else + { + draggingStick = true; + SendMessage(statusDlg, WM_MOUSEMOVE, 0, 0); //updates stick + ActivateEmulatorWindow(); + } + SetCapture(statusDlg); //let mouse escape window + + break; + case WM_RBUTTONDOWN: + printf("rd\n"); + //flip permadrag state and update dragging stick accordingly + if (IsMouseOverControl(statusDlg, IDC_STICKPIC)) + { + draggingPermaStick = !draggingPermaStick; + if (draggingStick = draggingPermaStick) + { + ActivateEmulatorWindow(); + SetTimer(statusDlg, IDT_TIMER3, 50, (TIMERPROC)NULL); + } + else KillTimer(statusDlg, IDT_TIMER3); + } + break; case EDIT_END: EndEdit(activeCombo, (char*)lParam); break; @@ -2208,7 +2263,7 @@ LRESULT Status::StatusDlgMethod (UINT msg, WPARAM wParam, LPARAM lParam) if(newOverrideX > 127) newOverrideX = 127; if(newOverrideX < -128) newOverrideX = -128; sprintf(str, "%d", newOverrideX); - SetDlgItemText(statusDlg, IDC_EDITX, str); + SetXYTextFast(statusDlg, true, str); } } else @@ -2219,12 +2274,12 @@ LRESULT Status::StatusDlgMethod (UINT msg, WPARAM wParam, LPARAM lParam) if(newAng >= 360) { sprintf(str, "%d", newAng-360); - SetDlgItemText(statusDlg, IDC_EDITX, str); + SetXYTextFast(statusDlg, true, str); } else if(newAng < 0) { sprintf(str, "%d", newAng+360); - SetDlgItemText(statusDlg, IDC_EDITX, str); + SetXYTextFast(statusDlg, true, str); } float newAngF = (newAng - 90) * (PI/180.0f); newOverrideX = (int)(xScale * radialDistance * cosf((float)newAngF)); @@ -2263,7 +2318,7 @@ LRESULT Status::StatusDlgMethod (UINT msg, WPARAM wParam, LPARAM lParam) if(newOverrideY > 127) newOverrideY = 127; if(newOverrideY < -128) newOverrideY = -128; sprintf(str, "%d", -newOverrideY); - SetDlgItemText(statusDlg, IDC_EDITY, str); + SetXYTextFast(statusDlg, false, str); } } else @@ -2361,21 +2416,20 @@ LRESULT Status::StatusDlgMethod (UINT msg, WPARAM wParam, LPARAM lParam) } break; //on checkbox click set buttonOverride and buttonDisplayed field and reset autofire - #define DISP_UPDATE(field) buttonDisplayed.field = buttonOverride.field = IsDlgButtonChecked(statusDlg, LOWORD(wParam))?1:0; buttonAutofire.field=buttonAutofire2.field =0; ActivateEmulatorWindow(); break; - case IDC_CHECK_A: DISP_UPDATE(A_BUTTON); - case IDC_CHECK_B: DISP_UPDATE(B_BUTTON); - case IDC_CHECK_START: DISP_UPDATE(START_BUTTON); - case IDC_CHECK_Z: DISP_UPDATE(Z_TRIG); - case IDC_CHECK_L: DISP_UPDATE(L_TRIG); - case IDC_CHECK_R: DISP_UPDATE(R_TRIG); - case IDC_CHECK_CLEFT: DISP_UPDATE(L_CBUTTON); - case IDC_CHECK_CUP: DISP_UPDATE(U_CBUTTON); - case IDC_CHECK_CRIGHT: DISP_UPDATE(R_CBUTTON); - case IDC_CHECK_CDOWN: DISP_UPDATE(D_CBUTTON); - case IDC_CHECK_DLEFT: DISP_UPDATE(L_DPAD); - case IDC_CHECK_DUP: DISP_UPDATE(U_DPAD); - case IDC_CHECK_DRIGHT: DISP_UPDATE(R_DPAD); - case IDC_CHECK_DDOWN: DISP_UPDATE(D_DPAD); + case IDC_CHECK_A: buttonOverride.A_BUTTON = IsDlgButtonChecked(statusDlg, LOWORD(wParam)) ? 1 : 0; buttonAutofire.A_BUTTON = buttonAutofire2.A_BUTTON = 0; ActivateEmulatorWindow(); break; + case IDC_CHECK_B: buttonOverride.B_BUTTON = IsDlgButtonChecked(statusDlg, LOWORD(wParam)) ? 1 : 0; buttonAutofire.B_BUTTON = buttonAutofire2.B_BUTTON = 0; ActivateEmulatorWindow(); break; + case IDC_CHECK_START: buttonOverride.START_BUTTON = IsDlgButtonChecked(statusDlg, LOWORD(wParam)) ? 1 : 0; buttonAutofire.START_BUTTON = buttonAutofire2.START_BUTTON = 0; ActivateEmulatorWindow(); break; + case IDC_CHECK_Z: buttonOverride.Z_TRIG = IsDlgButtonChecked(statusDlg, LOWORD(wParam)) ? 1 : 0; buttonAutofire.Z_TRIG = buttonAutofire2.Z_TRIG = 0; ActivateEmulatorWindow(); break; + case IDC_CHECK_L: buttonOverride.L_TRIG = IsDlgButtonChecked(statusDlg, LOWORD(wParam)) ? 1 : 0; buttonAutofire.L_TRIG = buttonAutofire2.L_TRIG = 0; ActivateEmulatorWindow(); break; + case IDC_CHECK_R: buttonOverride.R_TRIG = IsDlgButtonChecked(statusDlg, LOWORD(wParam)) ? 1 : 0; buttonAutofire.R_TRIG = buttonAutofire2.R_TRIG = 0; ActivateEmulatorWindow(); break; + case IDC_CHECK_CLEFT: buttonOverride.L_CBUTTON = IsDlgButtonChecked(statusDlg, LOWORD(wParam)) ? 1 : 0; buttonAutofire.L_CBUTTON = buttonAutofire2.L_CBUTTON = 0; ActivateEmulatorWindow(); break; + case IDC_CHECK_CUP: buttonOverride.U_CBUTTON = IsDlgButtonChecked(statusDlg, LOWORD(wParam)) ? 1 : 0; buttonAutofire.U_CBUTTON = buttonAutofire2.U_CBUTTON = 0; ActivateEmulatorWindow(); break; + case IDC_CHECK_CRIGHT: buttonOverride.R_CBUTTON = IsDlgButtonChecked(statusDlg, LOWORD(wParam)) ? 1 : 0; buttonAutofire.R_CBUTTON = buttonAutofire2.R_CBUTTON = 0; ActivateEmulatorWindow(); break; + case IDC_CHECK_CDOWN: buttonOverride.D_CBUTTON = IsDlgButtonChecked(statusDlg, LOWORD(wParam)) ? 1 : 0; buttonAutofire.D_CBUTTON = buttonAutofire2.D_CBUTTON = 0; ActivateEmulatorWindow(); break; + case IDC_CHECK_DLEFT: buttonOverride.L_DPAD = IsDlgButtonChecked(statusDlg, LOWORD(wParam)) ? 1 : 0; buttonAutofire.L_DPAD = buttonAutofire2.L_DPAD = 0; ActivateEmulatorWindow(); break; + case IDC_CHECK_DUP: buttonOverride.U_DPAD = IsDlgButtonChecked(statusDlg, LOWORD(wParam)) ? 1 : 0; buttonAutofire.U_DPAD = buttonAutofire2.U_DPAD = 0; ActivateEmulatorWindow(); break; + case IDC_CHECK_DRIGHT: buttonOverride.R_DPAD = IsDlgButtonChecked(statusDlg, LOWORD(wParam)) ? 1 : 0; buttonAutofire.R_DPAD = buttonAutofire2.R_DPAD = 0; ActivateEmulatorWindow(); break; + case IDC_CHECK_DDOWN: buttonOverride.D_DPAD = IsDlgButtonChecked(statusDlg, LOWORD(wParam)) ? 1 : 0; buttonAutofire.D_DPAD = buttonAutofire2.D_DPAD = 0; ActivateEmulatorWindow(); break; case IDC_CLEARJOY: overrideAllowed = true; overrideOn = true; overrideX = 0; overrideY = 0; SetDlgItemText(statusDlg, IDC_EDITY, "0"); SetDlgItemText(statusDlg, IDC_EDITX, "0"); RefreshAnalogPicture(); ActivateEmulatorWindow(); break; case IDC_CLEARBUTTONS: buttonOverride.Value = buttonAutofire.Value = buttonAutofire2.Value = 0; GetKeys(0); ActivateEmulatorWindow(); break; case IDC_MOREBUTTON0: @@ -2418,6 +2472,10 @@ LRESULT Status::StatusDlgMethod (UINT msg, WPARAM wParam, LPARAM lParam) // Resizing wouldn't work, because any resizing causes visible damage to the dialog's background // due to some messages not getting through to repair it StartThread(Control); + + // Invalidate cache + validatedhTxtbox = FALSE; + } break; case IDC_PLAY: activeCombo = ListBox_GetCurSel(GetDlgItem(statusDlg, IDC_MACROLIST)); diff --git a/tasinput_plugin/src/DefDI.h b/tasinput_plugin/src/DefDI.h index ef0b04c6..5ec7d34a 100755 --- a/tasinput_plugin/src/DefDI.h +++ b/tasinput_plugin/src/DefDI.h @@ -116,11 +116,13 @@ enum PopupOptions { None, OnTop, Float, + Movable }; typedef struct { bool onTop = false; bool floatFromParent = true; + bool movable = true; } MENUCONFIG; //---- @@ -131,5 +133,18 @@ BOOL WINAPI CheckForDeviceChange(HKEY hKey); LRESULT CALLBACK StatusDlgProc (HWND hDlg, UINT Message, WPARAM wParam, LPARAM lParam); VOID CALLBACK StatusDlgProcTimer( UINT idEvent, UINT uMsg, DWORD dwUser, DWORD dw1, DWORD dw2); +#define UPDATEAUTO(idc,field) \ +{ \ + if(IsMouseOverControl(statusDlg,idc)) \ + { \ + CheckDlgButton(statusDlg,idc,buttonAutofire.field|buttonAutofire2.field ? 0 : 1); \ + BUTTONS &autoFire1 = (frameCounter%2 == 0) ? buttonAutofire : buttonAutofire2; \ + BUTTONS &autoFire2 = (frameCounter%2 == 0) ? buttonAutofire2 : buttonAutofire; \ + autoFire1.field = 0; \ + autoFire2.field = !(autoFire1.field|autoFire2.field); \ + buttonOverride.field ^= 1; \ + buttonDisplayed.field = autoFire2.field; \ + } \ +} #endif \ No newline at end of file diff --git a/winproject/icons/logo.bmp b/winproject/icons/logo.bmp index 966d0041..3886fcbc 100755 Binary files a/winproject/icons/logo.bmp and b/winproject/icons/logo.bmp differ diff --git a/winproject/mupen64/mupen64_2017.vcxproj b/winproject/mupen64/mupen64_2017.vcxproj index 3f305743..fb60f392 100644 --- a/winproject/mupen64/mupen64_2017.vcxproj +++ b/winproject/mupen64/mupen64_2017.vcxproj @@ -88,20 +88,22 @@ 4018;4244;%(DisableSpecificWarnings) CompileAsCpp false - NoExtensions + StreamingSIMDExtensions2 + /FI "../main/debughook.h" %(AdditionalOptions) Shlwapi.lib;vfw32.lib;winmm.lib;Comctl32.lib;zlib-2008-x32.lib;%(AdditionalDependencies) $(OutDir)$(TargetName)$(TargetExt) ../zlib;../../lua;%(AdditionalLibraryDirectories) true - $(OutDir)mupen64.pdb + $(OutDir)mupen64_debug.pdb Windows false false MachineX86 + true true @@ -146,6 +148,7 @@ MachineX86 UseLinkTimeCodeGeneration false + true @@ -186,11 +189,13 @@ + true + @@ -221,6 +226,7 @@ false + @@ -314,12 +320,14 @@ + CompileAsCpp Default Default true + CompileAsCpp @@ -393,6 +401,7 @@ CompileAsCpp CompileAsCpp + Default Default diff --git a/winproject/mupen64/mupen64_2017.vcxproj.filters b/winproject/mupen64/mupen64_2017.vcxproj.filters index 8a7c88d4..f336f823 100644 --- a/winproject/mupen64/mupen64_2017.vcxproj.filters +++ b/winproject/mupen64/mupen64_2017.vcxproj.filters @@ -203,11 +203,16 @@ Source Files\lua - - Source Files\r4300 + + Source Files\main\win - - Source Files\r4300\x86 + + Source Files\main + + + + + Source Files\lua @@ -448,11 +453,20 @@ Source Files\main - - Source Files\r4300\x86 + + Source Files\main\win + + + Source Files\main - Source Files\r4300 + Source Files + + + Source Files + + + Source Files\lua diff --git a/winproject/mupen64/mupen64_2017.vcxproj.user b/winproject/mupen64/mupen64_2017.vcxproj.user index ace9a86a..3f030911 100644 --- a/winproject/mupen64/mupen64_2017.vcxproj.user +++ b/winproject/mupen64/mupen64_2017.vcxproj.user @@ -1,3 +1,6 @@ サソ + + false + \ No newline at end of file diff --git a/winproject/resource.h b/winproject/resource.h index f31615ee..2d56a7fa 100755 --- a/winproject/resource.h +++ b/winproject/resource.h @@ -2,7 +2,10 @@ // Plik doウケczany wygenerowany przez 徨odowisko Microsoft Visual C++. // Uソywany przez: rsrc.rc // -#define MUPEN_VERSION "Mupen 64 1.0.8" +#define MUPEN_VERSION "Mupen 64 1.0.9" + +#define MIN_WINDOW_W 500 +#define MIN_WINDOW_H 250 #define IDR_MYMENU 101 #define IDR_ACCEL 103 @@ -145,6 +148,7 @@ #define IDC_DECREASE_MODIFIER 2263 #define IDC_RESET_MODIFIER 2264 #define IDC_SKIPFREQ 2265 +#define IDC_0INDEX 2266 #define STATE_SAVE 3000 @@ -242,6 +246,9 @@ #define ID_MENU_LUASCRIPT_NEW 6020 #define ID_MENU_LUASCRIPT_CLOSEALL 6021 #define ID_TRACELOG 6022 +#define ID_LUA_CLEAR_RECENT 6023 +#define ID_LUA_RECENT 6024 +//6024+5 reserved for recent, unless changed to more #define IDC_HOTKEYS_FLOWGROUP 6101 #define IDC_HOT_SCREENSHOT 6103 @@ -413,6 +420,14 @@ #define IDC_INPUTDELAY 40009 #define IDC_CLUADOUBLEBUFFER 40010 #define IDC_GITREPO 40011 +#define IDC_EXTSAVESTATE 40012 +#define ID_LUA_RECENT_RESET 40013 +#define ID_LUA_RECENT_FREEZE 40014 +#define IDD_OTHER_OPTIONS_DIALOG 40015 +#define IDC_OTHEROPTIONS 40016 +#define IDC_LUA_WARNONCLOSE 40017 +#define IDC_LUA_SIMPLEDIALOG 40018 +#define IDD_LUAWINDOW_SIMPLIFIED 40019 #define IDC_STATIC -1 // Next default values for new objects diff --git a/winproject/rsrc.rc b/winproject/rsrc.rc index 89ce52d4..b73ba829 100755 --- a/winproject/rsrc.rc +++ b/winproject/rsrc.rc @@ -136,6 +136,14 @@ BEGIN POPUP "Lua Script" BEGIN MENUITEM "New Instance", ID_MENU_LUASCRIPT_NEW + MENUITEM SEPARATOR + POPUP "Recent scripts" + BEGIN + MENUITEM "Reset", ID_LUA_RECENT_RESET + MENUITEM "Freeze", ID_LUA_RECENT_FREEZE + MENUITEM SEPARATOR + END + MENUITEM SEPARATOR MENUITEM "Close All", ID_MENU_LUASCRIPT_CLOSEALL END END @@ -167,7 +175,7 @@ BEGIN PUSHBUTTON "Website",IDC_WEBSITE,134,197,60,14 GROUPBOX "About this program",IDC_STATIC,5,65,189,127 LTEXT "Author:\r\n Hacktarux (hacktarux@yahoo.fr)\r\n\nWindows port:\r\n ShadowPrince (shadow@emulation64.com)\r\n linker (linker@mail.bg)\r\n\r\nContributors:\r\n Codex, Falcon4ever, Pir4nhaX, Malcolm,\r\n Olivieryuyu\r\n\r\nThanks to the many others who helped",IDC_STATIC,13,82,173,104 - CONTROL "",133,"Static",SS_BITMAP,0,0,200,100 + LTEXT MUPEN_VERSION,IDC_STATIC,0,0,200,100 END IDD_ADVANCED_OPTIONS DIALOGEX 0, 0, 231, 273 @@ -207,6 +215,15 @@ BEGIN "Button",BS_AUTOCHECKBOX | BS_MULTILINE | WS_TABSTOP,16,233,78,16 END +IDD_OTHER_OPTIONS_DIALOG DIALOGEX 0, 0, 231, 273 +STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP +FONT 8, "Tahoma", 0, 0, 0x0 +BEGIN +GROUPBOX "Other Options", IDC_OTHEROPTIONS, 7, 7, 215, 60 +CONTROL "Ask on lua close", IDC_LUA_WARNONCLOSE, "Button", BS_AUTOCHECKBOX | WS_TABSTOP, 16, 20, 100, 10 +CONTROL "Simplfied lua dialog", IDC_LUA_SIMPLEDIALOG, "Button", BS_AUTOCHECKBOX | WS_TABSTOP, 16, 30, 100, 10 +END + IDD_AUDIT_ROMS_DIALOG DIALOGEX 0, 0, 183, 138 STYLE DS_SETFONT | DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU CAPTION "Audit ROMs" @@ -242,6 +259,18 @@ BEGIN EDITTEXT IDC_TEXTBOX_LUACONSOLE,7,43,226,116,ES_MULTILINE | ES_READONLY | WS_VSCROLL END +IDD_LUAWINDOW_SIMPLIFIED DIALOGEX 0, 0, 230, 50 +STYLE DS_SETFONT | WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_VISIBLE | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME +CAPTION "LUA Instance" +FONT 8, "Ms Shell Dlg", 0, 0, 0x1 +BEGIN +PUSHBUTTON "Run", IDC_BUTTON_LUASTATE, 193, 23, 40, 18 +EDITTEXT IDC_TEXTBOX_LUASCRIPTPATH, 7, 7, 226, 14, ES_AUTOHSCROLL +PUSHBUTTON "Browse", IDC_BUTTON_LUABROWSE, 110, 23, 40, 18 +PUSHBUTTON "Stop", IDC_BUTTON_LUASTOP, 151, 23, 40, 18, WS_DISABLED +END + + IDD_DIRECTORIES DIALOGEX 0, 0, 231, 262 STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP FONT 8, "Tahoma", 0, 0, 0x0 @@ -393,7 +422,7 @@ BEGIN CONTROL "Alert for hacked ROM",IDC_ALERTHACKEDROM,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,16,34,150,10 CONTROL "Alert for save errors",IDC_ALERTSAVESERRORS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,16,49,150,10 GROUPBOX "FPS / VIs",IDC_FPSTITLE,7,71,215,94 - CONTROL "Limit VIs (auto)",IDC_LIMITFPS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,16,86,150,10 + CONTROL "Limit VIs (auto)",IDC_LIMITFPS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,16,86,69,10 CONTROL "Use Speed Modifier",IDC_SPEEDMODIFIER,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,26,100,150,10 CONTROL "Show FPS",IDC_SHOWFPS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,16,134,87,10 CONTROL "Show VIs",IDC_SHOWVIS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,16,149,79,10 @@ -405,6 +434,7 @@ BEGIN GROUPBOX "Ini file",IDC_INIFILE,7,230,215,26 EDITTEXT IDC_SKIPFREQ,162,138,45,12,ES_AUTOHSCROLL LTEXT "Fast forward skip frequency:",IDC_STATIC,108,133,49,19 + CONTROL "0-index statusbar",IDC_0INDEX,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,144,86,69,10 END IDD_MOVIE_PLAYBACK_DIALOG DIALOGEX 0, 0, 342, 330 @@ -528,6 +558,7 @@ BEGIN EDITTEXT IDC_MOVIE_CONTROLLER3_TEXT2,217,176,91,12,ES_AUTOHSCROLL | ES_READONLY | NOT WS_BORDER EDITTEXT IDC_MOVIE_CONTROLLER4_TEXT2,217,187,91,12,ES_AUTOHSCROLL | ES_READONLY | NOT WS_BORDER GROUPBOX "Start From",IDC_STARTFROM2,177,88,139,50 + CONTROL ".savestate",IDC_EXTSAVESTATE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,254,112,45,10 CONTROL "Savestate",IDC_FROMSNAPSHOT_RADIO,"Button",BS_AUTORADIOBUTTON,190,112,64,10 CONTROL "Start",IDC_FROMSTART_RADIO,"Button",BS_AUTORADIOBUTTON,190,100,50,10 CONTROL "EEPROM",IDC_FROMEEPROM_RADIO,"Button",BS_AUTORADIOBUTTON,190,125,64,10 @@ -656,6 +687,10 @@ BEGIN BEGIN END + IDD_OTHER_OPTIONS_DIALOG, DIALOG + BEGIN + END + IDD_AUDIT_ROMS_DIALOG, DIALOG BEGIN END @@ -756,7 +791,7 @@ END #endif // APSTUDIO_INVOKED -#endif // Neutral (Default) resources +#endif // Neutralny (Domy徑ny) resources /////////////////////////////////////////////////////////////////////////////