From 52e7882563317e93f11768d8911034b249b01887 Mon Sep 17 00:00:00 2001 From: klei1984 <53688147+klei1984@users.noreply.github.com> Date: Sat, 18 May 2024 17:31:01 +0200 Subject: [PATCH] Various linux related changes - destop shortcut does not execute scripts directly for some reason - sed does not preserve file line endings - linux may mount ISO 9660 CD-ROMs in all lower case mode which leads to game resources not being found on its case sensitive file systems --- assets/max-port.desktop.in | 4 +- assets/max-port.in | 24 +++---- src/color.cpp | 15 ++-- src/enums.hpp | 12 ++++ src/flicsmgr.cpp | 18 ++--- src/game_manager.cpp | 23 +++---- src/gamesetupmenu.cpp | 21 +++--- src/menu.cpp | 135 +++++++++++++++--------------------- src/movie.cpp | 121 ++++++++++++++------------------ src/resource_manager.cpp | 137 +++++++++++++++++++++++++++++-------- src/resource_manager.hpp | 7 +- src/saveloadmenu.cpp | 7 +- src/sound_manager.cpp | 84 ++++++++--------------- 13 files changed, 311 insertions(+), 297 deletions(-) diff --git a/assets/max-port.desktop.in b/assets/max-port.desktop.in index 39b7cea8..5fdc089a 100644 --- a/assets/max-port.desktop.in +++ b/assets/max-port.desktop.in @@ -3,6 +3,6 @@ Version=1.0 Type=Application Name=M.A.X. Port Categories=Game;StrategyGame; -TryExec=/usr/games/max-port -Exec=/usr/games/max-port +Terminal=false +Exec=gnome-terminal -x /usr/games/max-port Icon=@CMAKE_INSTALL_PREFIX@/@GAME_INSTALL_PATH@/max.png diff --git a/assets/max-port.in b/assets/max-port.in index 3df7a3c4..e2cd9ca2 100644 --- a/assets/max-port.in +++ b/assets/max-port.in @@ -21,18 +21,18 @@ fi maxport_base_dir="" for dir in $(echo "$XDG_DATA_DIRS" | sed "s/:/ /g"); do - if [ -f "$dir/max-port/PATCHES.RES" ]; then + if [ -f "$dir/max-port/PATCHES.RES" ] || [ -f "$dir/max-port/patches.res" ]; then maxport_base_dir="$dir/max-port" break fi done -if ! [ -f "$maxport_base_dir/PATCHES.RES" ]; then - if [ -f "/usr/share/max-port/PATCHES.RES" ]; then +if ! [ -f "$maxport_base_dir/PATCHES.RES" ] && ! [ -f "$maxport_base_dir/patches.res" ]; then + if [ -f "/usr/share/max-port/PATCHES.RES" ] || [ -f "/usr/share/max-port/patches.res" ]; then maxport_base_dir="/usr/share/max-port" - elif [ -f "$XDG_DATA_HOME/max-port/PATCHES.RES" ]; then + elif [ -f "$XDG_DATA_HOME/max-port/PATCHES.RES" ] || [ -f "$XDG_DATA_HOME/max-port/patches.res" ]; then maxport_base_dir="/usr/share/max-port" - elif [ -f "./PATCHES.RES" ]; then + elif [ -f "./PATCHES.RES" ] || [ -f "./patches.res" ]; then maxport_base_dir="." else exit 0 @@ -128,7 +128,7 @@ else fi # Find original game data - maxport_game_data_dir="/media/max/CDROM/max" + maxport_game_data_dir="/media/user/cdrom" while true do @@ -157,7 +157,8 @@ else fi if [ -f "$maxport_prefs_dir/settings.ini" ]; then - sed -i'' "/^\[SETUP]/,/^\[/{s+^game_data[[:space:]]*=.*+game_data=$maxport_game_data_dir+}" "$maxport_prefs_dir/settings.ini" + # Preserve original DOS line endinds + sed -bi'' "/^\[SETUP]/,/^\[/{s+^game_data[[:space:]]*=.*\r+game_data=$maxport_game_data_dir\r+}" "$maxport_prefs_dir/settings.ini" fi fi @@ -166,11 +167,10 @@ cp -n "$maxport_game_data_dir/*.DTA" "$maxport_prefs_dir" 2>/dev/null || true cp -n "$maxport_game_data_dir/*.HOT" "$maxport_prefs_dir" 2>/dev/null || true cp -n "$maxport_game_data_dir/*.MLT" "$maxport_prefs_dir" 2>/dev/null || true cp -n "$maxport_game_data_dir/*.BAK" "$maxport_prefs_dir" 2>/dev/null || true - -echo $maxport_selected_language -echo $maxport_prefs_dir -echo $maxport_base_dir -echo $maxport_game_data_dir +cp -n "$maxport_game_data_dir/*.dta" "$maxport_prefs_dir" 2>/dev/null || true +cp -n "$maxport_game_data_dir/*.hot" "$maxport_prefs_dir" 2>/dev/null || true +cp -n "$maxport_game_data_dir/*.mlt" "$maxport_prefs_dir" 2>/dev/null || true +cp -n "$maxport_game_data_dir/*.bak" "$maxport_prefs_dir" 2>/dev/null || true # Play the game if [ -x "@CMAKE_INSTALL_PREFIX@/@CMAKE_INSTALL_LIBDIR@/max-port/max" ]; then diff --git a/src/color.cpp b/src/color.cpp index 02066c16..c0bb16bd 100644 --- a/src/color.cpp +++ b/src/color.cpp @@ -97,25 +97,24 @@ int32_t Color_Init(void) { result = 1; } else { - auto filepath = (ResourceManager_FilePathGameData / "COLOR.PAL").lexically_normal(); - FILE* in = fopen(filepath.string().c_str(), "rb"); + auto fp{ResourceManager_OpenFileResource("COLOR.PAL", ResourceType_GameData)}; - if (in == NULL) { + if (!fp) { result = 0; } else { uint32_t tag; - fread(Color_ColorPalette, sizeof(Color_ColorPalette), 1, in); - fread(Color_RgbIndexTable, sizeof(Color_RgbIndexTable), 1, in); + fread(Color_ColorPalette, sizeof(Color_ColorPalette), 1, fp); + fread(Color_RgbIndexTable, sizeof(Color_RgbIndexTable), 1, fp); - fread(&tag, sizeof(tag), 1, in); + fread(&tag, sizeof(tag), 1, fp); if (tag == PALETTE_FILE_TAG) { - fread(Color_IntensityColorTable, sizeof(Color_IntensityColorTable), 1, in); + fread(Color_IntensityColorTable, sizeof(Color_IntensityColorTable), 1, fp); } - fclose(in); + fclose(fp); Color_SetSystemPalette(Color_ColorPalette); diff --git a/src/enums.hpp b/src/enums.hpp index 91490cc1..f62ccbcc 100644 --- a/src/enums.hpp +++ b/src/enums.hpp @@ -24,6 +24,18 @@ #include +enum ResourceType : uint8_t { + ResourceType_GameBase, + ResourceType_GamePref, + ResourceType_GameData, + ResourceType_Voice, + ResourceType_Movie, + ResourceType_Text, + ResourceType_Flic, + ResourceType_Sfx, + ResourceType_Music, +}; + enum ResourceID : uint16_t { COMMTWR = 0x0, POWERSTN = 0x1, diff --git a/src/flicsmgr.cpp b/src/flicsmgr.cpp index 55c639f8..a7371dbb 100644 --- a/src/flicsmgr.cpp +++ b/src/flicsmgr.cpp @@ -104,7 +104,7 @@ static void flicsmgr_decode_frame(FlicFrame *frame, Flic *flc); static char Flicsmgr_load_frame(FILE *file, FlicFrame *frame); static char flicsmgr_fill_frame_buffer(Flic *flc); static char flicsmgr_read(Flic *flc); -static char flicsmgr_load(char *flic_file, Flic *flc); +static char flicsmgr_load(ResourceID id, Flic *flc); void flicsmgr_decode_delta_flc(uint8_t *buffer, Flic *flc) { int16_t opt_word; @@ -394,18 +394,8 @@ char flicsmgr_read(Flic *flc) { return result; } -char flicsmgr_load(char *flic_file, Flic *flc) { - if (!flic_file) { - return 0; - } - - ResourceManager_ToUpperCase(flic_file); - - auto filepath = ResourceManager_FilePathFlic / flic_file; - - delete[] flic_file; - - flc->fp = fopen(filepath.lexically_normal().string().c_str(), "rb"); +char flicsmgr_load(ResourceID id, Flic *flc) { + flc->fp = ResourceManager_OpenFileResource(id, ResourceType_Flic); if (!flc->fp) { return 0; @@ -440,7 +430,7 @@ Flic *flicsmgr_construct(ResourceID id, WindowInfo *w, int32_t width, int32_t ul flc->frames[i].buffer = nullptr; } - if (flicsmgr_load(reinterpret_cast(ResourceManager_ReadResource(id)), flc)) { + if (flicsmgr_load(id, flc)) { if (!flc->animate) { free(flc); flc = nullptr; diff --git a/src/game_manager.cpp b/src/game_manager.cpp index 63b9dbf4..5c168e77 100644 --- a/src/game_manager.cpp +++ b/src/game_manager.cpp @@ -3986,22 +3986,17 @@ void GameManager_MenuClickChatGoalButton() { } else if (GameManager_GameFileNumber) { int32_t game_file_type; SmartString filename; - std::filesystem::path filepath; - FILE* fp; game_file_type = ini_get_setting(INI_GAME_FILE_TYPE); - filename.Sprintf(20, "descr%i.%s", GameManager_GameFileNumber, SaveLoadMenu_SaveFileTypes[game_file_type]) - .Toupper(); - filepath = (ResourceManager_FilePathText / filename.GetCStr()).lexically_normal(); + filename.Sprintf(20, "descr%i.%s", GameManager_GameFileNumber, SaveLoadMenu_SaveFileTypes[game_file_type]); - fp = fopen(filepath.string().c_str(), "rt"); + auto fp{ResourceManager_OpenFileResource(filename.GetCStr(), ResourceType_Text)}; if (fp) { int32_t text_size; const char* mission_title; int32_t mission_title_size; - char* text; fseek(fp, 0, SEEK_END); text_size = ftell(fp); @@ -4018,20 +4013,18 @@ void GameManager_MenuClickChatGoalButton() { mission_title_size = strlen(mission_title) + 2; - text = new (std::nothrow) char[text_size + mission_title_size + 5]; + auto text = std::make_unique(text_size + mission_title_size + 5); - memset(text, '\0', text_size + mission_title_size + 5); + memset(text.get(), '\0', text_size + mission_title_size + 5); - strcpy(text, mission_title); - strcat(text, "\n\n"); + strcpy(text.get(), mission_title); + strcat(text.get(), "\n\n"); fseek(fp, 0, SEEK_SET); - fread(&text[mission_title_size], sizeof(char), text_size, fp); + fread(&text.get()[mission_title_size], sizeof(char), text_size, fp); fclose(fp); - MessageManager_DrawMessage(text, 0, 1); - - delete[] text; + MessageManager_DrawMessage(text.get(), 0, 1); } } } diff --git a/src/gamesetupmenu.cpp b/src/gamesetupmenu.cpp index bb790077..6c9f701c 100644 --- a/src/gamesetupmenu.cpp +++ b/src/gamesetupmenu.cpp @@ -332,8 +332,6 @@ void GameSetupMenu::DrawMissionList() { void GameSetupMenu::LoadMissionDescription() { SmartString string; SmartString filename; - std::filesystem::path filepath; - FILE* fp; int32_t width; int32_t height; @@ -350,19 +348,24 @@ void GameSetupMenu::LoadMissionDescription() { } } - filename.Sprintf(20, "descr%i.%s", game_file_number, SaveLoadMenu_SaveFileTypes[game_file_type]).Toupper(); - filepath = (ResourceManager_FilePathText / filename.GetCStr()).lexically_normal(); + filename.Sprintf(20, "descr%i.%s", game_file_number, SaveLoadMenu_SaveFileTypes[game_file_type]); - fp = fopen(filepath.string().c_str(), "rt"); + auto fp{ResourceManager_OpenFileResource(filename.GetCStr(), ResourceType_Text)}; if (fp) { - char character; + fseek(fp, 0, SEEK_END); + int32_t text_size = ftell(fp); - while ((character = fgetc(fp)), character != EOF) { - string += character; - } + auto text = std::make_unique(text_size + 1); + + text.get()[text_size] = '\0'; + + fseek(fp, 0, SEEK_SET); + fread(text.get(), sizeof(char), text_size, fp); fclose(fp); + + string = text.get(); } Text_SetFont(GNW_TEXT_FONT_5); diff --git a/src/menu.cpp b/src/menu.cpp index 9574ffc3..1a0d1a1e 100644 --- a/src/menu.cpp +++ b/src/menu.cpp @@ -662,29 +662,27 @@ void menu_wrap_up_game(uint16_t* teams, int32_t teams_in_play, int32_t global_tu palette = GameManager_MenuFadeOut(); if (is_winner && ini_get_setting(INI_GAME_FILE_TYPE) == GAME_TYPE_CAMPAIGN) { - FILE* fp; SmartString filename; - std::filesystem::path filepath; - filename.Sprintf(20, "win%i.cam", GameManager_GameFileNumber).Toupper(); - filepath = (ResourceManager_FilePathText / filename.GetCStr()).lexically_normal(); + filename.Sprintf(20, "win%i.cam", GameManager_GameFileNumber); - fp = fopen(filepath.string().c_str(), "rt"); + auto fp{ResourceManager_OpenFileResource(filename.GetCStr(), ResourceType_Text)}; if (fp) { - int32_t character; + fseek(fp, 0, SEEK_END); + int32_t text_size = ftell(fp); - for (;;) { - character = fgetc(fp); - if (character == EOF) { - break; - } + auto text = std::make_unique(text_size + 1); - mission_briefing += static_cast(character); - } + text.get()[text_size] = '\0'; + + fseek(fp, 0, SEEK_SET); + fread(text.get(), sizeof(char), text_size, fp); fclose(fp); + mission_briefing = text.get(); + Text_TypeWriter_CharacterTimeMs = 10; } } @@ -957,63 +955,49 @@ void ReadFile(FILE* fp, T* buffer, int32_t size) { } int32_t Menu_LoadPlanetMinimap(int32_t planet_index, uint8_t* buffer, int32_t width) { - char* filename; + auto fp{ResourceManager_OpenFileResource(static_cast(SNOW_1 + planet_index), ResourceType_GameData)}; int32_t result; - filename = reinterpret_cast(ResourceManager_ReadResource(static_cast(SNOW_1 + planet_index))); - - ResourceManager_ToUpperCase(filename); - - if (filename) { - auto filepath = ResourceManager_FilePathGameData / filename; - FILE* fp; - - fp = fopen(filepath.lexically_normal().string().c_str(), "rb"); - delete[] filename; - - if (fp) { - char map_type[5]; - Point map_dimensions; - int16_t map_tile_count; - Color palette[PALETTE_STRIDE * PALETTE_SIZE]; + if (fp) { + char map_type[5]; + Point map_dimensions; + int16_t map_tile_count; + Color palette[PALETTE_STRIDE * PALETTE_SIZE]; - ReadFile(fp, map_type); - ReadFile(fp, map_dimensions); + ReadFile(fp, map_type); + ReadFile(fp, map_dimensions); - for (int32_t i = 0; i < map_dimensions.x; ++i) { - ReadFile(fp, &buffer[width * i], map_dimensions.y); - } + for (int32_t i = 0; i < map_dimensions.x; ++i) { + ReadFile(fp, &buffer[width * i], map_dimensions.y); + } - fseek(fp, map_dimensions.x * map_dimensions.y * 2, SEEK_CUR); + fseek(fp, map_dimensions.x * map_dimensions.y * 2, SEEK_CUR); - ReadFile(fp, map_tile_count); - fseek(fp, map_tile_count * 64 * 64, SEEK_CUR); + ReadFile(fp, map_tile_count); + fseek(fp, map_tile_count * 64 * 64, SEEK_CUR); - ReadFile(fp, palette); + ReadFile(fp, palette); - for (int32_t i = 0; i < sizeof(palette); ++i) { - palette[i] /= 4; - } + for (int32_t i = 0; i < sizeof(palette); ++i) { + palette[i] /= 4; + } - WindowManager_ColorPalette = Color_GetColorPalette(); + WindowManager_ColorPalette = Color_GetColorPalette(); - for (int32_t i = 0; i < sizeof(palette); i += PALETTE_STRIDE) { - palette[i / PALETTE_STRIDE] = - Color_MapColor(WindowManager_ColorPalette, palette[i], palette[i + 1], palette[i + 2], true); - } + for (int32_t i = 0; i < sizeof(palette); i += PALETTE_STRIDE) { + palette[i / PALETTE_STRIDE] = + Color_MapColor(WindowManager_ColorPalette, palette[i], palette[i + 1], palette[i + 2], true); + } - for (int32_t i = 0; i < map_dimensions.x; ++i) { - for (int32_t j = 0; j < map_dimensions.y; ++j) { - buffer[i * width + j] = palette[buffer[i * width + j]]; - } + for (int32_t i = 0; i < map_dimensions.x; ++i) { + for (int32_t j = 0; j < map_dimensions.y; ++j) { + buffer[i * width + j] = palette[buffer[i * width + j]]; } + } - fclose(fp); - result = true; + fclose(fp); + result = true; - } else { - result = false; - } } else { result = false; } @@ -1023,35 +1007,33 @@ int32_t Menu_LoadPlanetMinimap(int32_t planet_index, uint8_t* buffer, int32_t wi void menu_draw_campaign_mission_briefing_screen() { int32_t image_index; - FILE* fp; SmartString filename; - std::filesystem::path filepath; - SmartString text; + SmartString mission_briefing; WindowInfo window; image_index = (dos_rand() * 9) >> 15; Text_TypeWriter_CharacterTimeMs = 10; - filename.Sprintf(20, "intro%i.cam", GameManager_GameFileNumber).Toupper(); + filename.Sprintf(20, "intro%i.cam", GameManager_GameFileNumber); - filepath = (ResourceManager_FilePathText / filename.GetCStr()).lexically_normal(); - - fp = fopen(filepath.string().c_str(), "rt"); + auto fp{ResourceManager_OpenFileResource(filename.GetCStr(), ResourceType_Text)}; if (fp) { - for (;;) { - int32_t character = fgetc(fp); + fseek(fp, 0, SEEK_END); + int32_t text_size = ftell(fp); - if (character == EOF) { - break; - } + auto text = std::make_unique(text_size + 1); - text += character; - } + text.get()[text_size] = '\0'; + + fseek(fp, 0, SEEK_SET); + fread(text.get(), sizeof(char), text_size, fp); fclose(fp); + mission_briefing = text.get(); + Window briefing_window(menu_briefing_backgrounds[image_index]); Button* button_end_ok; bool exit_loop; @@ -1065,7 +1047,7 @@ void menu_draw_campaign_mission_briefing_screen() { win_draw(window.id); Text_SetFont(GNW_TEXT_FONT_1); - Text_TypeWriter_TextBoxMultiLineWrapText(&window, text.GetCStr(), 20, 20, 600, 400, 0); + Text_TypeWriter_TextBoxMultiLineWrapText(&window, mission_briefing.GetCStr(), 20, 20, 600, 400, 0); Text_TypeWriter_CharacterTimeMs = 0; Text_SetFont(GNW_TEXT_FONT_5); @@ -1099,7 +1081,7 @@ void menu_draw_campaign_mission_briefing_screen() { Text_SetFont(GNW_TEXT_FONT_1); - Text_TypeWriter_TextBoxMultiLineWrapText(&window, text.GetCStr(), 20, 20, 600, 400, 0); + Text_TypeWriter_TextBoxMultiLineWrapText(&window, mission_briefing.GetCStr(), 20, 20, 600, 400, 0); win_draw(window.id); } break; } @@ -1481,15 +1463,12 @@ void menu_delete_menu_buttons() { } int32_t play_attract_demo(int32_t save_slot) { - char filename[20]; - FILE* fp; + SmartString filename; int32_t result; - sprintf(filename, "save%i.%s", save_slot, save_file_extensions[0]); - - ResourceManager_ToUpperCase(filename); + filename.Sprintf(20, "save%i.%s", save_slot, save_file_extensions[0]); - fp = fopen(filename, "rb"); + auto fp{ResourceManager_OpenFileResource(filename.GetCStr(), ResourceType_GameData)}; if (fp) { int32_t backup_opponent; diff --git a/src/movie.cpp b/src/movie.cpp index 9aa9ed24..6d58a7c4 100644 --- a/src/movie.cpp +++ b/src/movie.cpp @@ -38,7 +38,7 @@ static void movie_cb_show_frame(uint8_t* buffer, int32_t bufw, int32_t bufh, int int32_t h, int32_t dstx, int32_t dsty); static void movie_cb_set_palette(uint8_t* p, int32_t start, int32_t count); static void movie_init_palette(void); -static int32_t movie_run(ResourceID resource_id, int32_t mode); +static int32_t movie_run(ResourceID resource_id); static uint32_t movie_music_level; @@ -122,115 +122,94 @@ static void movie_init_palette(void) { Svga_SetPaletteColor(PALETTE_SIZE - 1, &color); } -int32_t movie_run(ResourceID resource_id, int32_t mode) { - FILE* fp; +int32_t movie_run(ResourceID resource_id) { int32_t result; - const char* file_name; uint8_t* palette; SoundManager_FreeMusic(); WindowManager_ClearWindow(); - file_name = reinterpret_cast(ResourceManager_ReadResource(resource_id)); - if (file_name) { - SmartString filename(file_name); - std::filesystem::path filepath; - std::error_code ec; + auto fp{ResourceManager_OpenFileResource(resource_id, ResourceType_Movie)}; - delete[] file_name; + if (fp) { + palette = Color_GetSystemPalette(); + Cursor_SetCursor(CURSOR_HIDDEN); + mouse_show(); - if (mode) { - filepath = ResourceManager_FilePathMovie; - } - - filepath.append(filename.Toupper().GetCStr()); - - fp = fopen(filepath.string().c_str(), "rb"); - - if (fp) { - palette = Color_GetSystemPalette(); - Cursor_SetCursor(CURSOR_HIDDEN); - mouse_show(); - - MVE_memCallbacks(mve_cb_alloc, mve_cb_free); - MVE_ioCallbacks(mve_cb_read); - MVE_rmCallbacks(mve_cb_ctl); - MVE_sfCallbacks(movie_cb_show_frame); + MVE_memCallbacks(mve_cb_alloc, mve_cb_free); + MVE_ioCallbacks(mve_cb_read); + MVE_rmCallbacks(mve_cb_ctl); + MVE_sfCallbacks(movie_cb_show_frame); - movie_init_palette(); - MVE_palCallbacks(movie_cb_set_palette); + movie_init_palette(); + MVE_palCallbacks(movie_cb_set_palette); - movie_music_level = (32767 * ini_get_setting(INI_MUSIC_LEVEL)) / 100; + movie_music_level = (32767 * ini_get_setting(INI_MUSIC_LEVEL)) / 100; - if (ini_get_setting(INI_DISABLE_MUSIC)) { - movie_music_level = 0; - } - - MVE_sndVolume(movie_music_level); + if (ini_get_setting(INI_DISABLE_MUSIC)) { + movie_music_level = 0; + } - if (ini_get_setting(INI_MOVIE_PLAY)) { - MVE_rmFastMode(1); - } + MVE_sndVolume(movie_music_level); - const int32_t gfx_buf_size = Svga_GetScreenWidth() * Svga_GetScreenHeight(); + if (ini_get_setting(INI_MOVIE_PLAY)) { + MVE_rmFastMode(1); + } - gfx_buf = (uint8_t*)malloc(Svga_GetScreenWidth() * Svga_GetScreenHeight()); + const int32_t gfx_buf_size = Svga_GetScreenWidth() * Svga_GetScreenHeight(); - memset(gfx_buf, 0, gfx_buf_size); + gfx_buf = (uint8_t*)malloc(Svga_GetScreenWidth() * Svga_GetScreenHeight()); - MVE_sfSVGA(Svga_GetScreenWidth(), Svga_GetScreenHeight(), Svga_GetScreenWidth(), 0, nullptr, 0, 0, nullptr, - 0); + memset(gfx_buf, 0, gfx_buf_size); - if (!MVE_rmPrepMovie(fp, -1, -1, 0)) { - int32_t aborted = 0; - int32_t frame_index = 0; + MVE_sfSVGA(Svga_GetScreenWidth(), Svga_GetScreenHeight(), Svga_GetScreenWidth(), 0, nullptr, 0, 0, nullptr, 0); - for (; (result = MVE_rmStepMovie()) == 0 && !aborted;) { - if (mve_cb_ctl()) { - aborted = 1; - result = 1; - } + if (!MVE_rmPrepMovie(fp, -1, -1, 0)) { + int32_t aborted = 0; + int32_t frame_index = 0; - ++frame_index; + for (; (result = MVE_rmStepMovie()) == 0 && !aborted;) { + if (mve_cb_ctl()) { + aborted = 1; + result = 1; } - MVE_rmEndMovie(); + ++frame_index; } - free(gfx_buf); - gfx_buf = NULL; + MVE_rmEndMovie(); + } - MVE_ReleaseMem(); + free(gfx_buf); + gfx_buf = NULL; - Color_SetColorPalette(palette); - fclose(fp); + MVE_ReleaseMem(); - result = 0; + Color_SetColorPalette(palette); + fclose(fp); - } else { - result = 1; - } + result = 0; - if (!result || result == 3) { - win_reinit(Svga_Init); - WindowManager_ClearWindow(); + } else { + result = 1; + } - result = 0; - } + if (!result || result == 3) { + win_reinit(Svga_Init); + WindowManager_ClearWindow(); - } else { result = 0; } return result; } -int32_t Movie_PlayOemLogo(void) { return movie_run(LOGOFLIC, 0); } +int32_t Movie_PlayOemLogo(void) { return movie_run(LOGOFLIC); } -int32_t Movie_PlayIntro(void) { return movie_run(INTROFLC, 1); } +int32_t Movie_PlayIntro(void) { return movie_run(INTROFLC); } int32_t Movie_Play(ResourceID resource_id) { WindowManager_ClearWindow(); - return movie_run(resource_id, 0); + return movie_run(resource_id); } diff --git a/src/resource_manager.cpp b/src/resource_manager.cpp index c66f6d8c..021a866e 100644 --- a/src/resource_manager.cpp +++ b/src/resource_manager.cpp @@ -336,7 +336,6 @@ const char *const ResourceManager_ResourceIdList[RESOURCE_E] = { std::filesystem::path ResourceManager_FilePathGameData; std::filesystem::path ResourceManager_FilePathGameBase; std::filesystem::path ResourceManager_FilePathGamePref; -std::filesystem::path ResourceManager_FilePathResource; std::filesystem::path ResourceManager_FilePathMovie; std::filesystem::path ResourceManager_FilePathText; std::filesystem::path ResourceManager_FilePathFlic; @@ -363,7 +362,7 @@ static void ResourceManager_InitInternals(); static int32_t ResourceManager_InitResManager(); static void ResourceManager_TestMouse(); static bool ResourceManager_GetGameDataPath(std::filesystem::path &path); -static int32_t ResourceManager_BuildResourceTable(const char *file_path); +static int32_t ResourceManager_BuildResourceTable(const char *const cstr, const ResourceType type); static int32_t ResourceManager_BuildColorTables(); static bool ResourceManager_LoadMapTiles(FILE *fp, DrawLoadBar *loadbar); static void ResourceManager_SetClanUpgrades(int32_t clan, ResourceID unit_type, UnitValues *unit_values); @@ -371,6 +370,50 @@ static SDL_AssertState SDLCALL ResourceManager_AssertionHandler(const SDL_Assert static void ResourceManager_LogOutputHandler(void *userdata, int category, SDL_LogPriority priority, const char *message); +static inline std::filesystem::path &ResourceManager_GetResourcePath(ResourceType type) { + auto &path{ResourceManager_FilePathGameData}; + + switch (type) { + case ResourceType_GameBase: { + path = ResourceManager_FilePathGameBase; + } break; + + case ResourceType_GamePref: { + path = ResourceManager_FilePathGamePref; + } break; + + case ResourceType_GameData: { + path = ResourceManager_FilePathGameData; + } break; + + case ResourceType_Voice: { + path = ResourceManager_FilePathVoice; + } break; + + case ResourceType_Movie: { + path = ResourceManager_FilePathMovie; + } break; + + case ResourceType_Text: { + path = ResourceManager_FilePathText; + } break; + + case ResourceType_Flic: { + path = ResourceManager_FilePathFlic; + } break; + + case ResourceType_Sfx: { + path = ResourceManager_FilePathSfx; + } break; + + case ResourceType_Music: { + path = ResourceManager_FilePathMusic; + } break; + } + + return path; +} + bool ResourceManager_GetBasePath(std::filesystem::path &path) { bool result; std::filesystem::path local_path; @@ -671,7 +714,6 @@ void ResourceManager_ExitGame(int32_t error_code) { int32_t ResourceManager_InitResManager() { int32_t result; - std::error_code ec; ResourceManager_ResMetaTable = new (std::nothrow) GameResourceMeta[RESOURCE_E]; @@ -683,18 +725,14 @@ int32_t ResourceManager_InitResManager() { ResourceManager_ResItemCount = 0; - auto filepath = ResourceManager_FilePathGameBase / "PATCHES.RES"; + result = ResourceManager_BuildResourceTable("PATCHES.RES", ResourceType_GameBase); - if (!std::filesystem::exists(filepath, ec) || ec) { - filepath = ResourceManager_FilePathGameData / "PATCHES.RES"; + if (result == EXIT_CODE_RES_FILE_NOT_FOUND) { + result = ResourceManager_BuildResourceTable("PATCHES.RES", ResourceType_GameData); } - result = ResourceManager_BuildResourceTable(filepath.string().c_str()); - if (result == EXIT_CODE_NO_ERROR || result == EXIT_CODE_RES_FILE_NOT_FOUND) { - filepath = ResourceManager_FilePathGameData / "MAX.RES"; - - result = ResourceManager_BuildResourceTable(filepath.string().c_str()); + result = ResourceManager_BuildResourceTable("MAX.RES", ResourceType_GameData); if (result == EXIT_CODE_NO_ERROR) { ResourceManager_MinimapFov = new (std::nothrow) uint8_t[GFX_MAP_SIZE * GFX_MAP_SIZE]; @@ -860,6 +898,49 @@ FILE *ResourceManager_GetFileHandle(ResourceID id) { return fp; } +FILE *ResourceManager_OpenFileResource(const char *const cstr, const ResourceType type, const char *const mode, + std::filesystem::path *path) { + auto buffer = std::make_unique(strlen(cstr) + 1); + FILE *handle{nullptr}; + + strcpy(buffer.get(), cstr); + + ResourceManager_ToLowerCase(buffer.get()); + + auto pathprefix = ResourceManager_GetResourcePath(type); + auto filepath = pathprefix / buffer.get(); + + handle = fopen(filepath.lexically_normal().string().c_str(), mode); + + if (!handle) { + ResourceManager_ToUpperCase(buffer.get()); + + filepath = pathprefix / buffer.get(); + + handle = fopen(filepath.lexically_normal().string().c_str(), mode); + } + + if (handle && path) { + *path = filepath.lexically_normal(); + } + + return handle; +} + +FILE *ResourceManager_OpenFileResource(const ResourceID id, const ResourceType type, const char *const mode, + std::filesystem::path *path) { + char *resource{reinterpret_cast(ResourceManager_ReadResource(id))}; + FILE *handle{nullptr}; + + if (resource) { + handle = ResourceManager_OpenFileResource(resource, type, mode, path); + + delete[] resource; + } + + return handle; +} + ResourceID ResourceManager_GetResourceID(int32_t index) { char buffer[9]; @@ -997,12 +1078,13 @@ int32_t ResourceManager_BuildColorTables() { return result; } -int32_t ResourceManager_BuildResourceTable(const char *file_path) { +int32_t ResourceManager_BuildResourceTable(const char *const cstr, const ResourceType type) { int32_t result; FILE *fp; struct res_header header; - fp = fopen(file_path, "rb"); + fp = ResourceManager_OpenFileResource(cstr, type); + res_file_handle_array[ResourceManager_ResFileCount] = fp; if (fp) { @@ -1066,10 +1148,22 @@ const char *ResourceManager_ToUpperCase(std::string &string) { return string.c_str(); } +const char *ResourceManager_ToLowerCase(char *cstr) { + for (char *cstring = cstr; *cstring; ++cstring) { + *cstring = tolower(*cstring); + } + + return cstr; +} + +const char *ResourceManager_ToLowerCase(std::string &string) { + for (auto &c : string) c = tolower(c); + + return string.c_str(); +} + void ResourceManager_InitInGameAssets(int32_t world) { WindowInfo *window = WindowManager_GetWindow(WINDOW_MAIN_WINDOW); - uint8_t *world_file_name; - FILE *fp; int32_t progress_bar_value; uint16_t map_layer_count = 0; Point map_layer_dimensions[12]; @@ -1114,18 +1208,7 @@ void ResourceManager_InitInGameAssets(int32_t world) { world = SNOW_1 + world; - world_file_name = ResourceManager_ReadResource(static_cast(world)); - - if (!world_file_name) { - ResourceManager_ExitGame(EXIT_CODE_RES_FILE_NOT_FOUND); - } - - ResourceManager_ToUpperCase(reinterpret_cast(world_file_name)); - - auto filepath = (ResourceManager_FilePathGameData / reinterpret_cast(world_file_name)).lexically_normal(); - - fp = fopen(filepath.string().c_str(), "rb"); - delete[] world_file_name; + auto fp{ResourceManager_OpenFileResource(static_cast(world), ResourceType_GameData)}; if (!fp) { ResourceManager_ExitGame(EXIT_CODE_WRL_FILE_OPEN_ERROR); diff --git a/src/resource_manager.hpp b/src/resource_manager.hpp index 002d2843..7cf17646 100644 --- a/src/resource_manager.hpp +++ b/src/resource_manager.hpp @@ -67,7 +67,6 @@ struct ImageMultiHeader { extern std::filesystem::path ResourceManager_FilePathGameData; extern std::filesystem::path ResourceManager_FilePathGameBase; extern std::filesystem::path ResourceManager_FilePathGamePref; -extern std::filesystem::path ResourceManager_FilePathResource; extern std::filesystem::path ResourceManager_FilePathMovie; extern std::filesystem::path ResourceManager_FilePathText; extern std::filesystem::path ResourceManager_FilePathFlic; @@ -115,9 +114,15 @@ int32_t ResourceManager_GetResourceFileID(ResourceID id); const char *ResourceManager_GetResourceID(ResourceID id); void ResourceManager_Realloc(ResourceID id, uint8_t *buffer, int32_t data_size); FILE *ResourceManager_GetFileHandle(ResourceID id); +FILE *ResourceManager_OpenFileResource(const char *const cstr, const ResourceType type, const char *const mode = "rb", + std::filesystem::path *path = nullptr); +FILE *ResourceManager_OpenFileResource(const ResourceID id, const ResourceType type, const char *const mode = "rb", + std::filesystem::path *path = nullptr); void ResourceManager_InitInGameAssets(int32_t world); const char *ResourceManager_ToUpperCase(char *cstr); const char *ResourceManager_ToUpperCase(std::string &string); +const char *ResourceManager_ToLowerCase(char *cstr); +const char *ResourceManager_ToLowerCase(std::string &string); void ResourceManager_FreeResources(); void ResourceManager_InitClanUnitValues(uint16_t team); void ResourceManager_InitHeatMaps(uint16_t team); diff --git a/src/saveloadmenu.cpp b/src/saveloadmenu.cpp index 77f2cb04..4488465d 100644 --- a/src/saveloadmenu.cpp +++ b/src/saveloadmenu.cpp @@ -252,8 +252,6 @@ void SaveLoadMenu_Init(SaveSlot *slots, int32_t num_buttons, Button *buttons[], WindowInfo *window = WindowManager_GetWindow(WINDOW_MAIN_WINDOW); uint8_t game_file_type; SmartString filename; - std::filesystem::path filepath; - FILE *fp; uint16_t version; ImageSimpleHeader *image_up; ImageSimpleHeader *image_down; @@ -279,11 +277,8 @@ void SaveLoadMenu_Init(SaveSlot *slots, int32_t num_buttons, Button *buttons[], filename.Sprintf(20, "save%i.%s", first_slot_on_page + i, SaveLoadMenu_SaveFileTypes[save_file_type]); strcpy(slots[i].file_name, filename.GetCStr()); - filename.Toupper(); - - filepath = (ResourceManager_FilePathGamePref / filename.GetCStr()).lexically_normal(); - fp = fopen(filepath.string().c_str(), "rb"); + auto fp{ResourceManager_OpenFileResource(filename.GetCStr(), ResourceType_GamePref)}; if (fp) { fread(&version, sizeof(version), 1, fp); diff --git a/src/sound_manager.cpp b/src/sound_manager.cpp index cfb3de36..594b77a2 100644 --- a/src/sound_manager.cpp +++ b/src/sound_manager.cpp @@ -597,23 +597,11 @@ void SoundManager::PlaySfx(UnitInfo* const unit, const int32_t sound, const bool if (volumes[resource_id - GEN_IDLE].flags == -1) { volumes[volume_index].flags = 1; - char* const filename = - reinterpret_cast(ResourceManager_ReadResource(static_cast(resource_id))); + auto fp{ResourceManager_OpenFileResource(static_cast(resource_id), ResourceType_Sfx)}; - if (filename) { - FILE* fp; - - ResourceManager_ToUpperCase(filename); - const auto filepath = - (std::filesystem::path(ResourceManager_FilePathSfx) / filename).lexically_normal(); - delete[] filename; - - fp = fopen(filepath.string().c_str(), "rb"); - - if (fp) { - volumes[volume_index].flags = 0; - fclose(fp); - } + if (fp) { + volumes[volume_index].flags = 0; + fclose(fp); } } @@ -1063,58 +1051,46 @@ bool SoundManager::PlayMusic(const ResourceID id) noexcept { int32_t SoundManager::LoadSound(SoundJob& job, SoundSample& sample) noexcept { int32_t result; - - char* const filename = reinterpret_cast(ResourceManager_ReadResource(job.id)); + ma_sound_group* group; + ma_uint32 flags; + ResourceType type; + std::filesystem::path filepath; MA_ZERO_OBJECT(&sample.sound); - if (filename) { - std::filesystem::path root_path; - ma_sound_group* group; - ma_uint32 flags; - - ResourceManager_ToUpperCase(filename); + if (JOB_TYPE_MUSIC == job.type) { + type = ResourceType_Music; + group = music_group->GetGroup(); + flags = MA_SOUND_FLAG_NO_SPATIALIZATION | MA_SOUND_FLAG_DECODE | MA_SOUND_FLAG_STREAM; - if (JOB_TYPE_MUSIC == job.type) { - root_path = ResourceManager_FilePathMusic; - group = music_group->GetGroup(); - flags = MA_SOUND_FLAG_NO_SPATIALIZATION | MA_SOUND_FLAG_DECODE | MA_SOUND_FLAG_STREAM; + } else if (JOB_TYPE_VOICE == job.type) { + type = ResourceType_Voice; + group = voice_group->GetGroup(); + flags = MA_SOUND_FLAG_NO_SPATIALIZATION | MA_SOUND_FLAG_DECODE; - } else if (JOB_TYPE_VOICE == job.type) { - root_path = ResourceManager_FilePathVoice; - group = voice_group->GetGroup(); - flags = MA_SOUND_FLAG_NO_SPATIALIZATION | MA_SOUND_FLAG_DECODE; - - } else { - root_path = ResourceManager_FilePathSfx; - group = sfx_group->GetGroup(); - flags = MA_SOUND_FLAG_NO_SPATIALIZATION | MA_SOUND_FLAG_DECODE; - } - - const auto filepath = (root_path / filename).lexically_normal(); - delete[] filename; - - FILE* fp = fopen(filepath.string().c_str(), "rb"); + } else { + type = ResourceType_Sfx; + group = sfx_group->GetGroup(); + flags = MA_SOUND_FLAG_NO_SPATIALIZATION | MA_SOUND_FLAG_DECODE; + } - if (fp) { - LoadLoopPoints(fp, sample); - fclose(fp); + auto fp{ResourceManager_OpenFileResource(job.id, type, "rb", &filepath)}; - if (ma_sound_init_from_file(engine, filepath.string().c_str(), flags, group, nullptr, &sample.sound) == - MA_SUCCESS) { - sample.initialized = true; - result = 0; + if (fp) { + LoadLoopPoints(fp, sample); + fclose(fp); - } else { - result = 4; - } + if (ma_sound_init_from_file(engine, filepath.string().c_str(), flags, group, nullptr, &sample.sound) == + MA_SUCCESS) { + sample.initialized = true; + result = 0; } else { result = 4; } } else { - result = 6; + result = 4; } return result;