Browse Source

Linux/GCC Support (#28)

* Initial Linux/GCC support commit

* Add instructins for linux in the README

* apply suggestions by @Erotemic and @Emill

* Fix python 3.10 symlink line

* Fix func_80041E80 type mismatch (#3)

Type mismatch functions.h:664

* Makefile: clean OTRExporter/libultraship/ZAPDTR with distclean and fix CXX_FILES

* Makefile: find C/CXX_FILES automatically

* Makefile: remove ugly conditions in find commands

* cleanup _MSC_VER usage

* fix Windows build

* cleanup extraction scripts

* fix Windows build

* Fix Windows path separator issue

* fix rumble support for linux

* use glew-cmake in dockerfile

* add pulseaudio backend

* fix ZAPDTR linkage

* Check for "soh.elf" in directory (#6)

hide second button if `soh.exe` or `soh.elf` is present

* Fix hardcoded segment addresses (#5)

* fix condition

* hack lus -> soh dep for ZAPDTR

Co-authored-by: sholdee <102821812+sholdee@users.noreply.github.com>
Co-authored-by: qurious-pixel <62252937+qurious-pixel@users.noreply.github.com>
Co-authored-by: GaryOderNichts <12049776+GaryOderNichts@users.noreply.github.com>
pull/282/head
Random 2 months ago committed by GitHub
parent
commit
09432ee7f4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 7
      .gitignore
  2. 35
      BUILDING.md
  3. 38
      Dockerfile
  4. 4
      OTRExporter/OTRExporter/AnimationExporter.cpp
  5. 8
      OTRExporter/OTRExporter/ArrayExporter.cpp
  6. 8
      OTRExporter/OTRExporter/CutsceneExporter.cpp
  7. 58
      OTRExporter/OTRExporter/DisplayListExporter.cpp
  8. 14
      OTRExporter/OTRExporter/Main.cpp
  9. 14
      OTRExporter/OTRExporter/Makefile
  10. 4
      OTRExporter/OTRExporter/PathExporter.cpp
  11. 34
      OTRExporter/OTRExporter/RoomExporter.cpp
  12. 4
      OTRExporter/OTRExporter/TextExporter.cpp
  13. 36
      OTRExporter/OTRExporter/VersionInfo.cpp
  14. 135
      OTRExporter/extract_assets.py
  15. 125
      OTRExporter/extract_assets_old.py
  16. 53
      OTRExporter/extract_baserom.py
  17. 1608
      OTRExporter/extract_baserom_debug.py
  18. 1586
      OTRExporter/extract_baserom_gc.py
  19. 37
      OTRExporter/rom_chooser.py
  20. 87
      OTRExporter/rom_info.py
  21. 6
      OTRGui/src/game/game.cpp
  22. 2
      README.md
  23. 2
      ZAPDTR/ExporterTest/CollisionExporter.cpp
  24. 2
      ZAPDTR/ExporterTest/CollisionExporter.h
  25. 2
      ZAPDTR/ExporterTest/RoomExporter.cpp
  26. 2
      ZAPDTR/ExporterTest/RoomExporter.h
  27. 2
      ZAPDTR/ExporterTest/TextureExporter.cpp
  28. 2
      ZAPDTR/ExporterTest/TextureExporter.h
  29. 7
      ZAPDTR/Makefile
  30. 34
      ZAPDTR/ZAPD/Main.cpp
  31. 2
      ZAPDTR/ZAPD/OutputFormatter.cpp
  32. 2
      ZAPDTR/ZAPD/OutputFormatter.h
  33. 118
      ZAPDTR/ZAPD/ZDisplayList.cpp
  34. 116
      ZAPDTR/ZAPD/ZDisplayList.h
  35. 14
      ZAPDTR/ZAPD/ZLimb.h
  36. 1
      ZAPDTR/ZAPDUtils/Utils/BitConverter.h
  37. 2
      ZAPDTR/ZAPDUtils/Utils/Directory.h
  38. 6
      ZAPDTR/ZAPDUtils/Utils/StringHelper.cpp
  39. 4
      libultraship/.gitignore
  40. 84
      libultraship/Makefile
  41. 2
      libultraship/libultraship/Animation.cpp
  42. 50
      libultraship/libultraship/Archive.cpp
  43. 2
      libultraship/libultraship/Array.cpp
  44. 2
      libultraship/libultraship/ConfigFile.h
  45. 2
      libultraship/libultraship/Cvar.cpp
  46. 71
      libultraship/libultraship/Factories/OTRResourceLoader.cpp
  47. 3
      libultraship/libultraship/GameSettings.cpp
  48. 6
      libultraship/libultraship/GlobalCtx2.cpp
  49. 10
      libultraship/libultraship/Lib/Fast3D/U64/PR/ultra64/gbi.h
  50. 1
      libultraship/libultraship/Lib/Fast3D/U64/PR/ultra64/mbi.h
  51. 6
      libultraship/libultraship/Lib/Fast3D/gfx_direct3d11.cpp
  52. 79
      libultraship/libultraship/Lib/Fast3D/gfx_glx.cpp
  53. 2
      libultraship/libultraship/Lib/Fast3D/gfx_glx.h
  54. 5
      libultraship/libultraship/Lib/Fast3D/gfx_opengl.cpp
  55. 38
      libultraship/libultraship/Lib/Fast3D/gfx_pc.cpp
  56. 6
      libultraship/libultraship/Lib/Fast3D/gfx_pc.h
  57. 12
      libultraship/libultraship/Lib/Fast3D/gfx_sdl2.cpp
  58. 12
      libultraship/libultraship/Lib/StrHash64.h
  59. 6
      libultraship/libultraship/Lib/spdlog/include/spdlog/sinks/sohconsole_sink.h
  60. 12
      libultraship/libultraship/Model.cpp
  61. 173
      libultraship/libultraship/PulseAudioPlayer.cpp
  62. 26
      libultraship/libultraship/PulseAudioPlayer.h
  63. 12
      libultraship/libultraship/Resource.cpp
  64. 10
      libultraship/libultraship/Resource.h
  65. 64
      libultraship/libultraship/ResourceMgr.cpp
  66. 4
      libultraship/libultraship/ResourceMgr.h
  67. 16
      libultraship/libultraship/SDLController.cpp
  68. 9
      libultraship/libultraship/SDLController.h
  69. 12
      libultraship/libultraship/Scene.cpp
  70. 2
      libultraship/libultraship/SkeletonLimb.cpp
  71. 14
      libultraship/libultraship/SohConsole.cpp
  72. 10
      libultraship/libultraship/SohConsole.h
  73. 2
      libultraship/libultraship/SohHooks.cpp
  74. 1
      libultraship/libultraship/SohHooks.h
  75. 46
      libultraship/libultraship/SohImGuiImpl.cpp
  76. 7
      libultraship/libultraship/Utils.cpp
  77. 4
      libultraship/libultraship/WasapiAudioPlayer.cpp
  78. 4
      libultraship/libultraship/WasapiAudioPlayer.h
  79. 14
      libultraship/libultraship/Window.cpp
  80. 4
      libultraship/libultraship/WindowShim.cpp
  81. 5
      libultraship/libultraship/mixer.c
  82. 1
      libultraship/libultraship/stox.cpp
  83. 11
      soh/.gitignore
  84. 158
      soh/Makefile
  85. 2
      soh/include/alloca.h
  86. 2
      soh/include/functions.h
  87. 4
      soh/include/global.h
  88. 10
      soh/include/macros.h
  89. 3
      soh/include/ultra64.h
  90. 1
      soh/soh.vcxproj
  91. 2
      soh/soh/Enhancements/debugconsole.cpp
  92. 1
      soh/soh/Enhancements/debugger/colViewer.cpp
  93. 2
      soh/soh/Enhancements/gameconsole.h
  94. 67
      soh/soh/OTRGlobals.cpp
  95. 6
      soh/soh/stubs.c
  96. 8
      soh/soh/z_play_otr.cpp
  97. 18
      soh/soh/z_scene_otr.cpp
  98. 6
      soh/src/code/audio_effects.c
  99. 20
      soh/src/code/audio_load.c
  100. 4
      soh/src/code/audio_seqplayer.c
  101. Some files were not shown because too many files have changed in this diff Show More

7
.gitignore vendored

@ -279,7 +279,7 @@ ClientBin/ @@ -279,7 +279,7 @@ ClientBin/
*.publishsettings
orleans.codegen.cs
# Including strong name files can present a security risk
# Including strong name files can present a security risk
# (https://github.com/github/gitignore/pull/2483#issue-259490424)
#*.snk
@ -375,7 +375,7 @@ __pycache__/ @@ -375,7 +375,7 @@ __pycache__/
# OpenCover UI analysis results
OpenCover/
# Azure Stream Analytics local run output
# Azure Stream Analytics local run output
ASALocalRun/
# MSBuild Binary and Structured Log
@ -384,7 +384,7 @@ ASALocalRun/ @@ -384,7 +384,7 @@ ASALocalRun/
# NVidia Nsight GPU debugger configuration file
*.nvuser
# MFractors (Xamarin productivity tool) working folder
# MFractors (Xamarin productivity tool) working folder
.mfractor/
*.out
@ -395,6 +395,7 @@ ExporterTest/ExporterTest.a @@ -395,6 +395,7 @@ ExporterTest/ExporterTest.a
ZAPDUtils/ZAPDUtils.a
.vscode/
build/
external/
ZAPDUtils/build/
ZAPD/BuildInfo.h

35
BUILDING.md

@ -1,5 +1,7 @@ @@ -1,5 +1,7 @@
# Building Ship of Harkinian
## Windows
1. Install [Python](https://www.python.org/ftp/python/3.10.2/python-3.10.2-amd64.exe)
2. Install [Visual Studio 2022 Community Edition](https://visualstudio.microsoft.com/vs/community/)
2b. In the Visual Studio Installer, install `MSVC v142 - VS 2019 C++`.
@ -7,7 +9,7 @@ @@ -7,7 +9,7 @@
5. Place one or more [compatible](#compatible-roms) roms in the `OTRExporter` directory with namings of your choice.
6. Run `OTRExporter/OTRExporter.sln`.
7. Switch the solution to `Release x64`.
8. Build the solution.
8. Build the solution.
9. Launching `OTRExporter/extract_assets.py` will generate an `oot.otr` archive file in `OTRExporter/oot.otr`.
10. Run `soh/soh.sln`
11. Switch the solution to `Release x86`.
@ -15,7 +17,36 @@ @@ -15,7 +17,36 @@
13. Copy the `OTRExporter/oot.otr` archive file to `soh/Release`.
14. Launch `soh.exe`.
## Compatible Roms
## Linux
```bash
# Clone the repo
git clone git@github.com:HarbourMasters/ShipWright.git
cd ShipWright
# Copy the baserom to the OTRExporter folder
cp <path to your ROM> OTRExporter
# Build the docker image
sudo docker build . -t soh
# Run the docker image with the working directory mounted to /soh
sudo docker run --rm -it -v $(pwd):/soh soh /bin/bash
```
Inside the Docker container:
```bash
# Clone and build StormLib
git clone https://github.com/ladislav-zezula/StormLib external/StormLib
cmake -B external/StormLib/build -S external/StormLib
cmake --build external/StormLib/build
cp external/StormLib/build/libstorm.a external
cp /usr/local/lib/libGLEW.a external
cd soh
# Extract the assets/Compile the exporter/Run the exporter
make setup -j$(nproc)
# Compile the code
make -j $(nproc)
```
# Compatible Roms
```
OOT_PAL_GC checksum 0x09465AC3
OOT_PAL_GC_DBG1 checksum 0x871E1C92 (debug non-master quest)

38
Dockerfile

@ -0,0 +1,38 @@ @@ -0,0 +1,38 @@
FROM ubuntu:21.04 as build
ENV LANG C.UTF-8
ARG DEBIAN_FRONTEND=noninteractive
RUN dpkg --add-architecture i386 && \
apt-get update && \
apt-get upgrade -y && \
apt-get install -y \
binutils:i386 \
gcc-10:i386 \
g++-10:i386 \
python3.10 \
python \
make \
cmake \
git \
lld \
libsdl2-dev:i386 \
zlib1g-dev:i386 \
libbz2-dev:i386 \
libpng-dev:i386 \
libgles2-mesa-dev && \
ln -sf /usr/bin/python3.10 /usr/bin/python3 && \
ln -s /usr/bin/gcc-10 /usr/bin/gcc && \
ln -s /usr/bin/gcc-10 /usr/bin/cc && \
ln -s /usr/bin/g++-10 /usr/bin/g++ && \
ln -s /usr/bin/g++-10 /usr/bin/c++
RUN git clone https://github.com/Perlmint/glew-cmake.git && \
cmake glew-cmake && \
make -j$(nproc) && \
make install ARCH64=false
RUN mkdir /soh
WORKDIR /soh

4
OTRExporter/OTRExporter/AnimationExporter.cpp

@ -49,12 +49,12 @@ void OTRExporter_Animation::Save(ZResource* res, const fs::path& outPath, Binary @@ -49,12 +49,12 @@ void OTRExporter_Animation::Save(ZResource* res, const fs::path& outPath, Binary
writer->Write((uint32_t)normalAnim->rotationValues.size());
for (int i = 0; i < normalAnim->rotationValues.size(); i++)
for (size_t i = 0; i < normalAnim->rotationValues.size(); i++)
writer->Write(normalAnim->rotationValues[i]);
writer->Write((uint32_t)normalAnim->rotationIndices.size());
for (int i = 0; i < normalAnim->rotationIndices.size(); i++)
for (size_t i = 0; i < normalAnim->rotationIndices.size(); i++)
{
writer->Write(normalAnim->rotationIndices[i].x);
writer->Write(normalAnim->rotationIndices[i].y);

8
OTRExporter/OTRExporter/ArrayExporter.cpp

@ -10,7 +10,7 @@ void OTRExporter_Array::Save(ZResource* res, const fs::path& outPath, BinaryWrit @@ -10,7 +10,7 @@ void OTRExporter_Array::Save(ZResource* res, const fs::path& outPath, BinaryWrit
writer->Write((uint32_t)arr->resList[0]->GetResourceType());
writer->Write((uint32_t)arr->arrayCnt);
for (int i = 0; i < arr->arrayCnt; i++)
for (size_t i = 0; i < arr->arrayCnt; i++)
{
if (arr->resList[i]->GetResourceType() == ZResourceType::Vertex)
{
@ -32,7 +32,7 @@ void OTRExporter_Array::Save(ZResource* res, const fs::path& outPath, BinaryWrit @@ -32,7 +32,7 @@ void OTRExporter_Array::Save(ZResource* res, const fs::path& outPath, BinaryWrit
writer->Write((uint32_t)vec->scalarType);
writer->Write((uint32_t)vec->dimensions);
for (int k = 0; k < vec->dimensions; k++)
for (size_t k = 0; k < vec->dimensions; k++)
{
// OTRTODO: Duplicate code here. Cleanup at a later date...
switch (vec->scalarType)
@ -62,6 +62,8 @@ void OTRExporter_Array::Save(ZResource* res, const fs::path& outPath, BinaryWrit @@ -62,6 +62,8 @@ void OTRExporter_Array::Save(ZResource* res, const fs::path& outPath, BinaryWrit
writer->Write(vec->scalars[k].scalarData.u64);
break;
// OTRTODO: ADD OTHER TYPES
default:
break;
}
}
}
@ -98,6 +100,8 @@ void OTRExporter_Array::Save(ZResource* res, const fs::path& outPath, BinaryWrit @@ -98,6 +100,8 @@ void OTRExporter_Array::Save(ZResource* res, const fs::path& outPath, BinaryWrit
writer->Write(scal->scalarData.u64);
break;
// OTRTODO: ADD OTHER TYPES
default:
break;
}
}
}

8
OTRExporter/OTRExporter/CutsceneExporter.cpp

@ -29,7 +29,7 @@ void OTRExporter_Cutscene::Save(ZResource* res, const fs::path& outPath, BinaryW @@ -29,7 +29,7 @@ void OTRExporter_Cutscene::Save(ZResource* res, const fs::path& outPath, BinaryW
for (auto& e : ((CutsceneCommandSetCameraPos*)cs->commands[i])->entries)
{
writer->Write(CMD_BBH(e->continueFlag, e->cameraRoll, e->nextPointFrame));
writer->Write(CMD_F(e->viewAngle));
writer->Write(e->viewAngle);
writer->Write(CMD_HH(e->posX, e->posY));
writer->Write(CMD_HH(e->posZ, e->unused));
}
@ -46,7 +46,7 @@ void OTRExporter_Cutscene::Save(ZResource* res, const fs::path& outPath, BinaryW @@ -46,7 +46,7 @@ void OTRExporter_Cutscene::Save(ZResource* res, const fs::path& outPath, BinaryW
for (auto& e : ((CutsceneCommandSetCameraPos*)cs->commands[i])->entries)
{
writer->Write(CMD_BBH(e->continueFlag, e->cameraRoll, e->nextPointFrame));
writer->Write(CMD_F(e->viewAngle));
writer->Write(e->viewAngle);
writer->Write(CMD_HH(e->posX, e->posY));
writer->Write(CMD_HH(e->posZ, e->unused));
}
@ -105,7 +105,7 @@ void OTRExporter_Cutscene::Save(ZResource* res, const fs::path& outPath, BinaryW @@ -105,7 +105,7 @@ void OTRExporter_Cutscene::Save(ZResource* res, const fs::path& outPath, BinaryW
for (auto& e : ((CutsceneCommandSetCameraPos*)cs->commands[i])->entries)
{
writer->Write(CMD_BBH(e->continueFlag, e->cameraRoll, e->nextPointFrame));
writer->Write(CMD_F(e->viewAngle));
writer->Write(e->viewAngle);
writer->Write(CMD_HH(e->posX, e->posY));
writer->Write(CMD_HH(e->posZ, e->unused));
}
@ -122,7 +122,7 @@ void OTRExporter_Cutscene::Save(ZResource* res, const fs::path& outPath, BinaryW @@ -122,7 +122,7 @@ void OTRExporter_Cutscene::Save(ZResource* res, const fs::path& outPath, BinaryW
for (auto& e : ((CutsceneCommandSetCameraPos*)cs->commands[i])->entries)
{
writer->Write(CMD_BBH(e->continueFlag, e->cameraRoll, e->nextPointFrame));
writer->Write(CMD_F(e->viewAngle));
writer->Write(e->viewAngle);
writer->Write(CMD_HH(e->posX, e->posY));
writer->Write(CMD_HH(e->posZ, e->unused));
}

58
OTRExporter/OTRExporter/DisplayListExporter.cpp

@ -29,20 +29,6 @@ @@ -29,20 +29,6 @@
Ab1, Ad1)) \
}
typedef int32_t Mtx_t[4][4];
typedef union Mtx
{
//_Alignas(8)
Mtx_t m;
int32_t l[16];
struct
{
int16_t i[16];
uint16_t f[16];
};
} Mtx;
#define gsSPBranchLessZraw2(dl, vtx, zval) \
{ _SHIFTL(G_BRANCH_Z,24,8)|_SHIFTL((vtx)*5,12,12)|_SHIFTL((vtx)*2,0,12),\
(unsigned int)(zval), }
@ -71,7 +57,7 @@ void OTRExporter_DisplayList::Save(ZResource* res, const fs::path& outPath, Bina @@ -71,7 +57,7 @@ void OTRExporter_DisplayList::Save(ZResource* res, const fs::path& outPath, Bina
// DEBUG: Write in a marker
Declaration* dbgDecl = dList->parent->GetDeclaration(dList->GetRawDataIndex());
std::string dbgName = StringHelper::Sprintf("%s\\%s", GetParentFolderName(res).c_str(), dbgDecl->varName.c_str());
std::string dbgName = StringHelper::Sprintf("%s/%s", GetParentFolderName(res).c_str(), dbgDecl->varName.c_str());
uint64_t hash = CRC64(dbgName.c_str());
writer->Write((uint32_t)(G_MARKER << 24));
writer->Write((uint32_t)0xBEEFBEEF);
@ -81,7 +67,7 @@ void OTRExporter_DisplayList::Save(ZResource* res, const fs::path& outPath, Bina @@ -81,7 +67,7 @@ void OTRExporter_DisplayList::Save(ZResource* res, const fs::path& outPath, Bina
auto dlStart = std::chrono::steady_clock::now();
//for (auto data : dList->instructions)
for (int dataIdx = 0; dataIdx < dList->instructions.size(); dataIdx++)
for (size_t dataIdx = 0; dataIdx < dList->instructions.size(); dataIdx++)
{
auto data = dList->instructions[dataIdx];
uint32_t word0 = 0;
@ -216,7 +202,7 @@ void OTRExporter_DisplayList::Save(ZResource* res, const fs::path& outPath, Bina @@ -216,7 +202,7 @@ void OTRExporter_DisplayList::Save(ZResource* res, const fs::path& outPath, Bina
pp ^= G_MTX_PUSH;
mm = (mm & 0x0FFFFFFF) + 0xF0000000;
mm = (mm & 0x0FFFFFFF) + 1;
Gfx value = gsSPMatrix(mm, pp);
word0 = value.words.w0;
@ -243,7 +229,7 @@ void OTRExporter_DisplayList::Save(ZResource* res, const fs::path& outPath, Bina @@ -243,7 +229,7 @@ void OTRExporter_DisplayList::Save(ZResource* res, const fs::path& outPath, Bina
if (mtxDecl != nullptr)
{
std::string vName = StringHelper::Sprintf("%s\\%s", (GetParentFolderName(res).c_str()), mtxDecl->varName.c_str());
std::string vName = StringHelper::Sprintf("%s/%s", (GetParentFolderName(res).c_str()), mtxDecl->varName.c_str());
uint64_t hash = CRC64(vName.c_str());
@ -347,7 +333,7 @@ void OTRExporter_DisplayList::Save(ZResource* res, const fs::path& outPath, Bina @@ -347,7 +333,7 @@ void OTRExporter_DisplayList::Save(ZResource* res, const fs::path& outPath, Bina
if (dListDecl != nullptr)
{
std::string vName = StringHelper::Sprintf("%s\\%s", (GetParentFolderName(res).c_str()), dListDecl->varName.c_str());
std::string vName = StringHelper::Sprintf("%s/%s", (GetParentFolderName(res).c_str()), dListDecl->varName.c_str());
uint64_t hash = CRC64(vName.c_str());
@ -370,7 +356,7 @@ void OTRExporter_DisplayList::Save(ZResource* res, const fs::path& outPath, Bina @@ -370,7 +356,7 @@ void OTRExporter_DisplayList::Save(ZResource* res, const fs::path& outPath, Bina
//std::string fName = StringHelper::Sprintf("%s\\%s", GetParentFolderName(res).c_str(), dListDecl2->varName.c_str());
std::string fName = OTRExporter_DisplayList::GetPathToRes(res, dListDecl2->varName.c_str());
if (files.find(fName) == files.end() && !File::Exists("Extract\\" + fName))
if (files.find(fName) == files.end() && !File::Exists("Extract/" + fName))
{
MemoryStream* dlStream = new MemoryStream();
BinaryWriter dlWriter = BinaryWriter(dlStream);
@ -383,7 +369,7 @@ void OTRExporter_DisplayList::Save(ZResource* res, const fs::path& outPath, Bina @@ -383,7 +369,7 @@ void OTRExporter_DisplayList::Save(ZResource* res, const fs::path& outPath, Bina
#endif
if (Globals::Instance->fileMode != ZFileMode::ExtractDirectory)
File::WriteAllBytes("Extract\\" + fName, dlStream->ToVector());
File::WriteAllBytes("Extract/" + fName, dlStream->ToVector());
else
files[fName] = dlStream->ToVector();
@ -411,7 +397,7 @@ void OTRExporter_DisplayList::Save(ZResource* res, const fs::path& outPath, Bina @@ -411,7 +397,7 @@ void OTRExporter_DisplayList::Save(ZResource* res, const fs::path& outPath, Bina
Gfx value;
u32 dListVal = (data & 0x0FFFFFFF) + 0xF0000000;
u32 dListVal = (data & 0x0FFFFFFF) + 1;
if (pp != 0)
value = gsSPBranchList(dListVal);
@ -444,7 +430,7 @@ void OTRExporter_DisplayList::Save(ZResource* res, const fs::path& outPath, Bina @@ -444,7 +430,7 @@ void OTRExporter_DisplayList::Save(ZResource* res, const fs::path& outPath, Bina
if (dListDecl != nullptr)
{
std::string vName = StringHelper::Sprintf("%s\\%s", (GetParentFolderName(res).c_str()), dListDecl->varName.c_str());
std::string vName = StringHelper::Sprintf("%s/%s", (GetParentFolderName(res).c_str()), dListDecl->varName.c_str());
uint64_t hash = CRC64(vName.c_str());
@ -467,7 +453,7 @@ void OTRExporter_DisplayList::Save(ZResource* res, const fs::path& outPath, Bina @@ -467,7 +453,7 @@ void OTRExporter_DisplayList::Save(ZResource* res, const fs::path& outPath, Bina
//std::string fName = StringHelper::Sprintf("%s\\%s", GetParentFolderName(res).c_str(), dListDecl2->varName.c_str());
std::string fName = OTRExporter_DisplayList::GetPathToRes(res, dListDecl2->varName.c_str());
if (files.find(fName) == files.end() && !File::Exists("Extract\\" + fName))
if (files.find(fName) == files.end() && !File::Exists("Extract/" + fName))
{
MemoryStream* dlStream = new MemoryStream();
BinaryWriter dlWriter = BinaryWriter(dlStream);
@ -475,7 +461,7 @@ void OTRExporter_DisplayList::Save(ZResource* res, const fs::path& outPath, Bina @@ -475,7 +461,7 @@ void OTRExporter_DisplayList::Save(ZResource* res, const fs::path& outPath, Bina
Save(dList->otherDLists[i], outPath, &dlWriter);
if (Globals::Instance->fileMode != ZFileMode::ExtractDirectory)
File::WriteAllBytes("Extract\\" + fName, dlStream->ToVector());
File::WriteAllBytes("Extract/" + fName, dlStream->ToVector());
else
files[fName] = dlStream->ToVector();
}
@ -533,7 +519,7 @@ void OTRExporter_DisplayList::Save(ZResource* res, const fs::path& outPath, Bina @@ -533,7 +519,7 @@ void OTRExporter_DisplayList::Save(ZResource* res, const fs::path& outPath, Bina
int32_t bb = ((data & 0x0000FF0000000000ULL) >> 40) / 2;
int32_t cc = ((data & 0x000000FF00000000ULL) >> 32) / 2;
int32_t dd = ((data & 0x000000000000FFULL)) / 2;
Gfx test = gsSP1Quadrangle(aa, bb, cc, dd, 0);
word0 = test.words.w0;
word1 = test.words.w1;
@ -689,7 +675,7 @@ void OTRExporter_DisplayList::Save(ZResource* res, const fs::path& outPath, Bina @@ -689,7 +675,7 @@ void OTRExporter_DisplayList::Save(ZResource* res, const fs::path& outPath, Bina
uint32_t fmt = (__ & 0xE0) >> 5;
uint32_t siz = (__ & 0x18) >> 3;
Gfx value = gsDPSetTextureImage(fmt, siz, www + 1, (seg & 0x0FFFFFFF) + 0xF0000000);
Gfx value = gsDPSetTextureImage(fmt, siz, www + 1, (seg & 0x0FFFFFFF) + 1);
word0 = value.words.w0;
word1 = value.words.w1;
@ -721,7 +707,7 @@ void OTRExporter_DisplayList::Save(ZResource* res, const fs::path& outPath, Bina @@ -721,7 +707,7 @@ void OTRExporter_DisplayList::Save(ZResource* res, const fs::path& outPath, Bina
ZFile* assocFile = Globals::Instance->GetSegment(GETSEGNUM(seg), res->parent->workerID);
std::string assocFileName = assocFile->GetName();
std::string fName = "";
if (GETSEGNUM(seg) == SEGMENT_SCENE || GETSEGNUM(seg) == SEGMENT_ROOM)
fName = GetPathToRes(res, texName.c_str());
else
@ -753,7 +739,7 @@ void OTRExporter_DisplayList::Save(ZResource* res, const fs::path& outPath, Bina @@ -753,7 +739,7 @@ void OTRExporter_DisplayList::Save(ZResource* res, const fs::path& outPath, Bina
Gfx value = gsSPVertex(data & 0xFFFFFFFF, nn, ((aa >> 1) - nn));
word0 = value.words.w0;
word1 = value.words.w1 | 0xF0000000;
word1 = value.words.w1 | 1;
}
else
{
@ -790,7 +776,7 @@ void OTRExporter_DisplayList::Save(ZResource* res, const fs::path& outPath, Bina @@ -790,7 +776,7 @@ void OTRExporter_DisplayList::Save(ZResource* res, const fs::path& outPath, Bina
word0 = hash >> 32;
word1 = hash & 0xFFFFFFFF;
if (files.find(fName) == files.end() && !File::Exists("Extract\\" + fName))
if (files.find(fName) == files.end() && !File::Exists("Extract/" + fName))
{
// Write vertices to file
MemoryStream* vtxStream = new MemoryStream();
@ -800,7 +786,7 @@ void OTRExporter_DisplayList::Save(ZResource* res, const fs::path& outPath, Bina @@ -800,7 +786,7 @@ void OTRExporter_DisplayList::Save(ZResource* res, const fs::path& outPath, Bina
auto split = StringHelper::Split(vtxDecl->text, "\n");
for (int i = 0; i < split.size(); i++)
for (size_t i = 0; i < split.size(); i++)
{
std::string line = split[i];
@ -842,7 +828,7 @@ void OTRExporter_DisplayList::Save(ZResource* res, const fs::path& outPath, Bina @@ -842,7 +828,7 @@ void OTRExporter_DisplayList::Save(ZResource* res, const fs::path& outPath, Bina
}
if (Globals::Instance->fileMode != ZFileMode::ExtractDirectory)
File::WriteAllBytes("Extract\\" + fName, vtxStream->ToVector());
File::WriteAllBytes("Extract/" + fName, vtxStream->ToVector());
else
files[fName] = vtxStream->ToVector();
@ -858,7 +844,7 @@ void OTRExporter_DisplayList::Save(ZResource* res, const fs::path& outPath, Bina @@ -858,7 +844,7 @@ void OTRExporter_DisplayList::Save(ZResource* res, const fs::path& outPath, Bina
}
break;
}
writer->Write(word0);
writer->Write(word1);
}
@ -872,7 +858,7 @@ void OTRExporter_DisplayList::Save(ZResource* res, const fs::path& outPath, Bina @@ -872,7 +858,7 @@ void OTRExporter_DisplayList::Save(ZResource* res, const fs::path& outPath, Bina
std::string OTRExporter_DisplayList::GetPathToRes(ZResource* res, std::string varName)
{
std::string prefix = GetPrefix(res);
std::string fName = StringHelper::Sprintf("%s\\%s", GetParentFolderName(res).c_str(), varName.c_str());
std::string fName = StringHelper::Sprintf("%s/%s", GetParentFolderName(res).c_str(), varName.c_str());
return fName;
}
@ -886,7 +872,7 @@ std::string OTRExporter_DisplayList::GetParentFolderName(ZResource* res) @@ -886,7 +872,7 @@ std::string OTRExporter_DisplayList::GetParentFolderName(ZResource* res)
{
auto split = StringHelper::Split(oName, "_");
oName = "";
for (int i = 0; i < split.size() - 1; i++)
for (size_t i = 0; i < split.size() - 1; i++)
oName += split[i] + "_";
oName += "scene";
@ -897,7 +883,7 @@ std::string OTRExporter_DisplayList::GetParentFolderName(ZResource* res) @@ -897,7 +883,7 @@ std::string OTRExporter_DisplayList::GetParentFolderName(ZResource* res)
}
if (prefix != "")
oName = prefix + "\\" + oName;
oName = prefix + "/" + oName;
return oName;
}

14
OTRExporter/OTRExporter/Main.cpp

@ -52,7 +52,7 @@ static void ExporterParseFileMode(const std::string& buildMode, ZFileMode& fileM @@ -52,7 +52,7 @@ static void ExporterParseFileMode(const std::string& buildMode, ZFileMode& fileM
for (auto item : lst)
{
auto fileData = File::ReadAllBytes(item);
otrArchive->AddFile(StringHelper::Split(item, "Extract\\")[1], (uintptr_t)fileData.data(), fileData.size());
otrArchive->AddFile(StringHelper::Split(item, "Extract/")[1], (uintptr_t)fileData.data(), fileData.size());
}
}
}
@ -76,7 +76,7 @@ static void ExporterProgramEnd() @@ -76,7 +76,7 @@ static void ExporterProgramEnd()
for (auto item : lst)
{
auto fileData = File::ReadAllBytes(item);
otrArchive->AddFile(StringHelper::Split(item, "Extract\\")[1], (uintptr_t)fileData.data(), fileData.size());
otrArchive->AddFile(StringHelper::Split(item, "Extract/")[1], (uintptr_t)fileData.data(), fileData.size());
}
otrArchive->AddFile("Audiobank", (uintptr_t)Globals::Instance->GetBaseromFile("Audiobank").data(), Globals::Instance->GetBaseromFile("Audiobank").size());
@ -117,7 +117,7 @@ static void ExporterFileBegin(ZFile* file) @@ -117,7 +117,7 @@ static void ExporterFileBegin(ZFile* file)
static void ExporterFileEnd(ZFile* file)
{
int bp = 0;
// delete fileWriter;
}
static void ExporterResourceEnd(ZResource* res, BinaryWriter& writer)
@ -140,7 +140,7 @@ static void ExporterResourceEnd(ZResource* res, BinaryWriter& writer) @@ -140,7 +140,7 @@ static void ExporterResourceEnd(ZResource* res, BinaryWriter& writer)
{
auto split = StringHelper::Split(oName, "_");
oName = "";
for (int i = 0; i < split.size() - 1; i++)
for (size_t i = 0; i < split.size() - 1; i++)
oName += split[i] + "_";
oName += "scene";
@ -153,14 +153,14 @@ static void ExporterResourceEnd(ZResource* res, BinaryWriter& writer) @@ -153,14 +153,14 @@ static void ExporterResourceEnd(ZResource* res, BinaryWriter& writer)
std::string fName = "";
if (prefix != "")
fName = StringHelper::Sprintf("%s\\%s\\%s", prefix.c_str(), oName.c_str(), rName.c_str());
fName = StringHelper::Sprintf("%s/%s/%s", prefix.c_str(), oName.c_str(), rName.c_str());
else
fName = StringHelper::Sprintf("%s\\%s", oName.c_str(), rName.c_str());
fName = StringHelper::Sprintf("%s/%s", oName.c_str(), rName.c_str());
if (Globals::Instance->fileMode == ZFileMode::ExtractDirectory)
files[fName] = strem->ToVector();
else
File::WriteAllBytes("Extract\\" + fName, strem->ToVector());
File::WriteAllBytes("Extract/" + fName, strem->ToVector());
}
auto end = std::chrono::steady_clock::now();

14
OTRExporter/OTRExporter/Makefile

@ -39,13 +39,13 @@ D_FILES := $(O_FILES:%.o=%.d) @@ -39,13 +39,13 @@ D_FILES := $(O_FILES:%.o=%.d)
LIB := OTRExporter.a
INC_DIRS := $(addprefix -I, \
../../ZAPD/ZAPD \
../../ZAPD/lib/tinyxml2 \
../../ZAPD/lib/libgfxd \
../../ZAPD/ZAPDUtils \
../../OtrLib/otrlib \
../../OtrLib/otrlib/Lib/spdlog/include \
../../OtrLib/otrlib/Lib/Fast3D/U64 \
../../ZAPDTR/ZAPD \
../../ZAPDTR/lib/tinyxml2 \
../../ZAPDTR/lib/libgfxd \
../../ZAPDTR/ZAPDUtils \
../../libultraship/libultraship \
../../libultraship/libultraship/Lib/spdlog/include \
../../libultraship/libultraship/Lib/Fast3D/U64 \
)
# create build directories

4
OTRExporter/OTRExporter/PathExporter.cpp

@ -9,11 +9,11 @@ void OTRExporter_Path::Save(ZResource* res, const fs::path& outPath, BinaryWrite @@ -9,11 +9,11 @@ void OTRExporter_Path::Save(ZResource* res, const fs::path& outPath, BinaryWrite
writer->Write((uint32_t)path->pathways.size());
for (int k = 0; k < path->pathways.size(); k++)
for (size_t k = 0; k < path->pathways.size(); k++)
{
writer->Write((uint32_t)path->pathways[k].points.size());
for (int i = 0; i < path->pathways[k].points.size(); i++)
for (size_t i = 0; i < path->pathways[k].points.size(); i++)
{
writer->Write(path->pathways[k].points[i].scalars[0].scalarData.s16);
writer->Write(path->pathways[k].points[i].scalars[1].scalarData.s16);

34
OTRExporter/OTRExporter/RoomExporter.cpp

@ -46,7 +46,7 @@ void OTRExporter_Room::Save(ZResource* res, const fs::path& outPath, BinaryWrite @@ -46,7 +46,7 @@ void OTRExporter_Room::Save(ZResource* res, const fs::path& outPath, BinaryWrite
for (size_t i = 0; i < room->commands.size(); i++)
{
ZRoomCommand* cmd = room->commands[i];
writer->Write((uint32_t)cmd->cmdID);
switch (cmd->cmdID)
@ -172,7 +172,7 @@ void OTRExporter_Room::Save(ZResource* res, const fs::path& outPath, BinaryWrite @@ -172,7 +172,7 @@ void OTRExporter_Room::Save(ZResource* res, const fs::path& outPath, BinaryWrite
writer->Write((uint32_t)cmdCsCam->points.size());
for (int i = 0; i < cmdCsCam->points.size(); i++)
for (size_t i = 0; i < cmdCsCam->points.size(); i++)
{
writer->Write(cmdCsCam->points[i].scalars[0].scalarData.s16);
writer->Write(cmdCsCam->points[i].scalars[1].scalarData.s16);
@ -183,7 +183,7 @@ void OTRExporter_Room::Save(ZResource* res, const fs::path& outPath, BinaryWrite @@ -183,7 +183,7 @@ void OTRExporter_Room::Save(ZResource* res, const fs::path& outPath, BinaryWrite
case RoomCommand::SetMesh:
{
SetMesh* cmdMesh = (SetMesh*)cmd;
writer->Write((uint8_t)cmdMesh->data); // 0x01
writer->Write(cmdMesh->meshHeaderType);
@ -207,12 +207,12 @@ void OTRExporter_Room::Save(ZResource* res, const fs::path& outPath, BinaryWrite @@ -207,12 +207,12 @@ void OTRExporter_Room::Save(ZResource* res, const fs::path& outPath, BinaryWrite
Declaration* dListDeclXlu = poly->parent->GetDeclaration(GETSEGOFFSET(test->xlu));
if (test->opa != 0)
writer->Write(StringHelper::Sprintf("%s\\%s", OTRExporter_DisplayList::GetParentFolderName(res).c_str(), dListDeclOpa->varName.c_str()));
writer->Write(StringHelper::Sprintf("%s/%s", OTRExporter_DisplayList::GetParentFolderName(res).c_str(), dListDeclOpa->varName.c_str()));
else
writer->Write("");
if (test->xlu != 0)
writer->Write(StringHelper::Sprintf("%s\\%s", OTRExporter_DisplayList::GetParentFolderName(res).c_str(), dListDeclXlu->varName.c_str()));
writer->Write(StringHelper::Sprintf("%s/%s", OTRExporter_DisplayList::GetParentFolderName(res).c_str(), dListDeclXlu->varName.c_str()));
else
writer->Write("");
@ -228,7 +228,7 @@ void OTRExporter_Room::Save(ZResource* res, const fs::path& outPath, BinaryWrite @@ -228,7 +228,7 @@ void OTRExporter_Room::Save(ZResource* res, const fs::path& outPath, BinaryWrite
Declaration* bgDecl = poly->parent->GetDeclarationRanged(GETSEGOFFSET(poly->multiList[i].source));
writer->Write(OTRExporter_DisplayList::GetPathToRes(poly->multiList[i].sourceBackground, bgDecl->varName));
writer->Write(poly->multiList[i].unk_0C);
writer->Write(poly->multiList[i].tlut);
writer->Write(poly->multiList[i].width);
@ -338,7 +338,7 @@ void OTRExporter_Room::Save(ZResource* res, const fs::path& outPath, BinaryWrite @@ -338,7 +338,7 @@ void OTRExporter_Room::Save(ZResource* res, const fs::path& outPath, BinaryWrite
for (size_t i = 0;i < cmdRoom->romfile->numRooms; i++)
{
//std::string roomName = StringHelper::Sprintf("%s\\%s_room_%i", (StringHelper::Split(room->GetName(), "_")[0] + "_scene").c_str(), StringHelper::Split(room->GetName(), "_scene")[0].c_str(), i);
//std::string roomName = StringHelper::Sprintf("%s/%s_room_%i", (StringHelper::Split(room->GetName(), "_")[0] + "_scene").c_str(), StringHelper::Split(room->GetName(), "_scene")[0].c_str(), i);
std::string roomName = OTRExporter_DisplayList::GetPathToRes(room, StringHelper::Sprintf("%s_room_%i", StringHelper::Split(room->GetName(), "_scene")[0].c_str(), i));
writer->Write(roomName);
writer->Write(cmdRoom->romfile->rooms[i].virtualAddressStart);
@ -383,7 +383,7 @@ void OTRExporter_Room::Save(ZResource* res, const fs::path& outPath, BinaryWrite @@ -383,7 +383,7 @@ void OTRExporter_Room::Save(ZResource* res, const fs::path& outPath, BinaryWrite
uint32_t baseStreamEnd = writer->GetStream().get()->GetLength();
writer->Write((uint32_t)cmdStartPos->actors.size()); // 0x01
for (const ActorSpawnEntry& entry : cmdStartPos->actors)
{
writer->Write(entry.actorNum);
@ -441,7 +441,7 @@ void OTRExporter_Room::Save(ZResource* res, const fs::path& outPath, BinaryWrite @@ -441,7 +441,7 @@ void OTRExporter_Room::Save(ZResource* res, const fs::path& outPath, BinaryWrite
case RoomCommand::SetCutscenes:
{
SetCutscenes* cmdSetCutscenes = (SetCutscenes*)cmd;
std::string listName;
Globals::Instance->GetSegmentedPtrName(cmdSetCutscenes->cmdArg2, room->parent, "CutsceneData", listName, res->parent->workerID);
std::string fName = OTRExporter_DisplayList::GetPathToRes(room, listName);
@ -452,9 +452,9 @@ void OTRExporter_Room::Save(ZResource* res, const fs::path& outPath, BinaryWrite @@ -452,9 +452,9 @@ void OTRExporter_Room::Save(ZResource* res, const fs::path& outPath, BinaryWrite
BinaryWriter csWriter = BinaryWriter(csStream);
OTRExporter_Cutscene cs;
cs.Save(cmdSetCutscenes->cutscenes[0], "", &csWriter);
if (Globals::Instance->fileMode != ZFileMode::ExtractDirectory)
File::WriteAllBytes("Extract\\" + fName, csStream->ToVector());
File::WriteAllBytes("Extract/" + fName, csStream->ToVector());
else
files[fName] = csStream->ToVector();
@ -468,7 +468,7 @@ void OTRExporter_Room::Save(ZResource* res, const fs::path& outPath, BinaryWrite @@ -468,7 +468,7 @@ void OTRExporter_Room::Save(ZResource* res, const fs::path& outPath, BinaryWrite
writer->Write((uint32_t)cmdSetPathways->pathwayList.pathways.size());
for (int i = 0; i < cmdSetPathways->pathwayList.pathways.size(); i++)
for (size_t i = 0; i < cmdSetPathways->pathwayList.pathways.size(); i++)
{
Declaration* decl = room->parent->GetDeclaration(GETSEGOFFSET(cmdSetPathways->pathwayList.pathways[i].listSegmentAddress));
//std::string path = StringHelper::Sprintf("%s\\%s", OTRExporter_DisplayList::GetParentFolderName(res).c_str(), decl->varName.c_str());
@ -481,7 +481,7 @@ void OTRExporter_Room::Save(ZResource* res, const fs::path& outPath, BinaryWrite @@ -481,7 +481,7 @@ void OTRExporter_Room::Save(ZResource* res, const fs::path& outPath, BinaryWrite
pathExp.Save(&cmdSetPathways->pathwayList, outPath, &pathWriter);
if (Globals::Instance->fileMode != ZFileMode::ExtractDirectory)
File::WriteAllBytes("Extract\\" + path, pathStream->ToVector());
File::WriteAllBytes("Extract/" + path, pathStream->ToVector());
else
files[path] = pathStream->ToVector();
@ -514,12 +514,12 @@ void OTRExporter_Room::WritePolyDList(BinaryWriter* writer, ZRoom* room, Polygon @@ -514,12 +514,12 @@ void OTRExporter_Room::WritePolyDList(BinaryWriter* writer, ZRoom* room, Polygon
writer->Write(dlist->unk_06);
[[fallthrough]];
default:
//writer->Write(StringHelper::Sprintf("%s\\%s", OTRExporter_DisplayList::GetParentFolderName(res).c_str(), dListDeclOpa->varName.c_str()));
//writer->Write(StringHelper::Sprintf("%s/%s", OTRExporter_DisplayList::GetParentFolderName(res).c_str(), dListDeclOpa->varName.c_str()));
if (dlist->opaDList != nullptr)
{
auto opaDecl = room->parent->GetDeclaration(GETSEGOFFSET(dlist->opaDList->GetRawDataIndex()));
writer->Write(StringHelper::Sprintf("%s\\%s", OTRExporter_DisplayList::GetParentFolderName(room).c_str(), opaDecl->varName.c_str()));
writer->Write(StringHelper::Sprintf("%s/%s", OTRExporter_DisplayList::GetParentFolderName(room).c_str(), opaDecl->varName.c_str()));
}
else
writer->Write("");
@ -527,7 +527,7 @@ void OTRExporter_Room::WritePolyDList(BinaryWriter* writer, ZRoom* room, Polygon @@ -527,7 +527,7 @@ void OTRExporter_Room::WritePolyDList(BinaryWriter* writer, ZRoom* room, Polygon
if (dlist->xluDList != nullptr)
{
auto xluDecl = room->parent->GetDeclaration(GETSEGOFFSET(dlist->xluDList->GetRawDataIndex()));
writer->Write(StringHelper::Sprintf("%s\\%s", OTRExporter_DisplayList::GetParentFolderName(room).c_str(), xluDecl->varName.c_str()));
writer->Write(StringHelper::Sprintf("%s/%s", OTRExporter_DisplayList::GetParentFolderName(room).c_str(), xluDecl->varName.c_str()));
}
else
writer->Write("");

4
OTRExporter/OTRExporter/TextExporter.cpp

@ -8,8 +8,8 @@ void OTRExporter_Text::Save(ZResource* res, const fs::path& outPath, BinaryWrite @@ -8,8 +8,8 @@ void OTRExporter_Text::Save(ZResource* res, const fs::path& outPath, BinaryWrite
WriteHeader(txt, outPath, writer, Ship::ResourceType::Text);
writer->Write((uint32_t)txt->messages.size());
for (int i = 0; i < txt->messages.size(); i++)
for (size_t i = 0; i < txt->messages.size(); i++)
{
writer->Write(txt->messages[i].id);
writer->Write(txt->messages[i].textboxType);

36
OTRExporter/OTRExporter/VersionInfo.cpp

@ -5,21 +5,23 @@ std::map<Ship::ResourceType, uint32_t> resourceVersions; @@ -5,21 +5,23 @@ std::map<Ship::ResourceType, uint32_t> resourceVersions;
void InitVersionInfo()
{
resourceVersions[Ship::ResourceType::Animation] = 0;
resourceVersions[Ship::ResourceType::Model] = 0;
resourceVersions[Ship::ResourceType::Texture] = 0;
resourceVersions[Ship::ResourceType::Material] = 0;
resourceVersions[Ship::ResourceType::PlayerAnimation] = 0;
resourceVersions[Ship::ResourceType::DisplayList] = 0;
resourceVersions[Ship::ResourceType::Room] = 0;
resourceVersions[Ship::ResourceType::CollisionHeader] = 0;
resourceVersions[Ship::ResourceType::Skeleton] = 0;
resourceVersions[Ship::ResourceType::SkeletonLimb] = 0;
resourceVersions[Ship::ResourceType::Matrix] = 0;
resourceVersions[Ship::ResourceType::Path] = 0;
resourceVersions[Ship::ResourceType::Vertex] = 0;
resourceVersions[Ship::ResourceType::Cutscene] = 0;
resourceVersions[Ship::ResourceType::Array] = 0;
resourceVersions[Ship::ResourceType::Text] = 0;
resourceVersions[Ship::ResourceType::Blob] = 0;
resourceVersions = {
{ Ship::ResourceType::Animation, 0 },
{ Ship::ResourceType::Model, 0 },
{ Ship::ResourceType::Texture, 0 },
{ Ship::ResourceType::Material, 0 },
{ Ship::ResourceType::PlayerAnimation, 0 },
{ Ship::ResourceType::DisplayList, 0 },
{ Ship::ResourceType::Room, 0 },
{ Ship::ResourceType::CollisionHeader, 0 },
{ Ship::ResourceType::Skeleton, 0 },
{ Ship::ResourceType::SkeletonLimb, 0 },
{ Ship::ResourceType::Matrix, 0 },
{ Ship::ResourceType::Path, 0 },
{ Ship::ResourceType::Vertex, 0 },
{ Ship::ResourceType::Cutscene, 0 },
{ Ship::ResourceType::Array, 0 },
{ Ship::ResourceType::Text, 0 },
{ Ship::ResourceType::Blob, 0 },
};
}

135
OTRExporter/extract_assets.py

@ -1,51 +1,15 @@ @@ -1,51 +1,15 @@
#!/usr/bin/env python3
# How to use:
# Place a rom in this directory then run the script.
# If you are using multiple roms, the script will let you choose one.
# To choose with a commandline argument:
# Python3 extract_assets.py <number>
# Invalid input results in the first rom being selected
import json, os, signal, time, sys, shutil, glob
from multiprocessing import Pool, cpu_count, Event, Manager, ProcessError
from enum import Enum
import os, sys, shutil
import shutil
romVer = "..\\soh\\baserom_non_mq.z64"
roms = [];
checksums = ["", "", ""];
class Checksums(Enum):
OOT_NTSC_10 = "EC7011B7"
OOT_NTSC_11 = "D43DA81F"
OOT_NTSC_12 = "693BA2AE"
OOT_PAL_10 = "B044B569"
OOT_PAL_11 = "B2055FBD"
OOT_NTSC_JP_GC_CE = "F7F52DB8"
OOT_NTSC_JP_GC = "F611F4BA"
OOT_NTSC_US_GC = "F3DD35BA"
OOT_PAL_GC = "09465AC3"
OOT_NTSC_JP_MQ = "F43B45BA"
OOT_NTSC_US_MQ = "F034001A"
OOT_PAL_MQ = "1D4136F3"
OOT_PAL_GC_DBG1 = "871E1C92"
OOT_PAL_GC_DBG2 = "87121EFE"
OOT_PAL_GC_MQ_DBG = "917D18F6"
OOT_IQUE_TW = "3D81FB3E"
OOT_IQUE_CN = "B1E1E07B"
OOT_UNKNOWN = "FFFFFFFF"
CompatibleChecksums = [
Checksums.OOT_PAL_GC,
Checksums.OOT_PAL_GC_DBG1
]
from rom_info import Z64Rom
import rom_chooser
def BuildOTR(xmlPath, rom):
shutil.copytree("assets", "Extract/assets")
execStr = "x64\\Release\\ZAPD.exe" if sys.platform == "win32" else "../ZAPD/ZAPD.out"
execStr += " ed -i %s -b %s -fl CFG\\filelists -o placeholder -osf placeholder -gsf 1 -rconf CFG/Config.xml -se OTR" % (xmlPath, rom)
execStr = "x64\\Release\\ZAPD.exe" if sys.platform == "win32" else "../ZAPDTR/ZAPD.out"
execStr += " ed -i %s -b %s -fl CFG/filelists -o placeholder -osf placeholder -gsf 1 -rconf CFG/Config.xml -se OTR" % (xmlPath, rom)
print(execStr)
exitValue = os.system(execStr)
@ -55,95 +19,14 @@ def BuildOTR(xmlPath, rom): @@ -55,95 +19,14 @@ def BuildOTR(xmlPath, rom):
print("Aborting...", file=os.sys.stderr)
print("\n")
def checkChecksum(rom):
r = open(rom, "rb")
r.seek(16)
bytes = r.read(4).hex().upper()
r.close()
for checksum in Checksums:
if (checksum.value == bytes):
for compat in CompatibleChecksums:
if (checksum.name == compat.name):
print("Compatible rom found!")
return checksum
print("Valid oot rom found. However, not compatible with SoH.")
print("Compatible roms:")
for compat in CompatibleChecksums:
print(compat.name+" | 0x"+compat.value)
sys.exit(1)
print("Wrong rom! No valid checksum found")
sys.exit(1)
def main():
romToUse = "";
for file in glob.glob("*.z64"):
roms.append(file)
if not (roms):
print("Error: No roms located, place one in the OTRExporter directory", file=os.sys.stderr)
sys.exit(1)
if (len(roms) > 1):
# If commandline args exist
if (len(sys.argv) > 1):
try:
if ((int(sys.argv[1]) - 1) < 1):
romToUse = roms[0]
elif ((int(sys.argv[1]) - 1) > len(roms)):
romToUse = roms[len(roms) - 1]
else:
romToUse = roms[int(sys.argv[1]) - 1]
except:
romToUse = roms[0]
# No commandline args, select rom using user input
else:
print(str(len(roms))+" roms found, please select one by pressing 1-"+str(len(roms)))
count = 1
for list in range(len(roms)):
print(str(count)+". "+roms[list])
count += 1
while(1):
try:
selection = int(input())
except:
print("Bad input. Try again with the number keys.")
continue
if (selection < 1 or selection > len(roms)):
print("Bad input. Try again.")
continue
else: break
romToUse = roms[selection - 1]
else:
romToUse = roms[0]
match checkChecksum(romToUse):
case Checksums.OOT_PAL_GC:
xmlVer = "GC_NMQ_PAL_F"
case Checksums.OOT_PAL_GC_DBG1:
xmlVer = "GC_NMQ_D"
case _: # default case
xmlVer = "GC_MQ_D"
rom_path = rom_chooser.chooseROM()
rom = Z64Rom(rom_path)
if (os.path.exists("Extract")):
shutil.rmtree("Extract")
BuildOTR("..\\soh\\assets\\xml\\" + xmlVer + "\\", romToUse)
BuildOTR("../soh/assets/xml/" + rom.version.xml_ver + "/", rom_path)
if __name__ == "__main__":
main()

125
OTRExporter/extract_assets_old.py

@ -1,125 +0,0 @@ @@ -1,125 +0,0 @@
#!/usr/bin/env python3
import argparse, json, os, signal, time, sys, shutil
from multiprocessing import Pool, cpu_count, Event, Manager, ProcessError
import shutil
def SignalHandler(sig, frame):
print(f'Signal {sig} received. Aborting...')
mainAbort.set()
# Don't exit immediately to update the extracted assets file.
def BuildOTR():
shutil.copyfile("baserom/Audiobank", "Extract/Audiobank")
shutil.copyfile("baserom/Audioseq", "Extract/Audioseq")
shutil.copyfile("baserom/Audiotable", "Extract/Audiotable")
shutil.copytree("assets", "Extract/assets")
execStr = "x64\\Release\\ZAPD.exe" if sys.platform == "win32" else "../ZAPD/ZAPD.out"
execStr += " botr -se OTR"
print(execStr)
exitValue = os.system(execStr)
if exitValue != 0:
print("\n")
print("Error when building the OTR file...", file=os.sys.stderr)
print("Aborting...", file=os.sys.stderr)
print("\n")
def ExtractFile(xmlPath, outputPath, outputSourcePath):
execStr = "x64\\Release\\ZAPD.exe" if sys.platform == "win32" else "../ZAPD/ZAPD.out"
execStr += " e -eh -i %s -b baserom/ -o %s -osf %s -gsf 1 -rconf CFG/Config.xml -se OTR" % (xmlPath, outputPath, outputSourcePath)
if "overlays" in xmlPath:
execStr += " --static"
print(execStr)
exitValue = os.system(execStr)
#exitValue = 0
if exitValue != 0:
print("\n")
print("Error when extracting from file " + xmlPath, file=os.sys.stderr)
print("Aborting...", file=os.sys.stderr)
print("\n")
def ExtractFunc(fullPath):
*pathList, xmlName = fullPath.split(os.sep)
objectName = os.path.splitext(xmlName)[0]
outPath = os.path.join("..\\soh\\assets\\", *pathList[5:], objectName)
os.makedirs(outPath, exist_ok=True)
outSourcePath = outPath
ExtractFile(fullPath, outPath, outSourcePath)
def initializeWorker(abort, test):
global globalAbort
globalAbort = abort
def main():
parser = argparse.ArgumentParser(description="baserom asset extractor")
parser.add_argument("-s", "--single", help="asset path relative to assets/, e.g. objects/gameplay_keep")
parser.add_argument("-f", "--force", help="Force the extraction of every xml instead of checking the touched ones.", action="store_true")
parser.add_argument("-u", "--unaccounted", help="Enables ZAPD unaccounted detector warning system.", action="store_true")
parser.add_argument("-v", "--version", help="Sets game version.")
args = parser.parse_args()
global mainAbort
mainAbort = Event()
manager = Manager()
signal.signal(signal.SIGINT, SignalHandler)
extractedAssetsTracker = manager.dict()
xmlVer = "GC_NMQ_D"
if (args.version == "gc_pal_nmpq"):
xmlVer = "GC_NMQ_PAL_F"
elif (args.version == "dbg_mq"):
xmlVer = "GC_MQ_D"
asset_path = args.single
if asset_path is not None:
fullPath = os.path.join("..\\soh\\assets", "xml", asset_path + ".xml")
if not os.path.exists(fullPath):
print(f"Error. File {fullPath} doesn't exists.", file=os.sys.stderr)
exit(1)
ExtractFunc(fullPath)
else:
extract_text_path = "assets/text/message_data.h"
if os.path.isfile(extract_text_path):
extract_text_path = None
extract_staff_text_path = "assets/text/message_data_staff.h"
if os.path.isfile(extract_staff_text_path):
extract_staff_text_path = None
xmlFiles = []
for currentPath, _, files in os.walk(os.path.join("..\\soh\\assets\\xml\\", xmlVer)):
for file in files:
fullPath = os.path.join(currentPath, file)
if file.endswith(".xml"):
xmlFiles.append(fullPath)
try:
numCores = 2
print("Extracting assets with " + str(numCores) + " CPU cores.")
with Pool(numCores, initializer=initializeWorker, initargs=(mainAbort, 0)) as p:
p.map(ExtractFunc, xmlFiles)
except Exception as e:
print("Warning: Multiprocessing exception ocurred.", file=os.sys.stderr)
print("Disabling mutliprocessing.", file=os.sys.stderr)
initializeWorker(mainAbort, 0)
for singlePath in xmlFiles:
ExtractFunc(singlePath)
BuildOTR()
shutil.rmtree("Extract")
if __name__ == "__main__":
main()

53
OTRExporter/extract_baserom.py

@ -0,0 +1,53 @@ @@ -0,0 +1,53 @@
#!/usr/bin/python3
import os
import sys
import struct
from multiprocessing import Pool, cpu_count
from rom_info import Z64Rom
import rom_chooser
rom = None
def initialize_worker(input_rom):
global rom
rom = input_rom
def ExtractFunc(i):
dma_file = rom.getDmaEntryByIndex(i)
dma_data = rom.readDmaEntry(dma_file)
filename = '../soh/baserom/' + rom.version.file_table[i]
print('extracting ' + filename + " (0x%08X, 0x%08X)" % (dma_file.virtStart, dma_file.virtEnd))
try:
with open(filename, 'wb') as f:
f.write(dma_data)
except IOError:
print('failed to write file ' + filename)
# TODO: handle this better
if dma_file.compressed:
os.system('tools/yaz0 -d ' + filename + ' ' + filename)
#####################################################################
def main():
try:
os.mkdir('../soh/baserom')
except:
pass
rom_path = rom_chooser.chooseROM()
input_rom = Z64Rom(rom_path)
# extract files
num_cores = cpu_count()
print("Extracting baserom with " + str(num_cores) + " CPU cores.")
with Pool(num_cores, initialize_worker, (input_rom,)) as p:
p.map(ExtractFunc, range(len(input_rom.version.file_table)))
if __name__ == "__main__":
main()

1608
OTRExporter/extract_baserom_debug.py

File diff suppressed because it is too large Load Diff

1586
OTRExporter/extract_baserom_gc.py

File diff suppressed because it is too large Load Diff

37
OTRExporter/rom_chooser.py

@ -0,0 +1,37 @@ @@ -0,0 +1,37 @@
import os, sys, glob
from rom_info import Z64Rom
def chooseROM():
roms = []
for file in glob.glob("*.z64"):
if Z64Rom.isValidRom(file):
roms.append(file)
if not (roms):
print("Error: No roms located, place one in the OTRExporter directory", file=os.sys.stderr)
sys.exit(1)
if (len(roms) == 1):
return roms[0]
print(str(len(roms))+ " roms found, please select one by pressing 1-"+str(len(roms)))
for i in range(len(roms)):
print(str(i+1)+ ". " + roms[i])
while(1):
try:
selection = int(input())
except: