mirror of
https://github.com/kichikuou/system3-sdl2.git
synced 2026-10-13 17:58:32 +03:00
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.
This commit is contained in:
@@ -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 ninja-build
|
||||
sudo apt install libsdl3-dev libsdl3-ttf-dev librtmidi-dev nlohmann-json3-dev ninja-build
|
||||
|
||||
- name: Build
|
||||
run: |
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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 }}
|
||||
|
||||
|
||||
+30
-27
@@ -56,7 +56,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)
|
||||
@@ -92,20 +94,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
|
||||
@@ -127,29 +129,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}$<SEMICOLON>${SDL2TTF_LIBDIR}$<SEMICOLON>$ENV{PATH}")
|
||||
VS_DEBUGGER_ENVIRONMENT "PATH=${SDL3_LIBDIR}$<SEMICOLON>${SDL3TTF_LIBDIR}$<SEMICOLON>$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
|
||||
$<LINK_GROUP:RESCAN,${SDL2TTF_STATIC_LIBRARIES}>)
|
||||
set_property(TARGET sdl3_ttf PROPERTY INTERFACE_LINK_LIBRARIES
|
||||
$<LINK_GROUP:RESCAN,${SDL3TTF_STATIC_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)
|
||||
@@ -177,7 +179,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()
|
||||
@@ -261,6 +262,8 @@ 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)
|
||||
|
||||
if (BUILD_TESTING AND NOT ANDROID AND NOT EMSCRIPTEN AND NOT NINTENDO_SWITCH)
|
||||
|
||||
+3
-3
@@ -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
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
#include "debugger/frontend.h"
|
||||
#include <algorithm>
|
||||
#include <queue>
|
||||
#include <SDL.h>
|
||||
#include <SDL3/SDL.h>
|
||||
#include "nlohmann/json.hpp"
|
||||
#include "common.h"
|
||||
#include "encoding.h"
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
*/
|
||||
|
||||
#include <memory>
|
||||
#include <SDL.h>
|
||||
#include <SDL3/SDL.h>
|
||||
#include <emscripten.h>
|
||||
#include "mako.h"
|
||||
#include "fm/mako_ymfm.h"
|
||||
|
||||
+63
-52
@@ -8,7 +8,7 @@
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <limits.h>
|
||||
#include <SDL.h>
|
||||
#include <SDL3/SDL.h>
|
||||
|
||||
#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<MakoMusic> 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<Uint8*>(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<Uint8*>(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<MAKOMidi>(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<MakoMusic>(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<uint8_t> data = amus.load(page);
|
||||
if (data.empty())
|
||||
return;
|
||||
auto f = std::make_unique<MakoYmfm>(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<MakoMusic> old_music = std::move(music);
|
||||
std::unique_ptr<MakoYmfm> 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;
|
||||
}
|
||||
|
||||
|
||||
+2
-1
@@ -1,9 +1,10 @@
|
||||
#include <limits.h>
|
||||
#include <stdio.h>
|
||||
#ifdef _WIN32
|
||||
#include <windows.h>
|
||||
#undef ERROR
|
||||
#endif
|
||||
#include <SDL.h>
|
||||
#include <SDL3/SDL.h>
|
||||
#include "common.h"
|
||||
|
||||
SDL_RWops* open_resource(const char* name, const char* type) {
|
||||
|
||||
+4
-4
@@ -1,3 +1,4 @@
|
||||
#include <SDL3/SDL_main.h>
|
||||
#include <string>
|
||||
#include "common.h"
|
||||
#include "config.h"
|
||||
@@ -35,7 +36,6 @@ SDL_Window* create_window(const Config& config, 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
|
||||
@@ -48,7 +48,7 @@ SDL_Window* create_window(const Config& config, const GameId& game_id)
|
||||
SDL_SetHint(SDL_HINT_ORIENTATIONS, "LandscapeLeft LandscapeRight");
|
||||
Uint32 flags = SDL_WINDOW_FULLSCREEN;
|
||||
#else
|
||||
Uint32 flags = config.fullscreen ? SDL_WINDOW_FULLSCREEN_DESKTOP : SDL_WINDOW_RESIZABLE;
|
||||
Uint32 flags = config.fullscreen ? SDL_WINDOW_FULLSCREEN : SDL_WINDOW_RESIZABLE;
|
||||
#endif
|
||||
|
||||
#ifdef __EMSCRIPTEN__
|
||||
@@ -57,7 +57,7 @@ SDL_Window* create_window(const Config& config, 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(config, 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 初期化
|
||||
|
||||
+21
-21
@@ -20,7 +20,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<uint32*>(surface_line(sf, y));
|
||||
uint32 v = y % 2 ? (SCANLINE_ALPHA << 24) : 0;
|
||||
@@ -49,18 +49,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
|
||||
for(int i = 0; i < NR_SCREENS; 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<uint8_t(*)[640]>(hBmpScreen[i]->pixels);
|
||||
}
|
||||
|
||||
// All surfaces share the same palette.
|
||||
screen_palette = hBmpScreen[SCREEN_FRONT]->format->palette;
|
||||
screen_palette = SDL_CreateSurfacePalette(hBmpScreen[SCREEN_FRONT]);
|
||||
SDL_SetSurfacePalette(hBmpScreen[SCREEN_BACK], screen_palette);
|
||||
|
||||
if (!config.censor_list.empty())
|
||||
@@ -77,17 +77,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);
|
||||
@@ -279,8 +279,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;
|
||||
@@ -288,7 +288,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);
|
||||
@@ -298,7 +298,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);
|
||||
}
|
||||
|
||||
@@ -314,18 +314,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[SCREEN_FRONT], 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);
|
||||
|
||||
+1
-1
@@ -16,7 +16,7 @@
|
||||
#include "game_id.h"
|
||||
#include "cg.h"
|
||||
#include "dri.h"
|
||||
#include <SDL_ttf.h>
|
||||
#include <SDL3_ttf/SDL_ttf.h>
|
||||
|
||||
struct Config;
|
||||
|
||||
|
||||
+4
-23
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -160,10 +160,10 @@ void AGS::copy_screen(ScreenId src, ScreenId dest, int sx, int sy, int ex, int e
|
||||
|
||||
SDL_Surface* src_surface = hBmpScreen[src];
|
||||
if (transparent_color >= 0)
|
||||
SDL_SetColorKey(src_surface, SDL_TRUE, transparent_color);
|
||||
SDL_SetSurfaceColorKey(src_surface, true, transparent_color);
|
||||
SDL_BlitSurface(src_surface, &srcrect, hBmpScreen[dest], &destrect);
|
||||
if (transparent_color >= 0)
|
||||
SDL_SetColorKey(src_surface, SDL_FALSE, 0);
|
||||
SDL_SetSurfaceColorKey(src_surface, false, 0);
|
||||
|
||||
if (dest == SCREEN_FRONT)
|
||||
invalidate_screen(dx, dy, width, height);
|
||||
|
||||
@@ -30,8 +30,8 @@ int AGS::draw_text(ScreenId dest, int x, int y, std::u16string_view codes, int f
|
||||
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.
|
||||
int dest_y = y - (ascent - descent - font_size) / 2;
|
||||
|
||||
@@ -49,7 +49,7 @@ int AGS::draw_text(ScreenId dest, int x, int y, std::u16string_view codes, int f
|
||||
draw_char(dest, dest_x, dest_y, code, 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;
|
||||
|
||||
+1
-1
@@ -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;
|
||||
|
||||
+6
-4
@@ -8,7 +8,7 @@
|
||||
#define _CG_H_
|
||||
|
||||
#include <memory>
|
||||
#include <SDL.h>
|
||||
#include <SDL3/SDL.h>
|
||||
#include "common.h"
|
||||
|
||||
inline uint8_t* surface_line(SDL_Surface* surface, int y)
|
||||
@@ -29,14 +29,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<bool>(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()); }
|
||||
};
|
||||
|
||||
#endif // _CG_H_
|
||||
|
||||
+5
-5
@@ -7,7 +7,7 @@
|
||||
#include "dri.h"
|
||||
#include <memory>
|
||||
#include <string.h>
|
||||
#include <SDL.h>
|
||||
#include <SDL3/SDL.h>
|
||||
#include "game_id.h"
|
||||
#include "fileio.h"
|
||||
|
||||
@@ -191,7 +191,7 @@ std::vector<uint8> 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);
|
||||
|
||||
@@ -202,7 +202,7 @@ std::vector<uint8> 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];
|
||||
@@ -287,7 +287,7 @@ std::vector<uint8> 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);
|
||||
|
||||
@@ -299,7 +299,7 @@ std::vector<uint8> Dri::load_mda(const GameId& game_id, int page)
|
||||
}
|
||||
std::vector<uint8_t> 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);
|
||||
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
#include <string.h>
|
||||
#include <SDL.h>
|
||||
#include <SDL3/SDL.h>
|
||||
#include "game_id.h"
|
||||
#include "fileio.h"
|
||||
#include "config.h"
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
#include <SDL.h>
|
||||
#include <SDL3/SDL.h>
|
||||
#include <RtMidi.h>
|
||||
|
||||
#include "mako_midi.h"
|
||||
|
||||
+1
-1
@@ -3,7 +3,7 @@
|
||||
|
||||
#include <memory>
|
||||
#include <queue>
|
||||
#include <SDL.h>
|
||||
#include <SDL3/SDL.h>
|
||||
#include "common.h"
|
||||
|
||||
struct GameId;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <SDL.h>
|
||||
#include <SDL3/SDL.h>
|
||||
|
||||
class MakoMusicDecoder;
|
||||
|
||||
|
||||
+8
-6
@@ -79,17 +79,19 @@ NACT::NACT(const Config& config, const GameId& game_id)
|
||||
init_windows();
|
||||
init_text();
|
||||
|
||||
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()
|
||||
@@ -526,7 +528,7 @@ void NACT::text_wait()
|
||||
if (msgskip->skipping())
|
||||
return;
|
||||
|
||||
Uint32 dwTime = SDL_GetTicks() + text_wait_time;
|
||||
Uint64 dwTime = SDL_GetTicks() + text_wait_time;
|
||||
while (!terminate) {
|
||||
if (get_key(false) && wait_keydown)
|
||||
break;
|
||||
|
||||
+5
-1
@@ -14,7 +14,7 @@
|
||||
#include <string_view>
|
||||
#include <vector>
|
||||
#include <stdio.h>
|
||||
#include <SDL.h>
|
||||
#include <SDL3/SDL.h>
|
||||
#include "common.h"
|
||||
#include "config.h"
|
||||
#include "cg.h"
|
||||
@@ -285,6 +285,10 @@ protected:
|
||||
// helpers
|
||||
bool is_message(uint8_t c) { return c == ' ' || c & 0x80; }
|
||||
|
||||
#ifdef _WIN32
|
||||
void handle_windows_event(MSG* msg);
|
||||
#endif
|
||||
|
||||
private:
|
||||
std::u16string decode_text(std::string_view string);
|
||||
|
||||
|
||||
@@ -666,8 +666,7 @@ private:
|
||||
sheet_x, sheet_y, width, height, cg.width(), cg.height());
|
||||
return std::nullopt;
|
||||
}
|
||||
SDL_SetColorKey(cg.surface(), transparent ? SDL_TRUE : SDL_FALSE,
|
||||
TRANSPARENT_COLOR);
|
||||
SDL_SetSurfaceColorKey(cg.surface(), transparent, TRANSPARENT_COLOR);
|
||||
return SDL_Rect{ sheet_x, sheet_y, width, height };
|
||||
}
|
||||
|
||||
@@ -1472,7 +1471,7 @@ private:
|
||||
get_cursor(&seen_x, &seen_y);
|
||||
// Hides the system pointer and draws the cursor at (cx, cy) instead.
|
||||
auto show_cursor = [&] {
|
||||
SDL_ShowCursor(SDL_DISABLE);
|
||||
SDL_HideCursor();
|
||||
draw_mouse_cursor(shape, cx, cy);
|
||||
cursor_drawn = true;
|
||||
};
|
||||
@@ -1481,7 +1480,7 @@ private:
|
||||
auto hide_cursor = [&] {
|
||||
if (!cursor_drawn)
|
||||
return;
|
||||
SDL_ShowCursor(SDL_ENABLE);
|
||||
SDL_ShowCursor();
|
||||
ags->copy_screen(SCREEN_BACK, SCREEN_FRONT, cx, cy, cx + MOUSE_CURSOR_SIZE - 1,
|
||||
cy + MOUSE_CURSOR_SIZE - 1, cx, cy);
|
||||
cursor_drawn = false;
|
||||
|
||||
+18
-7
@@ -8,7 +8,6 @@
|
||||
#include <windows.h>
|
||||
#undef ERROR
|
||||
#endif
|
||||
#include <SDL_syswm.h>
|
||||
#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;
|
||||
@@ -116,7 +127,7 @@ uint8 NACT::get_key(bool notify_texthook)
|
||||
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;
|
||||
@@ -186,7 +197,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;
|
||||
}
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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) {
|
||||
@@ -705,7 +705,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;
|
||||
|
||||
@@ -691,7 +691,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;
|
||||
|
||||
+1
-1
@@ -3,7 +3,7 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <SDL.h>
|
||||
#include <SDL3/SDL.h>
|
||||
#include "common.h"
|
||||
#include "texthook.h"
|
||||
#ifdef __EMSCRIPTEN__
|
||||
|
||||
+16
-16
@@ -3,7 +3,6 @@
|
||||
#undef ERROR
|
||||
#include <time.h>
|
||||
#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<NACT*>(userdata)->handle_windows_event(msg);
|
||||
return true;
|
||||
}
|
||||
|
||||
void init_menu(bool mouse_move_enabled, const Config& config)
|
||||
@@ -146,7 +148,7 @@ void NACT::platform_initialize()
|
||||
{
|
||||
init_menu(mouse_move_enabled, config);
|
||||
init_console(config, game_id.sys_ver);
|
||||
SDL_EventState(SDL_SYSWMEVENT, SDL_ENABLE);
|
||||
SDL_SetWindowsMessageHook(windows_message_hook, this);
|
||||
}
|
||||
|
||||
void NACT::platform_finalize()
|
||||
@@ -191,16 +193,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;
|
||||
@@ -211,10 +212,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());
|
||||
@@ -252,5 +253,4 @@ bool NACT::handle_platform_event(const SDL_Event& e)
|
||||
}
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user