From ec71cf16de45ac46c93e02d548691fd9e185a501 Mon Sep 17 00:00:00 2001 From: kichikuou Date: Tue, 23 Jun 2026 07:09:08 +0900 Subject: [PATCH] Migrate to SDL3 (except for Android and Switch) Switch desktop/emscripten builds from SDL2 to SDL3, applying only the API changes that cannot compile through the SDL_oldnames.h aliases. Pure renames will be swept in a follow-up commit. --- .github/workflows/linux.yml | 4 +- .github/workflows/switch.yml | 4 +- .github/workflows/windows.yml | 9 ++- CMakeLists.txt | 57 +++++++++-------- src/common.h | 6 +- src/debugger/dap_frontend.cpp | 2 +- src/emscripten/mako.cpp | 2 +- src/generic/mako.cpp | 115 +++++++++++++++++++--------------- src/resource.cpp | 3 +- src/sdlmain.cpp | 6 +- src/sys/ags.cpp | 46 +++++++------- src/sys/ags.h | 10 +-- src/sys/ags_cursor.cpp | 27 ++------ src/sys/ags_draw.cpp | 14 ++--- src/sys/ags_text.cpp | 6 +- src/sys/ags_vsp.cpp | 2 +- src/sys/dri.cpp | 10 +-- src/sys/game_id.cpp | 2 +- src/sys/mako_midi.cpp | 2 +- src/sys/mako_midi.h | 2 +- src/sys/mako_music.cpp | 7 +-- src/sys/mako_music.h | 2 +- src/sys/nact.cpp | 14 +++-- src/sys/nact.h | 6 +- src/sys/nact_input.cpp | 25 +++++--- src/sys/nact_sys1.cpp | 4 +- src/sys/nact_sys2.cpp | 6 +- src/sys/nact_sys3.cpp | 2 +- src/texthook.cpp | 2 +- src/win/nact_win.cpp | 32 +++++----- 30 files changed, 222 insertions(+), 207 deletions(-) diff --git a/.github/workflows/linux.yml b/.github/workflows/linux.yml index 249acd1..fbb659d 100644 --- a/.github/workflows/linux.yml +++ b/.github/workflows/linux.yml @@ -3,7 +3,7 @@ on: [push, pull_request] jobs: build: - runs-on: ubuntu-latest + runs-on: ubuntu-26.04 strategy: matrix: build-type: ["Debug", "Release"] @@ -17,7 +17,7 @@ jobs: - name: Install Deps run: | sudo apt update - sudo apt install libsdl2-dev libsdl2-ttf-dev librtmidi-dev nlohmann-json3-dev + sudo apt install libsdl3-dev libsdl3-ttf-dev librtmidi-dev nlohmann-json3-dev - name: Build run: | diff --git a/.github/workflows/switch.yml b/.github/workflows/switch.yml index f32b917..393f606 100644 --- a/.github/workflows/switch.yml +++ b/.github/workflows/switch.yml @@ -1,5 +1,7 @@ name: Nintendo Switch Build -on: [push, pull_request] +# Disabled: devkitPro provides no SDL3 portlib yet, so the Switch build cannot be +# migrated off SDL2. Run manually once an SDL3 portlib is available. +on: workflow_dispatch jobs: build: diff --git a/.github/workflows/windows.yml b/.github/workflows/windows.yml index fee7652..dbd7520 100644 --- a/.github/workflows/windows.yml +++ b/.github/workflows/windows.yml @@ -8,9 +8,8 @@ jobs: fail-fast: false matrix: include: - - sys: mingw32 - package: "system3-sdl2-32bit" - deps: "" + # MSYS2 provides no i686 (mingw32) SDL3 packages, so the 32-bit MSYS2 + # build is dropped. 32-bit Windows is still covered by the MSVC Win32 build. - sys: ucrt64 package: "system3-sdl2-64bit" deps: "nlohmann-json:p" @@ -25,8 +24,8 @@ jobs: with: msystem: ${{ matrix.sys }} pacboy: >- - SDL2:p - SDL2_ttf:p + sdl3:p + sdl3-ttf:p rtmidi:p ${{ matrix.deps }} diff --git a/CMakeLists.txt b/CMakeLists.txt index 6b3bc40..e1ca992 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -53,7 +53,9 @@ elseif (EMSCRIPTEN) src/emscripten/nact_emscripten.cpp src/emscripten/mako.cpp ) - set(LIBS -sUSE_SDL=2 -sUSE_SDL_TTF=2) + # -Wno-experimental: the sdl3 port is marked experimental and would otherwise + # be promoted to an error by CMAKE_COMPILE_WARNING_AS_ERROR. + set(LIBS -sUSE_SDL=3 -sUSE_SDL_TTF=3 -Wno-experimental) target_compile_options(system3 PRIVATE ${LIBS}) target_link_options(system3 PRIVATE ${LIBS}) target_link_libraries(system3 PRIVATE idbfs.js ymfm) @@ -82,20 +84,20 @@ else() # NOT (ANDROID OR EMSCRIPTEN) if (MSVC) include(FetchContent) - FetchContent_Declare(sdl2 - URL https://github.com/libsdl-org/SDL/releases/download/release-2.32.10/SDL2-devel-2.32.10-VC.zip - URL_HASH SHA1=27f5179346a0b0db80c4dd1769c7c9d62b9a91f3) - FetchContent_MakeAvailable(sdl2) - find_package(SDL2 REQUIRED CONFIG PATHS ${sdl2_SOURCE_DIR}/cmake NO_DEFAULT_PATH) - get_target_property(SDL2_DLL SDL2::SDL2 IMPORTED_LOCATION) + FetchContent_Declare(sdl3 + URL https://github.com/libsdl-org/SDL/releases/download/release-3.4.10/SDL3-devel-3.4.10-VC.zip + URL_HASH SHA1=248b2d3f6e5def115793952ea14d8b519aca2791) + FetchContent_MakeAvailable(sdl3) + find_package(SDL3 REQUIRED CONFIG PATHS ${sdl3_SOURCE_DIR}/cmake NO_DEFAULT_PATH) + get_target_property(SDL3_DLL SDL3::SDL3 IMPORTED_LOCATION) - FetchContent_Declare(sdl2_ttf - URL https://github.com/libsdl-org/SDL_ttf/releases/download/release-2.24.0/SDL2_ttf-devel-2.24.0-VC.zip - URL_HASH SHA1=2d18b9a4fc2ec0eee80de2a946b088d4e6efd0ee) - FetchContent_MakeAvailable(sdl2_ttf) - find_package(SDL2_ttf REQUIRED CONFIG PATHS ${sdl2_ttf_SOURCE_DIR}/cmake NO_DEFAULT_PATH) - get_target_property(SDL2TTF_DLL SDL2_ttf::SDL2_ttf IMPORTED_LOCATION) - get_filename_component(SDL2TTF_LIBDIR ${SDL2TTF_DLL} DIRECTORY) + FetchContent_Declare(sdl3_ttf + URL https://github.com/libsdl-org/SDL_ttf/releases/download/release-3.2.2/SDL3_ttf-devel-3.2.2-VC.zip + URL_HASH SHA1=3786bc016d89ca4cf9739e4d342ca29e3e29c137) + FetchContent_MakeAvailable(sdl3_ttf) + find_package(SDL3_ttf REQUIRED CONFIG PATHS ${sdl3_ttf_SOURCE_DIR}/cmake NO_DEFAULT_PATH) + get_target_property(SDL3TTF_DLL SDL3_ttf::SDL3_ttf IMPORTED_LOCATION) + get_filename_component(SDL3TTF_LIBDIR ${SDL3TTF_DLL} DIRECTORY) FetchContent_Declare(rtmidi URL https://github.com/thestk/rtmidi/archive/refs/tags/6.0.0.zip @@ -117,29 +119,29 @@ else() # NOT (ANDROID OR EMSCRIPTEN) target_compile_definitions(system3 PRIVATE _CRT_NONSTDC_NO_DEPRECATE _CRT_SECURE_NO_WARNINGS) target_compile_options(system3 PRIVATE /utf-8 /wd4244) - target_link_libraries(system3 PRIVATE SDL2::SDL2main SDL2::SDL2 SDL2_ttf::SDL2_ttf) + target_link_libraries(system3 PRIVATE SDL3::SDL3 SDL3_ttf::SDL3_ttf) set_target_properties(system3 PROPERTIES WIN32_EXECUTABLE TRUE - VS_DEBUGGER_ENVIRONMENT "PATH=${SDL2_LIBDIR}$${SDL2TTF_LIBDIR}$$ENV{PATH}") + VS_DEBUGGER_ENVIRONMENT "PATH=${SDL3_LIBDIR}$${SDL3TTF_LIBDIR}$$ENV{PATH}") set_directory_properties(PROPERTIES VS_STARTUP_PROJECT system3) - install(FILES ${SDL2_DLL} ${SDL2TTF_DLL} DESTINATION .) + install(FILES ${SDL3_DLL} ${SDL3TTF_DLL} DESTINATION .) install(TARGETS system3 RUNTIME DESTINATION .) else() include(FindPkgConfig) - pkg_check_modules(SDL2 REQUIRED IMPORTED_TARGET sdl2) - pkg_check_modules(SDL2TTF REQUIRED IMPORTED_TARGET SDL2_ttf) + pkg_check_modules(SDL3 REQUIRED IMPORTED_TARGET sdl3) + pkg_check_modules(SDL3TTF REQUIRED IMPORTED_TARGET sdl3-ttf) if (MINGW) - add_static_library(sdl2 SDL2) - add_static_library(sdl2_ttf SDL2TTF) + add_static_library(sdl3 SDL3) + add_static_library(sdl3_ttf SDL3TTF) # Workaround for linking error - set_property(TARGET sdl2_ttf PROPERTY INTERFACE_LINK_LIBRARIES - $) + set_property(TARGET sdl3_ttf PROPERTY INTERFACE_LINK_LIBRARIES + $) else() - add_library(sdl2 ALIAS PkgConfig::SDL2) - add_library(sdl2_ttf ALIAS PkgConfig::SDL2TTF) + add_library(sdl3 ALIAS PkgConfig::SDL3) + add_library(sdl3_ttf ALIAS PkgConfig::SDL3TTF) endif() - target_link_libraries(system3 PRIVATE sdl2 sdl2_ttf) + target_link_libraries(system3 PRIVATE sdl3 sdl3_ttf) find_package(nlohmann_json 3.2.0) if (nlohmann_json_FOUND) @@ -167,7 +169,6 @@ else() # NOT (ANDROID OR EMSCRIPTEN) src/win/resource.rc ) target_compile_definitions(system3 PRIVATE NOMINMAX) - target_link_libraries(system3 PRIVATE winmm) if (MINGW) target_link_options(system3 PRIVATE -static) endif() @@ -249,4 +250,6 @@ if (NOT EMSCRIPTEN) endif() target_compile_definitions(system3 PRIVATE RESOURCE_PATH="${RESOURCE_PATH}") +# SDL2->SDL3 migration: keep SDL2-spelled symbols compiling via the oldnames aliases. +target_compile_definitions(system3 PRIVATE SDL_ENABLE_OLD_NAMES) target_include_directories(system3 PRIVATE src src/sys) diff --git a/src/common.h b/src/common.h index 946049a..f7ee727 100644 --- a/src/common.h +++ b/src/common.h @@ -42,8 +42,8 @@ enum CustomEvent { }; // resource.cpp -struct SDL_RWops; -SDL_RWops* open_resource(const char* name, const char* type); -SDL_RWops* open_file(const char* name); +struct SDL_IOStream; +SDL_IOStream* open_resource(const char* name, const char* type); +SDL_IOStream* open_file(const char* name); #endif diff --git a/src/debugger/dap_frontend.cpp b/src/debugger/dap_frontend.cpp index 0a404d9..ecc1bf3 100644 --- a/src/debugger/dap_frontend.cpp +++ b/src/debugger/dap_frontend.cpp @@ -3,7 +3,7 @@ #include "debugger/frontend.h" #include #include -#include +#include #include "nlohmann/json.hpp" #include "common.h" #include "encoding.h" diff --git a/src/emscripten/mako.cpp b/src/emscripten/mako.cpp index bf9fe80..6479e04 100644 --- a/src/emscripten/mako.cpp +++ b/src/emscripten/mako.cpp @@ -4,7 +4,7 @@ */ #include -#include +#include #include #include "mako.h" #include "fm/mako_ymfm.h" diff --git a/src/generic/mako.cpp b/src/generic/mako.cpp index d535cf7..6ae35a6 100644 --- a/src/generic/mako.cpp +++ b/src/generic/mako.cpp @@ -8,7 +8,7 @@ #include #include #include -#include +#include #include "mako.h" #include "mako_midi.h" @@ -33,7 +33,9 @@ const int8_t RANCE42_tracks[] = {2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,1 const int8_t DPSALL_tracks[] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,5,1,2,3,-1}; #endif -SDL_AudioDeviceID g_device; +// The main output stream, opened together with the audio device via +// SDL_OpenAudioDeviceStream(). Its callback mixes fm/music/pcm together. +SDL_AudioStream* g_stream; SDL_AudioSpec g_device_spec; std::unique_ptr music; @@ -62,24 +64,35 @@ void mix_pcm(Uint8* out, int len) Uint8* tmp = SDL_stack_alloc(Uint8, len); int got = SDL_AudioStreamGet(pcm_stream, tmp, len); if (got > 0) - SDL_MixAudioFormat(out, tmp, AUDIO_S16SYS, got, SDL_MIX_MAXVOLUME); + SDL_MixAudioFormat(out, tmp, AUDIO_S16SYS, got, 1.0f); SDL_stack_free(tmp); } -void audio_callback(void*, Uint8* stream, int len) +// SDL3 audio callback: rather than handing us a buffer to fill, SDL asks us to +// feed `additional_amount` bytes into the stream via SDL_PutAudioStreamData(). +void SDLCALL audio_callback(void*, SDL_AudioStream* stream, int additional_amount, int /*total_amount*/) { - SDL_memset(stream, 0, len); - if (fm) { - int frames = len / 4; - int16_t* tmp = SDL_stack_alloc(int16_t, frames * 2); - fm->Process(tmp, frames); - SDL_MixAudioFormat(stream, reinterpret_cast(tmp), AUDIO_S16SYS, len, SDL_MIX_MAXVOLUME); - SDL_stack_free(tmp); + // Mix in bounded chunks so the scratch buffers (and the per-source + // SDL_stack_alloc() below) stay small no matter how much SDL requests. + const int CHUNK = 4096; // bytes; 1024 stereo S16 frames + Uint8 buffer[CHUNK]; + while (additional_amount > 0) { + int len = additional_amount < CHUNK ? additional_amount : CHUNK; + SDL_memset(buffer, 0, len); + if (fm) { + int frames = len / 4; + int16_t* tmp = SDL_stack_alloc(int16_t, frames * 2); + fm->Process(tmp, frames); + SDL_MixAudioFormat(buffer, reinterpret_cast(tmp), AUDIO_S16SYS, len, 1.0f); + SDL_stack_free(tmp); + } + if (music) + music->mix(buffer, len); + if (pcm_stream) + mix_pcm(buffer, len); + SDL_PutAudioStreamData(stream, buffer, len); + additional_amount -= len; } - if (music) - music->mix(stream, len); - if (pcm_stream) - mix_pcm(stream, len); } } // namespace @@ -110,19 +123,18 @@ MAKO::MAKO(const Config& config, const GameId& game_id) : cd_track[i] = 0; SDL_InitSubSystem(SDL_INIT_AUDIO); - SDL_AudioSpec want; - SDL_zero(want); - want.freq = SAMPLE_RATE; - want.format = AUDIO_S16SYS; - want.channels = 2; - want.samples = 4096; - want.callback = &audio_callback; - g_device = SDL_OpenAudioDevice(nullptr, 0, &want, &g_device_spec, 0); - if (!g_device) { - WARNING("SDL_OpenAudioDevice failed: %s", SDL_GetError()); + // g_device_spec is the format our callback produces; the resampling streams + // used by MakoMusic/MakoYmfm/pcm convert their sources into this format. + SDL_zero(g_device_spec); + g_device_spec.freq = SAMPLE_RATE; + g_device_spec.format = AUDIO_S16SYS; + g_device_spec.channels = 2; + g_stream = SDL_OpenAudioDeviceStream(SDL_AUDIO_DEVICE_DEFAULT_PLAYBACK, &g_device_spec, audio_callback, nullptr); + if (!g_stream) { + WARNING("SDL_OpenAudioDeviceStream failed: %s", SDL_GetError()); use_fm = false; } else { - SDL_PauseAudioDevice(g_device, 0); + SDL_ResumeAudioStreamDevice(g_stream); } midi = std::make_unique(config.midi_device); @@ -136,8 +148,8 @@ MAKO::~MAKO() stop_pcm(); midi.reset(); - if (g_device) - SDL_CloseAudioDevice(g_device); + if (g_stream) + SDL_DestroyAudioStream(g_stream); // also closes the audio device SDL_QuitSubSystem(SDL_INIT_AUDIO); } @@ -185,17 +197,17 @@ void MAKO::play_music(int page) auto m = std::make_unique(file, next_loop, g_device_spec); if (!m->is_open()) return; - SDL_LockAudioDevice(g_device); + SDL_LockAudioStream(g_stream); music = std::move(m); - SDL_UnlockAudioDevice(g_device); + SDL_UnlockAudioStream(g_stream); } else if (use_fm) { std::vector data = amus.load(page); if (data.empty()) return; auto f = std::make_unique(SAMPLE_RATE, std::move(data)); - SDL_LockAudioDevice(g_device); + SDL_LockAudioStream(g_stream); fm = std::move(f); - SDL_UnlockAudioDevice(g_device); + SDL_UnlockAudioStream(g_stream); } else if (midi->is_available()) { if (!midi->play(game_id, amus, mda, page, next_loop)) return; @@ -207,10 +219,10 @@ void MAKO::play_music(int page) void MAKO::stop_music() { if (music || fm) { - SDL_LockAudioDevice(g_device); + SDL_LockAudioStream(g_stream); std::unique_ptr old_music = std::move(music); std::unique_ptr old_fm = std::move(fm); - SDL_UnlockAudioDevice(g_device); + SDL_UnlockAudioStream(g_stream); // old_music/old_fm are destroyed here, outside the lock. } if (midi->is_available()) @@ -220,19 +232,19 @@ void MAKO::stop_music() bool MAKO::check_music() { - SDL_LockAudioDevice(g_device); + SDL_LockAudioStream(g_stream); if (fm) { int mark, loop; fm->get_mark(&mark, &loop); - SDL_UnlockAudioDevice(g_device); + SDL_UnlockAudioStream(g_stream); return !loop; } if (music) { bool playing = music->is_playing(); - SDL_UnlockAudioDevice(g_device); + SDL_UnlockAudioStream(g_stream); return playing; } - SDL_UnlockAudioDevice(g_device); + SDL_UnlockAudioStream(g_stream); return midi->is_playing(); } @@ -297,13 +309,13 @@ void MAKO::select_sound(BGMDevice dev) void MAKO::get_mark(int* mark, int* loop) { - SDL_LockAudioDevice(g_device); + SDL_LockAudioStream(g_stream); if (fm) { fm->get_mark(mark, loop); - SDL_UnlockAudioDevice(g_device); + SDL_UnlockAudioStream(g_stream); return; } - SDL_UnlockAudioDevice(g_device); + SDL_UnlockAudioStream(g_stream); midi->get_mark(mark, loop); } @@ -326,8 +338,7 @@ void MAKO::play_pcm(int page, int loops) } src.assign(wav, wav + wavlen); SDL_FreeWAV(wav); - stream = SDL_NewAudioStream(spec.format, spec.channels, spec.freq, - g_device_spec.format, g_device_spec.channels, g_device_spec.freq); + stream = SDL_CreateAudioStream(&spec, &g_device_spec); } else { // AMSE形式 (乙女戦記) data = amse.load(page); @@ -339,29 +350,29 @@ void MAKO::play_pcm(int page, int loops) src.push_back(data[i] & 0xf0); src.push_back((data[i] & 0x0f) << 4); } - stream = SDL_NewAudioStream(AUDIO_U8, 1, 8000, - g_device_spec.format, g_device_spec.channels, g_device_spec.freq); + SDL_AudioSpec src_spec = { AUDIO_U8, 1, 8000 }; + stream = SDL_CreateAudioStream(&src_spec, &g_device_spec); } if (!stream) { - WARNING("SDL_NewAudioStream failed: %s", SDL_GetError()); + WARNING("SDL_CreateAudioStream failed: %s", SDL_GetError()); return; } - SDL_LockAudioDevice(g_device); + SDL_LockAudioStream(g_stream); pcm_stream = stream; pcm_src = std::move(src); pcm_loops = loops ? loops : -1; pcm_input_finished = false; - SDL_UnlockAudioDevice(g_device); + SDL_UnlockAudioStream(g_stream); } void MAKO::stop_pcm() { - SDL_LockAudioDevice(g_device); + SDL_LockAudioStream(g_stream); SDL_AudioStream* old = pcm_stream; pcm_stream = nullptr; pcm_src.clear(); pcm_input_finished = false; - SDL_UnlockAudioDevice(g_device); + SDL_UnlockAudioStream(g_stream); if (old) SDL_FreeAudioStream(old); } @@ -369,10 +380,10 @@ void MAKO::stop_pcm() bool MAKO::check_pcm() { // 再生中でtrue - SDL_LockAudioDevice(g_device); + SDL_LockAudioStream(g_stream); bool playing = pcm_stream && (!pcm_input_finished || SDL_AudioStreamAvailable(pcm_stream) > 0); - SDL_UnlockAudioDevice(g_device); + SDL_UnlockAudioStream(g_stream); return playing; } diff --git a/src/resource.cpp b/src/resource.cpp index 80d992a..64d3eaa 100644 --- a/src/resource.cpp +++ b/src/resource.cpp @@ -1,9 +1,10 @@ #include +#include #ifdef _WIN32 #include #undef ERROR #endif -#include +#include #include "common.h" SDL_RWops* open_resource(const char* name, const char* type) { diff --git a/src/sdlmain.cpp b/src/sdlmain.cpp index 9d30558..96c152c 100644 --- a/src/sdlmain.cpp +++ b/src/sdlmain.cpp @@ -1,3 +1,4 @@ +#include #include #include "common.h" #include "config.h" @@ -35,7 +36,6 @@ SDL_Window* create_window(const GameId& game_id) SDL_Init(SDL_INIT_VIDEO); SDL_SetHint(SDL_HINT_TOUCH_MOUSE_EVENTS, "0"); - SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "linear"); #ifdef __EMSCRIPTEN__ // Stop SDL from calling emscripten_sleep() in functions that are called // indirectly, which does not work with ASYNCIFY_IGNORE_INDIRECT=1. For @@ -57,7 +57,7 @@ SDL_Window* create_window(const GameId& game_id) #else const char *window_title = title.c_str(); #endif - return SDL_CreateWindow(window_title, SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 640, 400, flags); + return SDL_CreateWindow(window_title, 640, 400, flags); } } // namespace @@ -77,7 +77,7 @@ int main(int argc, char *argv[]) GameId game_id(config); g_window = create_window(game_id); - g_renderer = SDL_CreateRenderer(g_window, -1, 0); + g_renderer = SDL_CreateRenderer(g_window, NULL); sdl_custom_event_type = SDL_RegisterEvents(1); // system3 初期化 diff --git a/src/sys/ags.cpp b/src/sys/ags.cpp index ef468b4..46c39cf 100644 --- a/src/sys/ags.cpp +++ b/src/sys/ags.cpp @@ -21,7 +21,7 @@ const uint32 SCANLINE_ALPHA = 0x38; // 0-255 SDL_Texture* create_scanline_texture(SDL_Renderer* renderer, int width, int height) { - SDL_Surface* sf = SDL_CreateRGBSurfaceWithFormat(0, width, height, 32, SDL_PIXELFORMAT_ARGB8888); + SDL_Surface* sf = SDL_CreateSurface(width, height, SDL_PIXELFORMAT_ARGB8888); for (int y = 0; y < height; y++) { uint32* p = reinterpret_cast(surface_line(sf, y)); uint32 v = y % 2 ? (SCANLINE_ALPHA << 24) : 0; @@ -50,18 +50,18 @@ AGS::AGS(const Config& config, const GameId& game_id) : game_id(game_id) } SDL_SetWindowSize(g_window, window_width, window_height); - SDL_RenderSetLogicalSize(g_renderer, window_width, window_height); + SDL_SetRenderLogicalPresentation(g_renderer, window_width, window_height, SDL_LOGICAL_PRESENTATION_LETTERBOX); sdlTexture = SDL_CreateTexture(g_renderer, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_STREAMING, screen_width, screen_height); scanline_texture = NULL; // DIBSection 8bpp * 3 (表, 裏, メニュー) for(int i = 0; i < 3; i++) { - hBmpScreen[i] = SDL_CreateRGBSurfaceWithFormat(0, 640, 480, 8, SDL_PIXELFORMAT_INDEX8); + hBmpScreen[i] = SDL_CreateSurface(640, 480, SDL_PIXELFORMAT_INDEX8); vram[i] = reinterpret_cast(hBmpScreen[i]->pixels); } // All surfaces share the same palette. - screen_palette = hBmpScreen[0]->format->palette; + screen_palette = SDL_CreateSurfacePalette(hBmpScreen[0]); SDL_SetSurfacePalette(hBmpScreen[1], screen_palette); SDL_SetSurfacePalette(hBmpScreen[2], screen_palette); @@ -79,17 +79,17 @@ AGS::AGS(const Config& config, const GameId& game_id) : game_id(game_id) if (!rw_font) sys_error("Cannot open default font"); } - hFont16 = TTF_OpenFontRW(rw_font, 0, 16); - SDL_RWseek(rw_font, 0, SEEK_SET); - hFont24 = TTF_OpenFontRW(rw_font, 0, 24); - SDL_RWseek(rw_font, 0, SEEK_SET); - hFont32 = TTF_OpenFontRW(rw_font, 0, 32); - SDL_RWseek(rw_font, 0, SEEK_SET); - hFont48 = TTF_OpenFontRW(rw_font, 0, 48); - SDL_RWseek(rw_font, 0, SEEK_SET); - hFont64 = TTF_OpenFontRW(rw_font, 0, 64); + hFont16 = TTF_OpenFontIO(rw_font, false, 16); + SDL_RWseek(rw_font, 0, SDL_IO_SEEK_SET); + hFont24 = TTF_OpenFontIO(rw_font, false, 24); + SDL_RWseek(rw_font, 0, SDL_IO_SEEK_SET); + hFont32 = TTF_OpenFontIO(rw_font, false, 32); + SDL_RWseek(rw_font, 0, SDL_IO_SEEK_SET); + hFont48 = TTF_OpenFontIO(rw_font, false, 48); + SDL_RWseek(rw_font, 0, SDL_IO_SEEK_SET); + hFont64 = TTF_OpenFontIO(rw_font, false, 64); if (!hFont16 || !hFont24 || !hFont32 || !hFont48 || !hFont64) { - sys_error("TTF_OpenFontRW failed: %s", TTF_GetError()); + sys_error("TTF_OpenFontIO failed: %s", SDL_GetError()); } if (config.no_antialias) ags_setAntialiasedStringMode(0); @@ -379,7 +379,7 @@ void AGS::fade_out(int duration_ms, bool white) fade_color = white ? 255 : 0; - Uint32 dwStart = SDL_GetTicks(); + Uint64 dwStart = SDL_GetTicks(); while (fade_level < 255) { g_nact->sys_sleep(16); int t = SDL_GetTicks() - dwStart; @@ -393,7 +393,7 @@ void AGS::fade_in(int duration_ms) if (fade_level == 0) return; - Uint32 dwStart = SDL_GetTicks(); + Uint64 dwStart = SDL_GetTicks(); while (fade_level > 0) { g_nact->sys_sleep(16); int t = SDL_GetTicks() - dwStart; @@ -421,8 +421,8 @@ void AGS::update_screen() } SDL_RenderClear(g_renderer); - SDL_Rect src = {0, 0, screen_width, screen_height}; - SDL_Rect dest = {0, 0, window_width, screen_height}; + SDL_FRect src = {0.f, 0.f, (float)screen_width, (float)screen_height}; + SDL_FRect dest = {0.f, 0.f, (float)window_width, (float)screen_height}; if (scroll > 0) { src.y = scroll; src.h = dest.h = screen_height - scroll; @@ -430,7 +430,7 @@ void AGS::update_screen() dest.y = -scroll; src.h = dest.h = screen_height + scroll; } - SDL_RenderCopy(g_renderer, sdlTexture, &src, &dest); + SDL_RenderTexture(g_renderer, sdlTexture, &src, &dest); if (fade_level) { SDL_SetRenderDrawBlendMode(g_renderer, SDL_BLENDMODE_BLEND); @@ -440,7 +440,7 @@ void AGS::update_screen() SDL_SetRenderDrawBlendMode(g_renderer, SDL_BLENDMODE_NONE); } if (scanline_texture) - SDL_RenderCopy(g_renderer, scanline_texture, NULL, NULL); + SDL_RenderTexture(g_renderer, scanline_texture, NULL, NULL); SDL_RenderPresent(g_renderer); } @@ -456,18 +456,18 @@ void AGS::set_scanline_mode(bool enable) bool AGS::save_screenshot(const char* path) { - SDL_Surface* sf = SDL_CreateRGBSurface(0, screen_width, screen_height, 32, 0, 0, 0, 0); + SDL_Surface* sf = SDL_CreateSurface(screen_width, screen_height, SDL_GetPixelFormatForMasks(32, 0, 0, 0, 0)); SDL_BlitSurface(hBmpScreen[0], NULL, sf, NULL); if (scanline_texture) { SDL_Renderer* renderer = SDL_CreateSoftwareRenderer(sf); SDL_Texture *tx = create_scanline_texture(renderer, screen_width, screen_height); - SDL_RenderCopy(renderer, tx, NULL, NULL); + SDL_RenderTexture(renderer, tx, NULL, NULL); SDL_DestroyTexture(tx); SDL_DestroyRenderer(renderer); } - bool ok = SDL_SaveBMP(sf, path) == 0; + bool ok = SDL_SaveBMP(sf, path); if (!ok) { SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "system3", SDL_GetError(), g_window); diff --git a/src/sys/ags.h b/src/sys/ags.h index 7950180..e6d1ba3 100644 --- a/src/sys/ags.h +++ b/src/sys/ags.h @@ -17,7 +17,7 @@ #include "common.h" #include "game_id.h" #include "dri.h" -#include +#include inline uint8_t* surface_line(SDL_Surface* surface, int y) { @@ -40,14 +40,16 @@ struct CG { CG() = default; CG(int x, int y, int width, int height) - : surface_(SDL_CreateRGBSurfaceWithFormat(0, width, height, 8, SDL_PIXELFORMAT_INDEX8)), - x(x), y(y) {} + : surface_(SDL_CreateSurface(width, height, SDL_PIXELFORMAT_INDEX8)), + x(x), y(y) { + SDL_CreateSurfacePalette(surface_.get()); + } explicit operator bool() const noexcept { return static_cast(surface_); } SDL_Surface* surface() const { return surface_.get(); } int width() const { return surface_->w; } int height() const { return surface_->h; } - SDL_Palette* palette() const { return surface_->format->palette; } + SDL_Palette* palette() const { return SDL_GetSurfacePalette(surface_.get()); } }; class AGS diff --git a/src/sys/ags_cursor.cpp b/src/sys/ags_cursor.cpp index d3728e5..e621008 100644 --- a/src/sys/ags_cursor.cpp +++ b/src/sys/ags_cursor.cpp @@ -90,27 +90,8 @@ void AGS::select_cursor() void AGS::translate_mouse_coords(int* x, int* y) { - // scale mouse x and y - float scalex, scaley; - SDL_RenderGetScale(g_renderer, &scalex, &scaley); - *x *= scalex; - *y *= scaley; - - // calculate window borders - int logw, logh; - SDL_RenderGetLogicalSize(g_renderer, &logw, &logh); - - float scalew, scaleh; - scalew = logw * scalex; - scaleh = logh * scaley; - - int winw, winh; - SDL_GetWindowSize(g_window, &winw, &winh); - - float border_left = (winw - scalew) / 2; - float border_top = (winh - scaleh) / 2; - - // offset x and y by window borders - *x += border_left; - *y += border_top; + float window_x, window_y; + SDL_RenderCoordinatesToWindow(g_renderer, *x, *y, &window_x, &window_y); + *x = window_x; + *y = window_y; } diff --git a/src/sys/ags_draw.cpp b/src/sys/ags_draw.cpp index 0a9eadf..43aa534 100644 --- a/src/sys/ags_draw.cpp +++ b/src/sys/ags_draw.cpp @@ -19,13 +19,13 @@ namespace { const int MOSAIC_SIZE = 16; void mosaic(SDL_Surface* sf) { - SDL_Surface *tmp = SDL_CreateRGBSurfaceWithFormat( - 0, (sf->w + MOSAIC_SIZE - 1) / MOSAIC_SIZE, (sf->h + MOSAIC_SIZE - 1) / MOSAIC_SIZE, 8, SDL_PIXELFORMAT_INDEX8); - if (sf->format->palette) - SDL_SetSurfacePalette(tmp, sf->format->palette); - // NOTE: SDL_BlitScaled() does not support 8-bit surfaces. - SDL_SoftStretch(sf, NULL, tmp, NULL); - SDL_SoftStretch(tmp, NULL, sf, NULL); + SDL_Surface *tmp = SDL_CreateSurface( + (sf->w + MOSAIC_SIZE - 1) / MOSAIC_SIZE, (sf->h + MOSAIC_SIZE - 1) / MOSAIC_SIZE, SDL_PIXELFORMAT_INDEX8); + if (SDL_GetSurfacePalette(sf)) + SDL_SetSurfacePalette(tmp, SDL_GetSurfacePalette(sf)); + // NOTE: SDL_BlitSurfaceScaled() does not support 8-bit surfaces. + SDL_StretchSurface(sf, NULL, tmp, NULL, SDL_SCALEMODE_NEAREST); + SDL_StretchSurface(tmp, NULL, sf, NULL, SDL_SCALEMODE_NEAREST); SDL_FreeSurface(tmp); } diff --git a/src/sys/ags_text.cpp b/src/sys/ags_text.cpp index 0fe87a0..882cb30 100644 --- a/src/sys/ags_text.cpp +++ b/src/sys/ags_text.cpp @@ -371,8 +371,8 @@ void AGS::draw_text(std::string_view string, bool text_wait) case 48: font = hFont48; break; case 64: font = hFont64; break; } - int ascent = TTF_FontAscent(font); - int descent = TTF_FontDescent(font); + int ascent = TTF_GetFontAscent(font); + int descent = TTF_GetFontDescent(font); // Adjust dest_y if the font height is larger than the specified size. dest_y -= (ascent - descent - ctx.font_size) / 2; @@ -399,7 +399,7 @@ void AGS::draw_text(std::string_view string, bool text_wait) draw_char(screen, dest_x, dest_y, code, font, ctx.font_color); int miny, maxy, advance; - TTF_GlyphMetrics(font, code, NULL, NULL, &miny, &maxy, &advance); + TTF_GetGlyphMetrics(font, code, NULL, NULL, &miny, &maxy, &advance); // Some fonts report incorrect Ascent/Descent value so we need to fix them. if (miny < descent) descent = miny; if (maxy > ascent) ascent = maxy; diff --git a/src/sys/ags_vsp.cpp b/src/sys/ags_vsp.cpp index 18d36b3..13df3a8 100644 --- a/src/sys/ags_vsp.cpp +++ b/src/sys/ags_vsp.cpp @@ -12,7 +12,7 @@ namespace { void trim(CG& cg, int w, int h) { - SDL_Surface *sf = SDL_CreateRGBSurfaceWithFormat(0, w, h, 8, SDL_PIXELFORMAT_INDEX8); + SDL_Surface *sf = SDL_CreateSurface(w, h, SDL_PIXELFORMAT_INDEX8); SDL_SetSurfacePalette(sf, cg.palette()); if (SDL_HasColorKey(cg.surface())) { Uint32 key; diff --git a/src/sys/dri.cpp b/src/sys/dri.cpp index 46e09b0..4c2b26f 100644 --- a/src/sys/dri.cpp +++ b/src/sys/dri.cpp @@ -7,7 +7,7 @@ #include "dri.h" #include #include -#include +#include #include "game_id.h" #include "fileio.h" @@ -185,7 +185,7 @@ std::vector Dri::load_mda(const GameId& game_id, int page) uint8 buf[4]; // ページの位置を取得 - SDL_RWread(rw, buf, 4, 1); + SDL_ReadIO(rw, buf, 4); int link_sector = buf[0] | (buf[1] << 8); int data_sector = buf[2] | (buf[3] << 8); @@ -196,7 +196,7 @@ std::vector Dri::load_mda(const GameId& game_id, int page) } SDL_RWseek(rw, (link_sector - 1) * 256 + (page - 1) * 2, RW_SEEK_SET); - SDL_RWread(rw, buf, 2, 1); + SDL_ReadIO(rw, buf, 2); int disk_index = buf[0]; int link_index = buf[1]; @@ -281,7 +281,7 @@ std::vector Dri::load_mda(const GameId& game_id, int page) // データ取得 SDL_RWseek(rw, link_index * 2, RW_SEEK_SET); - SDL_RWread(rw, buf, 4, 1); + SDL_ReadIO(rw, buf, 4); int start_sector = buf[0] | (buf[1] << 8); int end_sector = buf[2] | (buf[3] << 8); @@ -293,7 +293,7 @@ std::vector Dri::load_mda(const GameId& game_id, int page) } std::vector buffer(size); SDL_RWseek(rw, (start_sector - 1) * 256, RW_SEEK_SET); - SDL_RWread(rw, buffer.data(), size, 1); + SDL_ReadIO(rw, buffer.data(), size); SDL_RWclose(rw); diff --git a/src/sys/game_id.cpp b/src/sys/game_id.cpp index dcff0fd..27c1cf1 100644 --- a/src/sys/game_id.cpp +++ b/src/sys/game_id.cpp @@ -1,5 +1,5 @@ #include -#include +#include #include "game_id.h" #include "fileio.h" #include "config.h" diff --git a/src/sys/mako_midi.cpp b/src/sys/mako_midi.cpp index 2bd0cc1..f3bbc1c 100644 --- a/src/sys/mako_midi.cpp +++ b/src/sys/mako_midi.cpp @@ -6,7 +6,7 @@ #include #include -#include +#include #include #include "mako_midi.h" diff --git a/src/sys/mako_midi.h b/src/sys/mako_midi.h index ab68adc..3368fdf 100644 --- a/src/sys/mako_midi.h +++ b/src/sys/mako_midi.h @@ -3,7 +3,7 @@ #include #include -#include +#include #include "common.h" struct GameId; diff --git a/src/sys/mako_music.cpp b/src/sys/mako_music.cpp index 78273af..832037c 100644 --- a/src/sys/mako_music.cpp +++ b/src/sys/mako_music.cpp @@ -178,10 +178,9 @@ MakoMusic::MakoMusic(const std::string& path, int loops, const SDL_AudioSpec& de return; const SDL_AudioSpec& src_spec = decoder->spec(); - stream = SDL_NewAudioStream(src_spec.format, src_spec.channels, src_spec.freq, - device_spec.format, device_spec.channels, device_spec.freq); + stream = SDL_CreateAudioStream(&src_spec, &device_spec); if (!stream) { - WARNING("SDL_NewAudioStream failed: %s", SDL_GetError()); + WARNING("SDL_CreateAudioStream failed: %s", SDL_GetError()); return; } playing = true; @@ -227,7 +226,7 @@ void MakoMusic::mix(Uint8* out, int len) Uint8* tmp = SDL_stack_alloc(Uint8, len); int got = SDL_AudioStreamGet(stream, tmp, len); if (got > 0) - SDL_MixAudioFormat(out, tmp, AUDIO_S16SYS, got, SDL_MIX_MAXVOLUME); + SDL_MixAudioFormat(out, tmp, AUDIO_S16SYS, got, 1.0f); SDL_stack_free(tmp); if (input_finished && SDL_AudioStreamAvailable(stream) <= 0) playing = false; diff --git a/src/sys/mako_music.h b/src/sys/mako_music.h index 0c5a640..d88be05 100644 --- a/src/sys/mako_music.h +++ b/src/sys/mako_music.h @@ -3,7 +3,7 @@ #include #include -#include +#include class MakoMusicDecoder; diff --git a/src/sys/nact.cpp b/src/sys/nact.cpp index 6d47406..94d0767 100644 --- a/src/sys/nact.cpp +++ b/src/sys/nact.cpp @@ -69,17 +69,19 @@ NACT::NACT(const Config& config, const GameId& game_id) mako = new MAKO(config, game_id); msgskip = new MsgSkip(); - SDL_Init(SDL_INIT_GAMECONTROLLER); - for (int i = 0; i < SDL_NumJoysticks(); ++i) { - if (SDL_IsGameController(i)) { - sdl_gamecontroller = SDL_GameControllerOpen(i); + SDL_Init(SDL_INIT_GAMEPAD); + SDL_JoystickID* ids = SDL_GetJoysticks(nullptr); + for (int i = 0; ids && ids[i]; ++i) { + if (SDL_IsGamepad(ids[i])) { + sdl_gamecontroller = SDL_OpenGamepad(ids[i]); if (sdl_gamecontroller) { break; } else { - WARNING("Could not open gamecontroller %i: %s\n", i, SDL_GetError()); + WARNING("Could not open gamepad %i: %s\n", i, SDL_GetError()); } } } + SDL_free(ids); } NACT::~NACT() @@ -513,7 +515,7 @@ void NACT::message(uint8_t first_byte) void NACT::text_wait() { - Uint32 dwTime = SDL_GetTicks() + text_wait_time; + Uint64 dwTime = SDL_GetTicks() + text_wait_time; for(;;) { if(terminate) { return; diff --git a/src/sys/nact.h b/src/sys/nact.h index cc159bb..1456a1a 100644 --- a/src/sys/nact.h +++ b/src/sys/nact.h @@ -11,7 +11,7 @@ #include #include #include -#include +#include #include "common.h" #include "config.h" #include "dri.h" @@ -196,6 +196,10 @@ public: const char* get_string(int index) const { return tvar[index].c_str(); } void set_string(int index, const std::string& value) { tvar[index] = value; } +#ifdef _WIN32 + void handle_windows_event(MSG* msg); +#endif + private: void pump_events(); void handle_event(SDL_Event e); diff --git a/src/sys/nact_input.cpp b/src/sys/nact_input.cpp index b745b78..81eb3e2 100644 --- a/src/sys/nact_input.cpp +++ b/src/sys/nact_input.cpp @@ -8,7 +8,6 @@ #include #undef ERROR #endif -#include #include "nact.h" #include "ags.h" #include "texthook.h" @@ -21,9 +20,18 @@ enum TouchState { }; extern SDL_Window* g_window; +extern SDL_Renderer* g_renderer; static int mousex, mousey, wheel; static TouchState touch_state = TOUCH_NONE; +static int GetNumTouchFingers(SDL_TouchID touchID) +{ + int num = 0; + SDL_Finger** fingers = SDL_GetTouchFingers(touchID, &num); + SDL_free(fingers); + return num; +} + void NACT::handle_event(SDL_Event e) { if (handle_platform_event(e)) @@ -42,10 +50,13 @@ void NACT::handle_event(SDL_Event e) break; #endif - case SDL_MOUSEMOTION: - mousex = e.motion.x * ags->screen_width / ags->window_width; - mousey = e.motion.y * ags->screen_height / ags->window_height; + case SDL_MOUSEMOTION: { + float rx, ry; + SDL_RenderCoordinatesFromWindow(g_renderer, e.motion.x, e.motion.y, &rx, &ry); + mousex = rx * ags->screen_width / ags->window_width; + mousey = ry * ags->screen_height / ags->window_height; break; + } case SDL_MOUSEWHEEL: wheel += e.wheel.y * (e.wheel.direction == SDL_MOUSEWHEEL_FLIPPED ? -1 : 1); @@ -56,7 +67,7 @@ void NACT::handle_event(SDL_Event e) case SDL_FINGERMOTION: mousex = e.tfinger.x * ags->screen_width; mousey = e.tfinger.y * ags->screen_height; - switch (SDL_GetNumTouchFingers(e.tfinger.touchId)) { + switch (GetNumTouchFingers(e.tfinger.touchID)) { case 0: touch_state = TOUCH_NONE; break; @@ -115,7 +126,7 @@ uint8 NACT::get_key() pump_events(); // キーボード&マウス - const Uint8* key = SDL_GetKeyboardState(NULL); + const bool* key = SDL_GetKeyboardState(NULL); Uint32 mouse = SDL_GetMouseState(NULL, NULL); if(key[SDL_SCANCODE_UP ] || key[SDL_SCANCODE_KP_8 ] ) val |= 0x01; @@ -185,7 +196,7 @@ void NACT::show_quit_dialog() buttons, }; int buttonid = 0; - if (SDL_ShowMessageBox(&messagebox_data, &buttonid) < 0) { + if (!SDL_ShowMessageBox(&messagebox_data, &buttonid)) { WARNING("error displaying message box"); buttonid = 1; } diff --git a/src/sys/nact_sys1.cpp b/src/sys/nact_sys1.cpp index ea51ed2..79fd2c7 100644 --- a/src/sys/nact_sys1.cpp +++ b/src/sys/nact_sys1.cpp @@ -42,14 +42,14 @@ protected: void exec_y(int cmd, int param); void wait_impl(int tm) { - uint32_t dwTime = SDL_GetTicks() + tm; + Uint64 dwTime = SDL_GetTicks() + tm; while (!terminate && SDL_GetTicks() < dwTime) { sys_sleep(16); } } void wait_keyquit_impl(int tm) { - Uint32 dwTime = SDL_GetTicks() + tm; + Uint64 dwTime = SDL_GetTicks() + tm; while (!terminate) { if (get_key()) { while (!terminate) { diff --git a/src/sys/nact_sys2.cpp b/src/sys/nact_sys2.cpp index 1a2c217..9eb1552 100644 --- a/src/sys/nact_sys2.cpp +++ b/src/sys/nact_sys2.cpp @@ -47,14 +47,14 @@ protected: uint16 cali() override; void wait_impl(int tm) { - uint32_t dwTime = SDL_GetTicks() + tm; + Uint64 dwTime = SDL_GetTicks() + tm; while (!terminate && SDL_GetTicks() < dwTime) { sys_sleep(16); } } void wait_keyquit_impl(int tm) { - Uint32 dwTime = SDL_GetTicks() + tm; + Uint64 dwTime = SDL_GetTicks() + tm; while (!terminate) { if (get_key()) { while (!terminate) { @@ -712,7 +712,7 @@ void NACT_Sys2::cmd_y() break; case 3: { - Uint32 dwTime = SDL_GetTicks() + param * 1000 / 60; + Uint64 dwTime = SDL_GetTicks() + param * 1000 / 60; for(;;) { if(terminate) { return; diff --git a/src/sys/nact_sys3.cpp b/src/sys/nact_sys3.cpp index 2d4ddcc..0e123ab 100644 --- a/src/sys/nact_sys3.cpp +++ b/src/sys/nact_sys3.cpp @@ -746,7 +746,7 @@ void NACT_Sys3::exec_y(int cmd, int param) } else if(param == 10001) { wait_keydown = true; } else { - Uint32 dwTime = SDL_GetTicks() + param * 1000 / 60; + Uint64 dwTime = SDL_GetTicks() + param * 1000 / 60; for(;;) { if(terminate) { return; diff --git a/src/texthook.cpp b/src/texthook.cpp index d6aa845..f6ef72d 100644 --- a/src/texthook.cpp +++ b/src/texthook.cpp @@ -3,7 +3,7 @@ #include #include #include -#include +#include #include "common.h" #include "texthook.h" #ifdef __EMSCRIPTEN__ diff --git a/src/win/nact_win.cpp b/src/win/nact_win.cpp index 77e8cd3..b5d3e10 100644 --- a/src/win/nact_win.cpp +++ b/src/win/nact_win.cpp @@ -3,7 +3,6 @@ #undef ERROR #include #include "nact.h" -#include "SDL_syswm.h" #include "encoding.h" #include "ags.h" #include "mako.h" @@ -19,10 +18,13 @@ namespace { bool auto_copy_enabled = false; HWND get_hwnd(SDL_Window* window) { - SDL_SysWMinfo info; - SDL_VERSION(&info.version); - SDL_GetWindowWMInfo(window, &info); - return info.info.win.window; + return (HWND)SDL_GetPointerProperty( + SDL_GetWindowProperties(window), SDL_PROP_WINDOW_WIN32_HWND_POINTER, NULL); +} + +bool SDLCALL windows_message_hook(void* userdata, MSG* msg) { + static_cast(userdata)->handle_windows_event(msg); + return true; } void init_menu(bool mouse_move_enabled, const Config& config) @@ -139,7 +141,7 @@ void NACT::platform_initialize() init_menu(mouse_move_enabled, config); if (config.debugger_mode == DebuggerMode::CLI || (config.trace && config.debugger_mode != DebuggerMode::DAP)) init_console(game_id.sys_ver); - SDL_EventState(SDL_SYSWMEVENT, SDL_ENABLE); + SDL_SetWindowsMessageHook(windows_message_hook, this); } void NACT::platform_finalize() @@ -184,16 +186,15 @@ bool NACT::handle_platform_event(const SDL_Event& e) } return true; } - return false; } + return false; +} - if (e.type != SDL_SYSWMEVENT) - return false; - const SDL_SysWMmsg* msg = e.syswm.msg; - - switch (msg->msg.win.msg) { +void NACT::handle_windows_event(MSG* msg) +{ + switch (msg->message) { case WM_COMMAND: - switch (msg->msg.win.wParam) { + switch (msg->wParam) { case ID_SCREENSHOT: save_screenshot(ags); break; @@ -204,10 +205,10 @@ bool NACT::handle_platform_event(const SDL_Event& e) quit(0); break; case ID_SCREEN_WINDOW: - SDL_SetWindowFullscreen(g_window, 0); + SDL_SetWindowFullscreen(g_window, false); break; case ID_SCREEN_FULL: - SDL_SetWindowFullscreen(g_window, SDL_WINDOW_FULLSCREEN_DESKTOP); + SDL_SetWindowFullscreen(g_window, true); break; case ID_SCANLINE: ags->set_scanline_mode(!ags->get_scanline_mode()); @@ -245,5 +246,4 @@ bool NACT::handle_platform_event(const SDL_Event& e) } break; } - return true; }