diff --git a/Core/FileFormats/ArcturusPAK.cpp b/Core/FileFormats/ArcturusPAK.cpp new file mode 100644 index 00000000..f091c1aa --- /dev/null +++ b/Core/FileFormats/ArcturusPAK.cpp @@ -0,0 +1,93 @@ +#include +#include +#include +#include +#include + +enum class EntryType : uint8_t { + File = 0, + Directory = 1 +}; + +struct FileEntry { + EntryType Type; + int32_t Offset; + int32_t SizeCompressed; + int32_t SizeOriginal; + std::string FileName; +}; + +std::vector ReadEntries(std::istream& stream, int version) { + std::vector entries; + + stream.seekg(-9, std::ios_base::end); + if(!stream) { + return entries; + } + + uint32_t entryTableOffset; + uint16_t entryCount; + + if(version == 0) { + stream.read(reinterpret_cast(&entryTableOffset), sizeof(entryTableOffset)); + stream.read(reinterpret_cast(&entryCount), sizeof(entryCount)); + } else { + stream.read(reinterpret_cast(&entryTableOffset), sizeof(entryTableOffset)); + stream.seekg(2, std::ios_base::cur); + stream.read(reinterpret_cast(&entryCount), sizeof(entryCount)); + stream.seekg(1, std::ios_base::cur); + } + + std::cout << "entryTableOffset: " << entryTableOffset << std::endl; + std::cout << "entryCount: " << entryCount << std::endl; + + stream.seekg(entryTableOffset, std::ios_base::beg); + for(size_t i = 0; i < entryCount; i++) { + uint8_t strLen; + + stream.read(reinterpret_cast(&strLen), sizeof(strLen)); + + FileEntry entry; + entry.Type = static_cast(stream.get()); + stream.read(reinterpret_cast(&entry.Offset), sizeof(entry.Offset)); + stream.read(reinterpret_cast(&entry.SizeCompressed), sizeof(entry.SizeCompressed)); + stream.read(reinterpret_cast(&entry.SizeOriginal), sizeof(entry.SizeOriginal)); + + std::string fileName; + fileName.resize(strLen); + stream.read(&fileName[0], strLen); + stream.seekg(1, std::ios::cur); // Skip null terminator + entry.FileName = fileName; + + entries.push_back(entry); + } + + return entries; +} + +int main() { + + const std::string EXPECTED_PAK_FILE = "data.pak"; + std::ifstream file(EXPECTED_PAK_FILE, std::ios::binary); + if(!file) { + std::cerr << "Failed to open file handle for " << EXPECTED_PAK_FILE << std::endl; + std::cerr << "Reason: I/O error - make sure this file exists and is readable" << std::endl; + return 1; + } + + std::cout << "Reading PAK data from " << EXPECTED_PAK_FILE << " ..." << std::endl; + + auto entries = ReadEntries(file, 0); + for(const auto& entry : entries) { + std::cout << "Type: " << static_cast(entry.Type) << std::endl; + std::cout << "Offset: " << entry.Offset << std::endl; + std::cout << "SizeCompressed: " << entry.SizeCompressed << std::endl; + std::cout << "SizeOriginal: " << entry.SizeOriginal << std::endl; + std::cout << "FileName: " << entry.FileName << std::endl; + std::cout << std::endl; + } + + std::cout << "Read " << entries.size() << " entries " << std::endl; + + return 0; +} diff --git a/build.bat b/build.bat index 86c9913f..52c6d286 100644 --- a/build.bat +++ b/build.bat @@ -7,6 +7,8 @@ if not exist %DEFAULT_BUILD_DIR% mkdir %DEFAULT_BUILD_DIR% set CPP_MAIN=Core\RagLite2.cpp set DEBUG_EXE=%DEFAULT_BUILD_DIR%/RagLiteWin32Dbg.exe set RELEASE_EXE=%DEFAULT_BUILD_DIR%/RagLiteWin32.exe +set PAK_MAIN=Core\FileFormats\ArcturusPAK.cpp +set PAK_COMMANDLINE_EXE=%DEFAULT_BUILD_DIR%/ArcturusPAK.exe set PROGRAM_DLLS=PatternTest DummyTest set CLI_TOOLS=DependencyCheck set RUNTIME_LIBS=gdi32.lib shlwapi.lib user32.lib xinput.lib winmm.lib imagehlp.lib @@ -130,6 +132,7 @@ for %%T in (%CLI_TOOLS%) do ( call :msvcbuild !DEBUG_EXE! "%CPP_MAIN%" "%RUNTIME_LIBS%" "%DEBUG_COMPILE_FLAGS%" "%ICON_RES% %DEBUG_LINK_FLAGS%" || exit /b call :msvcbuild !RELEASE_EXE! "%CPP_MAIN%" "%RUNTIME_LIBS%" "%RELEASE_COMPILE_FLAGS%" "%ICON_RES% %RELEASE_LINK_FLAGS%" || exit /b +call :msvcbuild !PAK_COMMANDLINE_EXE! "%PAK_MAIN%" "%RUNTIME_LIBS%" "%RELEASE_COMPILE_FLAGS%" "%ICON_RES% %RELEASE_LINK_FLAGS%" || exit /b call :checkdeps !DEBUG_EXE! %DEFAULT_BUILD_DIR% || exit /b call :checkdeps !RELEASE_EXE! %DEFAULT_BUILD_DIR% || exit /b