diff --git a/apu/apu.cpp b/apu/apu.cpp index c486e4b8..62d8423c 100644 --- a/apu/apu.cpp +++ b/apu/apu.cpp @@ -600,6 +600,9 @@ void S9xAPUTimingSetSpeedup (int ticks) void S9xAPUAllowTimeOverflow (bool allow) { + if (allow) + printf("APU time overflow allowed\n"); + spc_core->spc_allow_time_overflow(allow); } diff --git a/cpuops.cpp b/cpuops.cpp index d68cd37d..e9c71eda 100644 --- a/cpuops.cpp +++ b/cpuops.cpp @@ -3509,7 +3509,7 @@ static void Op42 (void) S9xMessage(S9X_DEBUG, S9X_DEBUG_OUTPUT, buf); if (trace != NULL) fclose(trace); - ENSURE_TRACE_OPEN(trace,"WDMtrace.log","ab") + ENSURE_TRACE_OPEN(trace, "WDMtrace.log", "ab") } break; diff --git a/debug.cpp b/debug.cpp index b2151d62..18ba1a12 100644 --- a/debug.cpp +++ b/debug.cpp @@ -1532,7 +1532,7 @@ static void debug_process_command (char *Line) if (SA1.Flags & TRACE_FLAG) { printf("SA1 CPU instruction tracing enabled.\n"); - ENSURE_TRACE_OPEN(trace2,"trace_sa1.log","wb") + ENSURE_TRACE_OPEN(trace2, "trace_sa1.log", "wb") } else { @@ -1548,7 +1548,7 @@ static void debug_process_command (char *Line) if (CPU.Flags & TRACE_FLAG) { printf("CPU instruction tracing enabled.\n"); - ENSURE_TRACE_OPEN(trace,"trace.log","wb") + ENSURE_TRACE_OPEN(trace, "trace.log", "wb") } else { @@ -2578,7 +2578,7 @@ void S9xTrace (void) { char msg[512]; - ENSURE_TRACE_OPEN(trace,"trace.log","a") + ENSURE_TRACE_OPEN(trace, "trace.log", "a") debug_cpu_op_print(msg, Registers.PB, Registers.PCw); fprintf(trace, "%s\n", msg); @@ -2588,7 +2588,7 @@ void S9xSA1Trace (void) { char msg[512]; - ENSURE_TRACE_OPEN(trace2,"trace_sa1.log","a") + ENSURE_TRACE_OPEN(trace2, "trace_sa1.log", "a") debug_sa1_op_print(msg, SA1Registers.PB, SA1Registers.PCw); fprintf(trace2, "%s\n", msg); diff --git a/debug.h b/debug.h index faa2ed54..2ff1b4d4 100644 --- a/debug.h +++ b/debug.h @@ -189,8 +189,13 @@ struct SBreakPoint uint16 Address; }; -#define ENSURE_TRACE_OPEN(fp,file,mode) \ - if(!fp) {std::string fn=S9xGetDirectory(DEFAULT_DIR);fn+=SLASH_STR file;fp=fopen(fn.c_str(),mode);} +#define ENSURE_TRACE_OPEN(fp, file, mode) \ + if (!fp) \ + { \ + std::string fn = S9xGetDirectory(LOG_DIR); \ + fn += SLASH_STR file; \ + fp = fopen(fn.c_str(), mode); \ + } extern struct SBreakPoint S9xBreakpoint[6]; diff --git a/macosx/English.lproj/Localizable.strings b/macosx/English.lproj/Localizable.strings index ce0b0740..89a822f4 100644 --- a/macosx/English.lproj/Localizable.strings +++ b/macosx/English.lproj/Localizable.strings @@ -30,8 +30,10 @@ "NPConnecting" = "Connecting"; "NPServerName" = "Server"; -"AlertMes_03" = "The folders for saving files could not be created."; -"AlertMes_04" = "Some features will not work properly without these folders."; +"AlertMes_01" = "The folder for saving files is not found."; +"AlertMes_02" = "Application Support folder will be used instead."; +"AlertMes_03" = "The folder for saving files is not writable."; +"AlertMes_04" = "Application Support folder will be used instead."; "AlertMes_05" = "This ROM image has bad checksum, so might not work properly."; "AlertMes_06" = "Or failed to detect map / interleave."; "AlertMes_07" = "No enough space in Cheat Entry."; diff --git a/macosx/mac-cheatfinder.cpp b/macosx/mac-cheatfinder.cpp index 62f21d72..01187e81 100755 --- a/macosx/mac-cheatfinder.cpp +++ b/macosx/mac-cheatfinder.cpp @@ -1278,7 +1278,7 @@ static void CheatFinderHandleAddEntryButton (WindowData *cf) PlayAlertSound(); else if (Cheat.num_cheats + cfViewNumBytes > MAX_CHEATS) - AppearanceAlert(kAlertCautionAlert, kCFCantAddWarning, kCFCantAddHint); + AppearanceAlert(kAlertCautionAlert, kS9xMacAlertCFCantAddEntry, kS9xMacAlertCFCantAddEntryHint); else CheatFinderBeginAddEntrySheet(cf); } diff --git a/macosx/mac-client.cpp b/macosx/mac-client.cpp index 152f2445..19763eb5 100644 --- a/macosx/mac-client.cpp +++ b/macosx/mac-client.cpp @@ -922,11 +922,10 @@ static bool8 NPClientBeginOpenROMImage (WindowRef window) static bool8 NPClientEndOpenROMImage (void) { - OSStatus err; - FSCatalogInfo info; - FSRef cartRef; - char filename[PATH_MAX + 1]; - bool8 r; + OSStatus err; + FSRef cartRef; + char filename[PATH_MAX + 1]; + bool8 r; r = NavEndOpenROMImageSheet(&cartRef); if (!r) @@ -935,8 +934,7 @@ static bool8 NPClientEndOpenROMImage (void) return (false); } - err = FSGetCatalogInfo(&cartRef, kFSCatInfoVolume, &info, NULL, NULL, NULL); - lockedROMMedia = IsLockedMedia(info.volume); + CheckSaveFolder(&cartRef); Settings.ForceLoROM = (romDetect == kLoROMForce ); Settings.ForceHiROM = (romDetect == kHiROMForce ); diff --git a/macosx/mac-dialog.h b/macosx/mac-dialog.h old mode 100644 new mode 100755 index b5942e62..4d7b9dbc --- a/macosx/mac-dialog.h +++ b/macosx/mac-dialog.h @@ -193,14 +193,16 @@ enum { - kFolderFail = 3, - kFolderHint, - kBadRomWarning, - kBadRomHint, - kCFCantAddWarning, - kCFCantAddHint, - kRequiredSystemWarning, - kRequiredSystemHint + kS9xMacAlertFolderNotFound = 1, + kS9xMacAlertFolderNotFoundHint, + kS9xMacAlertFolderFailToCreate, + kS9xMacAlertFolderFailToCreateHint, + kS9xMacAlertkBadRom, + kS9xMacAlertkBadRomHint, + kS9xMacAlertCFCantAddEntry, + kS9xMacAlertCFCantAddEntryHint, + kS9xMacAlertRequiredSystem, + kS9xMacAlertRequiredSystemHint }; extern int autofireLastTabIndex; diff --git a/macosx/mac-file.cpp b/macosx/mac-file.cpp index 33d1bf01..35a6df67 100644 --- a/macosx/mac-file.cpp +++ b/macosx/mac-file.cpp @@ -207,6 +207,78 @@ static OSStatus FindApplicationSupportFolder (FSRef *, char *, const char *); static OSStatus FindCustomFolder (FSRef *, char *, const char *); +void CheckSaveFolder (FSRef *cartRef) +{ + OSStatus err; + Boolean r; + FSCatalogInfo finfo; + FSVolumeInfo vinfo; + FSRef ref; + CFURLRef burl, purl; + char s[PATH_MAX + 1]; + + switch (saveInROMFolder) + { + case 0: // Snes9x folder + burl = CFBundleCopyBundleURL(CFBundleGetMainBundle()); + purl = CFURLCreateCopyDeletingLastPathComponent(kCFAllocatorDefault, burl); + r = CFURLGetFSRef(purl, &ref); + CFRelease(purl); + CFRelease(burl); + break; + + case 1: // ROM folder + err = FSGetCatalogInfo(cartRef, kFSCatInfoNone, NULL, NULL, NULL, &ref); + break; + + case 2: // Application Support folder + return; + + case 4: // Custom folder + if (saveFolderPath == NULL) + { + saveInROMFolder = 2; + return; + } + + r = CFStringGetCString(saveFolderPath, s, PATH_MAX, kCFStringEncodingUTF8); + err = FSPathMakeRef((unsigned char *) s, &ref, NULL); + if (err) + { + AppearanceAlert(kAlertCautionAlert, kS9xMacAlertFolderNotFound, kS9xMacAlertFolderNotFoundHint); + saveInROMFolder = 2; + return; + } + + break; + } + + err = FSGetCatalogInfo(&ref, kFSCatInfoUserPrivs | kFSCatInfoVolume, &finfo, NULL, NULL, NULL); + if (err == noErr) + { + if (finfo.userPrivileges & kioACUserNoMakeChangesMask) + { + AppearanceAlert(kAlertCautionAlert, kS9xMacAlertFolderFailToCreate, kS9xMacAlertFolderFailToCreateHint); + saveInROMFolder = 2; + return; + } + + err = FSGetVolumeInfo(finfo.volume, 0, NULL, kFSVolInfoFlags, &vinfo, NULL, NULL); + if (err == noErr) + { + if ((vinfo.flags & kFSVolFlagHardwareLockedMask) || (vinfo.flags & kFSVolFlagSoftwareLockedMask)) + { + AppearanceAlert(kAlertCautionAlert, kS9xMacAlertFolderFailToCreate, kS9xMacAlertFolderFailToCreateHint); + saveInROMFolder = 2; + return; + } + } + } + + if (err) + saveInROMFolder = 2; +} + static OSStatus FindSNESFolder (FSRef *folderRef, char *folderPath, const char *folderName) { OSStatus err; @@ -231,15 +303,7 @@ static OSStatus FindSNESFolder (FSRef *folderRef, char *folderPath, const char * AddFolderIcon(folderRef, folderName); } - if (err) - { - if (!folderWarning) - { - AppearanceAlert(kAlertCautionAlert, kFolderFail, kFolderHint); - folderWarning = true; - } - } - else + if (err == noErr) err = FSRefMakePath(folderRef, (unsigned char *) folderPath, PATH_MAX); CFRelease(purl); @@ -284,15 +348,7 @@ static OSStatus FindApplicationSupportFolder (FSRef *folderRef, char *folderPath AddFolderIcon(folderRef, folderName); } - if (err) - { - if (!folderWarning) - { - AppearanceAlert(kAlertCautionAlert, kFolderFail, kFolderHint); - folderWarning = true; - } - } - else + if (err == noErr) err = FSRefMakePath(folderRef, (unsigned char *) folderPath, PATH_MAX); CFRelease(fstr); @@ -308,6 +364,9 @@ static OSStatus FindCustomFolder (FSRef *folderRef, char *folderPath, const char UniChar buffer[PATH_MAX + 1]; char s[PATH_MAX + 1]; + if (saveFolderPath == NULL) + return (-1); + err = CFStringGetCString(saveFolderPath, s, PATH_MAX, kCFStringEncodingUTF8) ? noErr : -1; if (err == noErr) err = FSPathMakeRef((unsigned char *) s, &pref, NULL); @@ -326,15 +385,7 @@ static OSStatus FindCustomFolder (FSRef *folderRef, char *folderPath, const char AddFolderIcon(folderRef, folderName); } - if (err) - { - if (!folderWarning) - { - AppearanceAlert(kAlertCautionAlert, kFolderFail, kFolderHint); - folderWarning = true; - } - } - else + if (err == noErr) err = FSRefMakePath(folderRef, (unsigned char *) folderPath, PATH_MAX); CFRelease(fstr); @@ -437,21 +488,6 @@ static void AddFolderIcon (FSRef *fref, const char *folderName) } } -Boolean IsLockedMedia (FSVolumeRefNum volume) -{ - OSStatus err; - FSVolumeInfo info; - - err = FSGetVolumeInfo(volume, 0, NULL, kFSVolInfoFlags, &info, NULL, NULL); - if (err == noErr) - { - if ((info.flags & kFSVolFlagHardwareLockedMask) || (info.flags & kFSVolFlagSoftwareLockedMask)) - return (true); - } - - return (false); -} - const char * S9xGetFilename (const char *inExt, enum s9x_getdirtype dirtype) { static int index = 0; @@ -506,6 +542,7 @@ const char * S9xGetFilename (const char *inExt, enum s9x_getdirtype dirtype) case '.dat': case '.out': + case '.log': strcpy(folderName, "Logs"); break; @@ -514,18 +551,29 @@ const char * S9xGetFilename (const char *inExt, enum s9x_getdirtype dirtype) break; } - if (folderName[0] && ((saveInROMFolder != 1) || lockedROMMedia)) + if (folderName[0] && (saveInROMFolder != 1)) { char s[PATH_MAX + 1]; s[0] = 0; + err = -1; if (saveInROMFolder == 0) + { err = FindSNESFolder(&ref, s, folderName); - else - if (saveFolderPath && (saveInROMFolder == 4)) + if (err) + saveInROMFolder = 2; + } + + if (saveInROMFolder == 4) + { err = FindCustomFolder(&ref, s, folderName); - else + if (err) + saveInROMFolder = 2; + + } + + if (saveInROMFolder == 2) err = FindApplicationSupportFolder(&ref, s, folderName); if (err == noErr) @@ -675,6 +723,7 @@ const char * S9xGetDirectory (enum s9x_getdirtype dirtype) case SPC_DIR: strcpy(inExt, ".spc"); break; case CHEAT_DIR: strcpy(inExt, ".cht"); break; case BIOS_DIR: strcpy(inExt, ".bio"); break; + case LOG_DIR: strcpy(inExt, ".log"); break; default: strcpy(inExt, ".xxx"); break; } diff --git a/macosx/mac-file.h b/macosx/mac-file.h index 711ee7a2..aa6773cc 100644 --- a/macosx/mac-file.h +++ b/macosx/mac-file.h @@ -191,8 +191,8 @@ #ifndef _mac_file_h_ #define _mac_file_h_ +void CheckSaveFolder (FSRef *); void ChangeTypeAndCreator (const char *, OSType, OSType); -Boolean IsLockedMedia (FSVolumeRefNum); const char * S9xGetSPCFilename (void); const char * S9xGetPNGFilename (void); const char * S9xGetFreezeFilename (int); diff --git a/macosx/mac-os.h b/macosx/mac-os.h index 7abb3845..7cc23462 100644 --- a/macosx/mac-os.h +++ b/macosx/mac-os.h @@ -296,7 +296,7 @@ extern int64 lastFrame; extern unsigned long spcFileCount, pngFileCount; extern SInt32 systemVersion; extern bool8 finished, cartOpen, - autofire, hidExist, folderWarning, lockedROMMedia, directDisplay; + autofire, hidExist, directDisplay; extern bool8 fullscreen, autoRes, glstretch, gl32bit, vsync, drawoverscan, lastoverscan, screencurvature, multiprocessor, ciFilterEnable; diff --git a/macosx/mac-os.mm b/macosx/mac-os.mm index a07f6db2..b35f27a1 100644 --- a/macosx/mac-os.mm +++ b/macosx/mac-os.mm @@ -195,6 +195,7 @@ #import "crosshairs.h" #import "cheats.h" #import "movie.h" +#import "snapshot.h" #import "display.h" #import "blit.h" @@ -280,8 +281,6 @@ bool8 finished = false, cartOpen = false, autofire = false, hidExist = true, - folderWarning = false, - lockedROMMedia = false, directDisplay = false; bool8 fullscreen = false, @@ -433,7 +432,9 @@ enum kmCtrKey = 0x3B, kmMinusKey = 0x1B, kmQKey = 0x0C, - kmWKey = 0x0D + kmWKey = 0x0D, + kmOKey = 0x1F, + kmPKey = 0x23 }; struct ButtonCommand @@ -453,6 +454,9 @@ struct GameViewInfo static volatile bool8 rejectinput = false; +static bool8 pauseEmulation = false, + frameAdvance = false; + static pthread_t s9xthread; static MenuRef recentMenu; @@ -493,7 +497,9 @@ static ButtonCommand btncmd[] = { "_mac1", km0Key, false }, { "_mac2", kmMinusKey, false }, { "_mac3", kmQKey, false }, - { "_mac4", kmWKey, false } + { "_mac4", kmWKey, false }, + { "_mac5", kmOKey, false }, + { "_mac6", kmPKey, false } }; #define kCommandListSize (sizeof(btncmd) / sizeof(btncmd[0])) @@ -598,6 +604,13 @@ int main (int argc, char **argv) pthread_join(s9xthread, NULL); + if (!Settings.NetPlay || Settings.NetPlayServer) + { + SNES9X_SaveSRAM(); + S9xResetSaveTimer(false); + S9xSaveCheatFile(S9xGetFilename(".cht", CHEAT_DIR)); + } + S9xDeinitDisplay(); if (Settings.NetPlay) @@ -657,6 +670,10 @@ static void * MacSnes9xThread (void *) static inline void EmulationLoop (void) { bool8 olddisplayframerate = false; + int storedMacFrameSkip = macFrameSkip; + + pauseEmulation = false; + frameAdvance = false; if (macQTRecord) { @@ -704,7 +721,22 @@ static inline void EmulationLoop (void) while (running) { ProcessInput(); - S9xMainLoop(); + + if (!pauseEmulation) + S9xMainLoop(); + else + { + if (frameAdvance) + { + macFrameSkip = 1; + skipFrames = 1; + frameAdvance = false; + S9xMainLoop(); + macFrameSkip = storedMacFrameSkip; + } + + usleep(Settings.FrameTime); + } } } @@ -2767,6 +2799,14 @@ static void ProcessInput (void) sprintf(msg, "Emulation Speed: 100/%d", macFrameAdvanceRate / 10000); S9xSetInfoString(msg); break; + + case 5: + pauseEmulation = !pauseEmulation; + break; + + case 6: + frameAdvance = true; + break; } } else @@ -3123,7 +3163,7 @@ static void Initialize (void) if ((systemVersion < 0x1039) || (qtVersion < 0x07008000)) { - AppearanceAlert(kAlertStopAlert, kRequiredSystemWarning, kRequiredSystemHint); + AppearanceAlert(kAlertStopAlert, kS9xMacAlertRequiredSystem, kS9xMacAlertRequiredSystemHint); QuitWithFatalError(0, "os 09"); } @@ -3427,7 +3467,7 @@ void S9xMessage (int type, int number, const char *message) if ((type == S9X_INFO) && (number == S9X_ROM_INFO)) if (strstr(message, "checksum ok") == NULL) - AppearanceAlert(kAlertCautionAlert, kBadRomWarning, kBadRomHint); + AppearanceAlert(kAlertCautionAlert, kS9xMacAlertkBadRom, kS9xMacAlertkBadRomHint); } else { diff --git a/macosx/mac-prefs.cpp b/macosx/mac-prefs.cpp index b51948e1..a127fa2d 100755 --- a/macosx/mac-prefs.cpp +++ b/macosx/mac-prefs.cpp @@ -189,8 +189,7 @@ #include "snes9x.h" -#include "apu.h" -#include "gfx.h" +#include "memmap.h" #include "blit.h" #include @@ -202,6 +201,7 @@ #include "mac-cart.h" #include "mac-coreimage.h" #include "mac-dialog.h" +#include "mac-file.h" #include "mac-keyboard.h" #include "mac-os.h" #include "mac-render.h" @@ -1280,6 +1280,15 @@ void ConfigurePreferences (void) InitGameWindow(); ShowWindow(gWindow); } + + if (cartOpen) + { + FSRef ref; + + err = FSPathMakeRef((unsigned char *) Memory.ROMFilename, &ref, NULL); + if (err == noErr) + CheckSaveFolder(&ref); + } } } diff --git a/macosx/mac-snes9x.cpp b/macosx/mac-snes9x.cpp index 3cb1460d..388e077f 100755 --- a/macosx/mac-snes9x.cpp +++ b/macosx/mac-snes9x.cpp @@ -222,10 +222,9 @@ void SNES9X_Go (void) bool8 SNES9X_OpenCart (FSRef *inRef) { - OSStatus err; - FSCatalogInfo info; - FSRef cartRef; - char filename[PATH_MAX + 1]; + OSStatus err; + FSRef cartRef; + char filename[PATH_MAX + 1]; DeinitGameWindow(); @@ -251,8 +250,7 @@ bool8 SNES9X_OpenCart (FSRef *inRef) spcFileCount = pngFileCount = 0; - err = FSGetCatalogInfo(&cartRef, kFSCatInfoVolume, &info, NULL, NULL, NULL); - lockedROMMedia = IsLockedMedia(info.volume); + CheckSaveFolder(&cartRef); Settings.ForceLoROM = (romDetect == kLoROMForce ); Settings.ForceHiROM = (romDetect == kHiROMForce ); @@ -623,6 +621,7 @@ void SNES9X_Quit (void) if (cartOpen) { SNES9X_SaveSRAM(); + S9xResetSaveTimer(false); S9xSaveCheatFile(S9xGetFilename(".cht", CHEAT_DIR)); } diff --git a/win32/_tfwopen.h b/win32/_tfwopen.h index 2bb27d2e..0dd94e28 100644 --- a/win32/_tfwopen.h +++ b/win32/_tfwopen.h @@ -79,6 +79,6 @@ public: #define fopen _tfwopen #define remove _twremove -#endif +#endif // _TFWOPEN_H -#endif // _TFWOPEN_H \ No newline at end of file +#endif diff --git a/win32/render.cpp b/win32/render.cpp index b7e64ce2..97c68bb9 100644 --- a/win32/render.cpp +++ b/win32/render.cpp @@ -549,6 +549,34 @@ inline void SetRect(RECT* rect, int width, int height, int scale) rect->bottom = (height - (GUI.HeightExtend?0:15)) * scale; } +#define AVERAGE_565(el0, el1) (((el0) & (el1)) + ((((el0) ^ (el1)) & 0xF7DE) >> 1)) +void RenderMergeHires(void *buffer, int pitch, unsigned int &width, unsigned int &height) +{ + if (width <= 256) + return; + + for (register int y = 0; y < height; y++) + { + register uint16 *input = (uint16 *) ((uint8 *) buffer + y * pitch); + register uint16 *output = input; + register uint16 l, r; + + l = 0; + for (register int x = 0; x < (width >> 1); x++) + { + r = *input++; + *output++ = AVERAGE_565 (l, r); + l = r; + + r = *input++; + *output++ = AVERAGE_565 (l, r); + l = r; + } + } + + return; +} + // No enlargement, just render to the screen void RenderPlain (SSurface Src, SSurface Dst, RECT *rect) @@ -600,14 +628,14 @@ void RenderForced1X( SSurface Src, SSurface Dst, RECT *rect) memcpy (lpDst, lpSrc, Src.Width << 1); else for (H = 0; H < srcHeight; H++, lpDst += dstPitch, lpSrc += srcPitch) - HalfLine16 (lpDst, lpSrc, Src.Width); + HalfLine16 (lpDst, lpSrc, Src.Width >> 1); else if(Src.Width != 512) for (H = 0; H != Src.Height; H+=2, lpDst += dstPitch, lpSrc += srcPitch<<1) memcpy (lpDst, lpSrc, Src.Width << 1); else for (H = 0; H < Src.Height >> 1; H++, lpDst += dstPitch, lpSrc += srcPitch<<1) - HalfLine16 (lpDst, lpSrc, Src.Width); + HalfLine16 (lpDst, lpSrc, Src.Width >> 1); } else if(GUI.ScreenDepth == 32) { @@ -619,14 +647,14 @@ void RenderForced1X( SSurface Src, SSurface Dst, RECT *rect) SingleLine32 (lpDst, lpSrc, Src.Width); else for (H = 0; H < srcHeight; H++, lpDst += dstPitch, lpSrc += srcPitch) - HalfLine32 (lpDst, lpSrc, Src.Width); + HalfLine32 (lpDst, lpSrc, Src.Width >> 1); else if(Src.Width != 512) for (H = 0; H != Src.Height; H+=2, lpDst += dstPitch, lpSrc += srcPitch<<1) SingleLine32 (lpDst, lpSrc, Src.Width); else for (H = 0; H < Src.Height >> 1; H++, lpDst += dstPitch, lpSrc += srcPitch<<1) - HalfLine32 (lpDst, lpSrc, Src.Width); + HalfLine32 (lpDst, lpSrc, Src.Width >> 1); } } diff --git a/win32/render.h b/win32/render.h index 2ad453df..b80cdcd3 100644 --- a/win32/render.h +++ b/win32/render.h @@ -195,8 +195,9 @@ typedef void (*TRenderMethod)( SSurface Src, SSurface Dst, RECT *); void SelectRenderMethod(); void InitLUTsWin32(); +void RenderMergeHires(void *buffer, int pitch, unsigned int &width, unsigned int &height); extern TRenderMethod RenderMethod; extern TRenderMethod RenderMethodHiRes; -#endif \ No newline at end of file +#endif diff --git a/win32/rsrc/resource.h b/win32/rsrc/resource.h index d6603e0d..113860f4 100644 --- a/win32/rsrc/resource.h +++ b/win32/rsrc/resource.h @@ -129,6 +129,8 @@ #define IDC_TRANS 1113 #define IDC_HIRES 1114 #define IDC_CHEAT_CODE 1115 +#define IDC_HIRES2 1115 +#define IDC_HIRESBLEND 1115 #define IDC_FILTERBOX 1116 #define IDC_FILTERBOX2 1117 #define IDC_AUTOFRAME 1118 @@ -397,7 +399,7 @@ #define ID_OPTIONS_EMULATION 40069 #define ID_OPTIONS_SETTINGS 40070 #define ID_DEBUG_TRACE 40071 -#define ID_FRAME_ADVANCE 40074 +#define ID_FRAME_ADVANCE 40074 #define ID_DEBUG_FRAME_ADVANCE 40075 #define ID_DEBUG_SNES_STATUS 40076 #define ID_NETPLAY_SERVER 40077 diff --git a/win32/rsrc/snes9x.rc b/win32/rsrc/snes9x.rc index 7d744f39..9c9fbc4a 100644 --- a/win32/rsrc/snes9x.rc +++ b/win32/rsrc/snes9x.rc @@ -173,13 +173,13 @@ BEGIN CONTROL "Sync By Reset",IDC_SYNCBYRESET,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,10,90,174,15 END -IDD_NEWDISPLAY DIALOGEX 0, 0, 353, 259 +IDD_NEWDISPLAY DIALOGEX 0, 0, 353, 274 STYLE DS_SETFONT | DS_MODALFRAME | DS_3DLOOK | DS_CENTER | WS_POPUP | WS_CLIPCHILDREN | WS_CAPTION CAPTION "Display Settings" FONT 8, "MS Sans Serif", 0, 0, 0x1 BEGIN - DEFPUSHBUTTON "OK",IDOK,239,237,50,14 - PUSHBUTTON "Cancel",IDCANCEL,296,237,50,14 + DEFPUSHBUTTON "OK",IDOK,239,251,50,14 + PUSHBUTTON "Cancel",IDCANCEL,296,251,50,14 COMBOBOX IDC_OUTPUTMETHOD,68,17,101,58,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP CONTROL "Fullscreen",IDC_FULLSCREEN,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,11,36,48,10 CONTROL "Emulate Fullscreen",IDC_EMUFULLSCREEN,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,11,47,75,10 @@ -188,40 +188,41 @@ BEGIN COMBOBOX IDC_ASPECTDROP,104,67,63,41,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP CONTROL "Bilinear Filtering",IDC_BILINEAR,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,11,80,75,8 CONTROL "Show Frame Rate",IDC_SHOWFPS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,11,91,73,8 - CONTROL "Automatic",IDC_AUTOFRAME,"Button",BS_AUTORADIOBUTTON,11,126,43,8 - CONTROL "Fixed",IDC_FIXEDSKIP,"Button",BS_AUTORADIOBUTTON,11,143,43,10 - EDITTEXT IDC_MAXSKIP,133,125,35,14,ES_AUTOHSCROLL | ES_NUMBER - CONTROL "",IDC_SPIN_MAX_SKIP_DISP,"msctls_updown32",UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_ARROWKEYS,169,127,11,13 - EDITTEXT IDC_SKIPCOUNT,133,142,35,14,ES_AUTOHSCROLL | ES_NUMBER - CONTROL "",IDC_SPIN_MAX_SKIP_DISP_FIXED,"msctls_updown32",UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_ARROWKEYS,169,139,11,13 + CONTROL "Automatic",IDC_AUTOFRAME,"Button",BS_AUTORADIOBUTTON,11,140,43,8 + CONTROL "Fixed",IDC_FIXEDSKIP,"Button",BS_AUTORADIOBUTTON,11,157,43,10 + EDITTEXT IDC_MAXSKIP,133,139,35,14,ES_AUTOHSCROLL | ES_NUMBER + CONTROL "",IDC_SPIN_MAX_SKIP_DISP,"msctls_updown32",UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_ARROWKEYS,169,141,11,13 + EDITTEXT IDC_SKIPCOUNT,133,156,35,14,ES_AUTOHSCROLL | ES_NUMBER + CONTROL "",IDC_SPIN_MAX_SKIP_DISP_FIXED,"msctls_updown32",UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_ARROWKEYS,169,153,11,13 COMBOBOX IDC_FILTERBOX,186,17,153,90,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP COMBOBOX IDC_FILTERBOX2,217,33,122,90,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP LTEXT "Resolution",IDC_CURRMODE,187,71,41,8 COMBOBOX IDC_RESOLUTION,234,69,105,95,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP CONTROL "Enable Triple Buffering",IDC_DBLBUFFER,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,187,86,87,10 - CONTROL "VSync",IDC_VSYNC,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,300,86,37,10 CONTROL "Transparency Effects",IDC_TRANS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,187,113,153,10 CONTROL "Hi Resolution Support",IDC_HIRES,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,187,124,85,10 - CONTROL "Extend Height of SNES Image",IDC_HEIGHT_EXTEND,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,187,135,111,10 + CONTROL "Extend Height of SNES Image",IDC_HEIGHT_EXTEND,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,187,147,111,10 CONTROL "Display messages before applying filters",IDC_MESSAGES_IN_IMAGE, - "Button",BS_AUTOCHECKBOX | WS_TABSTOP,187,146,140,10 - GROUPBOX "",IDC_SHADER_GROUP,8,162,338,71,0,WS_EX_TRANSPARENT - EDITTEXT IDC_SHADER_HLSL_FILE,13,184,306,14,ES_AUTOHSCROLL | WS_DISABLED - PUSHBUTTON "...",IDC_SHADER_HLSL_BROWSE,322,184,19,14,WS_DISABLED - GROUPBOX "Frame Skipping:",IDC_STATIC,7,113,167,46,0,WS_EX_TRANSPARENT - GROUPBOX "SNES Image",IDC_STATIC,180,103,166,57,0,WS_EX_TRANSPARENT + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,187,158,140,10 + GROUPBOX "",IDC_SHADER_GROUP,8,176,338,71,0,WS_EX_TRANSPARENT + EDITTEXT IDC_SHADER_HLSL_FILE,13,198,306,14,ES_AUTOHSCROLL | WS_DISABLED + PUSHBUTTON "...",IDC_SHADER_HLSL_BROWSE,322,198,19,14,WS_DISABLED + GROUPBOX "Frame Skipping:",IDC_STATIC,7,127,167,46,0,WS_EX_TRANSPARENT + GROUPBOX "SNES Image",IDC_STATIC,180,103,166,71,0,WS_EX_TRANSPARENT GROUPBOX "Output Image Processing",IDC_STATIC,179,7,166,46,0,WS_EX_TRANSPARENT GROUPBOX "Fullscreen Display Settings",IDC_STATIC,179,56,166,44,0,WS_EX_TRANSPARENT LTEXT "Hi Res:",IDC_HIRESLABEL,186,36,31,8 - GROUPBOX "General",IDC_STATIC,7,7,167,99,0,WS_EX_TRANSPARENT - LTEXT "Max skipped frames:",IDC_STATIC,62,126,67,8 - LTEXT "Amount skipped:",IDC_STATIC,62,144,67,8 + GROUPBOX "General",IDC_STATIC,7,7,167,113,0,WS_EX_TRANSPARENT + LTEXT "Max skipped frames:",IDC_STATIC,62,140,67,8 + LTEXT "Amount skipped:",IDC_STATIC,62,158,67,8 LTEXT "Output Method",IDC_STATIC,10,19,51,11 - CONTROL "Use Shader",IDC_SHADER_ENABLED,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,11,162,52,9 - LTEXT "HLSL Effect File",IDC_STATIC,13,173,104,8 - EDITTEXT IDC_SHADER_GLSL_FILE,13,213,306,14,ES_AUTOHSCROLL | WS_DISABLED - PUSHBUTTON "...",IDC_SHADER_GLSL_BROWSE,322,213,19,14,WS_DISABLED - LTEXT "GLSL shader",IDC_STATIC,13,202,104,8 + CONTROL "Use Shader",IDC_SHADER_ENABLED,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,11,176,52,9 + LTEXT "HLSL Effect File",IDC_STATIC,13,187,104,8 + EDITTEXT IDC_SHADER_GLSL_FILE,13,227,306,14,ES_AUTOHSCROLL | WS_DISABLED + PUSHBUTTON "...",IDC_SHADER_GLSL_BROWSE,322,227,19,14,WS_DISABLED + LTEXT "GLSL shader",IDC_STATIC,13,216,104,8 + CONTROL "Blend Hi-Res Images",IDC_HIRESBLEND,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,187,136,82,10 + CONTROL "VSync",IDC_VSYNC,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,11,102,37,10 END IDD_CHEATER DIALOGEX 0, 0, 262, 218 @@ -603,7 +604,7 @@ BEGIN LEFTMARGIN, 7 RIGHTMARGIN, 346 TOPMARGIN, 7 - BOTTOMMARGIN, 251 + BOTTOMMARGIN, 266 END IDD_CHEATER, DIALOG diff --git a/win32/snes9xw.vcproj b/win32/snes9xw.vcproj index adad32fa..0fd8c850 100644 --- a/win32/snes9xw.vcproj +++ b/win32/snes9xw.vcproj @@ -57,7 +57,7 @@ OmitFramePointers="true" WholeProgramOptimization="true" AdditionalIncludeDirectories="$(ProjectDir),$(ProjectDir)..\,$(ProjectDir)..\..\,$(ProjectDir)..\..\zLib,$(ProjectDir)..\unzip,$(ProjectDir)..\..\FMOD\api\inc,$(ProjectDir)..\..\libPNG\src,$(ProjectDir)..\snes9x" - PreprocessorDefinitions="NDEBUG;HAVE_LIBPNG;JMA_SUPPORT;CORRECT_VRAM_READS;ZLIB;UNZIP_SUPPORT;__WIN32__;FMODEX_SUPPORT;NETPLAY_SUPPORT" + PreprocessorDefinitions="NDEBUG;HAVE_LIBPNG;JMA_SUPPORT;ZLIB;UNZIP_SUPPORT;__WIN32__;FMODEX_SUPPORT;NETPLAY_SUPPORT" StringPooling="true" RuntimeLibrary="0" StructMemberAlignment="0" @@ -159,7 +159,7 @@ OmitFramePointers="true" WholeProgramOptimization="true" AdditionalIncludeDirectories="$(ProjectDir),$(ProjectDir)..\,$(ProjectDir)..\..\,$(ProjectDir)..\..\zLib,$(ProjectDir)..\unzip,$(ProjectDir)..\..\FMOD\api\inc,$(ProjectDir)..\..\libPNG\src,$(ProjectDir)..\snes9x" - PreprocessorDefinitions="NDEBUG;HAVE_LIBPNG;JMA_SUPPORT;CORRECT_VRAM_READS;ZLIB;UNZIP_SUPPORT;__WIN32__;FMODEX_SUPPORT;NETPLAY_SUPPORT" + PreprocessorDefinitions="NDEBUG;HAVE_LIBPNG;JMA_SUPPORT;ZLIB;UNZIP_SUPPORT;__WIN32__;FMODEX_SUPPORT;NETPLAY_SUPPORT" StringPooling="true" RuntimeLibrary="0" StructMemberAlignment="0" @@ -355,7 +355,7 @@ Name="VCCLCompilerTool" Optimization="0" AdditionalIncludeDirectories="$(ProjectDir),$(ProjectDir)..\,$(ProjectDir)..\..\,$(ProjectDir)..\..\zLib,$(ProjectDir)..\unzip,$(ProjectDir)..\..\FMOD\api\inc,$(ProjectDir)..\..\libPNG\src,$(ProjectDir)..\snes9x" - PreprocessorDefinitions="_DEBUG;HAVE_LIBPNG;JMA_SUPPORT;CORRECT_VRAM_READS;ZLIB;UNZIP_SUPPORT;__WIN32__;NETPLAY_SUPPORT;FMODEX_SUPPORT;D3D_DEBUG_INFO" + PreprocessorDefinitions="_DEBUG;HAVE_LIBPNG;JMA_SUPPORT;ZLIB;UNZIP_SUPPORT;__WIN32__;NETPLAY_SUPPORT;FMODEX_SUPPORT;D3D_DEBUG_INFO" RuntimeLibrary="1" StructMemberAlignment="0" UsePrecompiledHeader="0" @@ -454,7 +454,7 @@ Name="VCCLCompilerTool" Optimization="0" AdditionalIncludeDirectories=""$(ProjectDir)";"$(ProjectDir)..\";"$(ProjectDir)..\..\";"$(ProjectDir)..\..\zLib";"$(ProjectDir)..\unzip";"$(ProjectDir)..\..\FMOD\api\inc";"$(ProjectDir)..\..\libPNG\src";"$(ProjectDir)..\snes9x"" - PreprocessorDefinitions="_DEBUG;HAVE_LIBPNG;JMA_SUPPORT;CORRECT_VRAM_READS;ZLIB;UNZIP_SUPPORT;__WIN32__;NETPLAY_SUPPORT;FMODEX_SUPPORT;D3D_DEBUG_INFO" + PreprocessorDefinitions="_DEBUG;HAVE_LIBPNG;JMA_SUPPORT;ZLIB;UNZIP_SUPPORT;__WIN32__;NETPLAY_SUPPORT;FMODEX_SUPPORT;D3D_DEBUG_INFO" RuntimeLibrary="1" StructMemberAlignment="0" UsePrecompiledHeader="0" @@ -554,7 +554,7 @@ Name="VCCLCompilerTool" Optimization="0" AdditionalIncludeDirectories=""$(ProjectDir)";"$(ProjectDir)..\";"$(ProjectDir)..\..\";"$(ProjectDir)..\..\zLib";"$(ProjectDir)..\unzip";"$(ProjectDir)..\..\FMOD\api\inc";"$(ProjectDir)..\..\libPNG\src";"$(ProjectDir)..\snes9x"" - PreprocessorDefinitions="_DEBUG;HAVE_LIBPNG;JMA_SUPPORT;CORRECT_VRAM_READS;CPU_SHUTDOWN;ZLIB;UNZIP_SUPPORT;__WIN32__;NETPLAY_SUPPORT;FMODEX_SUPPORT;D3D_DEBUG_INFO" + PreprocessorDefinitions="_DEBUG;HAVE_LIBPNG;JMA_SUPPORT;CORRECT_VRAM_READS;ZLIB;UNZIP_SUPPORT;__WIN32__;NETPLAY_SUPPORT;FMODEX_SUPPORT;D3D_DEBUG_INFO;DEBUGGER" RuntimeLibrary="1" StructMemberAlignment="0" UsePrecompiledHeader="0" @@ -597,7 +597,7 @@ RandomizedBaseAddress="1" DataExecutionPrevention="0" TargetMachine="17" - Profile="true" + Profile="false" /> Render(Src); + GUI.FlipCounter++; + } } void WinChangeWindowSize(unsigned int newWidth, unsigned int newHeight) @@ -329,9 +334,7 @@ bool8 S9xInitUpdate (void) bool8 S9xContinueUpdate(int Width, int Height) { // called every other frame during interlace - - SSurface Src; - + Src.Width = Width; if(Height%SNES_HEIGHT) Src.Height = Height; @@ -344,10 +347,8 @@ bool8 S9xContinueUpdate(int Width, int Height) Src.Pitch = GFX.Pitch; Src.Surface = (BYTE*)GFX.Screen; - Height = Src.Height; - // avi writing - DoAVIVideoFrame(&Src, Width, Height); + DoAVIVideoFrame(&Src); return true; } @@ -355,8 +356,6 @@ bool8 S9xContinueUpdate(int Width, int Height) // do the actual rendering of a frame bool8 S9xDeinitUpdate (int Width, int Height) { - SSurface Src; - Src.Width = Width; if(Height%SNES_HEIGHT) Src.Height = Height; @@ -372,10 +371,12 @@ bool8 S9xDeinitUpdate (int Width, int Height) const int OrigHeight = Height; Height = Src.Height; - // avi writing - DoAVIVideoFrame(&Src, Width, Height); + if(GUI.BlendHiRes) { + RenderMergeHires(Src.Surface,Src.Pitch,Src.Width,Src.Height); + } - SelectRenderMethod (); + // avi writing + DoAVIVideoFrame(&Src); // Clear some of the old SNES rendered image // when the resolution becomes lower in x or y, @@ -406,9 +407,7 @@ bool8 S9xDeinitUpdate (int Width, int Height) LastHeight = OrigHeight; } - S9xDisplayOutput->Render(Src); - - GUI.FlipCounter++; + WinRefreshDisplay(); return (true); } diff --git a/win32/wsnes9x.cpp b/win32/wsnes9x.cpp index 904c03f0..8c492099 100644 --- a/win32/wsnes9x.cpp +++ b/win32/wsnes9x.cpp @@ -6958,7 +6958,7 @@ INT_PTR CALLBACK DlgFunky(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam) // temporary GUI state for restoring after previewing while selecting options static int prevScale, prevScaleHiRes, prevPPL; - static bool prevStretch, prevAspectRatio, prevHeightExtend, prevAutoDisplayMessages, prevVideoMemory, prevShaderEnabled; + static bool prevStretch, prevAspectRatio, prevHeightExtend, prevAutoDisplayMessages, prevBilinearFilter, prevShaderEnabled; static int prevAspectWidth; static OutputMethod prevOutputMethod; static TCHAR prevHLSLShaderFile[MAX_PATH],prevGLSLShaderFile[MAX_PATH]; @@ -6983,7 +6983,7 @@ INT_PTR CALLBACK DlgFunky(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam) prevScaleHiRes = GUI.ScaleHiRes; prevPPL = GFX.RealPPL; prevStretch = GUI.Stretch; - prevVideoMemory = GUI.BilinearFilter; + prevBilinearFilter = GUI.BilinearFilter; prevAspectRatio = GUI.AspectRatio; prevAspectWidth = GUI.AspectWidth; prevHeightExtend = GUI.HeightExtend; @@ -7009,6 +7009,8 @@ INT_PTR CALLBACK DlgFunky(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam) if(Settings.SupportHiRes) SendDlgItemMessage(hDlg, IDC_HIRES, BM_SETCHECK, (WPARAM)BST_CHECKED, 0); + if(GUI.BlendHiRes) + SendDlgItemMessage(hDlg, IDC_HIRESBLEND, BM_SETCHECK, (WPARAM)BST_CHECKED, 0); if(GUI.HeightExtend) SendDlgItemMessage(hDlg, IDC_HEIGHT_EXTEND, BM_SETCHECK, (WPARAM)BST_CHECKED, 0); if(Settings.AutoDisplayMessages) @@ -7098,7 +7100,7 @@ INT_PTR CALLBACK DlgFunky(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam) // have to start focus on something like this or Escape won't exit the dialog SetFocus(hDlg); - goto checkUpdateFilterBox2; + SendDlgItemMessage(hDlg,IDC_FILTERBOX2,CB_SETCURSEL,(WPARAM)GUI.ScaleHiRes,0); break; case WM_CLOSE: @@ -7330,7 +7332,7 @@ updateFilterBox2: { char text [256]; text[0] = '\0'; - SendMessage(GetDlgItem(hDlg, IDC_FILTERBOX2), WM_GETTEXT, 256,(LPARAM)text); + SendMessageA(GetDlgItem(hDlg, IDC_FILTERBOX2), WM_GETTEXT, 256,(LPARAM)text); int scale = GUI.Scale; for(int i=0; i