From e7db30ca2720091ab24af60ccf5bd2611b4828b4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Nov=C3=A1k?= Date: Sun, 20 Apr 2025 18:16:29 +0200 Subject: [PATCH] prepare linux build, fix some memory leaks --- CMakeLists.txt | 42 +++++++++++++++++--------- game/console.c | 57 ++++++++++++++++++------------------ game/gamesave.c | 26 ++++++++-------- game/interfac.c | 2 +- game/inv.c | 10 +++---- game/realgame.c | 5 ++++ libs/bgraph2.c | 2 ++ platform/CMakeLists.txt | 44 +++++++++++++++------------- platform/achievements.cpp | 21 +++++++++---- platform/error.cpp | 4 +++ platform/error.h | 1 + platform/linux/skeldal.sh | 12 ++++---- platform/sdl/sdl_context.cpp | 1 - 13 files changed, 133 insertions(+), 94 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 772c57b..ca0216e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -3,19 +3,22 @@ project(skeldal) # Najít SDL2 knihovnu find_package(SDL2 REQUIRED) -set(STEAMWORKS_SDK_DIR "${CMAKE_SOURCE_DIR}/external/steamworks/") -# Check if Steamworks SDK directories exist -if(NOT EXISTS "${STEAMWORKS_SDK_DIR}/public") - message(FATAL_ERROR "❌ Could not find Steamworks SDK 'public' headers. - Make sure to download the Steamworks SDK and place it in:${STEAMWORKS_SDK_DIR} - Expected directory: ${STEAMWORKS_SDK_DIR}/public - ") -endif() -if(NOT EXISTS "${STEAMWORKS_SDK_DIR}/redistributable_bin") - message(FATAL_ERROR "❌ Could not find Steamworks SDK 'redistributable_bin' libraries. - Make sure to download the Steamworks SDK and place it in: ${STEAMWORKS_SDK_DIR} - Expected directory: ${STEAMWORKS_SDK_DIR}/redistributable_bin - ") + +set(STEAMWORKS_SDK_DIR "" CACHE PATH "Path to Steamworks SDK directory") + +if(NOT STEAMWORKS_SDK_DIR) + set(POSSIBLE_STEAMWORKS_DIR "${CMAKE_SOURCE_DIR}/external/steamworks") + if(EXISTS "${POSSIBLE_STEAMWORKS_DIR}/public") + if(NOT EXISTS "${STEAMWORKS_SDK_DIR}/redistributable_bin") + set(STEAMWORKS_SDK_DIR "${POSSIBLE_STEAMWORKS_DIR}" CACHE PATH "Path to Steamworks SDK directory" FORCE) + endif() + endif() + if (NOT STEAMWORKS_SDK_DIR) + message("!!! Steam is not installed") + message("!!! compiling without steam and without achievements support") + message("!!! To enable steam, set STEAMWORKS_SDK_DIR to correct value") + set(STEAMWORKS_SDK_DIR "none" CACHE PATH "Path to Steamworks SDK directory" FORCE) + endif() endif() if (MSVC) @@ -26,6 +29,18 @@ else() set(STANDARD_LIBRARIES "pthread") endif() + + +if(${STEAMWORKS_SDK_DIR} STREQUAL "none") + set(STEAM_ENABLED 0) +else() + add_compile_definitions(STEAM_ENABLED) + include_directories(${STEAMWORKS_SDK_DIR}/public) + set(STEAM_ENABLED 1) + +endif() + + include_directories(.) set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin/) @@ -33,7 +48,6 @@ set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib/) set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib/) include_directories( ${SDL2_INCLUDE_DIRS}) -include_directories(${STEAMWORKS_SDK_DIR}/public) add_subdirectory(libs) add_subdirectory(platform) add_subdirectory(game) diff --git a/game/console.c b/game/console.c index b440e2e..dc68777 100644 --- a/game/console.c +++ b/game/console.c @@ -2,6 +2,7 @@ #include #include #include "globals.h" +#include "../platform/error.h" #include "../platform/platform.h" #include @@ -227,7 +228,7 @@ static void flush_console_command() { if (console_command) { const char *cmd = concat2("> ", console_command); console_command = NULL; - console_add_line(cmd); + console_add_line(cmd); } } @@ -281,24 +282,6 @@ static PARSED_COMMAND parse_command(const char *cmd) { extern int ghost_walls; extern int nofloors; -static int add_file_to_console(const char *name, LIST_FILE_TYPE _, size_t __, void *ctx) { - int *cnt = (void *)ctx; - char buff[20] = ""; - for (int i = 0; i < 19; ++i) buff[i] = ' '; - buff[19] = 0; - int l = strlen(name); - if (l > 3 && istrcmp(name+l-4,".MAP") == 0) { - if (l>19) l = 19; - memcpy(buff, name, l); - wzprintf("%s", buff); - if (++(*cnt) == 6) { - wzprintf("\n"); - *cnt = 0; - } - } - return 0; - -} static int process_on_off_command(const char *cmd, char on) { if (istrcmp(cmd, "inner-eye") == 0) { @@ -358,9 +341,8 @@ static int process_on_off_command(const char *cmd, char on) { void postavy_teleport_effect(int sector,int dir,int postava,char effect); -static int command_ls_callback(const char*name, void* ctx) { +static void command_ls_callback(const char *name, void* ctx) { wzprintf("%s\n", name); - return 0; } static int process_actions(const char *command) { @@ -605,7 +587,7 @@ static int process_with_params(const char *cmd, const char *args) { if (istrcmp(cmd, "unvisit") == 0) { if (args[0] == 0) return 0; int id = atoi(args); - return dialog_set_notvisited(id); + return dialog_set_notvisited(id); } if (istrcmp(cmd, "cat") == 0) { @@ -650,7 +632,26 @@ static int process_with_params(const char *cmd, const char *args) { free(data2); free(data); return 1; - } + } + + if (istrcmp(cmd, "rm") == 0) { + if (strcmp(args, "*") == 0) { + temp_storage_clear(); + } else { + int32_t sz =temp_storage_find(args); + if (sz < 0) return 0; + temp_storage_delete(args); + } + return 1; + } + if (istrcmp(cmd, "crash") == 0) { + throw_exception(args); + return 1; + } + + + + return 0; } @@ -676,7 +677,7 @@ static int process_command(PARSED_COMMAND cmd) { static void console_copy_to_clipboard() { size_t needsz = 0; for (unsigned int i = 0; i < console_max_lines; ++i) { - if (console_output_lines[i]) needsz = needsz + strlen(console_output_lines[i]) + 2; + if (console_output_lines[i]) needsz = needsz + strlen(console_output_lines[i]) + 2; } needsz+=1; char *text = (char *)malloc(needsz); @@ -690,7 +691,7 @@ static void console_copy_to_clipboard() { *iter = '\r'; ++iter; *iter = '\n'; - ++iter; + ++iter; } } *iter = 0; @@ -698,7 +699,7 @@ static void console_copy_to_clipboard() { copied_text = 20; } free(text); -} +} static void console_keyboard(EVENT_MSG *msg, void **_) { if (msg->msg == E_KEYBOARD) { @@ -731,7 +732,7 @@ static void console_keyboard(EVENT_MSG *msg, void **_) { free(cmd.cmd_buffer); msg->msg = -1; } else if (c == 3 && !get_shift_key_state()) { - console_copy_to_clipboard(); + console_copy_to_clipboard(); } else if (c >=32 && len < console_max_characters) { console_input_line[len] = c; console_input_line[len+1] = 0; @@ -802,7 +803,7 @@ static void wzputs(const char *text) while (sep != NULL) { console_add_line_s(text, sep-text); text = sep+1; - sep = strchr(text, '\n'); + sep = strchr(text, '\n'); } if (text[0] != 0) console_add_line_s(text, strlen(text)); } diff --git a/game/gamesave.c b/game/gamesave.c index f43b71c..f3c75bd 100644 --- a/game/gamesave.c +++ b/game/gamesave.c @@ -38,7 +38,7 @@ #define SSAVE_VERSION 0 -static TMPFILE_WR *story=NULL; +//static TMPFILE_WR *story=NULL; static char load_another; static unsigned long current_campaign = 0; static long prev_game_time_save = -999; @@ -505,7 +505,7 @@ static void add_status_file(FILE *f, const char *name, size_t sz, void *data) { fwrite(name, 1, name_size_b, f); uint32_t data_size = sz; fwrite(&data_size,1,sizeof(data_size),f); - fwrite(data, 1,data_size, f); + if (data && data_size) fwrite(data,1,data_size, f); } static void pack_status_file_cb(const char *name, void *ctx) { @@ -942,6 +942,7 @@ typedef struct { char skip_autosave; } TSAVEGAME_CB_STATE; +/* static char is_same_prefix(const char *name, const char *prev_name) { const char *sep1 = strrchr(name, '.'); const char *sep2 = strrchr(prev_name, '.'); @@ -950,7 +951,7 @@ static char is_same_prefix(const char *name, const char *prev_name) { if (strncmp(name, prev_name,sep1-name) == 0) return 1; return 0; } - +*/ static int get_all_savegames_callback(const char *name, LIST_FILE_TYPE type , size_t tm, void *ctx) { if (istrncmp(name, "sav.", 4) != 0 && istrcmp(name+strlen(name)-4,".sav") != 0) @@ -974,11 +975,11 @@ static int get_all_savegames_callback(const char *name, LIST_FILE_TYPE type , s } return 0; } - +/* static int compare_strings (const void *a, const void *b) { return strcmp(*(const char **)a, *(const char **)b); } - +*/ static int compare_strings_third_back (const void *a, const void *b) { const char *sa = *(const char **)a; const char *sb = *(const char **)b; @@ -995,7 +996,7 @@ static int compare_strings_third_back (const void *a, const void *b) { return -strcmp(ba,bb); } - +/* static int dedup_strings_prefix(TSTR_LIST lst, int count) { int j = -1; for (int i = 0; i < count; ++i) { @@ -1014,7 +1015,7 @@ static int dedup_strings_prefix(TSTR_LIST lst, int count) { } -/* + static void load_specific_file(int slot_num,char *filename,void **out,int32_t *size) //call it in task! { FILE *slot; @@ -1596,7 +1597,7 @@ void wire_ask_gamename(int id) } static void save_as_dialog(int pos); -static const char *find_autosave(const char *name); + #define CLK_SAVELOAD 11 @@ -1799,24 +1800,20 @@ void wire_save_load(char save) { void open_story_file() { - - story=temp_storage_append(STORY_BOOK); - SEND_LOG("(STORY) Story temp file is opened...."); } void write_story_text(char *text) { int l = strlen(text); + TMPFILE_WR *story = temp_storage_append(STORY_BOOK); temp_storage_write( text, l, story); temp_storage_write("\n", 1, story); + temp_storage_close_wr(story); } void close_story_file() { - if (story!=NULL) temp_storage_close_wr(story); - story=NULL; - SEND_LOG("(STORY) Story temp file is closed..."); } #if 0 @@ -1909,6 +1906,7 @@ void do_autosave() { remove(build_pathname(2, gpathtable[SR_SAVES],n)); } } + release_list(st.files); } save_game(get_save_game_slot_id(), game_name,1); } diff --git a/game/interfac.c b/game/interfac.c index 042893e..28b1975 100644 --- a/game/interfac.c +++ b/game/interfac.c @@ -463,7 +463,7 @@ void type_text_v2(va_list args) case 8:if (pos>0) { pos--; - strcpy(&text[pos],&text[pos+1]); + memmove(text+pos,text+pos+1, strlen(text+pos+1)+1); len--; } break; diff --git a/game/inv.c b/game/inv.c index e3ef8f8..e20e230 100644 --- a/game/inv.c +++ b/game/inv.c @@ -1078,7 +1078,7 @@ char check_jidlo_voda(THUMAN *p) char check_map_specials(THUMAN *p) { char c=0; - if (p->inmaphash != current_map_hash) return; + if (p->inmaphash != current_map_hash) return c; switch(mglob.map_effector) { case ME_NORMAL:break; @@ -1144,16 +1144,16 @@ void real_regeneration(THE_TIMER *t) int i; THUMAN *p; - for(i=0;iused) + if (p->used) { if (p->lives) { pomala_regenerace_postavy(p); } else { umirani_postavy(p); } } + } send_message(E_KOUZLO_KOLO); sleep_ticks+=MAX_SLEEP/30; if (sleep_ticks>MAX_SLEEP) sleep_ticks=MAX_SLEEP; @@ -2584,7 +2584,7 @@ static void rebuild_shops(const void *shop_ptr) const char *c=(const char *)shop_ptr; int i; - + SEND_LOG("(SHOP) Rebuilding shops...."); max_shops = *(const int32_t *)c; diff --git a/game/realgame.c b/game/realgame.c index d8accc1..80fd10c 100644 --- a/game/realgame.c +++ b/game/realgame.c @@ -358,6 +358,7 @@ int load_map(const char *filename) { load_enemies(temp,size,&ofsts,mob_template,mob_size); ablock_free(mob_template); + mob_template=NULL; SEND_LOG("(GAME) Loading enemies from map template..."); } free(temp); @@ -365,6 +366,7 @@ int load_map(const char *filename) case A_MAPMACR: SEND_LOG("(GAME) Loading multiactions..."); load_macros(size,temp); + free(temp); break; case A_MAPVYK: map_vyk=temp; @@ -373,6 +375,7 @@ int load_map(const char *filename) case A_MOBS: mob_template=load_mob_legacy_format_direct(temp, &size,0); mob_size=size; + free(temp); break; case A_MOBSND: snd_load=1; @@ -391,11 +394,13 @@ int load_map(const char *filename) else { if (temp!=NULL)free(temp); + ablock_free(mob_template); fclose(f); return -3; } } while (nmapend); + ablock_free(mob_template); fclose(f); flag_map=(char *)getmem(mapsize*4); memset(minimap,0,sizeof(minimap)); diff --git a/libs/bgraph2.c b/libs/bgraph2.c index d1c6532..0d14e1b 100644 --- a/libs/bgraph2.c +++ b/libs/bgraph2.c @@ -538,11 +538,13 @@ void hide_ms_cursor() } void redraw_ms_cursor_on_screen(void) { +#ifdef FORCE_SOFTWARE_CURSOR if (mssavebuffer) { integer xs=*(integer *)mssavebuffer; integer ys=*((integer *)mssavebuffer+1); showview(mscuroldx,mscuroldy,xs,ys); } +#endif } diff --git a/platform/CMakeLists.txt b/platform/CMakeLists.txt index d05d4f7..bdb8382 100644 --- a/platform/CMakeLists.txt +++ b/platform/CMakeLists.txt @@ -35,23 +35,27 @@ if(WIN32) windows/skeldal.rc ) target_compile_definitions(skeldal_platform PRIVATE PLATFORM_WINDOWS) - if(CMAKE_SIZEOF_VOID_P EQUAL 8) - # 64-bit - set(STEAMLIB ${STEAMWORKS_SDK_DIR}redistributable_bin/win64/steam_api64.lib) - set(STEAMDLL ${STEAMWORKS_SDK_DIR}redistributable_bin/win64/steam_api64.dll) - target_compile_definitions(skeldal_platform PRIVATE PLATFORM_WINDOWS_64) + if(STEAM_ENABLED) + if(CMAKE_SIZEOF_VOID_P EQUAL 8) + # 64-bit + set(STEAMLIB ${STEAMWORKS_SDK_DIR}redistributable_bin/win64/steam_api64.lib) + set(STEAMDLL ${STEAMWORKS_SDK_DIR}redistributable_bin/win64/steam_api64.dll) + else() + # 32-bit + set(STEAMLIB ${STEAMWORKS_SDK_DIR}/redistributable_bin/win32/steam_api.lib) + set(STEAMDLL ${STEAMWORKS_SDK_DIR}redistributable_bin/win64/steam_api.dll) + endif() else() - # 32-bit - set(STEAMLIB ${STEAMWORKS_SDK_DIR}/redistributable_bin/win32/steam_api.lib) - set(STEAMDLL ${STEAMWORKS_SDK_DIR}redistributable_bin/win64/steam_api.dll) - target_compile_definitions(skeldal_platform PRIVATE PLATFORM_WINDOWS_32) + set(STEAMLIB "") + set(STEAMDLL "") endif() target_link_libraries(skeldal ${all_libs} ${STEAMLIB}) - add_custom_command(TARGET skeldal POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy_if_different - ${STEAMDLL} $ -) + if(STEAMDLL) + add_custom_command(TARGET skeldal POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy_if_different + ${STEAMDLL} $) + endif() message(STATUS "Building for Windows") @@ -65,14 +69,14 @@ elseif(UNIX AND NOT APPLE) linux/app_start.cpp ) target_compile_definitions(skeldal_bin PRIVATE PLATFORM_LINUX) - if(CMAKE_SIZEOF_VOID_P EQUAL 8) - # 64-bit - set(STEAMLIB ${STEAMWORKS_SDK_DIR}/redistributable_bin/linux64/libsteam_api.so) - target_compile_definitions(skeldal_bin PRIVATE PLATFORM_LINUX_64) - else() - # 32-bit - set(STEAMLIB ${STEAMWORKS_SDK_DIR}/redistributable_bin/linux32/libsteam_api.so) - target_compile_definitions(skeldal_bin PRIVATE PLATFORM_LINUX_32) + if(STEAM_ENABLED) + if(CMAKE_SIZEOF_VOID_P EQUAL 8) + # 64-bit + set(STEAMLIB ${STEAMWORKS_SDK_DIR}/redistributable_bin/linux64/libsteam_api.so) + else() + # 32-bit + set(STEAMLIB ${STEAMWORKS_SDK_DIR}/redistributable_bin/linux32/libsteam_api.so) + endif() endif() add_custom_command( TARGET skeldal_bin POST_BUILD diff --git a/platform/achievements.cpp b/platform/achievements.cpp index fa0fc8d..41bc0ef 100644 --- a/platform/achievements.cpp +++ b/platform/achievements.cpp @@ -1,9 +1,10 @@ -#include "achievements.h" -#include -#include "error.h" #include #include +#include "achievements.h" +#include "error.h" #include "platform.h" +#ifdef STEAM_ENABLED +#include extern "C" { #include @@ -25,7 +26,7 @@ void steam_init() steam_initialized = 1; steam_available = SteamAPI_Init(); if (steam_available) { - send_message(E_ADD, E_IDLE, &run_steam_callbacks); + send_message(E_ADD, E_IDLE, &run_steam_callbacks); SteamUserStats()->RequestUserStats(SteamUser()->GetSteamID()); } else { steam_available = 0; @@ -57,7 +58,7 @@ int8_t set_achievement(const char *id) } else { return -1; } - + } int8_t clear_achievement(const char *id) @@ -81,7 +82,7 @@ int8_t clear_achievement(const char *id) return 0; } else { return -1; - } + } } } @@ -104,3 +105,11 @@ char *get_steam_status() char *out = strdup(str.c_str()); return out; } +#else +void steam_init() {} +void steam_shutdown() {} +int8_t set_achievement(const char *id) {return -1;} +int8_t clear_achievement(const char *id) {return -1;} +char is_steam_available() {return 0;} +char *get_steam_status() {return NULL;} +#endif diff --git a/platform/error.cpp b/platform/error.cpp index 46b26d2..8002e9e 100644 --- a/platform/error.cpp +++ b/platform/error.cpp @@ -34,3 +34,7 @@ void send_log_impl(const char *format, ...) { #endif } + +void throw_exception(const char *text) { + throw std::runtime_error(std::string("Invoked crash:") + text); +} diff --git a/platform/error.h b/platform/error.h index 5b86ccd..5d0e975 100644 --- a/platform/error.h +++ b/platform/error.h @@ -8,6 +8,7 @@ extern "C" { void send_log_impl(const char *format, ...); void display_error(const char *format, ...); +void throw_exception(const char *text); #ifdef __cplusplus diff --git a/platform/linux/skeldal.sh b/platform/linux/skeldal.sh index 83b11b5..03e6c7f 100755 --- a/platform/linux/skeldal.sh +++ b/platform/linux/skeldal.sh @@ -1,14 +1,14 @@ #!/bin/bash - temp_file=$(mktemp /tmp/skeldal.XXXXXX.log) +CURDIR=`dirname "$0"` -`dirname $0`/skeldal_bin $* > "$temp_file" 2>&1 +LD_LIBRARY_PATH=$CURDIR:$LD_LIBRARY_PATH "$CURDIR/skeldal_bin" $* > "$temp_file" 2>&1 exit_code=$? if [ $exit_code -ne 0 ]; then error_message=$(cat "$temp_file") - + if command -v zenity > /dev/null; then zenity --warning --no-markup --title="Skeldal ERROR" --text="$error_message" elif command -v kdialog > /dev/null; then @@ -18,9 +18,11 @@ if [ $exit_code -ne 0 ]; then elif command -v xdg-open > /dev/null; then xdg-open "$temp_file" sleep 5; - else + else cat "$temp_file" fi fi rm $temp_file -exit $exit_code \ No newline at end of file +exit $exit_code + + diff --git a/platform/sdl/sdl_context.cpp b/platform/sdl/sdl_context.cpp index d3928b0..e0c59c7 100644 --- a/platform/sdl/sdl_context.cpp +++ b/platform/sdl/sdl_context.cpp @@ -11,7 +11,6 @@ #include #include #include -#include #include #include #include