mirror of
https://github.com/HarbourMasters/Shipwright.git
synced 2025-08-22 14:23:44 -07:00
Merge branch 'develop' into patch-5
This commit is contained in:
commit
cd1e48ae6e
149 changed files with 3282 additions and 4396 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -395,6 +395,7 @@ ExporterTest/ExporterTest.a
|
||||||
ZAPDUtils/ZAPDUtils.a
|
ZAPDUtils/ZAPDUtils.a
|
||||||
.vscode/
|
.vscode/
|
||||||
build/
|
build/
|
||||||
|
external/
|
||||||
ZAPDUtils/build/
|
ZAPDUtils/build/
|
||||||
ZAPD/BuildInfo.h
|
ZAPD/BuildInfo.h
|
||||||
|
|
||||||
|
|
33
BUILDING.md
33
BUILDING.md
|
@ -1,5 +1,7 @@
|
||||||
# Building Ship of Harkinian
|
# Building Ship of Harkinian
|
||||||
|
|
||||||
|
## Windows
|
||||||
|
|
||||||
1. Install [Python](https://www.python.org/ftp/python/3.10.2/python-3.10.2-amd64.exe)
|
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/)
|
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++`.
|
2b. In the Visual Studio Installer, install `MSVC v142 - VS 2019 C++`.
|
||||||
|
@ -15,7 +17,36 @@
|
||||||
13. Copy the `OTRExporter/oot.otr` archive file to `soh/Release`.
|
13. Copy the `OTRExporter/oot.otr` archive file to `soh/Release`.
|
||||||
14. Launch `soh.exe`.
|
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 checksum 0x09465AC3
|
||||||
OOT_PAL_GC_DBG1 checksum 0x871E1C92 (debug non-master quest)
|
OOT_PAL_GC_DBG1 checksum 0x871E1C92 (debug non-master quest)
|
||||||
|
|
38
Dockerfile
Normal file
38
Dockerfile
Normal 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
|
139
Jenkinsfile
vendored
139
Jenkinsfile
vendored
|
@ -1,5 +1,14 @@
|
||||||
pipeline {
|
pipeline {
|
||||||
|
agent none
|
||||||
|
|
||||||
|
options {
|
||||||
|
timestamps()
|
||||||
|
timeout(time: 30, unit: 'MINUTES')
|
||||||
|
skipDefaultCheckout(true)
|
||||||
|
}
|
||||||
|
|
||||||
|
stages {
|
||||||
|
stage ('Build Windows') {
|
||||||
environment {
|
environment {
|
||||||
MSBUILD='C:\\Program Files\\Microsoft Visual Studio\\2022\\Community\\Msbuild\\Current\\Bin\\msbuild.exe'
|
MSBUILD='C:\\Program Files\\Microsoft Visual Studio\\2022\\Community\\Msbuild\\Current\\Bin\\msbuild.exe'
|
||||||
CONFIG='Release'
|
CONFIG='Release'
|
||||||
|
@ -7,23 +16,12 @@ pipeline {
|
||||||
PLATFORM='x86'
|
PLATFORM='x86'
|
||||||
ZIP='C:\\Program Files\\7-Zip\\7z.exe'
|
ZIP='C:\\Program Files\\7-Zip\\7z.exe'
|
||||||
PYTHON='C:\\Users\\jenkins\\AppData\\Local\\Programs\\Python\\Python310\\python.exe'
|
PYTHON='C:\\Users\\jenkins\\AppData\\Local\\Programs\\Python\\Python310\\python.exe'
|
||||||
|
CMAKE='C:\\Program Files\\CMake\\bin\\cmake.exe'
|
||||||
TOOLSET='v142'
|
TOOLSET='v142'
|
||||||
EMAILTO=''
|
|
||||||
}
|
}
|
||||||
|
|
||||||
agent {
|
agent {
|
||||||
label 'SoH-Builders'
|
label "SoH-Builders"
|
||||||
}
|
}
|
||||||
|
|
||||||
options {
|
|
||||||
timestamps()
|
|
||||||
timeout(time: 15, unit: 'MINUTES')
|
|
||||||
skipDefaultCheckout(true)
|
|
||||||
}
|
|
||||||
|
|
||||||
stages {
|
|
||||||
|
|
||||||
stage ('Checkout') {
|
|
||||||
steps {
|
steps {
|
||||||
checkout([
|
checkout([
|
||||||
$class: 'GitSCM',
|
$class: 'GitSCM',
|
||||||
|
@ -32,68 +30,89 @@ pipeline {
|
||||||
extensions: scm.extensions,
|
extensions: scm.extensions,
|
||||||
userRemoteConfigs: scm.userRemoteConfigs
|
userRemoteConfigs: scm.userRemoteConfigs
|
||||||
])
|
])
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
stage ('Build OTRExporter') {
|
catchError(buildResult: 'FAILURE', stageResult: 'FAILURE') {
|
||||||
steps {
|
|
||||||
bat """
|
bat """
|
||||||
|
|
||||||
"${env.MSBUILD}" ".\\OTRExporter\\OTRExporter.sln" -t:restore,build -p:Configuration=${env.CONFIG};Platform=${env.OTRPLATFORM};PlatformToolset=${env.TOOLSET};RestorePackagesConfig=true /nodeReuse:false
|
"${env.MSBUILD}" ".\\OTRExporter\\OTRExporter.sln" -t:build -p:Configuration=${env.CONFIG};Platform=${env.OTRPLATFORM};PlatformToolset=${env.TOOLSET};RestorePackagesConfig=true /restore /nodeReuse:false /m
|
||||||
|
|
||||||
"""
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
stage ('Extract assets') {
|
|
||||||
steps {
|
|
||||||
bat """
|
|
||||||
|
|
||||||
xcopy "..\\..\\ZELOOTD.z64" "OTRExporter\\"
|
xcopy "..\\..\\ZELOOTD.z64" "OTRExporter\\"
|
||||||
|
|
||||||
cd "OTRExporter"
|
cd "OTRExporter"
|
||||||
"${env.PYTHON}" ".\\extract_assets.py"
|
"${env.PYTHON}" ".\\extract_assets.py"
|
||||||
cd "${env.WORKSPACE}"
|
cd "..\\"
|
||||||
|
|
||||||
|
"${env.MSBUILD}" ".\\soh\\soh.sln" -t:build -p:Configuration=${env.CONFIG};Platform=${env.PLATFORM};PlatformToolset=${env.TOOLSET} /nodeReuse:false /m
|
||||||
|
|
||||||
|
cd OTRGui
|
||||||
|
mkdir build
|
||||||
|
cd build
|
||||||
|
|
||||||
|
"${env.CMAKE}" ..
|
||||||
|
"${env.CMAKE}" --build . --config Release
|
||||||
|
|
||||||
|
cd "..\\..\\"
|
||||||
|
|
||||||
|
move "soh\\Release\\soh.exe" ".\\"
|
||||||
|
move "OTRGui\\build\\assets" ".\\"
|
||||||
|
move ".\\OTRExporter\\x64\\Release\\ZAPD.exe" ".\\assets\\extractor\\"
|
||||||
|
move ".\\OTRGui\\build\\Release\\OTRGui.exe" ".\\"
|
||||||
|
rename README.md readme.txt
|
||||||
|
|
||||||
|
"${env.ZIP}" a soh.7z soh.exe OTRGui.exe assets readme.txt
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
archiveArtifacts artifacts: 'soh.7z', followSymlinks: false, onlyIfSuccessful: true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
stage ('Build SoH') {
|
|
||||||
steps {
|
|
||||||
bat """
|
|
||||||
|
|
||||||
"${env.MSBUILD}" ".\\soh\\soh.sln" -t:build -p:Configuration=${env.CONFIG};Platform=${env.PLATFORM};PlatformToolset=${env.TOOLSET} /nodeReuse:false
|
|
||||||
|
|
||||||
"""
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
stage ('Archive artifacts') {
|
|
||||||
steps {
|
|
||||||
bat """
|
|
||||||
|
|
||||||
"${env.ZIP}" a "soh.zip" ".\\soh\\Release\\soh.exe"
|
|
||||||
|
|
||||||
"""
|
|
||||||
|
|
||||||
archiveArtifacts allowEmptyArchive: false,
|
|
||||||
artifacts: 'soh.zip',
|
|
||||||
caseSensitive: true,
|
|
||||||
defaultExcludes: true,
|
|
||||||
fingerprint: false,
|
|
||||||
onlyIfSuccessful: true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
post {
|
post {
|
||||||
always {
|
always {
|
||||||
step([$class: 'Mailer',
|
|
||||||
notifyEveryUnstableBuild: true,
|
|
||||||
recipients: "${env.EMAILTO}",
|
|
||||||
sendToIndividuals: false])
|
|
||||||
step([$class: 'WsCleanup']) // Clean workspace
|
step([$class: 'WsCleanup']) // Clean workspace
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
stage ('Build Linux') {
|
||||||
|
agent {
|
||||||
|
label "SoH-Linux-Builders"
|
||||||
|
}
|
||||||
|
steps {
|
||||||
|
checkout([
|
||||||
|
$class: 'GitSCM',
|
||||||
|
branches: scm.branches,
|
||||||
|
doGenerateSubmoduleConfigurations: scm.doGenerateSubmoduleConfigurations,
|
||||||
|
extensions: scm.extensions,
|
||||||
|
userRemoteConfigs: scm.userRemoteConfigs
|
||||||
|
])
|
||||||
|
catchError(buildResult: 'FAILURE', stageResult: 'FAILURE') {
|
||||||
|
sh '''
|
||||||
|
|
||||||
|
cp ../../ZELOOTD.z64 OTRExporter/baserom_non_mq.z64
|
||||||
|
docker build . -t soh
|
||||||
|
docker run --name sohcont -dit --rm -v $(pwd):/soh soh /bin/bash
|
||||||
|
cp ../../buildsoh.bash soh
|
||||||
|
docker exec sohcont soh/buildsoh.bash
|
||||||
|
|
||||||
|
mkdir build
|
||||||
|
mv soh/soh.elf build/
|
||||||
|
mv OTRGui/build/OTRGui build/
|
||||||
|
mv OTRGui/build/assets build/
|
||||||
|
mv ZAPDTR/ZAPD.out build/assets/extractor/
|
||||||
|
mv README.md build/readme.txt
|
||||||
|
cd build
|
||||||
|
|
||||||
|
7z a soh-linux.7z soh.elf OTRGui assets readme.txt
|
||||||
|
mv soh-linux.7z ../
|
||||||
|
|
||||||
|
'''
|
||||||
|
}
|
||||||
|
sh 'sudo docker container stop sohcont'
|
||||||
|
archiveArtifacts artifacts: 'soh-linux.7z', followSymlinks: false, onlyIfSuccessful: true
|
||||||
|
}
|
||||||
|
post {
|
||||||
|
always {
|
||||||
|
step([$class: 'WsCleanup']) // Clean workspace
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -49,12 +49,12 @@ void OTRExporter_Animation::Save(ZResource* res, const fs::path& outPath, Binary
|
||||||
|
|
||||||
writer->Write((uint32_t)normalAnim->rotationValues.size());
|
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(normalAnim->rotationValues[i]);
|
||||||
|
|
||||||
writer->Write((uint32_t)normalAnim->rotationIndices.size());
|
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].x);
|
||||||
writer->Write(normalAnim->rotationIndices[i].y);
|
writer->Write(normalAnim->rotationIndices[i].y);
|
||||||
|
|
|
@ -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->resList[0]->GetResourceType());
|
||||||
writer->Write((uint32_t)arr->arrayCnt);
|
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)
|
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->scalarType);
|
||||||
writer->Write((uint32_t)vec->dimensions);
|
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...
|
// OTRTODO: Duplicate code here. Cleanup at a later date...
|
||||||
switch (vec->scalarType)
|
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);
|
writer->Write(vec->scalars[k].scalarData.u64);
|
||||||
break;
|
break;
|
||||||
// OTRTODO: ADD OTHER TYPES
|
// 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);
|
writer->Write(scal->scalarData.u64);
|
||||||
break;
|
break;
|
||||||
// OTRTODO: ADD OTHER TYPES
|
// OTRTODO: ADD OTHER TYPES
|
||||||
|
default:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,7 +29,7 @@ void OTRExporter_Cutscene::Save(ZResource* res, const fs::path& outPath, BinaryW
|
||||||
for (auto& e : ((CutsceneCommandSetCameraPos*)cs->commands[i])->entries)
|
for (auto& e : ((CutsceneCommandSetCameraPos*)cs->commands[i])->entries)
|
||||||
{
|
{
|
||||||
writer->Write(CMD_BBH(e->continueFlag, e->cameraRoll, e->nextPointFrame));
|
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->posX, e->posY));
|
||||||
writer->Write(CMD_HH(e->posZ, e->unused));
|
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)
|
for (auto& e : ((CutsceneCommandSetCameraPos*)cs->commands[i])->entries)
|
||||||
{
|
{
|
||||||
writer->Write(CMD_BBH(e->continueFlag, e->cameraRoll, e->nextPointFrame));
|
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->posX, e->posY));
|
||||||
writer->Write(CMD_HH(e->posZ, e->unused));
|
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)
|
for (auto& e : ((CutsceneCommandSetCameraPos*)cs->commands[i])->entries)
|
||||||
{
|
{
|
||||||
writer->Write(CMD_BBH(e->continueFlag, e->cameraRoll, e->nextPointFrame));
|
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->posX, e->posY));
|
||||||
writer->Write(CMD_HH(e->posZ, e->unused));
|
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)
|
for (auto& e : ((CutsceneCommandSetCameraPos*)cs->commands[i])->entries)
|
||||||
{
|
{
|
||||||
writer->Write(CMD_BBH(e->continueFlag, e->cameraRoll, e->nextPointFrame));
|
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->posX, e->posY));
|
||||||
writer->Write(CMD_HH(e->posZ, e->unused));
|
writer->Write(CMD_HH(e->posZ, e->unused));
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,20 +29,6 @@
|
||||||
Ab1, Ad1)) \
|
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) \
|
#define gsSPBranchLessZraw2(dl, vtx, zval) \
|
||||||
{ _SHIFTL(G_BRANCH_Z,24,8)|_SHIFTL((vtx)*5,12,12)|_SHIFTL((vtx)*2,0,12),\
|
{ _SHIFTL(G_BRANCH_Z,24,8)|_SHIFTL((vtx)*5,12,12)|_SHIFTL((vtx)*2,0,12),\
|
||||||
(unsigned int)(zval), }
|
(unsigned int)(zval), }
|
||||||
|
@ -71,7 +57,7 @@ void OTRExporter_DisplayList::Save(ZResource* res, const fs::path& outPath, Bina
|
||||||
|
|
||||||
// DEBUG: Write in a marker
|
// DEBUG: Write in a marker
|
||||||
Declaration* dbgDecl = dList->parent->GetDeclaration(dList->GetRawDataIndex());
|
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());
|
uint64_t hash = CRC64(dbgName.c_str());
|
||||||
writer->Write((uint32_t)(G_MARKER << 24));
|
writer->Write((uint32_t)(G_MARKER << 24));
|
||||||
writer->Write((uint32_t)0xBEEFBEEF);
|
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();
|
auto dlStart = std::chrono::steady_clock::now();
|
||||||
|
|
||||||
//for (auto data : dList->instructions)
|
//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];
|
auto data = dList->instructions[dataIdx];
|
||||||
uint32_t word0 = 0;
|
uint32_t word0 = 0;
|
||||||
|
@ -216,7 +202,7 @@ void OTRExporter_DisplayList::Save(ZResource* res, const fs::path& outPath, Bina
|
||||||
|
|
||||||
pp ^= G_MTX_PUSH;
|
pp ^= G_MTX_PUSH;
|
||||||
|
|
||||||
mm = (mm & 0x0FFFFFFF) + 0xF0000000;
|
mm = (mm & 0x0FFFFFFF) + 1;
|
||||||
|
|
||||||
Gfx value = gsSPMatrix(mm, pp);
|
Gfx value = gsSPMatrix(mm, pp);
|
||||||
word0 = value.words.w0;
|
word0 = value.words.w0;
|
||||||
|
@ -243,7 +229,7 @@ void OTRExporter_DisplayList::Save(ZResource* res, const fs::path& outPath, Bina
|
||||||
|
|
||||||
if (mtxDecl != nullptr)
|
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());
|
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)
|
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());
|
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 = StringHelper::Sprintf("%s\\%s", GetParentFolderName(res).c_str(), dListDecl2->varName.c_str());
|
||||||
std::string fName = OTRExporter_DisplayList::GetPathToRes(res, 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();
|
MemoryStream* dlStream = new MemoryStream();
|
||||||
BinaryWriter dlWriter = BinaryWriter(dlStream);
|
BinaryWriter dlWriter = BinaryWriter(dlStream);
|
||||||
|
@ -383,7 +369,7 @@ void OTRExporter_DisplayList::Save(ZResource* res, const fs::path& outPath, Bina
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (Globals::Instance->fileMode != ZFileMode::ExtractDirectory)
|
if (Globals::Instance->fileMode != ZFileMode::ExtractDirectory)
|
||||||
File::WriteAllBytes("Extract\\" + fName, dlStream->ToVector());
|
File::WriteAllBytes("Extract/" + fName, dlStream->ToVector());
|
||||||
else
|
else
|
||||||
files[fName] = dlStream->ToVector();
|
files[fName] = dlStream->ToVector();
|
||||||
|
|
||||||
|
@ -411,7 +397,7 @@ void OTRExporter_DisplayList::Save(ZResource* res, const fs::path& outPath, Bina
|
||||||
|
|
||||||
Gfx value;
|
Gfx value;
|
||||||
|
|
||||||
u32 dListVal = (data & 0x0FFFFFFF) + 0xF0000000;
|
u32 dListVal = (data & 0x0FFFFFFF) + 1;
|
||||||
|
|
||||||
if (pp != 0)
|
if (pp != 0)
|
||||||
value = gsSPBranchList(dListVal);
|
value = gsSPBranchList(dListVal);
|
||||||
|
@ -444,7 +430,7 @@ void OTRExporter_DisplayList::Save(ZResource* res, const fs::path& outPath, Bina
|
||||||
|
|
||||||
if (dListDecl != nullptr)
|
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());
|
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 = StringHelper::Sprintf("%s\\%s", GetParentFolderName(res).c_str(), dListDecl2->varName.c_str());
|
||||||
std::string fName = OTRExporter_DisplayList::GetPathToRes(res, 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();
|
MemoryStream* dlStream = new MemoryStream();
|
||||||
BinaryWriter dlWriter = BinaryWriter(dlStream);
|
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);
|
Save(dList->otherDLists[i], outPath, &dlWriter);
|
||||||
|
|
||||||
if (Globals::Instance->fileMode != ZFileMode::ExtractDirectory)
|
if (Globals::Instance->fileMode != ZFileMode::ExtractDirectory)
|
||||||
File::WriteAllBytes("Extract\\" + fName, dlStream->ToVector());
|
File::WriteAllBytes("Extract/" + fName, dlStream->ToVector());
|
||||||
else
|
else
|
||||||
files[fName] = dlStream->ToVector();
|
files[fName] = dlStream->ToVector();
|
||||||
}
|
}
|
||||||
|
@ -689,7 +675,7 @@ void OTRExporter_DisplayList::Save(ZResource* res, const fs::path& outPath, Bina
|
||||||
uint32_t fmt = (__ & 0xE0) >> 5;
|
uint32_t fmt = (__ & 0xE0) >> 5;
|
||||||
uint32_t siz = (__ & 0x18) >> 3;
|
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;
|
word0 = value.words.w0;
|
||||||
word1 = value.words.w1;
|
word1 = value.words.w1;
|
||||||
|
|
||||||
|
@ -753,7 +739,7 @@ void OTRExporter_DisplayList::Save(ZResource* res, const fs::path& outPath, Bina
|
||||||
Gfx value = gsSPVertex(data & 0xFFFFFFFF, nn, ((aa >> 1) - nn));
|
Gfx value = gsSPVertex(data & 0xFFFFFFFF, nn, ((aa >> 1) - nn));
|
||||||
|
|
||||||
word0 = value.words.w0;
|
word0 = value.words.w0;
|
||||||
word1 = value.words.w1 | 0xF0000000;
|
word1 = value.words.w1 | 1;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -790,7 +776,7 @@ void OTRExporter_DisplayList::Save(ZResource* res, const fs::path& outPath, Bina
|
||||||
word0 = hash >> 32;
|
word0 = hash >> 32;
|
||||||
word1 = hash & 0xFFFFFFFF;
|
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
|
// Write vertices to file
|
||||||
MemoryStream* vtxStream = new MemoryStream();
|
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");
|
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];
|
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)
|
if (Globals::Instance->fileMode != ZFileMode::ExtractDirectory)
|
||||||
File::WriteAllBytes("Extract\\" + fName, vtxStream->ToVector());
|
File::WriteAllBytes("Extract/" + fName, vtxStream->ToVector());
|
||||||
else
|
else
|
||||||
files[fName] = vtxStream->ToVector();
|
files[fName] = vtxStream->ToVector();
|
||||||
|
|
||||||
|
@ -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 OTRExporter_DisplayList::GetPathToRes(ZResource* res, std::string varName)
|
||||||
{
|
{
|
||||||
std::string prefix = GetPrefix(res);
|
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;
|
return fName;
|
||||||
}
|
}
|
||||||
|
@ -886,7 +872,7 @@ std::string OTRExporter_DisplayList::GetParentFolderName(ZResource* res)
|
||||||
{
|
{
|
||||||
auto split = StringHelper::Split(oName, "_");
|
auto split = StringHelper::Split(oName, "_");
|
||||||
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 += split[i] + "_";
|
||||||
|
|
||||||
oName += "scene";
|
oName += "scene";
|
||||||
|
@ -897,7 +883,7 @@ std::string OTRExporter_DisplayList::GetParentFolderName(ZResource* res)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (prefix != "")
|
if (prefix != "")
|
||||||
oName = prefix + "\\" + oName;
|
oName = prefix + "/" + oName;
|
||||||
|
|
||||||
return oName;
|
return oName;
|
||||||
}
|
}
|
||||||
|
|
|
@ -52,7 +52,7 @@ static void ExporterParseFileMode(const std::string& buildMode, ZFileMode& fileM
|
||||||
for (auto item : lst)
|
for (auto item : lst)
|
||||||
{
|
{
|
||||||
auto fileData = File::ReadAllBytes(item);
|
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)
|
for (auto item : lst)
|
||||||
{
|
{
|
||||||
auto fileData = File::ReadAllBytes(item);
|
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());
|
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)
|
static void ExporterFileEnd(ZFile* file)
|
||||||
{
|
{
|
||||||
int bp = 0;
|
// delete fileWriter;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ExporterResourceEnd(ZResource* res, BinaryWriter& writer)
|
static void ExporterResourceEnd(ZResource* res, BinaryWriter& writer)
|
||||||
|
@ -140,7 +140,7 @@ static void ExporterResourceEnd(ZResource* res, BinaryWriter& writer)
|
||||||
{
|
{
|
||||||
auto split = StringHelper::Split(oName, "_");
|
auto split = StringHelper::Split(oName, "_");
|
||||||
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 += split[i] + "_";
|
||||||
|
|
||||||
oName += "scene";
|
oName += "scene";
|
||||||
|
@ -153,14 +153,14 @@ static void ExporterResourceEnd(ZResource* res, BinaryWriter& writer)
|
||||||
std::string fName = "";
|
std::string fName = "";
|
||||||
|
|
||||||
if (prefix != "")
|
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
|
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)
|
if (Globals::Instance->fileMode == ZFileMode::ExtractDirectory)
|
||||||
files[fName] = strem->ToVector();
|
files[fName] = strem->ToVector();
|
||||||
else
|
else
|
||||||
File::WriteAllBytes("Extract\\" + fName, strem->ToVector());
|
File::WriteAllBytes("Extract/" + fName, strem->ToVector());
|
||||||
}
|
}
|
||||||
|
|
||||||
auto end = std::chrono::steady_clock::now();
|
auto end = std::chrono::steady_clock::now();
|
||||||
|
|
|
@ -39,13 +39,13 @@ D_FILES := $(O_FILES:%.o=%.d)
|
||||||
LIB := OTRExporter.a
|
LIB := OTRExporter.a
|
||||||
|
|
||||||
INC_DIRS := $(addprefix -I, \
|
INC_DIRS := $(addprefix -I, \
|
||||||
../../ZAPD/ZAPD \
|
../../ZAPDTR/ZAPD \
|
||||||
../../ZAPD/lib/tinyxml2 \
|
../../ZAPDTR/lib/tinyxml2 \
|
||||||
../../ZAPD/lib/libgfxd \
|
../../ZAPDTR/lib/libgfxd \
|
||||||
../../ZAPD/ZAPDUtils \
|
../../ZAPDTR/ZAPDUtils \
|
||||||
../../OtrLib/otrlib \
|
../../libultraship/libultraship \
|
||||||
../../OtrLib/otrlib/Lib/spdlog/include \
|
../../libultraship/libultraship/Lib/spdlog/include \
|
||||||
../../OtrLib/otrlib/Lib/Fast3D/U64 \
|
../../libultraship/libultraship/Lib/Fast3D/U64 \
|
||||||
)
|
)
|
||||||
|
|
||||||
# create build directories
|
# create build directories
|
||||||
|
|
|
@ -9,11 +9,11 @@ void OTRExporter_Path::Save(ZResource* res, const fs::path& outPath, BinaryWrite
|
||||||
|
|
||||||
writer->Write((uint32_t)path->pathways.size());
|
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());
|
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[0].scalarData.s16);
|
||||||
writer->Write(path->pathways[k].points[i].scalars[1].scalarData.s16);
|
writer->Write(path->pathways[k].points[i].scalars[1].scalarData.s16);
|
||||||
|
|
|
@ -172,7 +172,7 @@ void OTRExporter_Room::Save(ZResource* res, const fs::path& outPath, BinaryWrite
|
||||||
|
|
||||||
writer->Write((uint32_t)cmdCsCam->points.size());
|
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[0].scalarData.s16);
|
||||||
writer->Write(cmdCsCam->points[i].scalars[1].scalarData.s16);
|
writer->Write(cmdCsCam->points[i].scalars[1].scalarData.s16);
|
||||||
|
@ -207,12 +207,12 @@ void OTRExporter_Room::Save(ZResource* res, const fs::path& outPath, BinaryWrite
|
||||||
Declaration* dListDeclXlu = poly->parent->GetDeclaration(GETSEGOFFSET(test->xlu));
|
Declaration* dListDeclXlu = poly->parent->GetDeclaration(GETSEGOFFSET(test->xlu));
|
||||||
|
|
||||||
if (test->opa != 0)
|
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
|
else
|
||||||
writer->Write("");
|
writer->Write("");
|
||||||
|
|
||||||
if (test->xlu != 0)
|
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
|
else
|
||||||
writer->Write("");
|
writer->Write("");
|
||||||
|
|
||||||
|
@ -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++)
|
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));
|
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(roomName);
|
||||||
writer->Write(cmdRoom->romfile->rooms[i].virtualAddressStart);
|
writer->Write(cmdRoom->romfile->rooms[i].virtualAddressStart);
|
||||||
|
@ -454,7 +454,7 @@ void OTRExporter_Room::Save(ZResource* res, const fs::path& outPath, BinaryWrite
|
||||||
cs.Save(cmdSetCutscenes->cutscenes[0], "", &csWriter);
|
cs.Save(cmdSetCutscenes->cutscenes[0], "", &csWriter);
|
||||||
|
|
||||||
if (Globals::Instance->fileMode != ZFileMode::ExtractDirectory)
|
if (Globals::Instance->fileMode != ZFileMode::ExtractDirectory)
|
||||||
File::WriteAllBytes("Extract\\" + fName, csStream->ToVector());
|
File::WriteAllBytes("Extract/" + fName, csStream->ToVector());
|
||||||
else
|
else
|
||||||
files[fName] = csStream->ToVector();
|
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());
|
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));
|
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());
|
//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);
|
pathExp.Save(&cmdSetPathways->pathwayList, outPath, &pathWriter);
|
||||||
|
|
||||||
if (Globals::Instance->fileMode != ZFileMode::ExtractDirectory)
|
if (Globals::Instance->fileMode != ZFileMode::ExtractDirectory)
|
||||||
File::WriteAllBytes("Extract\\" + path, pathStream->ToVector());
|
File::WriteAllBytes("Extract/" + path, pathStream->ToVector());
|
||||||
else
|
else
|
||||||
files[path] = pathStream->ToVector();
|
files[path] = pathStream->ToVector();
|
||||||
|
|
||||||
|
@ -514,12 +514,12 @@ void OTRExporter_Room::WritePolyDList(BinaryWriter* writer, ZRoom* room, Polygon
|
||||||
writer->Write(dlist->unk_06);
|
writer->Write(dlist->unk_06);
|
||||||
[[fallthrough]];
|
[[fallthrough]];
|
||||||
default:
|
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)
|
if (dlist->opaDList != nullptr)
|
||||||
{
|
{
|
||||||
auto opaDecl = room->parent->GetDeclaration(GETSEGOFFSET(dlist->opaDList->GetRawDataIndex()));
|
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
|
else
|
||||||
writer->Write("");
|
writer->Write("");
|
||||||
|
@ -527,7 +527,7 @@ void OTRExporter_Room::WritePolyDList(BinaryWriter* writer, ZRoom* room, Polygon
|
||||||
if (dlist->xluDList != nullptr)
|
if (dlist->xluDList != nullptr)
|
||||||
{
|
{
|
||||||
auto xluDecl = room->parent->GetDeclaration(GETSEGOFFSET(dlist->xluDList->GetRawDataIndex()));
|
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
|
else
|
||||||
writer->Write("");
|
writer->Write("");
|
||||||
|
|
|
@ -9,7 +9,7 @@ void OTRExporter_Text::Save(ZResource* res, const fs::path& outPath, BinaryWrite
|
||||||
|
|
||||||
writer->Write((uint32_t)txt->messages.size());
|
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].id);
|
||||||
writer->Write(txt->messages[i].textboxType);
|
writer->Write(txt->messages[i].textboxType);
|
||||||
|
|
|
@ -5,21 +5,23 @@ std::map<Ship::ResourceType, uint32_t> resourceVersions;
|
||||||
|
|
||||||
void InitVersionInfo()
|
void InitVersionInfo()
|
||||||
{
|
{
|
||||||
resourceVersions[Ship::ResourceType::Animation] = 0;
|
resourceVersions = {
|
||||||
resourceVersions[Ship::ResourceType::Model] = 0;
|
{ Ship::ResourceType::Animation, 0 },
|
||||||
resourceVersions[Ship::ResourceType::Texture] = 0;
|
{ Ship::ResourceType::Model, 0 },
|
||||||
resourceVersions[Ship::ResourceType::Material] = 0;
|
{ Ship::ResourceType::Texture, 0 },
|
||||||
resourceVersions[Ship::ResourceType::PlayerAnimation] = 0;
|
{ Ship::ResourceType::Material, 0 },
|
||||||
resourceVersions[Ship::ResourceType::DisplayList] = 0;
|
{ Ship::ResourceType::PlayerAnimation, 0 },
|
||||||
resourceVersions[Ship::ResourceType::Room] = 0;
|
{ Ship::ResourceType::DisplayList, 0 },
|
||||||
resourceVersions[Ship::ResourceType::CollisionHeader] = 0;
|
{ Ship::ResourceType::Room, 0 },
|
||||||
resourceVersions[Ship::ResourceType::Skeleton] = 0;
|
{ Ship::ResourceType::CollisionHeader, 0 },
|
||||||
resourceVersions[Ship::ResourceType::SkeletonLimb] = 0;
|
{ Ship::ResourceType::Skeleton, 0 },
|
||||||
resourceVersions[Ship::ResourceType::Matrix] = 0;
|
{ Ship::ResourceType::SkeletonLimb, 0 },
|
||||||
resourceVersions[Ship::ResourceType::Path] = 0;
|
{ Ship::ResourceType::Matrix, 0 },
|
||||||
resourceVersions[Ship::ResourceType::Vertex] = 0;
|
{ Ship::ResourceType::Path, 0 },
|
||||||
resourceVersions[Ship::ResourceType::Cutscene] = 0;
|
{ Ship::ResourceType::Vertex, 0 },
|
||||||
resourceVersions[Ship::ResourceType::Array] = 0;
|
{ Ship::ResourceType::Cutscene, 0 },
|
||||||
resourceVersions[Ship::ResourceType::Text] = 0;
|
{ Ship::ResourceType::Array, 0 },
|
||||||
resourceVersions[Ship::ResourceType::Blob] = 0;
|
{ Ship::ResourceType::Text, 0 },
|
||||||
|
{ Ship::ResourceType::Blob, 0 },
|
||||||
|
};
|
||||||
}
|
}
|
BIN
OTRExporter/assets/ship_of_harkinian/fonts/Fipps-Regular.otf
Normal file
BIN
OTRExporter/assets/ship_of_harkinian/fonts/Fipps-Regular.otf
Normal file
Binary file not shown.
Binary file not shown.
|
@ -10,42 +10,14 @@
|
||||||
import json, os, signal, time, sys, shutil, glob
|
import json, os, signal, time, sys, shutil, glob
|
||||||
from multiprocessing import Pool, cpu_count, Event, Manager, ProcessError
|
from multiprocessing import Pool, cpu_count, Event, Manager, ProcessError
|
||||||
from enum import Enum
|
from enum import Enum
|
||||||
import shutil
|
from rom_info import Z64Rom
|
||||||
|
import rom_chooser
|
||||||
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
|
|
||||||
]
|
|
||||||
|
|
||||||
def BuildOTR(xmlPath, rom):
|
def BuildOTR(xmlPath, rom):
|
||||||
shutil.copytree("assets", "Extract/assets")
|
shutil.copytree("assets", "Extract/assets")
|
||||||
|
|
||||||
execStr = "x64\\Release\\ZAPD.exe" if sys.platform == "win32" else "../ZAPD/ZAPD.out"
|
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)
|
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)
|
print(execStr)
|
||||||
exitValue = os.system(execStr)
|
exitValue = os.system(execStr)
|
||||||
|
@ -55,28 +27,6 @@ def BuildOTR(xmlPath, rom):
|
||||||
print("Aborting...", file=os.sys.stderr)
|
print("Aborting...", file=os.sys.stderr)
|
||||||
print("\n")
|
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():
|
def main():
|
||||||
|
|
||||||
romToUse = "";
|
romToUse = "";
|
||||||
|
@ -135,7 +85,7 @@ def main():
|
||||||
if (os.path.exists("Extract")):
|
if (os.path.exists("Extract")):
|
||||||
shutil.rmtree("Extract")
|
shutil.rmtree("Extract")
|
||||||
|
|
||||||
BuildOTR("..\\soh\\assets\\xml\\" + xmlVer + "\\", romToUse)
|
BuildOTR("../soh/assets/xml/" + rom.version.xml_ver + "/", rom_path)
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
main()
|
main()
|
||||||
|
|
|
@ -1,125 +0,0 @@
|
||||||
#!/usr/bin/env python3
|
|
||||||
|
|
||||||
import argparse, json, os, signal, time, sys, shutil
|
|
||||||
from multiprocessing import Pool, cpu_count, Event, Manager, ProcessError
|
|
||||||
import shutil
|
|
||||||
|
|
||||||
def SignalHandler(sig, frame):
|
|
||||||
print(f'Signal {sig} received. Aborting...')
|
|
||||||
mainAbort.set()
|
|
||||||
# Don't exit immediately to update the extracted assets file.
|
|
||||||
|
|
||||||
def BuildOTR():
|
|
||||||
shutil.copyfile("baserom/Audiobank", "Extract/Audiobank")
|
|
||||||
shutil.copyfile("baserom/Audioseq", "Extract/Audioseq")
|
|
||||||
shutil.copyfile("baserom/Audiotable", "Extract/Audiotable")
|
|
||||||
|
|
||||||
shutil.copytree("assets", "Extract/assets")
|
|
||||||
|
|
||||||
execStr = "x64\\Release\\ZAPD.exe" if sys.platform == "win32" else "../ZAPD/ZAPD.out"
|
|
||||||
|
|
||||||
execStr += " botr -se OTR"
|
|
||||||
|
|
||||||
print(execStr)
|
|
||||||
exitValue = os.system(execStr)
|
|
||||||
if exitValue != 0:
|
|
||||||
print("\n")
|
|
||||||
print("Error when building the OTR file...", file=os.sys.stderr)
|
|
||||||
print("Aborting...", file=os.sys.stderr)
|
|
||||||
print("\n")
|
|
||||||
|
|
||||||
def ExtractFile(xmlPath, outputPath, outputSourcePath):
|
|
||||||
execStr = "x64\\Release\\ZAPD.exe" if sys.platform == "win32" else "../ZAPD/ZAPD.out"
|
|
||||||
execStr += " e -eh -i %s -b baserom/ -o %s -osf %s -gsf 1 -rconf CFG/Config.xml -se OTR" % (xmlPath, outputPath, outputSourcePath)
|
|
||||||
|
|
||||||
if "overlays" in xmlPath:
|
|
||||||
execStr += " --static"
|
|
||||||
|
|
||||||
print(execStr)
|
|
||||||
exitValue = os.system(execStr)
|
|
||||||
#exitValue = 0
|
|
||||||
if exitValue != 0:
|
|
||||||
print("\n")
|
|
||||||
print("Error when extracting from file " + xmlPath, file=os.sys.stderr)
|
|
||||||
print("Aborting...", file=os.sys.stderr)
|
|
||||||
print("\n")
|
|
||||||
|
|
||||||
def ExtractFunc(fullPath):
|
|
||||||
*pathList, xmlName = fullPath.split(os.sep)
|
|
||||||
objectName = os.path.splitext(xmlName)[0]
|
|
||||||
|
|
||||||
outPath = os.path.join("..\\soh\\assets\\", *pathList[5:], objectName)
|
|
||||||
os.makedirs(outPath, exist_ok=True)
|
|
||||||
outSourcePath = outPath
|
|
||||||
|
|
||||||
ExtractFile(fullPath, outPath, outSourcePath)
|
|
||||||
|
|
||||||
def initializeWorker(abort, test):
|
|
||||||
global globalAbort
|
|
||||||
globalAbort = abort
|
|
||||||
|
|
||||||
|
|
||||||
def main():
|
|
||||||
parser = argparse.ArgumentParser(description="baserom asset extractor")
|
|
||||||
parser.add_argument("-s", "--single", help="asset path relative to assets/, e.g. objects/gameplay_keep")
|
|
||||||
parser.add_argument("-f", "--force", help="Force the extraction of every xml instead of checking the touched ones.", action="store_true")
|
|
||||||
parser.add_argument("-u", "--unaccounted", help="Enables ZAPD unaccounted detector warning system.", action="store_true")
|
|
||||||
parser.add_argument("-v", "--version", help="Sets game version.")
|
|
||||||
args = parser.parse_args()
|
|
||||||
|
|
||||||
global mainAbort
|
|
||||||
mainAbort = Event()
|
|
||||||
manager = Manager()
|
|
||||||
signal.signal(signal.SIGINT, SignalHandler)
|
|
||||||
|
|
||||||
extractedAssetsTracker = manager.dict()
|
|
||||||
|
|
||||||
xmlVer = "GC_NMQ_D"
|
|
||||||
|
|
||||||
if (args.version == "gc_pal_nmpq"):
|
|
||||||
xmlVer = "GC_NMQ_PAL_F"
|
|
||||||
elif (args.version == "dbg_mq"):
|
|
||||||
xmlVer = "GC_MQ_D"
|
|
||||||
|
|
||||||
asset_path = args.single
|
|
||||||
if asset_path is not None:
|
|
||||||
fullPath = os.path.join("..\\soh\\assets", "xml", asset_path + ".xml")
|
|
||||||
if not os.path.exists(fullPath):
|
|
||||||
print(f"Error. File {fullPath} doesn't exists.", file=os.sys.stderr)
|
|
||||||
exit(1)
|
|
||||||
|
|
||||||
ExtractFunc(fullPath)
|
|
||||||
else:
|
|
||||||
extract_text_path = "assets/text/message_data.h"
|
|
||||||
if os.path.isfile(extract_text_path):
|
|
||||||
extract_text_path = None
|
|
||||||
extract_staff_text_path = "assets/text/message_data_staff.h"
|
|
||||||
if os.path.isfile(extract_staff_text_path):
|
|
||||||
extract_staff_text_path = None
|
|
||||||
|
|
||||||
xmlFiles = []
|
|
||||||
for currentPath, _, files in os.walk(os.path.join("..\\soh\\assets\\xml\\", xmlVer)):
|
|
||||||
for file in files:
|
|
||||||
fullPath = os.path.join(currentPath, file)
|
|
||||||
if file.endswith(".xml"):
|
|
||||||
xmlFiles.append(fullPath)
|
|
||||||
|
|
||||||
try:
|
|
||||||
numCores = 2
|
|
||||||
print("Extracting assets with " + str(numCores) + " CPU cores.")
|
|
||||||
with Pool(numCores, initializer=initializeWorker, initargs=(mainAbort, 0)) as p:
|
|
||||||
p.map(ExtractFunc, xmlFiles)
|
|
||||||
except Exception as e:
|
|
||||||
print("Warning: Multiprocessing exception ocurred.", file=os.sys.stderr)
|
|
||||||
print("Disabling mutliprocessing.", file=os.sys.stderr)
|
|
||||||
|
|
||||||
initializeWorker(mainAbort, 0)
|
|
||||||
for singlePath in xmlFiles:
|
|
||||||
ExtractFunc(singlePath)
|
|
||||||
|
|
||||||
|
|
||||||
BuildOTR()
|
|
||||||
shutil.rmtree("Extract")
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
main()
|
|
53
OTRExporter/extract_baserom.py
Normal file
53
OTRExporter/extract_baserom.py
Normal 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
37
OTRExporter/rom_chooser.py
Normal file
37
OTRExporter/rom_chooser.py
Normal 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
87
OTRExporter/rom_info.py
Normal 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
|
|
@ -67,7 +67,7 @@ void OTRGame::init(){
|
||||||
mat.shader = shader;
|
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;
|
hide_second_btn = true;
|
||||||
sohFolder = ".";
|
sohFolder = ".";
|
||||||
}
|
}
|
||||||
|
|
15
README.md
15
README.md
|
@ -7,14 +7,21 @@ The Ship does not include assets and as such requires a prior copy of the game t
|
||||||
## Quick Start
|
## Quick Start
|
||||||
|
|
||||||
1) Download The Ship of Harkinian from Discord.
|
1) Download The Ship of Harkinian from Discord.
|
||||||
2) Requires an `oot debug` rom (not Master Quest).
|
2) Requires a supported copy of the game (See supported games below).
|
||||||
|
3) Use the OTRGui to generate an `oot.otr` archive file.
|
||||||
|
4) Launch `soh.exe`
|
||||||
|
|
||||||
|
### Supported Games
|
||||||
|
Ocarina of Time Debug (not Master Quest)
|
||||||
```
|
```
|
||||||
Build team: `zelda@srd022j`
|
Build team: `zelda@srd022j`
|
||||||
Build date: `03-02-21 00:49:18` (year-month-day)
|
Build date: `03-02-21 00:49:18` (year-month-day)
|
||||||
sha1: cee6bc3c2a634b41728f2af8da54d9bf8cc14099
|
sha1: cee6bc3c2a634b41728f2af8da54d9bf8cc14099
|
||||||
```
|
```
|
||||||
3) Use the OTRGui to generate an `oot.otr` archive file.
|
Ocarina of Time Pal Gamecube
|
||||||
4) Launch `soh.exe`
|
```
|
||||||
|
sha1: d0c95b2cb3c6682a171db267932af7af8cf5fa82
|
||||||
|
```
|
||||||
|
|
||||||
Congratulations, you are now sailing with the Ship of Harkinian! Have fun!
|
Congratulations, you are now sailing with the Ship of Harkinian! Have fun!
|
||||||
|
|
||||||
|
@ -51,7 +58,7 @@ Official Discord: https://discord.com/invite/BtBmd55HVH
|
||||||
|
|
||||||
## Building The Ship of Harkinian
|
## Building The Ship of Harkinian
|
||||||
|
|
||||||
Refer to the [building instructions](https://github.com/HarbourMasters/Shipwright/BUILDING.md) to compile SoH.
|
Refer to the [building instructions](BUILDING.md) to compile SoH.
|
||||||
|
|
||||||
## Troubleshooting The Exporter
|
## Troubleshooting The Exporter
|
||||||
- Affirm that you have an `/assets` folder filled with XMLs in the same directory as OTRGui.exe
|
- Affirm that you have an `/assets` folder filled with XMLs in the same directory as OTRGui.exe
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
#include "CollisionExporter.h"
|
#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)
|
BinaryWriter* writer)
|
||||||
{
|
{
|
||||||
ZCollisionHeader* col = (ZCollisionHeader*)res;
|
ZCollisionHeader* col = (ZCollisionHeader*)res;
|
||||||
|
|
|
@ -6,5 +6,5 @@
|
||||||
class ExporterExample_Collision : public ZResourceExporter
|
class ExporterExample_Collision : public ZResourceExporter
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
void Save(ZResource* res, fs::path outPath, BinaryWriter* writer) override;
|
void Save(ZResource* res, const fs::path& outPath, BinaryWriter* writer) override;
|
||||||
};
|
};
|
|
@ -20,7 +20,7 @@
|
||||||
#include "ZRoom/Commands/SetTimeSettings.h"
|
#include "ZRoom/Commands/SetTimeSettings.h"
|
||||||
#include "ZRoom/Commands/SetWind.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);
|
ZRoom* room = dynamic_cast<ZRoom*>(res);
|
||||||
|
|
||||||
|
|
|
@ -6,5 +6,5 @@
|
||||||
class ExporterExample_Room : public ZResourceExporter
|
class ExporterExample_Room : public ZResourceExporter
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
void Save(ZResource* res, fs::path outPath, BinaryWriter* writer) override;
|
void Save(ZResource* res, const fs::path& outPath, BinaryWriter* writer) override;
|
||||||
};
|
};
|
|
@ -1,7 +1,7 @@
|
||||||
#include "TextureExporter.h"
|
#include "TextureExporter.h"
|
||||||
#include "../ZAPD/ZFile.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)
|
BinaryWriter* writer)
|
||||||
{
|
{
|
||||||
ZTexture* tex = (ZTexture*)res;
|
ZTexture* tex = (ZTexture*)res;
|
||||||
|
|
|
@ -7,5 +7,5 @@
|
||||||
class ExporterExample_Texture : public ZResourceExporter
|
class ExporterExample_Texture : public ZResourceExporter
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
void Save(ZResource* res, fs::path outPath, BinaryWriter* writer) override;
|
void Save(ZResource* res, const fs::path& outPath, BinaryWriter* writer) override;
|
||||||
};
|
};
|
|
@ -44,7 +44,8 @@ ifneq ($(DEPRECATION_ON),0)
|
||||||
endif
|
endif
|
||||||
# CXXFLAGS += -DTEXTURE_DEBUG
|
# 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
|
# Use LLD if available. Set LLD=0 to not use it
|
||||||
ifeq ($(shell command -v ld.lld >/dev/null 2>&1; echo $$?),0)
|
ifeq ($(shell command -v ld.lld >/dev/null 2>&1; echo $$?),0)
|
||||||
|
@ -59,9 +60,9 @@ UNAME := $(shell uname)
|
||||||
UNAMEM := $(shell uname -m)
|
UNAMEM := $(shell uname -m)
|
||||||
ifneq ($(UNAME), Darwin)
|
ifneq ($(UNAME), Darwin)
|
||||||
LDFLAGS += -Wl,-export-dynamic -lstdc++fs
|
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
|
else
|
||||||
EXPORTERS := -Wl,-force_load ExporterTest/ExporterTest.a
|
EXPORTERS := -Wl,-force_load ../OTRExporter/OTRExporter/OTRExporter.a
|
||||||
ifeq ($(UNAMEM),arm64)
|
ifeq ($(UNAMEM),arm64)
|
||||||
ifeq ($(shell brew list libpng > /dev/null 2>&1; echo $$?),0)
|
ifeq ($(shell brew list libpng > /dev/null 2>&1; echo $$?),0)
|
||||||
LDFLAGS += -L $(shell brew --prefix)/lib
|
LDFLAGS += -L $(shell brew --prefix)/lib
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
#include "ZFile.h"
|
#include "ZFile.h"
|
||||||
#include "ZTexture.h"
|
#include "ZTexture.h"
|
||||||
|
|
||||||
#if !defined(_MSC_VER) && !defined(__CYGWIN__)
|
#ifdef __linux__
|
||||||
#include <csignal>
|
#include <csignal>
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
#include <ctime>
|
#include <ctime>
|
||||||
|
@ -28,6 +28,31 @@
|
||||||
//extern const char gBuildHash[];
|
//extern const char gBuildHash[];
|
||||||
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,
|
bool Parse(const fs::path& xmlFilePath, const fs::path& basePath, const fs::path& outPath,
|
||||||
ZFileMode fileMode, int workerID);
|
ZFileMode fileMode, int workerID);
|
||||||
|
|
||||||
|
@ -38,7 +63,7 @@ int ExtractFunc(int workerID, int fileListSize, std::string fileListItem, ZFileM
|
||||||
|
|
||||||
volatile int numWorkersLeft = 0;
|
volatile int numWorkersLeft = 0;
|
||||||
|
|
||||||
#if !defined(_MSC_VER) && !defined(__CYGWIN__)
|
#ifdef __linux__
|
||||||
#define ARRAY_COUNT(arr) (sizeof(arr) / sizeof(arr[0]))
|
#define ARRAY_COUNT(arr) (sizeof(arr) / sizeof(arr[0]))
|
||||||
void ErrorHandler(int sig)
|
void ErrorHandler(int sig)
|
||||||
{
|
{
|
||||||
|
@ -196,7 +221,7 @@ int main(int argc, char* argv[])
|
||||||
}
|
}
|
||||||
else if (arg == "-eh") // Enable Error Handler
|
else if (arg == "-eh") // Enable Error Handler
|
||||||
{
|
{
|
||||||
#if !defined(_MSC_VER) && !defined(__CYGWIN__)
|
#ifdef __linux__
|
||||||
signal(SIGSEGV, ErrorHandler);
|
signal(SIGSEGV, ErrorHandler);
|
||||||
signal(SIGABRT, ErrorHandler);
|
signal(SIGABRT, ErrorHandler);
|
||||||
#else
|
#else
|
||||||
|
@ -453,6 +478,7 @@ int ExtractFunc(int workerID, int fileListSize, std::string fileListItem, ZFileM
|
||||||
|
|
||||||
numWorkersLeft--;
|
numWorkersLeft--;
|
||||||
}
|
}
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Parse(const fs::path& xmlFilePath, const fs::path& basePath, const fs::path& outPath,
|
bool Parse(const fs::path& xmlFilePath, const fs::path& basePath, const fs::path& outPath,
|
||||||
|
|
|
@ -96,7 +96,7 @@ int OutputFormatter::Write(const std::string& buf)
|
||||||
return Write(buf.data(), buf.size());
|
return Write(buf.data(), buf.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
__declspec(thread) OutputFormatter* OutputFormatter::Instance;
|
thread_local OutputFormatter* OutputFormatter::Instance;
|
||||||
|
|
||||||
int OutputFormatter::WriteStatic(const char* buf, int count)
|
int OutputFormatter::WriteStatic(const char* buf, int count)
|
||||||
{
|
{
|
||||||
|
|
|
@ -25,7 +25,7 @@ private:
|
||||||
|
|
||||||
void Flush();
|
void Flush();
|
||||||
|
|
||||||
static __declspec(thread) OutputFormatter* Instance;
|
static thread_local OutputFormatter* Instance;
|
||||||
static int WriteStatic(const char* buf, int count);
|
static int WriteStatic(const char* buf, int count);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
|
@ -15,6 +15,124 @@
|
||||||
#include "WarningHandler.h"
|
#include "WarningHandler.h"
|
||||||
#include "gfxd.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);
|
REGISTER_ZFILENODE(DList, ZDisplayList);
|
||||||
|
|
||||||
ZDisplayList::ZDisplayList(ZFile* nParent) : ZResource(nParent)
|
ZDisplayList::ZDisplayList(ZFile* nParent) : ZResource(nParent)
|
||||||
|
|
|
@ -166,122 +166,6 @@ enum class OoTSegments
|
||||||
FrameBuffer = 16,
|
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
|
class ZDisplayList : public ZResource
|
||||||
{
|
{
|
||||||
|
|
|
@ -25,19 +25,19 @@ public:
|
||||||
|
|
||||||
ZLimbSkinType skinSegmentType = ZLimbSkinType::SkinType_0; // Skin only
|
ZLimbSkinType skinSegmentType = ZLimbSkinType::SkinType_0; // Skin only
|
||||||
segptr_t skinSegment = 0; // Skin only
|
segptr_t skinSegment = 0; // Skin only
|
||||||
Struct_800A5E28 segmentStruct; // Skin only
|
Struct_800A5E28 segmentStruct = {0}; // Skin only
|
||||||
|
|
||||||
// Legacy only
|
// Legacy only
|
||||||
float legTransX, legTransY, legTransZ; // Vec3f
|
float legTransX = 0, legTransY = 0, legTransZ = 0; // Vec3f
|
||||||
uint16_t rotX, rotY, rotZ; // Vec3s
|
uint16_t rotX = 0, rotY = 0, rotZ = 0; // Vec3s
|
||||||
segptr_t childPtr; // LegacyLimb*
|
segptr_t childPtr = 0; // LegacyLimb*
|
||||||
segptr_t siblingPtr; // LegacyLimb*
|
segptr_t siblingPtr = 0; // LegacyLimb*
|
||||||
|
|
||||||
segptr_t dListPtr = 0;
|
segptr_t dListPtr = 0;
|
||||||
segptr_t dList2Ptr = 0; // LOD and Curve Only
|
segptr_t dList2Ptr = 0; // LOD and Curve Only
|
||||||
|
|
||||||
int16_t transX, transY, transZ;
|
int16_t transX = 0, transY = 0, transZ = 0;
|
||||||
uint8_t childIndex, siblingIndex;
|
uint8_t childIndex = 0, siblingIndex = 0;
|
||||||
|
|
||||||
ZLimb(ZFile* nParent);
|
ZLimb(ZFile* nParent);
|
||||||
|
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <limits>
|
#include <limits>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
#include <cstring>
|
||||||
|
|
||||||
class BitConverter
|
class BitConverter
|
||||||
{
|
{
|
||||||
|
|
|
@ -52,7 +52,7 @@ public:
|
||||||
for (auto& p : fs::recursive_directory_iterator(dir))
|
for (auto& p : fs::recursive_directory_iterator(dir))
|
||||||
{
|
{
|
||||||
if (!p.is_directory())
|
if (!p.is_directory())
|
||||||
lst.push_back(p.path().string());
|
lst.push_back(p.path().generic_string());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,6 +3,10 @@
|
||||||
#pragma optimize("2", on)
|
#pragma optimize("2", on)
|
||||||
#define _CRT_SECURE_NO_WARNINGS
|
#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> StringHelper::Split(std::string s, const std::string& delimiter)
|
||||||
{
|
{
|
||||||
std::vector<std::string> result;
|
std::vector<std::string> result;
|
||||||
|
|
2
libultraship/.gitignore
vendored
2
libultraship/.gitignore
vendored
|
@ -354,3 +354,5 @@ MigrationBackup/
|
||||||
|
|
||||||
!libultraship/Lib/**
|
!libultraship/Lib/**
|
||||||
libultraship/DebugObj/*
|
libultraship/DebugObj/*
|
||||||
|
build/
|
||||||
|
libultraship.a
|
|
@ -1,15 +1,78 @@
|
||||||
# Only used for standalone compilation, usually inherits these from the main makefile
|
# 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*")
|
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)
|
CXX_FILES := \
|
||||||
LIB := otrlib.a
|
$(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
|
# create build directories
|
||||||
$(shell mkdir -p $(foreach dir,$(SRC_DIRS),build/$(dir)))
|
$(shell mkdir -p $(SRC_DIRS:%=build/%))
|
||||||
|
|
||||||
all: $(LIB)
|
all: $(LIB)
|
||||||
|
|
||||||
|
@ -17,12 +80,17 @@ clean:
|
||||||
rm -rf build $(LIB)
|
rm -rf build $(LIB)
|
||||||
|
|
||||||
format:
|
format:
|
||||||
clang-format-11 -i $(CPP_FILES) $(H_FILES)
|
$(FORMAT) -i $(FMT_FILES)
|
||||||
|
|
||||||
.PHONY: all clean format
|
.PHONY: all clean format
|
||||||
|
|
||||||
build/%.o: %.cpp
|
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)
|
$(LIB): $(O_FILES)
|
||||||
$(AR) rcs $@ $^
|
$(AR) rcs $@ $^
|
||||||
|
|
||||||
|
-include $(D_FILES)
|
|
@ -21,7 +21,7 @@ void Ship::AnimationV0::ParseFileBinary(BinaryReader* reader, Resource* res)
|
||||||
|
|
||||||
uint32_t rotIndCnt = reader->ReadUInt32();
|
uint32_t rotIndCnt = reader->ReadUInt32();
|
||||||
anim->rotationIndices.reserve(rotIndCnt);
|
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 x = reader->ReadUInt16();
|
||||||
uint16_t y = reader->ReadUInt16();
|
uint16_t y = reader->ReadUInt16();
|
||||||
|
|
|
@ -28,7 +28,7 @@ namespace Ship {
|
||||||
|
|
||||||
std::shared_ptr<Archive> Archive::CreateArchive(const std::string& archivePath, int fileCapacity)
|
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];
|
TCHAR* t_filename = new TCHAR[archivePath.size() + 1];
|
||||||
t_filename[archivePath.size()] = 0;
|
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);
|
bool success = SFileCreateArchive(t_filename, MPQ_CREATE_LISTFILE | MPQ_CREATE_ATTRIBUTES | MPQ_CREATE_ARCHIVE_V2, fileCapacity, &archive->mainMPQ);
|
||||||
int error = GetLastError();
|
int error = GetLastError();
|
||||||
|
|
||||||
if (success) {
|
delete[] t_filename;
|
||||||
|
|
||||||
|
if (success)
|
||||||
|
{
|
||||||
archive->mpqHandles[archivePath] = archive->mainMPQ;
|
archive->mpqHandles[archivePath] = archive->mainMPQ;
|
||||||
return std::make_shared<Archive>(*archive);
|
return archive;
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
SPDLOG_ERROR("({}) We tried to create an archive, but it has fallen and cannot get up.");
|
SPDLOG_ERROR("({}) We tried to create an archive, but it has fallen and cannot get up.");
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
@ -49,11 +54,16 @@ namespace Ship {
|
||||||
std::shared_ptr<File> Archive::LoadFile(const std::string& filePath, bool includeParent, std::shared_ptr<File> FileToLoad) {
|
std::shared_ptr<File> Archive::LoadFile(const std::string& filePath, bool includeParent, std::shared_ptr<File> FileToLoad) {
|
||||||
HANDLE fileHandle = NULL;
|
HANDLE fileHandle = NULL;
|
||||||
|
|
||||||
|
if (FileToLoad == nullptr) {
|
||||||
|
FileToLoad = std::make_shared<File>();
|
||||||
|
FileToLoad->path = filePath;
|
||||||
|
}
|
||||||
|
|
||||||
if (!SFileOpenFileEx(mainMPQ, filePath.c_str(), 0, &fileHandle)) {
|
if (!SFileOpenFileEx(mainMPQ, filePath.c_str(), 0, &fileHandle)) {
|
||||||
SPDLOG_ERROR("({}) Failed to open file {} from mpq archive {}", GetLastError(), filePath.c_str(), MainPath.c_str());
|
SPDLOG_ERROR("({}) Failed to open file {} from mpq archive {}", GetLastError(), filePath.c_str(), MainPath.c_str());
|
||||||
std::unique_lock<std::mutex> Lock(FileToLoad->FileLoadMutex);
|
std::unique_lock<std::mutex> Lock(FileToLoad->FileLoadMutex);
|
||||||
FileToLoad->bHasLoadError = true;
|
FileToLoad->bHasLoadError = true;
|
||||||
return nullptr;
|
return FileToLoad;
|
||||||
}
|
}
|
||||||
|
|
||||||
DWORD dwFileSize = SFileGetFileSize(fileHandle, 0);
|
DWORD dwFileSize = SFileGetFileSize(fileHandle, 0);
|
||||||
|
@ -67,18 +77,13 @@ namespace Ship {
|
||||||
}
|
}
|
||||||
std::unique_lock<std::mutex> Lock(FileToLoad->FileLoadMutex);
|
std::unique_lock<std::mutex> Lock(FileToLoad->FileLoadMutex);
|
||||||
FileToLoad->bHasLoadError = true;
|
FileToLoad->bHasLoadError = true;
|
||||||
return nullptr;
|
return FileToLoad;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!SFileCloseFile(fileHandle)) {
|
if (!SFileCloseFile(fileHandle)) {
|
||||||
SPDLOG_ERROR("({}) Failed to close file {} from mpq archive {}", GetLastError(), filePath.c_str(), MainPath.c_str());
|
SPDLOG_ERROR("({}) Failed to close file {} from mpq archive {}", GetLastError(), filePath.c_str(), MainPath.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (FileToLoad == nullptr) {
|
|
||||||
FileToLoad = std::make_shared<File>();
|
|
||||||
FileToLoad->path = filePath;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::unique_lock<std::mutex> Lock(FileToLoad->FileLoadMutex);
|
std::unique_lock<std::mutex> Lock(FileToLoad->FileLoadMutex);
|
||||||
FileToLoad->parent = includeParent ? shared_from_this() : nullptr;
|
FileToLoad->parent = includeParent ? shared_from_this() : nullptr;
|
||||||
FileToLoad->buffer = fileData;
|
FileToLoad->buffer = fileData;
|
||||||
|
@ -92,6 +97,11 @@ namespace Ship {
|
||||||
HANDLE fileHandle = NULL;
|
HANDLE fileHandle = NULL;
|
||||||
HANDLE mpqHandle = NULL;
|
HANDLE mpqHandle = NULL;
|
||||||
|
|
||||||
|
if (FileToLoad == nullptr) {
|
||||||
|
FileToLoad = std::make_shared<File>();
|
||||||
|
FileToLoad->path = filePath;
|
||||||
|
}
|
||||||
|
|
||||||
for(auto [path, handle] : mpqHandles) {
|
for(auto [path, handle] : mpqHandles) {
|
||||||
if (SFileOpenFileEx(mpqHandle, filePath.c_str(), 0, &fileHandle)) {
|
if (SFileOpenFileEx(mpqHandle, filePath.c_str(), 0, &fileHandle)) {
|
||||||
std::unique_lock Lock(FileToLoad->FileLoadMutex);
|
std::unique_lock Lock(FileToLoad->FileLoadMutex);
|
||||||
|
@ -116,18 +126,13 @@ namespace Ship {
|
||||||
}
|
}
|
||||||
std::unique_lock<std::mutex> Lock(FileToLoad->FileLoadMutex);
|
std::unique_lock<std::mutex> Lock(FileToLoad->FileLoadMutex);
|
||||||
FileToLoad->bHasLoadError = true;
|
FileToLoad->bHasLoadError = true;
|
||||||
return nullptr;
|
return FileToLoad;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!SFileCloseFile(fileHandle)) {
|
if (!SFileCloseFile(fileHandle)) {
|
||||||
SPDLOG_ERROR("({}) Failed to close file {} from mpq archive {}", GetLastError(), filePath.c_str(), MainPath.c_str());
|
SPDLOG_ERROR("({}) Failed to close file {} from mpq archive {}", GetLastError(), filePath.c_str(), MainPath.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (FileToLoad == nullptr) {
|
|
||||||
FileToLoad = std::make_shared<File>();
|
|
||||||
FileToLoad->path = filePath;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::unique_lock<std::mutex> Lock(FileToLoad->FileLoadMutex);
|
std::unique_lock<std::mutex> Lock(FileToLoad->FileLoadMutex);
|
||||||
FileToLoad->parent = includeParent ? shared_from_this() : nullptr;
|
FileToLoad->parent = includeParent ? shared_from_this() : nullptr;
|
||||||
FileToLoad->buffer = fileData;
|
FileToLoad->buffer = fileData;
|
||||||
|
@ -139,13 +144,16 @@ namespace Ship {
|
||||||
|
|
||||||
bool Archive::AddFile(const std::string& path, uintptr_t fileData, DWORD dwFileSize) {
|
bool Archive::AddFile(const std::string& path, uintptr_t fileData, DWORD dwFileSize) {
|
||||||
HANDLE hFile;
|
HANDLE hFile;
|
||||||
|
#ifdef _WIN32
|
||||||
SYSTEMTIME sysTime;
|
SYSTEMTIME sysTime;
|
||||||
GetSystemTime(&sysTime);
|
GetSystemTime(&sysTime);
|
||||||
FILETIME t;
|
FILETIME t;
|
||||||
SystemTimeToFileTime(&sysTime, &t);
|
SystemTimeToFileTime(&sysTime, &t);
|
||||||
ULONGLONG stupidHack = static_cast<uint64_t>(t.dwHighDateTime) << (sizeof(t.dwHighDateTime) * 8) | t.dwLowDateTime;
|
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)) {
|
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());
|
SPDLOG_ERROR("({}) Failed to create file of {} bytes {} in archive {}", GetLastError(), dwFileSize, path.c_str(), MainPath.c_str());
|
||||||
return false;
|
return false;
|
||||||
|
@ -302,11 +310,16 @@ namespace Ship {
|
||||||
|
|
||||||
bool Archive::LoadMainMPQ(bool enableWriting, bool genCRCMap) {
|
bool Archive::LoadMainMPQ(bool enableWriting, bool genCRCMap) {
|
||||||
HANDLE mpqHandle = NULL;
|
HANDLE mpqHandle = NULL;
|
||||||
|
#ifdef _WIN32
|
||||||
|
std::wstring wfullPath = std::filesystem::absolute(MainPath).wstring();
|
||||||
|
#endif
|
||||||
std::string fullPath = std::filesystem::absolute(MainPath).string();
|
std::string fullPath = std::filesystem::absolute(MainPath).string();
|
||||||
|
|
||||||
std::wstring wFileName = std::filesystem::absolute(MainPath).wstring();
|
#ifdef _WIN32
|
||||||
|
if (!SFileOpenArchive(wfullPath.c_str(), 0, enableWriting ? 0 : MPQ_OPEN_READ_ONLY, &mpqHandle)) {
|
||||||
if (!SFileOpenArchive(wFileName.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());
|
SPDLOG_ERROR("({}) Failed to open main mpq file {}.", GetLastError(), fullPath.c_str());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -340,12 +353,19 @@ namespace Ship {
|
||||||
|
|
||||||
std::wstring wPath = std::filesystem::absolute(path).wstring();
|
std::wstring wPath = std::filesystem::absolute(path).wstring();
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
if (!SFileOpenArchive(wPath.c_str(), 0, MPQ_OPEN_READ_ONLY, &patchHandle)) {
|
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());
|
SPDLOG_ERROR("({}) Failed to open patch mpq file {} while applying to {}.", GetLastError(), path.c_str(), MainPath.c_str());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
#ifdef _WIN32
|
||||||
if (!SFileOpenPatchArchive(mainMPQ, wPath.c_str(), "", 0)) {
|
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());
|
SPDLOG_ERROR("({}) Failed to apply patch mpq file {} to main mpq {}.", GetLastError(), path.c_str(), MainPath.c_str());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -51,6 +51,8 @@ namespace Ship
|
||||||
data.u16 = reader->ReadUInt16();
|
data.u16 = reader->ReadUInt16();
|
||||||
break;
|
break;
|
||||||
// OTRTODO: IMPLEMENT OTHER TYPES!
|
// OTRTODO: IMPLEMENT OTHER TYPES!
|
||||||
|
default:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
arr->scalars.push_back(data);
|
arr->scalars.push_back(data);
|
||||||
|
|
|
@ -29,9 +29,9 @@ namespace Ship {
|
||||||
bool CreateDefaultConfig();
|
bool CreateDefaultConfig();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
mINI::INIFile File;
|
|
||||||
mINI::INIStructure Val;
|
mINI::INIStructure Val;
|
||||||
std::weak_ptr<GlobalCtx2> Context;
|
std::weak_ptr<GlobalCtx2> Context;
|
||||||
std::string Path;
|
std::string Path;
|
||||||
|
mINI::INIFile File;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,23 +1,22 @@
|
||||||
#include "cvar.h"
|
#include "Cvar.h"
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <functional>
|
||||||
|
#include <memory>
|
||||||
|
#include <utility>
|
||||||
#include <PR/ultra64/gbi.h>
|
#include <PR/ultra64/gbi.h>
|
||||||
|
|
||||||
std::map<std::string, CVar*> cvars;
|
std::map<std::string, std::unique_ptr<CVar>, std::less<>> cvars;
|
||||||
|
|
||||||
CVar* CVar_GetVar(const char* name) {
|
|
||||||
std::string key(name);
|
|
||||||
return cvars.contains(key) ? cvars[key] : nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
extern "C" CVar* CVar_Get(const char* name) {
|
extern "C" CVar* CVar_Get(const char* name) {
|
||||||
return CVar_GetVar(name);
|
auto it = cvars.find(name);
|
||||||
|
return (it != cvars.end()) ? it->second.get() : nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" s32 CVar_GetS32(const char* name, s32 defaultValue) {
|
extern "C" s32 CVar_GetS32(const char* name, s32 defaultValue) {
|
||||||
CVar* cvar = CVar_Get(name);
|
CVar* cvar = CVar_Get(name);
|
||||||
|
|
||||||
if (cvar != nullptr) {
|
if (cvar) {
|
||||||
if (cvar->type == CVAR_TYPE_S32)
|
if (cvar->type == CVAR_TYPE_S32)
|
||||||
return cvar->value.valueS32;
|
return cvar->value.valueS32;
|
||||||
}
|
}
|
||||||
|
@ -28,7 +27,7 @@ extern "C" s32 CVar_GetS32(const char* name, s32 defaultValue) {
|
||||||
extern "C" float CVar_GetFloat(const char* name, float defaultValue) {
|
extern "C" float CVar_GetFloat(const char* name, float defaultValue) {
|
||||||
CVar* cvar = CVar_Get(name);
|
CVar* cvar = CVar_Get(name);
|
||||||
|
|
||||||
if (cvar != nullptr) {
|
if (cvar) {
|
||||||
if (cvar->type == CVAR_TYPE_FLOAT)
|
if (cvar->type == CVAR_TYPE_FLOAT)
|
||||||
return cvar->value.valueFloat;
|
return cvar->value.valueFloat;
|
||||||
}
|
}
|
||||||
|
@ -36,10 +35,10 @@ extern "C" float CVar_GetFloat(const char* name, float defaultValue) {
|
||||||
return defaultValue;
|
return defaultValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" char* CVar_GetString(const char* name, char* defaultValue) {
|
extern "C" const char* CVar_GetString(const char* name, const char* defaultValue) {
|
||||||
CVar* cvar = CVar_Get(name);
|
CVar* cvar = CVar_Get(name);
|
||||||
|
|
||||||
if (cvar != nullptr) {
|
if (cvar) {
|
||||||
if (cvar->type == CVAR_TYPE_STRING)
|
if (cvar->type == CVAR_TYPE_STRING)
|
||||||
return cvar->value.valueStr;
|
return cvar->value.valueStr;
|
||||||
}
|
}
|
||||||
|
@ -48,53 +47,43 @@ extern "C" char* CVar_GetString(const char* name, char* defaultValue) {
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" void CVar_SetS32(const char* name, s32 value) {
|
extern "C" void CVar_SetS32(const char* name, s32 value) {
|
||||||
CVar* cvar = CVar_Get(name);
|
auto& cvar = cvars[name];
|
||||||
if (!cvar) {
|
if (!cvar) {
|
||||||
cvar = new CVar;
|
cvar = std::make_unique<CVar>();
|
||||||
cvars[std::string(name)] = cvar;
|
|
||||||
}
|
}
|
||||||
cvar->type = CVAR_TYPE_S32;
|
cvar->type = CVAR_TYPE_S32;
|
||||||
cvar->value.valueS32 = value;
|
cvar->value.valueS32 = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CVar_SetFloat(const char* name, float value) {
|
void CVar_SetFloat(const char* name, float value) {
|
||||||
CVar* cvar = CVar_Get(name);
|
auto& cvar = cvars[name];
|
||||||
if (!cvar) {
|
if (!cvar) {
|
||||||
cvar = new CVar;
|
cvar = std::make_unique<CVar>();
|
||||||
cvars[std::string(name)] = cvar;
|
|
||||||
}
|
}
|
||||||
cvar->type = CVAR_TYPE_FLOAT;
|
cvar->type = CVAR_TYPE_FLOAT;
|
||||||
cvar->value.valueFloat = value;
|
cvar->value.valueFloat = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CVar_SetString(const char* name, char* value) {
|
void CVar_SetString(const char* name, const char* value) {
|
||||||
CVar* cvar = CVar_Get(name);
|
auto& cvar = cvars[name];
|
||||||
if (!cvar) {
|
if (!cvar) {
|
||||||
cvar = new CVar;
|
cvar = std::make_unique<CVar>();
|
||||||
cvars[std::string(name)] = cvar;
|
|
||||||
}
|
}
|
||||||
cvar->type = CVAR_TYPE_STRING;
|
cvar->type = CVAR_TYPE_STRING;
|
||||||
cvar->value.valueStr = value;
|
cvar->value.valueStr = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
extern "C" void CVar_RegisterS32(const char* name, s32 defaultValue) {
|
extern "C" void CVar_RegisterS32(const char* name, s32 defaultValue) {
|
||||||
CVar* cvar = CVar_Get(name);
|
if (!CVar_Get(name))
|
||||||
|
|
||||||
if (cvar == nullptr)
|
|
||||||
CVar_SetS32(name, defaultValue);
|
CVar_SetS32(name, defaultValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" void CVar_RegisterFloat(const char* name, float defaultValue) {
|
extern "C" void CVar_RegisterFloat(const char* name, float defaultValue) {
|
||||||
CVar* cvar = CVar_Get(name);
|
if (!CVar_Get(name))
|
||||||
|
|
||||||
if (cvar == nullptr)
|
|
||||||
CVar_SetFloat(name, defaultValue);
|
CVar_SetFloat(name, defaultValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" void CVar_RegisterString(const char* name, char* defaultValue) {
|
extern "C" void CVar_RegisterString(const char* name, const char* defaultValue) {
|
||||||
CVar* cvar = CVar_Get(name);
|
if (!CVar_Get(name))
|
||||||
|
|
||||||
if (cvar == nullptr)
|
|
||||||
CVar_SetString(name, defaultValue);
|
CVar_SetString(name, defaultValue);
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,13 +6,13 @@
|
||||||
typedef enum CVarType { CVAR_TYPE_S32, CVAR_TYPE_FLOAT, CVAR_TYPE_STRING } CVarType;
|
typedef enum CVarType { CVAR_TYPE_S32, CVAR_TYPE_FLOAT, CVAR_TYPE_STRING } CVarType;
|
||||||
|
|
||||||
typedef struct CVar {
|
typedef struct CVar {
|
||||||
char* name;
|
const char* name;
|
||||||
CVarType type;
|
CVarType type;
|
||||||
|
|
||||||
union {
|
union {
|
||||||
s32 valueS32;
|
s32 valueS32;
|
||||||
float valueFloat;
|
float valueFloat;
|
||||||
char* valueStr;
|
const char* valueStr;
|
||||||
} value;
|
} value;
|
||||||
} CVar;
|
} CVar;
|
||||||
|
|
||||||
|
@ -22,16 +22,15 @@ extern "C"
|
||||||
#endif
|
#endif
|
||||||
//#include <ultra64.h>
|
//#include <ultra64.h>
|
||||||
|
|
||||||
|
|
||||||
CVar* CVar_Get(const char* name);
|
CVar* CVar_Get(const char* name);
|
||||||
s32 CVar_GetS32(const char* name, s32 defaultValue);
|
s32 CVar_GetS32(const char* name, s32 defaultValue);
|
||||||
float CVar_GetFloat(const char* name, float defaultValue);
|
float CVar_GetFloat(const char* name, float defaultValue);
|
||||||
char* CVar_GetString(const char* name, char* defaultValue);
|
const char* CVar_GetString(const char* name, const char* defaultValue);
|
||||||
void CVar_SetS32(const char* name, s32 value);
|
void CVar_SetS32(const char* name, s32 value);
|
||||||
|
|
||||||
void CVar_RegisterS32(const char* name, s32 defaultValue);
|
void CVar_RegisterS32(const char* name, s32 defaultValue);
|
||||||
void CVar_RegisterFloat(const char* name, float defaultValue);
|
void CVar_RegisterFloat(const char* name, float defaultValue);
|
||||||
void CVar_RegisterString(const char* name, char* defaultValue);
|
void CVar_RegisterString(const char* name, const char* defaultValue);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
};
|
};
|
||||||
|
@ -40,10 +39,12 @@ void CVar_RegisterString(const char* name, char* defaultValue);
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <functional>
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
extern std::map<std::string, CVar*> cvars;
|
extern std::map<std::string, std::unique_ptr<CVar>, std::less<>> cvars;
|
||||||
CVar* CVar_GetVar(const char* name);
|
CVar* CVar_GetVar(const char* name);
|
||||||
void CVar_SetFloat(const char* name, float value);
|
void CVar_SetFloat(const char* name, float value);
|
||||||
void CVar_SetString(const char* name, char* value);
|
void CVar_SetString(const char* name, const char* value);
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -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;
|
|
||||||
}
|
|
||||||
}
|
|
186
libultraship/libultraship/GameOverlay.cpp
Normal file
186
libultraship/libultraship/GameOverlay.cpp
Normal file
|
@ -0,0 +1,186 @@
|
||||||
|
#include "GameOverlay.h"
|
||||||
|
|
||||||
|
#include "Cvar.h"
|
||||||
|
#include "File.h"
|
||||||
|
#include "Archive.h"
|
||||||
|
#include "ResourceMgr.h"
|
||||||
|
#include "SohConsole.h"
|
||||||
|
#include "SohImGuiImpl.h"
|
||||||
|
#include "TextureMod.h"
|
||||||
|
#include "Lib/ImGui/imgui_internal.h"
|
||||||
|
|
||||||
|
void Ship::GameOverlay::LoadFont(const std::string& name, const std::string& path, float fontSize) {
|
||||||
|
ImGuiIO& io = ImGui::GetIO();
|
||||||
|
std::shared_ptr<Archive> base = GlobalCtx2::GetInstance()->GetResourceManager()->GetArchive();
|
||||||
|
std::shared_ptr<File> font = std::make_shared<File>();
|
||||||
|
base->LoadFile(path, false, font);
|
||||||
|
if (font->bIsLoaded) {
|
||||||
|
char* font_data = new char[font->dwBufferSize];
|
||||||
|
memcpy(font_data, font->buffer.get(), font->dwBufferSize);
|
||||||
|
Fonts[name] = io.Fonts->AddFontFromMemoryTTF(font_data, font->dwBufferSize, fontSize);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Ship::GameOverlay::TextDraw(float x, float y, bool shadow, const char* fmt, ...) {
|
||||||
|
char buf[1024];
|
||||||
|
va_list args;
|
||||||
|
va_start(args, fmt);
|
||||||
|
vsnprintf(buf, IM_ARRAYSIZE(buf), fmt, args);
|
||||||
|
buf[IM_ARRAYSIZE(buf) - 1] = 0;
|
||||||
|
va_end(args);
|
||||||
|
|
||||||
|
ImGui::PushFont(Fonts[this->CurrentFont]);
|
||||||
|
if (shadow) {
|
||||||
|
ImGui::SetCursorPos(ImVec2(x + 1, y + 1));
|
||||||
|
ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(.0f, .0f, .0f, 255));
|
||||||
|
ImGui::Text(buf, args);
|
||||||
|
}
|
||||||
|
ImGui::PopStyleColor();
|
||||||
|
ImGui::SetCursorPos(ImVec2(x, y));
|
||||||
|
ImGui::Text(buf, args);
|
||||||
|
ImGui::PopFont();
|
||||||
|
}
|
||||||
|
|
||||||
|
float Ship::GameOverlay::GetScreenWidth() {
|
||||||
|
const ImGuiViewport* viewport = ImGui::GetMainViewport();
|
||||||
|
return viewport->Size.x;
|
||||||
|
}
|
||||||
|
|
||||||
|
float Ship::GameOverlay::GetScreenHeight() {
|
||||||
|
const ImGuiViewport* viewport = ImGui::GetMainViewport();
|
||||||
|
return viewport->Size.y;
|
||||||
|
}
|
||||||
|
|
||||||
|
float Ship::GameOverlay::GetStringWidth(const char* text) {
|
||||||
|
return CalculateTextSize(text).x;
|
||||||
|
}
|
||||||
|
|
||||||
|
ImVec2 Ship::GameOverlay::CalculateTextSize(const char* text, const char* text_end, bool hide_text_after_double_hash, float wrap_width) {
|
||||||
|
ImGuiContext& g = *GImGui;
|
||||||
|
|
||||||
|
const char* text_display_end;
|
||||||
|
if (hide_text_after_double_hash)
|
||||||
|
text_display_end = ImGui::FindRenderedTextEnd(text, text_end); // Hide anything after a '##' string
|
||||||
|
else
|
||||||
|
text_display_end = text_end;
|
||||||
|
|
||||||
|
GameOverlay* overlay = SohImGui::overlay;
|
||||||
|
|
||||||
|
ImFont* font = overlay->CurrentFont == "Default" ? g.Font : overlay->Fonts[overlay->CurrentFont];
|
||||||
|
const float font_size = font->FontSize;
|
||||||
|
if (text == text_display_end)
|
||||||
|
return ImVec2(0.0f, font_size);
|
||||||
|
ImVec2 text_size = font->CalcTextSizeA(font_size, FLT_MAX, wrap_width, text, text_display_end, NULL);
|
||||||
|
|
||||||
|
// Round
|
||||||
|
// FIXME: This has been here since Dec 2015 (7b0bf230) but down the line we want this out.
|
||||||
|
// FIXME: Investigate using ceilf or e.g.
|
||||||
|
// - https://git.musl-libc.org/cgit/musl/tree/src/math/ceilf.c
|
||||||
|
// - https://embarkstudios.github.io/rust-gpu/api/src/libm/math/ceilf.rs.html
|
||||||
|
text_size.x = IM_FLOOR(text_size.x + 0.99999f);
|
||||||
|
|
||||||
|
return text_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Ship::GameOverlay::Init() {
|
||||||
|
this->LoadFont("Press Start 2P", "assets/ship_of_harkinian/fonts/PressStart2P-Regular.ttf", 12.0f);
|
||||||
|
this->LoadFont("Fipps", "assets/ship_of_harkinian/fonts/Fipps-Regular.otf", 32.0f);
|
||||||
|
const std::string DefaultFont = this->Fonts.begin()->first;
|
||||||
|
if(!this->Fonts.empty()) {
|
||||||
|
const std::string font = CVar_GetString("gOverlayFont", ImStrdup(DefaultFont.c_str()));
|
||||||
|
for (auto& [name, _] : this->Fonts) {
|
||||||
|
if (font.starts_with(name)) {
|
||||||
|
this->CurrentFont = name;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
this->CurrentFont = DefaultFont;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
SohImGui::console->Commands["overlay"] = { OverlayCommand, "Draw an overlay using a cvar value" };
|
||||||
|
}
|
||||||
|
|
||||||
|
void Ship::GameOverlay::DrawSettings() {
|
||||||
|
ImGui::Text("Overlays Text Font");
|
||||||
|
if (ImGui::BeginCombo("##TextFont", this->CurrentFont.c_str())) {
|
||||||
|
for (auto& [name, font] : this->Fonts) {
|
||||||
|
if (ImGui::Selectable(name.c_str(), name == this->CurrentFont)) {
|
||||||
|
this->CurrentFont = name;
|
||||||
|
CVar_SetString("gOverlayFont", ImStrdup(name.c_str()));
|
||||||
|
SohImGui::needs_save = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
ImGui::EndCombo();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Ship::GameOverlay::Draw() {
|
||||||
|
const ImGuiViewport* viewport = ImGui::GetMainViewport();
|
||||||
|
|
||||||
|
ImGui::SetNextWindowPos(viewport->Pos, ImGuiCond_Always);
|
||||||
|
ImGui::SetNextWindowSize(viewport->Size, ImGuiCond_Always);
|
||||||
|
ImGui::Begin("SoHOverlay", nullptr, ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoBackground |
|
||||||
|
ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_NoSavedSettings | ImGuiWindowFlags_NoInputs);
|
||||||
|
|
||||||
|
float textY = 50;
|
||||||
|
for (auto &[key, overlay] : this->RegisteredOverlays) {
|
||||||
|
|
||||||
|
if (overlay.type == OverlayType::TEXT) {
|
||||||
|
const char* text = ImStrdup(key.c_str());
|
||||||
|
const CVar* var = CVar_GetVar(text);
|
||||||
|
|
||||||
|
switch (var->type) {
|
||||||
|
case CVAR_TYPE_FLOAT:
|
||||||
|
this->TextDraw(30, textY, true, "%s %.2f", text, var->value.valueFloat);
|
||||||
|
break;
|
||||||
|
case CVAR_TYPE_S32:
|
||||||
|
this->TextDraw(30, textY, true, "%s %d", text, var->value.valueS32);
|
||||||
|
break;
|
||||||
|
case CVAR_TYPE_STRING:
|
||||||
|
this->TextDraw(30, textY, true, "%s %s", text, var->value.valueStr);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
free((void*) text);
|
||||||
|
textY += 30;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui::End();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Ship::OverlayCommand(const std::vector<std::string>& args) {
|
||||||
|
if (args.size() < 3) {
|
||||||
|
return CMD_FAILED;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (CVar_GetVar(args[2].c_str()) != nullptr) {
|
||||||
|
const char* key = args[2].c_str();
|
||||||
|
GameOverlay* overlay = SohImGui::overlay;
|
||||||
|
if (args[1] == "add") {
|
||||||
|
if (!overlay->RegisteredOverlays.contains(args[2])) {
|
||||||
|
overlay->RegisteredOverlays[args[2]] = {
|
||||||
|
OverlayType::TEXT,
|
||||||
|
key
|
||||||
|
};
|
||||||
|
INFO("Added overlay: %s ", key);
|
||||||
|
} else {
|
||||||
|
ERROR("Overlay already exists: %s", key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (args[1] == "remove") {
|
||||||
|
if (overlay->RegisteredOverlays.contains(args[2])) {
|
||||||
|
overlay->RegisteredOverlays.erase(args[2]);
|
||||||
|
INFO("Removed overlay: %s ", key);
|
||||||
|
} else {
|
||||||
|
ERROR("Overlay not found: %s ", key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
ERROR("CVar %s does not exist", args[2].c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
return CMD_SUCCESS;
|
||||||
|
}
|
38
libultraship/libultraship/GameOverlay.h
Normal file
38
libultraship/libultraship/GameOverlay.h
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
#pragma once
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include "Lib/ImGui/imgui.h"
|
||||||
|
#include <map>
|
||||||
|
#include <unordered_map>
|
||||||
|
|
||||||
|
enum class OverlayType {
|
||||||
|
TEXT, IMAGE
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Overlay {
|
||||||
|
OverlayType type;
|
||||||
|
const char* value;
|
||||||
|
};
|
||||||
|
|
||||||
|
namespace Ship {
|
||||||
|
class GameOverlay {
|
||||||
|
public:
|
||||||
|
std::unordered_map<std::string, Overlay> RegisteredOverlays;
|
||||||
|
std::unordered_map<std::string, ImFont*> Fonts;
|
||||||
|
std::string CurrentFont = "Default";
|
||||||
|
void Init();
|
||||||
|
void Draw();
|
||||||
|
void DrawSettings();
|
||||||
|
static float GetScreenWidth();
|
||||||
|
static float GetScreenHeight();
|
||||||
|
static float GetStringWidth(const char* text);
|
||||||
|
static ImVec2 CalculateTextSize(const char* text, const char* text_end = NULL, bool hide_text_after_double_hash = false, float wrap_width = -1.0f);
|
||||||
|
private:
|
||||||
|
void TextDraw(float x, float y, bool shadow, const char* text, ...);
|
||||||
|
void LoadFont(const std::string& name, const std::string& path, float fontSize);
|
||||||
|
};
|
||||||
|
|
||||||
|
static bool OverlayCommand(const std::vector<std::string>& args);
|
||||||
|
}
|
||||||
|
|
|
@ -1,22 +1,22 @@
|
||||||
#include "GameSettings.h"
|
#include "GameSettings.h"
|
||||||
|
|
||||||
// Audio
|
// Audio
|
||||||
|
#include <cstddef>
|
||||||
|
#include <PR/ultra64/types.h>
|
||||||
#include <PR/ultra64/sptask.h>
|
#include <PR/ultra64/sptask.h>
|
||||||
#include <PR/ultra64/pi.h>
|
#include <PR/ultra64/pi.h>
|
||||||
#include <PR/ultra64/message.h>
|
#include <PR/ultra64/message.h>
|
||||||
#include <PR/ultra64/types.h>
|
|
||||||
|
|
||||||
#include "ConfigFile.h"
|
#include "ConfigFile.h"
|
||||||
#include "Cvar.h"
|
#include "Cvar.h"
|
||||||
#include "GlobalCtx2.h"
|
#include "GlobalCtx2.h"
|
||||||
#include "SohImGuiImpl.h"
|
#include "SohImGuiImpl.h"
|
||||||
#include "stox.h"
|
|
||||||
#include "../../soh/include/z64audio.h"
|
#include "../../soh/include/z64audio.h"
|
||||||
#include <string>
|
|
||||||
#include "SohHooks.h"
|
#include "SohHooks.h"
|
||||||
#include "../../soh/soh/Enhancements/debugconsole.h"
|
#include "../../soh/soh/Enhancements/debugconsole.h"
|
||||||
|
|
||||||
#include "Window.h"
|
#include "Window.h"
|
||||||
|
#include "Lib/Fast3D/gfx_rendering_api.h"
|
||||||
|
|
||||||
#define ABS(var) var < 0 ? -(var) : var
|
#define ABS(var) var < 0 ? -(var) : var
|
||||||
|
|
||||||
|
@ -25,14 +25,6 @@ using namespace Ship;
|
||||||
namespace Game {
|
namespace Game {
|
||||||
|
|
||||||
bool DeSyncAudio = false;
|
bool DeSyncAudio = false;
|
||||||
SoHConfigType Settings;
|
|
||||||
const std::string ConfSection = DEBUG_SECTION;
|
|
||||||
const std::string AudioSection = AUDIO_SECTION;
|
|
||||||
const std::string ControllerSection = CONTROLLER_SECTION;
|
|
||||||
const std::string EnhancementSection = ENHANCEMENTS_SECTION;
|
|
||||||
const std::string CosmeticsSection = COSMETICS_SECTION;
|
|
||||||
const std::string CheatSection = CHEATS_SECTION;
|
|
||||||
|
|
||||||
|
|
||||||
void UpdateAudio() {
|
void UpdateAudio() {
|
||||||
Audio_SetGameVolume(SEQ_BGM_MAIN, CVar_GetFloat("gMainMusicVolume", 1));
|
Audio_SetGameVolume(SEQ_BGM_MAIN, CVar_GetFloat("gMainMusicVolume", 1));
|
||||||
|
@ -41,18 +33,6 @@ namespace Game {
|
||||||
Audio_SetGameVolume(SEQ_SFX, CVar_GetFloat("gFanfareVolume", 1));
|
Audio_SetGameVolume(SEQ_SFX, CVar_GetFloat("gFanfareVolume", 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
void LoadSettings() {
|
|
||||||
const std::shared_ptr<ConfigFile> pConf = GlobalCtx2::GetInstance()->GetConfig();
|
|
||||||
ConfigFile& Conf = *pConf;
|
|
||||||
|
|
||||||
// Debug
|
|
||||||
SohImGui::console->opened = stob(Conf[ConfSection]["console"]);
|
|
||||||
Settings.debug.menu_bar = stob(Conf[ConfSection]["menu_bar"]);
|
|
||||||
Settings.debug.soh = stob(Conf[ConfSection]["soh_debug"]);
|
|
||||||
|
|
||||||
UpdateAudio();
|
|
||||||
}
|
|
||||||
|
|
||||||
void LoadPadSettings() {
|
void LoadPadSettings() {
|
||||||
const std::shared_ptr<ConfigFile> pConf = GlobalCtx2::GetInstance()->GetConfig();
|
const std::shared_ptr<ConfigFile> pConf = GlobalCtx2::GetInstance()->GetConfig();
|
||||||
ConfigFile& Conf = *pConf;
|
ConfigFile& Conf = *pConf;
|
||||||
|
@ -65,16 +45,11 @@ namespace Game {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void LoadSettings() {
|
||||||
|
DebugConsole_LoadCVars();
|
||||||
|
}
|
||||||
|
|
||||||
void SaveSettings() {
|
void SaveSettings() {
|
||||||
const std::shared_ptr<ConfigFile> pConf = GlobalCtx2::GetInstance()->GetConfig();
|
|
||||||
ConfigFile& Conf = *pConf;
|
|
||||||
|
|
||||||
// Debug
|
|
||||||
Conf[ConfSection]["console"] = std::to_string(SohImGui::console->opened);
|
|
||||||
Conf[ConfSection]["menu_bar"] = std::to_string(Settings.debug.menu_bar);
|
|
||||||
Conf[ConfSection]["soh_debug"] = std::to_string(Settings.debug.soh);
|
|
||||||
|
|
||||||
Conf.Save();
|
|
||||||
DebugConsole_SaveCVars();
|
DebugConsole_SaveCVars();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -82,6 +57,11 @@ namespace Game {
|
||||||
ModInternal::registerHookListener({ AUDIO_INIT, [](HookEvent ev) {
|
ModInternal::registerHookListener({ AUDIO_INIT, [](HookEvent ev) {
|
||||||
UpdateAudio();
|
UpdateAudio();
|
||||||
}});
|
}});
|
||||||
|
ModInternal::registerHookListener({ GFX_INIT, [](HookEvent ev) {
|
||||||
|
gfx_get_current_rendering_api()->set_texture_filter((FilteringMode) CVar_GetS32("gTextureFilter", THREE_POINT));
|
||||||
|
SohImGui::console->opened = CVar_GetS32("gConsoleEnabled", 0);
|
||||||
|
UpdateAudio();
|
||||||
|
}});
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetSeqPlayerVolume(SeqPlayers playerId, float volume) {
|
void SetSeqPlayerVolume(SeqPlayers playerId, float volume) {
|
||||||
|
|
|
@ -1,19 +1,5 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
struct SoHConfigType {
|
|
||||||
// Debug
|
|
||||||
struct {
|
|
||||||
bool soh = false;
|
|
||||||
bool menu_bar = false;
|
|
||||||
bool soh_sink = true;
|
|
||||||
} debug;
|
|
||||||
|
|
||||||
// Graphics
|
|
||||||
struct {
|
|
||||||
bool show = false;
|
|
||||||
} graphics;
|
|
||||||
};
|
|
||||||
|
|
||||||
enum SeqPlayers {
|
enum SeqPlayers {
|
||||||
/* 0 */ SEQ_BGM_MAIN,
|
/* 0 */ SEQ_BGM_MAIN,
|
||||||
/* 1 */ SEQ_FANFARE,
|
/* 1 */ SEQ_FANFARE,
|
||||||
|
@ -22,15 +8,7 @@ enum SeqPlayers {
|
||||||
/* 4 */ SEQ_MAX
|
/* 4 */ SEQ_MAX
|
||||||
};
|
};
|
||||||
|
|
||||||
#define DEBUG_SECTION "DEBUG SETTINGS"
|
|
||||||
#define AUDIO_SECTION "AUDIO SETTINGS"
|
|
||||||
#define CONTROLLER_SECTION "CONTROLLER SECTION"
|
|
||||||
#define ENHANCEMENTS_SECTION "ENHANCEMENT SETTINGS"
|
|
||||||
#define COSMETICS_SECTION "COSMETIC SETTINGS"
|
|
||||||
#define CHEATS_SECTION "CHEATS SETTINGS"
|
|
||||||
|
|
||||||
namespace Game {
|
namespace Game {
|
||||||
extern SoHConfigType Settings;
|
|
||||||
void InitSettings();
|
void InitSettings();
|
||||||
void LoadSettings();
|
void LoadSettings();
|
||||||
void LoadPadSettings();
|
void LoadPadSettings();
|
||||||
|
|
|
@ -54,7 +54,11 @@ namespace Ship {
|
||||||
|
|
||||||
if (!ResMan->DidLoadSuccessfully())
|
if (!ResMan->DidLoadSuccessfully())
|
||||||
{
|
{
|
||||||
|
#ifdef _WIN32
|
||||||
MessageBox(NULL, L"Main OTR file not found!", L"Uh oh", MB_OK);
|
MessageBox(NULL, L"Main OTR file not found!", L"Uh oh", MB_OK);
|
||||||
|
#else
|
||||||
|
SPDLOG_ERROR("Main OTR file not found!");
|
||||||
|
#endif
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
INSTANCE = new ModManager(ResMan);
|
INSTANCE = new ModManager(ResMan);
|
||||||
|
|
|
@ -1004,7 +1004,7 @@
|
||||||
#define G_DL_PUSH 0x00
|
#define G_DL_PUSH 0x00
|
||||||
#define G_DL_NOPUSH 0x01
|
#define G_DL_NOPUSH 0x01
|
||||||
|
|
||||||
#if _MSC_VER
|
#if defined(_MSC_VER) || defined(__GNUC__)
|
||||||
#define _LANGUAGE_C
|
#define _LANGUAGE_C
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -3132,7 +3132,7 @@ _DW({ \
|
||||||
#endif
|
#endif
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
#if defined(_MSC_VER)
|
||||||
#define CALL_2(A,B) A B
|
#define CALL_2(A,B) A B
|
||||||
#define CALL_3(A,B,C) A B C
|
#define CALL_3(A,B,C) A B C
|
||||||
|
|
||||||
|
@ -3143,11 +3143,11 @@ _DW({ \
|
||||||
#define gsDPSetCombineMode(a, b) gsDPSetCombineLERP(a, b)
|
#define gsDPSetCombineMode(a, b) gsDPSetCombineLERP(a, b)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if _MSC_VER
|
#if defined(_MSC_VER) || defined(__GNUC__)
|
||||||
#define CALL_2(A,B) A B
|
#define CALL_2(A,B) A B
|
||||||
#define CALL_3(A,B,C) A B C
|
#define CALL_3(A,B,C) A B C
|
||||||
|
|
||||||
#define gsDPSetCombineMode(a, b) CALL_2(gsDPSetCombineLERP, (a, b))
|
// #define gsDPSetCombineMode(a, b) CALL_2(gsDPSetCombineLERP, (a, b))
|
||||||
// #define gsDPSetCombineMode(a, b) _SHIFTL(0, 24, 8), 0
|
// #define gsDPSetCombineMode(a, b) _SHIFTL(0, 24, 8), 0
|
||||||
#else
|
#else
|
||||||
#define gsDPSetCombineMode(a, b) gsDPSetCombineLERP(a, b)
|
#define gsDPSetCombineMode(a, b) gsDPSetCombineLERP(a, b)
|
||||||
|
@ -4575,6 +4575,20 @@ _DW({ \
|
||||||
_g2->words.w1 = (_SHIFTL(dsdx, 16, 16) | _SHIFTL(dtdy, 0, 16)); \
|
_g2->words.w1 = (_SHIFTL(dsdx, 16, 16) | _SHIFTL(dtdy, 0, 16)); \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# define gsSPWideTextureRectangle(xl, yl, xh, yh, tile, s, t, dsdx, dtdy) \
|
||||||
|
{{ \
|
||||||
|
(_SHIFTL(G_TEXRECT_WIDE, 24, 8) | _SHIFTL((xh), 0, 24)), \
|
||||||
|
_SHIFTL((yh), 0, 24), \
|
||||||
|
}}, \
|
||||||
|
{{ \
|
||||||
|
(_SHIFTL((tile), 24, 3) | _SHIFTL((xl), 0, 24)), \
|
||||||
|
_SHIFTL((yl), 0, 24), \
|
||||||
|
}}, \
|
||||||
|
{{ \
|
||||||
|
_SHIFTL(s, 16, 16) | _SHIFTL(t, 0, 16), \
|
||||||
|
_SHIFTL(dsdx, 16, 16) | _SHIFTL(dtdy, 0, 16) \
|
||||||
|
}}
|
||||||
|
|
||||||
/* like gSPTextureRectangle but accepts negative position arguments */
|
/* like gSPTextureRectangle but accepts negative position arguments */
|
||||||
#define gSPScisTextureRectangle(pkt, xl, yl, xh, yh, tile, s, t, dsdx, dtdy) \
|
#define gSPScisTextureRectangle(pkt, xl, yl, xh, yh, tile, s, t, dsdx, dtdy) \
|
||||||
_DW({ \
|
_DW({ \
|
||||||
|
|
|
@ -33,6 +33,7 @@
|
||||||
#define G_OFF (0)
|
#define G_OFF (0)
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
#include "types.h"
|
||||||
#include "gbi.h"
|
#include "gbi.h"
|
||||||
#include "abi.h"
|
#include "abi.h"
|
||||||
|
|
||||||
|
|
|
@ -15,11 +15,9 @@
|
||||||
#ifndef _LANGUAGE_C
|
#ifndef _LANGUAGE_C
|
||||||
#define _LANGUAGE_C
|
#define _LANGUAGE_C
|
||||||
#endif
|
#endif
|
||||||
#include <PR/ultra64/gbi.h>
|
#include "PR/ultra64/gbi.h"
|
||||||
|
|
||||||
#include "gfx_cc.h"
|
|
||||||
#include "gfx_window_manager_api.h"
|
#include "gfx_window_manager_api.h"
|
||||||
#include "gfx_rendering_api.h"
|
|
||||||
#include "gfx_direct3d_common.h"
|
#include "gfx_direct3d_common.h"
|
||||||
|
|
||||||
#define DECLARE_GFX_DXGI_FUNCTIONS
|
#define DECLARE_GFX_DXGI_FUNCTIONS
|
||||||
|
@ -28,7 +26,9 @@
|
||||||
#include "gfx_screen_config.h"
|
#include "gfx_screen_config.h"
|
||||||
#include "../../SohImGuiImpl.h"
|
#include "../../SohImGuiImpl.h"
|
||||||
|
|
||||||
#define THREE_POINT_FILTERING 0
|
#include "gfx_cc.h"
|
||||||
|
#include "gfx_rendering_api.h"
|
||||||
|
#include "gfx_pc.h"
|
||||||
#define DEBUG_D3D 0
|
#define DEBUG_D3D 0
|
||||||
|
|
||||||
using namespace Microsoft::WRL; // For ComPtr
|
using namespace Microsoft::WRL; // For ComPtr
|
||||||
|
@ -135,6 +135,7 @@ static struct {
|
||||||
//uint32_t current_width, current_height;
|
//uint32_t current_width, current_height;
|
||||||
uint32_t render_target_height;
|
uint32_t render_target_height;
|
||||||
int current_framebuffer;
|
int current_framebuffer;
|
||||||
|
FilteringMode current_filter_mode = NONE;
|
||||||
|
|
||||||
int8_t depth_test;
|
int8_t depth_test;
|
||||||
int8_t depth_mask;
|
int8_t depth_mask;
|
||||||
|
@ -157,7 +158,7 @@ static LARGE_INTEGER last_time, accumulated_time, frequency;
|
||||||
|
|
||||||
int gfx_d3d11_create_framebuffer(void);
|
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;
|
D3D11_TEXTURE2D_DESC texture_desc;
|
||||||
texture_desc.Width = width;
|
texture_desc.Width = width;
|
||||||
texture_desc.Height = height;
|
texture_desc.Height = height;
|
||||||
|
@ -397,7 +398,7 @@ static struct ShaderProgram *gfx_d3d11_create_and_load_new_shader(uint64_t shade
|
||||||
char buf[4096];
|
char buf[4096];
|
||||||
size_t len, num_floats;
|
size_t len, num_floats;
|
||||||
|
|
||||||
gfx_direct3d_common_build_shader(buf, len, num_floats, cc_features, false, THREE_POINT_FILTERING);
|
gfx_direct3d_common_build_shader(buf, len, num_floats, cc_features, false, d3d.current_filter_mode == THREE_POINT);
|
||||||
|
|
||||||
ComPtr<ID3DBlob> vs, ps;
|
ComPtr<ID3DBlob> vs, ps;
|
||||||
ComPtr<ID3DBlob> error_blob;
|
ComPtr<ID3DBlob> error_blob;
|
||||||
|
@ -564,11 +565,8 @@ static void gfx_d3d11_set_sampler_parameters(int tile, bool linear_filter, uint3
|
||||||
D3D11_SAMPLER_DESC sampler_desc;
|
D3D11_SAMPLER_DESC sampler_desc;
|
||||||
ZeroMemory(&sampler_desc, sizeof(D3D11_SAMPLER_DESC));
|
ZeroMemory(&sampler_desc, sizeof(D3D11_SAMPLER_DESC));
|
||||||
|
|
||||||
#if THREE_POINT_FILTERING
|
sampler_desc.Filter = linear_filter && d3d.current_filter_mode == LINEAR ? D3D11_FILTER_MIN_MAG_MIP_LINEAR : D3D11_FILTER_MIN_MAG_MIP_POINT;
|
||||||
sampler_desc.Filter = D3D11_FILTER_MIN_MAG_MIP_POINT;
|
|
||||||
#else
|
|
||||||
sampler_desc.Filter = linear_filter ? D3D11_FILTER_MIN_MAG_MIP_LINEAR : D3D11_FILTER_MIN_MAG_MIP_POINT;
|
|
||||||
#endif
|
|
||||||
sampler_desc.AddressU = gfx_cm_to_d3d11(cms);
|
sampler_desc.AddressU = gfx_cm_to_d3d11(cms);
|
||||||
sampler_desc.AddressV = gfx_cm_to_d3d11(cmt);
|
sampler_desc.AddressV = gfx_cm_to_d3d11(cmt);
|
||||||
sampler_desc.AddressW = D3D11_TEXTURE_ADDRESS_WRAP;
|
sampler_desc.AddressW = D3D11_TEXTURE_ADDRESS_WRAP;
|
||||||
|
@ -672,12 +670,12 @@ static void gfx_d3d11_draw_triangles(float buf_vbo[], size_t buf_vbo_len, size_t
|
||||||
d3d.last_resource_views[i] = d3d.textures[d3d.current_texture_ids[i]].resource_view.Get();
|
d3d.last_resource_views[i] = d3d.textures[d3d.current_texture_ids[i]].resource_view.Get();
|
||||||
d3d.context->PSSetShaderResources(i, 1, d3d.textures[d3d.current_texture_ids[i]].resource_view.GetAddressOf());
|
d3d.context->PSSetShaderResources(i, 1, d3d.textures[d3d.current_texture_ids[i]].resource_view.GetAddressOf());
|
||||||
|
|
||||||
#if THREE_POINT_FILTERING
|
if (d3d.current_filter_mode == THREE_POINT) {
|
||||||
d3d.per_draw_cb_data.textures[i].width = d3d.textures[d3d.current_texture_ids[i]].width;
|
d3d.per_draw_cb_data.textures[i].width = d3d.textures[d3d.current_texture_ids[i]].width;
|
||||||
d3d.per_draw_cb_data.textures[i].height = d3d.textures[d3d.current_texture_ids[i]].height;
|
d3d.per_draw_cb_data.textures[i].height = d3d.textures[d3d.current_texture_ids[i]].height;
|
||||||
d3d.per_draw_cb_data.textures[i].linear_filtering = d3d.textures[d3d.current_texture_ids[i]].linear_filtering;
|
d3d.per_draw_cb_data.textures[i].linear_filtering = d3d.textures[d3d.current_texture_ids[i]].linear_filtering;
|
||||||
textures_changed = true;
|
textures_changed = true;
|
||||||
#endif
|
}
|
||||||
|
|
||||||
if (d3d.last_sampler_states[i].Get() != d3d.textures[d3d.current_texture_ids[i]].sampler_state.Get()) {
|
if (d3d.last_sampler_states[i].Get() != d3d.textures[d3d.current_texture_ids[i]].sampler_state.Get()) {
|
||||||
d3d.last_sampler_states[i] = d3d.textures[d3d.current_texture_ids[i]].sampler_state.Get();
|
d3d.last_sampler_states[i] = d3d.textures[d3d.current_texture_ids[i]].sampler_state.Get();
|
||||||
|
@ -880,6 +878,15 @@ void gfx_d3d11_select_texture_fb(int fbID) {
|
||||||
gfx_d3d11_select_texture(tile, d3d.framebuffers[fbID].texture_id);
|
gfx_d3d11_select_texture(tile, d3d.framebuffers[fbID].texture_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void gfx_d3d11_set_texture_filter(FilteringMode mode) {
|
||||||
|
d3d.current_filter_mode = mode;
|
||||||
|
gfx_texture_cache_clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
FilteringMode gfx_d3d11_get_texture_filter(void) {
|
||||||
|
return d3d.current_filter_mode;
|
||||||
|
}
|
||||||
|
|
||||||
std::map<std::pair<float, float>, uint16_t> gfx_d3d11_get_pixel_depth(int fb_id, const std::set<std::pair<float, float>>& coordinates) {
|
std::map<std::pair<float, float>, uint16_t> gfx_d3d11_get_pixel_depth(int fb_id, const std::set<std::pair<float, float>>& coordinates) {
|
||||||
Framebuffer& fb = d3d.framebuffers[fb_id];
|
Framebuffer& fb = d3d.framebuffers[fb_id];
|
||||||
TextureData& td = d3d.textures[fb.texture_id];
|
TextureData& td = d3d.textures[fb.texture_id];
|
||||||
|
@ -985,8 +992,8 @@ std::map<std::pair<float, float>, uint16_t> gfx_d3d11_get_pixel_depth(int fb_id,
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
ImTextureID SohImGui::GetTextureByID(int id) {
|
ImTextureID gfx_d3d11_get_texture_by_id(int id) {
|
||||||
return impl.backend == Backend::DX11 ? d3d.textures[id].resource_view.Get() : reinterpret_cast<ImTextureID>(id);
|
return d3d.textures[id].resource_view.Get();
|
||||||
}
|
}
|
||||||
|
|
||||||
struct GfxRenderingAPI gfx_direct3d11_api = {
|
struct GfxRenderingAPI gfx_direct3d11_api = {
|
||||||
|
@ -1019,7 +1026,9 @@ struct GfxRenderingAPI gfx_direct3d11_api = {
|
||||||
gfx_d3d11_get_pixel_depth,
|
gfx_d3d11_get_pixel_depth,
|
||||||
gfx_d3d11_get_framebuffer_texture_id,
|
gfx_d3d11_get_framebuffer_texture_id,
|
||||||
gfx_d3d11_select_texture_fb,
|
gfx_d3d11_select_texture_fb,
|
||||||
gfx_d3d11_delete_texture
|
gfx_d3d11_delete_texture,
|
||||||
|
gfx_d3d11_set_texture_filter,
|
||||||
|
gfx_d3d11_get_texture_filter
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -276,7 +276,7 @@ static void gfx_glx_set_fullscreen_state(bool on, bool call_callback) {
|
||||||
xev.xclient.data.l[2] = 0;
|
xev.xclient.data.l[2] = 0;
|
||||||
xev.xclient.data.l[3] = 0;
|
xev.xclient.data.l[3] = 0;
|
||||||
XSendEvent(glx.dpy, glx.root, 0, SubstructureNotifyMask | SubstructureRedirectMask, &xev);
|
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) {
|
if (glx.on_fullscreen_changed != NULL && call_callback) {
|
||||||
glx.on_fullscreen_changed(on);
|
glx.on_fullscreen_changed(on);
|
||||||
|
@ -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);
|
exit(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -458,7 +458,7 @@ static void gfx_glx_swap_buffers_begin(void) {
|
||||||
uint64_t target = glx.wanted_ust / FRAME_INTERVAL_US_DENOMINATOR;
|
uint64_t target = glx.wanted_ust / FRAME_INTERVAL_US_DENOMINATOR;
|
||||||
uint64_t now;
|
uint64_t now;
|
||||||
while (target > (now = (uint64_t)get_time() - glx.ust0)) {
|
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) {
|
if (nanosleep(&ts, NULL) == 0) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -600,6 +600,10 @@ static double gfx_glx_get_time(void) {
|
||||||
return 0.0;
|
return 0.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void gfx_glx_set_frame_divisor(int divisor) {
|
||||||
|
// TODO
|
||||||
|
}
|
||||||
|
|
||||||
struct GfxWindowManagerAPI gfx_glx = {
|
struct GfxWindowManagerAPI gfx_glx = {
|
||||||
gfx_glx_init,
|
gfx_glx_init,
|
||||||
gfx_glx_set_keyboard_callbacks,
|
gfx_glx_set_keyboard_callbacks,
|
||||||
|
@ -612,7 +616,8 @@ struct GfxWindowManagerAPI gfx_glx = {
|
||||||
gfx_glx_start_frame,
|
gfx_glx_start_frame,
|
||||||
gfx_glx_swap_buffers_begin,
|
gfx_glx_swap_buffers_begin,
|
||||||
gfx_glx_swap_buffers_end,
|
gfx_glx_swap_buffers_end,
|
||||||
gfx_glx_get_time
|
gfx_glx_get_time,
|
||||||
|
gfx_glx_set_frame_divisor,
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -3,6 +3,6 @@
|
||||||
|
|
||||||
#include "gfx_window_manager_api.h"
|
#include "gfx_window_manager_api.h"
|
||||||
|
|
||||||
struct GfxWindowManagerAPI gfx_glx;
|
extern struct GfxWindowManagerAPI gfx_glx;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -29,8 +29,9 @@
|
||||||
#include "SDL_opengl.h"
|
#include "SDL_opengl.h"
|
||||||
#else
|
#else
|
||||||
#include <SDL2/SDL.h>
|
#include <SDL2/SDL.h>
|
||||||
|
#include <GL/glew.h>
|
||||||
#define GL_GLEXT_PROTOTYPES 1
|
#define GL_GLEXT_PROTOTYPES 1
|
||||||
#include <SDL2/SDL_opengles2.h>
|
// #include <SDL2/SDL_opengles2.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "gfx_cc.h"
|
#include "gfx_cc.h"
|
||||||
|
@ -73,6 +74,7 @@ static uint32_t frame_count;
|
||||||
static vector<Framebuffer> framebuffers;
|
static vector<Framebuffer> framebuffers;
|
||||||
static size_t current_framebuffer;
|
static size_t current_framebuffer;
|
||||||
static float current_noise_scale;
|
static float current_noise_scale;
|
||||||
|
static FilteringMode current_filter_mode = THREE_POINT;
|
||||||
|
|
||||||
GLuint pixel_depth_rb, pixel_depth_fb;
|
GLuint pixel_depth_rb, pixel_depth_fb;
|
||||||
size_t pixel_depth_rb_size;
|
size_t pixel_depth_rb_size;
|
||||||
|
@ -177,6 +179,7 @@ static const char *shader_item_to_str(uint32_t item, bool with_alpha, bool only_
|
||||||
return "texel.a";
|
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) {
|
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) {
|
||||||
|
@ -211,7 +214,7 @@ static struct ShaderProgram* gfx_opengl_create_and_load_new_shader(uint64_t shad
|
||||||
gfx_cc_get_features(shader_id0, shader_id1, &cc_features);
|
gfx_cc_get_features(shader_id0, shader_id1, &cc_features);
|
||||||
|
|
||||||
char vs_buf[1024];
|
char vs_buf[1024];
|
||||||
char fs_buf[1024];
|
char fs_buf[3000];
|
||||||
size_t vs_len = 0;
|
size_t vs_len = 0;
|
||||||
size_t fs_len = 0;
|
size_t fs_len = 0;
|
||||||
size_t num_floats = 4;
|
size_t num_floats = 4;
|
||||||
|
@ -312,21 +315,42 @@ static struct ShaderProgram* gfx_opengl_create_and_load_new_shader(uint64_t shad
|
||||||
append_line(fs_buf, &fs_len, "}");
|
append_line(fs_buf, &fs_len, "}");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (current_filter_mode == THREE_POINT) {
|
||||||
|
append_line(fs_buf, &fs_len, "#define TEX_OFFSET(off) texture2D(tex, texCoord - (off)/texSize)");
|
||||||
|
append_line(fs_buf, &fs_len, "vec4 filter3point(in sampler2D tex, in vec2 texCoord, in vec2 texSize) {");
|
||||||
|
append_line(fs_buf, &fs_len, " vec2 offset = fract(texCoord*texSize - vec2(0.5));");
|
||||||
|
append_line(fs_buf, &fs_len, " offset -= step(1.0, offset.x + offset.y);");
|
||||||
|
append_line(fs_buf, &fs_len, " vec4 c0 = TEX_OFFSET(offset);");
|
||||||
|
append_line(fs_buf, &fs_len, " vec4 c1 = TEX_OFFSET(vec2(offset.x - sign(offset.x), offset.y));");
|
||||||
|
append_line(fs_buf, &fs_len, " vec4 c2 = TEX_OFFSET(vec2(offset.x, offset.y - sign(offset.y)));");
|
||||||
|
append_line(fs_buf, &fs_len, " return c0 + abs(offset.x)*(c1-c0) + abs(offset.y)*(c2-c0);");
|
||||||
|
append_line(fs_buf, &fs_len, "}");
|
||||||
|
append_line(fs_buf, &fs_len, "vec4 hookTexture2D(in sampler2D tex, in vec2 uv, in vec2 texSize) {");
|
||||||
|
append_line(fs_buf, &fs_len, " return filter3point(tex, uv, texSize);");
|
||||||
|
append_line(fs_buf, &fs_len, "}");
|
||||||
|
} else {
|
||||||
|
append_line(fs_buf, &fs_len, "vec4 hookTexture2D(in sampler2D tex, in vec2 uv, in vec2 texSize) {");
|
||||||
|
append_line(fs_buf, &fs_len, " return texture2D(tex, uv);");
|
||||||
|
append_line(fs_buf, &fs_len, "}");
|
||||||
|
}
|
||||||
|
|
||||||
append_line(fs_buf, &fs_len, "void main() {");
|
append_line(fs_buf, &fs_len, "void main() {");
|
||||||
|
|
||||||
for (int i = 0; i < 2; i++) {
|
for (int i = 0; i < 2; i++) {
|
||||||
if (cc_features.used_textures[i]) {
|
if (cc_features.used_textures[i]) {
|
||||||
bool s = cc_features.clamp[i][0], t = cc_features.clamp[i][1];
|
bool s = cc_features.clamp[i][0], t = cc_features.clamp[i][1];
|
||||||
if (!s && !t) {
|
|
||||||
fs_len += sprintf(fs_buf + fs_len, "vec4 texVal%d = texture2D(uTex%d, vTexCoord%d);\n", i, i, i);
|
|
||||||
} else {
|
|
||||||
fs_len += sprintf(fs_buf + fs_len, "vec2 texSize%d = textureSize(uTex%d, 0);\n", i, i);
|
fs_len += sprintf(fs_buf + fs_len, "vec2 texSize%d = textureSize(uTex%d, 0);\n", i, i);
|
||||||
if (s && t) {
|
|
||||||
fs_len += sprintf(fs_buf + fs_len, "vec4 texVal%d = texture2D(uTex%d, clamp(vTexCoord%d, 0.5 / texSize%d, vec2(vTexClampS%d, vTexClampT%d)));\n", i, i, i, i, i, i);
|
if (!s && !t) {
|
||||||
} else if (s) {
|
fs_len += sprintf(fs_buf + fs_len, "vec4 texVal%d = hookTexture2D(uTex%d, vTexCoord%d, texSize%d);\n", i, i, i, i);
|
||||||
fs_len += sprintf(fs_buf + fs_len, "vec4 texVal%d = texture2D(uTex%d, vec2(clamp(vTexCoord%d.s, 0.5 / texSize%d.s, vTexClampS%d), vTexCoord%d.t));\n", i, i, i, i, i, i);
|
|
||||||
} else {
|
} else {
|
||||||
fs_len += sprintf(fs_buf + fs_len, "vec4 texVal%d = texture2D(uTex%d, vec2(vTexCoord%d.s, clamp(vTexCoord%d.t, 0.5 / texSize%d.t, vTexClampT%d)));\n", i, i, i, i, i, i);
|
if (s && t) {
|
||||||
|
fs_len += sprintf(fs_buf + fs_len, "vec4 texVal%d = hookTexture2D(uTex%d, clamp(vTexCoord%d, 0.5 / texSize%d, vec2(vTexClampS%d, vTexClampT%d)), texSize%d);\n", i, i, i, i, i, i, i);
|
||||||
|
} else if (s) {
|
||||||
|
fs_len += sprintf(fs_buf + fs_len, "vec4 texVal%d = hookTexture2D(uTex%d, vec2(clamp(vTexCoord%d.s, 0.5 / texSize%d.s, vTexClampS%d), vTexCoord%d.t), texSize%d);\n", i, i, i, i, i, i, i);
|
||||||
|
} else {
|
||||||
|
fs_len += sprintf(fs_buf + fs_len, "vec4 texVal%d = hookTexture2D(uTex%d, vec2(vTexCoord%d.s, clamp(vTexCoord%d.t, 0.5 / texSize%d.t, vTexClampT%d)), texSize%d);\n", i, i, i, i, i, i, i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -422,9 +446,9 @@ static struct ShaderProgram* gfx_opengl_create_and_load_new_shader(uint64_t shad
|
||||||
GLint max_length = 0;
|
GLint max_length = 0;
|
||||||
glGetShaderiv(fragment_shader, GL_INFO_LOG_LENGTH, &max_length);
|
glGetShaderiv(fragment_shader, GL_INFO_LOG_LENGTH, &max_length);
|
||||||
char error_log[1024];
|
char error_log[1024];
|
||||||
//fprintf(stderr, "Fragment shader compilation failed\n");
|
fprintf(stderr, "Fragment shader compilation failed\n");
|
||||||
glGetShaderInfoLog(fragment_shader, max_length, &max_length, &error_log[0]);
|
glGetShaderInfoLog(fragment_shader, max_length, &max_length, &error_log[0]);
|
||||||
//fprintf(stderr, "%s\n", &error_log[0]);
|
fprintf(stderr, "%s\n", &error_log[0]);
|
||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -549,12 +573,14 @@ static uint32_t gfx_cm_to_opengl(uint32_t val) {
|
||||||
case G_TX_NOMIRROR | G_TX_WRAP:
|
case G_TX_NOMIRROR | G_TX_WRAP:
|
||||||
return GL_REPEAT;
|
return GL_REPEAT;
|
||||||
}
|
}
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void gfx_opengl_set_sampler_parameters(int tile, bool linear_filter, uint32_t cms, uint32_t cmt) {
|
static void gfx_opengl_set_sampler_parameters(int tile, bool linear_filter, uint32_t cms, uint32_t cmt) {
|
||||||
|
const GLint filter = linear_filter && current_filter_mode == LINEAR ? GL_LINEAR : GL_NEAREST;
|
||||||
glActiveTexture(GL_TEXTURE0 + tile);
|
glActiveTexture(GL_TEXTURE0 + tile);
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, linear_filter ? GL_LINEAR : GL_NEAREST);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filter);
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, linear_filter ? GL_LINEAR : GL_NEAREST);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filter);
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, gfx_cm_to_opengl(cms));
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, gfx_cm_to_opengl(cms));
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, gfx_cm_to_opengl(cmt));
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, gfx_cm_to_opengl(cmt));
|
||||||
}
|
}
|
||||||
|
@ -823,6 +849,15 @@ static std::map<std::pair<float, float>, uint16_t> gfx_opengl_get_pixel_depth(in
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void gfx_opengl_set_texture_filter(FilteringMode mode) {
|
||||||
|
current_filter_mode = mode;
|
||||||
|
gfx_texture_cache_clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
FilteringMode gfx_opengl_get_texture_filter(void) {
|
||||||
|
return current_filter_mode;
|
||||||
|
}
|
||||||
|
|
||||||
struct GfxRenderingAPI gfx_opengl_api = {
|
struct GfxRenderingAPI gfx_opengl_api = {
|
||||||
gfx_opengl_get_clip_parameters,
|
gfx_opengl_get_clip_parameters,
|
||||||
gfx_opengl_unload_shader,
|
gfx_opengl_unload_shader,
|
||||||
|
@ -853,7 +888,9 @@ struct GfxRenderingAPI gfx_opengl_api = {
|
||||||
gfx_opengl_get_pixel_depth,
|
gfx_opengl_get_pixel_depth,
|
||||||
gfx_opengl_get_framebuffer_texture_id,
|
gfx_opengl_get_framebuffer_texture_id,
|
||||||
gfx_opengl_select_texture_fb,
|
gfx_opengl_select_texture_fb,
|
||||||
gfx_opengl_delete_texture
|
gfx_opengl_delete_texture,
|
||||||
|
gfx_opengl_set_texture_filter,
|
||||||
|
gfx_opengl_get_texture_filter
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
#include <set>
|
#include <set>
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
#include <list>
|
||||||
|
|
||||||
#ifndef _LANGUAGE_C
|
#ifndef _LANGUAGE_C
|
||||||
#define _LANGUAGE_C
|
#define _LANGUAGE_C
|
||||||
|
@ -30,6 +31,8 @@
|
||||||
#include "../StrHash64.h"
|
#include "../StrHash64.h"
|
||||||
#include "../../SohImGuiImpl.h"
|
#include "../../SohImGuiImpl.h"
|
||||||
#include "../../Environment.h"
|
#include "../../Environment.h"
|
||||||
|
#include "../../GameVersions.h"
|
||||||
|
#include "../../ResourceMgr.h"
|
||||||
|
|
||||||
// OTRTODO: fix header files for these
|
// OTRTODO: fix header files for these
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
@ -45,6 +48,8 @@ extern "C" {
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
|
#define SEG_ADDR(seg, addr) (addr | (seg << 24) | 1)
|
||||||
|
|
||||||
#define SUPPORT_CHECK(x) assert(x)
|
#define SUPPORT_CHECK(x) assert(x)
|
||||||
|
|
||||||
// SCALE_M_N: upscale/downscale M-bit integer to N-bit
|
// SCALE_M_N: upscale/downscale M-bit integer to N-bit
|
||||||
|
@ -209,7 +214,7 @@ static map<int, FBInfo> framebuffers;
|
||||||
static set<pair<float, float>> get_pixel_depth_pending;
|
static set<pair<float, float>> get_pixel_depth_pending;
|
||||||
static map<pair<float, float>, uint16_t> get_pixel_depth_cached;
|
static map<pair<float, float>, uint16_t> get_pixel_depth_cached;
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
#ifdef _WIN32
|
||||||
// TODO: Properly implement for MSVC
|
// TODO: Properly implement for MSVC
|
||||||
static unsigned long get_time(void)
|
static unsigned long get_time(void)
|
||||||
{
|
{
|
||||||
|
@ -447,15 +452,15 @@ static void gfx_generate_cc(struct ColorCombiner *comb, uint64_t cc_id) {
|
||||||
val = SHADER_COMBINED;
|
val = SHADER_COMBINED;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
// fallthrough for G_ACMUX_LOD_FRACTION
|
|
||||||
c[i][1][j] = G_CCMUX_LOD_FRACTION;
|
c[i][1][j] = G_CCMUX_LOD_FRACTION;
|
||||||
|
[[fallthrough]]; // for G_ACMUX_LOD_FRACTION
|
||||||
case G_ACMUX_1:
|
case G_ACMUX_1:
|
||||||
//case G_ACMUX_PRIM_LOD_FRAC: same numerical value
|
//case G_ACMUX_PRIM_LOD_FRAC: same numerical value
|
||||||
if (j != 2) {
|
if (j != 2) {
|
||||||
val = SHADER_1;
|
val = SHADER_1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
// fallthrough for G_ACMUX_PRIM_LOD_FRAC
|
[[fallthrough]]; // for G_ACMUX_PRIM_LOD_FRAC
|
||||||
case G_ACMUX_PRIMITIVE:
|
case G_ACMUX_PRIMITIVE:
|
||||||
case G_ACMUX_SHADE:
|
case G_ACMUX_SHADE:
|
||||||
case G_ACMUX_ENVIRONMENT:
|
case G_ACMUX_ENVIRONMENT:
|
||||||
|
@ -564,7 +569,7 @@ static void gfx_texture_cache_delete(const uint8_t* orig_addr)
|
||||||
if (it->first.texture_addr == 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.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.free_texture_ids.push_back(it->second.texture_id);
|
||||||
gfx_texture_cache.map.erase(it);
|
gfx_texture_cache.map.erase(it->first);
|
||||||
again = true;
|
again = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -1692,7 +1697,7 @@ static void gfx_dp_load_block(uint8_t tile, uint32_t uls, uint32_t ult, uint32_t
|
||||||
SUPPORT_CHECK(ult == 0);
|
SUPPORT_CHECK(ult == 0);
|
||||||
|
|
||||||
// The lrs field rather seems to be number of pixels to load
|
// 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) {
|
switch (rdp.texture_to_load.siz) {
|
||||||
case G_IM_SIZ_4b:
|
case G_IM_SIZ_4b:
|
||||||
word_size_shift = 0; // Or -1? It's unused in SM64 anyway.
|
word_size_shift = 0; // Or -1? It's unused in SM64 anyway.
|
||||||
|
@ -1720,7 +1725,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) {
|
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);
|
SUPPORT_CHECK(tile == G_TX_LOADTILE);
|
||||||
|
|
||||||
uint32_t word_size_shift;
|
uint32_t word_size_shift = 0;
|
||||||
switch (rdp.texture_to_load.siz) {
|
switch (rdp.texture_to_load.siz) {
|
||||||
case G_IM_SIZ_4b:
|
case G_IM_SIZ_4b:
|
||||||
word_size_shift = 0;
|
word_size_shift = 0;
|
||||||
|
@ -2060,12 +2065,11 @@ static void gfx_s2dex_bg_copy(const uObjBg* bg) {
|
||||||
static inline void* seg_addr(uintptr_t w1)
|
static inline void* seg_addr(uintptr_t w1)
|
||||||
{
|
{
|
||||||
// Segmented?
|
// Segmented?
|
||||||
if (w1 >= 0xF0000000)
|
if (w1 & 1)
|
||||||
{
|
{
|
||||||
uint32_t segNum = (w1 >> 24);
|
uint32_t segNum = (w1 >> 24);
|
||||||
segNum -= 0xF0;
|
|
||||||
|
|
||||||
uint32_t offset = w1 & 0x00FFFFFF;
|
uint32_t offset = w1 & 0x00FFFFFE;
|
||||||
//offset = 0; // Cursed Malon bug
|
//offset = 0; // Cursed Malon bug
|
||||||
|
|
||||||
if (segmentPointers[segNum] != 0)
|
if (segmentPointers[segNum] != 0)
|
||||||
|
@ -2082,7 +2086,7 @@ static inline void* seg_addr(uintptr_t w1)
|
||||||
#define C0(pos, width) ((cmd->words.w0 >> (pos)) & ((1U << width) - 1))
|
#define C0(pos, width) ((cmd->words.w0 >> (pos)) & ((1U << width) - 1))
|
||||||
#define C1(pos, width) ((cmd->words.w1 >> (pos)) & ((1U << width) - 1))
|
#define C1(pos, width) ((cmd->words.w1 >> (pos)) & ((1U << width) - 1))
|
||||||
|
|
||||||
int dListBP;
|
unsigned int dListBP;
|
||||||
int matrixBP;
|
int matrixBP;
|
||||||
uintptr_t clearMtx;
|
uintptr_t clearMtx;
|
||||||
|
|
||||||
|
@ -2149,8 +2153,16 @@ static void gfx_run_dl(Gfx* cmd) {
|
||||||
uintptr_t mtxAddr = cmd->words.w1;
|
uintptr_t mtxAddr = cmd->words.w1;
|
||||||
|
|
||||||
// OTRTODO: Temp way of dealing with gMtxClear. Need something more elegant in the future...
|
// OTRTODO: Temp way of dealing with gMtxClear. Need something more elegant in the future...
|
||||||
if (mtxAddr == 0xF012DB20 || mtxAddr == 0xF012DB40)
|
uint32_t gameVersion = Ship::GlobalCtx2::GetInstance()->GetResourceManager()->GetGameVersion();
|
||||||
|
if (gameVersion == OOT_PAL_GC) {
|
||||||
|
if (mtxAddr == SEG_ADDR(0, 0x0FBC20)) {
|
||||||
mtxAddr = clearMtx;
|
mtxAddr = clearMtx;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (mtxAddr == SEG_ADDR(0, 0x12DB20) || mtxAddr == SEG_ADDR(0, 0x12DB40)) {
|
||||||
|
mtxAddr = clearMtx;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef F3DEX_GBI_2
|
#ifdef F3DEX_GBI_2
|
||||||
gfx_sp_matrix(C0(0, 8) ^ G_MTX_PUSH, (const int32_t *) seg_addr(mtxAddr));
|
gfx_sp_matrix(C0(0, 8) ^ G_MTX_PUSH, (const int32_t *) seg_addr(mtxAddr));
|
||||||
|
@ -2250,7 +2262,7 @@ static void gfx_run_dl(Gfx* cmd) {
|
||||||
|
|
||||||
cmd--;
|
cmd--;
|
||||||
|
|
||||||
if (ourHash != -1)
|
if (ourHash != (uint64_t)-1)
|
||||||
ResourceMgr_RegisterResourcePatch(ourHash, cmd - dListStart, cmd->words.w1);
|
ResourceMgr_RegisterResourcePatch(ourHash, cmd - dListStart, cmd->words.w1);
|
||||||
|
|
||||||
cmd->words.w1 = (uintptr_t)vtx;
|
cmd->words.w1 = (uintptr_t)vtx;
|
||||||
|
@ -2368,7 +2380,7 @@ static void gfx_run_dl(Gfx* cmd) {
|
||||||
case G_QUAD:
|
case G_QUAD:
|
||||||
{
|
{
|
||||||
int bp = 0;
|
int bp = 0;
|
||||||
// fallthrough
|
[[fallthrough]];
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#if defined(F3DEX_GBI) || defined(F3DLP_GBI)
|
#if defined(F3DEX_GBI) || defined(F3DLP_GBI)
|
||||||
|
@ -2398,7 +2410,7 @@ static void gfx_run_dl(Gfx* cmd) {
|
||||||
|
|
||||||
char* imgData = (char*)i;
|
char* imgData = (char*)i;
|
||||||
|
|
||||||
if ((i & 0xF0000000) != 0xF0000000)
|
if ((i & 1) != 1)
|
||||||
if (ResourceMgr_OTRSigCheck(imgData) == 1)
|
if (ResourceMgr_OTRSigCheck(imgData) == 1)
|
||||||
i = (uintptr_t)ResourceMgr_LoadTexByName(imgData);
|
i = (uintptr_t)ResourceMgr_LoadTexByName(imgData);
|
||||||
|
|
||||||
|
@ -2419,7 +2431,7 @@ static void gfx_run_dl(Gfx* cmd) {
|
||||||
char* tex = NULL;
|
char* tex = NULL;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (addr != NULL)
|
if (addr != 0)
|
||||||
{
|
{
|
||||||
tex = (char*)addr;
|
tex = (char*)addr;
|
||||||
}
|
}
|
||||||
|
@ -2433,7 +2445,7 @@ static void gfx_run_dl(Gfx* cmd) {
|
||||||
uintptr_t oldData = cmd->words.w1;
|
uintptr_t oldData = cmd->words.w1;
|
||||||
cmd->words.w1 = (uintptr_t)tex;
|
cmd->words.w1 = (uintptr_t)tex;
|
||||||
|
|
||||||
if (ourHash != -1)
|
if (ourHash != (uint64_t)-1)
|
||||||
ResourceMgr_RegisterResourcePatch(ourHash, cmd - dListStart, oldData);
|
ResourceMgr_RegisterResourcePatch(ourHash, cmd - dListStart, oldData);
|
||||||
|
|
||||||
cmd++;
|
cmd++;
|
||||||
|
@ -2648,7 +2660,7 @@ void gfx_init(struct GfxWindowManagerAPI *wapi, struct GfxRenderingAPI *rapi, co
|
||||||
game_framebuffer_msaa_resolved = gfx_rapi->create_framebuffer();
|
game_framebuffer_msaa_resolved = gfx_rapi->create_framebuffer();
|
||||||
|
|
||||||
for (int i = 0; i < 16; i++)
|
for (int i = 0; i < 16; i++)
|
||||||
segmentPointers[i] = NULL;
|
segmentPointers[i] = 0;
|
||||||
|
|
||||||
// Used in the 120 star TAS
|
// Used in the 120 star TAS
|
||||||
static uint32_t precomp_shaders[] = {
|
static uint32_t precomp_shaders[] = {
|
||||||
|
|
|
@ -4,12 +4,14 @@
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
|
#include <list>
|
||||||
|
|
||||||
struct GfxRenderingAPI;
|
struct GfxRenderingAPI;
|
||||||
struct GfxWindowManagerAPI;
|
struct GfxWindowManagerAPI;
|
||||||
|
|
||||||
struct XYWidthHeight {
|
struct XYWidthHeight {
|
||||||
int16_t x, y, width, height;
|
int16_t x, y;
|
||||||
|
uint32_t width, height;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct GfxDimensions {
|
struct GfxDimensions {
|
||||||
|
|
|
@ -15,6 +15,12 @@ struct GfxClipParameters {
|
||||||
bool invert_y;
|
bool invert_y;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum FilteringMode {
|
||||||
|
THREE_POINT,
|
||||||
|
LINEAR,
|
||||||
|
NONE
|
||||||
|
};
|
||||||
|
|
||||||
struct GfxRenderingAPI {
|
struct GfxRenderingAPI {
|
||||||
struct GfxClipParameters (*get_clip_parameters)(void);
|
struct GfxClipParameters (*get_clip_parameters)(void);
|
||||||
void (*unload_shader)(struct ShaderProgram *old_prg);
|
void (*unload_shader)(struct ShaderProgram *old_prg);
|
||||||
|
@ -46,6 +52,8 @@ struct GfxRenderingAPI {
|
||||||
void *(*get_framebuffer_texture_id)(int fb_id);
|
void *(*get_framebuffer_texture_id)(int fb_id);
|
||||||
void (*select_texture_fb)(int fb_id);
|
void (*select_texture_fb)(int fb_id);
|
||||||
void (*delete_texture)(uint32_t texID);
|
void (*delete_texture)(uint32_t texID);
|
||||||
|
void (*set_texture_filter)(FilteringMode mode);
|
||||||
|
FilteringMode(*get_texture_filter)(void);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
#if !defined(__linux__) && defined(ENABLE_OPENGL)
|
#if defined(ENABLE_OPENGL)
|
||||||
|
|
||||||
#ifdef __MINGW32__
|
#ifdef __MINGW32__
|
||||||
#define FOR_WINDOWS 1
|
#define FOR_WINDOWS 1
|
||||||
|
@ -23,7 +23,9 @@
|
||||||
|
|
||||||
#include "gfx_window_manager_api.h"
|
#include "gfx_window_manager_api.h"
|
||||||
#include "gfx_screen_config.h"
|
#include "gfx_screen_config.h"
|
||||||
|
#ifdef _WIN32
|
||||||
#include <WTypesbase.h>
|
#include <WTypesbase.h>
|
||||||
|
#endif
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
|
|
||||||
#define GFX_API_NAME "SDL2 - OpenGL"
|
#define GFX_API_NAME "SDL2 - OpenGL"
|
||||||
|
@ -117,7 +119,9 @@ static void set_fullscreen(bool on, bool call_callback) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint64_t previous_time;
|
static uint64_t previous_time;
|
||||||
|
#ifndef __linux__
|
||||||
static HANDLE timer;
|
static HANDLE timer;
|
||||||
|
#endif
|
||||||
|
|
||||||
static int frameDivisor = 1;
|
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_DEPTH_SIZE, 24);
|
||||||
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
|
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
|
||||||
|
|
||||||
|
#ifndef __linux
|
||||||
timer = CreateWaitableTimer(nullptr, false, nullptr);
|
timer = CreateWaitableTimer(nullptr, false, nullptr);
|
||||||
|
#endif
|
||||||
|
|
||||||
//SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 1);
|
//SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 1);
|
||||||
//SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, 4);
|
//SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, 4);
|
||||||
|
|
|
@ -86,14 +86,8 @@
|
||||||
|
|
||||||
#include <stdint.h>
|
#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
|
#define INITIAL_CRC64 0xffffffffffffffffULL
|
||||||
|
|
||||||
extern uint64_t update_crc64(const void* buf, unint len, u64 crc);
|
extern uint64_t update_crc64(const void* buf, uint32_t len, uint64_t crc);
|
||||||
extern u64 crc64(const void* buf, unint len);
|
extern uint64_t crc64(const void* buf, uint32_t len);
|
||||||
extern u64 CRC64(const char* t);
|
extern uint64_t CRC64(const char* t);
|
|
@ -10,6 +10,7 @@
|
||||||
#include <spdlog/details/synchronous_factory.h>
|
#include <spdlog/details/synchronous_factory.h>
|
||||||
#include "SohImGuiImpl.h"
|
#include "SohImGuiImpl.h"
|
||||||
#include "GameSettings.h"
|
#include "GameSettings.h"
|
||||||
|
#include "Cvar.h"
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
@ -45,8 +46,8 @@ protected:
|
||||||
}
|
}
|
||||||
formatted.push_back('\0');
|
formatted.push_back('\0');
|
||||||
const char *msg_output = formatted.data();
|
const char *msg_output = formatted.data();
|
||||||
if (Game::Settings.debug.soh_sink && SohImGui::console->opened)
|
if (CVar_GetS32("gSinkEnabled", 0) && SohImGui::console->opened)
|
||||||
SohImGui::console->Append("SoH Logging", priority, msg_output);
|
SohImGui::console->Append("SoH Logging", priority, "%s", msg_output);
|
||||||
}
|
}
|
||||||
|
|
||||||
void flush_() override {}
|
void flush_() override {}
|
||||||
|
@ -66,6 +67,8 @@ private:
|
||||||
return Priority::ERROR_LVL;
|
return Priority::ERROR_LVL;
|
||||||
case spdlog::level::critical:
|
case spdlog::level::critical:
|
||||||
return Priority::ERROR_LVL;
|
return Priority::ERROR_LVL;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
return Priority::LOG_LVL;
|
return Priority::LOG_LVL;
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,7 +39,7 @@ namespace Ship
|
||||||
Vertex* vtxData = new Vertex[numVerts];
|
Vertex* vtxData = new Vertex[numVerts];
|
||||||
uint32_t* indicesData = new uint32_t[numPolys];
|
uint32_t* indicesData = new uint32_t[numPolys];
|
||||||
|
|
||||||
if (vertices != NULL)
|
if (vertices != 0)
|
||||||
{
|
{
|
||||||
reader->Seek(headerStart + vertices, SeekOffsetType::Start);
|
reader->Seek(headerStart + vertices, SeekOffsetType::Start);
|
||||||
|
|
||||||
|
@ -47,7 +47,7 @@ namespace Ship
|
||||||
vtxData[i].pos = reader->ReadVec3f();
|
vtxData[i].pos = reader->ReadVec3f();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (normals != NULL)
|
if (normals != 0)
|
||||||
{
|
{
|
||||||
reader->Seek(headerStart + normals, SeekOffsetType::Start);
|
reader->Seek(headerStart + normals, SeekOffsetType::Start);
|
||||||
|
|
||||||
|
@ -55,7 +55,7 @@ namespace Ship
|
||||||
vtxData[i].normal = reader->ReadVec3f();
|
vtxData[i].normal = reader->ReadVec3f();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (vertexColors != NULL)
|
if (vertexColors != 0)
|
||||||
{
|
{
|
||||||
reader->Seek(headerStart + vertexColors, SeekOffsetType::Start);
|
reader->Seek(headerStart + vertexColors, SeekOffsetType::Start);
|
||||||
|
|
||||||
|
@ -63,7 +63,7 @@ namespace Ship
|
||||||
vtxData[i].color = reader->ReadColor3b();
|
vtxData[i].color = reader->ReadColor3b();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (uvCoords != NULL)
|
if (uvCoords != 0)
|
||||||
{
|
{
|
||||||
reader->Seek(headerStart + uvCoords, SeekOffsetType::Start);
|
reader->Seek(headerStart + uvCoords, SeekOffsetType::Start);
|
||||||
|
|
||||||
|
@ -71,7 +71,7 @@ namespace Ship
|
||||||
vtxData[i].uv = reader->ReadVec2f();
|
vtxData[i].uv = reader->ReadVec2f();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (boneWeights != NULL)
|
if (boneWeights != 0)
|
||||||
{
|
{
|
||||||
reader->Seek(headerStart + boneWeights, SeekOffsetType::Start);
|
reader->Seek(headerStart + boneWeights, SeekOffsetType::Start);
|
||||||
|
|
||||||
|
@ -81,7 +81,7 @@ namespace Ship
|
||||||
mdl->boneWeights[i] = reader->ReadVec2f();
|
mdl->boneWeights[i] = reader->ReadVec2f();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (faces != NULL)
|
if (faces != 0)
|
||||||
{
|
{
|
||||||
reader->Seek(headerStart + faces, SeekOffsetType::Start);
|
reader->Seek(headerStart + faces, SeekOffsetType::Start);
|
||||||
reader->Read((char*)indicesData, numPolys * sizeof(uint32_t));
|
reader->Read((char*)indicesData, numPolys * sizeof(uint32_t));
|
||||||
|
|
173
libultraship/libultraship/PulseAudioPlayer.cpp
Normal file
173
libultraship/libultraship/PulseAudioPlayer.cpp
Normal 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
|
26
libultraship/libultraship/PulseAudioPlayer.h
Normal file
26
libultraship/libultraship/PulseAudioPlayer.h
Normal 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
|
|
@ -2,8 +2,8 @@
|
||||||
#include "DisplayList.h"
|
#include "DisplayList.h"
|
||||||
#include "ResourceMgr.h"
|
#include "ResourceMgr.h"
|
||||||
#include "Utils/BinaryReader.h"
|
#include "Utils/BinaryReader.h"
|
||||||
#include "lib/tinyxml2/tinyxml2.h"
|
#include "Lib/tinyxml2/tinyxml2.h"
|
||||||
#include "lib/Fast3D/U64/PR/ultra64/gbi.h"
|
#include "Lib/Fast3D/U64/PR/ultra64/gbi.h"
|
||||||
|
|
||||||
namespace Ship
|
namespace Ship
|
||||||
{
|
{
|
||||||
|
@ -38,7 +38,7 @@ namespace Ship
|
||||||
free(cachedGameAsset);
|
free(cachedGameAsset);
|
||||||
cachedGameAsset = nullptr;
|
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);
|
std::string hashStr = resMgr->HashToString(patches[i].crc);
|
||||||
auto resShared = resMgr->GetCachedFile(hashStr);
|
auto resShared = resMgr->GetCachedFile(hashStr);
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
#include "GlobalCtx2.h"
|
#include "GlobalCtx2.h"
|
||||||
#include "StrHash.h"
|
#include "StrHash.h"
|
||||||
#include "File.h"
|
#include "File.h"
|
||||||
#include "lib/tinyxml2/tinyxml2.h"
|
#include "Lib/tinyxml2/tinyxml2.h"
|
||||||
|
|
||||||
namespace Ship
|
namespace Ship
|
||||||
{
|
{
|
||||||
|
@ -101,10 +101,10 @@ namespace Ship
|
||||||
|
|
||||||
class ResourcePromise {
|
class ResourcePromise {
|
||||||
public:
|
public:
|
||||||
std::shared_ptr<Resource> Resource;
|
std::shared_ptr<Resource> resource;
|
||||||
std::shared_ptr<File> File;
|
std::shared_ptr<File> file;
|
||||||
std::condition_variable ResourceLoadNotifier;
|
std::condition_variable resourceLoadNotifier;
|
||||||
std::mutex ResourceLoadMutex;
|
std::mutex resourceLoadMutex;
|
||||||
bool bHasResourceLoaded = false;
|
bool bHasResourceLoaded = false;
|
||||||
};
|
};
|
||||||
}
|
}
|
|
@ -124,15 +124,15 @@ namespace Ship {
|
||||||
|
|
||||||
// Wait for the underlying File to complete loading
|
// Wait for the underlying File to complete loading
|
||||||
{
|
{
|
||||||
std::unique_lock<std::mutex> FileLock(ToLoad->File->FileLoadMutex);
|
std::unique_lock<std::mutex> FileLock(ToLoad->file->FileLoadMutex);
|
||||||
while (!ToLoad->File->bIsLoaded && !ToLoad->File->bHasLoadError) {
|
while (!ToLoad->file->bIsLoaded && !ToLoad->file->bHasLoadError) {
|
||||||
ToLoad->File->FileLoadNotifier.wait(FileLock);
|
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)
|
if (UnmanagedRes != nullptr)
|
||||||
{
|
{
|
||||||
|
@ -140,13 +140,13 @@ namespace Ship {
|
||||||
auto Res = std::shared_ptr<Resource>(UnmanagedRes);
|
auto Res = std::shared_ptr<Resource>(UnmanagedRes);
|
||||||
|
|
||||||
if (Res != nullptr) {
|
if (Res != nullptr) {
|
||||||
std::unique_lock<std::mutex> Lock(ToLoad->ResourceLoadMutex);
|
std::unique_lock<std::mutex> Lock(ToLoad->resourceLoadMutex);
|
||||||
|
|
||||||
ToLoad->bHasResourceLoaded = true;
|
ToLoad->bHasResourceLoaded = true;
|
||||||
ToLoad->Resource = Res;
|
ToLoad->resource = Res;
|
||||||
ResourceCache[Res->file->path] = 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
|
// Disabled for now because it can cause random crashes
|
||||||
//FileCache[Res->File->path] = nullptr;
|
//FileCache[Res->File->path] = nullptr;
|
||||||
|
@ -155,9 +155,9 @@ namespace Ship {
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
ToLoad->bHasResourceLoaded = false;
|
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();
|
//ResLock.lock();
|
||||||
|
@ -167,10 +167,10 @@ namespace Ship {
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ToLoad->bHasResourceLoaded = false;
|
ToLoad->bHasResourceLoaded = false;
|
||||||
ToLoad->Resource = nullptr;
|
ToLoad->resource = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
ToLoad->ResourceLoadNotifier.notify_all();
|
ToLoad->resourceLoadNotifier.notify_all();
|
||||||
}
|
}
|
||||||
|
|
||||||
SPDLOG_INFO("Resource Manager LoadResourceThread ended");
|
SPDLOG_INFO("Resource Manager LoadResourceThread ended");
|
||||||
|
@ -232,17 +232,17 @@ namespace Ship {
|
||||||
|
|
||||||
if (!Promise->bHasResourceLoaded)
|
if (!Promise->bHasResourceLoaded)
|
||||||
{
|
{
|
||||||
std::unique_lock<std::mutex> Lock(Promise->ResourceLoadMutex);
|
std::unique_lock<std::mutex> Lock(Promise->resourceLoadMutex);
|
||||||
while (!Promise->bHasResourceLoaded) {
|
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) {
|
std::shared_ptr<ResourcePromise> ResourceMgr::LoadResourceAsync(std::string FilePath) {
|
||||||
StringHelper::ReplaceOriginal(FilePath, "/", "\\");
|
StringHelper::ReplaceOriginal(FilePath, "\\", "/");
|
||||||
|
|
||||||
if (StringHelper::StartsWith(FilePath, "__OTR__"))
|
if (StringHelper::StartsWith(FilePath, "__OTR__"))
|
||||||
FilePath = StringHelper::Split(FilePath, "__OTR__")[1];
|
FilePath = StringHelper::Split(FilePath, "__OTR__")[1];
|
||||||
|
@ -257,9 +257,9 @@ namespace Ship {
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<File> FileData = LoadFile(FilePath);
|
std::shared_ptr<File> FileData = LoadFile(FilePath);
|
||||||
Promise->File = FileData;
|
Promise->file = FileData;
|
||||||
|
|
||||||
if (Promise->File->bHasLoadError)
|
if (Promise->file->bHasLoadError)
|
||||||
{
|
{
|
||||||
Promise->bHasResourceLoaded = true;
|
Promise->bHasResourceLoaded = true;
|
||||||
}
|
}
|
||||||
|
@ -271,7 +271,7 @@ namespace Ship {
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Promise->bHasResourceLoaded = true;
|
Promise->bHasResourceLoaded = true;
|
||||||
Promise->Resource = resCacheFind->second;
|
Promise->resource = resCacheFind->second;
|
||||||
}
|
}
|
||||||
|
|
||||||
return Promise;
|
return Promise;
|
||||||
|
@ -295,15 +295,15 @@ namespace Ship {
|
||||||
auto PromiseList = CacheDirectoryAsync(SearchMask);
|
auto PromiseList = CacheDirectoryAsync(SearchMask);
|
||||||
auto LoadedList = std::make_shared<std::vector<std::shared_ptr<Resource>>>();
|
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);
|
auto Promise = PromiseList->at(i);
|
||||||
|
|
||||||
std::unique_lock<std::mutex> Lock(Promise->ResourceLoadMutex);
|
std::unique_lock<std::mutex> Lock(Promise->resourceLoadMutex);
|
||||||
while (!Promise->bHasResourceLoaded) {
|
while (!Promise->bHasResourceLoaded) {
|
||||||
Promise->ResourceLoadNotifier.wait(Lock);
|
Promise->resourceLoadNotifier.wait(Lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
LoadedList->push_back(Promise->Resource);
|
LoadedList->push_back(Promise->resource);
|
||||||
}
|
}
|
||||||
|
|
||||||
return LoadedList;
|
return LoadedList;
|
||||||
|
@ -314,18 +314,18 @@ namespace Ship {
|
||||||
auto PromiseList = CacheDirectoryAsync(SearchMask);
|
auto PromiseList = CacheDirectoryAsync(SearchMask);
|
||||||
auto LoadedList = std::make_shared<std::vector<std::shared_ptr<Resource>>>();
|
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);
|
auto Promise = PromiseList->at(i);
|
||||||
|
|
||||||
std::unique_lock<std::mutex> Lock(Promise->ResourceLoadMutex);
|
std::unique_lock<std::mutex> Lock(Promise->resourceLoadMutex);
|
||||||
while (!Promise->bHasResourceLoaded) {
|
while (!Promise->bHasResourceLoaded) {
|
||||||
Promise->ResourceLoadNotifier.wait(Lock);
|
Promise->resourceLoadNotifier.wait(Lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Promise->Resource != nullptr)
|
if (Promise->resource != nullptr)
|
||||||
Promise->Resource->isDirty = true;
|
Promise->resource->isDirty = true;
|
||||||
|
|
||||||
LoadedList->push_back(Promise->Resource);
|
LoadedList->push_back(Promise->resource);
|
||||||
}
|
}
|
||||||
|
|
||||||
return LoadedList;
|
return LoadedList;
|
||||||
|
|
|
@ -48,6 +48,7 @@ namespace Ship
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::weak_ptr<GlobalCtx2> Context;
|
std::weak_ptr<GlobalCtx2> Context;
|
||||||
|
volatile bool bIsRunning;
|
||||||
std::map<std::string, std::shared_ptr<File>> FileCache;
|
std::map<std::string, std::shared_ptr<File>> FileCache;
|
||||||
std::map<std::string, std::shared_ptr<Resource>> ResourceCache;
|
std::map<std::string, std::shared_ptr<Resource>> ResourceCache;
|
||||||
std::queue<std::shared_ptr<File>> FileLoadQueue;
|
std::queue<std::shared_ptr<File>> FileLoadQueue;
|
||||||
|
@ -59,7 +60,6 @@ namespace Ship
|
||||||
std::mutex ResourceLoadMutex;
|
std::mutex ResourceLoadMutex;
|
||||||
std::condition_variable FileLoadNotifier;
|
std::condition_variable FileLoadNotifier;
|
||||||
std::condition_variable ResourceLoadNotifier;
|
std::condition_variable ResourceLoadNotifier;
|
||||||
volatile bool bIsRunning;
|
|
||||||
uint32_t gameVersion;
|
uint32_t gameVersion;
|
||||||
};
|
};
|
||||||
}
|
}
|
|
@ -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) {
|
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);
|
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.
|
// We failed to load the controller. Go to next.
|
||||||
if (NewCont == nullptr) {
|
if (NewCont == nullptr) {
|
||||||
SPDLOG_ERROR("SDL Controller failed to open: ({})", SDL_GetError());
|
SPDLOG_ERROR("SDL Controller failed to open: ({})", SDL_GetError());
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (SDL_GameControllerHasSensor(NewCont, SDL_SENSOR_GYRO))
|
||||||
|
{
|
||||||
|
SDL_GameControllerSetSensorEnabled(NewCont, SDL_SENSOR_GYRO, SDL_TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
guid = NewGuid;
|
guid = NewGuid;
|
||||||
Cont = NewCont;
|
Cont = NewCont;
|
||||||
|
|
||||||
|
@ -101,7 +101,7 @@ namespace Ship {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SDLController::Close() {
|
bool SDLController::Close() {
|
||||||
if (SDL_GameControllerHasRumble(Cont)) {
|
if (CanRumble()) {
|
||||||
SDL_GameControllerRumble(Cont, 0, 0, 0);
|
SDL_GameControllerRumble(Cont, 0, 0, 0);
|
||||||
}
|
}
|
||||||
if (Cont != nullptr) {
|
if (Cont != nullptr) {
|
||||||
|
@ -198,7 +198,7 @@ namespace Ship {
|
||||||
const int isSpecialController = !strcmp("PS5 Controller", contName);
|
const int isSpecialController = !strcmp("PS5 Controller", contName);
|
||||||
float gyro_drift_x = CVar_GetFloat(StringHelper::Sprintf("gCont%i_GyroDriftX", contNumber).c_str(), 0.0f);
|
float gyro_drift_x = CVar_GetFloat(StringHelper::Sprintf("gCont%i_GyroDriftX", contNumber).c_str(), 0.0f);
|
||||||
float gyro_drift_y = CVar_GetFloat(StringHelper::Sprintf("gCont%i_GyroDriftY", contNumber).c_str(), 0.0f);
|
float gyro_drift_y = CVar_GetFloat(StringHelper::Sprintf("gCont%i_GyroDriftY", contNumber).c_str(), 0.0f);
|
||||||
const float gyro_sensitivity = CVar_GetFloat(StringHelper::Sprintf("gCont%i_GyroSensitivity").c_str(), 1.0f);
|
const float gyro_sensitivity = CVar_GetFloat(StringHelper::Sprintf("gCont%i_GyroSensitivity", contNumber).c_str(), 1.0f);
|
||||||
|
|
||||||
if (gyro_drift_x == 0) {
|
if (gyro_drift_x == 0) {
|
||||||
gyro_drift_x = gyroData[0];
|
gyro_drift_x = gyroData[0];
|
||||||
|
@ -347,7 +347,7 @@ namespace Ship {
|
||||||
|
|
||||||
void SDLController::WriteToSource(ControllerCallback* controller)
|
void SDLController::WriteToSource(ControllerCallback* controller)
|
||||||
{
|
{
|
||||||
if (SDL_GameControllerHasRumble(Cont)) {
|
if (CanRumble()) {
|
||||||
if (controller->rumble > 0) {
|
if (controller->rumble > 0) {
|
||||||
float rumble_strength = CVar_GetFloat(StringHelper::Sprintf("gCont%i_RumbleStrength", GetControllerNumber()).c_str(), 1.0f);
|
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);
|
SDL_GameControllerRumble(Cont, 0xFFFF * rumble_strength, 0xFFFF * rumble_strength, 0);
|
||||||
|
|
|
@ -13,7 +13,12 @@ namespace Ship {
|
||||||
void ReadFromSource();
|
void ReadFromSource();
|
||||||
void WriteToSource(ControllerCallback* controller);
|
void WriteToSource(ControllerCallback* controller);
|
||||||
bool Connected() const { return Cont != nullptr; }
|
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; };
|
std::string GetGuid() { return guid; };
|
||||||
|
|
||||||
|
@ -30,8 +35,8 @@ namespace Ship {
|
||||||
static bool IsGuidInUse(const std::string& guid);
|
static bool IsGuidInUse(const std::string& guid);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::string guid;
|
|
||||||
SDL_GameController* Cont;
|
SDL_GameController* Cont;
|
||||||
|
std::string guid;
|
||||||
std::map<int32_t, int16_t> ThresholdMapping;
|
std::map<int32_t, int16_t> ThresholdMapping;
|
||||||
|
|
||||||
void LoadAxisThresholds();
|
void LoadAxisThresholds();
|
||||||
|
|
|
@ -137,8 +137,8 @@ namespace Ship
|
||||||
y = 0;
|
y = 0;
|
||||||
z = 0;
|
z = 0;
|
||||||
unk_06 = 0;
|
unk_06 = 0;
|
||||||
opa;
|
// opa;
|
||||||
xlu;
|
// xlu;
|
||||||
}
|
}
|
||||||
|
|
||||||
SetMesh::SetMesh(BinaryReader* reader) : SceneCommand(reader)
|
SetMesh::SetMesh(BinaryReader* reader) : SceneCommand(reader)
|
||||||
|
|
|
@ -15,7 +15,7 @@ namespace Ship
|
||||||
limb->skinVtxCnt = reader->ReadUInt16();
|
limb->skinVtxCnt = reader->ReadUInt16();
|
||||||
uint32_t skinCnt = reader->ReadUInt32();
|
uint32_t skinCnt = reader->ReadUInt32();
|
||||||
|
|
||||||
for (int i = 0; i < skinCnt; i++)
|
for (size_t i = 0; i < skinCnt; i++)
|
||||||
{
|
{
|
||||||
Struct_800A598C struc;
|
Struct_800A598C struc;
|
||||||
|
|
||||||
|
|
|
@ -16,7 +16,7 @@ std::map<ImGuiKey, std::string> BindingToggle;
|
||||||
static bool HelpCommand(const std::vector<std::string>&) {
|
static bool HelpCommand(const std::vector<std::string>&) {
|
||||||
INFO("SoH Commands:");
|
INFO("SoH Commands:");
|
||||||
for(const auto& cmd : SohImGui::console->Commands) {
|
for(const auto& cmd : SohImGui::console->Commands) {
|
||||||
INFO((" - " + cmd.first).c_str());
|
INFO("%s", (" - " + cmd.first).c_str());
|
||||||
}
|
}
|
||||||
return CMD_SUCCESS;
|
return CMD_SUCCESS;
|
||||||
}
|
}
|
||||||
|
@ -35,7 +35,7 @@ std::string toLowerCase(std::string in) {
|
||||||
static bool BindCommand(const std::vector<std::string>& args) {
|
static bool BindCommand(const std::vector<std::string>& args) {
|
||||||
if(args.size() > 2) {
|
if(args.size() > 2) {
|
||||||
const ImGuiIO* io = &ImGui::GetIO();;
|
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));
|
std::string key(ImGui::GetKeyName(k));
|
||||||
|
|
||||||
if(toLowerCase(args[1]) == toLowerCase(key)) {
|
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) {
|
static bool BindToggleCommand(const std::vector<std::string>& args) {
|
||||||
if (args.size() > 2) {
|
if (args.size() > 2) {
|
||||||
const ImGuiIO* io = &ImGui::GetIO();;
|
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));
|
std::string key(ImGui::GetKeyName(k));
|
||||||
|
|
||||||
if (toLowerCase(args[1]) == toLowerCase(key)) {
|
if (toLowerCase(args[1]) == toLowerCase(key)) {
|
||||||
|
@ -92,7 +92,7 @@ void Console::Update() {
|
||||||
}
|
}
|
||||||
for (auto [key, var] : BindingToggle) {
|
for (auto [key, var] : BindingToggle) {
|
||||||
if (ImGui::IsKeyPressed(key)) {
|
if (ImGui::IsKeyPressed(key)) {
|
||||||
CVar* cvar = CVar_GetVar(var.c_str());
|
CVar* cvar = CVar_Get(var.c_str());
|
||||||
Dispatch("set " + var + " " + std::to_string(cvar == nullptr ? 0 : !static_cast<bool>(cvar->value.valueS32)));
|
Dispatch("set " + var + " " + std::to_string(cvar == nullptr ? 0 : !static_cast<bool>(cvar->value.valueS32)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -106,7 +106,7 @@ void Console::Draw() {
|
||||||
if (!this->opened) return;
|
if (!this->opened) return;
|
||||||
|
|
||||||
ImGui::SetNextWindowSize(ImVec2(520, 600), ImGuiCond_FirstUseEver);
|
ImGui::SetNextWindowSize(ImVec2(520, 600), ImGuiCond_FirstUseEver);
|
||||||
ImGui::Begin("Console", &this->opened);
|
ImGui::Begin("Console", nullptr);
|
||||||
const ImVec2 pos = ImGui::GetWindowPos();
|
const ImVec2 pos = ImGui::GetWindowPos();
|
||||||
const ImVec2 size = ImGui::GetWindowSize();
|
const ImVec2 size = ImGui::GetWindowSize();
|
||||||
|
|
||||||
|
@ -177,9 +177,11 @@ void Console::Draw() {
|
||||||
for (const auto& filter : priority_filters) {
|
for (const auto& filter : priority_filters) {
|
||||||
const bool is_selected = (filter == std::string(this->level_filter));
|
const bool is_selected = (filter == std::string(this->level_filter));
|
||||||
if (ImGui::Selectable(filter.c_str(), is_selected))
|
if (ImGui::Selectable(filter.c_str(), is_selected))
|
||||||
|
{
|
||||||
this->level_filter = filter;
|
this->level_filter = filter;
|
||||||
if (is_selected) ImGui::SetItemDefaultFocus();
|
if (is_selected) ImGui::SetItemDefaultFocus();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
ImGui::EndCombo();
|
ImGui::EndCombo();
|
||||||
}
|
}
|
||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
|
@ -194,7 +196,7 @@ void Console::Draw() {
|
||||||
if (ImGui::BeginTable("History", 1)) {
|
if (ImGui::BeginTable("History", 1)) {
|
||||||
|
|
||||||
if (ImGui::IsKeyPressed(ImGui::GetKeyIndex(ImGuiKey_DownArrow)))
|
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 (ImGui::IsKeyPressed(ImGui::GetKeyIndex(ImGuiKey_UpArrow)))
|
||||||
if (this->selectedId > 0) --this->selectedId;
|
if (this->selectedId > 0) --this->selectedId;
|
||||||
|
|
||||||
|
@ -317,7 +319,7 @@ int Console::CallbackStub(ImGuiInputTextCallbackData* data) {
|
||||||
return 0;
|
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];
|
char buf[1024];
|
||||||
va_list args;
|
va_list args;
|
||||||
va_start(args, fmt);
|
va_start(args, fmt);
|
||||||
|
|
|
@ -7,10 +7,10 @@
|
||||||
|
|
||||||
#include "Lib/ImGui/imgui.h"
|
#include "Lib/ImGui/imgui.h"
|
||||||
|
|
||||||
#define LOG(msg, ...) SohImGui::console->Append("Main", Priority::LOG_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 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 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 ERROR(msg, ...) SohImGui::console->Append("Main", Priority::ERROR_LVL, msg, ##__VA_ARGS__)
|
||||||
#define CMD_SUCCESS true
|
#define CMD_SUCCESS true
|
||||||
#define CMD_FAILED false
|
#define CMD_FAILED false
|
||||||
#define MAX_BUFFER_SIZE 255
|
#define MAX_BUFFER_SIZE 255
|
||||||
|
@ -75,7 +75,7 @@ public:
|
||||||
void Init();
|
void Init();
|
||||||
void Update();
|
void Update();
|
||||||
void Draw();
|
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);
|
void Dispatch(const std::string& line);
|
||||||
static int CallbackStub(ImGuiInputTextCallbackData* data);
|
static int CallbackStub(ImGuiInputTextCallbackData* data);
|
||||||
};
|
};
|
|
@ -24,7 +24,7 @@ namespace ModInternal {
|
||||||
|
|
||||||
bool handleHook(std::shared_ptr<HookCall> call) {
|
bool handleHook(std::shared_ptr<HookCall> call) {
|
||||||
std::string hookName = std::string(call->name);
|
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);
|
(listeners[hookName][l])(call);
|
||||||
}
|
}
|
||||||
return call->cancelled;
|
return call->cancelled;
|
||||||
|
|
|
@ -47,6 +47,7 @@ struct HookParameter {
|
||||||
#include <functional>
|
#include <functional>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <map>
|
#include <map>
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
struct HookCall {
|
struct HookCall {
|
||||||
std::string name;
|
std::string name;
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
#include "TextureMod.h"
|
#include "TextureMod.h"
|
||||||
#include "Window.h"
|
#include "Window.h"
|
||||||
#include "Cvar.h"
|
#include "Cvar.h"
|
||||||
|
#include "GameOverlay.h"
|
||||||
#include "Texture.h"
|
#include "Texture.h"
|
||||||
#include "../Fast3D/gfx_pc.h"
|
#include "../Fast3D/gfx_pc.h"
|
||||||
#include "Lib/stb/stb_image.h"
|
#include "Lib/stb/stb_image.h"
|
||||||
|
@ -43,6 +44,11 @@ IMGUI_IMPL_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hWnd, UINT msg, WPAR
|
||||||
using namespace Ship;
|
using namespace Ship;
|
||||||
bool oldCursorState = true;
|
bool oldCursorState = true;
|
||||||
|
|
||||||
|
#define EXPERIMENTAL() \
|
||||||
|
ImGui::PushStyleColor(ImGuiCol_Text, IM_COL32(255, 50, 50, 255)); \
|
||||||
|
ImGui::Text("Experimental"); \
|
||||||
|
ImGui::PopStyleColor(); \
|
||||||
|
ImGui::Separator();
|
||||||
#define TOGGLE_BTN ImGuiKey_F1
|
#define TOGGLE_BTN ImGuiKey_F1
|
||||||
#define HOOK(b) if(b) needs_save = true;
|
#define HOOK(b) if(b) needs_save = true;
|
||||||
OSContPad* pads;
|
OSContPad* pads;
|
||||||
|
@ -54,8 +60,11 @@ namespace SohImGui {
|
||||||
WindowImpl impl;
|
WindowImpl impl;
|
||||||
ImGuiIO* io;
|
ImGuiIO* io;
|
||||||
Console* console = new Console;
|
Console* console = new Console;
|
||||||
|
GameOverlay* overlay = new GameOverlay;
|
||||||
bool p_open = false;
|
bool p_open = false;
|
||||||
bool needs_save = false;
|
bool needs_save = false;
|
||||||
|
std::vector<const char*> CustomTexts;
|
||||||
|
int SelectedLanguage = CVar_GetS32("gLanguages", 0); //Default Language to 0=English 1=German 2=French
|
||||||
float kokiri_col[3] = { 0.118f, 0.41f, 0.106f };
|
float kokiri_col[3] = { 0.118f, 0.41f, 0.106f };
|
||||||
float goron_col[3] = { 0.392f, 0.078f, 0.0f };
|
float goron_col[3] = { 0.392f, 0.078f, 0.0f };
|
||||||
float zora_col[3] = { 0.0f, 0.235f, 0.392f };
|
float zora_col[3] = { 0.0f, 0.235f, 0.392f };
|
||||||
|
@ -72,6 +81,12 @@ namespace SohImGui {
|
||||||
float navi_prop_i_col[3] = { 0.0f, 0.0f, 0.0f };
|
float navi_prop_i_col[3] = { 0.0f, 0.0f, 0.0f };
|
||||||
float navi_prop_o_col[3] = { 0.0f, 0.0f, 0.0f };
|
float navi_prop_o_col[3] = { 0.0f, 0.0f, 0.0f };
|
||||||
|
|
||||||
|
const char* filters[3] = {
|
||||||
|
"Three-Point",
|
||||||
|
"Linear",
|
||||||
|
"None"
|
||||||
|
};
|
||||||
|
|
||||||
std::map<std::string, std::vector<std::string>> windowCategories;
|
std::map<std::string, std::vector<std::string>> windowCategories;
|
||||||
std::map<std::string, CustomWindow> customWindows;
|
std::map<std::string, CustomWindow> customWindows;
|
||||||
|
|
||||||
|
@ -80,9 +95,13 @@ namespace SohImGui {
|
||||||
case Backend::SDL:
|
case Backend::SDL:
|
||||||
ImGui_ImplSDL2_InitForOpenGL(static_cast<SDL_Window*>(impl.sdl.window), impl.sdl.context);
|
ImGui_ImplSDL2_InitForOpenGL(static_cast<SDL_Window*>(impl.sdl.window), impl.sdl.context);
|
||||||
break;
|
break;
|
||||||
|
#if defined(ENABLE_DX11) || defined(ENABLE_DX12)
|
||||||
case Backend::DX11:
|
case Backend::DX11:
|
||||||
ImGui_ImplWin32_Init(impl.dx11.window);
|
ImGui_ImplWin32_Init(impl.dx11.window);
|
||||||
break;
|
break;
|
||||||
|
#endif
|
||||||
|
default:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// OTRTODO: This gameplay specific stuff should not be in libultraship. This needs to be moved to soh and use sTunicColors
|
// OTRTODO: This gameplay specific stuff should not be in libultraship. This needs to be moved to soh and use sTunicColors
|
||||||
|
@ -136,9 +155,14 @@ namespace SohImGui {
|
||||||
case Backend::SDL:
|
case Backend::SDL:
|
||||||
ImGui_ImplOpenGL3_Init("#version 120");
|
ImGui_ImplOpenGL3_Init("#version 120");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
#if defined(ENABLE_DX11) || defined(ENABLE_DX12)
|
||||||
case Backend::DX11:
|
case Backend::DX11:
|
||||||
ImGui_ImplDX11_Init(static_cast<ID3D11Device*>(impl.dx11.device), static_cast<ID3D11DeviceContext*>(impl.dx11.device_context));
|
ImGui_ImplDX11_Init(static_cast<ID3D11Device*>(impl.dx11.device), static_cast<ID3D11DeviceContext*>(impl.dx11.device_context));
|
||||||
break;
|
break;
|
||||||
|
#endif
|
||||||
|
default:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -147,9 +171,13 @@ namespace SohImGui {
|
||||||
case Backend::SDL:
|
case Backend::SDL:
|
||||||
ImGui_ImplSDL2_ProcessEvent(static_cast<const SDL_Event*>(event.sdl.event));
|
ImGui_ImplSDL2_ProcessEvent(static_cast<const SDL_Event*>(event.sdl.event));
|
||||||
break;
|
break;
|
||||||
|
#if defined(ENABLE_DX11) || defined(ENABLE_DX12)
|
||||||
case Backend::DX11:
|
case Backend::DX11:
|
||||||
ImGui_ImplWin32_WndProcHandler(static_cast<HWND>(event.win32.handle), event.win32.msg, event.win32.wparam, event.win32.lparam);
|
ImGui_ImplWin32_WndProcHandler(static_cast<HWND>(event.win32.handle), event.win32.msg, event.win32.wparam, event.win32.lparam);
|
||||||
break;
|
break;
|
||||||
|
#endif
|
||||||
|
default:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -158,9 +186,13 @@ namespace SohImGui {
|
||||||
case Backend::SDL:
|
case Backend::SDL:
|
||||||
ImGui_ImplSDL2_NewFrame(static_cast<SDL_Window*>(impl.sdl.window));
|
ImGui_ImplSDL2_NewFrame(static_cast<SDL_Window*>(impl.sdl.window));
|
||||||
break;
|
break;
|
||||||
|
#if defined(ENABLE_DX11) || defined(ENABLE_DX12)
|
||||||
case Backend::DX11:
|
case Backend::DX11:
|
||||||
ImGui_ImplWin32_NewFrame();
|
ImGui_ImplWin32_NewFrame();
|
||||||
break;
|
break;
|
||||||
|
#endif
|
||||||
|
default:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -169,9 +201,13 @@ namespace SohImGui {
|
||||||
case Backend::SDL:
|
case Backend::SDL:
|
||||||
ImGui_ImplOpenGL3_NewFrame();
|
ImGui_ImplOpenGL3_NewFrame();
|
||||||
break;
|
break;
|
||||||
|
#if defined(ENABLE_DX11) || defined(ENABLE_DX12)
|
||||||
case Backend::DX11:
|
case Backend::DX11:
|
||||||
ImGui_ImplDX11_NewFrame();
|
ImGui_ImplDX11_NewFrame();
|
||||||
break;
|
break;
|
||||||
|
#endif
|
||||||
|
default:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -180,9 +216,13 @@ namespace SohImGui {
|
||||||
case Backend::SDL:
|
case Backend::SDL:
|
||||||
ImGui_ImplOpenGL3_RenderDrawData(data);
|
ImGui_ImplOpenGL3_RenderDrawData(data);
|
||||||
break;
|
break;
|
||||||
|
#if defined(ENABLE_DX11) || defined(ENABLE_DX12)
|
||||||
case Backend::DX11:
|
case Backend::DX11:
|
||||||
ImGui_ImplDX11_RenderDrawData(data);
|
ImGui_ImplDX11_RenderDrawData(data);
|
||||||
break;
|
break;
|
||||||
|
#endif
|
||||||
|
default:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -190,17 +230,18 @@ namespace SohImGui {
|
||||||
switch (impl.backend) {
|
switch (impl.backend) {
|
||||||
case Backend::DX11:
|
case Backend::DX11:
|
||||||
return true;
|
return true;
|
||||||
}
|
default:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void SohImGui::ShowCursor(bool hide, Dialogues d) {
|
void ShowCursor(bool hide, Dialogues d) {
|
||||||
if (d == Dialogues::dLoadSettings) {
|
if (d == Dialogues::dLoadSettings) {
|
||||||
GlobalCtx2::GetInstance()->GetWindow()->ShowCursor(hide);
|
GlobalCtx2::GetInstance()->GetWindow()->ShowCursor(hide);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (d == Dialogues::dConsole && Game::Settings.debug.menu_bar) {
|
if (d == Dialogues::dConsole && CVar_GetS32("gOpenMenuBar", 0)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!GlobalCtx2::GetInstance()->GetWindow()->IsFullscreen()) {
|
if (!GlobalCtx2::GetInstance()->GetWindow()->IsFullscreen()) {
|
||||||
|
@ -279,23 +320,26 @@ namespace SohImGui {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Init(WindowImpl window_impl) {
|
void Init(WindowImpl window_impl) {
|
||||||
impl = window_impl;
|
|
||||||
Game::LoadSettings();
|
Game::LoadSettings();
|
||||||
|
impl = window_impl;
|
||||||
ImGuiContext* ctx = ImGui::CreateContext();
|
ImGuiContext* ctx = ImGui::CreateContext();
|
||||||
ImGui::SetCurrentContext(ctx);
|
ImGui::SetCurrentContext(ctx);
|
||||||
io = &ImGui::GetIO();
|
io = &ImGui::GetIO();
|
||||||
io->ConfigFlags |= ImGuiConfigFlags_DockingEnable;
|
io->ConfigFlags |= ImGuiConfigFlags_DockingEnable;
|
||||||
|
io->Fonts->AddFontDefault();
|
||||||
|
|
||||||
if (UseViewports()) {
|
if (UseViewports()) {
|
||||||
io->ConfigFlags |= ImGuiConfigFlags_ViewportsEnable;
|
io->ConfigFlags |= ImGuiConfigFlags_ViewportsEnable;
|
||||||
}
|
}
|
||||||
console->Init();
|
console->Init();
|
||||||
|
overlay->Init();
|
||||||
ImGuiWMInit();
|
ImGuiWMInit();
|
||||||
ImGuiBackendInit();
|
ImGuiBackendInit();
|
||||||
|
|
||||||
ModInternal::registerHookListener({ GFX_INIT, [](const HookEvent ev) {
|
ModInternal::registerHookListener({ GFX_INIT, [](const HookEvent ev) {
|
||||||
|
|
||||||
if (GlobalCtx2::GetInstance()->GetWindow()->IsFullscreen())
|
if (GlobalCtx2::GetInstance()->GetWindow()->IsFullscreen())
|
||||||
ShowCursor(Game::Settings.debug.menu_bar, Dialogues::dLoadSettings);
|
ShowCursor(CVar_GetS32("gOpenMenuBar", 0), Dialogues::dLoadSettings);
|
||||||
|
|
||||||
LoadTexture("Game_Icon", "assets/ship_of_harkinian/icons/gSohIcon.png");
|
LoadTexture("Game_Icon", "assets/ship_of_harkinian/icons/gSohIcon.png");
|
||||||
LoadTexture("A-Btn", "assets/ship_of_harkinian/buttons/ABtn.png");
|
LoadTexture("A-Btn", "assets/ship_of_harkinian/buttons/ABtn.png");
|
||||||
|
@ -310,6 +354,13 @@ namespace SohImGui {
|
||||||
LoadTexture("C-Down", "assets/ship_of_harkinian/buttons/CDown.png");
|
LoadTexture("C-Down", "assets/ship_of_harkinian/buttons/CDown.png");
|
||||||
} });
|
} });
|
||||||
|
|
||||||
|
for (const auto& [i, controllers] : Ship::Window::Controllers)
|
||||||
|
{
|
||||||
|
CVar_SetFloat(StringHelper::Sprintf("gCont%i_GyroDriftX", i).c_str(), 0);
|
||||||
|
CVar_SetFloat(StringHelper::Sprintf("gCont%i_GyroDriftY", i).c_str(), 0);
|
||||||
|
needs_save = true;
|
||||||
|
}
|
||||||
|
|
||||||
ModInternal::registerHookListener({ CONTROLLER_READ, [](const HookEvent ev) {
|
ModInternal::registerHookListener({ CONTROLLER_READ, [](const HookEvent ev) {
|
||||||
pads = static_cast<OSContPad*>(ev->baseArgs["cont_pad"]);
|
pads = static_cast<OSContPad*>(ev->baseArgs["cont_pad"]);
|
||||||
}});
|
}});
|
||||||
|
@ -339,6 +390,24 @@ namespace SohImGui {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void EnhancementRadioButton(std::string text, std::string cvarName, int id) {
|
||||||
|
/*Usage :
|
||||||
|
EnhancementRadioButton("My Visible Name","gMyCVarName", MyID);
|
||||||
|
First arg is the visible name of the Radio button
|
||||||
|
Second is the cvar name where MyID will be saved.
|
||||||
|
Note: the CVar name should be the same to each Buddies.
|
||||||
|
Example :
|
||||||
|
EnhancementRadioButton("English", "gLanguages", 0);
|
||||||
|
EnhancementRadioButton("German", "gLanguages", 1);
|
||||||
|
EnhancementRadioButton("French", "gLanguages", 2);
|
||||||
|
*/
|
||||||
|
int val = CVar_GetS32(cvarName.c_str(), 0);
|
||||||
|
if (ImGui::RadioButton(text.c_str(), id==val)) {
|
||||||
|
CVar_SetS32(cvarName.c_str(), (int)id);
|
||||||
|
needs_save = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void EnhancementCheckbox(std::string text, std::string cvarName)
|
void EnhancementCheckbox(std::string text, std::string cvarName)
|
||||||
{
|
{
|
||||||
bool val = (bool)CVar_GetS32(cvarName.c_str(), 0);
|
bool val = (bool)CVar_GetS32(cvarName.c_str(), 0);
|
||||||
|
@ -437,7 +506,7 @@ namespace SohImGui {
|
||||||
ImGuiWindowFlags window_flags = ImGuiWindowFlags_NoDocking | ImGuiWindowFlags_NoBackground |
|
ImGuiWindowFlags window_flags = ImGuiWindowFlags_NoDocking | ImGuiWindowFlags_NoBackground |
|
||||||
ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoMove |
|
ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoMove |
|
||||||
ImGuiWindowFlags_NoBringToFrontOnFocus | ImGuiWindowFlags_NoNavFocus | ImGuiWindowFlags_NoResize;
|
ImGuiWindowFlags_NoBringToFrontOnFocus | ImGuiWindowFlags_NoNavFocus | ImGuiWindowFlags_NoResize;
|
||||||
if (Game::Settings.debug.menu_bar) window_flags |= ImGuiWindowFlags_MenuBar;
|
if (CVar_GetS32("gOpenMenuBar", 0)) window_flags |= ImGuiWindowFlags_MenuBar;
|
||||||
|
|
||||||
const ImGuiViewport* viewport = ImGui::GetMainViewport();
|
const ImGuiViewport* viewport = ImGui::GetMainViewport();
|
||||||
ImGui::SetNextWindowPos(viewport->WorkPos);
|
ImGui::SetNextWindowPos(viewport->WorkPos);
|
||||||
|
@ -465,10 +534,11 @@ namespace SohImGui {
|
||||||
ImGui::DockSpace(dockId, ImVec2(0.0f, 0.0f), ImGuiDockNodeFlags_None);
|
ImGui::DockSpace(dockId, ImVec2(0.0f, 0.0f), ImGuiDockNodeFlags_None);
|
||||||
|
|
||||||
if (ImGui::IsKeyPressed(TOGGLE_BTN)) {
|
if (ImGui::IsKeyPressed(TOGGLE_BTN)) {
|
||||||
Game::Settings.debug.menu_bar = !Game::Settings.debug.menu_bar;
|
bool menu_bar = CVar_GetS32("gOpenMenuBar", 0);
|
||||||
|
CVar_SetS32("gOpenMenuBar", !menu_bar);
|
||||||
needs_save = true;
|
needs_save = true;
|
||||||
GlobalCtx2::GetInstance()->GetWindow()->dwMenubar = Game::Settings.debug.menu_bar;
|
GlobalCtx2::GetInstance()->GetWindow()->dwMenubar = menu_bar;
|
||||||
ShowCursor(Game::Settings.debug.menu_bar, Dialogues::dMenubar);
|
ShowCursor(menu_bar, Dialogues::dMenubar);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ImGui::BeginMenuBar()) {
|
if (ImGui::BeginMenuBar()) {
|
||||||
|
@ -509,8 +579,8 @@ namespace SohImGui {
|
||||||
|
|
||||||
if (ImGui::Button("Recalibrate Gyro"))
|
if (ImGui::Button("Recalibrate Gyro"))
|
||||||
{
|
{
|
||||||
CVar_SetFloat(StringHelper::Sprintf("gCont%i_GyroDriftX").c_str(), 0);
|
CVar_SetFloat(StringHelper::Sprintf("gCont%i_GyroDriftX", i).c_str(), 0);
|
||||||
CVar_SetFloat(StringHelper::Sprintf("gCont%i_GyroDriftY").c_str(), 0);
|
CVar_SetFloat(StringHelper::Sprintf("gCont%i_GyroDriftY", i).c_str(), 0);
|
||||||
needs_save = true;
|
needs_save = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -537,13 +607,47 @@ namespace SohImGui {
|
||||||
ImGui::EndMenu();
|
ImGui::EndMenu();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ImGui::BeginMenu("Graphics"))
|
||||||
|
{
|
||||||
|
EnhancementSliderInt("Internal Resolution: %dx", "##IMul", "gInternalResolution", 1, 8, "");
|
||||||
|
gfx_current_dimensions.internal_mul = CVar_GetS32("gInternalResolution", 1);
|
||||||
|
EnhancementSliderInt("MSAA: %d", "##IMSAA", "gMSAAValue", 1, 8, "");
|
||||||
|
gfx_msaa_level = CVar_GetS32("gMSAAValue", 1);
|
||||||
|
|
||||||
|
EXPERIMENTAL();
|
||||||
|
ImGui::Text("Texture Filter (Needs reload)");
|
||||||
|
GfxRenderingAPI* gapi = gfx_get_current_rendering_api();
|
||||||
|
if (ImGui::BeginCombo("##filters", filters[gapi->get_texture_filter()])) {
|
||||||
|
for (int fId = 0; fId <= FilteringMode::NONE; fId++) {
|
||||||
|
if (ImGui::Selectable(filters[fId], fId == gapi->get_texture_filter())) {
|
||||||
|
INFO("New Filter: %s", filters[fId]);
|
||||||
|
gapi->set_texture_filter((FilteringMode)fId);
|
||||||
|
|
||||||
|
CVar_SetS32("gTextureFilter", (int) fId);
|
||||||
|
needs_save = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
ImGui::EndCombo();
|
||||||
|
}
|
||||||
|
overlay->DrawSettings();
|
||||||
|
ImGui::EndMenu();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ImGui::BeginMenu("Languages")) {
|
||||||
|
EnhancementRadioButton("English", "gLanguages", 0);
|
||||||
|
EnhancementRadioButton("German", "gLanguages", 1);
|
||||||
|
EnhancementRadioButton("French", "gLanguages", 2);
|
||||||
|
ImGui::EndMenu();
|
||||||
|
}
|
||||||
|
|
||||||
if (ImGui::BeginMenu("Enhancements"))
|
if (ImGui::BeginMenu("Enhancements"))
|
||||||
{
|
{
|
||||||
|
|
||||||
ImGui::Text("Gameplay");
|
ImGui::Text("Gameplay");
|
||||||
ImGui::Separator();
|
ImGui::Separator();
|
||||||
|
|
||||||
EnhancementSliderInt("Text Speed: %dx", "##TEXTSPEED", "gTextSpeed", 1, 5, "");
|
EnhancementSliderInt("Text Speed: %dx", "##TEXTSPEED", "gTextSpeed", 1, 5, "");
|
||||||
|
EnhancementSliderInt("King Zora Speed: %dx", "##WEEPSPEED", "gMweepSpeed", 1, 5, "");
|
||||||
|
|
||||||
EnhancementCheckbox("Skip Text", "gSkipText");
|
EnhancementCheckbox("Skip Text", "gSkipText");
|
||||||
EnhancementCheckbox("Minimal UI", "gMinimalUI");
|
EnhancementCheckbox("Minimal UI", "gMinimalUI");
|
||||||
|
@ -556,51 +660,18 @@ namespace SohImGui {
|
||||||
EnhancementCheckbox("N64 Mode", "gN64Mode");
|
EnhancementCheckbox("N64 Mode", "gN64Mode");
|
||||||
|
|
||||||
EnhancementCheckbox("Animated Link in Pause Menu", "gPauseLiveLink");
|
EnhancementCheckbox("Animated Link in Pause Menu", "gPauseLiveLink");
|
||||||
EnhancementCheckbox("Disable LOD", "gDisableLOD");
|
|
||||||
EnhancementCheckbox("Enable 3D Dropped items", "gNewDrops");
|
EnhancementCheckbox("Enable 3D Dropped items", "gNewDrops");
|
||||||
EnhancementCheckbox("Dynamic Wallet Icon", "gDynamicWalletIcon");
|
EnhancementCheckbox("Dynamic Wallet Icon", "gDynamicWalletIcon");
|
||||||
|
EnhancementCheckbox("Always show dungeon entrances", "gAlwaysShowDungeonMinimapIcon");
|
||||||
|
|
||||||
ImGui::EndMenu();
|
ImGui::Text("Fixes");
|
||||||
}
|
|
||||||
|
|
||||||
if (ImGui::BeginMenu("Developer Tools"))
|
|
||||||
{
|
|
||||||
HOOK(ImGui::MenuItem("Stats", nullptr, &Game::Settings.debug.soh));
|
|
||||||
HOOK(ImGui::MenuItem("Console", nullptr, &console->opened));
|
|
||||||
|
|
||||||
ImGui::Text("Debug");
|
|
||||||
ImGui::Separator();
|
ImGui::Separator();
|
||||||
|
EnhancementCheckbox("Fix L&R Pause menu", "gUniformLR");
|
||||||
|
EnhancementCheckbox("Fix Dungeon entrances", "gFixDungeonMinimapIcon");
|
||||||
|
|
||||||
EnhancementCheckbox("Debug Mode", "gDebugEnabled");
|
EXPERIMENTAL();
|
||||||
|
|
||||||
ImGui::EndMenu();
|
EnhancementCheckbox("Disable LOD", "gDisableLOD");
|
||||||
}
|
|
||||||
|
|
||||||
if (ImGui::BeginMenu("Graphics"))
|
|
||||||
{
|
|
||||||
HOOK(ImGui::MenuItem("Anti-aliasing", nullptr, &Game::Settings.graphics.show));
|
|
||||||
ImGui::EndMenu();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ImGui::BeginMenu("Cheats"))
|
|
||||||
{
|
|
||||||
if (ImGui::BeginMenu("Infinite...")) {
|
|
||||||
EnhancementCheckbox("Money", "gInfiniteMoney");
|
|
||||||
EnhancementCheckbox("Health", "gInfiniteHealth");
|
|
||||||
EnhancementCheckbox("Ammo", "gInfiniteAmmo");
|
|
||||||
EnhancementCheckbox("Magic", "gInfiniteMagic");
|
|
||||||
EnhancementCheckbox("Nayru's Love", "gInfiniteNayru");
|
|
||||||
|
|
||||||
ImGui::EndMenu();
|
|
||||||
}
|
|
||||||
|
|
||||||
EnhancementCheckbox("No Clip", "gNoClip");
|
|
||||||
EnhancementCheckbox("Climb Everything", "gClimbEverything");
|
|
||||||
EnhancementCheckbox("Moon Jump on L", "gMoonJumpOnL");
|
|
||||||
EnhancementCheckbox("Super Tunic", "gSuperTunic");
|
|
||||||
EnhancementCheckbox("Easy ISG", "gEzISG");
|
|
||||||
EnhancementCheckbox("Unrestricted Items", "gNoRestrictItems");
|
|
||||||
EnhancementCheckbox("Freeze Time", "gFreezeTime");
|
|
||||||
|
|
||||||
ImGui::EndMenu();
|
ImGui::EndMenu();
|
||||||
}
|
}
|
||||||
|
@ -629,10 +700,48 @@ namespace SohImGui {
|
||||||
ImGui::EndMenu();
|
ImGui::EndMenu();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ImGui::BeginMenu("Cheats"))
|
||||||
|
{
|
||||||
|
if (ImGui::BeginMenu("Infinite...")) {
|
||||||
|
EnhancementCheckbox("Money", "gInfiniteMoney");
|
||||||
|
EnhancementCheckbox("Health", "gInfiniteHealth");
|
||||||
|
EnhancementCheckbox("Ammo", "gInfiniteAmmo");
|
||||||
|
EnhancementCheckbox("Magic", "gInfiniteMagic");
|
||||||
|
EnhancementCheckbox("Nayru's Love", "gInfiniteNayru");
|
||||||
|
|
||||||
|
ImGui::EndMenu();
|
||||||
|
}
|
||||||
|
|
||||||
|
EnhancementCheckbox("No Clip", "gNoClip");
|
||||||
|
EnhancementCheckbox("Climb Everything", "gClimbEverything");
|
||||||
|
EnhancementCheckbox("Moon Jump on L", "gMoonJumpOnL");
|
||||||
|
EnhancementCheckbox("Super Tunic", "gSuperTunic");
|
||||||
|
EnhancementCheckbox("Easy ISG", "gEzISG");
|
||||||
|
EnhancementCheckbox("Unrestricted Items", "gNoRestrictItems");
|
||||||
|
EnhancementCheckbox("Freeze Time", "gFreezeTime");
|
||||||
|
|
||||||
|
ImGui::EndMenu();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ImGui::BeginMenu("Developer Tools"))
|
||||||
|
{
|
||||||
|
EnhancementCheckbox("Stats", "gStatsEnabled");
|
||||||
|
EnhancementCheckbox("Console", "gConsoleEnabled");
|
||||||
|
console->opened = CVar_GetS32("gConsoleEnabled", 0);
|
||||||
|
EnhancementCheckbox("OoT Debug Mode", "gDebugEnabled");
|
||||||
|
|
||||||
|
ImGui::EndMenu();
|
||||||
|
}
|
||||||
|
|
||||||
for (const auto& category : windowCategories) {
|
for (const auto& category : windowCategories) {
|
||||||
if (ImGui::BeginMenu(category.first.c_str())) {
|
if (ImGui::BeginMenu(category.first.c_str())) {
|
||||||
for (const std::string& name : category.second) {
|
for (const std::string& name : category.second) {
|
||||||
HOOK(ImGui::MenuItem(name.c_str(), nullptr, &customWindows[name].enabled));
|
std::string varName(name);
|
||||||
|
varName.erase(std::ranges::remove_if(varName, isspace).begin(), varName.end());
|
||||||
|
std::string toggleName = "g" + varName + "Enabled";
|
||||||
|
|
||||||
|
EnhancementCheckbox(name, toggleName);
|
||||||
|
customWindows[name].enabled = CVar_GetS32(toggleName.c_str(), 0);
|
||||||
}
|
}
|
||||||
ImGui::EndMenu();
|
ImGui::EndMenu();
|
||||||
}
|
}
|
||||||
|
@ -643,28 +752,21 @@ namespace SohImGui {
|
||||||
|
|
||||||
ImGui::End();
|
ImGui::End();
|
||||||
|
|
||||||
if (Game::Settings.debug.soh) {
|
if (CVar_GetS32("gStatsEnabled", 0)) {
|
||||||
const float framerate = ImGui::GetIO().Framerate;
|
const float framerate = ImGui::GetIO().Framerate;
|
||||||
ImGui::PushStyleColor(ImGuiCol_Border, ImVec4(0, 0, 0, 0));
|
ImGui::PushStyleColor(ImGuiCol_Border, ImVec4(0, 0, 0, 0));
|
||||||
ImGui::Begin("Debug Stats", nullptr, ImGuiWindowFlags_None);
|
ImGui::Begin("Debug Stats", nullptr, ImGuiWindowFlags_None);
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
ImGui::Text("Platform: Windows");
|
ImGui::Text("Platform: Windows");
|
||||||
|
#else
|
||||||
|
ImGui::Text("Platform: Linux");
|
||||||
|
#endif
|
||||||
ImGui::Text("Status: %.3f ms/frame (%.1f FPS)", 1000.0f / framerate, framerate);
|
ImGui::Text("Status: %.3f ms/frame (%.1f FPS)", 1000.0f / framerate, framerate);
|
||||||
ImGui::End();
|
ImGui::End();
|
||||||
ImGui::PopStyleColor();
|
ImGui::PopStyleColor();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Game::Settings.graphics.show) {
|
|
||||||
ImGui::PushStyleColor(ImGuiCol_Border, ImVec4(0, 0, 0, 0));
|
|
||||||
ImGui::Begin("Anti-aliasing settings", nullptr, ImGuiWindowFlags_None);
|
|
||||||
ImGui::Text("Internal Resolution:");
|
|
||||||
ImGui::SliderInt("Mul", reinterpret_cast<int*>(&gfx_current_dimensions.internal_mul), 1, 8);
|
|
||||||
ImGui::Text("MSAA:");
|
|
||||||
ImGui::SliderInt("MSAA", reinterpret_cast<int*>(&gfx_msaa_level), 1, 8);
|
|
||||||
ImGui::End();
|
|
||||||
ImGui::PopStyleColor();
|
|
||||||
}
|
|
||||||
|
|
||||||
console->Draw();
|
console->Draw();
|
||||||
|
|
||||||
for (auto& windowIter : customWindows) {
|
for (auto& windowIter : customWindows) {
|
||||||
|
@ -705,6 +807,8 @@ namespace SohImGui {
|
||||||
pos = ImVec2(size.x / 2 - sw / 2, 0);
|
pos = ImVec2(size.x / 2 - sw / 2, 0);
|
||||||
size = ImVec2(sw, size.y);
|
size = ImVec2(sw, size.y);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
overlay->Draw();
|
||||||
}
|
}
|
||||||
|
|
||||||
void DrawFramebufferAndGameInput() {
|
void DrawFramebufferAndGameInput() {
|
||||||
|
@ -814,4 +918,16 @@ namespace SohImGui {
|
||||||
ImTextureID GetTextureByName(const std::string& name) {
|
ImTextureID GetTextureByName(const std::string& name) {
|
||||||
return GetTextureByID(DefaultAssets[name]->textureId);
|
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
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "GameOverlay.h"
|
||||||
#include "Lib/ImGui/imgui.h"
|
#include "Lib/ImGui/imgui.h"
|
||||||
#include "SohConsole.h"
|
#include "SohConsole.h"
|
||||||
|
|
||||||
|
@ -58,13 +59,16 @@ namespace SohImGui {
|
||||||
} CustomWindow;
|
} CustomWindow;
|
||||||
|
|
||||||
extern Console* console;
|
extern Console* console;
|
||||||
|
extern Ship::GameOverlay* overlay;
|
||||||
|
extern bool needs_save;
|
||||||
void Init(WindowImpl window_impl);
|
void Init(WindowImpl window_impl);
|
||||||
void Update(EventImpl event);
|
void Update(EventImpl event);
|
||||||
|
|
||||||
|
void EnhancementRadioButton(std::string text, std::string cvarName, int value);
|
||||||
void EnhancementCheckbox(std::string text, std::string cvarName);
|
void EnhancementCheckbox(std::string text, std::string cvarName);
|
||||||
void EnhancementSliderInt(std::string text, std::string id, std::string cvarName, int min, int max, std::string format);
|
void EnhancementSliderInt(std::string text, std::string id, std::string cvarName, int min, int max, std::string format);
|
||||||
void EnhancementSliderFloat(std::string text, std::string id, std::string cvarName, float min, float max, std::string format, float defaultValue);
|
void EnhancementSliderFloat(std::string text, std::string id, std::string cvarName, float min, float max, std::string format, float defaultValue);
|
||||||
|
|
||||||
void DrawMainMenuAndCalculateGameSize(void);
|
void DrawMainMenuAndCalculateGameSize(void);
|
||||||
|
|
||||||
void DrawFramebufferAndGameInput(void);
|
void DrawFramebufferAndGameInput(void);
|
||||||
|
|
|
@ -1,9 +1,14 @@
|
||||||
#include "Utils.h"
|
#include "Utils.h"
|
||||||
|
#include <cstring>
|
||||||
|
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
#define strdup _strdup
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace Utils {
|
namespace Utils {
|
||||||
std::vector<std::string> SplitText(const std::string text, char separator = ' ', bool keep_quotes = false) {
|
std::vector<std::string> SplitText(const std::string text, char separator = ' ', bool keep_quotes = false) {
|
||||||
std::vector<std::string> args;
|
std::vector<std::string> args;
|
||||||
char* input = _strdup(text.c_str());
|
char* input = strdup(text.c_str());
|
||||||
const size_t length = strlen(input);
|
const size_t length = strlen(input);
|
||||||
|
|
||||||
bool inQuotes = false;
|
bool inQuotes = false;
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
#ifdef _WIN32
|
||||||
#include "WasapiAudioPlayer.h"
|
#include "WasapiAudioPlayer.h"
|
||||||
#include "spdlog/spdlog.h"
|
#include "spdlog/spdlog.h"
|
||||||
|
|
||||||
|
@ -170,3 +171,4 @@ namespace Ship {
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
|
@ -1,4 +1,7 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
|
||||||
#include "AudioPlayer.h"
|
#include "AudioPlayer.h"
|
||||||
#include <wrl/client.h>
|
#include <wrl/client.h>
|
||||||
#include <mmdeviceapi.h>
|
#include <mmdeviceapi.h>
|
||||||
|
@ -39,3 +42,4 @@ namespace Ship {
|
||||||
bool started;
|
bool started;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
|
@ -12,6 +12,8 @@
|
||||||
#include "Matrix.h"
|
#include "Matrix.h"
|
||||||
#include "AudioPlayer.h"
|
#include "AudioPlayer.h"
|
||||||
#include "WasapiAudioPlayer.h"
|
#include "WasapiAudioPlayer.h"
|
||||||
|
#include "PulseAudioPlayer.h"
|
||||||
|
#include "SDLAudioPlayer.h"
|
||||||
#include "Lib/Fast3D/gfx_pc.h"
|
#include "Lib/Fast3D/gfx_pc.h"
|
||||||
#include "Lib/Fast3D/gfx_sdl.h"
|
#include "Lib/Fast3D/gfx_sdl.h"
|
||||||
#include "Lib/Fast3D/gfx_opengl.h"
|
#include "Lib/Fast3D/gfx_opengl.h"
|
||||||
|
@ -48,7 +50,7 @@ extern "C" {
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: This for loop is debug. Burn it with fire.
|
// 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)) {
|
if (SDL_IsGameController(i)) {
|
||||||
// Get the GUID from SDL
|
// Get the GUID from SDL
|
||||||
char buf[33];
|
char buf[33];
|
||||||
|
@ -207,7 +209,7 @@ extern "C" {
|
||||||
return (char*)res->imageData;
|
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());
|
const auto res = static_cast<Ship::Texture*>(Ship::GlobalCtx2::GetInstance()->GetResourceManager()->LoadResource(texPath).get());
|
||||||
|
|
||||||
if (res != nullptr)
|
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);
|
void SetWindowManager(GfxWindowManagerAPI** WmApi, GfxRenderingAPI** RenderingApi, const std::string& gfx_backend);
|
||||||
|
|
||||||
namespace Ship {
|
namespace Ship {
|
||||||
|
@ -397,6 +399,12 @@ namespace Ship {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Window::SetAudioPlayer() {
|
void Window::SetAudioPlayer() {
|
||||||
|
#ifdef _WIN32
|
||||||
APlayer = std::make_shared<WasapiAudioPlayer>();
|
APlayer = std::make_shared<WasapiAudioPlayer>();
|
||||||
|
#elif defined(__linux)
|
||||||
|
APlayer = std::make_shared<PulseAudioPlayer>();
|
||||||
|
#else
|
||||||
|
APlayer = std::make_shared<SDLAudioPlayer>();
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,7 +23,9 @@ void SetWindowManager(struct GfxWindowManagerAPI** WmApi, struct GfxRenderingAPI
|
||||||
#ifdef ENABLE_OPENGL
|
#ifdef ENABLE_OPENGL
|
||||||
*RenderingApi = &gfx_opengl_api;
|
*RenderingApi = &gfx_opengl_api;
|
||||||
#if defined(__linux__)
|
#if defined(__linux__)
|
||||||
*WmApi = &gfx_glx;
|
// LINUX_TODO:
|
||||||
|
// *WmApi = &gfx_glx;
|
||||||
|
*WmApi = &gfx_sdl;
|
||||||
#else
|
#else
|
||||||
*WmApi = &gfx_sdl;
|
*WmApi = &gfx_sdl;
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -256,6 +256,7 @@
|
||||||
<ClCompile Include="Blob.cpp" />
|
<ClCompile Include="Blob.cpp" />
|
||||||
<ClCompile Include="Cvar.cpp" />
|
<ClCompile Include="Cvar.cpp" />
|
||||||
<ClCompile Include="Environment.cpp" />
|
<ClCompile Include="Environment.cpp" />
|
||||||
|
<ClCompile Include="GameOverlay.cpp" />
|
||||||
<ClCompile Include="GameSettings.cpp" />
|
<ClCompile Include="GameSettings.cpp" />
|
||||||
<ClCompile Include="Lib\ImGui\backends\imgui_impl_dx11.cpp" />
|
<ClCompile Include="Lib\ImGui\backends\imgui_impl_dx11.cpp" />
|
||||||
<ClCompile Include="Lib\ImGui\backends\imgui_impl_win32.cpp" />
|
<ClCompile Include="Lib\ImGui\backends\imgui_impl_win32.cpp" />
|
||||||
|
@ -343,6 +344,7 @@
|
||||||
<ClInclude Include="Blob.h" />
|
<ClInclude Include="Blob.h" />
|
||||||
<ClInclude Include="Cvar.h" />
|
<ClInclude Include="Cvar.h" />
|
||||||
<ClInclude Include="Environment.h" />
|
<ClInclude Include="Environment.h" />
|
||||||
|
<ClInclude Include="GameOverlay.h" />
|
||||||
<ClInclude Include="GameSettings.h" />
|
<ClInclude Include="GameSettings.h" />
|
||||||
<ClInclude Include="GameVersions.h" />
|
<ClInclude Include="GameVersions.h" />
|
||||||
<ClInclude Include="Lib\ImGui\backends\imgui_impl_dx11.h" />
|
<ClInclude Include="Lib\ImGui\backends\imgui_impl_dx11.h" />
|
||||||
|
|
|
@ -88,6 +88,9 @@
|
||||||
<Filter Include="Source Files\Logging">
|
<Filter Include="Source Files\Logging">
|
||||||
<UniqueIdentifier>{bd6557f1-9480-413b-b0cd-843f8efc1939}</UniqueIdentifier>
|
<UniqueIdentifier>{bd6557f1-9480-413b-b0cd-843f8efc1939}</UniqueIdentifier>
|
||||||
</Filter>
|
</Filter>
|
||||||
|
<Filter Include="Source Files\CustomImpl\Overlay">
|
||||||
|
<UniqueIdentifier>{3285ab8a-06d8-4dac-9af9-efb2a9723ab1}</UniqueIdentifier>
|
||||||
|
</Filter>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClCompile Include="Factories\MaterialFactory.cpp">
|
<ClCompile Include="Factories\MaterialFactory.cpp">
|
||||||
|
@ -339,6 +342,9 @@
|
||||||
<ClCompile Include="GameSettings.cpp">
|
<ClCompile Include="GameSettings.cpp">
|
||||||
<Filter>Source Files\CustomImpl</Filter>
|
<Filter>Source Files\CustomImpl</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="GameOverlay.cpp">
|
||||||
|
<Filter>Source Files\CustomImpl\Overlay</Filter>
|
||||||
|
</ClCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="Lib\tinyxml2\tinyxml2.h">
|
<ClInclude Include="Lib\tinyxml2\tinyxml2.h">
|
||||||
|
@ -629,5 +635,8 @@
|
||||||
<ClInclude Include="GameVersions.h">
|
<ClInclude Include="GameVersions.h">
|
||||||
<Filter>Source Files\Resources</Filter>
|
<Filter>Source Files\Resources</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="GameOverlay.h">
|
||||||
|
<Filter>Source Files\CustomImpl\Overlay</Filter>
|
||||||
|
</ClInclude>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
|
@ -449,7 +449,10 @@ void aFilterImpl(uint8_t flags, uint16_t count_or_buf, int16_t *state_or_filter)
|
||||||
int16_t *buf = BUF_S16(count_or_buf);
|
int16_t *buf = BUF_S16(count_or_buf);
|
||||||
|
|
||||||
if (flags == A_INIT) {
|
if (flags == A_INIT) {
|
||||||
|
#pragma GCC diagnostic push
|
||||||
|
#pragma GCC diagnostic ignored "-Wmemset-elt-size"
|
||||||
memset(tmp, 0, 8 * sizeof(int16_t));
|
memset(tmp, 0, 8 * sizeof(int16_t));
|
||||||
|
#pragma GCC diagnostic pop
|
||||||
memset(tmp2, 0, 8 * sizeof(int16_t));
|
memset(tmp2, 0, 8 * sizeof(int16_t));
|
||||||
} else {
|
} else {
|
||||||
memcpy(tmp, state_or_filter, 8 * sizeof(int16_t));
|
memcpy(tmp, state_or_filter, 8 * sizeof(int16_t));
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
#include <sstream>
|
||||||
#include "stox.h"
|
#include "stox.h"
|
||||||
#include "spdlog/spdlog.h"
|
#include "spdlog/spdlog.h"
|
||||||
|
|
||||||
|
|
5
soh/.gitignore
vendored
5
soh/.gitignore
vendored
|
@ -25,6 +25,10 @@ docs/doxygen/
|
||||||
*.map
|
*.map
|
||||||
*.dump
|
*.dump
|
||||||
out.txt
|
out.txt
|
||||||
|
shipofharkinian.ini
|
||||||
|
imgui.ini
|
||||||
|
oot.otr
|
||||||
|
oot_save.sav
|
||||||
|
|
||||||
# Tool artifacts
|
# Tool artifacts
|
||||||
tools/mipspro7.2_compiler/
|
tools/mipspro7.2_compiler/
|
||||||
|
@ -397,6 +401,7 @@ ZAPDUtils/ZAPDUtils.a
|
||||||
build/
|
build/
|
||||||
ZAPDUtils/build/
|
ZAPDUtils/build/
|
||||||
ZAPD/BuildInfo.h
|
ZAPD/BuildInfo.h
|
||||||
|
cvars.cfg
|
||||||
|
|
||||||
DebugObj/*
|
DebugObj/*
|
||||||
ReleaseObj/*
|
ReleaseObj/*
|
158
soh/Makefile
Normal file
158
soh/Makefile
Normal 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)
|
|
@ -1,7 +1,7 @@
|
||||||
#ifndef ALLOCA_H
|
#ifndef ALLOCA_H
|
||||||
#define ALLOCA_H
|
#define ALLOCA_H
|
||||||
|
|
||||||
void* alloca(u32);
|
// void* alloca(u32);
|
||||||
//#define alloca __builtin_alloca
|
//#define alloca __builtin_alloca
|
||||||
#define alloca malloc
|
#define alloca malloc
|
||||||
|
|
||||||
|
|
|
@ -14,7 +14,7 @@ extern "C"
|
||||||
#if defined(INCLUDE_GAME_PRINTF) && !defined(NDEBUG)
|
#if defined(INCLUDE_GAME_PRINTF) && !defined(NDEBUG)
|
||||||
#define osSyncPrintf(fmt, ...) lusprintf(__FILE__, __LINE__, 0, fmt, __VA_ARGS__)
|
#define osSyncPrintf(fmt, ...) lusprintf(__FILE__, __LINE__, 0, fmt, __VA_ARGS__)
|
||||||
#else
|
#else
|
||||||
#define osSyncPrintf(fmt, ...) osSyncPrintfUnused(fmt, __VA_ARGS__)
|
#define osSyncPrintf(fmt, ...) osSyncPrintfUnused(fmt, ##__VA_ARGS__)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
f32 fabsf(f32 f);
|
f32 fabsf(f32 f);
|
||||||
|
@ -381,7 +381,7 @@ void Flags_UnsetTempClear(GlobalContext* globalCtx, s32 flag);
|
||||||
s32 Flags_GetCollectible(GlobalContext* globalCtx, s32 flag);
|
s32 Flags_GetCollectible(GlobalContext* globalCtx, s32 flag);
|
||||||
void Flags_SetCollectible(GlobalContext* globalCtx, s32 flag);
|
void Flags_SetCollectible(GlobalContext* globalCtx, s32 flag);
|
||||||
void TitleCard_InitBossName(GlobalContext* globalCtx, TitleCardContext* titleCtx, void* texture, s16 x, s16 y, u8 width,
|
void TitleCard_InitBossName(GlobalContext* globalCtx, TitleCardContext* titleCtx, void* texture, s16 x, s16 y, u8 width,
|
||||||
u8 height);
|
u8 height, s16 hastranslation);
|
||||||
void TitleCard_InitPlaceName(GlobalContext* globalCtx, TitleCardContext* titleCtx, void* texture, s32 x, s32 y,
|
void TitleCard_InitPlaceName(GlobalContext* globalCtx, TitleCardContext* titleCtx, void* texture, s32 x, s32 y,
|
||||||
s32 width, s32 height, s32 delay);
|
s32 width, s32 height, s32 delay);
|
||||||
s32 func_8002D53C(GlobalContext* globalCtx, TitleCardContext* titleCtx);
|
s32 func_8002D53C(GlobalContext* globalCtx, TitleCardContext* titleCtx);
|
||||||
|
|
|
@ -4,8 +4,8 @@
|
||||||
#include "functions.h"
|
#include "functions.h"
|
||||||
#include "variables.h"
|
#include "variables.h"
|
||||||
#include "macros.h"
|
#include "macros.h"
|
||||||
#include "soh\OTRGlobals.h"
|
#include "soh/OTRGlobals.h"
|
||||||
#include "soh\Enhancements\gameconsole.h"
|
#include "soh/Enhancements/gameconsole.h"
|
||||||
#include "Cvar.h"
|
#include "Cvar.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -205,6 +205,14 @@ extern GraphicsContext* __gfxCtx;
|
||||||
#define ALIGNED8
|
#define ALIGNED8
|
||||||
#endif
|
#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
|
#endif
|
||||||
|
|
|
@ -1,6 +1,9 @@
|
||||||
#ifndef ULTRA64_H
|
#ifndef ULTRA64_H
|
||||||
#define ULTRA64_H
|
#define ULTRA64_H
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdint.h>
|
||||||
#include "ultra64/types.h"
|
#include "ultra64/types.h"
|
||||||
#include "unk.h"
|
#include "unk.h"
|
||||||
|
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue