fix bugs, better crt, mouse cursor size in config

This commit is contained in:
Ondřej Novák 2025-03-23 13:52:09 +01:00
parent 15c88740bf
commit 3eb73c4ad1
7 changed files with 43 additions and 18 deletions

View file

@ -23,4 +23,5 @@ enable_testing()
add_subdirectory(libs) add_subdirectory(libs)
add_subdirectory(platform) add_subdirectory(platform)
add_subdirectory(game) add_subdirectory(game)
add_subdirectory(tools)

View file

@ -219,7 +219,8 @@ void restore_items(TMPFILE_RD *f)
temp_storage_read(new_item_map[i],2*j,f); temp_storage_read(new_item_map[i],2*j,f);
short *v = new_item_map[i]; short *v = new_item_map[i];
while (*v) { //sanitize map items while (*v) { //sanitize map items
if (*v < 1 || *v >= item_count) { int vv = abs(*v);
if (vv > item_count) {
free(new_item_map[i]); free(new_item_map[i]);
new_item_map[i] = map_items[i]; new_item_map[i] = map_items[i];
map_items[i] = NULL; map_items[i] = NULL;
@ -230,7 +231,6 @@ void restore_items(TMPFILE_RD *f)
} }
for(i=0;i<mapsize*4;i++) if (map_items[i]!=NULL) free(map_items[i]); for(i=0;i<mapsize*4;i++) if (map_items[i]!=NULL) free(map_items[i]);
memset(map_items,0,mapsize*4*sizeof(*map_items));
free(map_items); free(map_items);
map_items = new_item_map; map_items = new_item_map;

View file

@ -805,7 +805,7 @@ void cti_texty(void)
//patch stringtable //patch stringtable
if (!texty[98]) str_replace(&texty,98,"Ulo\x91it hru jako"); if (!texty[98]) str_replace(&texty,98,"Ulo\x91it hru jako");
if (!texty[99]) str_replace(&texty,99,"CRT Filter (>720p)"); if (!texty[99]) str_replace(&texty,99,"CRT Filter (>720p)");
str_replace(&texty,0,"Byl nalezen p\xA9ipojen\x98 ovlada\x87\nPro aktivaci ovlada\x87""e stiskn\x88te kt\x82rekoliv tla\x87\xA1tko na ovlada\x87i"); str_replace(&texty,0,"Byl nalezen p\xA9ipojen\x98 ovlada\x87\nPro aktivaci ovlada\x87""e stiskn\x88te kter\x82koliv tla\x87\xA1tko na ovlada\x87i");
lang_patch_stringtable(&texty, "ui.csv", ""); lang_patch_stringtable(&texty, "ui.csv", "");
} }
@ -968,7 +968,7 @@ void show_joystick_info(void) {
break; break;
} }
} }
} }
void show_loading_picture(char *filename) void show_loading_picture(char *filename)
@ -996,7 +996,7 @@ void init_skeldal(const INI_CONFIG *cfg)
char verr = game_display_init(ini_section_open(cfg, "video"), "Skeldal"); char verr = game_display_init(ini_section_open(cfg, "video"), "Skeldal");
if (!verr) if (!verr)
{ {
display_error("Error game_display_init %d", verr); display_error("Error game_display_init %d", verr);
exit(1); exit(1);
} }
showview = game_display_update_rect; showview = game_display_update_rect;

View file

@ -40,6 +40,7 @@ char game_display_init(const INI_CONFIG_SECTION *display_section, const char *ti
else if (istrcmp(filter,"rgbmatrix_3") == 0) cfg.crt_filter = SDLContext::CrtFilterType::rgb_matrix_3; else if (istrcmp(filter,"rgbmatrix_3") == 0) cfg.crt_filter = SDLContext::CrtFilterType::rgb_matrix_3;
else cfg.crt_filter = SDLContext::CrtFilterType::autoselect; else cfg.crt_filter = SDLContext::CrtFilterType::autoselect;
cfg.cursor_size = ini_get_int(display_section, "cursor_size", 100)*0.01f;
screen_pitch = 640; screen_pitch = 640;
get_sdl_global_context().init_video(cfg, title); get_sdl_global_context().init_video(cfg, title);

View file

@ -74,13 +74,28 @@ void handle_sdl_error(const char *msg) {
void SDLContext::generateCRTTexture(SDL_Renderer* renderer, SDL_Texture** texture, int width, int height, CrtFilterType type) { void SDLContext::generateCRTTexture(SDL_Renderer* renderer, SDL_Texture** texture, int width, int height, CrtFilterType type) {
if (type == CrtFilterType::autoselect) { if (type == CrtFilterType::autoselect) {
if (height > 1680) type = CrtFilterType::rgb_matrix_3; if (height >= 1200) type = CrtFilterType::scanlines_2;
else if (height >= 1200) type = CrtFilterType::scanlines_2;
else type = CrtFilterType::scanlines; else type = CrtFilterType::scanlines;
} }
int interfer = 1;
switch (type) {
case CrtFilterType::scanlines: interfer = 2;break;
case CrtFilterType::scanlines_2: interfer = 3;break;
case CrtFilterType::rgb_matrix_2: interfer = 3;break;
case CrtFilterType::rgb_matrix_3: interfer = 4;break;
default: break;
}
if (type == CrtFilterType::scanlines || type == CrtFilterType::scanlines_2) { if (type == CrtFilterType::scanlines || type == CrtFilterType::scanlines_2) {
width = 32; width = 32;
} else {
unsigned int mult_of_base = std::max<unsigned int>((height+320)/640,interfer);
width = width * interfer / mult_of_base;
}
{
unsigned int mult_of_base = std::max<unsigned int>((height+240)/480,interfer);
height = height * interfer / mult_of_base;
} }
// Vytvoř novou texturu ve správné velikosti // Vytvoř novou texturu ve správné velikosti
*texture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_STREAMING, width, height); *texture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_STREAMING, width, height);
@ -169,9 +184,9 @@ static void crash_sdl_exception() {
try { try {
throw; throw;
} catch (std::exception &e) { } catch (std::exception &e) {
display_error("Display server - unhandled exception: %s", e.what()); display_error("Display server - unhandled exception: %s", e.what());
} catch (...) { } catch (...) {
display_error("Display server - unhandled unknown exception (probably crash)"); display_error("Display server - unhandled unknown exception (probably crash)");
} }
abort(); abort();
} }
@ -198,6 +213,7 @@ void SDLContext::init_video(const VideoConfig &config, const char *title) {
_fullscreen_mode = config.fullscreen; _fullscreen_mode = config.fullscreen;
_mouse_size = config.cursor_size;
std::atomic<bool> done = false; std::atomic<bool> done = false;
std::exception_ptr e; std::exception_ptr e;
@ -251,13 +267,13 @@ void SDLContext::init_video(const VideoConfig &config, const char *title) {
} }
done = true; done = true;
done.notify_all(); done.notify_all();
if (!err) { if (!err) {
try { try {
SDL_ShowCursor(SDL_DISABLE); SDL_ShowCursor(SDL_DISABLE);
event_loop(stp); event_loop(stp);
} catch (...) { } catch (...) {
SDL_ShowCursor(SDL_ENABLE); SDL_ShowCursor(SDL_ENABLE);
crash_sdl_exception(); crash_sdl_exception();
} }
} }
@ -641,9 +657,11 @@ void SDLContext::refresh_screen() {
} }
if (_mouse) { if (_mouse) {
SDL_Rect recalc_rect = to_window_rect(winrc, _mouse_rect); SDL_Rect recalc_rect = to_window_rect(winrc, _mouse_rect);
recalc_rect.w = static_cast<int>(recalc_rect.w * _mouse_size);
recalc_rect.h = static_cast<int>(recalc_rect.h * _mouse_size);
SDL_Point f= to_window_point({0,0,winrc.w, winrc.h}, _mouse_finger); SDL_Point f= to_window_point({0,0,winrc.w, winrc.h}, _mouse_finger);
recalc_rect.x = _mouse_rect.x - f.x; recalc_rect.x = _mouse_rect.x - static_cast<int>(f.x * _mouse_size);
recalc_rect.y = _mouse_rect.y - f.y; recalc_rect.y = _mouse_rect.y - static_cast<int>(f.y * _mouse_size);
SDL_RenderCopy(_renderer.get(), _mouse.get(), NULL, &recalc_rect); SDL_RenderCopy(_renderer.get(), _mouse.get(), NULL, &recalc_rect);
} }
if (winrc.h >= 720 && _crt_filter != CrtFilterType::none && _enable_crt) { if (winrc.h >= 720 && _crt_filter != CrtFilterType::none && _enable_crt) {

View file

@ -36,6 +36,7 @@ public:
bool fullscreen; bool fullscreen;
int aspect_x; int aspect_x;
int aspect_y; int aspect_y;
float cursor_size;
}; };
struct AudioConfig { struct AudioConfig {
@ -238,10 +239,9 @@ protected:
SDL_Texture *_visible_texture; SDL_Texture *_visible_texture;
SDL_Texture *_hidden_texture; SDL_Texture *_hidden_texture;
std::jthread _render_thread;
bool _fullscreen_mode = false; bool _fullscreen_mode = false;
bool _present = false; bool _present = false;
std::atomic<bool> _key_control = false; std::atomic<bool> _key_control = false;
std::atomic<bool> _key_shift = false; std::atomic<bool> _key_shift = false;
std::atomic<bool> _key_capslock = false; std::atomic<bool> _key_capslock = false;
@ -254,6 +254,7 @@ protected:
std::queue<uint16_t> _keyboard_queue; std::queue<uint16_t> _keyboard_queue;
SDL_Rect _mouse_rect; SDL_Rect _mouse_rect;
SDL_Point _mouse_finger; SDL_Point _mouse_finger;
float _mouse_size;
SpriteList _sprites; SpriteList _sprites;
@ -264,6 +265,8 @@ protected:
Uint32 _update_request_event; Uint32 _update_request_event;
Uint32 _refresh_request; Uint32 _refresh_request;
std::jthread _render_thread;
void event_loop(std::stop_token stp); void event_loop(std::stop_token stp);
void update_screen(bool force_refresh = false); void update_screen(bool force_refresh = false);

View file

@ -24,8 +24,8 @@
# crt_filter = enable filter simmulates lowres CRT monitor for higher resolution (>720p) # crt_filter = enable filter simmulates lowres CRT monitor for higher resolution (>720p)
# none = disabled # none = disabled
# auto = auto select depend on resolution (default) # auto = auto select depend on resolution (default)
# scanline = 1 pixel wide scanline (best for HD resolution, 960p-1080p) # scanlines = 1 pixel wide scanlines (best for HD resolution, 960p-1080p)
# scanline_2 = 2 pixels wide scanline (best for QHD resolution, 1440p) # scanlines_2 = 2 pixels wide scanlines (best for QHD resolution, 1440p)
# rgbmatrix_2 = emulates CRT shadow mask (best for QHD resolution, 1440p) # rgbmatrix_2 = emulates CRT shadow mask (best for QHD resolution, 1440p)
# rgbmatrix_3 = emulates CRT shadow mask (best for 4K resolution, 1920p+) # rgbmatrix_3 = emulates CRT shadow mask (best for 4K resolution, 1920p+)
# (hardware composer and linear filtering is recommended) # (hardware composer and linear filtering is recommended)
@ -38,6 +38,7 @@
# linear - use linear filtering (Direct3D and OpenGL) # linear - use linear filtering (Direct3D and OpenGL)
# nearest - use nearest filtering # nearest - use nearest filtering
# aspect_ratio = x:y, none = don't keep fixed ratio' # aspect_ratio = x:y, none = don't keep fixed ratio'
# cursor_size = mouse cursor size in percent
# #
[video] [video]
#fullscreen=on #fullscreen=on
@ -47,6 +48,7 @@
#scale_quality=auto #scale_quality=auto
#composer=auto #composer=auto
#aspect_ratio=4:3 #aspect_ratio=4:3
#cursor_size=100
### audio settings ### audio settings