Merge changes from develop-zhora

This commit is contained in:
Christopher Leggett 2022-08-02 19:17:08 -04:00
commit a007bfd14a
No known key found for this signature in database
GPG Key ID: 7093AE5FF7037D79
86 changed files with 2252 additions and 892 deletions

View File

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

View File

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

View File

@ -3,31 +3,29 @@ 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 \
gcc-${GCCVER} \
g++-${GCCVER} \
p7zip-full \
python3.9 \
python3 \
make \
cmake \
curl \
git \
lld \
wget \
libglew-dev \
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
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 && \
@ -38,10 +36,23 @@ 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/
./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

View File

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

15
Jenkinsfile vendored
View File

@ -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/
@ -107,7 +106,7 @@ pipeline {
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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -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 data = reader->ReadUInt32();
uint16_t opcode = data >> 16;
uint32_t numCommands = reader->ReadUInt32();
cs->commands.push_back(numCommands);
cs->commands.push_back(data);
// endFrame
cs->commands.push_back(reader->ReadUInt32());
while (true)
{
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);
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;
}
}
}

View File

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

View File

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

View File

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

View File

@ -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();
// OTRTODO: Setup the binaryreader to use the resource's endianess
reader->SetEndianness(endianness);
ResourceType resourceType = (ResourceType)reader->ReadUInt32();
Resource* result = nullptr;

View File

@ -162,15 +162,18 @@ void Ship::GameOverlay::Draw() {
ImVec4 color = ImVec4(1.0f, 1.0f, 1.0f, 1.0f);
switch (var->type) {
case CVAR_TYPE_FLOAT:
case CVarType::Float:
this->TextDraw(30, textY, true, color, "%s %.2f", text, var->value.valueFloat);
break;
case CVAR_TYPE_S32:
case CVarType::S32:
this->TextDraw(30, textY, true, color, "%s %d", text, var->value.valueS32);
break;
case CVAR_TYPE_STRING:
case CVarType::String:
this->TextDraw(30, textY, true, color, "%s %s", text, var->value.valueStr);
break;
case CVarType::RGBA:
this->TextDraw(30, textY, true, color, "#%08X", text, var->value.valueRGBA);
break;
}
free((void*) text);

View File

@ -68,6 +68,13 @@ OSContPad* pads;
std::map<std::string, GameAsset*> DefaultAssets;
std::vector<std::string> emptyArgs;
bool isBetaQuestEnabled = false;
extern "C" {
void enableBetaQuest() { isBetaQuestEnabled = true; }
void disableBetaQuest() { isBetaQuestEnabled = false; }
}
namespace SohImGui {
WindowImpl impl;
@ -130,8 +137,9 @@ namespace SohImGui {
}
void Tooltip(const char* text) {
if (ImGui::IsItemHovered())
ImGui::SetTooltip("%s", text);
if (ImGui::IsItemHovered()) {
ImGui::SetTooltip("%s", BreakTooltip(text, 60).c_str());
}
}
void ImGuiWMInit() {
@ -280,22 +288,20 @@ namespace SohImGui {
stbi_image_free(img_data);
}
void LoadPickersColors(ImVec4& ColorArray, const char* cvarname, const ImVec4& default_colors, bool has_alpha) {
std::string Cvar_Red = cvarname;
Cvar_Red += "R";
std::string Cvar_Green = cvarname;
Cvar_Green += "G";
std::string Cvar_Blue = cvarname;
Cvar_Blue += "B";
std::string Cvar_Alpha = cvarname;
Cvar_Alpha += "A";
void LoadPickersColors(ImVec4& ColorArray, const char* cvarname, const ImVec4& default_colors, bool has_alpha)
{
Color_RGBA8 defaultColors;
defaultColors.r = default_colors.x;
defaultColors.g = default_colors.y;
defaultColors.b = default_colors.z;
defaultColors.a = default_colors.w;
ColorArray.x = (float)CVar_GetS32(Cvar_Red.c_str(), default_colors.x) / 255;
ColorArray.y = (float)CVar_GetS32(Cvar_Green.c_str(), default_colors.y) / 255;
ColorArray.z = (float)CVar_GetS32(Cvar_Blue.c_str(), default_colors.z) / 255;
if (has_alpha) {
ColorArray.w = (float)CVar_GetS32(Cvar_Alpha.c_str(), default_colors.w) / 255;
}
Color_RGBA8 cvarColor = CVar_GetRGBA(cvarname, defaultColors);
ColorArray.x = cvarColor.r / 255.0;
ColorArray.y = cvarColor.g / 255.0;
ColorArray.z = cvarColor.b / 255.0;
ColorArray.w = cvarColor.a / 255.0;
}
void LoadResource(const std::string& name, const std::string& path, const ImVec4& tint) {
@ -661,14 +667,6 @@ namespace SohImGui {
}
void ResetColor(const char* cvarName, ImVec4* colors, ImVec4 defaultcolors, bool has_alpha) {
std::string Cvar_Red = cvarName;
Cvar_Red += "R";
std::string Cvar_Green = cvarName;
Cvar_Green += "G";
std::string Cvar_Blue = cvarName;
Cvar_Blue += "B";
std::string Cvar_Alpha = cvarName;
Cvar_Alpha += "A";
std::string Cvar_RBM = cvarName;
Cvar_RBM += "RBM";
std::string MakeInvisible = "Reset";
@ -680,10 +678,14 @@ namespace SohImGui {
colors->y = defaultcolors.y / 255;
colors->z = defaultcolors.z / 255;
if (has_alpha) { colors->w = defaultcolors.w / 255; };
CVar_SetS32(Cvar_Red.c_str(), ClampFloatToInt(colors->x * 255, 0, 255));
CVar_SetS32(Cvar_Green.c_str(), ClampFloatToInt(colors->y * 255, 0, 255));
CVar_SetS32(Cvar_Blue.c_str(), ClampFloatToInt(colors->z * 255, 0, 255));
if (has_alpha) { CVar_SetS32(Cvar_Alpha.c_str(), ClampFloatToInt(colors->w * 255, 0, 255)); };
Color_RGBA8 colorsRGBA;
colorsRGBA.r = defaultcolors.x / 255;
colorsRGBA.g = defaultcolors.y / 255;
colorsRGBA.b = defaultcolors.z / 255;
if (has_alpha) { colorsRGBA.a = defaultcolors.w / 255; };
CVar_SetRGBA(cvarName, colorsRGBA);
CVar_SetS32(Cvar_RBM.c_str(), 0); //On click disable rainbow mode.
needs_save = true;
}
@ -691,42 +693,47 @@ namespace SohImGui {
}
void EnhancementColor(const char* text, const char* cvarName, ImVec4 ColorRGBA, ImVec4 default_colors, bool allow_rainbow, bool has_alpha, bool TitleSameLine) {
//This will be moved to external cosmetics ed
std::string Cvar_Red = cvarName;
Cvar_Red += "R";
std::string Cvar_Green = cvarName;
Cvar_Green += "G";
std::string Cvar_Blue = cvarName;
Cvar_Blue += "B";
std::string Cvar_Alpha = cvarName;
Cvar_Alpha += "A";
std::string Cvar_RBM = cvarName;
Cvar_RBM += "RBM";
LoadPickersColors(ColorRGBA, cvarName, default_colors, has_alpha);
ImGuiColorEditFlags flags = ImGuiColorEditFlags_None;
if (!TitleSameLine) {
ImGui::Text("%s", text);
flags = ImGuiColorEditFlags_NoLabel;
}
ImGui::PushID(cvarName);
if (!has_alpha) {
if (ImGui::ColorEdit3(text, (float*)&ColorRGBA, flags)) {
CVar_SetS32(Cvar_Red.c_str(), ClampFloatToInt(ColorRGBA.x * 255, 0, 255));
CVar_SetS32(Cvar_Green.c_str(), ClampFloatToInt(ColorRGBA.y * 255, 0, 255));
CVar_SetS32(Cvar_Blue.c_str(), ClampFloatToInt(ColorRGBA.z * 255, 0, 255));
if (ImGui::ColorEdit3(text, (float*)&ColorRGBA, flags))
{
Color_RGBA8 colors;
colors.r = ColorRGBA.x * 255.0;
colors.g = ColorRGBA.y * 255.0;
colors.b = ColorRGBA.z * 255.0;
colors.a = ColorRGBA.w * 255.0;
CVar_SetRGBA(cvarName, colors);
needs_save = true;
}
} else {
if (ImGui::ColorEdit4(text, (float*)&ColorRGBA, flags)) {
CVar_SetS32(Cvar_Red.c_str(), ClampFloatToInt(ColorRGBA.x * 255, 0, 255));
CVar_SetS32(Cvar_Green.c_str(), ClampFloatToInt(ColorRGBA.y * 255, 0, 255));
CVar_SetS32(Cvar_Blue.c_str(), ClampFloatToInt(ColorRGBA.z * 255, 0, 255));
CVar_SetS32(Cvar_Alpha.c_str(), ClampFloatToInt(ColorRGBA.w * 255, 0, 255));
}
else
{
if (ImGui::ColorEdit4(text, (float*)&ColorRGBA, flags))
{
Color_RGBA8 colors;
colors.r = ColorRGBA.x / 255;
colors.g = ColorRGBA.y / 255;
colors.b = ColorRGBA.z / 255;
colors.a = ColorRGBA.w / 255;
CVar_SetRGBA(cvarName, colors);
needs_save = true;
}
}
ImGui::PopID();
}
//ImGui::SameLine(); // Removing that one to gain some width spacing on the HUD editor
ImGui::PushItemWidth(-FLT_MIN);
ResetColor(cvarName, &ColorRGBA, default_colors, has_alpha);
@ -868,7 +875,7 @@ namespace SohImGui {
// TODO mutual exclusions -- There should be some system to prevent conclifting enhancements from being selected
EnhancementCheckbox("D-pad Support on Pause and File Select", "gDpadPauseName");
Tooltip("Enables Pause and File Select screen navigation with the D-pad\nIf used with D-pad as Equip Items, you must hold C-Up\nto equip instead of navigate");
Tooltip("Enables Pause and File Select screen navigation with the D-pad\nIf used with D-pad as Equip Items, you must hold C-Up to equip instead of navigate");
EnhancementCheckbox("D-pad Support in Ocarina and Text Choice", "gDpadOcarinaText");
EnhancementCheckbox("D-pad Support for Browsing Shop Items", "gDpadShop");
EnhancementCheckbox("D-pad as Equip Items", "gDpadEquips");
@ -890,18 +897,20 @@ namespace SohImGui {
if (ImGui::BeginMenu("Graphics"))
{
#ifndef __APPLE__
EnhancementSliderFloat("Internal Resolution: %d %%", "##IMul", "gInternalResolution", 0.5f, 2.0f, "", 1.0f, true);
Tooltip("Multiplies your output resolution by the value inputted,\nas a more intensive but effective form of anti-aliasing");
Tooltip("Multiplies your output resolution by the value inputted, as a more intensive but effective form of anti-aliasing");
gfx_current_dimensions.internal_mul = CVar_GetFloat("gInternalResolution", 1);
EnhancementSliderInt("MSAA: %d", "##IMSAA", "gMSAAValue", 1, 8, "");
Tooltip("Activates multi-sample anti-aliasing when above 1x\nup to 8x for 8 samples for every pixel");
#endif
EnhancementSliderInt("MSAA: %d", "##IMSAA", "gMSAAValue", 1, 8, "", 1, true);
Tooltip("Activates multi-sample anti-aliasing when above 1x up to 8x for 8 samples for every pixel");
gfx_msaa_level = CVar_GetS32("gMSAAValue", 1);
if (impl.backend == Backend::DX11)
{
const char* cvar = "gExtraLatencyThreshold";
int val = CVar_GetS32(cvar, 80);
val = MAX(MIN(val, 250), 0);
val = MAX(MIN(val, 360), 0);
int fps = val;
if (fps == 0)
@ -923,18 +932,13 @@ namespace SohImGui {
ImGui::SameLine();
ImGui::SetCursorPosX(ImGui::GetCursorPosX() - 7.0f);
if (ImGui::SliderInt("##ExtraLatencyThreshold", &val, 0, 250, "", ImGuiSliderFlags_AlwaysClamp))
if (ImGui::SliderInt("##ExtraLatencyThreshold", &val, 0, 360, "", ImGuiSliderFlags_AlwaysClamp))
{
CVar_SetS32(cvar, val);
needs_save = true;
}
Tooltip("When Interpolation FPS setting is at least this threshold,\n"
"add one frame of input lag (e.g. 16.6 ms for 60 FPS)\n"
"in order to avoid jitter.This setting allows the CPU\n"
"to work on one frame while GPU works on the previous frame.\n"
"This setting should be used when your computer is too slow\n"
"to do CPU + GPU work in time.");
Tooltip("When Interpolation FPS setting is at least this threshold, add one frame of input lag (e.g. 16.6 ms for 60 FPS) in order to avoid jitter. This setting allows the CPU to work on one frame while GPU works on the previous frame.\nThis setting should be used when your computer is too slow to do CPU + GPU work in time.");
ImGui::SameLine();
ImGui::SetCursorPosX(ImGui::GetCursorPosX() - 7.0f);
@ -984,30 +988,32 @@ namespace SohImGui {
EnhancementSliderInt("Text Speed: %dx", "##TEXTSPEED", "gTextSpeed", 1, 5, "");
EnhancementSliderInt("King Zora Speed: %dx", "##MWEEPSPEED", "gMweepSpeed", 1, 5, "");
EnhancementSliderInt("Biggoron Forge Time: %d days", "##FORGETIME", "gForgeTime", 0, 3, "");
Tooltip("Allows you to change the number of days it takes for\nBiggoron to forge the Biggoron Sword");
Tooltip("Allows you to change the number of days it takes for Biggoron to forge the Biggoron Sword");
EnhancementSliderInt("Vine/Ladder Climb speed +%d", "##CLIMBSPEED", "gClimbSpeed", 0, 12, "");
EnhancementCheckbox("Faster Block Push", "gFasterBlockPush");
EnhancementCheckbox("Faster Heavy Block Lift", "gFasterHeavyBlockLift");
Tooltip("Speeds up lifting silver rocks and obelisks");
EnhancementCheckbox("No Forced Navi", "gNoForcedNavi");
Tooltip("Prevent forced Navi conversations");
EnhancementCheckbox("No Skulltula Freeze", "gSkulltulaFreeze");
Tooltip("Stops the game from freezing the player\nwhen picking up Gold Skulltulas");
Tooltip("Stops the game from freezing the player when picking up Gold Skulltulas");
EnhancementCheckbox("MM Bunny Hood", "gMMBunnyHood");
Tooltip("Wearing the Bunny Hood grants a speed\nincrease like in Majora's Mask");
Tooltip("Wearing the Bunny Hood grants a speed increase like in Majora's Mask");
EnhancementCheckbox("Fast Chests", "gFastChests");
Tooltip("Kick open every chest");
EnhancementCheckbox("Fast Drops", "gFastDrops");
Tooltip("Skip first-time pickup messages for consumable items");
EnhancementCheckbox("Skip Pickup Messages", "gFastDrops");
Tooltip("Skip pickup messages for new consumable items and bottle swipes");
EnhancementCheckbox("Better Owl", "gBetterOwl");
Tooltip("The default response to Kaepora Gaebora is\nalways that you understood what he said");
Tooltip("The default response to Kaepora Gaebora is always that you understood what he said");
EnhancementCheckbox("Fast Ocarina Playback", "gFastOcarinaPlayback");
Tooltip("Skip the part where the Ocarina playback is called when you play\na song");
Tooltip("Skip the part where the Ocarina playback is called when you play a song");
EnhancementCheckbox("Prevent Dropped Ocarina Inputs", "gDpadNoDropOcarinaInput");
Tooltip("Prevent dropping inputs when playing the ocarina quickly");
EnhancementCheckbox("Instant Putaway", "gInstantPutaway");
Tooltip("Allow Link to put items away without having to wait around");
EnhancementCheckbox("Mask Select in Inventory", "gMaskSelect");
Tooltip("After completing the mask trading sub-quest,\npress A and any direction on the mask slot to change masks");
Tooltip("After completing the mask trading sub-quest, press A and any direction on the mask slot to change masks");
ImGui::EndMenu();
}
@ -1138,11 +1144,13 @@ namespace SohImGui {
}
EnhancementCheckbox("Visual Stone of Agony", "gVisualAgony");
Tooltip("Displays an icon and plays a sound when Stone of Agony\nshould be activated, for those without rumble");
Tooltip("Displays an icon and plays a sound when Stone of Agony should be activated, for those without rumble");
EnhancementCheckbox("Assignable Tunics and Boots", "gAssignableTunicsAndBoots");
Tooltip("Allows equipping the tunic and boots to c-buttons");
EnhancementCheckbox("Equipment Toggle", "gEquipmentCanBeRemoved");
Tooltip("Allows equipment to be removed by toggling it off on\nthe equipment subscreen.");
EnhancementCheckbox("Link's Cow in Both Time Periods", "gCowOfTime");
Tooltip("Allows the Lon Lon Ranch obstacle course reward to be\nshared across time periods");
Tooltip("Allows the Lon Lon Ranch obstacle course reward to be shared across time periods");
EnhancementCheckbox("Enable visible guard vision", "gGuardVision");
EnhancementCheckbox("Enable passage of time on file select", "gTimeFlowFileSelect");
EnhancementCheckbox("Allow the cursor to be on any slot", "gPauseAnyCursor");
@ -1160,7 +1168,7 @@ namespace SohImGui {
ImGui::Text("Rotation");
EnhancementRadioButton("Disabled", "gPauseLiveLinkRotation", 0);
EnhancementRadioButton("Rotate Link with D-pad", "gPauseLiveLinkRotation", 1);
Tooltip("Allow you to rotate Link on the Equipment menu with the DPAD\nUse DPAD-Up or DPAD-Down to reset Link's rotation");
Tooltip("Allow you to rotate Link on the Equipment menu with the D-pad\nUse D-pad Up or D-pad Down to reset Link's rotation");
EnhancementRadioButton("Rotate Link with C-buttons", "gPauseLiveLinkRotation", 2);
Tooltip("Allow you to rotate Link on the Equipment menu with the C-buttons\nUse C-Up or C-Down to reset Link's rotation");
EnhancementRadioButton("Rotate Link with Right Stick", "gPauseLiveLinkRotation", 3);
@ -1205,7 +1213,7 @@ namespace SohImGui {
EnhancementCheckbox("Enable 3D Dropped items/projectiles", "gNewDrops");
Tooltip("Change most 2D items and projectiles on the overworld to their 3D versions");
EnhancementCheckbox("Disable Black Bar Letterboxes", "gDisableBlackBars");
Tooltip("Disables Black Bar Letterboxes during cutscenes and Z-targeting\nNote: there may be minor visual glitches that\nwere covered up by the black bars\nPlease disable this setting before reporting a bug");
Tooltip("Disables Black Bar Letterboxes during cutscenes and Z-targeting\nNote: there may be minor visual glitches that were covered up by the black bars\nPlease disable this setting before reporting a bug");
EnhancementCheckbox("Dynamic Wallet Icon", "gDynamicWalletIcon");
Tooltip("Changes the rupee in the wallet icon to match the wallet size you currently have");
EnhancementCheckbox("Always show dungeon entrances", "gAlwaysShowDungeonMinimapIcon");
@ -1221,19 +1229,19 @@ namespace SohImGui {
EnhancementCheckbox("Fix L&Z Page switch in Pause menu", "gNGCKaleidoSwitcher");
Tooltip("Makes L and R switch pages like on the GameCube\nZ opens the Debug Menu instead");
EnhancementCheckbox("Fix Dungeon entrances", "gFixDungeonMinimapIcon");
Tooltip("Removes the dungeon entrance icon on the top-left corner\nof the screen when no dungeon is present on the current map");
Tooltip("Removes the dungeon entrance icon on the top-left corner of the screen when no dungeon is present on the current map");
EnhancementCheckbox("Fix Two Handed idle animations", "gTwoHandedIdle");
Tooltip("Re-enables the two-handed idle animation, a seemingly\nfinished animation that was disabled on accident in the original game");
Tooltip("Re-enables the two-handed idle animation, a seemingly finished animation that was disabled on accident in the original game");
EnhancementCheckbox("Fix the Gravedigging Tour Glitch", "gGravediggingTourFix");
Tooltip("Fixes a bug where the Gravedigging Tour Heart\nPiece disappears if the area reloads");
Tooltip("Fixes a bug where the Gravedigging Tour Heart Piece disappears if the area reloads");
EnhancementCheckbox("Fix Deku Nut upgrade", "gDekuNutUpgradeFix");
Tooltip("Prevents the Forest Stage Deku Nut upgrade from\nbecoming unobtainable after receiving the Poacher's Saw");
Tooltip("Prevents the Forest Stage Deku Nut upgrade from becoming unobtainable after receiving the Poacher's Saw");
EnhancementCheckbox("Fix Navi text HUD position", "gNaviTextFix");
Tooltip("Correctly centers the Navi text prompt on the HUD's C-Up button");
EnhancementCheckbox("Fix Anubis fireballs", "gAnubisFix");
Tooltip("Make Anubis fireballs do fire damage when reflected\nback at them with the Mirror Shield");
Tooltip("Make Anubis fireballs do fire damage when reflected back at them with the Mirror Shield");
EnhancementCheckbox("Fix Megaton Hammer crouch stab", "gCrouchStabHammerFix");
Tooltip("Make the Megaton Hammer's crouch stab able to destroy\nrocks without first swinging it normally");
Tooltip("Make the Megaton Hammer's crouch stab able to destroy rocks without first swinging it normally");
if (CVar_GetS32("gCrouchStabHammerFix", 0) == 0) {
CVar_SetS32("gCrouchStabFix", 0);
} else {
@ -1249,7 +1257,7 @@ namespace SohImGui {
EnhancementCheckbox("Red Ganon blood", "gRedGanonBlood");
Tooltip("Restore the original red blood from NTSC 1.0/1.1. Disable for green blood");
EnhancementCheckbox("Fish while hovering", "gHoverFishing");
Tooltip("Restore a bug from NTSC 1.0 that allows casting\nthe Fishing Rod while using the Hover Boots");
Tooltip("Restore a bug from NTSC 1.0 that allows casting the Fishing Rod while using the Hover Boots");
EnhancementCheckbox("N64 Weird Frames", "gN64WeirdFrames");
Tooltip("Restores N64 Weird Frames allowing weirdshots to behave the same as N64");
EnhancementCheckbox("Bombchus out of bounds", "gBombchusOOB");
@ -1267,7 +1275,7 @@ namespace SohImGui {
int maxFps = 60;
#else
int minFps = 20;
int maxFps = 250;
int maxFps = 360;
#endif
int val = CVar_GetS32(fps_cvar, minFps);
@ -1295,9 +1303,9 @@ namespace SohImGui {
if (ImGui::SliderInt("##FPSInterpolation", &val, minFps, maxFps, "", ImGuiSliderFlags_AlwaysClamp))
{
if (val > 250)
if (val > 360)
{
val = 250;
val = 360;
}
else if (val < 20)
{
@ -1310,7 +1318,7 @@ namespace SohImGui {
Tooltip("Interpolate extra frames to get smoother graphics\n"
"Set to match your monitor's refresh rate, or a divisor of it\n"
"A higher target FPS than your monitor's refresh rate will just waste resources,\n"
"A higher target FPS than your monitor's refresh rate will just waste resources, "
"and might give a worse result.\n"
"For consistent input lag, set this value and your monitor's refresh rate to a multiple of 20\n"
"Ctrl+Click for keyboard input");
@ -1328,7 +1336,7 @@ namespace SohImGui {
if (ImGui::Button("Match Refresh Rate"))
{
int hz = roundf(gfx_get_detected_hz());
if (hz >= 20 && hz <= 250)
if (hz >= 20 && hz <= 360)
{
CVar_SetS32(fps_cvar, hz);
needs_save = true;
@ -1338,7 +1346,7 @@ namespace SohImGui {
EnhancementCheckbox("Disable LOD", "gDisableLOD");
Tooltip("Turns off the Level of Detail setting, making models use their higher-poly variants at any distance");
EnhancementCheckbox("Disable Draw Distance", "gDisableDrawDistance");
Tooltip("Turns off the objects draw distance,\nmaking objects being visible from a longer range");
Tooltip("Turns off the objects draw distance, making objects being visible from a longer range");
if (CVar_GetS32("gDisableDrawDistance", 0) == 0) {
CVar_SetS32("gDisableKokiriDrawDistance", 0);
} else if (CVar_GetS32("gDisableDrawDistance", 0) == 1) {
@ -1349,7 +1357,7 @@ namespace SohImGui {
Tooltip("Holding down B skips text\nKnown to cause a cutscene softlock in Water Temple\nSoftlock can be fixed by pressing D-Right in Debug mode");
EnhancementCheckbox("Free Camera", "gFreeCamera");
Tooltip("Enables camera control\nNote: You must remap C buttons off of\nthe right stick in the controller\nconfig menu, and map the camera stick\nto the right stick.");
Tooltip("Enables camera control\nNote: You must remap C buttons off of the right stick in the controller config menu, and map the camera stick to the right stick.");
#ifdef __SWITCH__
int slot = CVar_GetS32("gSwitchPerfMode", (int)SwitchProfiles::STOCK);
@ -1405,7 +1413,79 @@ namespace SohImGui {
EnhancementCheckbox("Fireproof Deku Shield", "gFireproofDekuShield");
Tooltip("Prevents the Deku Shield from burning on contact with fire");
EnhancementCheckbox("Shield with Two-Handed Weapons", "gShieldTwoHanded");
Tooltip("This allows you to put up your shield with any two-handed weapon in hand\nexcept for Deku Sticks");
Tooltip("This allows you to put up your shield with any two-handed weapon in hand except for Deku Sticks");
{
static int32_t betaQuestEnabled = CVar_GetS32("gEnableBetaQuest", 0);
static int32_t lastBetaQuestEnabled = betaQuestEnabled;
static int32_t betaQuestWorld = CVar_GetS32("gBetaQuestWorld", 0xFFEF);
static int32_t lastBetaQuestWorld = betaQuestWorld;
if (!isBetaQuestEnabled) {
ImGui::PushItemFlag(ImGuiItemFlags_Disabled, true);
ImGui::PushStyleVar(ImGuiStyleVar_Alpha, ImGui::GetStyle().Alpha * 0.5f);
}
EnhancementCheckbox("Enable Beta Quest", "gEnableBetaQuest");
Tooltip("Turns on OoT Beta Quest. *WARNING* This will reset your game.");
betaQuestEnabled = CVar_GetS32("gEnableBetaQuest", 0);
if (betaQuestEnabled) {
if (betaQuestEnabled != lastBetaQuestEnabled) {
betaQuestWorld = 0;
}
ImGui::Text("Beta Quest World: %d", betaQuestWorld);
if (ImGui::Button(" - ##BetaQuest")) {
betaQuestWorld--;
}
ImGui::SameLine();
ImGui::SetCursorPosX(ImGui::GetCursorPosX() - 7.0f);
ImGui::SliderInt("##BetaQuest", &betaQuestWorld, 0, 8, "", ImGuiSliderFlags_AlwaysClamp);
Tooltip("Set the Beta Quest world to explore. *WARNING* Changing this will reset your game.\nCtrl+Click to type in a value.");
ImGui::Text("After Slider Beta Quest World: %d", betaQuestWorld);
ImGui::SameLine();
ImGui::SetCursorPosX(ImGui::GetCursorPosX() - 7.0f);
if (ImGui::Button(" + ##BetaQuest")) {
betaQuestWorld++;
}
if (betaQuestWorld > 8) {
betaQuestWorld = 8;
}
else if (betaQuestWorld < 0) {
betaQuestWorld = 0;
}
ImGui::Text("After Clamp Beta Quest World: %d", betaQuestWorld);
}
else {
lastBetaQuestWorld = betaQuestWorld = 0xFFEF;
CVar_SetS32("gBetaQuestWorld", betaQuestWorld);
needs_save = true;
}
if (betaQuestEnabled != lastBetaQuestEnabled || betaQuestWorld != lastBetaQuestWorld)
{
// Reset the game if the beta quest state or world changed because beta quest happens on redirecting the title screen cutscene.
lastBetaQuestEnabled = betaQuestEnabled;
lastBetaQuestWorld = betaQuestWorld;
CVar_SetS32("gEnableBetaQuest", betaQuestEnabled);
CVar_SetS32("gBetaQuestWorld", betaQuestWorld);
console->Commands["reset"].handler(emptyArgs);
needs_save = true;
}
if (!isBetaQuestEnabled) {
ImGui::PopItemFlag();
ImGui::PopStyleVar();
}
}
ImGui::EndMenu();
}
@ -1415,11 +1495,11 @@ namespace SohImGui {
if (ImGui::BeginMenu("Developer Tools"))
{
EnhancementCheckbox("OoT Debug Mode", "gDebugEnabled");
Tooltip("Enables Debug Mode, allowing you to select maps with L + R + Z, noclip with L + D-pad Right,\nand open the debug menu with L on the pause screen");
Tooltip("Enables Debug Mode, allowing you to select maps with L + R + Z, noclip with L + D-pad Right, and open the debug menu with L on the pause screen");
EnhancementCheckbox("OoT Skulltula Debug", "gSkulltulaDebugEnabled");
Tooltip("Enables Skulltula Debug, when moving the cursor in the menu above various map\nicons (boss key, compass, map screen locations, etc) will set the GS bits in that\narea. USE WITH CAUTION AS IT DOES NOT UPDATE THE GS COUNT.");
Tooltip("Enables Skulltula Debug, when moving the cursor in the menu above various map icons (boss key, compass, map screen locations, etc) will set the GS bits in that area.\nUSE WITH CAUTION AS IT DOES NOT UPDATE THE GS COUNT.");
EnhancementCheckbox("Fast File Select", "gSkipLogoTitle");
Tooltip("Load the game to the selected menu or file\n\"Zelda Map Select\" require debug mode else you will fallback to File choose menu\nUsing a file number that don't have save will create a save file only\nif you toggle on \"Create a new save if none ?\" else it will bring you to the\nFile choose menu");
Tooltip("Load the game to the selected menu or file\n\"Zelda Map Select\" require debug mode else you will fallback to File choose menu\nUsing a file number that don't have save will create a save file only if you toggle on \"Create a new save if none ?\" else it will bring you to the File choose menu");
if (CVar_GetS32("gSkipLogoTitle", 0)) {
const char* FastFileSelect[5] = {
"File N.1",
@ -1431,13 +1511,13 @@ namespace SohImGui {
ImGui::Text("Loading :");
EnhancementCombobox("gSaveFileID", FastFileSelect, 5, 0);
EnhancementCheckbox("Create a new save if none", "gCreateNewSave");
Tooltip("Enable the creation of a new save file\nif none exist in the File number selected\nNo file name will be assigned please do in Save editor once you see the first text\nelse your save file name will be named \"00000000\"\nIf disabled you will fall back in File select menu");
Tooltip("Enable the creation of a new save file if none exist in the File number selected\nNo file name will be assigned please do in Save editor once you see the first text else your save file name will be named \"00000000\"\nIf disabled you will fall back in File select menu");
};
ImGui::Separator();
EnhancementCheckbox("Stats", "gStatsEnabled");
Tooltip("Shows the stats window, with your FPS and frametimes,\nand the OS you're playing on");
Tooltip("Shows the stats window, with your FPS and frametimes, and the OS you're playing on");
EnhancementCheckbox("Console", "gConsoleEnabled");
Tooltip("Enables the console window, allowing you to input commands,\ntype help for some examples");
Tooltip("Enables the console window, allowing you to input commands, type help for some examples");
console->opened = CVar_GetS32("gConsoleEnabled", 0);
ImGui::EndMenu();
@ -1779,4 +1859,36 @@ namespace SohImGui {
ImGui::EndGroup();
}
// Automatically add newlines to break up tooltips longer than a specified number of characters
// Manually included newlines will still be respected and reset the line length
// Default line length is 60 characters
std::string BreakTooltip(const char* text, int lineLength) {
std::string newText(text);
const int tipLength = newText.length();
int lastSpace = -1;
int currentLineLength = 0;
for (int currentCharacter = 0; currentCharacter < tipLength; currentCharacter++) {
if (newText[currentCharacter] == '\n') {
currentLineLength = 0;
lastSpace = -1;
continue;
}
else if (newText[currentCharacter] == ' ') {
lastSpace = currentCharacter;
}
if ((currentLineLength >= lineLength) && (lastSpace >= 0)) {
newText[lastSpace] = '\n';
currentLineLength = currentCharacter - lastSpace - 1;
lastSpace = -1;
}
currentLineLength++;
}
return newText;
}
std::string BreakTooltip(const std::string& text, int lineLength) {
return BreakTooltip(text.c_str(), lineLength);
}
}

View File

@ -1,5 +1,15 @@
#pragma once
#ifdef __cplusplus
extern "C" {
#endif
void enableBetaQuest();
void disableBetaQuest();
#ifdef __cplusplus
}
#endif
#ifdef __cplusplus
#include "GameOverlay.h"
#include "Lib/ImGui/imgui.h"
#include "Console.h"
@ -94,4 +104,8 @@ namespace SohImGui {
ImTextureID GetTextureByName(const std::string& name);
void BeginGroupPanel(const char* name, const ImVec2 & size = ImVec2(0.0f, 0.0f));
void EndGroupPanel(float minHeight = 0.0f);
std::string BreakTooltip(const char* text, int lineLength = 60);
std::string BreakTooltip(const std::string& text, int lineLength = 60);
}
#endif

View File

@ -2651,7 +2651,11 @@ void gfx_init(struct GfxWindowManagerAPI *wapi, struct GfxRenderingAPI *rapi, co
gfx_wapi->init(game_name, start_in_fullscreen, width, height);
gfx_rapi->init();
gfx_rapi->update_framebuffer_parameters(0, width, height, 1, false, true, true, true);
#ifdef __APPLE__
gfx_current_dimensions.internal_mul = 1;
#else
gfx_current_dimensions.internal_mul = CVar_GetFloat("gInternalResolution", 1);
#endif
gfx_msaa_level = CVar_GetS32("gMSAAValue", 1);
gfx_current_dimensions.width = width;
gfx_current_dimensions.height = height;

View File

@ -6,6 +6,7 @@
#include <filesystem>
#include <unordered_map>
#include <any>
#include <Utils/StringHelper.h>
namespace fs = std::filesystem;
using json = nlohmann::json;
@ -16,18 +17,9 @@ Mercury::Mercury(std::string path) : path_(std::move(path)) {
this->reload();
}
std::vector<std::string> split(const std::string& s, const char delimiter) {
std::vector<std::string> result;
std::stringstream ss(s);
std::string item;
while (getline(ss, item, delimiter)) {
result.push_back(item);
}
return result;
}
std::string Mercury::formatNestedKey(const std::string& key) {
const std::vector<std::string> dots = split(key, '.');
std::vector<std::string> dots = StringHelper::Split(key, ".");
std::string tmp;
if (dots.size() > 1)
for (const auto& dot : dots) {
@ -40,7 +32,7 @@ std::string Mercury::formatNestedKey(const std::string& key) {
}
json Mercury::nested(const std::string& key) {
std::vector<std::string> dots = split(key, '.');
std::vector<std::string> dots = StringHelper::Split(key, ".");
if (!this->vjson.is_object())
return this->vjson;
json gjson = this->vjson.unflatten();

View File

@ -4,6 +4,8 @@
#include <string>
#include "../nlohmann/json.hpp"
static const std::string mercuryRGBAObjectType = "RGBA";
class Mercury {
protected:
std::string path_;

View File

@ -51,12 +51,6 @@ namespace Ship
F64 = 10
};
enum class Endianess
{
Little = 0,
Big = 1,
};
enum class Version
{
// BR
@ -90,7 +84,7 @@ namespace Ship
class ResourceFile
{
public:
Endianess endianess; // 0x00 - Endianess of the file
Endianness endianness; // 0x00 - Endianness of the file
uint32_t resourceType; // 0x01 - 4 byte MAGIC
Version version; // 0x05 - Based on Ship release numbers
uint64_t id; // 0x09 - Unique Resource ID

View File

@ -10,7 +10,7 @@ namespace Ship {
SDL_AudioSpec want, have;
SDL_zero(want);
want.freq = this->GetSampleRate();
want.format = AUDIO_S16;
want.format = AUDIO_S16SYS;
want.channels = 2;
want.samples = 1024;
want.callback = NULL;

View File

@ -32,6 +32,8 @@
#include <iostream>
#define LOAD_TEX(texPath) static_cast<Ship::Texture*>(Ship::GlobalCtx2::GetInstance()->GetResourceManager()->LoadResource(texPath).get());
extern "C" {
struct OSMesgQueue;
@ -123,8 +125,7 @@ extern "C" {
const std::string* hashStr = Ship::GlobalCtx2::GetInstance()->GetResourceManager()->HashToString(crc);
if (hashStr != nullptr) {
const auto res = static_cast<Ship::Texture*>(Ship::GlobalCtx2::GetInstance()->GetResourceManager()->LoadResource(hashStr->c_str()).get());
const auto res = LOAD_TEX(hashStr->c_str());
ModInternal::ExecuteHooks<ModInternal::LoadTexture>(hashStr->c_str(), &res->imageData);
return reinterpret_cast<char*>(res->imageData);
@ -151,13 +152,40 @@ extern "C" {
}
char* ResourceMgr_LoadTexByName(char* texPath) {
const auto res = static_cast<Ship::Texture*>(Ship::GlobalCtx2::GetInstance()->GetResourceManager()->LoadResource(texPath).get());
const auto res = LOAD_TEX(texPath);
ModInternal::ExecuteHooks<ModInternal::LoadTexture>(texPath, &res->imageData);
return (char*)res->imageData;
}
uint16_t ResourceMgr_LoadTexWidthByName(char* texPath) {
const auto res = LOAD_TEX(texPath);
if (res != nullptr)
return res->width;
SPDLOG_ERROR("Given texture path is a non-existent resource");
return -1;
}
uint16_t ResourceMgr_LoadTexHeightByName(char* texPath) {
const auto res = LOAD_TEX(texPath);
if (res != nullptr)
return res->height;
SPDLOG_ERROR("Given texture path is a non-existent resource");
return -1;
}
uint32_t ResourceMgr_LoadTexSizeByName(char* texPath) {
const auto res = LOAD_TEX(texPath);
if (res != nullptr)
return res->imageDataSize;
SPDLOG_ERROR("Given texture path is a non-existent resource");
return -1;
}
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 = LOAD_TEX(texPath);
if (res != nullptr)
{

View File

@ -0,0 +1,50 @@
#ifndef COLOR_H
#define COLOR_H
#include <stdint.h>
#include "endianness.h"
#ifdef __cplusplus
extern "C"
{
#endif
typedef struct {
uint8_t r, g, b;
} Color_RGB8;
typedef struct {
uint8_t r, g, b, a;
} Color_RGBA8;
// only use when necessary for alignment purposes
typedef union {
struct {
#ifdef IS_BIGENDIAN
uint8_t r, g, b, a;
#else
uint8_t a, b, g, r;
#endif
};
uint32_t rgba;
} Color_RGBA8_u32;
typedef struct {
float r, g, b, a;
} Color_RGBAf;
typedef union {
struct {
uint16_t r : 5;
uint16_t g : 5;
uint16_t b : 5;
uint16_t a : 1;
};
uint16_t rgba;
} Color_RGBA16;
#ifdef __cplusplus
};
#endif
#endif

View File

@ -0,0 +1,67 @@
#ifndef ENDIANESS_H
#define ENDIANESS_H
#ifdef _MSC_VER
#include <stdlib.h>
#define BOMSWAP16 _byteswap_ushort
#define BOMSWAP32 _byteswap_ulong
#define BOMSWAP64 _byteswap_uint64
#define BOMSWAP16_CONST(x) \
((((x) >> 8) & 0x00FF) | (((x) << 8) & 0xFF00))
#define BOMSWAP32_CONST(x) \
((((x) >> 24) & 0x000000FF) | (((x) >> 8) & 0x0000FF00) | \
(((x) << 8) & 0x00FF0000) | (((x) << 24) & 0xFF000000))
#define BOMSWAP64_CONST(x) \
((((x) >> 56) & 0x00000000000000FF) | (((x) >> 40) & 0x000000000000FF00) | \
(((x) >> 24) & 0x0000000000FF0000) | (((x) >> 8) & 0x00000000FF000000) | \
(((x) << 8) & 0x000000FF00000000) | (((x) << 24) & 0x0000FF0000000000) | \
(((x) << 40) & 0x00FF000000000000) | (((x) << 56) & 0xFF00000000000000))
#else
#define BOMSWAP16 __builtin_bswap16
#define BOMSWAP32 __builtin_bswap32
#define BOMSWAP64 __builtin_bswap64
#define BOMSWAP16_CONST __builtin_bswap16
#define BOMSWAP32_CONST __builtin_bswap32
#define BOMSWAP64_CONST __builtin_bswap64
#endif
#if (defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__)) || defined(__BIG_ENDIAN__)
#ifndef IS_BIGENDIAN
#define IS_BIGENDIAN
#endif
#endif
#ifdef IS_BIGENDIAN
#define BE16SWAP(x) (x)
#define BE32SWAP(x) (x)
#define BE64SWAP(x) (x)
#define LE16SWAP(x) BOMSWAP16(x)
#define LE32SWAP(x) BOMSWAP32(x)
#define LE64SWAP(x) BOMSWAP64(x)
#define BE16SWAP_CONST(x) (x)
#define BE32SWAP_CONST(x) (x)
#define BE64SWAP_CONST(x) (x)
#define LE16SWAP_CONST(x) BOMSWAP16_CONST(x)
#define LE32SWAP_CONST(x) BOMSWAP32_CONST(x)
#define LE64SWAP_CONST(x) BOMSWAP64_CONST(x)
#else
#define BE16SWAP(x) BOMSWAP16(x)
#define BE32SWAP(x) BOMSWAP32(x)
#define BE64SWAP(x) BOMSWAP64(x)
#define LE16SWAP(x) (x)
#define LE32SWAP(x) (x)
#define LE64SWAP(x) (x)
#define BE16SWAP_CONST(x) BOMSWAP16_CONST(x)
#define BE32SWAP_CONST(x) BOMSWAP32_CONST(x)
#define BE64SWAP_CONST(x) BOMSWAP64_CONST(x)
#define LE16SWAP_CONST(x) (x)
#define LE32SWAP_CONST(x) (x)
#define LE64SWAP_CONST(x) (x)
#endif
#endif

View File

@ -351,6 +351,7 @@
<ClInclude Include="Audio.h" />
<ClInclude Include="AudioPlayer.h" />
<ClInclude Include="Blob.h" />
<ClInclude Include="color.h" />
<ClInclude Include="ControlDeck.h" />
<ClInclude Include="Cvar.h" />
<ClInclude Include="Environment.h" />

View File

@ -653,6 +653,9 @@
<ClInclude Include="GameVersions.h">
<Filter>Source Files\Resources</Filter>
</ClInclude>
<ClInclude Include="color.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="GameOverlay.h">
<Filter>Source Files\CustomImpl\Overlay</Filter>
</ClInclude>

View File

@ -6,7 +6,7 @@ curl -sSfL https://github.com$(curl https://github.com/probonopd/go-appimage/rel
chmod a+x mkappimage.AppImage
mkdir -p AppDir/usr/bin
cp appimage/{soh.desktop,soh.sh} AppDir/
cp scripts/linux/{soh.desktop,soh.sh} AppDir/
cp soh/macosx/sohIcon.png AppDir/soh.png
curl -sSfL https://raw.githubusercontent.com/gabomdq/SDL_GameControllerDB/master/gamecontrollerdb.txt -o AppDir/usr/bin/gamecontrollerdb.txt

11
scripts/linux/build.sh Executable file
View File

@ -0,0 +1,11 @@
#!/bin/bash
cd soh
make setup -j$(nproc) OPTFLAGS=-O2 DEBUG=0
make -j$(nproc) OPTFLAGS=-O2 DEBUG=0
cd ../OTRGui
mkdir build
cd build
cmake ..
cmake --build . --config Release

4
scripts/switch/build.sh Executable file
View File

@ -0,0 +1,4 @@
#!/bin/bash
make setup -C soh -j$(nproc) OPTFLAGS=-O2 DEBUG=0
make -f Makefile.switch -j$(nproc)

View File

@ -16,26 +16,35 @@ DEBUG ?= 1
OPTFLAGS ?= -O0
LTO ?= 0
# flag to save whether the compiler being used is clang or gcc by checking CXX --version
CXX_IS_CLANG ?= $(shell $(CXX) --version | grep -c clang)
WARN := \
-Wno-return-type \
-Wno-unused-command-line-argument \
-Wno-implicit-function-declaration \
-Wno-c++11-narrowing \
-funsigned-char \
-fno-stack-protector -fno-common -fno-zero-initialized-in-bss -fno-strict-aliasing -fno-inline-functions -fno-inline-small-functions -ffreestanding -fwrapv \
CXXFLAGS := $(WARN) -std=c++20 -D_GNU_SOURCE -fpermissive -no-pie -nostdlib
CFLAGS := $(WARN) -std=c99 -D_GNU_SOURCE -no-pie -nostdlib
LDFLAGS :=
ifeq ($(UNAME), Linux) #LINUX
CXXFLAGS += -mhard-float -msse2 -mfpmath=sse
CFLAGS += -mhard-float -msse2 -mfpmath=sse
ifeq ($(CXX_IS_CLANG),1)
WARN += -Wno-c++11-narrowing
endif
ifeq ($(UNAME), Darwin) #APPLE
CXXFLAGS += $(shell pkg-config --cflags sdl2) $(shell sdl2-config --cflags) $(shell pkg-config --cflags glew) -framework OpenGL
CFLAGS += $(shell pkg-config --cflags sdl2) $(shell sdl2-config --cflags) $(shell pkg-config --cflags glew) -framework OpenGL
CXXFLAGS := $(WARN) -std=c++20 -D_GNU_SOURCE -fpermissive -nostdlib $(shell pkg-config --cflags glew) $(shell sdl2-config --cflags)
CFLAGS := $(WARN) -std=c99 -Wno-implicit-function-declaration -D_GNU_SOURCE -nostdlib $(shell pkg-config --cflags glew) $(shell sdl2-config --cflags)
LDFLAGS :=
ifneq ($(CXX_IS_CLANG),1)
CXXFLAGS += -no-pie
CFLAGS += -no-pie
endif
ifeq ($(UNAME), Linux)
ifeq ($(UNAMEM), x86_64)
CXXFLAGS += -msse2 -mfpmath=sse -mhard-float
CFLAGS += -msse2 -mfpmath=sse -mhard-float
endif
CXXFLAGS += $(shell pkg-config --cflags libpulse)
CFLAGS += $(shell pkg-config --cflags libpulse)
endif
CPPFLAGS := -MMD
@ -57,11 +66,11 @@ ifneq ($(LTO),0)
LDFLAGS += -flto
endif
ifeq ($(UNAME), Linux) #LINUX
ifeq ($(UNAME), Linux)
TARGET := soh.elf
endif
ifeq ($(UNAME), Darwin) #APPLE
ifeq ($(UNAME), Darwin)
TARGET := soh-$(UNAMEM)
endif
@ -78,25 +87,15 @@ INC_DIRS := $(addprefix -I, \
../libultraship/libultraship/Lib/Fast3D/U64/PR \
)
ifeq ($(UNAME), Linux) #LINUX
INC_DIRS += $(addprefix -I, \
/opt/X11/include \
)
endif
LDDIRS := $(addprefix -L, \
../libultraship/ \
)
ifeq ($(UNAME), Linux) #LINUX
LDDIRS += $(addprefix -L, \
/opt/X11/lib \
)
endif
LDLIBS := \
$(ZAPDUTILS) \
$(LIBSTORM) \
$(shell sdl2-config --libs) \
$(shell pkg-config --libs glew) \
$(addprefix -l, \
dl \
bz2 \
@ -105,24 +104,16 @@ LDLIBS := \
ultraship \
)
ifeq ($(UNAME), Linux) #LINUX
LDLIBS += \
$(addprefix -l, \
X11 \
SDL2 \
GL \
GLEW \
pulse \
)
ifeq ($(UNAME), Linux)
LDLIBS += $(shell pkg-config --libs x11 libpulse)
endif
ifeq ($(UNAME), Darwin) #APPLE
ifeq ($(UNAME), Darwin)
LDLIBS += \
$(addprefix -framework , \
OpenGL \
Foundation \
) \
$(shell sdl2-config --libs) $(shell pkg-config --libs glew)
)
endif
ASSET_BIN_DIRS := $(shell find assets/* -type d -not -path "assets/xml*")

View File

@ -1,34 +0,0 @@
#ifndef COLOR_H
#define COLOR_H
typedef struct {
u8 r, g, b;
} Color_RGB8;
typedef struct {
u8 r, g, b, a;
} Color_RGBA8;
// only use when necessary for alignment purposes
typedef union {
struct {
u8 a, b, g, r;
};
u32 rgba;
} Color_RGBA8_u32;
typedef struct {
f32 r, g, b, a;
} Color_RGBAf;
typedef union {
struct {
u16 r : 5;
u16 g : 5;
u16 b : 5;
u16 a : 1;
};
u16 rgba;
} Color_RGBA16;
#endif

View File

@ -6,6 +6,15 @@
* Each macro packs bytes (B), halfwords (H) and words (W, for consistency) into a single word
*/
#ifdef IS_BIGENDIAN
#define CMD_BBBB(a, b, c, d) (_SHIFTL(a, 24, 8) | _SHIFTL(b, 16, 8) | _SHIFTL(c, 8, 8) | _SHIFTL(d, 0, 8))
#define CMD_BBH(a, b, c) (_SHIFTL(a, 24, 8) | _SHIFTL(b, 16, 8) | _SHIFTL(c, 0, 16))
#define CMD_HBB(a, b, c) (_SHIFTL(a, 16, 16) | _SHIFTL(b, 8, 8) | _SHIFTL(c, 0, 8))
#define CMD_HH(a, b) (_SHIFTL(a, 16, 16) | _SHIFTL(b, 0, 16))
#else
#define CMD_BBBB(a, b, c, d) (_SHIFTL(a, 0, 8) | _SHIFTL(b, 8, 8) | _SHIFTL(c, 16, 8) | _SHIFTL(d, 24, 8))
#define CMD_BBH(a, b, c) (_SHIFTL(a, 0, 8) | _SHIFTL(b, 8, 8) | _SHIFTL(c, 16, 16))
@ -13,6 +22,7 @@
#define CMD_HBB(a, b, c) (_SHIFTL(a, 0, 16) | _SHIFTL(b, 16, 8) | _SHIFTL(c, 24, 8))
#define CMD_HH(a, b) (_SHIFTL(a, 0, 16) | _SHIFTL(b, 16, 16))
#endif
#define CMD_W(a) (a)

View File

@ -1,6 +1,8 @@
#ifndef MACROS_H
#define MACROS_H
#include "endianness.h"
#define ARRAY_COUNT(arr) (s32)(sizeof(arr) / sizeof(arr[0]))
#define ARRAY_COUNTU(arr) (u32)(sizeof(arr) / sizeof(arr[0]))
@ -254,12 +256,5 @@ extern GraphicsContext* __gfxCtx;
#define SEG_ADDR(seg, addr) (addr | (seg << 24) | 1)
#ifdef _MSC_VER
#define BOMSWAP16 _byteswap_ushort
#define BOMSWAP32 _byteswap_ulong
#else
#define BOMSWAP16 __builtin_bswap16
#define BOMSWAP32 __builtin_bswap32
#endif
#endif

View File

@ -30,7 +30,7 @@
#include "ichain.h"
#include "regs.h"
#if defined(_WIN64) || defined(__x86_64__) || defined(__arm64__)
#if defined(__LP64__)
#define _SOH64
#endif
@ -1458,8 +1458,6 @@ typedef struct {
/* 0x18 */ s16 (*roomCompassOffsetY)[44]; // dungeon compass icon Y offset by room
/* 0x1C */ u8* dgnMinimapCount; // number of room minimaps
/* 0x20 */ u16* dgnMinimapTexIndexOffset; // dungeon minimap texture index offset
/* 0x24 */ u16* owMinimapTexSize;
/* 0x28 */ u16* owMinimapTexOffset;
/* 0x2C */ s16* owMinimapPosX;
/* 0x30 */ s16* owMinimapPosY;
/* 0x34 */ s16 (*owCompassInfo)[4]; // [X scale, Y scale, X offset, Y offset]

View File

@ -1,6 +1,8 @@
#ifndef Z64_AUDIO_H
#define Z64_AUDIO_H
#include "endianness.h"
#define MK_CMD(b0,b1,b2,b3) ((((b0) & 0xFF) << 0x18) | (((b1) & 0xFF) << 0x10) | (((b2) & 0xFF) << 0x8) | (((b3) & 0xFF) << 0))
#define NO_LAYER ((SequenceLayer*)(-1))
@ -685,6 +687,35 @@ typedef struct {
} AudioPreloadReq; // size = 0x14
typedef struct {
#ifdef IS_BIGENDIAN
union{
u32 opArgs;
struct {
u8 op;
u8 arg0;
u8 arg1;
u8 arg2;
};
};
union {
void* data;
f32 asFloat;
s32 asInt;
struct {
u16 asUShort;
u8 pad2[2];
};
struct {
s8 asSbyte;
u8 pad1[3];
};
struct {
u8 asUbyte;
u8 pad0[3];
};
u32 asUInt;
};
#else
union{
u32 opArgs;
struct {
@ -712,6 +743,7 @@ typedef struct {
};
u32 asUInt;
};
#endif
} AudioCmd;
typedef struct {

View File

@ -356,7 +356,20 @@ typedef struct {
/* 0x00 */ s32 active;
/* 0x04 */ Vec3f tip;
/* 0x10 */ Vec3f base;
} WeaponInfo; // size = 0x1C
} WeaponInfo; // size = 0x1C\
typedef enum {
FLAG_NONE,
FLAG_SCENE_SWITCH,
FLAG_SCENE_TREASURE,
FLAG_SCENE_CLEAR,
FLAG_SCENE_COLLECTIBLE,
} FlagType;
typedef struct {
/* 0x00 */ s32 flagID; // which flag to set when Player_SetPendingFlag is called
/* 0x04 */ FlagType flagType; // type of flag to set when Player_SetPendingFlag is called
} PendingFlag; // size = 0x06
#define PLAYER_STATE1_0 (1 << 0)
#define PLAYER_STATE1_1 (1 << 1)
@ -612,6 +625,7 @@ typedef struct Player {
/* 0x0A86 */ s8 unk_A86;
/* 0x0A87 */ u8 unk_A87;
/* 0x0A88 */ Vec3f unk_A88; // previous body part 0 position
} Player; // size = 0xA94
/* 0x0A94 */ PendingFlag pendingFlag;
} Player; // size = 0xAA0
#endif

View File

@ -3,6 +3,7 @@
#include "ultra64.h"
#include "z64math.h"
#include "z64audio.h"
#include "soh/Enhancements/randomizer/randomizerTypes.h"
typedef struct {
@ -114,9 +115,9 @@ typedef struct {
/* 0x0EF8 */ u16 infTable[30]; // "inf_table"
/* 0x0F38 */ u32 worldMapAreaData; // "area_arrival"
/* 0x0F40 */ u8 scarecrowCustomSongSet;
/* 0x0F41 */ u8 scarecrowCustomSong[0x360];
/* 0x0F41 */ OcarinaNote scarecrowCustomSong[108];
/* 0x12C5 */ u8 scarecrowSpawnSongSet;
/* 0x12C6 */ u8 scarecrowSpawnSong[0x80];
/* 0x12C6 */ OcarinaNote scarecrowSpawnSong[16];
/* 0x1346 */ char unk_1346[0x02];
/* 0x1348 */ HorseData horseData;
/* 0x1354 */ s32 fileNum; // "file_no"

View File

@ -990,7 +990,6 @@
<ClInclude Include="soh\frame_interpolation.h" />
<ClInclude Include="include\alloca.h" />
<ClInclude Include="include\bgm.h" />
<ClInclude Include="include\color.h" />
<ClInclude Include="include\command_macros_base.h" />
<ClInclude Include="include\fp.h" />
<ClInclude Include="include\functions.h" />

View File

@ -82,6 +82,24 @@
<Filter Include="Source Files\soh\Enhancements\debugger">
<UniqueIdentifier>{04fc1c52-49ff-48e2-ae23-2c00867374f8}</UniqueIdentifier>
</Filter>
<Filter Include="Source Files\soh\Enhancements\randomizer">
<UniqueIdentifier>{fd63976d-64b1-45ee-b3ab-530c636391c3}</UniqueIdentifier>
</Filter>
<Filter Include="Source Files\soh\Enhancements\randomizer\3drando">
<UniqueIdentifier>{ff94f63c-a792-49af-869b-42557318a32b}</UniqueIdentifier>
</Filter>
<Filter Include="Source Files\soh\Enhancements\randomizer\3drando\hint_list">
<UniqueIdentifier>{1ba82a8d-b7d9-4f79-b80b-389322e189bc}</UniqueIdentifier>
</Filter>
<Filter Include="Source Files\soh\Enhancements\randomizer\3drando\location_access">
<UniqueIdentifier>{9e20d69b-6a26-48ef-9aae-09c149b2c459}</UniqueIdentifier>
</Filter>
<Filter Include="Header Files\soh\Enhancements\randomizer">
<UniqueIdentifier>{d7b4c12f-3876-40ec-a8ec-db435513156c}</UniqueIdentifier>
</Filter>
<Filter Include="Header Files\soh\Enhancements\randomizer\3drando">
<UniqueIdentifier>{38ae4e39-fade-4f81-bfdb-af83bf641df0}</UniqueIdentifier>
</Filter>
<Filter Include="Source Files\soh\Enhancements\custom-message">
<UniqueIdentifier>{8f355b3b-15ba-4e0a-be8b-2a6ec0ff4ec7}</UniqueIdentifier>
</Filter>
@ -2212,172 +2230,172 @@
<Filter>Header Files\include</Filter>
</ClCompile>
<ClCompile Include="soh\Enhancements\randomizer\3drando\hint_list\hint_list_exclude_dungeon.cpp">
<Filter>Source Files</Filter>
<Filter>Source Files\soh\Enhancements\randomizer\3drando\hint_list</Filter>
</ClCompile>
<ClCompile Include="soh\Enhancements\randomizer\3drando\hint_list\hint_list_exclude_overworld.cpp">
<Filter>Source Files</Filter>
<Filter>Source Files\soh\Enhancements\randomizer\3drando\hint_list</Filter>
</ClCompile>
<ClCompile Include="soh\Enhancements\randomizer\3drando\hint_list\hint_list_item.cpp">
<Filter>Source Files</Filter>
<Filter>Source Files\soh\Enhancements\randomizer\3drando\hint_list</Filter>
</ClCompile>
<ClCompile Include="soh\Enhancements\randomizer\3drando\location_access\locacc_bottom_of_the_well.cpp">
<Filter>Source Files</Filter>
<Filter>Source Files\soh\Enhancements\randomizer\3drando\location_access</Filter>
</ClCompile>
<ClCompile Include="soh\Enhancements\randomizer\3drando\location_access\locacc_castle_town.cpp">
<Filter>Source Files</Filter>
<Filter>Source Files\soh\Enhancements\randomizer\3drando\location_access</Filter>
</ClCompile>
<ClCompile Include="soh\Enhancements\randomizer\3drando\location_access\locacc_death_mountain.cpp">
<Filter>Source Files</Filter>
<Filter>Source Files\soh\Enhancements\randomizer\3drando\location_access</Filter>
</ClCompile>
<ClCompile Include="soh\Enhancements\randomizer\3drando\location_access\locacc_deku_tree.cpp">
<Filter>Source Files</Filter>
<Filter>Source Files\soh\Enhancements\randomizer\3drando\location_access</Filter>
</ClCompile>
<ClCompile Include="soh\Enhancements\randomizer\3drando\location_access\locacc_dodongos_cavern.cpp">
<Filter>Source Files</Filter>
<Filter>Source Files\soh\Enhancements\randomizer\3drando\location_access</Filter>
</ClCompile>
<ClCompile Include="soh\Enhancements\randomizer\3drando\location_access\locacc_fire_temple.cpp">
<Filter>Source Files</Filter>
<Filter>Source Files\soh\Enhancements\randomizer\3drando\location_access</Filter>
</ClCompile>
<ClCompile Include="soh\Enhancements\randomizer\3drando\location_access\locacc_forest_temple.cpp">
<Filter>Source Files</Filter>
<Filter>Source Files\soh\Enhancements\randomizer\3drando\location_access</Filter>
</ClCompile>
<ClCompile Include="soh\Enhancements\randomizer\3drando\location_access\locacc_ganons_castle.cpp">
<Filter>Source Files</Filter>
<Filter>Source Files\soh\Enhancements\randomizer\3drando\location_access</Filter>
</ClCompile>
<ClCompile Include="soh\Enhancements\randomizer\3drando\location_access\locacc_gerudo_training_grounds.cpp">
<Filter>Source Files</Filter>
<Filter>Source Files\soh\Enhancements\randomizer\3drando\location_access</Filter>
</ClCompile>
<ClCompile Include="soh\Enhancements\randomizer\3drando\location_access\locacc_gerudo_valley.cpp">
<Filter>Source Files</Filter>
<Filter>Source Files\soh\Enhancements\randomizer\3drando\location_access</Filter>
</ClCompile>
<ClCompile Include="soh\Enhancements\randomizer\3drando\location_access\locacc_hyrule_field.cpp">
<Filter>Source Files</Filter>
<Filter>Source Files\soh\Enhancements\randomizer\3drando\location_access</Filter>
</ClCompile>
<ClCompile Include="soh\Enhancements\randomizer\3drando\location_access\locacc_ice_cavern.cpp">
<Filter>Source Files</Filter>
<Filter>Source Files\soh\Enhancements\randomizer\3drando\location_access</Filter>
</ClCompile>
<ClCompile Include="soh\Enhancements\randomizer\3drando\location_access\locacc_jabujabus_belly.cpp">
<Filter>Source Files</Filter>
<Filter>Source Files\soh\Enhancements\randomizer\3drando\location_access</Filter>
</ClCompile>
<ClCompile Include="soh\Enhancements\randomizer\3drando\location_access\locacc_kakariko.cpp">
<Filter>Source Files</Filter>
<Filter>Source Files\soh\Enhancements\randomizer\3drando\location_access</Filter>
</ClCompile>
<ClCompile Include="soh\Enhancements\randomizer\3drando\location_access\locacc_lost_woods.cpp">
<Filter>Source Files</Filter>
<Filter>Source Files\soh\Enhancements\randomizer\3drando\location_access</Filter>
</ClCompile>
<ClCompile Include="soh\Enhancements\randomizer\3drando\location_access\locacc_shadow_temple.cpp">
<Filter>Source Files</Filter>
<Filter>Source Files\soh\Enhancements\randomizer\3drando\location_access</Filter>
</ClCompile>
<ClCompile Include="soh\Enhancements\randomizer\3drando\location_access\locacc_spirit_temple.cpp">
<Filter>Source Files</Filter>
<Filter>Source Files\soh\Enhancements\randomizer\3drando\location_access</Filter>
</ClCompile>
<ClCompile Include="soh\Enhancements\randomizer\3drando\location_access\locacc_water_temple.cpp">
<Filter>Source Files</Filter>
<Filter>Source Files\soh\Enhancements\randomizer\3drando\location_access</Filter>
</ClCompile>
<ClCompile Include="soh\Enhancements\randomizer\3drando\location_access\locacc_zoras_domain.cpp">
<Filter>Source Files</Filter>
<Filter>Source Files\soh\Enhancements\randomizer\3drando\location_access</Filter>
</ClCompile>
<ClCompile Include="soh\Enhancements\randomizer\3drando\cosmetics.cpp">
<Filter>Source Files</Filter>
<Filter>Source Files\soh\Enhancements\randomizer\3drando</Filter>
</ClCompile>
<ClCompile Include="soh\Enhancements\randomizer\3drando\custom_messages.cpp">
<Filter>Source Files</Filter>
<Filter>Source Files\soh\Enhancements\randomizer\3drando</Filter>
</ClCompile>
<ClCompile Include="soh\Enhancements\randomizer\3drando\debug.cpp">
<Filter>Source Files</Filter>
<Filter>Source Files\soh\Enhancements\randomizer\3drando</Filter>
</ClCompile>
<ClCompile Include="soh\Enhancements\randomizer\3drando\dungeon.cpp">
<Filter>Source Files</Filter>
<Filter>Source Files\soh\Enhancements\randomizer\3drando</Filter>
</ClCompile>
<ClCompile Include="soh\Enhancements\randomizer\3drando\entrance.cpp">
<Filter>Source Files</Filter>
<Filter>Source Files\soh\Enhancements\randomizer\3drando</Filter>
</ClCompile>
<ClCompile Include="soh\Enhancements\randomizer\3drando\fill.cpp">
<Filter>Source Files</Filter>
<Filter>Source Files\soh\Enhancements\randomizer\3drando</Filter>
</ClCompile>
<ClCompile Include="soh\Enhancements\randomizer\3drando\hints.cpp">
<Filter>Source Files</Filter>
<Filter>Source Files\soh\Enhancements\randomizer\3drando</Filter>
</ClCompile>
<ClCompile Include="soh\Enhancements\randomizer\3drando\hint_list.cpp">
<Filter>Source Files</Filter>
<Filter>Source Files\soh\Enhancements\randomizer\3drando</Filter>
</ClCompile>
<ClCompile Include="soh\Enhancements\randomizer\3drando\item.cpp">
<Filter>Source Files</Filter>
<Filter>Source Files\soh\Enhancements\randomizer\3drando</Filter>
</ClCompile>
<ClCompile Include="soh\Enhancements\randomizer\3drando\item_list.cpp">
<Filter>Source Files</Filter>
<Filter>Source Files\soh\Enhancements\randomizer\3drando</Filter>
</ClCompile>
<ClCompile Include="soh\Enhancements\randomizer\3drando\item_location.cpp">
<Filter>Source Files</Filter>
<Filter>Source Files\soh\Enhancements\randomizer\3drando</Filter>
</ClCompile>
<ClCompile Include="soh\Enhancements\randomizer\3drando\item_pool.cpp">
<Filter>Source Files</Filter>
<Filter>Source Files\soh\Enhancements\randomizer\3drando</Filter>
</ClCompile>
<ClCompile Include="soh\Enhancements\randomizer\3drando\location_access.cpp">
<Filter>Source Files</Filter>
<Filter>Source Files\soh\Enhancements\randomizer\3drando</Filter>
</ClCompile>
<ClCompile Include="soh\Enhancements\randomizer\3drando\logic.cpp">
<Filter>Source Files</Filter>
<Filter>Source Files\soh\Enhancements\randomizer\3drando</Filter>
</ClCompile>
<ClCompile Include="soh\Enhancements\randomizer\3drando\menu.cpp">
<Filter>Source Files</Filter>
<Filter>Source Files\soh\Enhancements\randomizer\3drando</Filter>
</ClCompile>
<ClCompile Include="soh\Enhancements\randomizer\3drando\music.cpp">
<Filter>Source Files</Filter>
<Filter>Source Files\soh\Enhancements\randomizer\3drando</Filter>
</ClCompile>
<ClCompile Include="soh\Enhancements\randomizer\3drando\patch.cpp">
<Filter>Source Files</Filter>
<Filter>Source Files\soh\Enhancements\randomizer\3drando</Filter>
</ClCompile>
<ClCompile Include="soh\Enhancements\randomizer\3drando\playthrough.cpp">
<Filter>Source Files</Filter>
<Filter>Source Files\soh\Enhancements\randomizer\3drando</Filter>
</ClCompile>
<ClCompile Include="soh\Enhancements\randomizer\3drando\preset.cpp">
<Filter>Source Files</Filter>
<Filter>Source Files\soh\Enhancements\randomizer\3drando</Filter>
</ClCompile>
<ClCompile Include="soh\Enhancements\randomizer\3drando\random.cpp">
<Filter>Source Files</Filter>
<Filter>Source Files\soh\Enhancements\randomizer\3drando</Filter>
</ClCompile>
<ClCompile Include="soh\Enhancements\randomizer\3drando\rando_main.cpp">
<Filter>Source Files</Filter>
<Filter>Source Files\soh\Enhancements\randomizer\3drando</Filter>
</ClCompile>
<ClCompile Include="soh\Enhancements\randomizer\3drando\settings.cpp">
<Filter>Source Files</Filter>
<Filter>Source Files\soh\Enhancements\randomizer\3drando</Filter>
</ClCompile>
<ClCompile Include="soh\Enhancements\randomizer\3drando\setting_descriptions.cpp">
<Filter>Source Files</Filter>
<Filter>Source Files\soh\Enhancements\randomizer\3drando</Filter>
</ClCompile>
<ClCompile Include="soh\Enhancements\randomizer\3drando\shops.cpp">
<Filter>Source Files</Filter>
<Filter>Source Files\soh\Enhancements\randomizer\3drando</Filter>
</ClCompile>
<ClCompile Include="soh\Enhancements\randomizer\3drando\sound_effects.cpp">
<Filter>Source Files</Filter>
<Filter>Source Files\soh\Enhancements\randomizer\3drando</Filter>
</ClCompile>
<ClCompile Include="soh\Enhancements\randomizer\3drando\spoiler_log.cpp">
<Filter>Source Files</Filter>
<Filter>Source Files\soh\Enhancements\randomizer\3drando</Filter>
</ClCompile>
<ClCompile Include="soh\Enhancements\randomizer\3drando\starting_inventory.cpp">
<Filter>Source Files</Filter>
<Filter>Source Files\soh\Enhancements\randomizer\3drando</Filter>
</ClCompile>
<ClCompile Include="soh\Enhancements\randomizer\3drando\tinyxml2.cpp">
<Filter>Source Files</Filter>
<Filter>Source Files\soh\Enhancements\randomizer\3drando</Filter>
</ClCompile>
<ClCompile Include="soh\Enhancements\randomizer\3drando\trial.cpp">
<Filter>Source Files</Filter>
<Filter>Source Files\soh\Enhancements\randomizer\3drando</Filter>
</ClCompile>
<ClCompile Include="soh\Enhancements\randomizer\3drando\utils.cpp">
<Filter>Source Files</Filter>
<Filter>Source Files\soh\Enhancements\randomizer\3drando</Filter>
</ClCompile>
<ClCompile Include="soh\Enhancements\randomizer\randomizer.cpp">
<Filter>Source Files</Filter>
<Filter>Source Files\soh\Enhancements\randomizer</Filter>
</ClCompile>
<ClCompile Include="soh\Enhancements\randomizer\randomizer.h">
<Filter>Header Files</Filter>
<Filter>Header Files\soh\Enhancements\randomizer</Filter>
</ClCompile>
<ClCompile Include="soh\Enhancements\gfx.c">
<Filter>Header Files\soh\Enhancements</Filter>
</ClCompile>
<ClCompile Include="soh\Enhancements\randomizer\randomizer_item_tracker.cpp">
<Filter>Source Files\src</Filter>
<Filter>Source Files\soh\Enhancements\randomizer</Filter>
</ClCompile>
<ClCompile Include="soh\Enhancements\custom_message\CustomMessageManager.cpp">
<Filter>Source Files\soh\Enhancements\custom-message</Filter>
@ -2393,9 +2411,6 @@
<ClInclude Include="include\bgm.h">
<Filter>Header Files\include</Filter>
</ClInclude>
<ClInclude Include="include\color.h">
<Filter>Header Files\include</Filter>
</ClInclude>
<ClInclude Include="include\command_macros_base.h">
<Filter>Header Files\include</Filter>
</ClInclude>
@ -3957,118 +3972,118 @@
<Filter>Header Files\include</Filter>
</ClInclude>
<ClInclude Include="soh\Enhancements\randomizer\3drando\category.hpp">
<Filter>Header Files</Filter>
<Filter>Header Files\soh\Enhancements\randomizer\3drando</Filter>
</ClInclude>
<ClInclude Include="soh\Enhancements\randomizer\3drando\cosmetics.hpp">
<Filter>Header Files</Filter>
<Filter>Header Files\soh\Enhancements\randomizer\3drando</Filter>
</ClInclude>
<ClInclude Include="soh\Enhancements\randomizer\3drando\custom_messages.hpp">
<Filter>Header Files</Filter>
<Filter>Header Files\soh\Enhancements\randomizer\3drando</Filter>
</ClInclude>
<ClInclude Include="soh\Enhancements\randomizer\3drando\debug.hpp">
<Filter>Header Files</Filter>
<Filter>Header Files\soh\Enhancements\randomizer\3drando</Filter>
</ClInclude>
<ClInclude Include="soh\Enhancements\randomizer\3drando\dungeon.hpp">
<Filter>Header Files</Filter>
<Filter>Header Files\soh\Enhancements\randomizer\3drando</Filter>
</ClInclude>
<ClInclude Include="soh\Enhancements\randomizer\3drando\entrance.hpp">
<Filter>Header Files</Filter>
<Filter>Header Files\soh\Enhancements\randomizer\3drando</Filter>
</ClInclude>
<ClInclude Include="soh\Enhancements\randomizer\3drando\fill.hpp">
<Filter>Header Files</Filter>
<Filter>Header Files\soh\Enhancements\randomizer\3drando</Filter>
</ClInclude>
<ClInclude Include="soh\Enhancements\randomizer\3drando\hints.hpp">
<Filter>Header Files</Filter>
<Filter>Header Files\soh\Enhancements\randomizer\3drando</Filter>
</ClInclude>
<ClInclude Include="soh\Enhancements\randomizer\3drando\hint_list.hpp">
<Filter>Header Files</Filter>
<Filter>Header Files\soh\Enhancements\randomizer\3drando</Filter>
</ClInclude>
<ClInclude Include="soh\Enhancements\randomizer\3drando\item.hpp">
<Filter>Header Files</Filter>
<Filter>Header Files\soh\Enhancements\randomizer\3drando</Filter>
</ClInclude>
<ClInclude Include="soh\Enhancements\randomizer\3drando\item_list.hpp">
<Filter>Header Files</Filter>
<Filter>Header Files\soh\Enhancements\randomizer\3drando</Filter>
</ClInclude>
<ClInclude Include="soh\Enhancements\randomizer\3drando\item_location.hpp">
<Filter>Header Files</Filter>
<Filter>Header Files\soh\Enhancements\randomizer\3drando</Filter>
</ClInclude>
<ClInclude Include="soh\Enhancements\randomizer\3drando\item_pool.hpp">
<Filter>Header Files</Filter>
<Filter>Header Files\soh\Enhancements\randomizer\3drando</Filter>
</ClInclude>
<ClInclude Include="soh\Enhancements\randomizer\3drando\keys.hpp">
<Filter>Header Files</Filter>
<Filter>Header Files\soh\Enhancements\randomizer\3drando</Filter>
</ClInclude>
<ClInclude Include="soh\Enhancements\randomizer\3drando\location_access.hpp">
<Filter>Header Files</Filter>
<Filter>Header Files\soh\Enhancements\randomizer\3drando</Filter>
</ClInclude>
<ClInclude Include="soh\Enhancements\randomizer\3drando\logic.hpp">
<Filter>Header Files</Filter>
<Filter>Header Files\soh\Enhancements\randomizer\3drando</Filter>
</ClInclude>
<ClInclude Include="soh\Enhancements\randomizer\3drando\menu.hpp">
<Filter>Header Files</Filter>
<Filter>Header Files\soh\Enhancements\randomizer\3drando</Filter>
</ClInclude>
<ClInclude Include="soh\Enhancements\randomizer\3drando\music.hpp">
<Filter>Header Files</Filter>
<Filter>Header Files\soh\Enhancements\randomizer\3drando</Filter>
</ClInclude>
<ClInclude Include="soh\Enhancements\randomizer\3drando\patch.hpp">
<Filter>Header Files</Filter>
<Filter>Header Files\soh\Enhancements\randomizer\3drando</Filter>
</ClInclude>
<ClInclude Include="soh\Enhancements\randomizer\3drando\playthrough.hpp">
<Filter>Header Files</Filter>
<Filter>Header Files\soh\Enhancements\randomizer\3drando</Filter>
</ClInclude>
<ClInclude Include="soh\Enhancements\randomizer\3drando\pool_functions.hpp">
<Filter>Header Files</Filter>
<Filter>Header Files\soh\Enhancements\randomizer\3drando</Filter>
</ClInclude>
<ClInclude Include="soh\Enhancements\randomizer\3drando\preset.hpp">
<Filter>Header Files</Filter>
<Filter>Header Files\soh\Enhancements\randomizer\3drando</Filter>
</ClInclude>
<ClInclude Include="soh\Enhancements\randomizer\3drando\random.hpp">
<Filter>Header Files</Filter>
<Filter>Header Files\soh\Enhancements\randomizer\3drando</Filter>
</ClInclude>
<ClInclude Include="soh\Enhancements\randomizer\3drando\randomizer.hpp">
<Filter>Header Files</Filter>
<Filter>Header Files\soh\Enhancements\randomizer\3drando</Filter>
</ClInclude>
<ClInclude Include="soh\Enhancements\randomizer\3drando\rando_main.hpp">
<Filter>Header Files</Filter>
<Filter>Header Files\soh\Enhancements\randomizer\3drando</Filter>
</ClInclude>
<ClInclude Include="soh\Enhancements\randomizer\3drando\settings.hpp">
<Filter>Header Files</Filter>
<Filter>Header Files\soh\Enhancements\randomizer\3drando</Filter>
</ClInclude>
<ClInclude Include="soh\Enhancements\randomizer\3drando\setting_descriptions.hpp">
<Filter>Header Files</Filter>
<Filter>Header Files\soh\Enhancements\randomizer\3drando</Filter>
</ClInclude>
<ClInclude Include="soh\Enhancements\randomizer\3drando\shops.hpp">
<Filter>Header Files</Filter>
<Filter>Header Files\soh\Enhancements\randomizer\3drando</Filter>
</ClInclude>
<ClInclude Include="soh\Enhancements\randomizer\3drando\sound_effects.hpp">
<Filter>Header Files</Filter>
<Filter>Header Files\soh\Enhancements\randomizer\3drando</Filter>
</ClInclude>
<ClInclude Include="soh\Enhancements\randomizer\3drando\spoiler_log.hpp">
<Filter>Header Files</Filter>
<Filter>Header Files\soh\Enhancements\randomizer\3drando</Filter>
</ClInclude>
<ClInclude Include="soh\Enhancements\randomizer\3drando\starting_inventory.hpp">
<Filter>Header Files</Filter>
<Filter>Header Files\soh\Enhancements\randomizer\3drando</Filter>
</ClInclude>
<ClInclude Include="soh\Enhancements\randomizer\3drando\text.hpp">
<Filter>Header Files</Filter>
<Filter>Header Files\soh\Enhancements\randomizer\3drando</Filter>
</ClInclude>
<ClInclude Include="soh\Enhancements\randomizer\3drando\tinyxml2.h">
<Filter>Header Files</Filter>
<Filter>Header Files\soh\Enhancements\randomizer\3drando</Filter>
</ClInclude>
<ClInclude Include="soh\Enhancements\randomizer\3drando\trial.hpp">
<Filter>Header Files</Filter>
<Filter>Header Files\soh\Enhancements\randomizer\3drando</Filter>
</ClInclude>
<ClInclude Include="soh\Enhancements\randomizer\3drando\utils.hpp">
<Filter>Header Files</Filter>
<Filter>Header Files\soh\Enhancements\randomizer\3drando</Filter>
</ClInclude>
<ClInclude Include="soh\Enhancements\randomizer\randomizerTypes.h">
<Filter>Header Files</Filter>
<Filter>Header Files\soh\Enhancements\randomizer</Filter>
</ClInclude>
<ClInclude Include="soh\Enhancements\gfx.h">
<Filter>Header Files\soh\Enhancements</Filter>
</ClInclude>
<ClInclude Include="soh\Enhancements\randomizer\randomizer_item_tracker.h">
<Filter>Source Files\src</Filter>
<Filter>Header Files\soh\Enhancements\randomizer</Filter>
</ClInclude>
<ClInclude Include="soh\Enhancements\custom_message\CustomMessageManager.h">
<Filter>Header Files\soh\Enhancements\custom-message</Filter>

View File

@ -6668,10 +6668,12 @@
"$(inherited)",
"-DENABLE_OPENGL",
"-DNDEBUG",
"-DSPDLOG_ACTIVE_LEVEL=0",
);
OTHER_CPLUSPLUSFLAGS = (
"-DENABLE_OPENGL",
"-DNDEBUG",
"-DSPDLOG_ACTIVE_LEVEL=0",
);
OTHER_LIBTOOLFLAGS = "";
OTHER_REZFLAGS = "";
@ -6728,10 +6730,12 @@
"$(inherited)",
"-DENABLE_OPENGL",
"-D_DEBUG",
"-DSPDLOG_ACTIVE_LEVEL=0",
);
OTHER_CPLUSPLUSFLAGS = (
"-DENABLE_OPENGL",
"-D_DEBUG",
"-DSPDLOG_ACTIVE_LEVEL=0",
);
OTHER_LIBTOOLFLAGS = "";
OTHER_REZFLAGS = "";
@ -6842,7 +6846,6 @@
"-DENABLE_OPENGL",
"-D_CRT_SECURE_NO_WARNINGS",
"-D_CONSOLE",
"-DSPDLOG_ACTIVE_LEVEL=0",
"-DNDEBUG",
);
OTHER_LDFLAGS = (
@ -7031,7 +7034,6 @@
"-DENABLE_OPENGL",
"-D_CRT_SECURE_NO_WARNINGS",
"-D_CONSOLE",
"-DSPDLOG_ACTIVE_LEVEL=0",
"-D_DEBUG",
);
OTHER_LDFLAGS = (

View File

@ -0,0 +1,78 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1400"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "6D85CFA44008444FB26F04BA"
BuildableName = "soh.app"
BlueprintName = "soh"
ReferencedContainer = "container:soh.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES">
<Testables>
</Testables>
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
allowLocationSimulation = "YES">
<BuildableProductRunnable
runnableDebuggingMode = "0">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "6D85CFA44008444FB26F04BA"
BuildableName = "soh.app"
BlueprintName = "soh"
ReferencedContainer = "container:soh.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
debugDocumentVersioning = "YES">
<BuildableProductRunnable
runnableDebuggingMode = "0">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "6D85CFA44008444FB26F04BA"
BuildableName = "soh.app"
BlueprintName = "soh"
ReferencedContainer = "container:soh.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>

View File

@ -229,28 +229,28 @@ void Draw_Npcs(){
ImGui::TableSetupColumn("Outer colors##Navi", ImGuiTableColumnFlags_WidthStretch | ImGuiTableColumnFlags_IndentEnable | ImGuiTableColumnFlags_NoSort, TablesCellsWidth/2);
Table_InitHeader();
Draw_HelpIcon("Inner color for Navi (idle flying around)");
SohImGui::EnhancementColor("Navi Idle (Primary)", "gNavi_Idle_Inner_", navi_idle_i_col, ImVec4(255, 255, 255, 255), false);
SohImGui::EnhancementColor("Navi Idle (Primary)", "gNavi_Idle_Inner", navi_idle_i_col, ImVec4(255, 255, 255, 255), false);
Table_NextCol();
Draw_HelpIcon("Outer color for Navi (idle flying around)");
SohImGui::EnhancementColor("Navi Idle (Secondary)", "gNavi_Idle_Outer_", navi_idle_o_col, ImVec4(0, 0, 255, 255), false);
SohImGui::EnhancementColor("Navi Idle (Secondary)", "gNavi_Idle_Outer", navi_idle_o_col, ImVec4(0, 0, 255, 255), false);
Table_NextLine();
Draw_HelpIcon("Inner color for Navi (when Navi fly around NPCs)");
SohImGui::EnhancementColor("Navi NPC (Primary)", "gNavi_NPC_Inner_", navi_npc_i_col, ImVec4(150, 150, 255, 255), false);
SohImGui::EnhancementColor("Navi NPC (Primary)", "gNavi_NPC_Inner", navi_npc_i_col, ImVec4(150, 150, 255, 255), false);
Table_NextCol();
Draw_HelpIcon("Outer color for Navi (when Navi fly around NPCs)");
SohImGui::EnhancementColor("Navi NPC (Secondary)", "gNavi_NPC_Outer_", navi_npc_o_col, ImVec4(150, 150, 255, 255), false);
SohImGui::EnhancementColor("Navi NPC (Secondary)", "gNavi_NPC_Outer", navi_npc_o_col, ImVec4(150, 150, 255, 255), false);
Table_NextLine();
Draw_HelpIcon("Inner color for Navi (when Navi fly around Enemies or Bosses)");
SohImGui::EnhancementColor("Navi Enemy (Primary)", "gNavi_Enemy_Inner_", navi_enemy_i_col, ImVec4(255, 255, 0, 255), false);
SohImGui::EnhancementColor("Navi Enemy", "gNavi_Enemy_Inner", navi_enemy_i_col, ImVec4(255, 255, 0, 255), false);
Table_NextCol();
Draw_HelpIcon("Outer color for Navi (when Navi fly around Enemies or Bosses)");
SohImGui::EnhancementColor("Navi Enemy (Secondary)", "gNavi_Enemy_Outer_", navi_enemy_o_col, ImVec4(220, 155, 0, 255), false);
SohImGui::EnhancementColor("Navi Enemy (Secondary)", "gNavi_Enemy_Outer", navi_enemy_o_col, ImVec4(220, 155, 0, 255), false);
Table_NextLine();
Draw_HelpIcon("Inner color for Navi (when Navi fly around props (signs etc))");
SohImGui::EnhancementColor("Navi Prop (Primary)", "gNavi_Prop_Inner_", navi_prop_i_col, ImVec4(0, 255, 0, 255), false);
SohImGui::EnhancementColor("Navi Prop (Primary)", "gNavi_Prop_Inner", navi_prop_i_col, ImVec4(0, 255, 0, 255), false);
Table_NextCol();
Draw_HelpIcon("Outer color for Navi (when Navi fly around props (signs etc))");
SohImGui::EnhancementColor("Navi Prop (Secondary)", "gNavi_Prop_Outer_", navi_prop_o_col, ImVec4(0, 255, 0, 255), false);
SohImGui::EnhancementColor("Navi Prop (Secondary)", "gNavi_Prop_Outer", navi_prop_o_col, ImVec4(0, 255, 0, 255), false);
ImGui::EndTable();
}
SohImGui::EnhancementCheckbox("Custom colors for Keese", "gUseKeeseCol");

View File

@ -375,11 +375,16 @@ static bool StateSlotSelectHandler(const std::vector<std::string>& args) {
#define VARTYPE_INTEGER 0
#define VARTYPE_FLOAT 1
#define VARTYPE_STRING 2
#define VARTYPE_RGBA 3
static int CheckVarType(const std::string& input)
{
int result = VARTYPE_STRING;
if (input[0] == '#') {
return VARTYPE_RGBA;
}
for (size_t i = 0; i < input.size(); i++)
{
if (!(std::isdigit(input[i]) || input[i] == '.'))
@ -407,7 +412,17 @@ static bool SetCVarHandler(const std::vector<std::string>& args) {
if (vType == VARTYPE_STRING)
CVar_SetString(args[1].c_str(), args[2].c_str());
else if (vType == VARTYPE_FLOAT)
CVar_SetFloat(args[1].c_str(), std::stof(args[2]));
CVar_SetFloat((char*)args[1].c_str(), std::stof(args[2]));
else if (vType == VARTYPE_RGBA)
{
uint32_t val = std::stoul(&args[2].c_str()[1], nullptr, 16);
Color_RGBA8 clr;
clr.r = val >> 24;
clr.g = val >> 16;
clr.b = val >> 8;
clr.a = val & 0xFF;
CVar_SetRGBA((char*)args[1].c_str(), clr);
}
else
CVar_SetS32(args[1].c_str(), std::stoi(args[2]));
@ -426,12 +441,14 @@ static bool GetCVarHandler(const std::vector<std::string>& args) {
if (cvar != nullptr)
{
if (cvar->type == CVAR_TYPE_S32)
if (cvar->type == CVarType::S32)
INFO("[SOH] Variable %s is %i", args[1].c_str(), cvar->value.valueS32);
else if (cvar->type == CVAR_TYPE_FLOAT)
else if (cvar->type == CVarType::Float)
INFO("[SOH] Variable %s is %f", args[1].c_str(), cvar->value.valueFloat);
else if (cvar->type == CVAR_TYPE_STRING)
else if (cvar->type == CVarType::String)
INFO("[SOH] Variable %s is %s", args[1].c_str(), cvar->value.valueStr);
else if (cvar->type == CVarType::RGBA)
INFO("[SOH] Variable %s is %08X", args[1].c_str(), cvar->value.valueRGBA);
}
else
{
@ -508,6 +525,22 @@ void DebugConsole_LoadLegacyCVars() {
std::vector<std::string> cfg = StringHelper::Split(line, " = ");
if (line.empty()) continue;
if (cfg.size() < 2) continue;
if (cfg[1].find("\"") == std::string::npos && (cfg[1].find("#") != std::string::npos))
{
std::string value(cfg[1]);
value.erase(std::remove_if(value.begin(), value.end(), [](char c) { return c == '#'; }), value.end());
auto splitTest = StringHelper::Split(value, "\r")[0];
uint32_t val = std::stoul(splitTest, nullptr, 16);
Color_RGBA8 clr;
clr.r = val >> 24;
clr.g = val >> 16;
clr.b = val >> 8;
clr.a = val & 0xFF;
CVar_SetRGBA(cfg[0].c_str(), clr);
}
if (cfg[1].find("\"") != std::string::npos) {
std::string value(cfg[1]);
value.erase(std::remove(value.begin(), value.end(), '\"'), value.end());
@ -534,6 +567,16 @@ void DebugConsole_LoadCVars() {
auto value = item.value();
switch (value.type()) {
case nlohmann::detail::value_t::array:
break;
case nlohmann::detail::value_t::object:
if (value["Type"].get<std::string>() == mercuryRGBAObjectType) {
Color_RGBA8 clr;
clr.r = value["R"].get<uint8_t>();
clr.g = value["G"].get<uint8_t>();
clr.b = value["B"].get<uint8_t>();
clr.a = value["A"].get<uint8_t>();
}
break;
case nlohmann::detail::value_t::string:
CVar_SetString(item.key().c_str(), value.get<std::string>().c_str());
@ -565,12 +608,22 @@ void DebugConsole_SaveCVars()
for (const auto &cvar : cvars) {
const std::string key = StringHelper::Sprintf("CVars.%s", cvar.first.c_str());
if (cvar.second->type == CVAR_TYPE_STRING && cvar.second->value.valueStr != nullptr)
if (cvar.second->type == CVarType::String && cvar.second->value.valueStr != nullptr)
pConf->setString(key, std::string(cvar.second->value.valueStr));
else if (cvar.second->type == CVAR_TYPE_S32)
else if (cvar.second->type == CVarType::S32)
pConf->setInt(key, cvar.second->value.valueS32);
else if (cvar.second->type == CVAR_TYPE_FLOAT)
else if (cvar.second->type == CVarType::Float)
pConf->setFloat(key, cvar.second->value.valueFloat);
else if (cvar.second->type == CVarType::RGBA)
{
auto keyStr = key.c_str();
Color_RGBA8 clr = cvar.second->value.valueRGBA;
pConf->setUInt(StringHelper::Sprintf("%s.R", keyStr), clr.r);
pConf->setUInt(StringHelper::Sprintf("%s.G", keyStr), clr.r);
pConf->setUInt(StringHelper::Sprintf("%s.B", keyStr), clr.r);
pConf->setUInt(StringHelper::Sprintf("%s.A", keyStr), clr.r);
pConf->setString(StringHelper::Sprintf("%s.Type", keyStr), mercuryRGBAObjectType);
}
}
pConf->save();

View File

@ -1,10 +1,11 @@
#include "ImGuiHelpers.h"
#include "../../../../libultraship/libultraship/ImGuiImpl.h"
// Adds a text tooltip for the previous ImGui item
void SetLastItemHoverText(const std::string& text) {
if (ImGui::IsItemHovered()) {
ImGui::BeginTooltip();
ImGui::Text(text.c_str());
ImGui::Text(SohImGui::BreakTooltip(text, 60).c_str());
ImGui::EndTooltip();
}
}
@ -15,7 +16,7 @@ void InsertHelpHoverText(const std::string& text) {
ImGui::TextColored(ImVec4(0.7f, 0.7f, 0.7f, 1.0f), "?");
if (ImGui::IsItemHovered()) {
ImGui::BeginTooltip();
ImGui::Text(text.c_str());
ImGui::Text(SohImGui::BreakTooltip(text, 60).c_str());
ImGui::EndTooltip();
}
}

View File

@ -1001,7 +1001,7 @@ void DrawFlagsTab() {
// Draws a combo that lets you choose and upgrade value from a drop-down of text values
void DrawUpgrade(const std::string& categoryName, int32_t categoryId, const std::vector<std::string>& names) {
ImGui::Text(categoryName.c_str());
ImGui::Text("%s", categoryName.c_str());
ImGui::SameLine();
ImGui::PushID(categoryName.c_str());
if (ImGui::BeginCombo("##upgrade", names[CUR_UPG_VALUE(categoryId)].c_str())) {
@ -1435,7 +1435,7 @@ void DrawPlayerTab() {
InsertHelpHoverText("Link's speed along the Y plane. Caps at -20");
ImGui::InputScalar("Wall Height", ImGuiDataType_Float, &player->wallHeight);
InsertHelpHoverText("\"height used to determine whether link can climb or grab a ledge at the top\"");
InsertHelpHoverText("Height used to determine whether Link can climb or grab a ledge at the top");
ImGui::InputScalar("Invincibility Timer", ImGuiDataType_S8, &player->invincibilityTimer);
InsertHelpHoverText("Can't take damage while this is nonzero");

View File

@ -2102,7 +2102,7 @@ void HintTable_Init() {
hintTable[GANON_LINE07] = HintText::GanonLine({
//obscure text
Text{"What about Zelda makes you think she'd be a better ruler than I?^I saved Lon Lon Ranch,&fed the hungry,&and my castle floats.",
Text{"What about Zelda makes you think&she'd be a better ruler than I?^I saved Lon Lon Ranch,&fed the hungry,&and my castle floats.",
/*french*/"Zelda ne sera jamais un meilleur monarque que moi!^J'ai un château volant, mes sujets sont des belles amazones... et mes Moblins sont clairement plus puissants que jamais!",
/*spanish*/"¿Qué te hace pensar que Zelda gobierna mejor que yo?^Yo he salvado el Rancho Lon Lon,&he alimentado a los hambrientos&y hasta hago que mi castillo flote."},
});

View File

@ -579,7 +579,7 @@ std::string AutoFormatHintTextString(std::string unformattedHintTextString) {
bool needsAutomaicNewlines = true;
if (textStr == "Erreur 0x69a504:&Traduction manquante^C'est de la faute à Purple Hato!&J'vous jure!" ||
textStr == "Mon très cher @:&Viens vite au château, je t'ai préparé&un délicieux gâteau...^À bientôt, Princesse Zelda" ||
textStr == "What about Zelda makes you think she'd be a better ruler than I?^I saved Lon Lon Ranch,&fed the hungry,&and my castle floats." ||
textStr == "What about Zelda makes you think&she'd be a better ruler than I?^I saved Lon Lon Ranch,&fed the hungry,&and my castle floats." ||
textStr == "Many tricks are up my sleeve,&to save yourself&you'd better leave!" ||
textStr == "I've learned this spell,&it's really neat,&I'll keep it later&for your treat!" ||
textStr == "Sale petit garnement,&tu fais erreur!&C'est maintenant que marque&ta dernière heure!" ||

View File

@ -3518,21 +3518,21 @@ void DrawRandoEditor(bool& open) {
switch (CVar_GetS32("gRandomizeForest", 1)) {
case 1:
InsertHelpHoverText("Mido no longer blocks the path to the Deku Tree\n"
"The Kokiri boy no longer blocks the path\nout of the forest.");
"The Kokiri boy no longer blocks the path out of the forest.");
break;
case 2:
InsertHelpHoverText(
"The Kokiri boy no longer blocks the path out of the forest\nMido "
"still blocks the path to the Deku\nTree, requiring the Kokiri Sword "
"and a Deku Shield to\naccess the Deku Tree.");
"still blocks the path to the Deku Tree, requiring the Kokiri Sword "
"and a Deku Shield to access the Deku Tree.");
break;
case 0:
InsertHelpHoverText(
"Beating Deku Tree is logically required to leave\nthe forest area "
"(Kokiri Forest / Loost Woods / Sacred\nForest Meadow / Deku Tree) "
"while the Kokiri Sword\nand a Deku Shield are required to access the "
"Deku\nTree Items needed for this will be guaranteed\ninside the "
"forest area.\nThis settins is incompatible with starting as adult.");
"Beating Deku Tree is logically required to leave the forest area "
"(Kokiri Forest / Lost Woods / Sacred Forest Meadow / Deku Tree) "
"while the Kokiri Sword and a Deku Shield are required to access the "
"Deku Tree\nItems needed for this will be guaranteed inside the "
"forest area.\nThis setting is incompatible with starting as adult.");
break;
}
SohImGui::EnhancementCombobox("gRandomizeForest", randoForest, 3, 1);
@ -3542,13 +3542,13 @@ void DrawRandoEditor(bool& open) {
switch (CVar_GetS32("gRandomizeKakarikoGate", 0)) {
case 0:
InsertHelpHoverText(
"The gate and the Happy Mask Shop both remain\nclosed until showing "
"Zelda's Letter to the guard\nin Kakariko.");
"The gate and the Happy Mask Shop both remain closed until showing "
"Zelda's Letter to the guard in Kakariko.");
break;
case 1:
InsertHelpHoverText(
"The gate is always open instead of needing\nZelda's Letter.\nThe Happy Mask Shop "
"opens upon obtaining \n Zelda's Letter without needing to show\nit to the guard.");
"The gate is always open instead of needing Zelda's Letter.\nThe Happy Mask Shop "
"opens upon obtaining Zelda's Letter without needing to show it to the guard.");
break;
}
SohImGui::EnhancementCombobox("gRandomizeKakarikoGate", randoKakarikoGate, 2, 1);
@ -3559,16 +3559,16 @@ void DrawRandoEditor(bool& open) {
switch (CVar_GetS32("gRandomizeDoorOfTime", 0)) {
case 0:
InsertHelpHoverText(
"The Door of Time starts opened instead of needing\nto play the Song of Time.");
"The Door of Time starts opened instead of needing to play the Song of Time.");
break;
case 1:
InsertHelpHoverText(
"Only an Ocarina and the Song of Time need to be\nfound to open the Door of Time.");
"Only an Ocarina and the Song of Time need to be found to open the Door of Time.");
break;
case 2:
InsertHelpHoverText(
"The Ocarina of Time, the Song of Time and\nall Spiritual Stones need to "
"be found to\nopen the Door of Time.");
"The Ocarina of Time, the Song of Time and all Spiritual Stones need to "
"be found to open the Door of Time.");
break;
}
SohImGui::EnhancementCombobox("gRandomizeDoorOfTime", randoDoorOfTime, 3, 0);
@ -3580,17 +3580,17 @@ void DrawRandoEditor(bool& open) {
case 0:
InsertHelpHoverText(
"King Zora obstructs the way to Zora's Fountain.\nRuto's Letter must be "
"shown as child in order to\nmove him from both eras.");
"shown as child in order to move him from both eras.");
break;
case 1:
InsertHelpHoverText(
"King Zora is always moved in the adult era.\nThis means Ruto's Letter is "
"only required to\naccess Zora's fountain as child.");
"only required to access Zora's fountain as child.");
break;
case 2:
InsertHelpHoverText(
"King Zora starts as moved in both the child and\nadult eras.\nThis also "
"removes Ruto's Letter from the\npool since it can't be used.");
"King Zora starts as moved in both the child and adult eras.\nThis also "
"removes Ruto's Letter from the pool since it can't be used.");
break;
}
SohImGui::EnhancementCombobox("gRandomizeZorasFountain", randoZorasFountain, 3, 0);
@ -3607,9 +3607,9 @@ void DrawRandoEditor(bool& open) {
break;
case 2:
InsertHelpHoverText(
"The carpenters are rescued from the start of the\ngame and if \"Shuffle "
"Gerudo Card\" is disabled,\nthe player starts with the Gerudo Card in "
"the\ninventory allowing access to Gerudo Training\nGrounds.");
"The carpenters are rescued from the start of the game and if \"Shuffle "
"Gerudo Card\" is disabled, the player starts with the Gerudo Card in "
"the inventory allowing access to Gerudo Training Grounds.");
break;
}
SohImGui::EnhancementCombobox("gRandomizeGerudoFortress", randoGerudoFortress, 3, 1);
@ -3620,41 +3620,40 @@ void DrawRandoEditor(bool& open) {
SohImGui::EnhancementCombobox("gRandomizeRainbowBridge", randoRainbowBridge, 7, 3);
switch (CVar_GetS32("gRandomizeRainbowBridge", 3)) {
case 1:
InsertHelpHoverText("The Rainbow Bridge requires Shadow and Spirit\nMedallions as well "
InsertHelpHoverText("The Rainbow Bridge requires Shadow and Spirit Medallions as well "
"as Light Arrows.");
break;
case 2:
InsertHelpHoverText("The Rainbow Bridge requires collecting a\nconfigurable number of "
InsertHelpHoverText("The Rainbow Bridge requires collecting a configurable number of "
"Spiritual Stones.");
SohImGui::EnhancementSliderInt("Stone Count: %d", "##RandoStoneCount",
"gRandomizeStoneCount", 0, 3, "");
SetLastItemHoverText(
"Sets the number of Spiritual Stones required to\nspawn the Rainbow Bridge.");
"Sets the number of Spiritual Stones required to spawn the Rainbow Bridge.");
break;
case 3:
SohImGui::EnhancementSliderInt("Medallion Count: %d", "##RandoMedallionCount",
"gRandomizeMedallionCount", 0, 6, "", 6);
SetLastItemHoverText(
"The Rainbow Bridge requires collecting a\nconfigurable number of Medallions.");
"The Rainbow Bridge requires collecting a configurable number of Medallions.");
break;
case 4:
SohImGui::EnhancementSliderInt("Reward Count: %d", "##RandoRewardCount",
"gRandomizeRewardCount", 0, 9, "");
SetLastItemHoverText("The Rainbow Bridge requires collecting a\nconfigurable number of "
SetLastItemHoverText("The Rainbow Bridge requires collecting a configurable number of "
"Dungeon Rewards.");
break;
case 5:
SohImGui::EnhancementSliderInt("Dungeon Count: %d", "##RandoDungeonCount",
"gRandomizeDungeonCount", 0, 8, "");
SetLastItemHoverText(
"The Rainbow Bridge requires completing a\nconfigurable number of "
"Dungeons.\n\nDungeons "
"are considered complete when Link steps\ninto the blue warp at the end of them.");
"The Rainbow Bridge requires completing a configurable number of Dungeons.\nDungeons "
"are considered complete when Link steps into the blue warp at the end of them.");
break;
case 6:
SohImGui::EnhancementSliderInt("Token Count: %d", "##RandoTokenCount",
"gRandomizeTokenCount", 0, 100, "");
SetLastItemHoverText("The Rainbow Bridge requires collecting a\nconfigurable number of "
SetLastItemHoverText("The Rainbow Bridge requires collecting a configurable number of "
"Gold Skulltula Tokens.");
break;
}
@ -3663,17 +3662,17 @@ void DrawRandoEditor(bool& open) {
// Random Ganon's Trials
/*
ImGui::Text("Random Ganon's Trials");
InsertHelpHoverText("Sets a random number or required trials to enter\nGanon's Tower.");
InsertHelpHoverText("Sets a random number or required trials to enter Ganon's Tower.");
SohImGui::EnhancementCombobox("gRandomizeGanonTrial", randoGanonsTrial, 2, 0);
if (CVar_GetS32("gRandomizeGanonTrial", 0) == 0) {
*/
//SohImGui::EnhancementSliderInt("Ganon's Trial Count: %d", "##RandoTrialCount",
// "gRandomizeGanonTrialCount", 0, 6, "");
//InsertHelpHoverText("Set the number of trials required to enter\nGanon's Tower.");
//InsertHelpHoverText("Set the number of trials required to enter Ganon's Tower.");
// RANDTODO: Switch back to slider when pre-completing some of Ganon's Trials is properly implemnted.
SohImGui::EnhancementCheckbox("Skip Ganon's Trials", "gRandomizeGanonTrialCount");
InsertHelpHoverText(
"Sets whether or not Ganon's Castle Trials are required\nto enter Ganon's Tower.");
"Sets whether or not Ganon's Castle Trials are required to enter Ganon's Tower.");
// }
ImGui::Separator();
@ -3692,9 +3691,9 @@ void DrawRandoEditor(bool& open) {
// Starting Age
// ImGui::Text("Starting Age");
// InsertHelpHoverText(
// "Choose which age Link will start as.\n\nStarting as adult means you start with the "
// "Master\nSword "
// "in your inventory.\n\nOnly the child option is compatible with Closed\nForest.");
// "Choose which age Link will start as.\nStarting as adult means you start with the "
// "Master Sword in your inventory.\nOnly the child option is compatible with "
// "Closed Forest.");
// SohImGui::EnhancementCombobox("gRandomizeStartingAge", randoStartingAge, 3, 0);
// ImGui::Separator();
@ -3702,31 +3701,26 @@ void DrawRandoEditor(bool& open) {
// Shuffle Entrances
// ImGui::Text("Shuffle Entrances");
// InsertHelpHoverText("Shuffle where the entrances between areas lead to.\n"
// "If turned on, select which kinds of entrances you\n"
// "want shuffled in the options below. Note that some\n"
// "types of entrances can have widly varying\ngeneration times.");
// "If turned on, select which kinds of entrances you "
// "want shuffled in the options below.\n Note that some "
// "types of entrances can have widly varying generation times.");
// SohImGui::EnhancementCombobox("gRandomizeShuffleEntrances", randoShuffleEntrances, 2, 0);
// if (CVar_GetS32("gRandomizeShuffleEntrances", 0) == 1) {
// ImGui::Indent();
// ImGui::Text("Shuffle Dungeons Entrances");
// InsertHelpHoverText(
// "Shuffle the pool of dungeon entrances, including\nBottom of the Well, Ice caven and "
// "Gerudo\n"
// "Training Grounds However, Ganon's Caslte is not\nshuffled.\n\nAdditionally, the "
// "entrance "
// "of "
// "Deku Tree, Fire\nTemple and Bottom of the Well are opened for both\nadult and child.");
// "Shuffle the pool of dungeon entrances, including Bottom of the Well, Ice Cavern and "
// "Gerudo Training Grounds\nGanon's Castle is not shuffled.\nAdditionally, the entrance "
// "of Deku Tree, Fire Temple and Bottom of the Well are open for both adult and child.");
// SohImGui::EnhancementCombobox("gRandomizeShuffleDungeonsEntrances",
// randoShuffleDungeonsEntrances, 2, 0);
// ImGui::Text("Shuffle Overworld Entrances");
// InsertHelpHoverText(
// "Shuffle the pool of Overworld entrances, which\ncorresponds to almost all loading "
// "zones "
// "between\nOverworld areas.\n\nSome entrances are unshuffled to avoid issues:\n- Hyrule "
// "Castle "
// "Courtyard and Garden entrance\n- Both Market Back Alley entrances\n- Gerudo Valley to "
// "Lake "
// "Hylia (unless entrances\nare decoupled).");
// "Shuffle the pool of Overworld entrances, which corresponds to almost all loading "
// "zones between Overworld areas.\nSome entrances are unshuffled to avoid issues:\n"
// "- Hyrule Castle Courtyard and Garden entrance\n"
// "- Both Market Back Alley entrances\n"
// "- Gerudo Valley to Lake Hylia (unless entrances are decoupled)");
// SohImGui::EnhancementCombobox("gRandomizeShuffleOverworldEntrances",
// randoShuffleOverworldEntrances, 2, 0);
// ImGui::Text("Shuffle Interiors Entrances");
@ -3735,8 +3729,8 @@ void DrawRandoEditor(bool& open) {
// randoShuffleInteriorsEntrances, 2, 0);
// ImGui::Text("Shuffle Grottos Entrances");
// InsertHelpHoverText(
// "Shuffle the pool of grotto entrances, including\nall graves, small Fairy "
// "fountains and the Lost\nWoods Stage.");
// "Shuffle the pool of grotto entrances, including all graves, small Fairy "
// "fountains and the Lost Woods Stage.");
// SohImGui::EnhancementCombobox("gRandomizeShuffleGrottosEntrances",
// randoShuffleGrottosEntrances, 2, 0);
// ImGui::Unindent();
@ -3747,9 +3741,8 @@ void DrawRandoEditor(bool& open) {
// Bombchus in Logic
// ImGui::Text("Bombchus in Logic");
// InsertHelpHoverText(
// "Bombchus are properly considered in logic.\nThey can be replenished in shops "
// "or trough\nbombchu "
// "drops, if those are enabled.\nBombchu Bowling is opened by bombchus.");
// "Bombchus are properly considered in logic.\nThey can be replenished in shops or "
// "through bombchu drops, if those are enabled.\nBombchu Bowling is opened by bombchus.");
// SohImGui::EnhancementCombobox("gRandomizeBombchusInLogic", randoBombchusInLogic, 3, 0);
// ImGui::Separator();
@ -3759,17 +3752,17 @@ void DrawRandoEditor(bool& open) {
// switch (CVar_GetS32("gRandomizeAmmoDrops", 0)) {
// case 0:
// InsertHelpHoverText(
// "Bombs, arrows, seeds, nuts, sticks and\nmagic jars appear as normal.\n"
// "Bombs, arrows, seeds, nuts, sticks and magic jars appear as normal.\n"
// "Bombchus can sometimes replace bomb drops.");
// break;
// case 1:
// InsertHelpHoverText(
// "All ammo drops will be replaced by blue rupees,\nexcept for Deku Sticks.\n"
// "All ammo drops will be replaced by blue rupees, except for Deku Sticks.\n"
// "Ammo upgrades will only refill ammo by 10 units.");
// break;
// case 2:
// InsertHelpHoverText(
// "Bombs, arrow, seeds, nuts, sticks and\nmagic jars appear as normal.");
// "Bombs, arrow, seeds, nuts, sticks and magic jars appear as normal.");
// break;
// }
// SohImGui::EnhancementCombobox("gRandomizeAmmoDrops", randoAmmoDrops, 3, 0);
@ -3819,20 +3812,19 @@ void DrawRandoEditor(bool& open) {
switch (CVar_GetS32("gRandomizeShuffleDungeonReward", 0)) {
case 0:
InsertHelpHoverText(
"Medallions and Spiritual Stones will be given as\nrewards for beating "
"dungeons.\n\nThis "
"setting will force Link's Pocket to be a\nMedallion or a Spiritual Stone.");
"Medallions and Spiritual Stones will be given as rewards for beating dungeons.\n"
"This setting will force Link's Pocket to be a Medallion or a Spiritual Stone.");
break;
case 1:
InsertHelpHoverText(
"Medallions and Spiritual Stones can only appear\ninside of dungeons.");
"Medallions and Spiritual Stones can only appear inside of dungeons.");
break;
case 2:
InsertHelpHoverText(
"Medallions and Spiritual Stones can only appear\noutside dungeons.");
"Medallions and Spiritual Stones can only appear outside dungeons.");
break;
case 3:
InsertHelpHoverText("Medallions and Spiritual Stones can appear\nanywhere.");
InsertHelpHoverText("Medallions and Spiritual Stones can appear anywhere.");
break;
}
SohImGui::EnhancementCombobox("gRandomizeShuffleDungeonReward", randoShuffleDungeonRewards, 4,
@ -3845,16 +3837,16 @@ void DrawRandoEditor(bool& open) {
// ImGui::Text("Link's Pocket");
// switch (CVar_GetS32("gRandomizeLinksPocket", 0)) {
// case 0:
// InsertHelpHoverText("Link will start with a Dungeon Reward in his\ninventory.");
// InsertHelpHoverText("Link will start with a Dungeon Reward in his inventory.");
// break;
// case 1:
// InsertHelpHoverText("Link will receive a random advancement item at the\nbeginning "
// InsertHelpHoverText("Link will receive a random advancement item at the beginning "
// "of the playtrough.");
// break;
// case 2:
// InsertHelpHoverText(
// "Link will recieve a random item from the item pool\nat the beginning "
// "of the playthrought.");
// "Link will recieve a random item from the item pool at the beginning "
// "of the playthrough.");
// break;
// case 3:
// InsertHelpHoverText("Link will start with a very useful green rupee.");
@ -3869,16 +3861,15 @@ void DrawRandoEditor(bool& open) {
ImGui::Text("Shuffle Songs");
switch (CVar_GetS32("gRandomizeShuffleSongs", 0)) {
case 0:
InsertHelpHoverText("Songs will only appear at locations that normally\nteach songs.");
InsertHelpHoverText("Songs will only appear at locations that normally teach songs.");
break;
case 1:
InsertHelpHoverText("Songs appear at the end of dungeons.\nFor major dungeons, they "
"will be at the boss "
"heart container location.\nThe remaining 4 songs are placed "
"at:\n- Zelda's Lullaby "
"location\n- Ice Cavern's Serenade of Water Location\n- Bottom of "
"the Well's Lens of "
"Truth Location\n- Gerudo Training Ground's Ice Arrow Location.");
"will be at the boss heart container location.\nThe remaining 4 "
"songs are placed at:\n- Zelda's Lullaby location\n"
"- Ice Cavern's Serenade of Water Location\n"
"- Bottom of the Well's Lens of Truth Location\n"
"- Gerudo Training Ground's Ice Arrow Location.");
break;
case 2:
InsertHelpHoverText("Songs can appear in any location");
@ -3895,32 +3886,32 @@ void DrawRandoEditor(bool& open) {
// InsertHelpHoverText("All shop items will be the same as vanilla.");
// break;
// case 1:
// InsertHelpHoverText("Vanilla shop items will be shuffled among\ndifferent shops.");
// InsertHelpHoverText("Vanilla shop items will be shuffled among different shops.");
// break;
// case 2:
// InsertHelpHoverText(
// "Vanilla shop items will be shuffled among different shops, and each "
// "shop will contain\n1 non-vanilla shop item.");
// "shop will contain 1 non-vanilla shop item.");
// break;
// case 3:
// InsertHelpHoverText(
// "Vanilla shop items will be shuffled among different shops, and each "
// "shop will contain\n2 non-vanilla shop items.");
// "shop will contain 2 non-vanilla shop items.");
// break;
// case 4:
// InsertHelpHoverText(
// "Vanilla shop items will be shuffled among different shops, and each "
// "shop will contain\n3 non-vanilla shop items.");
// "shop will contain 3 non-vanilla shop items.");
// break;
// case 5:
// InsertHelpHoverText(
// "Vanilla shop items will be shuffled among different shops, and each "
// "shop will contain\n4 non-vanilla shop items.");
// "shop will contain 4 non-vanilla shop items.");
// break;
// case 6:
// InsertHelpHoverText(
// "Vanilla shop items will be shuffled among different shops, and each "
// "shop will contain\n1 to 4 non-vanilla shop items.");
// "shop will contain 1 to 4 non-vanilla shop items.");
// break;
// }
// SohImGui::EnhancementCombobox("gRandomizeShopsanity", randoShopsanity, 7, 0);
@ -3935,16 +3926,15 @@ void DrawRandoEditor(bool& open) {
// break;
// case 1:
// InsertHelpHoverText(
// "This only shuffles 65 location that are\nwithing dungeons, increasing the value "
// "of "
// "most\ndungeons and making internal dungeon exploration\nmore diverse.");
// "This only shuffles 65 location that are within dungeons, increasing the value "
// "of most dungeons and making internal dungeon exploration more diverse.");
// break;
// case 2:
// InsertHelpHoverText(
// "This only shuffles the 65 locations that are\noutside of dungeons.");
// "This only shuffles the 65 locations that are outside of dungeons.");
// break;
// case 3:
// InsertHelpHoverText("Effectively adds 100 new locations for items to\nappear.");
// InsertHelpHoverText("Effectively adds 100 new locations for items to appear.");
// break;
// }
// SohImGui::EnhancementCombobox("gRandomizeTokensanity", randoTokensanity, 4, 0);
@ -3956,15 +3946,15 @@ void DrawRandoEditor(bool& open) {
// switch (CVar_GetS32("gRandomizeShuffleScrubs", 0)) {
// case 0:
// InsertHelpHoverText(
// "Only the 3 Scrubs that give one-time items in the\nvanilla game (PoH, "
// "Deku Nut capacity, and Deku\nStick capacity) will have random items.");
// "Only the 3 Scrubs that give one-time items in the vanilla game (PoH, "
// "Deku Nut capacity, and Deku Stick capacity) will have random items.");
// break;
// case 1:
// InsertHelpHoverText("All Scrub prices will be reduced to 10 rupees each.");
// break;
// case 2:
// InsertHelpHoverText("All Scrub prices will be their vanilla prices.\nThis will require "
// "spending over 1000 rupees on\nSrubs.");
// "spending over 1000 rupees on Scrubs.");
// break;
// case 3:
// InsertHelpHoverText("All Scrub prices will be between 0 to 95 rupees.\nThis will on "
@ -3978,16 +3968,16 @@ void DrawRandoEditor(bool& open) {
// // Shuffle Cows
// ImGui::Text("Shuffle Cows");
// InsertHelpHoverText(
// "Enabling this will let cows give you items upon\nperforming Epona's Song in "
// "front of them. There\nare 9 cows.");
// "Enabling this will let cows give you items upon performing Epona's Song in "
// "front of them. There are 9 cows.");
// SohImGui::EnhancementCombobox("gRandomizeShuffleCows", randoShuffleCows, 2, 0);
// ImGui::Separator();
if(CVar_GetS32("gRandomizeStartingKokiriSword", 0) == 0) {
// Shuffle Kokiri Sword
ImGui::Text("Shuffle Kokiri Sword");
InsertHelpHoverText("Enabling this shuffles the Kokiri Sword into the item pool.\n\nThis will "
"require extensive use of sticks until\nthe sword is found.");
InsertHelpHoverText("Enabling this shuffles the Kokiri Sword into the item pool.\nThis will "
"require extensive use of sticks until the sword is found.");
SohImGui::EnhancementCombobox("gRandomizeShuffleKokiriSword", randoShuffleKokiriSword, 2, 0);
ImGui::Separator();
}
@ -3995,9 +3985,9 @@ void DrawRandoEditor(bool& open) {
if(CVar_GetS32("gRandomizeStartingOcarina", 0) == 0) {
// Shuffle Ocarinas
ImGui::Text("Shuffle Ocarinas");
InsertHelpHoverText("Enabling this shuffles the Fairy Ocarina and the\nOcarina of time into "
"the item pool.\n\nThis "
"will require finding an Ocarina before being\nable to play songs.");
InsertHelpHoverText("Enabling this shuffles the Fairy Ocarina and the Ocarina of time into "
"the item pool.\n"
"This will require finding an Ocarina before being able to play songs.");
SohImGui::EnhancementCombobox("gRandomizeShuffleOcarinas", randoShuffleOcarinas, 2, 0);
ImGui::Separator();
}
@ -4007,11 +3997,11 @@ void DrawRandoEditor(bool& open) {
// Shuffle Weird Egg
ImGui::Text("Shuffle Weird Egg");
InsertHelpHoverText(
"Enabling this shuffles the Weird Egg from Malon\ninto the item pool.\nThis "
"will require finding the Weird Egg to talk to\nZelda in Hyrule Castle which "
"in turn locks\nrewards from Impa, Xaria, Malon and Talon as\nwell as the "
"Happy Mask Sidequest. The Weird egg\nis also required for Zelda's Letter to "
"unlock the\nKakariko Gate as child which can lock some\nprogression.");
"Enabling this shuffles the Weird Egg from Malon into the item pool.\nThis "
"will require finding the Weird Egg to talk to Zelda in Hyrule Castle which "
"in turn unlocks rewards from Impa, Saria, Malon and Talon as well as the "
"Happy Mask Sidequest.\nThe Weird egg is also required for Zelda's Letter to "
"unlock the Kakariko Gate as child which can lock some progression.");
SohImGui::EnhancementCombobox("gRandomizeShuffleWeirdEgg", randoShuffleWeirdEgg, 2, 0);
ImGui::Separator();
}
@ -4019,16 +4009,16 @@ void DrawRandoEditor(bool& open) {
// Shuffle Gerudo Membership Card
ImGui::Text("Shuffle Gerudo Membership Card");
InsertHelpHoverText(
"Enabling this shuffles the Gerudo Membership Card into the\nitem pool.\n\nThe Gerudo "
"Token is required to enter the Gerudo\nTraining Ground.");
"Enabling this shuffles the Gerudo Membership Card into the item pool.\nThe Gerudo "
"Token is required to enter the Gerudo Training Ground.");
SohImGui::EnhancementCombobox("gRandomizeShuffleGerudoToken", randoShuffleGerudoToken, 2, 0);
ImGui::Separator();
// todo implement magic bean 10 pack
// // Shuffle Magic Beans
// ImGui::Text("Shuffle Magic Beans");
// InsertHelpHoverText("Enabling this adds a pack of 10 beans to the item\n"
// "pool and changes the Magic Bean Salesman to sell a\n"
// InsertHelpHoverText("Enabling this adds a pack of 10 beans to the item "
// "pool and changes the Magic Bean Salesman to sell a "
// "random item at a price of 60 rupees.");
// SohImGui::EnhancementCombobox("gRandomizeShuffleMagicBeans", randoShuffleMagicBeans, 2, 0);
// ImGui::Separator();
@ -4038,13 +4028,13 @@ void DrawRandoEditor(bool& open) {
// ImGui::Text("Shuffle Merchants");
// if (CVar_GetS32("gRandomizeShuffleMerchants", 0) == 0) {
// InsertHelpHoverText(
// "Enabling this adds a Giant's Knife and a pack\nof Bombchus to the item "
// "pool and changes both\nMediagoron and the Haunted Wasteland "
// "Carpet\nSalesman to sell a random item once at the price\nof 200 rupees.");
// "Enabling this adds a Giant's Knife and a pack of Bombchus to the item "
// "pool and changes both Mediagoron and the Haunted Wasteland "
// "Carpet Salesman to sell a random item once at the price of 200 rupees.");
// } else if (CVar_GetS32("gRandomizeShuffleMerchants", 0) <= 2) {
// InsertHelpHoverText(
// "These hints will make Medigoron and the Carpet\nsalesman tell you which item they\'re "
// "selling.\n\nThe Clearer Hints setting will affect how they\nrefer to the item.");
// "These hints will make Medigoron and the Carpet salesman tell you which item they're "
// "selling.\nThe Clearer Hints setting will affect how they refer to the item.");
// }
// SohImGui::EnhancementCombobox("gRandomizeShuffleMerchants", randoShuffleMerchants, 3, 0);
// ImGui::Separator();
@ -4053,13 +4043,10 @@ void DrawRandoEditor(bool& open) {
// Shuffle Adult Trade
// ImGui::Text("Shuffle Adult Trade");
// InsertHelpHoverText(
// "Enabling this adds all of the adult trade quest\nitems to the pool, each of which can be "
// "traded\nfor a unique reward You will be able to choose\nwhich of your owner adult trade "
// "items "
// " "
// "is visible\nin the inventory by selecting the item and using\nthe L and R buttons If "
// "disabled "
// "only the Claim\nCheck will be found in the pool.");
// "Enabling this adds all of the adult trade quest items to the pool, each of which can be "
// "traded for a unique reward.\nYou will be able to choose which of your adult trade items "
// "are visible in the inventory by selecting the item and using the L and R buttons.\n"
// "If disabled only the Claim Check will be found in the pool.");
// SohImGui::EnhancementCombobox("gRandomizeShuffleAdultTrade", randoShuffleAdultTrade, 2, 0);
}
ImGui::PopItemWidth();
@ -4090,26 +4077,26 @@ void DrawRandoEditor(bool& open) {
// ImGui::Text("Maps / Compasses");
// switch (CVar_GetS32("gRandomizeShuffleMapsAndCompasses", 0)) {
// case 0:
// InsertHelpHoverText("Maps and Compasses can only appear in their repsective dungeon.");
// InsertHelpHoverText("Maps and Compasses can only appear in their respective dungeon.");
// break;
// case 1:
// InsertHelpHoverText(
// "Maps and Compasses can only appear in a dungeon\nbut not necessarily the "
// "Maps and Compasses can only appear in a dungeon but not necessarily the "
// "dungeon they are for.");
// break;
// case 2:
// InsertHelpHoverText("Maps and Compasses can only appear outside of\ndungeons.");
// InsertHelpHoverText("Maps and Compasses can only appear outside of dungeons.");
// break;
// case 3:
// InsertHelpHoverText("Maps and Compasses can appear anywhere in the\nworld.");
// InsertHelpHoverText("Maps and Compasses can appear anywhere in the world.");
// break;
// case 4:
// InsertHelpHoverText(
// "Maps and Compasses are given to you from the start.\nThis will add a "
// "small amount of money and\nrefill items to the pool.");
// "small amount of money and refill items to the pool.");
// break;
// case 5:
// InsertHelpHoverText("Maps and Compasses will appear in their vanilla\nlocations.");
// InsertHelpHoverText("Maps and Compasses will appear in their vanilla locations.");
// break;
// }
// SohImGui::EnhancementCombobox("gRandomizeShuffleMapsAndCompasses", randoShuffleMapsAndCompasses,
@ -4121,28 +4108,28 @@ void DrawRandoEditor(bool& open) {
// ImGui::Text("Small Keys");
// switch (CVar_GetS32("gRandomizeShuffleSmallKeys", 0)) {
// case 0:
// InsertHelpHoverText("Small Keys can only appear in their respective\ndungeon.");
// InsertHelpHoverText("Small Keys can only appear in their respective dungeon.");
// break;
// case 1:
// InsertHelpHoverText(
// "Small Keys can only appear inside of any dungon,\nbut won't necessarily "
// "be in the dungeon that the\nkey is for.\nA difficult mode since it is "
// "more likely\nto need to enter a dungeon multiple times.");
// "Small Keys can only appear inside of any dungon, but won't necessarily "
// "be in the dungeon that the key is for.\nA difficult mode since it is "
// "more likely to need to enter a dungeon multiple times.");
// break;
// case 2:
// InsertHelpHoverText(
// "Small Keys can only appear outside of dungeons.\nYou may need to enter a "
// "dungeon multiple times to\ngain items to access the overworld locations "
// "with\nthe keys required to finish a dungeon.");
// "dungeon multiple times to gain items to access the overworld locations "
// "with the keys required to finish a dungeon.");
// break;
// case 3:
// InsertHelpHoverText(
// "Small Keys can appear anywhere in the world.\nA difficult mode since it "
// "is more likely to need to\nenter a dungeon multiple times.");
// "is more likely to need to enter a dungeon multiple times.");
// break;
// case 4:
// InsertHelpHoverText(
// "Small Keys are given to you from the start so you\nwon't have to worry "
// "Small Keys are given to you from the start so you won't have to worry "
// "about locked doors.\nAn easier mode.");
// break;
// case 5:
@ -4158,18 +4145,17 @@ void DrawRandoEditor(bool& open) {
// switch (CVar_GetS32("gRandomizeShuffleGerudoFortressKeys", 0)) {
// case 0:
// InsertHelpHoverText(
// "Gerudo Fortress Keys will appear in their vanilla\nlocation dropping "
// "from fighting Gerudo "
// "guard\nthat attack when trying to free the jailed\ncarpenters.");
// "Gerudo Fortress Keys will appear in their vanilla location dropping from "
// "fighting Gerudo guards that attack when trying to free the jailed carpenters.");
// break;
// case 1:
// InsertHelpHoverText("Gerudo Fortress Keys can only appear inside of\ndungeons.");
// InsertHelpHoverText("Gerudo Fortress Keys can only appear inside of dungeons.");
// break;
// case 2:
// InsertHelpHoverText("Gerudo Fortress Keys can only appear outside of\ndungeons.");
// InsertHelpHoverText("Gerudo Fortress Keys can only appear outside of dungeons.");
// break;
// case 3:
// InsertHelpHoverText("Gerudo Fortress Keys can appear anywhere in the\nworld.");
// InsertHelpHoverText("Gerudo Fortress Keys can appear anywhere in the world.");
// break;
// }
// SohImGui::EnhancementCombobox("gRandomizeShuffleGerudoFortressKeys",
@ -4181,28 +4167,27 @@ void DrawRandoEditor(bool& open) {
// ImGui::Text("Boss Keys");
// switch (CVar_GetS32("gRandomizeShuffleBossKeys", 0)) {
// case 0:
// InsertHelpHoverText("Boss Keys can only appear in their respective\ndungeons.");
// InsertHelpHoverText("Boss Keys can only appear in their respective dungeons.");
// break;
// case 1:
// InsertHelpHoverText(
// "Boss Keys can only appear inside of any dungeon,\nbut won't necessarily "
// "be in the dungon that the\nkey is for.\nA difficult mode since it is "
// "more\nlikely to need to enter a dungeon multiple times.");
// "Boss Keys can only appear inside of any dungeon, but won't necessarily "
// "be in the dungon that the key is for.\nA difficult mode since it is "
// "more likely to need to enter a dungeon multiple times.");
// break;
// case 2:
// InsertHelpHoverText(
// "Boss keys can only appear outside of dungeons.\nYou may need to enter a dungeon "
// "without "
// "the boss\nkey to get items required to find the key in the\noverworld.");
// "Boss Keys can only appear outside of dungeons.\nYou may need to enter a dungeon "
// "without the boss key to get items required to find the key in the overworld.");
// break;
// case 3:
// InsertHelpHoverText(
// "Boss key can appear anywhere in the overworld.\nA difficult mode since it "
// "is more likely to need to\nenter a dungeon multiple times.");
// "Boss Keys can appear anywhere in the overworld.\nA difficult mode since it "
// "is more likely to need to enter a dungeon multiple times.");
// break;
// case 4:
// InsertHelpHoverText(
// "Boss Keys are given to you from the start so you\nwon't have to worry "
// "Boss Keys are given to you from the start so you won't have to worry "
// "about boss doors.\nAn easier mode.");
// break;
// case 5:
@ -4221,80 +4206,80 @@ void DrawRandoEditor(bool& open) {
switch (CVar_GetS32("gRandomizeShuffleGanonBossKey", 0)) {
case 0:
SetLastItemHoverText(
"Ganon's Boss Key is given to you from the\nstart and you don't "
"Ganon's Boss Key is given to you from the start and you don't "
"have to worry about finding it.");
break;
case 1:
SetLastItemHoverText("Ganon's Boss Key will appear in the vanilla\nlocation.");
SetLastItemHoverText("Ganon's Boss Key will appear in the vanilla location.");
break;
case 2:
SetLastItemHoverText("Ganon's Boss Key will appear somewhere inside\nGanon's Castle.");
SetLastItemHoverText("Ganon's Boss Key will appear somewhere inside Ganon's Castle.");
break;
// case 0:
// SetLastItemHoverText(
// "Ganon's Castle Boss Key can only appear inside of\na dungeon, but not "
// "Ganon's Castle Boss Key can only appear inside of a dungeon, but not "
// "necessarily Ganon's Castle.");
// break;
// case 1:
// SetLastItemHoverText("Ganon's Castle Boss Key can only appear outside of\ndungeons.");
// SetLastItemHoverText("Ganon's Castle Boss Key can only appear outside of dungeons.");
// break;
// case 2:
// SetLastItemHoverText("Ganon's Castle Boss Key can appear anywhere in the\nworld.");
// SetLastItemHoverText("Ganon's Castle Boss Key can appear anywhere in the world.");
// break;
// case 3:
// SetLastItemHoverText(
// "These settings put the boss key on the Light Arrow\nCutscene location, "
// "from Zelda in Temple of Time as\nadult, with differing requirements.");
// "These settings put the boss key on the Light Arrow Cutscene location, "
// "from Zelda in Temple of Time as adult, with differing requirements.");
// break;
// case 4:
// SetLastItemHoverText("Ganon's Caslte Boss Key can appear anywhere in the\nworld.");
// SetLastItemHoverText("Ganon's Castle Boss Key can appear anywhere in the world.");
// break;
// case 5:
// SetLastItemHoverText(
// "These settings put the boss key on the Light Arrow\nCutscene location, "
// "from Zelda in Temple of Time as\nadult, with differing requirements.");
// "These settings put the boss key on the Light Arrow Cutscene location, "
// "from Zelda in Temple of Time as adult, with differing requirements.");
// SohImGui::EnhancementSliderInt("Medallion Count: %d", "##RandoGanonMedallionCount",
// "gRandomizeGanonMedallionCount", 0, 6, "");
// InsertHelpHoverText(
// "Set the number of Medallions required to trigger\nthe Light Arrow Cutscene.");
// "Set the number of Medallions required to trigger the Light Arrow Cutscene.");
// break;
// case 6:
// SetLastItemHoverText(
// "These settings put the boss key on the Light Arrow\nCutscene location, "
// "from Zelda in Temple of Time as\nadult, with differing requirements.");
// "These settings put the boss key on the Light Arrow Cutscene location, "
// "from Zelda in Temple of Time as adult, with differing requirements.");
// SohImGui::EnhancementSliderInt("Stone Count: %d", "##RandoGanonStoneCount",
// "gRandomizeGanonStoneCount", 0, 3, "");
// InsertHelpHoverText("Set the number of Spiritual Stones required to trigger\nthe Light "
// InsertHelpHoverText("Set the number of Spiritual Stones required to trigger the Light "
// "Arrow Cutscene.");
// break;
// case 7:
// SetLastItemHoverText(
// "These settings put the boss key on the Light Arrow\nCutscene location, "
// "from Zelda in Temple of Time as\nadult, with differing requirements.");
// "These settings put the boss key on the Light Arrow Cutscene location, "
// "from Zelda in Temple of Time as adult, with differing requirements.");
// SohImGui::EnhancementSliderInt("Reward Count: %d", "##RandoGanonRewardCount",
// "gRandomizeGanonRewardCount", 0, 9, "");
// InsertHelpHoverText(
// "Set the number of Dungeon Rewards (Spiritual\nStones and Medallions) "
// "required to trigger the\nLight Arrow Cutscene.");
// "Set the number of Dungeon Rewards (Spiritual Stones and Medallions) "
// "required to trigger the Light Arrow Cutscene.");
// break;
// case 8:
// SetLastItemHoverText(
// "These settings put the boss key on the Light Arrow\nCutscene location, "
// "from Zelda in Temple of Time as\nadult, with differing requirements.");
// "These settings put the boss key on the Light Arrow Cutscene location, "
// "from Zelda in Temple of Time as adult, with differing requirements.");
// SohImGui::EnhancementSliderInt("MDungeon Count: %d", "##RandoGanonDungeonCount",
// "gRandomizeGanonDungeonCount", 0, 8, "");
// InsertHelpHoverText(
// "Set the number of completed dungeons required to\ntrigger the Light Arrow "
// "Cutscene.\n\nDungeons are considered complete when Link steps\ninto the "
// "Set the number of completed dungeons required to trigger the Light Arrow "
// "Cutscene.\nDungeons are considered complete when Link steps into the "
// "blue warp at the end of them.");
// break;
// case 9:
// SetLastItemHoverText(
// "These settings put the boss key on the Light Arrow\nCutscene location, "
// "from Zelda in Temple of Time as\nadult, with differing requirements.");
// "These settings put the boss key on the Light Arrow Cutscene location, "
// "from Zelda in Temple of Time as adult, with differing requirements.");
// SohImGui::EnhancementSliderInt("Token Count: %d", "##RandoGanonTokenCount",
// "gRandomizeGanonTokenCount", 0, 100, "");
// InsertHelpHoverText("Set the number of Gold Skulltula Tokens required\nto trigger the "
// InsertHelpHoverText("Set the number of Gold Skulltula Tokens required to trigger the "
// "Light Arrow Cutscene.");
// break;
}
@ -4318,82 +4303,82 @@ void DrawRandoEditor(bool& open) {
// todo implement minigame repeat skip
// // Skip Minigame repetition
// SohImGui::EnhancementCheckbox("Skip Minigame Repetition", "gRandomizeSkipMinigameRepetition");
// InsertHelpHoverText("Completing the second objective in the Dampe Race\nand Gerudo Archery on the "
// "first attempt will give\nboth rewards at once for that minigame.");
// InsertHelpHoverText("Completing the second objective in the Dampe Race and Gerudo Archery on the "
// "first attempt will give both rewards at once for that minigame.");
// ImGui::Separator();
// todo implement free scarecrow (is this already in?)
// // Free scarecrow
// SohImGui::EnhancementCheckbox("Free Scarecrow", "gRandomizeFreeScarecrow");
// InsertHelpHoverText(
// "Pulling the Ocarina near a spot at which\nPierre can spawn will do so, without "
// "needing\nthe song.");
// "Pulling the Ocarina near a spot at which Pierre can spawn will do so, without "
// "needing the song.");
// ImGui::Separator();
// todo implement skip poes (did we already?)
// // Skip Four Poes cutscene
// SohImGui::EnhancementCheckbox("Skip Four Poes Cutscene", "gRandomizeSkipFourPoesCutscene");
// InsertHelpHoverText(
// "The cutscene with the 4 poes in Forest Temple will\nbe skipped. If the cutscene "
// "is not skipped, it can\nbe exploited to reach the basement early.");
// "The cutscene with the 4 poes in Forest Temple will be skipped. If the cutscene "
// "is not skipped, it can be exploited to reach the basement early.");
// ImGui::Separator();
// todo implement skip lake hylia owl
// // Skip Lake Hylia owl
// SohImGui::EnhancementCheckbox("Skip Lake Hylia Owl Cutscene", "gRandomizeSkipLakeHyliaOwl");
// InsertHelpHoverText(
// "The owl flight cutscene in Lake Hylia will be\nskipped. This cutscene lets you "
// "see what item\nis on top of the laboratory roof.");
// "The owl flight cutscene in Lake Hylia will be skipped. This cutscene lets you "
// "see what item is on top of the laboratory roof.");
// ImGui::Separator();
// Cuccos to return
SohImGui::EnhancementSliderInt("Cuccos to return: %d", "##RandoCuccosToReturn",
"gRandomizeCuccosToReturn", 0, 7, "", 7);
InsertHelpHoverText("The cucco Lady will give a reward for returning\nthis many of her cuccos to the pen.");
InsertHelpHoverText("The cucco Lady will give a reward for returning this many of her cuccos to the pen.");
ImGui::Separator();
// // Big Poe Target Count
SohImGui::EnhancementSliderInt("Big Poe Target Count: %d", "##RandoBigPoeTargetCount",
"gRandomizeBigPoeTargetCount", 1, 10, "", 10);
InsertHelpHoverText("The Poe buyer will give a reward for turning in\nthe chosen number of Big Poes.");
InsertHelpHoverText("The Poe buyer will give a reward for turning in the chosen number of Big Poes.");
ImGui::Separator();
// // Skip child stealth
SohImGui::EnhancementCheckbox("Skip Child Stealth", "gRandomizeSkipChildStealth");
InsertHelpHoverText("The crawlspace into Hyrule Castle goes straight to\nZelda, skipping the guards.");
InsertHelpHoverText("The crawlspace into Hyrule Castle goes straight to Zelda, skipping the guards.");
ImGui::Separator();
// Skip Epona race
SohImGui::EnhancementCheckbox("Skip Epona Race", "gRandomizeSkipEponaRace");
InsertHelpHoverText("Epona can be summoned with Epona's Song without\nneeding to race Ingo.");
InsertHelpHoverText("Epona can be summoned with Epona's Song without needing to race Ingo.");
ImGui::Separator();
// Skip tower escape
SohImGui::EnhancementCheckbox("Skip Tower Escape", "gRandomizeSkipTowerEscape");
InsertHelpHoverText("The tower escape sequence between Ganondorf and\nGanon will be skipped.");
InsertHelpHoverText("The tower escape sequence between Ganondorf and Ganon will be skipped.");
ImGui::Separator();
// todo implement complete mask quest
// // Complete Mask Quest
// SohImGui::EnhancementCheckbox("Complete Mask Quest", "gRandomizeCompleteMaskQuest");
// InsertHelpHoverText(
// "Once the Happy Mask Shop is opened, all masks\nwill be available to be borrowed.");
// "Once the Happy Mask Shop is opened, all masks will be available to be borrowed.");
// ImGui::Separator();
// todo implement keep farores (in soh)
// // Keep Farore's Wind Warp Point
// SohImGui::EnhancementCheckbox("Keep Farore's Wind Warp Point", "gRandomizeKeepFaroresWindWarp");
// InsertHelpHoverText(
// "The Farore's Wind warp point will stay active\nafter having been warped to. The "
// "old point will\nneed to be dispelled before setting a new one.");
// "The Farore's Wind warp point will stay active after having been warped to.\nThe "
// "old point will need to be dispelled before setting a new one.");
// ImGui::Separator();
// todo implement skip song replays (in soh)
// // Skip Song Replays
// ImGui::Text("Skip Song Replays");
// InsertHelpHoverText(
// "The automatic replay after you play a song will\nbe skipped.\nYou can choose to "
// "keep the SFX anyway, but you\nwill have control of Link during it.");
// "The automatic replay after you play a song will be skipped.\nYou can choose to "
// "keep the SFX anyway, but you will have control of Link during it.");
// SohImGui::EnhancementCombobox("gRandomizeSkipSongReplays", randoSkipSongReplays, 3, 0);
// ImGui::Separator();
@ -4404,12 +4389,10 @@ void DrawRandoEditor(bool& open) {
// Gossip Stone Hints
ImGui::Text("Gossip Stone Hints");
InsertHelpHoverText(
"Gossip Stones can be made to give hints about\nwhere items can be found.\nDifferent settings "
"can "
"be chosen to decide which\nitem is needed to speak to Gossip Stones. Choosing\nto sticl with "
"the "
"Mask of Trutj will make the\nhints very difficult to obtain.\nHints for \"on the way of the "
"hero\" are locations\ntaht contain items that are required to beat the\ngame.");
"Gossip Stones can be made to give hints about where items can be found.\nDifferent settings can "
"be chosen to decide which item is needed to speak to Gossip Stones. \nChoosing to stick with the "
"Mask of Truth will make the hints very difficult to obtain.\nHints for \"on the way of the "
"hero\" are locations that contain items that are required to beat the game.");
SohImGui::EnhancementCombobox("gRandomizeGossipStoneHints", randoGossipStoneHints, 4, 1);
if (CVar_GetS32("gRandomizeGossipStoneHints", 1) != 0) {
@ -4419,18 +4402,18 @@ void DrawRandoEditor(bool& open) {
switch (CVar_GetS32("gRandomizeHintClarity", 2)) {
case 0:
InsertHelpHoverText(
"Sets the difficulty of hints.\nObscure: Hints are unique for each thing, but\nthe "
"Sets the difficulty of hints.\nObscure: Hints are unique for each thing, but the "
"writing may be confusing.\nEx: Kokiri Sword > a butter knife");
break;
case 1:
InsertHelpHoverText(
"Sets the difficulty of hints.\nAmbiguous: Hints are clearly written, "
"but may\nrefer to more than one thing.\nEx: Kokiri Sword > a sword");
"but may refer to more than one thing.\nEx: Kokiri Sword > a sword");
break;
case 2:
InsertHelpHoverText(
"Sets the difficulty of hints.\nClear: Hints are clearly written and "
"are unique\nfor each thing.\nEx: Kokiri Sword > the Kokiri Sword");
"are unique for each thing.\nEx: Kokiri Sword > the Kokiri Sword");
break;
}
SohImGui::EnhancementCombobox("gRandomizeHintClarity", randoHintClarity, 3, 2);
@ -4474,7 +4457,7 @@ void DrawRandoEditor(bool& open) {
// // Chest Size and Color
// ImGui::Text("Chest Size and Color");
// InsertHelpHoverText(
// "This option will change the appearance of all\nregular chests depending on their "
// "This option will change the appearance of all regular chests depending on their "
// "contents:\nMajor Items = Big Wooden Chests\nLesser Items = Small Wooden "
// "Chests\nBoss Keys = Big Fancy Chests\nSmall Keys = Small Fancy Chests");
// SohImGui::EnhancementCombobox("gRandomizeChestSizeAndColor", randoChestSizeAndColor, 2, 0);
@ -4485,11 +4468,11 @@ void DrawRandoEditor(bool& open) {
// switch (CVar_GetS32("gRandomize", 0)) {
// case 0:
// InsertHelpHoverText(
// "All alternative traps will cause a small damage\nand no other negative effets.");
// "All alternative traps will cause small damage and no other negative effects.");
// break;
// case 1:
// InsertHelpHoverText("Some chest traps will burn your Deku Shield or\ncause a lot of damage "
// "(with one-hit protection).");
// InsertHelpHoverText("Some chest traps will burn your Deku Shield or cause a lot of damage "
// "(with one-hit KO protection).");
// break;
// case 2:
// InsertHelpHoverText("All traps will be the base game ice trap.");
@ -4511,7 +4494,7 @@ void DrawRandoEditor(bool& open) {
InsertHelpHoverText("Original item pool.");
break;
case 2:
InsertHelpHoverText("Some excess items are removed, including health\nupgrades.");
InsertHelpHoverText("Some excess items are removed, including health upgrades.");
break;
case 3:
InsertHelpHoverText("Most excess items are removed.");
@ -4531,14 +4514,14 @@ void DrawRandoEditor(bool& open) {
break;
case 2:
InsertHelpHoverText(
"Chance to add extra Ice Traps when junk items are\nadded to the item pool.");
"Chance to add extra Ice Traps when junk items are added to the item pool.");
break;
case 3:
InsertHelpHoverText("All added junk items will be Ice Traps.");
break;
case 4:
InsertHelpHoverText(
"All junk items will be replaced by Ice Traps, even\nthose in the base pool.");
"All junk items will be replaced by Ice Traps, even those in the base pool.");
break;
}
SohImGui::EnhancementCombobox("gRandomizeIceTraps", randoIceTraps, 5, 1);
@ -4547,7 +4530,7 @@ void DrawRandoEditor(bool& open) {
// todo implement double defense getitem
// // Remove Double Defense
// SohImGui::EnhancementCheckbox("Remove Double Defense", "gRandomizeRemoveDoubleDefense");
// InsertHelpHoverText("If set the double defense item will be removed\nfrom the item pool for "
// InsertHelpHoverText("If set the double defense item will be removed from the item pool for "
// "balanced and plentiful.");
// ImGui::Separator();
@ -4555,8 +4538,8 @@ void DrawRandoEditor(bool& open) {
// // Prog Goron Sword
// SohImGui::EnhancementCheckbox("Prog Goron Sword", "gRandomizeProgGoronSword");
// InsertHelpHoverText(
// "Giant's Knife will walays be found before Biggoron's\nSword. Medigoron only "
// "starts selling new knives\nonce the Giant's Knife has been found\nand broken.");
// "Giant's Knife will always be found before Biggoron's Sword.\nMedigoron only "
// "starts selling new knives once the Giant's Knife has been found and broken.");
// ImGui::Separator();
ImGui::PopItemWidth();
ImGui::EndTable();

View File

@ -985,7 +985,7 @@ void DrawItemTracker(bool& open) {
}
SohImGui::EnhancementCheckbox("Display \"Ammo/MaxAmo\"", "gItemTrackerAmmoDisplay");
SohImGui::EnhancementCheckbox("Randomizer colors for Songs", "gItemTrackeSongColor");
SohImGui::Tooltip("Will dispaly non-warp songs with randomizer\ncolors instead of pure white");
SohImGui::Tooltip("Will display non-warp songs with randomizer colors instead of pure white");
SohImGui::EnhancementSliderInt("Icon size : %dpx", "##ITEMTRACKERICONSIZE", "gRandoTrackIconSize", 32, 128, "");
SohImGui::EnhancementSliderInt("X spacing : %dpx", "##ITEMTRACKERSPACINGX", "gRandoTrackIconSpacingX", minimalSpacingX, 256,

View File

@ -17,6 +17,9 @@ void ResourceMgr_CacheDirectory(const char* resName);
void ResourceMgr_LoadFile(const char* resName);
char* ResourceMgr_LoadFileFromDisk(const char* filePath);
char* ResourceMgr_LoadTexByName(char* texPath);
uint16_t ResourceMgr_LoadTexWidthByName(char* texPath);
uint16_t ResourceMgr_LoadTexHeightByName(char* texPath);
uint32_t ResourceMgr_LoadTexSizeByName(char* texPath);
char* ResourceMgr_LoadTexOrDListByName(char* filePath);
char* ResourceMgr_LoadPlayerAnimByName(char* animPath);
char* ResourceMgr_GetNameByCRC(uint64_t crc, char* alloc);

View File

@ -121,8 +121,7 @@ extern "C" void InitOTR() {
if (!t->bHasLoadError)
{
//uint32_t gameVersion = BitConverter::ToUInt32BE((uint8_t*)t->buffer.get(), 0);
uint32_t gameVersion = *((uint32_t*)t->buffer.get());
uint32_t gameVersion = LE32SWAP(*((uint32_t*)t->buffer.get()));
OTRGlobals::Instance->context->GetResourceManager()->SetGameVersion(gameVersion);
}
@ -457,6 +456,12 @@ extern "C" char* ResourceMgr_LoadJPEG(char* data, int dataSize)
extern "C" char* ResourceMgr_LoadTexByName(const char* texPath);
extern "C" uint16_t ResourceMgr_LoadTexWidthByName(char* texPath);
extern "C" uint16_t ResourceMgr_LoadTexHeightByName(char* texPath);
extern "C" uint32_t ResourceMgr_LoadTexSizeByName(const char* texPath);
extern "C" char* ResourceMgr_LoadTexOrDListByName(const char* filePath) {
auto res = OTRGlobals::Instance->context->GetResourceManager()->LoadResource(filePath);
@ -799,8 +804,8 @@ extern "C" SoundFont* ResourceMgr_LoadAudioSoundFont(const char* path) {
for (size_t k = 0; k < soundFont->drums[i].env.size(); k++)
{
drum->envelope[k].delay = BOMSWAP16(soundFont->drums[i].env[k]->delay);
drum->envelope[k].arg = BOMSWAP16(soundFont->drums[i].env[k]->arg);
drum->envelope[k].delay = BE16SWAP(soundFont->drums[i].env[k]->delay);
drum->envelope[k].arg = BE16SWAP(soundFont->drums[i].env[k]->arg);
}
}
@ -831,8 +836,8 @@ extern "C" SoundFont* ResourceMgr_LoadAudioSoundFont(const char* path) {
for (int k = 0; k < soundFont->instruments[i].env.size(); k++)
{
inst->envelope[k].delay = BOMSWAP16(soundFont->instruments[i].env[k]->delay);
inst->envelope[k].arg = BOMSWAP16(soundFont->instruments[i].env[k]->arg);
inst->envelope[k].delay = BE16SWAP(soundFont->instruments[i].env[k]->delay);
inst->envelope[k].arg = BE16SWAP(soundFont->instruments[i].env[k]->arg);
}
}
if (soundFont->instruments[i].lowNotesSound != nullptr)
@ -1454,6 +1459,10 @@ extern "C" s32 Randomizer_GetItemIdFromKnownCheck(RandomizerCheck randomizerChec
return OTRGlobals::Instance->gRandomizer->GetRandomizedItemIdFromKnownCheck(randomizerCheck, ogId);
}
extern "C" bool Randomizer_ItemIsIceTrap(RandomizerCheck randomizerCheck, GetItemID ogId) {
return gSaveContext.n64ddFlag && Randomizer_GetItemIdFromKnownCheck(randomizerCheck, ogId) == GI_ICE_TRAP;
}
extern "C" CustomMessageEntry Randomizer_GetCustomGetItemMessage(GetItemID giid, char* buffer, const int maxBufferSize) {
const CustomMessageEntry getItemText = CustomMessageManager::Instance->RetrieveMessage(Randomizer::getItemMessageTableID, giid);
return getItemText;

View File

@ -46,6 +46,9 @@ void ResourceMgr_LoadFile(const char* resName);
char* ResourceMgr_LoadFileFromDisk(const char* filePath);
char* ResourceMgr_LoadJPEG(char* data, int dataSize);
char* ResourceMgr_LoadTexByName(const char* texPath);
uint16_t ResourceMgr_LoadTexWidthByName(char* texPath);
uint16_t ResourceMgr_LoadTexHeightByName(char* texPath);
uint32_t ResourceMgr_LoadTexSizeByName(char* texPath);
char* ResourceMgr_LoadTexOrDListByName(const char* filePath);
char* ResourceMgr_LoadPlayerAnimByName(const char* animPath);
AnimationHeaderCommon* ResourceMgr_LoadAnimByName(const char* path);
@ -95,6 +98,7 @@ s16 Randomizer_GetItemModelFromId(s16 itemId);
s32 Randomizer_GetItemIDFromGetItemID(s32 getItemId);
s32 Randomizer_GetRandomizedItemId(GetItemID ogId, s16 actorId, s16 actorParams, s16 sceneNum);
s32 Randomizer_GetItemIdFromKnownCheck(RandomizerCheck randomizerCheck, GetItemID ogId);
bool Randomizer_ItemIsIceTrap(RandomizerCheck randomizerCheck, GetItemID ogId);
int CustomMessage_RetrieveIfExists(GlobalContext* globalCtx);
#endif

View File

@ -22,7 +22,8 @@ std::filesystem::path SaveManager::GetFileName(int fileNum) {
SaveManager::SaveManager() {
AddLoadFunction("base", 1, LoadBaseVersion1);
AddSaveFunction("base", 1, SaveBase);
AddLoadFunction("base", 2, LoadBaseVersion2);
AddSaveFunction("base", 2, SaveBase);
AddLoadFunction("randomizer", 1, LoadRandomizerVersion1);
AddSaveFunction("randomizer", 1, SaveRandomizer);
@ -319,11 +320,23 @@ void SaveManager::InitFileNormal() {
gSaveContext.worldMapAreaData = 0;
gSaveContext.scarecrowCustomSongSet = 0;
for (int i = 0; i < ARRAY_COUNT(gSaveContext.scarecrowCustomSong); i++) {
gSaveContext.scarecrowCustomSong[i] = 0;
gSaveContext.scarecrowCustomSong[i].noteIdx = 0;
gSaveContext.scarecrowCustomSong[i].unk_01 = 0;
gSaveContext.scarecrowCustomSong[i].unk_02 = 0;
gSaveContext.scarecrowCustomSong[i].volume = 0;
gSaveContext.scarecrowCustomSong[i].vibrato = 0;
gSaveContext.scarecrowCustomSong[i].tone = 0;
gSaveContext.scarecrowCustomSong[i].semitone = 0;
}
gSaveContext.scarecrowSpawnSongSet = 0;
for (int i = 0; i < ARRAY_COUNT(gSaveContext.scarecrowSpawnSong); i++) {
gSaveContext.scarecrowSpawnSong[i] = 0;
gSaveContext.scarecrowSpawnSong[i].noteIdx = 0;
gSaveContext.scarecrowSpawnSong[i].unk_01 = 0;
gSaveContext.scarecrowSpawnSong[i].unk_02 = 0;
gSaveContext.scarecrowSpawnSong[i].volume = 0;
gSaveContext.scarecrowSpawnSong[i].vibrato = 0;
gSaveContext.scarecrowSpawnSong[i].tone = 0;
gSaveContext.scarecrowSpawnSong[i].semitone = 0;
}
gSaveContext.horseData.scene = SCENE_SPOT00;
@ -700,12 +713,172 @@ void SaveManager::LoadBaseVersion1() {
});
SaveManager::Instance->LoadData("worldMapAreaData", gSaveContext.worldMapAreaData);
SaveManager::Instance->LoadData("scarecrowCustomSongSet", gSaveContext.scarecrowCustomSongSet);
SaveManager::Instance->LoadArray("scarecrowCustomSong", sizeof(gSaveContext.scarecrowCustomSong), [](size_t i) {
SaveManager::Instance->LoadData("", ((u8*)&gSaveContext.scarecrowCustomSong)[i]);
});
SaveManager::Instance->LoadData("scarecrowSpawnSongSet", gSaveContext.scarecrowSpawnSongSet);
SaveManager::Instance->LoadArray("scarecrowSpawnSong", sizeof(gSaveContext.scarecrowSpawnSong), [](size_t i) {
SaveManager::Instance->LoadData("", ((u8*)&gSaveContext.scarecrowSpawnSong)[i]);
});
SaveManager::Instance->LoadStruct("horseData", []() {
SaveManager::Instance->LoadData("scene", gSaveContext.horseData.scene);
SaveManager::Instance->LoadStruct("pos", []() {
SaveManager::Instance->LoadData("x", gSaveContext.horseData.pos.x);
SaveManager::Instance->LoadData("y", gSaveContext.horseData.pos.y);
SaveManager::Instance->LoadData("z", gSaveContext.horseData.pos.z);
});
SaveManager::Instance->LoadData("angle", gSaveContext.horseData.angle);
});
SaveManager::Instance->LoadArray("dungeonsDone", ARRAY_COUNT(gSaveContext.dungeonsDone), [](size_t i) {
SaveManager::Instance->LoadData("", gSaveContext.dungeonsDone[i]);
});
SaveManager::Instance->LoadArray("trialsDone", ARRAY_COUNT(gSaveContext.trialsDone),
[](size_t i) { SaveManager::Instance->LoadData("", gSaveContext.trialsDone[i]); });
}
void SaveManager::LoadBaseVersion2() {
SaveManager::Instance->LoadData("entranceIndex", gSaveContext.entranceIndex);
SaveManager::Instance->LoadData("linkAge", gSaveContext.linkAge);
SaveManager::Instance->LoadData("cutsceneIndex", gSaveContext.cutsceneIndex);
SaveManager::Instance->LoadData("dayTime", gSaveContext.dayTime);
SaveManager::Instance->LoadData("nightFlag", gSaveContext.nightFlag);
SaveManager::Instance->LoadData("totalDays", gSaveContext.totalDays);
SaveManager::Instance->LoadData("bgsDayCount", gSaveContext.bgsDayCount);
SaveManager::Instance->LoadData("deaths", gSaveContext.deaths);
SaveManager::Instance->LoadArray("playerName", ARRAY_COUNT(gSaveContext.playerName), [](size_t i) {
SaveManager::Instance->LoadData("", gSaveContext.playerName[i]);
});
SaveManager::Instance->LoadData("n64ddFlag", gSaveContext.n64ddFlag);
SaveManager::Instance->LoadData("healthCapacity", gSaveContext.healthCapacity);
SaveManager::Instance->LoadData("health", gSaveContext.health);
SaveManager::Instance->LoadData("magicLevel", gSaveContext.magicLevel);
SaveManager::Instance->LoadData("magic", gSaveContext.magic);
SaveManager::Instance->LoadData("rupees", gSaveContext.rupees);
SaveManager::Instance->LoadData("swordHealth", gSaveContext.swordHealth);
SaveManager::Instance->LoadData("naviTimer", gSaveContext.naviTimer);
SaveManager::Instance->LoadData("magicAcquired", gSaveContext.magicAcquired);
SaveManager::Instance->LoadData("doubleMagic", gSaveContext.doubleMagic);
SaveManager::Instance->LoadData("doubleDefense", gSaveContext.doubleDefense);
SaveManager::Instance->LoadData("bgsFlag", gSaveContext.bgsFlag);
SaveManager::Instance->LoadData("ocarinaGameRoundNum", gSaveContext.ocarinaGameRoundNum);
SaveManager::Instance->LoadStruct("childEquips", []() {
SaveManager::Instance->LoadArray("buttonItems", ARRAY_COUNT(gSaveContext.childEquips.buttonItems), [](size_t i) {
SaveManager::Instance->LoadData("", gSaveContext.childEquips.buttonItems[i],
static_cast<uint8_t>(ITEM_NONE));
});
SaveManager::Instance->LoadArray("cButtonSlots", ARRAY_COUNT(gSaveContext.childEquips.cButtonSlots), [](size_t i) {
SaveManager::Instance->LoadData("", gSaveContext.childEquips.cButtonSlots[i],
static_cast<uint8_t>(SLOT_NONE));
});
SaveManager::Instance->LoadData("equipment", gSaveContext.childEquips.equipment);
});
SaveManager::Instance->LoadStruct("adultEquips", []() {
SaveManager::Instance->LoadArray("buttonItems", ARRAY_COUNT(gSaveContext.adultEquips.buttonItems), [](size_t i) {
SaveManager::Instance->LoadData("", gSaveContext.adultEquips.buttonItems[i],
static_cast<uint8_t>(ITEM_NONE));
});
SaveManager::Instance->LoadArray("cButtonSlots", ARRAY_COUNT(gSaveContext.adultEquips.cButtonSlots), [](size_t i) {
SaveManager::Instance->LoadData("", gSaveContext.adultEquips.cButtonSlots[i],
static_cast<uint8_t>(SLOT_NONE));
});
SaveManager::Instance->LoadData("equipment", gSaveContext.adultEquips.equipment);
});
SaveManager::Instance->LoadData("unk_54", gSaveContext.unk_54);
SaveManager::Instance->LoadData("savedSceneNum", gSaveContext.savedSceneNum);
SaveManager::Instance->LoadStruct("equips", []() {
SaveManager::Instance->LoadArray("buttonItems", ARRAY_COUNT(gSaveContext.equips.buttonItems), [](size_t i) {
SaveManager::Instance->LoadData("", gSaveContext.equips.buttonItems[i], static_cast<uint8_t>(ITEM_NONE));
});
SaveManager::Instance->LoadArray("cButtonSlots", ARRAY_COUNT(gSaveContext.equips.cButtonSlots), [](size_t i) {
SaveManager::Instance->LoadData("", gSaveContext.equips.cButtonSlots[i], static_cast<uint8_t>(SLOT_NONE));
});
SaveManager::Instance->LoadData("equipment", gSaveContext.equips.equipment);
});
SaveManager::Instance->LoadStruct("inventory", []() {
SaveManager::Instance->LoadArray("items", ARRAY_COUNT(gSaveContext.inventory.items), [](size_t i) {
SaveManager::Instance->LoadData("", gSaveContext.inventory.items[i]);
});
SaveManager::Instance->LoadArray("ammo", ARRAY_COUNT(gSaveContext.inventory.ammo), [](size_t i) {
SaveManager::Instance->LoadData("", gSaveContext.inventory.ammo[i]);
});
SaveManager::Instance->LoadData("equipment", gSaveContext.inventory.equipment);
SaveManager::Instance->LoadData("upgrades", gSaveContext.inventory.upgrades);
SaveManager::Instance->LoadData("questItems", gSaveContext.inventory.questItems);
SaveManager::Instance->LoadArray("dungeonItems", ARRAY_COUNT(gSaveContext.inventory.dungeonItems), [](size_t i) {
SaveManager::Instance->LoadData("", gSaveContext.inventory.dungeonItems[i]);
});
SaveManager::Instance->LoadArray("dungeonKeys", ARRAY_COUNT(gSaveContext.inventory.dungeonKeys), [](size_t i) {
SaveManager::Instance->LoadData("", gSaveContext.inventory.dungeonKeys[i]);
});
SaveManager::Instance->LoadData("defenseHearts", gSaveContext.inventory.defenseHearts);
SaveManager::Instance->LoadData("gsTokens", gSaveContext.inventory.gsTokens);
});
SaveManager::Instance->LoadArray("sceneFlags", ARRAY_COUNT(gSaveContext.sceneFlags), [](size_t i) {
SaveManager::Instance->LoadStruct("", [&i]() {
SaveManager::Instance->LoadData("chest", gSaveContext.sceneFlags[i].chest);
SaveManager::Instance->LoadData("swch", gSaveContext.sceneFlags[i].swch);
SaveManager::Instance->LoadData("clear", gSaveContext.sceneFlags[i].clear);
SaveManager::Instance->LoadData("collect", gSaveContext.sceneFlags[i].collect);
SaveManager::Instance->LoadData("unk", gSaveContext.sceneFlags[i].unk);
SaveManager::Instance->LoadData("rooms", gSaveContext.sceneFlags[i].rooms);
SaveManager::Instance->LoadData("floors", gSaveContext.sceneFlags[i].floors);
});
});
SaveManager::Instance->LoadStruct("fw", []() {
SaveManager::Instance->LoadStruct("pos", []() {
SaveManager::Instance->LoadData("x", gSaveContext.fw.pos.x);
SaveManager::Instance->LoadData("y", gSaveContext.fw.pos.y);
SaveManager::Instance->LoadData("z", gSaveContext.fw.pos.z);
});
SaveManager::Instance->LoadData("yaw", gSaveContext.fw.yaw);
SaveManager::Instance->LoadData("playerParams", gSaveContext.fw.playerParams);
SaveManager::Instance->LoadData("entranceIndex", gSaveContext.fw.entranceIndex);
SaveManager::Instance->LoadData("roomIndex", gSaveContext.fw.roomIndex);
SaveManager::Instance->LoadData("set", gSaveContext.fw.set);
SaveManager::Instance->LoadData("tempSwchFlags", gSaveContext.fw.tempSwchFlags);
SaveManager::Instance->LoadData("tempCollectFlags", gSaveContext.fw.tempCollectFlags);
});
SaveManager::Instance->LoadArray("gsFlags", ARRAY_COUNT(gSaveContext.gsFlags), [](size_t i) {
SaveManager::Instance->LoadData("", gSaveContext.gsFlags[i]);
});
SaveManager::Instance->LoadArray("highScores", ARRAY_COUNT(gSaveContext.highScores), [](size_t i) {
SaveManager::Instance->LoadData("", gSaveContext.highScores[i]);
});
SaveManager::Instance->LoadArray("eventChkInf", ARRAY_COUNT(gSaveContext.eventChkInf), [](size_t i) {
SaveManager::Instance->LoadData("", gSaveContext.eventChkInf[i]);
});
SaveManager::Instance->LoadArray("itemGetInf", ARRAY_COUNT(gSaveContext.itemGetInf), [](size_t i) {
SaveManager::Instance->LoadData("", gSaveContext.itemGetInf[i]);
});
SaveManager::Instance->LoadArray("infTable", ARRAY_COUNT(gSaveContext.infTable), [](size_t i) {
SaveManager::Instance->LoadData("", gSaveContext.infTable[i]);
});
SaveManager::Instance->LoadData("worldMapAreaData", gSaveContext.worldMapAreaData);
SaveManager::Instance->LoadData("scarecrowCustomSongSet", gSaveContext.scarecrowCustomSongSet);
SaveManager::Instance->LoadArray("scarecrowCustomSong", ARRAY_COUNT(gSaveContext.scarecrowCustomSong), [](size_t i) {
SaveManager::Instance->LoadData("", gSaveContext.scarecrowCustomSong[i]);
SaveManager::Instance->LoadStruct("", [&i]() {
SaveManager::Instance->LoadData("noteIdx", gSaveContext.scarecrowCustomSong[i].noteIdx);
SaveManager::Instance->LoadData("unk_01", gSaveContext.scarecrowCustomSong[i].unk_01);
SaveManager::Instance->LoadData("unk_02", gSaveContext.scarecrowCustomSong[i].unk_02);
SaveManager::Instance->LoadData("volume", gSaveContext.scarecrowCustomSong[i].volume);
SaveManager::Instance->LoadData("vibrato", gSaveContext.scarecrowCustomSong[i].vibrato);
SaveManager::Instance->LoadData("tone", gSaveContext.scarecrowCustomSong[i].tone);
SaveManager::Instance->LoadData("semitone", gSaveContext.scarecrowCustomSong[i].semitone);
});
});
SaveManager::Instance->LoadData("scarecrowSpawnSongSet", gSaveContext.scarecrowSpawnSongSet);
SaveManager::Instance->LoadArray("scarecrowSpawnSong", ARRAY_COUNT(gSaveContext.scarecrowSpawnSong), [](size_t i) {
SaveManager::Instance->LoadData("", gSaveContext.scarecrowSpawnSong[i]);
SaveManager::Instance->LoadStruct("", [&i]() {
SaveManager::Instance->LoadData("noteIdx", gSaveContext.scarecrowSpawnSong[i].noteIdx);
SaveManager::Instance->LoadData("unk_01", gSaveContext.scarecrowSpawnSong[i].unk_01);
SaveManager::Instance->LoadData("unk_02", gSaveContext.scarecrowSpawnSong[i].unk_02);
SaveManager::Instance->LoadData("volume", gSaveContext.scarecrowSpawnSong[i].volume);
SaveManager::Instance->LoadData("vibrato", gSaveContext.scarecrowSpawnSong[i].vibrato);
SaveManager::Instance->LoadData("tone", gSaveContext.scarecrowSpawnSong[i].tone);
SaveManager::Instance->LoadData("semitone", gSaveContext.scarecrowSpawnSong[i].semitone);
});
});
SaveManager::Instance->LoadStruct("horseData", []() {
SaveManager::Instance->LoadData("scene", gSaveContext.horseData.scene);
@ -841,11 +1014,27 @@ void SaveManager::SaveBase() {
SaveManager::Instance->SaveData("worldMapAreaData", gSaveContext.worldMapAreaData);
SaveManager::Instance->SaveData("scarecrowCustomSongSet", gSaveContext.scarecrowCustomSongSet);
SaveManager::Instance->SaveArray("scarecrowCustomSong", ARRAY_COUNT(gSaveContext.scarecrowCustomSong), [](size_t i) {
SaveManager::Instance->SaveData("", gSaveContext.scarecrowCustomSong[i]);
SaveManager::Instance->SaveStruct("", [&i]() {
SaveManager::Instance->SaveData("noteIdx", gSaveContext.scarecrowCustomSong[i].noteIdx);
SaveManager::Instance->SaveData("unk_01", gSaveContext.scarecrowCustomSong[i].unk_01);
SaveManager::Instance->SaveData("unk_02", gSaveContext.scarecrowCustomSong[i].unk_02);
SaveManager::Instance->SaveData("volume", gSaveContext.scarecrowCustomSong[i].volume);
SaveManager::Instance->SaveData("vibrato", gSaveContext.scarecrowCustomSong[i].vibrato);
SaveManager::Instance->SaveData("tone", gSaveContext.scarecrowCustomSong[i].tone);
SaveManager::Instance->SaveData("semitone", gSaveContext.scarecrowCustomSong[i].semitone);
});
});
SaveManager::Instance->SaveData("scarecrowSpawnSongSet", gSaveContext.scarecrowSpawnSongSet);
SaveManager::Instance->SaveArray("scarecrowSpawnSong", ARRAY_COUNT(gSaveContext.scarecrowSpawnSong), [](size_t i) {
SaveManager::Instance->SaveData("", gSaveContext.scarecrowSpawnSong[i]);
SaveManager::Instance->SaveStruct("", [&i]() {
SaveManager::Instance->SaveData("noteIdx", gSaveContext.scarecrowSpawnSong[i].noteIdx);
SaveManager::Instance->SaveData("unk_01", gSaveContext.scarecrowSpawnSong[i].unk_01);
SaveManager::Instance->SaveData("unk_02", gSaveContext.scarecrowSpawnSong[i].unk_02);
SaveManager::Instance->SaveData("volume", gSaveContext.scarecrowSpawnSong[i].volume);
SaveManager::Instance->SaveData("vibrato", gSaveContext.scarecrowSpawnSong[i].vibrato);
SaveManager::Instance->SaveData("tone", gSaveContext.scarecrowSpawnSong[i].tone);
SaveManager::Instance->SaveData("semitone", gSaveContext.scarecrowSpawnSong[i].semitone);
});
});
SaveManager::Instance->SaveStruct("horseData", []() {
SaveManager::Instance->SaveData("scene", gSaveContext.horseData.scene);
@ -1252,13 +1441,9 @@ void CopyV0Save(SaveContext_v0& src, SaveContext& dst) {
}
dst.worldMapAreaData = src.worldMapAreaData;
dst.scarecrowCustomSongSet = src.scarecrowCustomSongSet;
for (size_t i = 0; i < ARRAY_COUNT(src.scarecrowCustomSong); i++) {
dst.scarecrowCustomSong[i] = src.scarecrowCustomSong[i];
}
memcpy(&dst.scarecrowCustomSong[0], &src.scarecrowCustomSong[0], sizeof(src.scarecrowCustomSong));
dst.scarecrowSpawnSongSet = src.scarecrowSpawnSongSet;
for (size_t i = 0; i < ARRAY_COUNT(src.scarecrowSpawnSong); i++) {
dst.scarecrowSpawnSong[i] = src.scarecrowSpawnSong[i];
}
memcpy(&dst.scarecrowSpawnSong[0], &src.scarecrowSpawnSong[0], sizeof(src.scarecrowSpawnSong));
dst.horseData.scene = src.horseData.scene;
dst.horseData.pos.x = src.horseData.pos.x;
dst.horseData.pos.y = src.horseData.pos.y;

View File

@ -117,6 +117,7 @@ public:
static void SaveRandomizer();
static void LoadBaseVersion1();
static void LoadBaseVersion2();
static void SaveBase();
std::vector<InitFunc> initFuncs;

View File

@ -544,10 +544,10 @@ u8 gDefaultShortNoteGateTimeTable[] = {
};
AdsrEnvelope gDefaultEnvelope[] = {
{ 0x0100, 0x007D },
{ 0xE803, 0x007D },
{ 0xFFFF, 0x0000 },
{ 0x0000, 0x0000 },
{ BE16SWAP_CONST(1), BE16SWAP_CONST(32000) },
{ BE16SWAP_CONST(1000), BE16SWAP_CONST(32000) },
{ BE16SWAP_CONST(-1), BE16SWAP_CONST(0) },
{ BE16SWAP_CONST(0), BE16SWAP_CONST(0) },
};
NoteSubEu gZeroNoteSub = { 0 };

View File

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

View File

@ -1340,13 +1340,13 @@ void AudioSeq_SequenceChannelProcessScript(SequenceChannel* channel) {
break;
case 0xB2:
offset = (u16)parameters[0];
channel->unk_22 = BOMSWAP16(*(u16*)(seqPlayer->seqData + (uintptr_t)(offset + scriptState->value * 2)));
channel->unk_22 = BE16SWAP(*(u16*)(seqPlayer->seqData + (uintptr_t)(offset + scriptState->value * 2)));
break;
case 0xB4:
channel->dynTable = (void*)&seqPlayer->seqData[channel->unk_22];
break;
case 0xB5:
channel->unk_22 = BOMSWAP16(((u16*)(channel->dynTable))[scriptState->value]);
channel->unk_22 = BE16SWAP(((u16*)(channel->dynTable))[scriptState->value]);
break;
case 0xB6:
scriptState->value = (*channel->dynTable)[0][scriptState->value];

View File

@ -355,36 +355,20 @@ void func_8002BF60(TargetContext* targetCtx, Actor* actor, s32 actorCategory, Gl
}
} else {
if (actorCategory == ACTORCAT_PLAYER) {
naviColor->inner.r = CVar_GetS32("gNavi_Idle_Inner_R", naviColor->inner.r);
naviColor->inner.g = CVar_GetS32("gNavi_Idle_Inner_G", naviColor->inner.g);
naviColor->inner.b = CVar_GetS32("gNavi_Idle_Inner_B", naviColor->inner.b);
naviColor->outer.r = CVar_GetS32("gNavi_Idle_Outer_R", naviColor->outer.r);
naviColor->outer.g = CVar_GetS32("gNavi_Idle_Outer_G", naviColor->outer.g);
naviColor->outer.b = CVar_GetS32("gNavi_Idle_Outer_B", naviColor->outer.b);
naviColor->inner = CVar_GetRGBA("gNavi_Idle_Inner", naviColor->inner);
naviColor->outer = CVar_GetRGBA("gNavi_Idle_Outer", naviColor->outer);
}
if (actorCategory == ACTORCAT_NPC) {
naviColor->inner.r = CVar_GetS32("gNavi_NPC_Inner_R", naviColor->inner.r);
naviColor->inner.g = CVar_GetS32("gNavi_NPC_Inner_G", naviColor->inner.g);
naviColor->inner.b = CVar_GetS32("gNavi_NPC_Inner_B", naviColor->inner.b);
naviColor->outer.r = CVar_GetS32("gNavi_NPC_Outer_R", naviColor->outer.r);
naviColor->outer.g = CVar_GetS32("gNavi_NPC_Outer_G", naviColor->outer.g);
naviColor->outer.b = CVar_GetS32("gNavi_NPC_Outer_B", naviColor->outer.b);
naviColor->inner = CVar_GetRGBA("gNavi_NPC_Inner", naviColor->inner);
naviColor->outer = CVar_GetRGBA("gNavi_NPC_Outer", naviColor->outer);
}
if (actorCategory == ACTORCAT_BOSS || actorCategory == ACTORCAT_ENEMY) {
naviColor->inner.r = CVar_GetS32("gNavi_Enemy_Inner_R", naviColor->inner.r);
naviColor->inner.g = CVar_GetS32("gNavi_Enemy_Inner_G", naviColor->inner.g);
naviColor->inner.b = CVar_GetS32("gNavi_Enemy_Inner_B", naviColor->inner.b);
naviColor->outer.r = CVar_GetS32("gNavi_Enemy_Outer_R", naviColor->outer.r);
naviColor->outer.g = CVar_GetS32("gNavi_Enemy_Outer_G", naviColor->outer.g);
naviColor->outer.b = CVar_GetS32("gNavi_Enemy_Outer_B", naviColor->outer.b);
naviColor->inner = CVar_GetRGBA("gNavi_Enemy_Inner", naviColor->inner);
naviColor->outer = CVar_GetRGBA("gNavi_Enemy_Outer", naviColor->outer);
}
if (actorCategory == ACTORCAT_PROP) {
naviColor->inner.r = CVar_GetS32("gNavi_Prop_Inner_R", naviColor->inner.r);
naviColor->inner.g = CVar_GetS32("gNavi_Prop_Inner_G", naviColor->inner.g);
naviColor->inner.b = CVar_GetS32("gNavi_Prop_Inner_B", naviColor->inner.b);
naviColor->outer.r = CVar_GetS32("gNavi_Prop_Outer_R", naviColor->outer.r);
naviColor->outer.g = CVar_GetS32("gNavi_Prop_Outer_G", naviColor->outer.g);
naviColor->outer.b = CVar_GetS32("gNavi_Prop_Outer_B", naviColor->outer.b);
naviColor->inner = CVar_GetRGBA("gNavi_Prop_Inner", naviColor->inner);
naviColor->outer = CVar_GetRGBA("gNavi_Prop_Outer", naviColor->outer);
}
}

View File

@ -8,7 +8,7 @@ void SaveContext_Init(void) {
gSaveContext.seqId = (u8)NA_BGM_DISABLED;
gSaveContext.natureAmbienceId = NATURE_ID_DISABLED;
gSaveContext.forcedSeqId = NA_BGM_GENERAL_SFX;
gSaveContext.nextCutsceneIndex = 0xFFEF;
gSaveContext.nextCutsceneIndex = CVar_GetS32("gBetaQuestWorld", 0xFFEF);
gSaveContext.cutsceneTrigger = 0;
gSaveContext.chamberCutsceneNum = 0;
gSaveContext.nextDayTime = 0xFFFF;

View File

@ -8,7 +8,6 @@ void func_80110990(GlobalContext* globalCtx) {
void func_801109B0(GlobalContext* globalCtx) {
InterfaceContext* interfaceCtx = &globalCtx->interfaceCtx;
u32 parameterSize;
u16 doActionOffset;
u8 temp;
gSaveContext.sunsSongState = SUNSSONG_INACTIVE;
@ -49,30 +48,11 @@ void func_801109B0(GlobalContext* globalCtx) {
ASSERT(interfaceCtx->doActionSegment != NULL);
if (gSaveContext.language == LANGUAGE_ENG) {
doActionOffset = 0;
} else if (gSaveContext.language == LANGUAGE_GER) {
doActionOffset = 0x2B80;
} else {
doActionOffset = 0x5700;
}
uint32_t attackDoActionTexSize = ResourceMgr_LoadTexSizeByName(gAttackDoActionENGTex);
memcpy(interfaceCtx->doActionSegment, ResourceMgr_LoadTexByName(gAttackDoActionENGTex), attackDoActionTexSize);
memcpy(interfaceCtx->doActionSegment + (attackDoActionTexSize / 2), ResourceMgr_LoadTexByName(gCheckDoActionENGTex), attackDoActionTexSize);
memcpy(interfaceCtx->doActionSegment, ResourceMgr_LoadTexByName(gAttackDoActionENGTex), 0x180);
memcpy(interfaceCtx->doActionSegment + 0x180, ResourceMgr_LoadTexByName(gCheckDoActionENGTex), 0x180);
//DmaMgr_SendRequest1(interfaceCtx->doActionSegment, (uintptr_t)_do_action_staticSegmentRomStart + doActionOffset, 0x300,
//__FILE__, __LINE__);
if (gSaveContext.language == LANGUAGE_ENG) {
doActionOffset = 0x480;
} else if (gSaveContext.language == LANGUAGE_GER) {
doActionOffset = 0x3000;
} else {
doActionOffset = 0x5B80;
}
memcpy(interfaceCtx->doActionSegment + 0x300, ResourceMgr_LoadTexByName(gReturnDoActionENGTex), 0x180);
//DmaMgr_SendRequest1(interfaceCtx->doActionSegment + 0x300, (uintptr_t)_do_action_staticSegmentRomStart + doActionOffset,
//0x180);
memcpy(interfaceCtx->doActionSegment + attackDoActionTexSize, ResourceMgr_LoadTexByName(gReturnDoActionENGTex), ResourceMgr_LoadTexSizeByName(gReturnDoActionENGTex));
interfaceCtx->iconItemSegment = GAMESTATE_ALLOC_MC(
&globalCtx->state, 0x1000 * ARRAY_COUNT(gSaveContext.equips.buttonItems));

View File

@ -493,7 +493,8 @@ void Cutscene_Command_Terminator(GlobalContext* globalCtx, CutsceneContext* csCt
// Automatically skip certain cutscenes when in rando
// cmd->base == 33: Zelda escaping with impa cutscene
bool randoCsSkip = (gSaveContext.n64ddFlag && cmd->base == 33);
// cmd->base == 8: Traveling back/forward in time cutscene
bool randoCsSkip = (gSaveContext.n64ddFlag && (cmd->base == 33 || cmd->base == 8));
bool debugCsSkip = (CHECK_BTN_ALL(globalCtx->state.input[0].press.button, BTN_START) &&
(gSaveContext.fileNum != 0xFEDC) && CVar_GetS32("gDebugEnabled", 0));

View File

@ -184,16 +184,6 @@ static u16 sDgnMinimapTexIndexOffset[10] = {
0, 13, 32, 49, 76, 114, 158, 190, 217, 227,
};
static u16 sOwMinimapTexSize[24] = {
2920, 2560, 1560, 2784, 2976, 2040, 3240, 2336, 2080, 2600, 1792, 1888,
3400, 1792, 1888, 2040, 3120, 2304, 2176, 1888, 1560, 3240, 2600, 3400,
};
static u16 sOwMinimapTexOffset[24] = {
0x0000, 0x0B68, 0x1568, 0x1B80, 0x2660, 0x3200, 0x39F8, 0x46A0, 0x4FC0, 0x57E0, 0x6208, 0x6908,
0x7068, 0x7DB0, 0x84B0, 0x8C10, 0x9408, 0xA038, 0xA938, 0xB1B8, 0xB918, 0xBF30, 0xCBD8, 0xD600,
};
static s16 sOwMinimapPosX[24] = {
216, 216, 218, 202, 202, 250, 216, 234, 234, 216, 234, 234,
216, 234, 234, 250, 216, 234, 234, 234, 218, 80, 80, 216,
@ -322,11 +312,10 @@ MapData gMapDataTable = {
sFloorTexIndexOffset, sBossFloor, sRoomPalette,
sMaxPaletteCount, sPaletteRoom, sRoomCompassOffsetX,
sRoomCompassOffsetY, sDgnMinimapCount, sDgnMinimapTexIndexOffset,
sOwMinimapTexSize, sOwMinimapTexOffset, sOwMinimapPosX,
sOwMinimapPosY, sOwCompassInfo, sDgnMinimapTexIndexBase,
sDgnCompassInfo, sOwMinimapWidth, sOwMinimapHeight,
sOwEntranceIconPosX, sOwEntranceIconPosY, sOwEntranceFlag,
sFloorCoordY, sSwitchEntryCount, sSwitchFromRoom,
sSwitchFromFloor, sSwitchToRoom, sFloorID,
sSkullFloorIconY,
sOwMinimapPosX, sOwMinimapPosY, sOwCompassInfo,
sDgnMinimapTexIndexBase, sDgnCompassInfo, sOwMinimapWidth,
sOwMinimapHeight, sOwEntranceIconPosX, sOwEntranceIconPosY,
sOwEntranceFlag, sFloorCoordY, sSwitchEntryCount,
sSwitchFromRoom, sSwitchFromFloor, sSwitchToRoom,
sFloorID, sSkullFloorIconY,
};

View File

@ -412,8 +412,10 @@ void Map_InitData(GlobalContext* globalCtx, s16 room) {
//(uintptr_t)_map_grand_staticSegmentRomStart + gMapData->owMinimapTexOffset[extendedMapIndex],
//gMapData->owMinimapTexSize[mapIndex], __FILE__, __LINE__);
if (sEntranceIconMapIndex < 24)
memcpy(globalCtx->interfaceCtx.mapSegment, ResourceMgr_LoadTexByName(minimapTableOW[sEntranceIconMapIndex]), gMapData->owMinimapTexSize[mapIndex]);
if (sEntranceIconMapIndex < 24) {
const char* textureName = minimapTableOW[sEntranceIconMapIndex];
memcpy(globalCtx->interfaceCtx.mapSegment, ResourceMgr_LoadTexByName(textureName), ResourceMgr_LoadTexSizeByName(textureName));
}
interfaceCtx->unk_258 = mapIndex;
break;
@ -445,7 +447,8 @@ void Map_InitData(GlobalContext* globalCtx, s16 room) {
//((gMapData->dgnMinimapTexIndexOffset[mapIndex] + room) * 0xFF0),
//0xFF0, __FILE__, __LINE__);
memcpy(globalCtx->interfaceCtx.mapSegment, ResourceMgr_LoadTexByName(minimapTableDangeon[gMapData->dgnMinimapTexIndexOffset[mapIndex] + room]), 0xFF0);
const char* textureName = minimapTableDangeon[gMapData->dgnMinimapTexIndexOffset[mapIndex] + room];
memcpy(globalCtx->interfaceCtx.mapSegment, ResourceMgr_LoadTexByName(textureName), ResourceMgr_LoadTexSizeByName(textureName));
R_COMPASS_OFFSET_X = gMapData->roomCompassOffsetX[mapIndex][room];
R_COMPASS_OFFSET_Y = gMapData->roomCompassOffsetY[mapIndex][room];

View File

@ -1196,7 +1196,7 @@ void Message_LoadItemIcon(GlobalContext* globalCtx, u16 itemId, s16 y) {
R_TEXTBOX_ICON_YPOS = y + 6;
R_TEXTBOX_ICON_SIZE = 32;
memcpy((uintptr_t)msgCtx->textboxSegment + MESSAGE_STATIC_TEX_SIZE,
ResourceMgr_LoadTexByName(gItemIcons[itemId]), 0x1000);
ResourceMgr_LoadTexByName(gItemIcons[itemId]), ResourceMgr_LoadTexSizeByName(gItemIcons[itemId]));
// "Item 32-0"
osSyncPrintf("アイテム32-0\n");
} else {
@ -1204,7 +1204,7 @@ void Message_LoadItemIcon(GlobalContext* globalCtx, u16 itemId, s16 y) {
R_TEXTBOX_ICON_YPOS = y + 10;
R_TEXTBOX_ICON_SIZE = 24;
memcpy((uintptr_t)msgCtx->textboxSegment + MESSAGE_STATIC_TEX_SIZE,
ResourceMgr_LoadTexByName(gItemIcons[itemId]), 0x900);
ResourceMgr_LoadTexByName(gItemIcons[itemId]), ResourceMgr_LoadTexSizeByName(gItemIcons[itemId]));
// "Item 24"
osSyncPrintf("アイテム24%d (%d) {%d}\n", itemId, itemId - ITEM_KOKIRI_EMERALD, 84);
}
@ -1565,9 +1565,9 @@ void Message_Decode(GlobalContext* globalCtx) {
msgCtx->textboxBackgroundUnkArg = font->msgBuf[msgCtx->msgBufPos + 3] & 0xF;
memcpy((uintptr_t)msgCtx->textboxSegment + MESSAGE_STATIC_TEX_SIZE,
ResourceMgr_LoadTexByName(gRedMessageXLeftTex), 0x900);
ResourceMgr_LoadTexByName(gRedMessageXLeftTex), ResourceMgr_LoadTexSizeByName(gRedMessageXLeftTex));
memcpy((uintptr_t)msgCtx->textboxSegment + MESSAGE_STATIC_TEX_SIZE + 0x900,
ResourceMgr_LoadTexByName(gRedMessageXRightTex), 0x900);
ResourceMgr_LoadTexByName(gRedMessageXRightTex), ResourceMgr_LoadTexSizeByName(gRedMessageXRightTex));
msgCtx->msgBufPos += 3;
R_TEXTBOX_BG_YPOS = R_TEXTBOX_Y + 8;
@ -1688,7 +1688,8 @@ void Message_OpenText(GlobalContext* globalCtx, u16 textId) {
// "Text Box Type"
osSyncPrintf("吹き出し種類=%d\n", msgCtx->textBoxType);
if (textBoxType < TEXTBOX_TYPE_NONE_BOTTOM) {
memcpy(msgCtx->textboxSegment, ResourceMgr_LoadTexByName(msgStaticTbl[messageStaticIndices[textBoxType]]), MESSAGE_STATIC_TEX_SIZE);
const char* textureName = msgStaticTbl[messageStaticIndices[textBoxType]];
memcpy(msgCtx->textboxSegment, ResourceMgr_LoadTexByName(textureName), MESSAGE_STATIC_TEX_SIZE);
if (textBoxType == TEXTBOX_TYPE_BLACK) {
msgCtx->textboxColorRed = 0;
msgCtx->textboxColorGreen = 0;

View File

@ -1041,18 +1041,37 @@ s32 OnePointCutscene_SetInfo(GlobalContext* globalCtx, s16 camIdx, s16 csId, Act
func_800C0808(globalCtx, camIdx, player, CAM_SET_CS_C);
break;
case 4020:
if (CVar_GetS32("gFasterHeavyBlockLift", 0)) {
D_8012368C[0].timerInit *= (1.0f / 3.0f);
D_8012368C[1].timerInit *= (1.0f / 3.0f);
D_8012368C[2].timerInit *= (1.0f / 3.0f);
D_8012368C[3].timerInit *= (1.0f / 3.0f);
}
csInfo->keyFrames = D_8012368C;
csInfo->keyFrameCnt = 4;
func_800C0808(globalCtx, camIdx, player, CAM_SET_CS_C);
break;
case 4021:
if (CVar_GetS32("gFasterHeavyBlockLift", 0)) {
D_8012372C[0].timerInit *= (1.0f / 3.0f);
D_8012372C[1].timerInit *= (1.0f / 3.0f);
D_8012372C[2].timerInit *= (1.0f / 3.0f);
D_8012372C[3].timerInit *= (1.0f / 3.0f);
}
csInfo->keyFrames = D_8012372C;
csInfo->keyFrameCnt = 4;
func_800C0808(globalCtx, camIdx, player, CAM_SET_CS_C);
break;
case 4022:
if (CVar_GetS32("gFasterHeavyBlockLift", 0)) {
D_801237CC[0].timerInit *= (1.0f / 3.0f);
D_801237CC[1].timerInit *= (1.0f / 3.0f);
D_801237CC[2].timerInit *= (1.0f / 3.0f);
D_801237CC[3].timerInit *= (1.0f / 3.0f);
D_801237CC[4].timerInit *= (1.0f / 3.0f);
}
csCam->timer = D_801237CC[0].timerInit + D_801237CC[3].timerInit + D_801237CC[1].timerInit +
D_801237CC[2].timerInit + D_801237CC[4].timerInit;

View File

@ -624,21 +624,21 @@ static OnePointCsFull D_801235C4[5] = {
{ 0x12, 0xFF, 0x0000, 1, 0, 60.0f, 1.0f, { -1.0f, -1.0f, -1.0f }, { -1.0f, -1.0f, -1.0f } },
};
static OnePointCsFull D_8012368C[4] = {
OnePointCsFull D_8012368C[4] = {
{ 0x0F, 0xFF, 0x0101, 10, 0, 60.0f, 1.0f, { -1110.0f, -180.0f, -840.0f }, { -985.0f, -220.0f, -840.0f } },
{ 0x02, 0xFF, 0x0101, 70, -45, 75.0f, 1.0f, { -1060.0f, -160.0f, -840.0f }, { -1005.0f, -230.0f, -840.0f } },
{ 0x0F, 0xFF, 0x0000, 10, -45, 75.0f, 1.0f, { -1.0f, -1.0f, -1.0f }, { -1.0f, -1.0f, -1.0f } },
{ 0x0F, 0xFF, 0x0101, 180, 9, 80.0f, 1.0f, { -1205.0f, -175.0f, -840.0f }, { -1305.0f, -230.0f, -828.0f } },
};
static OnePointCsFull D_8012372C[4] = {
OnePointCsFull D_8012372C[4] = {
{ 0x0F, 0xFF, 0x0142, 10, 0, 70.0f, 1.0f, { 0.0f, 80.0f, 0.0f }, { -1650.0f, 200.0f, -2920.0f } },
{ 0x02, 0xFF, 0x0142, 110, -2, 50.0f, 0.5f, { 0.0f, 150.0f, 0.0f }, { -1320.0f, 170.0f, -2900.0f } },
{ 0x0B, 0xFF, 0x4242, 100, 2, 70.0f, 0.1f, { 0.0f, 150.0f, 50.0f }, { -1.0f, -1.0f, -1.0f } },
{ 0x03, 0xFF, 0x4242, 60, 2, 45.0f, 0.01f, { 0.0f, 150.0f, 50.0f }, { 0.0f, 200.0f, -80.0f } },
};
static OnePointCsFull D_801237CC[5] = {
OnePointCsFull D_801237CC[5] = {
{ 0x8F, 0xFF, 0x4242, 20, 0, 50.0f, 1.0f, { 0.0f, 50.0f, -10.0f }, { 0.0f, 0.0f, 100.0f } },
{ 0x0A, 0xFF, 0x0101, 80, 0, 75.0f, 1.0f, { 2900.0f, 1300.0f, 530.0f }, { 2800.0f, 1190.0f, 540.0f } },
{ 0x0F, 0xFF, 0x0000, 10, 0, 75.0f, 1.0f, { -1.0f, -1.0f, -1.0f }, { -1.0f, -1.0f, -1.0f } },

View File

@ -10,10 +10,31 @@
#include <assert.h>
#endif
// TODO extract this information from the texture definitions themselves
#define DO_ACTION_TEX_WIDTH 48
#define DO_ACTION_TEX_HEIGHT 16
#define DO_ACTION_TEX_SIZE ((DO_ACTION_TEX_WIDTH * DO_ACTION_TEX_HEIGHT) / 2) // (sizeof(gCheckDoActionENGTex))
static uint16_t _doActionTexWidth, _doActionTexHeight = -1;
static uint16_t DO_ACTION_TEX_WIDTH() {
return 48;
// TODO: Figure out why Ship::Texture is not returning a valid width
if (_doActionTexWidth == -1)
_doActionTexWidth = ResourceMgr_LoadTexWidthByName(gCheckDoActionENGTex);
return _doActionTexWidth;
}
static uint16_t DO_ACTION_TEX_HEIGHT() {
return 16;
// TODO: Figure out why Ship::Texture is not returning a valid height
if (_doActionTexHeight == -1)
_doActionTexHeight = ResourceMgr_LoadTexHeightByName(gCheckDoActionENGTex);
return _doActionTexHeight;
}
static uint32_t _doActionTexSize = -1;
static uint32_t DO_ACTION_TEX_SIZE() {
if (_doActionTexSize == -1)
_doActionTexSize = ResourceMgr_LoadTexSizeByName(gCheckDoActionENGTex);
return _doActionTexSize;
}
// The button statuses include the A button when most things are only the equip item buttons
// So, when indexing into it with a item button index, we need to adjust
@ -2457,8 +2478,8 @@ void Interface_LoadActionLabel(InterfaceContext* interfaceCtx, u16 action, s16 l
if (action != DO_ACTION_NONE) {
//osCreateMesgQueue(&interfaceCtx->loadQueue, &interfaceCtx->loadMsg, OS_MESG_BLOCK);
memcpy(interfaceCtx->doActionSegment + (loadOffset * DO_ACTION_TEX_SIZE), ResourceMgr_LoadTexByName(doAction),
DO_ACTION_TEX_SIZE);
memcpy(interfaceCtx->doActionSegment + (loadOffset * DO_ACTION_TEX_SIZE()), ResourceMgr_LoadTexByName(doAction),
DO_ACTION_TEX_SIZE());
//DmaMgr_SendRequest2(&interfaceCtx->dmaRequest_160,
//interfaceCtx->doActionSegment + (loadOffset * DO_ACTION_TEX_SIZE),
//(uintptr_t)_do_action_staticSegmentRomStart + (action * DO_ACTION_TEX_SIZE), DO_ACTION_TEX_SIZE,
@ -2467,7 +2488,7 @@ void Interface_LoadActionLabel(InterfaceContext* interfaceCtx, u16 action, s16 l
} else {
gSegments[7] = VIRTUAL_TO_PHYSICAL(interfaceCtx->doActionSegment);
//func_80086D5C(SEGMENTED_TO_VIRTUAL(sDoActionTextures[loadOffset]), DO_ACTION_TEX_SIZE / 4);
func_80086D5C(interfaceCtx->doActionSegment + (loadOffset * DO_ACTION_TEX_SIZE), DO_ACTION_TEX_SIZE / 4);
func_80086D5C(interfaceCtx->doActionSegment + (loadOffset * DO_ACTION_TEX_SIZE()), DO_ACTION_TEX_SIZE() / 4);
}
}
@ -2545,7 +2566,7 @@ void Interface_LoadActionLabelB(GlobalContext* globalCtx, u16 action) {
// OTRTODO
osCreateMesgQueue(&interfaceCtx->loadQueue, &interfaceCtx->loadMsg, OS_MESG_BLOCK);
memcpy(interfaceCtx->doActionSegment + DO_ACTION_TEX_SIZE, ResourceMgr_LoadTexByName(doAction), DO_ACTION_TEX_SIZE);
memcpy(interfaceCtx->doActionSegment + DO_ACTION_TEX_SIZE(), ResourceMgr_LoadTexByName(doAction), DO_ACTION_TEX_SIZE());
//DmaMgr_SendRequest2(&interfaceCtx->dmaRequest_160, interfaceCtx->doActionSegment + DO_ACTION_TEX_SIZE,
//(uintptr_t)_do_action_staticSegmentRomStart + (action * DO_ACTION_TEX_SIZE), DO_ACTION_TEX_SIZE, 0,
//&interfaceCtx->loadQueue, NULL, __FILE__, __LINE__);
@ -3181,7 +3202,7 @@ void func_80088B34(s16 arg0) {
void Interface_DrawActionLabel(GraphicsContext* gfxCtx, void* texture) {
OPEN_DISPS(gfxCtx);
gDPLoadTextureBlock_4b(OVERLAY_DISP++, texture, G_IM_FMT_IA, DO_ACTION_TEX_WIDTH, DO_ACTION_TEX_HEIGHT, 0,
gDPLoadTextureBlock_4b(OVERLAY_DISP++, texture, G_IM_FMT_IA, DO_ACTION_TEX_WIDTH(), DO_ACTION_TEX_HEIGHT(), 0,
G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD,
G_TX_NOLOD);
@ -3254,8 +3275,8 @@ void Interface_DrawItemButtons(GlobalContext* globalCtx) {
const s16 rStartLabelY_ori = R_START_LABEL_Y(gSaveContext.language)+Y_Margins_StartBtn;
const s16 PosX_StartBtn_ori = OTRGetRectDimensionFromRightEdge(startButtonLeftPos[gSaveContext.language]+X_Margins_StartBtn);
const s16 PosY_StartBtn_ori = 16+Y_Margins_StartBtn;
s16 StartBTN_Label_W = DO_ACTION_TEX_WIDTH;
s16 StartBTN_Label_H = DO_ACTION_TEX_HEIGHT;
s16 StartBTN_Label_W = DO_ACTION_TEX_WIDTH();
s16 StartBTN_Label_H = DO_ACTION_TEX_HEIGHT();
int StartBTN_Label_H_Scaled = StartBTN_Label_H * 1.0f;
int StartBTN_Label_W_Scaled = StartBTN_Label_W * 1.0f;
int StartBTN_Label_W_factor = (1 << 10) * StartBTN_Label_W / StartBTN_Label_W_Scaled;
@ -3511,10 +3532,11 @@ void Interface_DrawItemButtons(GlobalContext* globalCtx) {
}
doAction = newName;
}
memcpy(interfaceCtx->doActionSegment + DO_ACTION_TEX_SIZE * 2, ResourceMgr_LoadTexByName(doAction), DO_ACTION_TEX_SIZE);
gDPLoadTextureBlock_4b(OVERLAY_DISP++, interfaceCtx->doActionSegment + DO_ACTION_TEX_SIZE * 2, G_IM_FMT_IA,
DO_ACTION_TEX_WIDTH, DO_ACTION_TEX_HEIGHT, 0, G_TX_NOMIRROR | G_TX_WRAP,
memcpy(interfaceCtx->doActionSegment + DO_ACTION_TEX_SIZE() * 2, ResourceMgr_LoadTexByName(doAction), DO_ACTION_TEX_SIZE());
gDPLoadTextureBlock_4b(OVERLAY_DISP++, interfaceCtx->doActionSegment + DO_ACTION_TEX_SIZE() * 2, G_IM_FMT_IA,
DO_ACTION_TEX_WIDTH(), DO_ACTION_TEX_HEIGHT(), 0, G_TX_NOMIRROR | G_TX_WRAP,
G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD);
//const s16 rStartLabelX = OTRGetRectDimensionFromRightEdge(R_START_LABEL_X(gSaveContext.language)+Right_HUD_Margin);
@ -4330,7 +4352,7 @@ void Interface_Draw(GlobalContext* globalCtx) {
// Invalidate Do Action textures as they may have changed
gSPInvalidateTexCache(OVERLAY_DISP++, interfaceCtx->doActionSegment);
gSPInvalidateTexCache(OVERLAY_DISP++, interfaceCtx->doActionSegment + DO_ACTION_TEX_SIZE);
gSPInvalidateTexCache(OVERLAY_DISP++, interfaceCtx->doActionSegment + DO_ACTION_TEX_SIZE());
gSPSegment(OVERLAY_DISP++, 0x02, interfaceCtx->parameterSegment);
gSPSegment(OVERLAY_DISP++, 0x07, interfaceCtx->doActionSegment);
@ -4630,14 +4652,14 @@ void Interface_Draw(GlobalContext* globalCtx) {
PRIMITIVE, ENVIRONMENT, TEXEL0, ENVIRONMENT, TEXEL0, 0, PRIMITIVE, 0);
gDPSetPrimColor(OVERLAY_DISP++, 0, 0, 255, 255, 255, interfaceCtx->bAlpha);
gDPLoadTextureBlock_4b(OVERLAY_DISP++, interfaceCtx->doActionSegment + DO_ACTION_TEX_SIZE, G_IM_FMT_IA,
DO_ACTION_TEX_WIDTH, DO_ACTION_TEX_HEIGHT, 0, G_TX_NOMIRROR | G_TX_WRAP,
gDPLoadTextureBlock_4b(OVERLAY_DISP++, interfaceCtx->doActionSegment + DO_ACTION_TEX_SIZE(), G_IM_FMT_IA,
DO_ACTION_TEX_WIDTH(), DO_ACTION_TEX_HEIGHT(), 0, G_TX_NOMIRROR | G_TX_WRAP,
G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD);
R_B_LABEL_DD = (1 << 10) / (WREG(37 + gSaveContext.language) / 100.0f);
gSPWideTextureRectangle(OVERLAY_DISP++, BbtnPosX << 2, BbtnPosY << 2,
(BbtnPosX + DO_ACTION_TEX_WIDTH) << 2,
(BbtnPosY + DO_ACTION_TEX_HEIGHT) << 2, G_TX_RENDERTILE, 0, 0,
(BbtnPosX + DO_ACTION_TEX_WIDTH()) << 2,
(BbtnPosY + DO_ACTION_TEX_HEIGHT()) << 2, G_TX_RENDERTILE, 0, 0,
R_B_LABEL_DD, R_B_LABEL_DD);
}
@ -4723,12 +4745,14 @@ void Interface_Draw(GlobalContext* globalCtx) {
} else {
gDPSetPrimColor(OVERLAY_DISP++, 0, 0, 255, 255, 255, dpadAlpha);
}
if (fullUi) {
gDPLoadTextureBlock(OVERLAY_DISP++, ResourceMgr_LoadFileRaw("assets/ship_of_harkinian/buttons/dpad.bin"),
G_IM_FMT_IA, G_IM_SIZ_16b, 32, 32, 0, G_TX_NOMIRROR | G_TX_WRAP,
G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD);
gSPWideTextureRectangle(OVERLAY_DISP++, DpadPosX << 2, DpadPosY << 2,
(DpadPosX + 32) << 2, (DpadPosY + 32) << 2,
G_TX_RENDERTILE, 0, 0, (1 << 10), (1 << 10));
}
// DPad-Up Button Icon & Ammo Count
if (gSaveContext.equips.buttonItems[4] < 0xF0) {
@ -4846,7 +4870,7 @@ void Interface_Draw(GlobalContext* globalCtx) {
if ((interfaceCtx->unk_1EC < 2) || (interfaceCtx->unk_1EC == 3)) {
Interface_DrawActionLabel(globalCtx->state.gfxCtx, interfaceCtx->doActionSegment);
} else {
Interface_DrawActionLabel(globalCtx->state.gfxCtx, interfaceCtx->doActionSegment + DO_ACTION_TEX_SIZE);
Interface_DrawActionLabel(globalCtx->state.gfxCtx, interfaceCtx->doActionSegment + DO_ACTION_TEX_SIZE());
}
gDPPipeSync(OVERLAY_DISP++);

View File

@ -4,7 +4,7 @@
#include <string.h>
#include "soh/Enhancements/gameconsole.h"
#include "../libultraship/ImGuiImpl.h"
#include "soh/frame_interpolation.h"
void* D_8012D1F0 = NULL;
@ -190,6 +190,7 @@ void Gameplay_Destroy(GameState* thisx) {
KaleidoManager_Destroy();
ZeldaArena_Cleanup();
Fault_RemoveClient(&D_801614B8);
disableBetaQuest();
gGlobalCtx = NULL;
}
@ -237,10 +238,11 @@ void GivePlayerRandoRewardZeldaLightArrowsGift(GlobalContext* globalCtx, Randomi
if (CHECK_QUEST_ITEM(QUEST_MEDALLION_SPIRIT) && CHECK_QUEST_ITEM(QUEST_MEDALLION_SHADOW) && LINK_IS_ADULT &&
(gEntranceTable[((void)0, gSaveContext.entranceIndex)].scene == SCENE_TOKINOMA) &&
!Flags_GetTreasure(globalCtx, 0x1E) && player != NULL && !Player_InBlockingCsMode(globalCtx, player) &&
globalCtx->sceneLoadFlag == 0 && player->getItemId == GI_NONE) {
globalCtx->sceneLoadFlag == 0) {
GetItemID getItemId = Randomizer_GetItemIdFromKnownCheck(check, GI_ARROW_LIGHT);
GiveItemWithoutActor(globalCtx, getItemId);
Flags_SetTreasure(globalCtx, 0x1E);
player->pendingFlag.flagID = 0x1E;
player->pendingFlag.flagType = FLAG_SCENE_TREASURE;
}
}
@ -260,6 +262,7 @@ void GivePlayerRandoRewardSariaGift(GlobalContext* globalCtx, RandomizerCheck ch
void Gameplay_Init(GameState* thisx) {
GlobalContext* globalCtx = (GlobalContext*)thisx;
GraphicsContext* gfxCtx = globalCtx->state.gfxCtx;
enableBetaQuest();
gGlobalCtx = globalCtx;
//globalCtx->state.gfxCtx = NULL;
uintptr_t zAlloc;
@ -1407,7 +1410,7 @@ void Gameplay_Draw(GlobalContext* globalCtx) {
OVERLAY_DISP = sp70;
globalCtx->unk_121C7 = 2;
SREG(33) |= 1;
} else {
} else if (R_PAUSE_MENU_MODE != 3) {
Gameplay_Draw_DrawOverlayElements:
if ((HREG(80) != 10) || (HREG(89) != 0)) {
Gameplay_DrawOverlayElements(globalCtx);

View File

@ -752,18 +752,12 @@ void func_8008F470(GlobalContext* globalCtx, void** skeleton, Vec3s* jointTable,
};
color = &sTemp;
if (tunic == PLAYER_TUNIC_KOKIRI && CVar_GetS32("gUseTunicsCol",0)) {
color->r = CVar_GetS32("gTunic_Kokiri_R", sTunicColors[PLAYER_TUNIC_KOKIRI].r);
color->g = CVar_GetS32("gTunic_Kokiri_G", sTunicColors[PLAYER_TUNIC_KOKIRI].g);
color->b = CVar_GetS32("gTunic_Kokiri_B", sTunicColors[PLAYER_TUNIC_KOKIRI].b);
*color = CVar_GetRGB("gTunic_Kokiri", sTunicColors[PLAYER_TUNIC_KOKIRI]);
} else if (tunic == PLAYER_TUNIC_GORON && CVar_GetS32("gUseTunicsCol",0)) {
color->r = CVar_GetS32("gTunic_Goron_R", sTunicColors[PLAYER_TUNIC_GORON].r);
color->g = CVar_GetS32("gTunic_Goron_G", sTunicColors[PLAYER_TUNIC_GORON].g);
color->b = CVar_GetS32("gTunic_Goron_B", sTunicColors[PLAYER_TUNIC_GORON].b);
*color = CVar_GetRGB("gTunic_Goron", sTunicColors[PLAYER_TUNIC_GORON]);
} else if (tunic == PLAYER_TUNIC_ZORA && CVar_GetS32("gUseTunicsCol",0)) {
color->r = CVar_GetS32("gTunic_Zora_R", sTunicColors[PLAYER_TUNIC_ZORA].r);
color->g = CVar_GetS32("gTunic_Zora_G", sTunicColors[PLAYER_TUNIC_ZORA].g);
color->b = CVar_GetS32("gTunic_Zora_B", sTunicColors[PLAYER_TUNIC_ZORA].b);
} else if (!CVar_GetS32("gUseTunicsCol",0)) {
*color = CVar_GetRGB("gTunic_Zora", sTunicColors[PLAYER_TUNIC_ZORA]);
} else if (!CVar_GetS32("gUseTunicsCol",0)){
if (tunic >= 3) {
color->r = sOriginalTunicColors[0].r;
color->g = sOriginalTunicColors[0].g;

View File

@ -217,13 +217,12 @@ void func_80095D04(GlobalContext* globalCtx, Room* room, u32 flags) {
CLOSE_DISPS(globalCtx->state.gfxCtx);
}
//#define JPEG_MARKER 0xFFD8FFE0
#define JPEG_MARKER 0xE0FFD8FF
#define JPEG_MARKER 0xFFD8FFE0
s32 func_80096238(void* data) {
OSTime time;
if (*(u32*)data == JPEG_MARKER)
if (BE32SWAP(*(u32*)data) == JPEG_MARKER)
{
char* decodedJpeg = ResourceMgr_LoadJPEG(data, 320 * 240 * 2);
//char* decodedJpeg = ResourceMgr_LoadJPEG(data, 480 * 240 * 2);

View File

@ -1697,7 +1697,10 @@ void BossDodongo_DrawEffects(GlobalContext* globalCtx) {
func_80093D84(globalCtx->state.gfxCtx);
unkMtx = &globalCtx->billboardMtxF;
// OTRTODO: This call causes the whole texture cache to be cleaned up, which causes an important slowdown on switch so we need to find a way to avoid it.
#ifndef __SWITCH__
gSPInvalidateTexCache(POLY_XLU_DISP++, 0);
#endif
for (i = 0; i < 80; i++, eff++) {
if (eff->unk_24 == 1) {

View File

@ -1540,7 +1540,34 @@ void DemoEffect_UpdateJewelAdult(DemoEffect* this, GlobalContext* globalCtx) {
this->jewel.timer++;
this->actor.shape.rot.y += 0x0400;
DemoEffect_PlayJewelSfx(this, globalCtx);
if (gSaveContext.n64ddFlag) {
switch (this->jewel.type) {
case DEMO_EFFECT_JEWEL_KOKIRI:
if (CHECK_QUEST_ITEM(QUEST_KOKIRI_EMERALD)) {
DemoEffect_SetJewelColor(this, 1.0f);
} else {
DemoEffect_SetJewelColor(this, 0.0f);
}
break;
case DEMO_EFFECT_JEWEL_GORON:
if (CHECK_QUEST_ITEM(QUEST_GORON_RUBY)) {
DemoEffect_SetJewelColor(this, 1.0f);
} else {
DemoEffect_SetJewelColor(this, 0.0f);
}
break;
case DEMO_EFFECT_JEWEL_ZORA:
if (CHECK_QUEST_ITEM(QUEST_ZORA_SAPPHIRE)) {
DemoEffect_SetJewelColor(this, 1.0f);
} else {
DemoEffect_SetJewelColor(this, 0.0f);
}
break;
}
} else {
DemoEffect_SetJewelColor(this, 1.0f);
}
}
/**
@ -1604,6 +1631,34 @@ void DemoEffect_UpdateJewelChild(DemoEffect* this, GlobalContext* globalCtx) {
thisx->shape.rot.y += 0x0400;
DemoEffect_PlayJewelSfx(this, globalCtx);
this->effectFlags &= ~1;
if (gSaveContext.n64ddFlag) {
switch (this->jewel.type) {
case DEMO_EFFECT_JEWEL_KOKIRI:
if (CHECK_QUEST_ITEM(QUEST_KOKIRI_EMERALD)) {
DemoEffect_SetJewelColor(this, 1.0f);
} else {
DemoEffect_SetJewelColor(this, 0.0f);
}
break;
case DEMO_EFFECT_JEWEL_GORON:
if (CHECK_QUEST_ITEM(QUEST_GORON_RUBY)) {
DemoEffect_SetJewelColor(this, 1.0f);
} else {
DemoEffect_SetJewelColor(this, 0.0f);
}
break;
case DEMO_EFFECT_JEWEL_ZORA:
if (CHECK_QUEST_ITEM(QUEST_ZORA_SAPPHIRE)) {
DemoEffect_SetJewelColor(this, 1.0f);
} else {
DemoEffect_SetJewelColor(this, 0.0f);
}
break;
}
} else {
// Contrary to it's adult conterpart Authenthic doesn't use DemoEffect_SetJewelColor(this, 1.0f); here
}
}
/**

View File

@ -1059,7 +1059,7 @@ void EnSkj_SetupPostSariasSong(EnSkj* this) {
}
void EnSkj_ChangeModeAfterSong(EnSkj* this, GlobalContext* globalCtx) {
if ((Message_GetState(&globalCtx->msgCtx) == TEXT_STATE_DONE) && Message_ShouldAdvance(globalCtx)) {
if (((Message_GetState(&globalCtx->msgCtx) == TEXT_STATE_DONE) && Message_ShouldAdvance(globalCtx)) || Randomizer_ItemIsIceTrap(RC_LW_SKULL_KID, GI_HEART_PIECE)) {
gSaveContext.itemGetInf[1] |= 0x40;
EnSkj_SetNaviId(this);
EnSkj_SetupWaitInRange(this);

View File

@ -288,14 +288,16 @@ void func_80B3CA38(EnXc* this, GlobalContext* globalCtx) {
}
void GivePlayerRandoRewardSheikSong(EnXc* sheik, GlobalContext* globalCtx, RandomizerCheck check, int sheikType, GetItemID ogSongId) {
if (sheik->actor.parent != NULL && sheik->actor.parent->id == GET_PLAYER(globalCtx)->actor.id &&
Player* player = GET_PLAYER(globalCtx);
if (sheik->actor.parent != NULL && sheik->actor.parent->id == player->actor.id &&
!(gSaveContext.eventChkInf[5] & sheikType)) {
gSaveContext.eventChkInf[5] |= sheikType;
} else if (!(gSaveContext.eventChkInf[5] & sheikType)) {
GetItemID getItemId = Randomizer_GetItemIdFromKnownCheck(check, ogSongId);
if (check == RC_SHEIK_AT_TEMPLE && !Flags_GetTreasure(globalCtx, 0x1F)) {
if (func_8002F434(&sheik->actor, globalCtx, getItemId, 10000.0f, 100.0f)) {
Flags_SetTreasure(globalCtx, 0x1F);
player->pendingFlag.flagID = 0x1F;
player->pendingFlag.flagType = FLAG_SCENE_TREASURE;
}
} else if (check != RC_SHEIK_AT_TEMPLE) {
func_8002F434(&sheik->actor, globalCtx, getItemId, 10000.0f, 100.0f);

View File

@ -168,6 +168,7 @@ void func_8083CA20(GlobalContext* globalCtx, Player* this);
void func_8083CA54(GlobalContext* globalCtx, Player* this);
void func_8083CA9C(GlobalContext* globalCtx, Player* this);
s32 func_8083E0FC(Player* this, GlobalContext* globalCtx);
void Player_SetPendingFlag(Player* this, GlobalContext* globalCtx);
s32 func_8083E5A8(Player* this, GlobalContext* globalCtx);
s32 func_8083EB44(Player* this, GlobalContext* globalCtx);
s32 func_8083F7BC(Player* this, GlobalContext* globalCtx);
@ -4649,7 +4650,11 @@ void func_8083A0F4(GlobalContext* globalCtx, Player* this) {
anim = D_80853914[PLAYER_ANIMGROUP_13][this->modelAnimType];
}
func_80832264(globalCtx, this, anim);
if (CVar_GetS32("gFasterHeavyBlockLift", 0) && interactActorId == ACTOR_BG_HEAVY_BLOCK) {
LinkAnimation_PlayOnceSetSpeed(globalCtx, &this->skelAnime, anim, 3.0f);
} else {
LinkAnimation_PlayOnce(globalCtx, &this->skelAnime, anim);
}
}
}
else {
@ -6233,6 +6238,30 @@ void func_8083E4C4(GlobalContext* globalCtx, Player* this, GetItemEntry* giEntry
func_80078884((this->getItemId < 0) ? NA_SE_SY_GET_BOXITEM : NA_SE_SY_GET_ITEM);
}
// Sets a flag according to which type of flag is specified in player->pendingFlag.flagType
// and which flag is specified in player->pendingFlag.flagID.
void Player_SetPendingFlag(Player* this, GlobalContext* globalCtx) {
switch (this->pendingFlag.flagType) {
case FLAG_SCENE_CLEAR:
Flags_SetClear(globalCtx, this->pendingFlag.flagID);
break;
case FLAG_SCENE_COLLECTIBLE:
Flags_SetCollectible(globalCtx, this->pendingFlag.flagID);
break;
case FLAG_SCENE_SWITCH:
Flags_SetSwitch(globalCtx, this->pendingFlag.flagID);
break;
case FLAG_SCENE_TREASURE:
Flags_SetTreasure(globalCtx, this->pendingFlag.flagID);
break;
case FLAG_NONE:
default:
break;
}
this->pendingFlag.flagType = FLAG_NONE;
this->pendingFlag.flagID = 0;
}
s32 func_8083E5A8(Player* this, GlobalContext* globalCtx) {
Actor* interactedActor;
@ -6256,6 +6285,7 @@ s32 func_8083E5A8(Player* this, GlobalContext* globalCtx) {
this->stateFlags1 &= ~(PLAYER_STATE1_10 | PLAYER_STATE1_11);
this->actor.colChkInfo.damage = 0;
func_80837C0C(globalCtx, this, 3, 0.0f, 0.0f, 0, 20);
Player_SetPendingFlag(this, globalCtx);
return;
}
@ -12689,6 +12719,8 @@ s32 func_8084DFF4(GlobalContext* globalCtx, Player* this) {
Message_StartTextbox(globalCtx, giEntry->textId, &this->actor);
Item_Give(globalCtx, giEntry->itemId);
Player_SetPendingFlag(this, globalCtx);
if (((this->getItemId >= GI_RUPEE_GREEN) && (this->getItemId <= GI_RUPEE_RED)) ||
((this->getItemId >= GI_RUPEE_PURPLE) && (this->getItemId <= GI_RUPEE_GOLD)) ||
((this->getItemId >= GI_RUPEE_GREEN_LOSE) && (this->getItemId <= GI_RUPEE_PURPLE_LOSE)) ||
@ -13130,7 +13162,10 @@ void func_8084ECA4(Player* this, GlobalContext* globalCtx) {
if (LinkAnimation_Update(globalCtx, &this->skelAnime)) {
if (this->unk_84F != 0) {
if (this->unk_850 == 0) {
Message_StartTextbox(globalCtx, D_80854A04[this->unk_84F - 1].textId, &this->actor);
if (CVar_GetS32("gFastDrops", 0))
{ this->unk_84F = 0; }
else
{ Message_StartTextbox(globalCtx, D_80854A04[this->unk_84F - 1].textId, &this->actor); }
Audio_PlayFanfare(NA_BGM_ITEM_GET | 0x900);
this->unk_850 = 1;
}
@ -13166,9 +13201,10 @@ void func_8084ECA4(Player* this, GlobalContext* globalCtx) {
if (i < 4) {
this->unk_84F = i + 1;
this->unk_850 = 0;
this->stateFlags1 |= PLAYER_STATE1_28 | PLAYER_STATE1_29;
this->interactRangeActor->parent = &this->actor;
Player_UpdateBottleHeld(globalCtx, this, catchInfo->itemId, ABS(catchInfo->actionParam));
if (!CVar_GetS32("gFastDrops", 0)) {
this->stateFlags1 |= PLAYER_STATE1_28 | PLAYER_STATE1_29;
func_808322D0(globalCtx, this, sp24->unk_04);
func_80835EA4(globalCtx, 4);
}
@ -13177,6 +13213,7 @@ void func_8084ECA4(Player* this, GlobalContext* globalCtx) {
}
}
}
}
if (this->skelAnime.curFrame <= 7.0f) {
this->stateFlags1 |= PLAYER_STATE1_1;

View File

@ -515,12 +515,49 @@ void KaleidoScope_DrawEquipment(GlobalContext* globalCtx) {
(gEquipAgeReqs[pauseCtx->cursorY[PAUSE_EQUIP]][pauseCtx->cursorX[PAUSE_EQUIP]] ==
((void)0, gSaveContext.linkAge))) {
if (CHECK_BTN_ALL(input->press.button, BTN_A)) {
// Allow Link to remove his equipment from the equipment subscreen by toggling on/off
// Shields will be un-equipped entirely, and tunics/boots will revert to Kokiri Tunic/Kokiri Boots
// Only BGS/Giant's Knife is affected, and it will revert to Master Sword.
// If we have the feature toggled on
if (CVar_GetS32("gEquipmentCanBeRemoved", 0)) {
// If we're on the "swords" section of the equipment screen AND we're on a currently-equipped BGS/Giant's Knife
if (pauseCtx->cursorY[PAUSE_EQUIP] == 0 && pauseCtx->cursorX[PAUSE_EQUIP] == 3
&& CUR_EQUIP_VALUE(EQUIP_SWORD) == 3 && CHECK_OWNED_EQUIP(0,1)){ // And we have the Master Sword
Inventory_ChangeEquipment(EQUIP_SWORD, 2); // "Unequip" it by equipping Master Sword
gSaveContext.equips.buttonItems[0] = ITEM_SWORD_MASTER;
gSaveContext.infTable[29] = 0;
goto RESUME_EQUIPMENT_SWORD; // Skip to here so we don't re-equip it
}
// If we're on the "shields" section of the equipment screen AND we're on a currently-equipped shield
if (pauseCtx->cursorY[PAUSE_EQUIP] == 1 && pauseCtx->cursorX[PAUSE_EQUIP] == CUR_EQUIP_VALUE(EQUIP_SHIELD)) {
Inventory_ChangeEquipment(EQUIP_SHIELD, 0); // Unequip it
goto RESUME_EQUIPMENT; // Skip to here so we don't re-equip it
}
// If we're on the "tunics" section of the equipment screen AND we're on a currently-equipped tunic
if (pauseCtx->cursorY[PAUSE_EQUIP] == 2 && pauseCtx->cursorX[PAUSE_EQUIP] == CUR_EQUIP_VALUE(EQUIP_TUNIC)) {
Inventory_ChangeEquipment(EQUIP_TUNIC, 1); // "Unequip" it (by equipping Kokiri Tunic)
goto RESUME_EQUIPMENT; // Skip to here so we don't re-equip it
}
// If we're on the "boots" section of the equipment screen AND we're on currently-equipped boots
if (pauseCtx->cursorY[PAUSE_EQUIP] == 3 && pauseCtx->cursorX[PAUSE_EQUIP] == CUR_EQUIP_VALUE(EQUIP_BOOTS)) {
Inventory_ChangeEquipment(EQUIP_BOOTS, 1); // "Unequip" it (by equipping Kokiri Boots)
goto RESUME_EQUIPMENT; // Skip to here so we don't re-equip it
}
}
if (CHECK_OWNED_EQUIP(pauseCtx->cursorY[PAUSE_EQUIP], pauseCtx->cursorX[PAUSE_EQUIP] - 1)) {
Inventory_ChangeEquipment(pauseCtx->cursorY[PAUSE_EQUIP], pauseCtx->cursorX[PAUSE_EQUIP]);
} else {
goto EQUIP_FAIL;
}
RESUME_EQUIPMENT:
if (pauseCtx->cursorY[PAUSE_EQUIP] == 0) {
gSaveContext.infTable[29] = 0;
gSaveContext.equips.buttonItems[0] = cursorItem;
@ -537,7 +574,7 @@ void KaleidoScope_DrawEquipment(GlobalContext* globalCtx) {
gSaveContext.equips.buttonItems[0] = ITEM_SWORD_KNIFE;
}
}
RESUME_EQUIPMENT_SWORD:
Interface_LoadItemIcon1(globalCtx, 0);
}

View File

@ -2110,7 +2110,8 @@ void KaleidoScope_UpdateNamePanel(GlobalContext* globalCtx) {
sp2A += 12;
}
memcpy(pauseCtx->nameSegment, ResourceMgr_LoadTexByName(mapNameTextures[sp2A]), 0x400);
const char* textureName = mapNameTextures[sp2A];
memcpy(pauseCtx->nameSegment, ResourceMgr_LoadTexByName(textureName), ResourceMgr_LoadTexSizeByName(textureName));
} else {
osSyncPrintf("zoom_name=%d\n", pauseCtx->namedItem);
@ -2123,7 +2124,8 @@ void KaleidoScope_UpdateNamePanel(GlobalContext* globalCtx) {
osSyncPrintf("J_N=%d point=%d\n", gSaveContext.language, sp2A);
memcpy(pauseCtx->nameSegment, ResourceMgr_LoadTexByName(iconNameTextures[sp2A]), 0x400);
const char* textureName = iconNameTextures[sp2A];
memcpy(pauseCtx->nameSegment, ResourceMgr_LoadTexByName(textureName), ResourceMgr_LoadTexSizeByName(textureName));
}
pauseCtx->nameDisplayTimer = 0;
@ -3224,8 +3226,12 @@ void KaleidoScope_UpdateCursorSize(PauseContext* pauseCtx) {
void KaleidoScope_LoadDungeonMap(GlobalContext* globalCtx) {
InterfaceContext* interfaceCtx = &globalCtx->interfaceCtx;
memcpy(interfaceCtx->mapSegment, ResourceMgr_LoadTexByName(sDungeonMapTexs[R_MAP_TEX_INDEX]), 0x800);
memcpy(interfaceCtx->mapSegment + 0x800, ResourceMgr_LoadTexByName(sDungeonMapTexs[R_MAP_TEX_INDEX + 1]), 0x800);
char* firstTextureName = sDungeonMapTexs[R_MAP_TEX_INDEX];
char* secondTextureName = sDungeonMapTexs[R_MAP_TEX_INDEX + 1];
uint32_t firstTextureSize = ResourceMgr_LoadTexSizeByName(firstTextureName);
memcpy(interfaceCtx->mapSegment, ResourceMgr_LoadTexByName(firstTextureName), ResourceMgr_LoadTexSizeByName(firstTextureName));
memcpy(interfaceCtx->mapSegment + (firstTextureSize / 2), ResourceMgr_LoadTexByName(secondTextureName), ResourceMgr_LoadTexSizeByName(secondTextureName));
}
void KaleidoScope_UpdateDungeonMap(GlobalContext* globalCtx) {
@ -3403,11 +3409,14 @@ void KaleidoScope_Update(GlobalContext* globalCtx)
if (((void)0, gSaveContext.worldMapArea) < 22) {
if (gSaveContext.language == LANGUAGE_ENG) {
memcpy(pauseCtx->nameSegment + 0x400, ResourceMgr_LoadTexByName(mapNameTextures[36 + gSaveContext.worldMapArea]), 0xA00);
const char* textureName = mapNameTextures[36 + gSaveContext.worldMapArea];
memcpy(pauseCtx->nameSegment + 0x400, ResourceMgr_LoadTexByName(textureName), ResourceMgr_LoadTexSizeByName(textureName));
} else if (gSaveContext.language == LANGUAGE_GER) {
memcpy(pauseCtx->nameSegment + 0x400, ResourceMgr_LoadTexByName(mapNameTextures[58 + gSaveContext.worldMapArea]), 0xA00);
const char* textureName = mapNameTextures[58 + gSaveContext.worldMapArea];
memcpy(pauseCtx->nameSegment + 0x400, ResourceMgr_LoadTexByName(textureName), ResourceMgr_LoadTexSizeByName(textureName));
} else {
memcpy(pauseCtx->nameSegment + 0x400, ResourceMgr_LoadTexByName(mapNameTextures[80 + gSaveContext.worldMapArea]), 0xA00);
const char* textureName = mapNameTextures[80 + gSaveContext.worldMapArea];
memcpy(pauseCtx->nameSegment + 0x400, ResourceMgr_LoadTexByName(textureName), ResourceMgr_LoadTexSizeByName(textureName));
}
}
// OTRTODO - player on pause