diff --git a/neo/renderer/tr_backend.cpp b/neo/renderer/tr_backend.cpp index 08491413..cf1c5714 100644 --- a/neo/renderer/tr_backend.cpp +++ b/neo/renderer/tr_backend.cpp @@ -30,7 +30,7 @@ If you have questions concerning this license or the applicable additional terms #include "renderer/tr_local.h" -static idCVar r_fillWindowAlphaChan( "r_fillWindowAlphaChan", "-1", CVAR_SYSTEM | CVAR_NOCHEAT | CVAR_ARCHIVE, "Make sure alpha channel of windows default framebuffer is completely opaque at the end of each frame. Needed at least when using Wayland.\n 1: do this, 0: don't do it, -1: let dhewm3 decide (default)" ); +static idCVar r_fillWindowAlphaChan( "r_fillWindowAlphaChan", "-1", CVAR_SYSTEM | CVAR_NOCHEAT | CVAR_ARCHIVE, "Make sure alpha channel of windows default framebuffer is completely opaque at the end of each frame. Needed at least when using Wayland with older drivers.\n 1: do this, 0: don't do it, -1: let dhewm3 decide (default)" ); frameData_t *frameData; backEndState_t backEnd; diff --git a/neo/renderer/tr_local.h b/neo/renderer/tr_local.h index 3719c039..51ae91d4 100644 --- a/neo/renderer/tr_local.h +++ b/neo/renderer/tr_local.h @@ -1073,7 +1073,7 @@ typedef struct { bool fullScreen; bool fullScreenDesktop; bool stereo; - int displayHz; + int displayHz; // TODO: SDL3 uses float int multiSamples; } glimpParms_t; diff --git a/neo/sys/cpu.cpp b/neo/sys/cpu.cpp index c7f9e235..6d52e4c3 100644 --- a/neo/sys/cpu.cpp +++ b/neo/sys/cpu.cpp @@ -30,9 +30,6 @@ If you have questions concerning this license or the applicable additional terms #ifdef D3_SDL3 #include - // in SDL3, SDL_Has3DNow() has been removed, and nowadays it's not really relevant anyway, - // so just replace it with 0/false - #define SDL_Has3DNow() 0 #else // SDL1.2 or SDL2 #include #endif @@ -208,8 +205,11 @@ int Sys_GetProcessorId( void ) { if (SDL_HasMMX()) flags |= CPUID_MMX; + // SDL3 doesn't support detecting 3DNow, and current CPUs (even from AMD) don't support it either +#ifndef D3_SDL3 if (SDL_Has3DNow()) flags |= CPUID_3DNOW; +#endif if (SDL_HasSSE()) flags |= CPUID_SSE; diff --git a/neo/sys/events.cpp b/neo/sys/events.cpp index 6884eb0f..b50cd73d 100644 --- a/neo/sys/events.cpp +++ b/neo/sys/events.cpp @@ -152,8 +152,6 @@ If you have questions concerning this license or the applicable additional terms #define IS_SDL_BTN_DOWN(EV) EV.down - // FIXME: at some point I need to enable (and possibly later disable) SDL_TextInput! - #else // SDL2 and SDL1.2 #define IS_SDL_BTN_DOWN(EV) (EV.state == SDL_PRESSED) @@ -1209,7 +1207,9 @@ sysEvent_t Sys_GetEvent() { } #if SDL_VERSION_ATLEAST(2, 0, 0) - // s used to have SDL_TEXTINPUTEVENT_TEXT_SIZE (32) bytes, but in SDL3 the string can have + // s holds the string from the last SDL_TEXTINPUT event, to generate SE_CHARS D3 events, + // one event per call to this function until all chars have been handled + // it used to have SDL_TEXTINPUTEVENT_TEXT_SIZE (32) bytes, but in SDL3 the string can have // arbitrary size, however I assume that 128 should still be more than enough static char s[128] = {0}; static size_t s_pos = 0; @@ -1229,6 +1229,9 @@ sysEvent_t Sys_GetEvent() { } #endif + // c holds a single char for a SE_CHAR event, probably coming from a SDL_KEYDOWN event + // (that was also returned as SE_KEY), or from a SDL_TEXTINPUT event that contained just one char. + // It's 0 when not currently holding a char to generate an event static byte c = 0; if (c) { @@ -1421,6 +1424,7 @@ sysEvent_t Sys_GetEvent() { if (ev.key.state == SDL_PRESSED && (ev.key.keysym.unicode & 0xff00) == 0) c = ev.key.keysym.unicode & 0xff; #endif + // Note: c will be sent as SE_CHAR next time this function is called return res; @@ -1440,7 +1444,9 @@ sysEvent_t Sys_GetEvent() { memcpy( s, ev.text.text, SDL_TEXTINPUTEVENT_TEXT_SIZE ); s[SDL_TEXTINPUTEVENT_TEXT_SIZE] = '\0'; #endif - s_pos = 1; // pos 0 is returned + // pos 0 is returned, the rest of s is returned as SE_CHAR events + // at the next times this function is called + s_pos = 1; } return res; } else if( D3_UTF8toISO8859_1( ev.text.text, s, sizeof(s) ) && s[0] != '\0' ) { @@ -1449,7 +1455,9 @@ sysEvent_t Sys_GetEvent() { s_pos = 0; s[0] = '\0'; } else { - s_pos = 1; // pos 0 is returned + // pos 0 is returned, the rest of s is returned as SE_CHAR events + // at the next times this function is called + s_pos = 1; } return res; } diff --git a/neo/sys/glimp.cpp b/neo/sys/glimp.cpp index 4cb25b4b..e554d7a1 100644 --- a/neo/sys/glimp.cpp +++ b/neo/sys/glimp.cpp @@ -219,20 +219,25 @@ bool GLimp_Init(glimpParms_t parms) { * rendering bugs (the window is partly transparent or very white in areas with low alpha). * Mesa introduced an EGL extension that's supposed to fix that (EGL_EXT_present_opaque) * and newer SDL2 versions use it by default (in the Wayland backend). - * Unfortunately, the implementation of that extension is (currently?) broken (at least - * in Mesa), seems like they just give you a visual without any alpha chan - which doesn't + * Unfortunately, the implementation of that extension was broken (at least in Mesa before 24.1), + * seems like they just give you a visual without any alpha chan - which doesn't * work for Doom3, as it needs a functioning alpha chan for blending operations, see above. * See also: https://gitlab.freedesktop.org/mesa/mesa/-/issues/5886 * * So to make sure dhewm3 (finally) works as expected on Wayland, we tell SDL2 to * allow transparency and then fill the alpha-chan ourselves in RB_SwapBuffers() - * (unless the user disables that with r_fillWindowAlphaChan 0) */ + * (unless the user disables that with r_fillWindowAlphaChan 0) + * + * NOTE: This bug is fixed in Mesa 24.1 and newer, and doesn't seem to occur with recent + * NVIDIA drivers either, so for SDL3 (which should be mostly used with current drivers/mesa) + * I don't enable this hack by default. If r_fillWindowAlphaChan == 1, it's enabled + * when creating the window, though. + */ #ifdef SDL_HINT_VIDEO_EGL_ALLOW_TRANSPARENCY SDL_SetHint(SDL_HINT_VIDEO_EGL_ALLOW_TRANSPARENCY, "1"); #elif SDL_MAJOR_VERSION == 2 // little hack so this works if the SDL2 version used for building is older than runtime version SDL_SetHint("SDL_VIDEO_EGL_ALLOW_TRANSPARENCY", "1"); #endif - // Note: for SDL3 we use SDL_PROP_WINDOW_CREATE_TRANSPARENT_BOOLEAN below #endif int colorbits = 24; @@ -401,15 +406,17 @@ try_again: SDL_SetNumberProperty(props, SDL_PROP_WINDOW_CREATE_WIDTH_NUMBER, parms.width); SDL_SetNumberProperty(props, SDL_PROP_WINDOW_CREATE_HEIGHT_NUMBER, parms.height); SDL_SetNumberProperty(props, SDL_PROP_WINDOW_CREATE_FLAGS_NUMBER, flags); - // TODO: the following is probably redundant with the flag already set - //if ( parms.fullScreen && parms.fullScreenDesktop ) { - // SDL_SetBooleanProperty(props, SDL_PROP_WINDOW_CREATE_FULLSCREEN_BOOLEAN, true); - //} // for exclusive fullscreen, create in windowed mode first, need to call - // TODO: SDL_SetBooleanProperty(props, SDL_PROP_WINDOW_CREATE_TRANSPARENT_BOOLEAN, true); - // as replacement for SDL_VIDEO_EGL_ALLOW_TRANSPARENCY - but when? - // I don't want this on all platforms.. but can I already detect wayland at this point? - // Also: recent mesa versions should have this fixed, so maybe ignore the issue for SDL3? what about nvidia? + // See above for the big comment about Wayland and alpha channels. + // When using SDL3 I assume that people usually won't be affected by this bug, + // because it's fixed in recent Mesa versions (and also works with the NVIDIA driver). + // However, with `r_fillWindowAlphaChan 1` its usage can still be enforced + // on Unix-like platforms (I don't think there's a point in this on Windows or Mac) + #if defined(__unix__) && !defined(__APPLE__) + if ( cvarSystem->GetCVarInteger( "r_fillWindowAlphaChan" ) == 1 ) { + SDL_SetBooleanProperty(props, SDL_PROP_WINDOW_CREATE_TRANSPARENT_BOOLEAN, true); + } + #endif window = SDL_CreateWindowWithProperties(props); SDL_DestroyProperties(props); @@ -753,7 +760,9 @@ try_again: #if SDL_VERSION_ATLEAST(2, 0, 0) const char* videoDriver = SDL_GetCurrentVideoDriver(); if (idStr::Icmp(videoDriver, "wayland") == 0) { + #if SDL_MAJOR_VERSION == 2 // don't enable this hack by default with SDL3 glConfig.shouldFillWindowAlpha = true; + #endif glConfig.isWayland = true; } #endif