diff --git a/src/codecs/miles/miles_impl.cpp b/src/codecs/miles/miles_impl.cpp index ed56aa71..9de48fa9 100644 --- a/src/codecs/miles/miles_impl.cpp +++ b/src/codecs/miles/miles_impl.cpp @@ -40,9 +40,10 @@ bool Miles_Initialize() // if we are loading english and the file is still not found, we can let it hit the regular engine error, since that is not recoverable if (!FileSystem()->FileExists(baseStreamFilePath.c_str())) { - Error(eDLL_T::AUDIO, NO_ERROR, "%s: attempted to load language '%s' but the required stream bank (%s) was not found. falling back to english...\n", pszLanguage, baseStreamFilePath.c_str()); + Error(eDLL_T::AUDIO, NO_ERROR, "%s: attempted to load language '%s' but the required streaming source file (%s) was not found. falling back to english...\n", __FUNCTION__, pszLanguage, baseStreamFilePath.c_str()); pszLanguage = MILES_DEFAULT_LANGUAGE; + miles_language->SetValue(pszLanguage); } } @@ -67,7 +68,27 @@ void MilesQueueEventRun(Miles::Queue* queue, const char* eventName) void MilesBankPatch(Miles::Bank* bank, char* streamPatch, char* localizedStreamPatch) { - // TODO [REXX]: add print for patch loading when Miles::Bank struct is mapped out a bit better with file name + if (miles_debug.GetBool()) + { + Msg(eDLL_T::AUDIO, + "%s: patching bank \"%s\". stream patches: \"%s\", \"%s\"\n", + __FUNCTION__, + bank->GetBankName(), + V_UnqualifiedFileName(streamPatch), V_UnqualifiedFileName(localizedStreamPatch) + ); + } + + const Miles::BankHeader_t* header = bank->GetHeader(); + + if (header->bankIndex >= header->project->bankCount) + Error(eDLL_T::AUDIO, EXIT_FAILURE, + "%s: Attempted to patch bank '%s' that identified itself as bank idx %i.\nProject expects a highest index of %i\n", + __FUNCTION__, + bank->GetBankName(), + header->bankIndex, + header->project->bankCount - 1 + ); + v_MilesBankPatch(bank, streamPatch, localizedStreamPatch); } diff --git a/src/codecs/miles/miles_types.h b/src/codecs/miles/miles_types.h index bae8703a..3ac735e1 100644 --- a/src/codecs/miles/miles_types.h +++ b/src/codecs/miles/miles_types.h @@ -4,6 +4,9 @@ constexpr char MILES_DEFAULT_LANGUAGE[] = "english"; namespace Miles { + constexpr int TEMPLATEID_FLAG_SOURCE = 0x40000000; + + struct Queue { char gap0[0x8]; @@ -11,8 +14,107 @@ namespace Miles char gap10[0x20]; }; + struct BankHeader_t; + + struct Source_t + { + BankHeader_t* bank; // reserved on disk - written at runtime + char gap8[80]; + }; + + struct Event_t + { + int nameOffset; + int unkOffset; // offset into BankHeader_t::unk_68 data - some sort of event metadata? + }; + + // internal project data structure + struct IntProjectData_t + { + char gap0[0xCF0]; + int bankCount; + BankHeader_t** loadedBanks; + }; + + struct BankHeader_t + { + int magic; // 'CBNK' + int version; // 32 + uint32_t dataSize; + + int bankMagic; // 'BANK' + const char* bankName; + + void* unk_18; + IntProjectData_t* project; + + void* unk_28; + void* unk_30; + void* unk_38; + void* unk_40; // used to index into both sources and localised sources + + Source_t* sources; + Source_t* localizedSources; + + void* unk_58; + Event_t* events; + + void* unk_68; + const char* stringTable; + + void* unk_78; + void* unk_80; + void* unk_88; + + uint8_t bankIndex; + // 3 byte padding + + uint32_t localizedSourceCount; + uint32_t sourceCount; + + uint32_t patchCount; + uint32_t eventCount; + + uint32_t count_A4; + uint32_t count_A8; + uint32_t count_AC; + + uint32_t buildTag; + + uint32_t unk_B4; + uint32_t someDataSize; + + const char* GetBankName() const + { + return bankName; + } + + }; + static_assert(offsetof(BankHeader_t, project) == 0x20); + static_assert(offsetof(BankHeader_t, stringTable) == 0x70); + static_assert(offsetof(BankHeader_t, unk_B4) == 0xB4); + + struct Bank { - // TODO [REXX]: map out this struct and its internal counterpart + void* internalData; + void* unk_8; + + char* fileData; + + int unk_18; + char gap_1c[4]; + + const Miles::BankHeader_t* GetHeader() const + { + return reinterpret_cast(fileData); + } + + const char* GetBankName() const + { + return GetHeader()->GetBankName(); + } }; + + static_assert(sizeof(Bank) == 0x20); } \ No newline at end of file