diff --git a/redalert/conquer.cpp b/redalert/conquer.cpp index 37c578b9..d9abbcfe 100644 --- a/redalert/conquer.cpp +++ b/redalert/conquer.cpp @@ -3833,38 +3833,39 @@ typedef enum #error DVD must be defined! #endif -static void Reinit_Secondary_Mixfiles() +static void Reinit_Secondary_Mixfiles(const char *main_mix_name) { static bool in_progress = false; + if (in_progress) { + return; + } + in_progress = true; - // Only reinitialised if the main mix file has been initialised once already. - if (MainMix != nullptr && !in_progress) { - in_progress = true; - - delete MoviesMix; - delete Movies2Mix; - delete GeneralMix; - delete ScoreMix; - delete MainMix; + delete MainMix; + MainMix = new MFCD(main_mix_name, &FastKey); + assert(MainMix != NULL); - MainMix = new MFCD("MAIN.MIX", &FastKey); - assert(MainMix != NULL); - // ConquerMix = new MFCD("CONQUER.MIX", &FastKey); - if (CCFileClass("MOVIES1.MIX").Is_Available()) { - MoviesMix = new MFCD("MOVIES1.MIX", &FastKey); - } else { - MoviesMix = nullptr; - } - if (CCFileClass("MOVIES2.MIX").Is_Available()) { - Movies2Mix = new MFCD("MOVIES2.MIX", &FastKey); - } else { - Movies2Mix = nullptr; - } - GeneralMix = new MFCD("GENERAL.MIX", &FastKey); - ScoreMix = new MFCD("SCORES.MIX", &FastKey); + delete MoviesMix; + if (CCFileClass("MOVIES1.MIX").Is_Available()) { + MoviesMix = new MFCD("MOVIES1.MIX", &FastKey); + } else { + MoviesMix = nullptr; + } - in_progress = false; + delete Movies2Mix; + if (CCFileClass("MOVIES2.MIX").Is_Available()) { + Movies2Mix = new MFCD("MOVIES2.MIX", &FastKey); + } else { + Movies2Mix = nullptr; } + + delete GeneralMix; + GeneralMix = new MFCD("GENERAL.MIX", &FastKey); + + delete ScoreMix; + ScoreMix = new MFCD("SCORES.MIX", &FastKey); + + in_progress = false; } /** @@ -3872,6 +3873,8 @@ static void Reinit_Secondary_Mixfiles() */ static int LastCD = -1; +static struct { std::string Dir; std::string File; } CDPaths[CD_COUNT]; + static bool Change_Local_Dir(int cd) { static bool _initialised = false; @@ -3884,22 +3887,43 @@ static bool Change_Local_Dir(int cd) for (int i = 0; i < CD_COUNT; ++i) { for (int j = 0; j < 3; ++j) { std::string path = Paths.Concatenate_Paths(paths[j].c_str(), _vol_labels[i]); + RawFileClass vol(path.c_str()); + if (!vol.Is_Directory()) { + continue; + } - if (vol.Is_Directory()) { - CDFileClass::Refresh_Search_Drives(); - path += PathsClass::SEP; - CDFileClass::Add_Search_Drive(path.c_str()); - CCFileClass fc("MAIN.MIX"); + CDFileClass::Refresh_Search_Drives(); + path += PathsClass::SEP; + CDFileClass::Add_Search_Drive(path.c_str()); - // Populate _detected as a bitfield for which discs we found a local copy of. - if (fc.Is_Available()) { - _detected |= 1 << i; - } + CCFileClass fc("MAIN.MIX"); + if (!fc.Is_Available()) { + continue; + } - break; + _detected |= 1 << i; + CDPaths[i].Dir = path; + CDPaths[i].File = "MAIN.MIX"; + break; + } + + // Support for Steam release numbered mixes + if (CDPaths[i].File.empty()) { + char _mix_file[32]; + sprintf(_mix_file, "MAIN%d.MIX", i + 1); + + CCFileClass fc(_mix_file); + if (fc.Is_Available()) { + _detected |= 1 << i; + CDPaths[i].Dir = "."; + CDPaths[i].File = _mix_file; } } + + if (!CDPaths[i].File.empty()) { + DBG_INFO("Found '%s' disc at: %s/%s", _vol_labels[i], CDPaths[i].Dir.c_str(), CDPaths[i].File.c_str()); + } } _initialised = true; @@ -3947,32 +3971,27 @@ static bool Change_Local_Dir(int cd) cd = CD_DATADIR; } - // If the data from the CD we want was detected, then double check it and set it as though we used the -CD command line. - if (_detected & (1 << cd)) { - for (int j = 0; j < 3; ++j) { - std::string path = Paths.Concatenate_Paths(paths[j].c_str(), _vol_labels[cd]); - RawFileClass vol(path.c_str()); - - if (vol.Is_Directory()) { - CDFileClass::Refresh_Search_Drives(); - path += PathsClass::SEP; - CDFileClass::Add_Search_Drive(path.c_str()); + if (_detected & (1 << cd) == 0) { + return false; + } - // The file should be available if we reached this point. - assert(CCFileClass("MAIN.MIX").Is_Available()); + CDFileClass::Refresh_Search_Drives(); + auto path = CDPaths[cd].Dir; + if (path != ".") { + path += PathsClass::SEP; + CDFileClass::Add_Search_Drive(CDPaths[cd].Dir.c_str()); + } - CurrentCD = cd; - LastCD = cd; - Theme.Stop(); - Reinit_Secondary_Mixfiles(); - ThemeClass::Scan(); + // The file should be available if we reached this point. + assert(CCFileClass(CDPaths[cd].File.c_str()).Is_Available()); - return true; - } - } - } + CurrentCD = cd; + LastCD = cd; + Theme.Stop(); + Reinit_Secondary_Mixfiles(CDPaths[cd].File.c_str()); + ThemeClass::Scan(); - return false; + return true; } bool Force_CD_Available(int cd_desired) // ajw