From 00d08c851fbebc89eb04e54f756b37bad8337506 Mon Sep 17 00:00:00 2001 From: NepDisk Date: Tue, 3 Jun 2025 12:03:58 -0400 Subject: [PATCH 01/29] i_video.c refactor port based on https://git.do.srb2.org/STJr/SRB2/-/commit/4de2d8181572fc1c7767c67338bb09f4338a51cf --- src/d_main.cpp | 2 - src/dummy/i_system.c | 2 - src/i_system.h | 2 - src/m_anigif.c | 73 ++- src/sdl/i_system.cpp | 3 - src/sdl/i_video.cpp | 1025 ++++++++++++++++++------------------------ 6 files changed, 511 insertions(+), 596 deletions(-) diff --git a/src/d_main.cpp b/src/d_main.cpp index 22089ab2e..137d92c10 100644 --- a/src/d_main.cpp +++ b/src/d_main.cpp @@ -1459,8 +1459,6 @@ void D_SRB2Main(void) CV_RegisterVar(&cv_constextsize); } - I_RegisterSysCommands(); - #ifdef HWRENDER // Lactozilla: Add every hardware mode CVAR and CCMD. // Has to be done before the configuration file loads, diff --git a/src/dummy/i_system.c b/src/dummy/i_system.c index 5cd88243d..94e021dfd 100644 --- a/src/dummy/i_system.c +++ b/src/dummy/i_system.c @@ -174,7 +174,5 @@ char *I_ClipboardPaste(void) return NULL; } -void I_RegisterSysCommands(void) {} - #include "../sdl/dosstr.c" diff --git a/src/i_system.h b/src/i_system.h index 3624fbb03..59439faf5 100644 --- a/src/i_system.h +++ b/src/i_system.h @@ -326,8 +326,6 @@ INT32 I_ClipboardCopy(const char *data, size_t size); */ const char *I_ClipboardPaste(void); -void I_RegisterSysCommands(void); - #ifdef __cplusplus } // extern "C" #endif diff --git a/src/m_anigif.c b/src/m_anigif.c index 380eb6f00..6706b2cf8 100644 --- a/src/m_anigif.c +++ b/src/m_anigif.c @@ -57,6 +57,13 @@ static precise_t gif_prevframetime = 0; static UINT32 gif_delayus = 0; // "us" is microseconds static UINT8 gif_writeover = 0; +typedef struct +{ + void *pixels; + size_t size; + boolean owns_pixels; +} gif_screen_t; +static gif_screen_t gif_screens[2]; // OPTIMIZE gif output @@ -541,7 +548,8 @@ static void GIF_rgbconvert(UINT8 *linear, UINT8 *scr) static void GIF_framewrite(void) { UINT8 *p; - UINT8 *movie_screen = screens[2]; + UINT8 *base_screen = gif_screens[0].pixels; + UINT8 *movie_screen = gif_screens[1].pixels; INT32 blitx, blity, blitw, blith; boolean palchanged; @@ -566,7 +574,7 @@ static void GIF_framewrite(void) if (gif_optimize && gif_frames > 0 && (!palchanged)) { // before blit movie_screen points to last frame, cur_screen points to this frame - UINT8 *cur_screen = screens[0]; + UINT8 *cur_screen = base_screen; GIF_optimizeregion(cur_screen, movie_screen, &blitx, &blity, &blitw, &blith); // blit to temp screen @@ -576,7 +584,7 @@ static void GIF_framewrite(void) else if (rendermode == render_opengl) { UINT8 *linear = HWR_GetScreenshot(); - GIF_rgbconvert(linear, movie_screen); + GIF_rgbconvert(linear, base_screen); //free(linear); // Allocated 'statically', no need to free now } #endif @@ -602,7 +610,7 @@ static void GIF_framewrite(void) if (gif_frames == 0 && rendermode == render_soft) I_ReadScreen(movie_screen); - movie_screen = screens[0]; + movie_screen = base_screen; } // screen regions are handled in GIF_lzw @@ -750,13 +758,66 @@ INT32 GIF_open(const char *filename) return 1; } +static void GIF_checkscreens(void) +{ + for (size_t i = 0; i < sizeof(gif_screens) / sizeof(gif_screens[0]); i++) + { + if (rendermode == render_soft) + { + if (gif_screens[i].owns_pixels) + { + Z_Free(gif_screens[i].pixels); + gif_screens[i].owns_pixels = false; + } + + gif_screens[i].size = 0; + + if (i == 1) + gif_screens[i].pixels = screens[2]; + else + gif_screens[i].pixels = screens[0]; + } + else + { + size_t sz = vid.width * vid.height * vid.bpp; + + if (!gif_screens[i].owns_pixels) + { + gif_screens[i].size = sz; + gif_screens[i].pixels = Z_Malloc(gif_screens[i].size, PU_STATIC, NULL); + gif_screens[i].owns_pixels = true; + } + else if (gif_screens[i].size != sz) + { + gif_screens[i].size = sz; + gif_screens[i].pixels = Z_Realloc(gif_screens[i].pixels, gif_screens[i].size, PU_STATIC, NULL); + } + } + } +} + +static void GIF_freescreens(void) +{ + for (size_t i = 0; i < sizeof(gif_screens) / sizeof(gif_screens[0]); i++) + { + if (gif_screens[i].owns_pixels) + { + Z_Free(gif_screens[i].pixels); + gif_screens[i].owns_pixels = false; + } + + gif_screens[i].size = 0; + gif_screens[i].pixels = NULL; + } +} + // // GIF_frame // writes a frame into the output gif // void GIF_frame(void) { - // there's not much actually needed here, is there. + GIF_checkscreens(); GIF_framewrite(); } @@ -786,6 +847,8 @@ INT32 GIF_close(void) Z_Free(giflzw_hashTable); giflzw_hashTable = NULL; + GIF_freescreens(); + CONS_Printf(M_GetText("Animated gif closed; wrote %d frames\n"), gif_frames); return 1; } diff --git a/src/sdl/i_system.cpp b/src/sdl/i_system.cpp index d5fde7000..925812325 100644 --- a/src/sdl/i_system.cpp +++ b/src/sdl/i_system.cpp @@ -2681,7 +2681,4 @@ UINT32 I_GetFreeMem(UINT32 *total) #endif } -// note CPUAFFINITY code used to reside here -//void I_RegisterSysCommands(void) {} - #endif // HAVE_SDL diff --git a/src/sdl/i_video.cpp b/src/sdl/i_video.cpp index da3ddfd5b..26d58bbe8 100644 --- a/src/sdl/i_video.cpp +++ b/src/sdl/i_video.cpp @@ -16,7 +16,7 @@ // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. //----------------------------------------------------------------------------- -/// \file +/// \file i_video.cpp /// \brief SRB2 graphics stuff for SDL #include @@ -82,7 +82,6 @@ #ifdef HWRENDER #include "../hardware/hw_main.h" #include "../hardware/hw_drv.h" -// For dynamic referencing of HW rendering functions #include "hwsym_sdl.h" #include "ogl_sdl.h" #endif @@ -94,14 +93,6 @@ // maximum number of windowed modes (see windowedModes[][]) #define MAXWINMODES (22) -/** \brief -*/ -static INT32 numVidModes = -1; - -/** \brief -*/ -static char vidModeName[33][32]; // allow 33 different modes - rendermode_t rendermode = render_soft; rendermode_t chosenrendermode = render_none; // set by command line arguments @@ -118,43 +109,56 @@ 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; -#define USE_FULLSCREEN (disable_fullscreen||!allow_fullscreen)?0:cv_fullscreen.value + +#define USE_FULLSCREEN (disable_fullscreen||!allow_fullscreen)?static_cast(0):static_cast(cv_fullscreen.value) + static SDL_bool disable_mouse = SDL_FALSE; #define USE_MOUSEINPUT (!disable_mouse && cv_usemouse.value && havefocus) #define MOUSE_MENU false //(!disable_mouse && cv_usemouse.value && menustack[0] && !USE_FULLSCREEN) #define MOUSEBUTTONS_MAX MOUSEBUTTONS -// first entry in the modelist which is not bigger than MAXVIDWIDTHxMAXVIDHEIGHT -static INT32 firstEntry = 0; - // Total mouse motion X/Y offsets static INT32 mousemovex = 0, mousemovey = 0; // SDL vars static SDL_Surface *vidSurface = NULL; static SDL_Surface *bufSurface = NULL; -static SDL_Surface *icoSurface = NULL; static SDL_Color localPalette[256]; -#if 0 -static SDL_Rect **modeList = NULL; -static Uint8 BitsPerPixel = 16; -#endif -Uint16 realwidth = BASEVIDWIDTH; -Uint16 realheight = BASEVIDHEIGHT; static SDL_bool mousegrabok = SDL_TRUE; static SDL_bool wrapmouseok = SDL_FALSE; #define HalfWarpMouse(x,y) if (wrapmouseok) SDL_WarpMouseInWindow(window, (Uint16)(x/2),(Uint16)(y/2)) -static SDL_bool videoblitok = SDL_FALSE; -static SDL_bool exposevideo = SDL_FALSE; static SDL_bool usesdl2soft = SDL_FALSE; static SDL_bool borderlesswindow = SDL_FALSE; -// SDL2 vars +Uint16 realwidth = BASEVIDWIDTH; +Uint16 realheight = BASEVIDHEIGHT; + SDL_Window *window; SDL_Renderer *renderer; static SDL_Texture *texture; static SDL_bool havefocus = SDL_TRUE; -static const char *fallback_resolution_name = "Fallback"; + +static UINT32 refresh_rate; + +static boolean video_init = false; + +static SDL_bool Impl_CreateWindow(SDL_bool fullscreen); + +static void Impl_VideoSetupSurfaces(int width, int height); +static void Impl_VideoSetupBuffer(void); + +static void Impl_SetupSoftwareBuffer(void); + +static void Impl_InitOpenGL(void); + +#if !defined(__ANDROID__) && defined(HAVE_IMAGE) +#define USE_WINDOW_ICON +#endif + +#ifdef USE_WINDOW_ICON +static void Impl_SetWindowIcon(void); +static SDL_Surface *icoSurface = NULL; +#endif // windowed video modes from which to choose from. static INT32 windowedModes[MAXWINMODES][2] = @@ -187,11 +191,110 @@ static INT32 windowedModes[MAXWINMODES][2] = static INT32 custom_width = 0; static INT32 custom_height = 0; -static void Impl_VideoSetupSDLBuffer(void); -static void Impl_VideoSetupBuffer(void); -static SDL_bool Impl_CreateWindow(SDL_bool fullscreen); -//static void Impl_SetWindowName(const char *title); -static void Impl_SetWindowIcon(void); +static char vidModeName[MAXWINMODES][32]; +static const char *fallback_resolution_name = "Fallback"; + +#define VIDEO_INIT_ERROR(str) { \ + if (!graphics_started) \ + I_Error(str, SDL_GetError()); \ + else \ + CONS_Printf(str "\n", SDL_GetError()); \ +} + +static SDL_bool Impl_RenderContextCreate(void) +{ + if (rendermode != render_opengl) + { + int flags = 0; // Use this to set SDL_RENDERER_* flags now + + if (usesdl2soft) + flags |= SDL_RENDERER_SOFTWARE; + else if (cv_vidwait.value) + { +#if SDL_VERSION_ATLEAST(2, 0, 18) + // If SDL is new enough, we can turn off vsync later. + flags |= SDL_RENDERER_PRESENTVSYNC; +#else + // However, if it isn't, we should just silently turn vid_wait off + // This is because the renderer will be created before the config + // is read and vid_wait is set from the user's preferences, and thus + // vid_wait will have no effect. + CV_StealthSetValue(&cv_vidwait, 0); +#endif + } + + if (!renderer) + renderer = SDL_CreateRenderer(window, -1, flags); + + if (renderer == NULL) + { + VIDEO_INIT_ERROR("Couldn't create rendering context: %s"); + return SDL_FALSE; + } + } + +#ifdef HWRENDER + if (rendermode == render_opengl && vid.glstate != VID_GL_LIBRARY_ERROR) + { + if (sdlglcontext == NULL) + { + sdlglcontext = SDL_GL_CreateContext(window); + + if (sdlglcontext == NULL) + { + VIDEO_INIT_ERROR("Couldn't create OpenGL context: %s"); + return SDL_FALSE; + } + } + } +#endif + + return SDL_TRUE; +} + +static SDL_bool Impl_RenderContextReset(void) +{ + if (renderer) + { + SDL_DestroyRenderer(renderer); + texture = NULL; // Destroying a renderer also destroys all of its textures + } + renderer = NULL; + + if (Impl_RenderContextCreate() == SDL_FALSE) + return SDL_FALSE; + + if (vidSurface != NULL) + { + SDL_FreeSurface(vidSurface); + vidSurface = NULL; + } + + if (bufSurface != NULL) + { + SDL_FreeSurface(bufSurface); + bufSurface = NULL; + } + +#ifdef HWRENDER + if (rendermode == render_opengl) + { + SDL_GL_MakeCurrent(window, sdlglcontext); + SDL_GL_SetSwapInterval(cv_vidwait.value ? 1 : 0); + + OglSdlSurface(realwidth, realheight); + HWR_Startup(); + } + else +#endif + { + SDL_RenderClear(renderer); + SDL_RenderSetLogicalSize(renderer, realwidth, realheight); + Impl_VideoSetupSurfaces(realwidth, realheight); + } + + return SDL_TRUE; +} static void Impl_SetSoftwareVsync(int vsync) { @@ -205,25 +308,78 @@ static void Impl_SetSoftwareVsync(int vsync) #endif } -static void SDLSetMode(INT32 width, INT32 height, SDL_bool fullscreen, SDL_bool reposition) +static void Impl_VideoSetupSurfaces(int width, int height) { - static SDL_bool wasfullscreen = SDL_FALSE; - Uint32 rmask; - Uint32 gmask; - Uint32 bmask; - Uint32 amask; int bpp = 16; int sw_texture_format = SDL_PIXELFORMAT_ABGR8888; - realwidth = vid.width; - realheight = vid.height; +#if !defined(__ANDROID__) + if (!usesdl2soft) + { + sw_texture_format = SDL_PIXELFORMAT_RGB565; + } + else +#endif + { + bpp = 32; + sw_texture_format = SDL_PIXELFORMAT_RGBA8888; + } + + if (texture == NULL) + texture = SDL_CreateTexture(renderer, sw_texture_format, SDL_TEXTUREACCESS_STREAMING, width, height); + + // Set up SW surface + if (vidSurface == NULL) + { + Uint32 rmask; + Uint32 gmask; + Uint32 bmask; + Uint32 amask; + + SDL_PixelFormatEnumToMasks(sw_texture_format, &bpp, &rmask, &gmask, &bmask, &amask); + vidSurface = SDL_CreateRGBSurface(0, width, height, bpp, rmask, gmask, bmask, amask); + } +} + +static void Impl_SetupSoftwareBuffer(void) +{ + // Set up game's software render buffer + size_t size; + + vid.rowbytes = vid.width * vid.bpp; + vid.direct = NULL; + + free(vid.buffer); + + size = vid.rowbytes*vid.height * NUMSCREENS; + vid.buffer = static_cast(malloc(size)); + + if (vid.buffer) + { + // Clear the buffer + // HACK: Wasn't sure where else to put this. + memset(vid.buffer, 31, size); + } + else + I_Error("%s", M_GetText("Not enough memory for video buffer\n")); +} + +static SDL_Rect src_rect = { 0, 0, 0, 0 }; + +static SDL_bool SDLSetMode(INT32 width, INT32 height, SDL_bool fullscreen, SDL_bool reposition) +{ + static SDL_bool wasfullscreen = SDL_FALSE; + int fullscreen_type = SDL_WINDOW_FULLSCREEN_DESKTOP; + + src_rect.w = realwidth = width; + src_rect.h = realheight = height; if (window) { if (fullscreen) { wasfullscreen = SDL_TRUE; - SDL_SetWindowFullscreen(window, SDL_WINDOW_FULLSCREEN_DESKTOP); + SDL_SetWindowFullscreen(window, fullscreen_type); } else // windowed mode { @@ -233,9 +389,12 @@ static void SDLSetMode(INT32 width, INT32 height, SDL_bool fullscreen, SDL_bool SDL_SetWindowFullscreen(window, 0); } // Reposition window only in windowed mode + SDL_SetWindowSize(window, width, height); + if (reposition) { + // Reposition window only in windowed mode SDL_SetWindowPosition(window, SDL_WINDOWPOS_CENTERED_DISPLAY(SDL_GetWindowDisplayIndex(window)), SDL_WINDOWPOS_CENTERED_DISPLAY(SDL_GetWindowDisplayIndex(window)) @@ -245,60 +404,45 @@ static void SDLSetMode(INT32 width, INT32 height, SDL_bool fullscreen, SDL_bool } else { - Impl_CreateWindow(fullscreen); + if (Impl_CreateWindow(fullscreen) == SDL_FALSE) + return SDL_FALSE; + wasfullscreen = fullscreen; SDL_SetWindowSize(window, width, height); if (fullscreen) - { - SDL_SetWindowFullscreen(window, SDL_WINDOW_FULLSCREEN_DESKTOP); - } + SDL_SetWindowFullscreen(window, fullscreen_type); } -#ifdef HWRENDER - if (rendermode == render_opengl) + if (Impl_RenderContextReset() == SDL_FALSE) + I_Error("Couldn't create or reset rendering context"); + + if (vid.buffer) { - OglSdlSurface(vid.width, vid.height); + free(vid.buffer); + vid.buffer = NULL; } -#endif - if (rendermode == render_soft) + return SDL_TRUE; +} + +static UINT32 VID_GetRefreshRate(void) +{ + int index = SDL_GetWindowDisplayIndex(window); + SDL_DisplayMode m; + + if (SDL_WasInit(SDL_INIT_VIDEO) == 0) { - SDL_RenderClear(renderer); - SDL_RenderSetLogicalSize(renderer, width, height); - // Set up Texture - realwidth = width; - realheight = height; - if (texture != NULL) - { - SDL_DestroyTexture(texture); - } - - if (!usesdl2soft) - { - sw_texture_format = SDL_PIXELFORMAT_RGB565; - } - else - { - bpp = 32; - sw_texture_format = SDL_PIXELFORMAT_RGBA8888; - } - - texture = SDL_CreateTexture(renderer, sw_texture_format, SDL_TEXTUREACCESS_STREAMING, width, height); - - // Set up SW surface - if (vidSurface != NULL) - { - SDL_FreeSurface(vidSurface); - } - if (vid.buffer) - { - free(vid.buffer); - vid.buffer = NULL; - } - SDL_PixelFormatEnumToMasks(sw_texture_format, &bpp, &rmask, &gmask, &bmask, &amask); - vidSurface = SDL_CreateRGBSurface(0, width, height, bpp, rmask, gmask, bmask, amask); - Impl_SetSoftwareVsync(cv_vidwait.value); + // Video not init yet. + return 0; } + + if (SDL_GetCurrentDisplayMode(index, &m) != 0) + { + // Error has occurred. + return 0; + } + + return m.refresh_rate; } static INT32 Impl_SDL_Scancode_To_Keycode(SDL_Scancode code) @@ -385,6 +529,7 @@ static INT32 Impl_SDL_Scancode_To_Keycode(SDL_Scancode code) case SDL_SCANCODE_RALT: return KEY_RALT; case SDL_SCANCODE_LGUI: return KEY_LEFTWIN; case SDL_SCANCODE_RGUI: return KEY_RIGHTWIN; + default: break; } return 0; @@ -465,65 +610,14 @@ static void SurfaceInfo(const SDL_Surface *infoSurface, const char *SurfaceText) static void VID_Command_Info_f (void) { -#if 0 - SDL2STUB(); -#else -#if 0 - const SDL_VideoInfo *videoInfo; - videoInfo = SDL_GetVideoInfo(); //Alam: Double-Check - if (videoInfo) - { - CONS_Printf("%s", M_GetText("Video Interface Capabilities:\n")); - if (videoInfo->hw_available) - CONS_Printf("%s", M_GetText(" Hardware surfaces\n")); - if (videoInfo->wm_available) - CONS_Printf("%s", M_GetText(" Window manager\n")); - //UnusedBits1 :6 - //UnusedBits2 :1 - if (videoInfo->blit_hw) - CONS_Printf("%s", M_GetText(" Accelerated blits HW-2-HW\n")); - if (videoInfo->blit_hw_CC) - CONS_Printf("%s", M_GetText(" Accelerated blits HW-2-HW with Colorkey\n")); - if (videoInfo->wm_available) - CONS_Printf("%s", M_GetText(" Accelerated blits HW-2-HW with Alpha\n")); - if (videoInfo->blit_sw) - { - CONS_Printf("%s", M_GetText(" Accelerated blits SW-2-HW\n")); - if (!M_CheckParm("-noblit")) videoblitok = SDL_TRUE; - } - if (videoInfo->blit_sw_CC) - CONS_Printf("%s", M_GetText(" Accelerated blits SW-2-HW with Colorkey\n")); - if (videoInfo->blit_sw_A) - CONS_Printf("%s", M_GetText(" Accelerated blits SW-2-HW with Alpha\n")); - if (videoInfo->blit_fill) - CONS_Printf("%s", M_GetText(" Accelerated Color filling\n")); - //UnusedBits3 :16 - if (videoInfo->video_mem) - CONS_Printf(M_GetText(" There is %i KB of video memory\n"), videoInfo->video_mem); - else - CONS_Printf("%s", M_GetText(" There no video memory for SDL\n")); - //*vfmt - } -#else - if (!M_CheckParm("-noblit")) videoblitok = SDL_TRUE; -#endif SurfaceInfo(bufSurface, M_GetText("Current Engine Mode")); SurfaceInfo(vidSurface, M_GetText("Current Video Mode")); -#endif } 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++) - { + for (INT32 i = 0; i < MAXWINMODES; i++) CONS_Printf("%2d: %dx%d\n", i, windowedModes[i][0], windowedModes[i][1]); - } - } static void VID_Command_Mode_f (void) @@ -541,7 +635,26 @@ static void VID_Command_Mode_f (void) if (modenum >= VID_NumModes()) CONS_Printf(M_GetText("Video mode not present\n")); else - setmodeneeded = modenum+1; // request vid mode change + { + setmodeneeded = modenum + 1; // request vid mode change + } +} + +static void Impl_SetFocused(boolean focused) +{ + window_notinfocus = !focused; + + if (window_notinfocus) + { + if (! cv_playmusicifunfocused.value) + S_PauseAudio(); + if (! cv_playsoundifunfocused.value) + S_StopSounds(); + + memset(gamekeydown, 0, NUMKEYS); // TODO this is a scary memset + } + else if (!paused) + S_ResumeAudio(); } static inline void SDLJoyRemap(event_t *event) @@ -579,13 +692,10 @@ 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; - const unsigned int oldfocus = FOCUSUNION; - switch (evt.event) { case SDL_WINDOWEVENT_ENTER: @@ -604,28 +714,17 @@ static void Impl_HandleWindowEvent(SDL_WindowEvent evt) break; case SDL_WINDOWEVENT_MAXIMIZED: break; - } - - if (FOCUSUNION == oldfocus) // No state change - { - return; + case SDL_WINDOWEVENT_SIZE_CHANGED: + break; } if (mousefocus && kbfocus) { // Tell game we got focus back, resume music if necessary - window_notinfocus = false; + Impl_SetFocused(true); - S_InitMusicVolume(); - - if (cv_gamesounds.value) - S_EnableSound(); - - if (!firsttimeonmouse) - { - if (cv_usemouse.value) I_StartupMouse(); - } - //else firsttimeonmouse = SDL_FALSE; + if (!firsttimeonmouse && cv_usemouse.value) + I_StartupMouse(); if (USE_MOUSEINPUT && !IgnoreMouse()) SDLdoGrabMouse(); @@ -633,25 +732,14 @@ static void Impl_HandleWindowEvent(SDL_WindowEvent evt) else if (!mousefocus && !kbfocus) { // Tell game we lost focus, pause music - window_notinfocus = true; - if (!cv_playmusicifunfocused.value) - I_SetMusicVolume(0); - if (!cv_playsoundifunfocused.value) - S_DisableSound(); + Impl_SetFocused(false); if (!disable_mouse) - { SDLforceUngrabMouse(); - } - memset(gamekeydown, 0, sizeof(gamekeydown)); // TODO this is a scary memset - memset(deviceResponding, false, sizeof (deviceResponding)); if (MOUSE_MENU) - { SDLdoUngrabMouse(); - } } -#undef FOCUSUNION } static void Impl_HandleKeyboardEvent(SDL_KeyboardEvent evt, Uint32 type) @@ -673,6 +761,7 @@ static void Impl_HandleKeyboardEvent(SDL_KeyboardEvent evt, Uint32 type) return; } event.data1 = Impl_SDL_Scancode_To_Keycode(evt.keysym.scancode); + if (event.data1) D_PostEvent(&event); } @@ -886,31 +975,35 @@ static void Impl_HandleControllerButtonEvent(SDL_ControllerButtonEvent evt, Uint } } +static void Impl_HandleVideoEvent(SDL_Event *evt) +{ + switch (evt->type) + { + case SDL_WINDOWEVENT: + Impl_HandleWindowEvent(evt->window); + break; + default: + break; + } +} + void I_GetEvent(void) { SDL_Event evt; char* dropped_filedir; - // We only want the first motion event, - // otherwise we'll end up catching the warp back to center. - //int mouseMotionOnce = 0; - UINT8 i; - if (!graphics_started) - { - return; - } - mousemovex = mousemovey = 0; while (SDL_PollEvent(&evt)) { switch (evt.type) { - case SDL_WINDOWEVENT: - Impl_HandleWindowEvent(evt.window); + default: + Impl_HandleVideoEvent(&evt); break; + // TODO: Move input code out of this file, desperately case SDL_KEYUP: case SDL_KEYDOWN: Impl_HandleKeyboardEvent(evt.key, evt.type); @@ -1160,24 +1253,6 @@ void I_OsPolling(void) // void I_UpdateNoBlit(void) { - if (rendermode == render_none) - return; - if (exposevideo) - { -#ifdef HWRENDER - if (rendermode == render_opengl) - { - OglSdlFinishUpdate(cv_vidwait.value); - } - else -#endif - if (rendermode == render_soft) - { - SDL_RenderCopy(renderer, texture, NULL, NULL); - SDL_RenderPresent(renderer); - } - } - exposevideo = SDL_FALSE; } // I_SkipFrame @@ -1214,8 +1289,6 @@ static inline boolean I_SkipFrame(void) // // I_FinishUpdate // -static SDL_Rect src_rect = { 0, 0, 0, 0 }; - void I_FinishUpdate(void) { int player; @@ -1225,9 +1298,6 @@ void I_FinishUpdate(void) SCR_CalculateFPS(); - if (I_SkipFrame()) - return; - if (st_overlay) { if (cv_ticrate.value) @@ -1274,19 +1344,14 @@ void I_FinishUpdate(void) if (rendermode == render_soft && screens[0]) { - if (!bufSurface) //Double-Check - { - Impl_VideoSetupSDLBuffer(); - } + if (!bufSurface) // Double-check + Impl_VideoSetupBuffer(); - if (bufSurface) - { - SDL_BlitSurface(bufSurface, &src_rect, vidSurface, &src_rect); - // Fury -- there's no way around UpdateTexture, the GL backend uses it anyway - SDL_LockSurface(vidSurface); - SDL_UpdateTexture(texture, &src_rect, vidSurface->pixels, vidSurface->pitch); - SDL_UnlockSurface(vidSurface); - } + SDL_BlitSurface(bufSurface, &src_rect, vidSurface, &src_rect); + // Fury -- there's no way around UpdateTexture, the GL backend uses it anyway + SDL_LockSurface(vidSurface); + SDL_UpdateTexture(texture, &src_rect, vidSurface->pixels, vidSurface->pitch); + SDL_UnlockSurface(vidSurface); SDL_RenderClear(renderer); SDL_RenderCopy(renderer, texture, &src_rect, NULL); @@ -1295,12 +1360,8 @@ void I_FinishUpdate(void) } #ifdef HWRENDER else if (rendermode == render_opengl) - { OglSdlFinishUpdate(cv_vidwait.value); - } #endif - - exposevideo = SDL_FALSE; } // @@ -1347,39 +1408,18 @@ void I_SetPalette(RGBA_t *palette) // return number of fullscreen + X11 modes INT32 VID_NumModes(void) { - if (USE_FULLSCREEN && numVidModes != -1) - return numVidModes - firstEntry; - else - return MAXWINMODES; + return MAXWINMODES; } const char *VID_GetModeName(INT32 modeNum) { -#if 0 - if (USE_FULLSCREEN && numVidModes != -1) // fullscreen modes - { - modeNum += firstEntry; - if (modeNum >= numVidModes) - return NULL; - sprintf(&vidModeName[modeNum][0], "%dx%d", - modeList[modeNum]->w, - modeList[modeNum]->h); - } - else // windowed modes - { -#endif if (modeNum == -1) - { return fallback_resolution_name; - } - if (modeNum > MAXWINMODES) - return NULL; + else if (modeNum > MAXWINMODES) + return NULL; - sprintf(&vidModeName[modeNum][0], "%dx%d", - windowedModes[modeNum][0], - windowedModes[modeNum][1]); - //} + snprintf(&vidModeName[modeNum][0], 32, "%dx%d", windowedModes[modeNum][0], windowedModes[modeNum][1]); return &vidModeName[modeNum][0]; } @@ -1404,146 +1444,12 @@ INT32 VID_GetModeForSize(INT32 w, INT32 h) return CUSTOMMODENUM; } return -1; -#if 0 - INT32 matchMode = -1, i; - VID_PrepareModeList(); - if (USE_FULLSCREEN && numVidModes != -1) - { - for (i=firstEntry; iw == w && - modeList[i]->h == h) - { - matchMode = i; - break; - } - } - if (-1 == matchMode) // use smaller mode - { - w -= w%BASEVIDWIDTH; - h -= h%BASEVIDHEIGHT; - for (i=firstEntry; iw == w && - modeList[i]->h == h) - { - matchMode = i; - break; - } - } - if (-1 == matchMode) // use smallest mode - matchMode = numVidModes-1; - } - matchMode -= firstEntry; - } - else - { - for (i=0; iw <= MAXVIDWIDTH && - modeList[i]->h <= MAXVIDHEIGHT) - { - firstEntry = i; - break; - } - } - } - } - allow_fullscreen = true; -#endif -} - -static SDL_bool Impl_CreateContext(void) -{ - // Renderer-specific stuff -#ifdef HWRENDER - if ((rendermode == render_opengl) - && (vid.glstate != VID_GL_LIBRARY_ERROR)) - { - if (!sdlglcontext) - sdlglcontext = SDL_GL_CreateContext(window); - if (sdlglcontext == NULL) - { - SDL_DestroyWindow(window); - I_Error("Failed to create a GL context: %s\n", SDL_GetError()); - } - SDL_GL_MakeCurrent(window, sdlglcontext); - } - else -#endif - if (rendermode == render_soft) - { - int flags = 0; // Use this to set SDL_RENDERER_* flags now - if (usesdl2soft) - flags |= SDL_RENDERER_SOFTWARE; - - // 3 August 2022 - // Possibly a Windows 11 issue; the default - // "direct3d" driver (D3D9) causes Drmingw exchndl - // to not write RPT files. Every other driver - // seems fine. - SDL_SetHint(SDL_HINT_RENDER_DRIVER, "opengl"); - - if (!renderer) - renderer = SDL_CreateRenderer(window, -1, flags); - if (renderer == NULL) - { - CONS_Printf(M_GetText("Couldn't create rendering context: %s\n"), SDL_GetError()); - return SDL_FALSE; - } - SDL_RenderSetLogicalSize(renderer, BASEVIDWIDTH, BASEVIDHEIGHT); - } - return SDL_TRUE; } void VID_CheckGLLoaded(rendermode_t oldrender) @@ -1552,7 +1458,6 @@ void VID_CheckGLLoaded(rendermode_t oldrender) #ifdef HWRENDER if (vid.glstate == VID_GL_LIBRARY_ERROR) // Well, it didn't work the first time anyway. { - CONS_Alert(CONS_ERROR, "OpenGL never loaded\n"); rendermode = oldrender; if (chosenrendermode == render_opengl) // fallback to software rendermode = render_soft; @@ -1568,13 +1473,15 @@ void VID_CheckGLLoaded(rendermode_t oldrender) boolean VID_CheckRenderer(void) { boolean rendererchanged = false; - boolean contextcreated = false; + #ifdef HWRENDER rendermode_t oldrenderer = rendermode; #endif + refresh_rate = VID_GetRefreshRate(); + if (dedicated) - return false; + return 0; if (setrenderneeded) { @@ -1586,58 +1493,39 @@ boolean VID_CheckRenderer(void) { VID_CheckGLLoaded(oldrenderer); - // Initialise OpenGL before calling SDLSetMode!!! - // This is because SDLSetMode calls OglSdlSurface. + // Initialize OpenGL before calling SDLSetMode, because it calls OglSdlSurface. if (vid.glstate == VID_GL_LIBRARY_NOTLOADED) - { - VID_StartupOpenGL(); - - // Loaded successfully! - if (vid.glstate == VID_GL_LIBRARY_LOADED) - { - // Destroy the current window, if it exists. - if (window) - { - SDL_DestroyWindow(window); - window = NULL; - } - - // Destroy the current window rendering context, if that also exists. - if (renderer) - { - SDL_DestroyRenderer(renderer); - renderer = NULL; - } - - // Create a new window. - Impl_CreateWindow(static_cast(USE_FULLSCREEN)); - - // From there, the OpenGL context was already created. - contextcreated = true; - } - } + Impl_InitOpenGL(); else if (vid.glstate == VID_GL_LIBRARY_ERROR) rendererchanged = false; } #endif - if (!contextcreated) - Impl_CreateContext(); - setrenderneeded = 0; } - SDLSetMode(vid.width, vid.height, static_cast(USE_FULLSCREEN), (setmodeneeded ? SDL_TRUE : SDL_FALSE)); - Impl_VideoSetupBuffer(); + SDL_bool center = setmodeneeded ? SDL_TRUE : SDL_FALSE; + + if (SDLSetMode(vid.width, vid.height, USE_FULLSCREEN, center) == SDL_FALSE) + { + if (!graphics_started) + { + // Guess I'll die + I_Error("Couldn't initialize video"); + } + else + { + CONS_Printf("Couldn't initialize video\n"); + return false; + } + } + + if (rendererchanged) + vid.recalc = true; if (rendermode == render_soft) { - if (bufSurface) - { - SDL_FreeSurface(bufSurface); - bufSurface = NULL; - } - + Impl_SetupSoftwareBuffer(); SCR_SetDrawFuncs(); } #ifdef HWRENDER @@ -1651,32 +1539,30 @@ boolean VID_CheckRenderer(void) return rendererchanged; } -static UINT32 refresh_rate; -static UINT32 VID_GetRefreshRate(void) +#if 0 +static void Impl_GetCurrentDisplayMode(INT32 *width, INT32 *height) { - int index = SDL_GetWindowDisplayIndex(window); - SDL_DisplayMode m; + int i = SDL_GetWindowDisplayIndex(window); + SDL_DisplayMode resolution; - if (SDL_WasInit(SDL_INIT_VIDEO) == 0) + if (i < 0) + return; + + if (!SDL_GetCurrentDisplayMode(i, &resolution)) { - // Video not init yet. - return 0; + if ((*width) == 0) + (*width) = (INT32)(resolution.w); + if ((*height) == 0) + (*height) = (INT32)(resolution.h); } - - if (SDL_GetCurrentDisplayMode(index, &m) != 0) - { - // Error has occurred. - return 0; - } - - return m.refresh_rate; } +#endif INT32 VID_SetMode(INT32 modeNum) { SDLdoUngrabMouse(); - vid.recalc = 1; + vid.recalc = true; vid.bpp = 1; if (modeNum >= 0 && modeNum < MAXWINMODES) @@ -1710,13 +1596,8 @@ INT32 VID_SetMode(INT32 modeNum) vid.modenum = -1; } - src_rect.w = vid.width; - src_rect.h = vid.height; - - refresh_rate = VID_GetRefreshRate(); - - //Impl_SetWindowName("SRB2Kart "VERSIONSTRING); VID_CheckRenderer(); + return SDL_TRUE; } @@ -1724,11 +1605,8 @@ static SDL_bool Impl_CreateWindow(SDL_bool fullscreen) { int flags = 0; - if (rendermode == render_none) // dedicated - return SDL_TRUE; // Monster Iestyn -- not sure if it really matters what we return here tbh - if (window != NULL) - return SDL_FALSE; + return SDL_TRUE; if (fullscreen) flags |= SDL_WINDOW_FULLSCREEN_DESKTOP; @@ -1737,44 +1615,35 @@ static SDL_bool Impl_CreateWindow(SDL_bool fullscreen) flags |= SDL_WINDOW_BORDERLESS; #ifdef HWRENDER - if (vid.glstate == VID_GL_LIBRARY_LOADED) - flags |= SDL_WINDOW_OPENGL; + flags |= SDL_WINDOW_OPENGL; #endif // Create a window - window = SDL_CreateWindow("SRB2Kart " VERSIONSTRING, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, - realwidth, realheight, flags); - + window = SDL_CreateWindow("SRB2Kart " VERSIONSTRING, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, realwidth, realheight, flags); if (window == NULL) { - CONS_Printf(M_GetText("Couldn't create window: %s\n"), SDL_GetError()); + VIDEO_INIT_ERROR("Couldn't create window: %s"); return SDL_FALSE; } +#ifdef USE_WINDOW_ICON Impl_SetWindowIcon(); +#endif + + return SDL_TRUE; - return Impl_CreateContext(); } -/* -static void Impl_SetWindowName(const char *title) -{ - if (window == NULL) - { - return; - } - SDL_SetWindowTitle(window, title); -} -*/ - +#ifdef USE_WINDOW_ICON static void Impl_SetWindowIcon(void) { if (window && icoSurface) SDL_SetWindowIcon(window, icoSurface); } +#endif -static void Impl_VideoSetupSDLBuffer(void) +static void Impl_VideoSetupBuffer(void) { if (bufSurface != NULL) { @@ -1802,32 +1671,26 @@ static void Impl_VideoSetupSDLBuffer(void) } } -static void Impl_VideoSetupBuffer(void) +static void Impl_InitVideoSubSystem(void) { - // Set up game's software render buffer - vid.rowbytes = vid.width * vid.bpp; - vid.direct = NULL; - if (vid.buffer) - free(vid.buffer); - vid.buffer = static_cast(calloc(vid.rowbytes*vid.height, NUMSCREENS)); - if (!vid.buffer) - { - I_Error("%s", M_GetText("Not enough memory for video buffer\n")); - } -} - -void I_RegisterSysCommands(void) -{ - if (dedicated || graphics_started) + if (video_init) return; - COM_AddCommand ("vid_nummodes", VID_Command_NumModes_f); - COM_AddCommand ("vid_info", VID_Command_Info_f); - COM_AddCommand ("vid_modelist", VID_Command_ModeList_f); - COM_AddCommand ("vid_mode", VID_Command_Mode_f); - CV_RegisterVar (&cv_vidwait); - CV_RegisterVar (&cv_stretch); - CV_RegisterVar (&cv_alwaysgrabmouse); + if (SDL_InitSubSystem(SDL_INIT_VIDEO) < 0) + { + CONS_Printf(M_GetText("Couldn't initialize SDL's Video System: %s\n"), SDL_GetError()); + return; + } + +#ifdef HAVE_GLES + Impl_InitGLESDriver(); +#endif + +#ifdef MOBILE_PLATFORM + SDL_SetHint(SDL_HINT_ORIENTATIONS, "LandscapeLeft LandscapeRight"); +#endif + + video_init = true; } void I_StartupGraphics(void) @@ -1840,31 +1703,38 @@ void I_StartupGraphics(void) if (graphics_started) return; + COM_AddCommand ("vid_nummodes", VID_Command_NumModes_f); + COM_AddCommand ("vid_info", VID_Command_Info_f); + COM_AddCommand ("vid_modelist", VID_Command_ModeList_f); + COM_AddCommand ("vid_mode", VID_Command_Mode_f); + CV_RegisterVar (&cv_vidwait); + CV_RegisterVar (&cv_stretch); + CV_RegisterVar (&cv_alwaysgrabmouse); disable_mouse = static_cast(M_CheckParm("-nomouse")); disable_fullscreen = M_CheckParm("-win") ? SDL_TRUE : SDL_FALSE; keyboard_started = true; -#if !defined(HAVE_TTF) - // Previously audio was init here for questionable reasons? - if (SDL_InitSubSystem(SDL_INIT_VIDEO) < 0) - { - CONS_Printf(M_GetText("Couldn't initialize SDL's Video System: %s\n"), SDL_GetError()); - return; - } -#endif + // If it wasn't already initialized + if (!video_init) + Impl_InitVideoSubSystem(); + + const char *vd = SDL_GetCurrentVideoDriver(); + if (vd) { const char *vd = SDL_GetCurrentVideoDriver(); //CONS_Printf(M_GetText("Starting up with video driver: %s\n"), vd); - if (vd && ( + if ( strncasecmp(vd, "gcvideo", 8) == 0 || strncasecmp(vd, "fbcon", 6) == 0 || strncasecmp(vd, "wii", 4) == 0 || strncasecmp(vd, "psl1ght", 8) == 0 - )) + ) framebuffer = SDL_TRUE; } + rendermode = render_soft; + // Renderer choices // Takes priority over the config. if (M_CheckParm("-renderer")) @@ -1907,54 +1777,36 @@ void I_StartupGraphics(void) usesdl2soft = M_CheckParm("-softblit") ? SDL_TRUE : SDL_FALSE; borderlesswindow = M_CheckParm("-borderless") ? SDL_TRUE : SDL_FALSE; - //SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY>>1,SDL_DEFAULT_REPEAT_INTERVAL<<2); - VID_Command_ModeList_f(); - #ifdef HWRENDER if (rendermode == render_opengl) - VID_StartupOpenGL(); + Impl_InitOpenGL(); #endif // Window icon -#ifdef HAVE_IMAGE +#ifdef USE_WINDOW_ICON icoSurface = IMG_ReadXPMFromArray(SDL_icon_xpm); #endif // Fury: we do window initialization after GL setup to allow // SDL_GL_LoadLibrary to work well on Windows + vid.recalc = true; + vid.direct = NULL; + vid.bpp = 1; + vid.WndParent = NULL; // Create window - //Impl_CreateWindow(USE_FULLSCREEN); - //Impl_SetWindowName("SRB2Kart "VERSIONSTRING); - VID_SetMode(VID_GetModeForSize(BASEVIDWIDTH, BASEVIDHEIGHT)); + // Default size for startup + vid.width = BASEVIDWIDTH; + vid.height = BASEVIDHEIGHT; - vid.width = BASEVIDWIDTH; // Default size for startup - vid.height = BASEVIDHEIGHT; // BitsPerPixel is the SDL interface's - vid.recalc = true; // Set up the console stufff - vid.direct = NULL; // Maybe direct access? - vid.bpp = 1; // This is the game engine's Bpp - vid.WndParent = NULL; //For the window? + VID_SetMode(VID_GetModeForSize(vid.width, vid.height)); #ifdef HAVE_TTF I_ShutdownTTF(); #endif - VID_SetMode(VID_GetModeForSize(BASEVIDWIDTH, BASEVIDHEIGHT)); - if (M_CheckParm("-nomousegrab")) mousegrabok = SDL_FALSE; -#if 0 // defined (_DEBUG) - else - { - char videodriver[4] = {'S','D','L',0}; - if (!M_CheckParm("-mousegrab") && - *strncpy(videodriver, SDL_GetCurrentVideoDriver(), 4) != '\0' && - strncasecmp("x11",videodriver,4) == 0) - mousegrabok = SDL_FALSE; //X11's XGrabPointer not good - } -#endif - realwidth = (Uint16)vid.width; - realheight = (Uint16)vid.height; VID_Command_Info_f(); SDLdoUngrabMouse(); @@ -1967,81 +1819,90 @@ void I_StartupGraphics(void) graphics_started = true; } -void VID_StartupOpenGL(void) +static void Impl_InitOpenGL(void) { #ifdef HWRENDER - static boolean glstartup = false; - if (!glstartup) + if (vid.glstate == VID_GL_LIBRARY_LOADED) + return; + + CONS_Printf("VID_StartupOpenGL()...\n"); + *(void**)&HWD.pfnInit = hwSym("Init",NULL); + *(void**)&HWD.pfnFinishUpdate = NULL; + *(void**)&HWD.pfnDraw2DLine = hwSym("Draw2DLine",NULL); + *(void**)&HWD.pfnDrawPolygon = hwSym("DrawPolygon",NULL); + *(void**)&HWD.pfnDrawIndexedTriangles = hwSym("DrawIndexedTriangles",NULL); + *(void**)&HWD.pfnRenderSkyDome = hwSym("RenderSkyDome",NULL); + *(void**)&HWD.pfnSetBlend = hwSym("SetBlend",NULL); + *(void**)&HWD.pfnClearBuffer = hwSym("ClearBuffer",NULL); + *(void**)&HWD.pfnSetTexture = hwSym("SetTexture",NULL); + *(void**)&HWD.pfnUpdateTexture = hwSym("UpdateTexture",NULL); + *(void**)&HWD.pfnDeleteTexture = hwSym("DeleteTexture",NULL); + *(void**)&HWD.pfnReadRect = hwSym("ReadRect",NULL); + *(void**)&HWD.pfnGClipRect = hwSym("GClipRect",NULL); + *(void**)&HWD.pfnClearMipMapCache = hwSym("ClearMipMapCache",NULL); + *(void**)&HWD.pfnSetSpecialState = hwSym("SetSpecialState",NULL); + *(void**)&HWD.pfnSetPalette = hwSym("SetPalette",NULL); + *(void**)&HWD.pfnGetTextureUsed = hwSym("GetTextureUsed",NULL); + *(void**)&HWD.pfnDrawModel = hwSym("DrawModel",NULL); + *(void**)&HWD.pfnCreateModelVBOs = hwSym("CreateModelVBOs",NULL); + *(void**)&HWD.pfnSetTransform = hwSym("SetTransform",NULL); + *(void**)&HWD.pfnPostImgRedraw = hwSym("PostImgRedraw",NULL); + *(void**)&HWD.pfnFlushScreenTextures=hwSym("FlushScreenTextures",NULL); + *(void**)&HWD.pfnStartScreenWipe = hwSym("StartScreenWipe",NULL); + *(void**)&HWD.pfnEndScreenWipe = hwSym("EndScreenWipe",NULL); + *(void**)&HWD.pfnDoScreenWipe = hwSym("DoScreenWipe",NULL); + *(void**)&HWD.pfnDrawIntermissionBG=hwSym("DrawIntermissionBG",NULL); + *(void**)&HWD.pfnMakeScreenTexture= hwSym("MakeScreenTexture",NULL); + *(void**)&HWD.pfnRenderVhsEffect = hwSym("RenderVhsEffect",NULL); + *(void**)&HWD.pfnMakeScreenFinalTexture=hwSym("MakeScreenFinalTexture",NULL); + *(void**)&HWD.pfnDrawScreenFinalTexture=hwSym("DrawScreenFinalTexture",NULL); + + *(void**)&HWD.pfnCompileShaders = hwSym("CompileShaders",NULL); + *(void**)&HWD.pfnCleanShaders = hwSym("CleanShaders",NULL); + *(void**)&HWD.pfnSetShader = hwSym("SetShader",NULL); + *(void**)&HWD.pfnUnSetShader = hwSym("UnSetShader",NULL); + + *(void**)&HWD.pfnSetShaderInfo = hwSym("SetShaderInfo",NULL); + *(void**)&HWD.pfnLoadCustomShader = hwSym("LoadCustomShader",NULL); + + if (HWD.pfnInit()) + vid.glstate = VID_GL_LIBRARY_LOADED; + else { - CONS_Printf("VID_StartupOpenGL()...\n"); - *(void**)&HWD.pfnInit = hwSym("Init",NULL); - *(void**)&HWD.pfnFinishUpdate = NULL; - *(void**)&HWD.pfnDraw2DLine = hwSym("Draw2DLine",NULL); - *(void**)&HWD.pfnDrawPolygon = hwSym("DrawPolygon",NULL); - *(void**)&HWD.pfnDrawIndexedTriangles = hwSym("DrawIndexedTriangles",NULL); - *(void**)&HWD.pfnRenderSkyDome = hwSym("RenderSkyDome",NULL); - *(void**)&HWD.pfnSetBlend = hwSym("SetBlend",NULL); - *(void**)&HWD.pfnClearBuffer = hwSym("ClearBuffer",NULL); - *(void**)&HWD.pfnSetTexture = hwSym("SetTexture",NULL); - *(void**)&HWD.pfnUpdateTexture = hwSym("UpdateTexture",NULL); - *(void**)&HWD.pfnDeleteTexture = hwSym("DeleteTexture",NULL); - *(void**)&HWD.pfnReadRect = hwSym("ReadRect",NULL); - *(void**)&HWD.pfnGClipRect = hwSym("GClipRect",NULL); - *(void**)&HWD.pfnClearMipMapCache = hwSym("ClearMipMapCache",NULL); - *(void**)&HWD.pfnSetSpecialState = hwSym("SetSpecialState",NULL); - *(void**)&HWD.pfnSetPalette = hwSym("SetPalette",NULL); - *(void**)&HWD.pfnGetTextureUsed = hwSym("GetTextureUsed",NULL); - *(void**)&HWD.pfnDrawModel = hwSym("DrawModel",NULL); - *(void**)&HWD.pfnCreateModelVBOs = hwSym("CreateModelVBOs",NULL); - *(void**)&HWD.pfnSetTransform = hwSym("SetTransform",NULL); - *(void**)&HWD.pfnPostImgRedraw = hwSym("PostImgRedraw",NULL); - *(void**)&HWD.pfnFlushScreenTextures=hwSym("FlushScreenTextures",NULL); - *(void**)&HWD.pfnStartScreenWipe = hwSym("StartScreenWipe",NULL); - *(void**)&HWD.pfnEndScreenWipe = hwSym("EndScreenWipe",NULL); - *(void**)&HWD.pfnDoScreenWipe = hwSym("DoScreenWipe",NULL); - *(void**)&HWD.pfnDrawIntermissionBG=hwSym("DrawIntermissionBG",NULL); - *(void**)&HWD.pfnMakeScreenTexture= hwSym("MakeScreenTexture",NULL); - *(void**)&HWD.pfnRenderVhsEffect = hwSym("RenderVhsEffect",NULL); - *(void**)&HWD.pfnMakeScreenFinalTexture=hwSym("MakeScreenFinalTexture",NULL); - *(void**)&HWD.pfnDrawScreenFinalTexture=hwSym("DrawScreenFinalTexture",NULL); + vid.glstate = VID_GL_LIBRARY_ERROR; - *(void**)&HWD.pfnCompileShaders = hwSym("CompileShaders",NULL); - *(void**)&HWD.pfnCleanShaders = hwSym("CleanShaders",NULL); - *(void**)&HWD.pfnSetShader = hwSym("SetShader",NULL); - *(void**)&HWD.pfnUnSetShader = hwSym("UnSetShader",NULL); + CV_StealthSet(&cv_renderer, "Software"); + rendermode = render_soft; - *(void**)&HWD.pfnSetShaderInfo = hwSym("SetShaderInfo",NULL); - *(void**)&HWD.pfnLoadCustomShader = hwSym("LoadCustomShader",NULL); - - vid.glstate = HWD.pfnInit() ? VID_GL_LIBRARY_LOADED : VID_GL_LIBRARY_ERROR; // let load the OpenGL library - - if (vid.glstate == VID_GL_LIBRARY_ERROR) - { - rendermode = render_soft; + if (setrenderneeded) setrenderneeded = 0; - } - glstartup = true; } #endif } void I_ShutdownGraphics(void) { - const rendermode_t oldrendermode = rendermode; - - rendermode = render_none; - if (icoSurface) SDL_FreeSurface(icoSurface); +#ifdef USE_WINDOW_ICON + if (icoSurface) + SDL_FreeSurface(icoSurface); icoSurface = NULL; - if (oldrendermode == render_soft) +#endif + if (rendermode == render_soft) { - if (vidSurface) SDL_FreeSurface(vidSurface); + if (vidSurface) + SDL_FreeSurface(vidSurface); vidSurface = NULL; - if (vid.buffer) free(vid.buffer); - vid.buffer = NULL; - if (bufSurface) SDL_FreeSurface(bufSurface); + + if (bufSurface) + SDL_FreeSurface(bufSurface); bufSurface = NULL; } + free(vid.buffer); + vid.buffer = NULL; + + rendermode = render_none; + I_OutputMsg("I_ShutdownGraphics(): "); // was graphics initialized anyway? From de91aa3a138f8e54481eb1e8663e8b10bec6d20f Mon Sep 17 00:00:00 2001 From: NepDisk Date: Tue, 3 Jun 2025 12:52:32 -0400 Subject: [PATCH 02/29] Clean up of I_video port --- src/sdl/i_video.cpp | 31 +------------------------------ 1 file changed, 1 insertion(+), 30 deletions(-) diff --git a/src/sdl/i_video.cpp b/src/sdl/i_video.cpp index 26d58bbe8..d25243eae 100644 --- a/src/sdl/i_video.cpp +++ b/src/sdl/i_video.cpp @@ -151,7 +151,7 @@ static void Impl_SetupSoftwareBuffer(void); static void Impl_InitOpenGL(void); -#if !defined(__ANDROID__) && defined(HAVE_IMAGE) +#if defined(HAVE_IMAGE) #define USE_WINDOW_ICON #endif @@ -313,13 +313,11 @@ static void Impl_VideoSetupSurfaces(int width, int height) int bpp = 16; int sw_texture_format = SDL_PIXELFORMAT_ABGR8888; -#if !defined(__ANDROID__) if (!usesdl2soft) { sw_texture_format = SDL_PIXELFORMAT_RGB565; } else -#endif { bpp = 32; sw_texture_format = SDL_PIXELFORMAT_RGBA8888; @@ -1539,25 +1537,6 @@ boolean VID_CheckRenderer(void) return rendererchanged; } -#if 0 -static void Impl_GetCurrentDisplayMode(INT32 *width, INT32 *height) -{ - int i = SDL_GetWindowDisplayIndex(window); - SDL_DisplayMode resolution; - - if (i < 0) - return; - - if (!SDL_GetCurrentDisplayMode(i, &resolution)) - { - if ((*width) == 0) - (*width) = (INT32)(resolution.w); - if ((*height) == 0) - (*height) = (INT32)(resolution.h); - } -} -#endif - INT32 VID_SetMode(INT32 modeNum) { SDLdoUngrabMouse(); @@ -1682,14 +1661,6 @@ static void Impl_InitVideoSubSystem(void) return; } -#ifdef HAVE_GLES - Impl_InitGLESDriver(); -#endif - -#ifdef MOBILE_PLATFORM - SDL_SetHint(SDL_HINT_ORIENTATIONS, "LandscapeLeft LandscapeRight"); -#endif - video_init = true; } From d0d8236bad0264a8d7b0746c89c68f5be7cf5d35 Mon Sep 17 00:00:00 2001 From: NepDisk Date: Tue, 3 Jun 2025 13:21:47 -0400 Subject: [PATCH 03/29] Fix waterpanel in deh_tables --- src/deh_tables.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/deh_tables.c b/src/deh_tables.c index 9eb28fce4..4bd08029b 100644 --- a/src/deh_tables.c +++ b/src/deh_tables.c @@ -1582,7 +1582,7 @@ struct int_const_s const INT_CONST[] = { // terrain_flags_t {"TRF_LIQUID",TRF_LIQUID}, {"TRF_SNEAKERPANEL",TRF_SNEAKERPANEL}, - {"TRF_WATERRUNPANEL",}, + {"TRF_WATERRUNPANEL", TRF_WATERRUNPANEL}, {"TRF_TRIPWIRE",TRF_TRIPWIRE}, {"TRF_REMAP",TRF_REMAP}, {"TRF_BYPASSBOOST", TRF_BYPASSBOOST}, From c958ce87ca1fa1e841579eb98a00411b7ebc9e7e Mon Sep 17 00:00:00 2001 From: NepDisk Date: Tue, 3 Jun 2025 13:47:29 -0400 Subject: [PATCH 04/29] I_RegisterSysCommands so video cvars are registerd before menu init happens --- src/d_main.cpp | 2 ++ src/dummy/i_system.c | 2 ++ src/i_system.h | 2 ++ src/sdl/i_video.cpp | 21 ++++++++++++++------- 4 files changed, 20 insertions(+), 7 deletions(-) diff --git a/src/d_main.cpp b/src/d_main.cpp index 137d92c10..22089ab2e 100644 --- a/src/d_main.cpp +++ b/src/d_main.cpp @@ -1459,6 +1459,8 @@ void D_SRB2Main(void) CV_RegisterVar(&cv_constextsize); } + I_RegisterSysCommands(); + #ifdef HWRENDER // Lactozilla: Add every hardware mode CVAR and CCMD. // Has to be done before the configuration file loads, diff --git a/src/dummy/i_system.c b/src/dummy/i_system.c index 94e021dfd..5cd88243d 100644 --- a/src/dummy/i_system.c +++ b/src/dummy/i_system.c @@ -174,5 +174,7 @@ char *I_ClipboardPaste(void) return NULL; } +void I_RegisterSysCommands(void) {} + #include "../sdl/dosstr.c" diff --git a/src/i_system.h b/src/i_system.h index 59439faf5..3624fbb03 100644 --- a/src/i_system.h +++ b/src/i_system.h @@ -326,6 +326,8 @@ INT32 I_ClipboardCopy(const char *data, size_t size); */ const char *I_ClipboardPaste(void); +void I_RegisterSysCommands(void); + #ifdef __cplusplus } // extern "C" #endif diff --git a/src/sdl/i_video.cpp b/src/sdl/i_video.cpp index d25243eae..c05272bb3 100644 --- a/src/sdl/i_video.cpp +++ b/src/sdl/i_video.cpp @@ -1664,6 +1664,20 @@ static void Impl_InitVideoSubSystem(void) video_init = true; } +void I_RegisterSysCommands(void) +{ + if (dedicated || graphics_started) + return; + + COM_AddCommand ("vid_nummodes", VID_Command_NumModes_f); + COM_AddCommand ("vid_info", VID_Command_Info_f); + COM_AddCommand ("vid_modelist", VID_Command_ModeList_f); + COM_AddCommand ("vid_mode", VID_Command_Mode_f); + CV_RegisterVar (&cv_vidwait); + CV_RegisterVar (&cv_stretch); + CV_RegisterVar (&cv_alwaysgrabmouse); +} + void I_StartupGraphics(void) { if (dedicated) @@ -1674,13 +1688,6 @@ void I_StartupGraphics(void) if (graphics_started) return; - COM_AddCommand ("vid_nummodes", VID_Command_NumModes_f); - COM_AddCommand ("vid_info", VID_Command_Info_f); - COM_AddCommand ("vid_modelist", VID_Command_ModeList_f); - COM_AddCommand ("vid_mode", VID_Command_Mode_f); - CV_RegisterVar (&cv_vidwait); - CV_RegisterVar (&cv_stretch); - CV_RegisterVar (&cv_alwaysgrabmouse); disable_mouse = static_cast(M_CheckParm("-nomouse")); disable_fullscreen = M_CheckParm("-win") ? SDL_TRUE : SDL_FALSE; From 6c10edcdb48084007c8fcb15ef6c3c3f7c6cbf43 Mon Sep 17 00:00:00 2001 From: NepDisk Date: Tue, 3 Jun 2025 14:05:21 -0400 Subject: [PATCH 05/29] Fix OpenGL gif recording issues --- src/m_anigif.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/m_anigif.c b/src/m_anigif.c index 6706b2cf8..89e3d13d2 100644 --- a/src/m_anigif.c +++ b/src/m_anigif.c @@ -584,7 +584,7 @@ static void GIF_framewrite(void) else if (rendermode == render_opengl) { UINT8 *linear = HWR_GetScreenshot(); - GIF_rgbconvert(linear, base_screen); + GIF_rgbconvert(linear, movie_screen); //free(linear); // Allocated 'statically', no need to free now } #endif @@ -600,7 +600,7 @@ static void GIF_framewrite(void) if (rendermode == render_opengl) { UINT8 *linear = HWR_GetScreenshot(); - GIF_rgbconvert(linear, screens[0]); + GIF_rgbconvert(linear, base_screen); //free(linear); // Allocated 'statically', no need to free now } #endif @@ -618,7 +618,7 @@ static void GIF_framewrite(void) UINT16 delay = 0; INT32 startline; - if (gif_dynamicdelay ==(UINT8) 2) + if (gif_dynamicdelay ==(UINT8) 2 && !singletics) { // golden's attempt at creating a "dynamic delay" UINT16 mingifdelay = 10; // minimum gif delay in milliseconds (keep at 10 because gifs can't get more precise). @@ -631,7 +631,7 @@ static void GIF_framewrite(void) gif_delayus -= frames*(mingifdelay*1000); // remove frames by the amount of milliseconds they take. don't reset to 0, the microseconds help consistency. } } - else if (gif_dynamicdelay ==(UINT8) 1) + else if (gif_dynamicdelay ==(UINT8) 1 && !singletics) { float delayf = ceil(100.0f/NEWTICRATE); From a47594d4be0a0adf2545002974d886cfa4e5659c Mon Sep 17 00:00:00 2001 From: NepDisk Date: Wed, 4 Jun 2025 17:52:04 -0400 Subject: [PATCH 06/29] Make this code look less ass --- src/k_kart.c | 20 +++++++------------- 1 file changed, 7 insertions(+), 13 deletions(-) diff --git a/src/k_kart.c b/src/k_kart.c index 085e46373..057145b5c 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -7266,27 +7266,21 @@ INT32 K_ChainOrDeincrementTime(player_t *player, INT32 timer, INT32 deincrement, } // Get the tic inverse sum using kartspeed, kartweight and your number of boosts. -static INT32 ticinversesum(UINT8 kartspeed, UINT8 kartweight, UINT8 grade) +static INT32 K_TicInversesum(UINT8 kartspeed, UINT8 kartweight, UINT8 grade) { return (TICRATE / kartspeed) + (TICRATE / CLAMP(kartweight, 1, 5)) + grade; } -// Get the maximum required stacks needed for the ringnerf based on kartspeed and kartweight -static INT32 statrangemap(UINT8 kartspeed, UINT8 kartweight) +// Get the threshold for the ringnerf based on kartspeed and kartweight +static INT32 K_StackThreshold(UINT8 kartspeed, UINT8 kartweight) { INT32 scaledsw = (9 - kartspeed) + (9 - kartweight); - - fixed_t scaled_input = (scaledsw)*FRACUNIT/16; - - // Scale the result to be within range [2, 4] - fixed_t result = 4*FRACUNIT - (FixedMul(scaled_input, 2*FRACUNIT)); + fixed_t result = 4*FRACUNIT - (FixedMul(scaledsw*FRACUNIT/16, 2*FRACUNIT)); // Stay within range please! result = CLAMP(result, 2*FRACUNIT, 4*FRACUNIT); - result = result >> FRACBITS; - - return result; + return result >> FRACBITS; } static void K_HandleRingDeincrement(player_t *player, boolean chainnerf) @@ -7301,11 +7295,11 @@ static void K_HandleRingDeincrement(player_t *player, boolean chainnerf) if (chainnerf) { - UINT8 requiredgrade = statrangemap(player->kartspeed, player->kartweight); + UINT8 requiredgrade = K_StackThreshold(player->kartspeed, player->kartweight); if (player->numboosts >= requiredgrade) { - INT32 insum = ticinversesum(player->kartspeed, player->kartweight, player->numboosts); + INT32 insum = K_TicInversesum(player->kartspeed, player->kartweight, player->numboosts); INT32 subring = (player->ringboost*2)/insum; if (player->kartspeed == 1) From dcc8b1d8680d33bad42628f826e2687bf630a8e1 Mon Sep 17 00:00:00 2001 From: NepDisk Date: Thu, 5 Jun 2025 08:35:53 -0400 Subject: [PATCH 07/29] Stop bots from moving when exiting properly. --- src/k_bot.cpp | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/k_bot.cpp b/src/k_bot.cpp index 72bb4eb07..109eacb74 100644 --- a/src/k_bot.cpp +++ b/src/k_bot.cpp @@ -359,10 +359,6 @@ void K_UpdateMatchRaceBots(void) --------------------------------------------------*/ boolean K_PlayerUsesBotMovement(const player_t *player) { - - if (player->exiting) - return false; - if (player->bot) return true; @@ -1541,6 +1537,14 @@ static void K_BuildBotTiccmdNormal(player_t *player, ticcmd_t *cmd) return; } + if (player->exiting) + { + + //Bot finish + // TODO: Make bots spin around like a player would based on random chance + return; + } + if (player->botvars.respawnconfirm >= BOTRESPAWNCONFIRM) { // We want to respawn. Simply hold brake and stop here! From 7247768278dd609e526a4d7bff342ba1b202bc76 Mon Sep 17 00:00:00 2001 From: Alug Date: Fri, 6 Jun 2025 15:12:11 +0200 Subject: [PATCH 08/29] fix 2560x1440 resolution crashing --- src/screen.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/screen.h b/src/screen.h index 8ae4743ad..ca3d91fac 100644 --- a/src/screen.h +++ b/src/screen.h @@ -43,8 +43,8 @@ extern "C" { // we try to re-allocate a minimum of buffers for stability of the memory, // so all the small-enough tables based on screen size, are allocated once // and for all at the maximum size. -#define MAXVIDWIDTH 1920 // don't set this too high because actually -#define MAXVIDHEIGHT 1200 // lots of tables are allocated with the MAX size. +#define MAXVIDWIDTH 2560 // don't set this too high because actually +#define MAXVIDHEIGHT 1440 // lots of tables are allocated with the MAX size. #define BASEVIDWIDTH 320 // NEVER CHANGE THIS! This is the original #define BASEVIDHEIGHT 200 // resolution of the graphics. From 1c5dc89b33c448f02b5e805944bb989fc70f2ddc Mon Sep 17 00:00:00 2001 From: Alug Date: Fri, 6 Jun 2025 15:31:38 +0200 Subject: [PATCH 09/29] fix non papersprite clipping in R_ProjectSprite overflowing --- src/r_things.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/r_things.cpp b/src/r_things.cpp index ec3a927f3..682768d2d 100644 --- a/src/r_things.cpp +++ b/src/r_things.cpp @@ -1812,7 +1812,7 @@ static void R_ProjectSprite(mobj_t *thing) basetx = tx = FixedMul(tr_x, viewsin) - FixedMul(tr_y, viewcos); // sideways distance // too far off the side? - if (!papersprite && abs(tx) > FixedMul(tz, fovtan[viewssnum])<<2) // papersprite clipping is handled later + if (!papersprite && abs(tx) > (INT64)FixedMul(tz, fovtan[viewssnum])<<2) // papersprite clipping is handled later return; // aspect ratio stuff @@ -2545,7 +2545,7 @@ static void R_ProjectPrecipitationSprite(precipmobj_t *thing) // uncapped/interpolation interpmobjstate_t interp = {0}; - + // okay... this is a hack, but weather isn't networked, so it should be ok if (!P_PrecipThinker(thing)) { From e63f68e732e8e5382dbed8c33771892b16f317ff Mon Sep 17 00:00:00 2001 From: Alug Date: Sun, 8 Jun 2025 22:01:41 +0200 Subject: [PATCH 10/29] fix portal clipping being completely completely broken on kart maps truly amazing --- src/r_portal.c | 29 +++++++++++++++++++++++++++++ src/r_portal.h | 1 + src/r_segs.cpp | 6 +++--- src/w_wad.c | 4 ++-- 4 files changed, 35 insertions(+), 5 deletions(-) diff --git a/src/r_portal.c b/src/r_portal.c index f5e9874d6..416dc4b6f 100644 --- a/src/r_portal.c +++ b/src/r_portal.c @@ -37,6 +37,32 @@ void Portal_InitList (void) portal_base = portal_cap = NULL; } +/** Store the clipping window for a portal in its given range. + * + * The window is copied from the current window at the time + * the function is called, so it is useful for converting one-sided + * lines into portals. + */ +void Portal_ClipRange (portal_t* portal) +{ + INT32 start = portal->start; + INT32 end = portal->end; + INT16 *ceil = portal->ceilingclip; + INT16 *floor = portal->floorclip; + fixed_t *scale = portal->frontscale; + + INT32 i; + for (i = 0; i < end-start; i++) + { + *ceil = ceilingclip[start+i]; + ceil++; + *floor = floorclip[start+i]; + floor++; + *scale = frontscale[start+i]; + scale++; + } +} + /** Apply the clipping window from a portal. */ void Portal_ClipApply (const portal_t* portal) @@ -158,6 +184,9 @@ void Portal_Add2Lines (const INT32 line1, const INT32 line2, const INT32 x1, con portal->clipline = line2; + if (mapnamespace == MNS_SRB2KART) + Portal_ClipRange(portal); + g_portal = portal; // this tells R_StoreWallRange that curline is a portal seg } diff --git a/src/r_portal.h b/src/r_portal.h index 60bde34bc..05fe3d977 100644 --- a/src/r_portal.h +++ b/src/r_portal.h @@ -58,6 +58,7 @@ void Portal_Remove (portal_t* portal); void Portal_Add2Lines (const INT32 line1, const INT32 line2, const INT32 x1, const INT32 x2); void Portal_AddSkybox (const visplane_t* plane); +void Portal_ClipRange (portal_t* portal); void Portal_ClipApply (const portal_t* portal); void Portal_AddSkyboxPortals (void); diff --git a/src/r_segs.cpp b/src/r_segs.cpp index 7197ee609..0565d5256 100644 --- a/src/r_segs.cpp +++ b/src/r_segs.cpp @@ -1596,7 +1596,7 @@ static void R_RenderSegLoop (drawcolumndata_t* dc) // Portal line // Spans the entire height of a single-sided line or // the "window" of a double-sided line. - if (g_portal) + if (g_portal && (mapnamespace != MNS_SRB2KART)) { I_Assert(rw_x >= g_portal->start && rw_x < g_portal->end); i = rw_x - g_portal->start; @@ -2245,7 +2245,7 @@ void R_StoreWallRange(INT32 start, INT32 stop) || frontsector->extra_colormap != backsector->extra_colormap || (frontsector->ffloors != backsector->ffloors && !Tag_Compare(&frontsector->tags, &backsector->tags)) // Portals block traversal behind them - || g_portal + || (g_portal && mapnamespace != MNS_SRB2KART) // Highlighting death pits || (cv_debugfinishline.value && frontsector->damagetype != backsector->damagetype)) { @@ -2283,7 +2283,7 @@ void R_StoreWallRange(INT32 start, INT32 stop) || frontsector->extra_colormap != backsector->extra_colormap || (frontsector->ffloors != backsector->ffloors && !Tag_Compare(&frontsector->tags, &backsector->tags)) // Portals block traversal behind them - || g_portal + || (g_portal && mapnamespace != MNS_SRB2KART) // Highlighting death pits || (cv_debugfinishline.value && frontsector->damagetype != backsector->damagetype)) { diff --git a/src/w_wad.c b/src/w_wad.c index 6fa3f1a80..2d669bd37 100644 --- a/src/w_wad.c +++ b/src/w_wad.c @@ -1402,7 +1402,7 @@ lumpnum_t W_CheckNumForName(const char *name) INT32 i; UINT32 hash = name ? quickncasehash(name, 8) : 0; lumpnum_t check = INT16_MAX; - + if (name == NULL) return LUMPERROR; @@ -1454,7 +1454,7 @@ lumpnum_t W_CheckNumForLongName(const char *name) INT32 i; UINT32 hash = name ? quickncasehash(name, 8) : 0; lumpnum_t check = INT16_MAX; - + if (name == NULL) return LUMPERROR; From cd3715bfaa4f49baf082a5ea556077d93eb86d8c Mon Sep 17 00:00:00 2001 From: Alug Date: Sun, 8 Jun 2025 22:07:30 +0200 Subject: [PATCH 11/29] fix portals not accounting for slopes (only for kartmaps) fixes the last portal paths on ante station --- src/r_portal.c | 30 ++++++++++++++++++++++++------ 1 file changed, 24 insertions(+), 6 deletions(-) diff --git a/src/r_portal.c b/src/r_portal.c index 416dc4b6f..4e08e3b97 100644 --- a/src/r_portal.c +++ b/src/r_portal.c @@ -165,6 +165,13 @@ void Portal_Add2Lines (const INT32 line1, const INT32 line2, const INT32 x1, con vertex_t dest_c, start_c; + if (mapnamespace == MNS_SRB2KART) + { + portal->viewx = viewx; + portal->viewy = viewy; + portal->viewz = viewz; + } + // looking glass center start_c.x = (start->v1->x + start->v2->x) / 2; start_c.y = (start->v1->y + start->v2->y) / 2; @@ -173,13 +180,24 @@ void Portal_Add2Lines (const INT32 line1, const INT32 line2, const INT32 x1, con dest_c.x = (dest->v1->x + dest->v2->x) / 2; dest_c.y = (dest->v1->y + dest->v2->y) / 2; - disttopoint = R_PointToDist2(start_c.x, start_c.y, viewx, viewy); - angtopoint = R_PointToAngle2(start_c.x, start_c.y, viewx, viewy); - angtopoint += dangle; - - portal->viewx = dest_c.x + FixedMul(FINECOSINE(angtopoint>>ANGLETOFINESHIFT), disttopoint); - portal->viewy = dest_c.y + FixedMul(FINESINE(angtopoint>>ANGLETOFINESHIFT), disttopoint); portal->viewz = viewz + dest->frontsector->floorheight - start->frontsector->floorheight; + + if ((dangle == 0) && (mapnamespace == MNS_SRB2KART)) + { + // the entrance goes straight opposite the exit, so we just need to mess with the offset. + portal->viewx += dest_c.x - start_c.x; + portal->viewy += dest_c.y - start_c.y; + } + else + { + disttopoint = R_PointToDist2(start_c.x, start_c.y, viewx, viewy); + angtopoint = R_PointToAngle2(start_c.x, start_c.y, viewx, viewy); + angtopoint += dangle; + + portal->viewx = dest_c.x + FixedMul(FINECOSINE(angtopoint>>ANGLETOFINESHIFT), disttopoint); + portal->viewy = dest_c.y + FixedMul(FINESINE(angtopoint>>ANGLETOFINESHIFT), disttopoint); + } + portal->viewangle = viewangle + dangle; portal->clipline = line2; From 37ea829b2fb89568879386976cf87b68bd3b5b61 Mon Sep 17 00:00:00 2001 From: Alug Date: Sun, 8 Jun 2025 22:16:30 +0200 Subject: [PATCH 12/29] fix the horrible ffloorclip clearing loops if yall ever decide to get rid of the static screensize buffer, the compiler will just straight up never optimize those loops and it will turn some maps into absolute cache miss hell, using std::fill only cause it looks fancy lmao --- src/r_plane.cpp | 32 ++++++++++++-------------------- 1 file changed, 12 insertions(+), 20 deletions(-) diff --git a/src/r_plane.cpp b/src/r_plane.cpp index ec3001b2e..cd0bd462d 100644 --- a/src/r_plane.cpp +++ b/src/r_plane.cpp @@ -265,18 +265,16 @@ static void R_MapTiltedPlane(drawspandata_t *ds, void(*spanfunc)(drawspandata_t* spanfunc(ds); } -void R_ClearFFloorClips (void) +void R_ClearFFloorClips(void) { - INT32 i, p; + INT32 p; // opening / clipping determination - for (i = 0; i < viewwidth; i++) + for (p = 0; p < MAXFFLOORS; p++) { - for (p = 0; p < MAXFFLOORS; p++) - { - ffloor[p].f_clip[i] = (INT16)viewheight; - ffloor[p].c_clip[i] = -1; - } + visffloor_t *fffloor = &ffloor[p]; + std::fill(fffloor->f_clip, fffloor->f_clip + viewwidth, static_cast(viewheight)); + std::fill(fffloor->c_clip, fffloor->c_clip + viewwidth, static_cast(-1)); } numffloors = 0; @@ -288,20 +286,14 @@ void R_ClearFFloorClips (void) // void R_ClearPlanes(void) { - INT32 i, p; + INT32 i; // opening / clipping determination - for (i = 0; i < viewwidth; i++) - { - floorclip[i] = (INT16)viewheight; - ceilingclip[i] = -1; - frontscale[i] = INT32_MAX; - for (p = 0; p < MAXFFLOORS; p++) - { - ffloor[p].f_clip[i] = (INT16)viewheight; - ffloor[p].c_clip[i] = -1; - } - } + std::fill(floorclip, floorclip + viewwidth, static_cast(viewheight)); + std::fill(ceilingclip, ceilingclip + viewwidth, static_cast(-1)); + std::fill(frontscale, frontscale + viewwidth, INT32_MAX); + + R_ClearFFloorClips(); for (i = 0; i < MAXVISPLANES; i++) for (*freehead = visplanes[i], visplanes[i] = NULL; From 64fd5b93aca715bc1ea15a151dde1f18b839153f Mon Sep 17 00:00:00 2001 From: NepDisk Date: Tue, 10 Jun 2025 15:23:41 -0400 Subject: [PATCH 13/29] raise skinlimit to 4096 Why not UINT16_MAX? Thats 22gb of allocation lmao --- src/acs/call-funcs.cpp | 2 +- src/d_clisrv.c | 14 +++++++------- src/d_clisrv.h | 8 ++++---- src/d_netcmd.c | 8 ++++---- src/doomdef.h | 4 ++-- src/g_demo.c | 10 +++++----- src/g_demo.h | 2 +- src/k_bot.cpp | 22 +++++++++++----------- src/k_bot.h | 8 ++++---- src/k_grandprix.c | 40 ++++++++++++++++++++-------------------- src/k_grandprix.h | 4 ++-- src/k_hud.c | 4 ++-- src/m_menu.c | 4 ++-- src/m_menu.h | 2 +- src/p_saveg.c | 4 ++-- src/p_saveg.h | 2 +- 16 files changed, 69 insertions(+), 69 deletions(-) diff --git a/src/acs/call-funcs.cpp b/src/acs/call-funcs.cpp index 6b51cfba4..417346faf 100644 --- a/src/acs/call-funcs.cpp +++ b/src/acs/call-funcs.cpp @@ -1624,7 +1624,7 @@ bool CallFunc_PlayerSkin(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM:: && (info->mo != NULL && P_MobjWasRemoved(info->mo) == false) && (info->mo->player != NULL)) { - UINT8 skin = info->mo->player->skin; + UINT16 skin = info->mo->player->skin; thread->dataStk.push(~env->getString( skins[skin].name )->idx); return false; } diff --git a/src/d_clisrv.c b/src/d_clisrv.c index 8ae37a308..f916f11de 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -1080,7 +1080,7 @@ static void SV_SendPlayerInfo(INT32 node) netbuffer->u.playerinfo[i].score = LONG(players[i].score); netbuffer->u.playerinfo[i].timeinserver = SHORT((UINT16)(players[i].jointime / TICRATE)); - netbuffer->u.playerinfo[i].skin = (UINT8)(players[i].skin + netbuffer->u.playerinfo[i].skin = (UINT16)(players[i].skin #ifdef DEVELOP // it's safe to do this only because PLAYERINFO isn't read by the game itself % 3 #endif @@ -3712,7 +3712,7 @@ static void Got_RemovePlayer(UINT8 **p, INT32 playernum) static void Got_AddBot(UINT8 **p, INT32 playernum) { INT16 newplayernum; - UINT8 skinnum = 0; + UINT16 skinnum = 0; UINT8 difficulty = DIFFICULTBOT; botStyle_e style = BOT_STYLE_NORMAL; @@ -3728,7 +3728,7 @@ static void Got_AddBot(UINT8 **p, INT32 playernum) } newplayernum = READUINT8(*p); - skinnum = READUINT8(*p); + skinnum = READUINT16(*p); difficulty = READUINT8(*p); style = READUINT8(*p); @@ -3832,11 +3832,11 @@ static boolean SV_AddWaitingPlayers(SINT8 node, const char *name, const char *na } /*-------------------------------------------------- - boolean K_AddBotFromServer(UINT8 skin, UINT8 difficulty, botStyle_e style, UINT8 *p) + boolean K_AddBotFromServer(UINT16 skin, UINT8 difficulty, botStyle_e style, UINT8 *p) See header file for description. --------------------------------------------------*/ -boolean K_AddBotFromServer(UINT8 skin, UINT8 difficulty, botStyle_e style, UINT8 *p) +boolean K_AddBotFromServer(UINT16 skin, UINT8 difficulty, botStyle_e style, UINT8 *p) { UINT8 newplayernum = *p; @@ -3877,7 +3877,7 @@ boolean K_AddBotFromServer(UINT8 skin, UINT8 difficulty, botStyle_e style, UINT8 if (server) { - UINT8 buf[4]; + UINT8 buf[5]; UINT8 *buf_p = buf; WRITEUINT8(buf_p, newplayernum); @@ -3887,7 +3887,7 @@ boolean K_AddBotFromServer(UINT8 skin, UINT8 difficulty, botStyle_e style, UINT8 skin = numskins; } - WRITEUINT8(buf_p, skin); + WRITEUINT16(buf_p, skin); if (difficulty < 1) { diff --git a/src/d_clisrv.h b/src/d_clisrv.h index 558d02cfa..0234beab5 100644 --- a/src/d_clisrv.h +++ b/src/d_clisrv.h @@ -317,7 +317,7 @@ struct plrinfo char name[MAXPLAYERNAME+1]; UINT8 address[4]; // sending another string would run us up against MAXPACKETLENGTH UINT8 team; - UINT8 skin; + UINT16 skin; UINT8 data; // Color is first four bits, hasflag, isit and issuper have one bit each, the last is unused. UINT32 score; UINT16 timeinserver; // In seconds. @@ -327,7 +327,7 @@ struct plrinfo struct plrconfig { char name[MAXPLAYERNAME+1]; - UINT8 skin; + UINT16 skin; UINT16 color; UINT32 pflags; UINT32 score; @@ -481,7 +481,7 @@ void SV_StopServer(void); void SV_ResetServer(void); /*-------------------------------------------------- - boolean K_AddBotFromServer(UINT8 skin, UINT8 difficulty, botStyle_e style, UINT8 *newplayernum); + boolean K_AddBotFromServer(UINT16 skin, UINT8 difficulty, botStyle_e style, UINT8 *newplayernum); Adds a new bot, using a server-sided packet sent to all clients. Using regular K_AddBot wherever possible is better, but this is kept @@ -498,7 +498,7 @@ void SV_ResetServer(void); true if a bot can be added via a packet later, otherwise false. --------------------------------------------------*/ -boolean K_AddBotFromServer(UINT8 skin, UINT8 difficulty, botStyle_e style, UINT8 *p); +boolean K_AddBotFromServer(UINT16 skin, UINT8 difficulty, botStyle_e style, UINT8 *p); void CL_AddSplitscreenPlayer(void); void CL_RemoveSplitscreenPlayer(UINT8 p); diff --git a/src/d_netcmd.c b/src/d_netcmd.c index 32e074609..eaaf44033 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -1726,7 +1726,7 @@ static void SendNameAndColor(UINT8 n) WRITESTRINGN(p, cv_playername[n].zstring, MAXPLAYERNAME); WRITEUINT32(p, (UINT32)player->availabilities); WRITEUINT16(p, (UINT16)cv_playercolor[n].value); - WRITEUINT8(p, (UINT8)cv_skin[n].value); + WRITEUINT16(p, (UINT16)cv_skin[n].value); WRITESINT8(p, (SINT8)cv_follower[n].value); WRITEUINT16(p, (UINT16)cv_followercolor[n].value); @@ -1738,10 +1738,10 @@ static void Got_NameAndColor(UINT8 **cp, INT32 playernum) player_t *p = &players[playernum]; char name[MAXPLAYERNAME+1]; UINT16 color, followercolor; - UINT8 skin; + UINT16 skin; SINT8 follower; SINT8 localplayer = -1; - UINT8 i; + UINT16 i; #ifdef PARANOIA if (playernum < 0 || playernum > MAXPLAYERS) @@ -1767,7 +1767,7 @@ static void Got_NameAndColor(UINT8 **cp, INT32 playernum) READSTRINGN(*cp, name, MAXPLAYERNAME); p->availabilities = READUINT32(*cp); color = READUINT16(*cp); - skin = READUINT8(*cp); + skin = READUINT16(*cp); follower = READSINT8(*cp); followercolor = READUINT16(*cp); diff --git a/src/doomdef.h b/src/doomdef.h index c69a3e0e7..f6776387f 100644 --- a/src/doomdef.h +++ b/src/doomdef.h @@ -103,7 +103,7 @@ extern "C" { // Special Hashing. //#define NOMD5 -//#define NOFILEHASH +#define NOFILEHASH // Uncheck this to compile debugging code //#define RANGECHECK @@ -207,7 +207,7 @@ extern char logfilename[1024]; #define MAXSPLITSCREENPLAYERS 4 // Max number of players on a single computer #define MAXGAMEPADS (MAXSPLITSCREENPLAYERS * 2) // Number of gamepads we'll be allowing -#define MAXSKINS UINT8_MAX +#define MAXSKINS 4096 #define MAXFOLLOWERS UINT16_MAX #define COLORRAMPSIZE 16 diff --git a/src/g_demo.c b/src/g_demo.c index ffc746131..b045ed0e5 100644 --- a/src/g_demo.c +++ b/src/g_demo.c @@ -973,7 +973,7 @@ void G_WriteGhostTic(mobj_t *ghost, INT32 playernum) if (ghost->player->followmobj->colorized) followtic |= FZT_COLORIZED; if (followtic & FZT_SKIN) - WRITEUINT8(demobuf.p,(UINT8)(((skin_t *)(ghost->player->followmobj->skin))-skins)); + WRITEUINT16(demobuf.p,(UINT16)(((skin_t *)(ghost->player->followmobj->skin))-skins)); oldghost[playernum].flags2 |= MF2_AMBUSH; } @@ -1134,14 +1134,14 @@ void G_ConsGhostTic(INT32 playernum) { demobuf.p += sizeof(INT16); if (followtic & FZT_SKIN) - demobuf.p++; + demobuf.p += sizeof(UINT16); } if (followtic & FZT_SCALE) demobuf.p += sizeof(fixed_t); // momx, momy and momz demobuf.p += sizeof(fixed_t) * 3; if (followtic & FZT_SKIN) - demobuf.p++; + demobuf.p += sizeof(UINT16); demobuf.p += sizeof(UINT16); demobuf.p++; demobuf.p += sizeof(UINT16); @@ -1432,7 +1432,7 @@ void G_GhostTicker(void) follow->colorized = true; if (followtic & FZT_SKIN) - follow->skin = &skins[READUINT8(g->p)]; + follow->skin = &skins[READUINT16(g->p)]; } if (follow) { @@ -1452,7 +1452,7 @@ void G_GhostTicker(void) follow->z = g->mo->z + temp; P_SetThingPosition(follow); if (followtic & FZT_SKIN) - follow->sprite2 = READUINT8(g->p); + follow->sprite2 = READUINT16(g->p); else follow->sprite2 = 0; follow->sprite = READUINT16(g->p); diff --git a/src/g_demo.h b/src/g_demo.h index 60fe5c5b1..7a6fa6e6d 100644 --- a/src/g_demo.h +++ b/src/g_demo.h @@ -85,7 +85,7 @@ struct menudemo_t { struct { UINT8 ranking; char name[17]; - UINT8 skin, color; + UINT16 skin, color; UINT32 timeorscore; } standings[MAXPLAYERS]; }; diff --git a/src/k_bot.cpp b/src/k_bot.cpp index 109eacb74..376258b8b 100644 --- a/src/k_bot.cpp +++ b/src/k_bot.cpp @@ -47,7 +47,7 @@ consvar_t cv_forcebots = CVAR_INIT ("kartforcebots", "Off", CV_NETVAR|CV_CHEAT, consvar_t cv_botcontrol = CVAR_INIT ("kartbotcontrol", "On", CV_NETVAR|CV_CHEAT, CV_OnOff, NULL); /*-------------------------------------------------- - void K_SetNameForBot(UINT8 playerNum, UINT8 skinnum) + void K_SetNameForBot(UINT8 playerNum, const char *realname) See header file for description. --------------------------------------------------*/ @@ -100,11 +100,11 @@ void K_SetNameForBot(UINT8 newplayernum, const char *realname) } /*-------------------------------------------------- - void K_SetBot(UINT8 playerNum, UINT8 skinnum, UINT8 difficulty, botStyle_e style) + void K_SetBot(UINT8 playerNum, UINT16 skinnum, UINT8 difficulty, botStyle_e style) See header file for description. --------------------------------------------------*/ -void K_SetBot(UINT8 newplayernum, UINT8 skinnum, UINT8 difficulty, botStyle_e style) +void K_SetBot(UINT8 newplayernum, UINT16 skinnum, UINT8 difficulty, botStyle_e style) { CONS_Debug(DBG_NETPLAY, "addbot: %d\n", newplayernum); @@ -146,11 +146,11 @@ void K_SetBot(UINT8 newplayernum, UINT8 skinnum, UINT8 difficulty, botStyle_e st } /*-------------------------------------------------- - boolean K_AddBot(UINT8 skin, UINT8 difficulty, botStyle_e style, UINT8 *p) + boolean K_AddBot(UINT16 skin, UINT8 difficulty, botStyle_e style, UINT8 *p) See header file for description. --------------------------------------------------*/ -boolean K_AddBot(UINT8 skin, UINT8 difficulty, botStyle_e style, UINT8 *p) +boolean K_AddBot(UINT16 skin, UINT8 difficulty, botStyle_e style, UINT8 *p) { UINT8 newplayernum = *p; @@ -186,16 +186,16 @@ boolean K_AddBot(UINT8 skin, UINT8 difficulty, botStyle_e style, UINT8 *p) --------------------------------------------------*/ void K_UpdateMatchRaceBots(void) { - const UINT8 defaultbotskin = K_BotDefaultSkin(); + const UINT16 defaultbotskin = K_BotDefaultSkin(); UINT8 difficulty; UINT8 pmax = (dedicated ? MAXPLAYERS-1 : MAXPLAYERS); UINT8 numplayers = 0; UINT8 numbots = 0; UINT8 numwaiting = 0; SINT8 wantedbots = 0; - UINT8 usableskins = 0, skincount = numskins; - UINT8 grabskins[MAXSKINS+1]; - UINT8 i; + UINT16 usableskins = 0, skincount = numskins; + UINT16 grabskins[MAXSKINS+1]; + UINT16 i; // Init usable bot skins list for (i = 0; i < skincount; i++) @@ -318,11 +318,11 @@ void K_UpdateMatchRaceBots(void) while (numbots < wantedbots) { - UINT8 skinnum = defaultbotskin; + UINT16 skinnum = defaultbotskin; if (usableskins > 0) { - UINT8 index = P_RandomKey(usableskins); + UINT16 index = P_RandomKey(usableskins); skinnum = grabskins[index]; if (((cv_ingamecap.value > 0) && (usableskins+1 >= cv_ingamecap.value)) || (usableskins+1 >= cv_maxplayers.value)) { diff --git a/src/k_bot.h b/src/k_bot.h index e01c87380..139b0d46e 100644 --- a/src/k_bot.h +++ b/src/k_bot.h @@ -175,7 +175,7 @@ fixed_t K_DistanceOfLineFromPoint(fixed_t v1x, fixed_t v1y, fixed_t v2x, fixed_t /*-------------------------------------------------- - boolean K_AddBot(UINT8 skin, UINT8 difficulty, botStyle_e style, UINT8 *p); + boolean K_AddBot(UINT16 skin, UINT8 difficulty, botStyle_e style, UINT8 *p); Adds a new bot, using code intended to run on all clients. @@ -190,7 +190,7 @@ fixed_t K_DistanceOfLineFromPoint(fixed_t v1x, fixed_t v1y, fixed_t v2x, fixed_t true if a bot was added, otherwise false. --------------------------------------------------*/ -boolean K_AddBot(UINT8 skin, UINT8 difficulty, botStyle_e style, UINT8 *p); +boolean K_AddBot(UINT16 skin, UINT8 difficulty, botStyle_e style, UINT8 *p); // NOT AVAILABLE FOR LUA @@ -215,7 +215,7 @@ void K_SetNameForBot(UINT8 newplayernum, const char *realname); /*-------------------------------------------------- - void K_SetBot(UINT8 newplayernum, UINT8 skinnum, UINT8 difficulty, botStyle_e style); + void K_SetBot(UINT8 newplayernum, UINT16 skinnum, UINT8 difficulty, botStyle_e style); Sets a player ID to be a new bot directly. Invoked directly by K_AddBot, and indirectly by K_AddBotFromServer by sending @@ -231,7 +231,7 @@ void K_SetNameForBot(UINT8 newplayernum, const char *realname); None --------------------------------------------------*/ -void K_SetBot(UINT8 newplayernum, UINT8 skinnum, UINT8 difficulty, botStyle_e style); +void K_SetBot(UINT8 newplayernum, UINT16 skinnum, UINT8 difficulty, botStyle_e style); /*-------------------------------------------------- diff --git a/src/k_grandprix.c b/src/k_grandprix.c index 507556c82..1ec7a98b8 100644 --- a/src/k_grandprix.c +++ b/src/k_grandprix.c @@ -96,11 +96,11 @@ INT16 K_CalculateGPRankPoints(UINT8 position, UINT8 numplayers) } /*-------------------------------------------------- - UINT8 K_BotDefaultSkin(void) + UINT16 K_BotDefaultSkin(void) See header file for description. --------------------------------------------------*/ -UINT8 K_BotDefaultSkin(void) +UINT16 K_BotDefaultSkin(void) { const char *defaultbotskinname = "tails"; INT32 defaultbotskin = R_SkinAvailable(defaultbotskinname); @@ -111,7 +111,7 @@ UINT8 K_BotDefaultSkin(void) defaultbotskin = 0; } - return (UINT8)defaultbotskin; + return (UINT16)defaultbotskin; } /*-------------------------------------------------- @@ -136,7 +136,7 @@ UINT8 K_GetGPPlayerCount(UINT8 humans) --------------------------------------------------*/ void K_InitGrandPrixBots(void) { - const UINT8 defaultbotskin = K_BotDefaultSkin(); + const UINT16 defaultbotskin = K_BotDefaultSkin(); const UINT8 startingdifficulty = K_BotStartingDifficulty(grandprixinfo.gamespeed); UINT8 difficultylevels[MAXPLAYERS]; @@ -147,14 +147,14 @@ void K_InitGrandPrixBots(void) UINT8 numplayers = 0; UINT8 competitors[MAXSPLITSCREENPLAYERS]; - UINT8 usableskins, skincount = numskins; - UINT8 grabskins[MAXSKINS+1]; + UINT16 usableskins, skincount = numskins; + UINT16 grabskins[MAXSKINS+1]; - UINT8 botskinlist[MAXPLAYERS]; - UINT8 botskinlistpos = 0; + UINT16 botskinlist[MAXPLAYERS]; + UINT16 botskinlistpos = 0; UINT8 newplayernum = 0; - UINT8 i, j; + UINT16 i, j; memset(competitors, MAXPLAYERS, sizeof (competitors)); memset(botskinlist, defaultbotskin, sizeof (botskinlist)); @@ -237,10 +237,10 @@ void K_InitGrandPrixBots(void) rivalnum = R_SkinAvailable(rivalname); // Intentionally referenced before (currently dummied out) unlock check. Such a tease! - if (rivalnum != -1 && grabskins[(UINT8)rivalnum] != MAXSKINS) + if (rivalnum != -1 && grabskins[(UINT16)rivalnum] != MAXSKINS) { - botskinlist[botskinlistpos++] = (UINT8)rivalnum; - grabskins[(UINT8)rivalnum] = MAXSKINS; + botskinlist[botskinlistpos++] = (UINT16)rivalnum; + grabskins[(UINT16)rivalnum] = MAXSKINS; } } } @@ -268,11 +268,11 @@ void K_InitGrandPrixBots(void) { while (botskinlistpos < wantedbots) { - UINT8 skinnum = defaultbotskin; + UINT16 skinnum = defaultbotskin; if (usableskins > 0) { - UINT8 index = P_RandomKey(usableskins); + UINT16 index = P_RandomKey(usableskins); skinnum = grabskins[index]; if (usableskins >= K_GetGPPlayerCount(1)) { @@ -545,13 +545,13 @@ void K_IncreaseBotDifficulty(player_t *bot) --------------------------------------------------*/ void K_RetireBots(void) { - const UINT8 defaultbotskin = K_BotDefaultSkin(); + const UINT16 defaultbotskin = K_BotDefaultSkin(); SINT8 newDifficulty; - UINT8 usableskins = 0, skincount = numskins; - UINT8 grabskins[MAXSKINS+1]; + UINT16 usableskins = 0, skincount = numskins; + UINT16 grabskins[MAXSKINS+1]; - UINT8 i; + UINT16 i; if (grandprixinfo.gp == true && (((grandprixinfo.cup != NULL) && (grandprixinfo.roundnum >= grandprixinfo.cup->numlevels)) @@ -643,11 +643,11 @@ void K_RetireBots(void) if (bot->pflags & PF_NOCONTEST) { - UINT8 skinnum = defaultbotskin; + UINT16 skinnum = defaultbotskin; if (usableskins > 0) { - UINT8 index = P_RandomKey(usableskins); + UINT16 index = P_RandomKey(usableskins); skinnum = grabskins[index]; if (usableskins+1 >= K_GetGPPlayerCount(1)) { diff --git a/src/k_grandprix.h b/src/k_grandprix.h index 59481d3d0..bb0998cd6 100644 --- a/src/k_grandprix.h +++ b/src/k_grandprix.h @@ -72,13 +72,13 @@ INT16 K_CalculateGPRankPoints(UINT8 position, UINT8 numplayers); /*-------------------------------------------------- - UINT8 K_BotDefaultSkin(void); + UINT16 K_BotDefaultSkin(void); Returns the skin number of the skin the game uses as a fallback option. --------------------------------------------------*/ -UINT8 K_BotDefaultSkin(void); +UINT16 K_BotDefaultSkin(void); /*-------------------------------------------------- UINT8 K_GetGPPlayerCount(UINT8 humans) diff --git a/src/k_hud.c b/src/k_hud.c index 29c214624..13e51fde8 100644 --- a/src/k_hud.c +++ b/src/k_hud.c @@ -3342,7 +3342,7 @@ static void K_drawKartMinimapNametag(fixed_t objx, fixed_t objy, INT32 hudx, INT fixed_t amnumxpos, amnumypos; INT32 amxpos, amypos; - UINT8 skin = 0; + UINT16 skin = 0; UINT16 chatcolor = skincolors[player->mo->color].chatcolor; amnumxpos = (FixedMul(objx, minimapinfo.zoom) - minimapinfo.offs_x); @@ -3457,7 +3457,7 @@ static void K_drawKartMinimap(void) INT32 x, y; INT32 minimaptrans = cv_kartminimap.value; INT32 splitflags = 0; - UINT8 skin = 0; + UINT16 skin = 0; UINT8 *colormap = NULL; SINT8 localplayers[MAXSPLITSCREENPLAYERS]; SINT8 numlocalplayers = 0; diff --git a/src/m_menu.c b/src/m_menu.c index 1b6cb89b8..a667010d1 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -1891,7 +1891,7 @@ void M_Init(void) void M_InitCharacterTables(void) { - UINT8 i; + UINT16 i; // Setup description table for (i = 0; i < MAXSKINS; i++) @@ -6930,7 +6930,7 @@ Update the maxplayers label... #define iconwidth 32 #define spacingwidth 32 #define incrwidth (iconwidth + spacingwidth) - UINT8 i = 0, pskin, pcol; + UINT16 i = 0, pskin, pcol; // player arrangement width, but there's also a chance i'm a furry, shhhhhh const INT32 paw = iconwidth + 3*incrwidth; INT32 trans = 0; diff --git a/src/m_menu.h b/src/m_menu.h index 740d977b6..82a058ed3 100644 --- a/src/m_menu.h +++ b/src/m_menu.h @@ -457,7 +457,7 @@ struct modedesc_t typedef struct { char levelname[32]; - UINT8 skinnum; + UINT16 skinnum; UINT8 numemeralds; UINT8 numgameovers; INT32 lives; diff --git a/src/p_saveg.c b/src/p_saveg.c index e054ef45d..6ccef8670 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -2492,7 +2492,7 @@ static void SaveMobjThinker(savebuffer_t *save, const thinker_t *th, const UINT8 if (diff2 & MD2_CVMEM) WRITEINT32(save->p, mobj->cvmem); if (diff2 & MD2_SKIN) - WRITEUINT8(save->p, (UINT8)((skin_t *)mobj->skin - skins)); + WRITEUINT16(save->p, (UINT16)((skin_t *)mobj->skin - skins)); if (diff2 & MD2_COLOR) WRITEUINT16(save->p, mobj->color); if (diff2 & MD2_EXTVAL1) @@ -3726,7 +3726,7 @@ static thinker_t* LoadMobjThinker(savebuffer_t *save, actionf_p1 thinker) if (diff2 & MD2_CVMEM) mobj->cvmem = READINT32(save->p); if (diff2 & MD2_SKIN) - mobj->skin = &skins[READUINT8(save->p)]; + mobj->skin = &skins[READUINT16(save->p)]; if (diff2 & MD2_COLOR) mobj->color = READUINT16(save->p); if (diff2 & MD2_EXTVAL1) diff --git a/src/p_saveg.h b/src/p_saveg.h index a85916f69..64e37554d 100644 --- a/src/p_saveg.h +++ b/src/p_saveg.h @@ -36,7 +36,7 @@ mobj_t *P_FindNewPosition(UINT32 oldposition); struct savedata_t { - UINT8 skin; + UINT16 skin; INT32 score; INT32 lives; UINT16 emeralds; From b93a8215c8009f2e970dfcf70df83308bde1d1f7 Mon Sep 17 00:00:00 2001 From: NepDisk Date: Tue, 10 Jun 2025 18:41:20 -0400 Subject: [PATCH 14/29] Make bonuschars.kart an Iwad --- src/d_main.cpp | 20 ++++++++++++-------- src/d_main.h | 2 ++ src/d_netfil.c | 1 + src/doomdef.h | 2 +- 4 files changed, 16 insertions(+), 9 deletions(-) diff --git a/src/d_main.cpp b/src/d_main.cpp index 22089ab2e..47583d29d 100644 --- a/src/d_main.cpp +++ b/src/d_main.cpp @@ -81,15 +81,16 @@ #include // Put hashes here to get them out of header hell. -#define ASSET_HASH_SRB2_SRB 0xf3ec1ea4d0eca4a9 -#define ASSET_HASH_GFX_KART 0xc91b0d43f5ba131f -#define ASSET_HASH_TEXTURES_KART 0xb4211b2f32b6a291 -#define ASSET_HASH_CHARS_KART 0x1e68a3e01aa5c68b -#define ASSET_HASH_MAPS_KART 0x38558ed00da41ce9 -#define ASSET_HASH_MAIN_PK3 0xfd350f17314cd848 -#define ASSET_HASH_MAPPATCH_PK3 0x36ef622b54d98871 +#define ASSET_HASH_SRB2_SRB 0xf3ec1ea4d0eca4a9 +#define ASSET_HASH_GFX_KART 0xc91b0d43f5ba131f +#define ASSET_HASH_TEXTURES_KART 0xb4211b2f32b6a291 +#define ASSET_HASH_CHARS_KART 0x1e68a3e01aa5c68b +#define ASSET_HASH_MAPS_KART 0x38558ed00da41ce9 +#define ASSET_HASH_MAIN_PK3 0x41568cadaf608e27 +#define ASSET_HASH_MAPPATCH_PK3 0x36ef622b54d98871 +#define ASSET_HASH_BONUSCHARS_KART 0x60e6f13d822a7461 #ifdef USE_PATCH_FILE -#define ASSET_HASH_PATCH_PK3 0x0000000000000000 +#define ASSET_HASH_PATCH_PK3 0x0000000000000000 #endif #ifdef CMAKECONFIG @@ -1202,6 +1203,7 @@ static void IdentifyVersion(void) D_AddFile(startupiwads, va(pandf,srb2waddir,MAPSNAME)); D_AddFile(startupiwads, va(pandf,srb2waddir,MAINNAME)); D_AddFile(startupiwads, va(pandf,srb2waddir,MAPPATCHNAME)); + D_AddFile(startupiwads, va(pandf,srb2waddir,BONUSCHARSNAME)); #ifdef USE_PATCH_FILE D_AddFile(startupiwads, va(pandf,srb2waddir,PATCHNAME)); #endif @@ -1483,6 +1485,7 @@ void D_SRB2Main(void) W_VerifyFileHash(MAINWAD_MAPS, ASSET_HASH_MAPS_KART); W_VerifyFileHash(MAINWAD_MAIN, ASSET_HASH_MAIN_PK3); W_VerifyFileHash(MAINWAD_MAPPATCH, ASSET_HASH_MAPPATCH_PK3); + W_VerifyFileHash(MAINWAD_BONUSCHARS, ASSET_HASH_BONUSCHARS_KART); #ifdef USE_PATCH_FILE W_VerifyFileHash(MAINWAD_PATCH, ASSET_HASH_PATCH_PK3); #endif @@ -1495,6 +1498,7 @@ void D_SRB2Main(void) wadfiles[MAINWAD_MAPS]->compatmode = true; wadfiles[MAINWAD_MAIN]->compatmode = false; wadfiles[MAINWAD_MAPPATCH]->compatmode = false; + wadfiles[MAINWAD_BONUSCHARS]->compatmode = true; #ifdef USE_PATCH_FILE wadfiles[MAINWAD_PATCH]->compatmode = false; #endif diff --git a/src/d_main.h b/src/d_main.h index 69f5459b7..0d30cb8df 100644 --- a/src/d_main.h +++ b/src/d_main.h @@ -29,6 +29,7 @@ extern "C" { #define MAPSNAME "maps.kart" #define MAINNAME "main.pk3" #define MAPPATCHNAME "mappatch.pk3" +#define BONUSCHARSNAME "bonuschars.kart" #define PATCHNAME "patch.pk3" #define MUSICNAME "music.kart" #define SOUNDSNAME "sounds.kart" @@ -42,6 +43,7 @@ typedef enum MAINWAD_MAPS, MAINWAD_MAIN, MAINWAD_MAPPATCH, + MAINWAD_BONUSCHARS, #ifdef USE_PATCH_FILE MAINWAD_PATCH, #endif diff --git a/src/d_netfil.c b/src/d_netfil.c index d9d9be166..ddddb18f6 100644 --- a/src/d_netfil.c +++ b/src/d_netfil.c @@ -1409,6 +1409,7 @@ void PT_FileFragment(void) || !strcmp(filename, MAPSNAME) || !strcmp(filename, MAINNAME) || !strcmp(filename, MAPPATCHNAME) + || !strcmp(filename, BONUSCHARSNAME) || !strcmp(filename, PATCHNAME) || !strcmp(filename, SOUNDSNAME) || !strcmp(filename, MUSICNAME) diff --git a/src/doomdef.h b/src/doomdef.h index f6776387f..b45082c55 100644 --- a/src/doomdef.h +++ b/src/doomdef.h @@ -103,7 +103,7 @@ extern "C" { // Special Hashing. //#define NOMD5 -#define NOFILEHASH +//#define NOFILEHASH // Uncheck this to compile debugging code //#define RANGECHECK From a306d117a8ddd5ee262b13617b0f4626260a2d50 Mon Sep 17 00:00:00 2001 From: NepDisk Date: Wed, 11 Jun 2025 00:37:34 -0400 Subject: [PATCH 15/29] Fix music going away on unfocus --- src/sdl/i_video.cpp | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/sdl/i_video.cpp b/src/sdl/i_video.cpp index c05272bb3..7cb7355b7 100644 --- a/src/sdl/i_video.cpp +++ b/src/sdl/i_video.cpp @@ -645,14 +645,17 @@ static void Impl_SetFocused(boolean focused) if (window_notinfocus) { if (! cv_playmusicifunfocused.value) - S_PauseAudio(); + I_SetMusicVolume(0); if (! cv_playsoundifunfocused.value) - S_StopSounds(); + S_DisableSound(); memset(gamekeydown, 0, NUMKEYS); // TODO this is a scary memset } else if (!paused) - S_ResumeAudio(); + { + S_InitMusicVolume(); + S_EnableSound(); + } } static inline void SDLJoyRemap(event_t *event) From 12c93988e6b165760fd8734c42e6fdedef2e37f8 Mon Sep 17 00:00:00 2001 From: NepDisk Date: Wed, 11 Jun 2025 00:38:59 -0400 Subject: [PATCH 16/29] Experiment: always stack rubberband boost --- src/k_kart.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/k_kart.c b/src/k_kart.c index 057145b5c..f9116cc49 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -3654,7 +3654,9 @@ static void K_GetKartBoostPower(player_t *player) // This should always remain the last boost if (player->botvars.rubberband > FRACUNIT && K_PlayerUsesBotMovement(player) == true) { - K_DoBoost(player, player->botvars.rubberband - FRACUNIT, 0, false, false); + //K_DoBoost(player, player->botvars.rubberband - FRACUNIT, 0, false, false); + //Always stack this boost.... + player->boostinfo.stackspeedboost += player->botvars.rubberband - FRACUNIT; } player->boostpower = boostpower; From 457527d77a3656c9ee965ca94d73d811c0c5ecfe Mon Sep 17 00:00:00 2001 From: NepDisk Date: Wed, 11 Jun 2025 13:39:33 -0400 Subject: [PATCH 17/29] GL renderer changes Always draw the skybox to prevent it from randomly going black and remove deprecated polyskys define. Thaanks Alug for suggestion and assistance. --- src/hardware/hw_main.c | 82 ++------------------------------ src/hardware/r_opengl/r_opengl.c | 1 + 2 files changed, 4 insertions(+), 79 deletions(-) diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index 71732222a..609c96e50 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -53,7 +53,6 @@ #define R_FAKEFLOORS #define HWPRECIP -//#define POLYSKY // ========================================================================== // the hardware driver object @@ -78,8 +77,6 @@ void HWR_AddTransparentFloor(levelflat_t *levelflat, extrasubsector_t *xsub, boo void HWR_AddTransparentPolyobjectFloor(levelflat_t *levelflat, polyobj_t *polysector, boolean isceiling, fixed_t fixedheight, INT32 lightlevel, INT32 alpha, sector_t *FOFSector, FBITFIELD blend, extracolormap_t *planecolormap); -boolean drawsky = true; - // ========================================================================== // VIEW GLOBALS // ========================================================================== @@ -108,10 +105,6 @@ static angle_t gl_xtoviewangle[MAXVIDWIDTH+1]; #define DOPLANES //#define DOWALLS -// test of drawing sky by polygons like in software with visplane, unfortunately -// this doesn't work since we must have z for pixel and z for texture (not like now with z = oow) -//#define POLYSKY - // test change fov when looking up/down but bsp projection messup :( //#define NOCRAPPYMLOOK @@ -644,50 +637,6 @@ static void HWR_RenderPlane(subsector_t *subsector, extrasubsector_t *xsub, bool #endif } -#ifdef POLYSKY -// this don't draw anything it only update the z-buffer so there isn't problem with -// wall/things upper that sky (map12) -static void HWR_RenderSkyPlane(extrasubsector_t *xsub, fixed_t fixedheight) -{ - polyvertex_t *pv; - float height; //constant y for all points on the convex flat polygon - FOutVector *v3d; - INT32 nrPlaneVerts; //verts original define of convex flat polygon - INT32 i; - - // no convex poly were generated for this subsector - if (!xsub->planepoly) - return; - - height = FIXED_TO_FLOAT(fixedheight); - - pv = xsub->planepoly->pts; - nrPlaneVerts = xsub->planepoly->numpts; - - if (nrPlaneVerts < 3) // not even a triangle? - return; - - if (nrPlaneVerts > MAXPLANEVERTICES) // FIXME: exceeds plVerts size - { - CONS_Debug(DBG_RENDER, "polygon size of %d exceeds max value of %d vertices\n", nrPlaneVerts, MAXPLANEVERTICES); - return; - } - - // transform - v3d = planeVerts; - for (i = 0; i < nrPlaneVerts; i++,v3d++,pv++) - { - v3d->s = 0.0f; - v3d->t = 0.0f; - v3d->x = pv->x; - v3d->y = height; - v3d->z = pv->y; - } - - HWD.pfnDrawPolygon(NULL, planeVerts, nrPlaneVerts, PF_Invisible|PF_NoTexture|PF_Occlude); -} -#endif //polysky - #endif //doplanes FBITFIELD HWR_GetBlendModeFlag(INT32 ast) @@ -2761,12 +2710,6 @@ static void HWR_Subsector(size_t num) floorlightlevel, &levelflats[gl_frontsector->floorpic], NULL, 255, floorcolormap); } } - else - { -#ifdef POLYSKY - HWR_RenderSkyPlane(&extrasubsectors[num], locFloorHeight); -#endif - } } if (cullCeilingHeight > dup_viewz) @@ -2784,20 +2727,8 @@ static void HWR_Subsector(size_t num) ceilinglightlevel, &levelflats[gl_frontsector->ceilingpic], NULL, 255, ceilingcolormap); } } - else - { -#ifdef POLYSKY - HWR_RenderSkyPlane(&extrasubsectors[num], locCeilingHeight); -#endif - } } -#ifndef POLYSKY - // Moved here because before, when above the ceiling and the floor does not have the sky flat, it doesn't draw the sky - if (gl_frontsector->ceilingpic == skyflatnum || gl_frontsector->floorpic == skyflatnum) - drawsky = true; -#endif - #ifdef R_FAKEFLOORS if (gl_frontsector->ffloors) { @@ -5928,11 +5859,7 @@ void HWR_RenderSkyboxView(player_t *player) //------------------------------------------------------------------------ HWR_ClearView(); - if (drawsky) - HWR_DrawSkyBackground(player); - - //Hurdler: it doesn't work in splitscreen mode - drawsky = r_splitscreen; + HWR_DrawSkyBackground(player); HWR_ClearSprites(); @@ -6028,7 +5955,7 @@ void HWR_RenderPlayerView(void) HWD.pfnClearBuffer(true, false, &ClearColor); // Clear the Color Buffer, stops HOMs. Also seems to fix the skybox issue on Intel GPUs. ps_hw_skyboxtime = I_GetPreciseTime(); - if (skybox && drawsky) // If there's a skybox and we should be drawing the sky, draw the skybox + if (skybox) // If there's a skybox and we should be drawing the sky, draw the skybox HWR_RenderSkyboxView(player); // This is drawn before everything else so it is placed behind ps_hw_skyboxtime = I_GetPreciseTime() - ps_hw_skyboxtime; @@ -6115,12 +6042,9 @@ void HWR_RenderPlayerView(void) //------------------------------------------------------------------------ HWR_ClearView(); // Clears the depth buffer and resets the view I believe - if (!skybox && drawsky) // Don't draw the regular sky if there's a skybox + if (!skybox) // Don't draw the regular sky if there's a skybox HWR_DrawSkyBackground(player); - //Hurdler: it doesn't work in splitscreen mode - drawsky = r_splitscreen; - HWR_ClearSprites(); drawcount = 0; diff --git a/src/hardware/r_opengl/r_opengl.c b/src/hardware/r_opengl/r_opengl.c index b41297d24..3a83255b0 100644 --- a/src/hardware/r_opengl/r_opengl.c +++ b/src/hardware/r_opengl/r_opengl.c @@ -1836,6 +1836,7 @@ EXPORT void HWRAPI(SetBlend) (FBITFIELD PolyFlags) pglDepthMask(0); } ////Hurdler: not used if we don't define POLYSKY + ////Nep: This is also used for portals and HWR_DrawSkyWall acutally. if (Xor & PF_Invisible) { if (PolyFlags&PF_Invisible) From 6a122b060001424c255ee722e6c4e8b510e27dc2 Mon Sep 17 00:00:00 2001 From: NepDisk Date: Wed, 11 Jun 2025 19:02:06 -0400 Subject: [PATCH 18/29] Implement ring spam nerf Less impactful in vanilla + rings. With Chaining and Stacking on however this makes a big difference since it prevents you from having a large stack count forever if you can keep chugging rings --- src/d_player.h | 1 + src/k_kart.c | 22 +++++++++++++++++++++- src/p_enemy.c | 8 ++++++-- src/p_saveg.c | 4 +++- 4 files changed, 31 insertions(+), 4 deletions(-) diff --git a/src/d_player.h b/src/d_player.h index b3d6e3a8e..df70e2dd1 100644 --- a/src/d_player.h +++ b/src/d_player.h @@ -675,6 +675,7 @@ struct player_t UINT8 pickuprings; // Number of rings being picked up before added to the counter (prevents rings from being deleted forever over 20) UINT8 ringdelay; // (0 to 3) - 3 tic delay between every ring usage UINT16 ringboost; // Ring boost timer + UINT16 ringtime; // The current Ring boost timer if it wasn't capped. Used for spam prevention measures. UINT16 superring; // Spawn rings on top of you every tic! UINT8 nextringaward; // When should we spawn our next superring ring? UINT8 ringvolume; // When consuming lots of rings, lower the sound a little. diff --git a/src/k_kart.c b/src/k_kart.c index f9116cc49..d92475783 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -7524,12 +7524,18 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd) player->ringdelay--; if (P_PlayerInPain(player)) + { player->ringboost = 0; + player->ringtime = 0; + } else if (player->ringboost) { K_HandleRingDeincrement(player, chainingactive); } + if (!player->ringboost && !player->chaintimer) + player->ringtime = 0; + if (player->sneakertimer) player->sneakertimer = K_ChainOrDeincrementTime(player, player->sneakertimer, 1, false); @@ -9075,6 +9081,7 @@ static void K_UpdatePlayerWaypoints(player_t *const player) INT32 K_GetKartRingPower(player_t *player, boolean boosted) { fixed_t ringPower = ((9 - player->kartspeed) + (9 - player->kartweight)) * (FRACUNIT/2); + UINT16 finalPower = 0; if (boosted == true) { @@ -9087,7 +9094,20 @@ INT32 K_GetKartRingPower(player_t *player, boolean boosted) ringPower += 1; } - return max(ringPower / FRACUNIT, 1); + finalPower = max(ringPower / FRACUNIT, 1); + + // the base is 4 tics + finalPower += 3; + + // If you use more then 20 rings at a time, you start gaining less ring timer.. + if (player->ringtime == finalPower*20) + S_StartSound(NULL, sfx_cdfm66); + else if (player->ringtime > finalPower*20) + { + finalPower = 2; + } + + return finalPower; } // Returns false if this player being placed here causes them to collide with any other player diff --git a/src/p_enemy.c b/src/p_enemy.c index 43b1115bb..9f4fa86c6 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -3171,7 +3171,8 @@ void A_AttractChase(mobj_t *actor) { // Base add is 4 tics for 9,9, adds 1 tic for each point closer to the 1,1 end - actor->target->player->ringboost += K_GetKartRingPower(actor->target->player, true) + 3; + actor->target->player->ringboost += K_GetKartRingPower(actor->target->player, true); + actor->target->player->ringtime += K_GetKartRingPower(actor->target->player, true); S_StartSoundAtVolume(actor->target, sfx_s1b5, actor->target->player->ringvolume); if (actor->target->player->rings <= 10) @@ -3204,7 +3205,10 @@ void A_AttractChase(mobj_t *actor) if (actor->extravalue1 >= 16) { if (!P_GivePlayerRings(actor->target->player, 1)) // returns 0 if addition failed - actor->target->player->ringboost += K_GetKartRingPower(actor->target->player, true) + 3; + { + actor->target->player->ringboost += K_GetKartRingPower(actor->target->player, true); + actor->target->player->ringtime += K_GetKartRingPower(actor->target->player, true); + } if (actor->target->player->ringboost > (4*TICRATE + TICRATE/2)) actor->target->player->ringboost = (4*TICRATE + TICRATE/2); diff --git a/src/p_saveg.c b/src/p_saveg.c index 6ccef8670..363d0ad75 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -315,6 +315,7 @@ static void P_NetArchivePlayers(savebuffer_t *save) WRITEUINT8(save->p, players[i].pickuprings); WRITEUINT8(save->p, players[i].ringdelay); WRITEUINT16(save->p, players[i].ringboost); + WRITEUINT16(save->p, players[i].ringtime); WRITEUINT16(save->p, players[i].superring); WRITEUINT8(save->p, players[i].nextringaward); WRITEUINT8(save->p, players[i].ringvolume); @@ -652,7 +653,8 @@ static void P_NetUnArchivePlayers(savebuffer_t *save) players[i].rings = READSINT8(save->p); players[i].pickuprings = READUINT8(save->p); players[i].ringdelay = READUINT8(save->p); - players[i].ringboost = READUINT16(save->p);; + players[i].ringboost = READUINT16(save->p); + players[i].ringtime = READUINT16(save->p);; players[i].superring = READUINT16(save->p); players[i].nextringaward = READUINT8(save->p); players[i].ringvolume = READUINT8(save->p); From 614506381df853aa042353b8fc032f3d7e6e50eb Mon Sep 17 00:00:00 2001 From: NepDisk Date: Thu, 12 Jun 2025 10:58:33 -0400 Subject: [PATCH 19/29] Make Ring Burnout sound Only play for local players --- src/k_kart.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/k_kart.c b/src/k_kart.c index d92475783..ef2974bac 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -9101,7 +9101,10 @@ INT32 K_GetKartRingPower(player_t *player, boolean boosted) // If you use more then 20 rings at a time, you start gaining less ring timer.. if (player->ringtime == finalPower*20) - S_StartSound(NULL, sfx_cdfm66); + { + if (P_IsLocalPlayer(player)) + S_StartSound(NULL, sfx_cdfm66); + } else if (player->ringtime > finalPower*20) { finalPower = 2; From 3d475504e3e26306241e4aee083afa958eef1b3d Mon Sep 17 00:00:00 2001 From: Oni Date: Sat, 12 Aug 2023 16:45:18 +0000 Subject: [PATCH 20/29] Merge branch 'reset-command' into 'master' Add 'reset' command to reset a cvar to its default value See merge request KartKrew/Kart!1382 --- src/command.c | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/src/command.c b/src/command.c index b21e76ba8..014dcb039 100644 --- a/src/command.c +++ b/src/command.c @@ -57,6 +57,7 @@ static void COM_Toggle_f(void); static void COM_Add_f(void); static void COM_Choose_f(void); static void COM_ChooseWeighted_f(void); +static void COM_Reset_f(void); static void CV_EnforceExecVersion(void); @@ -354,6 +355,7 @@ void COM_Init(void) COM_AddCommand("add", COM_Add_f); COM_AddCommand("choose", COM_Choose_f); COM_AddCommand("chooseweighted", COM_ChooseWeighted_f); + COM_AddCommand("reset", COM_Reset_f); RegisterNetXCmd(XD_NETVAR, Got_NetVar); } @@ -1219,6 +1221,36 @@ static void COM_ChooseWeighted_f(void) } } +static void COM_Reset_f(void) +{ + size_t i; + + if (COM_Argc() < 2) + { + CONS_Printf(M_GetText("reset [cvar2] [...]: Resets a cvar to its default value\n")); + return; + } + + for (i = 1; i < COM_Argc(); ++i) + { + consvar_t *cvar = CV_FindVar(COM_Argv(i)); + + if (!cvar) + { + CONS_Alert(CONS_NOTICE, M_GetText("%s is not a cvar\n"), COM_Argv(i)); + continue; + } + + CV_Set(cvar, cvar->defaultvalue); + + // Sometimes a cvar cannot be changed, e.g. CV_NETVAR without admin privilege. + if (!stricmp(cvar->string, cvar->defaultvalue)) + { + CONS_Printf("%s = %s\n", cvar->name, cvar->string); + } + } +} + // ========================================================================= // VARIABLE SIZE BUFFERS // ========================================================================= From 1553224270a1830d6a4900abd28b039f9cb8e172 Mon Sep 17 00:00:00 2001 From: James R Date: Fri, 11 Aug 2023 01:02:27 -0700 Subject: [PATCH 21/29] D_SRB2Main: set music volume on init :) --- src/d_main.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/d_main.cpp b/src/d_main.cpp index 47583d29d..188501e48 100644 --- a/src/d_main.cpp +++ b/src/d_main.cpp @@ -1638,6 +1638,7 @@ void D_SRB2Main(void) I_StartupSound(); I_InitMusic(); S_InitSfxChannels(cv_soundvolume.value); + S_InitMusicVolume(); } CON_SetLoadingProgress(LOADED_SINITSFXCHANNELS); From de5434ea23dc1bad9ab5c2ff49ba560a83aae158 Mon Sep 17 00:00:00 2001 From: NepDisk Date: Fri, 13 Jun 2025 09:40:57 -0400 Subject: [PATCH 22/29] Add support for using custom SDL2 mappings --- src/sdl/i_system.cpp | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/sdl/i_system.cpp b/src/sdl/i_system.cpp index 925812325..995edc626 100644 --- a/src/sdl/i_system.cpp +++ b/src/sdl/i_system.cpp @@ -1294,6 +1294,18 @@ void I_InitJoystick(UINT8 index) if (M_CheckParm("-nojoy")) return; + { + char dbpath[1024]; + sprintf(dbpath, "%s" PATHSEP "gamecontrollerdb.txt", srb2path); + SDL_GameControllerAddMappingsFromFile(dbpath); + } + + { + char dbpath[1024]; + sprintf(dbpath, "%s" PATHSEP "gamecontrollerdb_user.txt", srb2home); + SDL_GameControllerAddMappingsFromFile(dbpath); + } + if (M_CheckParm("-noxinput")) SDL_SetHintWithPriority("SDL_XINPUT_ENABLED", "0", SDL_HINT_OVERRIDE); From 30e63490cd199a18628aa3df49fe7676510af86f Mon Sep 17 00:00:00 2001 From: toaster Date: Fri, 28 Jul 2023 21:54:55 +0000 Subject: [PATCH 23/29] Merge branch 'max-errors' into 'master' CMakeLists.txt: add -fmax-errors=5 for GNU See merge request KartKrew/Kart!1357 --- src/CMakeLists.txt | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 50ae6d93f..abd6a66b1 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -328,6 +328,11 @@ target_compile_options(SRB2SDL2 PRIVATE $<$,$>: /Wv:19.20.27004.0 > + + # GNU + $<$: + -fmax-errors=5 + > ) if(SRB2_CONFIG_ERRORMODE) target_compile_options(SRB2SDL2 PRIVATE From 3eff2ef29218602bdf6c5f865d8e8f2e630e5bf6 Mon Sep 17 00:00:00 2001 From: Oni Date: Mon, 24 Jul 2023 23:12:41 +0000 Subject: [PATCH 24/29] Merge branch 'dont-rewrite-the-past' into 'master' Don't rewrite the past if we might still need to send it See merge request KartKrew/Kart!1333 --- src/d_clisrv.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/d_clisrv.c b/src/d_clisrv.c index f916f11de..8935fbf94 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -4659,7 +4659,8 @@ static void HandlePacketFromPlayer(SINT8 node) // If we already received a ticcmd for this tic, just submit it for the next one. tic_t faketic = maketic; - if (!!(netcmds[maketic % BACKUPTICS][netconsole].flags & TICCMD_RECEIVED)) + if ((!!(netcmds[maketic % BACKUPTICS][netconsole].flags & TICCMD_RECEIVED)) + && (maketic - firstticstosend < BACKUPTICS)) faketic++; // Copy ticcmd From 1947eb62773ef54c3762a71d583bf702b7f999f1 Mon Sep 17 00:00:00 2001 From: NepDisk Date: Fri, 13 Jun 2025 10:25:52 -0400 Subject: [PATCH 25/29] Remove GS_CONTINUING and GS_GAMEEND --- src/d_main.cpp | 8 ------- src/deh_soc.c | 16 -------------- src/deh_tables.c | 2 -- src/f_finale.c | 54 +++------------------------------------------ src/f_finale.h | 7 ------ src/f_wipe.c | 4 ---- src/g_game.c | 17 -------------- src/g_state.h | 2 -- src/hu_stuff.c | 1 - src/m_menu.c | 2 +- src/sdl/i_video.cpp | 2 +- 11 files changed, 5 insertions(+), 110 deletions(-) diff --git a/src/d_main.cpp b/src/d_main.cpp index 188501e48..27dc1c98b 100644 --- a/src/d_main.cpp +++ b/src/d_main.cpp @@ -557,20 +557,12 @@ static bool D_Display(void) HU_Drawer(); break; - case GS_GAMEEND: - F_GameEndDrawer(); - break; - case GS_EVALUATION: F_GameEvaluationDrawer(); HU_Erase(); HU_Drawer(); break; - case GS_CONTINUING: - //F_ContinueDrawer(); - break; - case GS_CREDITS: F_CreditDrawer(); HU_Erase(); diff --git a/src/deh_soc.c b/src/deh_soc.c index 4411da648..a709edbe8 100644 --- a/src/deh_soc.c +++ b/src/deh_soc.c @@ -3585,14 +3585,6 @@ void readwipes(MYFILE *f) else if (fastcmp(pword, "FINAL")) wipeoffset = wipe_voting_final; } - else if (fastncmp(word, "CONTINUING_", 11)) - { - pword = word + 11; - if (fastcmp(pword, "TOBLACK")) - wipeoffset = wipe_continuing_toblack; - else if (fastcmp(pword, "FINAL")) - wipeoffset = wipe_continuing_final; - } else if (fastncmp(word, "TITLESCREEN_", 12)) { pword = word + 12; @@ -3627,14 +3619,6 @@ void readwipes(MYFILE *f) else if (fastcmp(pword, "FINAL")) wipeoffset = wipe_evaluation_final; } - else if (fastncmp(word, "GAMEEND_", 8)) - { - pword = word + 8; - if (fastcmp(pword, "TOBLACK")) - wipeoffset = wipe_gameend_toblack; - else if (fastcmp(pword, "FINAL")) - wipeoffset = wipe_gameend_final; - } else if (fastncmp(word, "ENCORE_", 7)) { pword = word + 7; diff --git a/src/deh_tables.c b/src/deh_tables.c index 4bd08029b..dcc834a49 100644 --- a/src/deh_tables.c +++ b/src/deh_tables.c @@ -1429,12 +1429,10 @@ struct int_const_s const INT_CONST[] = { {"GS_NULL",GS_NULL}, {"GS_LEVEL",GS_LEVEL}, {"GS_INTERMISSION",GS_INTERMISSION}, - {"GS_CONTINUING",GS_CONTINUING}, {"GS_TITLESCREEN",GS_TITLESCREEN}, {"GS_TIMEATTACK",GS_TIMEATTACK}, {"GS_CREDITS",GS_CREDITS}, {"GS_EVALUATION",GS_EVALUATION}, - {"GS_GAMEEND",GS_GAMEEND}, {"GS_INTRO",GS_INTRO}, {"GS_CUTSCENE",GS_CUTSCENE}, {"GS_DEDICATEDSERVER",GS_DEDICATEDSERVER}, diff --git a/src/f_finale.c b/src/f_finale.c index f1f5c749b..e9472deac 100644 --- a/src/f_finale.c +++ b/src/f_finale.c @@ -1067,13 +1067,6 @@ void F_BlanCreditTicker(void) void F_StartGameEvaluation(void) { - // Credits option in secrets menu - if (cursaveslot == -2) - { - F_StartGameEnd(); - return; - } - G_SetGamestate(GS_EVALUATION); // Just in case they're open ... somehow @@ -1084,6 +1077,9 @@ void F_StartGameEvaluation(void) CON_ToggleOff(); finalecount = 0; + + G_SetGamestate(GS_TITLESCREEN); + S_StopMusic(); } void F_GameEvaluationDrawer(void) @@ -1093,12 +1089,6 @@ void F_GameEvaluationDrawer(void) void F_GameEvaluationTicker(void) { - if (++finalecount > 10*TICRATE) - { - F_StartGameEnd(); - return; - } - if (finalecount == 5*TICRATE) { if (netgame || multiplayer) // modify this when we finally allow unlocking stuff in 2P @@ -1127,44 +1117,6 @@ void F_GameEvaluationTicker(void) } } -// ========== -// GAME END -// ========== -void F_StartGameEnd(void) -{ - G_SetGamestate(GS_GAMEEND); - - gameaction = ga_nothing; - paused = false; - CON_ToggleOff(); - S_StopSounds(); - - // In case menus are still up?!! - M_ClearMenus(true); - - timetonext = TICRATE; -} - -// -// F_GameEndDrawer -// -void F_GameEndDrawer(void) -{ - // this function does nothing -} - -// -// F_GameEndTicker -// -void F_GameEndTicker(void) -{ - if (timetonext > 0) - timetonext--; - else - D_StartTitle(); -} - - // ============== // TITLE SCREEN // ============== diff --git a/src/f_finale.h b/src/f_finale.h index 2f42ac9fa..0d8e3fb8d 100644 --- a/src/f_finale.h +++ b/src/f_finale.h @@ -33,7 +33,6 @@ boolean F_CutsceneResponder(event_t *ev); boolean F_CreditResponder(event_t *ev); // Called by main loop. -void F_GameEndTicker(void); void F_IntroTicker(void); void F_TitleScreenTicker(boolean run); void F_CutsceneTicker(void); @@ -41,7 +40,6 @@ void F_TitleDemoTicker(void); void F_TextPromptTicker(void); // Called by main loop. -void F_GameEndDrawer(void); void F_IntroDrawer(void); void F_TitleScreenDrawer(void); void F_SkyScroll(INT32 scrollxspeed, INT32 scrollyspeed, const char *patchname); @@ -73,7 +71,6 @@ void F_EndTextPrompt(boolean forceexec, boolean noexec); boolean F_GetPromptHideHudAll(void); boolean F_GetPromptHideHud(fixed_t y); -void F_StartGameEnd(void); void F_StartIntro(void); void F_StartTitleScreen(void); void F_StartCredits(void); @@ -164,12 +161,10 @@ enum wipe_level_toblack, wipe_intermission_toblack, wipe_voting_toblack, - wipe_continuing_toblack, wipe_titlescreen_toblack, wipe_timeattack_toblack, wipe_credits_toblack, wipe_evaluation_toblack, - wipe_gameend_toblack, wipe_intro_toblack, wipe_ending_toblack, wipe_cutscene_toblack, @@ -182,12 +177,10 @@ enum wipe_level_final, wipe_intermission_final, wipe_voting_final, - wipe_continuing_final, wipe_titlescreen_final, wipe_timeattack_final, wipe_credits_final, wipe_evaluation_final, - wipe_gameend_final, wipe_intro_final, wipe_ending_final, wipe_cutscene_final, diff --git a/src/f_wipe.c b/src/f_wipe.c index c6daebc77..20e0b0085 100644 --- a/src/f_wipe.c +++ b/src/f_wipe.c @@ -56,12 +56,10 @@ UINT8 wipedefs[NUMWIPEDEFS] = { 0, // wipe_level_toblack 0, // wipe_intermission_toblack 0, // wipe_voting_toblack, - 0, // wipe_continuing_toblack 0, // wipe_titlescreen_toblack 0, // wipe_timeattack_toblack 99, // wipe_credits_toblack 0, // wipe_evaluation_toblack - 0, // wipe_gameend_toblack UINT8_MAX, // wipe_intro_toblack (hardcoded) 99, // wipe_ending_toblack (hardcoded) 99, // wipe_cutscene_toblack (hardcoded) @@ -72,12 +70,10 @@ UINT8 wipedefs[NUMWIPEDEFS] = { UINT8_MAX, // wipe_level_final 0, // wipe_intermission_final 0, // wipe_voting_final - 0, // wipe_continuing_final 0, // wipe_titlescreen_final 0, // wipe_timeattack_final 99, // wipe_credits_final 0, // wipe_evaluation_final - 0, // wipe_gameend_final 99, // wipe_intro_final (hardcoded) 99, // wipe_ending_final (hardcoded) 99 // wipe_cutscene_final (hardcoded) diff --git a/src/g_game.c b/src/g_game.c index 295fdb599..5b5d33969 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -1605,15 +1605,6 @@ boolean G_Responder(event_t *ev) return true; } } - else if (gamestate == GS_CONTINUING) - { - return true; - } - // Demo End - else if (gamestate == GS_GAMEEND) - { - return true; - } else if (gamestate == GS_INTERMISSION || gamestate == GS_VOTING || gamestate == GS_EVALUATION) if (HU_Responder(ev)) { @@ -2224,20 +2215,12 @@ void G_Ticker(boolean run) HU_Ticker(); break; - case GS_GAMEEND: - if (run) - F_GameEndTicker(); - break; - case GS_EVALUATION: if (run) F_GameEvaluationTicker(); HU_Ticker(); break; - case GS_CONTINUING: - break; - case GS_CREDITS: if (run) F_CreditTicker(); diff --git a/src/g_state.h b/src/g_state.h index 2dc1cc82f..d6261dc2a 100644 --- a/src/g_state.h +++ b/src/g_state.h @@ -28,14 +28,12 @@ typedef enum GS_LEVEL, // Playing, in a level. GS_INTERMISSION, // Gazing at the intermission screen. GS_VOTING, // SRB2Kart: MP voting screen - GS_CONTINUING, // continue screen GS_TITLESCREEN, // title screen GS_TIMEATTACK, // time attack menu GS_CREDITS, // credit sequence GS_EVALUATION, // Evaluation at the end of a game. - GS_GAMEEND, // game end sequence - "did you get all those chaos emeralds?" // Hardcoded fades or other fading methods GS_INTRO, // introduction diff --git a/src/hu_stuff.c b/src/hu_stuff.c index c7c010c8e..5aa55c976 100644 --- a/src/hu_stuff.c +++ b/src/hu_stuff.c @@ -2142,7 +2142,6 @@ void HU_Drawer(void) if (!( Playing() || demo.playback ) || gamestate == GS_INTERMISSION || gamestate == GS_CUTSCENE || gamestate == GS_CREDITS || gamestate == GS_EVALUATION - || gamestate == GS_GAMEEND || gamestate == GS_VOTING || gamestate == GS_WAITINGPLAYERS || gamestate == GS_BLANCREDITS ) // SRB2kart diff --git a/src/m_menu.c b/src/m_menu.c index a667010d1..376d1845b 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -946,7 +946,7 @@ boolean M_Responder(event_t *ev) INT32 deviceplayer = G_GetDevicePlayer(ev->device); if (dedicated || (demo.playback && demo.title) - || gamestate == GS_INTRO || gamestate == GS_CUTSCENE || gamestate == GS_GAMEEND + || gamestate == GS_INTRO || gamestate == GS_CUTSCENE || gamestate == GS_CREDITS || gamestate == GS_EVALUATION || gamestate == GS_BLANCREDITS ) diff --git a/src/sdl/i_video.cpp b/src/sdl/i_video.cpp index 7cb7355b7..ff27a587d 100644 --- a/src/sdl/i_video.cpp +++ b/src/sdl/i_video.cpp @@ -542,7 +542,7 @@ static boolean IgnoreMouse(void) if (paused || con_destlines || chat_on) return true; if (gamestate != GS_LEVEL && gamestate != GS_INTERMISSION && - gamestate != GS_CONTINUING && gamestate != GS_CUTSCENE) + gamestate != GS_CUTSCENE) return true; return false; } From e8bafe7fc57e0f3625c8c2a43404f1afb8e561bf Mon Sep 17 00:00:00 2001 From: NepDisk Date: Sat, 14 Jun 2025 08:09:28 -0400 Subject: [PATCH 26/29] Add kartdebugshrink and remove NOSHOWHELP from kart vars --- src/d_netcmd.c | 23 ++++++++++++----------- src/d_netcmd.h | 1 + src/k_kart.c | 4 ++++ src/screen.c | 2 +- 4 files changed, 18 insertions(+), 12 deletions(-) diff --git a/src/d_netcmd.c b/src/d_netcmd.c index eaaf44033..cdcc2d01c 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -509,9 +509,10 @@ static CV_PossibleValue_t kartdebugitem_cons_t[] = #undef FOREACH {0} }; -consvar_t cv_kartdebugitem = CVAR_INIT ("kartdebugitem", "0", CV_NETVAR|CV_CHEAT|CV_NOSHOWHELP, kartdebugitem_cons_t, NULL); +consvar_t cv_kartdebugitem = CVAR_INIT ("kartdebugitem", "0", CV_NETVAR|CV_CHEAT, kartdebugitem_cons_t, NULL); static CV_PossibleValue_t kartdebugamount_cons_t[] = {{1, "MIN"}, {255, "MAX"}, {0, NULL}}; -consvar_t cv_kartdebugamount = CVAR_INIT ("kartdebugamount", "1", CV_NETVAR|CV_CHEAT|CV_NOSHOWHELP, kartdebugamount_cons_t, NULL); +consvar_t cv_kartdebugamount = CVAR_INIT ("kartdebugamount", "1", CV_NETVAR|CV_CHEAT, kartdebugamount_cons_t, NULL); +consvar_t cv_kartdebugshrink = CVAR_INIT ("kartdebugshrink", "Off", CV_NETVAR|CV_CHEAT, CV_OnOff, NULL); #ifdef DEVELOP #define VALUE "Yes" #else @@ -519,17 +520,17 @@ consvar_t cv_kartdebugamount = CVAR_INIT ("kartdebugamount", "1", CV_NETVAR|CV_C #endif #undef VALUE -consvar_t cv_kartdebugdistribution = CVAR_INIT ("kartdebugdistribution", "Off", CV_NETVAR|CV_CHEAT|CV_NOSHOWHELP, CV_OnOff, NULL); -consvar_t cv_kartdebughuddrop = CVAR_INIT ("kartdebughuddrop", "Off", CV_NETVAR|CV_CHEAT|CV_NOSHOWHELP, CV_OnOff, NULL); +consvar_t cv_kartdebugdistribution = CVAR_INIT ("kartdebugdistribution", "Off", CV_NETVAR|CV_CHEAT, CV_OnOff, NULL); +consvar_t cv_kartdebughuddrop = CVAR_INIT ("kartdebughuddrop", "Off", CV_NETVAR|CV_CHEAT, CV_OnOff, NULL); static CV_PossibleValue_t kartdebugwaypoint_cons_t[] = {{0, "Off"}, {1, "Forwards"}, {2, "Backwards"}, {0, NULL}}; -consvar_t cv_kartdebugwaypoints = CVAR_INIT ("kartdebugwaypoints", "Off", CV_NETVAR|CV_CHEAT|CV_NOSHOWHELP, kartdebugwaypoint_cons_t, NULL); -consvar_t cv_kartdebuglap = CVAR_INIT ("kartdebuglap", "Off", CV_NETVAR|CV_CHEAT|CV_NOSHOWHELP, kartdebugwaypoint_cons_t, NULL); -consvar_t cv_kartdebugbot = CVAR_INIT ("kartdebugbot", "Off", CV_NETVAR|CV_CHEAT|CV_NOSHOWHELP, CV_OnOff, NULL); +consvar_t cv_kartdebugwaypoints = CVAR_INIT ("kartdebugwaypoints", "Off", CV_NETVAR|CV_CHEAT, kartdebugwaypoint_cons_t, NULL); +consvar_t cv_kartdebuglap = CVAR_INIT ("kartdebuglap", "Off", CV_NETVAR|CV_CHEAT, kartdebugwaypoint_cons_t, NULL); +consvar_t cv_kartdebugbot = CVAR_INIT ("kartdebugbot", "Off", CV_NETVAR|CV_CHEAT, CV_OnOff, NULL); -consvar_t cv_kartdebugcheckpoint = CVAR_INIT ("kartdebugcheckpoint", "Off", CV_NOSHOWHELP, CV_OnOff, NULL); -consvar_t cv_kartdebugnodes = CVAR_INIT ("kartdebugnodes", "Off", CV_NOSHOWHELP, CV_OnOff, NULL); -consvar_t cv_kartdebugcolorize = CVAR_INIT ("kartdebugcolorize", "Off", CV_NOSHOWHELP, CV_OnOff, NULL); -consvar_t cv_kartdebugdirector = CVAR_INIT ("kartdebugdirector", "Off", CV_NOSHOWHELP, CV_OnOff, NULL); +consvar_t cv_kartdebugcheckpoint = CVAR_INIT ("kartdebugcheckpoint", "Off", 0, CV_OnOff, NULL); +consvar_t cv_kartdebugnodes = CVAR_INIT ("kartdebugnodes", "Off", 0, CV_OnOff, NULL); +consvar_t cv_kartdebugcolorize = CVAR_INIT ("kartdebugcolorize", "Off", 0, CV_OnOff, NULL); +consvar_t cv_kartdebugdirector = CVAR_INIT ("kartdebugdirector", "Off", 0, CV_OnOff, NULL); static CV_PossibleValue_t votetime_cons_t[] = {{10, "MIN"}, {3600, "MAX"}, {0, NULL}}; consvar_t cv_votetime = CVAR_INIT ("votetime", "20", CV_NETVAR, votetime_cons_t, NULL); diff --git a/src/d_netcmd.h b/src/d_netcmd.h index 4c9419642..96d6634f1 100644 --- a/src/d_netcmd.h +++ b/src/d_netcmd.h @@ -176,6 +176,7 @@ extern consvar_t cv_encorevotes; extern consvar_t cv_votetime; extern consvar_t cv_kartdebugitem, cv_kartdebugamount, cv_kartdebugdistribution, cv_kartdebughuddrop; +extern consvar_t cv_kartdebugshrink; extern consvar_t cv_kartdebugcheckpoint, cv_kartdebugnodes, cv_kartdebugcolorize, cv_kartdebugdirector; extern consvar_t cv_kartdebugwaypoints, cv_kartdebuglap, cv_kartdebugbot; diff --git a/src/k_kart.c b/src/k_kart.c index ef2974bac..04d2baea5 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -262,6 +262,7 @@ void K_RegisterKartStuff(void) CV_RegisterVar(&cv_kartdebugitem); CV_RegisterVar(&cv_kartdebugamount); + CV_RegisterVar(&cv_kartdebugshrink); CV_RegisterVar(&cv_kartdebugdistribution); CV_RegisterVar(&cv_kartdebughuddrop); CV_RegisterVar(&cv_kartdebugwaypoints); @@ -3810,6 +3811,9 @@ UINT16 K_GetKartFlashing(player_t *player) boolean K_PlayerShrinkCheat(player_t *player) { + if (cv_kartdebugshrink.value) + return true; + return ( (player->pflags & PF_SHRINKACTIVE) && (player->bot == false) diff --git a/src/screen.c b/src/screen.c index f5c5cf2b2..ac7c0d391 100644 --- a/src/screen.c +++ b/src/screen.c @@ -63,7 +63,7 @@ consvar_t cv_renderview = CVAR_INIT ("renderview", "On", 0, CV_OnOff, NULL); consvar_t cv_vhseffect = CVAR_INIT ("vhspause", "On", CV_SAVE, CV_OnOff, NULL); static CV_PossibleValue_t shittyscreen_cons_t[] = {{0, "Okay"}, {1, "Shitty"}, {2, "Extra Shitty"}, {0, NULL}}; -consvar_t cv_shittyscreen = CVAR_INIT ("televisionsignal", "Okay", CV_NOSHOWHELP, shittyscreen_cons_t, NULL); +consvar_t cv_shittyscreen = CVAR_INIT ("televisionsignal", "Okay", 0, shittyscreen_cons_t, NULL); CV_PossibleValue_t cv_renderer_t[] = { {1, "Software"}, From 38495d44497b58ffa672364640dfa284b831e974 Mon Sep 17 00:00:00 2001 From: NepDisk Date: Sat, 14 Jun 2025 16:46:49 -0400 Subject: [PATCH 27/29] Fix some clang warnings --- src/g_game.c | 2 +- src/hu_stuff.c | 4 ++-- src/p_mobj.c | 2 +- src/r_segs.cpp | 6 ++---- src/r_skins.c | 2 +- src/v_video.c | 2 +- 6 files changed, 8 insertions(+), 10 deletions(-) diff --git a/src/g_game.c b/src/g_game.c index 5b5d33969..91c259448 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -2531,7 +2531,7 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps) starpostnum = players[player].starpostnum; starposttime = players[player].starposttime; prevcheck = players[player].prevcheck; - prevcheck = players[player].nextcheck; + nextcheck = players[player].nextcheck; lastsafelap = players[player].lastsafelap; lastsafestarpost = players[player].lastsafestarpost; bigwaypointgap = players[player].bigwaypointgap; diff --git a/src/hu_stuff.c b/src/hu_stuff.c index 5aa55c976..4cf04d528 100644 --- a/src/hu_stuff.c +++ b/src/hu_stuff.c @@ -922,7 +922,7 @@ static void Got_Saycmd(UINT8 **p, INT32 playernum) // Handles key input and string input // -static inline boolean HU_keyInChatString(char *s, char ch) +/*static inline boolean HU_keyInChatString(char *s, char ch) { size_t l; @@ -983,7 +983,7 @@ static inline boolean HU_keyInChatString(char *s, char ch) return false; // did not eat key return true; // ate the key -} +}*/ // // diff --git a/src/p_mobj.c b/src/p_mobj.c index 1d462aa89..11e10c829 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -7780,7 +7780,7 @@ static boolean P_MobjDeadThink(mobj_t *mobj) { P_SetObjectMomZ(mobj, -2*FRACUNIT/3, true); - if (mobj->player && (skins[mobj->player->skin].flags && SF_OLDDEATH)) + if (mobj->player && (skins[mobj->player->skin].flags & SF_OLDDEATH)) { mobj->player->drawangle -= ANGLE_22h; } diff --git a/src/r_segs.cpp b/src/r_segs.cpp index 0565d5256..ead2fe3e6 100644 --- a/src/r_segs.cpp +++ b/src/r_segs.cpp @@ -688,8 +688,7 @@ void R_RenderMaskedSegRange(drawseg_t *drawseg, INT32 x1, INT32 x2) template static constexpr T saturating_add(T x, T y) noexcept { - INT64 z; - z = static_cast(x) + static_cast(y); + INT64 z = static_cast(x) + static_cast(y); if (z > static_cast(std::numeric_limits::max())) { z = static_cast(std::numeric_limits::max()); @@ -704,8 +703,7 @@ static constexpr T saturating_add(T x, T y) noexcept template static constexpr T saturating_mul(T x, T y) noexcept { - INT64 z; - z = static_cast(x) * static_cast(y); + INT64 z = static_cast(x) * static_cast(y); if (z > static_cast(std::numeric_limits::max())) { z = static_cast(std::numeric_limits::max()); diff --git a/src/r_skins.c b/src/r_skins.c index 16b479643..15f2034a7 100644 --- a/src/r_skins.c +++ b/src/r_skins.c @@ -173,7 +173,7 @@ UINT32 R_GetSkinAvailabilities(void) { if (unlockables[i].type == SECRET_SKIN && unlockables[i].unlocked) { - UINT8 s = min(unlockables[i].variable, MAXSKINS); + UINT16 s = min(unlockables[i].variable, MAXSKINS); response |= (1 << s); } } diff --git a/src/v_video.c b/src/v_video.c index 061027dc1..e4d39cd40 100644 --- a/src/v_video.c +++ b/src/v_video.c @@ -1571,7 +1571,7 @@ void V_DrawVhsEffect(boolean rewind) fixed_t uby = upbary>>FRACBITS, dby = downbary>>FRACBITS; #ifdef HWRENDER - if ((rendermode == render_opengl)) + if (rendermode == render_opengl) { HWR_RenderVhsEffect(uby, dby, updistort, downdistort, barsize); return; From d96c16b157dacafde914ddaa396964e9419f259f Mon Sep 17 00:00:00 2001 From: NepDisk Date: Sat, 14 Jun 2025 16:59:48 -0400 Subject: [PATCH 28/29] Fix skynum skyboxes being broken in clang due to undefined behaviour --- src/deh_soc.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/deh_soc.c b/src/deh_soc.c index a709edbe8..c948bbd67 100644 --- a/src/deh_soc.c +++ b/src/deh_soc.c @@ -1280,8 +1280,13 @@ void readlevelheader(MYFILE *f, char * name) deh_strlcpy(mapheaderinfo[num]->skytexture, word2, sizeof(mapheaderinfo[num]->skytexture), va("Level header %d: sky texture", num)); else if (fastcmp(word, "SKYNUM")) - deh_strlcpy(mapheaderinfo[num]->skytexture, va("SKY%s", word2), + { + char namebuf[9]; + + sprintf(namebuf, "SKY%.5s", word2); + deh_strlcpy(mapheaderinfo[num]->skytexture, namebuf, sizeof(mapheaderinfo[num]->skytexture), va("Level header %d: sky texture", num)); + } else if (fastcmp(word, "PRECUTSCENENUM")) mapheaderinfo[num]->precutscenenum = (UINT8)i; else if (fastcmp(word, "CUTSCENENUM")) From f64b79260e88bd177f97d26887f8412105eed515 Mon Sep 17 00:00:00 2001 From: NepDisk Date: Thu, 19 Jun 2025 01:01:28 -0400 Subject: [PATCH 29/29] Fix blendmodes on HWR_DrawFill not working https://git.do.srb2.org/STJr/SRB2/-/merge_requests/2670 --- src/hardware/hw_draw.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/hardware/hw_draw.c b/src/hardware/hw_draw.c index af06449a6..e0ec963c1 100644 --- a/src/hardware/hw_draw.c +++ b/src/hardware/hw_draw.c @@ -1116,9 +1116,11 @@ void HWR_DrawConsoleFill(INT32 x, INT32 y, INT32 w, INT32 h, INT32 color, UINT32 void HWR_DrawFill(INT32 x, INT32 y, INT32 w, INT32 h, INT32 color) { FOutVector v[4]; + FBITFIELD flags; FSurfaceInfo Surf; float fx, fy, fw, fh; UINT8 alphalevel = ((color & V_ALPHAMASK) >> V_ALPHASHIFT); + UINT8 blendmode = ((color & V_BLENDMASK) >> V_BLENDSHIFT); // 3--2 // | /| @@ -1198,6 +1200,8 @@ void HWR_DrawFill(INT32 x, INT32 y, INT32 w, INT32 h, INT32 color) Surf.PolyColor = V_GetColor(color); + flags = HWR_GetBlendModeFlag(blendmode+1)|PF_Modulated|PF_NoDepthTest|PF_NoTexture; + if (alphalevel) { if (alphalevel == 13) Surf.PolyColor.s.alpha = softwaretranstogl_lo[st_translucency]; // V_HUDTRANSHALF @@ -1208,7 +1212,7 @@ void HWR_DrawFill(INT32 x, INT32 y, INT32 w, INT32 h, INT32 color) } HWD.pfnDrawPolygon(&Surf, v, 4, - PF_Modulated|PF_NoTexture|PF_NoDepthTest|PF_Translucent); + flags); } #ifdef HAVE_PNG