From ebcd71ece838e82b616fba2ee9f06c8456550e61 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Nov=C3=A1k?= Date: Thu, 30 Jan 2025 10:46:58 +0100 Subject: [PATCH] fix buffer overflow in chargen + CRT effect --- game/chargen.c | 2 +- game/gamesave.c | 2 +- game/kouzla.c | 2 +- platform/sdl/sdl_context.cpp | 44 +++++++++++++++++++++++++++++++++++- platform/sdl/sdl_context.h | 3 ++- 5 files changed, 48 insertions(+), 5 deletions(-) diff --git a/game/chargen.c b/game/chargen.c index bf44510..498aedc 100644 --- a/game/chargen.c +++ b/game/chargen.c @@ -454,7 +454,7 @@ static char select_xicht(int id,int xa,int ya,int xr,int yr) def_handle(H_XICHTY+cur_edited,s,pcx_8bit_decomp,SR_BGRAFIKA); sprintf(s,CHAR_NAME,k); def_handle(H_POSTAVY+cur_edited,s,pcx_8bit_decomp,SR_BGRAFIKA); - for(j=0;jspellname[-1]; //traceon was there; + char traceon = *(k->spellname-1); //traceon was there; size_t bofs = offsetof(TKOUZLO, traceon); size_t eofs = offsetof(TKOUZLO, spellname)-1; memmove(b+bofs+1, b+bofs, eofs-bofs);\ diff --git a/platform/sdl/sdl_context.cpp b/platform/sdl/sdl_context.cpp index 17d9144..419c212 100644 --- a/platform/sdl/sdl_context.cpp +++ b/platform/sdl/sdl_context.cpp @@ -48,6 +48,35 @@ SDLContext::SDLContext() { } +void SDLContext::generateCRTTexture(SDL_Renderer* renderer, SDL_Texture** texture, int width, int height) { + + // Vytvoř novou texturu ve správné velikosti + *texture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_STREAMING, width, height); + SDL_SetTextureBlendMode(*texture, SDL_BLENDMODE_BLEND); + + // Zamkni texturu pro přímý přístup k pixelům + void* pixels; + int pitch; + SDL_LockTexture(*texture, nullptr, &pixels, &pitch); + + // Vyplň texturu patternem (liché řádky tmavší) + Uint32* pixelArray = (Uint32*)pixels; + Uint32 darkPixel = 0x00000080; // Černá s částečnou průhledností + Uint32 transparentPixel = 0x00000000; + + for (int y = 0; y < height; y++) { + Uint32 color = (y % 3 == 0) ? darkPixel : transparentPixel; + for (int x = 0; x < width; x++) { + pixelArray[y * (pitch / 4) + x] = color; + } + } + + // Odemkni texturu + SDL_UnlockTexture(*texture); +} + + + void SDLContext::init_screen(DisplayMode mode, const char *title) { char buff[256]; static Uint32 update_request_event = SDL_RegisterEvents(1); @@ -78,6 +107,7 @@ void SDLContext::init_screen(DisplayMode mode, const char *title) { snprintf(buff, sizeof(buff), "SDL Error create window: %s\n", SDL_GetError()); throw std::runtime_error(buff); } + SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "2"); _window.reset(window); SDL_Renderer *renderer = SDL_CreateRenderer(_window.get(), -1, 0); @@ -151,7 +181,11 @@ void SDLContext::event_loop(std::stop_token stp) { update_screen(); } - if (e.type == SDL_KEYDOWN) { + if (e.type == SDL_WINDOWEVENT) { + if (e.window.event == SDL_WINDOWEVENT_SIZE_CHANGED) { + _crt_effect.reset(); + } + } else if (e.type == SDL_KEYDOWN) { _key_capslock = e.key.keysym.mod & KMOD_CAPS; _key_shift =e.key.keysym.mod & KMOD_SHIFT; _key_control =e.key.keysym.mod & KMOD_CTRL; @@ -320,6 +354,14 @@ void SDLContext::update_screen() { SDL_SetTextureAlphaMod(_visible_texture, 255); SDL_RenderCopy(_renderer.get(), _visible_texture, NULL, &winrc); } + if (winrc.w > 1280 && winrc.h > 960) { + if (!_crt_effect) { + SDL_Texture *txt; + generateCRTTexture(_renderer.get(), &txt, 128, std::min(1440, winrc.h)); + _crt_effect.reset(txt); + } + } + SDL_RenderCopy(_renderer.get(), _crt_effect.get(), NULL, &winrc); SDL_RenderPresent(_renderer.get()); } diff --git a/platform/sdl/sdl_context.h b/platform/sdl/sdl_context.h index 34e91ff..6af3f0d 100644 --- a/platform/sdl/sdl_context.h +++ b/platform/sdl/sdl_context.h @@ -94,6 +94,7 @@ protected: std::unique_ptr _renderer; std::unique_ptr _texture; std::unique_ptr _texture2; + std::unique_ptr _crt_effect; SDL_Texture *_visible_texture; SDL_Texture *_hidden_texture; @@ -136,7 +137,7 @@ protected: static SDL_Point to_source_point(const SDL_Rect &win_rec, const SDL_Point &win_pt) ; static SDL_Rect transition_rect(const SDL_Rect &beg, const SDL_Rect &end, float phase); static int transition_int(int beg, int end, float phase); - + void generateCRTTexture(SDL_Renderer* renderer, SDL_Texture** texture, int width, int height); void signal_push();