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>
This commit is contained in:
Random 2022-05-12 02:18:24 +09:00 committed by GitHub
parent 2e1a0b5144
commit 09432ee7f4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
116 changed files with 1403 additions and 4054 deletions

7
.gitignore vendored
View File

@ -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__/
# 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/
# 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
ZAPDUtils/ZAPDUtils.a
.vscode/
build/
external/
ZAPDUtils/build/
ZAPD/BuildInfo.h

View File

@ -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 @@
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 @@
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 Normal file
View File

@ -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

View File

@ -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);

View File

@ -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
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
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
writer->Write(scal->scalarData.u64);
break;
// OTRTODO: ADD OTHER TYPES
default:
break;
}
}
}

View File

@ -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
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
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
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));
}

View File

@ -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
// 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
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
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
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
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
//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
#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
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
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
//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
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
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
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
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
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
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
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
}
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
}
break;
}
writer->Write(word0);
writer->Write(word1);
}
@ -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)
{
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)
}
if (prefix != "")
oName = prefix + "\\" + oName;
oName = prefix + "/" + oName;
return oName;
}

View File

@ -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()
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)
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)
{
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)
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();

View File

@ -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

View File

@ -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);

View File

@ -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
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
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
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
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
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
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
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
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
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
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
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
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("");

View File

@ -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);

View File

@ -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 },
};
}

View File

@ -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):
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()

View File

@ -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()

View File

@ -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()

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -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:
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
return roms[selection - 1]

87
OTRExporter/rom_info.py Normal file
View File

@ -0,0 +1,87 @@
from enum import Enum
from tabnanny import check
import struct
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"
@classmethod
def has_value(self, value):
return value in self._value2member_map_
class RomVersion:
def __init__(self, file_table_path, file_table_off, xml_ver):
self.file_table_off = file_table_off
self.xml_ver = xml_ver
with open(file_table_path, 'r') as f:
self.file_table = [line.strip('\n') for line in f]
ROM_INFO_TABLE = dict()
ROM_INFO_TABLE[Checksums.OOT_PAL_GC] = RomVersion("CFG/filelists/gamecube_pal.txt", 0x7170, "GC_NMQ_PAL_F")
ROM_INFO_TABLE[Checksums.OOT_PAL_GC_DBG1] = RomVersion("CFG/filelists/dbg.txt", 0x12F70, "GC_NMQ_D")
class RomDmaEntry:
def __init__(self, rom, i):
off = rom.version.file_table_off + 16 * i
(self.virtStart, \
self.virtEnd, \
self.physStart, \
self.physEnd) = struct.unpack('>IIII', rom.rom_data[off:off+4*4])
self.compressed = self.physEnd != 0
self.size = self.physEnd - self.physStart \
if self.compressed \
else self.virtEnd - self.virtStart
self.name = rom.version.file_table[i]
class Z64Rom:
def __init__(self, file_path):
self.file_path = file_path
with open(file_path, 'rb') as f:
self.rom_data = f.read()
self.is_valid = len(self.rom_data) > 20 * 1024 * 1024
if not self.is_valid:
return
# get checkum
checksum_str = self.rom_data[16:16+4].hex().upper()
self.checksum = Checksums(checksum_str) if Checksums.has_value(checksum_str) else Checksums.OOT_UNKNOWN
if self.checksum == Checksums.OOT_UNKNOWN:
self.is_valid = False
return
# get rom version
self.version = ROM_INFO_TABLE[self.checksum]
def getDmaEntryByIndex(self, i):
return RomDmaEntry(self, i)
def readDmaEntry(self, entry):
return self.rom_data[entry.physStart:entry.physStart + entry.size]
@staticmethod
def isValidRom(rom_path):
return Z64Rom(rom_path).is_valid

View File

@ -67,13 +67,13 @@ void OTRGame::init(){
mat.shader = shader;
}
if(fs::exists("soh.exe") && !fs::exists("oot.otr")) {
if((fs::exists("soh.exe") || fs::exists("soh.elf")) && !fs::exists("oot.otr")) {
hide_second_btn = true;
sohFolder = ".";
}
}
void ExtractRom()
void ExtractRom()
{
WriteResult result;
@ -220,4 +220,4 @@ void setCurrentStep(const std::string& step) {
void OTRGame::exit(){
}
}

View File

@ -44,7 +44,7 @@ If you still cannot get the tool to work, join our [Discord Server](https://disc
### Running The Ship of Harkinian
Launch the game. If the window immediately closes, or if there are visual artifacts, you may have selected the wrong rom in the OTRGui tool.
Launch the game. If the window immediately closes, or if there are visual artifacts, you may have selected the wrong rom in the OTRGui tool.
Currently, DirectX 11 and OpenGL is supported. Change the renderer by opening the `shipofharkinian.ini` configuration file in notepad and add `sdl` to `gfx backend` for OpenGL or leave blank for DirectX.

View File

@ -1,6 +1,6 @@
#include "CollisionExporter.h"
void ExporterExample_Collision::Save(ZResource* res, [[maybe_unused]] fs::path outPath,
void ExporterExample_Collision::Save(ZResource* res, [[maybe_unused]] const fs::path& outPath,
BinaryWriter* writer)
{
ZCollisionHeader* col = (ZCollisionHeader*)res;

View File

@ -6,5 +6,5 @@
class ExporterExample_Collision : public ZResourceExporter
{
public:
void Save(ZResource* res, fs::path outPath, BinaryWriter* writer) override;
void Save(ZResource* res, const fs::path& outPath, BinaryWriter* writer) override;
};

View File

@ -20,7 +20,7 @@
#include "ZRoom/Commands/SetTimeSettings.h"
#include "ZRoom/Commands/SetWind.h"
void ExporterExample_Room::Save(ZResource* res, fs::path outPath, BinaryWriter* writer)
void ExporterExample_Room::Save(ZResource* res, const fs::path& outPath, BinaryWriter* writer)
{
ZRoom* room = dynamic_cast<ZRoom*>(res);

View File

@ -6,5 +6,5 @@
class ExporterExample_Room : public ZResourceExporter
{
public:
void Save(ZResource* res, fs::path outPath, BinaryWriter* writer) override;
void Save(ZResource* res, const fs::path& outPath, BinaryWriter* writer) override;
};

View File

@ -1,7 +1,7 @@
#include "TextureExporter.h"
#include "../ZAPD/ZFile.h"
void ExporterExample_Texture::Save(ZResource* res, [[maybe_unused]] fs::path outPath,
void ExporterExample_Texture::Save(ZResource* res, [[maybe_unused]] const fs::path& outPath,
BinaryWriter* writer)
{
ZTexture* tex = (ZTexture*)res;

View File

@ -7,5 +7,5 @@
class ExporterExample_Texture : public ZResourceExporter
{
public:
void Save(ZResource* res, fs::path outPath, BinaryWriter* writer) override;
void Save(ZResource* res, const fs::path& outPath, BinaryWriter* writer) override;
};

View File

@ -44,7 +44,8 @@ ifneq ($(DEPRECATION_ON),0)
endif
# CXXFLAGS += -DTEXTURE_DEBUG
LDFLAGS := -lm -ldl -lpng
LDFLAGS := -lm -ldl -lpng \
-L../external -L../libultraship -lz -lbz2 -pthread -lpulse -lultraship -lstorm -lSDL2 -lGLEW -lGL -lX11
# Use LLD if available. Set LLD=0 to not use it
ifeq ($(shell command -v ld.lld >/dev/null 2>&1; echo $$?),0)
@ -59,9 +60,9 @@ UNAME := $(shell uname)
UNAMEM := $(shell uname -m)
ifneq ($(UNAME), Darwin)
LDFLAGS += -Wl,-export-dynamic -lstdc++fs
EXPORTERS := -Wl,--whole-archive ExporterTest/ExporterTest.a -Wl,--no-whole-archive
EXPORTERS := -Wl,--whole-archive ../OTRExporter/OTRExporter/OTRExporter.a -Wl,--no-whole-archive
else
EXPORTERS := -Wl,-force_load ExporterTest/ExporterTest.a
EXPORTERS := -Wl,-force_load ../OTRExporter/OTRExporter/OTRExporter.a
ifeq ($(UNAMEM),arm64)
ifeq ($(shell brew list libpng > /dev/null 2>&1; echo $$?),0)
LDFLAGS += -L $(shell brew --prefix)/lib

View File

@ -10,7 +10,7 @@
#include "ZFile.h"
#include "ZTexture.h"
#if !defined(_MSC_VER) && !defined(__CYGWIN__)
#ifdef __linux__
#include <csignal>
#include <cstdlib>
#include <ctime>
@ -28,6 +28,31 @@
//extern const char gBuildHash[];
const char gBuildHash[] = "";
// LINUX_TODO: remove, those are because of soh <-> lus dependency problems
float divisor_num = 0.0f;
extern "C" void Audio_SetGameVolume(int player_id, float volume)
{
}
extern "C" int ResourceMgr_OTRSigCheck(char* imgData)
{
}
void DebugConsole_SaveCVars()
{
}
void DebugConsole_LoadCVars()
{
}
bool Parse(const fs::path& xmlFilePath, const fs::path& basePath, const fs::path& outPath,
ZFileMode fileMode, int workerID);
@ -38,7 +63,7 @@ int ExtractFunc(int workerID, int fileListSize, std::string fileListItem, ZFileM
volatile int numWorkersLeft = 0;
#if !defined(_MSC_VER) && !defined(__CYGWIN__)
#ifdef __linux__
#define ARRAY_COUNT(arr) (sizeof(arr) / sizeof(arr[0]))
void ErrorHandler(int sig)
{
@ -196,7 +221,7 @@ int main(int argc, char* argv[])
}
else if (arg == "-eh") // Enable Error Handler
{
#if !defined(_MSC_VER) && !defined(__CYGWIN__)
#ifdef __linux__
signal(SIGSEGV, ErrorHandler);
signal(SIGABRT, ErrorHandler);
#else
@ -302,7 +327,7 @@ int main(int argc, char* argv[])
ctpl::thread_pool pool(num_threads / 2);
bool parseSuccessful;
auto start = std::chrono::steady_clock::now();
int fileListSize = fileList.size();
Globals::Instance->singleThreaded = false;
@ -453,6 +478,7 @@ int ExtractFunc(int workerID, int fileListSize, std::string fileListItem, ZFileM
numWorkersLeft--;
}
return 0;
}
bool Parse(const fs::path& xmlFilePath, const fs::path& basePath, const fs::path& outPath,

View File

@ -96,7 +96,7 @@ int OutputFormatter::Write(const std::string& buf)
return Write(buf.data(), buf.size());
}
__declspec(thread) OutputFormatter* OutputFormatter::Instance;
thread_local OutputFormatter* OutputFormatter::Instance;
int OutputFormatter::WriteStatic(const char* buf, int count)
{

View File

@ -25,7 +25,7 @@ private:
void Flush();
static __declspec(thread) OutputFormatter* Instance;
static thread_local OutputFormatter* Instance;
static int WriteStatic(const char* buf, int count);
public:

View File

@ -15,6 +15,124 @@
#include "WarningHandler.h"
#include "gfxd.h"
#define G_MDSFT_ALPHACOMPARE 0
#define G_MDSFT_ZSRCSEL 2
#define G_MDSFT_RENDERMODE 3
#define G_MDSFT_BLENDER 16
#define G_RM_FOG_SHADE_A 0xC8000000
#define G_RM_FOG_PRIM_A 0xC4000000
#define G_RM_PASS 0x0C080000
#define G_RM_AA_ZB_OPA_SURF 0x442078
#define G_RM_AA_ZB_OPA_SURF2 0x112078
#define G_RM_AA_ZB_XLU_SURF 0x4049D8
#define G_RM_AA_ZB_XLU_SURF2 0x1049D8
#define G_RM_AA_ZB_OPA_DECAL 0x442D58
#define G_RM_AA_ZB_OPA_DECAL2 0x112D58
#define G_RM_AA_ZB_XLU_DECAL 0x404DD8
#define G_RM_AA_ZB_XLU_DECAL2 0x104DD8
#define G_RM_AA_ZB_OPA_INTER 0x442478
#define G_RM_AA_ZB_OPA_INTER2 0x112478
#define G_RM_AA_ZB_XLU_INTER 0x4045D8
#define G_RM_AA_ZB_XLU_INTER2 0x1045D8
#define G_RM_AA_ZB_XLU_LINE 0x407858
#define G_RM_AA_ZB_XLU_LINE2 0x107858
#define G_RM_AA_ZB_DEC_LINE 0x407F58
#define G_RM_AA_ZB_DEC_LINE2 0x107F58
#define G_RM_AA_ZB_TEX_EDGE 0x443078
#define G_RM_AA_ZB_TEX_EDGE2 0x113078
#define G_RM_AA_ZB_TEX_INTER 0x443478
#define G_RM_AA_ZB_TEX_INTER2 0x113478
#define G_RM_AA_ZB_SUB_SURF 0x442878
#define G_RM_AA_ZB_SUB_SURF2 0x112278
#define G_RM_AA_ZB_PCL_SURF 0x40007B
#define G_RM_AA_ZB_PCL_SURF2 0x10007B
#define G_RM_AA_ZB_OPA_TERR 0x402078
#define G_RM_AA_ZB_OPA_TERR2 0x102078
#define G_RM_AA_ZB_TEX_TERR 0x403078
#define G_RM_AA_ZB_TEX_TERR2 0x103078
#define G_RM_AA_ZB_SUB_TERR 0x402278
#define G_RM_AA_ZB_SUB_TERR2 0x102278
#define G_RM_RA_ZB_OPA_SURF 0x442038
#define G_RM_RA_ZB_OPA_SURF2 0x112038
#define G_RM_RA_ZB_OPA_DECAL 0x442D18
#define G_RM_RA_ZB_OPA_DECAL2 0x112D18
#define G_RM_RA_ZB_OPA_INTER 0x442438
#define G_RM_RA_ZB_OPA_INTER2 0x112438
#define G_RM_AA_OPA_SURF 0x442048
#define G_RM_AA_OPA_SURF2 0x112048
#define G_RM_AA_XLU_SURF 0x4041C8
#define G_RM_AA_XLU_SURF2 0x1041C8
#define G_RM_AA_XLU_LINE 0x407048
#define G_RM_AA_XLU_LINE2 0x107048
#define G_RM_AA_DEC_LINE 0x407248
#define G_RM_AA_DEC_LINE2 0x107248
#define G_RM_AA_TEX_EDGE 0x443048
#define G_RM_AA_TEX_EDGE2 0x113048
#define G_RM_AA_SUB_SURF 0x442248
#define G_RM_AA_SUB_SURF2 0x112248
#define G_RM_AA_PCL_SURF 0x40004B
#define G_RM_AA_PCL_SURF2 0x10004B
#define G_RM_AA_OPA_TERR 0x402048
#define G_RM_AA_OPA_TERR2 0x102048
#define G_RM_AA_TEX_TERR 0x403048
#define G_RM_AA_TEX_TERR2 0x103048
#define G_RM_AA_SUB_TERR 0x402248
#define G_RM_AA_SUB_TERR2 0x102248
#define G_RM_RA_OPA_SURF 0x442008
#define G_RM_RA_OPA_SURF2 0x112008
#define G_RM_ZB_OPA_SURF 0x442230
#define G_RM_ZB_OPA_SURF2 0x112230
#define G_RM_ZB_XLU_SURF 0x404A50
#define G_RM_ZB_XLU_SURF2 0x104A50
#define G_RM_ZB_OPA_DECAL 0x442E10
#define G_RM_ZB_OPA_DECAL2 0x112E10
#define G_RM_ZB_XLU_DECAL 0x404E50
#define G_RM_ZB_XLU_DECAL2 0x104E50
#define G_RM_ZB_CLD_SURF 0x404B50
#define G_RM_ZB_CLD_SURF2 0x104B50
#define G_RM_ZB_OVL_SURF 0x404F50
#define G_RM_ZB_OVL_SURF2 0x104F50
#define G_RM_ZB_PCL_SURF 0x0C080233
#define G_RM_ZB_PCL_SURF2 0x03020233
#define G_RM_OPA_SURF 0x0C084000
#define G_RM_OPA_SURF2 0x03024000
#define G_RM_XLU_SURF 0x00404200
#define G_RM_XLU_SURF2 0x00104240
#define G_RM_CLD_SURF 0x00404340
#define G_RM_CLD_SURF2 0x00104340
#define G_RM_TEX_EDGE 0x0C087008
#define G_RM_TEX_EDGE2 0x03027008
#define G_RM_PCL_SURF 0x0C084203
#define G_RM_PCL_SURF2 0x03024203
#define G_RM_ADD 0x04484340
#define G_RM_ADD2 0x01124340
#define G_RM_NOOP 0x00000000
#define G_RM_NOOP2 0x00000000
#define G_RM_VISCVG 0x0C844040
#define G_RM_VISCVG2 0x03214040
#define G_RM_OPA_CI 0x0C080000
#define G_RM_OPA_CI2 0x03020000
#define AA_EN 0x8
#define Z_CMP 0x10
#define Z_UPD 0x20
#define IM_RD 0x40
#define CLR_ON_CVG 0x80
#define CVG_DST_CLAMP 0
#define CVG_DST_WRAP 0x100
#define CVG_DST_FULL 0x200
#define CVG_DST_SAVE 0x300
#define ZMODE_OPA 0
#define ZMODE_INTER 0x400
#define ZMODE_XLU 0x800
#define ZMODE_DEC 0xc00
#define CVG_X_ALPHA 0x1000
#define ALPHA_CVG_SEL 0x2000
#define FORCE_BL 0x4000
#define TEX_EDGE 0x0000
REGISTER_ZFILENODE(DList, ZDisplayList);
ZDisplayList::ZDisplayList(ZFile* nParent) : ZResource(nParent)

View File

@ -166,122 +166,6 @@ enum class OoTSegments
FrameBuffer = 16,
};
#define G_MDSFT_ALPHACOMPARE 0
#define G_MDSFT_ZSRCSEL 2
#define G_MDSFT_RENDERMODE 3
#define G_MDSFT_BLENDER 16
#define G_RM_FOG_SHADE_A 0xC8000000
#define G_RM_FOG_PRIM_A 0xC4000000
#define G_RM_PASS 0x0C080000
#define G_RM_AA_ZB_OPA_SURF 0x442078
#define G_RM_AA_ZB_OPA_SURF2 0x112078
#define G_RM_AA_ZB_XLU_SURF 0x4049D8
#define G_RM_AA_ZB_XLU_SURF2 0x1049D8
#define G_RM_AA_ZB_OPA_DECAL 0x442D58
#define G_RM_AA_ZB_OPA_DECAL2 0x112D58
#define G_RM_AA_ZB_XLU_DECAL 0x404DD8
#define G_RM_AA_ZB_XLU_DECAL2 0x104DD8
#define G_RM_AA_ZB_OPA_INTER 0x442478
#define G_RM_AA_ZB_OPA_INTER2 0x112478
#define G_RM_AA_ZB_XLU_INTER 0x4045D8
#define G_RM_AA_ZB_XLU_INTER2 0x1045D8
#define G_RM_AA_ZB_XLU_LINE 0x407858
#define G_RM_AA_ZB_XLU_LINE2 0x107858
#define G_RM_AA_ZB_DEC_LINE 0x407F58
#define G_RM_AA_ZB_DEC_LINE2 0x107F58
#define G_RM_AA_ZB_TEX_EDGE 0x443078
#define G_RM_AA_ZB_TEX_EDGE2 0x113078
#define G_RM_AA_ZB_TEX_INTER 0x443478
#define G_RM_AA_ZB_TEX_INTER2 0x113478
#define G_RM_AA_ZB_SUB_SURF 0x442878
#define G_RM_AA_ZB_SUB_SURF2 0x112278
#define G_RM_AA_ZB_PCL_SURF 0x40007B
#define G_RM_AA_ZB_PCL_SURF2 0x10007B
#define G_RM_AA_ZB_OPA_TERR 0x402078
#define G_RM_AA_ZB_OPA_TERR2 0x102078
#define G_RM_AA_ZB_TEX_TERR 0x403078
#define G_RM_AA_ZB_TEX_TERR2 0x103078
#define G_RM_AA_ZB_SUB_TERR 0x402278
#define G_RM_AA_ZB_SUB_TERR2 0x102278
#define G_RM_RA_ZB_OPA_SURF 0x442038
#define G_RM_RA_ZB_OPA_SURF2 0x112038
#define G_RM_RA_ZB_OPA_DECAL 0x442D18
#define G_RM_RA_ZB_OPA_DECAL2 0x112D18
#define G_RM_RA_ZB_OPA_INTER 0x442438
#define G_RM_RA_ZB_OPA_INTER2 0x112438
#define G_RM_AA_OPA_SURF 0x442048
#define G_RM_AA_OPA_SURF2 0x112048
#define G_RM_AA_XLU_SURF 0x4041C8
#define G_RM_AA_XLU_SURF2 0x1041C8
#define G_RM_AA_XLU_LINE 0x407048
#define G_RM_AA_XLU_LINE2 0x107048
#define G_RM_AA_DEC_LINE 0x407248
#define G_RM_AA_DEC_LINE2 0x107248
#define G_RM_AA_TEX_EDGE 0x443048
#define G_RM_AA_TEX_EDGE2 0x113048
#define G_RM_AA_SUB_SURF 0x442248
#define G_RM_AA_SUB_SURF2 0x112248
#define G_RM_AA_PCL_SURF 0x40004B
#define G_RM_AA_PCL_SURF2 0x10004B
#define G_RM_AA_OPA_TERR 0x402048
#define G_RM_AA_OPA_TERR2 0x102048
#define G_RM_AA_TEX_TERR 0x403048
#define G_RM_AA_TEX_TERR2 0x103048
#define G_RM_AA_SUB_TERR 0x402248
#define G_RM_AA_SUB_TERR2 0x102248
#define G_RM_RA_OPA_SURF 0x442008
#define G_RM_RA_OPA_SURF2 0x112008
#define G_RM_ZB_OPA_SURF 0x442230
#define G_RM_ZB_OPA_SURF2 0x112230
#define G_RM_ZB_XLU_SURF 0x404A50
#define G_RM_ZB_XLU_SURF2 0x104A50
#define G_RM_ZB_OPA_DECAL 0x442E10
#define G_RM_ZB_OPA_DECAL2 0x112E10
#define G_RM_ZB_XLU_DECAL 0x404E50
#define G_RM_ZB_XLU_DECAL2 0x104E50
#define G_RM_ZB_CLD_SURF 0x404B50
#define G_RM_ZB_CLD_SURF2 0x104B50
#define G_RM_ZB_OVL_SURF 0x404F50
#define G_RM_ZB_OVL_SURF2 0x104F50
#define G_RM_ZB_PCL_SURF 0x0C080233
#define G_RM_ZB_PCL_SURF2 0x03020233
#define G_RM_OPA_SURF 0x0C084000
#define G_RM_OPA_SURF2 0x03024000
#define G_RM_XLU_SURF 0x00404200
#define G_RM_XLU_SURF2 0x00104240
#define G_RM_CLD_SURF 0x00404340
#define G_RM_CLD_SURF2 0x00104340
#define G_RM_TEX_EDGE 0x0C087008
#define G_RM_TEX_EDGE2 0x03027008
#define G_RM_PCL_SURF 0x0C084203
#define G_RM_PCL_SURF2 0x03024203
#define G_RM_ADD 0x04484340
#define G_RM_ADD2 0x01124340
#define G_RM_NOOP 0x00000000
#define G_RM_NOOP2 0x00000000
#define G_RM_VISCVG 0x0C844040
#define G_RM_VISCVG2 0x03214040
#define G_RM_OPA_CI 0x0C080000
#define G_RM_OPA_CI2 0x03020000
#define AA_EN 0x8
#define Z_CMP 0x10
#define Z_UPD 0x20
#define IM_RD 0x40
#define CLR_ON_CVG 0x80
#define CVG_DST_CLAMP 0
#define CVG_DST_WRAP 0x100
#define CVG_DST_FULL 0x200
#define CVG_DST_SAVE 0x300
#define ZMODE_OPA 0
#define ZMODE_INTER 0x400
#define ZMODE_XLU 0x800
#define ZMODE_DEC 0xc00
#define CVG_X_ALPHA 0x1000
#define ALPHA_CVG_SEL 0x2000
#define FORCE_BL 0x4000
#define TEX_EDGE 0x0000
class ZDisplayList : public ZResource
{

View File

@ -25,19 +25,19 @@ public:
ZLimbSkinType skinSegmentType = ZLimbSkinType::SkinType_0; // Skin only
segptr_t skinSegment = 0; // Skin only
Struct_800A5E28 segmentStruct; // Skin only
Struct_800A5E28 segmentStruct = {0}; // Skin only
// Legacy only
float legTransX, legTransY, legTransZ; // Vec3f
uint16_t rotX, rotY, rotZ; // Vec3s
segptr_t childPtr; // LegacyLimb*
segptr_t siblingPtr; // LegacyLimb*
float legTransX = 0, legTransY = 0, legTransZ = 0; // Vec3f
uint16_t rotX = 0, rotY = 0, rotZ = 0; // Vec3s
segptr_t childPtr = 0; // LegacyLimb*
segptr_t siblingPtr = 0; // LegacyLimb*
segptr_t dListPtr = 0;
segptr_t dList2Ptr = 0; // LOD and Curve Only
int16_t transX, transY, transZ;
uint8_t childIndex, siblingIndex;
int16_t transX = 0, transY = 0, transZ = 0;
uint8_t childIndex = 0, siblingIndex = 0;
ZLimb(ZFile* nParent);

View File

@ -3,6 +3,7 @@
#include <cstdint>
#include <limits>
#include <vector>
#include <cstring>
class BitConverter
{

View File

@ -52,7 +52,7 @@ public:
for (auto& p : fs::recursive_directory_iterator(dir))
{
if (!p.is_directory())
lst.push_back(p.path().string());
lst.push_back(p.path().generic_string());
}
}

View File

@ -3,6 +3,10 @@
#pragma optimize("2", on)
#define _CRT_SECURE_NO_WARNINGS
#ifndef _MSC_VER
#define vsprintf_s vsprintf
#endif
std::vector<std::string> StringHelper::Split(std::string s, const std::string& delimiter)
{
std::vector<std::string> result;
@ -44,7 +48,7 @@ std::string StringHelper::Replace(std::string str, const std::string& from,
while (start_pos != std::string::npos)
{
str.replace(start_pos, from.length(), to);
str.replace(start_pos, from.length(), to);
start_pos = str.find(from);
}

View File

@ -353,4 +353,6 @@ MigrationBackup/
.ionide/
!libultraship/Lib/**
libultraship/DebugObj/*
libultraship/DebugObj/*
build/
libultraship.a

View File

@ -1,15 +1,78 @@
# Only used for standalone compilation, usually inherits these from the main makefile
CXXFLAGS ?= -Wall -Wextra -O2 -g -std=c++17
CXX := g++
CC := gcc
AR := ar
FORMAT := clang-format-11
ASAN ?= 0
DEBUG ?= 1
OPTFLAGS ?= -O0
LTO ?= 0
WARN := -Wall -Wextra -Werror \
-Wno-unused-variable \
-Wno-unused-parameter \
-Wno-unused-function \
-Wno-parentheses \
-Wno-narrowing \
-Wno-missing-field-initializers
CXXFLAGS := $(WARN) -std=c++20 -D_GNU_SOURCE -DENABLE_OPENGL -DSPDLOG_ACTIVE_LEVEL=0 -m32
CFLAGS := $(WARN) -std=c99 -D_GNU_SOURCE -DENABLE_OPENGL -DSPDLOG_ACTIVE_LEVEL=0 -m32
CPPFLAGS := -MMD
ifneq ($(DEBUG),0)
CXXFLAGS += -g -D_DEBUG
CFLAGS += -g -D_DEBUG
endif
ifneq ($(ASAN),0)
CXXFLAGS += -fsanitize=address
CFLAGS += -fsanitize=address
endif
ifneq ($(LTO),0)
CXXFLAGS += -flto
CFLAGS += -flto
endif
SRC_DIRS := $(shell find -type d -not -path "*build*")
CPP_FILES := $(foreach dir,$(SRC_DIRS),$(wildcard $(dir)/*.cpp))
H_FILES := $(foreach dir,$(SRC_DIRS),$(wildcard $(dir)/*.h))
O_FILES := $(foreach f,$(CPP_FILES:.cpp=.o),build/$f)
LIB := otrlib.a
CXX_FILES := \
$(shell find libultraship/Factories -name *.cpp) \
$(shell find libultraship/Lib/Fast3D -name *.cpp) \
$(shell find libultraship -maxdepth 1 -name *.cpp) \
$(shell find libultraship/Lib/ImGui -maxdepth 1 -name *.cpp) \
libultraship/Lib/ImGui/backends/imgui_impl_opengl3.cpp \
libultraship/Lib/ImGui/backends/imgui_impl_sdl.cpp \
libultraship/Lib/StrHash64.cpp \
libultraship/Lib/tinyxml2/tinyxml2.cpp
C_FILES := \
libultraship/mixer.c \
libultraship/Lib/stb/stb_impl.c
FMT_FILES := $(shell find libultraship/ -type f \( -name *.cpp -o -name *.h \) -a -not -path "libultraship/Lib/*")
O_FILES := \
$(CXX_FILES:%.cpp=build/%.o) \
$(C_FILES:%.c=build/%.o)
D_FILES := $(O_FILES:%.o=%.d)
LIB := libultraship.a
INC_DIRS := $(addprefix -I, \
../ZAPDTR/ZAPDUtils \
libultraship/Lib/Fast3D/U64 \
libultraship/Lib/spdlog \
libultraship/Lib/spdlog/include \
libultraship \
)
# create build directories
$(shell mkdir -p $(foreach dir,$(SRC_DIRS),build/$(dir)))
$(shell mkdir -p $(SRC_DIRS:%=build/%))
all: $(LIB)
@ -17,12 +80,17 @@ clean:
rm -rf build $(LIB)
format:
clang-format-11 -i $(CPP_FILES) $(H_FILES)
$(FORMAT) -i $(FMT_FILES)
.PHONY: all clean format
build/%.o: %.cpp
$(CXX) $(CXXFLAGS) $(OPTFLAGS) -I ./ -I ../ZAPD/ZAPD -I ../ZAPD/ZAPDUtils -I ../../ZAPD/lib/tinyxml2 -I otrlib/Lib/spdlog/include -c $(OUTPUT_OPTION) $<
$(CXX) $(CXXFLAGS) $(CPPFLAGS) $(OPTFLAGS) $(INC_DIRS) -c $< -o $@
build/%.o: %.c
$(CC) $(CFLAGS) $(CPPFLAGS) $(OPTFLAGS) $(INC_DIRS) -c $< -o $@
$(LIB): $(O_FILES)
$(AR) rcs $@ $^
-include $(D_FILES)

View File

@ -21,7 +21,7 @@ void Ship::AnimationV0::ParseFileBinary(BinaryReader* reader, Resource* res)
uint32_t rotIndCnt = reader->ReadUInt32();
anim->rotationIndices.reserve(rotIndCnt);
for (int i = 0; i < rotIndCnt; i++)
for (size_t i = 0; i < rotIndCnt; i++)
{
uint16_t x = reader->ReadUInt16();
uint16_t y = reader->ReadUInt16();

View File

@ -7,7 +7,7 @@
#include <filesystem>
namespace Ship {
Archive::Archive(const std::string& MainPath, bool enableWriting) : Archive(MainPath, "", enableWriting)
Archive::Archive(const std::string& MainPath, bool enableWriting) : Archive(MainPath, "", enableWriting)
{
mainMPQ = nullptr;
}
@ -28,7 +28,7 @@ namespace Ship {
std::shared_ptr<Archive> Archive::CreateArchive(const std::string& archivePath, int fileCapacity)
{
Archive* archive = new Archive(archivePath, true);
auto archive = std::make_shared<Archive>(archivePath, true);
TCHAR* t_filename = new TCHAR[archivePath.size() + 1];
t_filename[archivePath.size()] = 0;
@ -37,10 +37,15 @@ namespace Ship {
bool success = SFileCreateArchive(t_filename, MPQ_CREATE_LISTFILE | MPQ_CREATE_ATTRIBUTES | MPQ_CREATE_ARCHIVE_V2, fileCapacity, &archive->mainMPQ);
int error = GetLastError();
if (success) {
delete[] t_filename;
if (success)
{
archive->mpqHandles[archivePath] = archive->mainMPQ;
return std::make_shared<Archive>(*archive);
} else {
return archive;
}
else
{
SPDLOG_ERROR("({}) We tried to create an archive, but it has fallen and cannot get up.");
return nullptr;
}
@ -139,13 +144,16 @@ namespace Ship {
bool Archive::AddFile(const std::string& path, uintptr_t fileData, DWORD dwFileSize) {
HANDLE hFile;
#ifdef _WIN32
SYSTEMTIME sysTime;
GetSystemTime(&sysTime);
FILETIME t;
SystemTimeToFileTime(&sysTime, &t);
ULONGLONG stupidHack = static_cast<uint64_t>(t.dwHighDateTime) << (sizeof(t.dwHighDateTime) * 8) | t.dwLowDateTime;
#else
time_t stupidHack;
time(&stupidHack);
#endif
if (!SFileCreateFile(mainMPQ, path.c_str(), stupidHack, dwFileSize, 0, MPQ_FILE_COMPRESS, &hFile)) {
SPDLOG_ERROR("({}) Failed to create file of {} bytes {} in archive {}", GetLastError(), dwFileSize, path.c_str(), MainPath.c_str());
return false;
@ -181,7 +189,7 @@ namespace Ship {
SPDLOG_ERROR("({}) Failed to remove file {} in archive {}", GetLastError(), path.c_str(), MainPath.c_str());
return false;
}
return true;
}
@ -201,7 +209,7 @@ namespace Ship {
SFILE_FIND_DATA findContext;
HANDLE hFind;
hFind = SFileFindFirstFile(mainMPQ, searchMask.c_str(), &findContext, nullptr);
//if (hFind && GetLastError() != ERROR_NO_MORE_FILES) {
if (hFind != nullptr) {
@ -245,7 +253,7 @@ namespace Ship {
auto start = std::chrono::steady_clock::now();
auto lst = ListFiles(filename);
for (const auto& item : lst) {
if (item.cFileName == filename) {
result = true;
@ -267,7 +275,7 @@ namespace Ship {
return LoadMainMPQ(enableWriting, genCRCMap) && LoadPatchMPQs();
}
bool Archive::Unload()
bool Archive::Unload()
{
bool success = true;
for (const auto& mpqHandle : mpqHandles) {
@ -302,11 +310,16 @@ namespace Ship {
bool Archive::LoadMainMPQ(bool enableWriting, bool genCRCMap) {
HANDLE mpqHandle = NULL;
#ifdef _WIN32
std::wstring wfullPath = std::filesystem::absolute(MainPath).wstring();
#endif
std::string fullPath = std::filesystem::absolute(MainPath).string();
std::wstring wFileName = std::filesystem::absolute(MainPath).wstring();
if (!SFileOpenArchive(wFileName.c_str(), 0, enableWriting ? 0 : MPQ_OPEN_READ_ONLY, &mpqHandle)) {
#ifdef _WIN32
if (!SFileOpenArchive(wfullPath.c_str(), 0, enableWriting ? 0 : MPQ_OPEN_READ_ONLY, &mpqHandle)) {
#else
if (!SFileOpenArchive(fullPath.c_str(), 0, enableWriting ? 0 : MPQ_OPEN_READ_ONLY, &mpqHandle)) {
#endif
SPDLOG_ERROR("({}) Failed to open main mpq file {}.", GetLastError(), fullPath.c_str());
return false;
}
@ -340,12 +353,19 @@ namespace Ship {
std::wstring wPath = std::filesystem::absolute(path).wstring();
#ifdef _WIN32
if (!SFileOpenArchive(wPath.c_str(), 0, MPQ_OPEN_READ_ONLY, &patchHandle)) {
#else
if (!SFileOpenArchive(fullPath.c_str(), 0, MPQ_OPEN_READ_ONLY, &patchHandle)) {
#endif
SPDLOG_ERROR("({}) Failed to open patch mpq file {} while applying to {}.", GetLastError(), path.c_str(), MainPath.c_str());
return false;
}
#ifdef _WIN32
if (!SFileOpenPatchArchive(mainMPQ, wPath.c_str(), "", 0)) {
#else
if (!SFileOpenPatchArchive(mainMPQ, fullPath.c_str(), "", 0)) {
#endif
SPDLOG_ERROR("({}) Failed to apply patch mpq file {} to main mpq {}.", GetLastError(), path.c_str(), MainPath.c_str());
return false;
}

View File

@ -51,6 +51,8 @@ namespace Ship
data.u16 = reader->ReadUInt16();
break;
// OTRTODO: IMPLEMENT OTHER TYPES!
default:
break;
}
arr->scalars.push_back(data);

View File

@ -29,9 +29,9 @@ namespace Ship {
bool CreateDefaultConfig();
private:
mINI::INIFile File;
mINI::INIStructure Val;
std::weak_ptr<GlobalCtx2> Context;
std::string Path;
mINI::INIFile File;
};
}

View File

@ -1,4 +1,4 @@
#include "cvar.h"
#include "Cvar.h"
#include <map>
#include <string>
#include <PR/ultra64/gbi.h>

View File

@ -1,71 +0,0 @@
#include "OTRResourceLoader.h"
#include "OTRMaterialFactory.h"
#include "OTRSceneFactory.h"
#include "OTRCollisionHeaderFactory.h"
#include "OTRDisplayListFactory.h"
#include "OTRPlayerAnimationFactory.h"
#include "OTRSkeletonFactory.h"
#include "OTRSkeletonLimbFactory.h"
#include "OTRAnimationFactory.h"
#include "OTRVtxFactory.h"
#include "OTRCutsceneFactory.h"
#include "OTRArrayFactory.h"
#include "OTRPathFactory.h"
namespace OtrLib
{
OTRResource* OTRResourceLoader::LoadResource(BinaryReader* reader)
{
Endianess endianess = (Endianess)reader->ReadByte();
// TODO: Setup the binaryreader to use the resource's endianess
ResourceType resourceType = (ResourceType)reader->ReadUInt32();
OTRResource* result = nullptr;
switch (resourceType)
{
case ResourceType::OTRMaterial:
result = OTRMaterialFactory::ReadMaterial(reader);
break;
case ResourceType::OTRRoom:
result = OTRSceneFactory::ReadScene(reader);
break;
case ResourceType::OTRCollisionHeader:
result = OTRCollisionHeaderFactory::ReadCollisionHeader(reader);
break;
case ResourceType::OTRDisplayList:
result = OTRDisplayListFactory::ReadDisplayList(reader);
break;
case ResourceType::OTRPlayerAnimation:
result = OTRPlayerAnimationFactory::ReadPlayerAnimation(reader);
break;
case ResourceType::OTRSkeleton:
result = OTRSkeletonFactory::ReadSkeleton(reader);
break;
case ResourceType::OTRSkeletonLimb:
result = OTRSkeletonLimbFactory::ReadSkeletonLimb(reader);
break;
case ResourceType::OTRVtx:
result = OTRVtxFactory::ReadVtx(reader);
break;
case ResourceType::OTRAnimation:
result = OTRAnimationFactory::ReadAnimation(reader);
break;
case ResourceType::OTRCutscene:
result = OTRCutsceneFactory::ReadCutscene(reader);
break;
case ResourceType::OTRArray:
result = OTRArrayFactory::ReadArray(reader);
break;
case ResourceType::OTRPath:
result = OTRPathFactory::ReadPath(reader);
break;
default:
// RESOURCE TYPE NOT SUPPORTED
break;
}
return result;
}
}

View File

@ -1,10 +1,11 @@
#include "GameSettings.h"
// Audio
#include <cstddef>
#include <PR/ultra64/types.h>
#include <PR/ultra64/sptask.h>
#include <PR/ultra64/pi.h>
#include <PR/ultra64/message.h>
#include <PR/ultra64/types.h>
#include "ConfigFile.h"
#include "Cvar.h"

View File

@ -30,7 +30,7 @@ namespace Ship {
}
GlobalCtx2::GlobalCtx2(const std::string& Name) : Name(Name), MainPath(""), PatchesPath("") {
}
GlobalCtx2::~GlobalCtx2() {
@ -54,7 +54,11 @@ namespace Ship {
if (!ResMan->DidLoadSuccessfully())
{
#ifdef _WIN32
MessageBox(NULL, L"Main OTR file not found!", L"Uh oh", MB_OK);
#else
SPDLOG_ERROR("Main OTR file not found!");
#endif
exit(1);
}
INSTANCE = new ModManager(ResMan);

View File

@ -1004,7 +1004,7 @@
#define G_DL_PUSH 0x00
#define G_DL_NOPUSH 0x01
#if _MSC_VER
#if defined(_MSC_VER) || defined(__GNUC__)
#define _LANGUAGE_C
#endif
@ -3132,7 +3132,7 @@ _DW({ \
#endif
*/
#ifdef _MSC_VER
#if defined(_MSC_VER)
#define CALL_2(A,B) A B
#define CALL_3(A,B,C) A B C
@ -3143,12 +3143,12 @@ _DW({ \
#define gsDPSetCombineMode(a, b) gsDPSetCombineLERP(a, b)
#endif
#if _MSC_VER
#if defined(_MSC_VER) || defined(__GNUC__)
#define CALL_2(A,B) A B
#define CALL_3(A,B,C) A B C
#define gsDPSetCombineMode(a, b) CALL_2(gsDPSetCombineLERP, (a, b))
//#define gsDPSetCombineMode(a, b) _SHIFTL(0, 24, 8), 0
// #define gsDPSetCombineMode(a, b) CALL_2(gsDPSetCombineLERP, (a, b))
// #define gsDPSetCombineMode(a, b) _SHIFTL(0, 24, 8), 0
#else
#define gsDPSetCombineMode(a, b) gsDPSetCombineLERP(a, b)
#endif

View File

@ -33,6 +33,7 @@
#define G_OFF (0)
#include <stdint.h>
#include "types.h"
#include "gbi.h"
#include "abi.h"

View File

@ -158,7 +158,7 @@ static LARGE_INTEGER last_time, accumulated_time, frequency;
int gfx_d3d11_create_framebuffer(void);
void create_depth_stencil_objects(uint32_t width, uint32_t height, uint32_t msaa_count, ID3D11DepthStencilView **view, ID3D11ShaderResourceView **srv) {
static void create_depth_stencil_objects(uint32_t width, uint32_t height, uint32_t msaa_count, ID3D11DepthStencilView **view, ID3D11ShaderResourceView **srv) {
D3D11_TEXTURE2D_DESC texture_desc;
texture_desc.Width = width;
texture_desc.Height = height;
@ -992,8 +992,8 @@ std::map<std::pair<float, float>, uint16_t> gfx_d3d11_get_pixel_depth(int fb_id,
} // namespace
ImTextureID SohImGui::GetTextureByID(int id) {
return impl.backend == Backend::DX11 ? d3d.textures[id].resource_view.Get() : reinterpret_cast<ImTextureID>(id);
ImTextureID gfx_d3d11_get_texture_by_id(int id) {
return d3d.textures[id].resource_view.Get();
}
struct GfxRenderingAPI gfx_direct3d11_api = {

View File

@ -150,29 +150,29 @@ static struct {
Display *dpy;
Window root;
Window win;
Atom atom_wm_state;
Atom atom_wm_state_fullscreen;
Atom atom_wm_delete_window;
bool is_fullscreen;
void (*on_fullscreen_changed)(bool is_now_fullscreen);
int keymap[256];
bool (*on_key_down)(int scancode);
bool (*on_key_up)(int scancode);
void (*on_all_keys_up)(void);
PFNGLXGETSYNCVALUESOMLPROC glXGetSyncValuesOML;
PFNGLXSWAPBUFFERSMSCOMLPROC glXSwapBuffersMscOML;
PFNGLXWAITFORSBCOMLPROC glXWaitForSbcOML;
PFNGLXSWAPINTERVALEXTPROC glXSwapIntervalEXT;
PFNGLXSWAPINTERVALSGIPROC glXSwapIntervalSGI;
PFNGLXGETVIDEOSYNCSGIPROC glXGetVideoSyncSGI;
PFNGLXWAITVIDEOSYNCSGIPROC glXWaitVideoSyncSGI;
bool has_oml_sync_control;
uint64_t ust0;
int64_t last_msc;
@ -181,7 +181,7 @@ static struct {
uint64_t last_ust;
int64_t target_msc;
bool dropped_frame;
bool has_sgi_video_sync;
uint64_t last_sync_counter;
int64_t this_msc;
@ -220,7 +220,7 @@ static int64_t glXGetVideoSyncSGI_wrapper(void) {
static void init_keymap(void) {
XkbDescPtr desc = XkbGetMap(glx.dpy, 0, XkbUseCoreKbd);
XkbGetNames(glx.dpy, XkbKeyNamesMask, desc);
for (int i = desc->min_key_code; i <= desc->max_key_code && i < 256; i++) {
char name[XkbKeyNameLength + 1];
memcpy(name, desc->names->keys[i].name, XkbKeyNameLength);
@ -232,7 +232,7 @@ static void init_keymap(void) {
}
}
}
XkbFreeNames(desc, XkbKeyNamesMask, True);
XkbFreeKeyboard(desc, 0, True);
}
@ -265,7 +265,7 @@ static void gfx_glx_set_fullscreen_state(bool on, bool call_callback) {
return;
}
glx.is_fullscreen = on;
XEvent xev;
xev.xany.type = ClientMessage;
xev.xclient.message_type = glx.atom_wm_state;
@ -276,8 +276,8 @@ static void gfx_glx_set_fullscreen_state(bool on, bool call_callback) {
xev.xclient.data.l[2] = 0;
xev.xclient.data.l[3] = 0;
XSendEvent(glx.dpy, glx.root, 0, SubstructureNotifyMask | SubstructureRedirectMask, &xev);
gfx_glx_ShowHideMouse(on);
gfx_glx_show_cursor(on);
if (glx.on_fullscreen_changed != NULL && call_callback) {
glx.on_fullscreen_changed(on);
}
@ -303,7 +303,7 @@ static void gfx_glx_init(const char *game_name, bool start_in_fullscreen) {
// which means that glXSwapBuffers should be non-blocking,
// if we are sure to wait at least one vsync interval between calls.
setenv("__GL_MaxFramesAllowed", "2", true);
glx.dpy = XOpenDisplay(NULL);
if (glx.dpy == NULL) {
fprintf(stderr, "Cannot connect to X server\n");
@ -311,7 +311,7 @@ static void gfx_glx_init(const char *game_name, bool start_in_fullscreen) {
}
int screen = DefaultScreen(glx.dpy);
glx.root = RootWindow(glx.dpy, screen);
GLint att[] = { GLX_RGBA, GLX_DEPTH_SIZE, 24, GLX_DOUBLEBUFFER, None };
XVisualInfo *vi = glXChooseVisual(glx.dpy, 0, att);
if (vi == NULL) {
@ -323,7 +323,7 @@ static void gfx_glx_init(const char *game_name, bool start_in_fullscreen) {
swa.colormap = cmap;
swa.event_mask = ExposureMask | KeyPressMask | KeyReleaseMask | FocusChangeMask;
glx.win = XCreateWindow(glx.dpy, glx.root, 0, 0, DESIRED_SCREEN_WIDTH, DESIRED_SCREEN_HEIGHT, 0, vi->depth, InputOutput, vi->visual, CWColormap | CWEventMask, &swa);
glx.atom_wm_state = XInternAtom(glx.dpy, "_NET_WM_STATE", False);
glx.atom_wm_state_fullscreen = XInternAtom(glx.dpy, "_NET_WM_STATE_FULLSCREEN", False);
glx.atom_wm_delete_window = XInternAtom(glx.dpy, "WM_DELETE_WINDOW", False);
@ -340,11 +340,11 @@ static void gfx_glx_init(const char *game_name, bool start_in_fullscreen) {
XStoreName(glx.dpy, glx.win, title);
GLXContext glc = glXCreateContext(glx.dpy, vi, NULL, GL_TRUE);
glXMakeCurrent(glx.dpy, glx.win, glc);
init_keymap();
const char *extensions = glXQueryExtensionsString(glx.dpy, screen);
if (gfx_glx_check_extension(extensions, "GLX_OML_sync_control")) {
glx.glXGetSyncValuesOML = (PFNGLXGETSYNCVALUESOMLPROC)glXGetProcAddressARB((const GLubyte *)"glXGetSyncValuesOML");
glx.glXSwapBuffersMscOML = (PFNGLXSWAPBUFFERSMSCOMLPROC)glXGetProcAddressARB((const GLubyte *)"glXSwapBuffersMscOML");
@ -360,7 +360,7 @@ static void gfx_glx_init(const char *game_name, bool start_in_fullscreen) {
glx.glXGetVideoSyncSGI = (PFNGLXGETVIDEOSYNCSGIPROC)glXGetProcAddressARB((const GLubyte *)"glXGetVideoSyncSGI");
glx.glXWaitVideoSyncSGI = (PFNGLXWAITVIDEOSYNCSGIPROC)glXGetProcAddressARB((const GLubyte *)"glXWaitVideoSyncSGI");
}
int64_t ust, msc, sbc;
if (glx.glXGetSyncValuesOML != NULL && glx.glXGetSyncValuesOML(glx.dpy, glx.win, &ust, &msc, &sbc)) {
glx.has_oml_sync_control = true;
@ -439,7 +439,7 @@ static void gfx_glx_handle_events(void) {
}
}
}
if (xev.type == ClientMessage && xev.xclient.data.l[0] == glx.atom_wm_delete_window) {
if (xev.type == ClientMessage && (Atom)xev.xclient.data.l[0] == glx.atom_wm_delete_window) {
exit(0);
}
}
@ -451,19 +451,19 @@ static bool gfx_glx_start_frame(void) {
static void gfx_glx_swap_buffers_begin(void) {
glx.wanted_ust += FRAME_INTERVAL_US_NUMERATOR; // advance 1/30 seconds on JP/US or 1/25 seconds on EU
if (!glx.has_oml_sync_control && !glx.has_sgi_video_sync) {
glFlush();
uint64_t target = glx.wanted_ust / FRAME_INTERVAL_US_DENOMINATOR;
uint64_t now;
while (target > (now = (uint64_t)get_time() - glx.ust0)) {
struct timespec ts = {(target - now) / 1000000, ((target - now) % 1000000) * 1000};
struct timespec ts = {(time_t)((target - now) / 1000000), (time_t)(((target - now) % 1000000) * 1000)};
if (nanosleep(&ts, NULL) == 0) {
break;
}
}
if (target + 2 * FRAME_INTERVAL_US_NUMERATOR / FRAME_INTERVAL_US_DENOMINATOR < now) {
if (target + 32 * FRAME_INTERVAL_US_NUMERATOR / FRAME_INTERVAL_US_DENOMINATOR >= now) {
printf("Dropping frame\n");
@ -476,10 +476,10 @@ static void gfx_glx_swap_buffers_begin(void) {
}
glXSwapBuffers(glx.dpy, glx.win);
glx.dropped_frame = false;
return;
}
double vsyncs_to_wait = (int64_t)(glx.wanted_ust / FRAME_INTERVAL_US_DENOMINATOR - glx.last_ust) / (double)glx.vsync_interval;
if (vsyncs_to_wait <= 0) {
printf("Dropping frame\n");
@ -519,17 +519,17 @@ static void gfx_glx_swap_buffers_begin(void) {
vsyncs_to_wait = 2;
}
glx.target_msc = glx.last_msc + vsyncs_to_wait;
if (glx.has_oml_sync_control) {
glx.glXSwapBuffersMscOML(glx.dpy, glx.win, glx.target_msc, 0, 0);
} else if (glx.has_sgi_video_sync) {
glFlush(); // Try to submit pending work. Don't use glFinish since that busy loops on NVIDIA proprietary driver.
//uint64_t counter0;
uint64_t counter1, counter2;
//uint64_t before_wait = get_time();
counter1 = glXGetVideoSyncSGI_wrapper();
//counter0 = counter1;
//int waits = 0;
@ -537,17 +537,17 @@ static void gfx_glx_swap_buffers_begin(void) {
counter1 = glXWaitVideoSyncSGI_wrapper();
//++waits;
}
//uint64_t before = get_time();
glXSwapBuffers(glx.dpy, glx.win);
counter2 = glXGetVideoSyncSGI_wrapper();
while (counter2 < (uint64_t)glx.target_msc) {
counter2 = glXWaitVideoSyncSGI_wrapper();
}
uint64_t after = get_time();
//printf("%.3f %.3f %.3f\t%.3f\t%u %d %.2f %u %d\n", before_wait * 0.000060, before * 0.000060, after * 0.000060, (after - before) * 0.000060, counter0, counter2 - counter0, vsyncs_to_wait, (unsigned int)glx.target_msc, waits);
glx.this_msc = counter2;
glx.this_ust = after;
@ -558,7 +558,7 @@ static void gfx_glx_swap_buffers_end(void) {
if (glx.dropped_frame || (!glx.has_oml_sync_control && !glx.has_sgi_video_sync)) {
return;
}
int64_t ust, msc, sbc;
if (glx.has_oml_sync_control) {
if (!glx.glXWaitForSbcOML(glx.dpy, glx.win, 0, &ust, &msc, &sbc)) {
@ -600,6 +600,10 @@ static double gfx_glx_get_time(void) {
return 0.0;
}
static void gfx_glx_set_frame_divisor(int divisor) {
// TODO
}
struct GfxWindowManagerAPI gfx_glx = {
gfx_glx_init,
gfx_glx_set_keyboard_callbacks,
@ -612,7 +616,8 @@ struct GfxWindowManagerAPI gfx_glx = {
gfx_glx_start_frame,
gfx_glx_swap_buffers_begin,
gfx_glx_swap_buffers_end,
gfx_glx_get_time
gfx_glx_get_time,
gfx_glx_set_frame_divisor,
};
#endif

View File

@ -3,6 +3,6 @@
#include "gfx_window_manager_api.h"
struct GfxWindowManagerAPI gfx_glx;
extern struct GfxWindowManagerAPI gfx_glx;
#endif

View File

@ -29,8 +29,9 @@
#include "SDL_opengl.h"
#else
#include <SDL2/SDL.h>
#include <GL/glew.h>
#define GL_GLEXT_PROTOTYPES 1
#include <SDL2/SDL_opengles2.h>
// #include <SDL2/SDL_opengles2.h>
#endif
#include "gfx_cc.h"
@ -178,6 +179,7 @@ static const char *shader_item_to_str(uint32_t item, bool with_alpha, bool only_
return "texel.a";
}
}
return "";
}
static void append_formula(char *buf, size_t *len, uint8_t c[2][4], bool do_single, bool do_multiply, bool do_mix, bool with_alpha, bool only_alpha, bool opt_alpha) {
@ -571,6 +573,7 @@ static uint32_t gfx_cm_to_opengl(uint32_t val) {
case G_TX_NOMIRROR | G_TX_WRAP:
return GL_REPEAT;
}
return 0;
}
static void gfx_opengl_set_sampler_parameters(int tile, bool linear_filter, uint32_t cms, uint32_t cmt) {

View File

@ -10,6 +10,7 @@
#include <set>
#include <unordered_map>
#include <vector>
#include <list>
#ifndef _LANGUAGE_C
#define _LANGUAGE_C
@ -45,6 +46,8 @@ extern "C" {
using namespace std;
#define SEG_ADDR(seg, addr) (addr | (seg << 24) | 1)
#define SUPPORT_CHECK(x) assert(x)
// SCALE_M_N: upscale/downscale M-bit integer to N-bit
@ -209,7 +212,7 @@ static map<int, FBInfo> framebuffers;
static set<pair<float, float>> get_pixel_depth_pending;
static map<pair<float, float>, uint16_t> get_pixel_depth_cached;
#ifdef _MSC_VER
#ifdef _WIN32
// TODO: Properly implement for MSVC
static unsigned long get_time(void)
{
@ -447,15 +450,15 @@ static void gfx_generate_cc(struct ColorCombiner *comb, uint64_t cc_id) {
val = SHADER_COMBINED;
break;
}
// fallthrough for G_ACMUX_LOD_FRACTION
c[i][1][j] = G_CCMUX_LOD_FRACTION;
[[fallthrough]]; // for G_ACMUX_LOD_FRACTION
case G_ACMUX_1:
//case G_ACMUX_PRIM_LOD_FRAC: same numerical value
if (j != 2) {
val = SHADER_1;
break;
}
// fallthrough for G_ACMUX_PRIM_LOD_FRAC
[[fallthrough]]; // for G_ACMUX_PRIM_LOD_FRAC
case G_ACMUX_PRIMITIVE:
case G_ACMUX_SHADE:
case G_ACMUX_ENVIRONMENT:
@ -564,7 +567,7 @@ static void gfx_texture_cache_delete(const uint8_t* orig_addr)
if (it->first.texture_addr == orig_addr) {
gfx_texture_cache.lru.erase(*(list<TextureCacheMap::iterator>::iterator*)&it->second.lru_location);
gfx_texture_cache.free_texture_ids.push_back(it->second.texture_id);
gfx_texture_cache.map.erase(it);
gfx_texture_cache.map.erase(it->first);
again = true;
break;
}
@ -1692,7 +1695,7 @@ static void gfx_dp_load_block(uint8_t tile, uint32_t uls, uint32_t ult, uint32_t
SUPPORT_CHECK(ult == 0);
// The lrs field rather seems to be number of pixels to load
uint32_t word_size_shift;
uint32_t word_size_shift = 0;
switch (rdp.texture_to_load.siz) {
case G_IM_SIZ_4b:
word_size_shift = 0; // Or -1? It's unused in SM64 anyway.
@ -1720,7 +1723,7 @@ static void gfx_dp_load_block(uint8_t tile, uint32_t uls, uint32_t ult, uint32_t
static void gfx_dp_load_tile(uint8_t tile, uint32_t uls, uint32_t ult, uint32_t lrs, uint32_t lrt) {
SUPPORT_CHECK(tile == G_TX_LOADTILE);
uint32_t word_size_shift;
uint32_t word_size_shift = 0;
switch (rdp.texture_to_load.siz) {
case G_IM_SIZ_4b:
word_size_shift = 0;
@ -2060,12 +2063,11 @@ static void gfx_s2dex_bg_copy(const uObjBg* bg) {
static inline void* seg_addr(uintptr_t w1)
{
// Segmented?
if (w1 >= 0xF0000000)
if (w1 & 1)
{
uint32_t segNum = (w1 >> 24);
segNum -= 0xF0;
uint32_t offset = w1 & 0x00FFFFFF;
uint32_t offset = w1 & 0x00FFFFFE;
//offset = 0; // Cursed Malon bug
if (segmentPointers[segNum] != 0)
@ -2082,7 +2084,7 @@ static inline void* seg_addr(uintptr_t w1)
#define C0(pos, width) ((cmd->words.w0 >> (pos)) & ((1U << width) - 1))
#define C1(pos, width) ((cmd->words.w1 >> (pos)) & ((1U << width) - 1))
int dListBP;
unsigned int dListBP;
int matrixBP;
uintptr_t clearMtx;
@ -2149,7 +2151,7 @@ static void gfx_run_dl(Gfx* cmd) {
uintptr_t mtxAddr = cmd->words.w1;
// OTRTODO: Temp way of dealing with gMtxClear. Need something more elegant in the future...
if (mtxAddr == 0xF012DB20 || mtxAddr == 0xF012DB40)
if (mtxAddr == SEG_ADDR(0, 0x12DB20) || mtxAddr == SEG_ADDR(0, 0x12DB40))
mtxAddr = clearMtx;
#ifdef F3DEX_GBI_2
@ -2250,7 +2252,7 @@ static void gfx_run_dl(Gfx* cmd) {
cmd--;
if (ourHash != -1)
if (ourHash != (uint64_t)-1)
ResourceMgr_RegisterResourcePatch(ourHash, cmd - dListStart, cmd->words.w1);
cmd->words.w1 = (uintptr_t)vtx;
@ -2368,7 +2370,7 @@ static void gfx_run_dl(Gfx* cmd) {
case G_QUAD:
{
int bp = 0;
// fallthrough
[[fallthrough]];
}
#endif
#if defined(F3DEX_GBI) || defined(F3DLP_GBI)
@ -2398,11 +2400,11 @@ static void gfx_run_dl(Gfx* cmd) {
char* imgData = (char*)i;
if ((i & 0xF0000000) != 0xF0000000)
if ((i & 1) != 1)
if (ResourceMgr_OTRSigCheck(imgData) == 1)
i = (uintptr_t)ResourceMgr_LoadTexByName(imgData);
gfx_dp_set_texture_image(C0(21, 3), C0(19, 2), C0(0, 10), (void*) i, imgData);
gfx_dp_set_texture_image(C0(21, 3), C0(19, 2), C0(0, 10), (void*) i, imgData);
break;
}
case G_SETTIMG_OTR:
@ -2419,7 +2421,7 @@ static void gfx_run_dl(Gfx* cmd) {
char* tex = NULL;
#endif
if (addr != NULL)
if (addr != 0)
{
tex = (char*)addr;
}
@ -2433,7 +2435,7 @@ static void gfx_run_dl(Gfx* cmd) {
uintptr_t oldData = cmd->words.w1;
cmd->words.w1 = (uintptr_t)tex;
if (ourHash != -1)
if (ourHash != (uint64_t)-1)
ResourceMgr_RegisterResourcePatch(ourHash, cmd - dListStart, oldData);
cmd++;
@ -2648,7 +2650,7 @@ void gfx_init(struct GfxWindowManagerAPI *wapi, struct GfxRenderingAPI *rapi, co
game_framebuffer_msaa_resolved = gfx_rapi->create_framebuffer();
for (int i = 0; i < 16; i++)
segmentPointers[i] = NULL;
segmentPointers[i] = 0;
// Used in the 120 star TAS
static uint32_t precomp_shaders[] = {

View File

@ -4,12 +4,14 @@
#include <stdbool.h>
#include <stdint.h>
#include <unordered_map>
#include <list>
struct GfxRenderingAPI;
struct GfxWindowManagerAPI;
struct XYWidthHeight {
int16_t x, y, width, height;
int16_t x, y;
uint32_t width, height;
};
struct GfxDimensions {
@ -25,7 +27,7 @@ struct TextureCacheKey {
uint8_t palette_index;
bool operator==(const TextureCacheKey&) const noexcept = default;
struct Hasher {
size_t operator()(const TextureCacheKey& key) const noexcept {
uintptr_t addr = (uintptr_t)key.texture_addr;

View File

@ -1,6 +1,6 @@
#include <stdio.h>
#if !defined(__linux__) && defined(ENABLE_OPENGL)
#if defined(ENABLE_OPENGL)
#ifdef __MINGW32__
#define FOR_WINDOWS 1
@ -23,7 +23,9 @@
#include "gfx_window_manager_api.h"
#include "gfx_screen_config.h"
#ifdef _WIN32
#include <WTypesbase.h>
#endif
#include <time.h>
#define GFX_API_NAME "SDL2 - OpenGL"
@ -41,7 +43,7 @@ static bool (*on_key_up_callback)(int scancode);
static void (*on_all_keys_up_callback)(void);
const SDL_Scancode windows_scancode_table[] =
{
{
/* 0 1 2 3 4 5 6 7 */
/* 8 9 A B C D E F */
SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_ESCAPE, SDL_SCANCODE_1, SDL_SCANCODE_2, SDL_SCANCODE_3, SDL_SCANCODE_4, SDL_SCANCODE_5, SDL_SCANCODE_6, /* 0 */
@ -117,7 +119,9 @@ static void set_fullscreen(bool on, bool call_callback) {
}
static uint64_t previous_time;
#ifndef __linux__
static HANDLE timer;
#endif
static int frameDivisor = 1;
@ -131,7 +135,9 @@ static void gfx_sdl_init(const char *game_name, bool start_in_fullscreen) {
SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24);
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
#ifndef __linux
timer = CreateWaitableTimer(nullptr, false, nullptr);
#endif
//SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 1);
//SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, 4);
@ -188,7 +194,7 @@ static void gfx_sdl_set_keyboard_callbacks(bool (*on_key_down)(int scancode), bo
}
static void gfx_sdl_main_loop(void (*run_one_game_iter)(void)) {
while (1)
while (1)
{
run_one_game_iter();
}

View File

@ -86,14 +86,8 @@
#include <stdint.h>
#define u8 uint8_t
#define u16 uint16_t
#define u32 uint32_t
#define u64 uint64_t
#define unint uint32_t
#define INITIAL_CRC64 0xffffffffffffffffULL
extern uint64_t update_crc64(const void* buf, unint len, u64 crc);
extern u64 crc64(const void* buf, unint len);
extern u64 CRC64(const char* t);
extern uint64_t update_crc64(const void* buf, uint32_t len, uint64_t crc);
extern uint64_t crc64(const void* buf, uint32_t len);
extern uint64_t CRC64(const char* t);

View File

@ -46,8 +46,8 @@ protected:
}
formatted.push_back('\0');
const char *msg_output = formatted.data();
if (CVar_GetS32("gSinkEnabled", 0) && SohImGui::console->opened)
SohImGui::console->Append("SoH Logging", priority, msg_output);
if (CVar_GetS32("gSinkEnabled", 0) && SohImGui::console->opened)
SohImGui::console->Append("SoH Logging", priority, "%s", msg_output);
}
void flush_() override {}
@ -67,6 +67,8 @@ private:
return Priority::ERROR_LVL;
case spdlog::level::critical:
return Priority::ERROR_LVL;
default:
break;
}
return Priority::LOG_LVL;
}

View File

@ -39,7 +39,7 @@ namespace Ship
Vertex* vtxData = new Vertex[numVerts];
uint32_t* indicesData = new uint32_t[numPolys];
if (vertices != NULL)
if (vertices != 0)
{
reader->Seek(headerStart + vertices, SeekOffsetType::Start);
@ -47,7 +47,7 @@ namespace Ship
vtxData[i].pos = reader->ReadVec3f();
}
if (normals != NULL)
if (normals != 0)
{
reader->Seek(headerStart + normals, SeekOffsetType::Start);
@ -55,7 +55,7 @@ namespace Ship
vtxData[i].normal = reader->ReadVec3f();
}
if (vertexColors != NULL)
if (vertexColors != 0)
{
reader->Seek(headerStart + vertexColors, SeekOffsetType::Start);
@ -63,7 +63,7 @@ namespace Ship
vtxData[i].color = reader->ReadColor3b();
}
if (uvCoords != NULL)
if (uvCoords != 0)
{
reader->Seek(headerStart + uvCoords, SeekOffsetType::Start);
@ -71,7 +71,7 @@ namespace Ship
vtxData[i].uv = reader->ReadVec2f();
}
if (boneWeights != NULL)
if (boneWeights != 0)
{
reader->Seek(headerStart + boneWeights, SeekOffsetType::Start);
@ -81,7 +81,7 @@ namespace Ship
mdl->boneWeights[i] = reader->ReadVec2f();
}
if (faces != NULL)
if (faces != 0)
{
reader->Seek(headerStart + faces, SeekOffsetType::Start);
reader->Read((char*)indicesData, numPolys * sizeof(uint32_t));

View File

@ -0,0 +1,173 @@
#if defined(__linux__) || defined(__BSD__)
#include "PulseAudioPlayer.h"
#include <spdlog/spdlog.h>
namespace Ship
{
static void pas_context_state_cb(pa_context *c, void *userdata) {
switch (pa_context_get_state(c)) {
case PA_CONTEXT_READY:
case PA_CONTEXT_TERMINATED:
case PA_CONTEXT_FAILED:
*(bool*)userdata = true;
break;
default:
break;
}
}
static void pas_stream_state_cb(pa_stream *s, void *userdata) {
switch (pa_stream_get_state(s)) {
case PA_STREAM_READY:
case PA_STREAM_FAILED:
case PA_STREAM_TERMINATED:
*(bool*)userdata = true;
break;
default:
break;
}
}
static void pas_stream_write_cb(pa_stream* s, size_t length, void* userdata) {
}
static void pas_update_complete(pa_stream* stream, int success, void* userdata) {
*(bool*)userdata = true;
}
static void pas_write_complete(void* userdata) {
*(bool*)userdata = true;
}
bool PulseAudioPlayer::Init()
{
bool done = false;
const pa_buffer_attr* applied_attr = nullptr;
// Create mainloop
m_MainLoop = pa_mainloop_new();
if (m_MainLoop == NULL) {
return false;
}
// Create context and connect
m_Context = pa_context_new(pa_mainloop_get_api(m_MainLoop), "Ocarina of Time");
if (m_Context == NULL) {
goto fail;
}
pa_context_set_state_callback(m_Context, pas_context_state_cb, &done);
if (pa_context_connect(m_Context, NULL, PA_CONTEXT_NOFLAGS, NULL) < 0) {
goto fail;
}
while (!done) {
pa_mainloop_iterate(m_MainLoop, true, NULL);
}
pa_context_set_state_callback(m_Context, NULL, NULL);
if (pa_context_get_state(m_Context) != PA_CONTEXT_READY) {
goto fail;
}
// Create stream
pa_sample_spec ss;
ss.format = PA_SAMPLE_S16LE;
ss.rate = 32000;
ss.channels = 2;
pa_buffer_attr attr;
attr.maxlength = (1600 + 544 + 528 + 1600) * 4;
attr.tlength = (528*2 + 544) * 4;
attr.prebuf = 1500 * 4;
attr.minreq = 161 * 4;
attr.fragsize = (uint32_t)-1;
m_Stream = pa_stream_new(m_Context, "zelda", &ss, NULL);
if (m_Stream == NULL) {
goto fail;
}
done = false;
pa_stream_set_state_callback(m_Stream, pas_stream_state_cb, &done);
pa_stream_set_write_callback(m_Stream, pas_stream_write_cb, NULL);
if (pa_stream_connect_playback(m_Stream, NULL, &attr, PA_STREAM_ADJUST_LATENCY, NULL, NULL) < 0) {
goto fail;
}
while (!done) {
pa_mainloop_iterate(m_MainLoop, true, NULL);
}
pa_stream_set_state_callback(m_Stream, NULL, NULL);
if (pa_stream_get_state(m_Stream) != PA_STREAM_READY) {
goto fail;
}
applied_attr = pa_stream_get_buffer_attr(m_Stream);
SPDLOG_TRACE("maxlength: {}\ntlength: {}\nprebuf: {}\nminreq: {}\nfragsize: {}\n",
applied_attr->maxlength, applied_attr->tlength, applied_attr->prebuf, applied_attr->minreq, applied_attr->fragsize);
m_Attr = *applied_attr;
return true;
fail:
if (m_Stream != NULL) {
pa_stream_unref(m_Stream);
m_Stream = NULL;
}
if (m_Context != NULL) {
pa_context_disconnect(m_Context);
pa_context_unref(m_Context);
m_Context = NULL;
}
if (m_MainLoop != NULL) {
pa_mainloop_free(m_MainLoop);
m_MainLoop = NULL;
}
return false;
}
int PulseAudioPlayer::Buffered()
{
if (m_Stream == NULL) {
return 0;
}
bool done = false;
pa_stream_update_timing_info(m_Stream, pas_update_complete, &done);
while (!done) {
pa_mainloop_iterate(m_MainLoop, true, NULL);
}
const pa_timing_info *info = pa_stream_get_timing_info(m_Stream);
if (info == NULL) {
SPDLOG_ERROR("pa_stream_get_timing_info failed, state is %d\n", pa_stream_get_state(m_Stream));
}
return (info->write_index - info->read_index) / 4;
}
int PulseAudioPlayer::GetDesiredBuffered()
{
// return 1100;
return 1680;
}
void PulseAudioPlayer::Play(const uint8_t* buff, uint32_t len)
{
size_t ws = m_Attr.maxlength - Buffered() * 4;
if (ws < len) {
len = ws;
}
if (pa_stream_write_ext_free(m_Stream, buff, len, pas_write_complete, &m_WriteComplete, 0LL, PA_SEEK_RELATIVE) < 0) {
SPDLOG_ERROR("pa_stream_write failed");
return;
}
while (!m_WriteComplete) {
pa_mainloop_iterate(m_MainLoop, true, NULL);
}
m_WriteComplete = false;
}
}
#endif

View File

@ -0,0 +1,26 @@
#pragma once
#if defined(__linux__) || defined(__BSD__)
#include "AudioPlayer.h"
#include <pulse/pulseaudio.h>
namespace Ship {
class PulseAudioPlayer : public AudioPlayer {
public:
PulseAudioPlayer() {}
bool Init() override;
int Buffered() override;
int GetDesiredBuffered() override;
void Play(const uint8_t* buff, uint32_t len) override;
private:
pa_context* m_Context = nullptr;
pa_stream* m_Stream = nullptr;
pa_mainloop* m_MainLoop = nullptr;
bool m_WriteComplete = false;
pa_buffer_attr m_Attr = {0};
};
}
#endif

View File

@ -2,8 +2,8 @@
#include "DisplayList.h"
#include "ResourceMgr.h"
#include "Utils/BinaryReader.h"
#include "lib/tinyxml2/tinyxml2.h"
#include "lib/Fast3D/U64/PR/ultra64/gbi.h"
#include "Lib/tinyxml2/tinyxml2.h"
#include "Lib/Fast3D/U64/PR/ultra64/gbi.h"
namespace Ship
{
@ -25,7 +25,7 @@ namespace Ship
void ResourceFile::WriteFileBinary(BinaryWriter* writer, Resource* res)
{
}
void ResourceFile::WriteFileXML(tinyxml2::XMLElement* writer, Resource* res)
@ -35,17 +35,17 @@ namespace Ship
Resource::~Resource()
{
free(cachedGameAsset);
free(cachedGameAsset);
cachedGameAsset = nullptr;
for (int i = 0; i < patches.size(); i++)
for (size_t i = 0; i < patches.size(); i++)
{
std::string hashStr = resMgr->HashToString(patches[i].crc);
auto resShared = resMgr->GetCachedFile(hashStr);
if (resShared != nullptr)
{
auto res = (Ship::DisplayList*)resShared.get();
Gfx* gfx = (Gfx*)&res->instructions[patches[i].index];
gfx->words.w1 = patches[i].origData;
}

View File

@ -6,7 +6,7 @@
#include "GlobalCtx2.h"
#include "StrHash.h"
#include "File.h"
#include "lib/tinyxml2/tinyxml2.h"
#include "Lib/tinyxml2/tinyxml2.h"
namespace Ship
{
@ -101,10 +101,10 @@ namespace Ship
class ResourcePromise {
public:
std::shared_ptr<Resource> Resource;
std::shared_ptr<File> File;
std::condition_variable ResourceLoadNotifier;
std::mutex ResourceLoadMutex;
std::shared_ptr<Resource> resource;
std::shared_ptr<File> file;
std::condition_variable resourceLoadNotifier;
std::mutex resourceLoadMutex;
bool bHasResourceLoaded = false;
};
}

View File

@ -43,7 +43,7 @@ namespace Ship {
const std::lock_guard<std::mutex> ResLock(ResourceLoadMutex);
bIsRunning = false;
}
FileLoadNotifier.notify_all();
ResourceLoadNotifier.notify_all();
FileLoadThread->join();
@ -89,7 +89,7 @@ namespace Ship {
OTR->LoadFile(ToLoad->path, true, ToLoad);
//Lock.lock();
if (!ToLoad->bHasLoadError)
FileCache[ToLoad->path] = ToLoad->bIsLoaded && !ToLoad->bHasLoadError ? ToLoad : nullptr;
@ -124,15 +124,15 @@ namespace Ship {
// Wait for the underlying File to complete loading
{
std::unique_lock<std::mutex> FileLock(ToLoad->File->FileLoadMutex);
while (!ToLoad->File->bIsLoaded && !ToLoad->File->bHasLoadError) {
ToLoad->File->FileLoadNotifier.wait(FileLock);
std::unique_lock<std::mutex> FileLock(ToLoad->file->FileLoadMutex);
while (!ToLoad->file->bIsLoaded && !ToLoad->file->bHasLoadError) {
ToLoad->file->FileLoadNotifier.wait(FileLock);
}
}
if (!ToLoad->File->bHasLoadError)
if (!ToLoad->file->bHasLoadError)
{
auto UnmanagedRes = ResourceLoader::LoadResource(ToLoad->File);
auto UnmanagedRes = ResourceLoader::LoadResource(ToLoad->file);
if (UnmanagedRes != nullptr)
{
@ -140,13 +140,13 @@ namespace Ship {
auto Res = std::shared_ptr<Resource>(UnmanagedRes);
if (Res != nullptr) {
std::unique_lock<std::mutex> Lock(ToLoad->ResourceLoadMutex);
std::unique_lock<std::mutex> Lock(ToLoad->resourceLoadMutex);
ToLoad->bHasResourceLoaded = true;
ToLoad->Resource = Res;
ToLoad->resource = Res;
ResourceCache[Res->file->path] = Res;
SPDLOG_DEBUG("Loaded Resource {} on ResourceMgr thread", ToLoad->File->path);
SPDLOG_DEBUG("Loaded Resource {} on ResourceMgr thread", ToLoad->file->path);
// Disabled for now because it can cause random crashes
//FileCache[Res->File->path] = nullptr;
@ -155,9 +155,9 @@ namespace Ship {
}
else {
ToLoad->bHasResourceLoaded = false;
ToLoad->Resource = nullptr;
ToLoad->resource = nullptr;
SPDLOG_ERROR("Resource load FAILED {} on ResourceMgr thread", ToLoad->File->path);
SPDLOG_ERROR("Resource load FAILED {} on ResourceMgr thread", ToLoad->file->path);
}
//ResLock.lock();
@ -167,10 +167,10 @@ namespace Ship {
else
{
ToLoad->bHasResourceLoaded = false;
ToLoad->Resource = nullptr;
ToLoad->resource = nullptr;
}
ToLoad->ResourceLoadNotifier.notify_all();
ToLoad->resourceLoadNotifier.notify_all();
}
SPDLOG_INFO("Resource Manager LoadResourceThread ended");
@ -232,17 +232,17 @@ namespace Ship {
if (!Promise->bHasResourceLoaded)
{
std::unique_lock<std::mutex> Lock(Promise->ResourceLoadMutex);
std::unique_lock<std::mutex> Lock(Promise->resourceLoadMutex);
while (!Promise->bHasResourceLoaded) {
Promise->ResourceLoadNotifier.wait(Lock);
Promise->resourceLoadNotifier.wait(Lock);
}
}
return Promise->Resource;
return Promise->resource;
}
std::shared_ptr<ResourcePromise> ResourceMgr::LoadResourceAsync(std::string FilePath) {
StringHelper::ReplaceOriginal(FilePath, "/", "\\");
StringHelper::ReplaceOriginal(FilePath, "\\", "/");
if (StringHelper::StartsWith(FilePath, "__OTR__"))
FilePath = StringHelper::Split(FilePath, "__OTR__")[1];
@ -257,9 +257,9 @@ namespace Ship {
}
std::shared_ptr<File> FileData = LoadFile(FilePath);
Promise->File = FileData;
Promise->file = FileData;
if (Promise->File->bHasLoadError)
if (Promise->file->bHasLoadError)
{
Promise->bHasResourceLoaded = true;
}
@ -271,7 +271,7 @@ namespace Ship {
}
} else {
Promise->bHasResourceLoaded = true;
Promise->Resource = resCacheFind->second;
Promise->resource = resCacheFind->second;
}
return Promise;
@ -295,37 +295,37 @@ namespace Ship {
auto PromiseList = CacheDirectoryAsync(SearchMask);
auto LoadedList = std::make_shared<std::vector<std::shared_ptr<Resource>>>();
for (int32_t i = 0; i < PromiseList->size(); i++) {
for (size_t i = 0; i < PromiseList->size(); i++) {
auto Promise = PromiseList->at(i);
std::unique_lock<std::mutex> Lock(Promise->ResourceLoadMutex);
std::unique_lock<std::mutex> Lock(Promise->resourceLoadMutex);
while (!Promise->bHasResourceLoaded) {
Promise->ResourceLoadNotifier.wait(Lock);
Promise->resourceLoadNotifier.wait(Lock);
}
LoadedList->push_back(Promise->Resource);
LoadedList->push_back(Promise->resource);
}
return LoadedList;
}
std::shared_ptr<std::vector<std::shared_ptr<Resource>>> ResourceMgr::DirtyDirectory(std::string SearchMask)
std::shared_ptr<std::vector<std::shared_ptr<Resource>>> ResourceMgr::DirtyDirectory(std::string SearchMask)
{
auto PromiseList = CacheDirectoryAsync(SearchMask);
auto LoadedList = std::make_shared<std::vector<std::shared_ptr<Resource>>>();
for (int32_t i = 0; i < PromiseList->size(); i++) {
for (size_t i = 0; i < PromiseList->size(); i++) {
auto Promise = PromiseList->at(i);
std::unique_lock<std::mutex> Lock(Promise->ResourceLoadMutex);
std::unique_lock<std::mutex> Lock(Promise->resourceLoadMutex);
while (!Promise->bHasResourceLoaded) {
Promise->ResourceLoadNotifier.wait(Lock);
Promise->resourceLoadNotifier.wait(Lock);
}
if (Promise->Resource != nullptr)
Promise->Resource->isDirty = true;
if (Promise->resource != nullptr)
Promise->resource->isDirty = true;
LoadedList->push_back(Promise->Resource);
LoadedList->push_back(Promise->resource);
}
return LoadedList;

View File

@ -28,7 +28,7 @@ namespace Ship
std::string HashToString(uint64_t Hash);
void InvalidateResourceCache();
uint32_t GetGameVersion();
void SetGameVersion(uint32_t newGameVersion);
std::shared_ptr<File> LoadFileAsync(std::string FilePath);
@ -48,6 +48,7 @@ namespace Ship
private:
std::weak_ptr<GlobalCtx2> Context;
volatile bool bIsRunning;
std::map<std::string, std::shared_ptr<File>> FileCache;
std::map<std::string, std::shared_ptr<Resource>> ResourceCache;
std::queue<std::shared_ptr<File>> FileLoadQueue;
@ -59,7 +60,6 @@ namespace Ship
std::mutex ResourceLoadMutex;
std::condition_variable FileLoadNotifier;
std::condition_variable ResourceLoadNotifier;
volatile bool bIsRunning;
uint32_t gameVersion;
};
}

View File

@ -61,17 +61,17 @@ namespace Ship {
if (Conf[ConfSection]["GUID"].compare("") == 0 || Conf[ConfSection]["GUID"].compare(INVALID_SDL_CONTROLLER_GUID) == 0 || Conf[ConfSection]["GUID"].compare(NewGuid) == 0) {
auto NewCont = SDL_GameControllerOpen(i);
if (SDL_GameControllerHasSensor(NewCont, SDL_SENSOR_GYRO))
{
SDL_GameControllerSetSensorEnabled(NewCont, SDL_SENSOR_GYRO, SDL_TRUE);
}
// We failed to load the controller. Go to next.
if (NewCont == nullptr) {
SPDLOG_ERROR("SDL Controller failed to open: ({})", SDL_GetError());
continue;
}
if (SDL_GameControllerHasSensor(NewCont, SDL_SENSOR_GYRO))
{
SDL_GameControllerSetSensorEnabled(NewCont, SDL_SENSOR_GYRO, SDL_TRUE);
}
guid = NewGuid;
Cont = NewCont;
@ -101,7 +101,7 @@ namespace Ship {
}
bool SDLController::Close() {
if (SDL_GameControllerHasRumble(Cont)) {
if (CanRumble()) {
SDL_GameControllerRumble(Cont, 0, 0, 0);
}
if (Cont != nullptr) {
@ -190,7 +190,7 @@ namespace Ship {
if (SDL_GameControllerHasSensor(Cont, SDL_SENSOR_GYRO))
{
size_t contNumber = GetControllerNumber();
float gyroData[3];
SDL_GameControllerGetSensorData(Cont, SDL_SENSOR_GYRO, gyroData, 3);
@ -347,7 +347,7 @@ namespace Ship {
void SDLController::WriteToSource(ControllerCallback* controller)
{
if (SDL_GameControllerHasRumble(Cont)) {
if (CanRumble()) {
if (controller->rumble > 0) {
float rumble_strength = CVar_GetFloat(StringHelper::Sprintf("gCont%i_RumbleStrength", GetControllerNumber()).c_str(), 1.0f);
SDL_GameControllerRumble(Cont, 0xFFFF * rumble_strength, 0xFFFF * rumble_strength, 0);

View File

@ -13,7 +13,12 @@ namespace Ship {
void ReadFromSource();
void WriteToSource(ControllerCallback* controller);
bool Connected() const { return Cont != nullptr; }
bool CanRumble() const { return SDL_GameControllerHasRumble(Cont); }
bool CanRumble() const {
#if SDL_COMPILEDVERSION >= SDL_VERSIONNUM(2,0,18)
return SDL_GameControllerHasRumble(Cont);
#endif
return true;
}
std::string GetGuid() { return guid; };
@ -30,8 +35,8 @@ namespace Ship {
static bool IsGuidInUse(const std::string& guid);
private:
std::string guid;
SDL_GameController* Cont;
std::string guid;
std::map<int32_t, int16_t> ThresholdMapping;
void LoadAxisThresholds();

View File

@ -137,8 +137,8 @@ namespace Ship
y = 0;
z = 0;
unk_06 = 0;
opa;
xlu;
// opa;
// xlu;
}
SetMesh::SetMesh(BinaryReader* reader) : SceneCommand(reader)
@ -398,18 +398,18 @@ namespace Ship
LightInfo light = LightInfo();
light.type = reader->ReadUByte();
light.x = reader->ReadInt16();
light.y = reader->ReadInt16();
light.y = reader->ReadInt16();
light.z = reader->ReadInt16();
light.r = reader->ReadUByte();
light.g = reader->ReadUByte();
light.b = reader->ReadUByte();
light.drawGlow = reader->ReadUByte();
light.radius = reader->ReadInt16();
lights.push_back(light);
}
}

View File

@ -15,7 +15,7 @@ namespace Ship
limb->skinVtxCnt = reader->ReadUInt16();
uint32_t skinCnt = reader->ReadUInt32();
for (int i = 0; i < skinCnt; i++)
for (size_t i = 0; i < skinCnt; i++)
{
Struct_800A598C struc;

View File

@ -16,7 +16,7 @@ std::map<ImGuiKey, std::string> BindingToggle;
static bool HelpCommand(const std::vector<std::string>&) {
INFO("SoH Commands:");
for(const auto& cmd : SohImGui::console->Commands) {
INFO((" - " + cmd.first).c_str());
INFO("%s", (" - " + cmd.first).c_str());
}
return CMD_SUCCESS;
}
@ -35,7 +35,7 @@ std::string toLowerCase(std::string in) {
static bool BindCommand(const std::vector<std::string>& args) {
if(args.size() > 2) {
const ImGuiIO* io = &ImGui::GetIO();;
for (int k = 0; k < std::size(io->KeysData); k++) {
for (size_t k = 0; k < std::size(io->KeysData); k++) {
std::string key(ImGui::GetKeyName(k));
if(toLowerCase(args[1]) == toLowerCase(key)) {
@ -55,7 +55,7 @@ static bool BindCommand(const std::vector<std::string>& args) {
static bool BindToggleCommand(const std::vector<std::string>& args) {
if (args.size() > 2) {
const ImGuiIO* io = &ImGui::GetIO();;
for (int k = 0; k < std::size(io->KeysData); k++) {
for (size_t k = 0; k < std::size(io->KeysData); k++) {
std::string key(ImGui::GetKeyName(k));
if (toLowerCase(args[1]) == toLowerCase(key)) {
@ -177,8 +177,10 @@ void Console::Draw() {
for (const auto& filter : priority_filters) {
const bool is_selected = (filter == std::string(this->level_filter));
if (ImGui::Selectable(filter.c_str(), is_selected))
{
this->level_filter = filter;
if (is_selected) ImGui::SetItemDefaultFocus();
}
}
ImGui::EndCombo();
}
@ -194,7 +196,7 @@ void Console::Draw() {
if (ImGui::BeginTable("History", 1)) {
if (ImGui::IsKeyPressed(ImGui::GetKeyIndex(ImGuiKey_DownArrow)))
if (this->selectedId < this->Log.size() - 1) ++this->selectedId;
if (this->selectedId < (int)this->Log.size() - 1) ++this->selectedId;
if (ImGui::IsKeyPressed(ImGui::GetKeyIndex(ImGuiKey_UpArrow)))
if (this->selectedId > 0) --this->selectedId;
@ -226,7 +228,7 @@ void Console::Draw() {
ImGui::EndChild();
// Renders input textfield
constexpr ImGuiInputTextFlags flags = ImGuiInputTextFlags_EnterReturnsTrue | ImGuiInputTextFlags_CallbackEdit |
constexpr ImGuiInputTextFlags flags = ImGuiInputTextFlags_EnterReturnsTrue | ImGuiInputTextFlags_CallbackEdit |
ImGuiInputTextFlags_CallbackCompletion | ImGuiInputTextFlags_CallbackHistory;
ImGui::PushItemWidth(-1);
if(ImGui::InputTextWithHint("CMDInput", ">", this->InputBuffer, MAX_BUFFER_SIZE, flags, &Console::CallbackStub, this)) {
@ -317,7 +319,7 @@ int Console::CallbackStub(ImGuiInputTextCallbackData* data) {
return 0;
}
void Console::Append(const std::string& channel, Priority priority, const char* fmt, ...) IM_FMTARGS(4) {
void Console::Append(const std::string& channel, Priority priority, const char* fmt, ...) {
char buf[1024];
va_list args;
va_start(args, fmt);

View File

@ -7,10 +7,10 @@
#include "Lib/ImGui/imgui.h"
#define LOG(msg, ...) SohImGui::console->Append("Main", Priority::LOG_LVL, msg, __VA_ARGS__)
#define INFO(msg, ...) SohImGui::console->Append("Main", Priority::INFO_LVL, msg, __VA_ARGS__)
#define WARNING(msg, ...) SohImGui::console->Append("Main", Priority::WARNING_LVL, msg, __VA_ARGS__)
#define ERROR(msg, ...) SohImGui::console->Append("Main", Priority::ERROR_LVL, msg, __VA_ARGS__)
#define LOG(msg, ...) SohImGui::console->Append("Main", Priority::LOG_LVL, msg, ##__VA_ARGS__)
#define INFO(msg, ...) SohImGui::console->Append("Main", Priority::INFO_LVL, msg, ##__VA_ARGS__)
#define WARNING(msg, ...) SohImGui::console->Append("Main", Priority::WARNING_LVL, msg, ##__VA_ARGS__)
#define ERROR(msg, ...) SohImGui::console->Append("Main", Priority::ERROR_LVL, msg, ##__VA_ARGS__)
#define CMD_SUCCESS true
#define CMD_FAILED false
#define MAX_BUFFER_SIZE 255
@ -75,7 +75,7 @@ public:
void Init();
void Update();
void Draw();
void Append(const std::string& channel, Priority priority, const char* fmt, ...);
void Append(const std::string& channel, Priority priority, const char* fmt, ...) IM_FMTARGS(4);
void Dispatch(const std::string& line);
static int CallbackStub(ImGuiInputTextCallbackData* data);
};

View File

@ -24,7 +24,7 @@ namespace ModInternal {
bool handleHook(std::shared_ptr<HookCall> call) {
std::string hookName = std::string(call->name);
for (int l = 0; l < listeners[hookName].size(); l++) {
for (size_t l = 0; l < listeners[hookName].size(); l++) {
(listeners[hookName][l])(call);
}
return call->cancelled;

View File

@ -47,6 +47,7 @@ struct HookParameter {
#include <functional>
#include <string>
#include <map>
#include <memory>
struct HookCall {
std::string name;

View File

@ -92,9 +92,13 @@ namespace SohImGui {
case Backend::SDL:
ImGui_ImplSDL2_InitForOpenGL(static_cast<SDL_Window*>(impl.sdl.window), impl.sdl.context);
break;
#if defined(ENABLE_DX11) || defined(ENABLE_DX12)
case Backend::DX11:
ImGui_ImplWin32_Init(impl.dx11.window);
break;
#endif
default:
break;
}
// OTRTODO: This gameplay specific stuff should not be in libultraship. This needs to be moved to soh and use sTunicColors
@ -148,9 +152,14 @@ namespace SohImGui {
case Backend::SDL:
ImGui_ImplOpenGL3_Init("#version 120");
break;
#if defined(ENABLE_DX11) || defined(ENABLE_DX12)
case Backend::DX11:
ImGui_ImplDX11_Init(static_cast<ID3D11Device*>(impl.dx11.device), static_cast<ID3D11DeviceContext*>(impl.dx11.device_context));
break;
#endif
default:
break;
}
}
@ -159,9 +168,13 @@ namespace SohImGui {
case Backend::SDL:
ImGui_ImplSDL2_ProcessEvent(static_cast<const SDL_Event*>(event.sdl.event));
break;
#if defined(ENABLE_DX11) || defined(ENABLE_DX12)
case Backend::DX11:
ImGui_ImplWin32_WndProcHandler(static_cast<HWND>(event.win32.handle), event.win32.msg, event.win32.wparam, event.win32.lparam);
break;
#endif
default:
break;
}
}
@ -170,9 +183,13 @@ namespace SohImGui {
case Backend::SDL:
ImGui_ImplSDL2_NewFrame(static_cast<SDL_Window*>(impl.sdl.window));
break;
#if defined(ENABLE_DX11) || defined(ENABLE_DX12)
case Backend::DX11:
ImGui_ImplWin32_NewFrame();
break;
#endif
default:
break;
}
}
@ -181,9 +198,13 @@ namespace SohImGui {
case Backend::SDL:
ImGui_ImplOpenGL3_NewFrame();
break;
#if defined(ENABLE_DX11) || defined(ENABLE_DX12)
case Backend::DX11:
ImGui_ImplDX11_NewFrame();
break;
#endif
default:
break;
}
}
@ -192,9 +213,13 @@ namespace SohImGui {
case Backend::SDL:
ImGui_ImplOpenGL3_RenderDrawData(data);
break;
#if defined(ENABLE_DX11) || defined(ENABLE_DX12)
case Backend::DX11:
ImGui_ImplDX11_RenderDrawData(data);
break;
#endif
default:
break;
}
}
@ -202,11 +227,12 @@ namespace SohImGui {
switch (impl.backend) {
case Backend::DX11:
return true;
default:
return false;
}
return false;
}
void SohImGui::ShowCursor(bool hide, Dialogues d) {
void ShowCursor(bool hide, Dialogues d) {
if (d == Dialogues::dLoadSettings) {
GlobalCtx2::GetInstance()->GetWindow()->ShowCursor(hide);
return;
@ -724,7 +750,11 @@ namespace SohImGui {
ImGui::PushStyleColor(ImGuiCol_Border, ImVec4(0, 0, 0, 0));
ImGui::Begin("Debug Stats", nullptr, ImGuiWindowFlags_None);
#ifdef _WIN32
ImGui::Text("Platform: Windows");
#else
ImGui::Text("Platform: Linux");
#endif
ImGui::Text("Status: %.3f ms/frame (%.1f FPS)", 1000.0f / framerate, framerate);
ImGui::End();
ImGui::PopStyleColor();
@ -879,4 +909,16 @@ namespace SohImGui {
ImTextureID GetTextureByName(const std::string& name) {
return GetTextureByID(DefaultAssets[name]->textureId);
}
ImTextureID GetTextureByID(int id) {
#ifdef ENABLE_DX11
if (impl.backend == Backend::DX11)
{
ImTextureID gfx_d3d11_get_texture_by_id(int id);
return gfx_d3d11_get_texture_by_id(id);
}
#else
return reinterpret_cast<ImTextureID>(id);
#endif
}
}

View File

@ -1,9 +1,14 @@
#include "Utils.h"
#include <cstring>
#ifdef _MSC_VER
#define strdup _strdup
#endif
namespace Utils {
std::vector<std::string> SplitText(const std::string text, char separator = ' ', bool keep_quotes = false) {
std::vector<std::string> args;
char* input = _strdup(text.c_str());
char* input = strdup(text.c_str());
const size_t length = strlen(input);
bool inQuotes = false;

View File

@ -1,3 +1,4 @@
#ifdef _WIN32
#include "WasapiAudioPlayer.h"
#include "spdlog/spdlog.h"
@ -169,4 +170,5 @@ namespace Ship {
}
return S_OK;
}
}
}
#endif

View File

@ -1,4 +1,7 @@
#pragma once
#ifdef _WIN32
#include "AudioPlayer.h"
#include <wrl/client.h>
#include <mmdeviceapi.h>
@ -39,3 +42,4 @@ namespace Ship {
bool started;
};
}
#endif

View File

@ -12,6 +12,8 @@
#include "Matrix.h"
#include "AudioPlayer.h"
#include "WasapiAudioPlayer.h"
#include "PulseAudioPlayer.h"
#include "SDLAudioPlayer.h"
#include "Lib/Fast3D/gfx_pc.h"
#include "Lib/Fast3D/gfx_sdl.h"
#include "Lib/Fast3D/gfx_opengl.h"
@ -48,7 +50,7 @@ extern "C" {
}
// TODO: This for loop is debug. Burn it with fire.
for (size_t i = 0; i < SDL_NumJoysticks(); i++) {
for (int i = 0; i < SDL_NumJoysticks(); i++) {
if (SDL_IsGameController(i)) {
// Get the GUID from SDL
char buf[33];
@ -207,7 +209,7 @@ extern "C" {
return (char*)res->imageData;
}
void ResourceMgr_WriteTexS16ByName(char* texPath, int index, s16 value) {
void ResourceMgr_WriteTexS16ByName(char* texPath, size_t index, s16 value) {
const auto res = static_cast<Ship::Texture*>(Ship::GlobalCtx2::GetInstance()->GetResourceManager()->LoadResource(texPath).get());
if (res != nullptr)
@ -237,7 +239,7 @@ extern "C" {
}
}
extern "C" GfxWindowManagerAPI gfx_sdl;
extern GfxWindowManagerAPI gfx_sdl;
void SetWindowManager(GfxWindowManagerAPI** WmApi, GfxRenderingAPI** RenderingApi, const std::string& gfx_backend);
namespace Ship {
@ -397,6 +399,12 @@ namespace Ship {
}
void Window::SetAudioPlayer() {
#ifdef _WIN32
APlayer = std::make_shared<WasapiAudioPlayer>();
#elif defined(__linux)
APlayer = std::make_shared<PulseAudioPlayer>();
#else
APlayer = std::make_shared<SDLAudioPlayer>();
#endif
}
}

View File

@ -23,7 +23,9 @@ void SetWindowManager(struct GfxWindowManagerAPI** WmApi, struct GfxRenderingAPI
#ifdef ENABLE_OPENGL
*RenderingApi = &gfx_opengl_api;
#if defined(__linux__)
*WmApi = &gfx_glx;
// LINUX_TODO:
// *WmApi = &gfx_glx;
*WmApi = &gfx_sdl;
#else
*WmApi = &gfx_sdl;
#endif

View File

@ -449,13 +449,16 @@ void aFilterImpl(uint8_t flags, uint16_t count_or_buf, int16_t *state_or_filter)
int16_t *buf = BUF_S16(count_or_buf);
if (flags == A_INIT) {
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wmemset-elt-size"
memset(tmp, 0, 8 * sizeof(int16_t));
#pragma GCC diagnostic pop
memset(tmp2, 0, 8 * sizeof(int16_t));
} else {
memcpy(tmp, state_or_filter, 8 * sizeof(int16_t));
memcpy(tmp2, state_or_filter + 8, 8 * sizeof(int16_t));
}
for (int i = 0; i < 8; i++) {
rspa.filter[i] = (tmp2[i] + rspa.filter[i]) / 2;
}

View File

@ -1,3 +1,4 @@
#include <sstream>
#include "stox.h"
#include "spdlog/spdlog.h"

11
soh/.gitignore vendored
View File

@ -25,6 +25,10 @@ docs/doxygen/
*.map
*.dump
out.txt
shipofharkinian.ini
imgui.ini
oot.otr
oot_save.sav
# Tool artifacts
tools/mipspro7.2_compiler/
@ -279,7 +283,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 +379,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 +388,7 @@ ASALocalRun/
# NVidia Nsight GPU debugger configuration file
*.nvuser
# MFractors (Xamarin productivity tool) working folder
# MFractors (Xamarin productivity tool) working folder
.mfractor/
*.out
@ -397,6 +401,7 @@ ZAPDUtils/ZAPDUtils.a
build/
ZAPDUtils/build/
ZAPD/BuildInfo.h
cvars.cfg
DebugObj/*
ReleaseObj/*

158
soh/Makefile Normal file
View File

@ -0,0 +1,158 @@
CXX := g++
CC := gcc
LD := lld
AR := ar
FORMAT := clang-format-11
ZAPD := ../ZAPDTR/ZAPD.out
LIBULTRASHIP := ../libultraship/libultraship.a
ZAPDUTILS := ../ZAPDTR/ZAPDUtils/ZAPDUtils.a
ASAN ?= 0
DEBUG ?= 1
OPTFLAGS ?= -O0
LTO ?= 0
WARN := \
-Wno-return-type \
-funsigned-char \
-m32 -mhard-float -fno-stack-protector -fno-common -fno-zero-initialized-in-bss -fno-strict-aliasing -fno-inline-functions -fno-inline-small-functions -fno-toplevel-reorder -ffreestanding -fwrapv \
CXXFLAGS := $(WARN) -std=c++20 -D_GNU_SOURCE -fpermissive -no-pie -nostdlib -march=i386
CFLAGS := $(WARN) -std=c99 -D_GNU_SOURCE -no-pie -nostdlib -march=i386
LDFLAGS := -m32
CPPFLAGS := -MMD
ifneq ($(DEBUG),0)
CXXFLAGS += -g
CFLAGS += -g
endif
ifneq ($(ASAN),0)
CXXFLAGS += -fsanitize=address
LDFLAGS += -fsanitize=address
endif
ifneq ($(LTO),0)
CXXFLAGS += -flto
LDFLAGS += -flto
endif
TARGET := soh.elf
INC_DIRS := $(addprefix -I, \
. \
assets \
build \
include \
src \
../ZAPDTR/ZAPDUtils \
../libultraship/libultraship \
../libultraship/libultraship/Lib/spdlog/include \
../libultraship/libultraship/Lib/Fast3D/U64 \
../libultraship/libultraship/Lib/Fast3D/U64/PR \
)
LDDIRS := $(addprefix -L, \
../external \
../libultraship/ \
)
LDLIBS := \
$(ZAPDUTILS) \
$(addprefix -l, \
X11 \
dl \
bz2 \
z \
pthread \
atomic \
SDL2 \
GL \
GLEW \
storm \
pulse\
ultraship \
) \
ASSET_BIN_DIRS := $(shell find assets/* -type d -not -path "assets/xml*")
ASSET_FILES_XML := $(foreach dir,$(ASSET_BIN_DIRS),$(wildcard $(dir)/*.xml))
ASSET_FILES_BIN := $(foreach dir,$(ASSET_BIN_DIRS),$(wildcard $(dir)/*.bin))
ASSET_FILES_OUT := $(foreach f,$(ASSET_FILES_XML:.xml=.c),$f) \
$(foreach f,$(ASSET_FILES_BIN:.bin=.bin.inc.c),build/$f)
TEXTURE_FILES_PNG := $(foreach dir,$(ASSET_BIN_DIRS),$(wildcard $(dir)/*.png))
TEXTURE_FILES_JPG := $(foreach dir,$(ASSET_BIN_DIRS),$(wildcard $(dir)/*.jpg))
TEXTURE_FILES_OUT := $(foreach f,$(TEXTURE_FILES_PNG:.png=.inc.c),build/$f) \
$(foreach f,$(TEXTURE_FILES_JPG:.jpg=.jpg.inc.c),build/$f) \
CXX_FILES := \
$(shell find soh -type f -name *.cpp)
C_FILES := \
$(shell find soh -type f -name *.c) \
$(shell find src/boot -type f -name *.c) \
$(shell find src/buffers -type f -name *.c) \
$(shell find src/code -type f -name *.c) \
$(shell find src/overlays -type f -name *.c) \
src/libultra/gu/coss.c \
src/libultra/gu/guLookAt.c \
src/libultra/gu/guLookAtHilite.c \
src/libultra/gu/guPerspectiveF.c \
src/libultra/gu/guPosition.c \
src/libultra/gu/guS2DInitBg.c \
src/libultra/gu/ortho.c \
src/libultra/gu/rotate.c \
src/libultra/gu/sins.c \
src/libultra/gu/sintable.c \
src/libultra/libc/sprintf.c
O_FILES := \
$(C_FILES:%.c=build/%.o) \
$(CXX_FILES:%.cpp=build/%.o)
D_FILES := $(O_FILES:%.o=%.d)
# create build directory
SRC_DIRS := $(shell find . -type d -a -not -path "*build*")
$(shell mkdir -p $(SRC_DIRS:%=build/%))
all:
$(MAKE) -C ../libultraship
$(MAKE) $(TARGET)
setup:
cd ../OTRExporter && python3 extract_baserom.py
$(MAKE) mpq
mpq:
$(MAKE) -C ../libultraship
$(MAKE) -C ../OTRExporter/OTRExporter
$(MAKE) -C ../ZAPDTR
rm -rf ../OTRExporter/oot.otr
cd ../OTRExporter && python3 extract_assets.py
cp ../OTRExporter/oot.otr .
distclean: clean
$(RM) -r baserom/
$(MAKE) clean -C ../libultraship
$(MAKE) clean -C ../OTRExporter/OTRExporter
$(MAKE) clean -C ../ZAPDTR
clean:
rm -rf build $(TARGET)
.PHONY: all clean distclean setup mpq
build/%.o: %.cpp
$(CXX) -c $(CXXFLAGS) $(CPPFLAGS) $(OPTFLAGS) $(INC_DIRS) $< -o $@
build/%.o: %.c
$(CC) -c $(CFLAGS) $(CPPFLAGS) $(OPTFLAGS) $(INC_DIRS) $< -o $@
# make soh depend on libultraship
$(TARGET): $(LIBULTRASHIP)
$(TARGET): $(O_FILES)
$(CXX) $^ -o $@ $(LDFLAGS) -fuse-ld=$(LD) $(LDDIRS) $(LDLIBS)
-include $(D_FILES)

View File

@ -1,7 +1,7 @@
#ifndef ALLOCA_H
#define ALLOCA_H
void* alloca(u32);
// void* alloca(u32);
//#define alloca __builtin_alloca
#define alloca malloc

View File

@ -14,7 +14,7 @@ extern "C"
#if defined(INCLUDE_GAME_PRINTF) && !defined(NDEBUG)
#define osSyncPrintf(fmt, ...) lusprintf(__FILE__, __LINE__, 0, fmt, __VA_ARGS__)
#else
#define osSyncPrintf(fmt, ...) osSyncPrintfUnused(fmt, __VA_ARGS__)
#define osSyncPrintf(fmt, ...) osSyncPrintfUnused(fmt, ##__VA_ARGS__)
#endif
f32 fabsf(f32 f);

View File

@ -4,8 +4,8 @@
#include "functions.h"
#include "variables.h"
#include "macros.h"
#include "soh\OTRGlobals.h"
#include "soh\Enhancements\gameconsole.h"
#include "soh/OTRGlobals.h"
#include "soh/Enhancements/gameconsole.h"
#include "Cvar.h"

View File

@ -205,6 +205,14 @@ extern GraphicsContext* __gfxCtx;
#define ALIGNED8
#endif
#define SEG_ADDR(seg, addr) (addr | (seg << 24) | 0xF0000000)
#define SEG_ADDR(seg, addr) (addr | (seg << 24) | 1)
#ifdef _MSC_VER
#define BOMSWAP16 _byteswap_ushort
#define BOMSWAP32 _byteswap_ulong
#else
#define BOMSWAP16 __builtin_bswap16
#define BOMSWAP32 __builtin_bswap32
#endif
#endif

View File

@ -1,6 +1,9 @@
#ifndef ULTRA64_H
#define ULTRA64_H
#include <stddef.h>
#include <stdlib.h>
#include <stdint.h>
#include "ultra64/types.h"
#include "unk.h"

View File

@ -278,6 +278,7 @@
<ClCompile Include="src\code\z_actor_dlftbls.c" />
<ClCompile Include="src\code\z_bgcheck.c" />
<ClCompile Include="src\code\z_camera.c" />
<ClCompile Include="src\code\z_cheap_proc.c" />
<ClCompile Include="src\code\z_collision_btltbls.c" />
<ClCompile Include="src\code\z_collision_check.c" />
<ClCompile Include="src\code\z_common_data.c" />

View File

@ -18,7 +18,7 @@ extern "C" {
extern GlobalContext* gGlobalCtx;
}
#include "cvar.h"
#include "Cvar.h"
#define CMD_REGISTER SohImGui::BindCmd

View File

@ -4,6 +4,7 @@
#include <vector>
#include <string>
#include <cmath>
extern "C" {
#include <z64.h>

View File

@ -3,7 +3,7 @@
#include <ultra64.h>
#include <z64.h>
#include "cvar.h"
#include "Cvar.h"
#define MAX_CVARS 2048

View File

@ -11,10 +11,14 @@
#include "Window.h"
#include "z64animation.h"
#include "z64bgcheck.h"
#include "../soh/enhancements/gameconsole.h"
#include "Enhancements/gameconsole.h"
#include <ultra64/gbi.h>
#include <Animation.h>
#ifdef _WIN32
#include <Windows.h>
#else
#include <time.h>
#endif
#include <Vertex.h>
#include <CollisionHeader.h>
#include <Array.h>
@ -22,10 +26,11 @@
#include <Texture.h>
#include "Lib/stb/stb_image.h"
#include "AudioPlayer.h"
#include "../soh/Enhancements/debugconsole.h"
#include "../soh/Enhancements/debugger/debugger.h"
#include "Enhancements/debugconsole.h"
#include "Enhancements/debugger/debugger.h"
#include "Utils/BitConverter.h"
#include "variables.h"
#include "macros.h"
#include <Utils/StringHelper.h>
OTRGlobals* OTRGlobals::Instance;
@ -59,7 +64,7 @@ extern "C" void InitOTR() {
OTRGlobals::Instance = new OTRGlobals();
auto t = OTRGlobals::Instance->context->GetResourceManager()->LoadFile("version");
if (!t->bHasLoadError)
if (!t->bHasLoadError)
{
//uint32_t gameVersion = BitConverter::ToUInt32BE((uint8_t*)t->buffer.get(), 0);
uint32_t gameVersion = *((uint32_t*)t->buffer.get());
@ -72,6 +77,7 @@ extern "C" void InitOTR() {
Debug_Init();
}
#ifdef _WIN32
extern "C" uint64_t GetFrequency() {
LARGE_INTEGER nFreq;
@ -86,6 +92,21 @@ extern "C" uint64_t GetPerfCounter() {
return ticks.QuadPart;
}
#else
extern "C" uint64_t GetFrequency() {
return 1000; // sec -> ms
}
extern "C" uint64_t GetPerfCounter() {
struct timespec monotime;
clock_gettime(CLOCK_MONOTONIC, &monotime);
uint64_t remainingMs = (monotime.tv_nsec / 1000000);
// in milliseconds
return monotime.tv_sec * 1000 + remainingMs;
}
#endif
// C->C++ Bridge
extern "C" void Graph_ProcessFrame(void (*run_one_game_iter)(void)) {
@ -185,7 +206,7 @@ extern "C" void OTRResetScancode()
OTRGlobals::Instance->context->GetWindow()->lastScancode = -1;
}
extern "C" uint32_t ResourceMgr_GetGameVersion()
extern "C" uint32_t ResourceMgr_GetGameVersion()
{
return OTRGlobals::Instance->context->GetResourceManager()->GetGameVersion();
}
@ -309,7 +330,7 @@ extern "C" char* ResourceMgr_LoadArrayByNameAsVec3s(const char* path) {
if (res->cachedGameAsset != nullptr)
return (char*)res->cachedGameAsset;
else
else
{
Vec3s* data = (Vec3s*)malloc(sizeof(Vec3s) * res->scalars.size());
@ -429,7 +450,7 @@ extern "C" int ResourceMgr_OTRSigCheck(char* imgData)
{
uintptr_t i = (uintptr_t)(imgData);
if (i == 0xD9000000 || i == 0xE7000000 || (i & 0xF0000000) == 0xF0000000)
if (i == 0xD9000000 || i == 0xE7000000 || (i & 1) == 1)
return 0;
if ((i & 0xFF000000) != 0xAB000000 && (i & 0xFF000000) != 0xCD000000 && i != 0) {
@ -823,24 +844,24 @@ extern "C" int16_t OTRGetRectDimensionFromRightEdge(float v) {
}
extern "C" void bswapSoundFontSound(SoundFontSound* swappable) {
swappable->sample = (SoundFontSample*)_byteswap_ulong((u32)swappable->sample);
swappable->tuningAsU32 = _byteswap_ulong((u32)swappable->tuningAsU32);
swappable->sample = (SoundFontSample*)BOMSWAP32((u32)swappable->sample);
swappable->tuningAsU32 = BOMSWAP32((u32)swappable->tuningAsU32);
}
extern "C" void bswapDrum(Drum* swappable) {
bswapSoundFontSound(&swappable->sound);
swappable->envelope = (AdsrEnvelope*)_byteswap_ulong((u32)swappable->envelope);
swappable->envelope = (AdsrEnvelope*)BOMSWAP32((u32)swappable->envelope);
}
extern "C" void bswapInstrument(Instrument* swappable) {
swappable->envelope = (AdsrEnvelope*)_byteswap_ulong((u32)swappable->envelope);
swappable->envelope = (AdsrEnvelope*)BOMSWAP32((u32)swappable->envelope);
bswapSoundFontSound(&swappable->lowNotesSound);
bswapSoundFontSound(&swappable->normalNotesSound);
bswapSoundFontSound(&swappable->highNotesSound);
}
extern "C" void bswapSoundFontSample(SoundFontSample* swappable) {
u32 origBitfield = _byteswap_ulong(swappable->asU32);
u32 origBitfield = BOMSWAP32(swappable->asU32);
swappable->codec = (origBitfield >> 28) & 0x0F;
swappable->medium = (origBitfield >> 24) & 0x03;
@ -848,29 +869,29 @@ extern "C" void bswapSoundFontSample(SoundFontSample* swappable) {
swappable->unk_bit25 = (origBitfield >> 21) & 0x01;
swappable->size = (origBitfield) & 0x00FFFFFF;
swappable->sampleAddr = (u8*)_byteswap_ulong((u32)swappable->sampleAddr);
swappable->loop = (AdpcmLoop*)_byteswap_ulong((u32)swappable->loop);
swappable->book = (AdpcmBook*)_byteswap_ulong((u32)swappable->book);
swappable->sampleAddr = (u8*)BOMSWAP32((u32)swappable->sampleAddr);
swappable->loop = (AdpcmLoop*)BOMSWAP32((u32)swappable->loop);
swappable->book = (AdpcmBook*)BOMSWAP32((u32)swappable->book);
}
extern "C" void bswapAdpcmLoop(AdpcmLoop* swappable) {
swappable->start = (u32)_byteswap_ulong((u32)swappable->start);
swappable->end = (u32)_byteswap_ulong((u32)swappable->end);
swappable->count = (u32)_byteswap_ulong((u32)swappable->count);
swappable->start = (u32)BOMSWAP32((u32)swappable->start);
swappable->end = (u32)BOMSWAP32((u32)swappable->end);
swappable->count = (u32)BOMSWAP32((u32)swappable->count);
if (swappable->count != 0) {
for (int i = 0; i < 16; i++) {
swappable->state[i] = (s16)_byteswap_ushort(swappable->state[i]);
swappable->state[i] = (s16)BOMSWAP16(swappable->state[i]);
}
}
}
extern "C" void bswapAdpcmBook(AdpcmBook* swappable) {
swappable->order = (u32)_byteswap_ulong((u32)swappable->order);
swappable->npredictors = (u32)_byteswap_ulong((u32)swappable->npredictors);
swappable->order = (u32)BOMSWAP32((u32)swappable->order);
swappable->npredictors = (u32)BOMSWAP32((u32)swappable->npredictors);
for (int i = 0; i < swappable->npredictors * swappable->order * sizeof(s16) * 4; i++)
swappable->book[i] = (s16)_byteswap_ushort(swappable->book[i]);
swappable->book[i] = (s16)BOMSWAP16(swappable->book[i]);
}
extern "C" bool AudioPlayer_Init(void) {
@ -900,7 +921,7 @@ extern "C" void AudioPlayer_Play(const uint8_t* buf, uint32_t len) {
}
extern "C" int Controller_ShouldRumble(size_t i) {
for (const auto& controller : Ship::Window::Controllers.at(i))
for (const auto& controller : Ship::Window::Controllers.at(i))
{
float rumble_strength = CVar_GetFloat(StringHelper::Sprintf("gCont%i_RumbleStrength", i).c_str(), 1.0f);

View File

@ -12,12 +12,12 @@ OSViMode osViModeNtscLan1;
OSViMode osViModeMpalLan1;
OSViMode osViModeFpalLan1;
OSViMode osViModePalLan1;
AudioContext gAudioContext;
unk_D_8016E750 D_8016E750[4];
// AudioContext gAudioContext;
// unk_D_8016E750 D_8016E750[4];
u8 gLetterTLUT[4][32];
u8 gFontFF[999];
DmaEntry gDmaDataTable[0x60C];
u8 D_80133418;
// u8 D_80133418;
u16 gAudioSEFlagSwapSource[64];
u16 gAudioSEFlagSwapTarget[64];
u8 gAudioSEFlagSwapMode[64];

View File

@ -12,7 +12,7 @@ void OTRGameplay_InitScene(GlobalContext* globalCtx, s32 spawn);
s32 OTRScene_ExecuteCommands(GlobalContext* globalCtx, Ship::Scene* sceneCmd);
//Ship::OTRResource* OTRGameplay_LoadFile(GlobalContext* globalCtx, RomFile* file) {
Ship::Resource* OTRGameplay_LoadFile(GlobalContext* globalCtx, const char* fileName)
Ship::Resource* OTRGameplay_LoadFile(GlobalContext* globalCtx, const char* fileName)
{
auto res = OTRGlobals::Instance->context->GetResourceManager()->LoadResource(fileName);
return res.get();
@ -28,7 +28,7 @@ extern "C" void OTRGameplay_SpawnScene(GlobalContext* globalCtx, s32 sceneNum, s
//osSyncPrintf("\nSCENE SIZE %fK\n", (scene->sceneFile.vromEnd - scene->sceneFile.vromStart) / 1024.0f);
std::string scenePath = StringHelper::Sprintf("scenes\\%s\\%s", scene->sceneFile.fileName, scene->sceneFile.fileName);
std::string scenePath = StringHelper::Sprintf("scenes/%s/%s", scene->sceneFile.fileName, scene->sceneFile.fileName);
globalCtx->sceneSegment = (Ship::Scene*)OTRGameplay_LoadFile(globalCtx, scenePath.c_str());
@ -47,7 +47,7 @@ extern "C" void OTRGameplay_SpawnScene(GlobalContext* globalCtx, s32 sceneNum, s
//gSegments[2] = VIRTUAL_TO_PHYSICAL(globalCtx->sceneSegment);
OTRGameplay_InitScene(globalCtx, spawn);
osSyncPrintf("ROOM SIZE=%fK\n", func_80096FE8(globalCtx, &globalCtx->roomCtx) / 1024.0f);
}
@ -72,7 +72,7 @@ void OTRGameplay_InitScene(GlobalContext* globalCtx, s32 spawn) {
->GetResourceManager()
->LoadResource("object_link_child\\object_link_childVtx_01FE08")
.get());
auto data2 = ResourceMgr_LoadVtxByCRC(0x68d4ea06044e228f);*/
volatile int a = 0;

View File

@ -72,7 +72,7 @@ bool func_800985DC(GlobalContext* globalCtx, Ship::SceneCommand* cmd) {
else
{
ActorEntry* entries = (ActorEntry*)malloc(cmdActor->entries.size() * sizeof(ActorEntry));
for (int i = 0; i < cmdActor->entries.size(); i++)
{
entries[i].id = cmdActor->entries[i].actorNum;
@ -241,7 +241,7 @@ bool func_800987F8(GlobalContext* globalCtx, Ship::SceneCommand* cmd)
globalCtx->setupEntranceList[i].room = otrEntrance->entrances[i].roomToLoad;
globalCtx->setupEntranceList[i].spawn = otrEntrance->entrances[i].startPositionIndex;
}
otrEntrance->cachedGameData = globalCtx->setupEntranceList;
}
@ -252,11 +252,11 @@ bool func_800987F8(GlobalContext* globalCtx, Ship::SceneCommand* cmd)
bool func_8009883C(GlobalContext* globalCtx, Ship::SceneCommand* cmd)
{
Ship::SetSpecialObjects* otrSpecial = (Ship::SetSpecialObjects*)cmd;
if (otrSpecial->globalObject != 0)
globalCtx->objectCtx.subKeepIndex = Object_Spawn(&globalCtx->objectCtx, otrSpecial->globalObject);
if (otrSpecial->elfMessage != 0)
if (otrSpecial->elfMessage != 0)
{
auto res = (Ship::Blob*)OTRGameplay_LoadFile(globalCtx, sNaviMsgFiles[otrSpecial->elfMessage - 1].fileName);
globalCtx->cUpElfMsgs = (ElfMessage*)res->data.data();
@ -436,7 +436,7 @@ extern "C" void* func_800982FC(ObjectContext * objectCtx, s32 bankIndex, s16 obj
bool func_8009899C(GlobalContext* globalCtx, Ship::SceneCommand* cmd)
{
Ship::SetObjectList* cmdObj = (Ship::SetObjectList*)cmd;
s32 i;
s32 j;
s32 k;
@ -743,7 +743,7 @@ bool func_8009918C(GlobalContext* globalCtx, Ship::SceneCommand* cmd)
}
// Scene Command 0x18: Alternate Headers
bool func_800991A0(GlobalContext* globalCtx, Ship::SceneCommand* cmd)
bool func_800991A0(GlobalContext* globalCtx, Ship::SceneCommand* cmd)
{
Ship::SetAlternateHeaders* cmdHeaders = (Ship::SetAlternateHeaders*)cmd;
@ -754,7 +754,7 @@ bool func_800991A0(GlobalContext* globalCtx, Ship::SceneCommand* cmd)
//osSyncPrintf("\n[ZU]sceneset time =[%X]", ((void)0, gSaveContext.cutsceneIndex));
//osSyncPrintf("\n[ZU]sceneset counter=[%X]", ((void)0, gSaveContext.sceneSetupIndex));
if (gSaveContext.sceneSetupIndex != 0)
if (gSaveContext.sceneSetupIndex != 0)
{
std::string desiredHeader = cmdHeaders->headers[gSaveContext.sceneSetupIndex - 1];
Ship::Scene* headerData = nullptr;
@ -798,7 +798,7 @@ bool func_800991A0(GlobalContext* globalCtx, Ship::SceneCommand* cmd)
}
// Scene Command 0x17: Cutscene Data
bool func_8009934C(GlobalContext* globalCtx, Ship::SceneCommand* cmd)
bool func_8009934C(GlobalContext* globalCtx, Ship::SceneCommand* cmd)
{
Ship::SetCutscenes* cmdCS = (Ship::SetCutscenes*)cmd;
@ -810,7 +810,7 @@ bool func_8009934C(GlobalContext* globalCtx, Ship::SceneCommand* cmd)
}
// Scene Command 0x19: Misc. Settings (Camera & World Map Area)
bool func_800993C0(GlobalContext* globalCtx, Ship::SceneCommand* cmd)
bool func_800993C0(GlobalContext* globalCtx, Ship::SceneCommand* cmd)
{
Ship::SetCameraSettings* cmdCam = (Ship::SetCameraSettings*)cmd;

View File

@ -246,7 +246,7 @@ f32 Audio_AdsrUpdate(AdsrState* adsr) {
retry:
case ADSR_STATE_LOOP:
adsr->delay = (s16)_byteswap_ushort(adsr->envelope[adsr->envIndex].delay);
adsr->delay = (s16)BOMSWAP16(adsr->envelope[adsr->envIndex].delay);
switch (adsr->delay) {
case ADSR_DISABLE:
adsr->action.s.state = ADSR_STATE_DISABLED;
@ -255,7 +255,7 @@ f32 Audio_AdsrUpdate(AdsrState* adsr) {
adsr->action.s.state = ADSR_STATE_HANG;
break;
case ADSR_GOTO:
adsr->envIndex = (s16)_byteswap_ushort(adsr->envelope[adsr->envIndex].arg);
adsr->envIndex = (s16)BOMSWAP16(adsr->envelope[adsr->envIndex].arg);
goto retry;
case ADSR_RESTART:
adsr->action.s.state = ADSR_STATE_INITIAL;
@ -266,7 +266,7 @@ f32 Audio_AdsrUpdate(AdsrState* adsr) {
if (adsr->delay == 0) {
adsr->delay = 1;
}
adsr->target = (s16)_byteswap_ushort(adsr->envelope[adsr->envIndex].arg) / 32767.0f;
adsr->target = (s16)BOMSWAP16(adsr->envelope[adsr->envIndex].arg) / 32767.0f;
adsr->target = adsr->target * adsr->target;
adsr->velocity = (adsr->target - adsr->current) / adsr->delay;
adsr->action.s.state = ADSR_STATE_FADE;

View File

@ -1058,7 +1058,7 @@ void AudioLoad_InitSwapFontSampleHeaders(SoundFontSample* sample, uintptr_t romA
size_t maxSoundFontSize = 0x3AA0; // soundFont 0 is the largest size at 0x3AA0
AdpcmLoop* loop;
AdpcmBook* book;
if (((uintptr_t)sample->loop > maxSoundFontSize) || ((uintptr_t)sample->book > maxSoundFontSize) ) {
bswapSoundFontSample(sample);
@ -1093,7 +1093,7 @@ void AudioLoad_InitSwapFont(void) {
SoundFontSound* sfxList;
SoundFontSound* sfx;
Instrument** instList;
Instrument* inst;
Instrument* inst;
// Only up to (numFonts - 1) as final font has garbage data to prevent corruption and is never used
for (fontId = 0; fontId < (numFonts - 1); fontId++) {
@ -1110,12 +1110,12 @@ void AudioLoad_InitSwapFont(void) {
numInstruments = font->numInstruments;
// drums
ptrs[0] = (void*)_byteswap_ulong((uintptr_t)ptrs[0]);
ptrs[0] = (void*)BOMSWAP32((uintptr_t)ptrs[0]);
if ((ptrs[0] != NULL) && (numDrums != 0)) {
drumList = (Drum**)BASE_ROM_OFFSET(ptrs[0]);
for (i = 0; i < numDrums; i++) {
drumList[i] = (Drum*)_byteswap_ulong((uintptr_t)drumList[i]);
drumList[i] = (Drum*)BOMSWAP32((uintptr_t)drumList[i]);
if (drumList[i] != NULL) {
drum = (Drum*)BASE_ROM_OFFSET(drumList[i]);
@ -1128,7 +1128,7 @@ void AudioLoad_InitSwapFont(void) {
}
// sfxs
ptrs[1] = (void*)_byteswap_ulong((u32)ptrs[1]);
ptrs[1] = (void*)BOMSWAP32((u32)ptrs[1]);
if ((ptrs[1] != NULL) && (numSfxs != 0)) {
sfxList = (SoundFontSound*)BASE_ROM_OFFSET(ptrs[1]);
@ -1151,7 +1151,7 @@ void AudioLoad_InitSwapFont(void) {
instList = (Instrument**)(&ptrs[2]);
for (i = 0; i < numInstruments; i++) {
instList[i] = (Instrument*)_byteswap_ulong((uintptr_t)instList[i]);
instList[i] = (Instrument*)BOMSWAP32((uintptr_t)instList[i]);
if (instList[i] != NULL) {
inst = BASE_ROM_OFFSET(instList[i]);
@ -1159,15 +1159,15 @@ void AudioLoad_InitSwapFont(void) {
if (inst->normalRangeLo != 0) {
sample = (SoundFontSample*)BASE_ROM_OFFSET(inst->lowNotesSound.sample);
AudioLoad_InitSwapFontSampleHeaders(sample, romAddr);
AudioLoad_InitSwapFontSampleHeaders(sample, romAddr);
}
sample = (SoundFontSample*)BASE_ROM_OFFSET(inst->normalNotesSound.sample);
AudioLoad_InitSwapFontSampleHeaders(sample, romAddr);
AudioLoad_InitSwapFontSampleHeaders(sample, romAddr);
if (inst->normalRangeHi != 0x7F) {
sample = (SoundFontSample*)BASE_ROM_OFFSET(inst->highNotesSound.sample);
AudioLoad_InitSwapFontSampleHeaders(sample, romAddr);
AudioLoad_InitSwapFontSampleHeaders(sample, romAddr);
}
}
}

View File

@ -1323,14 +1323,14 @@ void AudioSeq_SequenceChannelProcessScript(SequenceChannel* channel) {
case 0xB2:
offset = (u16)parameters[0];
// OTRTODO: Byteswap added for quick audio
channel->unk_22 = _byteswap_ushort(*(u16*)(seqPlayer->seqData + (uintptr_t)(offset + scriptState->value * 2)));
channel->unk_22 = BOMSWAP16(*(u16*)(seqPlayer->seqData + (uintptr_t)(offset + scriptState->value * 2)));
break;
case 0xB4:
channel->dynTable = (void*)&seqPlayer->seqData[channel->unk_22];
break;
case 0xB5:
// OTRTODO: Byteswap added for quick audio
channel->unk_22 = _byteswap_ushort(((u16*)(channel->dynTable))[scriptState->value]);
channel->unk_22 = BOMSWAP16(((u16*)(channel->dynTable))[scriptState->value]);
break;
case 0xB6:
scriptState->value = (*channel->dynTable)[0][scriptState->value];

Some files were not shown because too many files have changed in this diff Show More