Merge changes from develop-zhora

pull/831/head
Christopher Leggett 10 months ago
commit a007bfd14a
No known key found for this signature in database
GPG Key ID: 7093AE5FF7037D79

@ -1,11 +0,0 @@
#!/bin/bash
cp -av /usr/local/lib/libSDL2* /lib/x86_64-linux-gnu/
git config --global --add safe.directory /soh
make setup -C soh -j$(nproc) OPTFLAGS=-O2 DEBUG=0 CC="gcc" CXX="g++"
/opt/devkitpro/portlibs/switch/bin/aarch64-none-elf-cmake -B StormLib/build-switch -S StormLib -DCMAKE_INSTALL_PREFIX=/opt/devkitpro/portlibs/switch/
make -C StormLib/build-switch -j$(nproc)
make install -C StormLib/build-switch
make -f Makefile.switch -j$(nproc) OPTFLAGS=-O2 DEBUG=0

@ -32,13 +32,6 @@ 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) OPTFLAGS=-O2 DEBUG=0

@ -3,45 +3,56 @@ FROM ubuntu:20.04 as build
ENV LANG C.UTF-8
ARG DEBIAN_FRONTEND=noninteractive
ENV GCCVER=10
RUN apt-get update && \
apt-get upgrade -y && \
apt-get install -y \
binutils \
gcc-10 \
g++-10 \
patchelf \
p7zip-full \
python3.9 \
make \
cmake \
curl \
git \
lld \
libsdl2-dev \
zlib1g-dev \
libbz2-dev \
libpng-dev \
libgles2-mesa-dev && \
ln -s /usr/bin/g++-10 /usr/bin/g++ && \
update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-10 10 && \
gcc --version && \
g++ --version
RUN apt-get clean autoclean && apt-get autoremove --yes && rm -rf /var/lib/apt /var/lib/cache /var/lib/log
apt-get upgrade -y && \
apt-get install -y \
binutils \
gcc-${GCCVER} \
g++-${GCCVER} \
p7zip-full \
python3 \
make \
cmake \
curl \
git \
lld \
wget \
libglew-dev \
libsdl2-dev \
zlib1g-dev \
libbz2-dev \
libpng-dev \
libgles2-mesa-dev && \
update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-${GCCVER} 10 && \
update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-${GCCVER} 10
RUN git clone https://github.com/Perlmint/glew-cmake.git && \
cmake glew-cmake && \
make -j$(nproc) && \
make install
cmake glew-cmake && \
make -j$(nproc) && \
make install
ENV SDL2VER=2.0.22
RUN curl -sLO https://libsdl.org/release/SDL2-${SDL2VER}.tar.gz && \
tar -xzf SDL2-${SDL2VER}.tar.gz && \
cd SDL2-${SDL2VER} && \
./configure --prefix=/usr && \
make && make install && \
rm ../SDL2-${SDL2VER}.tar.gz && \
cp -av /lib/libSDL* /lib/x86_64-linux-gnu/
tar -xzf SDL2-${SDL2VER}.tar.gz && \
cd SDL2-${SDL2VER} && \
./configure --build=x86_64-linux-gnu && \
make -j$(nproc) && make install && \
rm ../SDL2-${SDL2VER}.tar.gz
RUN \
ln -sf /proc/self/mounts /etc/mtab && \
mkdir -p /usr/local/share/keyring/ && \
wget -O /usr/local/share/keyring/devkitpro-pub.gpg https://apt.devkitpro.org/devkitpro-pub.gpg && \
echo "deb [signed-by=/usr/local/share/keyring/devkitpro-pub.gpg] https://apt.devkitpro.org stable main" > /etc/apt/sources.list.d/devkitpro.list && \
apt-get update -y && \
apt-get install -y devkitpro-pacman && \
yes | dkp-pacman -Syu switch-dev switch-portlibs --noconfirm
ENV DEVKITPRO=/opt/devkitpro
ENV DEVKITARM=/opt/devkitpro/devkitARM
ENV DEVKITPPC=/opt/devkitpro/devkitPPC
ENV PATH=$PATH:/opt/devkitpro/portlibs/switch/bin/
RUN mkdir /soh
WORKDIR /soh

@ -1,58 +0,0 @@
FROM ubuntu:20.04 as build
ENV LANG C.UTF-8
ARG DEBIAN_FRONTEND=noninteractive
ENV GCCVER=10
RUN \
apt-get update && \
apt-get upgrade -y && \
apt-get install -y \
binutils \
gcc-10 \
g++-10 \
p7zip-full \
python3 \
make \
cmake \
curl \
git \
lld \
wget \
libsdl2-dev \
zlib1g-dev \
libbz2-dev \
libpng-dev \
libgles2-mesa-dev && \
update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-${GCCVER} 10 && \
update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-${GCCVER} 10
RUN git clone https://github.com/Perlmint/glew-cmake.git && \
cmake glew-cmake && \
make -j$(nproc) && \
make install ARCH64=true
ENV SDL2VER=2.0.22
RUN curl -sLO https://libsdl.org/release/SDL2-${SDL2VER}.tar.gz && \
tar -xzf SDL2-${SDL2VER}.tar.gz && \
cd SDL2-${SDL2VER} && \
./configure --build=x86_64-linux-gnu && \
make && make install && \
rm ../SDL2-${SDL2VER}.tar.gz
RUN \
ln -sf /proc/self/mounts /etc/mtab && \
mkdir -p /usr/local/share/keyring/ && \
wget -O /usr/local/share/keyring/devkitpro-pub.gpg https://apt.devkitpro.org/devkitpro-pub.gpg && \
echo "deb [signed-by=/usr/local/share/keyring/devkitpro-pub.gpg] https://apt.devkitpro.org stable main" > /etc/apt/sources.list.d/devkitpro.list && \
apt-get update -y && \
apt-get install -y devkitpro-pacman && \
yes | dkp-pacman -Syu switch-dev switch-portlibs --noconfirm
ENV DEVKITPRO=/opt/devkitpro
ENV DEVKITARM=/opt/devkitpro/devkitARM
ENV DEVKITPPC=/opt/devkitpro/devkitPPC
ENV PATH=$PATH:/opt/devkitpro/portlibs/switch/bin/
RUN mkdir /soh
WORKDIR /soh

19
Jenkinsfile vendored

@ -97,8 +97,7 @@ pipeline {
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
docker exec sohcont scripts/linux/build.sh
mkdir build
mv soh/soh.elf build/
@ -106,9 +105,9 @@ pipeline {
mv OTRGui/build/assets build/
mv ZAPDTR/ZAPD.out build/assets/extractor/
mv README.md readme.txt
docker exec sohcont appimage/appimage.sh
docker exec sohcont scripts/linux/build-appimage.sh
7z a soh-linux.7z SOH-Linux.AppImage readme.txt
'''
@ -143,9 +142,9 @@ pipeline {
sh '''
cp ../../ZELOOTD.z64 OTRExporter/baserom_non_mq.z64
cd soh
make setup -j4 OPTFLAGS=-O2 DEBUG=0 LD="ld"
make -j4 DEBUG=0 OPTFLAGS=-O2 LD="ld"
make -j4 appbundle
make setup -j$(sysctl -n hw.physicalcpu) OPTFLAGS=-O2 DEBUG=0 LD="ld"
make -j$(sysctl -n hw.physicalcpu) DEBUG=0 OPTFLAGS=-O2 LD="ld"
make appbundle
mv ../README.md readme.txt
7z a soh-mac.7z soh.app readme.txt
'''
@ -177,9 +176,9 @@ pipeline {
sh '''
cp ../../ZELOOTD.z64 OTRExporter/baserom_non_mq.z64
docker build . -t sohswitch -f Dockerfile.switch
docker build . -t sohswitch
docker run --name sohcont -dit --rm -v $(pwd):/soh sohswitch /bin/bash
docker exec sohcont .ci/switch/buildswitch.bash
docker exec sohcont scripts/switch/build.sh
mv soh/soh.nro .
mv README.md readme.txt

@ -3,7 +3,7 @@
void OTRExporter::WriteHeader(ZResource* res, const fs::path& outPath, BinaryWriter* writer, Ship::ResourceType resType, Ship::Version resVersion)
{
writer->Write((uint8_t)Endianess::Little); // 0x00
writer->Write((uint8_t)Endianness::Little); // 0x00
writer->Write((uint8_t)0); // 0x01
writer->Write((uint8_t)0); // 0x02
writer->Write((uint8_t)0); // 0x03

@ -83,7 +83,7 @@ Refer to the [building instructions](BUILDING.md) to compile SoH.
- Confirm that `zapd.exe` exists in the `/assets/extractor` folder
## Nightly Builds
Nightly builds of Ship of Harkinian are available [here](https://builds.shipofharkinian.com/job/SoH_Multibranch/job/develop)
Nightly builds of Ship of Harkinian are available [here](https://builds.shipofharkinian.com/)
## The Harbour Masters Are...

@ -48,11 +48,15 @@ endif
LDFLAGS := -Llib/libgfxd -L../libultraship -L../StormLib/build \
-pthread -lgfxd -lultraship ZAPDUtils/ZAPDUtils.a -lstorm -lbz2 -lm -ldl
LDFLAGS += $(shell pkg-config --libs glew libpng zlib) $(shell sdl2-config --libs)
INC += $(shell pkg-config --cflags libpng)
ifeq ($(UNAME), Darwin)
LDFLAGS += $(shell pkg-config --libs glew libpng zlib) $(shell sdl2-config --libs) -framework OpenGL -framework Foundation
INC += $(shell pkg-config --cflags libpng)
else
LDFLAGS += -lpng -lGL -lGLEW -lX11 -lz -lSDL2 -lpulse
LDFLAGS += -framework OpenGL -framework Foundation
endif
ifeq ($(UNAME), Linux)
LDFLAGS += $(shell pkg-config --libs x11 libpulse)
endif
# Use LLD if available. Set LLD=0 to not use it
@ -65,10 +69,12 @@ ifneq ($(LLD),0)
endif
UNAMEM := $(shell uname -m)
ifneq ($(UNAME), Darwin)
ifeq ($(UNAME), Linux)
LDFLAGS += -Wl,-export-dynamic -lstdc++fs
EXPORTERS := -Wl,--whole-archive ../OTRExporter/OTRExporter/OTRExporter.a -Wl,--no-whole-archive
else
endif
ifeq ($(UNAME), Darwin)
EXPORTERS := -Wl,-force_load ../OTRExporter/OTRExporter/OTRExporter.a
endif

@ -18,6 +18,16 @@ void BinaryReader::Close()
stream->Close();
}
void BinaryReader::SetEndianness(Endianness endianness)
{
this->endianness = endianness;
}
Endianness BinaryReader::GetEndianness() const
{
return endianness;
}
void BinaryReader::Seek(uint32_t offset, SeekOffsetType seekType)
{
stream->Seek(offset, seekType);
@ -28,11 +38,16 @@ uint32_t BinaryReader::GetBaseAddress()
return stream->GetBaseAddress();
}
void BinaryReader::Read([[maybe_unused]] char* buffer, int32_t length)
void BinaryReader::Read(int32_t length)
{
stream->Read(length);
}
void BinaryReader::Read(char* buffer, int32_t length)
{
stream->Read(buffer, length);
}
char BinaryReader::ReadChar()
{
return (char)stream->ReadByte();
@ -53,6 +68,10 @@ int16_t BinaryReader::ReadInt16()
int16_t result = 0;
stream->Read((char*)&result, sizeof(int16_t));
if (endianness != Endianness::Native)
result = BSWAP16(result);
return result;
}
@ -61,6 +80,10 @@ int32_t BinaryReader::ReadInt32()
int32_t result = 0;
stream->Read((char*)&result, sizeof(int32_t));
if (endianness != Endianness::Native)
result = BSWAP32(result);
return result;
}
@ -69,6 +92,10 @@ uint16_t BinaryReader::ReadUInt16()
uint16_t result = 0;
stream->Read((char*)&result, sizeof(uint16_t));
if (endianness != Endianness::Native)
result = BSWAP16(result);
return result;
}
@ -77,6 +104,10 @@ uint32_t BinaryReader::ReadUInt32()
uint32_t result = 0;
stream->Read((char*)&result, sizeof(uint32_t));
if (endianness != Endianness::Native)
result = BSWAP32(result);
return result;
}
@ -85,6 +116,10 @@ uint64_t BinaryReader::ReadUInt64()
uint64_t result = 0;
stream->Read((char*)&result, sizeof(uint64_t));
if (endianness != Endianness::Native)
result = BSWAP64(result);
return result;
}
@ -94,6 +129,9 @@ float BinaryReader::ReadSingle()
stream->Read((char*)&result, sizeof(float));
if (endianness != Endianness::Native)
result = BitConverter::ToFloatBE((uint8_t*)&result, 0);
if (std::isnan(result))
throw std::runtime_error("BinaryReader::ReadSingle(): Error reading stream");
@ -105,6 +143,10 @@ double BinaryReader::ReadDouble()
double result = NAN;
stream->Read((char*)&result, sizeof(double));
if (endianness != Endianness::Native)
result = BitConverter::ToDoubleBE((uint8_t*)&result, 0);
if (std::isnan(result))
throw std::runtime_error("BinaryReader::ReadDouble(): Error reading stream");

@ -8,6 +8,7 @@
#include "../Vec2f.h"
#include "../Vec3f.h"
#include "../Vec3s.h"
#include "BitConverter.h"
#include "Stream.h"
class BinaryReader
@ -18,9 +19,13 @@ public:
void Close();
void SetEndianness(Endianness endianness);
Endianness GetEndianness() const;
void Seek(uint32_t offset, SeekOffsetType seekType);
uint32_t GetBaseAddress();
void Read(int32_t length);
void Read(char* buffer, int32_t length);
char ReadChar();
int8_t ReadByte();
@ -41,4 +46,5 @@ public:
protected:
std::shared_ptr<Stream> stream;
Endianness endianness = Endianness::Native;
};

@ -10,6 +10,11 @@ BinaryWriter::BinaryWriter(std::shared_ptr<Stream> nStream)
stream = nStream;
}
void BinaryWriter::SetEndianness(Endianness endianness)
{
this->endianness = endianness;
}
void BinaryWriter::Close()
{
stream->Close();
@ -47,16 +52,25 @@ void BinaryWriter::Write(uint8_t value)
void BinaryWriter::Write(int16_t value)
{
if (endianness != Endianness::Native)
value = BSWAP16(value);
stream->Write((char*)&value, sizeof(int16_t));
}
void BinaryWriter::Write(uint16_t value)
{
if (endianness != Endianness::Native)
value = BSWAP16(value);
stream->Write((char*)&value, sizeof(uint16_t));
}
void BinaryWriter::Write(int32_t value)
{
if (endianness != Endianness::Native)
value = BSWAP32(value);
stream->Write((char*)&value, sizeof(int32_t));
}
@ -68,33 +82,48 @@ void BinaryWriter::Write(int32_t valueA, int32_t valueB)
void BinaryWriter::Write(uint32_t value)
{
if (endianness != Endianness::Native)
value = BSWAP32(value);
stream->Write((char*)&value, sizeof(uint32_t));
}
void BinaryWriter::Write(int64_t value)
{
if (endianness != Endianness::Native)
value = BSWAP64(value);
stream->Write((char*)&value, sizeof(int64_t));
}
void BinaryWriter::Write(uint64_t value)
{
if (endianness != Endianness::Native)
value = BSWAP64(value);
stream->Write((char*)&value, sizeof(uint64_t));
}
void BinaryWriter::Write(float value)
{
if (endianness != Endianness::Native)
value = BitConverter::ToFloatBE((uint8_t*)&value, 0);
stream->Write((char*)&value, sizeof(float));
}
void BinaryWriter::Write(double value)
{
if (endianness != Endianness::Native)
value = BitConverter::ToDoubleBE((uint8_t*)&value, 0);
stream->Write((char*)&value, sizeof(double));
}
void BinaryWriter::Write(const std::string& str)
{
int strLen = str.size();
stream->Write((char*)&strLen, sizeof(int));
Write(strLen);
for (char c : str)
stream->WriteByte(c);

@ -4,6 +4,7 @@
#include <memory>
#include <string>
#include <vector>
#include "BitConverter.h"
#include "Stream.h"
class BinaryWriter
@ -12,6 +13,8 @@ public:
BinaryWriter(Stream* nStream);
BinaryWriter(std::shared_ptr<Stream> nStream);
void SetEndianness(Endianness endianness);
std::shared_ptr<Stream> GetStream();
uint64_t GetBaseAddress();
uint64_t GetLength();
@ -34,4 +37,5 @@ public:
protected:
std::shared_ptr<Stream> stream;
Endianness endianness = Endianness::Native;
};

@ -5,6 +5,28 @@
#include <vector>
#include <cstring>
#ifdef _MSC_VER
#define BSWAP16 _byteswap_ushort
#define BSWAP32 _byteswap_ulong
#define BSWAP64 _byteswap_uint64
#else
#define BSWAP16 __builtin_bswap16
#define BSWAP32 __builtin_bswap32
#define BSWAP64 __builtin_bswap64
#endif
enum class Endianness
{
Little = 0,
Big = 1,
#if (defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__)) || defined(__BIG_ENDIAN__)
Native = Big,
#else
Native = Little,
#endif
};
class BitConverter
{
public:

@ -10,13 +10,6 @@ enum class SeekOffsetType
End
};
// TODO: Eventually account for endianess in binaryreader and binarywriter
enum class Endianess
{
Little = 0,
Big = 1,
};
class Stream
{
public:

@ -29,7 +29,6 @@ WARN := -Wall -Wextra -Werror \
-Wno-narrowing \
-Wno-missing-field-initializers \
-Wno-error=multichar \
-Wno-unused-command-line-argument \
-Wno-delete-non-abstract-non-virtual-dtor \
-Wno-unused-private-field \
-Wno-deprecated-copy-with-user-provided-copy \
@ -46,7 +45,7 @@ endif
CXXFLAGS := $(WARN) $(CXXWARN) -std=c++20 -D_GNU_SOURCE -DENABLE_OPENGL -DSPDLOG_ACTIVE_LEVEL=0
CFLAGS := $(WARN) $(CWARN) -std=c99 -D_GNU_SOURCE -DENABLE_OPENGL -DSPDLOG_ACTIVE_LEVEL=0
CPPFLAGS := -MMD
CPPFLAGS := -MMD $(shell pkg-config --cflags sdl2 glew)
MMFLAGS := -Wno-deprecated-declarations -ObjC++ -fobjc-weak -fobjc-arc
@ -62,10 +61,6 @@ ifneq ($(CXX_IS_CLANG),1)
MMFLAGS += -stdlib++-isystem ${STD_ISYSTEM} -cxx-isystem ${CXX_ISYSTEM}
endif
ifeq ($(UNAME), Darwin) #APPLE
CPPFLAGS += $(shell pkg-config --cflags sdl2 glew) -framework OpenGL -framework Foundation
endif
ifneq ($(DEBUG),0)
CXXFLAGS += -g -D_DEBUG
CFLAGS += -g -D_DEBUG

@ -1,5 +1,103 @@
#include "Cutscene.h"
enum class CutsceneCommands
{
Cmd00 = 0x0000,
SetCameraPos = 0x0001,
SetCameraFocus = 0x0002,
SpecialAction = 0x0003,
SetLighting = 0x0004,
SetCameraPosLink = 0x0005,
SetCameraFocusLink = 0x0006,
Cmd07 = 0x0007,
Cmd08 = 0x0008,
Cmd09 = 0x0009,
Unknown = 0x001A,
Textbox = 0x0013,
SetActorAction0 = 0x000A,
SetActorAction1 = 0x000F,
SetActorAction2 = 0x000E,
SetActorAction3 = 0x0019,
SetActorAction4 = 0x001D,
SetActorAction5 = 0x001E,
SetActorAction6 = 0x002C,
SetActorAction7 = 0x001F,
SetActorAction8 = 0x0031,
SetActorAction9 = 0x003E,
SetActorAction10 = 0x008F,
SetSceneTransFX = 0x002D,
Nop = 0x000B,
PlayBGM = 0x0056,
StopBGM = 0x0057,
FadeBGM = 0x007C,
SetTime = 0x008C,
Terminator = 0x03E8,
End = 0xFFFF,
Error = 0xFEAF,
};
static inline uint32_t read_CMD_BBBB(BinaryReader* reader)
{
uint32_t v;
reader->Read((char*)&v, sizeof(uint32_t));
return v;
}
static inline uint32_t read_CMD_BBH(BinaryReader* reader)
{
uint32_t v;
reader->Read((char*)&v, sizeof(uint32_t));
// swap the half word to match endianness
if (reader->GetEndianness() != Endianness::Native)
{
uint8_t* b = (uint8_t*)&v;
uint8_t tmp = b[2];
b[2] = b[3];
b[3] = tmp;
}
return v;
}
static inline uint32_t read_CMD_HBB(BinaryReader* reader)
{
uint32_t v;
reader->Read((char*)&v, sizeof(uint32_t));
// swap the half word to match endianness
if (reader->GetEndianness() != Endianness::Native)
{
uint8_t* b = (uint8_t*)&v;
uint8_t tmp = b[0];
b[0] = b[1];
b[1] = tmp;
}
return v;
}
static inline uint32_t read_CMD_HH(BinaryReader* reader)
{
uint32_t v;
reader->Read((char*)&v, sizeof(uint32_t));
// swap the half words to match endianness
if (reader->GetEndianness() != Endianness::Native)
{
uint8_t* b = (uint8_t*)&v;
uint8_t tmp = b[0];
b[0] = b[1];
b[1] = tmp;
tmp = b[2];
b[2] = b[3];
b[3] = tmp;
}
return v;
}
void Ship::CutsceneV0::ParseFileBinary(BinaryReader* reader, Resource* res)
{
Cutscene* cs = (Cutscene*)res;
@ -9,11 +107,415 @@ void Ship::CutsceneV0::ParseFileBinary(BinaryReader* reader, Resource* res)
uint32_t numEntries = reader->ReadUInt32();
cs->commands.reserve(numEntries);
for (uint32_t i = 0; i < numEntries; i++)
uint32_t numCommands = reader->ReadUInt32();
cs->commands.push_back(numCommands);
// endFrame
cs->commands.push_back(reader->ReadUInt32());
while (true)
{
uint32_t data = reader->ReadUInt32();
uint16_t opcode = data >> 16;
uint32_t commandId = reader->ReadUInt32();
cs->commands.push_back(commandId);
switch (commandId)
{
case (uint32_t)CutsceneCommands::SetCameraPos:
{
cs->commands.push_back(read_CMD_HH(reader));
cs->commands.push_back(read_CMD_HH(reader));
while (true)
{
uint32_t val = read_CMD_BBH(reader);
int8_t continueFlag = ((int8_t*)&val)[0];
cs->commands.push_back(val);
cs->commands.push_back(reader->ReadUInt32());
cs->commands.push_back(read_CMD_HH(reader));
cs->commands.push_back(read_CMD_HH(reader));
if (continueFlag == -1)
break;
}
}
break;
case (uint32_t)CutsceneCommands::SetCameraFocus:
{
cs->commands.push_back(read_CMD_HH(reader));
cs->commands.push_back(read_CMD_HH(reader));
while (true)
{
uint32_t val = read_CMD_BBH(reader);
int8_t continueFlag = ((int8_t*)&val)[0];
cs->commands.push_back(val);
cs->commands.push_back(reader->ReadUInt32());
cs->commands.push_back(read_CMD_HH(reader));
cs->commands.push_back(read_CMD_HH(reader));
if (continueFlag == -1)
break;
}
break;
}
case (uint32_t)CutsceneCommands::SpecialAction:
{
uint32_t size = reader->ReadUInt32();
cs->commands.push_back(size);
for (uint32_t i = 0; i < size; i++)
{
cs->commands.push_back(read_CMD_HH(reader));
cs->commands.push_back(read_CMD_HH(reader));
cs->commands.push_back(reader->ReadUInt32());
cs->commands.push_back(reader->ReadUInt32());
cs->commands.push_back(reader->ReadUInt32());
cs->commands.push_back(reader->ReadUInt32());
cs->commands.push_back(reader->ReadUInt32());
cs->commands.push_back(reader->ReadUInt32());
cs->commands.push_back(reader->ReadUInt32());
cs->commands.push_back(reader->ReadUInt32());
cs->commands.push_back(reader->ReadUInt32());
cs->commands.push_back(reader->ReadUInt32());
}
break;
}
case (uint32_t)CutsceneCommands::SetLighting:
{
uint32_t size = reader->ReadUInt32();
cs->commands.push_back(size);
for (uint32_t i = 0; i < size; i++)
{
cs->commands.push_back(read_CMD_HH(reader));
cs->commands.push_back(read_CMD_HH(reader));
cs->commands.push_back(reader->ReadUInt32());
cs->commands.push_back(reader->ReadUInt32());
cs->commands.push_back(reader->ReadUInt32());
cs->commands.push_back(reader->ReadUInt32());
cs->commands.push_back(reader->ReadUInt32());
cs->commands.push_back(reader->ReadUInt32());
cs->commands.push_back(reader->ReadUInt32());
cs->commands.push_back(reader->ReadUInt32());
cs->commands.push_back(reader->ReadUInt32());
cs->commands.push_back(reader->ReadUInt32());
}
break;
}
case (uint32_t)CutsceneCommands::SetCameraPosLink:
{
cs->commands.push_back(read_CMD_HH(reader));
cs->commands.push_back(read_CMD_HH(reader));
while (true)
{
uint32_t val = read_CMD_BBH(reader);
int8_t continueFlag = ((int8_t*)&val)[0];
cs->commands.push_back(val);
cs->commands.push_back(reader->ReadUInt32());
cs->commands.push_back(read_CMD_HH(reader));
cs->commands.push_back(read_CMD_HH(reader));
if (continueFlag == -1)
break;
}
break;
}
case (uint32_t)CutsceneCommands::SetCameraFocusLink:
{
cs->commands.push_back(read_CMD_HH(reader));
cs->commands.push_back(read_CMD_HH(reader));
while (true)
{
uint32_t val = read_CMD_BBH(reader);
int8_t continueFlag = ((int8_t*)&val)[0];
cs->commands.push_back(val);
cs->commands.push_back(reader->ReadUInt32());
cs->commands.push_back(read_CMD_HH(reader));
cs->commands.push_back(read_CMD_HH(reader));
if (continueFlag == -1)
break;
}
break;
}
case (uint32_t)CutsceneCommands::Cmd09:
{
uint32_t size = reader->ReadUInt32();
cs->commands.push_back(size);
for (uint32_t i = 0; i < size; i++)
{
cs->commands.push_back(read_CMD_HH(reader));
cs->commands.push_back(read_CMD_HBB(reader));
cs->commands.push_back(read_CMD_BBH(reader));
}
break;
}
case 0x15:
case (uint32_t)CutsceneCommands::Unknown:
{
uint32_t size = reader->ReadUInt32();
cs->commands.push_back(size);
for (uint32_t i = 0; i < size; i++)
{
cs->commands.push_back(reader->ReadUInt32());
cs->commands.push_back(reader->ReadUInt32());
cs->commands.push_back(reader->ReadUInt32());
cs->commands.push_back(reader->ReadUInt32());
cs->commands.push_back(reader->ReadUInt32());
cs->commands.push_back(reader->ReadUInt32());
cs->commands.push_back(reader->ReadUInt32());
cs->commands.push_back(reader->ReadUInt32());
cs->commands.push_back(reader->ReadUInt32());
cs->commands.push_back(reader->ReadUInt32());
cs->commands.push_back(reader->ReadUInt32());
cs->commands.push_back(reader->ReadUInt32());
}
}
break;
case (uint32_t)CutsceneCommands::Textbox:
{
uint32_t size = reader->ReadUInt32();
cs->commands.push_back(size);
for (uint32_t i = 0; i < size; i++)
{
cs->commands.push_back(read_CMD_HH(reader));
cs->commands.push_back(read_CMD_HH(reader));
cs->commands.push_back(read_CMD_HH(reader));
}
break;
}
case (uint32_t)CutsceneCommands::SetActorAction0:
case (uint32_t)CutsceneCommands::SetActorAction1:
case 17:
case 18:
case 23:
case 34:
case 39:
case 46:
case 76:
case 85:
case 93:
case 105:
case 107:
case 110:
case 119:
case 123:
case 138:
case 139:
case 144:
case (uint32_t)CutsceneCommands::SetActorAction2:
case 16:
case 24:
case 35:
case 40:
case 48:
case 64:
case 68:
case 70:
case 78:
case 80:
case 94:
case 116:
case 118:
case 120:
case 125:
case 131:
case 141:
case (uint32_t)CutsceneCommands::SetActorAction3:
case 36:
case 41:
case 50:
case 67:
case 69:
case 72:
case 74:
case 81:
case 106:
case 117:
case 121:
case 126:
case 132:
case (uint32_t)CutsceneCommands::SetActorAction4:
case 37:
case 42:
case 51:
case 53:
case 63:
case 65:
case 66:
case 75:
case 82:
case 108:
case 127:
case 133:
case (uint32_t)CutsceneCommands::SetActorAction5:
case 38:
case 43:
case 47:
case 54:
case 79:
case 83:
case 128:
case 135:
case (uint32_t)CutsceneCommands::SetActorAction6:
case 55:
case 77:
case 84:
case 90:
case 129:
case 136:
case (uint32_t)CutsceneCommands::SetActorAction7:
case 52:
case 57:
case 58:
case 88:
case 115:
case 130:
case 137:
case (uint32_t)CutsceneCommands::SetActorAction8:
case 60:
case 89:
case 111:
case 114:
case 134:
case 142:
case (uint32_t)CutsceneCommands::SetActorAction9:
case (uint32_t)CutsceneCommands::SetActorAction10:
{
uint32_t size = reader->ReadUInt32();
cs->commands.push_back(size);
for (uint32_t i = 0; i < size; i++)
{
cs->commands.push_back(read_CMD_HH(reader));
cs->commands.push_back(read_CMD_HH(reader));
cs->commands.push_back(read_CMD_HH(reader));
cs->commands.push_back(reader->ReadUInt32());
cs->commands.push_back(reader->ReadUInt32());
cs->commands.push_back(reader->ReadUInt32());
cs->commands.push_back(reader->ReadUInt32());
cs->commands.push_back(reader->ReadUInt32());
cs->commands.push_back(reader->ReadUInt32());
cs->commands.push_back(reader->ReadUInt32());
cs->commands.push_back(reader->ReadUInt32());
cs->commands.push_back(reader->ReadUInt32());
}
break;
}
case (uint32_t)CutsceneCommands::SetSceneTransFX:
{
cs->commands.push_back(reader->ReadUInt32());
cs->commands.push_back(read_CMD_HH(reader));
cs->commands.push_back(read_CMD_HH(reader));
break;
}
case (uint32_t)CutsceneCommands::PlayBGM:
{
uint32_t size = reader->ReadUInt32();
cs->commands.push_back(size);
for (uint32_t i = 0; i < size; i++)
{
cs->commands.push_back(read_CMD_HH(reader));
cs->commands.push_back(read_CMD_HH(reader));
cs->commands.push_back(reader->ReadUInt32());
cs->commands.push_back(reader->ReadUInt32());
cs->commands.push_back(reader->ReadUInt32());
cs->commands.push_back(reader->ReadUInt32());
cs->commands.push_back(reader->ReadUInt32());
cs->commands.push_back(reader->ReadUInt32());
cs->commands.push_back(reader->ReadUInt32());
cs->commands.push_back(reader->ReadUInt32());
cs->commands.push_back(reader->ReadUInt32());
cs->commands.push_back(reader->ReadUInt32());
}
break;
}
case (uint32_t)CutsceneCommands::StopBGM:
{
uint32_t size = reader->ReadUInt32();
cs->commands.push_back(size);
for (uint32_t i = 0; i < size; i++)
{
cs->commands.push_back(read_CMD_HH(reader));
cs->commands.push_back(read_CMD_HH(reader));
cs->commands.push_back(reader->ReadUInt32());
cs->commands.push_back(reader->ReadUInt32());
cs->commands.push_back(reader->ReadUInt32());
cs->commands.push_back(reader->ReadUInt32());
cs->commands.push_back(reader->ReadUInt32());
cs->commands.push_back(reader->ReadUInt32());
cs->commands.push_back(reader->ReadUInt32());
cs->commands.push_back(reader->ReadUInt32());
cs->commands.push_back(reader->ReadUInt32());
cs->commands.push_back(reader->ReadUInt32());
}
break;
}
case (uint32_t)CutsceneCommands::FadeBGM:
{
uint32_t size = reader->ReadUInt32();
cs->commands.push_back(size);
for (uint32_t i = 0; i < size; i++)
{
cs->commands.push_back(read_CMD_HH(reader));
cs->commands.push_back(read_CMD_HH(reader));
cs->commands.push_back(reader->ReadUInt32());
cs->commands.push_back(reader->ReadUInt32());
cs->commands.push_back(reader->ReadUInt32());
cs->commands.push_back(reader->ReadUInt32());
cs->commands.push_back(reader->ReadUInt32());
cs->commands.push_back(reader->ReadUInt32());
cs->commands.push_back(reader->ReadUInt32());
cs->commands.push_back(reader->ReadUInt32());
cs->commands.push_back(reader->ReadUInt32());
cs->commands.push_back(reader->ReadUInt32());
}
break;
}
case (uint32_t)CutsceneCommands::SetTime:
{
uint32_t size = reader->ReadUInt32();
cs->commands.push_back(size);
cs->commands.push_back(data);
for (uint32_t i = 0; i < size; i++)
{
cs->commands.push_back(read_CMD_HH(reader));
cs->commands.push_back(read_CMD_HBB(reader));
cs->commands.push_back(reader->ReadUInt32());
}
break;
}
case (uint32_t)CutsceneCommands::Terminator:
{
cs->commands.push_back(reader->ReadUInt32());
cs->commands.push_back(read_CMD_HH(reader));
cs->commands.push_back(read_CMD_HH(reader));
break;
}
case 0xFFFFFFFF: // CS_END
{
cs->commands.push_back(reader->ReadUInt32());
return;
}
default:
#ifdef _DEBUG
printf("CutsceneV0: Unknown command %x\n", commandId);
#endif
// error?
break;
}
}
}

@ -9,7 +9,7 @@
std::map<std::string, std::unique_ptr<CVar>, std::less<>> cvars;
extern "C" CVar* CVar_Get(const char* name) {
CVar* CVar_Get(const char* name) {
auto it = cvars.find(name);
return (it != cvars.end()) ? it->second.get() : nullptr;
}
@ -18,7 +18,7 @@ extern "C" int32_t CVar_GetS32(const char* name, int32_t defaultValue) {
CVar* cvar = CVar_Get(name);
if (cvar) {
if (cvar->type == CVAR_TYPE_S32)
if (cvar->type == CVarType::S32)
return cvar->value.valueS32;
}
@ -29,7 +29,7 @@ extern "C" float CVar_GetFloat(const char* name, float defaultValue) {
CVar* cvar = CVar_Get(name);
if (cvar) {
if (cvar->type == CVAR_TYPE_FLOAT)
if (cvar->type == CVarType::Float)
return cvar->value.valueFloat;
}
@ -40,19 +40,59 @@ extern "C" const char* CVar_GetString(const char* name, const char* defaultValue
CVar* cvar = CVar_Get(name);
if (cvar) {
if (cvar->type == CVAR_TYPE_STRING)
if (cvar->type == CVarType::String)
return cvar->value.valueStr;
}
return defaultValue;
}
extern "C" Color_RGB8 CVar_GetRGB(const char* name, Color_RGB8 defaultValue)
{
Color_RGBA8 defaultValueRGBA;
defaultValueRGBA.r = defaultValue.r;
defaultValueRGBA.g = defaultValue.g;
defaultValueRGBA.b = defaultValue.b;
defaultValueRGBA.a = 255;
Color_RGBA8 cvarGet = CVar_GetRGBA(name, defaultValueRGBA);
Color_RGB8 result;
result.r = cvarGet.r;
result.g = cvarGet.g;
result.b = cvarGet.b;
return result;
}
extern "C" Color_RGBA8 CVar_GetRGBA(const char* name, Color_RGBA8 defaultValue) {
CVar* cvar = CVar_Get(name);
if (cvar != nullptr) {
if (cvar->type == CVarType::RGBA)
return cvar->value.valueRGBA;
}
return defaultValue;
}
extern "C" void CVar_SetRGBA(const char* name, Color_RGBA8 value)
{
auto& cvar = cvars[name];
if (!cvar) {
cvar = std::make_unique<CVar>();
}
cvar->type = CVarType::RGBA;
cvar->value.valueRGBA = value;
}
extern "C" void CVar_SetS32(const char* name, int32_t value) {
auto& cvar = cvars[name];
if (!cvar) {
cvar = std::make_unique<CVar>();
}
cvar->type = CVAR_TYPE_S32;
cvar->type = CVarType::S32;
cvar->value.valueS32 = value;
}
@ -61,7 +101,7 @@ void CVar_SetFloat(const char* name, float value) {
if (!cvar) {
cvar = std::make_unique<CVar>();
}
cvar->type = CVAR_TYPE_FLOAT;
cvar->type = CVarType::Float;
cvar->value.valueFloat = value;
}
@ -70,10 +110,15 @@ extern "C" void CVar_SetString(const char* name, const char* value) {
if (!cvar) {
cvar = std::make_unique<CVar>();
}
cvar->type = CVAR_TYPE_STRING;
cvar->type = CVarType::String;
cvar->value.valueStr = ImStrdup(value);
}
extern "C" void CVar_RegisterRGBA(const char* name, Color_RGBA8 defaultValue) {
if (!CVar_Get(name))
CVar_SetRGBA(name, defaultValue);
}
extern "C" void CVar_RegisterS32(const char* name, int32_t defaultValue) {
if (!CVar_Get(name))
CVar_SetS32(name, defaultValue);

@ -1,9 +1,17 @@
#ifndef _CVAR_H
#define _CVAR_H
#include "color.h"
#include <stdint.h>
typedef enum CVarType { CVAR_TYPE_S32, CVAR_TYPE_FLOAT, CVAR_TYPE_STRING } CVarType;
#ifdef __cplusplus
typedef enum class CVarType
{
S32,
Float,
String,
RGBA
} CVarType;
typedef struct CVar {
const char* name;
@ -13,25 +21,33 @@ typedef struct CVar {
int32_t valueS32;
float valueFloat;
const char* valueStr;
Color_RGBA8 valueRGBA;
} value;
} CVar;
extern "C" CVar * CVar_Get(const char* name);
#endif
#ifdef __cplusplus
extern "C"
{
#endif
//#include <ultra64.h>
CVar* CVar_Get(const char* name);
int32_t CVar_GetS32(const char* name, int32_t defaultValue);
float CVar_GetFloat(const char* name, float defaultValue);
const char* CVar_GetString(const char* name, const char* defaultValue);
void CVar_SetS32(const char* name, int32_t value);
void CVar_SetString(const char* name, const char* value);
Color_RGB8 CVar_GetRGB(const char* name, Color_RGB8 defaultValue);
Color_RGBA8 CVar_GetRGBA(const char* name, Color_RGBA8 defaultValue);
void CVar_SetRGBA(const char* name, Color_RGBA8 value);
void CVar_RegisterS32(const char* name, int32_t defaultValue);
void CVar_RegisterFloat(const char* name, float defaultValue);
void CVar_RegisterString(const char* name, const char* defaultValue);
void CVar_RegisterRGBA(const char* name, Color_RGBA8 defaultValue);
#ifdef __cplusplus
};
@ -43,6 +59,7 @@ void CVar_RegisterString(const char* name, const char* defaultValue);
#include <functional>
#include <memory>
//extern "C" CVar * CVar_Get(const char* name);
extern std::map<std::string, std::unique_ptr<CVar>, std::less<>> cvars;
void CVar_SetFloat(const char* name, float value);
#endif

@ -14,23 +14,25 @@ namespace Ship
while (true)
{
uint64_t data = reader->ReadUInt64();
uint32_t w0 = reader->ReadUInt32();
uint32_t w1 = reader->ReadUInt32();
if (sizeof(uintptr_t) < 8){
dl->instructions.push_back(data);
dl->instructions.push_back(((uint64_t) w0 << 32) | w1);
uint8_t opcode = data >> 24;
uint8_t opcode = w0 >> 24;
// These are 128-bit commands, so read an extra 64 bits...
if (opcode == G_SETTIMG_OTR || opcode == G_DL_OTR || opcode == G_VTX_OTR || opcode == G_BRANCH_Z_OTR || opcode == G_MARKER || opcode == G_MTX_OTR)
dl->instructions.push_back(reader->ReadUInt64());
if (opcode == G_SETTIMG_OTR || opcode == G_DL_OTR || opcode == G_VTX_OTR || opcode == G_BRANCH_Z_OTR || opcode == G_MARKER || opcode == G_MTX_OTR) {
w0 = reader->ReadUInt32();
w1 = reader->ReadUInt32();
dl->instructions.push_back(((uint64_t) w0 << 32) | w1);
}
if (opcode == G_ENDDL)
break;
} else {
uint32_t w0 = (uint32_t)data;
uint32_t w1 = (uint32_t)(data >> 32);
dl->instructions.push_back(w0);
dl->instructions.push_back(w1);
@ -38,10 +40,8 @@ namespace Ship
if (opcode == G_SETTIMG_OTR || opcode == G_DL_OTR || opcode == G_VTX_OTR || opcode == G_BRANCH_Z_OTR || opcode == G_MARKER || opcode == G_MTX_OTR)
{
data = reader->ReadUInt64();
w0 = (uint32_t)data;
w1 = (uint32_t)(data >> 32);
w0 = reader->ReadUInt32();
w1 = reader->ReadUInt32();
dl->instructions.push_back(w0);
dl->instructions.push_back(w1);

@ -25,12 +25,12 @@ namespace Ship
auto memStream = std::make_shared<MemoryStream>(FileToLoad->buffer.get(), FileToLoad->dwBufferSize);
auto reader = std::make_shared<BinaryReader>(memStream);
Endianess endianess = (Endianess)reader->ReadByte();
Endianness endianness = (Endianness)reader->ReadByte();
for (int i = 0; i < 3; i++)
reader->ReadByte();