diff --git a/external/imgui/snes9x_imgui.cpp b/external/imgui/snes9x_imgui.cpp index 4643d961..747185f5 100644 --- a/external/imgui/snes9x_imgui.cpp +++ b/external/imgui/snes9x_imgui.cpp @@ -279,5 +279,5 @@ void S9xImGuiInit(S9xImGuiInitInfo *init_info) builder.AddText("←↑→↓▶❚"); ranges.clear(); builder.BuildRanges(&ranges); - ImGui::GetIO().Fonts->AddFontFromMemoryCompressedTTF(imgui_noto_font_compressed_data, settings.font_size, nullptr, ranges.Data); + ImGui::GetIO().Fonts->AddFontFromMemoryCompressedTTF(imgui_noto_font_compressed_data, imgui_noto_font_compressed_size, settings.font_size, nullptr, ranges.Data); } diff --git a/gfx.cpp b/gfx.cpp index fbeee33f..2fb1968c 100644 --- a/gfx.cpp +++ b/gfx.cpp @@ -12,7 +12,6 @@ #include "cheats.h" #include "movie.h" #include "screenshot.h" -#include "font.h" #include "display.h" extern struct SCheatData Cheat; @@ -21,7 +20,6 @@ extern struct SLineMatrixData LineMatrixData[240]; void S9xComputeClipWindows (void); -static int font_width = 8, font_height = 9; void (*S9xCustomDisplayString) (const char *, int, int, bool, int) = NULL; static void SetupOBJ (void); @@ -1733,76 +1731,147 @@ void S9xSetInfoString (const char *string) } } -void S9xDisplayChar (uint16 *s, uint8 c) +#include "var8x10font.h" +static const int font_width = 8; +static const int font_height = 10; + +static inline int CharWidth(uint8 c) { - const uint16 black = BUILD_PIXEL(0, 0, 0); + return font_width - var8x10font_kern[c - 32][0] - var8x10font_kern[c - 32][1]; +} - int line = ((c - 32) >> 4) * font_height; - int offset = ((c - 32) & 15) * font_width; +static int StringWidth(const char* str) +{ + int length = strlen(str); + int pixcount = 0; - for (int h = 0; h < font_height; h++, line++, s += GFX.RealPPL - font_width) + if (length > 0) + pixcount++; + + for (int i = 0; i < length; i++) { - for (int w = 0; w < font_width; w++, s++) - { - char p = font[line][offset + w]; + pixcount += (CharWidth(str[i]) - 1); + } - if (p == '#') + return pixcount; +} + +static void VariableDisplayChar(int x, int y, uint8 c, bool monospace = false, int overlap = 0) +{ + int cindex = c - 32; + int crow = cindex >> 4; + int ccol = cindex & 15; + int cwidth = font_width - (monospace ? 0 : (var8x10font_kern[cindex][0] + var8x10font_kern[cindex][1])); + + int line = crow * font_height; + int offset = ccol * font_width + (monospace ? 0 : var8x10font_kern[cindex][0]); + int scale = IPPU.RenderedScreenWidth / SNES_WIDTH; + + uint16* s = GFX.Screen + y * GFX.RealPPL + x * scale; + + for (int h = 0; h < font_height; h++, line++, s += GFX.RealPPL - cwidth * scale) + { + for (int w = 0; w < cwidth; w++, s++) + { + if (var8x10font[line][offset + w] == '#') *s = Settings.DisplayColor; - else - if (p == '.') - *s = black; + else if (var8x10font[line][offset + w] == '.') + *s = 0x0000; + // else if (!monospace && w >= overlap) + // *s = (*s & 0xf7de) >> 1; + // *s = (*s & 0xe79c) >> 2; + + if (scale > 1) + { + s[1] = s[0]; + s++; + } } } } -static void DisplayStringFromBottom (const char *string, int linesFromBottom, int pixelsFromLeft, bool allowWrap) +static void S9xVariableDisplayString(const char* string, int linesFromBottom, + int pixelsFromLeft, bool allowWrap, int type) { - if (S9xCustomDisplayString) + bool monospace = true; + if (type == S9X_NO_INFO) { - S9xCustomDisplayString (string, linesFromBottom, pixelsFromLeft, allowWrap, S9X_NO_INFO); - return; + if (linesFromBottom <= 0) + linesFromBottom = 1; + + if (linesFromBottom >= 5 && !Settings.DisplayPressedKeys) + { + if (!Settings.DisplayPressedKeys) + linesFromBottom -= 3; + else + linesFromBottom -= 1; + } + + if (pixelsFromLeft > 128) + pixelsFromLeft = SNES_WIDTH - StringWidth(string); + + monospace = false; } - if (linesFromBottom <= 0) - linesFromBottom = 1; + int dst_x = pixelsFromLeft; + int dst_y = IPPU.RenderedScreenHeight - (font_height)*linesFromBottom; + int len = strlen(string); - uint16 *dst = GFX.Screen + (IPPU.RenderedScreenHeight - font_height * linesFromBottom) * GFX.RealPPL + pixelsFromLeft; + if (IPPU.RenderedScreenHeight % 224 && !Settings.ShowOverscan) + dst_y -= 8; + else if (Settings.ShowOverscan) + dst_y += 8; - int len = strlen(string); - int max_chars = IPPU.RenderedScreenWidth / (font_width - 1); - int char_count = 0; + int overlap = 0; - for (int i = 0 ; i < len ; i++, char_count++) + for (int i = 0; i < len; i++) { - if (char_count >= max_chars || (uint8) string[i] < 32) + int cindex = string[i] - 32; + int char_width = font_width - (monospace ? 1 : (var8x10font_kern[cindex][0] + var8x10font_kern[cindex][1])); + + if (dst_x + char_width > SNES_WIDTH || (uint8)string[i] < 32) { if (!allowWrap) break; - dst += font_height * GFX.RealPPL - (font_width - 1) * max_chars; - if (dst >= GFX.Screen + IPPU.RenderedScreenHeight * GFX.RealPPL) - break; + linesFromBottom--; + dst_y = IPPU.RenderedScreenHeight - font_height * linesFromBottom; + dst_x = pixelsFromLeft; - char_count -= max_chars; + if (dst_y >= IPPU.RenderedScreenHeight) + break; } - if ((uint8) string[i] < 32) + if ((uint8)string[i] < 32) continue; - S9xDisplayChar(dst, string[i]); - dst += font_width - 1; + VariableDisplayChar(dst_x, dst_y, string[i], monospace, overlap); + + dst_x += char_width - 1; + overlap = 1; } } -static void S9xDisplayStringType (const char *string, int linesFromBottom, int pixelsFromLeft, bool allowWrap, int type) +static void DisplayStringFromBottom(const char* string, int linesFromBottom, int pixelsFromLeft, bool allowWrap) { - if (S9xCustomDisplayString) - { - S9xCustomDisplayString (string, linesFromBottom, pixelsFromLeft, allowWrap, type); - return; - } + if (S9xCustomDisplayString) + { + S9xCustomDisplayString(string, linesFromBottom, pixelsFromLeft, allowWrap, S9X_NO_INFO); + return; + } - S9xDisplayString (string, linesFromBottom, pixelsFromLeft, allowWrap); + S9xVariableDisplayString(string, linesFromBottom, pixelsFromLeft, allowWrap, S9X_NO_INFO); +} + +static void S9xDisplayStringType(const char* string, int linesFromBottom, int pixelsFromLeft, bool allowWrap, int type) +{ + if (S9xCustomDisplayString) + { + S9xCustomDisplayString(string, linesFromBottom, pixelsFromLeft, allowWrap, type); + return; + } + + S9xVariableDisplayString(string, linesFromBottom, pixelsFromLeft, allowWrap, type); } static void DisplayTime (void) diff --git a/port.h b/port.h index a6864a79..0a267154 100644 --- a/port.h +++ b/port.h @@ -123,20 +123,11 @@ typedef size_t pint; #include "fscompat.h" -#ifndef __WIN32__ #define S9xDisplayString DisplayStringFromBottom -#else // __WIN32__ +#ifdef __WIN32__ #define snprintf _snprintf #define strcasecmp stricmp #define strncasecmp strnicmp -#ifndef __LIBRETRO__ -void WinDisplayStringFromBottom(const char *string, int linesFromBottom, int pixelsFromLeft, bool allowWrap); -#define S9xDisplayString WinDisplayStringFromBottom -void SetInfoDlgColor(unsigned char, unsigned char, unsigned char); -#define SET_UI_COLOR(r,g,b) SetInfoDlgColor(r,g,b) -#else // __LIBRETRO__ -#define S9xDisplayString DisplayStringFromBottom -#endif // __LIBRETRO__ #endif // __WIN32__ #if defined(__DJGPP) || defined(__WIN32__) diff --git a/snes9x.h b/snes9x.h index df305469..57fab48b 100644 --- a/snes9x.h +++ b/snes9x.h @@ -259,6 +259,7 @@ struct SSettings uint32 InitialInfoStringTimeout; uint16 DisplayColor; bool8 BilinearFilter; + bool ShowOverscan; bool8 Multi; char CartAName[PATH_MAX + 1]; diff --git a/gtk/src/var8x10font.h b/var8x10font.h similarity index 100% rename from gtk/src/var8x10font.h rename to var8x10font.h diff --git a/win32/CDirect3D.cpp b/win32/CDirect3D.cpp index eeb2077b..122a101f 100644 --- a/win32/CDirect3D.cpp +++ b/win32/CDirect3D.cpp @@ -290,10 +290,6 @@ void CDirect3D::Render(SSurface Src) Dst.Pitch = lr.Pitch; RenderMethod (Src, Dst, &dstRect); - if(!Settings.AutoDisplayMessages) { - WinSetCustomDisplaySurface((void *)Dst.Surface, Dst.Pitch/2, dstRect.right-dstRect.left, dstRect.bottom-dstRect.top, GetFilterScale(CurrentScale)); - S9xDisplayMessages ((uint16*)Dst.Surface, Dst.Pitch/2, dstRect.right-dstRect.left, dstRect.bottom-dstRect.top, GetFilterScale(CurrentScale)); - } drawSurface->UnlockRect(0); } diff --git a/win32/CDirectDraw.cpp b/win32/CDirectDraw.cpp index 981527e6..c9536dd5 100644 --- a/win32/CDirectDraw.cpp +++ b/win32/CDirectDraw.cpp @@ -435,11 +435,6 @@ void CDirectDraw::Render(SSurface Src) RenderMethod (Src, Dst, &srcRect); } - if(!Settings.AutoDisplayMessages) { - WinSetCustomDisplaySurface((void *)Dst.Surface, (Dst.Pitch*8/GUI.ScreenDepth), srcRect.right-srcRect.left, srcRect.bottom-srcRect.top, GetFilterScale(CurrentScale)); - S9xDisplayMessages ((uint16*)Dst.Surface, Dst.Pitch/2, srcRect.right-srcRect.left, srcRect.bottom-srcRect.top, GetFilterScale(CurrentScale)); - } - RECT lastRect = SizeHistory [GUI.FlipCounter % GUI.NumFlipFrames]; POINT p; @@ -456,7 +451,7 @@ void CDirectDraw::Render(SSurface Src) int height = dstRect.bottom - dstRect.top; int oldWidth = GUI.AspectWidth; - int oldHeight = GUI.HeightExtend ? SNES_HEIGHT_EXTENDED : SNES_HEIGHT; + int oldHeight = Settings.ShowOverscan ? SNES_HEIGHT_EXTENDED : SNES_HEIGHT; int newWidth, newHeight; if(oldWidth * height > oldHeight * width) diff --git a/win32/COpenGL.cpp b/win32/COpenGL.cpp index b5dd7740..f5ae9451 100644 --- a/win32/COpenGL.cpp +++ b/win32/COpenGL.cpp @@ -297,10 +297,6 @@ void COpenGL::Render(SSurface Src) Dst.Pitch = outTextureWidth * 2; RenderMethod (Src, Dst, &dstRect); - if(!Settings.AutoDisplayMessages) { - WinSetCustomDisplaySurface((void *)Dst.Surface, Dst.Pitch/2, dstRect.right-dstRect.left, dstRect.bottom-dstRect.top, GetFilterScale(CurrentScale)); - S9xDisplayMessages ((uint16*)Dst.Surface, Dst.Pitch/2, dstRect.right-dstRect.left, dstRect.bottom-dstRect.top, GetFilterScale(CurrentScale)); - } if(pboFunctionsLoaded) glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER); diff --git a/win32/CVulkan.cpp b/win32/CVulkan.cpp index 8a3badb3..d0d0ef1e 100644 --- a/win32/CVulkan.cpp +++ b/win32/CVulkan.cpp @@ -74,11 +74,6 @@ void CVulkan::Render(SSurface Src) RenderMethod(Src, Dst, &dstRect); - if (!Settings.AutoDisplayMessages) { - WinSetCustomDisplaySurface((void*)Dst.Surface, Dst.Pitch / 2, dstRect.right - dstRect.left, dstRect.bottom - dstRect.top, GetFilterScale(GUI.Scale)); - S9xDisplayMessages((uint16*)Dst.Surface, Dst.Pitch / 2, dstRect.right - dstRect.left, dstRect.bottom - dstRect.top, GetFilterScale(GUI.Scale)); - } - RECT windowSize, displayRect; GetClientRect(hWnd, &windowSize); //Get maximum rect respecting AR setting diff --git a/win32/render.cpp b/win32/render.cpp index 5cf659c8..944a8d83 100644 --- a/win32/render.cpp +++ b/win32/render.cpp @@ -300,7 +300,7 @@ inline static bool GetFilterBlendSupport(RenderFilter filterID) void AdjustHeightExtend(unsigned int &height) { - if(GUI.HeightExtend) + if(Settings.ShowOverscan) { if(height == SNES_HEIGHT) height = SNES_HEIGHT_EXTENDED; diff --git a/win32/rsrc/resource.h b/win32/rsrc/resource.h index 085455c7..e298a516 100644 --- a/win32/rsrc/resource.h +++ b/win32/rsrc/resource.h @@ -418,6 +418,8 @@ #define IDC_NO_SPRITE_LIMIT 3037 #define IDC_SET_DEFAULTS 3038 #define IDC_BUTTON_SLOT_1 3039 +#define IDC_OSD_SCALE 3041 +#define IDC_SPIN_OSD_SIZE 3042 #define IDC_STATIC_SLOT_1 3059 #define ID_FILE_EXIT 40001 #define ID_WINDOW_HIDEMENUBAR 40004 @@ -561,7 +563,7 @@ #ifndef APSTUDIO_READONLY_SYMBOLS #define _APS_NEXT_RESOURCE_VALUE 169 #define _APS_NEXT_COMMAND_VALUE 40189 -#define _APS_NEXT_CONTROL_VALUE 3040 +#define _APS_NEXT_CONTROL_VALUE 3044 #define _APS_NEXT_SYMED_VALUE 101 #endif #endif diff --git a/win32/rsrc/snes9x.rc b/win32/rsrc/snes9x.rc index 9a2ab695..7753533b 100644 --- a/win32/rsrc/snes9x.rc +++ b/win32/rsrc/snes9x.rc @@ -222,10 +222,8 @@ BEGIN CONTROL "Transparency Effects",IDC_TRANS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,186,131,150,8 CONTROL "Blend Hi-Res Images",IDC_HIRESBLEND,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,186,143,150,8 CONTROL "Extend Height of SNES Image",IDC_HEIGHT_EXTEND,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,186,155,150,8 - CONTROL "Display messages before applying filters",IDC_MESSAGES_IN_IMAGE, + CONTROL "Display messages inside SNES image",IDC_MESSAGES_IN_IMAGE, "Button",BS_AUTOCHECKBOX | WS_TABSTOP,186,167,150,8 - CONTROL "Scale messages with EPX if possible",IDC_MESSAGES_SCALE, - "Button",BS_AUTOCHECKBOX | WS_TABSTOP,186,179,150,8 GROUPBOX "Frame Skipping:",IDC_STATIC,6,145,168,48,0,WS_EX_TRANSPARENT GROUPBOX "SNES Image",IDC_STATIC,180,118,162,75,0,WS_EX_TRANSPARENT GROUPBOX "Output Image Processing",IDC_STATIC,180,6,162,61,0,WS_EX_TRANSPARENT @@ -233,6 +231,9 @@ BEGIN LTEXT "Hi Res:",IDC_HIRESLABEL,186,36,31,8 GROUPBOX "General",IDC_STATIC,6,6,168,138,0,WS_EX_TRANSPARENT LTEXT "Output Method",IDC_STATIC,12,18,51,12 + LTEXT "On-screen Display Size:",IDC_STATIC,186,179,79,8 + EDITTEXT IDC_OSD_SCALE,296,176,40,14,ES_AUTOHSCROLL | ES_NUMBER + CONTROL "",IDC_SPIN_OSD_SIZE,"msctls_updown32",UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_ARROWKEYS,320,177,9,12 END IDD_CHEATER DIALOGEX 0, 0, 378, 189 diff --git a/win32/snes9xw.vcxproj b/win32/snes9xw.vcxproj index 31e04fd8..f7e8fbc0 100644 --- a/win32/snes9xw.vcxproj +++ b/win32/snes9xw.vcxproj @@ -118,7 +118,7 @@ Disabled $(ProjectDir);$(ProjectDir)..\;$(ProjectDir)..\..\;$(ProjectDir)zlib\src;$(ProjectDir)..\unzip;$(ProjectDir)libpng\src;$(ProjectDir)..\apu\bapu;$(ProjectDir)..\external\glslang;$(ProjectDir)..\external\stb;$(ProjectDir)..\external\vulkan-headers\include;$(ProjectDir)..\external\VulkanMemoryAllocator-Hpp\include;$(ProjectDir)..\external\fmt\include - _DEBUG;ALLOW_CPU_OVERCLOCK;HAVE_LIBPNG;JMA_SUPPORT;ZLIB;UNZIP_SUPPORT;__WIN32__;NETPLAY_SUPPORT;D3D_DEBUG_INFO;DIRECTDRAW_SUPPORT;USE_SLANG;%(PreprocessorDefinitions);VK_USE_PLATFORM_WIN32_KHR;VULKAN_HPP_DISPATCH_LOADER_DYNAMIC=1;VMA_DYNAMIC_VULKAN_FUNCTIONS=1;VMA_STATIC_VULKAN_FUNCTIONS=0;VMA_USE_STL_SHARED_MUTEX=0 + _DEBUG;ALLOW_CPU_OVERCLOCK;HAVE_LIBPNG;JMA_SUPPORT;ZLIB;UNZIP_SUPPORT;__WIN32__;NETPLAY_SUPPORT;D3D_DEBUG_INFO;DIRECTDRAW_SUPPORT;USE_SLANG;%(PreprocessorDefinitions);VK_USE_PLATFORM_WIN32_KHR;VULKAN_HPP_DISPATCH_LOADER_DYNAMIC=1;VMA_DYNAMIC_VULKAN_FUNCTIONS=1;VMA_STATIC_VULKAN_FUNCTIONS=0;VMA_USE_STL_SHARED_MUTEX=0;IMGUI_IMPL_VULKAN_NO_PROTOTYPES MultiThreadedDebug Default @@ -169,7 +169,7 @@ Disabled $(ProjectDir);$(ProjectDir)..\;$(ProjectDir)..\..\;$(ProjectDir)zlib\src;$(ProjectDir)..\unzip;$(ProjectDir)libpng\src;$(ProjectDir)..\apu\bapu;$(ProjectDir)..\external\glslang;$(ProjectDir)..\external\stb;$(ProjectDir)..\external\vulkan-headers\include;$(ProjectDir)..\external\VulkanMemoryAllocator-Hpp\include;$(ProjectDir)..\external\fmt\include - _DEBUG;ALLOW_CPU_OVERCLOCK;HAVE_LIBPNG;JMA_SUPPORT;ZLIB;UNZIP_SUPPORT;__WIN32__;NETPLAY_SUPPORT;D3D_DEBUG_INFO;DIRECTDRAW_SUPPORT;USE_SLANG;%(PreprocessorDefinitions);VK_USE_PLATFORM_WIN32_KHR;VULKAN_HPP_DISPATCH_LOADER_DYNAMIC=1;VMA_DYNAMIC_VULKAN_FUNCTIONS=1;VMA_STATIC_VULKAN_FUNCTIONS=0;VMA_USE_STL_SHARED_MUTEX=0 + _DEBUG;ALLOW_CPU_OVERCLOCK;HAVE_LIBPNG;JMA_SUPPORT;ZLIB;UNZIP_SUPPORT;__WIN32__;NETPLAY_SUPPORT;D3D_DEBUG_INFO;DIRECTDRAW_SUPPORT;USE_SLANG;%(PreprocessorDefinitions);VK_USE_PLATFORM_WIN32_KHR;VULKAN_HPP_DISPATCH_LOADER_DYNAMIC=1;VMA_DYNAMIC_VULKAN_FUNCTIONS=1;VMA_STATIC_VULKAN_FUNCTIONS=0;VMA_USE_STL_SHARED_MUTEX=0;IMGUI_IMPL_VULKAN_NO_PROTOTYPES MultiThreadedDebug Default @@ -225,7 +225,7 @@ true true $(ProjectDir);$(ProjectDir)..\;$(ProjectDir)..\..\;$(ProjectDir)zlib\src;$(ProjectDir)..\unzip;$(ProjectDir)libpng\src;$(ProjectDir)..\apu\bapu;$(ProjectDir)..\external\glslang;$(ProjectDir)..\external\stb;$(ProjectDir)..\external\vulkan-headers\include;$(ProjectDir)..\external\VulkanMemoryAllocator-Hpp\include;$(ProjectDir)..\external\fmt\include - NDEBUG;ALLOW_CPU_OVERCLOCK;HAVE_LIBPNG;JMA_SUPPORT;ZLIB;UNZIP_SUPPORT;__WIN32__;NETPLAY_SUPPORT;DIRECTDRAW_SUPPORT;USE_SLANG;%(PreprocessorDefinitions);VK_USE_PLATFORM_WIN32_KHR;VULKAN_HPP_DISPATCH_LOADER_DYNAMIC=1;VMA_DYNAMIC_VULKAN_FUNCTIONS=1;VMA_STATIC_VULKAN_FUNCTIONS=0;VMA_USE_STL_SHARED_MUTEX=0 + NDEBUG;ALLOW_CPU_OVERCLOCK;HAVE_LIBPNG;JMA_SUPPORT;ZLIB;UNZIP_SUPPORT;__WIN32__;NETPLAY_SUPPORT;DIRECTDRAW_SUPPORT;USE_SLANG;%(PreprocessorDefinitions);VK_USE_PLATFORM_WIN32_KHR;VULKAN_HPP_DISPATCH_LOADER_DYNAMIC=1;VMA_DYNAMIC_VULKAN_FUNCTIONS=1;VMA_STATIC_VULKAN_FUNCTIONS=0;VMA_USE_STL_SHARED_MUTEX=0;IMGUI_IMPL_VULKAN_NO_PROTOTYPES true MultiThreaded Default @@ -280,7 +280,7 @@ true true $(ProjectDir);$(ProjectDir)..\;$(ProjectDir)..\..\;$(ProjectDir)zlib\src;$(ProjectDir)..\unzip;$(ProjectDir)libpng\src;$(ProjectDir)..\apu\bapu;$(ProjectDir)..\external\glslang;$(ProjectDir)..\external\stb;$(ProjectDir)..\external\vulkan-headers\include;$(ProjectDir)..\external\VulkanMemoryAllocator-Hpp\include;$(ProjectDir)..\external\fmt\include - NDEBUG;ALLOW_CPU_OVERCLOCK;HAVE_LIBPNG;JMA_SUPPORT;ZLIB;UNZIP_SUPPORT;__WIN32__;NETPLAY_SUPPORT;DIRECTDRAW_SUPPORT;USE_SLANG;%(PreprocessorDefinitions);VK_USE_PLATFORM_WIN32_KHR;VULKAN_HPP_DISPATCH_LOADER_DYNAMIC=1;VMA_DYNAMIC_VULKAN_FUNCTIONS=1;VMA_STATIC_VULKAN_FUNCTIONS=0;VMA_USE_STL_SHARED_MUTEX=0 + NDEBUG;ALLOW_CPU_OVERCLOCK;HAVE_LIBPNG;JMA_SUPPORT;ZLIB;UNZIP_SUPPORT;__WIN32__;NETPLAY_SUPPORT;DIRECTDRAW_SUPPORT;USE_SLANG;%(PreprocessorDefinitions);VK_USE_PLATFORM_WIN32_KHR;VULKAN_HPP_DISPATCH_LOADER_DYNAMIC=1;VMA_DYNAMIC_VULKAN_FUNCTIONS=1;VMA_STATIC_VULKAN_FUNCTIONS=0;VMA_USE_STL_SHARED_MUTEX=0;IMGUI_IMPL_VULKAN_NO_PROTOTYPES true MultiThreaded Default @@ -343,6 +343,17 @@ + + + + + + + + + + + @@ -508,6 +519,15 @@ + + + + + + + + + diff --git a/win32/snes9xw.vcxproj.filters b/win32/snes9xw.vcxproj.filters index 623dba4e..3c56eaaa 100644 --- a/win32/snes9xw.vcxproj.filters +++ b/win32/snes9xw.vcxproj.filters @@ -46,6 +46,9 @@ {33cdb579-8582-4adc-91d3-c6624af3ad94} + + {fc57774a-1be8-4755-932f-90d2f6609097} + @@ -330,6 +333,39 @@ GUI\VideoDriver\Vulkan + + GUI\VideoDriver\ImGui + + + GUI\VideoDriver\ImGui + + + GUI\VideoDriver\ImGui + + + GUI\VideoDriver\ImGui + + + GUI\VideoDriver\ImGui + + + GUI\VideoDriver\ImGui + + + GUI\VideoDriver\ImGui + + + GUI\VideoDriver\ImGui + + + GUI\VideoDriver\ImGui + + + GUI\VideoDriver\ImGui + + + GUI\VideoDriver\ImGui + @@ -725,6 +761,33 @@ GUI\VideoDriver\Vulkan + + GUI\VideoDriver\ImGui + + + GUI\VideoDriver\ImGui + + + GUI\VideoDriver\ImGui + + + GUI\VideoDriver\ImGui + + + GUI\VideoDriver\ImGui + + + GUI\VideoDriver\ImGui + + + GUI\VideoDriver\ImGui + + + GUI\VideoDriver\ImGui + + + GUI\VideoDriver\ImGui + diff --git a/win32/wconfig.cpp b/win32/wconfig.cpp index 454b21d4..5f70026d 100644 --- a/win32/wconfig.cpp +++ b/win32/wconfig.cpp @@ -766,7 +766,7 @@ void WinRegisterConfigItems() AddStringC("Direct3D:D3DShader", GUI.D3DshaderFileName, MAX_PATH, "", "shader filename for Direct3D mode (HLSL effect file or CG shader"); AddStringC("OpenGL:OGLShader", GUI.OGLshaderFileName, MAX_PATH, "", "shader filename for OpenGL mode (bsnes-style XML shader or CG shader)"); AddBoolC("OpenGL:DisablePBOs", GUI.OGLdisablePBOs, true, "do not use PBOs in OpenGL mode, even if the video card supports them"); - AddBoolC("ExtendHeight", GUI.HeightExtend, false, "true to display an extra 15 pixels at the bottom, which few games use. Also increases AVI output size from 256x224 to 256x240."); + AddBoolC("ExtendHeight", Settings.ShowOverscan, false, "true to display an extra 15 pixels at the bottom, which few games use. Also increases AVI output size from 256x224 to 256x240."); AddBoolC("AlwaysCenterImage", GUI.AlwaysCenterImage,false, "true to center the image even if larger than window"); AddIntC("Window:Width", GUI.window_size.right, 512, "256=1x, 512=2x, 768=3x, 1024=4x, etc. (usually)"); AddIntC("Window:Height", GUI.window_size.bottom, 448, "224=1x, 448=2x, 672=3x, 896=4x, etc. (usually)"); @@ -800,7 +800,7 @@ void WinRegisterConfigItems() AddBoolC("Vsync", GUI.Vsync, false, "true to enable Vsync"); AddBoolC("ReduceInputLag", GUI.ReduceInputLag, false, "true to reduce input lag by hard synchronization"); AddBoolC("DWMSync", GUI.DWMSync, false, "sync to DWM compositor if it is running"); - AddBoolC("FilterMessageFont", GUI.filterMessagFont, true, "true to filter message font with EPX on 2x/3x scales if MessagesInImage is false)"); + AddUInt("OSDSize", GUI.OSDSize, 24, "Size of On-Screen Display"); #undef CATEGORY #define CATEGORY "Settings" AddUIntC("FrameSkip", Settings.SkipFrames, AUTO_FRAMERATE, "200=automatic (limits at 50/60 fps), 0=none, 1=skip every other, ..."); diff --git a/win32/win32.cpp b/win32/win32.cpp index 7211be19..0555ce60 100644 --- a/win32/win32.cpp +++ b/win32/win32.cpp @@ -1169,7 +1169,7 @@ void DoAVIOpen(const TCHAR* filename) AVISetFramerate(framerate, frameskip, GUI.AVIOut); avi_width = SNES_WIDTH; - avi_height = GUI.HeightExtend ? SNES_HEIGHT_EXTENDED : SNES_HEIGHT; + avi_height = Settings.ShowOverscan ? SNES_HEIGHT_EXTENDED : SNES_HEIGHT; avi_skip_frames = Settings.SkipFrames; if(GUI.AVIHiRes) { diff --git a/win32/win32_display.cpp b/win32/win32_display.cpp index 09ad97ca..a7c4a21b 100644 --- a/win32/win32_display.cpp +++ b/win32/win32_display.cpp @@ -59,7 +59,7 @@ void DoAVIVideoFrame(); static void CheckOverscanOffset() { int lines_to_skip = 0; - if (!GUI.HeightExtend) + if (!Settings.ShowOverscan) { if (Src.Height == SNES_HEIGHT_EXTENDED) lines_to_skip = 7; @@ -207,7 +207,7 @@ RECT CalculateDisplayRect(unsigned int sourceWidth,unsigned int sourceHeight, double yFactor; double minFactor; double renderWidthCalc,renderHeightCalc; - int hExtend = GUI.HeightExtend ? SNES_HEIGHT_EXTENDED : SNES_HEIGHT; + int hExtend = Settings.ShowOverscan ? SNES_HEIGHT_EXTENDED : SNES_HEIGHT; double snesAspect = (double)GUI.AspectWidth/hExtend; RECT drawRect; @@ -888,189 +888,3 @@ void ConvertDepth (SSurface *src, SSurface *dst, RECT *srect) } /* Depth conversion functions end */ - - -/* The rest of the functions are recreations of the core string display functions with additional scaling. - They provide the possibility to render the messages into a surface other than the core GFX.Screen. -*/ - -void WinDisplayStringFromBottom (const char *string, int linesFromBottom, int pixelsFromLeft, bool allowWrap) -{ - if(Settings.StopEmulation) - return; - if(Settings.AutoDisplayMessages) { - WinSetCustomDisplaySurface((void *)GFX.Screen, GFX.RealPPL, IPPU.RenderedScreenWidth, IPPU.RenderedScreenHeight, 1); - WinDisplayStringInBuffer(string, linesFromBottom, pixelsFromLeft, allowWrap); - } else - if(GUI.ScreenDepth == 32) { - WinDisplayStringInBuffer(string, linesFromBottom, pixelsFromLeft, allowWrap); - } else { - WinDisplayStringInBuffer(string, linesFromBottom, pixelsFromLeft, allowWrap); - } -} - -static int font_width = 8, font_height = 9; -static void *displayScreen; -int displayPpl, displayWidth, displayHeight, displayScale, fontwidth_scaled, fontheight_scaled; - -void WinSetCustomDisplaySurface(void *screen, int ppl, int width, int height, int scale) -{ - displayScreen=screen; - displayPpl=ppl; - displayWidth=width; - displayHeight=height; - displayScale=max(1,width/IPPU.RenderedScreenWidth); - fontwidth_scaled=font_width*displayScale; - fontheight_scaled=font_height*displayScale; -} - -template -void WinDisplayChar (screenPtrType *s, uint8 c) -{ - int h, w; - - int line = ((c - 32) >> 4) * fontheight_scaled; - int offset = ((c - 32) & 15) * fontwidth_scaled; - - if (GUI.filterMessagFont && (displayScale == 2 || displayScale == 3)) - { - if (displayScale == 2) { - for (h = 0; h < fontheight_scaled; h += 2, line += 2, s += 2 * displayPpl - fontwidth_scaled) - for (w = 0; w < fontwidth_scaled; w += 2, s += 2) - FontPixToScreenEPX((offset + w) / 2, line / 2, s); - } - else if (displayScale == 3) { - for (h = 0; h < fontheight_scaled; h += 3, line += 3, s += 3 * displayPpl - fontwidth_scaled) - for (w = 0; w < fontwidth_scaled; w += 3, s += 3) - FontPixToScreenEPXSimple3((offset + w) / 3, line / 3, s); - } - } - else - { - for(h=0; h> 11) ) << /*RedShift+3*/ 19) | \ - ((((pixel) >> 6) & 0x1f) << /*GreenShift+3*/11) | \ - (((pixel) & 0x1f) << /*BlueShift+3*/ 3)) - - if(p == '#') - { - *s = CONVERT_16_TO_32(Settings.DisplayColor); - } - else if(p == '.') - { - static const uint32 black = CONVERT_16_TO_32(BUILD_PIXEL(0,0,0)); - *s = black; - } -} - -#define CHOOSE(c1) ((c1=='#'||X=='#') ? '#' : ((c1=='.'||X=='.') ? '.' : c1)) - -template -static inline void FontPixToScreenEPX(int x, int y, screenPtrType *s) -{ - const char X = font[y][x]; // E D H - const char A = x>0 ?font[y][x-1]:' '; // A X C - const char C = x<143?font[y][x+1]:' '; // F B G - if (A != C) - { - const char D = y>0 ?font[y-1][x]:' '; - const char B = y<125?font[y+1][x]:' '; - if (B != D) - { - FontPixToScreen((D == A) ? CHOOSE(D) : X, s); - FontPixToScreen((C == D) ? CHOOSE(C) : X, s+1); - FontPixToScreen((A == B) ? CHOOSE(A) : X, s+displayPpl); - FontPixToScreen((B == C) ? CHOOSE(B) : X, s+displayPpl+1); - return; - } - } - FontPixToScreen(X, s); - FontPixToScreen(X, s+1); - FontPixToScreen(X, s+displayPpl); - FontPixToScreen(X, s+displayPpl+1); -} -#undef CHOOSE - -#define CHOOSE(c1) ((X=='#') ? '#' : c1) -template -inline void FontPixToScreenEPXSimple3(int x, int y, screenPtrType *s) -{ - const char X = font[y][x]; // E D H - const char A = x>0 ?font[y][x-1]:' '; // A X C - const char C = x<143?font[y][x+1]:' '; // F B G - const char D = y>0 ?font[y-1][x]:' '; - const char B = y<125?font[y+1][x]:' '; - const bool XnE = y>0 &&x>0 ?(X != font[y-1][x-1]):X!=' '; - const bool XnF = y<125&&x<143?(X != font[y+1][x-1]):X!=' '; - const bool XnG = y<125&&x>0 ?(X != font[y+1][x+1]):X!=' '; - const bool XnH = y>0 &&x<143?(X != font[y-1][x+1]):X!=' '; - const bool DA = D == A && (XnE || CHOOSE(D)!=X); - const bool AB = A == B && (XnF || CHOOSE(A)!=X); - const bool BC = B == C && (XnG || CHOOSE(B)!=X); - const bool CD = C == D && (XnH || CHOOSE(C)!=X); - FontPixToScreen(DA ? A : X, s); - FontPixToScreen(X, s+1); - FontPixToScreen(CD ? C : X, s+2); - FontPixToScreen(X, s+displayPpl); - FontPixToScreen(X, s+displayPpl+1); - FontPixToScreen(X, s+displayPpl+2); - FontPixToScreen(AB ? A : X, s+displayPpl+displayPpl); - FontPixToScreen(X, s+displayPpl+displayPpl+1); - FontPixToScreen(BC ? C : X, s+displayPpl+displayPpl+2); -} -#undef CHOOSE - -template -void WinDisplayStringInBuffer (const char *string, int linesFromBottom, int pixelsFromLeft, bool allowWrap) -{ - if (linesFromBottom <= 0) - linesFromBottom = 1; - - screenPtrType *dst = (screenPtrType *)displayScreen + (displayHeight - fontheight_scaled * linesFromBottom) * displayPpl + (int)(pixelsFromLeft * (float)displayWidth/IPPU.RenderedScreenWidth); - - int len = strlen(string); - int max_chars = displayWidth / (fontwidth_scaled - displayScale); - int char_count = 0; - - for (int i = 0 ; i < len ; i++, char_count++) - { - if (char_count >= max_chars || (uint8) string[i] < 32) - { - if (!allowWrap) - break; - - dst += fontheight_scaled * displayPpl - (fontwidth_scaled - displayScale) * max_chars; - if (dst >= (screenPtrType *)displayScreen + displayHeight * displayPpl) - break; - - char_count -= max_chars; - } - - if ((uint8) string[i] < 32) - continue; - - WinDisplayChar(dst, string[i]); - dst += fontwidth_scaled - displayScale; - } -} diff --git a/win32/win32_display.h b/win32/win32_display.h index 84fcd9fc..d4f9e871 100644 --- a/win32/win32_display.h +++ b/win32/win32_display.h @@ -33,10 +33,6 @@ RECT CalculateDisplayRect(unsigned int sourceWidth,unsigned int sourceHeight, unsigned int displayWidth,unsigned int displayHeight); void WinEnumDisplayModes(std::vector *modeVector); void ConvertDepth (SSurface *src, SSurface *dst, RECT *srect); -void WinDisplayStringFromBottom (const char *string, int linesFromBottom, int pixelsFromLeft, bool allowWrap); -void WinSetCustomDisplaySurface(void *screen, int ppl, int width, int height, int scale); -template -void WinDisplayStringInBuffer (const char *string, int linesFromBottom, int pixelsFromLeft, bool allowWrap); char *ReadShaderFileContents(const TCHAR *filename); void ReduceToPath(TCHAR *filename); double WinGetRefreshRate(); diff --git a/win32/wsnes9x.cpp b/win32/wsnes9x.cpp index 78ba05bd..a9d05cd2 100644 --- a/win32/wsnes9x.cpp +++ b/win32/wsnes9x.cpp @@ -2114,7 +2114,7 @@ LRESULT CALLBACK WinProc( RECT margins; factor = (wParam & 0xffff) - ID_WINDOW_SIZE_1X + 1; newWidth = GUI.AspectWidth * factor; - newHeight = (GUI.HeightExtend ? SNES_HEIGHT_EXTENDED : SNES_HEIGHT) * factor; + newHeight = (Settings.ShowOverscan ? SNES_HEIGHT_EXTENDED : SNES_HEIGHT) * factor; margins = GetWindowMargins(GUI.hWnd,newWidth); newHeight += margins.top + margins.bottom; @@ -2448,7 +2448,7 @@ LRESULT CALLBACK WinProc( // int theight; // (IPPU.RenderedScreenHeight> 256)? theight= SNES_HEIGHT_EXTENDED<<1: theight = SNES_HEIGHT_EXTENDED; - int theight = GUI.HeightExtend ? SNES_HEIGHT_EXTENDED : SNES_HEIGHT; + int theight = Settings.ShowOverscan ? SNES_HEIGHT_EXTENDED : SNES_HEIGHT; if(IPPU.RenderedScreenHeight > SNES_HEIGHT_EXTENDED) theight <<= 1; startx= size.right-IPPU.RenderedScreenWidth; @@ -2478,7 +2478,7 @@ LRESULT CALLBACK WinProc( sizex=IPPU.RenderedScreenWidth; else sizex=IPPU.RenderedScreenWidth*2; - int theight = GUI.HeightExtend ? SNES_HEIGHT_EXTENDED : SNES_HEIGHT; + int theight = Settings.ShowOverscan ? SNES_HEIGHT_EXTENDED : SNES_HEIGHT; sizey = (IPPU.RenderedScreenHeight > SNES_HEIGHT_EXTENDED) ? theight : (theight << 1); startx= size.right-sizex; @@ -2503,7 +2503,7 @@ LRESULT CALLBACK WinProc( else { int sizex = IPPU.RenderedScreenWidth; - int sizey = GUI.HeightExtend ? SNES_HEIGHT_EXTENDED : SNES_HEIGHT; + int sizey = Settings.ShowOverscan ? SNES_HEIGHT_EXTENDED : SNES_HEIGHT; sizey = (IPPU.RenderedScreenHeight > SNES_HEIGHT_EXTENDED) ? (sizey << 1) : sizey; int width = size.right, height = size.bottom, xdiff = 0, ydiff = 0; if(GUI.AspectRatio) @@ -7504,7 +7504,7 @@ INT_PTR CALLBACK DlgFunky(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam) prevAspectRatio = GUI.AspectRatio; prevAspectWidth = GUI.AspectWidth; prevIntegerScaling = GUI.IntegerScaling; - prevHeightExtend = GUI.HeightExtend; + prevHeightExtend = Settings.ShowOverscan; prevAutoDisplayMessages = Settings.AutoDisplayMessages != 0; prevShaderEnabled = GUI.shaderEnabled; prevBlendHires = GUI.BlendHiRes; @@ -7533,12 +7533,10 @@ INT_PTR CALLBACK DlgFunky(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam) if (GUI.BlendHiRes) SendDlgItemMessage(hDlg, IDC_HIRESBLEND, BM_SETCHECK, (WPARAM)BST_CHECKED, 0); - if (GUI.HeightExtend) + if (Settings.ShowOverscan) SendDlgItemMessage(hDlg, IDC_HEIGHT_EXTEND, BM_SETCHECK, (WPARAM)BST_CHECKED, 0); if (Settings.AutoDisplayMessages) SendDlgItemMessage(hDlg, IDC_MESSAGES_IN_IMAGE, BM_SETCHECK, (WPARAM)BST_CHECKED, 0); - if (GUI.filterMessagFont) - SendDlgItemMessage(hDlg, IDC_MESSAGES_SCALE, BM_SETCHECK, (WPARAM)BST_CHECKED, 0); if (Settings.SkipFrames == AUTO_FRAMERATE) SendDlgItemMessage(hDlg, IDC_AUTOFRAME, BM_SETCHECK, (WPARAM)BST_CHECKED, 0); if (GUI.Stretch) @@ -7592,6 +7590,8 @@ INT_PTR CALLBACK DlgFunky(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam) SendDlgItemMessage(hDlg, IDC_SPIN_MAX_SKIP_DISP, UDM_SETPOS, 0, Settings.AutoMaxSkipFrames); SendDlgItemMessage(hDlg, IDC_SPIN_MAX_SKIP_DISP_FIXED, UDM_SETRANGE, 0, MAKELPARAM((short)59, (short)0)); SendDlgItemMessage(hDlg, IDC_SPIN_MAX_SKIP_DISP_FIXED, UDM_SETPOS, 0, Settings.SkipFrames == AUTO_FRAMERATE ? 0 : Settings.SkipFrames); + SendDlgItemMessage(hDlg, IDC_SPIN_OSD_SIZE, UDM_SETRANGE, 0, MAKELPARAM(160, 24)); + SendDlgItemMessage(hDlg, IDC_SPIN_OSD_SIZE, UDM_SETPOS, 0, GUI.OSDSize); if (GUI.shaderEnabled) { SendDlgItemMessage(hDlg, IDC_SHADER_ENABLED, BM_SETCHECK, (WPARAM)BST_CHECKED, 0); @@ -7688,7 +7688,6 @@ INT_PTR CALLBACK DlgFunky(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam) case IDC_MESSAGES_IN_IMAGE: case IDC_MESSAGES_SCALE: Settings.AutoDisplayMessages = (bool)(IsDlgButtonChecked(hDlg,IDC_MESSAGES_IN_IMAGE)==BST_CHECKED); - GUI.filterMessagFont = (bool)(IsDlgButtonChecked(hDlg, IDC_MESSAGES_SCALE) == BST_CHECKED); if(Settings.AutoDisplayMessages) { if(GFX.InfoString.empty()) { @@ -7740,7 +7739,7 @@ INT_PTR CALLBACK DlgFunky(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam) break; case IDC_HEIGHT_EXTEND: - GUI.HeightExtend = (bool)(IsDlgButtonChecked(hDlg,IDC_HEIGHT_EXTEND)==BST_CHECKED); + Settings.ShowOverscan = (bool)(IsDlgButtonChecked(hDlg,IDC_HEIGHT_EXTEND)==BST_CHECKED); // refresh screen, so the user can see the new mode WinDisplayApplyChanges(); @@ -7922,9 +7921,8 @@ INT_PTR CALLBACK DlgFunky(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam) bool fullscreenWanted; Settings.Transparency = IsDlgButtonChecked(hDlg, IDC_TRANS); Settings.BilinearFilter = (bool)(IsDlgButtonChecked(hDlg,IDC_BILINEAR)==BST_CHECKED); - GUI.HeightExtend = IsDlgButtonChecked(hDlg, IDC_HEIGHT_EXTEND)!=0; + Settings.ShowOverscan = IsDlgButtonChecked(hDlg, IDC_HEIGHT_EXTEND)!=0; Settings.AutoDisplayMessages = IsDlgButtonChecked(hDlg, IDC_MESSAGES_IN_IMAGE); - GUI.filterMessagFont = IsDlgButtonChecked(hDlg, IDC_MESSAGES_SCALE); GUI.DoubleBuffered = (bool)(IsDlgButtonChecked(hDlg, IDC_DBLBUFFER)==BST_CHECKED); GUI.ReduceInputLag = (bool)(IsDlgButtonChecked(hDlg, IDC_REDUCEINPUTLAG) == BST_CHECKED); GUI.Vsync = (bool)(IsDlgButtonChecked(hDlg, IDC_VSYNC @@ -8004,7 +8002,7 @@ INT_PTR CALLBACK DlgFunky(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam) GUI.AspectRatio = prevAspectRatio; GUI.AspectWidth = prevAspectWidth; GUI.IntegerScaling = prevIntegerScaling; - GUI.HeightExtend = prevHeightExtend; + Settings.ShowOverscan = prevHeightExtend; GUI.shaderEnabled = prevShaderEnabled; GUI.BlendHiRes = prevBlendHires; GUI.NTSCScanlines = prevNTSCScanlines; diff --git a/win32/wsnes9x.h b/win32/wsnes9x.h index f3fa7b0c..2995fd16 100644 --- a/win32/wsnes9x.h +++ b/win32/wsnes9x.h @@ -162,7 +162,6 @@ struct sGUI { bool FullScreen; bool FullscreenOnOpen; bool Stretch; - bool HeightExtend; bool AspectRatio; bool IntegerScaling; OutputMethod outputMethod; @@ -179,7 +178,7 @@ struct sGUI { TCHAR OGLshaderFileName[MAX_PATH]; bool OGLdisablePBOs; - bool filterMessagFont; + int OSDSize; bool IgnoreNextMouseMove; RECT window_size;