From c94b5f75d2e69b900eb381d0922ad06583280edf Mon Sep 17 00:00:00 2001 From: Chris Collins Date: Sun, 19 Jul 2020 12:43:57 +1000 Subject: [PATCH 1/9] Enable HighDPI canvas support for macOS This provides half the HighDPI support solution. The other half is we need to use Renderer to do the final blit rather than the surface blitting features - that's not done yet. --- CMakeLists.txt | 2 ++ MacOSXBundleInfo.plist.in | 36 ++++++++++++++++++++++++++++++++++++ src/sdl_main.cpp | 2 +- 3 files changed, 39 insertions(+), 1 deletion(-) create mode 100644 MacOSXBundleInfo.plist.in diff --git a/CMakeLists.txt b/CMakeLists.txt index 3666339..1271a40 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -122,6 +122,7 @@ if(CMAKE_SYSTEM_NAME MATCHES Darwin) if(BUILD_DEMO) set_target_properties(strangedemo PROPERTIES OUTPUT_NAME "Strange Adventures in Infinite Space Demo" + MACOSX_BUNDLE_INFO_PLIST "${CMAKE_CURRENT_SOURCE_DIR}/MacOSXBundleInfo.plist.in" MACOSX_FRAMEWORK_IDENTIFIER "au.com.ecsim.saisgpldemo" MACOSX_BUNDLE TRUE MACOSX_BUNDLE_BUNDLE_NAME "Strange Adventures Demo" @@ -136,6 +137,7 @@ if(CMAKE_SYSTEM_NAME MATCHES Darwin) else() set_target_properties(strange PROPERTIES OUTPUT_NAME "Strange Adventures in Infinite Space" + MACOSX_BUNDLE_INFO_PLIST "${CMAKE_CURRENT_SOURCE_DIR}/MacOSXBundleInfo.plist.in" MACOSX_FRAMEWORK_IDENTIFIER "au.com.ecsim.saisgpl" MACOSX_BUNDLE TRUE MACOSX_BUNDLE_BUNDLE_NAME "Strange Adventures" diff --git a/MacOSXBundleInfo.plist.in b/MacOSXBundleInfo.plist.in new file mode 100644 index 0000000..640b1e6 --- /dev/null +++ b/MacOSXBundleInfo.plist.in @@ -0,0 +1,36 @@ + + + + + CFBundleDevelopmentRegion + English + CFBundleExecutable + ${MACOSX_BUNDLE_EXECUTABLE_NAME} + CFBundleGetInfoString + ${MACOSX_BUNDLE_INFO_STRING} + CFBundleIconFile + ${MACOSX_BUNDLE_ICON_FILE} + CFBundleIdentifier + ${MACOSX_BUNDLE_GUI_IDENTIFIER} + CFBundleInfoDictionaryVersion + 6.0 + CFBundleLongVersionString + ${MACOSX_BUNDLE_LONG_VERSION_STRING} + CFBundleName + ${MACOSX_BUNDLE_BUNDLE_NAME} + CFBundlePackageType + APPL + CFBundleShortVersionString + ${MACOSX_BUNDLE_SHORT_VERSION_STRING} + CFBundleSignature + au.com.ecsim.SAISGPL + CFBundleVersion + ${MACOSX_BUNDLE_BUNDLE_VERSION} + CSResourcesFileMapped + + NSHumanReadableCopyright + ${MACOSX_BUNDLE_COPYRIGHT} + NSHighResolutionCapable + + + diff --git a/src/sdl_main.cpp b/src/sdl_main.cpp index 21fc0b7..ea74097 100644 --- a/src/sdl_main.cpp +++ b/src/sdl_main.cpp @@ -141,7 +141,7 @@ int main(int argc, char *argv[]) { sound_init(); // create the application window - int sdlFlags = SDL_WINDOW_RESIZABLE; + int sdlFlags = SDL_WINDOW_RESIZABLE | SDL_WINDOW_ALLOW_HIGHDPI; if (globalsettings.opt_fullscreen) { sdlFlags |= SDL_WINDOW_FULLSCREEN_DESKTOP; } From 18b9cd6170367044f38c2bf88fc4c9f250440d47 Mon Sep 17 00:00:00 2001 From: Chris Collins Date: Sun, 19 Jul 2020 13:15:05 +1000 Subject: [PATCH 2/9] hack copy the SDL Surface to a streaming texture and use the SDL dynamic viewport sizing to resolve that. --- .idea/vcs.xml | 1 + src/main.cpp | 5 ++-- src/sdl_main.cpp | 25 +++++++++++++++-- src/w32_gfx.cpp | 72 ++++++++++++++++-------------------------------- 4 files changed, 51 insertions(+), 52 deletions(-) diff --git a/.idea/vcs.xml b/.idea/vcs.xml index 94a25f7..5543b88 100644 --- a/.idea/vcs.xml +++ b/.idea/vcs.xml @@ -2,5 +2,6 @@ + \ No newline at end of file diff --git a/src/main.cpp b/src/main.cpp index 971ca3b..f19371d 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -775,7 +775,8 @@ int32 intro_screen() break; case 8: - globalsettings.opt_whole_multiple_rescale_ratio = !globalsettings.opt_whole_multiple_rescale_ratio; + globalsettings.opt_whole_multiple_rescale_ratio = !globalsettings.opt_whole_multiple_rescale_ratio; + break; default: ; } @@ -962,7 +963,7 @@ int32 intro_screen() ik_dsprite(screen, bx+16, by+y-5, spr_IFbutton->spr[globalsettings.opt_fullscreen], 2+(MAIN_INTERFACE_COLOR<<8)); y+=16; - ik_print(screen, font_6x8, bx+32, by+y, MAIN_INTERFACE_COLOR, "LIMIT TO WHOLE MULTIPLE SCALING"); + ik_print(screen, font_6x8, bx+32, by+y, MAIN_INTERFACE_COLOR, "PIXEL PERFECT SCALING"); ik_dsprite(screen, bx+16, by+y-5, spr_IFbutton->spr[globalsettings.opt_whole_multiple_rescale_ratio], 2 + (MAIN_INTERFACE_COLOR << 8)); y+=16; diff --git a/src/sdl_main.cpp b/src/sdl_main.cpp index ea74097..6ba2902 100644 --- a/src/sdl_main.cpp +++ b/src/sdl_main.cpp @@ -31,7 +31,8 @@ int sound_init(); extern SDL_Window *sdlWind; extern SDL_Surface *sdlsurf; SDL_Surface *blitIntermedSurf = nullptr; - +SDL_Renderer *sdlRend = nullptr; +SDL_Texture *sdlWindTexture = nullptr; // directory paths for our core. std::string fsBaseDir; @@ -141,7 +142,7 @@ int main(int argc, char *argv[]) { sound_init(); // create the application window - int sdlFlags = SDL_WINDOW_RESIZABLE | SDL_WINDOW_ALLOW_HIGHDPI; + int sdlFlags = SDL_WINDOW_RESIZABLE | SDL_WINDOW_ALLOW_HIGHDPI | SDL_WINDOW_OPENGL; if (globalsettings.opt_fullscreen) { sdlFlags |= SDL_WINDOW_FULLSCREEN_DESKTOP; } @@ -157,6 +158,19 @@ int main(int argc, char *argv[]) { } SDL_SetWindowMinimumSize(sdlWind, 640, 480); + + // create the SDL Renderer we use to stream from the intermed blitting surface to the window. + sdlRend = SDL_CreateRenderer(sdlWind, -1, SDL_RENDERER_ACCELERATED); + if (sdlRend == nullptr) { + SDL_Log("Failed to create SDL Renderer: %s", SDL_GetError()); + return 1; + } + if (SDL_RenderSetLogicalSize(sdlRend, 640, 480)) { + SDL_Log("Renderer refused our logical window scale: %s", SDL_GetError()); + return 1; + } + SDL_RenderSetIntegerScale(sdlRend, (globalsettings.opt_whole_multiple_rescale_ratio != 0)?SDL_TRUE:SDL_FALSE); + // create the i8 surface sdlsurf = SDL_CreateRGBSurfaceWithFormat(0, 640, 480, 8, SDL_PIXELFORMAT_INDEX8); if (sdlsurf == nullptr) { @@ -168,6 +182,13 @@ int main(int argc, char *argv[]) { auto *realSurf = SDL_GetWindowSurface(sdlWind); blitIntermedSurf = SDL_ConvertSurface(sdlsurf, realSurf->format, 0); + // and create the streaming texture. + sdlWindTexture = SDL_CreateTexture(sdlRend, realSurf->format->format, SDL_TEXTUREACCESS_STREAMING, 640, 480); + if (sdlWindTexture == nullptr) { + SDL_Log("Failed to create intermediate window texture (for fullscreen scaling): %s", SDL_GetError()); + return 1; + } + my_main(); return 0; } diff --git a/src/w32_gfx.cpp b/src/w32_gfx.cpp index 9a2710b..7f9a2d3 100644 --- a/src/w32_gfx.cpp +++ b/src/w32_gfx.cpp @@ -42,6 +42,8 @@ All DIRECTDRAW stuff here extern SDL_Window *sdlWind; extern SDL_Surface *sdlsurf; extern SDL_Surface *blitIntermedSurf; +extern SDL_Renderer *sdlRend; +extern SDL_Texture *sdlWindTexture; #ifdef MOVIE int when = 0; @@ -53,57 +55,31 @@ int sdl_y_offset = 0; float sdl_screen_scale = 1.0f; void gfx_refresh_screen() { - auto *realsurf = SDL_GetWindowSurface(sdlWind); - - // calculate scale factor. - if (realsurf->w != sdlsurf->w || realsurf->h != sdlsurf->h) { - if (globalsettings.opt_whole_multiple_rescale_ratio) { - // for pixel perfect scaling, use integer ratios only. - int yrat = realsurf->h / sdlsurf->h; - int xrat = realsurf->w / sdlsurf->w; - sdl_screen_scale = static_cast(std::min(xrat, yrat)); - if (sdl_screen_scale < 1) { - sdl_screen_scale = 1; - } - } else { - float yrat = static_cast(realsurf->h) / static_cast(sdlsurf->h); - float xrat = static_cast(realsurf->w) / static_cast(sdlsurf->w); - sdl_screen_scale = std::min(xrat, yrat); - } + SDL_RenderSetIntegerScale(sdlRend, (globalsettings.opt_whole_multiple_rescale_ratio != 0)?SDL_TRUE:SDL_FALSE); - int targetXSize = static_cast(sdlsurf->w * sdl_screen_scale); - int targetYSize = static_cast(sdlsurf->h * sdl_screen_scale); - sdl_x_offset = (realsurf->w - targetXSize) / 2; - sdl_y_offset = (realsurf->h - targetYSize) / 2; - - SDL_Rect destRect{ - sdl_x_offset, - sdl_y_offset, - targetXSize, - targetYSize, - }; - // clear the surface first. - SDL_FillRect(realsurf, nullptr, 0); - // convert the surface. - if (SDL_BlitSurface(sdlsurf, nullptr, blitIntermedSurf, nullptr)) { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Blit to correct format failed: %s", SDL_GetError()); - abort(); - } - // now blit in the scaled window - if (SDL_BlitScaled(blitIntermedSurf, nullptr, realsurf, &destRect)) { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "BlitScaled failed: %s", SDL_GetError()); - abort(); - } - } else { - if (SDL_BlitSurface(sdlsurf, nullptr, realsurf, nullptr)) { - SDL_Log("Blit Failed?: %s", SDL_GetError()); - abort(); - } - } - if (SDL_UpdateWindowSurface(sdlWind)) { - SDL_Log("Update Surface Failed: %s", SDL_GetError()); + // convert the surface. + if (SDL_BlitSurface(sdlsurf, nullptr, blitIntermedSurf, nullptr)) { + SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Blit to correct format failed: %s", SDL_GetError()); abort(); } + // now, copy the surface data to the texture. + char *TexPixelData = nullptr; int pitch = 0; + if (!SDL_LockTexture(sdlWindTexture, nullptr, reinterpret_cast(&TexPixelData), &pitch)) { + SDL_LockSurface(blitIntermedSurf); + const int lineLength = blitIntermedSurf->format->BytesPerPixel * blitIntermedSurf->w; + for (int y = 0; y < blitIntermedSurf->h; y++) { + const int lOffset = pitch * y; + const int sOffset = blitIntermedSurf->pitch * y; + memcpy(TexPixelData + lOffset, reinterpret_cast(blitIntermedSurf->pixels) + sOffset, lineLength); + } + SDL_UnlockSurface(blitIntermedSurf); + SDL_UnlockTexture(sdlWindTexture); + } + + // and blat the texture onto the screen. + SDL_RenderClear(sdlRend); + SDL_RenderCopy(sdlRend, sdlWindTexture, nullptr, nullptr); + SDL_RenderPresent(sdlRend); } // blit screen From 043f45b85fe64fa24fb2190ba547278c4204cd18 Mon Sep 17 00:00:00 2001 From: Chris Collins Date: Sun, 19 Jul 2020 13:27:11 +1000 Subject: [PATCH 3/9] we can't grab the 2D surface with the renderer active, so assume RGBA8888 for our intermediate before we blockcopy from the 2D surfaces to the Renderer. --- src/sdl_main.cpp | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/src/sdl_main.cpp b/src/sdl_main.cpp index 6ba2902..05b52af 100644 --- a/src/sdl_main.cpp +++ b/src/sdl_main.cpp @@ -142,7 +142,7 @@ int main(int argc, char *argv[]) { sound_init(); // create the application window - int sdlFlags = SDL_WINDOW_RESIZABLE | SDL_WINDOW_ALLOW_HIGHDPI | SDL_WINDOW_OPENGL; + int sdlFlags = SDL_WINDOW_RESIZABLE | SDL_WINDOW_ALLOW_HIGHDPI; if (globalsettings.opt_fullscreen) { sdlFlags |= SDL_WINDOW_FULLSCREEN_DESKTOP; } @@ -160,7 +160,7 @@ int main(int argc, char *argv[]) { // create the SDL Renderer we use to stream from the intermed blitting surface to the window. - sdlRend = SDL_CreateRenderer(sdlWind, -1, SDL_RENDERER_ACCELERATED); + sdlRend = SDL_CreateRenderer(sdlWind, -1, 0); if (sdlRend == nullptr) { SDL_Log("Failed to create SDL Renderer: %s", SDL_GetError()); return 1; @@ -179,11 +179,18 @@ int main(int argc, char *argv[]) { } // create the intermediate blitting surface (needed for fullscreen support) +#if 0 auto *realSurf = SDL_GetWindowSurface(sdlWind); - blitIntermedSurf = SDL_ConvertSurface(sdlsurf, realSurf->format, 0); + if (realSurf == nullptr) { + SDL_Log("Couldn't get window surface: %s", SDL_GetError()); + return 1; + } + blitIntermedSurf = SDL_ConvertSurface(sdlsurf, SDL_PIXELFORMAT_RGBA8888, 0); +#endif + blitIntermedSurf = SDL_CreateRGBSurfaceWithFormat(0, 640, 480, 32, SDL_PIXELFORMAT_RGBA8888); // and create the streaming texture. - sdlWindTexture = SDL_CreateTexture(sdlRend, realSurf->format->format, SDL_TEXTUREACCESS_STREAMING, 640, 480); + sdlWindTexture = SDL_CreateTexture(sdlRend, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_STREAMING, 640, 480); if (sdlWindTexture == nullptr) { SDL_Log("Failed to create intermediate window texture (for fullscreen scaling): %s", SDL_GetError()); return 1; From ab6d966fce4fe08149c8114d8dbc0a36bbd3ad9e Mon Sep 17 00:00:00 2001 From: Chris Collins Date: Sun, 19 Jul 2020 18:46:51 +1000 Subject: [PATCH 4/9] Codesign the mac build so we can notarize it. --- Jenkinsfile | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Jenkinsfile b/Jenkinsfile index 278a9bb..dee9f6a 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -55,6 +55,8 @@ pipeline { [args: 'all'] ] dir('saisgpl.m64') { + sh ''' + codesign --keychain appsigning -s "AA22B289D7BCD9C66BC95F2AD2E8B35D8D1E4E7C" "bin/Strange Adventures in Infinite Space.app" cpack installation: 'CMake 3.16.0' archiveArtifacts artifacts: 'SAIS-GPL-**', defaultExcludes: false, fingerprint: true } From 6bcc26590bf5d42b57def64ec1495f0f36674265 Mon Sep 17 00:00:00 2001 From: Chris Collins Date: Tue, 21 Jul 2020 03:53:37 +1000 Subject: [PATCH 5/9] reinstate our manual rescaling calculations. --- src/sdl_main.cpp | 7 +------ src/w32_gfx.cpp | 38 ++++++++++++++++++++++++++++++++++---- 2 files changed, 35 insertions(+), 10 deletions(-) diff --git a/src/sdl_main.cpp b/src/sdl_main.cpp index 6ba2902..76580bc 100644 --- a/src/sdl_main.cpp +++ b/src/sdl_main.cpp @@ -160,16 +160,11 @@ int main(int argc, char *argv[]) { // create the SDL Renderer we use to stream from the intermed blitting surface to the window. - sdlRend = SDL_CreateRenderer(sdlWind, -1, SDL_RENDERER_ACCELERATED); + sdlRend = SDL_CreateRenderer(sdlWind, -1, 0); if (sdlRend == nullptr) { SDL_Log("Failed to create SDL Renderer: %s", SDL_GetError()); return 1; } - if (SDL_RenderSetLogicalSize(sdlRend, 640, 480)) { - SDL_Log("Renderer refused our logical window scale: %s", SDL_GetError()); - return 1; - } - SDL_RenderSetIntegerScale(sdlRend, (globalsettings.opt_whole_multiple_rescale_ratio != 0)?SDL_TRUE:SDL_FALSE); // create the i8 surface sdlsurf = SDL_CreateRGBSurfaceWithFormat(0, 640, 480, 8, SDL_PIXELFORMAT_INDEX8); diff --git a/src/w32_gfx.cpp b/src/w32_gfx.cpp index 7f9a2d3..c19f217 100644 --- a/src/w32_gfx.cpp +++ b/src/w32_gfx.cpp @@ -55,13 +55,44 @@ int sdl_y_offset = 0; float sdl_screen_scale = 1.0f; void gfx_refresh_screen() { - SDL_RenderSetIntegerScale(sdlRend, (globalsettings.opt_whole_multiple_rescale_ratio != 0)?SDL_TRUE:SDL_FALSE); + int w,h; + SDL_GetWindowSize(sdlWind, &w, &h); + + // calculate scale factor. + if (globalsettings.opt_whole_multiple_rescale_ratio) { + // for pixel perfect scaling, use integer ratios only. + int yrat = h / sdlsurf->h; + int xrat = w / sdlsurf->w; + sdl_screen_scale = static_cast(std::min(xrat, yrat)); + if (sdl_screen_scale < 1) { + sdl_screen_scale = 1; + } + } else { + float yrat = static_cast(h) / static_cast(sdlsurf->h); + float xrat = static_cast(w) / static_cast(sdlsurf->w); + sdl_screen_scale = std::min(xrat, yrat); + } + + int targetXSize = static_cast(sdlsurf->w * sdl_screen_scale); + int targetYSize = static_cast(sdlsurf->h * sdl_screen_scale); + sdl_x_offset = (w - targetXSize) / 2; + sdl_y_offset = (h - targetYSize) / 2; + + SDL_Rect destRect{ + sdl_x_offset, + sdl_y_offset, + targetXSize, + targetYSize, + }; + // clear the surface first. + SDL_RenderClear(sdlRend); - // convert the surface. + // now, blit the 8I surface to the RGBA32 surface if (SDL_BlitSurface(sdlsurf, nullptr, blitIntermedSurf, nullptr)) { SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Blit to correct format failed: %s", SDL_GetError()); abort(); } + // now, copy the surface data to the texture. char *TexPixelData = nullptr; int pitch = 0; if (!SDL_LockTexture(sdlWindTexture, nullptr, reinterpret_cast(&TexPixelData), &pitch)) { @@ -77,8 +108,7 @@ void gfx_refresh_screen() { } // and blat the texture onto the screen. - SDL_RenderClear(sdlRend); - SDL_RenderCopy(sdlRend, sdlWindTexture, nullptr, nullptr); + SDL_RenderCopy(sdlRend, sdlWindTexture, nullptr, &destRect); SDL_RenderPresent(sdlRend); } From 49b729595d6d0d9efe09fc8f9041f0c5b3a4d05f Mon Sep 17 00:00:00 2001 From: Chris Collins Date: Tue, 21 Jul 2020 04:26:59 +1000 Subject: [PATCH 6/9] Reset the video settings in a more sensible manner. This tidies up a few inconsistencies in how we were managing window state. First of all, we only assert fullscreen vs windowed if the flag changes. Secondly, we now flip the texture hint and rebuild the target texture when we toggle the pixel perfect option. Finally, we now use the vid_reset_settings() function to do the initial setup of the texture, rather than just using it to fix things later. Unfortunately, the hint is only used at texture creation time, meaning we can't just flip it on the texture (which would be possible if we were using GL directly), we do need to destroy and recreate it. --- src/main.cpp | 3 ++- src/sdl_main.cpp | 61 ++++++++++++++++++++++++++++++++++-------------- 2 files changed, 45 insertions(+), 19 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index f19371d..dfbbdc5 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -775,7 +775,8 @@ int32 intro_screen() break; case 8: - globalsettings.opt_whole_multiple_rescale_ratio = !globalsettings.opt_whole_multiple_rescale_ratio; + globalsettings.opt_whole_multiple_rescale_ratio = !globalsettings.opt_whole_multiple_rescale_ratio; + vid_reset_settings(); break; default: ; diff --git a/src/sdl_main.cpp b/src/sdl_main.cpp index 76580bc..71e2527 100644 --- a/src/sdl_main.cpp +++ b/src/sdl_main.cpp @@ -38,18 +38,47 @@ SDL_Texture *sdlWindTexture = nullptr; std::string fsBaseDir; std::string fsPreferencesDir; +static int8 isPixelPerfect = -1; +static int8 isFullscreen = -1; + int vid_reset_settings() { if (sdlWind != nullptr) { - if (globalsettings.opt_fullscreen) { - SDL_SetWindowFullscreen(sdlWind, SDL_WINDOW_FULLSCREEN_DESKTOP); - } else { - SDL_SetWindowFullscreen(sdlWind, SDL_WINDOW_RESIZABLE); - SDL_SetWindowSize(sdlWind, 640, 480); - SDL_SetWindowMinimumSize(sdlWind, 640, 480); - sdl_screen_scale = 1.0; - sdl_x_offset = 0; - sdl_y_offset = 0; + if (isFullscreen != globalsettings.opt_fullscreen) { + isFullscreen = globalsettings.opt_fullscreen; + if (isFullscreen) { + SDL_SetWindowFullscreen(sdlWind, SDL_WINDOW_FULLSCREEN_DESKTOP); + } else { + SDL_SetWindowFullscreen(sdlWind, SDL_WINDOW_RESIZABLE); + SDL_SetWindowSize(sdlWind, 640, 480); + SDL_SetWindowMinimumSize(sdlWind, 640, 480); + sdl_screen_scale = 1.0; + sdl_x_offset = 0; + sdl_y_offset = 0; + } + } + if (sdlRend != nullptr) { + if (globalsettings.opt_whole_multiple_rescale_ratio != isPixelPerfect + || sdlWindTexture == nullptr) { + isPixelPerfect = globalsettings.opt_whole_multiple_rescale_ratio; + if (isPixelPerfect) { + SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "nearest"); + } else { + SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "linear"); + } + if (sdlWindTexture != nullptr) { + SDL_DestroyTexture(sdlWindTexture); + sdlWindTexture = nullptr; + } + // and create the streaming texture. + sdlWindTexture = SDL_CreateTexture(sdlRend, blitIntermedSurf->format->format, + SDL_TEXTUREACCESS_STREAMING, 640, 480); + if (sdlWindTexture == nullptr) { + SDL_Log("Failed to create intermediate window texture (for fullscreen scaling): %s", + SDL_GetError()); + return 1; + } + } } } return 0; @@ -160,7 +189,7 @@ int main(int argc, char *argv[]) { // create the SDL Renderer we use to stream from the intermed blitting surface to the window. - sdlRend = SDL_CreateRenderer(sdlWind, -1, 0); + sdlRend = SDL_CreateRenderer(sdlWind, -1, SDL_RENDERER_ACCELERATED); if (sdlRend == nullptr) { SDL_Log("Failed to create SDL Renderer: %s", SDL_GetError()); return 1; @@ -174,15 +203,11 @@ int main(int argc, char *argv[]) { } // create the intermediate blitting surface (needed for fullscreen support) - auto *realSurf = SDL_GetWindowSurface(sdlWind); - blitIntermedSurf = SDL_ConvertSurface(sdlsurf, realSurf->format, 0); + blitIntermedSurf = SDL_CreateRGBSurfaceWithFormat(0, 640, 480, 32, SDL_PIXELFORMAT_RGBA8888); - // and create the streaming texture. - sdlWindTexture = SDL_CreateTexture(sdlRend, realSurf->format->format, SDL_TEXTUREACCESS_STREAMING, 640, 480); - if (sdlWindTexture == nullptr) { - SDL_Log("Failed to create intermediate window texture (for fullscreen scaling): %s", SDL_GetError()); - return 1; - } + // make sure our video state matches what we think it should be. This also + // creates the SDL_Texture we use to do the screen copy. + vid_reset_settings(); my_main(); return 0; From b6c470d6ed795c5b22efdfbae1e8ebdae0b06274 Mon Sep 17 00:00:00 2001 From: Chris Collins Date: Tue, 21 Jul 2020 04:29:55 +1000 Subject: [PATCH 7/9] Fix the comment in the README about pixel perfect scaling now that it definitely is pixel perfect. :) --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 37790d3..49fb40f 100644 --- a/README.md +++ b/README.md @@ -38,8 +38,8 @@ Key changes to the game source include: * Make use of writable local directories for scores and config -* Support rescaling to native resolution full-screen including "whole multiple" - scaling. (I'd like pixel perfect, but the scaled blit always filters) +* Support rescaling to native resolution full-screen including pixel perfect + scaling. * Allow the main window to be resized on the fly. Doesn't redraw whilst you're resizing (yet), but it will once the resize is complete. From 334daba1346843f9843f1dc82f9ebcdc7d1d2d2b Mon Sep 17 00:00:00 2001 From: Chris Collins Date: Tue, 21 Jul 2020 04:52:10 +1000 Subject: [PATCH 8/9] Fix highdpi scaling and input. --- src/w32_gfx.cpp | 47 ++++++++++++++++++++++++++++++++--------------- 1 file changed, 32 insertions(+), 15 deletions(-) diff --git a/src/w32_gfx.cpp b/src/w32_gfx.cpp index c19f217..b20b2d4 100644 --- a/src/w32_gfx.cpp +++ b/src/w32_gfx.cpp @@ -55,32 +55,49 @@ int sdl_y_offset = 0; float sdl_screen_scale = 1.0f; void gfx_refresh_screen() { - int w,h; - SDL_GetWindowSize(sdlWind, &w, &h); + int outw,outh,inw,inh,render_offx,render_offy; + float render_scale = 1.0f; + SDL_GetWindowSize(sdlWind, &inw, &inh); + SDL_GetRendererOutputSize(sdlRend, &outw, &outh); - // calculate scale factor. + // calculate scale factor. This is based on output sizes. if (globalsettings.opt_whole_multiple_rescale_ratio) { // for pixel perfect scaling, use integer ratios only. - int yrat = h / sdlsurf->h; - int xrat = w / sdlsurf->w; - sdl_screen_scale = static_cast(std::min(xrat, yrat)); - if (sdl_screen_scale < 1) { - sdl_screen_scale = 1; + int yrat = outh / sdlsurf->h; + int xrat = outw / sdlsurf->w; + render_scale = static_cast(std::min(xrat, yrat)); + if (render_scale < 1) { + render_scale = 1; } } else { - float yrat = static_cast(h) / static_cast(sdlsurf->h); - float xrat = static_cast(w) / static_cast(sdlsurf->w); - sdl_screen_scale = std::min(xrat, yrat); + float yrat = static_cast(outh) / static_cast(sdlsurf->h); + float xrat = static_cast(outw) / static_cast(sdlsurf->w); + render_scale = std::min(xrat, yrat); } + // damnit SDL! When we're on a HighDPI device, we have to work in two separate scales. + // + // Input is always in logical pixels, whereas output is in actual display pixels. + // + // this means we need to calculate our ratios twice - once to position the actual output rect + // and the second time to get the equivalent input transform information. + + sdl_screen_scale = render_scale * static_cast(inw) / static_cast(outw); + int targetXSize = static_cast(sdlsurf->w * sdl_screen_scale); int targetYSize = static_cast(sdlsurf->h * sdl_screen_scale); - sdl_x_offset = (w - targetXSize) / 2; - sdl_y_offset = (h - targetYSize) / 2; + sdl_x_offset = (inw - targetXSize) / 2; + sdl_y_offset = (inh - targetYSize) / 2; + + targetXSize = static_cast(sdlsurf->w * render_scale); + targetYSize = static_cast(sdlsurf->h * render_scale); + render_offx = (outw - targetXSize) / 2; + render_offy = (outh - targetYSize) / 2; + SDL_Rect destRect{ - sdl_x_offset, - sdl_y_offset, + render_offx, + render_offy, targetXSize, targetYSize, }; From 5905a5dd49e169651d971bddbc50a31d981b2e25 Mon Sep 17 00:00:00 2001 From: Chris Collins Date: Tue, 21 Jul 2020 04:53:15 +1000 Subject: [PATCH 9/9] Remove the old azure pipelines bits. --- CMakeLists.txt | 3 +++ Jenkinsfile | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index d82c56f..8dba8f7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -7,6 +7,9 @@ cmake_policy(SET CMP0091 NEW) set(CMAKE_CXX_STANDARD 14) set(CMAKE_CXX_STANDARD_REQUIRED 14) +# on macos, target 10.11 +set(CMAKE_OSX_DEPLOYMENT_TARGET 10.11) + project(strange VERSION 1.6.0 LANGUAGES C CXX) option(USE_CONAN "Use conan for dependencies" OFF) diff --git a/Jenkinsfile b/Jenkinsfile index 7fd63a6..1c53cf9 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -38,7 +38,7 @@ pipeline { deleteDir() sh ''' export PATH=/usr/local/bin:$PATH - export MACOS_DEPLOYMENT_TARGET=10.9 + export MACOS_DEPLOYMENT_TARGET=10.11 conan install ../saisgpl --build --update --profile=default ''' }