diff --git a/CMakeLists.txt b/CMakeLists.txt index f919c860f..6daa765e4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -94,7 +94,7 @@ endif() find_package(ZLIB REQUIRED) find_package(PNG REQUIRED) -find_package(SDL2 CONFIG REQUIRED) +find_package(SDL3 CONFIG REQUIRED) find_package(CURL REQUIRED) find_package(Opus REQUIRED) if(WIN32 AND NOT MINGW) diff --git a/cmake/Modules/FindSDL2.cmake b/cmake/Modules/FindSDL2.cmake deleted file mode 100644 index 2d625f84c..000000000 --- a/cmake/Modules/FindSDL2.cmake +++ /dev/null @@ -1,43 +0,0 @@ -# Find SDL2 -# Once done, this will define -# -# SDL2_FOUND - system has SDL2 -# SDL2_INCLUDE_DIRS - SDL2 include directories -# SDL2_LIBRARIES - link libraries - -include(LibFindMacros) - -libfind_pkg_check_modules(SDL2_PKGCONF SDL2) - -# includes -find_path(SDL2_INCLUDE_DIR - NAMES SDL.h - PATHS - ${SDL2_PKGCONF_INCLUDE_DIRS} - "/usr/include/SDL2" - "/usr/local/include/SDL2" -) - -# library -find_library(SDL2_LIBRARY - NAMES SDL2 - PATHS - ${SDL2_PKGCONF_LIBRARY_DIRS} - "/usr/lib" - "/usr/local/lib" -) - -# set include dir variables -set(SDL2_PROCESS_INCLUDES SDL2_INCLUDE_DIR) -set(SDL2_PROCESS_LIBS SDL2_LIBRARY) -libfind_process(SDL2) - -if(SDL2_FOUND AND NOT TARGET SDL2::SDL2) - add_library(SDL2::SDL2 UNKNOWN IMPORTED) - set_target_properties( - SDL2::SDL2 - PROPERTIES - IMPORTED_LOCATION "${SDL2_LIBRARY}" - INTERFACE_INCLUDE_DIRECTORIES "${SDL2_INCLUDE_DIR}" - ) -endif() diff --git a/cmake/Modules/FindSDL2_main.cmake b/cmake/Modules/FindSDL2_main.cmake deleted file mode 100644 index d4cbdeb11..000000000 --- a/cmake/Modules/FindSDL2_main.cmake +++ /dev/null @@ -1,34 +0,0 @@ -# Find SDL2 -# Once done, this will define -# -# SDL2_MAIN_FOUND - system has SDL2 -# SDL2_MAIN_INCLUDE_DIRS - SDL2 include directories -# SDL2_MAIN_LIBRARIES - link libraries - -include(LibFindMacros) - -libfind_pkg_check_modules(SDL2_MAIN_PKGCONF SDL2) - -# includes -find_path(SDL2_MAIN_INCLUDE_DIR - NAMES SDL.h - PATHS - ${SDL2_MAIN_PKGCONF_INCLUDE_DIRS} - "/usr/include/SDL2" - "/usr/local/include/SDL2" -) - -# library -find_library(SDL2_MAIN_LIBRARY - NAMES SDL2_main - PATHS - ${SDL2_MAIN_PKGCONF_LIBRARY_DIRS} - "/usr/lib" - "/usr/local/lib" -) - - -# set include dir variables -set(SDL2_MAIN_PROCESS_INCLUDES SDL2_MAIN_INCLUDE_DIR) -set(SDL2_MAIN_PROCESS_LIBS SDL2_MAIN_LIBRARY) -libfind_process(SDL2_MAIN) diff --git a/src/doomtype.h b/src/doomtype.h index 4c661a662..91789fc07 100644 --- a/src/doomtype.h +++ b/src/doomtype.h @@ -50,7 +50,6 @@ extern "C" { #define SINT8 int8_t #ifdef __APPLE_CC__ -#define DIRECTFULLSCREEN 1 #define DEBUG_LOG #define NOIPX #endif @@ -138,12 +137,16 @@ typedef int32_t boolean; #ifndef __cplusplus #ifndef _WIN32 +#ifndef false // SDL3 workaround enum {false = 0, true = 1}; +#endif #else +#ifndef false // SDL3 workaround #define false FALSE #define true TRUE #endif #endif +#endif /* 7.18.2.1 Limits of exact-width integer types */ diff --git a/src/f_wipe.cpp b/src/f_wipe.cpp index 7562d3cad..09bfecde0 100644 --- a/src/f_wipe.cpp +++ b/src/f_wipe.cpp @@ -500,6 +500,11 @@ void F_RunWipe(UINT8 wipemode, UINT8 wipetype, boolean drawMenu, const char *col rhi::Rhi* rhi = srb2::sys::get_rhi(srb2::sys::g_current_rhi); hwr2::HardwareState* hw_state = srb2::sys::main_hardware_state(); + if (!rhi) + { + break; + } + if (reverse) { hw_state->wipe->set_start(hw_state->wipe_frames.end); diff --git a/src/hardware/r_opengl/r_opengl.h b/src/hardware/r_opengl/r_opengl.h index a15f2854a..2f2148b32 100644 --- a/src/hardware/r_opengl/r_opengl.h +++ b/src/hardware/r_opengl/r_opengl.h @@ -21,7 +21,7 @@ #pragma warning(disable : 4214 4244) #endif -#include "SDL_opengl.h" //Alam_GBC: Simple, yes? +#include //Alam_GBC: Simple, yes? #ifdef _MSC_VER #pragma warning(default : 4214 4244) diff --git a/src/screen.c b/src/screen.c index 67b8f13fb..f24f8692a 100644 --- a/src/screen.c +++ b/src/screen.c @@ -429,7 +429,6 @@ void SCR_SetDefaultMode(void) void SCR_ChangeFullscreen(void); void SCR_ChangeFullscreen(void) { -#ifdef DIRECTFULLSCREEN // allow_fullscreen is set by VID_PrepareModeList // it is used to prevent switching to fullscreen during startup if (!allow_fullscreen) @@ -441,7 +440,6 @@ void SCR_ChangeFullscreen(void) setmodeneeded = VID_GetModeForSize(vid.width, vid.height) + 1; } return; -#endif } void SCR_ChangeRenderer(void) diff --git a/src/sdl/CMakeLists.txt b/src/sdl/CMakeLists.txt index d6f32a67c..06df94258 100644 --- a/src/sdl/CMakeLists.txt +++ b/src/sdl/CMakeLists.txt @@ -1,4 +1,4 @@ -# Declare SDL2 interface sources +# Declare SDL3 interface sources target_sources(SRB2SDL2 PRIVATE new_sound.cpp @@ -15,11 +15,6 @@ target_sources(SRB2SDL2 PRIVATE hwsym_sdl.c ) -if(${SRB2_USEASM}) - set_source_files_properties(${SRB2_ASM_SOURCES} PROPERTIES LANGUAGE C) - set_source_files_properties(${SRB2_ASM_SOURCES} PROPERTIES COMPILE_FLAGS "-x assembler-with-cpp") -endif() - if("${CMAKE_SYSTEM_NAME}" MATCHES Windows) target_sources(SRB2SDL2 PRIVATE ../win32/win_dbg.c @@ -60,25 +55,13 @@ endif() target_link_libraries(SRB2SDL2 PRIVATE - $,SDL2::SDL2,SDL2::SDL2-static> + $,SDL3::SDL3,SDL3::SDL3-static> ) if("${CMAKE_SYSTEM_NAME}" MATCHES Linux) target_link_libraries(SRB2SDL2 PRIVATE m rt) endif() -if(${SRB2_USEASM}) - if(${SRB2_CONFIG_YASM}) - set(ASM_ASSEMBLER_TEMP ${CMAKE_ASM_YASM_COMPILER}) - set(ASM_ASSEMBLER_OBJFORMAT ${CMAKE_ASM_YASM_OBJECT_FORMAT}) - set_source_files_properties(${SRB2_NASM_SOURCES} LANGUAGE ASM_YASM) - else() - set(ASM_ASSEMBLER_TEMP ${CMAKE_ASM_NASM_COMPILER}) - set(ASM_ASSEMBLER_OBJFORMAT ${CMAKE_ASM_NASM_OBJECT_FORMAT}) - set_source_files_properties(${SRB2_NASM_SOURCES} LANGUAGE ASM_NASM) - endif() -endif() - if("${CMAKE_SYSTEM_NAME}" MATCHES Windows) target_link_libraries(SRB2SDL2 PRIVATE ws2_32 @@ -88,8 +71,7 @@ if("${CMAKE_SYSTEM_NAME}" MATCHES Windows) # ) endif() -target_compile_definitions(SRB2SDL2 PRIVATE -DHAVE_MIXER -DSOUND=SOUND_MIXER) -target_compile_definitions(SRB2SDL2 PRIVATE -DDIRECTFULLSCREEN -DHAVE_SDL) +target_compile_definitions(SRB2SDL2 PRIVATE -DHAVE_SDL -DHAVE_SDL3) #### Installation #### if("${CMAKE_SYSTEM_NAME}" MATCHES Darwin) @@ -131,5 +113,3 @@ if("${CMAKE_SYSTEM_NAME}" MATCHES Darwin) )" ) endif() - -set(SRB2_SDL2_AVAILABLE YES PARENT_SCOPE) diff --git a/src/sdl/IMG_xpm.c b/src/sdl/IMG_xpm.c index 458131620..b6aac4639 100644 --- a/src/sdl/IMG_xpm.c +++ b/src/sdl/IMG_xpm.c @@ -42,21 +42,15 @@ * requires about 13K in binary form. */ -#if 0 -#include "SDL_image.h" -#else // SDLCALL terms removed from original SDL_image declarations -int IMG_isXPM(SDL_RWops *src); -SDL_Surface *IMG_LoadXPM_RW(SDL_RWops *src); +int IMG_isXPM(SDL_IOStream *src); +SDL_Surface *IMG_LoadXPM_IO(SDL_IOStream *src); SDL_Surface *IMG_ReadXPMFromArray(const char **xpm); #define IMG_SetError SDL_SetError #define IMG_GetError SDL_GetError -#endif - -#ifdef LOAD_XPM /* See if an image is contained in a data source */ -int IMG_isXPM(SDL_RWops *src) +int IMG_isXPM(SDL_IOStream *src) { Sint64 start; int is_XPM; @@ -64,14 +58,14 @@ int IMG_isXPM(SDL_RWops *src) if ( !src ) return 0; - start = SDL_RWtell(src); + start = SDL_TellIO(src); is_XPM = 0; - if ( SDL_RWread(src, magic, sizeof(magic), 1) ) { + if ( SDL_ReadIO(src, magic, sizeof(magic)) ) { if ( SDL_memcmp(magic, "/* XPM */", sizeof(magic)) == 0 ) { is_XPM = 1; } } - SDL_RWseek(src, start, RW_SEEK_SET); + SDL_SeekIO(src, start, SDL_IO_SEEK_SET); return(is_XPM); } @@ -933,7 +927,7 @@ static const char *error; * If len > 0, it's assumed to be at least len chars (for efficiency). * Return NULL and set error upon EOF or parse error. */ -static const char *get_next_line(const char ***lines, SDL_RWops *src, int len) +static const char *get_next_line(const char ***lines, SDL_IOStream *src, int len) { char *linebufnew; @@ -943,7 +937,7 @@ static const char *get_next_line(const char ***lines, SDL_RWops *src, int len) char c; int n; do { - if (SDL_RWread(src, &c, 1, 1) <= 0) { + if (SDL_ReadIO(src, &c, 1) <= 0) { error = "Premature end of data"; return NULL; } @@ -960,7 +954,7 @@ static const char *get_next_line(const char ***lines, SDL_RWops *src, int len) } linebuf = linebufnew; } - if (SDL_RWread(src, linebuf, len - 1, 1) <= 0) { + if (SDL_ReadIO(src, linebuf, len - 1) <= 0) { error = "Premature end of data"; return NULL; } @@ -980,7 +974,7 @@ static const char *get_next_line(const char ***lines, SDL_RWops *src, int len) } linebuf = linebufnew; } - if (SDL_RWread(src, linebuf + n, 1, 1) <= 0) { + if (SDL_ReadIO(src, linebuf + n, 1) <= 0) { error = "Premature end of data"; return NULL; } @@ -1005,7 +999,7 @@ do { \ } while (0) /* read XPM from either array or RWops */ -static SDL_Surface *load_xpm(const char **xpm, SDL_RWops *src) +static SDL_Surface *load_xpm(const char **xpm, SDL_IOStream *src) { Sint64 start = 0; SDL_Surface *image = NULL; @@ -1027,7 +1021,7 @@ static SDL_Surface *load_xpm(const char **xpm, SDL_RWops *src) buflen = 0; if (src) - start = SDL_RWtell(src); + start = SDL_TellIO(src); if (xpm) xpmlines = &xpm; @@ -1065,14 +1059,13 @@ static SDL_Surface *load_xpm(const char **xpm, SDL_RWops *src) /* Create the new surface */ if (ncolors <= 256) { indexed = 1; - image = SDL_CreateRGBSurface(SDL_SWSURFACE, w, h, 8, - 0, 0, 0, 0); - im_colors = image->format->palette->colors; - image->format->palette->ncolors = ncolors; + image = SDL_CreateSurface(w, h, SDL_PIXELFORMAT_INDEX8); + SDL_Palette* palette = SDL_CreateSurfacePalette(image); + im_colors = palette->colors; + SDL_GetSurfacePalette(image)->ncolors = ncolors; } else { indexed = 0; - image = SDL_CreateRGBSurface(SDL_SWSURFACE, w, h, 32, - 0xff0000, 0x00ff00, 0x0000ff, 0); + image = SDL_CreateSurface(w, h, SDL_GetPixelFormatForMasks(32, 0xff0000, 0x00ff00, 0x0000ff, 0)); } if (!image) { /* Hmm, some SDL error (out of memory?) */ @@ -1128,7 +1121,7 @@ static SDL_Surface *load_xpm(const char **xpm, SDL_RWops *src) add_colorhash(colors, nextkey, cpp, pixel); nextkey += cpp; if (rgb == 0xffffffff) - SDL_SetColorKey(image, SDL_TRUE, pixel); + SDL_SetSurfaceColorKey(image, true, pixel); break; } } @@ -1164,9 +1157,9 @@ static SDL_Surface *load_xpm(const char **xpm, SDL_RWops *src) done: if (error) { if ( src ) - SDL_RWseek(src, start, RW_SEEK_SET); + SDL_SeekIO(src, start, SDL_IO_SEEK_SET); if ( image ) { - SDL_FreeSurface(image); + SDL_DestroySurface(image); image = NULL; } IMG_SetError("%s", error); @@ -1180,7 +1173,7 @@ done: } /* Load a XPM type image from an RWops datasource */ -SDL_Surface *IMG_LoadXPM_RW(SDL_RWops *src) +SDL_Surface *IMG_LoadXPM_RW(SDL_IOStream *src) { if ( !src ) { /* The error message has been set in SDL_RWFromFile */ @@ -1197,24 +1190,3 @@ SDL_Surface *IMG_ReadXPMFromArray(const char **xpm) } return load_xpm(xpm, NULL); } - -#else /* not LOAD_XPM */ - -/* See if an image is contained in a data source */ -int IMG_isXPM(SDL_RWops *src) -{ - return(0); -} - - -/* Load a XPM type image from an SDL datasource */ -SDL_Surface *IMG_LoadXPM_RW(SDL_RWops *src) -{ - return(NULL); -} - -SDL_Surface *IMG_ReadXPMFromArray(const char **xpm) -{ - return NULL; -} -#endif /* not LOAD_XPM */ diff --git a/src/sdl/hwsym_sdl.c b/src/sdl/hwsym_sdl.c index e9c73891d..b1e75786d 100644 --- a/src/sdl/hwsym_sdl.c +++ b/src/sdl/hwsym_sdl.c @@ -26,14 +26,14 @@ #ifdef HAVE_SDL -#include "SDL.h" +#include #ifdef _MSC_VER #pragma warning(default : 4214 4244) #endif #ifndef NOLOADSO -#include "SDL_loadso.h" +#include #endif #define _CREATE_DLL_ // necessary for Unix AND Windows @@ -138,7 +138,7 @@ void *hwSym(const char *funcName,void *handle) funcPointer = handle; #else else if (handle) - funcPointer = SDL_LoadFunction(handle,funcName); + funcPointer = (void*)SDL_LoadFunction(handle,funcName); #endif if (!funcPointer) I_OutputMsg("hwSym for %s: %s\n", funcName, SDL_GetError()); diff --git a/src/sdl/i_main.cpp b/src/sdl/i_main.cpp index 0566eb146..171256a4c 100644 --- a/src/sdl/i_main.cpp +++ b/src/sdl/i_main.cpp @@ -1,6 +1,6 @@ // DR. ROBOTNIK'S RING RACERS //----------------------------------------------------------------------------- -// Copyright (C) 2025 by Kart Krew. +// Copyright (C) 2026 by Kart Krew. // Copyright (C) 2020 by Sonic Team Junior. // Copyright (C) 2000 by DooM Legacy Team. // Copyright (C) 1996 by id Software, Inc. @@ -12,6 +12,9 @@ /// \file /// \brief Main program, simply calls D_SRB2Main and D_SRB2Loop, the high level loop. +#include +#include + #include "../doomdef.h" #include "../m_argv.h" #include "../d_main.h" @@ -31,22 +34,7 @@ #include #endif -#include "time.h" // For log timestamps - -#ifdef HAVE_TTF -#include "SDL.h" -#include "i_ttf.h" -#endif - -#if defined (_WIN32) && !defined (main) -//#define SDLMAIN -#endif - -#ifdef SDLMAIN -#include "SDL_main.h" -#elif defined(FORCESDLMAIN) -extern int SDL_main(int argc, char *argv[]); -#endif +#include // For log timestamps #ifdef LOGMESSAGES FILE *logstream = NULL; @@ -221,11 +209,7 @@ static void walk_exception_stack(srb2::String& accum, const std::exception& ex, #pragma GCC diagnostic ignored "-Wmissing-noreturn" #endif -#ifdef FORCESDLMAIN -int SDL_main(int argc, char **argv) -#else int main(int argc, char **argv) -#endif { myargc = argc; myargv = argv; /// \todo pull out path to exe from this string @@ -234,9 +218,9 @@ int main(int argc, char **argv) #ifdef HAVE_TTF #ifdef _WIN32 - I_StartupTTF(FONTPOINTSIZE, SDL_INIT_VIDEO|SDL_INIT_AUDIO, SDL_SWSURFACE); + I_StartupTTF(FONTPOINTSIZE, SDL_INIT_VIDEO|SDL_INIT_AUDIO, 0); #else - I_StartupTTF(FONTPOINTSIZE, SDL_INIT_VIDEO, SDL_SWSURFACE); + I_StartupTTF(FONTPOINTSIZE, SDL_INIT_VIDEO, 0); #endif #endif @@ -291,13 +275,6 @@ int main(int argc, char **argv) return 0; } -#ifdef _MSC_VER -int WINAPI WinMain(HINSTANCE pInstance, HINSTANCE pPrevInstance, LPSTR lpCmdLine, int nShowCmd) -{ - return main(__argc, __argv); -} -#endif - void* operator new(size_t count) { auto p = malloc(count); diff --git a/src/sdl/i_net.c b/src/sdl/i_net.c index c297f52a4..422c82efc 100644 --- a/src/sdl/i_net.c +++ b/src/sdl/i_net.c @@ -31,7 +31,7 @@ #ifdef HAVE_SDLNET -#include "SDL_net.h" +#include #define MAXBANS 20 diff --git a/src/sdl/i_system.cpp b/src/sdl/i_system.cpp index 7c5aef985..d63daa9f6 100644 --- a/src/sdl/i_system.cpp +++ b/src/sdl/i_system.cpp @@ -69,7 +69,7 @@ typedef LPVOID (WINAPI *p_MapViewOfFile) (HANDLE, DWORD, DWORD, DWORD, SIZE_T); #ifdef HAVE_SDL #define _MATH_DEFINES_DEFINED -#include "SDL.h" +#include #ifdef HAVE_TTF #include "i_ttf.h" @@ -79,7 +79,7 @@ typedef LPVOID (WINAPI *p_MapViewOfFile) (HANDLE, DWORD, DWORD, DWORD, SIZE_T); #pragma warning(default : 4214 4244) #endif -#include "SDL_cpuinfo.h" +#include #define HAVE_SDLCPUINFO #if defined (__unix__) || defined(__APPLE__) || (defined (UNIXCOMMON) && !defined (__HAIKU__)) @@ -216,8 +216,8 @@ static std::thread::id g_main_thread_id; */ SDLJoyInfo_t JoyInfo[MAXSPLITSCREENPLAYERS]; -SDL_bool consolevent = SDL_FALSE; -SDL_bool framebuffer = SDL_FALSE; +bool consolevent = false; +bool framebuffer = false; UINT8 keyboard_started = false; boolean g_in_exiting_signal_handler = false; @@ -649,7 +649,7 @@ FUNCNORETURN static ATTRNORETURN void quit_handler(int num) #ifdef HAVE_TERMIOS // TERMIOS console code from Quake3: thank you! -SDL_bool stdin_active = SDL_TRUE; +bool stdin_active = true; typedef struct { @@ -755,7 +755,7 @@ static void I_ShutdownConsole(void) if (consolevent) { I_OutputMsg("Shutdown tty console\n"); - consolevent = SDL_FALSE; + consolevent = false; tcsetattr (STDIN_FILENO, TCSADRAIN, &tty_tc); } } @@ -770,18 +770,18 @@ static void I_StartupConsole(void) signal(SIGTTIN, SIG_IGN); signal(SIGTTOU, SIG_IGN); - consolevent = static_cast(!M_CheckParm("-noconsole")); - framebuffer = static_cast(M_CheckParm("-framebuffer")); + consolevent = static_cast(!M_CheckParm("-noconsole")); + framebuffer = static_cast(M_CheckParm("-framebuffer")); if (framebuffer) - consolevent = SDL_FALSE; + consolevent = false; if (!consolevent) return; if (isatty(STDIN_FILENO)!=1) { I_OutputMsg("stdin is not a tty, tty console mode failed\n"); - consolevent = SDL_FALSE; + consolevent = false; return; } memset(&tty_con, 0x00, sizeof(tty_con)); @@ -959,7 +959,7 @@ static void I_StartupConsole(void) if (gotConsole) { SetConsoleTitleA("Dr. Robotnik's Ring Racers Console"); - consolevent = SDL_TRUE; + consolevent = true; } //Let get the real console HANDLE, because Mingw's Bash is bad! @@ -984,15 +984,15 @@ void I_GetConsoleEvents(void){} static inline void I_StartupConsole(void) { #ifdef _DEBUG - consolevent = M_CheckParm("-noconsole") > 0 ? SDL_FALSE : SDL_TRUE; + consolevent = M_CheckParm("-noconsole") > 0 ? false : true; #else - consolevent = M_CheckParm("-console") > 0 ? SDL_TRUE : SDL_FALSE; + consolevent = M_CheckParm("-console") > 0 ? true : false; #endif - framebuffer = M_CheckParm("-framebuffer") > 0 ? SDL_TRUE : SDL_FALSE; + framebuffer = M_CheckParm("-framebuffer") > 0 ? true : false; if (framebuffer) - consolevent = SDL_FALSE; + consolevent = false; } static inline void I_ShutdownConsole(void){} #endif @@ -1208,21 +1208,12 @@ I_CursedWindowMovement (int xd, int yd) boolean I_HasOpenURL() { - #if (SDL_VERSION_ATLEAST(2, 0, 14)) - return true; - #else - return false; - #endif + return true; } void I_OpenURL(const char *data) { - #if (SDL_VERSION_ATLEAST(2, 0, 14)) - SDL_OpenURL(data); - #else - (void)data; - return; - #endif + SDL_OpenURL(data); } // @@ -1254,48 +1245,36 @@ void I_JoyScale4(void) void I_SetGamepadPlayerIndex(INT32 device_id, INT32 player) { -#if !(SDL_VERSION_ATLEAST(2,0,12)) - (void)device_id; - (void)player; -#else I_Assert(device_id > 0); // Gamepad devices are always ID 1 or higher I_Assert(player >= 0 && player < MAXSPLITSCREENPLAYERS); - SDL_GameController *controller = SDL_GameControllerFromInstanceID(device_id - 1); + SDL_Gamepad *controller = SDL_GetGamepadFromID(device_id - 1); if (controller == NULL) { return; } - SDL_GameControllerSetPlayerIndex(controller, player); -#endif + SDL_SetGamepadPlayerIndex(controller, player); } void I_SetGamepadIndicatorColor(INT32 device_id, UINT8 red, UINT8 green, UINT8 blue) { -#if !(SDL_VERSION_ATLEAST(2,0,14)) - (void)device_id; - (void)red; - (void)green; - (void)blue; -#else I_Assert(device_id > 0); // Gamepad devices are always ID 1 or higher - SDL_GameController *controller = SDL_GameControllerFromInstanceID(device_id - 1); + SDL_Gamepad *controller = SDL_GetGamepadFromID(device_id - 1); if (controller == NULL) { return; } - SDL_GameControllerSetLED(controller, red, green, blue); -#endif + SDL_SetGamepadLED(controller, red, green, blue); } void I_GetGamepadGuid(INT32 device_id, char *out, int out_len) { - SDL_GameController *controller; + SDL_Gamepad *controller; SDL_Joystick *joystick; - SDL_JoystickGUID guid; + SDL_GUID guid; I_Assert(device_id > 0); I_Assert(out != NULL); @@ -1307,26 +1286,26 @@ void I_GetGamepadGuid(INT32 device_id, char *out, int out_len) return; } - controller = SDL_GameControllerFromInstanceID(device_id - 1); + controller = SDL_GetGamepadFromID(device_id - 1); if (controller == NULL) { out[0] = 0; return; } - joystick = SDL_GameControllerGetJoystick(controller); + joystick = SDL_GetGamepadJoystick(controller); if (joystick == NULL) { out[0] = 0; return; } - guid = SDL_JoystickGetGUID(joystick); - SDL_JoystickGetGUIDString(guid, out, out_len); + guid = SDL_GetJoystickGUID(joystick); + SDL_GUIDToString(guid, out, out_len); } void I_GetGamepadName(INT32 device_id, char *out, int out_len) { - SDL_GameController *controller; + SDL_Gamepad *controller; const char *name; int name_len; @@ -1334,14 +1313,14 @@ void I_GetGamepadName(INT32 device_id, char *out, int out_len) I_Assert(out != NULL); I_Assert(out_len > 0); - controller = SDL_GameControllerFromInstanceID(device_id - 1); + controller = SDL_GetGamepadFromID(device_id - 1); if (controller == NULL) { out[0] = 0; return; } - name = SDL_GameControllerName(controller); + name = SDL_GetGamepadName(controller); name_len = strlen(name) + 1; memcpy(out, name, out_len < name_len ? out_len : name_len); out[out_len - 1] = 0; @@ -1349,40 +1328,28 @@ void I_GetGamepadName(INT32 device_id, char *out, int out_len) void I_GamepadRumble(INT32 device_id, UINT16 low_strength, UINT16 high_strength) { -#if !(SDL_VERSION_ATLEAST(2,0,9)) - (void)device_id; - (void)low_strength; - (void)high_strength; -#else I_Assert(device_id > 0); // Gamepad devices are always ID 1 or higher - SDL_GameController *controller = SDL_GameControllerFromInstanceID(device_id - 1); + SDL_Gamepad *controller = SDL_GetGamepadFromID(device_id - 1); if (controller == NULL) { return; } - SDL_GameControllerRumble(controller, low_strength, high_strength, 0); -#endif + SDL_RumbleGamepad(controller, low_strength, high_strength, 0); } void I_GamepadRumbleTriggers(INT32 device_id, UINT16 left_strength, UINT16 right_strength) { -#if !(SDL_VERSION_ATLEAST(2,0,14)) - (void)device_id; - (void)left_strength; - (void)right_strength; -#else I_Assert(device_id > 0); // Gamepad devices are always ID 1 or higher - SDL_GameController *controller = SDL_GameControllerFromInstanceID(device_id - 1); + SDL_Gamepad *controller = SDL_GetGamepadFromID(device_id - 1); if (controller == NULL) { return; } - SDL_GameControllerRumbleTriggers(controller, left_strength, right_strength, 0); -#endif + SDL_RumbleGamepadTriggers(controller, left_strength, right_strength, 0); } // @@ -1396,16 +1363,16 @@ void I_StartupInput(void) { char dbpath[1024]; sprintf(dbpath, "%s" PATHSEP "gamecontrollerdb.txt", srb2path); - SDL_GameControllerAddMappingsFromFile(dbpath); + SDL_AddGamepadMappingsFromFile(dbpath); } { char dbpath[1024]; sprintf(dbpath, "%s" PATHSEP "gamecontrollerdb_user.txt", srb2home); - SDL_GameControllerAddMappingsFromFile(dbpath); + SDL_AddGamepadMappingsFromFile(dbpath); } - if (SDL_WasInit(SDL_INIT_GAMECONTROLLER)) + if (SDL_WasInit(SDL_INIT_GAMEPAD)) { return; } @@ -1418,7 +1385,7 @@ void I_StartupInput(void) CONS_Printf("I_StartupInput()...\n"); - if (SDL_InitSubSystem(SDL_INIT_GAMECONTROLLER) == -1) + if (!SDL_InitSubSystem(SDL_INIT_GAMEPAD)) { CONS_Printf(M_GetText("Couldn't initialize game controllers: %s\n"), SDL_GetError()); return; @@ -1433,10 +1400,10 @@ static void I_ShutdownInput(void) // The game code is now responsible for resetting its internal state based on ev_gamepad_device_removed events. // In practice, Input should never be shutdown and restarted during runtime. - if (SDL_WasInit(SDL_INIT_GAMECONTROLLER) == SDL_INIT_GAMECONTROLLER) + if (SDL_WasInit(SDL_INIT_GAMEPAD) == SDL_INIT_GAMEPAD) { CONS_Printf("Shutting down gamecontroller system\n"); - SDL_QuitSubSystem(SDL_INIT_GAMECONTROLLER); + SDL_QuitSubSystem(SDL_INIT_GAMEPAD); I_OutputMsg("I_Joystick: SDL's Game Controller system has been shutdown\n"); } @@ -1452,7 +1419,12 @@ INT32 I_NumJoys(void) { INT32 numjoy = 0; if (SDL_WasInit(SDL_INIT_JOYSTICK) == SDL_INIT_JOYSTICK) - numjoy = SDL_NumJoysticks(); + { + int count = 0; + SDL_JoystickID *joysticks = SDL_GetJoysticks(&count); + numjoy = count; + if (joysticks) SDL_free(joysticks); + } return numjoy; } @@ -1471,13 +1443,13 @@ const char *I_GetJoyName(INT32 joyindex) } // joyindex corresponds to the open joystick *instance* ID, not the joystick number - joystick = SDL_JoystickFromInstanceID(joyindex); + joystick = SDL_GetJoystickFromID(joyindex); if (joystick == NULL) { return joyname; } - tempname = SDL_JoystickNameForIndex(joyindex); + tempname = SDL_GetJoystickName(joystick); if (tempname) { strncpy(joyname, tempname, 254); @@ -1810,10 +1782,8 @@ static void I_Fork(void) INT32 I_StartupSystem(void) { - SDL_version SDLcompiled; - SDL_version SDLlinked; - SDL_VERSION(&SDLcompiled) - SDL_GetVersion(&SDLlinked); + Uint32 SDLcompiled = SDL_VERSION; + Uint32 SDLlinked = SDL_GetVersion(); I_StartupConsole(); #ifdef NEWSIGNALHANDLER // This is useful when debugging. It lets GDB attach to @@ -1829,15 +1799,13 @@ INT32 I_StartupSystem(void) #endif I_RegisterSignals(); I_OutputMsg("Compiled for SDL version: %d.%d.%d\n", - SDLcompiled.major, SDLcompiled.minor, SDLcompiled.patch); + SDL_VERSIONNUM_MAJOR(SDLcompiled), SDL_VERSIONNUM_MINOR(SDLcompiled), SDL_VERSIONNUM_MICRO(SDLcompiled)); I_OutputMsg("Linked with SDL version: %d.%d.%d\n", - SDLlinked.major, SDLlinked.minor, SDLlinked.patch); + SDL_VERSIONNUM_MAJOR(SDLlinked), SDL_VERSIONNUM_MINOR(SDLlinked), SDL_VERSIONNUM_MICRO(SDLlinked)); -#if (SDL_VERSION_ATLEAST(2, 0, 18)) - SDL_SetHint(SDL_HINT_APP_NAME, "Dr. Robotnik's Ring Racers"); -#endif + SDL_SetHint(SDL_HINT_APP_NAME, "Dr. Robotnik's Ring Racers"); - if (SDL_Init(0) < 0) + if (!SDL_Init(0)) I_Error("Dr. Robotnik's Ring Racers: SDL System Error: %s", SDL_GetError()); //Alam: Oh no.... #ifndef NOMUMBLE I_SetupMumble(); @@ -1850,12 +1818,12 @@ INT32 I_StartupSystem(void) // FUNCNORETURN void ATTRNORETURN I_Quit(void) { - static SDL_bool quiting = SDL_FALSE; + static bool quiting = false; /* prevent recursive I_Quit() */ if (quiting) goto death; - SDL_ShowCursor(SDL_TRUE); - quiting = SDL_FALSE; + SDL_ShowCursor(); + quiting = false; M_SaveConfig(NULL); //save game config, cvars.. M_SaveJoinedIPs(); diff --git a/src/sdl/i_threads.c b/src/sdl/i_threads.c index 9cd5824f5..a69be4db2 100644 --- a/src/sdl/i_threads.c +++ b/src/sdl/i_threads.c @@ -13,7 +13,7 @@ #include "../doomdef.h" #include "../i_threads.h" -#include +#include typedef void * (*Create_fn)(void); @@ -46,7 +46,7 @@ static I_mutex i_thread_pool_mutex; static I_mutex i_mutex_pool_mutex; static I_mutex i_cond_pool_mutex; -static SDL_atomic_t i_threads_running = {1}; +static SDL_AtomicInt i_threads_running = {1}; static Link Insert_link ( @@ -104,13 +104,13 @@ Identity ( ){ void * id; - id = SDL_AtomicGetPtr(anchor); + id = SDL_GetAtomicPointer(anchor); if (! id) { I_lock_mutex(&pool_mutex); { - id = SDL_AtomicGetPtr(anchor); + id = SDL_GetAtomicPointer(anchor); if (! id) { @@ -121,7 +121,7 @@ Identity ( Insert_link(pool_anchor, New_link(id)); - SDL_AtomicSetPtr(anchor, id); + SDL_SetAtomicPointer(anchor, id); } } I_unlock_mutex(pool_mutex); @@ -140,11 +140,11 @@ Worker ( (*th->entry)(th->userdata); - if (SDL_AtomicGet(&i_threads_running)) + if (SDL_GetAtomicInt(&i_threads_running)) { I_lock_mutex(&i_thread_pool_mutex); { - if (SDL_AtomicGet(&i_threads_running)) + if (SDL_GetAtomicInt(&i_threads_running)) { SDL_DetachThread(th->thread); Free_link(&i_thread_pool, link); @@ -177,7 +177,7 @@ I_spawn_thread ( { link = Insert_link(&i_thread_pool, New_link(th)); - if (SDL_AtomicGet(&i_threads_running)) + if (SDL_GetAtomicInt(&i_threads_running)) { th->thread = SDL_CreateThread( (SDL_ThreadFunction)Worker, @@ -195,7 +195,7 @@ I_spawn_thread ( int I_thread_is_stopped (void) { - return ( ! SDL_AtomicGet(&i_threads_running) ); + return ( ! SDL_GetAtomicInt(&i_threads_running) ); } void @@ -221,13 +221,13 @@ I_stop_threads (void) Link next; Thread th; - SDL_mutex * mutex; - SDL_cond * cond; + SDL_Mutex * mutex; + SDL_Condition * cond; if (i_threads_running.value) { /* rely on the good will of thread-san */ - SDL_AtomicSet(&i_threads_running, 0); + SDL_SetAtomicInt(&i_threads_running, 0); I_lock_mutex(&i_thread_pool_mutex); { @@ -268,7 +268,7 @@ I_stop_threads (void) next = link->next; cond = link->data; - SDL_DestroyCond(cond); + SDL_DestroyCondition(cond); free(link); } @@ -283,7 +283,7 @@ void I_lock_mutex ( I_mutex * anchor ){ - SDL_mutex * mutex; + SDL_Mutex * mutex; mutex = Identity( &i_mutex_pool, @@ -292,16 +292,14 @@ I_lock_mutex ( (Create_fn)SDL_CreateMutex ); - if (SDL_LockMutex(mutex) == -1) - abort(); + SDL_LockMutex(mutex); } void I_unlock_mutex ( I_mutex id ){ - if (SDL_UnlockMutex(id) == -1) - abort(); + SDL_UnlockMutex(id); } void @@ -309,49 +307,46 @@ I_hold_cond ( I_cond * cond_anchor, I_mutex mutex_id ){ - SDL_cond * cond; + SDL_Condition * cond; cond = Identity( &i_cond_pool, i_cond_pool_mutex, cond_anchor, - (Create_fn)SDL_CreateCond + (Create_fn)SDL_CreateCondition ); - if (SDL_CondWait(cond, mutex_id) == -1) - abort(); + SDL_WaitCondition(cond, mutex_id); } void I_wake_one_cond ( I_cond * anchor ){ - SDL_cond * cond; + SDL_Condition * cond; cond = Identity( &i_cond_pool, i_cond_pool_mutex, anchor, - (Create_fn)SDL_CreateCond + (Create_fn)SDL_CreateCondition ); - if (SDL_CondSignal(cond) == -1) - abort(); + SDL_SignalCondition(cond); } void I_wake_all_cond ( I_cond * anchor ){ - SDL_cond * cond; + SDL_Condition * cond; cond = Identity( &i_cond_pool, i_cond_pool_mutex, anchor, - (Create_fn)SDL_CreateCond + (Create_fn)SDL_CreateCondition ); - if (SDL_CondBroadcast(cond) == -1) - abort(); + SDL_BroadcastCondition(cond); } diff --git a/src/sdl/i_ttf.c b/src/sdl/i_ttf.c index a0eccf36c..cf3d6293c 100644 --- a/src/sdl/i_ttf.c +++ b/src/sdl/i_ttf.c @@ -12,8 +12,8 @@ /// \brief SDL_ttf interface code. Necessary for platforms with no framebuffer console systems. #if defined(HAVE_SDL) && defined(HAVE_TTF) -#include "SDL.h" -#include "SDL_ttf.h" +#include +#include #include "../doomdef.h" #include "../doomstat.h" #include "../d_netfil.h" diff --git a/src/sdl/i_ttf.h b/src/sdl/i_ttf.h index 3244dd73f..23301503c 100644 --- a/src/sdl/i_ttf.h +++ b/src/sdl/i_ttf.h @@ -15,7 +15,7 @@ #define __I_TTF__ #include "../doomdef.h" -#include +#include #ifdef __cplusplus extern "C" { diff --git a/src/sdl/i_video.cpp b/src/sdl/i_video.cpp index fa09ef4e4..538d861a4 100644 --- a/src/sdl/i_video.cpp +++ b/src/sdl/i_video.cpp @@ -12,7 +12,9 @@ /// \file /// \brief SRB2 graphics stuff for SDL -#include +#include +#include +#include #include #include #include @@ -31,7 +33,7 @@ #ifdef HAVE_SDL #define _MATH_DEFINES_DEFINED -#include "SDL.h" +#include #ifdef _MSC_VER #define WIN32_LEAN_AND_MEAN @@ -44,13 +46,8 @@ #include "i_ttf.h" #endif -#ifdef HAVE_IMAGE -#include "SDL_image.h" -#elif defined (__unix__) || (!defined(__APPLE__) && defined (UNIXCOMMON)) // Windows & Mac don't need this, as SDL will do it for us. -#define LOAD_XPM //I want XPM! #include "IMG_xpm.c" //Alam: I don't want to add SDL_Image.dll/so #define HAVE_IMAGE //I have SDL_Image, sortof -#endif #ifdef HAVE_IMAGE #include "SDL_icon.xpm" @@ -58,10 +55,6 @@ #include "../doomdef.h" -#ifdef _WIN32 -#include "SDL_syswm.h" -#endif - #include "../doomstat.h" #include "../i_system.h" #include "../v_video.h" @@ -113,9 +106,9 @@ UINT8 graphics_started = 0; // Is used in console.c and screen.c // To disable fullscreen at startup; is set in VID_PrepareModeList boolean allow_fullscreen = false; -static SDL_bool disable_fullscreen = SDL_FALSE; +static bool disable_fullscreen = false; #define USE_FULLSCREEN (disable_fullscreen||!allow_fullscreen)?0:cv_fullscreen.value -static SDL_bool disable_mouse = SDL_FALSE; +static bool disable_mouse = false; #define USE_MOUSEINPUT (!disable_mouse && cv_usemouse.value && havefocus) #define MOUSE_MENU false //(!disable_mouse && cv_usemouse.value && menuactive && !USE_FULLSCREEN) #define MOUSEBUTTONS_MAX MOUSEBUTTONS @@ -133,13 +126,13 @@ static SDL_Surface *icoSurface = NULL; static SDL_Color localPalette[256]; Uint16 realwidth = BASEVIDWIDTH; Uint16 realheight = BASEVIDHEIGHT; -static SDL_bool mousegrabok = SDL_TRUE; -static SDL_bool exposevideo = SDL_FALSE; -static SDL_bool borderlesswindow = SDL_FALSE; +static bool mousegrabok = true; +static bool exposevideo = false; +static bool borderlesswindow = false; -// SDL2 vars +// SDL vars SDL_Window *window; -static SDL_bool havefocus = SDL_TRUE; +static bool havefocus = true; static const char *fallback_resolution_name = "Fallback"; static std::unique_ptr g_rhi; @@ -170,16 +163,16 @@ static INT32 windowedModes[MAXWINMODES][2] = }; static void Impl_VideoSetupBuffer(void); -static SDL_bool Impl_CreateWindow(SDL_bool fullscreen); +static bool Impl_CreateWindow(bool fullscreen); //static void Impl_SetWindowName(const char *title); static void Impl_SetWindowIcon(void); static void ValidateDisplay(void) { - // Validate display index, otherwise use main display - if (cv_display.value >= SDL_GetNumVideoDisplays()) + // Validate display ID, otherwise use main display + if (cv_display.value == 0) { - CV_SetValue(&cv_display, 0); + CV_SetValue(&cv_display, static_cast(SDL_GetPrimaryDisplay())); } } @@ -191,9 +184,9 @@ static void CenterWindow(void) ); } -static void SDLSetMode(int width, int height, SDL_bool fullscreen, SDL_bool reposition) +static void SDLSetMode(int width, int height, bool fullscreen, bool reposition) { - static SDL_bool wasfullscreen = SDL_FALSE; + static bool wasfullscreen = false; realwidth = vid.width; realheight = vid.height; @@ -205,20 +198,21 @@ static void SDLSetMode(int width, int height, SDL_bool fullscreen, SDL_bool repo if (reposition) { ValidateDisplay(); - if (SDL_GetWindowDisplayIndex(window) != cv_display.value) + if (SDL_GetDisplayForWindow(window) != cv_display.value) { CenterWindow(); } } - wasfullscreen = SDL_TRUE; - SDL_SetWindowFullscreen(window, SDL_WINDOW_FULLSCREEN_DESKTOP); + wasfullscreen = true; + SDL_SetWindowFullscreenMode(window, NULL); + SDL_SetWindowFullscreen(window, true); } else // windowed mode { if (wasfullscreen) { - wasfullscreen = SDL_FALSE; - SDL_SetWindowFullscreen(window, 0); + wasfullscreen = false; + SDL_SetWindowFullscreen(window, false); } // Reposition window only in windowed mode SDL_SetWindowSize(window, width, height); @@ -231,12 +225,16 @@ static void SDLSetMode(int width, int height, SDL_bool fullscreen, SDL_bool repo } else { - Impl_CreateWindow(fullscreen); + if (!Impl_CreateWindow(fullscreen)) + { + return; + } wasfullscreen = fullscreen; SDL_SetWindowSize(window, width, height); if (fullscreen) { - SDL_SetWindowFullscreen(window, SDL_WINDOW_FULLSCREEN_DESKTOP); + SDL_SetWindowFullscreenMode(window, NULL); + SDL_SetWindowFullscreen(window, true); } } @@ -375,28 +373,16 @@ static void VID_Command_NumModes_f (void) CONS_Printf(M_GetText("%d video mode(s) available(s)\n"), VID_NumModes()); } -// SDL2 doesn't have SDL_GetVideoSurface or a lot of the SDL_Surface flags that SDL 1.2 had static void SurfaceInfo(const SDL_Surface *infoSurface, const char *SurfaceText) { - INT32 vfBPP; - if (!infoSurface) return; if (!SurfaceText) SurfaceText = M_GetText("Unknown Surface"); - vfBPP = infoSurface->format?infoSurface->format->BitsPerPixel:0; - CONS_Printf("\x82" "%s\n", SurfaceText); - CONS_Printf(M_GetText(" %ix%i at %i bit color\n"), infoSurface->w, infoSurface->h, vfBPP); - - if (infoSurface->flags&SDL_PREALLOC) - CONS_Printf("%s", M_GetText(" Uses preallocated memory\n")); - else - CONS_Printf("%s", M_GetText(" Stored in system memory\n")); - if (infoSurface->flags&SDL_RLEACCEL) - CONS_Printf("%s", M_GetText(" Colorkey RLE acceleration blit\n")); + CONS_Printf(M_GetText(" %ix%i, %s\n"), infoSurface->w, infoSurface->h, SDL_GetPixelFormatName(infoSurface->format)); } static void VID_Command_Info_f (void) @@ -409,9 +395,6 @@ static void VID_Command_ModeList_f(void) { // List windowed modes INT32 i = 0; - CONS_Printf("NOTE: Under SDL2, all modes are supported on all platforms.\n"); - CONS_Printf("Under opengl, fullscreen only supports native desktop resolution.\n"); - CONS_Printf("Under software, the mode is stretched up to desktop resolution.\n"); for (i = 0; i < MAXWINMODES; i++) { CONS_Printf("%2d: %dx%d\n", i, windowedModes[i][0], windowedModes[i][1]); @@ -473,43 +456,45 @@ static INT32 SDLJoyAxis(const Sint16 axis, UINT8 pid) static void Impl_HandleWindowEvent(SDL_WindowEvent evt) { #define FOCUSUNION static_cast(mousefocus | (kbfocus << 1)) - static SDL_bool firsttimeonmouse = SDL_TRUE; - static SDL_bool mousefocus = SDL_TRUE; - static SDL_bool kbfocus = SDL_TRUE; + static bool firsttimeonmouse = true; + static bool mousefocus = true; + static bool kbfocus = true; const unsigned int oldfocus = FOCUSUNION; - switch (evt.event) + switch (evt.type) { - case SDL_WINDOWEVENT_ENTER: - mousefocus = SDL_TRUE; + case SDL_EVENT_WINDOW_MOUSE_ENTER: + mousefocus = true; break; - case SDL_WINDOWEVENT_LEAVE: - mousefocus = SDL_FALSE; + case SDL_EVENT_WINDOW_MOUSE_LEAVE: + mousefocus = false; break; - case SDL_WINDOWEVENT_FOCUS_GAINED: - kbfocus = SDL_TRUE; - mousefocus = SDL_TRUE; - SDL_ShowCursor(SDL_FALSE); + case SDL_EVENT_WINDOW_FOCUS_GAINED: + kbfocus = true; + mousefocus = true; + SDL_HideCursor(); break; - case SDL_WINDOWEVENT_FOCUS_LOST: - kbfocus = SDL_FALSE; - mousefocus = SDL_FALSE; - SDL_ShowCursor(SDL_TRUE); + case SDL_EVENT_WINDOW_FOCUS_LOST: + kbfocus = false; + mousefocus = false; + SDL_ShowCursor(); break; - case SDL_WINDOWEVENT_MAXIMIZED: + case SDL_EVENT_WINDOW_MAXIMIZED: break; - case SDL_WINDOWEVENT_MOVED: + case SDL_EVENT_WINDOW_MOVED: window_x = evt.data1; window_y = evt.data2; break; - case SDL_WINDOWEVENT_SIZE_CHANGED: + case SDL_EVENT_WINDOW_RESIZED: vid.realwidth = evt.data1; vid.realheight = evt.data2; break; - case SDL_WINDOWEVENT_DISPLAY_CHANGED: + case SDL_EVENT_WINDOW_DISPLAY_CHANGED: CV_SetValue(&cv_display, evt.data1); break; + default: + break; } if (FOCUSUNION == oldfocus) // No state change @@ -553,11 +538,11 @@ static void Impl_HandleKeyboardEvent(SDL_KeyboardEvent evt, Uint32 type) event.device = 0; - if (type == SDL_KEYUP) + if (type == SDL_EVENT_KEY_UP) { event.type = ev_keyup; } - else if (type == SDL_KEYDOWN) + else if (type == SDL_EVENT_KEY_DOWN) { event.type = ev_keydown; } @@ -565,7 +550,7 @@ static void Impl_HandleKeyboardEvent(SDL_KeyboardEvent evt, Uint32 type) { return; } - event.data1 = Impl_SDL_Scancode_To_Keycode(evt.keysym.scancode); + event.data1 = Impl_SDL_Scancode_To_Keycode(evt.scancode); event.data2 = evt.repeat; if (event.data1) D_PostEvent(&event); } @@ -593,11 +578,11 @@ static void Impl_HandleMouseButtonEvent(SDL_MouseButtonEvent evt, Uint32 type) { event.device = 0; - if (type == SDL_MOUSEBUTTONUP) + if (type == SDL_EVENT_MOUSE_BUTTON_UP) { event.type = ev_keyup; } - else if (type == SDL_MOUSEBUTTONDOWN) + else if (type == SDL_EVENT_MOUSE_BUTTON_DOWN) { event.type = ev_keydown; } @@ -648,7 +633,7 @@ static void Impl_HandleMouseWheelEvent(SDL_MouseWheelEvent evt) } } -static void Impl_HandleControllerAxisEvent(SDL_ControllerAxisEvent evt) +static void Impl_HandleControllerAxisEvent(SDL_GamepadAxisEvent evt) { event_t event; INT32 value; @@ -686,7 +671,7 @@ static void Impl_HandleControllerAxisEvent(SDL_ControllerAxisEvent evt) D_PostEvent(&event); } -static void Impl_HandleControllerButtonEvent(SDL_ControllerButtonEvent evt, Uint32 type) +static void Impl_HandleControllerButtonEvent(SDL_GamepadButtonEvent evt, Uint32 type) { event_t event; @@ -700,11 +685,11 @@ static void Impl_HandleControllerButtonEvent(SDL_ControllerButtonEvent evt, Uint event.data1 = KEY_JOY1; event.data2 = 0; - if (type == SDL_CONTROLLERBUTTONUP) + if (type == SDL_EVENT_GAMEPAD_BUTTON_UP) { event.type = ev_keyup; } - else if (type == SDL_CONTROLLERBUTTONDOWN) + else if (type == SDL_EVENT_GAMEPAD_BUTTON_DOWN) { event.type = ev_keydown; } @@ -730,19 +715,19 @@ static void Impl_HandleControllerButtonEvent(SDL_ControllerButtonEvent evt, Uint } } -static void Impl_HandleControllerDeviceAddedEvent(SDL_ControllerDeviceEvent event) +static void Impl_HandleControllerDeviceAddedEvent(SDL_GamepadDeviceEvent event) { // The game is always interested in controller events, even if they aren't internally assigned to a player. // Thus, we *always* open SDL controllers as they become available, to begin receiving their events. - SDL_GameController* controller = SDL_GameControllerOpen(event.which); + SDL_Gamepad* controller = SDL_OpenGamepad(event.which); if (controller == NULL) { return; } - SDL_Joystick* joystick = SDL_GameControllerGetJoystick(controller); - SDL_JoystickID joystick_instance_id = SDL_JoystickInstanceID(joystick); + SDL_Joystick* joystick = SDL_GetGamepadJoystick(controller); + SDL_JoystickID joystick_instance_id = SDL_GetJoystickID(joystick); event_t engine_event {}; @@ -752,7 +737,7 @@ static void Impl_HandleControllerDeviceAddedEvent(SDL_ControllerDeviceEvent even D_PostEvent(&engine_event); } -static void Impl_HandleControllerDeviceRemovedEvent(SDL_ControllerDeviceEvent event) +static void Impl_HandleControllerDeviceRemovedEvent(SDL_GamepadDeviceEvent event) { // SDL only posts Device Removed events for controllers that have actually been opened. // Thus, we don't need to filter out controllers that may not have opened successfully prior to this event. @@ -764,7 +749,7 @@ static void Impl_HandleControllerDeviceRemovedEvent(SDL_ControllerDeviceEvent ev D_PostEvent(&engine_event); } -static ImGuiKey ImGui_ImplSDL2_KeycodeToImGuiKey(int keycode) +static ImGuiKey ImGui_ImplSDL3_KeycodeToImGuiKey(int keycode) { switch (keycode) { @@ -783,7 +768,7 @@ static ImGuiKey ImGui_ImplSDL2_KeycodeToImGuiKey(int keycode) case SDLK_SPACE: return ImGuiKey_Space; case SDLK_RETURN: return ImGuiKey_Enter; case SDLK_ESCAPE: return ImGuiKey_Escape; - case SDLK_QUOTE: return ImGuiKey_Apostrophe; + case SDLK_APOSTROPHE: return ImGuiKey_Apostrophe; case SDLK_COMMA: return ImGuiKey_Comma; case SDLK_MINUS: return ImGuiKey_Minus; case SDLK_PERIOD: return ImGuiKey_Period; @@ -793,7 +778,7 @@ static ImGuiKey ImGui_ImplSDL2_KeycodeToImGuiKey(int keycode) case SDLK_LEFTBRACKET: return ImGuiKey_LeftBracket; case SDLK_BACKSLASH: return ImGuiKey_Backslash; case SDLK_RIGHTBRACKET: return ImGuiKey_RightBracket; - case SDLK_BACKQUOTE: return ImGuiKey_GraveAccent; + case SDLK_GRAVE: return ImGuiKey_GraveAccent; case SDLK_CAPSLOCK: return ImGuiKey_CapsLock; case SDLK_SCROLLLOCK: return ImGuiKey_ScrollLock; case SDLK_NUMLOCKCLEAR: return ImGuiKey_NumLock; @@ -835,32 +820,32 @@ static ImGuiKey ImGui_ImplSDL2_KeycodeToImGuiKey(int keycode) case SDLK_7: return ImGuiKey_7; case SDLK_8: return ImGuiKey_8; case SDLK_9: return ImGuiKey_9; - case SDLK_a: return ImGuiKey_A; - case SDLK_b: return ImGuiKey_B; - case SDLK_c: return ImGuiKey_C; - case SDLK_d: return ImGuiKey_D; - case SDLK_e: return ImGuiKey_E; - case SDLK_f: return ImGuiKey_F; - case SDLK_g: return ImGuiKey_G; - case SDLK_h: return ImGuiKey_H; - case SDLK_i: return ImGuiKey_I; - case SDLK_j: return ImGuiKey_J; - case SDLK_k: return ImGuiKey_K; - case SDLK_l: return ImGuiKey_L; - case SDLK_m: return ImGuiKey_M; - case SDLK_n: return ImGuiKey_N; - case SDLK_o: return ImGuiKey_O; - case SDLK_p: return ImGuiKey_P; - case SDLK_q: return ImGuiKey_Q; - case SDLK_r: return ImGuiKey_R; - case SDLK_s: return ImGuiKey_S; - case SDLK_t: return ImGuiKey_T; - case SDLK_u: return ImGuiKey_U; - case SDLK_v: return ImGuiKey_V; - case SDLK_w: return ImGuiKey_W; - case SDLK_x: return ImGuiKey_X; - case SDLK_y: return ImGuiKey_Y; - case SDLK_z: return ImGuiKey_Z; + case SDLK_A: return ImGuiKey_A; + case SDLK_B: return ImGuiKey_B; + case SDLK_C: return ImGuiKey_C; + case SDLK_D: return ImGuiKey_D; + case SDLK_E: return ImGuiKey_E; + case SDLK_F: return ImGuiKey_F; + case SDLK_G: return ImGuiKey_G; + case SDLK_H: return ImGuiKey_H; + case SDLK_I: return ImGuiKey_I; + case SDLK_J: return ImGuiKey_J; + case SDLK_K: return ImGuiKey_K; + case SDLK_L: return ImGuiKey_L; + case SDLK_M: return ImGuiKey_M; + case SDLK_N: return ImGuiKey_N; + case SDLK_O: return ImGuiKey_O; + case SDLK_P: return ImGuiKey_P; + case SDLK_Q: return ImGuiKey_Q; + case SDLK_R: return ImGuiKey_R; + case SDLK_S: return ImGuiKey_S; + case SDLK_T: return ImGuiKey_T; + case SDLK_U: return ImGuiKey_U; + case SDLK_V: return ImGuiKey_V; + case SDLK_W: return ImGuiKey_W; + case SDLK_X: return ImGuiKey_X; + case SDLK_Y: return ImGuiKey_Y; + case SDLK_Z: return ImGuiKey_Z; case SDLK_F1: return ImGuiKey_F1; case SDLK_F2: return ImGuiKey_F2; case SDLK_F3: return ImGuiKey_F3; @@ -877,13 +862,13 @@ static ImGuiKey ImGui_ImplSDL2_KeycodeToImGuiKey(int keycode) return ImGuiKey_None; } -static void ImGui_ImplSDL2_UpdateKeyModifiers(SDL_Keymod sdl_key_mods) +static void ImGui_ImplSDL3_UpdateKeyModifiers(SDL_Keymod sdl_key_mods) { ImGuiIO& io = ImGui::GetIO(); - io.AddKeyEvent(ImGuiMod_Ctrl, (sdl_key_mods & KMOD_CTRL) != 0); - io.AddKeyEvent(ImGuiMod_Shift, (sdl_key_mods & KMOD_SHIFT) != 0); - io.AddKeyEvent(ImGuiMod_Alt, (sdl_key_mods & KMOD_ALT) != 0); - io.AddKeyEvent(ImGuiMod_Super, (sdl_key_mods & KMOD_GUI) != 0); + io.AddKeyEvent(ImGuiMod_Ctrl, (sdl_key_mods & SDL_KMOD_CTRL) != 0); + io.AddKeyEvent(ImGuiMod_Shift, (sdl_key_mods & SDL_KMOD_SHIFT) != 0); + io.AddKeyEvent(ImGuiMod_Alt, (sdl_key_mods & SDL_KMOD_ALT) != 0); + io.AddKeyEvent(ImGuiMod_Super, (sdl_key_mods & SDL_KMOD_GUI) != 0); } // You can read the io.WantCaptureMouse, io.WantCaptureKeyboard flags to tell if dear imgui wants to use your inputs. @@ -891,26 +876,26 @@ static void ImGui_ImplSDL2_UpdateKeyModifiers(SDL_Keymod sdl_key_mods) // - When io.WantCaptureKeyboard is true, do not dispatch keyboard input data to your main application, or clear/overwrite your copy of the keyboard data. // Generally you may always pass all inputs to dear imgui, and hide them from your application based on those two flags. // If you have multiple SDL events and some of them are not meant to be used by dear imgui, you may need to filter events based on their windowID field. -bool ImGui_ImplSDL2_ProcessEvent(const SDL_Event* event) +bool ImGui_ImplSDL3_ProcessEvent(const SDL_Event* event) { ImGuiIO& io = ImGui::GetIO(); switch (event->type) { - case SDL_MOUSEMOTION: + case SDL_EVENT_MOUSE_MOTION: { io.AddMousePosEvent((float)event->motion.x, (float)event->motion.y); return true; } - case SDL_MOUSEWHEEL: + case SDL_EVENT_MOUSE_WHEEL: { float wheel_x = (event->wheel.x > 0) ? 1.0f : (event->wheel.x < 0) ? -1.0f : 0.0f; float wheel_y = (event->wheel.y > 0) ? 1.0f : (event->wheel.y < 0) ? -1.0f : 0.0f; io.AddMouseWheelEvent(wheel_x, wheel_y); return true; } - case SDL_MOUSEBUTTONDOWN: - case SDL_MOUSEBUTTONUP: + case SDL_EVENT_MOUSE_BUTTON_DOWN: + case SDL_EVENT_MOUSE_BUTTON_UP: { int mouse_button = -1; if (event->button.button == SDL_BUTTON_LEFT) { mouse_button = 0; } @@ -920,42 +905,39 @@ bool ImGui_ImplSDL2_ProcessEvent(const SDL_Event* event) if (event->button.button == SDL_BUTTON_X2) { mouse_button = 4; } if (mouse_button == -1) break; - io.AddMouseButtonEvent(mouse_button, (event->type == SDL_MOUSEBUTTONDOWN)); - // bd->MouseButtonsDown = (event->type == SDL_MOUSEBUTTONDOWN) ? (bd->MouseButtonsDown | (1 << mouse_button)) : (bd->MouseButtonsDown & ~(1 << mouse_button)); + io.AddMouseButtonEvent(mouse_button, (event->type == SDL_EVENT_MOUSE_BUTTON_DOWN)); return true; } - case SDL_TEXTINPUT: + case SDL_EVENT_TEXT_INPUT: { io.AddInputCharactersUTF8(event->text.text); return true; } - case SDL_KEYDOWN: - case SDL_KEYUP: + case SDL_EVENT_KEY_DOWN: + case SDL_EVENT_KEY_UP: { - ImGui_ImplSDL2_UpdateKeyModifiers((SDL_Keymod)event->key.keysym.mod); - ImGuiKey key = ImGui_ImplSDL2_KeycodeToImGuiKey(event->key.keysym.sym); - io.AddKeyEvent(key, (event->type == SDL_KEYDOWN)); - io.SetKeyEventNativeData(key, event->key.keysym.sym, event->key.keysym.scancode, event->key.keysym.scancode); // To support legacy indexing (<1.87 user code). Legacy backend uses SDLK_*** as indices to IsKeyXXX() functions. + ImGui_ImplSDL3_UpdateKeyModifiers((SDL_Keymod)event->key.mod); + ImGuiKey key = ImGui_ImplSDL3_KeycodeToImGuiKey(event->key.key); + io.AddKeyEvent(key, (event->type == SDL_EVENT_KEY_DOWN)); + io.SetKeyEventNativeData(key, event->key.key, event->key.scancode, event->key.scancode); return true; } - case SDL_WINDOWEVENT: + case SDL_EVENT_WINDOW_MOUSE_ENTER: { - // - When capturing mouse, SDL will send a bunch of conflicting LEAVE/ENTER event on every mouse move, but the final ENTER tends to be right. - // - However we won't get a correct LEAVE event for a captured window. - // - In some cases, when detaching a window from main viewport SDL may send SDL_WINDOWEVENT_ENTER one frame too late, - // causing SDL_WINDOWEVENT_LEAVE on previous frame to interrupt drag operation by clear mouse position. This is why - // we delay process the SDL_WINDOWEVENT_LEAVE events by one frame. See issue #5012 for details. - Uint8 window_event = event->window.event; - if (window_event == SDL_WINDOWEVENT_ENTER) - (void)0; - // bd->PendingMouseLeaveFrame = 0; - if (window_event == SDL_WINDOWEVENT_LEAVE) - (void)0; - // bd->PendingMouseLeaveFrame = ImGui::GetFrameCount() + 1; - if (window_event == SDL_WINDOWEVENT_FOCUS_GAINED) - io.AddFocusEvent(true); - else if (event->window.event == SDL_WINDOWEVENT_FOCUS_LOST) - io.AddFocusEvent(false); + return true; + } + case SDL_EVENT_WINDOW_MOUSE_LEAVE: + { + return true; + } + case SDL_EVENT_WINDOW_FOCUS_GAINED: + { + io.AddFocusEvent(true); + return true; + } + case SDL_EVENT_WINDOW_FOCUS_LOST: + { + io.AddFocusEvent(false); return true; } } @@ -981,7 +963,7 @@ void I_GetEvent(void) while (SDL_PollEvent(&evt)) { - ImGui_ImplSDL2_ProcessEvent(&evt); + ImGui_ImplSDL3_ProcessEvent(&evt); if (io.WantCaptureMouse || io.WantCaptureKeyboard) { continue; @@ -989,45 +971,55 @@ void I_GetEvent(void) switch (evt.type) { - case SDL_WINDOWEVENT: + case SDL_EVENT_WINDOW_MOUSE_ENTER: + case SDL_EVENT_WINDOW_MOUSE_LEAVE: + case SDL_EVENT_WINDOW_FOCUS_GAINED: + case SDL_EVENT_WINDOW_FOCUS_LOST: + case SDL_EVENT_WINDOW_MAXIMIZED: + case SDL_EVENT_WINDOW_MOVED: + case SDL_EVENT_WINDOW_RESIZED: + case SDL_EVENT_WINDOW_DISPLAY_CHANGED: Impl_HandleWindowEvent(evt.window); break; - case SDL_KEYUP: - case SDL_KEYDOWN: + case SDL_EVENT_KEY_UP: + case SDL_EVENT_KEY_DOWN: Impl_HandleKeyboardEvent(evt.key, evt.type); break; - case SDL_MOUSEMOTION: + case SDL_EVENT_MOUSE_MOTION: //if (!mouseMotionOnce) Impl_HandleMouseMotionEvent(evt.motion); //mouseMotionOnce = 1; break; - case SDL_MOUSEBUTTONUP: - case SDL_MOUSEBUTTONDOWN: + case SDL_EVENT_MOUSE_BUTTON_UP: + case SDL_EVENT_MOUSE_BUTTON_DOWN: Impl_HandleMouseButtonEvent(evt.button, evt.type); break; - case SDL_MOUSEWHEEL: + case SDL_EVENT_MOUSE_WHEEL: Impl_HandleMouseWheelEvent(evt.wheel); break; - case SDL_CONTROLLERAXISMOTION: - Impl_HandleControllerAxisEvent(evt.caxis); + case SDL_EVENT_GAMEPAD_AXIS_MOTION: + Impl_HandleControllerAxisEvent(evt.gaxis); break; - case SDL_CONTROLLERBUTTONUP: - case SDL_CONTROLLERBUTTONDOWN: - Impl_HandleControllerButtonEvent(evt.cbutton, evt.type); + case SDL_EVENT_GAMEPAD_BUTTON_UP: + case SDL_EVENT_GAMEPAD_BUTTON_DOWN: + Impl_HandleControllerButtonEvent(evt.gbutton, evt.type); break; - case SDL_CONTROLLERDEVICEADDED: - Impl_HandleControllerDeviceAddedEvent(evt.cdevice); + case SDL_EVENT_GAMEPAD_ADDED: + Impl_HandleControllerDeviceAddedEvent(evt.gdevice); break; - case SDL_CONTROLLERDEVICEREMOVED: - Impl_HandleControllerDeviceRemovedEvent(evt.cdevice); + case SDL_EVENT_GAMEPAD_REMOVED: + Impl_HandleControllerDeviceRemovedEvent(evt.gdevice); break; - case SDL_QUIT: + case SDL_EVENT_QUIT: LUA_HookBool(true, HOOK(GameQuit)); I_Quit(); break; + + default: + break; } } @@ -1055,7 +1047,7 @@ void I_StartupMouse(void) if (disable_mouse) return; - SDL_ShowCursor(SDL_FALSE); + SDL_HideCursor(); } // @@ -1068,8 +1060,8 @@ void I_OsPolling(void) if (consolevent) I_GetConsoleEvents(); - if (SDL_WasInit(SDL_INIT_JOYSTICK | SDL_INIT_GAMECONTROLLER) == (SDL_INIT_JOYSTICK | SDL_INIT_GAMECONTROLLER)) - SDL_GameControllerUpdate(); + if (SDL_WasInit(SDL_INIT_JOYSTICK | SDL_INIT_GAMEPAD) == (SDL_INIT_JOYSTICK | SDL_INIT_GAMEPAD)) + SDL_UpdateGamepads(); I_GetEvent(); @@ -1077,13 +1069,13 @@ void I_OsPolling(void) /* Handle here so that our state is always synched with the system. */ shiftdown = ctrldown = altdown = 0; capslock = false; - if (mod & KMOD_LSHIFT) shiftdown |= 1; - if (mod & KMOD_RSHIFT) shiftdown |= 2; - if (mod & KMOD_LCTRL) ctrldown |= 1; - if (mod & KMOD_RCTRL) ctrldown |= 2; - if (mod & KMOD_LALT) altdown |= 1; - if (mod & KMOD_RALT) altdown |= 2; - if (mod & KMOD_CAPS) capslock = true; + if (mod & SDL_KMOD_LSHIFT) shiftdown |= 1; + if (mod & SDL_KMOD_RSHIFT) shiftdown |= 2; + if (mod & SDL_KMOD_LCTRL) ctrldown |= 1; + if (mod & SDL_KMOD_RCTRL) ctrldown |= 2; + if (mod & SDL_KMOD_LALT) altdown |= 1; + if (mod & SDL_KMOD_RALT) altdown |= 2; + if (mod & SDL_KMOD_CAPS) capslock = true; } // @@ -1102,7 +1094,7 @@ void I_UpdateNoBlit(void) } #endif } - exposevideo = SDL_FALSE; + exposevideo = false; } // @@ -1264,7 +1256,7 @@ INT32 VID_GetModeForSize(INT32 w, INT32 h) void VID_PrepareModeList(void) { - // Under SDL2, we just use the windowed modes list, and scale in windowed fullscreen. + // Under SDL3, we just use the windowed modes list, and scale in windowed fullscreen. allow_fullscreen = true; #if 0 INT32 i; @@ -1319,7 +1311,7 @@ static void init_imgui() ImGui::StyleColorsDark(); } -static SDL_bool Impl_CreateContext(void) +static bool Impl_CreateContext(void) { if (!sdlglcontext) { @@ -1351,7 +1343,7 @@ static SDL_bool Impl_CreateContext(void) g_rhi_generation += 1; } - return SDL_TRUE; + return true; } void VID_CheckGLLoaded(rendermode_t oldrender) @@ -1389,7 +1381,7 @@ boolean VID_CheckRenderer(void) setrenderneeded = 0; } - SDLSetMode(vid.width, vid.height, static_cast(USE_FULLSCREEN), (setmodeneeded ? SDL_TRUE : SDL_FALSE)); + SDLSetMode(vid.width, vid.height, static_cast(USE_FULLSCREEN), (setmodeneeded ? true : false)); Impl_VideoSetupBuffer(); if (rendermode == render_soft) @@ -1412,22 +1404,22 @@ boolean VID_CheckRenderer(void) static UINT32 refresh_rate; static UINT32 VID_GetRefreshRate(void) { - int index = SDL_GetWindowDisplayIndex(window); - SDL_DisplayMode m; - if (SDL_WasInit(SDL_INIT_VIDEO) == 0) { // Video not init yet. return 0; } - if (SDL_GetCurrentDisplayMode(index, &m) != 0) + SDL_DisplayID display_id = SDL_GetDisplayForWindow(window); + const SDL_DisplayMode *m = SDL_GetCurrentDisplayMode(display_id); + + if (m == nullptr) { // Error has occurred. return 0; } - return m.refresh_rate; + return static_cast(m->refresh_rate); } INT32 VID_SetMode(INT32 modeNum) @@ -1452,21 +1444,21 @@ INT32 VID_SetMode(INT32 modeNum) refresh_rate = VID_GetRefreshRate(); VID_CheckRenderer(); - return SDL_TRUE; + return true; } -static SDL_bool Impl_CreateWindow(SDL_bool fullscreen) +static bool Impl_CreateWindow(bool fullscreen) { uint32_t flags = SDL_WINDOW_RESIZABLE; if (rendermode == render_none) // dedicated - return SDL_TRUE; // Monster Iestyn -- not sure if it really matters what we return here tbh + return true; // Monster Iestyn -- not sure if it really matters what we return here tbh if (window != NULL) - return SDL_FALSE; + return false; if (fullscreen) - flags |= SDL_WINDOW_FULLSCREEN_DESKTOP; + flags |= SDL_WINDOW_FULLSCREEN; if (borderlesswindow) flags |= SDL_WINDOW_BORDERLESS; @@ -1475,13 +1467,18 @@ static SDL_bool Impl_CreateWindow(SDL_bool fullscreen) flags |= SDL_WINDOW_OPENGL; // Create a window - window = SDL_CreateWindow("Dr. Robotnik's Ring Racers " VERSIONSTRING, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, + window = SDL_CreateWindow("Dr. Robotnik's Ring Racers " VERSIONSTRING, realwidth, realheight, flags); if (window == NULL) { CONS_Printf(M_GetText("Couldn't create window: %s\n"), SDL_GetError()); - return SDL_FALSE; + return false; + } + + if (!fullscreen) + { + SDL_SetWindowPosition(window, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED); } Impl_SetWindowIcon(); @@ -1526,14 +1523,14 @@ void I_StartupGraphics(void) COM_AddCommand ("vid_modelist", VID_Command_ModeList_f); COM_AddCommand ("vid_mode", VID_Command_Mode_f); CV_RegisterList(cvlist_graphics_driver); - disable_mouse = static_cast(M_CheckParm("-nomouse")); - disable_fullscreen = M_CheckParm("-win") ? SDL_TRUE : SDL_FALSE; + disable_mouse = static_cast(M_CheckParm("-nomouse")); + disable_fullscreen = M_CheckParm("-win") ? true : false; keyboard_started = true; #if !defined(HAVE_TTF) // Previously audio was init here for questionable reasons? - if (SDL_InitSubSystem(SDL_INIT_VIDEO) < 0) + if (!SDL_InitSubSystem(SDL_INIT_VIDEO)) { CONS_Printf(M_GetText("Couldn't initialize SDL's Video System: %s\n"), SDL_GetError()); return; @@ -1579,7 +1576,7 @@ void I_StartupGraphics(void) if (chosenrendermode != render_none) rendermode = chosenrendermode; - borderlesswindow = M_CheckParm("-borderless") ? SDL_TRUE : SDL_FALSE; + borderlesswindow = M_CheckParm("-borderless") ? true : false; VID_Command_ModeList_f(); @@ -1589,7 +1586,7 @@ void I_StartupGraphics(void) #endif // Window icon -#ifdef HAVE_IMAGE +#if defined(HAVE_IMAGE) && (defined (__unix__) || (!defined(__APPLE__) && defined (UNIXCOMMON))) icoSurface = IMG_ReadXPMFromArray(SDL_icon_xpm); #endif @@ -1605,7 +1602,7 @@ void I_StartupGraphics(void) VID_SetMode(VID_GetModeForSize(BASEVIDWIDTH, BASEVIDHEIGHT)); if (M_CheckParm("-nomousegrab")) - mousegrabok = SDL_FALSE; + mousegrabok = false; realwidth = (Uint16)vid.width; realheight = (Uint16)vid.height; @@ -1683,7 +1680,7 @@ void VID_StartupOpenGL(void) void I_ShutdownGraphics(void) { rendermode = render_none; - if (icoSurface) SDL_FreeSurface(icoSurface); + if (icoSurface) SDL_DestroySurface(icoSurface); icoSurface = NULL; I_OutputMsg("I_ShutdownGraphics(): "); @@ -1695,16 +1692,21 @@ void I_ShutdownGraphics(void) } graphics_started = false; + g_rhi.reset(); + g_rhi_generation = 0; + #ifdef HWRENDER if (GLUhandle) hwClose(GLUhandle); if (sdlglcontext) { - SDL_GL_DeleteContext(sdlglcontext); + SDL_GL_DestroyContext(sdlglcontext); + sdlglcontext = nullptr; } #endif + window = NULL; SDL_QuitSubSystem(SDL_INIT_VIDEO); - framebuffer = SDL_FALSE; + framebuffer = false; } rhi::Rhi* srb2::sys::get_rhi(rhi::Handle handle) diff --git a/src/sdl/mixer_sound.c b/src/sdl/mixer_sound.c deleted file mode 100644 index b6b9e72f9..000000000 --- a/src/sdl/mixer_sound.c +++ /dev/null @@ -1,1537 +0,0 @@ -// DR. ROBOTNIK'S RING RACERS -//----------------------------------------------------------------------------- -// Copyright (C) 2025 by Kart Krew. -// Copyright (C) 2020 by Sonic Team Junior. -// -// This program is free software distributed under the -// terms of the GNU General Public License, version 2. -// See the 'LICENSE' file for more details. -//----------------------------------------------------------------------------- -/// \file -/// \brief SDL Mixer interface for sound - -#ifdef HAVE_GME -#ifdef HAVE_ZLIB -#ifndef _MSC_VER -#ifndef _LARGEFILE64_SOURCE -#define _LARGEFILE64_SOURCE -#endif -#endif - -#ifndef _LFS64_LARGEFILE -#define _LFS64_LARGEFILE -#endif - -#ifndef _FILE_OFFSET_BITS -#define _FILE_OFFSET_BITS 0 -#endif - -#include -#endif // HAVE_ZLIB -#endif // HAVE_GME - -#include "../doomdef.h" -#include "../doomstat.h" // menuactive - -#if defined(HAVE_SDL) && defined(HAVE_MIXER) && SOUND==SOUND_MIXER - -/* -Just for hu_stopped. I promise I didn't -write netcode into the sound code, OKAY? -*/ -#include "../d_clisrv.h" - -#include "../sounds.h" -#include "../s_sound.h" -#include "../i_sound.h" -#include "../w_wad.h" -#include "../z_zone.h" -#include "../byteptr.h" - -#ifdef _MSC_VER -#pragma warning(disable : 4214 4244) -#endif -#include "SDL.h" -#ifdef _MSC_VER -#pragma warning(default : 4214 4244) -#endif - -#ifdef HAVE_MIXERX -#include "SDL_mixer_ext.h" -#else -#include "SDL_mixer.h" -#endif - -/* This is the version number macro for the current SDL_mixer version: */ -#ifndef SDL_MIXER_COMPILEDVERSION -#define SDL_MIXER_COMPILEDVERSION \ - SDL_VERSIONNUM(MIX_MAJOR_VERSION, MIX_MINOR_VERSION, MIX_PATCHLEVEL) -#endif - -/* This macro will evaluate to true if compiled with SDL_mixer at least X.Y.Z */ -#ifndef SDL_MIXER_VERSION_ATLEAST -#define SDL_MIXER_VERSION_ATLEAST(X, Y, Z) \ - (SDL_MIXER_COMPILEDVERSION >= SDL_VERSIONNUM(X, Y, Z)) -#endif - -// thanks alam for making the buildbots happy! -#if SDL_MIXER_VERSION_ATLEAST(2,0,2) -#define MUS_MP3_MAD MUS_MP3_MAD_UNUSED -#define MUS_MODPLUG MUS_MODPLUG_UNUSED -#endif - -#ifdef HAVE_GME -#include -#define GME_TREBLE 5.0f -#define GME_BASS 1.0f -#endif // HAVE_GME - -static UINT16 BUFFERSIZE = 2048; -static UINT16 SAMPLERATE = 44100; - -#ifdef HAVE_OPENMPT -#include "libopenmpt/libopenmpt.h" -#endif - -/// ------------------------ -/// Audio Declarations -/// ------------------------ - -UINT8 sound_started = false; - -static UINT32 stutter_threshold_user; -static UINT32 stutter_threshold; - -static Mix_Music *music; -static int music_volume; -static int sfx_volume; -static int internal_volume; -static float loop_point; -static float song_length; // length in seconds -static boolean songpaused; -static UINT32 music_end_bytes; -static UINT32 music_bytes; -static UINT32 music_stutter_bytes; -static boolean is_looping; - -// fading -static boolean is_fading; -static UINT8 fading_source; -static UINT8 fading_target; -static UINT32 fading_timer; -static UINT32 fading_duration; -static INT32 fading_id; -static void (*fading_callback)(void); -static boolean fading_nocleanup; - -#ifdef HAVE_GME -static Music_Emu *gme; -static UINT16 current_track; -#endif - -#ifdef HAVE_OPENMPT -static int mod_err = OPENMPT_ERROR_OK; -static const char *mod_err_str; -static UINT16 current_subsong; -static size_t probesize; -static int result; -#endif - -static void var_cleanup(void) -{ - song_length = loop_point = 0.0f; - music_bytes = fading_source = fading_target =\ - fading_timer = fading_duration = 0; - music_end_bytes = 0; - music_stutter_bytes = 0; - - songpaused = is_looping =\ - is_fading = false; - - // HACK: See music_loop, where we want the fade timing to proceed after a non-looping - // song has stopped playing - if (!fading_nocleanup) - fading_callback = NULL; - else - fading_nocleanup = false; // use it once, set it back immediately - - internal_volume = 100; -} - -#if defined (HAVE_GME) && defined (HAVE_ZLIB) -static const char* get_zlib_error(int zErr) -{ - switch (zErr) - { - case Z_ERRNO: - return "Z_ERRNO"; - case Z_STREAM_ERROR: - return "Z_STREAM_ERROR"; - case Z_DATA_ERROR: - return "Z_DATA_ERROR"; - case Z_MEM_ERROR: - return "Z_MEM_ERROR"; - case Z_BUF_ERROR: - return "Z_BUF_ERROR"; - case Z_VERSION_ERROR: - return "Z_VERSION_ERROR"; - default: - return "unknown error"; - } -} -#endif - -/// ------------------------ -/// Audio System -/// ------------------------ - -void I_StartupSound(void) -{ - //I_Assert(!sound_started); - if (sound_started) - return; - -#ifdef _WIN32 - // Force DirectSound instead of WASAPI - // SDL 2.0.6+ defaults to the latter and it screws up our sound effects - SDL_setenv("SDL_AUDIODRIVER", "directsound", 1); -#endif - - // EE inits audio first so we're following along. - if (SDL_WasInit(SDL_INIT_AUDIO) == SDL_INIT_AUDIO) - { - CONS_Debug(DBG_DETAILED, "SDL Audio already started\n"); - return; - } - else if (SDL_InitSubSystem(SDL_INIT_AUDIO) < 0) - { - CONS_Alert(CONS_ERROR, "Error initializing SDL Audio: %s\n", SDL_GetError()); - // call to start audio failed -- we do not have it - return; - } - - fading_nocleanup = false; - - var_cleanup(); - - music = NULL; - music_volume = sfx_volume = 0; - -#if SDL_MIXER_VERSION_ATLEAST(1,2,11) - Mix_Init(MIX_INIT_FLAC|MIX_INIT_MP3|MIX_INIT_OGG|MIX_INIT_MOD); -#endif - - if (Mix_OpenAudio(SAMPLERATE, AUDIO_S16SYS, 2, BUFFERSIZE) < 0) - { - CONS_Alert(CONS_ERROR, "Error starting SDL_Mixer: %s\n", Mix_GetError()); - // call to start audio failed -- we do not have it - return; - } - -#ifdef HAVE_OPENMPT - CONS_Printf("libopenmpt version: %s\n", openmpt_get_string("library_version")); - CONS_Printf("libopenmpt build date: %s\n", openmpt_get_string("build")); -#endif - - sound_started = true; - songpaused = false; - Mix_AllocateChannels(256); -} - -void I_ShutdownSound(void) -{ - if (!sound_started) - return; // not an error condition - sound_started = false; - - Mix_CloseAudio(); -#if SDL_MIXER_VERSION_ATLEAST(1,2,11) - Mix_Quit(); -#endif - - SDL_QuitSubSystem(SDL_INIT_AUDIO); - -#ifdef HAVE_GME - if (gme) - gme_delete(gme); -#endif -#ifdef HAVE_OPENMPT - if (openmpt_mhandle) - openmpt_module_destroy(openmpt_mhandle); -#endif -} - -void I_UpdateSound(void) -{ -} - -/// ------------------------ -/// SFX -/// ------------------------ - -static int -get_real_sfx_volume (int vol) -{ - const int scale = SOUND_VOLUME_RANGE / MIX_MAX_VOLUME; - const int divider = VOLUME_DIVIDER * scale; - const int volume = ( vol + 1 ) / divider * sfx_volume / 100; - return volume; -} - -// this is as fast as I can possibly make it. -// sorry. more asm needed. -static Mix_Chunk *ds2chunk(void *stream) -{ - UINT16 ver,freq; - UINT32 samples, i, newsamples; - UINT8 *sound; - - SINT8 *s; - INT16 *d; - INT16 o; - fixed_t step, frac; - - // lump header - ver = READUINT16(stream); // sound version format? - if (ver != 3) // It should be 3 if it's a doomsound... - return NULL; // onos! it's not a doomsound! - freq = READUINT16(stream); - samples = READUINT32(stream); - - // convert from signed 8bit ???hz to signed 16bit 44100hz. - switch(freq) - { - case 44100: - if (samples >= UINT32_MAX>>2) - return NULL; // would wrap, can't store. - newsamples = samples; - break; - case 22050: - if (samples >= UINT32_MAX>>3) - return NULL; // would wrap, can't store. - newsamples = samples<<1; - break; - case 11025: - if (samples >= UINT32_MAX>>4) - return NULL; // would wrap, can't store. - newsamples = samples<<2; - break; - default: - frac = (44100 << FRACBITS) / (UINT32)freq; - if (!(frac & 0xFFFF)) // other solid multiples (change if FRACBITS != 16) - newsamples = samples * (frac >> FRACBITS); - else // strange and unusual fractional frequency steps, plus anything higher than 44100hz. - newsamples = FixedMul(FixedDiv(samples, freq), 44100) + 1; // add 1 to counter truncation. - if (newsamples >= UINT32_MAX>>2) - return NULL; // would and/or did wrap, can't store. - break; - } - sound = Z_Malloc(newsamples<<2, PU_SOUND, NULL); // samples * frequency shift * bytes per sample * channels - - s = (SINT8 *)stream; - d = (INT16 *)sound; - - i = 0; - switch(freq) - { - case 44100: // already at the same rate? well that makes it simple. - while(i++ < samples) - { - o = ((INT16)(*s++)+0x80)<<8; // changed signedness and shift up to 16 bits - *d++ = o; // left channel - *d++ = o; // right channel - } - break; - case 22050: // unwrap 2x - while(i++ < samples) - { - o = ((INT16)(*s++)+0x80)<<8; // changed signedness and shift up to 16 bits - *d++ = o; // left channel - *d++ = o; // right channel - *d++ = o; // left channel - *d++ = o; // right channel - } - break; - case 11025: // unwrap 4x - while(i++ < samples) - { - o = ((INT16)(*s++)+0x80)<<8; // changed signedness and shift up to 16 bits - *d++ = o; // left channel - *d++ = o; // right channel - *d++ = o; // left channel - *d++ = o; // right channel - *d++ = o; // left channel - *d++ = o; // right channel - *d++ = o; // left channel - *d++ = o; // right channel - } - break; - default: // convert arbitrary hz to 44100. - step = 0; - frac = ((UINT32)freq << FRACBITS) / 44100 + 1; //Add 1 to counter truncation. - while (i < samples) - { - o = (INT16)(*s+0x80)<<8; // changed signedness and shift up to 16 bits - while (step < FRACUNIT) // this is as fast as I can make it. - { - *d++ = o; // left channel - *d++ = o; // right channel - step += frac; - } - do { - i++; s++; - step -= FRACUNIT; - } while (step >= FRACUNIT); - } - break; - } - - // return Mixer Chunk. - return Mix_QuickLoad_RAW(sound, (Uint32)((UINT8*)d-sound)); -} - -void *I_GetSfx(sfxinfo_t *sfx) -{ - void *lump; - Mix_Chunk *chunk; - SDL_RWops *rw; -#ifdef HAVE_GME - Music_Emu *emu; - gme_info_t *info; -#endif - - if (sfx->lumpnum == LUMPERROR) - sfx->lumpnum = S_GetSfxLumpNum(sfx); - sfx->length = W_LumpLength(sfx->lumpnum); - - lump = W_CacheLumpNum(sfx->lumpnum, PU_SOUND); - - // convert from standard DoomSound format. - chunk = ds2chunk(lump); - if (chunk) - { - Z_Free(lump); - return chunk; - } - - // Not a doom sound? Try something else. -#ifdef HAVE_GME - // VGZ format - if (((UINT8 *)lump)[0] == 0x1F - && ((UINT8 *)lump)[1] == 0x8B) - { -#ifdef HAVE_ZLIB - UINT8 *inflatedData; - size_t inflatedLen; - z_stream stream; - int zErr; // Somewhere to handle any error messages zlib tosses out - - memset(&stream, 0x00, sizeof (z_stream)); // Init zlib stream - // Begin the inflation process - inflatedLen = *(UINT32 *)lump + (sfx->length-4); // Last 4 bytes are the decompressed size, typically - inflatedData = (UINT8 *)Z_Malloc(inflatedLen, PU_SOUND, NULL); // Make room for the decompressed data - stream.total_in = stream.avail_in = sfx->length; - stream.total_out = stream.avail_out = inflatedLen; - stream.next_in = (UINT8 *)lump; - stream.next_out = inflatedData; - - zErr = inflateInit2(&stream, 32 + MAX_WBITS); - if (zErr == Z_OK) // We're good to go - { - zErr = inflate(&stream, Z_FINISH); - if (zErr == Z_STREAM_END) { - // Run GME on new data - if (!gme_open_data(inflatedData, inflatedLen, &emu, SAMPLERATE)) - { - short *mem; - UINT32 len; - gme_equalizer_t eq = {GME_TREBLE, GME_BASS, 0,0,0,0,0,0,0,0}; - - Z_Free(inflatedData); // GME supposedly makes a copy for itself, so we don't need this lying around - Z_Free(lump); // We're done with the uninflated lump now, too. - - gme_start_track(emu, 0); - gme_set_equalizer(emu, &eq); - gme_track_info(emu, &info, 0); - - len = (info->play_length * 441 / 10) << 2; - mem = Z_Malloc(len, PU_SOUND, 0); - gme_play(emu, len >> 1, mem); - gme_free_info(info); - gme_delete(emu); - - return Mix_QuickLoad_RAW((Uint8 *)mem, len); - } - } - else - CONS_Alert(CONS_ERROR,"Encountered %s when running inflate: %s\n", get_zlib_error(zErr), stream.msg); - (void)inflateEnd(&stream); - } - else // Hold up, zlib's got a problem - CONS_Alert(CONS_ERROR,"Encountered %s when running inflateInit: %s\n", get_zlib_error(zErr), stream.msg); - Z_Free(inflatedData); // GME didn't open jack, but don't let that stop us from freeing this up -#else - return NULL; // No zlib support -#endif - } - // Try to read it as a GME sound - else if (!gme_open_data(lump, sfx->length, &emu, SAMPLERATE)) - { - short *mem; - UINT32 len; - gme_equalizer_t eq = {GME_TREBLE, GME_BASS, 0,0,0,0,0,0,0,0}; - - Z_Free(lump); - - gme_start_track(emu, 0); - gme_set_equalizer(emu, &eq); - gme_track_info(emu, &info, 0); - - len = (info->play_length * 441 / 10) << 2; - mem = Z_Malloc(len, PU_SOUND, 0); - gme_play(emu, len >> 1, mem); - gme_free_info(info); - gme_delete(emu); - - return Mix_QuickLoad_RAW((Uint8 *)mem, len); - } -#endif - - // Try to load it as a WAVE or OGG using Mixer. - rw = SDL_RWFromMem(lump, sfx->length); - if (rw != NULL) - { - chunk = Mix_LoadWAV_RW(rw, 1); - return chunk; - } - - return NULL; // haven't been able to get anything -} - -void I_FreeSfx(sfxinfo_t *sfx) -{ - if (sfx->data) - { - Mix_Chunk *chunk = (Mix_Chunk*)sfx->data; - UINT8 *abufdata = NULL; - if (chunk->allocated == 0) - { - // We allocated the data in this chunk, so get the abuf from mixer, then let it free the chunk, THEN we free the data - // I believe this should ensure the sound is not playing when we free it - abufdata = chunk->abuf; - } - Mix_FreeChunk(sfx->data); - if (abufdata) - { - // I'm going to assume we used Z_Malloc to allocate this data. - Z_Free(abufdata); - } - } - sfx->data = NULL; - sfx->lumpnum = LUMPERROR; -} - -INT32 I_StartSound(sfxenum_t id, UINT8 vol, UINT8 sep, UINT8 pitch, UINT8 priority, INT32 channel) -{ - //UINT8 volume = (((UINT16)vol + 1) * (UINT16)sfx_volume) / 62; // (256 * 31) / 62 == 127 - UINT8 volume = get_real_sfx_volume(vol); - INT32 handle = Mix_PlayChannel(channel, S_sfx[id].data, 0); - Mix_Volume(handle, volume); - Mix_SetPanning(handle, min((UINT16)(0xff-sep)<<1, 0xff), min((UINT16)(sep)<<1, 0xff)); - (void)pitch; // Mixer can't handle pitch - (void)priority; // priority and channel management is handled by SRB2... - return handle; -} - -void I_StopSound(INT32 handle) -{ - Mix_HaltChannel(handle); -} - -boolean I_SoundIsPlaying(INT32 handle) -{ - return Mix_Playing(handle); -} - -void I_UpdateSoundParams(INT32 handle, UINT8 vol, UINT8 sep, UINT8 pitch) -{ - //UINT8 volume = (((UINT16)vol + 1) * (UINT16)sfx_volume) / 62; // (256 * 31) / 62 == 127 - UINT8 volume = get_real_sfx_volume(vol); - Mix_Volume(handle, volume); - Mix_SetPanning(handle, min((UINT16)(0xff-sep)<<1, 0xff), min((UINT16)(sep)<<1, 0xff)); - (void)pitch; -} - -void I_SetSfxVolume(int volume) -{ - sfx_volume = volume; -} - -/// ------------------------ -/// Music Utilities -/// ------------------------ - -static int attenuate(int scale) -{ - // attenuate scale by all volumes as percentages - return scale - * musicdef_volume / 100 - * internal_volume / 100 - * music_volume / 100; -} - -static UINT32 get_adjusted_position(UINT32 position) -{ - // all in milliseconds - UINT32 length = I_GetSongLength(); - UINT32 looppoint = I_GetSongLoopPoint(); - if (length) - return position >= length ? (position % (length-looppoint)) : position; - else - return position; -} - -static void do_fading_callback(void) -{ - if (fading_callback) - (*fading_callback)(); - fading_callback = NULL; -} - -/// ------------------------ -/// Music Hooks -/// ------------------------ - -static void -Countstutter (int len) -{ - UINT32 bytes; - - if (hu_stopped) - { - music_stutter_bytes += len; - } - else if (stutter_threshold) - { - if (music_stutter_bytes >= stutter_threshold) - { - /* - This would be after looping. If we're too near to the start of the - file, subtracting the delta will just underflow. - */ - if (music_stutter_bytes > music_bytes) - { - /* We already know where the end is because we looped. */ - bytes = ( music_end_bytes - ( music_stutter_bytes - music_bytes )); - } - else - bytes = ( music_bytes - music_stutter_bytes ); - I_SetSongPosition((int)( bytes/4/44100.0*1000 )); - } - } -} - -static void count_music_bytes(int chan, void *stream, int len, void *udata) -{ - (void)chan; - (void)stream; - (void)udata; - - if (!music || I_SongType() == MU_GME || I_SongType() == MU_MOD) - return; - music_bytes += len; - - if (gamestate == GS_LEVEL) - Countstutter(len); -} - -static void music_loop(void) -{ - if (is_looping) - { - music_end_bytes = music_bytes; - Mix_PlayMusic(music, 0); - Mix_SetMusicPosition(loop_point); - music_bytes = (UINT32)(loop_point*44100.0L*4); //assume 44.1khz, 4-byte length (see I_GetSongPosition) - } - else - { - // HACK: Let fade timing proceed beyond the end of a - // non-looping song. This is a specific case where the timing - // should persist after stopping a song, so I don't believe - // this should apply every time the user stops a song. - // This is auto-unset in var_cleanup, called by I_StopSong - fading_nocleanup = true; - I_StopSong(); - } -} - -static UINT32 music_fade(UINT32 interval, void *param) -{ - (void)param; - - if (!is_fading || - internal_volume == fading_target || - fading_duration == 0) - { - I_StopFadingSong(); - do_fading_callback(); - return 0; - } - else if (songpaused) // don't decrement timer - return interval; - else if ((fading_timer -= 10) <= 0) - { - internal_volume = fading_target; - Mix_VolumeMusic(attenuate(MIX_MAX_VOLUME)); - I_StopFadingSong(); - do_fading_callback(); - return 0; - } - else - { - UINT8 delta = abs(fading_target - fading_source); - fixed_t factor = FixedDiv(fading_duration - fading_timer, fading_duration); - if (fading_target < fading_source) - internal_volume = max(min(internal_volume, fading_source - FixedMul(delta, factor)), fading_target); - else if (fading_target > fading_source) - internal_volume = min(max(internal_volume, fading_source + FixedMul(delta, factor)), fading_target); - Mix_VolumeMusic(attenuate(MIX_MAX_VOLUME)); - return interval; - } -} - -#ifdef HAVE_GME -static void mix_gme(void *udata, Uint8 *stream, int len) -{ - int i; - short *p; - - (void)udata; - - // no gme? no music. - if (!gme || gme_track_ended(gme) || songpaused) - return; - - // play gme into stream - gme_play(gme, len/2, (short *)stream); - - // apply volume to stream - for (i = 0, p = (short *)stream; i < len/2; i++, p++) - *p = attenuate(*p); -} -#endif - -#ifdef HAVE_OPENMPT -static void mix_openmpt(void *udata, Uint8 *stream, int len) -{ - int i; - short *p; - - (void)udata; - - if (!openmpt_mhandle || songpaused) - return; - - // Play module into stream - openmpt_module_read_interleaved_stereo(openmpt_mhandle, SAMPLERATE, BUFFERSIZE, (short *)stream); - - // apply volume to stream - for (i = 0, p = (short *)stream; i < len/2; i++, p++) - *p = attenuate(*p); -} -#endif - -/// ------------------------ -/// Music System -/// ------------------------ - -void I_InitMusic(void) -{ -} - -void I_ShutdownMusic(void) -{ - I_UnloadSong(); -} - -/// ------------------------ -/// Music Properties -/// ------------------------ - -musictype_t I_SongType(void) -{ -#ifdef HAVE_GME - if (gme) - return MU_GME; - else -#endif -#ifdef HAVE_OPENMPT - if (openmpt_mhandle) - return MU_MOD_EX; -#endif - if (!music) - return MU_NONE; - else if (Mix_GetMusicType(music) == MUS_MID) - { -#ifdef HAVE_MIXERX - if (Mix_GetMidiPlayer() != MIDI_Native) - return MU_MID_EX; - else -#endif - return MU_MID; - } - else if (Mix_GetMusicType(music) == MUS_MOD || Mix_GetMusicType(music) == MUS_MODPLUG) - return MU_MOD; - else if (Mix_GetMusicType(music) == MUS_MP3 || Mix_GetMusicType(music) == MUS_MP3_MAD) - return MU_MP3; - else - return (musictype_t)Mix_GetMusicType(music); -} - -boolean I_SongPlaying(void) -{ - return ( -#ifdef HAVE_GME - (I_SongType() == MU_GME && gme) || -#endif -#ifdef HAVE_OPENMPT - (I_SongType() == MU_MOD_EX && openmpt_mhandle) || -#endif - music != NULL - ); -} - -boolean I_SongPaused(void) -{ - return songpaused; -} - -/// ------------------------ -/// Music Effects -/// ------------------------ - -boolean I_SetSongSpeed(float speed) -{ - if (speed > 250.0f) - speed = 250.0f; //limit speed up to 250x -#ifdef HAVE_GME - if (gme) - { - SDL_LockAudio(); - gme_set_tempo(gme, speed); - SDL_UnlockAudio(); - return true; - } - else -#endif -#ifdef HAVE_OPENMPT - if (openmpt_mhandle) - { - if (speed > 4.0f) - speed = 4.0f; // Limit this to 4x to prevent crashing, stupid fix but... ~SteelT 27/9/19 -#if OPENMPT_API_VERSION_MAJOR < 1 && OPENMPT_API_VERSION_MINOR < 5 - { - // deprecated in 0.5.0 - char modspd[13]; - sprintf(modspd, "%g", speed); - openmpt_module_ctl_set(openmpt_mhandle, "play.tempo_factor", modspd); - } -#else - openmpt_module_ctl_set_floatingpoint(openmpt_mhandle, "play.tempo_factor", (double)speed); -#endif - return true; - } -#else - (void)speed; - return false; -#endif - return false; -} - -/// ------------------------ -/// MUSIC SEEKING -/// ------------------------ - -UINT32 I_GetSongLength(void) -{ - INT32 length; - -#ifdef HAVE_GME - if (gme) - { - gme_info_t *info; - gme_err_t gme_e = gme_track_info(gme, &info, current_track); - - if (gme_e != NULL) - { - CONS_Alert(CONS_ERROR, "GME error: %s\n", gme_e); - length = 0; - } - else - { - // reconstruct info->play_length, from GME source - // we only want intro + 1 loop, not 2 - length = info->length; - if (length <= 0) - { - length = info->intro_length + info->loop_length; // intro + 1 loop - if (length <= 0) - length = 150 * 1000; // 2.5 minutes - } - } - - gme_free_info(info); - return max(length, 0); - } - else -#endif -#ifdef HAVE_OPENMPT - if (openmpt_mhandle) - return (UINT32)(openmpt_module_get_duration_seconds(openmpt_mhandle) * 1000.); - else -#endif - if (!music || I_SongType() == MU_MOD || I_SongType() == MU_MID) - return 0; - else - { -#ifdef HAVE_MIXERX - double xlength = Mix_GetMusicTotalTime(music); - if (xlength >= 0) - return (UINT32)(xlength*1000); -#endif - // VERY IMPORTANT to set your LENGTHMS= in your song files, folks! - // SDL mixer can't read music length itself. - length = (UINT32)(song_length*1000); - if (!length) - CONS_Debug(DBG_DETAILED, "Getting music length: music is missing LENGTHMS= tag. Needed for seeking.\n"); - return length; - } -} - -boolean I_SetSongLoopPoint(UINT32 looppoint) -{ - if (!music || I_SongType() == MU_GME || I_SongType() == MU_MOD || !is_looping) - return false; - else - { - UINT32 length = I_GetSongLength(); - - if (length > 0) - looppoint %= length; - - loop_point = max((float)(looppoint / 1000.0L), 0); - return true; - } -} - -UINT32 I_GetSongLoopPoint(void) -{ -#ifdef HAVE_GME - if (gme) - { - INT32 looppoint; - gme_info_t *info; - gme_err_t gme_e = gme_track_info(gme, &info, current_track); - - if (gme_e != NULL) - { - CONS_Alert(CONS_ERROR, "GME error: %s\n", gme_e); - looppoint = 0; - } - else - looppoint = info->intro_length > 0 ? info->intro_length : 0; - - gme_free_info(info); - return max(looppoint, 0); - } - else -#endif - if (!music || I_SongType() == MU_MOD) - return 0; - else - return (UINT32)(loop_point * 1000); -} - -boolean I_SetSongPosition(UINT32 position) -{ - UINT32 length; -#ifdef HAVE_GME - if (gme) - { - // this is unstable, so fail silently - return true; - // this isn't required technically, but GME thread-locks for a second - // if you seek too high from the counter - // length = I_GetSongLength(); - // if (length) - // position = get_adjusted_position(position); - - // SDL_LockAudio(); - // gme_err_t gme_e = gme_seek(gme, position); - // SDL_UnlockAudio(); - - // if (gme_e != NULL) - // { - // CONS_Alert(CONS_ERROR, "GME error: %s\n", gme_e); - // return false; - // } - // else - // return true; - } - else -#endif -#ifdef HAVE_OPENMPT - if (openmpt_mhandle) - { - // This isn't 100% correct because we don't account for loop points because we can't get them. - // But if you seek past end of song, OpenMPT seeks to 0. So adjust the position anyway. - openmpt_module_set_position_seconds(openmpt_mhandle, (double)(get_adjusted_position(position)/1000.0L)); // returns new position - return true; - } - else -#endif - if (!music || I_SongType() == MU_MID) - return false; - else if (I_SongType() == MU_MOD) - return Mix_SetMusicPosition(position); // Goes by channels - else - { - // Because SDL mixer can't identify song length, if you have - // a position input greater than the real length, then - // music_bytes becomes inaccurate. - - length = I_GetSongLength(); // get it in MS - if (length) - position = get_adjusted_position(position); - - Mix_RewindMusic(); // needed for mp3 - if(Mix_SetMusicPosition((float)(position/1000.0L)) == 0) - music_bytes = (UINT32)(position/1000.0L*44100.0L*4); //assume 44.1khz, 4-byte length (see I_GetSongPosition) - else - // NOTE: This block fires on incorrect song format, - // NOT if position input is greater than song length. - music_bytes = 0; - - music_stutter_bytes = 0; - - return true; - } -} - -UINT32 I_GetSongPosition(void) -{ -#ifdef HAVE_GME - if (gme) - { - INT32 position = gme_tell(gme); - - gme_info_t *info; - gme_err_t gme_e = gme_track_info(gme, &info, current_track); - - if (gme_e != NULL) - { - CONS_Alert(CONS_ERROR, "GME error: %s\n", gme_e); - return position; - } - else - { - // adjust position, since GME's counter keeps going past loop - if (info->length > 0) - position %= info->length; - else if (info->intro_length + info->loop_length > 0) - position = position >= (info->intro_length + info->loop_length) ? (position % info->loop_length) : position; - else - position %= 150 * 1000; // 2.5 minutes - } - - gme_free_info(info); - return max(position, 0); - } - else -#endif -#ifdef HAVE_OPENMPT - if (openmpt_mhandle) - // This will be incorrect if we adjust for length because we can't get loop points. - // So return unadjusted. See note in SetMusicPosition: we adjust for that. - return (UINT32)(openmpt_module_get_position_seconds(openmpt_mhandle)*1000.); - //return get_adjusted_position((UINT32)(openmpt_module_get_position_seconds(openmpt_mhandle)*1000.)); - else -#endif - if (!music || I_SongType() == MU_MID) - return 0; - else - { -#ifdef HAVE_MIXERX - double xposition = Mix_GetMusicPosition(music); - if (xposition >= 0) - return (UINT32)(xposition*1000); -#endif - return (UINT32)(music_bytes/44100.0L*1000.0L/4); //assume 44.1khz - // 4 = byte length for 16-bit samples (AUDIO_S16SYS), stereo (2-channel) - // This is hardcoded in I_StartupSound. Other formats for factor: - // 8M: 1 | 8S: 2 | 16M: 2 | 16S: 4 - } -} - -void -I_UpdateSongLagThreshold (void) -{ - stutter_threshold_user = cv_music_resync_threshold.value/1000.0*(4*44100); - I_UpdateSongLagConditions(); -} - -void -I_UpdateSongLagConditions (void) -{ - if (! cv_music_resync_powerups_only.value || S_MusicUsage() == MUS_SPECIAL) - stutter_threshold = stutter_threshold_user; - else - stutter_threshold = 0; -} - -/// ------------------------ -/// Music Playback -/// ------------------------ - -boolean I_LoadSong(char *data, size_t len) -{ - const char *key1 = "LOOP"; - const char *key2 = "POINT="; - const char *key3 = "MS="; - const size_t key1len = strlen(key1); - const size_t key2len = strlen(key2); - const size_t key3len = strlen(key3); - char *p = data; - SDL_RWops *rw; - - if (music -#ifdef HAVE_GME - || gme -#endif -#ifdef HAVE_OPENMPT - || openmpt_mhandle -#endif - ) - I_UnloadSong(); - - // always do this whether or not a music already exists - var_cleanup(); - -#ifdef HAVE_GME - if ((UINT8)data[0] == 0x1F - && (UINT8)data[1] == 0x8B) - { -#ifdef HAVE_ZLIB - UINT8 *inflatedData; - size_t inflatedLen; - z_stream stream; - int zErr; // Somewhere to handle any error messages zlib tosses out - - memset(&stream, 0x00, sizeof (z_stream)); // Init zlib stream - // Begin the inflation process - inflatedLen = *(UINT32 *)(data + (len-4)); // Last 4 bytes are the decompressed size, typically - inflatedData = (UINT8 *)Z_Calloc(inflatedLen, PU_MUSIC, NULL); // Make room for the decompressed data - stream.total_in = stream.avail_in = len; - stream.total_out = stream.avail_out = inflatedLen; - stream.next_in = (UINT8 *)data; - stream.next_out = inflatedData; - - zErr = inflateInit2(&stream, 32 + MAX_WBITS); - if (zErr == Z_OK) // We're good to go - { - zErr = inflate(&stream, Z_FINISH); - if (zErr == Z_STREAM_END) - { - // Run GME on new data - if (!gme_open_data(inflatedData, inflatedLen, &gme, SAMPLERATE)) - { - Z_Free(inflatedData); // GME supposedly makes a copy for itself, so we don't need this lying around - return true; - } - } - else - CONS_Alert(CONS_ERROR, "Encountered %s when running inflate: %s\n", get_zlib_error(zErr), stream.msg); - (void)inflateEnd(&stream); - } - else // Hold up, zlib's got a problem - CONS_Alert(CONS_ERROR, "Encountered %s when running inflateInit: %s\n", get_zlib_error(zErr), stream.msg); - Z_Free(inflatedData); // GME didn't open jack, but don't let that stop us from freeing this up - return false; -#else - CONS_Alert(CONS_ERROR, "Cannot decompress VGZ; no zlib support\n"); - return false; -#endif - } - else if (!gme_open_data(data, len, &gme, SAMPLERATE)) - return true; -#endif - -#ifdef HAVE_OPENMPT - /* - If the size of the data to be checked is bigger than the recommended size (> 2048 bytes) - Let's just set the probe size to the recommended size - Otherwise let's give it the full data size - */ - - if (len > openmpt_probe_file_header_get_recommended_size()) - probesize = openmpt_probe_file_header_get_recommended_size(); - else - probesize = len; - - result = openmpt_probe_file_header(OPENMPT_PROBE_FILE_HEADER_FLAGS_DEFAULT, data, probesize, len, NULL, NULL, NULL, NULL, NULL, NULL); - - if (result == OPENMPT_PROBE_FILE_HEADER_RESULT_SUCCESS) // We only cared if it succeeded, continue on if not. - { - openmpt_mhandle = openmpt_module_create_from_memory2(data, len, NULL, NULL, NULL, NULL, NULL, NULL, NULL); - if (!openmpt_mhandle) // Failed to create module handle? Show error and return! - { - mod_err = openmpt_module_error_get_last(openmpt_mhandle); - mod_err_str = openmpt_error_string(mod_err); - CONS_Alert(CONS_ERROR, "openmpt_module_create_from_memory2: %s\n", mod_err_str); - return false; - } - else - return true; // All good and we're ready for music playback! - } -#endif - - // Let's see if Mixer is able to load this. - rw = SDL_RWFromMem(data, len); - { - music = Mix_LoadMUS_RW(rw, 1); - } - if (!music) - { - CONS_Alert(CONS_ERROR, "Mix_LoadMUS_RW: %s\n", Mix_GetError()); - return false; - } - - // Find the OGG loop point. - loop_point = 0.0f; - song_length = 0.0f; - - while ((UINT32)(p - data) < len) - { - if (fpclassify(loop_point) == FP_ZERO && !strncmp(p, key1, key1len)) - { - p += key1len; // skip LOOP - if (!strncmp(p, key2, key2len)) // is it LOOPPOINT=? - { - p += key2len; // skip POINT= - loop_point = (float)((44.1L+atoi(p)) / 44100.0L); // LOOPPOINT works by sample count. - // because SDL_Mixer is USELESS and can't even tell us - // something simple like the frequency of the streaming music, - // we are unfortunately forced to assume that ALL MUSIC is 44100hz. - // This means a lot of tracks that are only 22050hz for a reasonable downloadable file size will loop VERY badly. - } - else if (!strncmp(p, key3, key3len)) // is it LOOPMS=? - { - p += key3len; // skip MS= - loop_point = atof(p) / 1000.f; // LOOPMS works by real time, as miliseconds. - // Everything that uses LOOPMS will work perfectly with SDL_Mixer. - } - } - - if (fpclassify(loop_point) != FP_ZERO) // Got what we needed - break; - else // continue searching - p++; - } - return true; -} - -void I_UnloadSong(void) -{ - I_StopSong(); - -#ifdef HAVE_GME - if (gme) - { - gme_delete(gme); - gme = NULL; - } -#endif -#ifdef HAVE_OPENMPT - if (openmpt_mhandle) - { - openmpt_module_destroy(openmpt_mhandle); - openmpt_mhandle = NULL; - } -#endif - if (music) - { - Mix_FreeMusic(music); - music = NULL; - } -} - -boolean I_PlaySong(boolean looping) -{ -#ifdef HAVE_GME - if (gme) - { - gme_equalizer_t eq = {GME_TREBLE, GME_BASS, 0,0,0,0,0,0,0,0}; -#if defined (GME_VERSION) && GME_VERSION >= 0x000603 - if (looping) - gme_set_autoload_playback_limit(gme, 0); -#endif - gme_set_equalizer(gme, &eq); - gme_start_track(gme, 0); - current_track = 0; - Mix_HookMusic(mix_gme, gme); - return true; - } - else -#endif -#ifdef HAVE_OPENMPT - if (openmpt_mhandle) - { - openmpt_module_select_subsong(openmpt_mhandle, 0); - openmpt_module_set_render_param(openmpt_mhandle, OPENMPT_MODULE_RENDER_INTERPOLATIONFILTER_LENGTH, cv_modfilter.value); - if (looping) - openmpt_module_set_repeat_count(openmpt_mhandle, -1); // Always repeat - current_subsong = 0; - Mix_HookMusic(mix_openmpt, openmpt_mhandle); - return true; - } - else -#endif - if (!music) - return false; - - if (fpclassify(song_length) == FP_ZERO && (I_SongType() == MU_OGG || I_SongType() == MU_MP3 || I_SongType() == MU_FLAC)) - CONS_Debug(DBG_DETAILED, "This song is missing a LENGTHMS= tag! Required to make seeking work properly.\n"); - - if (I_SongType() != MU_MOD && Mix_PlayMusic(music, 0) == -1) - { - CONS_Alert(CONS_ERROR, "Mix_PlayMusic: %s\n", Mix_GetError()); - return false; - } - else if ((I_SongType() == MU_MOD || I_SongType() == MU_MID || I_SongType() == MU_MID_EX) && Mix_PlayMusic(music, looping ? -1 : 0) == -1) // if MOD, loop forever - { - CONS_Alert(CONS_ERROR, "Mix_PlayMusic: %s\n", Mix_GetError()); - return false; - } - - is_looping = looping; - - I_SetMusicVolume(music_volume); - - if (I_SongType() != MU_MOD && I_SongType() != MU_MID && I_SongType() != MU_MID_EX) - Mix_HookMusicFinished(music_loop); // don't bother counting if MOD - - if(I_SongType() != MU_MOD && I_SongType() != MU_MID && I_SongType() != MU_MID_EX && !Mix_RegisterEffect(MIX_CHANNEL_POST, count_music_bytes, NULL, NULL)) - CONS_Alert(CONS_WARNING, "Error registering SDL music position counter: %s\n", Mix_GetError()); - - return true; -} - -void I_StopSong(void) -{ - // HACK: See music_loop on why we want fade timing to proceed - // after end of song - if (!fading_nocleanup) - I_StopFadingSong(); - -#ifdef HAVE_GME - if (gme) - { - Mix_HookMusic(NULL, NULL); - current_track = -1; - } -#endif -#ifdef HAVE_OPENMPT - if (openmpt_mhandle) - { - Mix_HookMusic(NULL, NULL); - current_subsong = -1; - } -#endif - if (music) - { - Mix_UnregisterEffect(MIX_CHANNEL_POST, count_music_bytes); - Mix_HookMusicFinished(NULL); - Mix_HaltMusic(); - } - - var_cleanup(); -} - -void I_PauseSong(void) -{ - // really, SRB2? why do you support MIDI??? - - if(I_SongType() != MU_GME && I_SongType() != MU_MOD) - Mix_UnregisterEffect(MIX_CHANNEL_POST, count_music_bytes); - - Mix_PauseMusic(); - songpaused = true; -} - -void I_ResumeSong(void) -{ - if (I_SongType() != MU_GME && I_SongType() != MU_MOD) - { - while(Mix_UnregisterEffect(MIX_CHANNEL_POST, count_music_bytes) != 0) { } - // HACK: fixes issue of multiple effect callbacks being registered - - if(music && I_SongType() != MU_MOD && !Mix_RegisterEffect(MIX_CHANNEL_POST, count_music_bytes, NULL, NULL)) - CONS_Alert(CONS_WARNING, "Error registering SDL music position counter: %s\n", Mix_GetError()); - } - - Mix_ResumeMusic(); - songpaused = false; -} - -void I_SetMusicVolume(int volume) -{ - if (!I_SongPlaying()) - return; - - music_volume = volume; - - Mix_VolumeMusic(attenuate(MIX_MAX_VOLUME)); -} - -boolean I_SetSongTrack(int track) -{ -#ifdef HAVE_GME - // If the specified track is within the number of tracks playing, then change it - if (gme) - { - if (current_track == track) - return false; - SDL_LockAudio(); - if (track >= 0 && track < gme_track_count(gme)-1) - { - gme_err_t gme_e = gme_start_track(gme, track); - if (gme_e != NULL) - { - CONS_Alert(CONS_ERROR, "GME error: %s\n", gme_e); - return false; - } - current_track = track; - SDL_UnlockAudio(); - return true; - } - SDL_UnlockAudio(); - return false; - } - else -#endif -#ifdef HAVE_OPENMPT - if (openmpt_mhandle) - { - if (current_subsong == track) - return false; - SDL_LockAudio(); - if (track >= 0 && track < openmpt_module_get_num_subsongs(openmpt_mhandle)) - { - openmpt_module_select_subsong(openmpt_mhandle, track); - current_subsong = track; - SDL_UnlockAudio(); - return true; - } - SDL_UnlockAudio(); - - return false; - } -#endif - if (I_SongType() == MU_MOD) - return !Mix_SetMusicPosition(track); - (void)track; - return false; -} - -/// ------------------------ -/// MUSIC FADING -/// ------------------------ - -void I_SetInternalMusicVolume(UINT8 volume) -{ - internal_volume = volume; - if (!I_SongPlaying()) - return; - Mix_VolumeMusic(attenuate(MIX_MAX_VOLUME)); -} - -void I_StopFadingSong(void) -{ - if (fading_id) - SDL_RemoveTimer(fading_id); - is_fading = false; - fading_source = fading_target = fading_timer = fading_duration = fading_id = 0; - // don't unset fading_nocleanup here just yet; fading_callback is cleaned up - // in var_cleanup() -} - -boolean I_FadeSongFromVolume(UINT8 target_volume, UINT8 source_volume, UINT32 ms, void (*callback)(void)) -{ - INT16 volume_delta; - - source_volume = min(source_volume, 100); - volume_delta = (INT16)(target_volume - source_volume); - - I_StopFadingSong(); - - if (!ms && volume_delta) - { - I_SetInternalMusicVolume(target_volume); - if (callback) - (*callback)(); - return true; - - } - else if (!volume_delta) - { - if (callback) - (*callback)(); - return true; - } - - // Round MS to nearest 10 - // If n - lower > higher - n, then round up - ms = (ms - ((ms / 10) * 10) > (((ms / 10) * 10) + 10) - ms) ? - (((ms / 10) * 10) + 10) // higher - : ((ms / 10) * 10); // lower - - if (!ms) - I_SetInternalMusicVolume(target_volume); - else if (source_volume != target_volume) - { - fading_id = SDL_AddTimer(10, music_fade, NULL); - if (fading_id) - { - is_fading = true; - fading_timer = fading_duration = ms; - fading_source = source_volume; - fading_target = target_volume; - fading_callback = callback; - - if (internal_volume != source_volume) - I_SetInternalMusicVolume(source_volume); - } - } - - return is_fading; -} - -boolean I_FadeSong(UINT8 target_volume, UINT32 ms, void (*callback)(void)) -{ - return I_FadeSongFromVolume(target_volume, internal_volume, ms, callback); -} - -boolean I_FadeOutStopSong(UINT32 ms) -{ - return I_FadeSongFromVolume(0, internal_volume, ms, &I_StopSong); -} - -boolean I_FadeInPlaySong(UINT32 ms, boolean looping) -{ - if (I_PlaySong(looping)) - return I_FadeSongFromVolume(100, 0, ms, NULL); - else - return false; -} -#endif diff --git a/src/sdl/new_sound.cpp b/src/sdl/new_sound.cpp index b3bb1c71b..4a8eda0db 100644 --- a/src/sdl/new_sound.cpp +++ b/src/sdl/new_sound.cpp @@ -8,11 +8,12 @@ // See the 'LICENSE' file for more details. //----------------------------------------------------------------------------- +#include #include #include #include -#include +#include #include #include "../audio/chunk_load.hpp" @@ -23,7 +24,6 @@ #include "../audio/sound_chunk.hpp" #include "../audio/sound_effect_player.hpp" #include "../cxxutil.hpp" -#include "../io/streams.hpp" #ifdef SRB2_CONFIG_ENABLE_WEBM_MOVIES #include "../m_avrecorder.hpp" @@ -52,7 +52,6 @@ using srb2::audio::SoundChunk; using srb2::audio::SoundEffectPlayer; using srb2::audio::Source; using namespace srb2; -using namespace srb2::io; namespace { @@ -62,7 +61,15 @@ class SdlAudioStream final public: SdlAudioStream(const SDL_AudioFormat format, const Uint8 channels, const int src_rate, const SDL_AudioFormat dst_format, const Uint8 dst_channels, const int dst_rate) noexcept { - stream_ = SDL_NewAudioStream(format, channels, src_rate, dst_format, dst_channels, dst_rate); + SDL_AudioSpec src {}; + src.channels = channels; + src.freq = src_rate; + src.format = format; + SDL_AudioSpec dst {}; + dst.channels = dst_channels; + dst.freq = dst_rate; + dst.format = dst_format; + stream_ = SDL_CreateAudioStream(&src, &dst); } SdlAudioStream(const SdlAudioStream&) = delete; SdlAudioStream(SdlAudioStream&&) = default; @@ -70,27 +77,28 @@ public: SdlAudioStream& operator=(SdlAudioStream&&) = default; ~SdlAudioStream() { - SDL_FreeAudioStream(stream_); + SDL_DestroyAudioStream(stream_); } void put(tcb::span buf) { - int result = SDL_AudioStreamPut(stream_, buf.data(), buf.size_bytes()); - if (result < 0) + if (!SDL_PutAudioStreamData(stream_, buf.data(), buf.size_bytes())) { char errbuf[512]; - SDL_GetErrorMsg(errbuf, sizeof(errbuf)); + SDL_strlcpy(errbuf, SDL_GetError(), sizeof(errbuf) - 1); + errbuf[sizeof(errbuf) - 1] = '\0'; throw std::runtime_error(errbuf); } } size_t available() const { - int result = SDL_AudioStreamAvailable(stream_); + int result = SDL_GetAudioStreamAvailable(stream_); if (result < 0) { char errbuf[512]; - SDL_GetErrorMsg(errbuf, sizeof(errbuf)); + SDL_strlcpy(errbuf, SDL_GetError(), sizeof(errbuf) - 1); + errbuf[sizeof(errbuf) - 1] = '\0'; throw std::runtime_error(errbuf); } return result; @@ -98,11 +106,12 @@ public: size_t get(tcb::span out) { - int result = SDL_AudioStreamGet(stream_, out.data(), out.size_bytes()); + int result = SDL_GetAudioStreamData(stream_, out.data(), out.size_bytes()); if (result < 0) { char errbuf[512]; - SDL_GetErrorMsg(errbuf, sizeof(errbuf)); + SDL_strlcpy(errbuf, SDL_GetError(), sizeof(errbuf) - 1); + errbuf[sizeof(errbuf) - 1] = '\0'; throw std::runtime_error(errbuf); } return result; @@ -110,7 +119,7 @@ public: void clear() noexcept { - SDL_AudioStreamClear(stream_); + SDL_ClearAudioStream(stream_); } }; @@ -122,7 +131,7 @@ class SdlVoiceStreamPlayer : public Source<2> bool terminal_ = true; public: - SdlVoiceStreamPlayer() : stream_(AUDIO_F32SYS, 1, 48000, AUDIO_F32SYS, 2, 44100) {} + SdlVoiceStreamPlayer() : stream_(SDL_AUDIO_F32, 1, 48000, SDL_AUDIO_F32, 2, 44100) {} virtual ~SdlVoiceStreamPlayer() = default; virtual std::size_t generate(tcb::span> buffer) override @@ -197,9 +206,9 @@ static shared_ptr av_recorder; static void (*music_fade_callback)(); -static SDL_AudioDeviceID g_device_id; -static SDL_AudioDeviceID g_input_device_id; -static SDL_mutex* microphone_mutex = nullptr; +static SDL_AudioStream* g_output_stream; +static SDL_AudioStream* g_input_stream; +static SDL_Mutex* microphone_mutex = nullptr; static SDL_Thread* microphone_thread = nullptr; void* I_GetSfx(sfxinfo_t* sfx) @@ -248,39 +257,42 @@ namespace class SdlAudioLockHandle { public: - SdlAudioLockHandle() { SDL_LockAudioDevice(g_device_id); } - ~SdlAudioLockHandle() { SDL_UnlockAudioDevice(g_device_id); } + SdlAudioLockHandle() { SDL_LockAudioStream(g_output_stream); } + ~SdlAudioLockHandle() { SDL_UnlockAudioStream(g_output_stream); } }; #ifdef TRACY_ENABLE static const char* kAudio = "Audio"; #endif -void audio_callback(void* userdata, Uint8* buffer, int len) +void audio_callback(void* userdata, SDL_AudioStream* stream, int add, int total) { tracy::SetThreadName("SDL Audio Thread"); FrameMarkStart(kAudio); ZoneScoped; + if (add <= 0) + return; floatdenormalstate_t dtzstate = M_EnterFloatDenormalToZero(); auto dtzrestore = srb2::finally([dtzstate] { M_ExitFloatDenormalToZero(dtzstate); }); - // The SDL Audio lock is implied to be held during callback. + if (!master_gain) + { + FrameMarkEnd(kAudio); + return; + } + + static std::array, 2048> float_buffer = {}; + + SDL_LockAudioStream(stream); try { - Sample<2>* float_buffer = reinterpret_cast*>(buffer); - size_t float_len = len / 8; - + size_t float_len = std::min(float_buffer.size(), add / sizeof(Sample<2>)); for (size_t i = 0; i < float_len; i++) { float_buffer[i] = Sample<2> {0.f, 0.f}; } - - if (!master_gain) - return; - - master_gain->generate(tcb::span {float_buffer, float_len}); - + master_gain->generate(tcb::span {float_buffer.data(), float_len}); for (size_t i = 0; i < float_len; i++) { float_buffer[i] = { @@ -290,13 +302,16 @@ void audio_callback(void* userdata, Uint8* buffer, int len) } #ifdef SRB2_CONFIG_ENABLE_WEBM_MOVIES if (av_recorder) - av_recorder->push_audio_samples(tcb::span {float_buffer, float_len}); + av_recorder->push_audio_samples(tcb::span {float_buffer.data(), float_len}); #endif + SDL_PutAudioStreamData(stream, float_buffer.data(), float_len * sizeof(Sample<2>)); } catch (...) { } + SDL_UnlockAudioStream(stream); + FrameMarkEnd(kAudio); return; @@ -304,27 +319,25 @@ void audio_callback(void* userdata, Uint8* buffer, int len) void initialize_sound() { - if (SDL_InitSubSystem(SDL_INIT_AUDIO) < 0) + if (!SDL_InitSubSystem(SDL_INIT_AUDIO)) { CONS_Alert(CONS_ERROR, "Error initializing SDL Audio: %s\n", SDL_GetError()); return; } SDL_AudioSpec desired {}; - desired.format = AUDIO_F32SYS; + desired.format = SDL_AUDIO_F32; desired.channels = 2; - desired.samples = cv_soundmixingbuffersize.value; + // desired.samples = cv_soundmixingbuffersize.value; desired.freq = 44100; - desired.callback = audio_callback; - if ((g_device_id = SDL_OpenAudioDevice(NULL, SDL_FALSE, &desired, NULL, 0)) == 0) + if ((g_output_stream = SDL_OpenAudioDeviceStream(SDL_AUDIO_DEVICE_DEFAULT_PLAYBACK, &desired, audio_callback, nullptr)) == 0) { CONS_Alert(CONS_ERROR, "Failed to open SDL Audio device: %s\n", SDL_GetError()); SDL_QuitSubSystem(SDL_INIT_AUDIO); return; } - - SDL_PauseAudioDevice(g_device_id, SDL_FALSE); + SDL_ResumeAudioStreamDevice(g_output_stream); { SdlAudioLockHandle _; @@ -380,16 +393,16 @@ void I_StartupSound(void) void I_ShutdownSound(void) { - if (g_device_id) + if (g_output_stream) { - SDL_CloseAudioDevice(g_device_id); - g_device_id = 0; + SDL_DestroyAudioStream(g_output_stream); + g_output_stream = nullptr; } SDL_LockMutex(microphone_mutex); - if (g_input_device_id) + if (g_input_stream) { - SDL_CloseAudioDevice(g_input_device_id); - g_input_device_id = 0; + SDL_DestroyAudioStream(g_input_stream); + g_input_stream = nullptr; } SDL_UnlockMutex(microphone_mutex); @@ -1008,7 +1021,7 @@ void I_UpdateAudioRecorder(void) boolean I_SoundInputIsEnabled(void) { SDL_LockMutex(microphone_mutex); - boolean ret = g_input_device_id != 0; + boolean ret = g_input_stream != nullptr; SDL_UnlockMutex(microphone_mutex); return ret; } @@ -1016,25 +1029,17 @@ boolean I_SoundInputIsEnabled(void) static int microphone_opener(void* data) { SDL_AudioSpec input_desired {}; - input_desired.format = AUDIO_F32SYS; + input_desired.format = SDL_AUDIO_F32; input_desired.channels = 1; - input_desired.samples = 1024; input_desired.freq = 48000; - SDL_AudioSpec input_obtained {}; - SDL_AudioDeviceID device_id = SDL_OpenAudioDevice(nullptr, SDL_TRUE, &input_desired, &input_obtained, 0); - if (!device_id) + SDL_AudioStream* stream = SDL_OpenAudioDeviceStream(SDL_AUDIO_DEVICE_DEFAULT_RECORDING, &input_desired, nullptr, nullptr); + if (!stream) { - // CONS_Alert(CONS_WARNING, "Failed to open input audio device: %s\n", SDL_GetError()); return 0; } - if (input_obtained.freq != 48000 || input_obtained.format != AUDIO_F32SYS || input_obtained.channels != 1) - { - // CONS_Alert(CONS_WARNING, "Input audio device has unexpected unusable format: %s\n", SDL_GetError()); - return 0; - } - SDL_PauseAudioDevice(device_id, SDL_FALSE); + SDL_ResumeAudioStreamDevice(stream); SDL_LockMutex(microphone_mutex); - g_input_device_id = device_id; + g_input_stream = stream; SDL_UnlockMutex(microphone_mutex); return 0; } @@ -1043,9 +1048,13 @@ boolean I_SoundInputSetEnabled(boolean enabled) { SDL_LockMutex(microphone_mutex); - if (g_input_device_id == 0 && enabled) + if (g_input_stream == nullptr && enabled) { - if (!sound_started || SDL_GetNumAudioDevices(true) == 0) + int recording_devices = 0; + SDL_AudioDeviceID* device_ids; + device_ids = SDL_GetAudioRecordingDevices(&recording_devices); + SDL_free(device_ids); + if (!sound_started || recording_devices == 0) { SDL_UnlockMutex(microphone_mutex); return false; @@ -1053,13 +1062,13 @@ boolean I_SoundInputSetEnabled(boolean enabled) SDL_CreateThread(microphone_opener, "Microphone Opener", nullptr); } - else if (g_input_device_id != 0 && !enabled) + else if (g_input_stream != nullptr && !enabled) { microphone_thread = nullptr; - SDL_PauseAudioDevice(g_input_device_id, SDL_TRUE); - SDL_ClearQueuedAudio(g_input_device_id); - SDL_CloseAudioDevice(g_input_device_id); - g_input_device_id = 0; + SDL_PauseAudioStreamDevice(g_input_stream); + SDL_ClearAudioStream(g_input_stream); + SDL_DestroyAudioStream(g_input_stream); + g_input_stream = nullptr; } SDL_UnlockMutex(microphone_mutex); @@ -1070,13 +1079,13 @@ boolean I_SoundInputSetEnabled(boolean enabled) UINT32 I_SoundInputDequeueSamples(void *data, UINT32 len) { SDL_LockMutex(microphone_mutex); - if (!g_input_device_id) + if (!g_input_stream) { SDL_UnlockMutex(microphone_mutex); return 0; } - UINT32 ret = SDL_DequeueAudio(g_input_device_id, data, len); + UINT32 ret = SDL_GetAudioStreamData(g_input_stream, data, len); SDL_UnlockMutex(microphone_mutex); return ret; } @@ -1084,12 +1093,12 @@ UINT32 I_SoundInputDequeueSamples(void *data, UINT32 len) UINT32 I_SoundInputRemainingSamples(void) { SDL_LockMutex(microphone_mutex); - if (!g_input_device_id) + if (!g_input_stream) { SDL_UnlockMutex(microphone_mutex); return 0; } - UINT32 avail = SDL_GetQueuedAudioSize(g_input_device_id); + UINT32 avail = SDL_GetAudioStreamAvailable(g_input_stream); SDL_UnlockMutex(microphone_mutex); return avail / sizeof(float); } diff --git a/src/sdl/ogl_sdl.c b/src/sdl/ogl_sdl.c index 73433b98f..2a5300f6c 100644 --- a/src/sdl/ogl_sdl.c +++ b/src/sdl/ogl_sdl.c @@ -18,7 +18,13 @@ #ifdef HAVE_SDL #define _MATH_DEFINES_DEFINED -#include "SDL.h" +/* + * TODO ISO C forbids converting object pointers to function pointers and vice versa. + * The existing legacy GL code still uses void pointers though, so to clear the warning we need + * to tell SDL3 to declare SDL_FunctionPointer as void*. +*/ +#define SDL_FUNCTION_POINTER_IS_VOID_POINTER +#include #include "sdlmain.h" @@ -76,7 +82,7 @@ void *GetGLFunc(const char *proc) else return NULL; } - return SDL_GL_GetProcAddress(proc); + return (void*)SDL_GL_GetProcAddress(proc); } boolean LoadGL(void) @@ -94,7 +100,7 @@ boolean LoadGL(void) if (M_CheckParm("-OGLlib") && M_IsNextParm()) OGLLibname = M_GetNextParm(); - if (SDL_GL_LoadLibrary(OGLLibname) != 0) + if (!SDL_GL_LoadLibrary(OGLLibname)) { CONS_Alert(CONS_ERROR, "Could not load OpenGL Library: %s\n" "Falling back to Software mode.\n", SDL_GetError()); diff --git a/src/sdl/ogl_sdl.h b/src/sdl/ogl_sdl.h index c38cdb6a2..1e9b54188 100644 --- a/src/sdl/ogl_sdl.h +++ b/src/sdl/ogl_sdl.h @@ -15,7 +15,7 @@ #ifndef __SDL_OGL_SDL_H__ #define __SDL_OGL_SDL_H__ -#include +#include #include "../v_video.h" diff --git a/src/sdl/rhi_gl2_platform.cpp b/src/sdl/rhi_gl2_platform.cpp index f3f10fe90..beef7f681 100644 --- a/src/sdl/rhi_gl2_platform.cpp +++ b/src/sdl/rhi_gl2_platform.cpp @@ -14,7 +14,7 @@ #include #include -#include +#include #include "../core/string.h" #include "../core/vector.hpp" @@ -118,6 +118,6 @@ rhi::Rect SdlGl2Platform::get_default_framebuffer_dimensions() SRB2_ASSERT(window != nullptr); int w; int h; - SDL_GL_GetDrawableSize(window, &w, &h); + SDL_GetWindowSizeInPixels(window, &w, &h); return {0, 0, static_cast(w), static_cast(h)}; } diff --git a/src/sdl/rhi_gl2_platform.hpp b/src/sdl/rhi_gl2_platform.hpp index acaf48618..7b81a125f 100644 --- a/src/sdl/rhi_gl2_platform.hpp +++ b/src/sdl/rhi_gl2_platform.hpp @@ -18,7 +18,7 @@ #include "../rhi/gl2/gl2_rhi.hpp" #include "../rhi/rhi.hpp" -#include +#include namespace srb2::rhi { diff --git a/src/sdl/rhi_gles2_platform.cpp b/src/sdl/rhi_gles2_platform.cpp index 8fc70feff..cefa89221 100644 --- a/src/sdl/rhi_gles2_platform.cpp +++ b/src/sdl/rhi_gles2_platform.cpp @@ -10,7 +10,7 @@ #include "rhi_gles2_platform.hpp" -#include +#include #include "../cxxutil.hpp" #include "../w_wad.h" @@ -65,6 +65,6 @@ rhi::Rect SdlGles2Platform::get_default_framebuffer_dimensions() SRB2_ASSERT(window != nullptr); int w; int h; - SDL_GL_GetDrawableSize(window, &w, &h); + SDL_GetWindowSizeInPixels(window, &w, &h); return {0, 0, static_cast(w), static_cast(h)}; } diff --git a/src/sdl/rhi_gles2_platform.hpp b/src/sdl/rhi_gles2_platform.hpp index 99c56cbe8..0be314f18 100644 --- a/src/sdl/rhi_gles2_platform.hpp +++ b/src/sdl/rhi_gles2_platform.hpp @@ -14,7 +14,7 @@ #include "../rhi/gles2/gles2_rhi.hpp" #include "../rhi/rhi.hpp" -#include +#include namespace srb2::rhi { diff --git a/src/sdl/sdl_sound.c b/src/sdl/sdl_sound.c deleted file mode 100644 index 2637be3a0..000000000 --- a/src/sdl/sdl_sound.c +++ /dev/null @@ -1,1582 +0,0 @@ -// DR. ROBOTNIK'S RING RACERS -//----------------------------------------------------------------------------- -// Copyright (C) 2025 by Kart Krew. -// Copyright (C) 2020 by Sonic Team Junior. -// Copyright (C) 1996 by id Software, Inc. -// -// This program is free software distributed under the -// terms of the GNU General Public License, version 2. -// See the 'LICENSE' file for more details. -//----------------------------------------------------------------------------- -/// \file -/// \brief SDL interface for sound - -#include -#include "../doomdef.h" - -#ifdef _MSC_VER -#pragma warning(disable : 4214 4244) -#endif - -#if defined(HAVE_SDL) && SOUND==SOUND_SDL - -#include "SDL.h" - -#ifdef _MSC_VER -#pragma warning(default : 4214 4244) -#endif - -#ifdef HAVE_MIXER -#include -/* This is the version number macro for the current SDL_mixer version: */ -#ifndef SDL_MIXER_COMPILEDVERSION -#define SDL_MIXER_COMPILEDVERSION \ - SDL_VERSIONNUM(MIX_MAJOR_VERSION, MIX_MINOR_VERSION, MIX_PATCHLEVEL) -#endif - -/* This macro will evaluate to true if compiled with SDL_mixer at least X.Y.Z */ -#ifndef SDL_MIXER_VERSION_ATLEAST -#define SDL_MIXER_VERSION_ATLEAST(X, Y, Z) \ - (SDL_MIXER_COMPILEDVERSION >= SDL_VERSIONNUM(X, Y, Z)) -#endif - -#else -#define MIX_CHANNELS 8 -#endif - -#ifdef _WIN32 -#include -#elif defined (__GNUC__) -#include -#endif -#include "../z_zone.h" - -#include "../m_swap.h" -#include "../i_system.h" -#include "../i_sound.h" -#include "../m_argv.h" -#include "../m_misc.h" -#include "../w_wad.h" -#include "../screen.h" //vid.WndParent -#include "../doomdef.h" -#include "../doomstat.h" -#include "../s_sound.h" - -#include "../d_main.h" - -#ifdef HW3SOUND -#include "../hardware/hw3dsdrv.h" -#include "../hardware/hw3sound.h" -#include "hwsym_sdl.h" -#endif - -#ifdef HAVE_LIBGME -#include "gme/gme.h" -#endif - -// The number of internal mixing channels, -// the samples calculated for each mixing step, -// the size of the 16bit, 2 hardware channel (stereo) -// mixing buffer, and the samplerate of the raw data. - -// Needed for calling the actual sound output. -#define NUM_CHANNELS MIX_CHANNELS*4 - -#define INDEXOFSFX(x) ((sfxinfo_t *)x - S_sfx) - -static Uint16 samplecount = 1024; //Alam: 1KB samplecount at 22050hz is 46.439909297052154195011337868481ms of buffer - -typedef struct chan_struct -{ - // The channel data pointers, start and end. - Uint8 *data; //static unsigned char *channels[NUM_CHANNELS]; - Uint8 *end; //static unsigned char *channelsend[NUM_CHANNELS]; - - // pitch - Uint32 realstep; // The channel step amount... - Uint32 step; //static UINT32 channelstep[NUM_CHANNELS]; - Uint32 stepremainder; //static UINT32 channelstepremainder[NUM_CHANNELS]; - Uint32 samplerate; // ... and a 0.16 bit remainder of last step. - - // Time/gametic that the channel started playing, - // used to determine oldest, which automatically - // has lowest priority. - tic_t starttic; //static INT32 channelstart[NUM_CHANNELS]; - - // The sound handle, determined on registration, - // used to unregister/stop/modify, - INT32 handle; //static INT32 channelhandles[NUM_CHANNELS]; - - // SFX id of the playing sound effect. - void *id; // Used to catch duplicates (like chainsaw). - sfxenum_t sfxid; //static INT32 channelids[NUM_CHANNELS]; - INT32 vol; //the channel volume - INT32 sep; //the channel pan - - // Hardware left and right channel volume lookup. - Sint16* leftvol_lookup; //static INT32 *channelleftvol_lookup[NUM_CHANNELS]; - Sint16* rightvol_lookup; //static INT32 *channelrightvol_lookup[NUM_CHANNELS]; -} chan_t; - -static chan_t channels[NUM_CHANNELS]; - -// Pitch to stepping lookup -static INT32 steptable[256]; - -// Volume lookups. -static Sint16 vol_lookup[128 * 256]; - -UINT8 sound_started = false; -static SDL_mutex *Snd_Mutex = NULL; - -//SDL's Audio -static SDL_AudioSpec audio; - -static SDL_bool musicStarted = SDL_FALSE; -#ifdef HAVE_MIXER -static SDL_mutex *Msc_Mutex = NULL; -/* FIXME: Make this file instance-specific */ -#define MIDI_PATH srb2home -#if defined (__unix__) || defined(__APPLE__) || defined (UNIXCOMMON) -#define MIDI_PATH2 "/tmp" -#endif -#define MIDI_TMPFILE "srb2music" -#define MIDI_TMPFILE2 "srb2wav" -static INT32 musicvol = 62; - -#if SDL_MIXER_VERSION_ATLEAST(1,2,2) -#define MIXER_POS //Mix_FadeInMusicPos in 1.2.2+ -static void SDLCALL I_FinishMusic(void); -static double loopstartDig = 0.0l; -static SDL_bool loopingDig = SDL_FALSE; -static SDL_bool canlooping = SDL_TRUE; -#endif - -#if SDL_MIXER_VERSION_ATLEAST(1,2,7) -#define USE_RWOPS // ok, USE_RWOPS is in here -#if 0 // defined(_WIN32) -#undef USE_RWOPS -#endif -#endif - -#if SDL_MIXER_VERSION_ATLEAST(1,2,10) -//#define MIXER_INIT -#endif - -#ifdef USE_RWOPS -static void * Smidi[2] = { NULL, NULL }; -static SDL_bool canuseRW = SDL_TRUE; -#endif -static const char *fmidi[2] = { MIDI_TMPFILE, MIDI_TMPFILE2}; - -static const INT32 MIDIfade = 500; -static const INT32 Digfade = 0; - -static Mix_Music *music[2] = { NULL, NULL }; -#endif - -typedef struct srb2audio_s { - void *userdata; -#ifdef HAVE_LIBGME - Music_Emu *gme_emu; - UINT8 gme_pause; - UINT8 gme_loop; -#endif -} srb2audio_t; - -static srb2audio_t localdata; - -static void Snd_LockAudio(void) //Alam: Lock audio data and uninstall audio callback -{ - if (Snd_Mutex) SDL_LockMutex(Snd_Mutex); - else if (sound_disabled) return; - else if (digital_disabled -#ifdef HW3SOUND - && hws_mode == HWS_DEFAULT_MODE -#endif - ) SDL_LockAudio(); -#ifdef HAVE_MIXER - else if (musicStarted) Mix_SetPostMix(NULL, NULL); -#endif -} - -static void Snd_UnlockAudio(void) //Alam: Unlock audio data and reinstall audio callback -{ - if (Snd_Mutex) SDL_UnlockMutex(Snd_Mutex); - else if (sound_disabled) return; - else if (digital_disabled -#ifdef HW3SOUND - && hws_mode == HWS_DEFAULT_MODE -#endif - ) SDL_UnlockAudio(); -#ifdef HAVE_MIXER - else if (musicStarted) Mix_SetPostMix(audio.callback, audio.userdata); -#endif -} - -static inline Uint16 Snd_LowerRate(Uint16 sr) -{ - if (sr <= audio.freq) // already lowered rate? - return sr; // good then - for (;sr > audio.freq;) // not good? - { // then let see... - if (sr % 2) // can we div by half? - return sr; // no, just use the currect rate - sr /= 2; // we can? wonderful - } // let start over again - if (sr == audio.freq) // did we drop to the desired rate? - return sr; // perfect! but if not - return sr*2; // just keep it just above the output sample rate -} - -#ifdef _MSC_VER -#pragma warning(disable : 4200) -#pragma pack(1) -#endif - -typedef struct -{ - Uint16 header; // 3? - Uint16 samplerate; // 11025+ - Uint16 samples; // number of samples - Uint16 dummy; // 0 - Uint8 data[0]; // data; -} ATTRPACK dssfx_t; - -#ifdef _MSC_VER -#pragma pack() -#pragma warning(default : 4200) -#endif - -// -// This function loads the sound data from the WAD lump, -// for single sound. -// -static void *getsfx(lumpnum_t sfxlump, size_t *len) -{ - dssfx_t *sfx, *paddedsfx; - Uint16 sr , csr; - size_t size = *len; - SDL_AudioCVT sfxcvt; - - sfx = (dssfx_t *)malloc(size); - if (sfx) W_ReadLump(sfxlump, (void *)sfx); - else return NULL; - sr = SHORT(sfx->samplerate); - csr = Snd_LowerRate(sr); - - if (sr > csr && SDL_BuildAudioCVT(&sfxcvt, AUDIO_U8, 1, sr, AUDIO_U8, 1, csr)) - {//Alam: Setup the AudioCVT for the SFX - - sfxcvt.len = (INT32)size-8; //Alam: Chop off the header - sfxcvt.buf = malloc(sfxcvt.len * sfxcvt.len_mult); //Alam: make room - if (sfxcvt.buf) M_Memcpy(sfxcvt.buf, &(sfx->data), sfxcvt.len); //Alam: copy the sfx sample - - if (sfxcvt.buf && SDL_ConvertAudio(&sfxcvt) == 0) //Alam: let convert it! - { - size = sfxcvt.len_cvt + 8; - *len = sfxcvt.len_cvt; - - // Allocate from zone memory. - paddedsfx = (dssfx_t *) Z_Malloc(size, PU_SOUND, NULL); - - // Now copy and pad. - M_Memcpy(paddedsfx->data, sfxcvt.buf, sfxcvt.len_cvt); - free(sfxcvt.buf); - M_Memcpy(paddedsfx,sfx,8); - paddedsfx->samplerate = SHORT(csr); // new freq - } - else //Alam: the convert failed, not needed or I couldn't malloc the buf - { - if (sfxcvt.buf) free(sfxcvt.buf); - *len = size - 8; - - // Allocate from zone memory then copy and pad - paddedsfx = (dssfx_t *)M_Memcpy(Z_Malloc(size, PU_SOUND, NULL), sfx, size); - } - } - else - { - // Pads the sound effect out to the mixing buffer size. - // The original realloc would interfere with zone memory. - *len = size - 8; - - // Allocate from zone memory then copy and pad - paddedsfx = (dssfx_t *)M_Memcpy(Z_Malloc(size, PU_SOUND, NULL), sfx, size); - } - - // Remove the cached lump. - free(sfx); - - // Return allocated padded data. - return paddedsfx; -} - -// used to (re)calculate channel params based on vol, sep, pitch -static void I_SetChannelParams(chan_t *c, INT32 vol, INT32 sep, INT32 step) -{ - INT32 leftvol; - INT32 rightvol; - c->vol = vol; - c->sep = sep; - c->step = c->realstep = step; - - if (step != steptable[128]) - c->step += (((c->samplerate<<16)/audio.freq)-65536); - else if (c->samplerate != (unsigned)audio.freq) - c->step = ((c->samplerate<<16)/audio.freq); - // x^2 separation, that is, orientation/stereo. - // range is: 0 (left) - 255 (right) - - // Volume arrives in range 0..255 and it must be in 0..cv_soundvolume... - vol = (vol * cv_soundvolume.value) >> 7; - // note: >> 6 would use almost the entire dynamical range, but - // then there would be no "dynamical room" for other sounds :-/ - - leftvol = vol - ((vol*sep*sep) >> 16); ///(256*256); - sep = 255 - sep; - rightvol = vol - ((vol*sep*sep) >> 16); - - // Sanity check, clamp volume. - if (rightvol < 0) - rightvol = 0; - else if (rightvol > 127) - rightvol = 127; - if (leftvol < 0) - leftvol = 0; - else if (leftvol > 127) - leftvol = 127; - - // Get the proper lookup table piece - // for this volume level - c->leftvol_lookup = &vol_lookup[leftvol*256]; - c->rightvol_lookup = &vol_lookup[rightvol*256]; -} - -static INT32 FindChannel(INT32 handle) -{ - INT32 i; - - for (i = 0; i < NUM_CHANNELS; i++) - if (channels[i].handle == handle) - return i; - - // not found - return -1; -} - -// -// This function adds a sound to the -// list of currently active sounds, -// which is maintained as a given number -// (eight, usually) of internal channels. -// Returns a handle. -// -static INT32 addsfx(sfxenum_t sfxid, INT32 volume, INT32 step, INT32 seperation) -{ - static UINT16 handlenums = 0; - INT32 i, slot, oldestnum = 0; - tic_t oldest = gametic; - - // Play these sound effects only one at a time. -#if 1 - if ( -#if 0 - sfxid == sfx_stnmov || sfxid == sfx_sawup || sfxid == sfx_sawidl || sfxid == sfx_sawful || sfxid == sfx_sawhit || sfxid == sfx_pistol -#else - ( sfx_litng1 <= sfxid && sfxid >= sfx_litng4 ) - || sfxid == sfx_trfire || sfxid == sfx_alarm || sfxid == sfx_spin - || sfxid == sfx_athun1 || sfxid == sfx_athun2 || sfxid == sfx_rainin -#endif - ) - { - // Loop all channels, check. - for (i = 0; i < NUM_CHANNELS; i++) - { - // Active, and using the same SFX? - if ((channels[i].end) && (channels[i].sfxid == sfxid)) - { - // Reset. - channels[i].end = NULL; - // We are sure that iff, - // there will only be one. - break; - } - } - } -#endif - - // Loop all channels to find oldest SFX. - for (i = 0; (i < NUM_CHANNELS) && (channels[i].end); i++) - { - if (channels[i].starttic < oldest) - { - oldestnum = i; - oldest = channels[i].starttic; - } - } - - // Tales from the cryptic. - // If we found a channel, fine. - // If not, we simply overwrite the first one, 0. - // Probably only happens at startup. - if (i == NUM_CHANNELS) - slot = oldestnum; - else - slot = i; - - channels[slot].end = NULL; - // Okay, in the less recent channel, - // we will handle the new SFX. - // Set pointer to raw data. - channels[slot].data = (Uint8 *)S_sfx[sfxid].data; - channels[slot].samplerate = (channels[slot].data[3]<<8)+channels[slot].data[2]; - channels[slot].data += 8; //Alam: offset of the sound header - - while (FindChannel(handlenums)!=-1) - { - handlenums++; - // Reset current handle number, limited to 0..65535. - if (handlenums == UINT16_MAX) - handlenums = 0; - } - - // Assign current handle number. - // Preserved so sounds could be stopped. - channels[slot].handle = handlenums; - - // Restart steper - channels[slot].stepremainder = 0; - // Should be gametic, I presume. - channels[slot].starttic = gametic; - - I_SetChannelParams(&channels[slot], volume, seperation, step); - - // Preserve sound SFX id, - // e.g. for avoiding duplicates of chainsaw. - channels[slot].id = S_sfx[sfxid].data; - - channels[slot].sfxid = sfxid; - - // Set pointer to end of raw data. - channels[slot].end = channels[slot].data + S_sfx[sfxid].length; - - - // You tell me. - return handlenums; -} - -// -// SFX API -// Note: this was called by S_Init. -// However, whatever they did in the -// old DPMS based DOS version, this -// were simply dummies in the Linux -// version. -// See soundserver initdata(). -// -// Well... To keep compatibility with legacy doom, I have to call this in -// I_InitSound since it is not called in S_Init... (emanne@absysteme.fr) - -static inline void I_SetChannels(void) -{ - // Init internal lookups (raw data, mixing buffer, channels). - // This function sets up internal lookups used during - // the mixing process. - INT32 i; - INT32 j; - - INT32 *steptablemid = steptable + 128; - - if (sound_disabled) - return; - - // This table provides step widths for pitch parameters. - for (i = -128; i < 128; i++) - { - const double po = pow((double)(2.0l), (double)(i / 64.0l)); - steptablemid[i] = (INT32)(po * 65536.0l); - } - - // Generates volume lookup tables - // which also turn the unsigned samples - // into signed samples. - for (i = 0; i < 128; i++) - for (j = 0; j < 256; j++) - { - //From PrDoom - // proff - made this a little bit softer, because with - // full volume the sound clipped badly - vol_lookup[i * 256 + j] = (Sint16)((i * (j - 128) * 256) / 127); - } -} - -void I_SetSfxVolume(int volume) -{ - INT32 i; - - (void)volume; - //Snd_LockAudio(); - - for (i = 0; i < NUM_CHANNELS; i++) - if (channels[i].end) I_SetChannelParams(&channels[i], channels[i].vol, channels[i].sep, channels[i].realstep); - - //Snd_UnlockAudio(); -} - -void *I_GetSfx(sfxinfo_t *sfx) -{ - if (sfx->lumpnum == LUMPERROR) - sfx->lumpnum = S_GetSfxLumpNum(sfx); -// else if (sfx->lumpnum != S_GetSfxLumpNum(sfx)) -// I_FreeSfx(sfx); - -#ifdef HW3SOUND - if (hws_mode != HWS_DEFAULT_MODE) - return HW3S_GetSfx(sfx); -#endif - - if (sfx->data) - return sfx->data; //Alam: I have it done! - - sfx->length = W_LumpLength(sfx->lumpnum); - - return getsfx(sfx->lumpnum, &sfx->length); - -} - -void I_FreeSfx(sfxinfo_t * sfx) -{ -// if (sfx->lumpnum<0) -// return; - -#ifdef HW3SOUND - if (hws_mode != HWS_DEFAULT_MODE) - { - HW3S_FreeSfx(sfx); - } - else -#endif - { - size_t i; - - for (i = 1; i < NUMSFX; i++) - { - // Alias? Example is the chaingun sound linked to pistol. - if (S_sfx[i].data == sfx->data) - { - if (S_sfx+i != sfx) S_sfx[i].data = NULL; - S_sfx[i].lumpnum = LUMPERROR; - S_sfx[i].length = 0; - } - } - //Snd_LockAudio(); //Alam: too much? - // Loop all channels, check. - for (i = 0; i < NUM_CHANNELS; i++) - { - // Active, and using the same SFX? - if (channels[i].end && channels[i].id == sfx->data) - { - channels[i].end = NULL; // Reset. - } - } - //Snd_UnlockAudio(); //Alam: too much? - Z_Free(sfx->data); - } - sfx->data = NULL; - sfx->lumpnum = LUMPERROR; -} - -// -// Starting a sound means adding it -// to the current list of active sounds -// in the internal channels. -// As the SFX info struct contains -// e.g. a pointer to the raw data, -// it is ignored. -// As our sound handling does not handle -// priority, it is ignored. -// Pitching (that is, increased speed of playback) -// is set, but currently not used by mixing. -// -INT32 I_StartSound(sfxenum_t id, UINT8 vol, UINT8 sep, UINT8 pitch, UINT8 priority, INT32 channel) -{ - (void)priority; - (void)pitch; - (void)channel; - - if (sound_disabled) - return 0; - - if (S_sfx[id].data == NULL) return -1; - - Snd_LockAudio(); - id = addsfx(id, vol, steptable[pitch], sep); - Snd_UnlockAudio(); - - return id; // Returns a handle (not used). -} - -void I_StopSound(INT32 handle) -{ - // You need the handle returned by StartSound. - // Would be looping all channels, - // tracking down the handle, - // an setting the channel to zero. - INT32 i; - - i = FindChannel(handle); - - if (i != -1) - { - //Snd_LockAudio(); //Alam: too much? - channels[i].end = NULL; - //Snd_UnlockAudio(); //Alam: too much? - channels[i].handle = -1; - channels[i].starttic = 0; - } - -} - -boolean I_SoundIsPlaying(INT32 handle) -{ - boolean isplaying = false; - int chan = FindChannel(handle); - if (chan != -1) - isplaying = (channels[chan].end != NULL); - return isplaying; -} - -FUNCINLINE static ATTRINLINE void I_UpdateStream8S(Uint8 *stream, int len) -{ - // Mix current sound data. - // Data, from raw sound - register Sint16 dr; // Right 8bit stream - register Uint8 sample; // Center 8bit sfx - register Sint16 dl; // Left 8bit stream - - // Pointers in audio stream - Sint8 *rightout = (Sint8 *)stream; // currect right - Sint8 *leftout = rightout + 1;// currect left - const Uint8 step = 2; // Step in stream, left and right, thus two. - - INT32 chan; // Mixing channel index. - - // Determine end of the stream - len /= 2; // not 8bit mono samples, 8bit stereo ones - - if (Snd_Mutex) SDL_LockMutex(Snd_Mutex); - - // Mix sounds into the mixing buffer. - // Loop over len - while (len--) - { - // Reset left/right value. - dl = *leftout; - dr = *rightout; - - // Love thy L2 cache - made this a loop. - // Now more channels could be set at compile time - // as well. Thus loop those channels. - for (chan = 0; chan < NUM_CHANNELS; chan++) - { - // Check channel, if active. - if (channels[chan].end) - { -#if 1 - // Get the raw data from the channel. - sample = channels[chan].data[0]; -#else - // linear filtering from PrDoom - sample = (((Uint32)channels[chan].data[0] *(0x10000 - channels[chan].stepremainder)) - + ((Uint32)channels[chan].data[1]) * (channels[chan].stepremainder))) >> 16; -#endif - // Add left and right part - // for this channel (sound) - // to the current data. - // Adjust volume accordingly. - dl = (Sint16)(dl+(channels[chan].leftvol_lookup[sample]>>8)); - dr = (Sint16)(dr+(channels[chan].rightvol_lookup[sample]>>8)); - // Increment stepage - channels[chan].stepremainder += channels[chan].step; - // Check whether we are done. - if (channels[chan].data + (channels[chan].stepremainder >> 16) >= channels[chan].end) - channels[chan].end = NULL; - else - { - // step to next sample - channels[chan].data += (channels[chan].stepremainder >> 16); - // Limit to LSB??? - channels[chan].stepremainder &= 0xffff; - } - } - } - - // Clamp to range. Left hardware channel. - // Has been char instead of short. - - if (dl > 0x7f) - *leftout = 0x7f; - else if (dl < -0x80) - *leftout = -0x80; - else - *leftout = (Sint8)dl; - - // Same for right hardware channel. - if (dr > 0x7f) - *rightout = 0x7f; - else if (dr < -0x80) - *rightout = -0x80; - else - *rightout = (Sint8)dr; - - // Increment current pointers in stream - leftout += step; - rightout += step; - - } - if (Snd_Mutex) SDL_UnlockMutex(Snd_Mutex); -} - -FUNCINLINE static ATTRINLINE void I_UpdateStream8M(Uint8 *stream, int len) -{ - // Mix current sound data. - // Data, from raw sound - register Sint16 d; // Mono 8bit stream - register Uint8 sample; // Center 8bit sfx - - // Pointers in audio stream - Sint8 *monoout = (Sint8 *)stream; // currect mono - const Uint8 step = 1; // Step in stream, left and right, thus two. - - INT32 chan; // Mixing channel index. - - // Determine end of the stream - //len /= 1; // not 8bit mono samples, 8bit mono ones? - - if (Snd_Mutex) SDL_LockMutex(Snd_Mutex); - - // Mix sounds into the mixing buffer. - // Loop over len - while (len--) - { - // Reset left/right value. - d = *monoout; - - // Love thy L2 cache - made this a loop. - // Now more channels could be set at compile time - // as well. Thus loop those channels. - for (chan = 0; chan < NUM_CHANNELS; chan++) - { - // Check channel, if active. - if (channels[chan].end) - { -#if 1 - // Get the raw data from the channel. - sample = channels[chan].data[0]; -#else - // linear filtering from PrDoom - sample = (((Uint32)channels[chan].data[0] *(0x10000 - channels[chan].stepremainder)) - + ((Uint32)channels[chan].data[1]) * (channels[chan].stepremainder))) >> 16; -#endif - // Add left and right part - // for this channel (sound) - // to the current data. - // Adjust volume accordingly. - d = (Sint16)(d+((channels[chan].leftvol_lookup[sample] + channels[chan].rightvol_lookup[sample])>>9)); - // Increment stepage - channels[chan].stepremainder += channels[chan].step; - // Check whether we are done. - if (channels[chan].data + (channels[chan].stepremainder >> 16) >= channels[chan].end) - channels[chan].end = NULL; - else - { - // step to next sample - channels[chan].data += (channels[chan].stepremainder >> 16); - // Limit to LSB??? - channels[chan].stepremainder &= 0xffff; - } - } - } - - // Clamp to range. Left hardware channel. - // Has been char instead of short. - - if (d > 0x7f) - *monoout = 0x7f; - else if (d < -0x80) - *monoout = -0x80; - else - *monoout = (Sint8)d; - - // Increment current pointers in stream - monoout += step; - } - if (Snd_Mutex) SDL_UnlockMutex(Snd_Mutex); -} - -FUNCINLINE static ATTRINLINE void I_UpdateStream16S(Uint8 *stream, int len) -{ - // Mix current sound data. - // Data, from raw sound - register Sint32 dr; // Right 16bit stream - register Uint8 sample; // Center 8bit sfx - register Sint32 dl; // Left 16bit stream - - // Pointers in audio stream - Sint16 *rightout = (Sint16 *)(void *)stream; // currect right - Sint16 *leftout = rightout + 1;// currect left - const Uint8 step = 2; // Step in stream, left and right, thus two. - - INT32 chan; // Mixing channel index. - - // Determine end of the stream - len /= 4; // not 8bit mono samples, 16bit stereo ones - - if (Snd_Mutex) SDL_LockMutex(Snd_Mutex); - - - // Mix sounds into the mixing buffer. - // Loop over len - while (len--) - { - // Reset left/right value. - dl = *leftout; - dr = *rightout; - - // Love thy L2 cache - made this a loop. - // Now more channels could be set at compile time - // as well. Thus loop those channels. - for (chan = 0; chan < NUM_CHANNELS; chan++) - { - // Check channel, if active. - if (channels[chan].end) - { -#if 1 - // Get the raw data from the channel. - sample = channels[chan].data[0]; -#else - // linear filtering from PrDoom - sample = (((Uint32)channels[chan].data[0] *(0x10000 - channels[chan].stepremainder)) - + ((Uint32)channels[chan].data[1]) * (channels[chan].stepremainder))) >> 16; -#endif - // Add left and right part - // for this channel (sound) - // to the current data. - // Adjust volume accordingly. - dl += channels[chan].leftvol_lookup[sample]; - dr += channels[chan].rightvol_lookup[sample]; - // Increment stepage - channels[chan].stepremainder += channels[chan].step; - // Check whether we are done. - if (channels[chan].data + (channels[chan].stepremainder >> 16) >= channels[chan].end) - channels[chan].end = NULL; - else - { - // step to next sample - channels[chan].data += (channels[chan].stepremainder >> 16); - // Limit to LSB??? - channels[chan].stepremainder &= 0xffff; - } - } - } - - // Clamp to range. Left hardware channel. - // Has been char instead of short. - - if (dl > 0x7fff) - *leftout = 0x7fff; - else if (dl < -0x8000) - *leftout = -0x8000; - else - *leftout = (Sint16)dl; - - // Same for right hardware channel. - if (dr > 0x7fff) - *rightout = 0x7fff; - else if (dr < -0x8000) - *rightout = -0x8000; - else - *rightout = (Sint16)dr; - - // Increment current pointers in stream - leftout += step; - rightout += step; - - } - if (Snd_Mutex) SDL_UnlockMutex(Snd_Mutex); -} - -FUNCINLINE static ATTRINLINE void I_UpdateStream16M(Uint8 *stream, int len) -{ - // Mix current sound data. - // Data, from raw sound - register Sint32 d; // Mono 16bit stream - register Uint8 sample; // Center 8bit sfx - - // Pointers in audio stream - Sint16 *monoout = (Sint16 *)(void *)stream; // currect mono - const Uint8 step = 1; // Step in stream, left and right, thus two. - - INT32 chan; // Mixing channel index. - - // Determine end of the stream - len /= 2; // not 8bit mono samples, 16bit mono ones - - if (Snd_Mutex) SDL_LockMutex(Snd_Mutex); - - - // Mix sounds into the mixing buffer. - // Loop over len - while (len--) - { - // Reset left/right value. - d = *monoout; - - // Love thy L2 cache - made this a loop. - // Now more channels could be set at compile time - // as well. Thus loop those channels. - for (chan = 0; chan < NUM_CHANNELS; chan++) - { - // Check channel, if active. - if (channels[chan].end) - { -#if 1 - // Get the raw data from the channel. - sample = channels[chan].data[0]; -#else - // linear filtering from PrDoom - sample = (((Uint32)channels[chan].data[0] *(0x10000 - channels[chan].stepremainder)) - + ((Uint32)channels[chan].data[1]) * (channels[chan].stepremainder))) >> 16; -#endif - // Add left and right part - // for this channel (sound) - // to the current data. - // Adjust volume accordingly. - d += (channels[chan].leftvol_lookup[sample] + channels[chan].rightvol_lookup[sample])>>1; - // Increment stepage - channels[chan].stepremainder += channels[chan].step; - // Check whether we are done. - if (channels[chan].data + (channels[chan].stepremainder >> 16) >= channels[chan].end) - channels[chan].end = NULL; - else - { - // step to next sample - channels[chan].data += (channels[chan].stepremainder >> 16); - // Limit to LSB??? - channels[chan].stepremainder &= 0xffff; - } - } - } - - // Clamp to range. Left hardware channel. - // Has been char instead of short. - - if (d > 0x7fff) - *monoout = 0x7fff; - else if (d < -0x8000) - *monoout = -0x8000; - else - *monoout = (Sint16)d; - - // Increment current pointers in stream - monoout += step; - } - if (Snd_Mutex) SDL_UnlockMutex(Snd_Mutex); -} - -#if 0 //#ifdef HAVE_LIBGME -static void I_UpdateSteamGME(Music_Emu *emu, INT16 *stream, int len, UINT8 looping) -{ - #define GME_BUFFER_LEN 44100*2048 - // Mix current sound data. - // Data, from raw sound - register Sint32 da; - - static short gme_buffer[GME_BUFFER_LEN]; // a large buffer for gme - Sint16 *in = gme_buffer; - - do - { - int out = min(GME_BUFFER_LEN, len); - if ( gme_play( emu, len, gme_buffer ) ) { } // ignore error - len -= out; - while (out--) - { - //Left - da = *in; - in++; - da += *stream; - stream++; - //Right - da = *in; - in++; - da += *stream; - stream++; - } - if (gme_track_ended( emu )) - { - if (looping) - gme_seek( emu, 0); - else - break; - } - } while ( len ); - #undef GME_BUFFER_LEN -} -#endif - -static void SDLCALL I_UpdateStream(void *userdata, Uint8 *stream, int len) -{ - if (!sound_started || !userdata) - return; - - memset(stream, 0x00, len); // only work in !AUDIO_U8, that needs 0x80 - - if ((audio.channels != 1 && audio.channels != 2) || - (audio.format != AUDIO_S8 && audio.format != AUDIO_S16SYS)) - ; // no function to encode this type of stream - else if (audio.channels == 1 && audio.format == AUDIO_S8) - I_UpdateStream8M(stream, len); - else if (audio.channels == 2 && audio.format == AUDIO_S8) - I_UpdateStream8S(stream, len); - else if (audio.channels == 1 && audio.format == AUDIO_S16SYS) - I_UpdateStream16M(stream, len); - else if (audio.channels == 2 && audio.format == AUDIO_S16SYS) - { - I_UpdateStream16S(stream, len); - - // Crashes! But no matter; this build doesn't play music anyway... -// #ifdef HAVE_LIBGME -// if (userdata) -// { -// srb2audio_t *sa_userdata = userdata; -// if (!sa_userdata->gme_pause) -// I_UpdateSteamGME(sa_userdata->gme_emu, (INT16 *)stream, len/4, sa_userdata->gme_loop); -// } -// #endif - - } -} - -void I_UpdateSoundParams(INT32 handle, UINT8 vol, UINT8 sep, UINT8 pitch) -{ - // Would be using the handle to identify - // on which channel the sound might be active, - // and resetting the channel parameters. - - INT32 i = FindChannel(handle); - - if (i != -1 && channels[i].end) - { - //Snd_LockAudio(); //Alam: too much? - I_SetChannelParams(&channels[i], vol, sep, steptable[pitch]); - //Snd_UnlockAudio(); //Alam: too much? - } - -} - -#ifdef HW3SOUND - -static void *soundso = NULL; - -static INT32 Init3DSDriver(const char *soName) -{ - if (soName) soundso = hwOpen(soName); -#if defined (_WIN32) && defined (_X86_) && !defined (STATIC3DS) - HW3DS.pfnStartup = hwSym("Startup@8",soundso); - HW3DS.pfnShutdown = hwSym("Shutdown@0",soundso); - HW3DS.pfnAddSfx = hwSym("AddSfx@4",soundso); - HW3DS.pfnAddSource = hwSym("AddSource@8",soundso); - HW3DS.pfnStartSource = hwSym("StartSource@4",soundso); - HW3DS.pfnStopSource = hwSym("StopSource@4",soundso); - HW3DS.pfnGetHW3DSVersion = hwSym("GetHW3DSVersion@0",soundso); - HW3DS.pfnBeginFrameUpdate = hwSym("BeginFrameUpdate@0",soundso); - HW3DS.pfnEndFrameUpdate = hwSym("EndFrameUpdate@0",soundso); - HW3DS.pfnIsPlaying = hwSym("IsPlaying@4",soundso); - HW3DS.pfnUpdateListener = hwSym("UpdateListener@8",soundso); - HW3DS.pfnUpdateSourceParms = hwSym("UpdateSourceParms@12",soundso); - HW3DS.pfnSetCone = hwSym("SetCone@8",soundso); - HW3DS.pfnSetGlobalSfxVolume = hwSym("SetGlobalSfxVolume@4",soundso); - HW3DS.pfnUpdate3DSource = hwSym("Update3DSource@8",soundso); - HW3DS.pfnReloadSource = hwSym("ReloadSource@8",soundso); - HW3DS.pfnKillSource = hwSym("KillSource@4",soundso); - HW3DS.pfnKillSfx = hwSym("KillSfx@4",soundso); - HW3DS.pfnGetHW3DSTitle = hwSym("GetHW3DSTitle@8",soundso); -#else - HW3DS.pfnStartup = hwSym("Startup",soundso); - HW3DS.pfnShutdown = hwSym("Shutdown",soundso); - HW3DS.pfnAddSfx = hwSym("AddSfx",soundso); - HW3DS.pfnAddSource = hwSym("AddSource",soundso); - HW3DS.pfnStartSource = hwSym("StartSource",soundso); - HW3DS.pfnStopSource = hwSym("StopSource",soundso); - HW3DS.pfnGetHW3DSVersion = hwSym("GetHW3DSVersion",soundso); - HW3DS.pfnBeginFrameUpdate = hwSym("BeginFrameUpdate",soundso); - HW3DS.pfnEndFrameUpdate = hwSym("EndFrameUpdate",soundso); - HW3DS.pfnIsPlaying = hwSym("IsPlaying",soundso); - HW3DS.pfnUpdateListener = hwSym("UpdateListener",soundso); - HW3DS.pfnUpdateSourceParms = hwSym("UpdateSourceParms",soundso); - HW3DS.pfnSetCone = hwSym("SetCone",soundso); - HW3DS.pfnSetGlobalSfxVolume = hwSym("SetGlobalSfxVolume",soundso); - HW3DS.pfnUpdate3DSource = hwSym("Update3DSource",soundso); - HW3DS.pfnReloadSource = hwSym("ReloadSource",soundso); - HW3DS.pfnKillSource = hwSym("KillSource",soundso); - HW3DS.pfnKillSfx = hwSym("KillSfx",soundso); - HW3DS.pfnGetHW3DSTitle = hwSym("GetHW3DSTitle",soundso); -#endif - -// if (HW3DS.pfnUpdateListener2 && HW3DS.pfnUpdateListener2 != soundso) - return true; -// else -// return false; -} -#endif - -void I_ShutdownSound(void) -{ - if (sound_disabled || !sound_started) - return; - - CONS_Printf("I_ShutdownSound: "); - -#ifdef HW3SOUND - if (hws_mode != HWS_DEFAULT_MODE) - { - HW3S_Shutdown(); - hwClose(soundso); - return; - } -#endif - - if (digital_disabled) - SDL_CloseAudio(); - CONS_Printf("%s", M_GetText("shut down\n")); - sound_started = false; - SDL_QuitSubSystem(SDL_INIT_AUDIO); - if (Snd_Mutex) - SDL_DestroyMutex(Snd_Mutex); - Snd_Mutex = NULL; -} - -void I_UpdateSound(void) -{ -} - -void I_StartupSound(void) -{ -#ifdef HW3SOUND - const char *sdrv_name = NULL; -#endif -#ifndef HAVE_MIXER - digital_disabled = true; -#endif - - memset(channels, 0, sizeof (channels)); //Alam: Clean it - - audio.format = AUDIO_S16SYS; - audio.channels = 2; - audio.callback = I_UpdateStream; - audio.userdata = &localdata; - - // Configure sound device - CONS_Printf("I_StartupSound:\n"); - -#ifdef _WIN32 - // Force DirectSound instead of WASAPI - // SDL 2.0.6+ defaults to the latter and it screws up our sound effects - SDL_setenv("SDL_AUDIODRIVER", "directsound", 1); -#endif - - // EE inits audio first so we're following along. - if (SDL_WasInit(SDL_INIT_AUDIO) == SDL_INIT_AUDIO) - CONS_Printf("SDL Audio already started\n"); - else if (SDL_InitSubSystem(SDL_INIT_AUDIO) < 0) - { - CONS_Alert(CONS_ERROR, "Error initializing SDL Audio: %s\n", SDL_GetError()); - // call to start audio failed -- we do not have it - return; - } - - // Open the audio device - if (M_CheckParm ("-freq") && M_IsNextParm()) - { - audio.freq = atoi(M_GetNextParm()); - if (!audio.freq) audio.freq = cv_samplerate.value; - audio.samples = (Uint16)((samplecount/2)*(INT32)(audio.freq/11025)); //Alam: to keep it around the same XX ms - CONS_Printf (M_GetText(" requested frequency of %d hz\n"), audio.freq); - } - else - { - audio.samples = samplecount; - audio.freq = cv_samplerate.value; - } - - if (M_CheckParm ("-mono")) - { - audio.channels = 1; - audio.samples /= 2; - } - - if (sound_disabled) - return; - -#ifdef HW3SOUND -#ifdef STATIC3DS - if (M_CheckParm("-3dsound") || M_CheckParm("-ds3d")) - { - hws_mode = HWS_OPENAL; - } -#elif defined (_WIN32) - if (M_CheckParm("-ds3d")) - { - hws_mode = HWS_DS3D; - sdrv_name = "s_ds3d.dll"; - } - else if (M_CheckParm("-fmod3d")) - { - hws_mode = HWS_FMOD3D; - sdrv_name = "s_fmod.dll"; - } - else if (M_CheckParm("-openal")) - { - hws_mode = HWS_OPENAL; - sdrv_name = "s_openal.dll"; - } -#else - if (M_CheckParm("-fmod3d")) - { - hws_mode = HWS_FMOD3D; - sdrv_name = "./s_fmod.so"; - } - else if (M_CheckParm("-openal")) - { - hws_mode = HWS_OPENAL; - sdrv_name = "./s_openal.so"; - } -#endif - else if (M_CheckParm("-sounddriver") && M_IsNextParm()) - { - hws_mode = HWS_OTHER; - sdrv_name = M_GetNextParm(); - } - if (hws_mode != HWS_DEFAULT_MODE) - { - if (Init3DSDriver(sdrv_name)) - { - snddev_t snddev; - - //sound_disabled = true; - //I_AddExitFunc(I_ShutdownSound); - snddev.bps = 16; - snddev.sample_rate = audio.freq; - snddev.numsfxs = NUMSFX; -#if defined (_WIN32) - snddev.cooplevel = 0x00000002; - snddev.hWnd = vid.WndParent; -#endif - if (HW3S_Init(I_Error, &snddev)) - { - audio.userdata = NULL; - CONS_Printf("%s", M_GetText(" Using 3D sound driver\n")); - return; - } - CONS_Printf("%s", M_GetText(" Failed loading 3D sound driver\n")); - // Falls back to default sound system - HW3S_Shutdown(); - hwClose(soundso); - } - CONS_Printf("%s", M_GetText(" Failed loading 3D sound driver\n")); - hws_mode = HWS_DEFAULT_MODE; - } -#endif - if (!musicStarted && SDL_OpenAudio(&audio, &audio) < 0) - { - CONS_Printf("%s", M_GetText(" couldn't open audio with desired format\n")); - sound_disabled = true; - return; - } - else - { - //char ad[100]; - //CONS_Printf(M_GetText(" Starting up with audio driver : %s\n"), SDL_AudioDriverName(ad, (int)sizeof ad)); - } - samplecount = audio.samples; - CV_SetValue(&cv_samplerate, audio.freq); - CONS_Printf(M_GetText(" configured audio device with %d samples/slice at %ikhz(%dms buffer)\n"), samplecount, audio.freq/1000, (INT32) (((float)audio.samples * 1000.0f) / audio.freq)); - // Finished initialization. - CONS_Printf("%s", M_GetText(" Sound module ready\n")); - //[segabor] - if (!musicStarted) SDL_PauseAudio(0); - //Mix_Pause(0); - I_SetChannels(); - sound_started = true; - Snd_Mutex = SDL_CreateMutex(); -} - -// -// MUSIC API. -// - -/// ------------------------ -// MUSIC SYSTEM -/// ------------------------ - -#if 0 //#ifdef HAVE_LIBGME -static void I_ShutdownGMEMusic(void) -{ - Snd_LockAudio(); - if (localdata.gme_emu) - gme_delete(localdata.gme_emu); - localdata.gme_emu = NULL; - Snd_UnlockAudio(); -} -#endif - -void I_InitMusic(void) -{ -#if 0 //#ifdef HAVE_LIBGME - I_AddExitFunc(I_ShutdownGMEMusic); -#endif -} - -void I_ShutdownMusic(void) { } - -/// ------------------------ -// MUSIC PROPERTIES -/// ------------------------ - -musictype_t I_SongType(void) -{ - return MU_NONE; -} - -boolean I_SongPlaying(void) -{ - return false; -} - -boolean I_SongPaused(void) -{ - return false; -} - -/// ------------------------ -// MUSIC EFFECTS -/// ------------------------ - -boolean I_SetSongSpeed(float speed) -{ - (void)speed; - return false; -} - -/// ------------------------ -// MUSIC SEEKING -/// ------------------------ - -UINT32 I_GetSongLength(void) -{ - return 0; -} - -boolean I_SetSongLoopPoint(UINT32 looppoint) -{ - (void)looppoint; - return false; -} - -UINT32 I_GetSongLoopPoint(void) -{ - return 0; -} - -boolean I_SetSongPosition(UINT32 position) -{ - (void)position; - return false; -} - -UINT32 I_GetSongPosition(void) -{ - return 0; -} - -/// ------------------------ -// MUSIC PLAYBACK -/// ------------------------ - -#if 0 //#ifdef HAVE_LIBGME -static void I_StopGME(void) -{ - Snd_LockAudio(); - gme_seek(localdata.gme_emu, 0); - Snd_UnlockAudio(); -} - -static void I_PauseGME(void) -{ - localdata.gme_pause = true; -} - -static void I_ResumeGME(void) -{ - localdata.gme_pause = false; -} -#endif - -boolean I_LoadSong(char *data, size_t len) -{ - (void)data; - (void)len; - return false; -} - -void I_UnloadSong(void) { } - -boolean I_PlaySong(boolean looping) -{ - (void)looping; - return false; -} - -void I_StopSong(void) -{ -#if 0 //#ifdef HAVE_LIBGME - I_StopGME(); -#endif -} - -void I_PauseSong(void) -{ -#if 0 //#ifdef HAVE_LIBGME - I_PauseGME(); -#endif -} - -void I_ResumeSong(void) -{ -#if 0 - I_ResumeGME(); -#endif -} - -void I_SetMusicVolume(int volume) -{ - (void)volume; -} - -boolean I_SetSongTrack(int track) -{ - (void)track; - return false; -} - -void I_UpdateSongLagThreshold(void){} -void I_UpdateSongLagConditions(void){} - -/// ------------------------ -/// MUSIC FADING -/// ------------------------ - -void I_SetInternalMusicVolume(UINT8 volume) -{ - (void)volume; -} - -void I_StopFadingSong(void) -{ -} - -boolean I_FadeSongFromVolume(UINT8 target_volume, UINT8 source_volume, UINT32 ms, void (*callback)(void)) -{ - (void)target_volume; - (void)source_volume; - (void)ms; - (void)callback; - return false; -} - -boolean I_FadeSong(UINT8 target_volume, UINT32 ms, void (*callback)(void)) -{ - (void)target_volume; - (void)ms; - (void)callback; - return false; -} - -boolean I_FadeOutStopSong(UINT32 ms) -{ - (void)ms; - return false; -} - -boolean I_FadeInPlaySong(UINT32 ms, boolean looping) -{ - (void)ms; - (void)looping; - return false; -} - -/// ------------------------ -// MUSIC LOADING AND CLEANUP -// \todo Split logic between loading and playing, -// then move to Playback section -/// ------------------------ - -#if 0 //#ifdef HAVE_LIBGME -static void I_CleanupGME(void *userdata) -{ - Z_Free(userdata); -} - -static boolean I_StartGMESong(const char *musicname, boolean looping) -{ - char filename[9]; - void *data; - lumpnum_t lumpnum; - size_t lumplength; - Music_Emu *emu; - const char* gme_err; - - Snd_LockAudio(); - if (localdata.gme_emu) - gme_delete(localdata.gme_emu); - localdata.gme_emu = NULL; - Snd_UnlockAudio(); - - snprintf(filename, sizeof filename, "o_%s", musicname); - - lumpnum = W_CheckNumForName(filename); - - if (lumpnum == LUMPERROR) - { - return false; // No music found. Oh well! - } - else - lumplength = W_LumpLength(lumpnum); - - data = W_CacheLumpNum(lumpnum, PU_MUSIC); - - gme_err = gme_open_data(data, (long)lumplength, &emu, audio.freq); - if (gme_err != NULL) { - //I_OutputMsg("I_StartGMESong: error %s\n",gme_err); - return false; - } - gme_set_user_data(emu, data); - gme_set_user_cleanup(emu, I_CleanupGME); - gme_start_track(emu, 0); -#ifdef HAVE_MIXER - gme_set_fade(emu, Digfade); -#endif - - Snd_LockAudio(); - localdata.gme_emu = emu; - localdata.gme_pause = false; - localdata.gme_loop = (UINT8)looping; - Snd_UnlockAudio(); - - return true; -} -#endif - -#endif //HAVE_SDL diff --git a/src/sdl/sdlmain.h b/src/sdl/sdlmain.h index 0c438b0aa..b41b661ac 100644 --- a/src/sdl/sdlmain.h +++ b/src/sdl/sdlmain.h @@ -13,8 +13,8 @@ #ifndef __sdlmain__ #define __sdlmain__ -extern SDL_bool consolevent; -extern SDL_bool framebuffer; +extern bool consolevent; +extern bool framebuffer; #include "../m_fixed.h" #include "../doomdef.h" @@ -37,7 +37,7 @@ extern "C" { typedef struct SDLJoyInfo_s { /// Controller handle - SDL_GameController *dev; + SDL_Gamepad *dev; /// number of old joystick int oldjoy; /// number of axies @@ -60,7 +60,6 @@ extern SDLJoyInfo_t JoyInfo[MAXSPLITSCREENPLAYERS]; /** \brief joystick axis deadzone */ #define SDL_JDEADZONE 153 -#undef SDL_JDEADZONE void I_GetConsoleEvents(void); diff --git a/vcpkg.json b/vcpkg.json index 00a58c1c2..d4602e1c7 100644 --- a/vcpkg.json +++ b/vcpkg.json @@ -16,7 +16,7 @@ "libyuv", "opus", { - "name": "sdl2", + "name": "sdl3", "features": ["vulkan"] }, "zlib"