mirror of
https://github.com/HarbourMasters/Shipwright.git
synced 2025-08-22 14:23:44 -07:00
Merge branch 'develop' into SpammableKaepora
This commit is contained in:
commit
35d97bdd6e
140 changed files with 5298 additions and 1180 deletions
21
BUILDING.md
21
BUILDING.md
|
@ -2,9 +2,9 @@
|
|||
|
||||
## Windows
|
||||
|
||||
1. Install [Python](https://www.python.org/ftp/python/3.10.2/python-3.10.2-amd64.exe)
|
||||
1. Requires [Python](https://www.python.org/downloads/) >= 3.6.
|
||||
2. Install [Visual Studio 2022 Community Edition](https://visualstudio.microsoft.com/vs/community/)
|
||||
2b. In the Visual Studio Installer, install `MSVC v142 - VS 2019 C++`.
|
||||
3. In the Visual Studio Installer, install `MSVC v142 - VS 2019 C++`.
|
||||
4. Clone the Ship of Harkinian repository.
|
||||
5. Place one or more [compatible](#compatible-roms) roms in the `OTRExporter` directory with namings of your choice.
|
||||
6. Run `OTRExporter/OTRExporter.sln`.
|
||||
|
@ -41,9 +41,9 @@ cp /usr/local/lib/libGLEW.a external
|
|||
|
||||
cd soh
|
||||
# Extract the assets/Compile the exporter/Run the exporter
|
||||
make setup -j$(nproc)
|
||||
make setup -j$(nproc) OPTFLAGS=-O0 DEBUG=0
|
||||
# Compile the code
|
||||
make -j $(nproc)
|
||||
make -j $(nproc) OPTFLAGS=-O0 DEBUG=0
|
||||
```
|
||||
|
||||
# Compatible Roms
|
||||
|
@ -51,3 +51,16 @@ make -j $(nproc)
|
|||
OOT_PAL_GC checksum 0x09465AC3
|
||||
OOT_PAL_GC_DBG1 checksum 0x871E1C92 (debug non-master quest)
|
||||
```
|
||||
|
||||
# OTRExporter Usage
|
||||
|
||||
The OTRExporter exports an `oot.otr` archive file which Ship of Harkinian requires to play.
|
||||
|
||||
Use the `extract_assets.py` script file to run the exporter using any of the following methods:
|
||||
1) Double click on the script after placing one or more roms in the directory.
|
||||
2) Drag & Drop a rom onto the script.
|
||||
3) In a terminal run `python3 extract_assets.py` after placing one or more roms in the directory.
|
||||
4) In a terminal run `python3 extract_assets.py <path_to_rom>`
|
||||
|
||||
If the script finds multiple roms the user is prompted which to use. Selection is done using the number keys and then pressing the carriage return key.
|
||||
|
||||
|
|
1
Jenkinsfile
vendored
1
Jenkinsfile
vendored
|
@ -3,7 +3,6 @@ pipeline {
|
|||
|
||||
options {
|
||||
timestamps()
|
||||
timeout(time: 30, unit: 'MINUTES')
|
||||
skipDefaultCheckout(true)
|
||||
}
|
||||
|
||||
|
|
BIN
OTRExporter/assets/ship_of_harkinian/fonts/Fipps-Regular.otf
Normal file
BIN
OTRExporter/assets/ship_of_harkinian/fonts/Fipps-Regular.otf
Normal file
Binary file not shown.
Binary file not shown.
|
@ -188,7 +188,7 @@ void OTRGame::draw() {
|
|||
sohFolder = path;
|
||||
}
|
||||
|
||||
if (UIUtils::GuiIconButton("Cartridge", "Open\nOoT Rom", 32, 50, currentStep != NULLSTR, "Select an Ocarina of Time\nMaster Quest or Vanilla Debug Rom\n\nYou can dump it or lend one from Nintendo")) {
|
||||
if (UIUtils::GuiIconButton("Cartridge", "Open\nOoT Rom", 32, 50, currentStep != NULLSTR, "Select an Ocarina of Time\nGameCube PAL or Vanilla Debug Rom\n\nYou can dump it or lend one from Nintendo")) {
|
||||
const std::string path = NativeFS->LaunchFileExplorer(LaunchType::FILE);
|
||||
if (path != NULLSTR) {
|
||||
const std::string patched_n64 = std::string(patched_rom);
|
||||
|
|
21
README.md
21
README.md
|
@ -6,7 +6,7 @@ The Ship does not include assets and as such requires a prior copy of the game t
|
|||
|
||||
## Quick Start
|
||||
|
||||
1) Download The Ship of Harkinian from Discord.
|
||||
1) Download The Ship of Harkinian from [Discord](https://discord.com/invite/BtBmd55HVH).
|
||||
2) Requires a supported copy of the game (See supported games below).
|
||||
3) Use the OTRGui to generate an `oot.otr` archive file.
|
||||
4) Launch `soh.exe`
|
||||
|
@ -18,9 +18,9 @@ Build team: `zelda@srd022j`
|
|||
Build date: `03-02-21 00:49:18` (year-month-day)
|
||||
sha1: cee6bc3c2a634b41728f2af8da54d9bf8cc14099
|
||||
```
|
||||
Ocarina of Time Pal Gamecube
|
||||
Ocarina of Time PAL GameCube
|
||||
```
|
||||
sha1: d0c95b2cb3c6682a171db267932af7af8cf5fa82
|
||||
sha1: 0227d7c0074f2d0ac935631990da8ec5914597b4
|
||||
```
|
||||
|
||||
Congratulations, you are now sailing with the Ship of Harkinian! Have fun!
|
||||
|
@ -64,6 +64,9 @@ Refer to the [building instructions](BUILDING.md) to compile SoH.
|
|||
- Affirm that you have an `/assets` folder filled with XMLs in the same directory as OTRGui.exe
|
||||
- Affirm that `zapd.exe` exists in the `/assets/extractor` folder
|
||||
|
||||
## Nightly Builds
|
||||
Nightly builds of Ship of Harkinian are available at [https://builds.shipofharkinian.com/job/SoH_Multibranch/job/develop]
|
||||
|
||||
|
||||
## The Harbour Masters Are...
|
||||
|
||||
|
@ -99,7 +102,13 @@ Refer to the [building instructions](BUILDING.md) to compile SoH.
|
|||
Logg | Tester - General Testing
|
||||
Taylor Daley | Graphic Design
|
||||
Can't Sleep | Graphic Design
|
||||
MicTheMicrophone | Voice actor for the King
|
||||
Amphibibro | Voice actor for Link
|
||||
|
||||
Lemons
|
||||
## Video Credits
|
||||
Kenix | Producer / Writer
|
||||
rainbow_fash | Executive Producer
|
||||
TheLegendOfXela | Editor
|
||||
MicTheMicrophone | Gwonam / The King
|
||||
Amphibibro | Link
|
||||
AceHeart | Zelda
|
||||
|
||||
###### Lemons
|
|
@ -54,11 +54,16 @@ namespace Ship {
|
|||
std::shared_ptr<File> Archive::LoadFile(const std::string& filePath, bool includeParent, std::shared_ptr<File> FileToLoad) {
|
||||
HANDLE fileHandle = NULL;
|
||||
|
||||
if (FileToLoad == nullptr) {
|
||||
FileToLoad = std::make_shared<File>();
|
||||
FileToLoad->path = filePath;
|
||||
}
|
||||
|
||||
if (!SFileOpenFileEx(mainMPQ, filePath.c_str(), 0, &fileHandle)) {
|
||||
SPDLOG_ERROR("({}) Failed to open file {} from mpq archive {}", GetLastError(), filePath.c_str(), MainPath.c_str());
|
||||
std::unique_lock<std::mutex> Lock(FileToLoad->FileLoadMutex);
|
||||
FileToLoad->bHasLoadError = true;
|
||||
return nullptr;
|
||||
return FileToLoad;
|
||||
}
|
||||
|
||||
DWORD dwFileSize = SFileGetFileSize(fileHandle, 0);
|
||||
|
@ -72,18 +77,13 @@ namespace Ship {
|
|||
}
|
||||
std::unique_lock<std::mutex> Lock(FileToLoad->FileLoadMutex);
|
||||
FileToLoad->bHasLoadError = true;
|
||||
return nullptr;
|
||||
return FileToLoad;
|
||||
}
|
||||
|
||||
if (!SFileCloseFile(fileHandle)) {
|
||||
SPDLOG_ERROR("({}) Failed to close file {} from mpq archive {}", GetLastError(), filePath.c_str(), MainPath.c_str());
|
||||
}
|
||||
|
||||
if (FileToLoad == nullptr) {
|
||||
FileToLoad = std::make_shared<File>();
|
||||
FileToLoad->path = filePath;
|
||||
}
|
||||
|
||||
std::unique_lock<std::mutex> Lock(FileToLoad->FileLoadMutex);
|
||||
FileToLoad->parent = includeParent ? shared_from_this() : nullptr;
|
||||
FileToLoad->buffer = fileData;
|
||||
|
@ -97,6 +97,11 @@ namespace Ship {
|
|||
HANDLE fileHandle = NULL;
|
||||
HANDLE mpqHandle = NULL;
|
||||
|
||||
if (FileToLoad == nullptr) {
|
||||
FileToLoad = std::make_shared<File>();
|
||||
FileToLoad->path = filePath;
|
||||
}
|
||||
|
||||
for(auto [path, handle] : mpqHandles) {
|
||||
if (SFileOpenFileEx(mpqHandle, filePath.c_str(), 0, &fileHandle)) {
|
||||
std::unique_lock Lock(FileToLoad->FileLoadMutex);
|
||||
|
@ -121,18 +126,13 @@ namespace Ship {
|
|||
}
|
||||
std::unique_lock<std::mutex> Lock(FileToLoad->FileLoadMutex);
|
||||
FileToLoad->bHasLoadError = true;
|
||||
return nullptr;
|
||||
return FileToLoad;
|
||||
}
|
||||
|
||||
if (!SFileCloseFile(fileHandle)) {
|
||||
SPDLOG_ERROR("({}) Failed to close file {} from mpq archive {}", GetLastError(), filePath.c_str(), MainPath.c_str());
|
||||
}
|
||||
|
||||
if (FileToLoad == nullptr) {
|
||||
FileToLoad = std::make_shared<File>();
|
||||
FileToLoad->path = filePath;
|
||||
}
|
||||
|
||||
std::unique_lock<std::mutex> Lock(FileToLoad->FileLoadMutex);
|
||||
FileToLoad->parent = includeParent ? shared_from_this() : nullptr;
|
||||
FileToLoad->buffer = fileData;
|
||||
|
@ -204,7 +204,7 @@ namespace Ship {
|
|||
return true;
|
||||
}
|
||||
|
||||
std::vector<SFILE_FIND_DATA> Archive::ListFiles(const std::string& searchMask) {
|
||||
std::vector<SFILE_FIND_DATA> Archive::ListFiles(const std::string& searchMask) const {
|
||||
auto fileList = std::vector<SFILE_FIND_DATA>();
|
||||
SFILE_FIND_DATA findContext;
|
||||
HANDLE hFind;
|
||||
|
@ -248,7 +248,7 @@ namespace Ship {
|
|||
return fileList;
|
||||
}
|
||||
|
||||
bool Archive::HasFile(const std::string& filename) {
|
||||
bool Archive::HasFile(const std::string& filename) const {
|
||||
bool result = false;
|
||||
auto start = std::chrono::steady_clock::now();
|
||||
|
||||
|
@ -267,8 +267,9 @@ namespace Ship {
|
|||
return result;
|
||||
}
|
||||
|
||||
std::string Archive::HashToString(uint64_t hash) {
|
||||
return hashes[hash];
|
||||
const std::string* Archive::HashToString(uint64_t hash) const {
|
||||
auto it = hashes.find(hash);
|
||||
return it != hashes.end() ? &it->second : nullptr;
|
||||
}
|
||||
|
||||
bool Archive::Load(bool enableWriting, bool genCRCMap) {
|
||||
|
|
|
@ -34,9 +34,9 @@ namespace Ship
|
|||
bool AddFile(const std::string& path, uintptr_t fileData, DWORD dwFileSize);
|
||||
bool RemoveFile(const std::string& path);
|
||||
bool RenameFile(const std::string& oldPath, const std::string& newPath);
|
||||
std::vector<SFILE_FIND_DATA> ListFiles(const std::string& searchMask);
|
||||
bool HasFile(const std::string& searchMask);
|
||||
std::string HashToString(uint64_t hash);
|
||||
std::vector<SFILE_FIND_DATA> ListFiles(const std::string& searchMask) const;
|
||||
bool HasFile(const std::string& searchMask) const;
|
||||
const std::string* HashToString(uint64_t hash) const;
|
||||
protected:
|
||||
bool Load(bool enableWriting, bool genCRCMap);
|
||||
bool Unload();
|
||||
|
|
|
@ -72,7 +72,7 @@ namespace Ship {
|
|||
(*this)["WINDOW"]["FULLSCREEN WIDTH"] = std::to_string(1920);
|
||||
(*this)["WINDOW"]["FULLSCREEN HEIGHT"] = std::to_string(1080);
|
||||
(*this)["WINDOW"]["FULLSCREEN"] = std::to_string(false);
|
||||
(*this)["WINDOW"]["GFX BACKEND"] = "sdl";
|
||||
(*this)["WINDOW"]["GFX BACKEND"] = "";
|
||||
|
||||
(*this)["KEYBOARD CONTROLLER BINDING 1"][STR(BTN_CRIGHT)] = std::to_string(0x14D);
|
||||
(*this)["KEYBOARD CONTROLLER BINDING 1"][STR(BTN_CLEFT)] = std::to_string(0x14B);
|
||||
|
|
|
@ -1,3 +1,6 @@
|
|||
#ifndef CONFIG_FILE_H
|
||||
#define CONFIG_FILE_H
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
|
@ -35,3 +38,5 @@ namespace Ship {
|
|||
mINI::INIFile File;
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,23 +1,22 @@
|
|||
#include "Cvar.h"
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
#include <utility>
|
||||
#include <PR/ultra64/gbi.h>
|
||||
|
||||
std::map<std::string, CVar*> cvars;
|
||||
|
||||
CVar* CVar_GetVar(const char* name) {
|
||||
std::string key(name);
|
||||
return cvars.contains(key) ? cvars[key] : nullptr;
|
||||
}
|
||||
std::map<std::string, std::unique_ptr<CVar>, std::less<>> cvars;
|
||||
|
||||
extern "C" CVar* CVar_Get(const char* name) {
|
||||
return CVar_GetVar(name);
|
||||
auto it = cvars.find(name);
|
||||
return (it != cvars.end()) ? it->second.get() : nullptr;
|
||||
}
|
||||
|
||||
extern "C" s32 CVar_GetS32(const char* name, s32 defaultValue) {
|
||||
CVar* cvar = CVar_Get(name);
|
||||
|
||||
if (cvar != nullptr) {
|
||||
if (cvar) {
|
||||
if (cvar->type == CVAR_TYPE_S32)
|
||||
return cvar->value.valueS32;
|
||||
}
|
||||
|
@ -28,7 +27,7 @@ extern "C" s32 CVar_GetS32(const char* name, s32 defaultValue) {
|
|||
extern "C" float CVar_GetFloat(const char* name, float defaultValue) {
|
||||
CVar* cvar = CVar_Get(name);
|
||||
|
||||
if (cvar != nullptr) {
|
||||
if (cvar) {
|
||||
if (cvar->type == CVAR_TYPE_FLOAT)
|
||||
return cvar->value.valueFloat;
|
||||
}
|
||||
|
@ -36,10 +35,10 @@ extern "C" float CVar_GetFloat(const char* name, float defaultValue) {
|
|||
return defaultValue;
|
||||
}
|
||||
|
||||
extern "C" char* CVar_GetString(const char* name, char* defaultValue) {
|
||||
extern "C" const char* CVar_GetString(const char* name, const char* defaultValue) {
|
||||
CVar* cvar = CVar_Get(name);
|
||||
|
||||
if (cvar != nullptr) {
|
||||
if (cvar) {
|
||||
if (cvar->type == CVAR_TYPE_STRING)
|
||||
return cvar->value.valueStr;
|
||||
}
|
||||
|
@ -48,53 +47,43 @@ extern "C" char* CVar_GetString(const char* name, char* defaultValue) {
|
|||
}
|
||||
|
||||
extern "C" void CVar_SetS32(const char* name, s32 value) {
|
||||
CVar* cvar = CVar_Get(name);
|
||||
auto& cvar = cvars[name];
|
||||
if (!cvar) {
|
||||
cvar = new CVar;
|
||||
cvars[std::string(name)] = cvar;
|
||||
cvar = std::make_unique<CVar>();
|
||||
}
|
||||
cvar->type = CVAR_TYPE_S32;
|
||||
cvar->value.valueS32 = value;
|
||||
}
|
||||
|
||||
void CVar_SetFloat(const char* name, float value) {
|
||||
CVar* cvar = CVar_Get(name);
|
||||
auto& cvar = cvars[name];
|
||||
if (!cvar) {
|
||||
cvar = new CVar;
|
||||
cvars[std::string(name)] = cvar;
|
||||
cvar = std::make_unique<CVar>();
|
||||
}
|
||||
cvar->type = CVAR_TYPE_FLOAT;
|
||||
cvar->value.valueFloat = value;
|
||||
}
|
||||
|
||||
void CVar_SetString(const char* name, char* value) {
|
||||
CVar* cvar = CVar_Get(name);
|
||||
void CVar_SetString(const char* name, const char* value) {
|
||||
auto& cvar = cvars[name];
|
||||
if (!cvar) {
|
||||
cvar = new CVar;
|
||||
cvars[std::string(name)] = cvar;
|
||||
cvar = std::make_unique<CVar>();
|
||||
}
|
||||
cvar->type = CVAR_TYPE_STRING;
|
||||
cvar->value.valueStr = value;
|
||||
}
|
||||
|
||||
|
||||
extern "C" void CVar_RegisterS32(const char* name, s32 defaultValue) {
|
||||
CVar* cvar = CVar_Get(name);
|
||||
|
||||
if (cvar == nullptr)
|
||||
if (!CVar_Get(name))
|
||||
CVar_SetS32(name, defaultValue);
|
||||
}
|
||||
|
||||
extern "C" void CVar_RegisterFloat(const char* name, float defaultValue) {
|
||||
CVar* cvar = CVar_Get(name);
|
||||
|
||||
if (cvar == nullptr)
|
||||
if (!CVar_Get(name))
|
||||
CVar_SetFloat(name, defaultValue);
|
||||
}
|
||||
|
||||
extern "C" void CVar_RegisterString(const char* name, char* defaultValue) {
|
||||
CVar* cvar = CVar_Get(name);
|
||||
|
||||
if (cvar == nullptr)
|
||||
extern "C" void CVar_RegisterString(const char* name, const char* defaultValue) {
|
||||
if (!CVar_Get(name))
|
||||
CVar_SetString(name, defaultValue);
|
||||
}
|
||||
|
|
|
@ -6,13 +6,13 @@
|
|||
typedef enum CVarType { CVAR_TYPE_S32, CVAR_TYPE_FLOAT, CVAR_TYPE_STRING } CVarType;
|
||||
|
||||
typedef struct CVar {
|
||||
char* name;
|
||||
const char* name;
|
||||
CVarType type;
|
||||
|
||||
union {
|
||||
s32 valueS32;
|
||||
float valueFloat;
|
||||
char* valueStr;
|
||||
const char* valueStr;
|
||||
} value;
|
||||
} CVar;
|
||||
|
||||
|
@ -22,16 +22,15 @@ extern "C"
|
|||
#endif
|
||||
//#include <ultra64.h>
|
||||
|
||||
|
||||
CVar* CVar_Get(const char* name);
|
||||
s32 CVar_GetS32(const char* name, s32 defaultValue);
|
||||
float CVar_GetFloat(const char* name, float defaultValue);
|
||||
char* CVar_GetString(const char* name, char* defaultValue);
|
||||
const char* CVar_GetString(const char* name, const char* defaultValue);
|
||||
void CVar_SetS32(const char* name, s32 value);
|
||||
|
||||
void CVar_RegisterS32(const char* name, s32 defaultValue);
|
||||
void CVar_RegisterFloat(const char* name, float defaultValue);
|
||||
void CVar_RegisterString(const char* name, char* defaultValue);
|
||||
void CVar_RegisterString(const char* name, const char* defaultValue);
|
||||
|
||||
#ifdef __cplusplus
|
||||
};
|
||||
|
@ -40,10 +39,11 @@ void CVar_RegisterString(const char* name, char* defaultValue);
|
|||
#ifdef __cplusplus
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
|
||||
extern std::map<std::string, CVar*> cvars;
|
||||
CVar* CVar_GetVar(const char* name);
|
||||
extern std::map<std::string, std::unique_ptr<CVar>, std::less<>> cvars;
|
||||
void CVar_SetFloat(const char* name, float value);
|
||||
void CVar_SetString(const char* name, char* value);
|
||||
void CVar_SetString(const char* name, const char* value);
|
||||
#endif
|
||||
#endif
|
||||
|
|
225
libultraship/libultraship/GameOverlay.cpp
Normal file
225
libultraship/libultraship/GameOverlay.cpp
Normal file
|
@ -0,0 +1,225 @@
|
|||
#include "GameOverlay.h"
|
||||
|
||||
#include "Cvar.h"
|
||||
#include "File.h"
|
||||
#include "Archive.h"
|
||||
#include "ResourceMgr.h"
|
||||
#include "SohConsole.h"
|
||||
#include "SohImGuiImpl.h"
|
||||
#include "TextureMod.h"
|
||||
#include "Lib/ImGui/imgui_internal.h"
|
||||
#include "Utils/StringHelper.h"
|
||||
|
||||
void Ship::GameOverlay::LoadFont(const std::string& name, const std::string& path, float fontSize) {
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
std::shared_ptr<Archive> base = GlobalCtx2::GetInstance()->GetResourceManager()->GetArchive();
|
||||
std::shared_ptr<File> font = std::make_shared<File>();
|
||||
base->LoadFile(path, false, font);
|
||||
if (font->bIsLoaded) {
|
||||
char* font_data = new char[font->dwBufferSize];
|
||||
memcpy(font_data, font->buffer.get(), font->dwBufferSize);
|
||||
Fonts[name] = io.Fonts->AddFontFromMemoryTTF(font_data, font->dwBufferSize, fontSize);
|
||||
}
|
||||
}
|
||||
|
||||
void Ship::GameOverlay::TextDraw(float x, float y, bool shadow, ImVec4 color, const char* fmt, ...) {
|
||||
char buf[1024];
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
vsnprintf(buf, IM_ARRAYSIZE(buf), fmt, args);
|
||||
buf[IM_ARRAYSIZE(buf) - 1] = 0;
|
||||
va_end(args);
|
||||
|
||||
ImGui::PushStyleColor(ImGuiCol_Text, color);
|
||||
ImGui::PushFont(Fonts[this->CurrentFont]);
|
||||
if (shadow) {
|
||||
ImGui::SetCursorPos(ImVec2(x + 1, y + 1));
|
||||
ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(.0f, .0f, .0f, color.w));
|
||||
ImGui::Text(buf, args);
|
||||
}
|
||||
ImGui::PopStyleColor();
|
||||
ImGui::SetCursorPos(ImVec2(x, y));
|
||||
ImGui::Text(buf, args);
|
||||
ImGui::PopFont();
|
||||
ImGui::PopStyleColor();
|
||||
}
|
||||
|
||||
void Ship::GameOverlay::TextDrawNotification(float duration, bool shadow, const char* fmt, ...) {
|
||||
char buf[1024];
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
vsnprintf(buf, IM_ARRAYSIZE(buf), fmt, args);
|
||||
buf[IM_ARRAYSIZE(buf) - 1] = 0;
|
||||
va_end(args);
|
||||
this->RegisteredOverlays[StringHelper::Sprintf("NotificationID:%d%d", rand(), this->RegisteredOverlays.size())] = new Overlay({ OverlayType::NOTIFICATION, ImStrdup(buf), duration, duration });
|
||||
NeedsCleanup = true;
|
||||
}
|
||||
|
||||
void Ship::GameOverlay::CleanupNotifications() {
|
||||
if(!NeedsCleanup) return;
|
||||
for (auto it = this->RegisteredOverlays.begin(); it != this->RegisteredOverlays.end(); ) {
|
||||
if (it->second->type == OverlayType::NOTIFICATION && it->second->duration <= 0.0f) {
|
||||
it = this->RegisteredOverlays.erase(it);
|
||||
} else {
|
||||
++it;
|
||||
}
|
||||
}
|
||||
NeedsCleanup = false;
|
||||
}
|
||||
|
||||
float Ship::GameOverlay::GetScreenWidth() {
|
||||
const ImGuiViewport* viewport = ImGui::GetMainViewport();
|
||||
return viewport->Size.x;
|
||||
}
|
||||
|
||||
float Ship::GameOverlay::GetScreenHeight() {
|
||||
const ImGuiViewport* viewport = ImGui::GetMainViewport();
|
||||
return viewport->Size.y;
|
||||
}
|
||||
|
||||
float Ship::GameOverlay::GetStringWidth(const char* text) {
|
||||
return CalculateTextSize(text).x;
|
||||
}
|
||||
|
||||
ImVec2 Ship::GameOverlay::CalculateTextSize(const char* text, const char* text_end, bool hide_text_after_double_hash, float wrap_width) {
|
||||
ImGuiContext& g = *GImGui;
|
||||
|
||||
const char* text_display_end;
|
||||
if (hide_text_after_double_hash)
|
||||
text_display_end = ImGui::FindRenderedTextEnd(text, text_end); // Hide anything after a '##' string
|
||||
else
|
||||
text_display_end = text_end;
|
||||
|
||||
GameOverlay* overlay = SohImGui::overlay;
|
||||
|
||||
ImFont* font = overlay->CurrentFont == "Default" ? g.Font : overlay->Fonts[overlay->CurrentFont];
|
||||
const float font_size = font->FontSize;
|
||||
if (text == text_display_end)
|
||||
return ImVec2(0.0f, font_size);
|
||||
ImVec2 text_size = font->CalcTextSizeA(font_size, FLT_MAX, wrap_width, text, text_display_end, NULL);
|
||||
|
||||
// Round
|
||||
// FIXME: This has been here since Dec 2015 (7b0bf230) but down the line we want this out.
|
||||
// FIXME: Investigate using ceilf or e.g.
|
||||
// - https://git.musl-libc.org/cgit/musl/tree/src/math/ceilf.c
|
||||
// - https://embarkstudios.github.io/rust-gpu/api/src/libm/math/ceilf.rs.html
|
||||
text_size.x = IM_FLOOR(text_size.x + 0.99999f);
|
||||
|
||||
return text_size;
|
||||
}
|
||||
|
||||
void Ship::GameOverlay::Init() {
|
||||
this->LoadFont("Press Start 2P", "assets/ship_of_harkinian/fonts/PressStart2P-Regular.ttf", 12.0f);
|
||||
this->LoadFont("Fipps", "assets/ship_of_harkinian/fonts/Fipps-Regular.otf", 32.0f);
|
||||
const std::string DefaultFont = this->Fonts.begin()->first;
|
||||
if(!this->Fonts.empty()) {
|
||||
const std::string font = CVar_GetString("gOverlayFont", ImStrdup(DefaultFont.c_str()));
|
||||
for (auto& [name, _] : this->Fonts) {
|
||||
if (font.starts_with(name)) {
|
||||
this->CurrentFont = name;
|
||||
break;
|
||||
}
|
||||
this->CurrentFont = DefaultFont;
|
||||
}
|
||||
}
|
||||
SohImGui::console->Commands["overlay"] = { OverlayCommand, "Draw an overlay using a cvar value" };
|
||||
}
|
||||
|
||||
void Ship::GameOverlay::DrawSettings() {
|
||||
ImGui::Text("Overlays Text Font");
|
||||
if (ImGui::BeginCombo("##TextFont", this->CurrentFont.c_str())) {
|
||||
for (auto& [name, font] : this->Fonts) {
|
||||
if (ImGui::Selectable(name.c_str(), name == this->CurrentFont)) {
|
||||
this->CurrentFont = name;
|
||||
CVar_SetString("gOverlayFont", ImStrdup(name.c_str()));
|
||||
SohImGui::needs_save = true;
|
||||
}
|
||||
|
||||
}
|
||||
ImGui::EndCombo();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Ship::GameOverlay::Draw() {
|
||||
const ImGuiViewport* viewport = ImGui::GetMainViewport();
|
||||
|
||||
ImGui::SetNextWindowPos(viewport->Pos, ImGuiCond_Always);
|
||||
ImGui::SetNextWindowSize(viewport->Size, ImGuiCond_Always);
|
||||
ImGui::Begin("SoHOverlay", nullptr, ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoBackground |
|
||||
ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_NoSavedSettings | ImGuiWindowFlags_NoInputs);
|
||||
|
||||
this->CleanupNotifications();
|
||||
|
||||
float textY = 50;
|
||||
float notY = 0;
|
||||
|
||||
for (auto &[key, overlay] : this->RegisteredOverlays) {
|
||||
|
||||
if (overlay->type == OverlayType::TEXT) {
|
||||
const char* text = ImStrdup(overlay->value);
|
||||
const CVar* var = CVar_Get(text);
|
||||
ImVec4 color = ImVec4(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
|
||||
switch (var->type) {
|
||||
case CVAR_TYPE_FLOAT:
|
||||
this->TextDraw(30, textY, true, color, "%s %.2f", text, var->value.valueFloat);
|
||||
break;
|
||||
case CVAR_TYPE_S32:
|
||||
this->TextDraw(30, textY, true, color, "%s %d", text, var->value.valueS32);
|
||||
break;
|
||||
case CVAR_TYPE_STRING:
|
||||
this->TextDraw(30, textY, true, color, "%s %s", text, var->value.valueStr);
|
||||
break;
|
||||
}
|
||||
|
||||
free((void*) text);
|
||||
textY += 30;
|
||||
}
|
||||
|
||||
if (overlay->type == OverlayType::NOTIFICATION && overlay->duration > 0) {
|
||||
const char* text = overlay->value;
|
||||
const float duration = overlay->duration / overlay->fadeTime;
|
||||
|
||||
const ImVec4 color = ImVec4(1.0f, 1.0f, 1.0f, duration);
|
||||
const float textWidth = this->GetStringWidth(overlay->value);
|
||||
|
||||
this->TextDraw(GetScreenWidth() - textWidth - 40, GetScreenHeight() - 40 - notY, true, color, text);
|
||||
notY += 30;
|
||||
overlay->duration -= .05f;
|
||||
}
|
||||
}
|
||||
|
||||
ImGui::End();
|
||||
}
|
||||
|
||||
|
||||
bool Ship::OverlayCommand(const std::vector<std::string>& args) {
|
||||
if (args.size() < 3) {
|
||||
return CMD_FAILED;
|
||||
}
|
||||
|
||||
if (CVar_Get(args[2].c_str()) != nullptr) {
|
||||
const char* key = args[2].c_str();
|
||||
GameOverlay* overlay = SohImGui::overlay;
|
||||
if (args[1] == "add") {
|
||||
if (!overlay->RegisteredOverlays.contains(key)) {
|
||||
overlay->RegisteredOverlays[key] = new Overlay({ OverlayType::TEXT, ImStrdup(key), -1.0f });
|
||||
INFO("Added overlay: %s ", key);
|
||||
} else {
|
||||
ERROR("Overlay already exists: %s", key);
|
||||
}
|
||||
} else if (args[1] == "remove") {
|
||||
if (overlay->RegisteredOverlays.contains(key)) {
|
||||
overlay->RegisteredOverlays.erase(key);
|
||||
INFO("Removed overlay: %s ", key);
|
||||
} else {
|
||||
ERROR("Overlay not found: %s ", key);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
ERROR("CVar %s does not exist", args[2].c_str());
|
||||
}
|
||||
|
||||
return CMD_SUCCESS;
|
||||
}
|
42
libultraship/libultraship/GameOverlay.h
Normal file
42
libultraship/libultraship/GameOverlay.h
Normal file
|
@ -0,0 +1,42 @@
|
|||
#pragma once
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "Lib/ImGui/imgui.h"
|
||||
#include <map>
|
||||
#include <unordered_map>
|
||||
|
||||
enum class OverlayType {
|
||||
TEXT, IMAGE, NOTIFICATION
|
||||
};
|
||||
|
||||
struct Overlay {
|
||||
OverlayType type;
|
||||
const char* value;
|
||||
float fadeTime;
|
||||
float duration;
|
||||
};
|
||||
|
||||
namespace Ship {
|
||||
class GameOverlay {
|
||||
public:
|
||||
std::unordered_map<std::string, Overlay*> RegisteredOverlays;
|
||||
std::unordered_map<std::string, ImFont*> Fonts;
|
||||
std::string CurrentFont = "Default";
|
||||
void Init();
|
||||
void Draw();
|
||||
void DrawSettings();
|
||||
static float GetScreenWidth();
|
||||
static float GetScreenHeight();
|
||||
static float GetStringWidth(const char* text);
|
||||
static ImVec2 CalculateTextSize(const char* text, const char* text_end = NULL, bool hide_text_after_double_hash = false, float wrap_width = -1.0f);
|
||||
void TextDraw(float x, float y, bool shadow, ImVec4 color, const char* text, ...);
|
||||
void TextDrawNotification(float duration, bool shadow, const char* fmt, ...);
|
||||
private:
|
||||
bool NeedsCleanup = false;
|
||||
void CleanupNotifications();
|
||||
void LoadFont(const std::string& name, const std::string& path, float fontSize);
|
||||
};
|
||||
|
||||
static bool OverlayCommand(const std::vector<std::string>& args);
|
||||
}
|
|
@ -1,3 +1,6 @@
|
|||
#ifndef GAME_VERSION_H
|
||||
#define GAME_VERSION_H
|
||||
|
||||
#pragma once
|
||||
|
||||
#define OOT_NTSC_10 0xEC7011B7
|
||||
|
@ -18,3 +21,5 @@
|
|||
#define OOT_IQUE_TW 0x3D81FB3E
|
||||
#define OOT_IQUE_CN 0xB1E1E07B
|
||||
#define OOT_UNKNOWN 0xFFFFFFFF
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,3 +1,6 @@
|
|||
#ifndef GLOBAL_CTX_2
|
||||
#define GLOBAL_CTX_2
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
@ -39,3 +42,5 @@ namespace Ship {
|
|||
};
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
|
@ -31,10 +31,12 @@
|
|||
#include "../StrHash64.h"
|
||||
#include "../../SohImGuiImpl.h"
|
||||
#include "../../Environment.h"
|
||||
#include "../../GameVersions.h"
|
||||
#include "../../ResourceMgr.h"
|
||||
|
||||
// OTRTODO: fix header files for these
|
||||
extern "C" {
|
||||
char* ResourceMgr_GetNameByCRC(uint64_t crc, char* alloc);
|
||||
const char* ResourceMgr_GetNameByCRC(uint64_t crc);
|
||||
int32_t* ResourceMgr_LoadMtxByCRC(uint64_t crc);
|
||||
Vtx* ResourceMgr_LoadVtxByCRC(uint64_t crc);
|
||||
Gfx* ResourceMgr_LoadGfxByCRC(uint64_t crc);
|
||||
|
@ -86,7 +88,7 @@ struct LoadedVertex {
|
|||
|
||||
static struct {
|
||||
TextureCacheMap map;
|
||||
list<TextureCacheMap::iterator> lru;
|
||||
list<TextureCacheMapIter> lru;
|
||||
vector<uint32_t> free_texture_ids;
|
||||
} gfx_texture_cache;
|
||||
|
||||
|
@ -132,14 +134,14 @@ static struct RDP {
|
|||
const uint8_t *addr;
|
||||
uint8_t siz;
|
||||
uint32_t width;
|
||||
char* otr_path;
|
||||
const char* otr_path;
|
||||
} texture_to_load;
|
||||
struct {
|
||||
const uint8_t *addr;
|
||||
uint32_t size_bytes;
|
||||
uint32_t full_image_line_size_bytes;
|
||||
uint32_t line_size_bytes;
|
||||
char* otr_path;
|
||||
const char* otr_path;
|
||||
} loaded_texture[2];
|
||||
struct {
|
||||
uint8_t fmt;
|
||||
|
@ -188,8 +190,12 @@ static int game_framebuffer_msaa_resolved;
|
|||
|
||||
uint32_t gfx_msaa_level = 1;
|
||||
|
||||
static bool has_drawn_imgui_menu;
|
||||
|
||||
static bool dropped_frame;
|
||||
|
||||
static const std::unordered_map<Mtx *, MtxF> *current_mtx_replacements;
|
||||
|
||||
static float buf_vbo[MAX_BUFFERED * (32 * 3)]; // 3 vertices in a triangle and 32 floats per vtx
|
||||
static size_t buf_vbo_len;
|
||||
static size_t buf_vbo_num_tris;
|
||||
|
@ -521,18 +527,18 @@ static bool gfx_texture_cache_lookup(int i, int tile) {
|
|||
key = { orig_addr, { }, fmt, siz, palette_index };
|
||||
}
|
||||
|
||||
auto it = gfx_texture_cache.map.find(key);
|
||||
TextureCacheMap::iterator it = gfx_texture_cache.map.find(key);
|
||||
|
||||
if (it != gfx_texture_cache.map.end()) {
|
||||
gfx_rapi->select_texture(i, it->second.texture_id);
|
||||
*n = &*it;
|
||||
gfx_texture_cache.lru.splice(gfx_texture_cache.lru.end(), gfx_texture_cache.lru, *(list<TextureCacheMap::iterator>::iterator*)&it->second.lru_location); // move to back
|
||||
gfx_texture_cache.lru.splice(gfx_texture_cache.lru.end(), gfx_texture_cache.lru, it->second.lru_location); // move to back
|
||||
return true;
|
||||
}
|
||||
|
||||
if (gfx_texture_cache.map.size() >= TEXTURE_CACHE_MAX_SIZE) {
|
||||
// Remove the texture that was least recently used
|
||||
it = gfx_texture_cache.lru.front();
|
||||
it = gfx_texture_cache.lru.front().it;
|
||||
gfx_texture_cache.free_texture_ids.push_back(it->second.texture_id);
|
||||
gfx_texture_cache.map.erase(it);
|
||||
gfx_texture_cache.lru.pop_front();
|
||||
|
@ -549,7 +555,7 @@ static bool gfx_texture_cache_lookup(int i, int tile) {
|
|||
it = gfx_texture_cache.map.insert(make_pair(key, TextureCacheValue())).first;
|
||||
TextureCacheNode* node = &*it;
|
||||
node->second.texture_id = texture_id;
|
||||
*(list<TextureCacheMap::iterator>::iterator*)&node->second.lru_location = gfx_texture_cache.lru.insert(gfx_texture_cache.lru.end(), it);
|
||||
node->second.lru_location = gfx_texture_cache.lru.insert(gfx_texture_cache.lru.end(), { it });
|
||||
|
||||
gfx_rapi->select_texture(i, texture_id);
|
||||
gfx_rapi->set_sampler_parameters(i, false, 0, 0);
|
||||
|
@ -565,7 +571,7 @@ static void gfx_texture_cache_delete(const uint8_t* orig_addr)
|
|||
bool again = false;
|
||||
for (auto it = gfx_texture_cache.map.begin(bucket); it != gfx_texture_cache.map.end(bucket); ++it) {
|
||||
if (it->first.texture_addr == orig_addr) {
|
||||
gfx_texture_cache.lru.erase(*(list<TextureCacheMap::iterator>::iterator*)&it->second.lru_location);
|
||||
gfx_texture_cache.lru.erase(it->second.lru_location);
|
||||
gfx_texture_cache.free_texture_ids.push_back(it->second.texture_id);
|
||||
gfx_texture_cache.map.erase(it->first);
|
||||
again = true;
|
||||
|
@ -914,6 +920,16 @@ static void gfx_matrix_mul(float res[4][4], const float a[4][4], const float b[4
|
|||
|
||||
static void gfx_sp_matrix(uint8_t parameters, const int32_t *addr) {
|
||||
float matrix[4][4];
|
||||
|
||||
if (auto it = current_mtx_replacements->find((Mtx *)addr); it != current_mtx_replacements->end()) {
|
||||
for (int i = 0; i < 4; i++) {
|
||||
for (int j = 0; j < 4; j++) {
|
||||
float v = it->second.mf[i][j];
|
||||
int as_int = (int)(v * 65536.0f);
|
||||
matrix[i][j] = as_int * (1.0f / 65536.0f);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
#ifndef GBI_FLOATS
|
||||
// Original GBI where fixed point matrices are used
|
||||
for (int i = 0; i < 4; i++) {
|
||||
|
@ -928,6 +944,7 @@ static void gfx_sp_matrix(uint8_t parameters, const int32_t *addr) {
|
|||
// For a modified GBI where fixed point values are replaced with floats
|
||||
memcpy(matrix, addr, sizeof(matrix));
|
||||
#endif
|
||||
}
|
||||
|
||||
if (parameters & G_MTX_PROJECTION) {
|
||||
if (parameters & G_MTX_LOAD) {
|
||||
|
@ -1619,11 +1636,11 @@ static void gfx_dp_set_scissor(uint32_t mode, uint32_t ulx, uint32_t uly, uint32
|
|||
rdp.viewport_or_scissor_changed = true;
|
||||
}
|
||||
|
||||
static void gfx_dp_set_texture_image(uint32_t format, uint32_t size, uint32_t width, const void* addr, char* otr_path) {
|
||||
static void gfx_dp_set_texture_image(uint32_t format, uint32_t size, uint32_t width, const void* addr, const char* otr_path) {
|
||||
rdp.texture_to_load.addr = (const uint8_t*)addr;
|
||||
rdp.texture_to_load.siz = size;
|
||||
rdp.texture_to_load.width = width;
|
||||
if ( otr_path != nullptr && !strncmp(otr_path, "__OTR__", 7)) otr_path = otr_path + 7;
|
||||
if (otr_path != nullptr && !strncmp(otr_path, "__OTR__", 7)) otr_path = otr_path + 7;
|
||||
rdp.texture_to_load.otr_path = otr_path;
|
||||
}
|
||||
|
||||
|
@ -2097,7 +2114,7 @@ static void gfx_run_dl(Gfx* cmd) {
|
|||
//puts("dl");
|
||||
int dummy = 0;
|
||||
char dlName[128];
|
||||
char fileName[128];
|
||||
const char* fileName;
|
||||
|
||||
Gfx* dListStart = cmd;
|
||||
uint64_t ourHash = -1;
|
||||
|
@ -2151,8 +2168,16 @@ static void gfx_run_dl(Gfx* cmd) {
|
|||
uintptr_t mtxAddr = cmd->words.w1;
|
||||
|
||||
// OTRTODO: Temp way of dealing with gMtxClear. Need something more elegant in the future...
|
||||
if (mtxAddr == SEG_ADDR(0, 0x12DB20) || mtxAddr == SEG_ADDR(0, 0x12DB40))
|
||||
uint32_t gameVersion = Ship::GlobalCtx2::GetInstance()->GetResourceManager()->GetGameVersion();
|
||||
if (gameVersion == OOT_PAL_GC) {
|
||||
if (mtxAddr == SEG_ADDR(0, 0x0FBC20)) {
|
||||
mtxAddr = clearMtx;
|
||||
}
|
||||
} else {
|
||||
if (mtxAddr == SEG_ADDR(0, 0x12DB20) || mtxAddr == SEG_ADDR(0, 0x12DB40)) {
|
||||
mtxAddr = clearMtx;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef F3DEX_GBI_2
|
||||
gfx_sp_matrix(C0(0, 8) ^ G_MTX_PUSH, (const int32_t *) seg_addr(mtxAddr));
|
||||
|
@ -2412,7 +2437,7 @@ static void gfx_run_dl(Gfx* cmd) {
|
|||
uintptr_t addr = cmd->words.w1;
|
||||
cmd++;
|
||||
uint64_t hash = ((uint64_t)cmd->words.w0 << 32) + (uint64_t)cmd->words.w1;
|
||||
ResourceMgr_GetNameByCRC(hash, fileName);
|
||||
fileName = ResourceMgr_GetNameByCRC(hash);
|
||||
#if _DEBUG && 0
|
||||
char* tex = ResourceMgr_LoadTexByCRC(hash);
|
||||
ResourceMgr_GetNameByCRC(hash, fileName);
|
||||
|
@ -2698,6 +2723,7 @@ void gfx_start_frame(void) {
|
|||
gfx_wapi->handle_events();
|
||||
gfx_wapi->get_dimensions(&gfx_current_window_dimensions.width, &gfx_current_window_dimensions.height);
|
||||
SohImGui::DrawMainMenuAndCalculateGameSize();
|
||||
has_drawn_imgui_menu = true;
|
||||
if (gfx_current_dimensions.height == 0) {
|
||||
// Avoid division by zero
|
||||
gfx_current_dimensions.height = 1;
|
||||
|
@ -2736,7 +2762,7 @@ void gfx_start_frame(void) {
|
|||
fbActive = 0;
|
||||
}
|
||||
|
||||
void gfx_run(Gfx *commands) {
|
||||
void gfx_run(Gfx *commands, const std::unordered_map<Mtx *, MtxF>& mtx_replacements) {
|
||||
gfx_sp_reset();
|
||||
|
||||
//puts("New frame");
|
||||
|
@ -2745,12 +2771,21 @@ void gfx_run(Gfx *commands) {
|
|||
|
||||
if (!gfx_wapi->start_frame()) {
|
||||
dropped_frame = true;
|
||||
if (has_drawn_imgui_menu) {
|
||||
SohImGui::DrawFramebufferAndGameInput();
|
||||
SohImGui::CancelFrame();
|
||||
has_drawn_imgui_menu = false;
|
||||
}
|
||||
return;
|
||||
}
|
||||
dropped_frame = false;
|
||||
|
||||
if (!has_drawn_imgui_menu) {
|
||||
SohImGui::DrawMainMenuAndCalculateGameSize();
|
||||
}
|
||||
|
||||
current_mtx_replacements = &mtx_replacements;
|
||||
|
||||
double t0 = gfx_wapi->get_time();
|
||||
gfx_rapi->update_framebuffer_parameters(0, gfx_current_window_dimensions.width, gfx_current_window_dimensions.height, 1, false, true, true, !game_renders_to_framebuffer);
|
||||
gfx_rapi->start_frame();
|
||||
|
@ -2782,6 +2817,7 @@ void gfx_run(Gfx *commands) {
|
|||
//printf("Process %f %f\n", t1, t1 - t0);
|
||||
gfx_rapi->end_frame();
|
||||
gfx_wapi->swap_buffers_begin();
|
||||
has_drawn_imgui_menu = false;
|
||||
}
|
||||
|
||||
void gfx_end_frame(void) {
|
||||
|
|
|
@ -6,6 +6,8 @@
|
|||
#include <unordered_map>
|
||||
#include <list>
|
||||
|
||||
#include "U64/PR/ultra64/types.h"
|
||||
|
||||
struct GfxRenderingAPI;
|
||||
struct GfxWindowManagerAPI;
|
||||
|
||||
|
@ -44,34 +46,31 @@ struct TextureCacheValue {
|
|||
uint8_t cms, cmt;
|
||||
bool linear_filter;
|
||||
|
||||
// Old versions of libstdc++ fail to compile this
|
||||
#ifdef _MSC_VER
|
||||
std::list<TextureCacheMap::iterator>::iterator lru_location;
|
||||
#else
|
||||
std::list<int>::iterator lru_location;
|
||||
#endif
|
||||
std::list<struct TextureCacheMapIter>::iterator lru_location;
|
||||
};
|
||||
|
||||
struct TextureCacheMapIter {
|
||||
TextureCacheMap::iterator it;
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
extern struct GfxDimensions gfx_current_window_dimensions; // The dimensions of the window
|
||||
extern struct GfxDimensions gfx_current_dimensions; // The dimensions of the draw area the game draws to, before scaling (if applicable)
|
||||
extern struct XYWidthHeight gfx_current_game_window_viewport; // The area of the window the game is drawn to, (0, 0) is top-left corner
|
||||
extern uint32_t gfx_msaa_level;
|
||||
|
||||
}
|
||||
|
||||
void gfx_init(struct GfxWindowManagerAPI* wapi, struct GfxRenderingAPI* rapi, const char* game_name, bool start_in_fullscreen);
|
||||
struct GfxRenderingAPI* gfx_get_current_rendering_api(void);
|
||||
void gfx_start_frame(void);
|
||||
void gfx_run(Gfx* commands);
|
||||
void gfx_run(Gfx* commands, const std::unordered_map<Mtx*, MtxF>& mtx_replacements);
|
||||
void gfx_end_frame(void);
|
||||
void gfx_set_framedivisor(int);
|
||||
void gfx_texture_cache_clear();
|
||||
int gfx_create_framebuffer(uint32_t width, uint32_t height);
|
||||
extern "C" int gfx_create_framebuffer(uint32_t width, uint32_t height);
|
||||
void gfx_get_pixel_depth_prepare(float x, float y);
|
||||
uint16_t gfx_get_pixel_depth(float x, float y);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
|
|
@ -40,8 +40,11 @@ namespace Ship
|
|||
|
||||
for (size_t i = 0; i < patches.size(); i++)
|
||||
{
|
||||
std::string hashStr = resMgr->HashToString(patches[i].crc);
|
||||
auto resShared = resMgr->GetCachedFile(hashStr);
|
||||
const std::string* hashStr = resMgr->HashToString(patches[i].crc);
|
||||
if (hashStr == nullptr)
|
||||
continue;
|
||||
|
||||
auto resShared = resMgr->GetCachedFile(hashStr->c_str());
|
||||
if (resShared != nullptr)
|
||||
{
|
||||
auto res = (Ship::DisplayList*)resShared.get();
|
||||
|
|
|
@ -215,7 +215,7 @@ namespace Ship {
|
|||
return ToLoad;
|
||||
}
|
||||
|
||||
std::shared_ptr<Ship::Resource> ResourceMgr::GetCachedFile(std::string FilePath) {
|
||||
std::shared_ptr<Ship::Resource> ResourceMgr::GetCachedFile(const char* FilePath) const {
|
||||
auto resCacheFind = ResourceCache.find(FilePath);
|
||||
|
||||
if (resCacheFind != ResourceCache.end() &&
|
||||
|
@ -227,8 +227,13 @@ namespace Ship {
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
std::shared_ptr<Resource> ResourceMgr::LoadResource(std::string FilePath) {
|
||||
auto Promise = LoadResourceAsync(FilePath);
|
||||
std::shared_ptr<Resource> ResourceMgr::LoadResource(const char* FilePath) {
|
||||
auto Res = LoadResourceAsync(FilePath);
|
||||
|
||||
if (std::holds_alternative<std::shared_ptr<Resource>>(Res))
|
||||
return std::get<std::shared_ptr<Resource>>(Res);
|
||||
|
||||
auto& Promise = std::get<std::shared_ptr<ResourcePromise>>(Res);
|
||||
|
||||
if (!Promise->bHasResourceLoaded)
|
||||
{
|
||||
|
@ -241,21 +246,18 @@ namespace Ship {
|
|||
return Promise->resource;
|
||||
}
|
||||
|
||||
std::shared_ptr<ResourcePromise> ResourceMgr::LoadResourceAsync(std::string FilePath) {
|
||||
StringHelper::ReplaceOriginal(FilePath, "\\", "/");
|
||||
|
||||
if (StringHelper::StartsWith(FilePath, "__OTR__"))
|
||||
FilePath = StringHelper::Split(FilePath, "__OTR__")[1];
|
||||
|
||||
std::shared_ptr<ResourcePromise> Promise = std::make_shared<ResourcePromise>();
|
||||
std::variant<std::shared_ptr<Resource>, std::shared_ptr<ResourcePromise>> ResourceMgr::LoadResourceAsync(const char* FilePath) {
|
||||
if (FilePath[0] == '_' && FilePath[1] == '_' && FilePath[2] == 'O' && FilePath[3] == 'T' && FilePath[4] == 'R' && FilePath[5] == '_' && FilePath[6] == '_')
|
||||
FilePath += 7;
|
||||
|
||||
const std::lock_guard<std::mutex> ResLock(ResourceLoadMutex);
|
||||
auto resCacheFind = ResourceCache.find(FilePath);
|
||||
if (resCacheFind == ResourceCache.end() || resCacheFind->second->isDirty/* || !FileData->bIsLoaded*/) {
|
||||
if (resCacheFind == ResourceCache.end()) {
|
||||
SPDLOG_TRACE("Cache miss on Resource load: {}", FilePath.c_str());
|
||||
SPDLOG_TRACE("Cache miss on Resource load: {}", FilePath);
|
||||
}
|
||||
|
||||
std::shared_ptr<ResourcePromise> Promise = std::make_shared<ResourcePromise>();
|
||||
std::shared_ptr<File> FileData = LoadFile(FilePath);
|
||||
Promise->file = FileData;
|
||||
|
||||
|
@ -269,23 +271,29 @@ namespace Ship {
|
|||
ResourceLoadQueue.push(Promise);
|
||||
ResourceLoadNotifier.notify_all();
|
||||
}
|
||||
} else {
|
||||
Promise->bHasResourceLoaded = true;
|
||||
Promise->resource = resCacheFind->second;
|
||||
}
|
||||
|
||||
return Promise;
|
||||
}
|
||||
else
|
||||
{
|
||||
return resCacheFind->second;
|
||||
}
|
||||
}
|
||||
|
||||
std::shared_ptr<std::vector<std::shared_ptr<ResourcePromise>>> ResourceMgr::CacheDirectoryAsync(std::string SearchMask) {
|
||||
auto loadedList = std::make_shared<std::vector<std::shared_ptr<ResourcePromise>>>();
|
||||
auto fileList = OTR->ListFiles(SearchMask);
|
||||
|
||||
for (DWORD i = 0; i < fileList.size(); i++) {
|
||||
auto file = LoadResourceAsync(fileList.operator[](i).cFileName);
|
||||
if (file != nullptr) {
|
||||
loadedList->push_back(file);
|
||||
auto resource = LoadResourceAsync(fileList.operator[](i).cFileName);
|
||||
if (std::holds_alternative<std::shared_ptr<Resource>>(resource))
|
||||
{
|
||||
auto promise = std::make_shared<ResourcePromise>();
|
||||
promise->bHasResourceLoaded = true;
|
||||
promise->resource = std::get<std::shared_ptr<Resource>>(resource);
|
||||
resource = promise;
|
||||
}
|
||||
loadedList->push_back(std::get<std::shared_ptr<ResourcePromise>>(resource));
|
||||
}
|
||||
|
||||
return loadedList;
|
||||
|
@ -335,7 +343,7 @@ namespace Ship {
|
|||
ResourceCache.clear();
|
||||
}
|
||||
|
||||
std::string ResourceMgr::HashToString(uint64_t Hash) {
|
||||
const std::string* ResourceMgr::HashToString(uint64_t Hash) const {
|
||||
return OTR->HashToString(Hash);
|
||||
}
|
||||
}
|
|
@ -4,6 +4,7 @@
|
|||
#include <string>
|
||||
#include <thread>
|
||||
#include <queue>
|
||||
#include <variant>
|
||||
#include "Resource.h"
|
||||
#include "GlobalCtx2.h"
|
||||
|
||||
|
@ -25,7 +26,7 @@ namespace Ship
|
|||
std::shared_ptr<Archive> GetArchive() { return OTR; }
|
||||
std::shared_ptr<GlobalCtx2> GetContext() { return Context.lock(); }
|
||||
|
||||
std::string HashToString(uint64_t Hash);
|
||||
const std::string* HashToString(uint64_t Hash) const;
|
||||
|
||||
void InvalidateResourceCache();
|
||||
|
||||
|
@ -33,9 +34,10 @@ namespace Ship
|
|||
void SetGameVersion(uint32_t newGameVersion);
|
||||
std::shared_ptr<File> LoadFileAsync(std::string FilePath);
|
||||
std::shared_ptr<File> LoadFile(std::string FilePath);
|
||||
std::shared_ptr<Ship::Resource> GetCachedFile(std::string FilePath);
|
||||
std::shared_ptr<Resource> LoadResource(std::string FilePath);
|
||||
std::shared_ptr<ResourcePromise> LoadResourceAsync(std::string FilePath);
|
||||
std::shared_ptr<Ship::Resource> GetCachedFile(const char* FilePath) const;
|
||||
std::shared_ptr<Resource> LoadResource(const char* FilePath);
|
||||
std::shared_ptr<Resource> LoadResource(const std::string& FilePath) { return LoadResource(FilePath.c_str()); }
|
||||
std::variant<std::shared_ptr<Resource>, std::shared_ptr<ResourcePromise>> LoadResourceAsync(const char* FilePath);
|
||||
std::shared_ptr<std::vector<std::shared_ptr<Resource>>> CacheDirectory(std::string SearchMask);
|
||||
std::shared_ptr<std::vector<std::shared_ptr<ResourcePromise>>> CacheDirectoryAsync(std::string SearchMask);
|
||||
std::shared_ptr<std::vector<std::shared_ptr<Resource>>> DirtyDirectory(std::string SearchMask);
|
||||
|
@ -50,7 +52,7 @@ namespace Ship
|
|||
std::weak_ptr<GlobalCtx2> Context;
|
||||
volatile bool bIsRunning;
|
||||
std::map<std::string, std::shared_ptr<File>> FileCache;
|
||||
std::map<std::string, std::shared_ptr<Resource>> ResourceCache;
|
||||
std::map<std::string, std::shared_ptr<Resource>, std::less<>> ResourceCache;
|
||||
std::queue<std::shared_ptr<File>> FileLoadQueue;
|
||||
std::queue<std::shared_ptr<ResourcePromise>> ResourceLoadQueue;
|
||||
std::shared_ptr<Archive> OTR;
|
||||
|
|
|
@ -92,7 +92,7 @@ void Console::Update() {
|
|||
}
|
||||
for (auto [key, var] : BindingToggle) {
|
||||
if (ImGui::IsKeyPressed(key)) {
|
||||
CVar* cvar = CVar_GetVar(var.c_str());
|
||||
CVar* cvar = CVar_Get(var.c_str());
|
||||
Dispatch("set " + var + " " + std::to_string(cvar == nullptr ? 0 : !static_cast<bool>(cvar->value.valueS32)));
|
||||
}
|
||||
}
|
||||
|
@ -106,7 +106,7 @@ void Console::Draw() {
|
|||
if (!this->opened) return;
|
||||
|
||||
ImGui::SetNextWindowSize(ImVec2(520, 600), ImGuiCond_FirstUseEver);
|
||||
ImGui::Begin("Console", nullptr);
|
||||
ImGui::Begin("Console", nullptr, ImGuiWindowFlags_NoFocusOnAppearing);
|
||||
const ImVec2 pos = ImGui::GetWindowPos();
|
||||
const ImVec2 size = ImGui::GetWindowSize();
|
||||
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
#include "TextureMod.h"
|
||||
#include "Window.h"
|
||||
#include "Cvar.h"
|
||||
#include "GameOverlay.h"
|
||||
#include "Texture.h"
|
||||
#include "../Fast3D/gfx_pc.h"
|
||||
#include "Lib/stb/stb_image.h"
|
||||
|
@ -59,8 +60,10 @@ namespace SohImGui {
|
|||
WindowImpl impl;
|
||||
ImGuiIO* io;
|
||||
Console* console = new Console;
|
||||
GameOverlay* overlay = new GameOverlay;
|
||||
bool p_open = false;
|
||||
bool needs_save = false;
|
||||
std::vector<const char*> CustomTexts;
|
||||
int SelectedLanguage = CVar_GetS32("gLanguages", 0); //Default Language to 0=English 1=German 2=French
|
||||
float kokiri_col[3] = { 0.118f, 0.41f, 0.106f };
|
||||
float goron_col[3] = { 0.392f, 0.078f, 0.0f };
|
||||
|
@ -254,7 +257,7 @@ namespace SohImGui {
|
|||
|
||||
void LoadTexture(const std::string& name, const std::string& path) {
|
||||
GfxRenderingAPI* api = gfx_get_current_rendering_api();
|
||||
const auto res = GlobalCtx2::GetInstance()->GetResourceManager()->LoadFile(normalize(path));
|
||||
const auto res = GlobalCtx2::GetInstance()->GetResourceManager()->LoadFile(path);
|
||||
|
||||
const auto asset = new GameAsset{ api->new_texture() };
|
||||
uint8_t* img_data = stbi_load_from_memory(reinterpret_cast<const stbi_uc*>(res->buffer.get()), res->dwBufferSize, &asset->width, &asset->height, nullptr, 4);
|
||||
|
@ -274,7 +277,7 @@ namespace SohImGui {
|
|||
|
||||
void LoadResource(const std::string& name, const std::string& path, const ImVec4& tint) {
|
||||
GfxRenderingAPI* api = gfx_get_current_rendering_api();
|
||||
const auto res = static_cast<Ship::Texture*>(GlobalCtx2::GetInstance()->GetResourceManager()->LoadResource(normalize(path)).get());
|
||||
const auto res = static_cast<Ship::Texture*>(GlobalCtx2::GetInstance()->GetResourceManager()->LoadResource(path).get());
|
||||
|
||||
std::vector<uint8_t> texBuffer;
|
||||
texBuffer.reserve(res->width * res->height * 4);
|
||||
|
@ -323,10 +326,13 @@ namespace SohImGui {
|
|||
ImGui::SetCurrentContext(ctx);
|
||||
io = &ImGui::GetIO();
|
||||
io->ConfigFlags |= ImGuiConfigFlags_DockingEnable;
|
||||
io->Fonts->AddFontDefault();
|
||||
|
||||
if (UseViewports()) {
|
||||
io->ConfigFlags |= ImGuiConfigFlags_ViewportsEnable;
|
||||
}
|
||||
console->Init();
|
||||
overlay->Init();
|
||||
ImGuiWMInit();
|
||||
ImGuiBackendInit();
|
||||
|
||||
|
@ -357,7 +363,7 @@ namespace SohImGui {
|
|||
|
||||
ModInternal::registerHookListener({ CONTROLLER_READ, [](const HookEvent ev) {
|
||||
pads = static_cast<OSContPad*>(ev->baseArgs["cont_pad"]);
|
||||
}});
|
||||
} });
|
||||
Game::InitSettings();
|
||||
}
|
||||
|
||||
|
@ -396,7 +402,7 @@ namespace SohImGui {
|
|||
EnhancementRadioButton("French", "gLanguages", 2);
|
||||
*/
|
||||
int val = CVar_GetS32(cvarName.c_str(), 0);
|
||||
if (ImGui::RadioButton(text.c_str(), id==val)) {
|
||||
if (ImGui::RadioButton(text.c_str(), id == val)) {
|
||||
CVar_SetS32(cvarName.c_str(), (int)id);
|
||||
needs_save = true;
|
||||
}
|
||||
|
@ -411,6 +417,15 @@ namespace SohImGui {
|
|||
}
|
||||
}
|
||||
|
||||
void EnhancementButton(std::string text, std::string cvarName)
|
||||
{
|
||||
bool val = (bool)CVar_GetS32(cvarName.c_str(), 0);
|
||||
if (ImGui::Button(text.c_str())) {
|
||||
CVar_SetS32(cvarName.c_str(), !val);
|
||||
needs_save = true;
|
||||
}
|
||||
}
|
||||
|
||||
void EnhancementSliderInt(std::string text, std::string id, std::string cvarName, int min, int max, std::string format)
|
||||
{
|
||||
int val = CVar_GetS32(cvarName.c_str(), 0);
|
||||
|
@ -490,6 +505,11 @@ namespace SohImGui {
|
|||
}
|
||||
}
|
||||
|
||||
void Tooltip(std::string text) {
|
||||
if (ImGui::IsItemHovered())
|
||||
ImGui::SetTooltip("%s", text.c_str());
|
||||
}
|
||||
|
||||
void DrawMainMenuAndCalculateGameSize() {
|
||||
console->Update();
|
||||
ImGuiBackendNewFrame();
|
||||
|
@ -588,15 +608,17 @@ namespace SohImGui {
|
|||
}
|
||||
|
||||
EnhancementCheckbox("Show Inputs", "gInputEnabled");
|
||||
Tooltip("Shows currently pressed inputs on the bottom right of the screen");
|
||||
EnhancementCheckbox("Rumble Enabled", "gRumbleEnabled");
|
||||
|
||||
EnhancementSliderFloat("Input Scale: %.1f", "##Input", "gInputScale", 1.0f, 3.0f, "", 1.0f, false);
|
||||
Tooltip("Sets the on screen size of the displayed inputs from Show Inputs");
|
||||
|
||||
ImGui::Separator();
|
||||
|
||||
EnhancementCheckbox("Dpad Support on Pause and File Select", "gDpadPauseName");
|
||||
EnhancementCheckbox("DPad Support in Ocarina and Text Choice", "gDpadOcarinaText");
|
||||
EnhancementCheckbox("DPad Support for Browsing Shop Items", "gDpadShop");
|
||||
EnhancementCheckbox("D-pad Support on Pause and File Select", "gDpadPauseName");
|
||||
EnhancementCheckbox("D-pad Support in Ocarina and Text Choice", "gDpadOcarinaText");
|
||||
EnhancementCheckbox("D-pad Support for Browsing Shop Items", "gDpadShop");
|
||||
|
||||
ImGui::EndMenu();
|
||||
}
|
||||
|
@ -604,8 +626,10 @@ namespace SohImGui {
|
|||
if (ImGui::BeginMenu("Graphics"))
|
||||
{
|
||||
EnhancementSliderInt("Internal Resolution: %dx", "##IMul", "gInternalResolution", 1, 8, "");
|
||||
Tooltip("Increases the render resolution of the game, up to 8x your output resolution,\nas a more intensive but effective form of anti-aliasing");
|
||||
gfx_current_dimensions.internal_mul = CVar_GetS32("gInternalResolution", 1);
|
||||
EnhancementSliderInt("MSAA: %d", "##IMSAA", "gMSAAValue", 1, 8, "");
|
||||
Tooltip("Activates anti-aliasing when above 1, up to 8x for 8 samples for every pixel");
|
||||
gfx_msaa_level = CVar_GetS32("gMSAAValue", 1);
|
||||
|
||||
EXPERIMENTAL();
|
||||
|
@ -617,13 +641,14 @@ namespace SohImGui {
|
|||
INFO("New Filter: %s", filters[fId]);
|
||||
gapi->set_texture_filter((FilteringMode)fId);
|
||||
|
||||
CVar_SetS32("gTextureFilter", (int) fId);
|
||||
CVar_SetS32("gTextureFilter", (int)fId);
|
||||
needs_save = true;
|
||||
}
|
||||
|
||||
}
|
||||
ImGui::EndCombo();
|
||||
}
|
||||
overlay->DrawSettings();
|
||||
ImGui::EndMenu();
|
||||
}
|
||||
|
||||
|
@ -636,35 +661,59 @@ namespace SohImGui {
|
|||
|
||||
if (ImGui::BeginMenu("Enhancements"))
|
||||
{
|
||||
ImGui::Text("Gameplay");
|
||||
ImGui::Separator();
|
||||
|
||||
if (ImGui::BeginMenu("Gameplay"))
|
||||
{
|
||||
EnhancementSliderInt("Text Speed: %dx", "##TEXTSPEED", "gTextSpeed", 1, 5, "");
|
||||
EnhancementSliderInt("King Zora Speed: %dx", "##WEEPSPEED", "gMweepSpeed", 1, 5, "");
|
||||
|
||||
EnhancementCheckbox("Skip Text", "gSkipText");
|
||||
Tooltip("Holding down B skips text");
|
||||
EnhancementCheckbox("Mute Low HP Alarm", "gLowHpAlarm");
|
||||
Tooltip("Disable the low HP beeping sound");
|
||||
EnhancementCheckbox("Minimal UI", "gMinimalUI");
|
||||
EnhancementCheckbox("MM Bunny Hood", "gMMBunnyHood");
|
||||
Tooltip("Hides most of the UI when not needed");
|
||||
EnhancementCheckbox("Visual Stone of Agony", "gVisualAgony");
|
||||
Tooltip("Displays an icon and plays a sound when Stone of Agony should be activated, for those without rumble");
|
||||
EnhancementCheckbox("Faster Block Push", "gFasterBlockPush");
|
||||
EnhancementCheckbox("Assignable Tunics and Boots", "gAssignableTunicsAndBoots");
|
||||
Tooltip("Allows equiping the tunic and boots to c-buttons");
|
||||
EnhancementCheckbox("MM Bunny Hood", "gMMBunnyHood");
|
||||
Tooltip("Wearing the Bunny Hood grants a speed increase like in Majora's Mask");
|
||||
|
||||
ImGui::Text("Graphics");
|
||||
ImGui::Separator();
|
||||
ImGui::EndMenu();
|
||||
}
|
||||
|
||||
if (ImGui::BeginMenu("Graphics"))
|
||||
{
|
||||
EnhancementCheckbox("N64 Mode", "gN64Mode");
|
||||
|
||||
Tooltip("Sets aspect ratio to 4:3 and lowers resolution to 240p, the N64's native resolution");
|
||||
EnhancementCheckbox("Animated Link in Pause Menu", "gPauseLiveLink");
|
||||
EnhancementCheckbox("Enable 3D Dropped items", "gNewDrops");
|
||||
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");
|
||||
Tooltip("Always shows dungeon entrance icons on the minimap");
|
||||
|
||||
ImGui::Text("Fixes");
|
||||
ImGui::Separator();
|
||||
ImGui::EndMenu();
|
||||
}
|
||||
|
||||
if (ImGui::BeginMenu("Fixes"))
|
||||
{
|
||||
EnhancementCheckbox("Fix L&R Pause menu", "gUniformLR");
|
||||
Tooltip("Makes the L and R buttons in the pause menu the same color");
|
||||
EnhancementCheckbox("Fix Dungeon entrances", "gFixDungeonMinimapIcon");
|
||||
Tooltip("Show dungeon entrances icon only when it should be");
|
||||
EnhancementCheckbox("Fix Two Handed idle animations", "gTwoHandedIdle");
|
||||
Tooltip("Makes two handed idle animation play, a seemingly finished animation that was disabled on accident in the original game");
|
||||
|
||||
ImGui::EndMenu();
|
||||
}
|
||||
|
||||
EXPERIMENTAL();
|
||||
|
||||
EnhancementCheckbox("60FPS Interpolation", "g60FPS");
|
||||
EnhancementCheckbox("Disable LOD", "gDisableLOD");
|
||||
Tooltip("Turns off the level of detail setting, making models always use their higher poly variants");
|
||||
|
||||
ImGui::EndMenu();
|
||||
}
|
||||
|
@ -706,22 +755,33 @@ namespace SohImGui {
|
|||
}
|
||||
|
||||
EnhancementCheckbox("No Clip", "gNoClip");
|
||||
Tooltip("Allows you to walk through walls");
|
||||
EnhancementCheckbox("Climb Everything", "gClimbEverything");
|
||||
Tooltip("Makes every surface in the game climbable");
|
||||
EnhancementCheckbox("Moon Jump on L", "gMoonJumpOnL");
|
||||
Tooltip("Holding L makes you float into the air");
|
||||
EnhancementCheckbox("Super Tunic", "gSuperTunic");
|
||||
Tooltip("Makes every tunic have the effects of every other tunic");
|
||||
EnhancementCheckbox("Easy ISG", "gEzISG");
|
||||
Tooltip("Automatically activates the Infinite Sword glitch, making you constantly swing your sword");
|
||||
EnhancementCheckbox("Unrestricted Items", "gNoRestrictItems");
|
||||
Tooltip("Allows you to use any item at any location");
|
||||
EnhancementCheckbox("Freeze Time", "gFreezeTime");
|
||||
Tooltip("Freezes the time of day");
|
||||
|
||||
ImGui::EndMenu();
|
||||
}
|
||||
|
||||
if (ImGui::BeginMenu("Developer Tools"))
|
||||
{
|
||||
EnhancementCheckbox("Stats", "gStatsEnabled");
|
||||
EnhancementCheckbox("Console", "gConsoleEnabled");
|
||||
console->opened = CVar_GetS32("gConsoleEnabled", 0);
|
||||
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");
|
||||
ImGui::Separator();
|
||||
EnhancementCheckbox("Stats", "gStatsEnabled");
|
||||
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, type help for some examples");
|
||||
console->opened = CVar_GetS32("gConsoleEnabled", 0);
|
||||
|
||||
ImGui::EndMenu();
|
||||
}
|
||||
|
@ -738,6 +798,7 @@ namespace SohImGui {
|
|||
}
|
||||
ImGui::EndMenu();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
ImGui::EndMenuBar();
|
||||
|
@ -748,7 +809,7 @@ namespace SohImGui {
|
|||
if (CVar_GetS32("gStatsEnabled", 0)) {
|
||||
const float framerate = ImGui::GetIO().Framerate;
|
||||
ImGui::PushStyleColor(ImGuiCol_Border, ImVec4(0, 0, 0, 0));
|
||||
ImGui::Begin("Debug Stats", nullptr, ImGuiWindowFlags_None);
|
||||
ImGui::Begin("Debug Stats", nullptr, ImGuiWindowFlags_NoFocusOnAppearing);
|
||||
|
||||
#ifdef _WIN32
|
||||
ImGui::Text("Platform: Windows");
|
||||
|
@ -800,6 +861,8 @@ namespace SohImGui {
|
|||
pos = ImVec2(size.x / 2 - sw / 2, 0);
|
||||
size = ImVec2(sw, size.y);
|
||||
}
|
||||
|
||||
overlay->Draw();
|
||||
}
|
||||
|
||||
void DrawFramebufferAndGameInput() {
|
||||
|
@ -917,8 +980,7 @@ namespace SohImGui {
|
|||
ImTextureID gfx_d3d11_get_texture_by_id(int id);
|
||||
return gfx_d3d11_get_texture_by_id(id);
|
||||
}
|
||||
#else
|
||||
return reinterpret_cast<ImTextureID>(id);
|
||||
#endif
|
||||
return reinterpret_cast<ImTextureID>(id);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
#pragma once
|
||||
|
||||
#include "GameOverlay.h"
|
||||
#include "Lib/ImGui/imgui.h"
|
||||
#include "SohConsole.h"
|
||||
|
||||
|
@ -58,6 +59,8 @@ namespace SohImGui {
|
|||
} CustomWindow;
|
||||
|
||||
extern Console* console;
|
||||
extern Ship::GameOverlay* overlay;
|
||||
extern bool needs_save;
|
||||
void Init(WindowImpl window_impl);
|
||||
void Update(EventImpl event);
|
||||
|
||||
|
|
|
@ -43,7 +43,7 @@ namespace Ship {
|
|||
if (raw_path == nullptr) return;
|
||||
|
||||
const auto api = BIND_PTR("gfx_api", GfxRenderingAPI*);
|
||||
const auto path = normalize(raw_path) + ".png";
|
||||
const auto path = std::string(raw_path) + ".png";
|
||||
const auto node = BIND_PTR("node", TextureCacheNode**);
|
||||
const auto fmt = BIND_VAR("fmt", uint32_t*);
|
||||
const auto siz = BIND_VAR("siz", uint32_t*);
|
||||
|
|
|
@ -36,15 +36,6 @@ namespace Ship {
|
|||
void Hook_InvalidateTexture(HookEvent event);
|
||||
};
|
||||
|
||||
inline std::string normalize(std::string path) {
|
||||
#ifdef _WIN32
|
||||
std::ranges::replace(path, '/', '\\');
|
||||
#else
|
||||
std::replace(path.begin(), path.end(), '\\', '/');
|
||||
#endif
|
||||
return path;
|
||||
}
|
||||
|
||||
inline void GrayOutTexture(uint8_t* data, int width, int height) {
|
||||
for (int x = 0; x < width * height * 4; x += 4) {
|
||||
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
#include <chrono>
|
||||
#include "SohHooks.h"
|
||||
#include "SohConsole.h"
|
||||
|
||||
#include <iostream>
|
||||
|
||||
extern "C" {
|
||||
|
@ -118,17 +119,16 @@ extern "C" {
|
|||
ModInternal::callBindHook(0);
|
||||
}
|
||||
|
||||
char* ResourceMgr_GetNameByCRC(uint64_t crc, char* alloc) {
|
||||
std::string hashStr = Ship::GlobalCtx2::GetInstance()->GetResourceManager()->HashToString(crc);
|
||||
strcpy(alloc, hashStr.c_str());
|
||||
return (char*)hashStr.c_str();
|
||||
const char* ResourceMgr_GetNameByCRC(uint64_t crc) {
|
||||
const std::string* hashStr = Ship::GlobalCtx2::GetInstance()->GetResourceManager()->HashToString(crc);
|
||||
return hashStr != nullptr ? hashStr->c_str() : nullptr;
|
||||
}
|
||||
|
||||
Vtx* ResourceMgr_LoadVtxByCRC(uint64_t crc) {
|
||||
std::string hashStr = Ship::GlobalCtx2::GetInstance()->GetResourceManager()->HashToString(crc);
|
||||
const std::string* hashStr = Ship::GlobalCtx2::GetInstance()->GetResourceManager()->HashToString(crc);
|
||||
|
||||
if (hashStr != "") {
|
||||
auto res = std::static_pointer_cast<Ship::Array>(Ship::GlobalCtx2::GetInstance()->GetResourceManager()->LoadResource(hashStr));
|
||||
if (hashStr != nullptr) {
|
||||
auto res = std::static_pointer_cast<Ship::Array>(Ship::GlobalCtx2::GetInstance()->GetResourceManager()->LoadResource(hashStr->c_str()));
|
||||
|
||||
//if (res != nullptr)
|
||||
return (Vtx*)res->vertices.data();
|
||||
|
@ -141,10 +141,10 @@ extern "C" {
|
|||
}
|
||||
|
||||
int32_t* ResourceMgr_LoadMtxByCRC(uint64_t crc) {
|
||||
std::string hashStr = Ship::GlobalCtx2::GetInstance()->GetResourceManager()->HashToString(crc);
|
||||
const std::string* hashStr = Ship::GlobalCtx2::GetInstance()->GetResourceManager()->HashToString(crc);
|
||||
|
||||
if (hashStr != "") {
|
||||
auto res = std::static_pointer_cast<Ship::Matrix>(Ship::GlobalCtx2::GetInstance()->GetResourceManager()->LoadResource(hashStr));
|
||||
if (hashStr != nullptr) {
|
||||
auto res = std::static_pointer_cast<Ship::Matrix>(Ship::GlobalCtx2::GetInstance()->GetResourceManager()->LoadResource(hashStr->c_str()));
|
||||
return (int32_t*)res->mtx.data();
|
||||
} else {
|
||||
return nullptr;
|
||||
|
@ -152,10 +152,10 @@ extern "C" {
|
|||
}
|
||||
|
||||
Gfx* ResourceMgr_LoadGfxByCRC(uint64_t crc) {
|
||||
std::string hashStr = Ship::GlobalCtx2::GetInstance()->GetResourceManager()->HashToString(crc);
|
||||
const std::string* hashStr = Ship::GlobalCtx2::GetInstance()->GetResourceManager()->HashToString(crc);
|
||||
|
||||
if (hashStr != "") {
|
||||
auto res = std::static_pointer_cast<Ship::DisplayList>(Ship::GlobalCtx2::GetInstance()->GetResourceManager()->LoadResource(hashStr));
|
||||
if (hashStr != nullptr) {
|
||||
auto res = std::static_pointer_cast<Ship::DisplayList>(Ship::GlobalCtx2::GetInstance()->GetResourceManager()->LoadResource(hashStr->c_str()));
|
||||
return (Gfx*)&res->instructions[0];
|
||||
} else {
|
||||
return nullptr;
|
||||
|
@ -163,14 +163,14 @@ extern "C" {
|
|||
}
|
||||
|
||||
char* ResourceMgr_LoadTexByCRC(uint64_t crc) {
|
||||
const std::string hashStr = Ship::GlobalCtx2::GetInstance()->GetResourceManager()->HashToString(crc);
|
||||
const std::string* hashStr = Ship::GlobalCtx2::GetInstance()->GetResourceManager()->HashToString(crc);
|
||||
|
||||
if (!hashStr.empty()) {
|
||||
const auto res = static_cast<Ship::Texture*>(Ship::GlobalCtx2::GetInstance()->GetResourceManager()->LoadResource(hashStr).get());
|
||||
if (hashStr != nullptr) {
|
||||
const auto res = static_cast<Ship::Texture*>(Ship::GlobalCtx2::GetInstance()->GetResourceManager()->LoadResource(hashStr->c_str()).get());
|
||||
|
||||
ModInternal::bindHook(LOAD_TEXTURE);
|
||||
ModInternal::initBindHook(2,
|
||||
HookParameter({.name = "path", .parameter = (void*)hashStr.c_str() }),
|
||||
HookParameter({.name = "path", .parameter = (void*)hashStr->c_str() }),
|
||||
HookParameter({.name = "texture", .parameter = static_cast<void*>(&res->imageData) })
|
||||
);
|
||||
ModInternal::callBindHook(0);
|
||||
|
@ -183,11 +183,11 @@ extern "C" {
|
|||
|
||||
void ResourceMgr_RegisterResourcePatch(uint64_t hash, uint32_t instrIndex, uintptr_t origData)
|
||||
{
|
||||
std::string hashStr = Ship::GlobalCtx2::GetInstance()->GetResourceManager()->HashToString(hash);
|
||||
const std::string* hashStr = Ship::GlobalCtx2::GetInstance()->GetResourceManager()->HashToString(hash);
|
||||
|
||||
if (hashStr != "")
|
||||
if (hashStr != nullptr)
|
||||
{
|
||||
auto res = (Ship::Texture*)Ship::GlobalCtx2::GetInstance()->GetResourceManager()->LoadResource(hashStr).get();
|
||||
auto res = (Ship::Texture*)Ship::GlobalCtx2::GetInstance()->GetResourceManager()->LoadResource(hashStr->c_str()).get();
|
||||
|
||||
Ship::Patch patch;
|
||||
patch.crc = hash;
|
||||
|
@ -281,8 +281,12 @@ namespace Ship {
|
|||
gfx_start_frame();
|
||||
}
|
||||
|
||||
void Window::RunCommands(Gfx* Commands) {
|
||||
gfx_run(Commands);
|
||||
void Window::RunCommands(Gfx* Commands, const std::vector<std::unordered_map<Mtx*, MtxF>>& mtx_replacements) {
|
||||
for (const auto& m : mtx_replacements) {
|
||||
gfx_run(Commands, m);
|
||||
gfx_end_frame();
|
||||
}
|
||||
gfx_run(Commands, {});
|
||||
gfx_end_frame();
|
||||
}
|
||||
|
||||
|
@ -328,6 +332,8 @@ namespace Ship {
|
|||
GlobalCtx2::GetInstance()->GetWindow()->ToggleFullscreen();
|
||||
}
|
||||
|
||||
|
||||
|
||||
// OTRTODO: Rig with Kirito's console?
|
||||
//if (dwScancode == Ship::stoi(Conf["KEYBOARD SHORTCUTS"]["KEY_CONSOLE"])) {
|
||||
// ToggleConsole();
|
||||
|
|
|
@ -19,7 +19,7 @@ namespace Ship {
|
|||
void MainLoop(void (*MainFunction)(void));
|
||||
void Init();
|
||||
void StartFrame();
|
||||
void RunCommands(Gfx* Commands);
|
||||
void RunCommands(Gfx* Commands, const std::vector<std::unordered_map<Mtx*, MtxF>>& mtx_replacements);
|
||||
void SetFrameDivisor(int divisor);
|
||||
void GetPixelDepthPrepare(float x, float y);
|
||||
uint16_t GetPixelDepth(float x, float y);
|
||||
|
|
|
@ -256,6 +256,7 @@
|
|||
<ClCompile Include="Blob.cpp" />
|
||||
<ClCompile Include="Cvar.cpp" />
|
||||
<ClCompile Include="Environment.cpp" />
|
||||
<ClCompile Include="GameOverlay.cpp" />
|
||||
<ClCompile Include="GameSettings.cpp" />
|
||||
<ClCompile Include="Lib\ImGui\backends\imgui_impl_dx11.cpp" />
|
||||
<ClCompile Include="Lib\ImGui\backends\imgui_impl_win32.cpp" />
|
||||
|
@ -343,6 +344,7 @@
|
|||
<ClInclude Include="Blob.h" />
|
||||
<ClInclude Include="Cvar.h" />
|
||||
<ClInclude Include="Environment.h" />
|
||||
<ClInclude Include="GameOverlay.h" />
|
||||
<ClInclude Include="GameSettings.h" />
|
||||
<ClInclude Include="GameVersions.h" />
|
||||
<ClInclude Include="Lib\ImGui\backends\imgui_impl_dx11.h" />
|
||||
|
|
|
@ -88,6 +88,9 @@
|
|||
<Filter Include="Source Files\Logging">
|
||||
<UniqueIdentifier>{bd6557f1-9480-413b-b0cd-843f8efc1939}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Source Files\CustomImpl\Overlay">
|
||||
<UniqueIdentifier>{3285ab8a-06d8-4dac-9af9-efb2a9723ab1}</UniqueIdentifier>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="Factories\MaterialFactory.cpp">
|
||||
|
@ -339,6 +342,9 @@
|
|||
<ClCompile Include="GameSettings.cpp">
|
||||
<Filter>Source Files\CustomImpl</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="GameOverlay.cpp">
|
||||
<Filter>Source Files\CustomImpl\Overlay</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="Lib\tinyxml2\tinyxml2.h">
|
||||
|
@ -629,5 +635,8 @@
|
|||
<ClInclude Include="GameVersions.h">
|
||||
<Filter>Source Files\Resources</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="GameOverlay.h">
|
||||
<Filter>Source Files\CustomImpl\Overlay</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
</Project>
|
|
@ -1,72 +1,72 @@
|
|||
<Root>
|
||||
<File Name="map_48x85_static" Segment="12">
|
||||
<Texture Name="gDekuTreePauseScreenMapFloor3LeftTex" OutName="deku_tree_pause_screen_map_floor_3_left" Format="ci4" Width="48" Height="85"/>
|
||||
<Texture Name="gDekuTreePauseScreenMapFloor3RightTex" OutName="deku_tree_pause_screen_map_floor_3_right" Format="ci4" Width="48" Height="85"/>
|
||||
<Texture Name="gDekuTreePauseScreenMapFloor2LeftTex" OutName="deku_tree_pause_screen_map_floor_2_left" Format="ci4" Width="48" Height="85"/>
|
||||
<Texture Name="gDekuTreePauseScreenMapFloor2RightTex" OutName="deku_tree_pause_screen_map_floor_2_right" Format="ci4" Width="48" Height="85"/>
|
||||
<Texture Name="gDekuTreePauseScreenMapFloor1LeftTex" OutName="deku_tree_pause_screen_map_floor_1_left" Format="ci4" Width="48" Height="85"/>
|
||||
<Texture Name="gDekuTreePauseScreenMapFloor1RightTex" OutName="deku_tree_pause_screen_map_floor_1_right" Format="ci4" Width="48" Height="85"/>
|
||||
<Texture Name="gDekuTreePauseScreenMapBasement1LeftTex" OutName="deku_tree_pause_screen_map_basement_1_left" Format="ci4" Width="48" Height="85"/>
|
||||
<Texture Name="gDekuTreePauseScreenMapBasement1RightTex" OutName="deku_tree_pause_screen_map_basement_1_right" Format="ci4" Width="48" Height="85"/>
|
||||
<Texture Name="gDekuTreePauseScreenMapBasement2LeftTex" OutName="deku_tree_pause_screen_map_basement_2_left" Format="ci4" Width="48" Height="85"/>
|
||||
<Texture Name="gDekuTreePauseScreenMapBasement2RightTex" OutName="deku_tree_pause_screen_map_basement_2_right" Format="ci4" Width="48" Height="85"/>
|
||||
<Texture Name="gDodongosCavernPauseScreenMapFloor2LeftTex" OutName="dodongos_cavern_pause_screen_map_floor_2_left" Format="ci4" Width="48" Height="85"/>
|
||||
<Texture Name="gDodongosCavernPauseScreenMapFloor2RightTex" OutName="dodongos_cavern_pause_screen_map_floor_2_right" Format="ci4" Width="48" Height="85"/>
|
||||
<Texture Name="gDodongosCavernPauseScreenMapFloor1LeftTex" OutName="dodongos_cavern_pause_screen_map_floor_1_left" Format="ci4" Width="48" Height="85"/>
|
||||
<Texture Name="gDodongosCavernPauseScreenMapFloor1RightTex" OutName="dodongos_cavern_pause_screen_map_floor_1_right" Format="ci4" Width="48" Height="85"/>
|
||||
<Texture Name="gJabuPauseScreenMapFloor1LeftTex" OutName="jabu_pause_screen_map_floor_1_left" Format="ci4" Width="48" Height="85"/>
|
||||
<Texture Name="gJabuPauseScreenMapFloor1RightTex" OutName="jabu_pause_screen_map_floor_1_right" Format="ci4" Width="48" Height="85"/>
|
||||
<Texture Name="gJabuPauseScreenMapBasement1LeftTex" OutName="jabu_pause_screen_map_basement_1_left" Format="ci4" Width="48" Height="85"/>
|
||||
<Texture Name="gJabuPauseScreenMapBasement1RightTex" OutName="jabu_pause_screen_map_basement_1_right" Format="ci4" Width="48" Height="85"/>
|
||||
<Texture Name="gForestTemplePauseScreenMapFloor2LeftTex" OutName="forest_temple_pause_screen_map_floor_2_left" Format="ci4" Width="48" Height="85"/>
|
||||
<Texture Name="gForestTemplePauseScreenMapFloor2RightTex" OutName="forest_temple_pause_screen_map_floor_2_right" Format="ci4" Width="48" Height="85"/>
|
||||
<Texture Name="gForestTemplePauseScreenMapFloor1LeftTex" OutName="forest_temple_pause_screen_map_floor_1_left" Format="ci4" Width="48" Height="85"/>
|
||||
<Texture Name="gForestTemplePauseScreenMapFloor1RightTex" OutName="forest_temple_pause_screen_map_floor_1_right" Format="ci4" Width="48" Height="85"/>
|
||||
<Texture Name="gForestTemplePauseScreenMapBasement1LeftTex" OutName="forest_temple_pause_screen_map_basement_1_left" Format="ci4" Width="48" Height="85"/>
|
||||
<Texture Name="gForestTemplePauseScreenMapBasement1RightTex" OutName="forest_temple_pause_screen_map_basement_1_right" Format="ci4" Width="48" Height="85"/>
|
||||
<Texture Name="gForestTemplePauseScreenMapBasement2LeftTex" OutName="forest_temple_pause_screen_map_basement_2_left" Format="ci4" Width="48" Height="85"/>
|
||||
<Texture Name="gForestTemplePauseScreenMapBasement2RightTex" OutName="forest_temple_pause_screen_map_basement_2_right" Format="ci4" Width="48" Height="85"/>
|
||||
<Texture Name="gFireTemplePauseScreenMapFloor5LeftTex" OutName="fire_temple_pause_screen_map_floor_5_left" Format="ci4" Width="48" Height="85"/>
|
||||
<Texture Name="gFireTemplePauseScreenMapFloor5RightTex" OutName="fire_temple_pause_screen_map_floor_5_right" Format="ci4" Width="48" Height="85"/>
|
||||
<Texture Name="gFireTemplePauseScreenMapFloor4LeftTex" OutName="fire_temple_pause_screen_map_floor_4_left" Format="ci4" Width="48" Height="85"/>
|
||||
<Texture Name="gFireTemplePauseScreenMapFloor4RightTex" OutName="fire_temple_pause_screen_map_floor_4_right" Format="ci4" Width="48" Height="85"/>
|
||||
<Texture Name="gFireTemplePauseScreenMapFloor3LeftTex" OutName="fire_temple_pause_screen_map_floor_3_left" Format="ci4" Width="48" Height="85"/>
|
||||
<Texture Name="gFireTemplePauseScreenMapFloor3RightTex" OutName="fire_temple_pause_screen_map_floor_3_right" Format="ci4" Width="48" Height="85"/>
|
||||
<Texture Name="gFireTemplePauseScreenMapFloor2LeftTex" OutName="fire_temple_pause_screen_map_floor_2_left" Format="ci4" Width="48" Height="85"/>
|
||||
<Texture Name="gFireTemplePauseScreenMapFloor2RightTex" OutName="fire_temple_pause_screen_map_floor_2_right" Format="ci4" Width="48" Height="85"/>
|
||||
<Texture Name="gFireTemplePauseScreenMapFloor1LeftTex" OutName="fire_temple_pause_screen_map_floor_1_left" Format="ci4" Width="48" Height="85"/>
|
||||
<Texture Name="gFireTemplePauseScreenMapFloor1RightTex" OutName="fire_temple_pause_screen_map_floor_1_right" Format="ci4" Width="48" Height="85"/>
|
||||
<Texture Name="gWaterTemplePauseScreenMapFloor3LeftTex" OutName="water_temple_pause_screen_map_floor_3_left" Format="ci4" Width="48" Height="85"/>
|
||||
<Texture Name="gWaterTemplePauseScreenMapFloor3RightTex" OutName="water_temple_pause_screen_map_floor_3_right" Format="ci4" Width="48" Height="85"/>
|
||||
<Texture Name="gWaterTemplePauseScreenMapFloor2LeftTex" OutName="water_temple_pause_screen_map_floor_2_left" Format="ci4" Width="48" Height="85"/>
|
||||
<Texture Name="gWaterTemplePauseScreenMapFloor2RightTex" OutName="water_temple_pause_screen_map_floor_2_right" Format="ci4" Width="48" Height="85"/>
|
||||
<Texture Name="gWaterTemplePauseScreenMapFloor1LeftTex" OutName="water_temple_pause_screen_map_floor_1_left" Format="ci4" Width="48" Height="85"/>
|
||||
<Texture Name="gWaterTemplePauseScreenMapFloor1RightTex" OutName="water_temple_pause_screen_map_floor_1_right" Format="ci4" Width="48" Height="85"/>
|
||||
<Texture Name="gWaterTemplePauseScreenMapBasement1LeftTex" OutName="water_temple_pause_screen_map_basement_1_left" Format="ci4" Width="48" Height="85"/>
|
||||
<Texture Name="gWaterTemplePauseScreenMapBasement1RightTex" OutName="water_temple_pause_screen_map_basement_1_right" Format="ci4" Width="48" Height="85"/>
|
||||
<Texture Name="gSpiritTemplePauseScreenMapFloor4LeftTex" OutName="spirit_temple_pause_screen_map_floor_4_left" Format="ci4" Width="48" Height="85"/>
|
||||
<Texture Name="gSpiritTemplePauseScreenMapFloor4RightTex" OutName="spirit_temple_pause_screen_map_floor_4_right" Format="ci4" Width="48" Height="85"/>
|
||||
<Texture Name="gSpiritTemplePauseScreenMapFloor3LeftTex" OutName="spirit_temple_pause_screen_map_floor_3_left" Format="ci4" Width="48" Height="85"/>
|
||||
<Texture Name="gSpiritTemplePauseScreenMapFloor3RightTex" OutName="spirit_temple_pause_screen_map_floor_3_right" Format="ci4" Width="48" Height="85"/>
|
||||
<Texture Name="gSpiritTemplePauseScreenMapFloor2LeftTex" OutName="spirit_temple_pause_screen_map_floor_2_left" Format="ci4" Width="48" Height="85"/>
|
||||
<Texture Name="gSpiritTemplePauseScreenMapFloor2RightTex" OutName="spirit_temple_pause_screen_map_floor_2_right" Format="ci4" Width="48" Height="85"/>
|
||||
<Texture Name="gSpiritTemplePauseScreenMapFloor1LeftTex" OutName="spirit_temple_pause_screen_map_floor_1_left" Format="ci4" Width="48" Height="85"/>
|
||||
<Texture Name="gSpiritTemplePauseScreenMapFloor1RightTex" OutName="spirit_temple_pause_screen_map_floor_1_right" Format="ci4" Width="48" Height="85"/>
|
||||
<Texture Name="gShadowTemplePauseScreenMapBasement1LeftTex" OutName="shadow_temple_pause_screen_map_basement_1_left" Format="ci4" Width="48" Height="85"/>
|
||||
<Texture Name="gShadowTemplePauseScreenMapBasement1RightTex" OutName="shadow_temple_pause_screen_map_basement_1_right" Format="ci4" Width="48" Height="85"/>
|
||||
<Texture Name="gShadowTemplePauseScreenMapBasement2LeftTex" OutName="shadow_temple_pause_screen_map_basement_2_left" Format="ci4" Width="48" Height="85"/>
|
||||
<Texture Name="gShadowTemplePauseScreenMapBasement2RightTex" OutName="shadow_temple_pause_screen_map_basement_2_right" Format="ci4" Width="48" Height="85"/>
|
||||
<Texture Name="gShadowTemplePauseScreenMapBasement3LeftTex" OutName="shadow_temple_pause_screen_map_basement_3_left" Format="ci4" Width="48" Height="85"/>
|
||||
<Texture Name="gShadowTemplePauseScreenMapBasement3RightTex" OutName="shadow_temple_pause_screen_map_basement_3_right" Format="ci4" Width="48" Height="85"/>
|
||||
<Texture Name="gShadowTemplePauseScreenMapBasement4LeftTex" OutName="shadow_temple_pause_screen_map_basement_4_left" Format="ci4" Width="48" Height="85"/>
|
||||
<Texture Name="gShadowTemplePauseScreenMapBasement4RightTex" OutName="shadow_temple_pause_screen_map_basement_4_right" Format="ci4" Width="48" Height="85"/>
|
||||
<Texture Name="gBottomOfTheWellPauseScreenMapBasement1LeftTex" OutName="bottom_of_the_well_pause_screen_map_basement_1_left" Format="ci4" Width="48" Height="85"/>
|
||||
<Texture Name="gBottomOfTheWellPauseScreenMapBasement1RightTex" OutName="bottom_of_the_well_pause_screen_map_basement_1_right" Format="ci4" Width="48" Height="85"/>
|
||||
<Texture Name="gBottomOfTheWellPauseScreenMapBasement2LeftTex" OutName="bottom_of_the_well_pause_screen_map_basement_2_left" Format="ci4" Width="48" Height="85"/>
|
||||
<Texture Name="gBottomOfTheWellPauseScreenMapBasement2RightTex" OutName="bottom_of_the_well_pause_screen_map_basement_2_right" Format="ci4" Width="48" Height="85"/>
|
||||
<Texture Name="gBottomOfTheWellPauseScreenMapBasement3LeftTex" OutName="bottom_of_the_well_pause_screen_map_basement_3_left" Format="ci4" Width="48" Height="85"/>
|
||||
<Texture Name="gBottomOfTheWellPauseScreenMapBasement3RightTex" OutName="bottom_of_the_well_pause_screen_map_basement_3_right" Format="ci4" Width="48" Height="85"/>
|
||||
<Texture Name="gIceCavernPauseScreenMapFloor1LeftTex" OutName="ice_cavern_pause_screen_map_floor_1_left" Format="ci4" Width="48" Height="85"/>
|
||||
<Texture Name="gIceCavernPauseScreenMapFloor1RightTex" OutName="ice_cavern_pause_screen_map_floor_1_right" Format="ci4" Width="48" Height="85"/>
|
||||
<Texture Name="gDekuTreePauseScreenMapFloor3LeftTex" OutName="deku_tree_pause_screen_map_floor_3_left" Format="ci4" Width="48" Height="85" Offset="0x0"/>
|
||||
<Texture Name="gDekuTreePauseScreenMapFloor3RightTex" OutName="deku_tree_pause_screen_map_floor_3_right" Format="ci4" Width="48" Height="85" Offset="0x07F8"/>
|
||||
<Texture Name="gDekuTreePauseScreenMapFloor2LeftTex" OutName="deku_tree_pause_screen_map_floor_2_left" Format="ci4" Width="48" Height="85" Offset="0x0FF0"/>
|
||||
<Texture Name="gDekuTreePauseScreenMapFloor2RightTex" OutName="deku_tree_pause_screen_map_floor_2_right" Format="ci4" Width="48" Height="85" Offset="0x17E8"/>
|
||||
<Texture Name="gDekuTreePauseScreenMapFloor1LeftTex" OutName="deku_tree_pause_screen_map_floor_1_left" Format="ci4" Width="48" Height="85" Offset="0x1FE0"/>
|
||||
<Texture Name="gDekuTreePauseScreenMapFloor1RightTex" OutName="deku_tree_pause_screen_map_floor_1_right" Format="ci4" Width="48" Height="85" Offset="0x27D8"/>
|
||||
<Texture Name="gDekuTreePauseScreenMapBasement1LeftTex" OutName="deku_tree_pause_screen_map_basement_1_left" Format="ci4" Width="48" Height="85" Offset="0x2FD0"/>
|
||||
<Texture Name="gDekuTreePauseScreenMapBasement1RightTex" OutName="deku_tree_pause_screen_map_basement_1_right" Format="ci4" Width="48" Height="85" Offset="0x37C8"/>
|
||||
<Texture Name="gDekuTreePauseScreenMapBasement2LeftTex" OutName="deku_tree_pause_screen_map_basement_2_left" Format="ci4" Width="48" Height="85" Offset="0x3FC0"/>
|
||||
<Texture Name="gDekuTreePauseScreenMapBasement2RightTex" OutName="deku_tree_pause_screen_map_basement_2_right" Format="ci4" Width="48" Height="85" Offset="0x47B8"/>
|
||||
<Texture Name="gDodongosCavernPauseScreenMapFloor2LeftTex" OutName="dodongos_cavern_pause_screen_map_floor_2_left" Format="ci4" Width="48" Height="85" Offset="0x4FB0"/>
|
||||
<Texture Name="gDodongosCavernPauseScreenMapFloor2RightTex" OutName="dodongos_cavern_pause_screen_map_floor_2_right" Format="ci4" Width="48" Height="85" Offset="0x57A8"/>
|
||||
<Texture Name="gDodongosCavernPauseScreenMapFloor1LeftTex" OutName="dodongos_cavern_pause_screen_map_floor_1_left" Format="ci4" Width="48" Height="85" Offset="0x5FA0"/>
|
||||
<Texture Name="gDodongosCavernPauseScreenMapFloor1RightTex" OutName="dodongos_cavern_pause_screen_map_floor_1_right" Format="ci4" Width="48" Height="85" Offset="0x6798"/>
|
||||
<Texture Name="gJabuPauseScreenMapFloor1LeftTex" OutName="jabu_pause_screen_map_floor_1_left" Format="ci4" Width="48" Height="85" Offset="0x6F90"/>
|
||||
<Texture Name="gJabuPauseScreenMapFloor1RightTex" OutName="jabu_pause_screen_map_floor_1_right" Format="ci4" Width="48" Height="85" Offset="0x7788"/>
|
||||
<Texture Name="gJabuPauseScreenMapBasement1LeftTex" OutName="jabu_pause_screen_map_basement_1_left" Format="ci4" Width="48" Height="85" Offset="0x7F80"/>
|
||||
<Texture Name="gJabuPauseScreenMapBasement1RightTex" OutName="jabu_pause_screen_map_basement_1_right" Format="ci4" Width="48" Height="85" Offset="0x8778"/>
|
||||
<Texture Name="gForestTemplePauseScreenMapFloor2LeftTex" OutName="forest_temple_pause_screen_map_floor_2_left" Format="ci4" Width="48" Height="85" Offset="0x8F70"/>
|
||||
<Texture Name="gForestTemplePauseScreenMapFloor2RightTex" OutName="forest_temple_pause_screen_map_floor_2_right" Format="ci4" Width="48" Height="85" Offset="0x9768"/>
|
||||
<Texture Name="gForestTemplePauseScreenMapFloor1LeftTex" OutName="forest_temple_pause_screen_map_floor_1_left" Format="ci4" Width="48" Height="85" Offset="0x9F60"/>
|
||||
<Texture Name="gForestTemplePauseScreenMapFloor1RightTex" OutName="forest_temple_pause_screen_map_floor_1_right" Format="ci4" Width="48" Height="85" Offset="0xA758"/>
|
||||
<Texture Name="gForestTemplePauseScreenMapBasement1LeftTex" OutName="forest_temple_pause_screen_map_basement_1_left" Format="ci4" Width="48" Height="85" Offset="0xAF50"/>
|
||||
<Texture Name="gForestTemplePauseScreenMapBasement1RightTex" OutName="forest_temple_pause_screen_map_basement_1_right" Format="ci4" Width="48" Height="85" Offset="0xB748"/>
|
||||
<Texture Name="gForestTemplePauseScreenMapBasement2LeftTex" OutName="forest_temple_pause_screen_map_basement_2_left" Format="ci4" Width="48" Height="85" Offset="0xBF40"/>
|
||||
<Texture Name="gForestTemplePauseScreenMapBasement2RightTex" OutName="forest_temple_pause_screen_map_basement_2_right" Format="ci4" Width="48" Height="85" Offset="0xC738"/>
|
||||
<Texture Name="gFireTemplePauseScreenMapFloor5LeftTex" OutName="fire_temple_pause_screen_map_floor_5_left" Format="ci4" Width="48" Height="85" Offset="0xCF30"/>
|
||||
<Texture Name="gFireTemplePauseScreenMapFloor5RightTex" OutName="fire_temple_pause_screen_map_floor_5_right" Format="ci4" Width="48" Height="85" Offset="0xD728"/>
|
||||
<Texture Name="gFireTemplePauseScreenMapFloor4LeftTex" OutName="fire_temple_pause_screen_map_floor_4_left" Format="ci4" Width="48" Height="85" Offset="0xDF20"/>
|
||||
<Texture Name="gFireTemplePauseScreenMapFloor4RightTex" OutName="fire_temple_pause_screen_map_floor_4_right" Format="ci4" Width="48" Height="85" Offset="0xE718"/>
|
||||
<Texture Name="gFireTemplePauseScreenMapFloor3LeftTex" OutName="fire_temple_pause_screen_map_floor_3_left" Format="ci4" Width="48" Height="85" Offset="0xEF10"/>
|
||||
<Texture Name="gFireTemplePauseScreenMapFloor3RightTex" OutName="fire_temple_pause_screen_map_floor_3_right" Format="ci4" Width="48" Height="85" Offset="0xF708"/>
|
||||
<Texture Name="gFireTemplePauseScreenMapFloor2LeftTex" OutName="fire_temple_pause_screen_map_floor_2_left" Format="ci4" Width="48" Height="85" Offset="0xFF00"/>
|
||||
<Texture Name="gFireTemplePauseScreenMapFloor2RightTex" OutName="fire_temple_pause_screen_map_floor_2_right" Format="ci4" Width="48" Height="85" Offset="0x106F8"/>
|
||||
<Texture Name="gFireTemplePauseScreenMapFloor1LeftTex" OutName="fire_temple_pause_screen_map_floor_1_left" Format="ci4" Width="48" Height="85" Offset="0x10EF0"/>
|
||||
<Texture Name="gFireTemplePauseScreenMapFloor1RightTex" OutName="fire_temple_pause_screen_map_floor_1_right" Format="ci4" Width="48" Height="85" Offset="0x116E8"/>
|
||||
<Texture Name="gWaterTemplePauseScreenMapFloor3LeftTex" OutName="water_temple_pause_screen_map_floor_3_left" Format="ci4" Width="48" Height="85" Offset="0x11EE0"/>
|
||||
<Texture Name="gWaterTemplePauseScreenMapFloor3RightTex" OutName="water_temple_pause_screen_map_floor_3_right" Format="ci4" Width="48" Height="85" Offset="0x126D8"/>
|
||||
<Texture Name="gWaterTemplePauseScreenMapFloor2LeftTex" OutName="water_temple_pause_screen_map_floor_2_left" Format="ci4" Width="48" Height="85" Offset="0x12ED0"/>
|
||||
<Texture Name="gWaterTemplePauseScreenMapFloor2RightTex" OutName="water_temple_pause_screen_map_floor_2_right" Format="ci4" Width="48" Height="85" Offset="0x136C8"/>
|
||||
<Texture Name="gWaterTemplePauseScreenMapFloor1LeftTex" OutName="water_temple_pause_screen_map_floor_1_left" Format="ci4" Width="48" Height="85" Offset="0x13EC0"/>
|
||||
<Texture Name="gWaterTemplePauseScreenMapFloor1RightTex" OutName="water_temple_pause_screen_map_floor_1_right" Format="ci4" Width="48" Height="85" Offset="0x146B8"/>
|
||||
<Texture Name="gWaterTemplePauseScreenMapBasement1LeftTex" OutName="water_temple_pause_screen_map_basement_1_left" Format="ci4" Width="48" Height="85" Offset="0x14EB0"/>
|
||||
<Texture Name="gWaterTemplePauseScreenMapBasement1RightTex" OutName="water_temple_pause_screen_map_basement_1_right" Format="ci4" Width="48" Height="85" Offset="0x156A8"/>
|
||||
<Texture Name="gSpiritTemplePauseScreenMapFloor4LeftTex" OutName="spirit_temple_pause_screen_map_floor_4_left" Format="ci4" Width="48" Height="85" Offset="0x15EA0"/>
|
||||
<Texture Name="gSpiritTemplePauseScreenMapFloor4RightTex" OutName="spirit_temple_pause_screen_map_floor_4_right" Format="ci4" Width="48" Height="85" Offset="0x16698"/>
|
||||
<Texture Name="gSpiritTemplePauseScreenMapFloor3LeftTex" OutName="spirit_temple_pause_screen_map_floor_3_left" Format="ci4" Width="48" Height="85" Offset="0x16E90"/>
|
||||
<Texture Name="gSpiritTemplePauseScreenMapFloor3RightTex" OutName="spirit_temple_pause_screen_map_floor_3_right" Format="ci4" Width="48" Height="85" Offset="0x17688"/>
|
||||
<Texture Name="gSpiritTemplePauseScreenMapFloor2LeftTex" OutName="spirit_temple_pause_screen_map_floor_2_left" Format="ci4" Width="48" Height="85" Offset="0x17E80"/>
|
||||
<Texture Name="gSpiritTemplePauseScreenMapFloor2RightTex" OutName="spirit_temple_pause_screen_map_floor_2_right" Format="ci4" Width="48" Height="85" Offset="0x18678"/>
|
||||
<Texture Name="gSpiritTemplePauseScreenMapFloor1LeftTex" OutName="spirit_temple_pause_screen_map_floor_1_left" Format="ci4" Width="48" Height="85" Offset="0x18E70"/>
|
||||
<Texture Name="gSpiritTemplePauseScreenMapFloor1RightTex" OutName="spirit_temple_pause_screen_map_floor_1_right" Format="ci4" Width="48" Height="85" Offset="0x19668"/>
|
||||
<Texture Name="gShadowTemplePauseScreenMapBasement1LeftTex" OutName="shadow_temple_pause_screen_map_basement_1_left" Format="ci4" Width="48" Height="85" Offset="0x19E60"/>
|
||||
<Texture Name="gShadowTemplePauseScreenMapBasement1RightTex" OutName="shadow_temple_pause_screen_map_basement_1_right" Format="ci4" Width="48" Height="85" Offset="0x1A658"/>
|
||||
<Texture Name="gShadowTemplePauseScreenMapBasement2LeftTex" OutName="shadow_temple_pause_screen_map_basement_2_left" Format="ci4" Width="48" Height="85" Offset="0x1AE50"/>
|
||||
<Texture Name="gShadowTemplePauseScreenMapBasement2RightTex" OutName="shadow_temple_pause_screen_map_basement_2_right" Format="ci4" Width="48" Height="85" Offset="0x1B648"/>
|
||||
<Texture Name="gShadowTemplePauseScreenMapBasement3LeftTex" OutName="shadow_temple_pause_screen_map_basement_3_left" Format="ci4" Width="48" Height="85" Offset="0x1BE40"/>
|
||||
<Texture Name="gShadowTemplePauseScreenMapBasement3RightTex" OutName="shadow_temple_pause_screen_map_basement_3_right" Format="ci4" Width="48" Height="85" Offset="0x1C638"/>
|
||||
<Texture Name="gShadowTemplePauseScreenMapBasement4LeftTex" OutName="shadow_temple_pause_screen_map_basement_4_left" Format="ci4" Width="48" Height="85" Offset="0x1CE30"/>
|
||||
<Texture Name="gShadowTemplePauseScreenMapBasement4RightTex" OutName="shadow_temple_pause_screen_map_basement_4_right" Format="ci4" Width="48" Height="85" Offset="0x1D628"/>
|
||||
<Texture Name="gBottomOfTheWellPauseScreenMapBasement1LeftTex" OutName="bottom_of_the_well_pause_screen_map_basement_1_left" Format="ci4" Width="48" Height="85" Offset="0x1DE20"/>
|
||||
<Texture Name="gBottomOfTheWellPauseScreenMapBasement1RightTex" OutName="bottom_of_the_well_pause_screen_map_basement_1_right" Format="ci4" Width="48" Height="85" Offset="0x1E618"/>
|
||||
<Texture Name="gBottomOfTheWellPauseScreenMapBasement2LeftTex" OutName="bottom_of_the_well_pause_screen_map_basement_2_left" Format="ci4" Width="48" Height="85" Offset="0x1EE10"/>
|
||||
<Texture Name="gBottomOfTheWellPauseScreenMapBasement2RightTex" OutName="bottom_of_the_well_pause_screen_map_basement_2_right" Format="ci4" Width="48" Height="85" Offset="0x1F608"/>
|
||||
<Texture Name="gBottomOfTheWellPauseScreenMapBasement3LeftTex" OutName="bottom_of_the_well_pause_screen_map_basement_3_left" Format="ci4" Width="48" Height="85" Offset="0x1FE00"/>
|
||||
<Texture Name="gBottomOfTheWellPauseScreenMapBasement3RightTex" OutName="bottom_of_the_well_pause_screen_map_basement_3_right" Format="ci4" Width="48" Height="85" Offset="0x205F8"/>
|
||||
<Texture Name="gIceCavernPauseScreenMapFloor1LeftTex" OutName="ice_cavern_pause_screen_map_floor_1_left" Format="ci4" Width="48" Height="85" Offset="0x20DF0"/>
|
||||
<Texture Name="gIceCavernPauseScreenMapFloor1RightTex" OutName="ice_cavern_pause_screen_map_floor_1_right" Format="ci4" Width="48" Height="85" Offset="0x215E8"/>
|
||||
</File>
|
||||
</Root>
|
||||
|
|
|
@ -1,72 +1,72 @@
|
|||
<Root>
|
||||
<File Name="map_48x85_static" Segment="12">
|
||||
<Texture Name="gDekuTreePauseScreenMapFloor3LeftTex" OutName="deku_tree_pause_screen_map_floor_3_left" Format="ci4" Width="48" Height="85"/>
|
||||
<Texture Name="gDekuTreePauseScreenMapFloor3RightTex" OutName="deku_tree_pause_screen_map_floor_3_right" Format="ci4" Width="48" Height="85"/>
|
||||
<Texture Name="gDekuTreePauseScreenMapFloor2LeftTex" OutName="deku_tree_pause_screen_map_floor_2_left" Format="ci4" Width="48" Height="85"/>
|
||||
<Texture Name="gDekuTreePauseScreenMapFloor2RightTex" OutName="deku_tree_pause_screen_map_floor_2_right" Format="ci4" Width="48" Height="85"/>
|
||||
<Texture Name="gDekuTreePauseScreenMapFloor1LeftTex" OutName="deku_tree_pause_screen_map_floor_1_left" Format="ci4" Width="48" Height="85"/>
|
||||
<Texture Name="gDekuTreePauseScreenMapFloor1RightTex" OutName="deku_tree_pause_screen_map_floor_1_right" Format="ci4" Width="48" Height="85"/>
|
||||
<Texture Name="gDekuTreePauseScreenMapBasement1LeftTex" OutName="deku_tree_pause_screen_map_basement_1_left" Format="ci4" Width="48" Height="85"/>
|
||||
<Texture Name="gDekuTreePauseScreenMapBasement1RightTex" OutName="deku_tree_pause_screen_map_basement_1_right" Format="ci4" Width="48" Height="85"/>
|
||||
<Texture Name="gDekuTreePauseScreenMapBasement2LeftTex" OutName="deku_tree_pause_screen_map_basement_2_left" Format="ci4" Width="48" Height="85"/>
|
||||
<Texture Name="gDekuTreePauseScreenMapBasement2RightTex" OutName="deku_tree_pause_screen_map_basement_2_right" Format="ci4" Width="48" Height="85"/>
|
||||
<Texture Name="gDodongosCavernPauseScreenMapFloor2LeftTex" OutName="dodongos_cavern_pause_screen_map_floor_2_left" Format="ci4" Width="48" Height="85"/>
|
||||
<Texture Name="gDodongosCavernPauseScreenMapFloor2RightTex" OutName="dodongos_cavern_pause_screen_map_floor_2_right" Format="ci4" Width="48" Height="85"/>
|
||||
<Texture Name="gDodongosCavernPauseScreenMapFloor1LeftTex" OutName="dodongos_cavern_pause_screen_map_floor_1_left" Format="ci4" Width="48" Height="85"/>
|
||||
<Texture Name="gDodongosCavernPauseScreenMapFloor1RightTex" OutName="dodongos_cavern_pause_screen_map_floor_1_right" Format="ci4" Width="48" Height="85"/>
|
||||
<Texture Name="gJabuPauseScreenMapFloor1LeftTex" OutName="jabu_pause_screen_map_floor_1_left" Format="ci4" Width="48" Height="85"/>
|
||||
<Texture Name="gJabuPauseScreenMapFloor1RightTex" OutName="jabu_pause_screen_map_floor_1_right" Format="ci4" Width="48" Height="85"/>
|
||||
<Texture Name="gJabuPauseScreenMapBasement1LeftTex" OutName="jabu_pause_screen_map_basement_1_left" Format="ci4" Width="48" Height="85"/>
|
||||
<Texture Name="gJabuPauseScreenMapBasement1RightTex" OutName="jabu_pause_screen_map_basement_1_right" Format="ci4" Width="48" Height="85"/>
|
||||
<Texture Name="gForestTemplePauseScreenMapFloor2LeftTex" OutName="forest_temple_pause_screen_map_floor_2_left" Format="ci4" Width="48" Height="85"/>
|
||||
<Texture Name="gForestTemplePauseScreenMapFloor2RightTex" OutName="forest_temple_pause_screen_map_floor_2_right" Format="ci4" Width="48" Height="85"/>
|
||||
<Texture Name="gForestTemplePauseScreenMapFloor1LeftTex" OutName="forest_temple_pause_screen_map_floor_1_left" Format="ci4" Width="48" Height="85"/>
|
||||
<Texture Name="gForestTemplePauseScreenMapFloor1RightTex" OutName="forest_temple_pause_screen_map_floor_1_right" Format="ci4" Width="48" Height="85"/>
|
||||
<Texture Name="gForestTemplePauseScreenMapBasement1LeftTex" OutName="forest_temple_pause_screen_map_basement_1_left" Format="ci4" Width="48" Height="85"/>
|
||||
<Texture Name="gForestTemplePauseScreenMapBasement1RightTex" OutName="forest_temple_pause_screen_map_basement_1_right" Format="ci4" Width="48" Height="85"/>
|
||||
<Texture Name="gForestTemplePauseScreenMapBasement2LeftTex" OutName="forest_temple_pause_screen_map_basement_2_left" Format="ci4" Width="48" Height="85"/>
|
||||
<Texture Name="gForestTemplePauseScreenMapBasement2RightTex" OutName="forest_temple_pause_screen_map_basement_2_right" Format="ci4" Width="48" Height="85"/>
|
||||
<Texture Name="gFireTemplePauseScreenMapFloor5LeftTex" OutName="fire_temple_pause_screen_map_floor_5_left" Format="ci4" Width="48" Height="85"/>
|
||||
<Texture Name="gFireTemplePauseScreenMapFloor5RightTex" OutName="fire_temple_pause_screen_map_floor_5_right" Format="ci4" Width="48" Height="85"/>
|
||||
<Texture Name="gFireTemplePauseScreenMapFloor4LeftTex" OutName="fire_temple_pause_screen_map_floor_4_left" Format="ci4" Width="48" Height="85"/>
|
||||
<Texture Name="gFireTemplePauseScreenMapFloor4RightTex" OutName="fire_temple_pause_screen_map_floor_4_right" Format="ci4" Width="48" Height="85"/>
|
||||
<Texture Name="gFireTemplePauseScreenMapFloor3LeftTex" OutName="fire_temple_pause_screen_map_floor_3_left" Format="ci4" Width="48" Height="85"/>
|
||||
<Texture Name="gFireTemplePauseScreenMapFloor3RightTex" OutName="fire_temple_pause_screen_map_floor_3_right" Format="ci4" Width="48" Height="85"/>
|
||||
<Texture Name="gFireTemplePauseScreenMapFloor2LeftTex" OutName="fire_temple_pause_screen_map_floor_2_left" Format="ci4" Width="48" Height="85"/>
|
||||
<Texture Name="gFireTemplePauseScreenMapFloor2RightTex" OutName="fire_temple_pause_screen_map_floor_2_right" Format="ci4" Width="48" Height="85"/>
|
||||
<Texture Name="gFireTemplePauseScreenMapFloor1LeftTex" OutName="fire_temple_pause_screen_map_floor_1_left" Format="ci4" Width="48" Height="85"/>
|
||||
<Texture Name="gFireTemplePauseScreenMapFloor1RightTex" OutName="fire_temple_pause_screen_map_floor_1_right" Format="ci4" Width="48" Height="85"/>
|
||||
<Texture Name="gWaterTemplePauseScreenMapFloor3LeftTex" OutName="water_temple_pause_screen_map_floor_3_left" Format="ci4" Width="48" Height="85"/>
|
||||
<Texture Name="gWaterTemplePauseScreenMapFloor3RightTex" OutName="water_temple_pause_screen_map_floor_3_right" Format="ci4" Width="48" Height="85"/>
|
||||
<Texture Name="gWaterTemplePauseScreenMapFloor2LeftTex" OutName="water_temple_pause_screen_map_floor_2_left" Format="ci4" Width="48" Height="85"/>
|
||||
<Texture Name="gWaterTemplePauseScreenMapFloor2RightTex" OutName="water_temple_pause_screen_map_floor_2_right" Format="ci4" Width="48" Height="85"/>
|
||||
<Texture Name="gWaterTemplePauseScreenMapFloor1LeftTex" OutName="water_temple_pause_screen_map_floor_1_left" Format="ci4" Width="48" Height="85"/>
|
||||
<Texture Name="gWaterTemplePauseScreenMapFloor1RightTex" OutName="water_temple_pause_screen_map_floor_1_right" Format="ci4" Width="48" Height="85"/>
|
||||
<Texture Name="gWaterTemplePauseScreenMapBasement1LeftTex" OutName="water_temple_pause_screen_map_basement_1_left" Format="ci4" Width="48" Height="85"/>
|
||||
<Texture Name="gWaterTemplePauseScreenMapBasement1RightTex" OutName="water_temple_pause_screen_map_basement_1_right" Format="ci4" Width="48" Height="85"/>
|
||||
<Texture Name="gSpiritTemplePauseScreenMapFloor4LeftTex" OutName="spirit_temple_pause_screen_map_floor_4_left" Format="ci4" Width="48" Height="85"/>
|
||||
<Texture Name="gSpiritTemplePauseScreenMapFloor4RightTex" OutName="spirit_temple_pause_screen_map_floor_4_right" Format="ci4" Width="48" Height="85"/>
|
||||
<Texture Name="gSpiritTemplePauseScreenMapFloor3LeftTex" OutName="spirit_temple_pause_screen_map_floor_3_left" Format="ci4" Width="48" Height="85"/>
|
||||
<Texture Name="gSpiritTemplePauseScreenMapFloor3RightTex" OutName="spirit_temple_pause_screen_map_floor_3_right" Format="ci4" Width="48" Height="85"/>
|
||||
<Texture Name="gSpiritTemplePauseScreenMapFloor2LeftTex" OutName="spirit_temple_pause_screen_map_floor_2_left" Format="ci4" Width="48" Height="85"/>
|
||||
<Texture Name="gSpiritTemplePauseScreenMapFloor2RightTex" OutName="spirit_temple_pause_screen_map_floor_2_right" Format="ci4" Width="48" Height="85"/>
|
||||
<Texture Name="gSpiritTemplePauseScreenMapFloor1LeftTex" OutName="spirit_temple_pause_screen_map_floor_1_left" Format="ci4" Width="48" Height="85"/>
|
||||
<Texture Name="gSpiritTemplePauseScreenMapFloor1RightTex" OutName="spirit_temple_pause_screen_map_floor_1_right" Format="ci4" Width="48" Height="85"/>
|
||||
<Texture Name="gShadowTemplePauseScreenMapBasement1LeftTex" OutName="shadow_temple_pause_screen_map_basement_1_left" Format="ci4" Width="48" Height="85"/>
|
||||
<Texture Name="gShadowTemplePauseScreenMapBasement1RightTex" OutName="shadow_temple_pause_screen_map_basement_1_right" Format="ci4" Width="48" Height="85"/>
|
||||
<Texture Name="gShadowTemplePauseScreenMapBasement2LeftTex" OutName="shadow_temple_pause_screen_map_basement_2_left" Format="ci4" Width="48" Height="85"/>
|
||||
<Texture Name="gShadowTemplePauseScreenMapBasement2RightTex" OutName="shadow_temple_pause_screen_map_basement_2_right" Format="ci4" Width="48" Height="85"/>
|
||||
<Texture Name="gShadowTemplePauseScreenMapBasement3LeftTex" OutName="shadow_temple_pause_screen_map_basement_3_left" Format="ci4" Width="48" Height="85"/>
|
||||
<Texture Name="gShadowTemplePauseScreenMapBasement3RightTex" OutName="shadow_temple_pause_screen_map_basement_3_right" Format="ci4" Width="48" Height="85"/>
|
||||
<Texture Name="gShadowTemplePauseScreenMapBasement4LeftTex" OutName="shadow_temple_pause_screen_map_basement_4_left" Format="ci4" Width="48" Height="85"/>
|
||||
<Texture Name="gShadowTemplePauseScreenMapBasement4RightTex" OutName="shadow_temple_pause_screen_map_basement_4_right" Format="ci4" Width="48" Height="85"/>
|
||||
<Texture Name="gBottomOfTheWellPauseScreenMapBasement1LeftTex" OutName="bottom_of_the_well_pause_screen_map_basement_1_left" Format="ci4" Width="48" Height="85"/>
|
||||
<Texture Name="gBottomOfTheWellPauseScreenMapBasement1RightTex" OutName="bottom_of_the_well_pause_screen_map_basement_1_right" Format="ci4" Width="48" Height="85"/>
|
||||
<Texture Name="gBottomOfTheWellPauseScreenMapBasement2LeftTex" OutName="bottom_of_the_well_pause_screen_map_basement_2_left" Format="ci4" Width="48" Height="85"/>
|
||||
<Texture Name="gBottomOfTheWellPauseScreenMapBasement2RightTex" OutName="bottom_of_the_well_pause_screen_map_basement_2_right" Format="ci4" Width="48" Height="85"/>
|
||||
<Texture Name="gBottomOfTheWellPauseScreenMapBasement3LeftTex" OutName="bottom_of_the_well_pause_screen_map_basement_3_left" Format="ci4" Width="48" Height="85"/>
|
||||
<Texture Name="gBottomOfTheWellPauseScreenMapBasement3RightTex" OutName="bottom_of_the_well_pause_screen_map_basement_3_right" Format="ci4" Width="48" Height="85"/>
|
||||
<Texture Name="gIceCavernPauseScreenMapFloor1LeftTex" OutName="ice_cavern_pause_screen_map_floor_1_left" Format="ci4" Width="48" Height="85"/>
|
||||
<Texture Name="gIceCavernPauseScreenMapFloor1RightTex" OutName="ice_cavern_pause_screen_map_floor_1_right" Format="ci4" Width="48" Height="85"/>
|
||||
<Texture Name="gDekuTreePauseScreenMapFloor3LeftTex" OutName="deku_tree_pause_screen_map_floor_3_left" Format="ci4" Width="48" Height="85" Offset="0x0"/>
|
||||
<Texture Name="gDekuTreePauseScreenMapFloor3RightTex" OutName="deku_tree_pause_screen_map_floor_3_right" Format="ci4" Width="48" Height="85" Offset="0x07F8"/>
|
||||
<Texture Name="gDekuTreePauseScreenMapFloor2LeftTex" OutName="deku_tree_pause_screen_map_floor_2_left" Format="ci4" Width="48" Height="85" Offset="0x0FF0"/>
|
||||
<Texture Name="gDekuTreePauseScreenMapFloor2RightTex" OutName="deku_tree_pause_screen_map_floor_2_right" Format="ci4" Width="48" Height="85" Offset="0x17E8"/>
|
||||
<Texture Name="gDekuTreePauseScreenMapFloor1LeftTex" OutName="deku_tree_pause_screen_map_floor_1_left" Format="ci4" Width="48" Height="85" Offset="0x1FE0"/>
|
||||
<Texture Name="gDekuTreePauseScreenMapFloor1RightTex" OutName="deku_tree_pause_screen_map_floor_1_right" Format="ci4" Width="48" Height="85" Offset="0x27D8"/>
|
||||
<Texture Name="gDekuTreePauseScreenMapBasement1LeftTex" OutName="deku_tree_pause_screen_map_basement_1_left" Format="ci4" Width="48" Height="85" Offset="0x2FD0"/>
|
||||
<Texture Name="gDekuTreePauseScreenMapBasement1RightTex" OutName="deku_tree_pause_screen_map_basement_1_right" Format="ci4" Width="48" Height="85" Offset="0x37C8"/>
|
||||
<Texture Name="gDekuTreePauseScreenMapBasement2LeftTex" OutName="deku_tree_pause_screen_map_basement_2_left" Format="ci4" Width="48" Height="85" Offset="0x3FC0"/>
|
||||
<Texture Name="gDekuTreePauseScreenMapBasement2RightTex" OutName="deku_tree_pause_screen_map_basement_2_right" Format="ci4" Width="48" Height="85" Offset="0x47B8"/>
|
||||
<Texture Name="gDodongosCavernPauseScreenMapFloor2LeftTex" OutName="dodongos_cavern_pause_screen_map_floor_2_left" Format="ci4" Width="48" Height="85" Offset="0x4FB0"/>
|
||||
<Texture Name="gDodongosCavernPauseScreenMapFloor2RightTex" OutName="dodongos_cavern_pause_screen_map_floor_2_right" Format="ci4" Width="48" Height="85" Offset="0x57A8"/>
|
||||
<Texture Name="gDodongosCavernPauseScreenMapFloor1LeftTex" OutName="dodongos_cavern_pause_screen_map_floor_1_left" Format="ci4" Width="48" Height="85" Offset="0x5FA0"/>
|
||||
<Texture Name="gDodongosCavernPauseScreenMapFloor1RightTex" OutName="dodongos_cavern_pause_screen_map_floor_1_right" Format="ci4" Width="48" Height="85" Offset="0x6798"/>
|
||||
<Texture Name="gJabuPauseScreenMapFloor1LeftTex" OutName="jabu_pause_screen_map_floor_1_left" Format="ci4" Width="48" Height="85" Offset="0x6F90"/>
|
||||
<Texture Name="gJabuPauseScreenMapFloor1RightTex" OutName="jabu_pause_screen_map_floor_1_right" Format="ci4" Width="48" Height="85" Offset="0x7788"/>
|
||||
<Texture Name="gJabuPauseScreenMapBasement1LeftTex" OutName="jabu_pause_screen_map_basement_1_left" Format="ci4" Width="48" Height="85" Offset="0x7F80"/>
|
||||
<Texture Name="gJabuPauseScreenMapBasement1RightTex" OutName="jabu_pause_screen_map_basement_1_right" Format="ci4" Width="48" Height="85" Offset="0x8778"/>
|
||||
<Texture Name="gForestTemplePauseScreenMapFloor2LeftTex" OutName="forest_temple_pause_screen_map_floor_2_left" Format="ci4" Width="48" Height="85" Offset="0x8F70"/>
|
||||
<Texture Name="gForestTemplePauseScreenMapFloor2RightTex" OutName="forest_temple_pause_screen_map_floor_2_right" Format="ci4" Width="48" Height="85" Offset="0x9768"/>
|
||||
<Texture Name="gForestTemplePauseScreenMapFloor1LeftTex" OutName="forest_temple_pause_screen_map_floor_1_left" Format="ci4" Width="48" Height="85" Offset="0x9F60"/>
|
||||
<Texture Name="gForestTemplePauseScreenMapFloor1RightTex" OutName="forest_temple_pause_screen_map_floor_1_right" Format="ci4" Width="48" Height="85" Offset="0xA758"/>
|
||||
<Texture Name="gForestTemplePauseScreenMapBasement1LeftTex" OutName="forest_temple_pause_screen_map_basement_1_left" Format="ci4" Width="48" Height="85" Offset="0xAF50"/>
|
||||
<Texture Name="gForestTemplePauseScreenMapBasement1RightTex" OutName="forest_temple_pause_screen_map_basement_1_right" Format="ci4" Width="48" Height="85" Offset="0xB748"/>
|
||||
<Texture Name="gForestTemplePauseScreenMapBasement2LeftTex" OutName="forest_temple_pause_screen_map_basement_2_left" Format="ci4" Width="48" Height="85" Offset="0xBF40"/>
|
||||
<Texture Name="gForestTemplePauseScreenMapBasement2RightTex" OutName="forest_temple_pause_screen_map_basement_2_right" Format="ci4" Width="48" Height="85" Offset="0xC738"/>
|
||||
<Texture Name="gFireTemplePauseScreenMapFloor5LeftTex" OutName="fire_temple_pause_screen_map_floor_5_left" Format="ci4" Width="48" Height="85" Offset="0xCF30"/>
|
||||
<Texture Name="gFireTemplePauseScreenMapFloor5RightTex" OutName="fire_temple_pause_screen_map_floor_5_right" Format="ci4" Width="48" Height="85" Offset="0xD728"/>
|
||||
<Texture Name="gFireTemplePauseScreenMapFloor4LeftTex" OutName="fire_temple_pause_screen_map_floor_4_left" Format="ci4" Width="48" Height="85" Offset="0xDF20"/>
|
||||
<Texture Name="gFireTemplePauseScreenMapFloor4RightTex" OutName="fire_temple_pause_screen_map_floor_4_right" Format="ci4" Width="48" Height="85" Offset="0xE718"/>
|
||||
<Texture Name="gFireTemplePauseScreenMapFloor3LeftTex" OutName="fire_temple_pause_screen_map_floor_3_left" Format="ci4" Width="48" Height="85" Offset="0xEF10"/>
|
||||
<Texture Name="gFireTemplePauseScreenMapFloor3RightTex" OutName="fire_temple_pause_screen_map_floor_3_right" Format="ci4" Width="48" Height="85" Offset="0xF708"/>
|
||||
<Texture Name="gFireTemplePauseScreenMapFloor2LeftTex" OutName="fire_temple_pause_screen_map_floor_2_left" Format="ci4" Width="48" Height="85" Offset="0xFF00"/>
|
||||
<Texture Name="gFireTemplePauseScreenMapFloor2RightTex" OutName="fire_temple_pause_screen_map_floor_2_right" Format="ci4" Width="48" Height="85" Offset="0x106F8"/>
|
||||
<Texture Name="gFireTemplePauseScreenMapFloor1LeftTex" OutName="fire_temple_pause_screen_map_floor_1_left" Format="ci4" Width="48" Height="85" Offset="0x10EF0"/>
|
||||
<Texture Name="gFireTemplePauseScreenMapFloor1RightTex" OutName="fire_temple_pause_screen_map_floor_1_right" Format="ci4" Width="48" Height="85" Offset="0x116E8"/>
|
||||
<Texture Name="gWaterTemplePauseScreenMapFloor3LeftTex" OutName="water_temple_pause_screen_map_floor_3_left" Format="ci4" Width="48" Height="85" Offset="0x11EE0"/>
|
||||
<Texture Name="gWaterTemplePauseScreenMapFloor3RightTex" OutName="water_temple_pause_screen_map_floor_3_right" Format="ci4" Width="48" Height="85" Offset="0x126D8"/>
|
||||
<Texture Name="gWaterTemplePauseScreenMapFloor2LeftTex" OutName="water_temple_pause_screen_map_floor_2_left" Format="ci4" Width="48" Height="85" Offset="0x12ED0"/>
|
||||
<Texture Name="gWaterTemplePauseScreenMapFloor2RightTex" OutName="water_temple_pause_screen_map_floor_2_right" Format="ci4" Width="48" Height="85" Offset="0x136C8"/>
|
||||
<Texture Name="gWaterTemplePauseScreenMapFloor1LeftTex" OutName="water_temple_pause_screen_map_floor_1_left" Format="ci4" Width="48" Height="85" Offset="0x13EC0"/>
|
||||
<Texture Name="gWaterTemplePauseScreenMapFloor1RightTex" OutName="water_temple_pause_screen_map_floor_1_right" Format="ci4" Width="48" Height="85" Offset="0x146B8"/>
|
||||
<Texture Name="gWaterTemplePauseScreenMapBasement1LeftTex" OutName="water_temple_pause_screen_map_basement_1_left" Format="ci4" Width="48" Height="85" Offset="0x14EB0"/>
|
||||
<Texture Name="gWaterTemplePauseScreenMapBasement1RightTex" OutName="water_temple_pause_screen_map_basement_1_right" Format="ci4" Width="48" Height="85" Offset="0x156A8"/>
|
||||
<Texture Name="gSpiritTemplePauseScreenMapFloor4LeftTex" OutName="spirit_temple_pause_screen_map_floor_4_left" Format="ci4" Width="48" Height="85" Offset="0x15EA0"/>
|
||||
<Texture Name="gSpiritTemplePauseScreenMapFloor4RightTex" OutName="spirit_temple_pause_screen_map_floor_4_right" Format="ci4" Width="48" Height="85" Offset="0x16698"/>
|
||||
<Texture Name="gSpiritTemplePauseScreenMapFloor3LeftTex" OutName="spirit_temple_pause_screen_map_floor_3_left" Format="ci4" Width="48" Height="85" Offset="0x16E90"/>
|
||||
<Texture Name="gSpiritTemplePauseScreenMapFloor3RightTex" OutName="spirit_temple_pause_screen_map_floor_3_right" Format="ci4" Width="48" Height="85" Offset="0x17688"/>
|
||||
<Texture Name="gSpiritTemplePauseScreenMapFloor2LeftTex" OutName="spirit_temple_pause_screen_map_floor_2_left" Format="ci4" Width="48" Height="85" Offset="0x17E80"/>
|
||||
<Texture Name="gSpiritTemplePauseScreenMapFloor2RightTex" OutName="spirit_temple_pause_screen_map_floor_2_right" Format="ci4" Width="48" Height="85" Offset="0x18678"/>
|
||||
<Texture Name="gSpiritTemplePauseScreenMapFloor1LeftTex" OutName="spirit_temple_pause_screen_map_floor_1_left" Format="ci4" Width="48" Height="85" Offset="0x18E70"/>
|
||||
<Texture Name="gSpiritTemplePauseScreenMapFloor1RightTex" OutName="spirit_temple_pause_screen_map_floor_1_right" Format="ci4" Width="48" Height="85" Offset="0x19668"/>
|
||||
<Texture Name="gShadowTemplePauseScreenMapBasement1LeftTex" OutName="shadow_temple_pause_screen_map_basement_1_left" Format="ci4" Width="48" Height="85" Offset="0x19E60"/>
|
||||
<Texture Name="gShadowTemplePauseScreenMapBasement1RightTex" OutName="shadow_temple_pause_screen_map_basement_1_right" Format="ci4" Width="48" Height="85" Offset="0x1A658"/>
|
||||
<Texture Name="gShadowTemplePauseScreenMapBasement2LeftTex" OutName="shadow_temple_pause_screen_map_basement_2_left" Format="ci4" Width="48" Height="85" Offset="0x1AE50"/>
|
||||
<Texture Name="gShadowTemplePauseScreenMapBasement2RightTex" OutName="shadow_temple_pause_screen_map_basement_2_right" Format="ci4" Width="48" Height="85" Offset="0x1B648"/>
|
||||
<Texture Name="gShadowTemplePauseScreenMapBasement3LeftTex" OutName="shadow_temple_pause_screen_map_basement_3_left" Format="ci4" Width="48" Height="85" Offset="0x1BE40"/>
|
||||
<Texture Name="gShadowTemplePauseScreenMapBasement3RightTex" OutName="shadow_temple_pause_screen_map_basement_3_right" Format="ci4" Width="48" Height="85" Offset="0x1C638"/>
|
||||
<Texture Name="gShadowTemplePauseScreenMapBasement4LeftTex" OutName="shadow_temple_pause_screen_map_basement_4_left" Format="ci4" Width="48" Height="85" Offset="0x1CE30"/>
|
||||
<Texture Name="gShadowTemplePauseScreenMapBasement4RightTex" OutName="shadow_temple_pause_screen_map_basement_4_right" Format="ci4" Width="48" Height="85" Offset="0x1D628"/>
|
||||
<Texture Name="gBottomOfTheWellPauseScreenMapBasement1LeftTex" OutName="bottom_of_the_well_pause_screen_map_basement_1_left" Format="ci4" Width="48" Height="85" Offset="0x1DE20"/>
|
||||
<Texture Name="gBottomOfTheWellPauseScreenMapBasement1RightTex" OutName="bottom_of_the_well_pause_screen_map_basement_1_right" Format="ci4" Width="48" Height="85" Offset="0x1E618"/>
|
||||
<Texture Name="gBottomOfTheWellPauseScreenMapBasement2LeftTex" OutName="bottom_of_the_well_pause_screen_map_basement_2_left" Format="ci4" Width="48" Height="85" Offset="0x1EE10"/>
|
||||
<Texture Name="gBottomOfTheWellPauseScreenMapBasement2RightTex" OutName="bottom_of_the_well_pause_screen_map_basement_2_right" Format="ci4" Width="48" Height="85" Offset="0x1F608"/>
|
||||
<Texture Name="gBottomOfTheWellPauseScreenMapBasement3LeftTex" OutName="bottom_of_the_well_pause_screen_map_basement_3_left" Format="ci4" Width="48" Height="85" Offset="0x1FE00"/>
|
||||
<Texture Name="gBottomOfTheWellPauseScreenMapBasement3RightTex" OutName="bottom_of_the_well_pause_screen_map_basement_3_right" Format="ci4" Width="48" Height="85" Offset="0x205F8"/>
|
||||
<Texture Name="gIceCavernPauseScreenMapFloor1LeftTex" OutName="ice_cavern_pause_screen_map_floor_1_left" Format="ci4" Width="48" Height="85" Offset="0x20DF0"/>
|
||||
<Texture Name="gIceCavernPauseScreenMapFloor1RightTex" OutName="ice_cavern_pause_screen_map_floor_1_right" Format="ci4" Width="48" Height="85" Offset="0x215E8"/>
|
||||
</File>
|
||||
</Root>
|
|
@ -29,6 +29,7 @@ void gDPSetTextureImage(Gfx* pkt, u32 f, u32 s, u32 w, uintptr_t i);
|
|||
void gSPDisplayList(Gfx* pkt, Gfx* dl);
|
||||
void gSPDisplayListOffset(Gfx* pkt, Gfx* dl, int offset);
|
||||
void gSPVertex(Gfx* pkt, uintptr_t v, int n, int v0);
|
||||
void gSPInvalidateTexCache(Gfx* pkt, uintptr_t texAddr);
|
||||
|
||||
void cleararena(void);
|
||||
void bootproc(void);
|
||||
|
@ -2404,7 +2405,9 @@ void Heaps_Alloc(void);
|
|||
void Heaps_Free(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
#undef this
|
||||
};
|
||||
#undef this
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,7 +1,12 @@
|
|||
#ifndef STDDEF_H
|
||||
#define STDDEF_H
|
||||
|
||||
#ifndef __cplusplus
|
||||
#define NULL ((void*)0)
|
||||
#else
|
||||
#define NULL nullptr
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
#define size_t unsigned long
|
||||
#define ssize_t long
|
||||
|
|
|
@ -138,6 +138,8 @@ extern GraphicsContext* __gfxCtx;
|
|||
#ifndef NDEBUG
|
||||
#define OPEN_DISPS(gfxCtx, file, line) \
|
||||
{ \
|
||||
void FrameInterpolation_RecordOpenChild(const void* a, int b); \
|
||||
FrameInterpolation_RecordOpenChild(file, line); \
|
||||
GraphicsContext* __gfxCtx; \
|
||||
Gfx* dispRefs[4]; \
|
||||
__gfxCtx = gfxCtx; \
|
||||
|
@ -146,6 +148,8 @@ extern GraphicsContext* __gfxCtx;
|
|||
#else
|
||||
#define OPEN_DISPS(gfxCtx, file, line) \
|
||||
{ \
|
||||
void FrameInterpolation_RecordOpenChild(const void* a, int b); \
|
||||
FrameInterpolation_RecordOpenChild(file, line); \
|
||||
GraphicsContext* __gfxCtx; \
|
||||
__gfxCtx = gfxCtx; \
|
||||
(void)__gfxCtx;
|
||||
|
@ -153,11 +157,15 @@ extern GraphicsContext* __gfxCtx;
|
|||
|
||||
#ifndef NDEBUG
|
||||
#define CLOSE_DISPS(gfxCtx, file, line) \
|
||||
{void FrameInterpolation_RecordCloseChild(void); \
|
||||
FrameInterpolation_RecordCloseChild();} \
|
||||
Graph_CloseDisps(dispRefs, gfxCtx, file, line); \
|
||||
} \
|
||||
(void)0
|
||||
#else
|
||||
#define CLOSE_DISPS(gfxCtx, file, line) \
|
||||
{void FrameInterpolation_RecordCloseChild(void); \
|
||||
FrameInterpolation_RecordCloseChild();} \
|
||||
(void)0; \
|
||||
} \
|
||||
(void)0
|
||||
|
|
|
@ -30,6 +30,9 @@
|
|||
#include "ichain.h"
|
||||
#include "regs.h"
|
||||
|
||||
#define AUDIO_HEAP_SIZE 0x38000
|
||||
#define SYSTEM_HEAP_SIZE (1024 * 1024 * 4)
|
||||
|
||||
#ifdef __cplusplus
|
||||
namespace Ship
|
||||
{
|
||||
|
|
|
@ -225,6 +225,7 @@ typedef struct EffectSs {
|
|||
/* 0x5C */ s16 life; // -1 means this entry is free
|
||||
/* 0x5E */ u8 priority; // Lower value means higher priority
|
||||
/* 0x5F */ u8 type;
|
||||
u32 epoch;
|
||||
} EffectSs; // size = 0x60
|
||||
|
||||
typedef struct {
|
||||
|
|
|
@ -78,6 +78,12 @@ typedef enum {
|
|||
/* 0x15 */ SLOT_BOTTLE_4,
|
||||
/* 0x16 */ SLOT_TRADE_ADULT,
|
||||
/* 0x17 */ SLOT_TRADE_CHILD,
|
||||
/* 0x18 */ SLOT_TUNIC_KOKIRI,
|
||||
/* 0x19 */ SLOT_TUNIC_GORON,
|
||||
/* 0x1A */ SLOT_TUNIC_ZORA,
|
||||
/* 0x1B */ SLOT_BOOTS_KOKIRI,
|
||||
/* 0x1C */ SLOT_BOOTS_IRON,
|
||||
/* 0x1D */ SLOT_BOOTS_HOVER,
|
||||
/* 0xFF */ SLOT_NONE = 0xFF
|
||||
} InventorySlot;
|
||||
|
||||
|
|
|
@ -128,7 +128,16 @@ typedef enum {
|
|||
/* 0x40 */ PLAYER_AP_MASK_GERUDO,
|
||||
/* 0x41 */ PLAYER_AP_MASK_TRUTH,
|
||||
/* 0x42 */ PLAYER_AP_LENS,
|
||||
/* 0x43 */ PLAYER_AP_MAX
|
||||
/* 0x43 */ PLAYER_AP_SHIELD_DEKU,
|
||||
/* 0x44 */ PLAYER_AP_SHIELD_HYLIAN,
|
||||
/* 0x45 */ PLAYER_AP_SHIELD_MIRROR,
|
||||
/* 0x46 */ PLAYER_AP_TUNIC_KOKIRI,
|
||||
/* 0x47 */ PLAYER_AP_TUNIC_GORON,
|
||||
/* 0x48 */ PLAYER_AP_TUNIC_ZORA,
|
||||
/* 0x49 */ PLAYER_AP_BOOTS_KOKIRI,
|
||||
/* 0x4A */ PLAYER_AP_BOOTS_IRON,
|
||||
/* 0x4B */ PLAYER_AP_BOOTS_HOVER,
|
||||
/* 0x4C */ PLAYER_AP_MAX
|
||||
} PlayerActionParam;
|
||||
|
||||
typedef enum {
|
||||
|
|
|
@ -173,6 +173,7 @@
|
|||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="soh\frame_interpolation.cpp" />
|
||||
<ClCompile Include="soh\Enhancements\bootcommands.c" />
|
||||
<ClCompile Include="soh\Enhancements\debugconsole.cpp" />
|
||||
<ClCompile Include="soh\Enhancements\debugger\colViewer.cpp" />
|
||||
|
@ -180,6 +181,7 @@
|
|||
<ClCompile Include="soh\Enhancements\debugger\debugSaveEditor.cpp" />
|
||||
<ClCompile Include="soh\Enhancements\debugger\ImGuiHelpers.cpp" />
|
||||
<ClCompile Include="soh\Enhancements\gameconsole.c" />
|
||||
<ClCompile Include="soh\Enhancements\savestates.cpp" />
|
||||
<ClCompile Include="soh\GbiWrap.cpp" />
|
||||
<ClCompile Include="soh\gu_pc.c" />
|
||||
<ClCompile Include="soh\OTRGlobals.cpp" />
|
||||
|
@ -328,7 +330,6 @@
|
|||
<ClCompile Include="src\code\z_msgevent.c" />
|
||||
<ClCompile Include="src\code\z_olib.c" />
|
||||
<ClCompile Include="src\code\z_onepointdemo.c" />
|
||||
<ClCompile Include="src\code\z_onepointdemo_data.c" />
|
||||
<ClCompile Include="src\code\z_parameter.c" />
|
||||
<ClCompile Include="src\code\z_path.c" />
|
||||
<ClCompile Include="src\code\z_play.c" />
|
||||
|
@ -878,6 +879,7 @@
|
|||
<ClCompile Include="src\overlays\misc\ovl_map_mark_data\z_map_mark_data.c" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="soh\frame_interpolation.h" />
|
||||
<ClInclude Include="include\alloca.h" />
|
||||
<ClInclude Include="include\bgm.h" />
|
||||
<ClInclude Include="include\color.h" />
|
||||
|
@ -926,10 +928,12 @@
|
|||
<ClInclude Include="soh\Enhancements\cvar.h" />
|
||||
<ClInclude Include="soh\Enhancements\debugconsole.h" />
|
||||
<ClInclude Include="soh\Enhancements\debugger\colViewer.h" />
|
||||
<ClInclude Include="soh\Enhancements\savestates.h" />
|
||||
<ClInclude Include="soh\Enhancements\debugger\debugger.h" />
|
||||
<ClInclude Include="soh\Enhancements\debugger\debugSaveEditor.h" />
|
||||
<ClInclude Include="soh\Enhancements\debugger\ImGuiHelpers.h" />
|
||||
<ClInclude Include="soh\gameconsole.h" />
|
||||
<ClInclude Include="soh\OTRAudio.h" />
|
||||
<ClInclude Include="soh\OTRGlobals.h" />
|
||||
<ClInclude Include="soh\util.h" />
|
||||
<ClInclude Include="src\overlays\actors\ovl_Arms_Hook\z_arms_hook.h" />
|
||||
|
|
|
@ -630,9 +630,6 @@
|
|||
<ClCompile Include="src\code\z_onepointdemo.c">
|
||||
<Filter>Source Files\src\code</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\code\z_onepointdemo_data.c">
|
||||
<Filter>Source Files\src\code</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\code\z_parameter.c">
|
||||
<Filter>Source Files\src\code</Filter>
|
||||
</ClCompile>
|
||||
|
@ -2189,6 +2186,14 @@
|
|||
</ClCompile>
|
||||
<ClCompile Include="soh\Enhancements\debugger\ImGuiHelpers.cpp">
|
||||
<Filter>Source Files\soh\Enhancements\debugger</Filter>
|
||||
<ClCompile Include="soh\frame_interpolation.cpp">
|
||||
<Filter>Source Files\soh</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\code\z_cheap_proc.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="soh\Enhancements\savestates.cpp">
|
||||
<Filter>Source Files\soh\Enhancements</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
|
@ -3745,6 +3750,14 @@
|
|||
</ClInclude>
|
||||
<ClInclude Include="soh\Enhancements\debugger\ImGuiHelpers.h">
|
||||
<Filter>Header Files\soh\Enhancements\debugger</Filter>
|
||||
<ClInclude Include="soh\frame_interpolation.h">
|
||||
<Filter>Header Files\soh</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="soh\Enhancements\savestates.h">
|
||||
<Filter>Source Files\soh\Enhancements</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="soh\OTRAudio.h">
|
||||
<Filter>Source Files\soh</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
|
|
|
@ -27,6 +27,7 @@ void BootCommands_Init()
|
|||
CVar_RegisterS32("gMinimalUI", 0);
|
||||
CVar_RegisterS32("gRumbleEnabled", 0);
|
||||
CVar_RegisterS32("gUniformLR", 1);
|
||||
CVar_RegisterS32("gTwoHandedIdle", 0);
|
||||
CVar_RegisterS32("gNewDrops", 0);
|
||||
CVar_RegisterS32("gVisualAgony", 0);
|
||||
CVar_RegisterS32("gLanguages", 0); //0 = English / 1 = German / 2 = French
|
||||
|
|
|
@ -1,12 +1,22 @@
|
|||
#ifdef _MSC_VER
|
||||
#define NOGDI
|
||||
#endif
|
||||
|
||||
#include "debugconsole.h"
|
||||
#include "../libultraship/SohImGuiImpl.h"
|
||||
#include "savestates.h"
|
||||
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include "soh/OTRGlobals.h"
|
||||
|
||||
|
||||
#define Path _Path
|
||||
#define PATH_HACK
|
||||
#include <Utils/StringHelper.h>
|
||||
#include <Utils/File.h>
|
||||
|
||||
#include "Lib/ImGui/imgui_internal.h"
|
||||
#undef PATH_HACK
|
||||
#undef Path
|
||||
|
||||
|
@ -301,6 +311,66 @@ static bool EntranceHandler(const std::vector<std::string>& args) {
|
|||
gSaveContext.nextTransition = 11;
|
||||
}
|
||||
|
||||
static bool SaveStateHandler(const std::vector<std::string>& args) {
|
||||
unsigned int slot = OTRGlobals::Instance->gSaveStateMgr->GetCurrentSlot();
|
||||
const SaveStateReturn rtn = OTRGlobals::Instance->gSaveStateMgr->AddRequest({ slot, RequestType::SAVE });
|
||||
|
||||
switch (rtn) {
|
||||
case SaveStateReturn::SUCCESS:
|
||||
INFO("[SOH] Saved state to slot %u", slot);
|
||||
return CMD_SUCCESS;
|
||||
case SaveStateReturn::FAIL_WRONG_GAMESTATE:
|
||||
ERROR("[SOH] Can not save a state outside of \"GamePlay\"");
|
||||
return CMD_FAILED;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
static bool LoadStateHandler(const std::vector<std::string>& args) {
|
||||
unsigned int slot = OTRGlobals::Instance->gSaveStateMgr->GetCurrentSlot();
|
||||
const SaveStateReturn rtn = OTRGlobals::Instance->gSaveStateMgr->AddRequest({ slot, RequestType::LOAD });
|
||||
|
||||
switch (rtn) {
|
||||
case SaveStateReturn::SUCCESS:
|
||||
INFO("[SOH] Loaded state from slot %u", slot);
|
||||
return CMD_SUCCESS;
|
||||
case SaveStateReturn::FAIL_INVALID_SLOT:
|
||||
ERROR("[SOH] Invalid State Slot Number (%u)", slot);
|
||||
return CMD_FAILED;
|
||||
case SaveStateReturn::FAIL_STATE_EMPTY:
|
||||
ERROR("[SOH] State Slot (%u) is empty", slot);
|
||||
return CMD_FAILED;
|
||||
case SaveStateReturn::FAIL_WRONG_GAMESTATE:
|
||||
ERROR("[SOH] Can not load a state outside of \"GamePlay\"");
|
||||
return CMD_FAILED;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static bool StateSlotSelectHandler(const std::vector<std::string>& args) {
|
||||
if (args.size() != 2) {
|
||||
ERROR("[SOH] Unexpected arguments passed");
|
||||
return CMD_FAILED;
|
||||
}
|
||||
int slot;
|
||||
|
||||
try {
|
||||
slot = std::stoi(args[1], nullptr, 10);
|
||||
} catch (std::invalid_argument const& ex) {
|
||||
ERROR("[SOH] SaveState slot value must be a number.");
|
||||
return CMD_FAILED;
|
||||
}
|
||||
|
||||
if (slot < 0) {
|
||||
ERROR("[SOH] Invalid slot passed. Slot must be between 0 and 2");
|
||||
return CMD_FAILED;
|
||||
}
|
||||
|
||||
OTRGlobals::Instance->gSaveStateMgr->SetCurrentSlot(slot);
|
||||
INFO("[SOH] Slot %u selected", OTRGlobals::Instance->gSaveStateMgr->GetCurrentSlot());
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
#define VARTYPE_INTEGER 0
|
||||
#define VARTYPE_FLOAT 1
|
||||
#define VARTYPE_STRING 2
|
||||
|
@ -334,7 +404,7 @@ static bool SetCVarHandler(const std::vector<std::string>& args) {
|
|||
int vType = CheckVarType(args[2]);
|
||||
|
||||
if (vType == VARTYPE_STRING)
|
||||
CVar_SetString(args[1].c_str(), (char*)args[2].c_str());
|
||||
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]));
|
||||
else
|
||||
|
@ -351,7 +421,7 @@ static bool GetCVarHandler(const std::vector<std::string>& args) {
|
|||
if (args.size() < 2)
|
||||
return CMD_FAILED;
|
||||
|
||||
CVar* cvar = CVar_GetVar(args[1].c_str());
|
||||
CVar* cvar = CVar_Get(args[1].c_str());
|
||||
|
||||
if (cvar != nullptr)
|
||||
{
|
||||
|
@ -414,6 +484,13 @@ void DebugConsole_Init(void) {
|
|||
{ { "slot", ArgumentType::NUMBER }, { "item id", ArgumentType::NUMBER } } });
|
||||
CMD_REGISTER("entrance",
|
||||
{ EntranceHandler, "Sends player to the entered entrance (hex)", { { "entrance", ArgumentType::NUMBER } } });
|
||||
|
||||
CMD_REGISTER("save_state", { SaveStateHandler, "Save a state." });
|
||||
CMD_REGISTER("load_state", { LoadStateHandler, "Load a state." });
|
||||
CMD_REGISTER("set_slot", { StateSlotSelectHandler, "Selects a SaveState slot", {
|
||||
{ "Slot number", ArgumentType::NUMBER, }
|
||||
} });
|
||||
DebugConsole_LoadCVars();
|
||||
}
|
||||
|
||||
template <typename Numeric> bool is_number(const std::string& s) {
|
||||
|
@ -431,7 +508,9 @@ void DebugConsole_LoadCVars()
|
|||
if (line.empty()) continue;
|
||||
if (cfg.size() < 2) continue;
|
||||
if (cfg[1].find("\"") != std::string::npos) {
|
||||
CVar_SetString(cfg[0].c_str(), const_cast<char*>(cfg[1].c_str()));
|
||||
std::string value(cfg[1]);
|
||||
value.erase(std::ranges::remove(value, '\"').begin(), value.end());
|
||||
CVar_SetString(cfg[0].c_str(), ImStrdup(value.c_str()));
|
||||
}
|
||||
if (is_number<float>(cfg[1])) {
|
||||
CVar_SetFloat(cfg[0].c_str(), std::stof(cfg[1]));
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#include "colViewer.h"
|
||||
#include "../libultraship/SohImGuiImpl.h"
|
||||
#include "ImGuiHelpers.h"
|
||||
#include "../../frame_interpolation.h"
|
||||
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
@ -97,7 +98,7 @@ void DrawColViewerWindow(bool& open) {
|
|||
}
|
||||
|
||||
ImGui::SetNextWindowSize(ImVec2(520, 600), ImGuiCond_FirstUseEver);
|
||||
if (!ImGui::Begin("Collision Viewer", &open)) {
|
||||
if (!ImGui::Begin("Collision Viewer", &open, ImGuiWindowFlags_NoFocusOnAppearing)) {
|
||||
ImGui::End();
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -251,15 +251,31 @@ void DrawGroupWithBorder(T&& drawFunc) {
|
|||
ImGui::EndGroup();
|
||||
}
|
||||
|
||||
void DrawInfoTab() {
|
||||
// TODO This is the bare minimum to get the player name showing
|
||||
// There will need to be more effort to get it robust and editable
|
||||
std::string name;
|
||||
for (int i = 0; i < 8; i++) {
|
||||
char letter = gSaveContext.playerName[i] + 0x3D;
|
||||
if (letter == '{') {
|
||||
letter = '\0';
|
||||
char z2ASCII(int code) {
|
||||
int ret;
|
||||
if (code < 10) { //Digits
|
||||
ret = code + 0x30;
|
||||
} else if (code >= 10 && code < 36) { //Uppercase letters
|
||||
ret = code + 0x37;
|
||||
} else if (code >= 36 && code < 62) { //Lowercase letters
|
||||
ret = code + 0x3D;
|
||||
} else if (code == 62) { //Space
|
||||
ret = code - 0x1E;
|
||||
} else if (code == 63 || code == 64) { // _ and .
|
||||
ret = code - 0x12;
|
||||
} else {
|
||||
ret = code;
|
||||
}
|
||||
return char(ret);
|
||||
|
||||
}
|
||||
|
||||
void DrawInfoTab() {
|
||||
// TODO Needs a better method for name changing but for now this will work.
|
||||
std::string name;
|
||||
ImU16 one = 1;
|
||||
for (int i = 0; i < 8; i++) {
|
||||
char letter = z2ASCII(gSaveContext.playerName[i]);
|
||||
name += letter;
|
||||
}
|
||||
name += '\0';
|
||||
|
@ -268,6 +284,14 @@ void DrawInfoTab() {
|
|||
|
||||
ImGui::Text("Name: %s", name.c_str());
|
||||
InsertHelpHoverText("Player Name");
|
||||
std::string nameID;
|
||||
for (int i = 0; i < 8; i++) {
|
||||
nameID = z2ASCII(i);
|
||||
if (i % 4 != 0) {
|
||||
ImGui::SameLine();
|
||||
}
|
||||
ImGui::InputScalar(nameID.c_str(), ImGuiDataType_U8, &gSaveContext.playerName[i], &one, NULL);
|
||||
}
|
||||
|
||||
// Use an intermediary to keep the health from updating (and potentially killing the player)
|
||||
// until it is done being edited
|
||||
|
@ -377,20 +401,100 @@ void DrawInfoTab() {
|
|||
ImGui::InputScalar("Bgs Day Count", ImGuiDataType_S32, &gSaveContext.bgsDayCount);
|
||||
InsertHelpHoverText("Total number of days elapsed since giving Biggoron the claim check");
|
||||
|
||||
// TODO Changing Link's age is more involved than just setting gSaveContext.linkAge
|
||||
// It might not fit here and instead should be only changable when changing scenes
|
||||
/*
|
||||
if (ImGui::BeginCombo("Link Age", LINK_IS_ADULT ? "Adult" : "Child")) {
|
||||
if (ImGui::Selectable("Adult")) {
|
||||
gSaveContext.linkAge = 0;
|
||||
ImGui::InputScalar("Entrance Index", ImGuiDataType_S32, &gSaveContext.entranceIndex);
|
||||
InsertHelpHoverText("From which entrance did Link arrive?");
|
||||
|
||||
ImGui::InputScalar("Cutscene Index", ImGuiDataType_S32, &gSaveContext.cutsceneIndex);
|
||||
InsertHelpHoverText("Which cutscene is this?");
|
||||
|
||||
ImGui::InputScalar("Navi Timer", ImGuiDataType_U16, &gSaveContext.naviTimer);
|
||||
InsertHelpHoverText("Navi wants to talk at 600 units, decides not to at 3000.");
|
||||
|
||||
ImGui::InputScalar("Timer 1 State", ImGuiDataType_S16, &gSaveContext.timer1State);
|
||||
InsertHelpHoverText("Heat timer, race timer, etc. Has white font");
|
||||
|
||||
ImGui::InputScalar("Timer 1 Value", ImGuiDataType_S16, &gSaveContext.timer1Value, &one, NULL);
|
||||
InsertHelpHoverText("Time, in seconds");
|
||||
|
||||
ImGui::InputScalar("Timer 2 State", ImGuiDataType_S16, &gSaveContext.timer2State);
|
||||
InsertHelpHoverText("Trade timer, Ganon collapse timer, etc. Has yellow font");
|
||||
|
||||
ImGui::InputScalar("Timer 2 Value", ImGuiDataType_S16, &gSaveContext.timer2Value, &one, NULL);
|
||||
InsertHelpHoverText("Time, in seconds");
|
||||
|
||||
const char* audioName;
|
||||
switch (gSaveContext.audioSetting) {
|
||||
case 0:
|
||||
audioName = "Stereo";
|
||||
break;
|
||||
case 1:
|
||||
audioName = "Mono";
|
||||
break;
|
||||
case 2:
|
||||
audioName = "Headset";
|
||||
break;
|
||||
case 3:
|
||||
audioName = "Surround";
|
||||
break;
|
||||
default:
|
||||
audioName = "?";
|
||||
}
|
||||
if (ImGui::Selectable("Child")) {
|
||||
gSaveContext.linkAge = 1;
|
||||
if (ImGui::BeginCombo("Audio", audioName)) {
|
||||
if (ImGui::Selectable("Stereo")) {
|
||||
gSaveContext.audioSetting = 0;
|
||||
}
|
||||
if (ImGui::Selectable("Mono")) {
|
||||
gSaveContext.audioSetting = 1;
|
||||
}
|
||||
if (ImGui::Selectable("Headset")) {
|
||||
gSaveContext.audioSetting = 2;
|
||||
}
|
||||
if (ImGui::Selectable("Surround")) {
|
||||
gSaveContext.audioSetting = 3;
|
||||
}
|
||||
|
||||
ImGui::EndCombo();
|
||||
}
|
||||
*/
|
||||
InsertHelpHoverText("Sound setting");
|
||||
|
||||
bool n64DDFlag = gSaveContext.n64ddFlag != 0;
|
||||
if (ImGui::Checkbox("64 DD file?", &n64DDFlag)) {
|
||||
gSaveContext.n64ddFlag = n64DDFlag;
|
||||
}
|
||||
InsertHelpHoverText("WARNING! If you save, your file may be locked! Use caution!");
|
||||
|
||||
if (ImGui::BeginCombo("Z Target Mode", gSaveContext.zTargetSetting ? "Hold" : "Switch")) {
|
||||
if (ImGui::Selectable("Switch")) {
|
||||
gSaveContext.zTargetSetting = 0;
|
||||
}
|
||||
if (ImGui::Selectable("Hold")) {
|
||||
gSaveContext.zTargetSetting = 1;
|
||||
}
|
||||
ImGui::EndCombo();
|
||||
}
|
||||
InsertHelpHoverText("Z-Targeting behavior");
|
||||
|
||||
|
||||
ImGui::PushItemWidth(ImGui::GetFontSize() * 10);
|
||||
static std::array<const char*, 7> minigameHS = { "Horseback Archery",
|
||||
"Big Poe Points",
|
||||
"Fishing",
|
||||
"Malon's Obstacle Course",
|
||||
"Running Man Race",
|
||||
"?",
|
||||
"Dampe's Race" };
|
||||
|
||||
if (ImGui::TreeNode("Minigames")) {
|
||||
for (int i = 0; i < 7; i++) {
|
||||
if (i == 5) { //HS_UNK_05 is unused
|
||||
continue;
|
||||
}
|
||||
std::string minigameLbl = minigameHS[i];
|
||||
ImGui::InputScalar(minigameLbl.c_str(), ImGuiDataType_S32, &gSaveContext.highScores[i], &one, NULL);
|
||||
}
|
||||
|
||||
ImGui::TreePop();
|
||||
}
|
||||
|
||||
ImGui::PopItemWidth();
|
||||
}
|
||||
|
@ -505,7 +609,7 @@ void DrawInventoryTab() {
|
|||
}
|
||||
|
||||
// Draw a flag bitfield as an grid of checkboxes
|
||||
void DrawFlagArray(const std::string& name, uint32_t& flags) {
|
||||
void DrawFlagArray32(const std::string& name, uint32_t& flags) {
|
||||
ImGui::PushID(name.c_str());
|
||||
for (int32_t flagIndex = 0; flagIndex < 32; flagIndex++) {
|
||||
if ((flagIndex % 8) != 0) {
|
||||
|
@ -526,6 +630,25 @@ void DrawFlagArray(const std::string& name, uint32_t& flags) {
|
|||
ImGui::PopID();
|
||||
}
|
||||
|
||||
void DrawFlagArray16(const std::string& name, uint16_t& flags) {
|
||||
ImGui::PushID(name.c_str());
|
||||
for (int32_t flagIndex = 15; flagIndex >= 0; flagIndex--) {
|
||||
ImGui::SameLine();
|
||||
ImGui::PushID(flagIndex);
|
||||
uint32_t bitMask = 1 << flagIndex;
|
||||
bool flag = (flags & bitMask) != 0;
|
||||
if (ImGui::Checkbox("##check", &flag)) {
|
||||
if (flag) {
|
||||
flags |= bitMask;
|
||||
} else {
|
||||
flags &= ~bitMask;
|
||||
}
|
||||
}
|
||||
ImGui::PopID();
|
||||
}
|
||||
ImGui::PopID();
|
||||
}
|
||||
|
||||
void DrawFlagsTab() {
|
||||
if (ImGui::TreeNode("Current Scene")) {
|
||||
if (gGlobalCtx != nullptr) {
|
||||
|
@ -534,7 +657,7 @@ void DrawFlagsTab() {
|
|||
DrawGroupWithBorder([&]() {
|
||||
ImGui::Text("Switch");
|
||||
InsertHelpHoverText("Permanently-saved switch flags");
|
||||
DrawFlagArray("Switch", act->flags.swch);
|
||||
DrawFlagArray32("Switch", act->flags.swch);
|
||||
});
|
||||
|
||||
ImGui::SameLine();
|
||||
|
@ -542,13 +665,13 @@ void DrawFlagsTab() {
|
|||
DrawGroupWithBorder([&]() {
|
||||
ImGui::Text("Temp Switch");
|
||||
InsertHelpHoverText("Temporary switch flags. Unset on scene transitions");
|
||||
DrawFlagArray("Temp Switch", act->flags.tempSwch);
|
||||
DrawFlagArray32("Temp Switch", act->flags.tempSwch);
|
||||
});
|
||||
|
||||
DrawGroupWithBorder([&]() {
|
||||
ImGui::Text("Clear");
|
||||
InsertHelpHoverText("Permanently-saved room-clear flags");
|
||||
DrawFlagArray("Clear", act->flags.clear);
|
||||
DrawFlagArray32("Clear", act->flags.clear);
|
||||
});
|
||||
|
||||
ImGui::SameLine();
|
||||
|
@ -556,13 +679,13 @@ void DrawFlagsTab() {
|
|||
DrawGroupWithBorder([&]() {
|
||||
ImGui::Text("Temp Clear");
|
||||
InsertHelpHoverText("Temporary room-clear flags. Unset on scene transitions");
|
||||
DrawFlagArray("Temp Clear", act->flags.tempClear);
|
||||
DrawFlagArray32("Temp Clear", act->flags.tempClear);
|
||||
});
|
||||
|
||||
DrawGroupWithBorder([&]() {
|
||||
ImGui::Text("Collect");
|
||||
InsertHelpHoverText("Permanently-saved collect flags");
|
||||
DrawFlagArray("Collect", act->flags.collect);
|
||||
DrawFlagArray32("Collect", act->flags.collect);
|
||||
});
|
||||
|
||||
ImGui::SameLine();
|
||||
|
@ -570,13 +693,13 @@ void DrawFlagsTab() {
|
|||
DrawGroupWithBorder([&]() {
|
||||
ImGui::Text("Temp Collect");
|
||||
InsertHelpHoverText("Temporary collect flags. Unset on scene transitions");
|
||||
DrawFlagArray("Temp Collect", act->flags.tempCollect);
|
||||
DrawFlagArray32("Temp Collect", act->flags.tempCollect);
|
||||
});
|
||||
|
||||
DrawGroupWithBorder([&]() {
|
||||
ImGui::Text("Chest");
|
||||
InsertHelpHoverText("Permanently-saved chest flags");
|
||||
DrawFlagArray("Chest", act->flags.chest);
|
||||
DrawFlagArray32("Chest", act->flags.chest);
|
||||
});
|
||||
|
||||
ImGui::SameLine();
|
||||
|
@ -633,7 +756,7 @@ void DrawFlagsTab() {
|
|||
DrawGroupWithBorder([&]() {
|
||||
ImGui::Text("Switch");
|
||||
InsertHelpHoverText("Switch flags");
|
||||
DrawFlagArray("Switch", gSaveContext.sceneFlags[selectedSceneFlagMap].swch);
|
||||
DrawFlagArray32("Switch", gSaveContext.sceneFlags[selectedSceneFlagMap].swch);
|
||||
});
|
||||
|
||||
ImGui::SameLine();
|
||||
|
@ -641,13 +764,13 @@ void DrawFlagsTab() {
|
|||
DrawGroupWithBorder([&]() {
|
||||
ImGui::Text("Clear");
|
||||
InsertHelpHoverText("Room-clear flags");
|
||||
DrawFlagArray("Clear", gSaveContext.sceneFlags[selectedSceneFlagMap].clear);
|
||||
DrawFlagArray32("Clear", gSaveContext.sceneFlags[selectedSceneFlagMap].clear);
|
||||
});
|
||||
|
||||
DrawGroupWithBorder([&]() {
|
||||
ImGui::Text("Collect");
|
||||
InsertHelpHoverText("Collect flags");
|
||||
DrawFlagArray("Collect", gSaveContext.sceneFlags[selectedSceneFlagMap].collect);
|
||||
DrawFlagArray32("Collect", gSaveContext.sceneFlags[selectedSceneFlagMap].collect);
|
||||
});
|
||||
|
||||
ImGui::SameLine();
|
||||
|
@ -655,13 +778,13 @@ void DrawFlagsTab() {
|
|||
DrawGroupWithBorder([&]() {
|
||||
ImGui::Text("Chest");
|
||||
InsertHelpHoverText("Chest flags");
|
||||
DrawFlagArray("Chest", gSaveContext.sceneFlags[selectedSceneFlagMap].chest);
|
||||
DrawFlagArray32("Chest", gSaveContext.sceneFlags[selectedSceneFlagMap].chest);
|
||||
});
|
||||
|
||||
DrawGroupWithBorder([&]() {
|
||||
ImGui::Text("Rooms");
|
||||
InsertHelpHoverText("Flags for visted rooms");
|
||||
DrawFlagArray("Rooms", gSaveContext.sceneFlags[selectedSceneFlagMap].rooms);
|
||||
DrawFlagArray32("Rooms", gSaveContext.sceneFlags[selectedSceneFlagMap].rooms);
|
||||
});
|
||||
|
||||
ImGui::SameLine();
|
||||
|
@ -669,7 +792,7 @@ void DrawFlagsTab() {
|
|||
DrawGroupWithBorder([&]() {
|
||||
ImGui::Text("Floors");
|
||||
InsertHelpHoverText("Flags for visted floors");
|
||||
DrawFlagArray("Floors", gSaveContext.sceneFlags[selectedSceneFlagMap].floors);
|
||||
DrawFlagArray32("Floors", gSaveContext.sceneFlags[selectedSceneFlagMap].floors);
|
||||
});
|
||||
|
||||
ImGui::TreePop();
|
||||
|
@ -730,6 +853,124 @@ void DrawFlagsTab() {
|
|||
gSaveContext.inventory.gsTokens = gsCount;
|
||||
}
|
||||
});
|
||||
|
||||
if (ImGui::TreeNode("Event Check Inf Flags")) {
|
||||
DrawGroupWithBorder([&]() {
|
||||
ImGui::Text("0");
|
||||
InsertHelpHoverText("Mostly Kokiri Forest related");
|
||||
DrawFlagArray16("eci0", gSaveContext.eventChkInf[0]);
|
||||
});
|
||||
|
||||
DrawGroupWithBorder([&]() {
|
||||
ImGui::Text("1");
|
||||
InsertHelpHoverText("Mostly Lon Lon Ranch related");
|
||||
DrawFlagArray16("eci1", gSaveContext.eventChkInf[1]);
|
||||
});
|
||||
|
||||
DrawGroupWithBorder([&]() {
|
||||
ImGui::Text("2");
|
||||
InsertHelpHoverText("Dodongo Related?");
|
||||
DrawFlagArray16("eci2", gSaveContext.eventChkInf[2]);
|
||||
});
|
||||
|
||||
DrawGroupWithBorder([&]() {
|
||||
ImGui::Text("3");
|
||||
InsertHelpHoverText("Mostly Zora related");
|
||||
DrawFlagArray16("eci3", gSaveContext.eventChkInf[3]);
|
||||
});
|
||||
|
||||
DrawGroupWithBorder([&]() {
|
||||
ImGui::Text("4");
|
||||
InsertHelpHoverText("Random");
|
||||
DrawFlagArray16("eci4", gSaveContext.eventChkInf[4]);
|
||||
});
|
||||
|
||||
DrawGroupWithBorder([&]() {
|
||||
ImGui::Text("5");
|
||||
InsertHelpHoverText("Mostly song learning related");
|
||||
DrawFlagArray16("eci5", gSaveContext.eventChkInf[5]);
|
||||
});
|
||||
|
||||
DrawGroupWithBorder([&]() {
|
||||
ImGui::Text("6");
|
||||
InsertHelpHoverText("Random");
|
||||
DrawFlagArray16("eci6", gSaveContext.eventChkInf[6]);
|
||||
});
|
||||
|
||||
DrawGroupWithBorder([&]() {
|
||||
ImGui::Text("7");
|
||||
InsertHelpHoverText("Boss Battle related");
|
||||
DrawFlagArray16("eci7", gSaveContext.eventChkInf[7]);
|
||||
});
|
||||
|
||||
DrawGroupWithBorder([&]() {
|
||||
ImGui::Text("8");
|
||||
InsertHelpHoverText("Mask related?");
|
||||
DrawFlagArray16("eci8", gSaveContext.eventChkInf[8]);
|
||||
});
|
||||
|
||||
DrawGroupWithBorder([&]() {
|
||||
ImGui::Text("9");
|
||||
InsertHelpHoverText("Mostly carpenter related");
|
||||
DrawFlagArray16("eci9", gSaveContext.eventChkInf[9]);
|
||||
});
|
||||
|
||||
DrawGroupWithBorder([&]() {
|
||||
ImGui::Text("A");
|
||||
InsertHelpHoverText("First-time overworld entrance cs related");
|
||||
DrawFlagArray16("eci1", gSaveContext.eventChkInf[10]);
|
||||
});
|
||||
|
||||
DrawGroupWithBorder([&]() {
|
||||
ImGui::Text("B");
|
||||
InsertHelpHoverText("First-time dungeon entrance cs/trial cs related");
|
||||
DrawFlagArray16("eci11", gSaveContext.eventChkInf[11]);
|
||||
});
|
||||
|
||||
DrawGroupWithBorder([&]() {
|
||||
ImGui::Text("C");
|
||||
InsertHelpHoverText("Random");
|
||||
DrawFlagArray16("eci12", gSaveContext.eventChkInf[12]);
|
||||
});
|
||||
|
||||
DrawGroupWithBorder([&]() {
|
||||
ImGui::Text("D");
|
||||
InsertHelpHoverText("Frog songs/GS rewards");
|
||||
DrawFlagArray16("eci13", gSaveContext.eventChkInf[13]);
|
||||
});
|
||||
|
||||
ImGui::TreePop();
|
||||
}
|
||||
if (ImGui::TreeNode("Inf Table Flags")) {
|
||||
for (int i = 0; i < 30; i++) {
|
||||
std::string it_id = "it" + std::to_string(i);
|
||||
DrawGroupWithBorder([&]() {
|
||||
ImGui::Text("%2d", i);
|
||||
DrawFlagArray16(it_id, gSaveContext.infTable[i]);
|
||||
});
|
||||
}
|
||||
ImGui::TreePop();
|
||||
}
|
||||
if (ImGui::TreeNode("Item Get Inf Flags")) {
|
||||
for (int i = 0; i < 4; i++) {
|
||||
std::string igi_id = "igi" + std::to_string(i);
|
||||
DrawGroupWithBorder([&]() {
|
||||
ImGui::Text("%d", i);
|
||||
DrawFlagArray16(igi_id, gSaveContext.itemGetInf[i]);
|
||||
});
|
||||
}
|
||||
ImGui::TreePop();
|
||||
}
|
||||
if (ImGui::TreeNode("Event Inf Flags")) {
|
||||
for (int i = 0; i < 4; i++) {
|
||||
std::string ei_id = "ei" + std::to_string(i);
|
||||
DrawGroupWithBorder([&]() {
|
||||
ImGui::Text("%d", i);
|
||||
DrawFlagArray16(ei_id, gSaveContext.eventInf[i]);
|
||||
});
|
||||
}
|
||||
ImGui::TreePop();
|
||||
}
|
||||
}
|
||||
|
||||
// Draws a combo that lets you choose and upgrade value from a drop-down of text values
|
||||
|
@ -1057,13 +1298,249 @@ void DrawQuestStatusTab() {
|
|||
ImGui::PopItemWidth();
|
||||
}
|
||||
|
||||
void DrawPlayerTab() {
|
||||
if (gGlobalCtx != nullptr) {
|
||||
Player* player = GET_PLAYER(gGlobalCtx);
|
||||
const char* curSword;
|
||||
const char* curShield;
|
||||
const char* curTunic;
|
||||
const char* curBoots;
|
||||
|
||||
switch (player->currentSwordItem) {
|
||||
case ITEM_SWORD_KOKIRI:
|
||||
curSword = "Kokiri Sword";
|
||||
break;
|
||||
case ITEM_SWORD_MASTER:
|
||||
curSword = "Master Sword";
|
||||
break;
|
||||
case ITEM_SWORD_BGS:
|
||||
curSword = "Biggoron's Sword";
|
||||
break;
|
||||
case ITEM_NONE:
|
||||
curSword = "None";
|
||||
break;
|
||||
default:
|
||||
curSword = "None";
|
||||
break;
|
||||
}
|
||||
|
||||
switch (player->currentShield) {
|
||||
case PLAYER_SHIELD_NONE:
|
||||
curShield = "None";
|
||||
break;
|
||||
case PLAYER_SHIELD_DEKU:
|
||||
curShield = "Deku Shield";
|
||||
break;
|
||||
case PLAYER_SHIELD_HYLIAN:
|
||||
curShield = "Hylian Shield";
|
||||
break;
|
||||
case PLAYER_SHIELD_MIRROR:
|
||||
curShield = "Mirror Shield";
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
switch (player->currentTunic) {
|
||||
case PLAYER_TUNIC_KOKIRI:
|
||||
curTunic = "Kokiri Tunic";
|
||||
break;
|
||||
case PLAYER_TUNIC_GORON:
|
||||
curTunic = "Goron Tunic";
|
||||
break;
|
||||
case PLAYER_TUNIC_ZORA:
|
||||
curTunic = "Zora Tunic";
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
switch (player->currentBoots) {
|
||||
case PLAYER_BOOTS_KOKIRI:
|
||||
curBoots = "Kokiri Boots";
|
||||
break;
|
||||
case PLAYER_BOOTS_IRON:
|
||||
curBoots = "Iron Boots";
|
||||
break;
|
||||
case PLAYER_BOOTS_HOVER:
|
||||
curBoots = "Hover Boots";
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
ImGui::PushItemWidth(ImGui::GetFontSize() * 6);
|
||||
DrawGroupWithBorder([&]() {
|
||||
ImGui::Text("Link's Position");
|
||||
ImGui::InputScalar("X Pos", ImGuiDataType_Float, &player->actor.world.pos.x);
|
||||
ImGui::SameLine();
|
||||
ImGui::InputScalar("Y Pos", ImGuiDataType_Float, &player->actor.world.pos.y);
|
||||
ImGui::SameLine();
|
||||
ImGui::InputScalar("Z Pos", ImGuiDataType_Float, &player->actor.world.pos.z);
|
||||
});
|
||||
|
||||
DrawGroupWithBorder([&]() {
|
||||
ImGui::Text("Link's Rotation");
|
||||
InsertHelpHoverText("For Link's rotation in relation to the world");
|
||||
ImGui::InputScalar("X Rot", ImGuiDataType_S16, &player->actor.world.rot.x);
|
||||
ImGui::SameLine();
|
||||
ImGui::InputScalar("Y Rot", ImGuiDataType_S16, &player->actor.world.rot.y);
|
||||
ImGui::SameLine();
|
||||
ImGui::InputScalar("Z Rot", ImGuiDataType_S16, &player->actor.world.rot.z);
|
||||
});
|
||||
|
||||
DrawGroupWithBorder([&]() {
|
||||
ImGui::Text("Link's Model Rotation");
|
||||
InsertHelpHoverText("For Link's actual model");
|
||||
ImGui::InputScalar("X ModRot", ImGuiDataType_S16, &player->actor.shape.rot.x);
|
||||
ImGui::SameLine();
|
||||
ImGui::InputScalar("Y ModRot", ImGuiDataType_S16, &player->actor.shape.rot.y);
|
||||
ImGui::SameLine();
|
||||
ImGui::InputScalar("Z ModRot", ImGuiDataType_S16, &player->actor.shape.rot.z);
|
||||
});
|
||||
|
||||
ImGui::InputScalar("Linear Velocity", ImGuiDataType_Float, &player->linearVelocity);
|
||||
InsertHelpHoverText("Link's speed along the XZ plane");
|
||||
|
||||
ImGui::InputScalar("Y Velocity", ImGuiDataType_Float, &player->actor.velocity.y);
|
||||
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\"");
|
||||
|
||||
ImGui::InputScalar("Invincibility Timer", ImGuiDataType_S8, &player->invincibilityTimer);
|
||||
InsertHelpHoverText("Can't take damage while this is nonzero");
|
||||
|
||||
ImGui::InputScalar("Gravity", ImGuiDataType_Float, &player->actor.gravity);
|
||||
InsertHelpHoverText("Rate at which Link falls. Default -4.0f");
|
||||
|
||||
if (ImGui::BeginCombo("Link Age on Load", gGlobalCtx->linkAgeOnLoad == 0 ? "Adult" : "Child")) {
|
||||
if (ImGui::Selectable("Adult")) {
|
||||
gGlobalCtx->linkAgeOnLoad = 0;
|
||||
}
|
||||
if (ImGui::Selectable("Child")) {
|
||||
gGlobalCtx->linkAgeOnLoad = 1;
|
||||
}
|
||||
ImGui::EndCombo();
|
||||
}
|
||||
|
||||
InsertHelpHoverText("This will change Link's age when you load a map");
|
||||
|
||||
ImGui::Separator();
|
||||
|
||||
ImGui::Text("Link's Current Equipment");
|
||||
ImGui::PushItemWidth(ImGui::GetFontSize() * 15);
|
||||
if (ImGui::BeginCombo("Sword", curSword)) {
|
||||
if (ImGui::Selectable("None")) {
|
||||
player->currentSwordItem = ITEM_NONE;
|
||||
gSaveContext.equips.buttonItems[0] = ITEM_NONE;
|
||||
Inventory_ChangeEquipment(EQUIP_SWORD, PLAYER_SWORD_NONE);
|
||||
}
|
||||
if (ImGui::Selectable("Kokiri Sword")) {
|
||||
player->currentSwordItem = ITEM_SWORD_KOKIRI;
|
||||
gSaveContext.equips.buttonItems[0] = ITEM_SWORD_KOKIRI;
|
||||
Inventory_ChangeEquipment(EQUIP_SWORD, PLAYER_SWORD_KOKIRI);
|
||||
}
|
||||
if (ImGui::Selectable("Master Sword")) {
|
||||
player->currentSwordItem = ITEM_SWORD_MASTER;
|
||||
gSaveContext.equips.buttonItems[0] = ITEM_SWORD_MASTER;
|
||||
Inventory_ChangeEquipment(EQUIP_SWORD, PLAYER_SWORD_MASTER);
|
||||
}
|
||||
if (ImGui::Selectable("Biggoron's Sword")) {
|
||||
if (gSaveContext.bgsFlag) {
|
||||
if (gSaveContext.swordHealth < 8) {
|
||||
gSaveContext.swordHealth = 8;
|
||||
}
|
||||
player->currentSwordItem = ITEM_SWORD_BGS;
|
||||
gSaveContext.equips.buttonItems[0] = ITEM_SWORD_BGS;
|
||||
} else {
|
||||
if (gSaveContext.swordHealth < 8) {
|
||||
gSaveContext.swordHealth = 8;
|
||||
}
|
||||
player->currentSwordItem = ITEM_SWORD_BGS;
|
||||
gSaveContext.equips.buttonItems[0] = ITEM_SWORD_KNIFE;
|
||||
}
|
||||
|
||||
Inventory_ChangeEquipment(EQUIP_SWORD, PLAYER_SWORD_BGS);
|
||||
}
|
||||
ImGui::EndCombo();
|
||||
|
||||
}
|
||||
if (ImGui::BeginCombo("Shield", curShield)) {
|
||||
if (ImGui::Selectable("None")) {
|
||||
player->currentShield = PLAYER_SHIELD_NONE;
|
||||
Inventory_ChangeEquipment(EQUIP_SHIELD, PLAYER_SHIELD_NONE);
|
||||
}
|
||||
if (ImGui::Selectable("Deku Shield")) {
|
||||
player->currentShield = PLAYER_SHIELD_DEKU;
|
||||
Inventory_ChangeEquipment(EQUIP_SHIELD, PLAYER_SHIELD_DEKU);
|
||||
}
|
||||
if (ImGui::Selectable("Hylian Shield")) {
|
||||
player->currentShield = PLAYER_SHIELD_HYLIAN;
|
||||
Inventory_ChangeEquipment(EQUIP_SHIELD, PLAYER_SHIELD_HYLIAN);
|
||||
}
|
||||
if (ImGui::Selectable("Mirror Shield")) {
|
||||
player->currentShield = PLAYER_SHIELD_MIRROR;
|
||||
Inventory_ChangeEquipment(EQUIP_SHIELD, PLAYER_SHIELD_MIRROR);
|
||||
}
|
||||
ImGui::EndCombo();
|
||||
}
|
||||
|
||||
if (ImGui::BeginCombo("Tunic", curTunic)) {
|
||||
if (ImGui::Selectable("Kokiri Tunic")) {
|
||||
player->currentTunic = PLAYER_TUNIC_KOKIRI;
|
||||
Inventory_ChangeEquipment(EQUIP_TUNIC, PLAYER_TUNIC_KOKIRI + 1);
|
||||
}
|
||||
if (ImGui::Selectable("Goron Tunic")) {
|
||||
player->currentTunic = PLAYER_TUNIC_GORON;
|
||||
Inventory_ChangeEquipment(EQUIP_TUNIC, PLAYER_TUNIC_GORON + 1);
|
||||
}
|
||||
if (ImGui::Selectable("Zora Tunic")) {
|
||||
player->currentTunic = PLAYER_TUNIC_ZORA;
|
||||
Inventory_ChangeEquipment(EQUIP_TUNIC, PLAYER_TUNIC_ZORA + 1);
|
||||
}
|
||||
ImGui::EndCombo();
|
||||
}
|
||||
|
||||
if (ImGui::BeginCombo("Boots", curBoots)) {
|
||||
if (ImGui::Selectable("Kokiri Boots")) {
|
||||
player->currentBoots = PLAYER_BOOTS_KOKIRI;
|
||||
Inventory_ChangeEquipment(EQUIP_BOOTS, PLAYER_BOOTS_KOKIRI + 1);
|
||||
}
|
||||
if (ImGui::Selectable("Iron Boots")) {
|
||||
player->currentBoots = PLAYER_BOOTS_IRON;
|
||||
Inventory_ChangeEquipment(EQUIP_BOOTS, PLAYER_BOOTS_IRON + 1);
|
||||
}
|
||||
if (ImGui::Selectable("Hover Boots")) {
|
||||
player->currentBoots = PLAYER_BOOTS_HOVER;
|
||||
Inventory_ChangeEquipment(EQUIP_BOOTS, PLAYER_BOOTS_HOVER + 1);
|
||||
}
|
||||
ImGui::EndCombo();
|
||||
}
|
||||
|
||||
ImU16 one = 1;
|
||||
ImGui::PushItemWidth(ImGui::GetFontSize() * 6);
|
||||
DrawGroupWithBorder([&]() {
|
||||
ImGui::Text("Current C Equips");
|
||||
ImGui::InputScalar("C Left", ImGuiDataType_U8, &gSaveContext.equips.buttonItems[1], &one, NULL);
|
||||
ImGui::SameLine();
|
||||
ImGui::InputScalar("C Down", ImGuiDataType_U8, &gSaveContext.equips.buttonItems[2], &one, NULL);
|
||||
ImGui::SameLine();
|
||||
ImGui::InputScalar("C Right", ImGuiDataType_U8, &gSaveContext.equips.buttonItems[3], &one, NULL);
|
||||
});
|
||||
|
||||
} else {
|
||||
ImGui::Text("Global Context needed for player info!");
|
||||
}
|
||||
}
|
||||
|
||||
void DrawSaveEditor(bool& open) {
|
||||
if (!open) {
|
||||
return;
|
||||
}
|
||||
|
||||
ImGui::SetNextWindowSize(ImVec2(520, 600), ImGuiCond_FirstUseEver);
|
||||
if (!ImGui::Begin("Save Editor", &open)) {
|
||||
if (!ImGui::Begin("Save Editor", &open, ImGuiWindowFlags_NoFocusOnAppearing)) {
|
||||
ImGui::End();
|
||||
return;
|
||||
}
|
||||
|
@ -1094,6 +1571,11 @@ void DrawSaveEditor(bool& open) {
|
|||
ImGui::EndTabItem();
|
||||
}
|
||||
|
||||
if (ImGui::BeginTabItem("Player")) {
|
||||
DrawPlayerTab();
|
||||
ImGui::EndTabItem();
|
||||
}
|
||||
|
||||
ImGui::EndTabBar();
|
||||
}
|
||||
|
||||
|
|
957
soh/soh/Enhancements/savestates.cpp
Normal file
957
soh/soh/Enhancements/savestates.cpp
Normal file
|
@ -0,0 +1,957 @@
|
|||
#include "savestates.h"
|
||||
|
||||
#include "GameVersions.h"
|
||||
|
||||
#include <cstdio> // std::sprintf
|
||||
|
||||
#include "spdlog/spdlog.h"
|
||||
|
||||
#include <soh/OTRGlobals.h>
|
||||
#include <soh/OTRAudio.h>
|
||||
|
||||
#include <SohImGuiImpl.h>
|
||||
|
||||
#include "z64.h"
|
||||
#include "z64save.h"
|
||||
#include <variables.h>
|
||||
#include <functions.h>
|
||||
#include "z64map_mark.h"
|
||||
#include "../../src/overlays/actors/ovl_Boss_Ganon/z_boss_ganon.h"
|
||||
#include "../../src/overlays/actors/ovl_Boss_Ganon2/z_boss_ganon2.h"
|
||||
#include "../../src/overlays/actors/ovl_Boss_Tw/z_boss_tw.h"
|
||||
#include "../../src/overlays/actors/ovl_En_Clear_Tag/z_en_clear_tag.h"
|
||||
#include "../../src/overlays/actors/ovl_En_Fr/z_en_fr.h"
|
||||
|
||||
extern "C" GlobalContext* gGlobalCtx;
|
||||
|
||||
// FROM z_lights.c
|
||||
// I didn't feel like moving it into a header file.
|
||||
#define LIGHTS_BUFFER_SIZE 32
|
||||
|
||||
typedef struct {
|
||||
/* 0x000 */ s32 numOccupied;
|
||||
/* 0x004 */ s32 searchIndex;
|
||||
/* 0x008 */ LightNode buf[LIGHTS_BUFFER_SIZE];
|
||||
} LightsBuffer; // size = 0x188
|
||||
|
||||
#include "savestates_extern.inc"
|
||||
|
||||
typedef struct SaveStateInfo {
|
||||
unsigned char sysHeapCopy[SYSTEM_HEAP_SIZE];
|
||||
unsigned char audioHeapCopy[AUDIO_HEAP_SIZE];
|
||||
|
||||
SaveContext saveContextCopy;
|
||||
GameInfo gameInfoCopy;
|
||||
LightsBuffer lightBufferCopy;
|
||||
AudioContext audioContextCopy;
|
||||
MtxF mtxStackCopy[20]; // always 20 matricies
|
||||
MtxF currentMtxCopy;
|
||||
uint32_t rngSeed;
|
||||
int16_t blueWarpTimerCopy; /* From door_warp_1 */
|
||||
|
||||
SeqScriptState seqScriptStateCopy[4];// Unrelocated
|
||||
unk_D_8016E750 unk_D_8016E750Copy[4];
|
||||
|
||||
ActiveSound gActiveSoundsCopy[7][MAX_CHANNELS_PER_BANK];
|
||||
uint8_t gSoundBankMutedCopy[7];
|
||||
|
||||
u8 D_801333F0_copy;
|
||||
u8 gAudioSfxSwapOff_copy;
|
||||
uint16_t gAudioSfxSwapSource_copy[10];
|
||||
uint16_t gAudioSfxSwapTarget_copy[10];
|
||||
uint8_t gAudioSfxSwapMode_copy[10];
|
||||
void (*D_801755D0_copy)(void);
|
||||
MapMarkData** sLoadedMarkDataTableCopy;
|
||||
|
||||
//Static Data
|
||||
|
||||
//Camera data
|
||||
int32_t sInitRegs_copy;
|
||||
int32_t gDbgCamEnabled_copy;
|
||||
int32_t sDbgModeIdx_copy;
|
||||
int16_t sNextUID_copy;
|
||||
int32_t sCameraInterfaceFlags_copy;
|
||||
int32_t sCameraInterfaceAlpha_copy;
|
||||
int32_t sCameraShrinkWindowVal_copy;
|
||||
int32_t D_8011D3AC_copy;
|
||||
int32_t sDemo5PrevAction12Frame_copy;
|
||||
int32_t sDemo5PrevSfxFrame_copy;
|
||||
int32_t D_8011D3F0_copy;
|
||||
OnePointCsFull D_8011D6AC_copy[3];
|
||||
OnePointCsFull D_8011D724_copy[3];
|
||||
OnePointCsFull D_8011D79C_copy[3];
|
||||
OnePointCsFull D_8011D83C_copy[2];
|
||||
OnePointCsFull D_8011D88C_copy[2];
|
||||
OnePointCsFull D_8011D8DC_copy[3];
|
||||
OnePointCsFull D_8011D954_copy[4];
|
||||
OnePointCsFull D_8011D9F4_copy[3];
|
||||
int16_t D_8011DB08_copy;
|
||||
int16_t D_8011DB0C_copy;
|
||||
int32_t sOOBTimer_copy;
|
||||
f32 D_8015CE50_copy;
|
||||
f32 D_8015CE54_copy;
|
||||
CamColChk D_8015CE58_copy;
|
||||
|
||||
//Gameover
|
||||
uint16_t gGameOverTimer_copy;
|
||||
|
||||
//One point demo
|
||||
uint32_t sPrevFrameCs1100_copy;
|
||||
CutsceneCameraPoint D_8012013C_copy[14];
|
||||
CutsceneCameraPoint D_8012021C_copy[14];
|
||||
CutsceneCameraPoint D_801204D4_copy[14];
|
||||
CutsceneCameraPoint D_801205B4_copy[14];
|
||||
OnePointCsFull D_801208EC_copy[3];
|
||||
OnePointCsFull D_80120964_copy[2];
|
||||
OnePointCsFull D_801209B4_copy[4];
|
||||
OnePointCsFull D_80120ACC_copy[5];
|
||||
OnePointCsFull D_80120B94_copy[11];
|
||||
OnePointCsFull D_80120D4C_copy[7];
|
||||
OnePointCsFull D_80120FA4_copy[6];
|
||||
OnePointCsFull D_80121184_copy[2];
|
||||
OnePointCsFull D_801211D4_copy[2];
|
||||
OnePointCsFull D_8012133C_copy[3];
|
||||
OnePointCsFull D_801213B4_copy[5];
|
||||
OnePointCsFull D_8012151C_copy[2];
|
||||
OnePointCsFull D_8012156C_copy[2];
|
||||
OnePointCsFull D_801215BC_copy[1];
|
||||
OnePointCsFull D_80121C24_copy[7];
|
||||
OnePointCsFull D_80121D3C_copy[3];
|
||||
OnePointCsFull D_80121F1C_copy[4];
|
||||
OnePointCsFull D_80121FBC_copy[4];
|
||||
OnePointCsFull D_801220D4_copy[5];
|
||||
OnePointCsFull D_80122714_copy[4];
|
||||
OnePointCsFull D_80122CB4_copy[2];
|
||||
OnePointCsFull D_80122D04_copy[2];
|
||||
OnePointCsFull D_80122E44_copy[2][7];
|
||||
OnePointCsFull D_8012313C_copy[3];
|
||||
OnePointCsFull D_801231B4_copy[4];
|
||||
OnePointCsFull D_80123254_copy[2];
|
||||
OnePointCsFull D_801232A4_copy[1];
|
||||
OnePointCsFull D_80123894_copy[3];
|
||||
OnePointCsFull D_8012390C_copy[2];
|
||||
OnePointCsFull D_8012395C_copy[3];
|
||||
OnePointCsFull D_801239D4_copy[3];
|
||||
|
||||
uint16_t gTimeIncrement_copy;
|
||||
|
||||
//Overlay static data
|
||||
// z_bg_ddan_kd
|
||||
Vec3f sBgDdanKdVelocity_copy;
|
||||
Vec3f sBgDdanKdAccel_copy;
|
||||
|
||||
// z_bg_dodoago
|
||||
s16 sBgDodoagoFirstExplosiveFlag_copy;
|
||||
u8 sBgDodoagoDisableBombCatcher_copy;
|
||||
s32 sBgDodoagoTimer_copy;
|
||||
|
||||
// z_bg_haka_trap
|
||||
uint32_t D_80880F30_copy;
|
||||
uint32_t D_80881014_copy;
|
||||
|
||||
// z_bg_hidan_rock
|
||||
float D_8088BFC0_copy;
|
||||
|
||||
// z_bg_menkuri_eye
|
||||
int32_t D_8089C1A0_copy;
|
||||
|
||||
// z_bg_mori_hineri
|
||||
int16_t sBgMoriHineriNextCamIdx_copy;
|
||||
|
||||
// z_bg_po_event
|
||||
uint8_t sBgPoEventBlocksAtRest_copy;
|
||||
uint8_t sBgPoEventPuzzleState_copy;
|
||||
float sBgPoEventblockPushDist_copy;
|
||||
|
||||
// z_bg_relay_objects
|
||||
uint32_t D_808A9508_copy;
|
||||
|
||||
// z_bg_spot18_basket
|
||||
int16_t D_808B85D0_copy;
|
||||
|
||||
// z_boss_ganon
|
||||
uint32_t sBossGanonSeed1_copy;
|
||||
uint32_t sBossGanonSeed2_copy;
|
||||
uint32_t sBossGanonSeed3_copy;
|
||||
void* sBossGanonGanondorf_copy;
|
||||
void* sBossGanonZelda_copy;
|
||||
void* sBossGanonCape_copy;
|
||||
GanondorfEffect sBossGanonEffectBuf_copy[200];
|
||||
|
||||
// z_boss_ganon
|
||||
uint32_t sBossGanonSeed1;
|
||||
uint32_t sBossGanonSeed2;
|
||||
uint32_t sBossGanonSeed3;
|
||||
void* sBossGanonGanondorf;
|
||||
void* sBossGanonZelda;
|
||||
void* sBossGanonCape;
|
||||
GanondorfEffect sBossGanonEffectBuf[200];
|
||||
|
||||
// z_boss_ganon2
|
||||
Vec3f D_8090EB20_copy;
|
||||
int8_t D_80910638_copy;
|
||||
void* sBossGanon2Zelda_copy;
|
||||
void* D_8090EB30_copy;
|
||||
int32_t sBossGanon2Seed1_copy;
|
||||
int32_t sBossGanon2Seed2_copy;
|
||||
int32_t sBossGanon2Seed3_copy;
|
||||
Vec3f D_809105D8_copy[4];
|
||||
Vec3f D_80910608_copy[4];
|
||||
BossGanon2Effect sBossGanon2Particles_copy[100];
|
||||
|
||||
// z_boss_tw
|
||||
uint8_t sTwInitalized_copy;
|
||||
BossTwEffect sTwEffects_copy[150];
|
||||
|
||||
// z_demo_6k
|
||||
Vec3f sDemo6kVelocity_copy;
|
||||
|
||||
// z_demo_du
|
||||
int32_t D_8096CE94_copy;
|
||||
|
||||
// z_demo_kekkai
|
||||
Vec3f demoKekkaiVel_copy;
|
||||
|
||||
// z_en_bw
|
||||
int32_t sSlugGroup_copy;
|
||||
|
||||
// z_en_clear_tag
|
||||
uint8_t sClearTagIsEffectInitialized_copy;
|
||||
EnClearTagEffect sClearTagEffects_copy[CLEAR_TAG_EFFECT_MAX_COUNT];
|
||||
|
||||
// z_en_fr
|
||||
EnFrPointers sEnFrPointers_copy;
|
||||
|
||||
// z_en_goma
|
||||
uint8_t sSpawnNum_copy;
|
||||
|
||||
// z_en_insect
|
||||
float D_80A7DEB0_copy;
|
||||
int16_t D_80A7DEB4_copy;
|
||||
int16_t D_80A7DEB8_copy;
|
||||
|
||||
// z_en_ishi
|
||||
int16_t sRockRotSpeedX_copy;
|
||||
int16_t sRockRotSpeedY_copy;
|
||||
|
||||
// z_en_niw
|
||||
int16_t D_80AB85E0_copy;
|
||||
uint8_t sLowerRiverSpawned_copy;
|
||||
uint8_t sUpperRiverSpawned_copy;
|
||||
|
||||
// z_en_po_field
|
||||
int32_t sEnPoFieldNumSpawned_copy;
|
||||
Vec3s sEnPoFieldSpawnPositions_copy[10];
|
||||
u8 sEnPoFieldSpawnSwitchFlags_copy[10];
|
||||
|
||||
// z_en_takara_man
|
||||
uint8_t sTakaraIsInitialized_copy;
|
||||
|
||||
// z_en_xc
|
||||
int32_t D_80B41D90_copy;
|
||||
int32_t sEnXcFlameSpawned_copy;
|
||||
int32_t D_80B41DA8_copy;
|
||||
int32_t D_80B41DAC_copy;
|
||||
|
||||
// z_en_zf
|
||||
int16_t D_80B4A1B0_copy;
|
||||
int16_t D_80B4A1B4_copy;
|
||||
|
||||
int32_t D_80B5A468_copy;
|
||||
int32_t D_80B5A494_copy;
|
||||
int32_t D_80B5A4BC_copy;
|
||||
|
||||
uint8_t sKankyoIsSpawned_copy;
|
||||
int16_t sTrailingFairies_copy;
|
||||
|
||||
|
||||
//Misc static data
|
||||
// z_map_exp
|
||||
|
||||
s16 sPlayerInitialPosX_copy;
|
||||
s16 sPlayerInitialPosZ_copy;
|
||||
s16 sPlayerInitialDirection_copy;
|
||||
|
||||
// code_800E(something. fill me in later)
|
||||
u8 sOcarinaInpEnabled_copy;
|
||||
s8 D_80130F10_copy;
|
||||
u8 sCurOcarinaBtnVal_copy;
|
||||
u8 sPrevOcarinaNoteVal_copy;
|
||||
u8 sCurOcarinaBtnIdx_copy;
|
||||
u8 sLearnSongLastBtn_copy;
|
||||
f32 D_80130F24_copy;
|
||||
f32 D_80130F28_copy;
|
||||
s8 D_80130F2C_copy;
|
||||
s8 D_80130F30_copy;
|
||||
s8 D_80130F34_copy;
|
||||
u8 sDisplayedNoteValue_copy;
|
||||
u8 sPlaybackState_copy;
|
||||
u32 D_80130F3C_copy;
|
||||
u32 sNotePlaybackTimer_copy;
|
||||
u16 sPlaybackNotePos_copy;
|
||||
u16 sStaffPlaybackPos_copy;
|
||||
|
||||
u32 sCurOcarinaBtnPress_copy;
|
||||
u32 D_8016BA10_copy;
|
||||
u32 sPrevOcarinaBtnPress_copy;
|
||||
s32 D_8016BA18_copy;
|
||||
s32 D_8016BA1C_copy;
|
||||
u8 sCurOcarinaSong_copy[8];
|
||||
u8 sOcarinaSongAppendPos_copy;
|
||||
u8 sOcarinaHasStartedSong_copy;
|
||||
u8 sOcarinaSongNoteStartIdx_copy;
|
||||
u8 sOcarinaSongCnt_copy;
|
||||
u16 sOcarinaAvailSongs_copy;
|
||||
u8 sStaffPlayingPos_copy;
|
||||
u16 sLearnSongPos_copy[0x10];
|
||||
u16 D_8016BA50_copy[0x10];
|
||||
u16 D_8016BA70_copy[0x10];
|
||||
u8 sLearnSongExpectedNote_copy[0x10];
|
||||
OcarinaNote D_8016BAA0_copy;
|
||||
u8 sAudioHasMalonBgm_copy;
|
||||
f32 sAudioMalonBgmDist_copy;
|
||||
|
||||
// Message_PAL
|
||||
s16 sOcarinaNoteBufPos_copy;
|
||||
s16 sOcarinaNoteBufLen_copy;
|
||||
u8 sOcarinaNoteBuf_copy[12];
|
||||
|
||||
u8 D_8014B2F4_copy;
|
||||
u8 sTextboxSkipped_copy;
|
||||
u16 sNextTextId_copy;
|
||||
s16 sLastPlayedSong_copy;
|
||||
s16 sHasSunsSong_copy;
|
||||
s16 sMessageHasSetSfx_copy;
|
||||
u16 sOcarinaSongBitFlags_copy;
|
||||
|
||||
|
||||
} SaveStateInfo;
|
||||
|
||||
class SaveState {
|
||||
friend class SaveStateMgr;
|
||||
|
||||
public:
|
||||
SaveState(std::shared_ptr<SaveStateMgr> mgr, unsigned int slot);
|
||||
|
||||
private:
|
||||
unsigned int slot;
|
||||
std::shared_ptr<SaveStateMgr> saveStateMgr;
|
||||
std::shared_ptr<SaveStateInfo> info;
|
||||
|
||||
void Save(void);
|
||||
void Load(void);
|
||||
void BackupSeqScriptState(void);
|
||||
void LoadSeqScriptState(void);
|
||||
void BackupCameraData(void);
|
||||
void LoadCameraData(void);
|
||||
void SaveOnePointDemoData(void);
|
||||
void LoadOnePointDemoData(void);
|
||||
void SaveOverlayStaticData(void);
|
||||
void LoadOverlayStaticData(void);
|
||||
|
||||
void SaveMiscCodeData(void);
|
||||
void LoadMiscCodeData(void);
|
||||
|
||||
SaveStateInfo* GetSaveStateInfo(void);
|
||||
};
|
||||
|
||||
SaveStateMgr::SaveStateMgr() {
|
||||
this->SetCurrentSlot(0);
|
||||
}
|
||||
SaveStateMgr::~SaveStateMgr() {
|
||||
this->states.clear();
|
||||
}
|
||||
|
||||
SaveState::SaveState(std::shared_ptr<SaveStateMgr> mgr, unsigned int slot) : saveStateMgr(mgr), slot(slot), info(nullptr) {
|
||||
this->info = std::make_shared<SaveStateInfo>();
|
||||
}
|
||||
|
||||
void SaveState::BackupSeqScriptState(void) {
|
||||
for (unsigned int i = 0; i < 4; i++) {
|
||||
info->seqScriptStateCopy[i].value = gAudioContext.seqPlayers[i].scriptState.value;
|
||||
|
||||
info->seqScriptStateCopy[i].remLoopIters[0] = gAudioContext.seqPlayers[i].scriptState.remLoopIters[0];
|
||||
info->seqScriptStateCopy[i].remLoopIters[1] = gAudioContext.seqPlayers[i].scriptState.remLoopIters[1];
|
||||
info->seqScriptStateCopy[i].remLoopIters[2] = gAudioContext.seqPlayers[i].scriptState.remLoopIters[2];
|
||||
info->seqScriptStateCopy[i].remLoopIters[3] = gAudioContext.seqPlayers[i].scriptState.remLoopIters[3];
|
||||
|
||||
info->seqScriptStateCopy[i].depth = gAudioContext.seqPlayers[i].scriptState.depth;
|
||||
|
||||
info->seqScriptStateCopy[i].pc = (u8*)((uintptr_t)gAudioContext.seqPlayers[i].scriptState.pc - (uintptr_t)gAudioHeap);
|
||||
|
||||
info->seqScriptStateCopy[i].stack[0] =
|
||||
(u8*)((uintptr_t)gAudioContext.seqPlayers[i].scriptState.stack[0] - (uintptr_t)gAudioHeap);
|
||||
info->seqScriptStateCopy[i].stack[1] =
|
||||
(u8*)((uintptr_t)gAudioContext.seqPlayers[i].scriptState.stack[1] - (uintptr_t)gAudioHeap);
|
||||
info->seqScriptStateCopy[i].stack[2] =
|
||||
(u8*)((uintptr_t)gAudioContext.seqPlayers[i].scriptState.stack[2] - (uintptr_t)gAudioHeap);
|
||||
info->seqScriptStateCopy[i].stack[3] =
|
||||
(u8*)((uintptr_t)gAudioContext.seqPlayers[i].scriptState.stack[3] - (uintptr_t)gAudioHeap);
|
||||
}
|
||||
}
|
||||
|
||||
void SaveState::LoadSeqScriptState(void) {
|
||||
for (unsigned int i = 0; i < 4; i++) {
|
||||
gAudioContext.seqPlayers[i].scriptState.value = info->seqScriptStateCopy[i].value;
|
||||
|
||||
gAudioContext.seqPlayers[i].scriptState.remLoopIters[0] = info->seqScriptStateCopy[i].remLoopIters[0];
|
||||
gAudioContext.seqPlayers[i].scriptState.remLoopIters[1] = info->seqScriptStateCopy[i].remLoopIters[1];
|
||||
gAudioContext.seqPlayers[i].scriptState.remLoopIters[2] = info->seqScriptStateCopy[i].remLoopIters[2];
|
||||
gAudioContext.seqPlayers[i].scriptState.remLoopIters[3] = info->seqScriptStateCopy[i].remLoopIters[3];
|
||||
|
||||
gAudioContext.seqPlayers[i].scriptState.depth = info->seqScriptStateCopy[i].depth;
|
||||
|
||||
gAudioContext.seqPlayers[i].scriptState.pc =
|
||||
(u8*)((uintptr_t)info->seqScriptStateCopy[i].pc + (uintptr_t)gAudioHeap);
|
||||
|
||||
gAudioContext.seqPlayers[i].scriptState.stack[0] =
|
||||
(u8*)((uintptr_t)info->seqScriptStateCopy[i].stack[0] + (uintptr_t)gAudioHeap);
|
||||
gAudioContext.seqPlayers[i].scriptState.stack[1] =
|
||||
(u8*)((uintptr_t)info->seqScriptStateCopy[i].stack[1] + (uintptr_t)gAudioHeap);
|
||||
gAudioContext.seqPlayers[i].scriptState.stack[2] =
|
||||
(u8*)((uintptr_t)info->seqScriptStateCopy[i].stack[2] + (uintptr_t)gAudioHeap);
|
||||
gAudioContext.seqPlayers[i].scriptState.stack[3] =
|
||||
(u8*)((uintptr_t)info->seqScriptStateCopy[i].stack[3] + (uintptr_t)gAudioHeap);
|
||||
}
|
||||
}
|
||||
|
||||
void SaveState::BackupCameraData(void) {
|
||||
info->sInitRegs_copy = sInitRegs;
|
||||
info->gDbgCamEnabled_copy = gDbgCamEnabled;
|
||||
info->sNextUID_copy = sNextUID;
|
||||
info->sCameraInterfaceFlags_copy = sCameraInterfaceFlags;
|
||||
info->sCameraInterfaceAlpha_copy = sCameraInterfaceAlpha;
|
||||
info->sCameraShrinkWindowVal_copy = sCameraShrinkWindowVal;
|
||||
info->D_8011D3AC_copy = D_8011D3AC;
|
||||
info->sDemo5PrevAction12Frame_copy = sDemo5PrevAction12Frame;
|
||||
info->sDemo5PrevSfxFrame_copy = sDemo5PrevSfxFrame;
|
||||
info->D_8011D3F0_copy = D_8011D3F0;
|
||||
memcpy(info->D_8011D6AC_copy, D_8011D6AC, sizeof(info->D_8011D6AC_copy));
|
||||
memcpy(info->D_8011D724_copy, D_8011D724, sizeof(info->D_8011D724_copy));
|
||||
memcpy(info->D_8011D79C_copy, D_8011D79C, sizeof(info->D_8011D79C_copy));
|
||||
memcpy(info->D_8011D83C_copy, D_8011D83C, sizeof(info->D_8011D83C_copy));
|
||||
memcpy(info->D_8011D88C_copy, D_8011D88C, sizeof(info->D_8011D88C_copy));
|
||||
memcpy(info->D_8011D8DC_copy, D_8011D8DC, sizeof(info->D_8011D8DC_copy));
|
||||
memcpy(info->D_8011D954_copy, D_8011D954, sizeof(info->D_8011D954_copy));
|
||||
memcpy(info->D_8011D9F4_copy, D_8011D9F4, sizeof(info->D_8011D9F4_copy));
|
||||
info->D_8011DB08_copy = D_8011DB08;
|
||||
info->D_8011DB0C_copy = D_8011DB0C;
|
||||
info->sOOBTimer_copy = sOOBTimer;
|
||||
info->D_8015CE50_copy = D_8015CE50;
|
||||
info->D_8015CE54_copy = D_8015CE54;
|
||||
memcpy(&info->D_8015CE58_copy, &D_8015CE58, sizeof(info->D_8015CE58_copy));
|
||||
}
|
||||
|
||||
void SaveState::LoadCameraData(void) {
|
||||
sInitRegs = info->sInitRegs_copy;
|
||||
gDbgCamEnabled = info->gDbgCamEnabled_copy;
|
||||
sDbgModeIdx = info->sDbgModeIdx_copy;
|
||||
sNextUID = info->sNextUID_copy;
|
||||
sCameraInterfaceAlpha = info->sCameraInterfaceAlpha_copy;
|
||||
sCameraInterfaceFlags = info->sCameraInterfaceFlags_copy;
|
||||
sCameraShrinkWindowVal = info->sCameraShrinkWindowVal_copy;
|
||||
D_8011D3AC = info->D_8011D3AC_copy;
|
||||
sDemo5PrevAction12Frame = info->sDemo5PrevAction12Frame_copy;
|
||||
sDemo5PrevSfxFrame = info->sDemo5PrevSfxFrame_copy;
|
||||
D_8011D3F0 = info->D_8011D3F0_copy;
|
||||
memcpy(D_8011D6AC, info->D_8011D6AC_copy, sizeof(info->D_8011D6AC_copy));
|
||||
memcpy(D_8011D724, info->D_8011D724_copy, sizeof(info->D_8011D724_copy));
|
||||
memcpy(D_8011D79C, info->D_8011D79C_copy, sizeof(info->D_8011D79C_copy));
|
||||
memcpy(D_8011D83C, info->D_8011D83C_copy, sizeof(info->D_8011D83C_copy));
|
||||
memcpy(D_8011D88C, info->D_8011D88C_copy, sizeof(info->D_8011D88C_copy));
|
||||
memcpy(D_8011D8DC, info->D_8011D8DC_copy, sizeof(info->D_8011D8DC_copy));
|
||||
memcpy(D_8011D954, info->D_8011D954_copy, sizeof(info->D_8011D954_copy));
|
||||
memcpy(D_8011D9F4, info->D_8011D9F4_copy, sizeof(info->D_8011D9F4_copy));
|
||||
D_8011DB08 = info->D_8011DB08_copy;
|
||||
D_8011DB0C = info->D_8011DB0C_copy;
|
||||
sOOBTimer = info->sOOBTimer_copy;
|
||||
D_8015CE50 = info->D_8015CE50_copy;
|
||||
D_8015CE54 = info->D_8015CE54_copy;
|
||||
memcpy(&D_8015CE58, &info->D_8015CE58_copy, sizeof(info->D_8015CE58_copy));
|
||||
}
|
||||
|
||||
void SaveState::SaveOnePointDemoData(void) {
|
||||
info->sPrevFrameCs1100_copy = sPrevFrameCs1100;
|
||||
memcpy(info->D_8012013C_copy, D_8012013C, sizeof(info->D_8012013C_copy));
|
||||
memcpy(info->D_8012021C_copy, D_8012021C, sizeof(info->D_8012021C_copy));
|
||||
memcpy(info->D_801204D4_copy, D_801204D4, sizeof(info->D_801204D4_copy));
|
||||
memcpy(info->D_801205B4_copy, D_801205B4, sizeof(info->D_801205B4_copy));
|
||||
memcpy(info->D_801208EC_copy, D_801208EC, sizeof(info->D_801208EC_copy));
|
||||
memcpy(info->D_80120964_copy, D_80120964, sizeof(info->D_80120964_copy));
|
||||
memcpy(info->D_801209B4_copy, D_801209B4, sizeof(info->D_801209B4_copy));
|
||||
memcpy(info->D_80120ACC_copy, D_80120ACC, sizeof(info->D_80120ACC_copy));
|
||||
memcpy(info->D_80120B94_copy, D_80120B94, sizeof(info->D_80120B94_copy));
|
||||
memcpy(info->D_80120D4C_copy, D_80120D4C, sizeof(info->D_80120D4C_copy));
|
||||
memcpy(info->D_80120FA4_copy, D_80120FA4, sizeof(info->D_80120FA4_copy));
|
||||
memcpy(info->D_80121184_copy, D_80121184, sizeof(info->D_80121184_copy));
|
||||
memcpy(info->D_801211D4_copy, D_801211D4, sizeof(info->D_801211D4_copy));
|
||||
memcpy(info->D_8012133C_copy, D_8012133C, sizeof(info->D_8012133C_copy));
|
||||
memcpy(info->D_801213B4_copy, D_801213B4, sizeof(info->D_801213B4_copy));
|
||||
memcpy(info->D_8012151C_copy, D_8012151C, sizeof(info->D_8012151C_copy));
|
||||
memcpy(info->D_8012156C_copy, D_8012156C, sizeof(info->D_8012156C_copy));
|
||||
memcpy(info->D_801215BC_copy, D_801215BC, sizeof(info->D_801215BC_copy));
|
||||
memcpy(info->D_80121C24_copy, D_80121C24, sizeof(info->D_80121C24_copy));
|
||||
memcpy(info->D_80121D3C_copy, D_80121D3C, sizeof(info->D_80121D3C_copy));
|
||||
memcpy(info->D_80121F1C_copy, D_80121F1C, sizeof(info->D_80121F1C_copy));
|
||||
memcpy(info->D_80121FBC_copy, D_80121FBC, sizeof(info->D_80121FBC_copy));
|
||||
memcpy(info->D_801220D4_copy, D_801220D4, sizeof(info->D_801220D4_copy));
|
||||
memcpy(info->D_80122714_copy, D_80122714, sizeof(info->D_80122714_copy));
|
||||
memcpy(info->D_80122CB4_copy, D_80122CB4, sizeof(info->D_80122CB4_copy));
|
||||
memcpy(info->D_80122D04_copy, D_80122D04, sizeof(info->D_80122D04_copy));
|
||||
memcpy(info->D_80122E44_copy, D_80122E44, sizeof(info->D_80122E44_copy));
|
||||
memcpy(info->D_8012313C_copy, D_8012313C, sizeof(info->D_8012313C_copy));
|
||||
memcpy(info->D_801231B4_copy, D_801231B4, sizeof(info->D_801231B4_copy));
|
||||
memcpy(info->D_80123254_copy, D_80123254, sizeof(info->D_80123254_copy));
|
||||
memcpy(info->D_801232A4_copy, D_801232A4, sizeof(info->D_801232A4_copy));
|
||||
memcpy(info->D_80123894_copy, D_80123894, sizeof(info->D_80123894_copy));
|
||||
memcpy(info->D_8012390C_copy, D_8012390C, sizeof(info->D_8012390C_copy));
|
||||
memcpy(info->D_8012395C_copy, D_8012395C, sizeof(info->D_8012395C_copy));
|
||||
memcpy(info->D_801239D4_copy, D_801239D4, sizeof(info->D_801239D4_copy));
|
||||
}
|
||||
|
||||
void SaveState::LoadOnePointDemoData(void) {
|
||||
sPrevFrameCs1100 = info->sPrevFrameCs1100_copy;
|
||||
memcpy(D_8012013C, info->D_8012013C_copy, sizeof(info->D_8012013C_copy));
|
||||
memcpy(D_8012021C, info->D_8012021C_copy, sizeof(info->D_8012021C_copy));
|
||||
memcpy(D_801204D4, info->D_801204D4_copy, sizeof(info->D_801204D4_copy));
|
||||
memcpy(D_801205B4, info->D_801205B4_copy, sizeof(info->D_801205B4_copy));
|
||||
memcpy(D_801208EC, info->D_801208EC_copy, sizeof(info->D_801208EC_copy));
|
||||
memcpy(D_80120964, info->D_80120964_copy, sizeof(info->D_80120964_copy));
|
||||
memcpy(D_801209B4, info->D_801209B4_copy, sizeof(info->D_801209B4_copy));
|
||||
memcpy(D_80120ACC, info->D_80120ACC_copy, sizeof(info->D_80120ACC_copy));
|
||||
memcpy(D_80120B94, info->D_80120B94_copy, sizeof(info->D_80120B94_copy));
|
||||
memcpy(D_80120D4C, info->D_80120D4C_copy, sizeof(info->D_80120D4C_copy));
|
||||
memcpy(D_80120FA4, info->D_80120FA4_copy, sizeof(info->D_80120FA4_copy));
|
||||
memcpy(D_80121184, info->D_80121184_copy, sizeof(info->D_80121184_copy));
|
||||
memcpy(D_801211D4, info->D_801211D4_copy, sizeof(info->D_801211D4_copy));
|
||||
memcpy(D_8012133C, info->D_8012133C_copy, sizeof(info->D_8012133C_copy));
|
||||
memcpy(D_801213B4, info->D_801213B4_copy, sizeof(info->D_801213B4_copy));
|
||||
memcpy(D_8012151C, info->D_8012151C_copy, sizeof(info->D_8012151C_copy));
|
||||
memcpy(D_8012156C, info->D_8012156C_copy, sizeof(info->D_8012156C_copy));
|
||||
memcpy(D_801215BC, info->D_801215BC_copy, sizeof(info->D_801215BC_copy));
|
||||
memcpy(D_80121C24, info->D_80121C24_copy, sizeof(info->D_80121C24_copy));
|
||||
memcpy(D_80121D3C, info->D_80121D3C_copy, sizeof(info->D_80121D3C_copy));
|
||||
memcpy(D_80121F1C, info->D_80121F1C_copy, sizeof(info->D_80121F1C_copy));
|
||||
memcpy(D_80121FBC, info->D_80121FBC_copy, sizeof(info->D_80121FBC_copy));
|
||||
memcpy(D_801220D4, info->D_801220D4_copy, sizeof(info->D_801220D4_copy));
|
||||
memcpy(D_80122714, info->D_80122714_copy, sizeof(info->D_80122714_copy));
|
||||
memcpy(D_80122CB4, info->D_80122CB4_copy, sizeof(info->D_80122CB4_copy));
|
||||
memcpy(D_80122D04, info->D_80122D04_copy, sizeof(info->D_80122D04_copy));
|
||||
memcpy(D_80122E44, info->D_80122E44_copy, sizeof(info->D_80122E44_copy));
|
||||
memcpy(D_8012313C, info->D_8012313C_copy, sizeof(info->D_8012313C_copy));
|
||||
memcpy(D_801231B4, info->D_801231B4_copy, sizeof(info->D_801231B4_copy));
|
||||
memcpy(D_80123254, info->D_80123254_copy, sizeof(info->D_80123254_copy));
|
||||
memcpy(D_801232A4, info->D_801232A4_copy, sizeof(info->D_801232A4_copy));
|
||||
memcpy(D_80123894, info->D_80123894_copy, sizeof(info->D_80123894_copy));
|
||||
memcpy(D_8012390C, info->D_8012390C_copy, sizeof(info->D_8012390C_copy));
|
||||
memcpy(D_8012395C, info->D_8012395C_copy, sizeof(info->D_8012395C_copy));
|
||||
memcpy(D_801239D4, info->D_801239D4_copy, sizeof(info->D_801239D4_copy));
|
||||
}
|
||||
|
||||
void SaveState::SaveOverlayStaticData(void) {
|
||||
info->sBgDdanKdVelocity_copy = sBgDdanKdVelocity;
|
||||
info->sBgDdanKdAccel_copy = sBgDdanKdAccel;
|
||||
info->sBgDodoagoFirstExplosiveFlag_copy = sBgDodoagoFirstExplosiveFlag;
|
||||
info->sBgDodoagoDisableBombCatcher_copy = sBgDodoagoDisableBombCatcher;
|
||||
info->sBgDodoagoTimer_copy = sBgDodoagoTimer;
|
||||
info->D_80880F30_copy = D_80880F30;
|
||||
info->D_80881014_copy = D_80881014;
|
||||
info->D_8088BFC0_copy = D_8088BFC0;
|
||||
info->sBgMoriHineriNextCamIdx_copy = sBgMoriHineriNextCamIdx;
|
||||
info->sBgPoEventBlocksAtRest_copy = sBgPoEventBlocksAtRest;
|
||||
info->sBgPoEventPuzzleState_copy = sBgPoEventPuzzleState;
|
||||
info->sBgPoEventblockPushDist_copy = sBgPoEventblockPushDist;
|
||||
info->D_808A9508_copy = D_808A9508;
|
||||
info->D_808B85D0_copy = D_808B85D0;
|
||||
info->sBossGanonSeed1_copy = sBossGanonSeed1;
|
||||
info->sBossGanonSeed2_copy = sBossGanonSeed2;
|
||||
info->sBossGanonSeed3_copy = sBossGanonSeed3;
|
||||
info->sBossGanonGanondorf_copy = sBossGanonGanondorf;
|
||||
info->sBossGanonZelda_copy = sBossGanonZelda;
|
||||
info->sBossGanonCape_copy = sBossGanonCape;
|
||||
memcpy(info->sBossGanonEffectBuf_copy, sBossGanonEffectBuf, sizeof(info->sBossGanonEffectBuf_copy));
|
||||
info->D_8090EB20_copy = D_8090EB20;
|
||||
info->D_80910638_copy = D_80910638;
|
||||
info->sBossGanon2Zelda_copy = sBossGanon2Zelda;
|
||||
info->D_8090EB30_copy = D_8090EB30;
|
||||
info->sBossGanon2Seed1_copy = sBossGanon2Seed1;
|
||||
info->sBossGanon2Seed2_copy = sBossGanon2Seed2;
|
||||
info->sBossGanon2Seed3_copy = sBossGanon2Seed3;
|
||||
memcpy(info->D_809105D8_copy, D_809105D8, sizeof(D_809105D8));
|
||||
memcpy(info->D_80910608_copy, D_80910608, sizeof(D_80910608));
|
||||
memcpy(info->sBossGanon2Particles_copy, sBossGanon2Particles, sizeof(sBossGanon2Particles));
|
||||
info->sTwInitalized_copy = sTwInitalized;
|
||||
memcpy(info->sTwEffects_copy, sTwEffects, sizeof(sTwEffects));
|
||||
info->sDemo6kVelocity_copy = sDemo6kVelocity;
|
||||
info->D_8096CE94_copy = D_8096CE94;
|
||||
info->demoKekkaiVel_copy = demoKekkaiVel;
|
||||
info->sSlugGroup_copy = sSlugGroup;
|
||||
info->sClearTagIsEffectInitialized_copy = sClearTagIsEffectsInitialized;
|
||||
memcpy(info->sClearTagEffects_copy, sClearTagEffects, sizeof(sClearTagEffects));
|
||||
|
||||
memcpy(&info->sEnFrPointers_copy, &sEnFrPointers, sizeof(info->sEnFrPointers_copy));
|
||||
info->sSpawnNum_copy = sSpawnNum;
|
||||
|
||||
info->D_80A7DEB0_copy = D_80A7DEB0;
|
||||
info->D_80A7DEB4_copy = D_80A7DEB4;
|
||||
info->D_80A7DEB8_copy = D_80A7DEB8;
|
||||
info->sRockRotSpeedX_copy = sRockRotSpeedX;
|
||||
info->sRockRotSpeedY_copy = sRockRotSpeedY;
|
||||
info->D_80AB85E0_copy = D_80AB85E0;
|
||||
info->sLowerRiverSpawned_copy = sLowerRiverSpawned;
|
||||
info->sUpperRiverSpawned_copy = sUpperRiverSpawned;
|
||||
info->sEnPoFieldNumSpawned_copy = sEnPoFieldNumSpawned;
|
||||
memcpy(info->sEnPoFieldSpawnPositions_copy, sEnPoFieldSpawnPositions, sizeof(info->sEnPoFieldSpawnPositions_copy));
|
||||
memcpy(info->sEnPoFieldSpawnSwitchFlags_copy, sEnPoFieldSpawnSwitchFlags, sizeof(info->sEnPoFieldSpawnSwitchFlags_copy));
|
||||
|
||||
info->sTakaraIsInitialized_copy = sTakaraIsInitialized;
|
||||
info->D_80B41D90_copy = D_80B41D90;
|
||||
info->sEnXcFlameSpawned_copy = sEnXcFlameSpawned;
|
||||
info->D_80B41DA8_copy = D_80B41DA8;
|
||||
info->D_80B41DAC_copy = D_80B41DAC;
|
||||
info->D_80B4A1B0_copy = D_80B4A1B0;
|
||||
info->D_80B4A1B4_copy = D_80B4A1B4;
|
||||
info->D_80B5A468_copy = D_80B5A468;
|
||||
info->D_80B5A494_copy = D_80B5A494;
|
||||
info->D_80B5A4BC_copy = D_80B5A4BC;
|
||||
info->sKankyoIsSpawned_copy = sKankyoIsSpawned;
|
||||
info->sTrailingFairies_copy = sTrailingFairies;
|
||||
|
||||
}
|
||||
|
||||
void SaveState::LoadOverlayStaticData(void) {
|
||||
sBgDdanKdVelocity = info->sBgDdanKdVelocity_copy;
|
||||
sBgDdanKdAccel = info->sBgDdanKdAccel_copy;
|
||||
sBgDodoagoFirstExplosiveFlag = info->sBgDodoagoFirstExplosiveFlag_copy;
|
||||
sBgDodoagoDisableBombCatcher = info->sBgDodoagoDisableBombCatcher_copy;
|
||||
sBgDodoagoTimer = info->sBgDodoagoTimer_copy;
|
||||
D_80880F30 = info->D_80880F30_copy;
|
||||
D_80881014 = info->D_80881014_copy;
|
||||
D_8088BFC0 = info->D_8088BFC0_copy;
|
||||
sBgMoriHineriNextCamIdx = info->sBgMoriHineriNextCamIdx_copy;
|
||||
sBgPoEventBlocksAtRest = info->sBgPoEventBlocksAtRest_copy;
|
||||
sBgPoEventPuzzleState = info->sBgPoEventPuzzleState_copy;
|
||||
sBgPoEventblockPushDist = info->sBgPoEventblockPushDist_copy;
|
||||
D_808A9508 = info->D_808A9508_copy;
|
||||
D_808B85D0 = info->D_808B85D0_copy;
|
||||
sBossGanonSeed1 = info->sBossGanonSeed1_copy;
|
||||
sBossGanonSeed2 = info->sBossGanonSeed2_copy;
|
||||
sBossGanonSeed3 = info->sBossGanonSeed3_copy;
|
||||
sBossGanonGanondorf = info->sBossGanonGanondorf_copy;
|
||||
sBossGanonZelda = info->sBossGanonZelda_copy;
|
||||
sBossGanonCape = info->sBossGanonCape_copy;
|
||||
memcpy(sBossGanonEffectBuf, info->sBossGanonEffectBuf_copy, sizeof(info->sBossGanonEffectBuf_copy));
|
||||
|
||||
D_8090EB20 = info->D_8090EB20_copy;
|
||||
D_80910638 = info->D_80910638_copy;
|
||||
sBossGanon2Zelda = info->sBossGanon2Zelda_copy;
|
||||
D_8090EB30 = info->D_8090EB30_copy;
|
||||
sBossGanon2Seed1 = info->sBossGanon2Seed1_copy;
|
||||
sBossGanon2Seed2 = info->sBossGanon2Seed2_copy;
|
||||
sBossGanon2Seed3 = info->sBossGanon2Seed3_copy;
|
||||
memcpy(D_809105D8, info->D_809105D8_copy, sizeof(D_809105D8));
|
||||
memcpy(D_80910608, info->D_80910608_copy, sizeof(D_80910608));
|
||||
memcpy(sBossGanon2Particles, info->sBossGanon2Particles_copy, sizeof(sBossGanon2Particles));
|
||||
sTwInitalized = info->sTwInitalized_copy;
|
||||
memcpy(sTwEffects, info->sTwEffects_copy, sizeof(sTwEffects));
|
||||
sDemo6kVelocity = info->sDemo6kVelocity_copy;
|
||||
|
||||
D_8096CE94 = info->D_8096CE94_copy;
|
||||
demoKekkaiVel = info->demoKekkaiVel_copy;
|
||||
sSlugGroup = info->sSlugGroup_copy;
|
||||
sClearTagIsEffectsInitialized = info->sClearTagIsEffectInitialized_copy;
|
||||
memcpy(sClearTagEffects, info->sClearTagEffects_copy, sizeof(sClearTagEffects));
|
||||
|
||||
D_80A7DEB0 = info->D_80A7DEB0_copy;
|
||||
D_80A7DEB4 = info->D_80A7DEB4_copy;
|
||||
D_80A7DEB8 = info->D_80A7DEB8_copy;
|
||||
sRockRotSpeedX = info->sRockRotSpeedX_copy;
|
||||
sRockRotSpeedY = info->sRockRotSpeedY_copy;
|
||||
D_80AB85E0 = info->D_80AB85E0_copy;
|
||||
sLowerRiverSpawned = info->sLowerRiverSpawned_copy;
|
||||
sUpperRiverSpawned = info->sUpperRiverSpawned_copy;
|
||||
sEnPoFieldNumSpawned = info->sEnPoFieldNumSpawned_copy;
|
||||
memcpy(sEnPoFieldSpawnPositions, info->sEnPoFieldSpawnPositions_copy, sizeof(info->sEnPoFieldSpawnPositions_copy));
|
||||
memcpy(sEnPoFieldSpawnSwitchFlags, info->sEnPoFieldSpawnSwitchFlags_copy, sizeof(info->sEnPoFieldSpawnSwitchFlags_copy));
|
||||
|
||||
sTakaraIsInitialized = info->sTakaraIsInitialized_copy;
|
||||
D_80B41D90 = info->D_80B41D90_copy;
|
||||
sEnXcFlameSpawned = info->sEnXcFlameSpawned_copy;
|
||||
D_80B41DA8 = info->D_80B41DA8_copy;
|
||||
D_80B41DAC = info->D_80B41DAC_copy;
|
||||
D_80B4A1B0 = info->D_80B4A1B0_copy;
|
||||
D_80B4A1B4 = info->D_80B4A1B4_copy;
|
||||
D_80B5A468 = info->D_80B5A468_copy;
|
||||
D_80B5A494 = info->D_80B5A494_copy;
|
||||
D_80B5A4BC = info->D_80B5A4BC_copy;
|
||||
sKankyoIsSpawned = info->sKankyoIsSpawned_copy;
|
||||
sTrailingFairies = info->sTrailingFairies_copy;
|
||||
}
|
||||
|
||||
void SaveState::SaveMiscCodeData(void) {
|
||||
info->gGameOverTimer_copy = gGameOverTimer;
|
||||
info->gTimeIncrement_copy = gTimeIncrement;
|
||||
info->sLoadedMarkDataTableCopy = sLoadedMarkDataTable;
|
||||
|
||||
info->sPlayerInitialPosX_copy = sPlayerInitialPosX;
|
||||
info->sPlayerInitialPosZ_copy = sPlayerInitialPosZ;
|
||||
info->sPlayerInitialDirection_copy = sPlayerInitialDirection;
|
||||
|
||||
info->sOcarinaInpEnabled_copy = sOcarinaInpEnabled;
|
||||
info->D_80130F10_copy = D_80130F10;
|
||||
info->sCurOcarinaBtnVal_copy = sCurOcarinaBtnVal;
|
||||
info->sPrevOcarinaNoteVal_copy = sPrevOcarinaNoteVal;
|
||||
info->sCurOcarinaBtnIdx_copy = sCurOcarinaBtnIdx;
|
||||
info->sLearnSongLastBtn_copy = sLearnSongLastBtn;
|
||||
info->D_80130F24_copy = D_80130F24;
|
||||
info->D_80130F28_copy = D_80130F28;
|
||||
info->D_80130F2C_copy = D_80130F2C;
|
||||
info->D_80130F30_copy = D_80130F30;
|
||||
info->D_80130F34_copy = D_80130F34;
|
||||
info->sPlaybackState_copy = sPlaybackState;
|
||||
info->D_80130F3C_copy = D_80130F3C;
|
||||
info->sNotePlaybackTimer_copy = sNotePlaybackTimer;
|
||||
info->sPlaybackNotePos_copy = sPlaybackNotePos;
|
||||
info->sStaffPlaybackPos_copy = sStaffPlaybackPos;
|
||||
|
||||
|
||||
info->sCurOcarinaBtnPress_copy = sCurOcarinaBtnPress;
|
||||
info->D_8016BA10_copy = D_8016BA10;
|
||||
info->sPrevOcarinaBtnPress_copy = sPrevOcarinaBtnPress;
|
||||
info->D_8016BA18_copy = D_8016BA18;
|
||||
info->D_8016BA1C_copy = D_8016BA1C;
|
||||
memcpy(info->sCurOcarinaSong_copy, sCurOcarinaSong, sizeof(sCurOcarinaSong));
|
||||
info->sOcarinaSongAppendPos_copy = sOcarinaSongAppendPos;
|
||||
info->sOcarinaHasStartedSong_copy = sOcarinaHasStartedSong;
|
||||
info->sOcarinaSongNoteStartIdx_copy = sOcarinaSongNoteStartIdx;
|
||||
info->sOcarinaSongCnt_copy = sOcarinaSongCnt;
|
||||
info->sOcarinaAvailSongs_copy = sOcarinaAvailSongs;
|
||||
info->sStaffPlayingPos_copy = sStaffPlayingPos;
|
||||
memcpy(info->sLearnSongPos_copy, sLearnSongPos, sizeof(sLearnSongPos));
|
||||
memcpy(info->D_8016BA50_copy, D_8016BA50, sizeof(D_8016BA50));
|
||||
memcpy(info->D_8016BA70_copy, D_8016BA70, sizeof(D_8016BA70));
|
||||
memcpy(info->sLearnSongExpectedNote_copy, sLearnSongExpectedNote, sizeof(sLearnSongExpectedNote));
|
||||
memcpy(&info->D_8016BAA0_copy, &D_8016BAA0, sizeof(D_8016BAA0));
|
||||
info->sAudioHasMalonBgm_copy = sAudioHasMalonBgm;
|
||||
info->sAudioMalonBgmDist_copy = sAudioMalonBgmDist;
|
||||
info->sDisplayedNoteValue_copy = sDisplayedNoteValue;
|
||||
|
||||
|
||||
info->sOcarinaNoteBufPos_copy = sOcarinaNoteBufPos;
|
||||
info->sOcarinaNoteBufLen_copy = sOcarinaNoteBufLen;
|
||||
memcpy(info->sOcarinaNoteBuf_copy, sOcarinaNoteBuf, sizeof(sOcarinaNoteBuf));
|
||||
info->D_8014B2F4_copy = D_8014B2F4;
|
||||
info->sTextboxSkipped_copy = sTextboxSkipped;
|
||||
info->sNextTextId_copy = sNextTextId;
|
||||
info->sLastPlayedSong_copy = sLastPlayedSong;
|
||||
info->sHasSunsSong_copy = sHasSunsSong;
|
||||
info->sMessageHasSetSfx_copy = sMessageHasSetSfx;
|
||||
info->sOcarinaSongBitFlags_copy = sOcarinaSongBitFlags;
|
||||
}
|
||||
|
||||
void SaveState::LoadMiscCodeData(void) {
|
||||
gGameOverTimer = info->gGameOverTimer_copy;
|
||||
gTimeIncrement = info->gTimeIncrement_copy;
|
||||
sLoadedMarkDataTable = info->sLoadedMarkDataTableCopy;
|
||||
|
||||
sPlayerInitialPosX = info->sPlayerInitialPosX_copy;
|
||||
sPlayerInitialPosZ = info->sPlayerInitialPosZ_copy;
|
||||
sPlayerInitialDirection = info->sPlayerInitialDirection_copy;
|
||||
|
||||
sOcarinaInpEnabled = info->sOcarinaInpEnabled_copy;
|
||||
D_80130F10 = info->D_80130F10_copy;
|
||||
sCurOcarinaBtnVal = info->sCurOcarinaBtnVal_copy;
|
||||
sPrevOcarinaNoteVal = info->sPrevOcarinaNoteVal_copy;
|
||||
sCurOcarinaBtnIdx = info->sCurOcarinaBtnIdx_copy;
|
||||
sLearnSongLastBtn = info->sLearnSongLastBtn_copy;
|
||||
D_80130F24 = info->D_80130F24_copy;
|
||||
D_80130F28 = info->D_80130F28_copy;
|
||||
D_80130F2C = info->D_80130F2C_copy;
|
||||
D_80130F30 = info->D_80130F30_copy;
|
||||
D_80130F34 = info->D_80130F34_copy;
|
||||
sPlaybackState = info->sPlaybackState_copy;
|
||||
D_80130F3C = info->D_80130F3C_copy;
|
||||
sNotePlaybackTimer = info->sNotePlaybackTimer_copy;
|
||||
sPlaybackNotePos = info->sPlaybackNotePos_copy;
|
||||
sStaffPlaybackPos = info->sStaffPlaybackPos_copy;
|
||||
|
||||
sCurOcarinaBtnPress = info->sCurOcarinaBtnPress_copy;
|
||||
D_8016BA10 = info->D_8016BA10_copy;
|
||||
sPrevOcarinaBtnPress = info->sPrevOcarinaBtnPress_copy;
|
||||
D_8016BA18 = info->D_8016BA18_copy;
|
||||
D_8016BA1C = info->D_8016BA1C_copy;
|
||||
memcpy(sCurOcarinaSong, info->sCurOcarinaSong_copy, sizeof(sCurOcarinaSong));
|
||||
sOcarinaSongAppendPos = info->sOcarinaSongAppendPos_copy;
|
||||
sOcarinaHasStartedSong = info->sOcarinaHasStartedSong_copy;
|
||||
sOcarinaSongNoteStartIdx = info->sOcarinaSongNoteStartIdx_copy;
|
||||
sOcarinaSongCnt = info->sOcarinaSongCnt_copy;
|
||||
sOcarinaAvailSongs = info->sOcarinaAvailSongs_copy;
|
||||
sStaffPlayingPos = info->sStaffPlayingPos_copy;
|
||||
memcpy(info->sLearnSongPos_copy, info->sLearnSongPos_copy, sizeof(sLearnSongPos));
|
||||
memcpy(info->D_8016BA50_copy, info->D_8016BA50_copy, sizeof(D_8016BA50));
|
||||
memcpy(info->D_8016BA70_copy, info->D_8016BA70_copy, sizeof(D_8016BA70));
|
||||
memcpy(info->sLearnSongExpectedNote_copy, info->sLearnSongExpectedNote_copy, sizeof(sLearnSongExpectedNote));
|
||||
memcpy(&D_8016BAA0, &info->D_8016BAA0_copy, sizeof(D_8016BAA0));
|
||||
sAudioHasMalonBgm = info->sAudioHasMalonBgm_copy;
|
||||
sAudioMalonBgmDist = info->sAudioMalonBgmDist_copy;
|
||||
sDisplayedNoteValue = info->sDisplayedNoteValue_copy;
|
||||
|
||||
sOcarinaNoteBufPos = info->sOcarinaNoteBufPos_copy;
|
||||
sOcarinaNoteBufLen = info->sOcarinaNoteBufLen_copy;
|
||||
memcpy(sOcarinaNoteBuf, info->sOcarinaNoteBuf_copy, sizeof(sOcarinaNoteBuf));
|
||||
|
||||
D_8014B2F4 = info->D_8014B2F4_copy;
|
||||
sTextboxSkipped = info->sTextboxSkipped_copy;
|
||||
sNextTextId = info->sNextTextId_copy;
|
||||
sLastPlayedSong = info->sLastPlayedSong_copy;
|
||||
sHasSunsSong = info->sHasSunsSong_copy;
|
||||
sMessageHasSetSfx = info->sMessageHasSetSfx_copy;
|
||||
sOcarinaSongBitFlags = info->sOcarinaSongBitFlags_copy;
|
||||
|
||||
|
||||
}
|
||||
|
||||
extern "C" void ProcessSaveStateRequests(void) {
|
||||
OTRGlobals::Instance->gSaveStateMgr->ProcessSaveStateRequests();
|
||||
}
|
||||
|
||||
void SaveStateMgr::SetCurrentSlot(unsigned int slot) {
|
||||
SohImGui::overlay->TextDrawNotification(1.0f, true, "slot %u set", slot);
|
||||
this->currentSlot = slot;
|
||||
}
|
||||
|
||||
unsigned int SaveStateMgr::GetCurrentSlot(void) {
|
||||
return this->currentSlot;
|
||||
}
|
||||
|
||||
void SaveStateMgr::ProcessSaveStateRequests(void) {
|
||||
while (!this->requests.empty()) {
|
||||
const auto& request = this->requests.front();
|
||||
|
||||
switch (request.type) {
|
||||
case RequestType::SAVE:
|
||||
if (!this->states.contains(request.slot)) {
|
||||
this->states[request.slot] = std::make_shared<SaveState>(OTRGlobals::Instance->gSaveStateMgr, request.slot);
|
||||
}
|
||||
this->states[request.slot]->Save();
|
||||
SohImGui::overlay->TextDrawNotification(1.0f, true, "saved state %u", request.slot);
|
||||
break;
|
||||
case RequestType::LOAD:
|
||||
if (this->states.contains(request.slot)) {
|
||||
this->states[request.slot]->Load();
|
||||
SohImGui::overlay->TextDrawNotification(1.0f, true, "loaded state %u", request.slot);
|
||||
} else {
|
||||
SPDLOG_ERROR("Invalid SaveState slot: {}", request.type);
|
||||
}
|
||||
break;
|
||||
[[unlikely]] default:
|
||||
SPDLOG_ERROR("Invalid SaveState request type: {}", request.type);
|
||||
break;
|
||||
}
|
||||
this->requests.pop();
|
||||
}
|
||||
}
|
||||
|
||||
SaveStateReturn SaveStateMgr::AddRequest(const SaveStateRequest request) {
|
||||
if (gGlobalCtx == nullptr) {
|
||||
SPDLOG_ERROR("[SOH] Can not save or load a state outside of \"GamePlay\"");
|
||||
SohImGui::overlay->TextDrawNotification(1.0f, true, "states not available here", request.slot);
|
||||
return SaveStateReturn::FAIL_WRONG_GAMESTATE;
|
||||
}
|
||||
|
||||
switch (request.type) {
|
||||
case RequestType::SAVE:
|
||||
requests.push(request);
|
||||
break;
|
||||
case RequestType::LOAD:
|
||||
if (states.contains(request.slot)) {
|
||||
requests.push(request);
|
||||
} else {
|
||||
SPDLOG_ERROR("Invalid SaveState slot: {}", request.type);
|
||||
SohImGui::overlay->TextDrawNotification(1.0f, true, "state slot %u empty", request.slot);
|
||||
return SaveStateReturn::FAIL_INVALID_SLOT;
|
||||
}
|
||||
break;
|
||||
[[unlikely]] default:
|
||||
SPDLOG_ERROR("Invalid SaveState request type: {}", request.type);
|
||||
return SaveStateReturn::FAIL_BAD_REQUEST;
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void SaveState::Save(void) {
|
||||
std::unique_lock<std::mutex> Lock(audio.mutex);
|
||||
memcpy(&info->sysHeapCopy, gSystemHeap, SYSTEM_HEAP_SIZE /* sizeof(gSystemHeap) */);
|
||||
memcpy(&info->audioHeapCopy, gAudioHeap, AUDIO_HEAP_SIZE /* sizeof(gAudioContext) */);
|
||||
|
||||
memcpy(&info->audioContextCopy, &gAudioContext, sizeof(AudioContext));
|
||||
memcpy(&info->unk_D_8016E750Copy, D_8016E750, sizeof(info->unk_D_8016E750Copy));
|
||||
BackupSeqScriptState();
|
||||
|
||||
memcpy(info->gActiveSoundsCopy, gActiveSounds, sizeof(gActiveSounds));
|
||||
memcpy(&info->gSoundBankMutedCopy, gSoundBankMuted, sizeof(info->gSoundBankMutedCopy));
|
||||
|
||||
info->D_801333F0_copy = D_801333F0;
|
||||
info->gAudioSfxSwapOff_copy = gAudioSfxSwapOff;
|
||||
|
||||
memcpy(&info->gAudioSfxSwapSource_copy, gAudioSfxSwapSource,
|
||||
sizeof(info->gAudioSfxSwapSource_copy));
|
||||
memcpy(&info->gAudioSfxSwapTarget_copy, gAudioSfxSwapTarget,
|
||||
sizeof(info->gAudioSfxSwapTarget_copy));
|
||||
memcpy(&info->gAudioSfxSwapMode_copy, gAudioSfxSwapMode,
|
||||
sizeof(info->gAudioSfxSwapMode_copy));
|
||||
|
||||
info->D_801755D0_copy = D_801755D0;
|
||||
|
||||
memcpy(&info->saveContextCopy, &gSaveContext, sizeof(gSaveContext));
|
||||
memcpy(&info->gameInfoCopy, gGameInfo, sizeof(*gGameInfo));
|
||||
memcpy(&info->lightBufferCopy, &sLightsBuffer, sizeof(sLightsBuffer));
|
||||
memcpy(&info->mtxStackCopy, &sMatrixStack, sizeof(MtxF) * 20);
|
||||
memcpy(&info->currentMtxCopy, &sCurrentMatrix, sizeof(MtxF));
|
||||
|
||||
//Various static data
|
||||
info->blueWarpTimerCopy = sWarpTimerTarget;
|
||||
BackupCameraData();
|
||||
SaveOnePointDemoData();
|
||||
SaveOverlayStaticData();
|
||||
SaveMiscCodeData();
|
||||
|
||||
}
|
||||
|
||||
void SaveState::Load(void) {
|
||||
std::unique_lock<std::mutex> Lock(audio.mutex);
|
||||
memcpy(gSystemHeap, &info->sysHeapCopy, SYSTEM_HEAP_SIZE);
|
||||
memcpy(gAudioHeap, &info->audioHeapCopy, AUDIO_HEAP_SIZE);
|
||||
|
||||
memcpy(&gAudioContext, &info->audioContextCopy, sizeof(AudioContext));
|
||||
memcpy(D_8016E750, &info->unk_D_8016E750Copy, sizeof(info->unk_D_8016E750Copy));
|
||||
LoadSeqScriptState();
|
||||
|
||||
memcpy(&gSaveContext, &info->saveContextCopy, sizeof(gSaveContext));
|
||||
memcpy(gGameInfo, &info->gameInfoCopy, sizeof(*gGameInfo));
|
||||
memcpy(&sLightsBuffer, &info->lightBufferCopy, sizeof(sLightsBuffer));
|
||||
memcpy(&sMatrixStack, &info->mtxStackCopy, sizeof(MtxF) * 20);
|
||||
memcpy(&sCurrentMatrix, &info->currentMtxCopy, sizeof(MtxF));
|
||||
sWarpTimerTarget = info->blueWarpTimerCopy;
|
||||
|
||||
memcpy(gActiveSounds, info->gActiveSoundsCopy, sizeof(gActiveSounds));
|
||||
memcpy(gSoundBankMuted, &info->gSoundBankMutedCopy, sizeof(info->gSoundBankMutedCopy));
|
||||
D_801333F0 = info->D_801333F0_copy;
|
||||
gAudioSfxSwapOff = info->gAudioSfxSwapOff_copy;
|
||||
|
||||
memcpy(gAudioSfxSwapSource, &info->gAudioSfxSwapSource_copy,
|
||||
sizeof(info->gAudioSfxSwapSource_copy));
|
||||
memcpy(gAudioSfxSwapTarget, &info->gAudioSfxSwapTarget_copy,
|
||||
sizeof(info->gAudioSfxSwapTarget_copy));
|
||||
memcpy(gAudioSfxSwapMode, &info->gAudioSfxSwapMode_copy,
|
||||
sizeof(info->gAudioSfxSwapMode_copy));
|
||||
|
||||
//Various static data
|
||||
D_801755D0 = info->D_801755D0_copy;
|
||||
LoadCameraData();
|
||||
LoadOnePointDemoData();
|
||||
LoadOverlayStaticData();
|
||||
LoadMiscCodeData();
|
||||
|
||||
}
|
62
soh/soh/Enhancements/savestates.h
Normal file
62
soh/soh/Enhancements/savestates.h
Normal file
|
@ -0,0 +1,62 @@
|
|||
#ifndef SAVE_STATES_H
|
||||
#define SAVE_STATES_H
|
||||
|
||||
#include <cstdint>
|
||||
#include <queue>
|
||||
#include <unordered_map>
|
||||
#include <memory>
|
||||
#include <mutex>
|
||||
|
||||
enum class SaveStateReturn {
|
||||
SUCCESS,
|
||||
FAIL_INVALID_SLOT,
|
||||
FAIL_NO_MEMORY,
|
||||
FAIL_STATE_EMPTY,
|
||||
FAIL_WRONG_GAMESTATE,
|
||||
FAIL_BAD_REQUEST,
|
||||
};
|
||||
|
||||
typedef struct SaveStateHeader {
|
||||
uint32_t stateMagic;
|
||||
uint32_t stateVersion;
|
||||
//uint32_t gameVersion;
|
||||
} SaveStateHeader;
|
||||
|
||||
enum class RequestType {
|
||||
SAVE,
|
||||
LOAD,
|
||||
};
|
||||
|
||||
typedef struct SaveStateRequest {
|
||||
unsigned int slot;
|
||||
RequestType type;
|
||||
} SaveStateRequest;
|
||||
|
||||
class SaveState;
|
||||
|
||||
class SaveStateMgr {
|
||||
friend class SaveState;
|
||||
private:
|
||||
unsigned int currentSlot;
|
||||
std::unordered_map<unsigned int, std::shared_ptr<SaveState>> states;
|
||||
std::queue <SaveStateRequest> requests;
|
||||
std::mutex mutex;
|
||||
|
||||
public:
|
||||
|
||||
SaveStateReturn AddRequest(const SaveStateRequest request);
|
||||
SaveStateMgr();
|
||||
~SaveStateMgr();
|
||||
|
||||
void SetCurrentSlot(unsigned int slot);
|
||||
unsigned int GetCurrentSlot(void);
|
||||
|
||||
SaveStateMgr& operator=(const SaveStateMgr& rhs) = delete;
|
||||
SaveStateMgr(const SaveStateMgr& rhs) = delete;
|
||||
|
||||
void ProcessSaveStateRequests(void);
|
||||
|
||||
};
|
||||
extern std::shared_ptr<SaveStateMgr> gSaveStateMgr;
|
||||
|
||||
#endif
|
257
soh/soh/Enhancements/savestates_extern.inc
Normal file
257
soh/soh/Enhancements/savestates_extern.inc
Normal file
|
@ -0,0 +1,257 @@
|
|||
extern "C" MtxF* sMatrixStack;
|
||||
extern "C" MtxF* sCurrentMatrix;
|
||||
extern "C" LightsBuffer sLightsBuffer;
|
||||
extern "C" s16 sWarpTimerTarget;
|
||||
extern "C" MapMarkData** sLoadedMarkDataTable;
|
||||
|
||||
//Camera static data
|
||||
extern "C" int32_t sInitRegs;
|
||||
extern "C" int32_t gDbgCamEnabled;
|
||||
extern "C" int32_t sDbgModeIdx;
|
||||
extern "C" int16_t sNextUID;
|
||||
extern "C" int32_t sCameraInterfaceFlags;
|
||||
extern "C" int32_t sCameraInterfaceAlpha;
|
||||
extern "C" int32_t sCameraShrinkWindowVal;
|
||||
extern "C" int32_t D_8011D3AC;
|
||||
extern "C" int32_t sDemo5PrevAction12Frame;
|
||||
extern "C" int32_t sDemo5PrevSfxFrame;
|
||||
extern "C" int32_t D_8011D3F0;
|
||||
extern "C" OnePointCsFull D_8011D6AC[];
|
||||
extern "C" OnePointCsFull D_8011D724[];
|
||||
extern "C" OnePointCsFull D_8011D79C[];
|
||||
extern "C" OnePointCsFull D_8011D83C[];
|
||||
extern "C" OnePointCsFull D_8011D88C[];
|
||||
extern "C" OnePointCsFull D_8011D8DC[];
|
||||
extern "C" OnePointCsFull D_8011D954[];
|
||||
extern "C" OnePointCsFull D_8011D9F4[];
|
||||
extern "C" int16_t D_8011DB08;
|
||||
extern "C" int16_t D_8011DB0C;
|
||||
extern "C" int32_t sOOBTimer;
|
||||
extern "C" f32 D_8015CE50;
|
||||
extern "C" f32 D_8015CE54;
|
||||
extern "C" CamColChk D_8015CE58;
|
||||
|
||||
//Gameover
|
||||
extern "C" uint16_t gGameOverTimer;
|
||||
|
||||
//One Point Demo
|
||||
extern "C" uint32_t sPrevFrameCs1100;
|
||||
extern "C" CutsceneCameraPoint D_8012013C[14];
|
||||
extern "C" CutsceneCameraPoint D_8012021C[14];
|
||||
extern "C" CutsceneCameraPoint D_801204D4[14];
|
||||
extern "C" CutsceneCameraPoint D_801205B4[14];
|
||||
extern "C" OnePointCsFull D_801208EC[3];
|
||||
extern "C" OnePointCsFull D_80120964[2];
|
||||
extern "C" OnePointCsFull D_801209B4[4];
|
||||
extern "C" OnePointCsFull D_80120ACC[5];
|
||||
extern "C" OnePointCsFull D_80120B94[11];
|
||||
extern "C" OnePointCsFull D_80120D4C[7];
|
||||
extern "C" OnePointCsFull D_80120FA4[6];
|
||||
extern "C" OnePointCsFull D_80121184[2];
|
||||
extern "C" OnePointCsFull D_801211D4[2];
|
||||
extern "C" OnePointCsFull D_8012133C[3];
|
||||
extern "C" OnePointCsFull D_801213B4[5];
|
||||
extern "C" OnePointCsFull D_8012151C[2];
|
||||
extern "C" OnePointCsFull D_8012156C[2];
|
||||
extern "C" OnePointCsFull D_801215BC[1];
|
||||
extern "C" OnePointCsFull D_80121C24[7];
|
||||
extern "C" OnePointCsFull D_80121D3C[3];
|
||||
extern "C" OnePointCsFull D_80121F1C[4];
|
||||
extern "C" OnePointCsFull D_80121FBC[4];
|
||||
extern "C" OnePointCsFull D_801220D4[5];
|
||||
extern "C" OnePointCsFull D_80122714[4];
|
||||
extern "C" OnePointCsFull D_80122CB4[2];
|
||||
extern "C" OnePointCsFull D_80122D04[2];
|
||||
extern "C" OnePointCsFull D_80122E44[2][7];
|
||||
extern "C" OnePointCsFull D_8012313C[3];
|
||||
extern "C" OnePointCsFull D_801231B4[4];
|
||||
extern "C" OnePointCsFull D_80123254[2];
|
||||
extern "C" OnePointCsFull D_801232A4[1];
|
||||
extern "C" OnePointCsFull D_80123894[3];
|
||||
extern "C" OnePointCsFull D_8012390C[2];
|
||||
extern "C" OnePointCsFull D_8012395C[3];
|
||||
extern "C" OnePointCsFull D_801239D4[3];
|
||||
|
||||
// z_bg_ddan_kd
|
||||
extern "C" Vec3f sBgDdanKdVelocity;
|
||||
extern "C" Vec3f sBgDdanKdAccel;
|
||||
|
||||
// z_bg_dodoago
|
||||
extern "C" s16 sBgDodoagoFirstExplosiveFlag;
|
||||
extern "C" u8 sBgDodoagoDisableBombCatcher;
|
||||
extern "C" s32 sBgDodoagoTimer;
|
||||
|
||||
// z_bg_haka_trap
|
||||
extern "C" uint32_t D_80880F30;
|
||||
extern "C" uint32_t D_80881014;
|
||||
|
||||
// z_bg_hidan_rock
|
||||
extern "C" float D_8088BFC0;
|
||||
|
||||
// z_bg_menkuri_eye
|
||||
extern "C" int32_t D_8089C1A0;
|
||||
|
||||
// z_bg_mori_hineri
|
||||
extern "C" int16_t sBgMoriHineriNextCamIdx;
|
||||
|
||||
// z_bg_po_event
|
||||
extern "C" uint8_t sBgPoEventBlocksAtRest;
|
||||
extern "C" uint8_t sBgPoEventPuzzleState;
|
||||
extern "C" float sBgPoEventblockPushDist;
|
||||
|
||||
// z_bg_relay_objects
|
||||
extern "C" uint32_t D_808A9508;
|
||||
|
||||
// z_bg_spot18_basket
|
||||
extern "C" int16_t D_808B85D0;
|
||||
|
||||
// z_boss_ganon
|
||||
extern "C" uint32_t sBossGanonSeed1;
|
||||
extern "C" uint32_t sBossGanonSeed2;
|
||||
extern "C" uint32_t sBossGanonSeed3;
|
||||
extern "C" void* sBossGanonGanondorf;
|
||||
extern "C" void* sBossGanonZelda;
|
||||
extern "C" void* sBossGanonCape;
|
||||
extern "C" GanondorfEffect sBossGanonEffectBuf[200];
|
||||
|
||||
// z_boss_ganon2
|
||||
extern "C" Vec3f D_8090EB20;
|
||||
extern "C" int8_t D_80910638;
|
||||
extern "C" void* sBossGanon2Zelda;
|
||||
extern "C" void* D_8090EB30;
|
||||
extern "C" int32_t sBossGanon2Seed1;
|
||||
extern "C" int32_t sBossGanon2Seed2;
|
||||
extern "C" int32_t sBossGanon2Seed3;
|
||||
extern "C" Vec3f D_809105D8[4];
|
||||
extern "C" Vec3f D_80910608[4];
|
||||
extern "C" BossGanon2Effect sBossGanon2Particles[100];
|
||||
|
||||
// z_boss_tw
|
||||
extern "C" uint8_t sTwInitalized;
|
||||
extern "C" BossTwEffect sTwEffects[150];
|
||||
|
||||
// z_demo_6k
|
||||
extern "C" Vec3f sDemo6kVelocity;
|
||||
|
||||
// z_demo_du
|
||||
extern "C" int32_t D_8096CE94;
|
||||
|
||||
// z_demo_kekkai
|
||||
extern "C" Vec3f demoKekkaiVel;
|
||||
|
||||
// z_en_bw
|
||||
extern "C" int32_t sSlugGroup;
|
||||
|
||||
// z_en_clear_tag
|
||||
extern "C" uint8_t sClearTagIsEffectsInitialized;
|
||||
extern "C" EnClearTagEffect sClearTagEffects[CLEAR_TAG_EFFECT_MAX_COUNT];
|
||||
|
||||
// z_en_fr
|
||||
extern "C" EnFrPointers sEnFrPointers;
|
||||
|
||||
// z_en_goma
|
||||
extern "C" uint8_t sSpawnNum;
|
||||
|
||||
// z_en_in
|
||||
extern "C" int32_t D_80A7B998;
|
||||
|
||||
// z_en_insect
|
||||
extern "C" float D_80A7DEB0;
|
||||
extern "C" int16_t D_80A7DEB4;
|
||||
extern "C" int16_t D_80A7DEB8;
|
||||
|
||||
// z_en_ishi
|
||||
extern "C" int16_t sRockRotSpeedX;
|
||||
extern "C" int16_t sRockRotSpeedY;
|
||||
|
||||
// z_en_niw
|
||||
extern "C" int16_t D_80AB85E0;
|
||||
extern "C" uint8_t sLowerRiverSpawned;
|
||||
extern "C" uint8_t sUpperRiverSpawned;
|
||||
|
||||
// z_en_po_field
|
||||
extern "C" int32_t sEnPoFieldNumSpawned;
|
||||
extern "C" Vec3s sEnPoFieldSpawnPositions[10];
|
||||
extern "C" u8 sEnPoFieldSpawnSwitchFlags[10];
|
||||
|
||||
// z_en_takara_man
|
||||
extern "C" uint8_t sTakaraIsInitialized;
|
||||
|
||||
// z_en_xc
|
||||
extern "C" int32_t D_80B41D90;
|
||||
extern "C" int32_t sEnXcFlameSpawned;
|
||||
extern "C" int32_t D_80B41DA8;
|
||||
extern "C" int32_t D_80B41DAC;
|
||||
|
||||
// z_en_zf
|
||||
extern "C" int16_t D_80B4A1B0;
|
||||
extern "C" int16_t D_80B4A1B4;
|
||||
|
||||
extern "C" int32_t D_80B5A468;
|
||||
extern "C" int32_t D_80B5A494;
|
||||
extern "C" int32_t D_80B5A4BC;
|
||||
|
||||
extern "C" uint8_t sKankyoIsSpawned;
|
||||
extern "C" int16_t sTrailingFairies;
|
||||
|
||||
extern "C" uint16_t gTimeIncrement;
|
||||
|
||||
extern "C" s16 sPlayerInitialPosX;
|
||||
extern "C" s16 sPlayerInitialPosZ;
|
||||
extern "C" s16 sPlayerInitialDirection;
|
||||
|
||||
// code_800EC960
|
||||
// Related to ocarina
|
||||
extern "C" u8 sOcarinaInpEnabled;
|
||||
extern "C" s8 D_80130F10;
|
||||
extern "C" u8 sCurOcarinaBtnVal;
|
||||
extern "C" u8 sPrevOcarinaNoteVal;
|
||||
extern "C" u8 sCurOcarinaBtnIdx;
|
||||
extern "C" u8 sLearnSongLastBtn;
|
||||
extern "C" f32 D_80130F24;
|
||||
extern "C" f32 D_80130F28;
|
||||
extern "C" s8 D_80130F2C;
|
||||
extern "C" s8 D_80130F30;
|
||||
extern "C" s8 D_80130F34;
|
||||
extern "C" u8 sPlaybackState;
|
||||
extern "C" u32 D_80130F3C;
|
||||
extern "C" u32 sNotePlaybackTimer;
|
||||
extern "C" u16 sPlaybackNotePos;
|
||||
extern "C" u16 sStaffPlaybackPos;
|
||||
|
||||
//IDK what this is but it looks important
|
||||
extern "C" u32 sCurOcarinaBtnPress;
|
||||
extern "C" u32 D_8016BA10;
|
||||
extern "C" u32 sPrevOcarinaBtnPress;
|
||||
extern "C" s32 D_8016BA18;
|
||||
extern "C" s32 D_8016BA1C;
|
||||
extern "C" u8 sCurOcarinaSong[8];
|
||||
extern "C" u8 sOcarinaSongAppendPos;
|
||||
extern "C" u8 sOcarinaHasStartedSong;
|
||||
extern "C" u8 sOcarinaSongNoteStartIdx;
|
||||
extern "C" u8 sOcarinaSongCnt;
|
||||
extern "C" u16 sOcarinaAvailSongs;
|
||||
extern "C" u8 sStaffPlayingPos;
|
||||
extern "C" u16 sLearnSongPos[0x10];
|
||||
extern "C" u16 D_8016BA50[0x10];
|
||||
extern "C" u16 D_8016BA70[0x10];
|
||||
extern "C" u8 sLearnSongExpectedNote[0x10];
|
||||
extern "C" OcarinaNote D_8016BAA0;
|
||||
extern "C" u8 sAudioHasMalonBgm;
|
||||
extern "C" f32 sAudioMalonBgmDist;
|
||||
extern "C" u8 sDisplayedNoteValue;
|
||||
|
||||
|
||||
|
||||
// z_message_PAL
|
||||
extern "C" s16 sOcarinaNoteBufPos;
|
||||
extern "C" s16 sOcarinaNoteBufLen;
|
||||
extern "C" u8 sOcarinaNoteBuf[12];
|
||||
|
||||
extern "C" u8 D_8014B2F4;
|
||||
extern "C" u8 sTextboxSkipped;
|
||||
extern "C" u16 sNextTextId;
|
||||
extern "C" s16 sLastPlayedSong;
|
||||
extern "C" s16 sHasSunsSong;
|
||||
extern "C" s16 sMessageHasSetSfx;
|
||||
extern "C" u16 sOcarinaSongBitFlags;
|
8
soh/soh/OTRAudio.h
Normal file
8
soh/soh/OTRAudio.h
Normal file
|
@ -0,0 +1,8 @@
|
|||
#pragma once
|
||||
|
||||
static struct {
|
||||
std::condition_variable cv_to_thread, cv_from_thread;
|
||||
std::mutex mutex;
|
||||
bool initialized;
|
||||
bool processing;
|
||||
} audio;
|
|
@ -1,4 +1,5 @@
|
|||
#include "OTRGlobals.h"
|
||||
#include "OTRAudio.h"
|
||||
#include <iostream>
|
||||
#include <locale>
|
||||
#include <codecvt>
|
||||
|
@ -28,22 +29,20 @@
|
|||
#include "AudioPlayer.h"
|
||||
#include "Enhancements/debugconsole.h"
|
||||
#include "Enhancements/debugger/debugger.h"
|
||||
#include "soh/frame_interpolation.h"
|
||||
#include "Utils/BitConverter.h"
|
||||
#include "variables.h"
|
||||
#include "macros.h"
|
||||
#include <Utils/StringHelper.h>
|
||||
|
||||
#include <SDL2/SDL_scancode.h>
|
||||
|
||||
OTRGlobals* OTRGlobals::Instance;
|
||||
|
||||
static struct {
|
||||
std::condition_variable cv_to_thread, cv_from_thread;
|
||||
std::mutex mutex;
|
||||
bool initialized;
|
||||
bool processing;
|
||||
} audio;
|
||||
|
||||
OTRGlobals::OTRGlobals() {
|
||||
|
||||
context = Ship::GlobalCtx2::CreateInstance("Ship of Harkinian");
|
||||
gSaveStateMgr = std::make_shared<SaveStateMgr>();
|
||||
context->GetWindow()->Init();
|
||||
}
|
||||
|
||||
|
@ -114,12 +113,69 @@ extern "C" void Graph_ProcessFrame(void (*run_one_game_iter)(void)) {
|
|||
}
|
||||
|
||||
extern "C" void Graph_StartFrame() {
|
||||
// Why -1?
|
||||
int32_t dwScancode = OTRGlobals::Instance->context->GetWindow()->lastScancode;
|
||||
OTRGlobals::Instance->context->GetWindow()->lastScancode = -1;
|
||||
|
||||
switch (dwScancode - 1) {
|
||||
case SDL_SCANCODE_F5: {
|
||||
const unsigned int slot = OTRGlobals::Instance->gSaveStateMgr->GetCurrentSlot();
|
||||
const SaveStateReturn stateReturn =
|
||||
OTRGlobals::Instance->gSaveStateMgr->AddRequest({ slot, RequestType::SAVE });
|
||||
|
||||
switch (stateReturn) {
|
||||
case SaveStateReturn::SUCCESS:
|
||||
SPDLOG_INFO("[SOH] Saved state to slot {}", slot);
|
||||
break;
|
||||
case SaveStateReturn::FAIL_WRONG_GAMESTATE:
|
||||
SPDLOG_ERROR("[SOH] Can not save a state outside of \"GamePlay\"");
|
||||
break;
|
||||
[[unlikely]] default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case SDL_SCANCODE_F6: {
|
||||
unsigned int slot = OTRGlobals::Instance->gSaveStateMgr->GetCurrentSlot();
|
||||
slot++;
|
||||
if (slot > 5) {
|
||||
slot = 0;
|
||||
}
|
||||
OTRGlobals::Instance->gSaveStateMgr->SetCurrentSlot(slot);
|
||||
SPDLOG_INFO("Set SaveState slot to {}.", slot);
|
||||
break;
|
||||
}
|
||||
case SDL_SCANCODE_F7: {
|
||||
const unsigned int slot = OTRGlobals::Instance->gSaveStateMgr->GetCurrentSlot();
|
||||
const SaveStateReturn stateReturn =
|
||||
OTRGlobals::Instance->gSaveStateMgr->AddRequest({ slot, RequestType::LOAD });
|
||||
|
||||
switch (stateReturn) {
|
||||
case SaveStateReturn::SUCCESS:
|
||||
SPDLOG_INFO("[SOH] Loaded state from slot {}", slot);
|
||||
break;
|
||||
case SaveStateReturn::FAIL_INVALID_SLOT:
|
||||
SPDLOG_ERROR("[SOH] Invalid State Slot Number {}", slot);
|
||||
break;
|
||||
case SaveStateReturn::FAIL_STATE_EMPTY:
|
||||
SPDLOG_ERROR("[SOH] State Slot {} is empty", slot);
|
||||
break;
|
||||
case SaveStateReturn::FAIL_WRONG_GAMESTATE:
|
||||
SPDLOG_ERROR("[SOH] Can not load a state outside of \"GamePlay\"");
|
||||
break;
|
||||
[[unlikely]] default:
|
||||
break;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
OTRGlobals::Instance->context->GetWindow()->StartFrame();
|
||||
}
|
||||
|
||||
// C->C++ Bridge
|
||||
extern "C" void Graph_ProcessGfxCommands(Gfx* commands) {
|
||||
OTRGlobals::Instance->context->GetWindow()->SetFrameDivisor(R_UPDATE_RATE);
|
||||
OTRGlobals::Instance->context->GetWindow()->SetFrameDivisor(CVar_GetS32("g60FPS", 0) == 0 ? R_UPDATE_RATE : 1);
|
||||
|
||||
if (!audio.initialized) {
|
||||
audio.initialized = true;
|
||||
|
@ -131,6 +187,7 @@ extern "C" void Graph_ProcessGfxCommands(Gfx* commands) {
|
|||
audio.cv_to_thread.wait(Lock);
|
||||
}
|
||||
}
|
||||
std::unique_lock<std::mutex> Lock(audio.mutex);
|
||||
//AudioMgr_ThreadEntry(&gAudioMgr);
|
||||
// 528 and 544 relate to 60 fps at 32 kHz 32000/60 = 533.333..
|
||||
// in an ideal world, one third of the calls should use num_samples=544 and two thirds num_samples=528
|
||||
|
@ -156,10 +213,7 @@ extern "C" void Graph_ProcessGfxCommands(Gfx* commands) {
|
|||
// printf("Audio samples before submitting: %d\n", audio_api->buffered());
|
||||
AudioPlayer_Play((u8*)audio_buffer, num_audio_samples * (sizeof(int16_t) * NUM_AUDIO_CHANNELS * AUDIO_FRAMES_PER_UPDATE));
|
||||
|
||||
{
|
||||
std::unique_lock<std::mutex> Lock(audio.mutex);
|
||||
audio.processing = false;
|
||||
}
|
||||
audio.cv_from_thread.notify_one();
|
||||
}
|
||||
}).detach();
|
||||
|
@ -171,7 +225,15 @@ extern "C" void Graph_ProcessGfxCommands(Gfx* commands) {
|
|||
}
|
||||
audio.cv_to_thread.notify_one();
|
||||
|
||||
OTRGlobals::Instance->context->GetWindow()->RunCommands(commands);
|
||||
std::vector<std::unordered_map<Mtx*, MtxF>> mtx_replacements;
|
||||
if (CVar_GetS32("g60FPS", 0) != 0) {
|
||||
int to = R_UPDATE_RATE;
|
||||
for (int i = 1; i < to; i++) {
|
||||
mtx_replacements.push_back(FrameInterpolation_Interpolate(i / (float)to));
|
||||
}
|
||||
}
|
||||
|
||||
OTRGlobals::Instance->context->GetWindow()->RunCommands(commands, mtx_replacements);
|
||||
|
||||
{
|
||||
std::unique_lock<std::mutex> Lock(audio.mutex);
|
||||
|
|
|
@ -1,14 +1,19 @@
|
|||
#ifndef OTR_GLOBALS_H
|
||||
#define OTR_GLOBALS_H
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "GlobalCtx2.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
#include "Enhancements/savestates.h"
|
||||
class OTRGlobals
|
||||
{
|
||||
public:
|
||||
static OTRGlobals* Instance;
|
||||
|
||||
std::shared_ptr<Ship::GlobalCtx2> context;
|
||||
std::shared_ptr<SaveStateMgr> gSaveStateMgr;
|
||||
|
||||
OTRGlobals();
|
||||
~OTRGlobals();
|
||||
|
@ -68,3 +73,5 @@ void AudioPlayer_Play(const uint8_t* buf, uint32_t len);
|
|||
void AudioMgr_CreateNextAudioBuffer(s16* samples, u32 num_samples);
|
||||
int Controller_ShouldRumble(size_t i);
|
||||
#endif
|
||||
|
||||
#endif
|
732
soh/soh/frame_interpolation.cpp
Normal file
732
soh/soh/frame_interpolation.cpp
Normal file
|
@ -0,0 +1,732 @@
|
|||
#include "Cvar.h"
|
||||
|
||||
#include <vector>
|
||||
#include <map>
|
||||
#include <unordered_map>
|
||||
#include <math.h>
|
||||
|
||||
#include "frame_interpolation.h"
|
||||
|
||||
/*
|
||||
Frame interpolation.
|
||||
|
||||
The idea of this code is to interpolate all matrices.
|
||||
|
||||
The code contains two approaches. The first is to interpolate
|
||||
all inputs in transformations, such as angles, scale and distances,
|
||||
and then perform the same transformations with the interpolated values.
|
||||
After evaluation for some reason some animations such rolling look strange.
|
||||
|
||||
The second approach is to simply interpolate the final matrices. This will
|
||||
more or less simply interpolate the world coordinates for movements.
|
||||
This will however make rotations ~180 degrees get the "paper effect".
|
||||
The mitigation is to identify this case for actors and interpolate the
|
||||
matrix but in model coordinates instead, by "removing" the rotation-
|
||||
translation before interpolating, create a rotation matrix with the
|
||||
interpolated angle which is then applied to the matrix.
|
||||
|
||||
Currently the code contains both methods but only the second one is currently
|
||||
used.
|
||||
|
||||
Both approaches build a tree of instructions, containing matrices
|
||||
at leaves. Every node is built from OPEN_DISPS/CLOSE_DISPS and manually
|
||||
inserted FrameInterpolation_OpenChild/FrameInterpolation_Close child calls.
|
||||
These nodes contain information that should suffice to identify the matrix,
|
||||
so we can find it in an adjacent frame.
|
||||
|
||||
We can interpolate an arbitrary amount of frames between two original frames,
|
||||
given a specific interpolation factor (0=old frame, 0.5=average of frames,
|
||||
1.0=new frame).
|
||||
*/
|
||||
|
||||
extern "C" {
|
||||
|
||||
void Matrix_Init(struct GameState* gameState);
|
||||
void Matrix_Push(void);
|
||||
void Matrix_Pop(void);
|
||||
void Matrix_Get(MtxF* dest);
|
||||
void Matrix_Put(MtxF* src);
|
||||
void Matrix_Mult(MtxF* mf, u8 mode);
|
||||
void Matrix_Translate(f32 x, f32 y, f32 z, u8 mode);
|
||||
void Matrix_Scale(f32 x, f32 y, f32 z, u8 mode);
|
||||
void Matrix_RotateX(f32 x, u8 mode);
|
||||
void Matrix_RotateY(f32 y, u8 mode);
|
||||
void Matrix_RotateZ(f32 z, u8 mode);
|
||||
void Matrix_RotateZYX(s16 x, s16 y, s16 z, u8 mode);
|
||||
void Matrix_TranslateRotateZYX(Vec3f* translation, Vec3s* rotation);
|
||||
void Matrix_SetTranslateRotateYXZ(f32 translateX, f32 translateY, f32 translateZ, Vec3s* rot);
|
||||
Mtx* Matrix_MtxFToMtx(MtxF* src, Mtx* dest);
|
||||
Mtx* Matrix_ToMtx(Mtx* dest, char* file, s32 line);
|
||||
Mtx* Matrix_NewMtx(struct GraphicsContext* gfxCtx, char* file, s32 line);
|
||||
Mtx* Matrix_MtxFToNewMtx(MtxF* src, struct GraphicsContext* gfxCtx);
|
||||
void Matrix_MultVec3f(Vec3f* src, Vec3f* dest);
|
||||
void Matrix_MtxFCopy(MtxF* dest, MtxF* src);
|
||||
void Matrix_MtxToMtxF(Mtx* src, MtxF* dest);
|
||||
void Matrix_MultVec3fExt(Vec3f* src, Vec3f* dest, MtxF* mf);
|
||||
void Matrix_Transpose(MtxF* mf);
|
||||
void Matrix_ReplaceRotation(MtxF* mf);
|
||||
void Matrix_MtxFToYXZRotS(MtxF* mf, Vec3s* rotDest, s32 flag);
|
||||
void Matrix_MtxFToZYXRotS(MtxF* mf, Vec3s* rotDest, s32 flag);
|
||||
void Matrix_RotateAxis(f32 angle, Vec3f* axis, u8 mode);
|
||||
MtxF* Matrix_CheckFloats(MtxF* mf, char* file, s32 line);
|
||||
void Matrix_SetTranslateScaleMtx2(Mtx* mtx, f32 scaleX, f32 scaleY, f32 scaleZ, f32 translateX, f32 translateY,
|
||||
f32 translateZ);
|
||||
|
||||
MtxF* Matrix_GetCurrent(void);
|
||||
|
||||
void SkinMatrix_MtxFMtxFMult(MtxF* mfA, MtxF* mfB, MtxF* dest);
|
||||
|
||||
}
|
||||
|
||||
static bool invert_matrix(const float m[16], float invOut[16]);
|
||||
|
||||
using namespace std;
|
||||
|
||||
namespace {
|
||||
|
||||
enum class Op {
|
||||
OpenChild,
|
||||
CloseChild,
|
||||
|
||||
MatrixPush,
|
||||
MatrixPop,
|
||||
MatrixPut,
|
||||
MatrixMult,
|
||||
MatrixTranslate,
|
||||
MatrixScale,
|
||||
MatrixRotate1Coord,
|
||||
MatrixRotateZYX,
|
||||
MatrixTranslateRotateZYX,
|
||||
MatrixSetTranslateRotateYXZ,
|
||||
MatrixMtxFToMtx,
|
||||
MatrixToMtx,
|
||||
MatrixReplaceRotation,
|
||||
MatrixRotateAxis,
|
||||
SkinMatrixMtxFToMtx
|
||||
};
|
||||
|
||||
typedef pair<const void*, int> label;
|
||||
|
||||
union Data {
|
||||
Data() {
|
||||
}
|
||||
|
||||
struct {
|
||||
MtxF src;
|
||||
} matrix_put;
|
||||
|
||||
struct {
|
||||
MtxF mf;
|
||||
u8 mode;
|
||||
} matrix_mult;
|
||||
|
||||
struct {
|
||||
f32 x, y, z;
|
||||
u8 mode;
|
||||
} matrix_translate, matrix_scale;
|
||||
|
||||
struct {
|
||||
u32 coord;
|
||||
f32 value;
|
||||
u8 mode;
|
||||
} matrix_rotate_1_coord;
|
||||
|
||||
struct {
|
||||
s16 x, y, z;
|
||||
u8 mode;
|
||||
} matrix_rotate_zyx;
|
||||
|
||||
struct {
|
||||
Vec3f translation;
|
||||
Vec3s rotation;
|
||||
} matrix_translate_rotate_zyx;
|
||||
|
||||
struct {
|
||||
f32 translateX, translateY, translateZ;
|
||||
Vec3s rot;
|
||||
//MtxF mtx;
|
||||
bool has_mtx;
|
||||
} matrix_set_translate_rotate_yxz;
|
||||
|
||||
struct {
|
||||
MtxF src;
|
||||
Mtx* dest;
|
||||
} matrix_mtxf_to_mtx;
|
||||
|
||||
struct {
|
||||
Mtx* dest;
|
||||
MtxF src;
|
||||
bool has_adjusted;
|
||||
} matrix_to_mtx;
|
||||
|
||||
struct {
|
||||
MtxF mf;
|
||||
} matrix_replace_rotation;
|
||||
|
||||
struct {
|
||||
f32 angle;
|
||||
Vec3f axis;
|
||||
u8 mode;
|
||||
} matrix_rotate_axis;
|
||||
|
||||
struct {
|
||||
label key;
|
||||
size_t idx;
|
||||
} open_child;
|
||||
};
|
||||
|
||||
struct Path {
|
||||
map<label, vector<Path>> children;
|
||||
map<Op, vector<Data>> ops;
|
||||
vector<pair<Op, size_t>> items;
|
||||
};
|
||||
|
||||
struct Recording {
|
||||
Path root_path;
|
||||
};
|
||||
|
||||
bool is_recording;
|
||||
vector<Path*> current_path;
|
||||
uint32_t camera_epoch;
|
||||
uint32_t previous_camera_epoch;
|
||||
Recording current_recording;
|
||||
Recording previous_recording;
|
||||
|
||||
bool next_is_actor_pos_rot_matrix;
|
||||
bool has_inv_actor_mtx;
|
||||
MtxF inv_actor_mtx;
|
||||
size_t inv_actor_mtx_path_index;
|
||||
|
||||
Data& append(Op op) {
|
||||
auto& m = current_path.back()->ops[op];
|
||||
current_path.back()->items.emplace_back(op, m.size());
|
||||
return m.emplace_back();
|
||||
}
|
||||
|
||||
struct InterpolateCtx {
|
||||
float step;
|
||||
float w;
|
||||
unordered_map<Mtx*, MtxF> mtx_replacements;
|
||||
MtxF tmp_mtxf, tmp_mtxf2;
|
||||
Vec3f tmp_vec3f;
|
||||
Vec3s tmp_vec3s;
|
||||
MtxF actor_mtx;
|
||||
|
||||
MtxF* new_replacement(Mtx* addr) {
|
||||
return &mtx_replacements[addr];
|
||||
}
|
||||
|
||||
void interpolate_mtxf(MtxF* res, MtxF* o, MtxF* n) {
|
||||
for (size_t i = 0; i < 4; i++) {
|
||||
for (size_t j = 0; j < 4; j++) {
|
||||
res->mf[i][j] = w * o->mf[i][j] + step * n->mf[i][j];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
float lerp(f32 o, f32 n) {
|
||||
return w * o + step * n;
|
||||
}
|
||||
|
||||
void lerp_vec3f(Vec3f* res, Vec3f* o, Vec3f* n) {
|
||||
res->x = lerp(o->x, n->x);
|
||||
res->y = lerp(o->y, n->y);
|
||||
res->z = lerp(o->z, n->z);
|
||||
}
|
||||
|
||||
float interpolate_angle(f32 o, f32 n) {
|
||||
if (o == n)
|
||||
return n;
|
||||
o = fmodf(o, 2 * M_PI);
|
||||
if (o < 0.0f) {
|
||||
o += 2 * M_PI;
|
||||
}
|
||||
n = fmodf(n, 2 * M_PI);
|
||||
if (n < 0.0f) {
|
||||
n += 2 * M_PI;
|
||||
}
|
||||
if (fabsf(o - n) > M_PI) {
|
||||
if (o < n) {
|
||||
o += 2 * M_PI;
|
||||
} else {
|
||||
n += 2 * M_PI;
|
||||
}
|
||||
}
|
||||
if (fabsf(o - n) > M_PI / 2) {
|
||||
//return n;
|
||||
}
|
||||
return lerp(o, n);
|
||||
}
|
||||
|
||||
s16 interpolate_angle(s16 os, s16 ns) {
|
||||
if (os == ns)
|
||||
return ns;
|
||||
int o = (u16)os;
|
||||
int n = (u16)ns;
|
||||
u16 res;
|
||||
int diff = o - n;
|
||||
if (-0x8000 <= diff && diff <= 0x8000) {
|
||||
if (diff < -0x4000 || diff > 0x4000) {
|
||||
return ns;
|
||||
}
|
||||
res = (u16)(w * o + step * n);
|
||||
} else {
|
||||
if (o < n) {
|
||||
o += 0x10000;
|
||||
} else {
|
||||
n += 0x10000;
|
||||
}
|
||||
diff = o - n;
|
||||
if (diff < -0x4000 || diff > 0x4000) {
|
||||
return ns;
|
||||
}
|
||||
res = (u16)(w * o + step * n);
|
||||
}
|
||||
if (os / 327 == ns / 327 && (s16)res / 327 != os / 327) {
|
||||
int bp = 0;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
void interpolate_angles(Vec3s* res, Vec3s* o, Vec3s* n) {
|
||||
res->x = interpolate_angle(o->x, n->x);
|
||||
res->y = interpolate_angle(o->y, n->y);
|
||||
res->z = interpolate_angle(o->z, n->z);
|
||||
}
|
||||
|
||||
void interpolate_branch(Path* old_path, Path *new_path) {
|
||||
for (auto& item : new_path->items) {
|
||||
Data& new_op = new_path->ops[item.first][item.second];
|
||||
|
||||
if (item.first == Op::OpenChild) {
|
||||
if (auto it = old_path->children.find(new_op.open_child.key);
|
||||
it != old_path->children.end() && new_op.open_child.idx < it->second.size()) {
|
||||
interpolate_branch(&it->second[new_op.open_child.idx],
|
||||
&new_path->children.find(new_op.open_child.key)->second[new_op.open_child.idx]);
|
||||
} else {
|
||||
interpolate_branch(
|
||||
&new_path->children.find(new_op.open_child.key)->second[new_op.open_child.idx],
|
||||
&new_path->children.find(new_op.open_child.key)->second[new_op.open_child.idx]);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
if (auto it = old_path->ops.find(item.first); it != old_path->ops.end()) {
|
||||
if (item.second < it->second.size()) {
|
||||
Data& old_op = it->second[item.second];
|
||||
switch (item.first) {
|
||||
case Op::OpenChild:
|
||||
break;
|
||||
case Op::CloseChild:
|
||||
break;
|
||||
|
||||
case Op::MatrixPush:
|
||||
Matrix_Push();
|
||||
break;
|
||||
|
||||
case Op::MatrixPop:
|
||||
Matrix_Pop();
|
||||
break;
|
||||
|
||||
case Op::MatrixPut:
|
||||
interpolate_mtxf(&tmp_mtxf, &old_op.matrix_put.src, &new_op.matrix_put.src);
|
||||
Matrix_Put(&tmp_mtxf);
|
||||
break;
|
||||
|
||||
case Op::MatrixMult:
|
||||
interpolate_mtxf(&tmp_mtxf, &old_op.matrix_mult.mf, &new_op.matrix_mult.mf);
|
||||
Matrix_Mult(&tmp_mtxf, new_op.matrix_mult.mode);
|
||||
break;
|
||||
|
||||
case Op::MatrixTranslate:
|
||||
Matrix_Translate(lerp(old_op.matrix_translate.x, new_op.matrix_translate.x),
|
||||
lerp(old_op.matrix_translate.y, new_op.matrix_translate.y),
|
||||
lerp(old_op.matrix_translate.z, new_op.matrix_translate.z),
|
||||
new_op.matrix_translate.mode);
|
||||
break;
|
||||
|
||||
case Op::MatrixScale:
|
||||
Matrix_Scale(lerp(old_op.matrix_scale.x, new_op.matrix_scale.x),
|
||||
lerp(old_op.matrix_scale.y, new_op.matrix_scale.y),
|
||||
lerp(old_op.matrix_scale.z, new_op.matrix_scale.z),
|
||||
new_op.matrix_scale.mode);
|
||||
break;
|
||||
|
||||
case Op::MatrixRotate1Coord: {
|
||||
float v = interpolate_angle(old_op.matrix_rotate_1_coord.value, new_op.matrix_rotate_1_coord.value);
|
||||
u8 mode = new_op.matrix_rotate_1_coord.mode;
|
||||
switch (new_op.matrix_rotate_1_coord.coord) {
|
||||
case 0:
|
||||
Matrix_RotateX(v, mode);
|
||||
break;
|
||||
|
||||
case 1:
|
||||
Matrix_RotateY(v, mode);
|
||||
break;
|
||||
|
||||
case 2:
|
||||
Matrix_RotateZ(v, mode);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case Op::MatrixRotateZYX:
|
||||
Matrix_RotateZYX(interpolate_angle(old_op.matrix_rotate_zyx.x, new_op.matrix_rotate_zyx.x),
|
||||
interpolate_angle(old_op.matrix_rotate_zyx.y, new_op.matrix_rotate_zyx.y),
|
||||
interpolate_angle(old_op.matrix_rotate_zyx.z, new_op.matrix_rotate_zyx.z),
|
||||
new_op.matrix_rotate_zyx.mode);
|
||||
break;
|
||||
|
||||
case Op::MatrixTranslateRotateZYX:
|
||||
lerp_vec3f(&tmp_vec3f, &old_op.matrix_translate_rotate_zyx.translation, &new_op.matrix_translate_rotate_zyx.translation);
|
||||
interpolate_angles(&tmp_vec3s, &old_op.matrix_translate_rotate_zyx.rotation, &new_op.matrix_translate_rotate_zyx.rotation);
|
||||
Matrix_TranslateRotateZYX(&tmp_vec3f, &tmp_vec3s);
|
||||
break;
|
||||
|
||||
case Op::MatrixSetTranslateRotateYXZ:
|
||||
interpolate_angles(&tmp_vec3s, &old_op.matrix_set_translate_rotate_yxz.rot,
|
||||
&new_op.matrix_set_translate_rotate_yxz.rot);
|
||||
Matrix_SetTranslateRotateYXZ(lerp(old_op.matrix_set_translate_rotate_yxz.translateX,
|
||||
new_op.matrix_set_translate_rotate_yxz.translateX),
|
||||
lerp(old_op.matrix_set_translate_rotate_yxz.translateY,
|
||||
new_op.matrix_set_translate_rotate_yxz.translateY),
|
||||
lerp(old_op.matrix_set_translate_rotate_yxz.translateZ,
|
||||
new_op.matrix_set_translate_rotate_yxz.translateZ),
|
||||
&tmp_vec3s);
|
||||
if (new_op.matrix_set_translate_rotate_yxz.has_mtx && old_op.matrix_set_translate_rotate_yxz.has_mtx) {
|
||||
actor_mtx = *Matrix_GetCurrent();
|
||||
}
|
||||
break;
|
||||
|
||||
case Op::MatrixMtxFToMtx:
|
||||
interpolate_mtxf(new_replacement(new_op.matrix_mtxf_to_mtx.dest),
|
||||
&old_op.matrix_mtxf_to_mtx.src, &new_op.matrix_mtxf_to_mtx.src);
|
||||
break;
|
||||
|
||||
case Op::MatrixToMtx: {
|
||||
//*new_replacement(new_op.matrix_to_mtx.dest) = *Matrix_GetCurrent();
|
||||
if (old_op.matrix_to_mtx.has_adjusted && new_op.matrix_to_mtx.has_adjusted) {
|
||||
interpolate_mtxf(&tmp_mtxf, &old_op.matrix_to_mtx.src, &new_op.matrix_to_mtx.src);
|
||||
SkinMatrix_MtxFMtxFMult(&actor_mtx, &tmp_mtxf, new_replacement(new_op.matrix_to_mtx.dest));
|
||||
} else {
|
||||
interpolate_mtxf(new_replacement(new_op.matrix_to_mtx.dest),
|
||||
&old_op.matrix_to_mtx.src, &new_op.matrix_to_mtx.src);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case Op::MatrixReplaceRotation:
|
||||
interpolate_mtxf(&tmp_mtxf, &old_op.matrix_replace_rotation.mf, &new_op.matrix_replace_rotation.mf);
|
||||
Matrix_ReplaceRotation(&tmp_mtxf);
|
||||
break;
|
||||
|
||||
case Op::MatrixRotateAxis:
|
||||
lerp_vec3f(&tmp_vec3f, &old_op.matrix_rotate_axis.axis, &new_op.matrix_rotate_axis.axis);
|
||||
Matrix_RotateAxis(interpolate_angle(old_op.matrix_rotate_axis.angle, new_op.matrix_rotate_axis.angle),
|
||||
&tmp_vec3f, new_op.matrix_rotate_axis.mode);
|
||||
break;
|
||||
|
||||
case Op::SkinMatrixMtxFToMtx:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
unordered_map<Mtx*, MtxF> FrameInterpolation_Interpolate(float step) {
|
||||
InterpolateCtx ctx;
|
||||
ctx.step = step;
|
||||
ctx.w = 1.0f - step;
|
||||
ctx.interpolate_branch(&previous_recording.root_path, ¤t_recording.root_path);
|
||||
return ctx.mtx_replacements;
|
||||
}
|
||||
|
||||
void FrameInterpolation_StartRecord(void) {
|
||||
previous_recording = move(current_recording);
|
||||
current_recording = {};
|
||||
current_path.clear();
|
||||
current_path.push_back(¤t_recording.root_path);
|
||||
if (CVar_GetS32("g60FPS", 0) != 0) {
|
||||
is_recording = true;
|
||||
}
|
||||
}
|
||||
|
||||
void FrameInterpolation_StopRecord(void) {
|
||||
previous_camera_epoch = camera_epoch;
|
||||
is_recording = false;
|
||||
}
|
||||
|
||||
void FrameInterpolation_RecordOpenChild(const void* a, int b) {
|
||||
if (!is_recording)
|
||||
return;
|
||||
label key = { a, b };
|
||||
auto& m = current_path.back()->children[key];
|
||||
append(Op::OpenChild).open_child = { key, m.size() };
|
||||
current_path.push_back(&m.emplace_back());
|
||||
}
|
||||
|
||||
void FrameInterpolation_RecordCloseChild(void) {
|
||||
if (!is_recording)
|
||||
return;
|
||||
//append(Op::CloseChild);
|
||||
if (has_inv_actor_mtx && current_path.size() == inv_actor_mtx_path_index) {
|
||||
has_inv_actor_mtx = false;
|
||||
}
|
||||
current_path.pop_back();
|
||||
}
|
||||
|
||||
void FrameInterpolation_DontInterpolateCamera(void) {
|
||||
camera_epoch = previous_camera_epoch + 1;
|
||||
}
|
||||
|
||||
int FrameInterpolation_GetCameraEpoch(void) {
|
||||
return (int)camera_epoch;
|
||||
}
|
||||
|
||||
void FrameInterpolation_RecordActorPosRotMatrix(void) {
|
||||
if (!is_recording)
|
||||
return;
|
||||
next_is_actor_pos_rot_matrix = true;
|
||||
}
|
||||
|
||||
void FrameInterpolation_RecordMatrixPush(void) {
|
||||
if (!is_recording)
|
||||
return;
|
||||
append(Op::MatrixPush);
|
||||
}
|
||||
|
||||
void FrameInterpolation_RecordMatrixPop(void) {
|
||||
if (!is_recording)
|
||||
return;
|
||||
append(Op::MatrixPop);
|
||||
}
|
||||
|
||||
void FrameInterpolation_RecordMatrixPut(MtxF* src) {
|
||||
if (!is_recording)
|
||||
return;
|
||||
append(Op::MatrixPut).matrix_put = { *src };
|
||||
}
|
||||
|
||||
void FrameInterpolation_RecordMatrixMult(MtxF* mf, u8 mode) {
|
||||
if (!is_recording)
|
||||
return;
|
||||
append(Op::MatrixMult).matrix_mult = { *mf, mode };
|
||||
}
|
||||
|
||||
void FrameInterpolation_RecordMatrixTranslate(f32 x, f32 y, f32 z, u8 mode) {
|
||||
if (!is_recording)
|
||||
return;
|
||||
append(Op::MatrixTranslate).matrix_translate = { x, y, z, mode };
|
||||
}
|
||||
|
||||
void FrameInterpolation_RecordMatrixScale(f32 x, f32 y, f32 z, u8 mode) {
|
||||
if (!is_recording)
|
||||
return;
|
||||
append(Op::MatrixScale).matrix_scale = { x, y, z, mode };
|
||||
}
|
||||
|
||||
void FrameInterpolation_RecordMatrixRotate1Coord(u32 coord, f32 value, u8 mode) {
|
||||
if (!is_recording)
|
||||
return;
|
||||
append(Op::MatrixRotate1Coord).matrix_rotate_1_coord = { coord, value, mode };
|
||||
}
|
||||
|
||||
void FrameInterpolation_RecordMatrixRotateZYX(s16 x, s16 y, s16 z, u8 mode) {
|
||||
if (!is_recording)
|
||||
return;
|
||||
append(Op::MatrixRotateZYX).matrix_rotate_zyx = { x, y, z, mode };
|
||||
}
|
||||
|
||||
void FrameInterpolation_RecordMatrixTranslateRotateZYX(Vec3f* translation, Vec3s* rotation) {
|
||||
if (!is_recording)
|
||||
return;
|
||||
append(Op::MatrixTranslateRotateZYX).matrix_translate_rotate_zyx = { *translation, *rotation };
|
||||
}
|
||||
|
||||
void FrameInterpolation_RecordMatrixSetTranslateRotateYXZ(f32 translateX, f32 translateY, f32 translateZ, Vec3s* rot) {
|
||||
if (!is_recording)
|
||||
return;
|
||||
auto& d = append(Op::MatrixSetTranslateRotateYXZ).matrix_set_translate_rotate_yxz = { translateX, translateY, translateZ,
|
||||
*rot };
|
||||
if (next_is_actor_pos_rot_matrix) {
|
||||
d.has_mtx = true;
|
||||
//d.mtx = *Matrix_GetCurrent();
|
||||
invert_matrix((const float *)Matrix_GetCurrent()->mf, (float *)inv_actor_mtx.mf);
|
||||
next_is_actor_pos_rot_matrix = false;
|
||||
has_inv_actor_mtx = true;
|
||||
inv_actor_mtx_path_index = current_path.size();
|
||||
}
|
||||
}
|
||||
|
||||
void FrameInterpolation_RecordMatrixMtxFToMtx(MtxF* src, Mtx* dest) {
|
||||
if (!is_recording)
|
||||
return;
|
||||
append(Op::MatrixMtxFToMtx).matrix_mtxf_to_mtx = { *src, dest };
|
||||
}
|
||||
|
||||
void FrameInterpolation_RecordMatrixToMtx(Mtx* dest, char* file, s32 line) {
|
||||
if (!is_recording)
|
||||
return;
|
||||
auto& d = append(Op::MatrixToMtx).matrix_to_mtx = { dest };
|
||||
if (has_inv_actor_mtx) {
|
||||
d.has_adjusted = true;
|
||||
SkinMatrix_MtxFMtxFMult(&inv_actor_mtx, Matrix_GetCurrent(), &d.src);
|
||||
} else {
|
||||
d.src = *Matrix_GetCurrent();
|
||||
}
|
||||
}
|
||||
|
||||
void FrameInterpolation_RecordMatrixReplaceRotation(MtxF* mf) {
|
||||
if (!is_recording)
|
||||
return;
|
||||
append(Op::MatrixReplaceRotation).matrix_replace_rotation = { *mf };
|
||||
}
|
||||
|
||||
void FrameInterpolation_RecordMatrixRotateAxis(f32 angle, Vec3f* axis, u8 mode) {
|
||||
if (!is_recording)
|
||||
return;
|
||||
append(Op::MatrixRotateAxis).matrix_rotate_axis = { angle, *axis, mode };
|
||||
}
|
||||
|
||||
void FrameInterpolation_RecordSkinMatrixMtxFToMtx(MtxF* src, Mtx* dest) {
|
||||
if (!is_recording)
|
||||
return;
|
||||
FrameInterpolation_RecordMatrixMtxFToMtx(src, dest);
|
||||
}
|
||||
|
||||
// https://stackoverflow.com/questions/1148309/inverting-a-4x4-matrix
|
||||
static bool invert_matrix(const float m[16], float invOut[16]) {
|
||||
float inv[16], det;
|
||||
int i;
|
||||
|
||||
inv[0] = m[5] * m[10] * m[15] -
|
||||
m[5] * m[11] * m[14] -
|
||||
m[9] * m[6] * m[15] +
|
||||
m[9] * m[7] * m[14] +
|
||||
m[13] * m[6] * m[11] -
|
||||
m[13] * m[7] * m[10];
|
||||
|
||||
inv[4] = -m[4] * m[10] * m[15] +
|
||||
m[4] * m[11] * m[14] +
|
||||
m[8] * m[6] * m[15] -
|
||||
m[8] * m[7] * m[14] -
|
||||
m[12] * m[6] * m[11] +
|
||||
m[12] * m[7] * m[10];
|
||||
|
||||
inv[8] = m[4] * m[9] * m[15] -
|
||||
m[4] * m[11] * m[13] -
|
||||
m[8] * m[5] * m[15] +
|
||||
m[8] * m[7] * m[13] +
|
||||
m[12] * m[5] * m[11] -
|
||||
m[12] * m[7] * m[9];
|
||||
|
||||
inv[12] = -m[4] * m[9] * m[14] +
|
||||
m[4] * m[10] * m[13] +
|
||||
m[8] * m[5] * m[14] -
|
||||
m[8] * m[6] * m[13] -
|
||||
m[12] * m[5] * m[10] +
|
||||
m[12] * m[6] * m[9];
|
||||
|
||||
inv[1] = -m[1] * m[10] * m[15] +
|
||||
m[1] * m[11] * m[14] +
|
||||
m[9] * m[2] * m[15] -
|
||||
m[9] * m[3] * m[14] -
|
||||
m[13] * m[2] * m[11] +
|
||||
m[13] * m[3] * m[10];
|
||||
|
||||
inv[5] = m[0] * m[10] * m[15] -
|
||||
m[0] * m[11] * m[14] -
|
||||
m[8] * m[2] * m[15] +
|
||||
m[8] * m[3] * m[14] +
|
||||
m[12] * m[2] * m[11] -
|
||||
m[12] * m[3] * m[10];
|
||||
|
||||
inv[9] = -m[0] * m[9] * m[15] +
|
||||
m[0] * m[11] * m[13] +
|
||||
m[8] * m[1] * m[15] -
|
||||
m[8] * m[3] * m[13] -
|
||||
m[12] * m[1] * m[11] +
|
||||
m[12] * m[3] * m[9];
|
||||
|
||||
inv[13] = m[0] * m[9] * m[14] -
|
||||
m[0] * m[10] * m[13] -
|
||||
m[8] * m[1] * m[14] +
|
||||
m[8] * m[2] * m[13] +
|
||||
m[12] * m[1] * m[10] -
|
||||
m[12] * m[2] * m[9];
|
||||
|
||||
inv[2] = m[1] * m[6] * m[15] -
|
||||
m[1] * m[7] * m[14] -
|
||||
m[5] * m[2] * m[15] +
|
||||
m[5] * m[3] * m[14] +
|
||||
m[13] * m[2] * m[7] -
|
||||
m[13] * m[3] * m[6];
|
||||
|
||||
inv[6] = -m[0] * m[6] * m[15] +
|
||||
m[0] * m[7] * m[14] +
|
||||
m[4] * m[2] * m[15] -
|
||||
m[4] * m[3] * m[14] -
|
||||
m[12] * m[2] * m[7] +
|
||||
m[12] * m[3] * m[6];
|
||||
|
||||
inv[10] = m[0] * m[5] * m[15] -
|
||||
m[0] * m[7] * m[13] -
|
||||
m[4] * m[1] * m[15] +
|
||||
m[4] * m[3] * m[13] +
|
||||
m[12] * m[1] * m[7] -
|
||||
m[12] * m[3] * m[5];
|
||||
|
||||
inv[14] = -m[0] * m[5] * m[14] +
|
||||
m[0] * m[6] * m[13] +
|
||||
m[4] * m[1] * m[14] -
|
||||
m[4] * m[2] * m[13] -
|
||||
m[12] * m[1] * m[6] +
|
||||
m[12] * m[2] * m[5];
|
||||
|
||||
inv[3] = -m[1] * m[6] * m[11] +
|
||||
m[1] * m[7] * m[10] +
|
||||
m[5] * m[2] * m[11] -
|
||||
m[5] * m[3] * m[10] -
|
||||
m[9] * m[2] * m[7] +
|
||||
m[9] * m[3] * m[6];
|
||||
|
||||
inv[7] = m[0] * m[6] * m[11] -
|
||||
m[0] * m[7] * m[10] -
|
||||
m[4] * m[2] * m[11] +
|
||||
m[4] * m[3] * m[10] +
|
||||
m[8] * m[2] * m[7] -
|
||||
m[8] * m[3] * m[6];
|
||||
|
||||
inv[11] = -m[0] * m[5] * m[11] +
|
||||
m[0] * m[7] * m[9] +
|
||||
m[4] * m[1] * m[11] -
|
||||
m[4] * m[3] * m[9] -
|
||||
m[8] * m[1] * m[7] +
|
||||
m[8] * m[3] * m[5];
|
||||
|
||||
inv[15] = m[0] * m[5] * m[10] -
|
||||
m[0] * m[6] * m[9] -
|
||||
m[4] * m[1] * m[10] +
|
||||
m[4] * m[2] * m[9] +
|
||||
m[8] * m[1] * m[6] -
|
||||
m[8] * m[2] * m[5];
|
||||
|
||||
det = m[0] * inv[0] + m[1] * inv[4] + m[2] * inv[8] + m[3] * inv[12];
|
||||
|
||||
if (det == 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
det = 1.0 / det;
|
||||
|
||||
for (i = 0; i < 16; i++) {
|
||||
invOut[i] = inv[i] * det;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
61
soh/soh/frame_interpolation.h
Normal file
61
soh/soh/frame_interpolation.h
Normal file
|
@ -0,0 +1,61 @@
|
|||
#pragma once
|
||||
|
||||
#include "include/z64math.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
#include <unordered_map>
|
||||
|
||||
std::unordered_map<Mtx*, MtxF> FrameInterpolation_Interpolate(float step);
|
||||
|
||||
extern "C" {
|
||||
|
||||
#endif
|
||||
|
||||
void FrameInterpolation_StartRecord(void);
|
||||
|
||||
void FrameInterpolation_StopRecord(void);
|
||||
|
||||
void FrameInterpolation_RecordOpenChild(const void* a, int b);
|
||||
|
||||
void FrameInterpolation_RecordCloseChild(void);
|
||||
|
||||
void FrameInterpolation_DontInterpolateCamera(void);
|
||||
|
||||
int FrameInterpolation_GetCameraEpoch(void);
|
||||
|
||||
void FrameInterpolation_RecordActorPosRotMatrix(void);
|
||||
|
||||
void FrameInterpolation_RecordMatrixPush(void);
|
||||
|
||||
void FrameInterpolation_RecordMatrixPop(void);
|
||||
|
||||
void FrameInterpolation_RecordMatrixPut(MtxF* src);
|
||||
|
||||
void FrameInterpolation_RecordMatrixMult(MtxF* mf, u8 mode);
|
||||
|
||||
void FrameInterpolation_RecordMatrixTranslate(f32 x, f32 y, f32 z, u8 mode);
|
||||
|
||||
void FrameInterpolation_RecordMatrixScale(f32 x, f32 y, f32 z, u8 mode);
|
||||
|
||||
void FrameInterpolation_RecordMatrixRotate1Coord(u32 coord, f32 value, u8 mode);
|
||||
|
||||
void FrameInterpolation_RecordMatrixRotateZYX(s16 x, s16 y, s16 z, u8 mode);
|
||||
|
||||
void FrameInterpolation_RecordMatrixTranslateRotateZYX(Vec3f* translation, Vec3s* rotation);
|
||||
|
||||
void FrameInterpolation_RecordMatrixSetTranslateRotateYXZ(f32 translateX, f32 translateY, f32 translateZ, Vec3s* rot);
|
||||
|
||||
void FrameInterpolation_RecordMatrixMtxFToMtx(MtxF* src, Mtx* dest);
|
||||
|
||||
void FrameInterpolation_RecordMatrixToMtx(Mtx* dest, char* file, s32 line);
|
||||
|
||||
void FrameInterpolation_RecordMatrixReplaceRotation(MtxF* mf);
|
||||
|
||||
void FrameInterpolation_RecordMatrixRotateAxis(f32 angle, Vec3f* axis, u8 mode);
|
||||
|
||||
void FrameInterpolation_RecordSkinMatrixMtxFToMtx(MtxF* src, Mtx* dest);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
|
@ -1,4 +1,4 @@
|
|||
const char gBuildVersion[] = "DECKARD ALFA (1.0.0)";
|
||||
const char gBuildVersion[] = "ROY ALFA (2.0.0)";
|
||||
const char gBuildTeam[] = "github.com/harbourmasters";
|
||||
const char gBuildDate[] = __DATE__ " " __TIME__;
|
||||
const char gBuildMakeOption[] = "";
|
||||
|
|
|
@ -6,9 +6,6 @@
|
|||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#define AUDIO_HEAP_SIZE 0x38000
|
||||
#define SYSTEM_HEAP_SIZE (1024 * 1024 * 128)
|
||||
|
||||
u8* gAudioHeap;
|
||||
u8* gSystemHeap;
|
||||
|
||||
|
|
|
@ -431,6 +431,8 @@ static struct RunFrameContext {
|
|||
|
||||
extern AudioMgr gAudioMgr;
|
||||
|
||||
extern void ProcessSaveStateRequests(void);
|
||||
|
||||
static void RunFrame()
|
||||
{
|
||||
u32 size;
|
||||
|
@ -476,7 +478,10 @@ static void RunFrame()
|
|||
|
||||
Graph_StartFrame();
|
||||
|
||||
// TODO: Workaround for rumble being too long. Implement os thread functions.
|
||||
for (int i = 0; i < 3; i++) {
|
||||
PadMgr_ThreadEntry(&gPadMgr);
|
||||
}
|
||||
|
||||
Graph_Update(&runFrameContext.gfxCtx, runFrameContext.gameState);
|
||||
ticksB = GetPerfCounter();
|
||||
|
@ -487,6 +492,7 @@ static void RunFrame()
|
|||
//uint64_t diff = (ticksB - ticksA) / (freq / 1000);
|
||||
//printf("Frame simulated in %ims\n", diff);
|
||||
runFrameContext.state = 1;
|
||||
ProcessSaveStateRequests();
|
||||
return;
|
||||
nextFrame:;
|
||||
}
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
#include "global.h"
|
||||
|
||||
#include "soh/frame_interpolation.h"
|
||||
|
||||
// clang-format off
|
||||
Mtx gMtxClear = {
|
||||
65536, 0, 1, 0,
|
||||
|
@ -25,11 +27,13 @@ void Matrix_Init(GameState* gameState) {
|
|||
}
|
||||
|
||||
void Matrix_Push(void) {
|
||||
FrameInterpolation_RecordMatrixPush();
|
||||
Matrix_MtxFCopy(sCurrentMatrix + 1, sCurrentMatrix);
|
||||
sCurrentMatrix++;
|
||||
}
|
||||
|
||||
void Matrix_Pop(void) {
|
||||
FrameInterpolation_RecordMatrixPop();
|
||||
sCurrentMatrix--;
|
||||
ASSERT(sCurrentMatrix >= sMatrixStack, "Matrix_now >= Matrix_stack", "../sys_matrix.c", 176);
|
||||
}
|
||||
|
@ -39,6 +43,7 @@ void Matrix_Get(MtxF* dest) {
|
|||
}
|
||||
|
||||
void Matrix_Put(MtxF* src) {
|
||||
FrameInterpolation_RecordMatrixPut(src);
|
||||
Matrix_MtxFCopy(sCurrentMatrix, src);
|
||||
}
|
||||
|
||||
|
@ -47,6 +52,7 @@ MtxF* Matrix_GetCurrent(void) {
|
|||
}
|
||||
|
||||
void Matrix_Mult(MtxF* mf, u8 mode) {
|
||||
FrameInterpolation_RecordMatrixMult(mf, mode);
|
||||
MtxF* cmf = Matrix_GetCurrent();
|
||||
|
||||
if (mode == MTXMODE_APPLY) {
|
||||
|
@ -57,6 +63,7 @@ void Matrix_Mult(MtxF* mf, u8 mode) {
|
|||
}
|
||||
|
||||
void Matrix_Translate(f32 x, f32 y, f32 z, u8 mode) {
|
||||
FrameInterpolation_RecordMatrixTranslate(x, y, z, mode);
|
||||
MtxF* cmf = sCurrentMatrix;
|
||||
f32 tx;
|
||||
f32 ty;
|
||||
|
@ -80,6 +87,7 @@ void Matrix_Translate(f32 x, f32 y, f32 z, u8 mode) {
|
|||
}
|
||||
|
||||
void Matrix_Scale(f32 x, f32 y, f32 z, u8 mode) {
|
||||
FrameInterpolation_RecordMatrixScale(x, y, z, mode);
|
||||
MtxF* cmf = sCurrentMatrix;
|
||||
|
||||
if (mode == MTXMODE_APPLY) {
|
||||
|
@ -101,6 +109,7 @@ void Matrix_Scale(f32 x, f32 y, f32 z, u8 mode) {
|
|||
}
|
||||
|
||||
void Matrix_RotateX(f32 x, u8 mode) {
|
||||
FrameInterpolation_RecordMatrixRotate1Coord(0, x, mode);
|
||||
MtxF* cmf;
|
||||
f32 sin;
|
||||
f32 cos;
|
||||
|
@ -165,6 +174,7 @@ void Matrix_RotateX(f32 x, u8 mode) {
|
|||
}
|
||||
|
||||
void Matrix_RotateY(f32 y, u8 mode) {
|
||||
FrameInterpolation_RecordMatrixRotate1Coord(1, y, mode);
|
||||
MtxF* cmf;
|
||||
f32 sin;
|
||||
f32 cos;
|
||||
|
@ -229,6 +239,7 @@ void Matrix_RotateY(f32 y, u8 mode) {
|
|||
}
|
||||
|
||||
void Matrix_RotateZ(f32 z, u8 mode) {
|
||||
FrameInterpolation_RecordMatrixRotate1Coord(2, z, mode);
|
||||
MtxF* cmf;
|
||||
f32 sin;
|
||||
f32 cos;
|
||||
|
@ -299,6 +310,7 @@ void Matrix_RotateZ(f32 z, u8 mode) {
|
|||
* Original Name: Matrix_RotateXYZ, changed to reflect rotation order.
|
||||
*/
|
||||
void Matrix_RotateZYX(s16 x, s16 y, s16 z, u8 mode) {
|
||||
FrameInterpolation_RecordMatrixRotateZYX(x, y, z, mode);
|
||||
MtxF* cmf = sCurrentMatrix;
|
||||
f32 temp1;
|
||||
f32 temp2;
|
||||
|
@ -389,6 +401,7 @@ void Matrix_RotateZYX(s16 x, s16 y, s16 z, u8 mode) {
|
|||
* transformed according to whatever the matrix was previously.
|
||||
*/
|
||||
void Matrix_TranslateRotateZYX(Vec3f* translation, Vec3s* rotation) {
|
||||
FrameInterpolation_RecordMatrixTranslateRotateZYX(translation, rotation);
|
||||
MtxF* cmf = sCurrentMatrix;
|
||||
f32 sin = Math_SinS(rotation->z);
|
||||
f32 cos = Math_CosS(rotation->z);
|
||||
|
@ -530,15 +543,20 @@ void Matrix_SetTranslateRotateYXZ(f32 translateX, f32 translateY, f32 translateZ
|
|||
} else {
|
||||
cmf->yx = 0.0f;
|
||||
}
|
||||
FrameInterpolation_RecordMatrixSetTranslateRotateYXZ(translateX, translateY, translateZ, rot);
|
||||
}
|
||||
|
||||
Mtx* Matrix_MtxFToMtx(MtxF* src, Mtx* dest) {
|
||||
FrameInterpolation_RecordMatrixMtxFToMtx(src, dest);
|
||||
guMtxF2L(src, dest);
|
||||
return dest;
|
||||
}
|
||||
|
||||
Mtx* Matrix_ToMtx(Mtx* dest, char* file, s32 line) {
|
||||
return Matrix_MtxFToMtx(Matrix_CheckFloats(sCurrentMatrix, file, line), dest);
|
||||
FrameInterpolation_RecordMatrixToMtx(dest, file, line);
|
||||
guMtxF2L(Matrix_CheckFloats(sCurrentMatrix, file, line), dest);
|
||||
return dest;
|
||||
//return Matrix_MtxFToMtx(Matrix_CheckFloats(sCurrentMatrix, file, line), dest);
|
||||
}
|
||||
|
||||
Mtx* Matrix_NewMtx(GraphicsContext* gfxCtx, char* file, s32 line) {
|
||||
|
@ -627,6 +645,7 @@ void Matrix_Transpose(MtxF* mf) {
|
|||
* seen as replacing the R rotation with `mf`, hence the function name.
|
||||
*/
|
||||
void Matrix_ReplaceRotation(MtxF* mf) {
|
||||
FrameInterpolation_RecordMatrixReplaceRotation(mf);
|
||||
MtxF* cmf = sCurrentMatrix;
|
||||
f32 acc;
|
||||
f32 temp;
|
||||
|
@ -779,6 +798,7 @@ void Matrix_MtxFToZYXRotS(MtxF* mf, Vec3s* rotDest, s32 flag) {
|
|||
* NB: `axis` is assumed to be a unit vector.
|
||||
*/
|
||||
void Matrix_RotateAxis(f32 angle, Vec3f* axis, u8 mode) {
|
||||
FrameInterpolation_RecordMatrixRotateAxis(angle, axis, mode);
|
||||
MtxF* cmf;
|
||||
f32 sin;
|
||||
f32 cos;
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
#include "objects/gameplay_keep/gameplay_keep.h"
|
||||
#include "objects/gameplay_dangeon_keep/gameplay_dangeon_keep.h"
|
||||
#include "objects/object_bdoor/object_bdoor.h"
|
||||
#include "soh/frame_interpolation.h"
|
||||
|
||||
#if defined(_MSC_VER) || defined(__GNUC__)
|
||||
#include <string.h>
|
||||
|
@ -410,6 +411,7 @@ void func_8002C124(TargetContext* targetCtx, GlobalContext* globalCtx) {
|
|||
f32 var2;
|
||||
s32 i;
|
||||
|
||||
FrameInterpolation_RecordOpenChild(actor, 0);
|
||||
player = GET_PLAYER(globalCtx);
|
||||
|
||||
spCE = 0xFF;
|
||||
|
@ -486,10 +488,12 @@ void func_8002C124(TargetContext* targetCtx, GlobalContext* globalCtx) {
|
|||
}
|
||||
}
|
||||
}
|
||||
FrameInterpolation_RecordCloseChild();
|
||||
}
|
||||
|
||||
actor = targetCtx->unk_94;
|
||||
if ((actor != NULL) && !(actor->flags & ACTOR_FLAG_27)) {
|
||||
FrameInterpolation_RecordOpenChild(actor, 1);
|
||||
NaviColor* naviColor = &sNaviColorList[actor->category];
|
||||
|
||||
POLY_XLU_DISP = Gfx_CallSetupDL(POLY_XLU_DISP, 0x7);
|
||||
|
@ -503,6 +507,7 @@ void func_8002C124(TargetContext* targetCtx, GlobalContext* globalCtx) {
|
|||
gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx, "../z_actor.c", 2153),
|
||||
G_MTX_MODELVIEW | G_MTX_LOAD);
|
||||
gSPDisplayList(POLY_XLU_DISP++, gZTargetArrowDL);
|
||||
FrameInterpolation_RecordCloseChild();
|
||||
}
|
||||
|
||||
CLOSE_DISPS(globalCtx->state.gfxCtx, "../z_actor.c", 2158);
|
||||
|
@ -2490,6 +2495,7 @@ void Actor_Draw(GlobalContext* globalCtx, Actor* actor) {
|
|||
|
||||
Fault_AddClient(&faultClient, Actor_FaultPrint, actor, "Actor_draw");
|
||||
|
||||
FrameInterpolation_RecordOpenChild(actor, 0);
|
||||
OPEN_DISPS(globalCtx->state.gfxCtx, "../z_actor.c", 6035);
|
||||
|
||||
lights = LightContext_NewLights(&globalCtx->lightCtx, globalCtx->state.gfxCtx);
|
||||
|
@ -2497,6 +2503,7 @@ void Actor_Draw(GlobalContext* globalCtx, Actor* actor) {
|
|||
Lights_BindAll(lights, globalCtx->lightCtx.listHead, (actor->flags & ACTOR_FLAG_22) ? NULL : &actor->world.pos);
|
||||
Lights_Draw(lights, globalCtx->state.gfxCtx);
|
||||
|
||||
FrameInterpolation_RecordActorPosRotMatrix();
|
||||
if (actor->flags & ACTOR_FLAG_12) {
|
||||
Matrix_SetTranslateRotateYXZ(
|
||||
actor->world.pos.x + globalCtx->mainCamera.skyboxOffset.x,
|
||||
|
@ -2546,6 +2553,7 @@ void Actor_Draw(GlobalContext* globalCtx, Actor* actor) {
|
|||
}
|
||||
|
||||
CLOSE_DISPS(globalCtx->state.gfxCtx, "../z_actor.c", 6119);
|
||||
FrameInterpolation_RecordCloseChild();
|
||||
|
||||
Fault_RemoveClient(&faultClient);
|
||||
}
|
||||
|
|
|
@ -6,6 +6,8 @@
|
|||
|
||||
#include "overlays/actors/ovl_En_Horse/z_en_horse.h"
|
||||
|
||||
#include "soh/frame_interpolation.h"
|
||||
|
||||
s16 Camera_ChangeSettingFlags(Camera* camera, s16 setting, s16 flags);
|
||||
s32 Camera_ChangeModeFlags(Camera* camera, s16 mode, u8 flags);
|
||||
s32 Camera_QRegInit(void);
|
||||
|
@ -565,10 +567,10 @@ s16 Camera_XZAngle(Vec3f* to, Vec3f* from) {
|
|||
return DEGF_TO_BINANG(RADF_TO_DEGF(Math_FAtan2F(from->x - to->x, from->z - to->z)));
|
||||
}
|
||||
|
||||
f32 D_8015CE50;
|
||||
f32 D_8015CE54;
|
||||
CamColChk D_8015CE58;
|
||||
s16 func_80044ADC(Camera* camera, s16 yaw, s16 arg2) {
|
||||
static f32 D_8015CE50;
|
||||
static f32 D_8015CE54;
|
||||
static CamColChk D_8015CE58;
|
||||
Vec3f playerPos;
|
||||
Vec3f rotatedPos;
|
||||
Vec3f floorNorm;
|
||||
|
@ -6675,6 +6677,7 @@ s32 Camera_Special9(Camera* camera) {
|
|||
case 1:
|
||||
spec9->doorParams.timer1--;
|
||||
if (spec9->doorParams.timer1 <= 0) {
|
||||
FrameInterpolation_DontInterpolateCamera();
|
||||
camera->animState++;
|
||||
if (params->interfaceFlags & 1) {
|
||||
camPosData = Camera_GetCamBGData(camera);
|
||||
|
@ -7221,9 +7224,9 @@ s32 Camera_DbgChangeMode(Camera* camera) {
|
|||
return true;
|
||||
}
|
||||
|
||||
s16 D_8011DB08 = 0x3F0;
|
||||
s16 D_8011DB0C = 0x156;
|
||||
void func_80058E8C(Camera* camera) {
|
||||
static s16 D_8011DB08 = 0x3F0;
|
||||
static s16 D_8011DB0C = 0x156;
|
||||
s32 pad3;
|
||||
f32 sp60;
|
||||
s32 pad;
|
||||
|
@ -7299,8 +7302,8 @@ void func_80058E8C(Camera* camera) {
|
|||
}
|
||||
}
|
||||
|
||||
s32 sOOBTimer = 0;
|
||||
Vec3s Camera_Update(Camera* camera) {
|
||||
static s32 sOOBTimer = 0;
|
||||
Vec3f viewAt;
|
||||
Vec3f viewEye;
|
||||
Vec3f viewUp;
|
||||
|
@ -7968,6 +7971,8 @@ s32 Camera_SetCSParams(Camera* camera, CutsceneCameraPoint* atPoints, CutsceneCa
|
|||
camera->speedRatio = 0.0f;
|
||||
}
|
||||
|
||||
FrameInterpolation_DontInterpolateCamera();
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
#include "global.h"
|
||||
#include "objects/gameplay_keep/gameplay_keep.h"
|
||||
|
||||
#include "soh/frame_interpolation.h"
|
||||
|
||||
void EffectBlure_AddVertex(EffectBlure* this, Vec3f* p1, Vec3f* p2) {
|
||||
EffectBlureElement* elem;
|
||||
s32 numElements;
|
||||
|
@ -946,6 +948,7 @@ void EffectBlure_Draw(void* thisx, GraphicsContext* gfxCtx) {
|
|||
s32 j;
|
||||
s32 phi_t2;
|
||||
|
||||
FrameInterpolation_RecordOpenChild(this, 0);
|
||||
OPEN_DISPS(gfxCtx, "../z_eff_blure.c", 1596);
|
||||
|
||||
gSPMatrix(POLY_XLU_DISP++, &gMtxClear, G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
|
||||
|
@ -1059,4 +1062,5 @@ void EffectBlure_Draw(void* thisx, GraphicsContext* gfxCtx) {
|
|||
}
|
||||
|
||||
CLOSE_DISPS(gfxCtx, "../z_eff_blure.c", 1823);
|
||||
FrameInterpolation_RecordCloseChild();
|
||||
}
|
||||
|
|
|
@ -2,6 +2,8 @@
|
|||
#include "vt.h"
|
||||
#include "objects/gameplay_keep/gameplay_keep.h"
|
||||
|
||||
#include "soh/frame_interpolation.h"
|
||||
|
||||
static Vtx sVertices[5] = {
|
||||
VTX(-32, -32, 0, 0, 1024, 0xFF, 0xFF, 0xFF, 0xFF),
|
||||
VTX(32, 32, 0, 1024, 0, 0xFF, 0xFF, 0xFF, 0xFF),
|
||||
|
@ -154,6 +156,7 @@ void EffectShieldParticle_Draw(void* thisx, GraphicsContext* gfxCtx) {
|
|||
Color_RGBA8 primColor;
|
||||
Color_RGBA8 envColor;
|
||||
|
||||
FrameInterpolation_RecordOpenChild(this, 0);
|
||||
OPEN_DISPS(gfxCtx, "../z_eff_shield_particle.c", 272);
|
||||
|
||||
if (this != NULL) {
|
||||
|
@ -213,4 +216,5 @@ void EffectShieldParticle_Draw(void* thisx, GraphicsContext* gfxCtx) {
|
|||
}
|
||||
|
||||
CLOSE_DISPS(gfxCtx, "../z_eff_shield_particle.c", 359);
|
||||
FrameInterpolation_RecordCloseChild();
|
||||
}
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
#include "global.h"
|
||||
#include "objects/gameplay_keep/gameplay_keep.h"
|
||||
|
||||
#include "soh/frame_interpolation.h"
|
||||
|
||||
// original name: "spark"
|
||||
void EffectSpark_Init(void* thisx, void* initParamsx) {
|
||||
EffectSpark* this = (EffectSpark*)thisx;
|
||||
|
@ -152,6 +154,7 @@ void EffectSpark_Draw(void* thisx, GraphicsContext* gfxCtx) {
|
|||
u8 sp1C4;
|
||||
f32 ratio;
|
||||
|
||||
FrameInterpolation_RecordOpenChild(this, 0);
|
||||
OPEN_DISPS(gfxCtx, "../z_eff_spark.c", 293);
|
||||
|
||||
if (this != NULL) {
|
||||
|
@ -274,4 +277,5 @@ void EffectSpark_Draw(void* thisx, GraphicsContext* gfxCtx) {
|
|||
|
||||
end:
|
||||
CLOSE_DISPS(gfxCtx, "../z_eff_spark.c", 498);
|
||||
FrameInterpolation_RecordCloseChild();
|
||||
}
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
#include "global.h"
|
||||
#include "vt.h"
|
||||
|
||||
#include "soh/frame_interpolation.h"
|
||||
|
||||
EffectSsInfo sEffectSsInfo = { 0 }; // "EffectSS2Info"
|
||||
|
||||
void EffectSs_InitInfo(GlobalContext* globalCtx, s32 tableSize) {
|
||||
|
@ -233,6 +235,7 @@ void EffectSs_Spawn(GlobalContext* globalCtx, s32 type, s32 priority, void* init
|
|||
|
||||
sEffectSsInfo.table[index].type = type;
|
||||
sEffectSsInfo.table[index].priority = priority;
|
||||
sEffectSsInfo.table[index].epoch++;
|
||||
|
||||
if (initInfo->init(globalCtx, index, &sEffectSsInfo.table[index], initParams) == 0) {
|
||||
osSyncPrintf(VT_FGCOL(GREEN));
|
||||
|
@ -284,7 +287,9 @@ void EffectSs_Draw(GlobalContext* globalCtx, s32 index) {
|
|||
EffectSs* effectSs = &sEffectSsInfo.table[index];
|
||||
|
||||
if (effectSs->draw != NULL) {
|
||||
FrameInterpolation_RecordOpenChild(effectSs, effectSs->epoch);
|
||||
effectSs->draw(globalCtx, index, effectSs);
|
||||
FrameInterpolation_RecordCloseChild();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -498,7 +498,7 @@ void HealthMeter_HandleCriticalAlarm(GlobalContext* globalCtx) {
|
|||
if (interfaceCtx->unk_22A <= 0) {
|
||||
interfaceCtx->unk_22A = 0;
|
||||
interfaceCtx->unk_22C = 0;
|
||||
if (!Player_InCsMode(globalCtx) && (globalCtx->pauseCtx.state == 0) &&
|
||||
if (CVar_GetS32("gLowHpAlarm", 0) == 0 && !Player_InCsMode(globalCtx) && (globalCtx->pauseCtx.state == 0) &&
|
||||
(globalCtx->pauseCtx.debugState == 0) && HealthMeter_IsCritical() && !Gameplay_InCsMode(globalCtx)) {
|
||||
func_80078884(NA_SE_SY_HITPOINT_ALARM);
|
||||
}
|
||||
|
|
|
@ -4,6 +4,8 @@
|
|||
|
||||
#include "objects/gameplay_keep/gameplay_keep.h"
|
||||
|
||||
#include "soh/frame_interpolation.h"
|
||||
|
||||
#define LIGHTS_BUFFER_SIZE 32
|
||||
//#define LIGHTS_BUFFER_SIZE 1024 // Kill me
|
||||
|
||||
|
@ -434,12 +436,14 @@ void Lights_DrawGlow(GlobalContext* globalCtx) {
|
|||
if ((info->type == LIGHT_POINT_GLOW) && (params->drawGlow)) {
|
||||
scale = SQ(params->radius) * 0.0000026f;
|
||||
|
||||
FrameInterpolation_RecordOpenChild(node, 0);
|
||||
gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, params->color[0], params->color[1], params->color[2], 50);
|
||||
Matrix_Translate(params->x, params->y, params->z, MTXMODE_NEW);
|
||||
Matrix_Scale(scale, scale, scale, MTXMODE_APPLY);
|
||||
gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx, "../z_lights.c", 918),
|
||||
G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
|
||||
gSPDisplayList(POLY_XLU_DISP++, gGlowCircleDL);
|
||||
FrameInterpolation_RecordCloseChild();
|
||||
}
|
||||
|
||||
node = node->next;
|
||||
|
|
|
@ -52,7 +52,7 @@ static MapMarkDataOverlay sMapMarkDataOvl = {
|
|||
gMapMarkDataTable,
|
||||
};
|
||||
|
||||
static MapMarkData** sLoadedMarkDataTable;
|
||||
MapMarkData** sLoadedMarkDataTable;
|
||||
|
||||
void MapMark_Init(GlobalContext* globalCtx) {
|
||||
MapMarkDataOverlay* overlay = &sMapMarkDataOvl;
|
||||
|
|
|
@ -4,9 +4,9 @@
|
|||
|
||||
static s16 sDisableAttention = false;
|
||||
static s16 sUnused = -1;
|
||||
static s32 sPrevFrameCs1100 = -4096;
|
||||
s32 sPrevFrameCs1100 = -4096;
|
||||
|
||||
#include "z_onepointdemo_data.c"
|
||||
#include "z_onepointdemo_data.inc"
|
||||
|
||||
void OnePointCutscene_AddVecSphToVec3f(Vec3f* dst, Vec3f* src, VecSph* vecSph) {
|
||||
Vec3f out;
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
#include "global.h"
|
||||
|
||||
static CutsceneCameraPoint D_8012013C[14] = {
|
||||
CutsceneCameraPoint D_8012013C[14] = {
|
||||
{ CS_CMD_CONTINUE, 25, 40, 70.79991f, { -1814, 533, -1297 } },
|
||||
{ CS_CMD_CONTINUE, 20, 40, 70.99991f, { -1805, 434, -1293 } },
|
||||
{ CS_CMD_CONTINUE, 10, 30, 60.0f, { -1794, 323, -1280 } },
|
||||
|
@ -16,7 +16,7 @@ static CutsceneCameraPoint D_8012013C[14] = {
|
|||
{ CS_CMD_STOP, 0, 50, 60.0f, { -1974, 12, -1179 } },
|
||||
{ CS_CMD_STOP, 0, 30, 60.0f, { -1974, 12, -1179 } },
|
||||
};
|
||||
static CutsceneCameraPoint D_8012021C[14] = {
|
||||
CutsceneCameraPoint D_8012021C[14] = {
|
||||
{ CS_CMD_CONTINUE, 0, 0, 60.0f, { -1751, 604, -1233 } }, { CS_CMD_CONTINUE, 0, 0, 60.0f, { -1752, 516, -1233 } },
|
||||
{ CS_CMD_CONTINUE, 0, 0, 60.0f, { -1751, 417, -1233 } }, { CS_CMD_CONTINUE, 0, 0, 60.0f, { -1767, 306, -1219 } },
|
||||
{ CS_CMD_CONTINUE, 0, 0, 60.0f, { -1776, 257, -1205 } }, { CS_CMD_CONTINUE, 0, 0, 60.0f, { -1881, 147, -1149 } },
|
||||
|
@ -54,7 +54,7 @@ static CutsceneCameraPoint D_80120434[10] = {
|
|||
{ CS_CMD_STOP, 0, 0, 60.0f, { 0, 62, -119 } }, { CS_CMD_STOP, 0, 0, 60.0f, { 0, 62, -119 } },
|
||||
};
|
||||
|
||||
static CutsceneCameraPoint D_801204D4[14] = {
|
||||
CutsceneCameraPoint D_801204D4[14] = {
|
||||
{ CS_CMD_CONTINUE, -15, 40, 80.600006f, { -60, 332, 183 } },
|
||||
{ CS_CMD_CONTINUE, -22, 30, 80.600006f, { -60, 332, 183 } },
|
||||
{ CS_CMD_CONTINUE, -20, 38, 80.600006f, { -118, 344, 41 } },
|
||||
|
@ -70,7 +70,7 @@ static CutsceneCameraPoint D_801204D4[14] = {
|
|||
{ CS_CMD_STOP, 6, 30, 85.199936f, { 25, 127, -950 } },
|
||||
{ CS_CMD_STOP, 0, 30, 85.199936f, { 25, 127, -950 } },
|
||||
};
|
||||
static CutsceneCameraPoint D_801205B4[14] = {
|
||||
CutsceneCameraPoint D_801205B4[14] = {
|
||||
{ CS_CMD_CONTINUE, 0, 0, 60.0f, { -225, 785, -242 } },
|
||||
{ CS_CMD_CONTINUE, -21, 0, 80.600006f, { -245, 784, -242 } },
|
||||
{ CS_CMD_CONTINUE, -21, 0, 80.600006f, { -288, 485, -379 } },
|
||||
|
@ -118,18 +118,18 @@ static s16 D_801208E0 = 12;
|
|||
static s16 D_801208E4 = 90;
|
||||
static s16 D_801208E8 = 8;
|
||||
|
||||
static OnePointCsFull D_801208EC[3] = {
|
||||
OnePointCsFull D_801208EC[3] = {
|
||||
{ 0x0F, 0x08, 0x0101, 1, 0, 60.0f, 1.0f, { 0.0f, 0.0f, 0.0f }, { 0.0f, 0.0f, 0.0f } },
|
||||
{ 0x81, 0xFF, 0x0101, 1, 0, 60.0f, 1.0f, { 0.0f, -10.0f, 0.0f }, { 0.0f, 0.0f, 150.0f } },
|
||||
{ 0x12, 0xFF, 0x0000, 1, 0, 60.0f, 1.0f, { -1.0f, -1.0f, -1.0f }, { -1.0f, -1.0f, -1.0f } },
|
||||
};
|
||||
|
||||
static OnePointCsFull D_80120964[2] = {
|
||||
OnePointCsFull D_80120964[2] = {
|
||||
{ 0x8F, 0xFF, 0x0101, 1, 0, 60.0f, 1.0f, { 0.0f, 0.0f, 0.0f }, { 0.0f, 0.0f, 0.0f } },
|
||||
{ 0x81, 0xFF, 0xA121, 1, 0, 75.0f, 0.6f, { 0.0f, -10.0f, 0.0f }, { 0.0f, 0.0f, 150.0f } },
|
||||
};
|
||||
|
||||
static OnePointCsFull D_801209B4[4] = {
|
||||
OnePointCsFull D_801209B4[4] = {
|
||||
{ 0x8F, 0x08, 0x0101, 1, 0, 60.0f, 0.9f, { 0.0f, 0.0f, 0.0f }, { 0.0f, 0.0f, 0.0f } },
|
||||
{ 0x84, 0x01, 0x0100, 29, 0, 45.0f, 0.1f, { 0.0f, -10.0f, 0.0f }, { 0.0f, 0.0f, 150.0f } },
|
||||
{ 0x83, 0xFF, 0x0000, 10, 0, 60.0f, 0.2f, { 0.0f, -10.0f, 0.0f }, { 0.0f, 0.0f, 150.0f } },
|
||||
|
@ -142,7 +142,7 @@ static OnePointCsFull D_80120A54[3] = {
|
|||
{ 0x8B, 0xFF, 0x0022, 5000, 0, 75.0f, 0.005f, { 0.0f, 0.0f, -10.0f }, { -1.0f, -1.0f, -1.0f } },
|
||||
};
|
||||
|
||||
static OnePointCsFull D_80120ACC[5] = {
|
||||
OnePointCsFull D_80120ACC[5] = {
|
||||
{ 0x8F, 0xFF, 0x0442, 10, 0, 40.0f, 1.0f, { -10.0f, 45.0f, 20.0f }, { 20.0f, 30.0f, 160.0f } },
|
||||
{ 0x95, 0xFF, 0x0000, 1, 0, 40.0f, 1.0f, { -1.0f, -1.0f, -1.0f }, { -1.0f, -1.0f, -1.0f } },
|
||||
{ 0x8F, 0x01, 0x0442, 10, 0, 40.0f, 1.0f, { -10.0f, 45.0f, 20.0f }, { 20.0f, 30.0f, 160.0f } },
|
||||
|
@ -150,7 +150,7 @@ static OnePointCsFull D_80120ACC[5] = {
|
|||
{ 0x11, 0xFF, 0x0000, 1, 0, 60.0f, 1.0f, { -1.0f, -1.0f, -1.0f }, { -1.0f, -1.0f, -1.0f } },
|
||||
};
|
||||
|
||||
static OnePointCsFull D_80120B94[11] = {
|
||||
OnePointCsFull D_80120B94[11] = {
|
||||
{ 0x8F, 0x01, 0x2142, 1, 0, 40.0f, 1.0f, { 20.0f, 40.0f, 20.0f }, { -20.0f, 0.0f, -30.0f } },
|
||||
{ 0x84, 0xFF, 0x0404, 19, 5, 70.0f, 0.01f, { 0.0f, 30.0f, 20.0f }, { 120.0f, 60.0f, 120.0f } },
|
||||
{ 0x84, 0xFF, 0x0404, 20, 0, 60.0f, 0.01f, { 0.0f, 20.0f, 20.0f }, { 120.0f, 60.0f, 120.0f } },
|
||||
|
@ -164,7 +164,7 @@ static OnePointCsFull D_80120B94[11] = {
|
|||
{ 0x98, 0xFF, 0x0000, 1, 0, 50.0f, 1.0f, { -1.0f, -1.0f, -1.0f }, { -1.0f, -1.0f, -1.0f } },
|
||||
};
|
||||
|
||||
static OnePointCsFull D_80120D4C[7] = {
|
||||
OnePointCsFull D_80120D4C[7] = {
|
||||
{ 0x8F, 0x01, 0x2142, 1, 0, 40.0f, 1.0f, { 20.0f, 40.0f, 20.0f }, { -20.0f, 0.0f, -30.0f } },
|
||||
{ 0x84, 0xFF, 0x0404, 19, 5, 70.0f, 0.01f, { 0.0f, 30.0f, 20.0f }, { 120.0f, 60.0f, 120.0f } },
|
||||
{ 0x84, 0xFF, 0x0404, 20, 0, 60.0f, 0.01f, { 0.0f, 20.0f, 20.0f }, { 120.0f, 60.0f, 120.0f } },
|
||||
|
@ -185,7 +185,7 @@ static OnePointCsFull D_80120E64[8] = {
|
|||
{ 0x12, 0xFF, 0x0000, 1, 0, 60.0f, 1.0f, { -1.0f, -1.0f, -1.0f }, { -1.0f, -1.0f, -1.0f } },
|
||||
};
|
||||
|
||||
static OnePointCsFull D_80120FA4[6] = {
|
||||
OnePointCsFull D_80120FA4[6] = {
|
||||
{ 0x8F, 0x01, 0x2143, 30, 0, 70.0f, 0.4f, { 0.0f, 40.0f, 50.0f }, { 30.0f, 10.0f, -50.0f } },
|
||||
{ 0x95, 0xFF, 0x0000, 1, 0, 50.0f, 1.0f, { -1.0f, -1.0f, -1.0f }, { -1.0f, -1.0f, -1.0f } },
|
||||
{ 0x8F, 0xFF, 0x2222, 10, 0, 42.0f, 1.0f, { 0.0f, 40.0f, 0.0f }, { 0.0f, 85.0f, 45.0f } },
|
||||
|
@ -206,12 +206,12 @@ static OnePointCsFull D_8012110C[3] = {
|
|||
{ 0x12, 0xFF, 0x0000, 1, 0, 60.0f, 1.0f, { -1.0f, -1.0f, -1.0f }, { -1.0f, -1.0f, -1.0f } },
|
||||
};
|
||||
|
||||
static OnePointCsFull D_80121184[2] = {
|
||||
OnePointCsFull D_80121184[2] = {
|
||||
{ 0x83, 0x01, 0x0101, 40, 0, -1.0f, 0.1f, { 0.0f, 10.0f, 0.0f }, { 0.0f, 0.0f, 0.0f } },
|
||||
{ 0x12, 0xFF, 0x0000, 1, 0, 60.0f, 1.0f, { -1.0f, -1.0f, -1.0f }, { -1.0f, -1.0f, -1.0f } },
|
||||
};
|
||||
|
||||
static OnePointCsFull D_801211D4[2] = {
|
||||
OnePointCsFull D_801211D4[2] = {
|
||||
{ 0x8F, 0x08, 0x0101, 50, 0, 60.0f, 1.0f, { 0.0f, 10.0f, 0.0f }, { -10.0f, 85.0f, 0.0f } },
|
||||
{ 0x11, 0xFF, 0x0000, 1, 0, 60.0f, 1.0f, { -1.0f, -1.0f, -1.0f }, { -1.0f, -1.0f, -1.0f } },
|
||||
};
|
||||
|
@ -229,13 +229,13 @@ static OnePointCsFull D_80121314[1] = {
|
|||
{ 0x8F, 0x08, 0x4141, 1000, 0, 75.0f, 0.6f, { 0.0f, 0.0f, 10.0f }, { 0.0f, 0.0f, 100.0f } },
|
||||
};
|
||||
|
||||
static OnePointCsFull D_8012133C[3] = {
|
||||
OnePointCsFull D_8012133C[3] = {
|
||||
{ 0x8F, 0x01, 0x0141, 40, 0, 75.0f, 1.0f, { 0.0f, 60.0f, 0.0f }, { 0.0f, 0.0f, 100.0f } },
|
||||
{ 0x83, 0xFF, 0x2121, 20, 0, 60.0f, 0.2f, { 0.0f, -10.0f, -10.0f }, { 0.0f, 10.0f, -100.0f } },
|
||||
{ 0x11, 0xFF, 0x0000, 1, 0, 60.0f, 1.0f, { -1.0f, -1.0f, -1.0f }, { -1.0f, -1.0f, -1.0f } },
|
||||
};
|
||||
|
||||
static OnePointCsFull D_801213B4[5] = {
|
||||
OnePointCsFull D_801213B4[5] = {
|
||||
{ 0x8F, 0x08, 0xC2C2, 40, 0, 70.0f, 1.0f, { 80.0f, 0.0f, 20.0f }, { 20.0f, 0.0f, 80.0f } },
|
||||
{ 0x8B, 0x01, 0xC2C2, 120, 0, 70.0f, 0.1f, { 80.0f, 0.0f, 20.0f }, { 20.0f, 0.0f, 80.0f } },
|
||||
{ 0x8F, 0x53, 0xC2C2, 30, 0, 50.0f, 1.0f, { 60.0f, 0.0f, 20.0f }, { 60.0f, 0.0f, 60.0f } },
|
||||
|
@ -250,17 +250,17 @@ static OnePointCsFull D_8012147C[4] = {
|
|||
{ 0x11, 0xFF, 0x0000, 1, 0, 60.0f, 1.0f, { -1.0f, -1.0f, -1.0f }, { -1.0f, -1.0f, -1.0f } },
|
||||
};
|
||||
|
||||
static OnePointCsFull D_8012151C[2] = {
|
||||
OnePointCsFull D_8012151C[2] = {
|
||||
{ 0x0F, 0x01, 0x0101, 29, 0, 60.0f, 1.0f, { -700.0f, 875.0f, -100.0f }, { -550.0f, 920.0f, -150.0f } },
|
||||
{ 0x12, 0xFF, 0x0000, 1, 0, 60.0f, 1.0f, { -1.0f, -1.0f, -1.0f }, { -1.0f, -1.0f, -1.0f } },
|
||||
};
|
||||
|
||||
static OnePointCsFull D_8012156C[2] = {
|
||||
OnePointCsFull D_8012156C[2] = {
|
||||
{ 0x8F, 0x4D, 0x4242, 1, 0, 65.0f, 1.0f, { 60.0f, 30.0f, 0.0f }, { 50.0f, 20.0f, 150.0f } },
|
||||
{ 0x81, 0xFF, 0x4242, -1, 0, 65.0f, 1.0f, { -50.0f, 60.0f, 0.0f }, { -60.0f, 40.0f, 150.0f } },
|
||||
};
|
||||
|
||||
static OnePointCsFull D_801215BC[1] = {
|
||||
OnePointCsFull D_801215BC[1] = {
|
||||
{ 0x0F, 0xFF, 0x0101, 5, 0, 65.0f, 1.0f, { -1185.0f, 655.0f, 1185.0f }, { -1255.0f, 735.0f, 1255.0f } },
|
||||
};
|
||||
|
||||
|
@ -331,7 +331,7 @@ static OnePointCsFull D_80121A44[12] = {
|
|||
{ 0x12, 0xFF, 0x0000, 1, 0, 60.0f, 1.0f, { -1.0f, -1.0f, -1.0f }, { -1.0f, -1.0f, -1.0f } },
|
||||
};
|
||||
|
||||
static OnePointCsFull D_80121C24[7] = {
|
||||
OnePointCsFull D_80121C24[7] = {
|
||||
{ 0x0F, 0x05, 0x0101, 1, 0, 60.0f, 1.0f, { 0.0f, 0.0f, 0.0f }, { 0.0f, 0.0f, 0.0f } },
|
||||
{ 0x03, 0xFF, 0x0101, 89, 0, 50.0f, 0.4f, { 125.0f, 320.0f, -1500.0f }, { 125.0f, 500.0f, -1150.0f } },
|
||||
{ 0x0F, 0x08, 0x0101, 40, 4, 55.0f, 1.0f, { 0.0f, 375.0f, -1440.0f }, { 5.0f, 365.0f, -1315.0f } },
|
||||
|
@ -341,7 +341,7 @@ static OnePointCsFull D_80121C24[7] = {
|
|||
{ 0x11, 0xFF, 0x0000, 1, 0, 60.0f, 1.0f, { -1.0f, -1.0f, -1.0f }, { -1.0f, -1.0f, -1.0f } },
|
||||
};
|
||||
|
||||
static OnePointCsFull D_80121D3C[3] = {
|
||||
OnePointCsFull D_80121D3C[3] = {
|
||||
{ 0x0F, 0xFF, 0x0101, 1, 0, 60.0f, 1.0f, { 1023.0f, 738.0f, -2628.0f }, { 993.0f, 770.0f, -2740.0f } },
|
||||
{ 0x02, 0xFF, 0x0101, 4, 0, 50.0f, 1.0f, { 1255.0f, 350.0f, -1870.0f }, { 1240.0f, 575.0f, -2100.0f } },
|
||||
{ 0x0F, 0xFF, 0x0000, -1, 0, 75.0f, 1.0f, { -1.0f, -1.0f, -1.0f }, { -1.0f, -1.0f, -1.0f } },
|
||||
|
@ -359,14 +359,14 @@ static OnePointCsFull D_80121DB4[9] = {
|
|||
{ 0x12, 0xFF, 0x0000, 1, -1, -1.0f, -1.0f, { -1.0f, -1.0f, -1.0f }, { -1.0f, -1.0f, -1.0f } },
|
||||
};
|
||||
|
||||
static OnePointCsFull D_80121F1C[4] = {
|
||||
OnePointCsFull D_80121F1C[4] = {
|
||||
{ 0x0F, 0x08, 0x0101, 10, 0, 60.0f, 1.0f, { 0.0f, 0.0f, 0.0f }, { 0.0f, 0.0f, 0.0f } },
|
||||
{ 0x01, 0xFF, 0x2121, 10, 0, 50.0f, 0.5f, { 0.0f, 0.0f, 0.0f }, { 0.0f, 0.0f, 150.0f } },
|
||||
{ 0x01, 0x02, 0x2121, 23, 0, 50.0f, 0.5f, { 0.0f, 0.0f, 0.0f }, { 0.0f, 0.0f, 150.0f } },
|
||||
{ 0x11, 0xFF, 0x0000, 1, -1, -1.0f, -1.0f, { -1.0f, -1.0f, -1.0f }, { -1.0f, -1.0f, -1.0f } },
|
||||
};
|
||||
|
||||
static OnePointCsFull D_80121FBC[4] = {
|
||||
OnePointCsFull D_80121FBC[4] = {
|
||||
{ 0x0F, 0xFF, 0x0101, 5, 0, 60.0f, 1.0f, { 0.0f, 0.0f, 0.0f }, { 0.0f, 0.0f, 0.0f } },
|
||||
{ 0x01, 0xFF, 0x0101, 10, 0, 30.0f, 1.0f, { -2130.0f, 2885.0f, -1055.0f }, { -2085.0f, 2875.0f, -1145.0f } },
|
||||
{ 0x0F, 0xFF, 0x0000, 30, 0, 60.0f, 1.0f, { -1.0f, -1.0f, -1.0f }, { -1.0f, -1.0f, -1.0f } },
|
||||
|
@ -379,7 +379,7 @@ static OnePointCsFull D_8012205C[3] = {
|
|||
{ 0x01, 0x01, 0x21A1, 10, 0, 60.0f, 1.0f, { 0.0f, -10.0f, 0.0f }, { 0.0f, 10.0f, -200.0f } },
|
||||
};
|
||||
|
||||
static OnePointCsFull D_801220D4[5] = {
|
||||
OnePointCsFull D_801220D4[5] = {
|
||||
{ 0x0F, 0x01, 0x0101, 5, 0, 60.0f, 1.0f, { 0.0f, 0.0f, 0.0f }, { 0.0f, 0.0f, 0.0f } },
|
||||
{ 0x01, 0xFF, 0x4141, 10, 5, 55.0f, 0.75f, { 400.0f, -50.0f, 800.0f }, { 600.0f, -60.0f, 800.0f } },
|
||||
{ 0x01, 0xFF, 0x4141, 15, 10, 40.0f, 0.75f, { 0.0f, 0.0f, 0.0f }, { 0.0f, 10.0f, 200.0f } },
|
||||
|
@ -443,7 +443,7 @@ static OnePointCsFull D_8012269C[3] = {
|
|||
{ 0x11, 0xFF, 0x0000, 1, -1, -1.0f, -1.0f, { -1.0f, -1.0f, -1.0f }, { -1.0f, -1.0f, -1.0f } },
|
||||
};
|
||||
|
||||
static OnePointCsFull D_80122714[4] = {
|
||||
OnePointCsFull D_80122714[4] = {
|
||||
{ 0x0F, 0xFF, 0x0101, 20, 0, 45.0f, 1.0f, { -915.0f, -2185.0f, 6335.0f }, { -915.0f, -2290.0f, 6165.0f } },
|
||||
{ 0x02, 0xFF, 0x0101, -1, 0, 80.0f, 0.8f, { -920.0f, -2270.0f, 6140.0f }, { -920.0f, -2280.0f, 6070.0f } },
|
||||
{ 0x02, 0xFF, 0x0101, 20, 0, 80.0f, 0.9f, { -920.0f, -2300.0f, 6140.0f }, { -920.0f, -2300.0f, 6070.0f } },
|
||||
|
@ -512,12 +512,12 @@ static OnePointCsFull D_80122C8C[1] = {
|
|||
{ 0x0F, 0xFF, 0x0101, 999, 5, 60.0f, 1.0f, { -70.0f, 140.0f, 25.0f }, { 10.0f, 180.0f, 195.0f } },
|
||||
};
|
||||
|
||||
static OnePointCsFull D_80122CB4[2] = {
|
||||
OnePointCsFull D_80122CB4[2] = {
|
||||
{ 0x0F, 0xFF, 0x4242, 5, 0, 60.0f, 1.0f, { 0.0f, 0.0f, 1000.0f }, { 0.0f, 0.0f, 1100.0f } },
|
||||
{ 0x02, 0xFF, 0x4242, -1, 0, 60.0f, 1.0f, { 0.0f, 0.0f, -100.0f }, { 0.0f, 0.0f, 0.0f } },
|
||||
};
|
||||
|
||||
static OnePointCsFull D_80122D04[2] = {
|
||||
OnePointCsFull D_80122D04[2] = {
|
||||
{ 0x0F, 0xFF, 0x4242, 10, 0, 60.0f, 1.0f, { 0.0f, 0.0f, -100.0f }, { 0.0f, 0.0f, 0.0f } },
|
||||
{ 0x02, 0xFF, 0x4242, -1, 0, 60.0f, 1.0f, { 0.0f, 0.0f, 1000.0f }, { 0.0f, 0.0f, 1100.0f } },
|
||||
};
|
||||
|
@ -534,7 +534,7 @@ static OnePointCsFull D_80122DCC[3] = {
|
|||
{ 0x11, 0xFF, 0x0000, 1, -1, -1.0f, -1.0f, { -1.0f, -1.0f, -1.0f }, { -1.0f, -1.0f, -1.0f } },
|
||||
};
|
||||
|
||||
static OnePointCsFull D_80122E44[2][7] = {
|
||||
OnePointCsFull D_80122E44[2][7] = {
|
||||
{
|
||||
{ 0x83, 0xFF, 0x2222, 10, 5, 90.0f, 0.2f, { 50.0f, 100.0f, 140.0f }, { -30.0f, 10.0f, -20.0f } },
|
||||
{ 0x8F, 0xFF, 0x0000, 20, 0, 90.0f, 1.0f, { -1.0f, -1.0f, -1.0f }, { -1.0f, -1.0f, -1.0f } },
|
||||
|
@ -563,25 +563,25 @@ static OnePointCsFull D_80123074[5] = {
|
|||
{ 0x92, 0xFF, 0x0000, 1, 0, 60.0f, 1.0f, { -1.0f, -1.0f, -1.0f }, { -1.0f, -1.0f, -1.0f } },
|
||||
};
|
||||
|
||||
static OnePointCsFull D_8012313C[3] = {
|
||||
OnePointCsFull D_8012313C[3] = {
|
||||
{ 0x8F, 0xFF, 0xA2A2, 20, 8, 70.0f, 1.0f, { 65.0f, -150.0f, 50.0f }, { 30.0f, 10.0f, 90.0f } },
|
||||
{ 0x81, 0xFF, 0xA2A2, 100, 0, 60.0f, 1.0f, { 70.0f, -160.0f, 50.0f }, { 25.0f, 180.0f, 180.0f } },
|
||||
{ 0x92, 0xFF, 0x0000, 1, 0, 60.0f, 1.0f, { -1.0f, -1.0f, -1.0f }, { -1.0f, -1.0f, -1.0f } },
|
||||
};
|
||||
|
||||
static OnePointCsFull D_801231B4[4] = {
|
||||
OnePointCsFull D_801231B4[4] = {
|
||||
{ 0x8F, 0xC5, 0x4343, 1, 0, 50.0f, 1.0f, { 0.0f, 20.0f, 0.0f }, { 0.0f, 5.0f, -1.0f } },
|
||||
{ 0x81, 0xC5, 0x4343, 48, 0, 50.0f, 0.75f, { 0.0f, 80.0f, 0.0f }, { 0.0f, 15.0f, -1.0f } },
|
||||
{ 0x8F, 0xC5, 0x4343, 1, 5, 45.0f, 1.0f, { 0.0f, 0.0f, 30.0f }, { 30.0f, 120.0f, 60.0f } },
|
||||
{ 0x81, 0xC5, 0x4343, -1, 0, -1.0f, 1.0f, { -1.0f, -1.0f, -1.0f }, { -1.0f, -1.0f, -1.0f } },
|
||||
};
|
||||
|
||||
static OnePointCsFull D_80123254[2] = {
|
||||
OnePointCsFull D_80123254[2] = {
|
||||
{ 0x0F, 0xFF, 0x0101, 1, 0, 60.0f, 1.0f, { 0.0f, 0.0f, 0.0f }, { 0.0f, 0.0f, 0.0f } },
|
||||
{ 0x03, 0xC5, 0x0101, 49, 0, 50.0f, 0.05f, { 0.0f, 0.0f, 0.0f }, { 0.0f, 0.0f, 0.0f } },
|
||||
};
|
||||
|
||||
static OnePointCsFull D_801232A4[1] = {
|
||||
OnePointCsFull D_801232A4[1] = {
|
||||
{ 0x0F, 0x45, 0x0101, 9999, 0, 60.0f, 1.0f, { 0.0f, 0.0f, 0.0f }, { 0.0f, 0.0f, 0.0f } },
|
||||
};
|
||||
|
||||
|
@ -646,24 +646,24 @@ static OnePointCsFull D_801237CC[5] = {
|
|||
{ 0x0F, 0xFF, 0x0000, 100, -45, 75.0f, 1.0f, { -1.0f, -1.0f, -1.0f }, { -1.0f, -1.0f, -1.0f } },
|
||||
};
|
||||
|
||||
static OnePointCsFull D_80123894[3] = {
|
||||
OnePointCsFull D_80123894[3] = {
|
||||
{ 0x0F, 0xFF, 0x0101, 60, 0, 60.0f, 1.0f, { 0.0f, 0.0f, 0.0f }, { 0.0f, 0.0f, 0.0f } },
|
||||
{ 0x0F, 0xFF, 0x4242, 30, 0, 50.0f, 1.0f, { 0.0f, 28.0f, 0.0f }, { 0.0f, 20.0f, 40.0f } },
|
||||
{ 0x0D, 0xFF, 0x0000, 120, 0, 180.0f, 0.4f, { 0.0f, -5.0f, 0.0f }, { 0.0f, 2.0f, 40.0f } },
|
||||
};
|
||||
|
||||
static OnePointCsFull D_8012390C[2] = {
|
||||
OnePointCsFull D_8012390C[2] = {
|
||||
{ 0x0F, 0xFF, 0x0101, 30, 0, 60.0f, 1.0f, { 0.0f, 0.0f, 0.0f }, { 0.0f, 0.0f, 0.0f } },
|
||||
{ 0x0F, 0xFF, 0x4242, 180, 0, 60.0f, 1.0f, { 0.0f, 78.0f, 0.0f }, { 0.0f, 78.0f, 200.0f } },
|
||||
};
|
||||
|
||||
static OnePointCsFull D_8012395C[3] = {
|
||||
OnePointCsFull D_8012395C[3] = {
|
||||
{ 0x0F, 0xFF, 0x0101, 60, 0, 60.0f, 1.0f, { 0.0f, 0.0f, 0.0f }, { 0.0f, 0.0f, 0.0f } },
|
||||
{ 0x0F, 0xFF, 0x4242, 30, 0, 50.0f, 1.0f, { 0.0f, 28.0f, 0.0f }, { 0.0f, 20.0f, -45.0f } },
|
||||
{ 0x0D, 0xFF, 0x0000, 120, 0, 180.0f, 0.4f, { 0.0f, -5.0f, 0.0f }, { 0.0f, 2.0f, 45.0f } },
|
||||
};
|
||||
|
||||
static OnePointCsFull D_801239D4[3] = {
|
||||
OnePointCsFull D_801239D4[3] = {
|
||||
{ 0x0F, 0xFF, 0x4242, 5, 0, 60.0f, 1.0f, { 0.0f, 20.0f, 0.0f }, { 0.0f, 40.0f, -120.0f } },
|
||||
{ 0x09, 0xFF, 0x4242, 0, 0, 60.0f, 1.0f, { 0.0f, 20.0f, 0.0f }, { 0.0f, 0.0f, 0.0f } },
|
||||
{ 0x12, 0xFF, 0x0000, 1, 0, 60.0f, 1.0f, { -1.0f, -1.0f, -1.0f }, { -1.0f, -1.0f, -1.0f } },
|
|
@ -753,7 +753,15 @@ void func_80083108(GlobalContext* globalCtx) {
|
|||
gSaveContext.buttonStatus[0] = BTN_DISABLED;
|
||||
|
||||
for (i = 1; i < 4; i++) {
|
||||
if (func_8008F2F8(globalCtx) == 2) {
|
||||
if ((gSaveContext.equips.buttonItems[i] >= ITEM_SHIELD_DEKU) &&
|
||||
(gSaveContext.equips.buttonItems[i] <= ITEM_BOOTS_HOVER)) {
|
||||
// Equipment on c-buttons is always enabled
|
||||
if (gSaveContext.buttonStatus[i] == BTN_DISABLED) {
|
||||
sp28 = 1;
|
||||
}
|
||||
|
||||
gSaveContext.buttonStatus[i] = BTN_ENABLED;
|
||||
} else if (func_8008F2F8(globalCtx) == 2) {
|
||||
if ((gSaveContext.equips.buttonItems[i] != ITEM_HOOKSHOT) &&
|
||||
(gSaveContext.equips.buttonItems[i] != ITEM_LONGSHOT)) {
|
||||
if (gSaveContext.buttonStatus[i] == BTN_ENABLED) {
|
||||
|
|
|
@ -5,6 +5,8 @@
|
|||
|
||||
#include "soh/Enhancements/gameconsole.h"
|
||||
|
||||
#include "soh/frame_interpolation.h"
|
||||
|
||||
void* D_8012D1F0 = NULL;
|
||||
//UNK_TYPE D_8012D1F4 = 0; // unused
|
||||
Input* D_8012D1F8 = NULL;
|
||||
|
@ -1379,7 +1381,9 @@ void Gameplay_Main(GameState* thisx) {
|
|||
LOG_NUM("1", 1, "../z_play.c", 4583);
|
||||
}
|
||||
|
||||
FrameInterpolation_StartRecord();
|
||||
Gameplay_Draw(globalCtx);
|
||||
FrameInterpolation_StopRecord();
|
||||
|
||||
if (1 && HREG(63)) {
|
||||
LOG_NUM("1", 1, "../z_play.c", 4587);
|
||||
|
|
|
@ -29,7 +29,8 @@ s16 sBootData[PLAYER_BOOTS_MAX][17] = {
|
|||
// Used to map action params to model groups
|
||||
u8 sActionModelGroups[] = {
|
||||
3, 15, 10, 2, 2, 5, 10, 11, 6, 6, 6, 6, 6, 6, 6, 6, 9, 9, 7, 7, 8, 3, 3, 6, 3, 3, 3, 3, 12, 13, 14, 14, 14, 14,
|
||||
14, 14, 14, 14, 14, 14, 14, 14, 14, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
|
||||
14, 14, 14, 14, 14, 14, 14, 14, 14, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
|
||||
3, 3, 3, 3, 3, 3, 3, 3
|
||||
};
|
||||
|
||||
TextTriggerEntry sTextTriggers[] = {
|
||||
|
@ -743,26 +744,24 @@ void func_8008F470(GlobalContext* globalCtx, void** skeleton, Vec3s* jointTable,
|
|||
#else
|
||||
gSPSegment(POLY_OPA_DISP++, 0x09, SEGMENTED_TO_VIRTUAL(sMouthTextures[eyeIndex]));
|
||||
#endif
|
||||
Color_RGB8 sTemp;
|
||||
color = &sTemp;
|
||||
if (tunic == PLAYER_TUNIC_KOKIRI) {
|
||||
Color_RGB8 sTemp = { CVar_GetS32("gTunic_Kokiri_Red", sTunicColors[PLAYER_TUNIC_KOKIRI].r),
|
||||
CVar_GetS32("gTunic_Kokiri_Green", sTunicColors[PLAYER_TUNIC_KOKIRI].g),
|
||||
CVar_GetS32("gTunic_Kokiri_Blue", sTunicColors[PLAYER_TUNIC_KOKIRI].b) };
|
||||
color = &sTemp;
|
||||
color->r = CVar_GetS32("gTunic_Kokiri_Red", sTunicColors[PLAYER_TUNIC_KOKIRI].r);
|
||||
color->g = CVar_GetS32("gTunic_Kokiri_Green", sTunicColors[PLAYER_TUNIC_KOKIRI].g);
|
||||
color->b = CVar_GetS32("gTunic_Kokiri_Blue", sTunicColors[PLAYER_TUNIC_KOKIRI].b);
|
||||
} else if (tunic == PLAYER_TUNIC_GORON) {
|
||||
Color_RGB8 sTemp = { CVar_GetS32("gTunic_Goron_Red", sTunicColors[PLAYER_TUNIC_GORON].r),
|
||||
CVar_GetS32("gTunic_Goron_Green", sTunicColors[PLAYER_TUNIC_GORON].g),
|
||||
CVar_GetS32("gTunic_Goron_Blue", sTunicColors[PLAYER_TUNIC_GORON].b) };
|
||||
color = &sTemp;
|
||||
color->r = CVar_GetS32("gTunic_Goron_Red", sTunicColors[PLAYER_TUNIC_GORON].r);
|
||||
color->g = CVar_GetS32("gTunic_Goron_Green", sTunicColors[PLAYER_TUNIC_GORON].g);
|
||||
color->b = CVar_GetS32("gTunic_Goron_Blue", sTunicColors[PLAYER_TUNIC_GORON].b);
|
||||
} else if (tunic == PLAYER_TUNIC_ZORA) {
|
||||
Color_RGB8 sTemp = { CVar_GetS32("gTunic_Zora_Red", sTunicColors[PLAYER_TUNIC_ZORA].r),
|
||||
CVar_GetS32("gTunic_Zora_Green", sTunicColors[PLAYER_TUNIC_ZORA].g),
|
||||
CVar_GetS32("gTunic_Zora_Blue", sTunicColors[PLAYER_TUNIC_ZORA].b) };
|
||||
color = &sTemp;
|
||||
color->r = CVar_GetS32("gTunic_Zora_Red", sTunicColors[PLAYER_TUNIC_ZORA].r);
|
||||
color->g = CVar_GetS32("gTunic_Zora_Green", sTunicColors[PLAYER_TUNIC_ZORA].g);
|
||||
color->b = CVar_GetS32("gTunic_Zora_Blue", sTunicColors[PLAYER_TUNIC_ZORA].b);
|
||||
} else {
|
||||
Color_RGB8 sTemp = { CVar_GetS32("gTunic_Kokiri_Red", sTunicColors[PLAYER_TUNIC_KOKIRI].r),
|
||||
CVar_GetS32("gTunic_Kokiri_Green", sTunicColors[PLAYER_TUNIC_KOKIRI].g),
|
||||
CVar_GetS32("gTunic_Kokiri_Blue", sTunicColors[PLAYER_TUNIC_KOKIRI].b) };
|
||||
color = &sTemp;
|
||||
color->r = CVar_GetS32("gTunic_Kokiri_Red", sTunicColors[PLAYER_TUNIC_KOKIRI].r);
|
||||
color->g = CVar_GetS32("gTunic_Kokiri_Green", sTunicColors[PLAYER_TUNIC_KOKIRI].g);
|
||||
color->b = CVar_GetS32("gTunic_Kokiri_Blue", sTunicColors[PLAYER_TUNIC_KOKIRI].b);
|
||||
}
|
||||
gDPSetEnvColor(POLY_OPA_DISP++, color->r, color->g, color->b, 0);
|
||||
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
#include "global.h"
|
||||
#include "vt.h"
|
||||
|
||||
#include "soh/frame_interpolation.h"
|
||||
|
||||
// clang-format off
|
||||
MtxF sMtxFClear = {
|
||||
1.0f, 0.0f, 0.0f, 0.0f,
|
||||
|
@ -523,6 +525,7 @@ void SkinMatrix_Vec3sToVec3f(Vec3s* src, Vec3f* dest) {
|
|||
}
|
||||
|
||||
void SkinMatrix_MtxFToMtx(MtxF* src, Mtx* dest) {
|
||||
FrameInterpolation_RecordSkinMatrixMtxFToMtx(src, dest);
|
||||
guMtxF2L(src, dest);
|
||||
}
|
||||
|
||||
|
|
|
@ -2,6 +2,9 @@
|
|||
#include "vt.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
|
||||
#include "soh/frame_interpolation.h"
|
||||
|
||||
vu32 D_8012ABF0 = true;
|
||||
|
||||
|
@ -277,6 +280,10 @@ void func_800AAA50(View* view, s32 arg1) {
|
|||
}
|
||||
}
|
||||
|
||||
static float sqr(float a) {
|
||||
return a * a;
|
||||
}
|
||||
|
||||
s32 func_800AAA9C(View* view) {
|
||||
f32 aspect;
|
||||
s32 width;
|
||||
|
@ -307,6 +314,85 @@ s32 func_800AAA9C(View* view) {
|
|||
height = view->viewport.bottomY - view->viewport.topY;
|
||||
aspect = (f32)width / (f32)height;
|
||||
|
||||
viewing = Graph_Alloc(gfxCtx, sizeof(Mtx));
|
||||
LogUtils_CheckNullPointer("viewing", viewing, "../z_view.c", 667);
|
||||
view->viewingPtr = viewing;
|
||||
|
||||
if (view->eye.x == view->lookAt.x && view->eye.y == view->lookAt.y && view->eye.z == view->lookAt.z) {
|
||||
view->eye.x += 1.0f;
|
||||
view->eye.y += 1.0f;
|
||||
view->eye.z += 1.0f;
|
||||
}
|
||||
|
||||
func_800ABE74(view->eye.x, view->eye.y, view->eye.z);
|
||||
MtxF viewingF;
|
||||
guLookAtF(viewingF.mf, view->eye.x, view->eye.y, view->eye.z, view->lookAt.x, view->lookAt.y, view->lookAt.z, view->up.x,
|
||||
view->up.y, view->up.z);
|
||||
|
||||
// Some heuristics to identify instant camera movements and skip interpolation in that case
|
||||
|
||||
static View old_view;
|
||||
|
||||
float dirx = view->eye.x - view->lookAt.x;
|
||||
float diry = view->eye.y - view->lookAt.y;
|
||||
float dirz = view->eye.z - view->lookAt.z;
|
||||
float dir_dist = sqrtf(sqr(dirx) + sqr(diry) + sqr(dirz));
|
||||
dirx /= dir_dist;
|
||||
diry /= dir_dist;
|
||||
dirz /= dir_dist;
|
||||
|
||||
float odirx = old_view.eye.x - old_view.lookAt.x;
|
||||
float odiry = old_view.eye.y - old_view.lookAt.y;
|
||||
float odirz = old_view.eye.z - old_view.lookAt.z;
|
||||
float odir_dist = sqrtf(sqr(odirx) + sqr(odiry) + sqr(odirz));
|
||||
odirx /= odir_dist;
|
||||
odiry /= odir_dist;
|
||||
odirz /= odir_dist;
|
||||
|
||||
float eye_dist = sqrtf(sqr(view->eye.x - old_view.eye.x) + sqr(view->eye.y - old_view.eye.y) + sqr(view->eye.z - old_view.eye.z));
|
||||
float look_dist = sqrtf(sqr(view->lookAt.x - old_view.lookAt.x) + sqr(view->lookAt.y - old_view.lookAt.y) + sqr(view->lookAt.z - old_view.lookAt.z));
|
||||
float up_dist = sqrtf(sqr(view->up.x - old_view.up.x) + sqr(view->up.y - old_view.up.y) + sqr(view->up.z - old_view.up.z));
|
||||
float d_dist = sqrtf(sqr(dirx - odirx) + sqr(diry - odiry) + sqr(dirz - odirz));
|
||||
|
||||
bool dont_interpolate = false;
|
||||
|
||||
if (up_dist < 0.01 && d_dist < 0.01) {
|
||||
if (eye_dist + look_dist > 300) {
|
||||
dont_interpolate = true;
|
||||
}
|
||||
} else {
|
||||
if (eye_dist >= 400) {
|
||||
dont_interpolate = true;
|
||||
}
|
||||
if (look_dist >= 100) {
|
||||
dont_interpolate = true;
|
||||
}
|
||||
if (up_dist >= 1.50f) {
|
||||
dont_interpolate = true;
|
||||
}
|
||||
if (d_dist >= 1.414f && look_dist >= 15) {
|
||||
dont_interpolate = true;
|
||||
}
|
||||
if (d_dist >= 1.414f && up_dist >= 0.31f && look_dist >= 1 && eye_dist >= 300) {
|
||||
dont_interpolate = true;
|
||||
}
|
||||
if (d_dist >= 0.5f && up_dist >= 0.31f && look_dist >= 3 && eye_dist >= 170) {
|
||||
dont_interpolate = true;
|
||||
}
|
||||
if (look_dist >= 52 && eye_dist >= 52) {
|
||||
dont_interpolate = true;
|
||||
}
|
||||
if (look_dist >= 30 && eye_dist >= 90) {
|
||||
dont_interpolate = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (dont_interpolate) {
|
||||
FrameInterpolation_DontInterpolateCamera();
|
||||
}
|
||||
|
||||
FrameInterpolation_RecordOpenChild(NULL, FrameInterpolation_GetCameraEpoch());
|
||||
|
||||
if (HREG(80) == 11) {
|
||||
if (HREG(94) != 11) {
|
||||
HREG(94) = 11;
|
||||
|
@ -347,22 +433,17 @@ s32 func_800AAA9C(View* view) {
|
|||
gSPPerspNormalize(POLY_KAL_DISP++, view->normal);
|
||||
gSPMatrix(POLY_KAL_DISP++, projection, G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_PROJECTION);
|
||||
|
||||
viewing = Graph_Alloc(gfxCtx, sizeof(Mtx));
|
||||
LogUtils_CheckNullPointer("viewing", viewing, "../z_view.c", 667);
|
||||
view->viewingPtr = viewing;
|
||||
|
||||
if (view->eye.x == view->lookAt.x && view->eye.y == view->lookAt.y && view->eye.z == view->lookAt.z) {
|
||||
view->eye.x += 1.0f;
|
||||
view->eye.y += 1.0f;
|
||||
view->eye.z += 1.0f;
|
||||
}
|
||||
|
||||
func_800ABE74(view->eye.x, view->eye.y, view->eye.z);
|
||||
guLookAt(viewing, view->eye.x, view->eye.y, view->eye.z, view->lookAt.x, view->lookAt.y, view->lookAt.z, view->up.x,
|
||||
view->up.y, view->up.z);
|
||||
Matrix_MtxFToMtx(viewingF.mf, viewing);
|
||||
|
||||
view->viewing = *viewing;
|
||||
|
||||
|
||||
/*if (eye_dist > 1 || look_dist > 1 || abs(up_dist) > 0.1 || abs(d_dist) > 0.1)
|
||||
printf("%d %f %f %f, %f %f %f, %f %f %f, %f %f %f %f %d\n", (int)view->fovy, view->eye.x, view->eye.y, view->eye.z, view->lookAt.x, view->lookAt.y, view->lookAt.z,
|
||||
view->up.x, view->up.y, view->up.z, eye_dist, look_dist, up_dist, d_dist, dont_interpolate);*/
|
||||
|
||||
old_view = *view;
|
||||
|
||||
if (QREG(88) & 2) {
|
||||
s32 i;
|
||||
MtxF mf;
|
||||
|
@ -374,10 +455,10 @@ s32 func_800AAA9C(View* view) {
|
|||
}
|
||||
osSyncPrintf("\n");
|
||||
}
|
||||
|
||||
gSPMatrix(POLY_OPA_DISP++, viewing, G_MTX_NOPUSH | G_MTX_MUL | G_MTX_PROJECTION);
|
||||
gSPMatrix(POLY_XLU_DISP++, viewing, G_MTX_NOPUSH | G_MTX_MUL | G_MTX_PROJECTION);
|
||||
gSPMatrix(POLY_KAL_DISP++, viewing, G_MTX_NOPUSH | G_MTX_MUL | G_MTX_PROJECTION);
|
||||
FrameInterpolation_RecordCloseChild();
|
||||
|
||||
CLOSE_DISPS(gfxCtx, "../z_view.c", 711);
|
||||
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
#include "global.h"
|
||||
|
||||
#include "soh/frame_interpolation.h"
|
||||
|
||||
Mtx* sSkyboxDrawMatrix;
|
||||
|
||||
Mtx* SkyboxDraw_UpdateMatrix(SkyboxContext* skyboxCtx, f32 x, f32 y, f32 z) {
|
||||
|
@ -13,6 +15,7 @@ Mtx* SkyboxDraw_UpdateMatrix(SkyboxContext* skyboxCtx, f32 x, f32 y, f32 z) {
|
|||
|
||||
void SkyboxDraw_Draw(SkyboxContext* skyboxCtx, GraphicsContext* gfxCtx, s16 skyboxId, s16 blend, f32 x, f32 y, f32 z) {
|
||||
OPEN_DISPS(gfxCtx, "../z_vr_box_draw.c", 52);
|
||||
FrameInterpolation_RecordOpenChild(NULL, FrameInterpolation_GetCameraEpoch());
|
||||
|
||||
func_800945A0(gfxCtx);
|
||||
|
||||
|
@ -85,7 +88,7 @@ void SkyboxDraw_Draw(SkyboxContext* skyboxCtx, GraphicsContext* gfxCtx, s16 skyb
|
|||
gDPPipeSync(POLY_OPA_DISP++);
|
||||
//gsSPShaderTest2(POLY_OPA_DISP++);
|
||||
|
||||
|
||||
FrameInterpolation_RecordCloseChild();
|
||||
CLOSE_DISPS(gfxCtx, "../z_vr_box_draw.c", 125);
|
||||
}
|
||||
|
||||
|
|
|
@ -62,5 +62,6 @@ void guLookAt(Mtx* m, f32 xEye, f32 yEye, f32 zEye, f32 xAt, f32 yAt, f32 zAt, f
|
|||
|
||||
guLookAtF(mf, xEye, yEye, zEye, xAt, yAt, zAt, xUp, yUp, zUp);
|
||||
|
||||
guMtxF2L((MtxF*)mf, m);
|
||||
//guMtxF2L((MtxF*)mf, m);
|
||||
Matrix_MtxFToMtx((MtxF*)mf, m);
|
||||
}
|
||||
|
|
|
@ -37,6 +37,6 @@ void guPerspective(Mtx* m, u16* perspNorm, f32 fovy, f32 aspect, f32 near, f32 f
|
|||
f32 mf[4][4];
|
||||
|
||||
guPerspectiveF(mf, perspNorm, fovy, aspect, near, far, scale);
|
||||
guMtxF2L((MtxF*)mf, m);
|
||||
|
||||
//guMtxF2L((MtxF*)mf, m);
|
||||
Matrix_MtxFToMtx((MtxF*)mf, m);
|
||||
}
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
#include "global.h"
|
||||
|
||||
#include "soh/frame_interpolation.h"
|
||||
|
||||
void guOrthoF(f32 mf[4][4], f32 left, f32 right, f32 bottom, f32 top, f32 near, f32 far, f32 scale) {
|
||||
s32 i, j;
|
||||
|
||||
|
@ -25,5 +27,8 @@ void guOrtho(Mtx* mtx, f32 left, f32 right, f32 bottom, f32 top, f32 near, f32 f
|
|||
|
||||
guOrthoF(mf, left, right, bottom, top, near, far, scale);
|
||||
|
||||
guMtxF2L((MtxF*)mf, mtx);
|
||||
//guMtxF2L((MtxF*)mf, mtx);
|
||||
FrameInterpolation_RecordOpenChild("ortho", 0);
|
||||
Matrix_MtxFToMtx((MtxF*)mf, mtx);
|
||||
FrameInterpolation_RecordCloseChild();
|
||||
}
|
||||
|
|
|
@ -121,8 +121,8 @@ void BgDdanKd_CheckForExplosions(BgDdanKd* this, GlobalContext* globalCtx) {
|
|||
}
|
||||
}
|
||||
|
||||
static Vec3f velocity = { 0.0f, 5.0f, 0.0f };
|
||||
static Vec3f accel = { 0.0f, -0.45f, 0.0f };
|
||||
Vec3f sBgDdanKdVelocity = { 0.0f, 5.0f, 0.0f };
|
||||
Vec3f sBgDdanKdAccel = { 0.0f, -0.45f, 0.0f };
|
||||
|
||||
void BgDdanKd_LowerStairs(BgDdanKd* this, GlobalContext* globalCtx) {
|
||||
Vec3f pos1;
|
||||
|
@ -158,11 +158,11 @@ void BgDdanKd_LowerStairs(BgDdanKd* this, GlobalContext* globalCtx) {
|
|||
func_80033480(globalCtx, &pos1, 20.0f, 1, effectStrength * 135.0f, 60, 1);
|
||||
func_80033480(globalCtx, &pos2, 20.0f, 1, effectStrength * 135.0f, 60, 1);
|
||||
|
||||
velocity.x = Rand_CenteredFloat(3.0f);
|
||||
velocity.z = Rand_CenteredFloat(3.0f);
|
||||
sBgDdanKdVelocity.x = Rand_CenteredFloat(3.0f);
|
||||
sBgDdanKdVelocity.z = Rand_CenteredFloat(3.0f);
|
||||
|
||||
func_8003555C(globalCtx, &pos1, &velocity, &accel);
|
||||
func_8003555C(globalCtx, &pos2, &velocity, &accel);
|
||||
func_8003555C(globalCtx, &pos1, &sBgDdanKdVelocity, &sBgDdanKdAccel);
|
||||
func_8003555C(globalCtx, &pos2, &sBgDdanKdVelocity, &sBgDdanKdAccel);
|
||||
|
||||
pos1 = this->dyna.actor.world.pos;
|
||||
pos1.z += 560.0f + Rand_ZeroOne() * 5.0f;
|
||||
|
@ -170,7 +170,7 @@ void BgDdanKd_LowerStairs(BgDdanKd* this, GlobalContext* globalCtx) {
|
|||
pos1.y = Rand_ZeroOne() * 3.0f + (this->dyna.actor.floorHeight + 20.0f);
|
||||
|
||||
func_80033480(globalCtx, &pos1, 20.0f, 1, effectStrength * 135.0f, 60, 1);
|
||||
func_8003555C(globalCtx, &pos1, &velocity, &accel);
|
||||
func_8003555C(globalCtx, &pos1, &sBgDdanKdVelocity, &sBgDdanKdAccel);
|
||||
}
|
||||
Camera_AddQuake(&globalCtx->mainCamera, 0, effectStrength * 0.6f, 3);
|
||||
Audio_PlaySoundGeneral(NA_SE_EV_PILLAR_SINK - SFX_FLAG, &this->dyna.actor.projectedPos, 4, &D_801333E0,
|
||||
|
@ -192,11 +192,11 @@ void BgDdanKd_Draw(Actor* thisx, GlobalContext* globalCtx) {
|
|||
}
|
||||
|
||||
void BgDdanKd_Reset(void) {
|
||||
velocity.x = 0.0f;
|
||||
velocity.y = 5.0f;
|
||||
velocity.z = 0.0f;
|
||||
sBgDdanKdVelocity.x = 0.0f;
|
||||
sBgDdanKdVelocity.y = 5.0f;
|
||||
sBgDdanKdVelocity.z = 0.0f;
|
||||
|
||||
accel.x = 0.0f;
|
||||
accel.y = -0.45f;
|
||||
accel.z = 0.0f;
|
||||
sBgDdanKdAccel.x = 0.0f;
|
||||
sBgDdanKdAccel.y = -0.45f;
|
||||
sBgDdanKdAccel.z = 0.0f;
|
||||
}
|
|
@ -74,13 +74,13 @@ static ColliderCylinderInit sColCylinderInitLeftRight = {
|
|||
{ 50, 60, 280, { 0, 0, 0 } },
|
||||
};
|
||||
|
||||
static s16 sFirstExplosiveFlag = false;
|
||||
s16 sBgDodoagoFirstExplosiveFlag = false;
|
||||
|
||||
static u8 sDisableBombCatcher;
|
||||
u8 sBgDodoagoDisableBombCatcher;
|
||||
|
||||
static u8 sUnused[90]; // unknown length
|
||||
//static u8 sUnused[90]; // unknown length
|
||||
|
||||
static s32 sTimer;
|
||||
s32 sBgDodoagoTimer;
|
||||
|
||||
void BgDodoago_SetupAction(BgDodoago* this, BgDodoagoActionFunc actionFunc) {
|
||||
this->actionFunc = actionFunc;
|
||||
|
@ -135,7 +135,7 @@ void BgDodoago_Init(Actor* thisx, GlobalContext* globalCtx) {
|
|||
Collider_SetCylinder(globalCtx, &this->colliderRight, &this->dyna.actor, &sColCylinderInitLeftRight);
|
||||
|
||||
BgDodoago_SetupAction(this, BgDodoago_WaitExplosives);
|
||||
sDisableBombCatcher = false;
|
||||
sBgDodoagoDisableBombCatcher = false;
|
||||
}
|
||||
|
||||
void BgDodoago_Destroy(Actor* thisx, GlobalContext* globalCtx) {
|
||||
|
@ -170,16 +170,16 @@ void BgDodoago_WaitExplosives(BgDodoago* this, GlobalContext* globalCtx) {
|
|||
} else {
|
||||
OnePointCutscene_Init(globalCtx, 3065, 20, &this->dyna.actor, MAIN_CAM);
|
||||
Audio_PlaySoundGeneral(NA_SE_SY_ERROR, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8);
|
||||
sTimer += 30;
|
||||
sBgDodoagoTimer += 30;
|
||||
return;
|
||||
}
|
||||
|
||||
// the flag is never set back to false, so this only runs once
|
||||
if (!sFirstExplosiveFlag) {
|
||||
if (!sBgDodoagoFirstExplosiveFlag) {
|
||||
// this disables the bomb catcher (see BgDodoago_Update) for a few seconds
|
||||
this->dyna.actor.parent = explosive;
|
||||
sFirstExplosiveFlag = true;
|
||||
sTimer = 50;
|
||||
sBgDodoagoFirstExplosiveFlag = true;
|
||||
sBgDodoagoTimer = 50;
|
||||
}
|
||||
} else if (Flags_GetEventChkInf(0xB0)) {
|
||||
Collider_UpdateCylinder(&this->dyna.actor, &this->colliderMain);
|
||||
|
@ -219,11 +219,11 @@ void BgDodoago_OpenJaw(BgDodoago* this, GlobalContext* globalCtx) {
|
|||
}
|
||||
|
||||
if (globalCtx->roomCtx.unk_74[BGDODOAGO_EYE_LEFT] != 255 || globalCtx->roomCtx.unk_74[BGDODOAGO_EYE_RIGHT] != 255) {
|
||||
sTimer--;
|
||||
sBgDodoagoTimer--;
|
||||
return;
|
||||
}
|
||||
|
||||
if (sTimer == 108) {
|
||||
if (sBgDodoagoTimer == 108) {
|
||||
for (i = ARRAY_COUNT(dustOffsets) - 1; i >= 0; i--) {
|
||||
pos.x = dustOffsets[i].x + this->dyna.actor.world.pos.x;
|
||||
pos.y = dustOffsets[i].y + this->dyna.actor.world.pos.y;
|
||||
|
@ -290,16 +290,16 @@ void BgDodoago_Update(Actor* thisx, GlobalContext* globalCtx) {
|
|||
this->dyna.actor.parent = &bomb->actor;
|
||||
bomb->timer = 50;
|
||||
bomb->actor.speedXZ = 0.0f;
|
||||
sTimer = 0;
|
||||
sBgDodoagoTimer = 0;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
sTimer++;
|
||||
sBgDodoagoTimer++;
|
||||
Flags_GetSwitch(globalCtx, this->dyna.actor.params & 0x3F);
|
||||
if (!sDisableBombCatcher && sTimer > 140) {
|
||||
if (!sBgDodoagoDisableBombCatcher && sBgDodoagoTimer > 140) {
|
||||
if (Flags_GetSwitch(globalCtx, this->dyna.actor.params & 0x3F)) {
|
||||
// this prevents clearing the actor's parent pointer, effectively disabling the bomb catcher
|
||||
sDisableBombCatcher++;
|
||||
sBgDodoagoDisableBombCatcher++;
|
||||
} else {
|
||||
this->dyna.actor.parent = NULL;
|
||||
}
|
||||
|
@ -322,7 +322,7 @@ void BgDodoago_Draw(Actor* thisx, GlobalContext* globalCtx) {
|
|||
}
|
||||
|
||||
void BgDodoago_Reset(void) {
|
||||
sFirstExplosiveFlag = false;
|
||||
sDisableBombCatcher = 0;
|
||||
sTimer = 0;
|
||||
sBgDodoagoFirstExplosiveFlag = false;
|
||||
sBgDodoagoDisableBombCatcher = 0;
|
||||
sBgDodoagoTimer = 0;
|
||||
}
|
|
@ -8,6 +8,8 @@
|
|||
#include "overlays/actors/ovl_Boss_Ganon/z_boss_ganon.h"
|
||||
#include "vt.h"
|
||||
|
||||
#include "soh/frame_interpolation.h"
|
||||
|
||||
#define FLAGS (ACTOR_FLAG_4 | ACTOR_FLAG_5)
|
||||
|
||||
typedef enum {
|
||||
|
@ -283,6 +285,7 @@ void BgGanonOtyuka_Draw(Actor* thisx, GlobalContext* globalCtx) {
|
|||
platform = (BgGanonOtyuka*)actor;
|
||||
|
||||
if (platform->dyna.actor.projectedPos.z > spBC) {
|
||||
FrameInterpolation_RecordOpenChild(platform, 0);
|
||||
if (camera->eye.y > platform->dyna.actor.world.pos.y) {
|
||||
phi_s2 = sPlatformTopDL;
|
||||
} else {
|
||||
|
@ -309,7 +312,7 @@ void BgGanonOtyuka_Draw(Actor* thisx, GlobalContext* globalCtx) {
|
|||
}
|
||||
|
||||
for (i = 0; i < ARRAY_COUNT(sSides); i++) {
|
||||
if (platform->visibleSides & sSides[i]) {
|
||||
if ((platform->visibleSides & sSides[i]) || 1) { // || 1 for frame interpolation
|
||||
Matrix_Push();
|
||||
Matrix_Translate(sSideCenters[i].x, 0.0f, sSideCenters[i].z, MTXMODE_APPLY);
|
||||
Matrix_RotateY(sSideAngles[i], MTXMODE_APPLY);
|
||||
|
@ -320,6 +323,7 @@ void BgGanonOtyuka_Draw(Actor* thisx, GlobalContext* globalCtx) {
|
|||
Matrix_Pop();
|
||||
}
|
||||
}
|
||||
FrameInterpolation_RecordCloseChild();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -333,6 +337,7 @@ void BgGanonOtyuka_Draw(Actor* thisx, GlobalContext* globalCtx) {
|
|||
platform = (BgGanonOtyuka*)actor;
|
||||
|
||||
if ((platform->dyna.actor.projectedPos.z > -30.0f) && (platform->flashState != FLASH_NONE)) {
|
||||
FrameInterpolation_RecordOpenChild(platform, 0);
|
||||
gSPSegment(POLY_XLU_DISP++, 0x08,
|
||||
Gfx_TwoTexScroll(globalCtx->state.gfxCtx, 0, platform->flashTimer * 4, 0, 32, 64, 1,
|
||||
platform->flashTimer * 4, 0, 32, 64));
|
||||
|
@ -344,7 +349,7 @@ void BgGanonOtyuka_Draw(Actor* thisx, GlobalContext* globalCtx) {
|
|||
Matrix_Translate(platform->dyna.actor.world.pos.x, 0.0f, platform->dyna.actor.world.pos.z, MTXMODE_NEW);
|
||||
|
||||
for (i = 0; i < ARRAY_COUNT(sSides); i++) {
|
||||
if (platform->unwalledSides & sSides[i]) {
|
||||
if ((platform->unwalledSides & sSides[i]) || 1) { // || 1 for frame interpolation
|
||||
Matrix_Push();
|
||||
Matrix_Translate(sSideCenters[i].x, 0.0f, sSideCenters[i].z, MTXMODE_APPLY);
|
||||
Matrix_RotateY(sSideAngles[i], MTXMODE_APPLY);
|
||||
|
@ -356,6 +361,7 @@ void BgGanonOtyuka_Draw(Actor* thisx, GlobalContext* globalCtx) {
|
|||
Matrix_Pop();
|
||||
}
|
||||
}
|
||||
FrameInterpolation_RecordCloseChild();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -47,7 +47,7 @@ void BgHakaGate_SkullOfTruth(BgHakaGate* this, GlobalContext* globalCtx);
|
|||
void BgHakaGate_FalseSkull(BgHakaGate* this, GlobalContext* globalCtx);
|
||||
|
||||
static s16 sSkullOfTruthRotY = 0x100;
|
||||
static u8 sPuzzleState = 1;
|
||||
static u8 sBgPoEventPuzzleState = 1;
|
||||
static f32 sStatueDistToPlayer = 0;
|
||||
|
||||
static s16 sStatueRotY;
|
||||
|
@ -82,7 +82,7 @@ void BgHakaGate_Init(Actor* thisx, GlobalContext* globalCtx) {
|
|||
if (sSkullOfTruthRotY != 0x100) {
|
||||
this->actionFunc = BgHakaGate_FalseSkull;
|
||||
} else if (ABS(thisx->shape.rot.y) < 0x4000) {
|
||||
if ((Rand_ZeroOne() * 3.0f) < sPuzzleState) {
|
||||
if ((Rand_ZeroOne() * 3.0f) < sBgPoEventPuzzleState) {
|
||||
this->vIsSkullOfTruth = true;
|
||||
sSkullOfTruthRotY = thisx->shape.rot.y + 0x8000;
|
||||
if (Flags_GetSwitch(globalCtx, this->switchFlag)) {
|
||||
|
@ -91,7 +91,7 @@ void BgHakaGate_Init(Actor* thisx, GlobalContext* globalCtx) {
|
|||
this->actionFunc = BgHakaGate_SkullOfTruth;
|
||||
}
|
||||
} else {
|
||||
sPuzzleState++;
|
||||
sBgPoEventPuzzleState++;
|
||||
this->actionFunc = BgHakaGate_FalseSkull;
|
||||
}
|
||||
} else {
|
||||
|
@ -141,7 +141,7 @@ void BgHakaGate_Destroy(Actor* thisx, GlobalContext* globalCtx) {
|
|||
DynaPoly_DeleteBgActor(globalCtx, &globalCtx->colCtx.dyna, this->dyna.bgId);
|
||||
if (this->dyna.actor.params == BGHAKAGATE_STATUE) {
|
||||
sSkullOfTruthRotY = 0x100;
|
||||
sPuzzleState = 1;
|
||||
sBgPoEventPuzzleState = 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -178,7 +178,7 @@ void BgHakaGate_StatueIdle(BgHakaGate* this, GlobalContext* globalCtx) {
|
|||
}
|
||||
}
|
||||
} else {
|
||||
if (sPuzzleState == SKULL_OF_TRUTH_FOUND) {
|
||||
if (sBgPoEventPuzzleState == SKULL_OF_TRUTH_FOUND) {
|
||||
this->actionFunc = BgHakaGate_StatueInactive;
|
||||
} else {
|
||||
this->vTimer = 0;
|
||||
|
@ -192,7 +192,12 @@ void BgHakaGate_StatueTurn(BgHakaGate* this, GlobalContext* globalCtx) {
|
|||
s16 turnAngle;
|
||||
|
||||
this->vTurnRateDeg10++;
|
||||
if (CVar_GetS32("gFasterBlockPush", 0) != 0) {
|
||||
this->vTurnRateDeg10 = 10;
|
||||
CLAMP_MAX(this->vTurnRateDeg10, 5);
|
||||
} else {
|
||||
this->vTurnRateDeg10 = CLAMP_MAX(this->vTurnRateDeg10, 5);
|
||||
}
|
||||
turnFinished = Math_StepToS(&this->vTurnAngleDeg10, 600, this->vTurnRateDeg10);
|
||||
turnAngle = this->vTurnAngleDeg10 * this->vTurnDirection;
|
||||
this->dyna.actor.shape.rot.y = (this->vRotYDeg10 + turnAngle) * 0.1f * (0x10000 / 360.0f);
|
||||
|
@ -212,7 +217,7 @@ void BgHakaGate_StatueTurn(BgHakaGate* this, GlobalContext* globalCtx) {
|
|||
this->vRotYDeg10 = (this->vRotYDeg10 + turnAngle) % 3600;
|
||||
this->vTurnRateDeg10 = 0;
|
||||
this->vTurnAngleDeg10 = 0;
|
||||
this->vTimer = 5;
|
||||
this->vTimer = CVar_GetS32("gFasterBlockPush", 0) != 0 ? 2 : 5;
|
||||
this->actionFunc = BgHakaGate_StatueIdle;
|
||||
this->dyna.unk_150 = 0.0f;
|
||||
}
|
||||
|
@ -238,7 +243,7 @@ void BgHakaGate_FloorClosed(BgHakaGate* this, GlobalContext* globalCtx) {
|
|||
sStatueDistToPlayer = 0.0f;
|
||||
if (ABS(yawDiff) < 0x80) {
|
||||
Flags_SetSwitch(globalCtx, this->switchFlag);
|
||||
sPuzzleState = SKULL_OF_TRUTH_FOUND;
|
||||
sBgPoEventPuzzleState = SKULL_OF_TRUTH_FOUND;
|
||||
this->actionFunc = BgHakaGate_DoNothing;
|
||||
} else {
|
||||
func_80078884(NA_SE_SY_ERROR);
|
||||
|
|
|
@ -28,7 +28,7 @@ void func_80880AE8(BgHakaTrap* this, GlobalContext* globalCtx);
|
|||
void func_80880C0C(BgHakaTrap* this, GlobalContext* globalCtx);
|
||||
void func_80880D68(BgHakaTrap* this);
|
||||
|
||||
static UNK_TYPE D_80880F30 = 0;
|
||||
UNK_TYPE D_80880F30 = 0;
|
||||
|
||||
const ActorInit Bg_Haka_Trap_InitVars = {
|
||||
ACTOR_BG_HAKA_TRAP,
|
||||
|
@ -107,7 +107,7 @@ static InitChainEntry sInitChain[] = {
|
|||
ICHAIN_VEC3F_DIV1000(scale, 100, ICHAIN_STOP),
|
||||
};
|
||||
|
||||
static UNK_TYPE D_80881014 = 0;
|
||||
UNK_TYPE D_80881014 = 0;
|
||||
void BgHakaTrap_Init(Actor* thisx, GlobalContext* globalCtx) {
|
||||
BgHakaTrap* this = (BgHakaTrap*)thisx;
|
||||
s32 pad;
|
||||
|
|
|
@ -120,7 +120,7 @@ void func_8088B24C(BgHidanRock* this) {
|
|||
this->actionFunc = func_8088B990;
|
||||
}
|
||||
|
||||
static f32 D_8088BFC0 = 0.0f;
|
||||
f32 D_8088BFC0 = 0.0f;
|
||||
void func_8088B268(BgHidanRock* this, GlobalContext* globalCtx) {
|
||||
f32 sp2C;
|
||||
s32 temp_v1;
|
||||
|
@ -137,7 +137,7 @@ void func_8088B268(BgHidanRock* this, GlobalContext* globalCtx) {
|
|||
}
|
||||
}
|
||||
|
||||
this->dyna.actor.speedXZ += 0.05f;
|
||||
this->dyna.actor.speedXZ += CVar_GetS32("gFasterBlockPush", 0) != 0 ? 0.5f : 0.05f;
|
||||
this->dyna.actor.speedXZ = CLAMP_MAX(this->dyna.actor.speedXZ, 2.0f);
|
||||
|
||||
if (D_8088BFC0 > 0.0f) {
|
||||
|
@ -156,7 +156,7 @@ void func_8088B268(BgHidanRock* this, GlobalContext* globalCtx) {
|
|||
this->dyna.actor.home.pos.z = this->dyna.actor.world.pos.z;
|
||||
D_8088BFC0 = 0.0f;
|
||||
this->dyna.actor.speedXZ = 0.0f;
|
||||
this->timer = 5;
|
||||
this->timer = CVar_GetS32("gFasterBlockPush", 0) != 0 ? 2 : 5;
|
||||
}
|
||||
|
||||
func_8002F974(&this->dyna.actor, NA_SE_EV_ROCK_SLIDE - SFX_FLAG);
|
||||
|
|
|
@ -240,7 +240,8 @@ void BgHidanRsekizou_Draw(Actor* thisx, GlobalContext* globalCtx) {
|
|||
|
||||
POLY_XLU_DISP = Gfx_CallSetupDL(POLY_XLU_DISP, 0x14);
|
||||
|
||||
if ((s16)((Camera_GetCamDirYaw(GET_ACTIVE_CAM(globalCtx)) - this->dyna.actor.shape.rot.y) - 0x2E6C) >= 0) {
|
||||
// Strange original code. Add || 1 for frame interpolation to get correct.
|
||||
if ((s16)((Camera_GetCamDirYaw(GET_ACTIVE_CAM(globalCtx)) - this->dyna.actor.shape.rot.y) - 0x2E6C) >= 0 || 1) {
|
||||
for (i = 3; i >= 0; i--) {
|
||||
POLY_XLU_DISP = BgHidanRsekizou_DrawFireball(globalCtx, this, i, &mf, 0, POLY_XLU_DISP);
|
||||
}
|
||||
|
|
|
@ -23,7 +23,7 @@ void BgJya1flift_SetupDoNothing(BgJya1flift* this);
|
|||
void BgJya1flift_ResetMoveDelay(BgJya1flift* this);
|
||||
void BgJya1flift_DelayMove(BgJya1flift* this, GlobalContext* globalCtx);
|
||||
|
||||
static u8 sIsSpawned = false;
|
||||
static u8 sKankyoIsSpawned = false;
|
||||
|
||||
const ActorInit Bg_Jya_1flift_InitVars = {
|
||||
ACTOR_BG_JYA_1FLIFT,
|
||||
|
@ -94,9 +94,9 @@ void BgJya1flift_InitCollision(Actor* thisx, GlobalContext* globalCtx) {
|
|||
void BgJya1flift_Init(Actor* thisx, GlobalContext* globalCtx) {
|
||||
BgJya1flift* this = (BgJya1flift*)thisx;
|
||||
// "1 F lift"
|
||||
osSyncPrintf("(1Fリフト)(flag %d)(room %d)\n", sIsSpawned, globalCtx->roomCtx.curRoom.num);
|
||||
osSyncPrintf("(1Fリフト)(flag %d)(room %d)\n", sKankyoIsSpawned, globalCtx->roomCtx.curRoom.num);
|
||||
this->hasInitialized = false;
|
||||
if (sIsSpawned) {
|
||||
if (sKankyoIsSpawned) {
|
||||
Actor_Kill(thisx);
|
||||
return;
|
||||
}
|
||||
|
@ -109,7 +109,7 @@ void BgJya1flift_Init(Actor* thisx, GlobalContext* globalCtx) {
|
|||
BgJya1flift_SetupWaitForSwitch(this);
|
||||
}
|
||||
thisx->room = -1;
|
||||
sIsSpawned = true;
|
||||
sKankyoIsSpawned = true;
|
||||
this->hasInitialized = true;
|
||||
}
|
||||
|
||||
|
@ -117,7 +117,7 @@ void BgJya1flift_Destroy(Actor* thisx, GlobalContext* globalCtx) {
|
|||
BgJya1flift* this = (BgJya1flift*)thisx;
|
||||
|
||||
if (this->hasInitialized) {
|
||||
sIsSpawned = false;
|
||||
sKankyoIsSpawned = false;
|
||||
Collider_DestroyCylinder(globalCtx, &this->collider);
|
||||
DynaPoly_DeleteBgActor(globalCtx, &globalCtx->colCtx.dyna, this->dyna.bgId);
|
||||
}
|
||||
|
|
|
@ -14,7 +14,7 @@ void BgJyaBigmirror_Destroy(Actor* thisx, GlobalContext* globalCtx);
|
|||
void BgJyaBigmirror_Update(Actor* thisx, GlobalContext* globalCtx);
|
||||
void BgJyaBigmirror_Draw(Actor* thisx, GlobalContext* globalCtx);
|
||||
|
||||
static u8 sIsSpawned = false;
|
||||
static u8 sKankyoIsSpawned = false;
|
||||
|
||||
const ActorInit Bg_Jya_Bigmirror_InitVars = {
|
||||
ACTOR_BG_JYA_BIGMIRROR,
|
||||
|
@ -176,7 +176,7 @@ void BgJyaBigmirror_HandleMirRay(Actor* thisx, GlobalContext* globalCtx) {
|
|||
void BgJyaBigmirror_Init(Actor* thisx, GlobalContext* globalCtx) {
|
||||
BgJyaBigmirror* this = (BgJyaBigmirror*)thisx;
|
||||
|
||||
if (sIsSpawned) {
|
||||
if (sKankyoIsSpawned) {
|
||||
Actor_Kill(&this->actor);
|
||||
return;
|
||||
}
|
||||
|
@ -185,7 +185,7 @@ void BgJyaBigmirror_Init(Actor* thisx, GlobalContext* globalCtx) {
|
|||
this->cobraInfo[0].rotY = sCobraSpawnData[0].initRotY;
|
||||
this->cobraInfo[1].rotY = sCobraSpawnData[1].initRotY;
|
||||
this->actor.room = -1;
|
||||
sIsSpawned = true;
|
||||
sKankyoIsSpawned = true;
|
||||
this->spawned = true;
|
||||
this->mirRayObjIndex = -1;
|
||||
|
||||
|
@ -197,7 +197,7 @@ void BgJyaBigmirror_Destroy(Actor* thisx, GlobalContext* globalCtx) {
|
|||
BgJyaBigmirror* this = (BgJyaBigmirror*)thisx;
|
||||
|
||||
if (this->spawned) {
|
||||
sIsSpawned = false;
|
||||
sKankyoIsSpawned = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -444,7 +444,7 @@ void func_80896950(BgJyaCobra* this, GlobalContext* globalCtx) {
|
|||
|
||||
if (this->dyna.unk_150 > 0.001f) {
|
||||
this->unk_168++;
|
||||
if (this->unk_168 >= 15) {
|
||||
if (this->unk_168 >= CVar_GetS32("gFasterBlockPush", 0) != 0 ? 5 : 15) {
|
||||
func_808969F8(this, globalCtx);
|
||||
}
|
||||
} else {
|
||||
|
@ -484,9 +484,11 @@ void func_808969F8(BgJyaCobra* this, GlobalContext* globalCtx) {
|
|||
void func_80896ABC(BgJyaCobra* this, GlobalContext* globalCtx) {
|
||||
s16 temp_v0;
|
||||
Player* player = GET_PLAYER(globalCtx);
|
||||
if (CVar_GetS32("gFasterBlockPush", 0) != 0)
|
||||
this->unk_16E = 150.0f;
|
||||
|
||||
temp_v0 = (s16)((this->unk_16C * 0x2000) + this->dyna.actor.home.rot.y) - this->dyna.actor.world.rot.y;
|
||||
if (ABS(temp_v0) < 7424) {
|
||||
if (ABS(temp_v0) < CVar_GetS32("gFasterBlockPush", 0) != 0 ? 3712 : 7424) {
|
||||
Math_StepToS(&this->unk_16E, 106, 4);
|
||||
} else {
|
||||
Math_StepToS(&this->unk_16E, 21, 10);
|
||||
|
|
|
@ -20,7 +20,7 @@ void BgJyaLift_DelayMove(BgJyaLift* this, GlobalContext* globalCtx);
|
|||
void BgJyaLift_SetupMove(BgJyaLift* this);
|
||||
void BgJyaLift_Move(BgJyaLift* this, GlobalContext* globalCtx);
|
||||
|
||||
static s16 sIsSpawned = false;
|
||||
static s16 sKankyoIsSpawned = false;
|
||||
|
||||
const ActorInit Bg_Jya_Lift_InitVars = {
|
||||
ACTOR_BG_JYA_LIFT,
|
||||
|
@ -55,7 +55,7 @@ void BgJyaLift_Init(Actor* thisx, GlobalContext* globalCtx) {
|
|||
BgJyaLift* this = (BgJyaLift*)thisx;
|
||||
|
||||
this->isSpawned = false;
|
||||
if (sIsSpawned) {
|
||||
if (sKankyoIsSpawned) {
|
||||
Actor_Kill(thisx);
|
||||
return;
|
||||
}
|
||||
|
@ -70,7 +70,7 @@ void BgJyaLift_Init(Actor* thisx, GlobalContext* globalCtx) {
|
|||
BgJyaLift_SetInitPosY(this);
|
||||
}
|
||||
thisx->room = -1;
|
||||
sIsSpawned = true;
|
||||
sKankyoIsSpawned = true;
|
||||
this->isSpawned = true;
|
||||
}
|
||||
|
||||
|
@ -81,7 +81,7 @@ void BgJyaLift_Destroy(Actor* thisx, GlobalContext* globalCtx) {
|
|||
|
||||
// "Goddess Lift DT"
|
||||
osSyncPrintf("女神リフト DT\n");
|
||||
sIsSpawned = false;
|
||||
sKankyoIsSpawned = false;
|
||||
DynaPoly_DeleteBgActor(globalCtx, &globalCtx->colCtx.dyna, this->dyna.bgId);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -28,7 +28,7 @@ const ActorInit Bg_Menkuri_Eye_InitVars = {
|
|||
(ActorResetFunc)BgMenkuriEye_Reset,
|
||||
};
|
||||
|
||||
static s32 D_8089C1A0;
|
||||
s32 D_8089C1A0;
|
||||
|
||||
static ColliderJntSphElementInit sJntSphElementsInit[1] = {
|
||||
{
|
||||
|
|
|
@ -17,7 +17,7 @@ void func_808A2008(BgMoriElevator* this, GlobalContext* globalCtx);
|
|||
void BgMoriElevator_MoveIntoGround(BgMoriElevator* this, GlobalContext* globalCtx);
|
||||
void BgMoriElevator_MoveAboveGround(BgMoriElevator* this, GlobalContext* globalCtx);
|
||||
|
||||
static s16 sIsSpawned = false;
|
||||
static s16 sKankyoIsSpawned = false;
|
||||
|
||||
const ActorInit Bg_Mori_Elevator_InitVars = {
|
||||
ACTOR_BG_MORI_ELEVATOR,
|
||||
|
@ -87,18 +87,18 @@ void BgMoriElevator_Init(Actor* thisx, GlobalContext* globalCtx) {
|
|||
s32 pad;
|
||||
CollisionHeader* colHeader = NULL;
|
||||
|
||||
this->unk_172 = sIsSpawned;
|
||||
this->unk_172 = sKankyoIsSpawned;
|
||||
this->moriTexObjIndex = Object_GetIndex(&globalCtx->objectCtx, OBJECT_MORI_TEX);
|
||||
if (this->moriTexObjIndex < 0) {
|
||||
Actor_Kill(thisx);
|
||||
// "Forest Temple obj elevator Bank Danger!"
|
||||
osSyncPrintf("Error : 森の神殿 obj elevator バンク危険!(%s %d)\n", "../z_bg_mori_elevator.c", 277);
|
||||
} else {
|
||||
switch (sIsSpawned) {
|
||||
switch (sKankyoIsSpawned) {
|
||||
case false:
|
||||
// "Forest Temple elevator CT"
|
||||
osSyncPrintf("森の神殿 elevator CT\n");
|
||||
sIsSpawned = true;
|
||||
sKankyoIsSpawned = true;
|
||||
this->dyna.actor.room = -1;
|
||||
Actor_ProcessInitChain(&this->dyna.actor, sInitChain);
|
||||
DynaPolyActor_Init(&this->dyna, DPM_PLAYER);
|
||||
|
@ -120,7 +120,7 @@ void BgMoriElevator_Destroy(Actor* thisx, GlobalContext* globalCtx) {
|
|||
// "Forest Temple elevator DT"
|
||||
osSyncPrintf("森の神殿 elevator DT\n");
|
||||
DynaPoly_DeleteBgActor(globalCtx, &globalCtx->colCtx.dyna, this->dyna.bgId);
|
||||
sIsSpawned = false;
|
||||
sKankyoIsSpawned = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -28,7 +28,7 @@ void BgMoriHineri_SpawnBossKeyChest(BgMoriHineri* this, GlobalContext* globalCtx
|
|||
void BgMoriHineri_DoNothing(BgMoriHineri* this, GlobalContext* globalCtx);
|
||||
void func_808A3D58(BgMoriHineri* this, GlobalContext* globalCtx);
|
||||
|
||||
static s16 sNextCamIdx = SUBCAM_NONE;
|
||||
s16 sBgMoriHineriNextCamIdx = SUBCAM_NONE;
|
||||
|
||||
const ActorInit Bg_Mori_Hineri_InitVars = {
|
||||
ACTOR_BG_MORI_HINERI,
|
||||
|
@ -194,28 +194,28 @@ void func_808A3D58(BgMoriHineri* this, GlobalContext* globalCtx) {
|
|||
OnePointCutscene_EndCutscene(globalCtx, mainCamChildIdx);
|
||||
}
|
||||
OnePointCutscene_Init(globalCtx, 3260, 40, &this->dyna.actor, MAIN_CAM);
|
||||
sNextCamIdx = OnePointCutscene_Init(globalCtx, 3261, 40, &this->dyna.actor, MAIN_CAM);
|
||||
sBgMoriHineriNextCamIdx = OnePointCutscene_Init(globalCtx, 3261, 40, &this->dyna.actor, MAIN_CAM);
|
||||
}
|
||||
}
|
||||
|
||||
void func_808A3E54(BgMoriHineri* this, GlobalContext* globalCtx) {
|
||||
s8 objBankIndex;
|
||||
|
||||
if (globalCtx->activeCamera == sNextCamIdx) {
|
||||
if (sNextCamIdx != MAIN_CAM) {
|
||||
if (globalCtx->activeCamera == sBgMoriHineriNextCamIdx) {
|
||||
if (sBgMoriHineriNextCamIdx != MAIN_CAM) {
|
||||
objBankIndex = this->dyna.actor.objBankIndex;
|
||||
this->dyna.actor.objBankIndex = this->moriHineriObjIdx;
|
||||
this->moriHineriObjIdx = objBankIndex;
|
||||
this->dyna.actor.params ^= 1;
|
||||
sNextCamIdx = MAIN_CAM;
|
||||
sBgMoriHineriNextCamIdx = MAIN_CAM;
|
||||
func_80078884(NA_SE_SY_TRE_BOX_APPEAR);
|
||||
} else {
|
||||
this->dyna.actor.draw = NULL;
|
||||
this->actionFunc = func_808A3D58;
|
||||
sNextCamIdx = SUBCAM_NONE;
|
||||
sBgMoriHineriNextCamIdx = SUBCAM_NONE;
|
||||
}
|
||||
}
|
||||
if ((sNextCamIdx >= SUBCAM_FIRST) &&
|
||||
if ((sBgMoriHineriNextCamIdx >= SUBCAM_FIRST) &&
|
||||
((GET_ACTIVE_CAM(globalCtx)->eye.z - this->dyna.actor.world.pos.z) < 1100.0f)) {
|
||||
func_8002F948(&this->dyna.actor, NA_SE_EV_FLOOR_ROLLING - SFX_FLAG);
|
||||
}
|
||||
|
@ -283,5 +283,5 @@ void BgMoriHineri_DrawHallAndRoom(Actor* thisx, GlobalContext* globalCtx) {
|
|||
}
|
||||
|
||||
void BgMoriHineri_Reset() {
|
||||
sNextCamIdx = SUBCAM_NONE;
|
||||
sBgMoriHineriNextCamIdx = SUBCAM_NONE;
|
||||
}
|
|
@ -19,7 +19,7 @@ void BgMoriIdomizu_WaitForMoriTex(BgMoriIdomizu* this, GlobalContext* globalCtx)
|
|||
void BgMoriIdomizu_SetupMain(BgMoriIdomizu* this);
|
||||
void BgMoriIdomizu_Main(BgMoriIdomizu* this, GlobalContext* globalCtx);
|
||||
|
||||
static s16 sIsSpawned = false;
|
||||
static s16 sKankyoIsSpawned = false;
|
||||
|
||||
const ActorInit Bg_Mori_Idomizu_InitVars = {
|
||||
ACTOR_BG_MORI_IDOMIZU,
|
||||
|
@ -50,7 +50,7 @@ void BgMoriIdomizu_Init(Actor* thisx, GlobalContext* globalCtx) {
|
|||
s32 pad;
|
||||
BgMoriIdomizu* this = (BgMoriIdomizu*)thisx;
|
||||
|
||||
if (sIsSpawned) {
|
||||
if (sKankyoIsSpawned) {
|
||||
Actor_Kill(&this->actor);
|
||||
return;
|
||||
}
|
||||
|
@ -76,7 +76,7 @@ void BgMoriIdomizu_Init(Actor* thisx, GlobalContext* globalCtx) {
|
|||
return;
|
||||
}
|
||||
BgMoriIdomizu_SetupWaitForMoriTex(this);
|
||||
sIsSpawned = true;
|
||||
sKankyoIsSpawned = true;
|
||||
this->isLoaded = true;
|
||||
this->actor.room = -1;
|
||||
// "Forest Temple well water"
|
||||
|
@ -88,7 +88,7 @@ void BgMoriIdomizu_Destroy(Actor* thisx, GlobalContext* globalCtx) {
|
|||
BgMoriIdomizu* this = (BgMoriIdomizu*)thisx;
|
||||
|
||||
if (this->isLoaded) {
|
||||
sIsSpawned = false;
|
||||
sKankyoIsSpawned = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -94,7 +94,7 @@ void BgMoriKaitenkabe_Wait(BgMoriKaitenkabe* this, GlobalContext* globalCtx) {
|
|||
|
||||
if (this->dyna.unk_150 > 0.001f) {
|
||||
this->timer++;
|
||||
if ((this->timer > 28) && !Player_InCsMode(globalCtx)) {
|
||||
if ((this->timer > CVar_GetS32("gFasterBlockPush", 0) != 0 ? 14 : 28) && !Player_InCsMode(globalCtx)) {
|
||||
BgMoriKaitenkabe_SetupRotate(this);
|
||||
func_8002DF54(globalCtx, &this->dyna.actor, 8);
|
||||
Math_Vec3f_Copy(&this->lockedPlayerPos, &player->actor.world.pos);
|
||||
|
@ -118,7 +118,7 @@ void BgMoriKaitenkabe_Wait(BgMoriKaitenkabe* this, GlobalContext* globalCtx) {
|
|||
|
||||
void BgMoriKaitenkabe_SetupRotate(BgMoriKaitenkabe* this) {
|
||||
this->actionFunc = BgMoriKaitenkabe_Rotate;
|
||||
this->rotSpeed = 0.0f;
|
||||
this->rotSpeed = CVar_GetS32("gFasterBlockPush", 0) != 0 ? 0.5f : 0.0f;
|
||||
this->rotYdeg = 0.0f;
|
||||
}
|
||||
|
||||
|
|
|
@ -80,11 +80,11 @@ static ColliderTrisInit sTrisInit = {
|
|||
sTrisElementsInit,
|
||||
};
|
||||
|
||||
static u8 sBlocksAtRest = 0;
|
||||
u8 sBgPoEventBlocksAtRest = 0;
|
||||
|
||||
static Vec3f sZeroVec = { 0.0f, 0.0f, 0.0f };
|
||||
|
||||
static u8 sPuzzleState;
|
||||
u8 sBgPoEventPuzzleState;
|
||||
|
||||
void BgPoEvent_InitPaintings(BgPoEvent* this, GlobalContext* globalCtx) {
|
||||
static s16 paintingPosX[] = { -1302, -866, 1421, 985 };
|
||||
|
@ -142,10 +142,10 @@ void BgPoEvent_InitPaintings(BgPoEvent* this, GlobalContext* globalCtx) {
|
|||
}
|
||||
this->timer = 0;
|
||||
if (this->type == 4) {
|
||||
sPuzzleState = 0;
|
||||
sBgPoEventPuzzleState = 0;
|
||||
this->actionFunc = BgPoEvent_AmyWait;
|
||||
} else {
|
||||
sPuzzleState = (s32)(Rand_ZeroOne() * 3.0f) % 3;
|
||||
sBgPoEventPuzzleState = (s32)(Rand_ZeroOne() * 3.0f) % 3;
|
||||
this->actionFunc = BgPoEvent_PaintingEmpty;
|
||||
}
|
||||
}
|
||||
|
@ -236,7 +236,7 @@ void BgPoEvent_Destroy(Actor* thisx, GlobalContext* globalCtx) {
|
|||
|
||||
void BgPoEvent_BlockWait(BgPoEvent* this, GlobalContext* globalCtx) {
|
||||
this->dyna.actor.world.pos.y = 833.0f;
|
||||
if (sPuzzleState == 0x3F) {
|
||||
if (sBgPoEventPuzzleState == 0x3F) {
|
||||
if (this->type == 1) {
|
||||
OnePointCutscene_Init(globalCtx, 3150, 65, NULL, MAIN_CAM);
|
||||
}
|
||||
|
@ -244,14 +244,14 @@ void BgPoEvent_BlockWait(BgPoEvent* this, GlobalContext* globalCtx) {
|
|||
this->actionFunc = BgPoEvent_BlockShake;
|
||||
} else if (this->dyna.actor.xzDistToPlayer > 50.0f) {
|
||||
if (this->type != 1) {
|
||||
sPuzzleState |= (1 << this->index);
|
||||
sBgPoEventPuzzleState |= (1 << this->index);
|
||||
} else {
|
||||
sPuzzleState |= 0x10;
|
||||
sBgPoEventPuzzleState |= 0x10;
|
||||
}
|
||||
} else if (this->type != 1) {
|
||||
sPuzzleState &= ~(1 << this->index);
|
||||
sBgPoEventPuzzleState &= ~(1 << this->index);
|
||||
} else {
|
||||
sPuzzleState &= ~0x10;
|
||||
sBgPoEventPuzzleState &= ~0x10;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -265,7 +265,7 @@ void BgPoEvent_BlockShake(BgPoEvent* this, GlobalContext* globalCtx) {
|
|||
}
|
||||
if (this->timer == 0) {
|
||||
this->dyna.actor.world.pos.x = this->dyna.actor.home.pos.x;
|
||||
sPuzzleState = 0;
|
||||
sBgPoEventPuzzleState = 0;
|
||||
this->timer = 60;
|
||||
this->actionFunc = BgPoEvent_BlockFall;
|
||||
}
|
||||
|
@ -299,9 +299,9 @@ void BgPoEvent_CheckBlock(BgPoEvent* this) {
|
|||
}
|
||||
}
|
||||
if ((phi_v1 == phi_a1) && ((phi_t0 - phi_a3) == 60)) {
|
||||
sPuzzleState |= (1 << this->index);
|
||||
sBgPoEventPuzzleState |= (1 << this->index);
|
||||
} else {
|
||||
sPuzzleState &= ~(1 << this->index);
|
||||
sBgPoEventPuzzleState &= ~(1 << this->index);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -312,7 +312,7 @@ void BgPoEvent_BlockFall(BgPoEvent* this, GlobalContext* globalCtx) {
|
|||
if (Math_StepToF(&this->dyna.actor.world.pos.y, 433.0f, this->dyna.actor.velocity.y)) {
|
||||
this->dyna.actor.flags &= ~ACTOR_FLAG_5;
|
||||
this->dyna.actor.velocity.y = 0.0f;
|
||||
sBlocksAtRest++;
|
||||
sBgPoEventBlocksAtRest++;
|
||||
if (this->type != 1) {
|
||||
BgPoEvent_CheckBlock(this);
|
||||
} else {
|
||||
|
@ -334,7 +334,7 @@ void BgPoEvent_BlockIdle(BgPoEvent* this, GlobalContext* globalCtx) {
|
|||
Player* player = GET_PLAYER(globalCtx);
|
||||
Actor* amy;
|
||||
|
||||
if (sPuzzleState == 0xF) {
|
||||
if (sBgPoEventPuzzleState == 0xF) {
|
||||
this->actionFunc = BgPoEvent_BlockSolved;
|
||||
if ((this->type == 0) && (this->index == 0)) {
|
||||
amy =
|
||||
|
@ -348,23 +348,23 @@ void BgPoEvent_BlockIdle(BgPoEvent* this, GlobalContext* globalCtx) {
|
|||
gSaveContext.timer1State = 0xA;
|
||||
}
|
||||
} else {
|
||||
if ((gSaveContext.timer1Value == 0) && (sBlocksAtRest == 5)) {
|
||||
if ((gSaveContext.timer1Value == 0) && (sBgPoEventBlocksAtRest == 5)) {
|
||||
player->stateFlags2 &= ~0x10;
|
||||
sPuzzleState = 0x10;
|
||||
sBlocksAtRest = 0;
|
||||
sBgPoEventPuzzleState = 0x10;
|
||||
sBgPoEventBlocksAtRest = 0;
|
||||
}
|
||||
if ((sPuzzleState == 0x40) || ((sPuzzleState == 0x10) && !Player_InCsMode(globalCtx))) {
|
||||
if ((sBgPoEventPuzzleState == 0x40) || ((sBgPoEventPuzzleState == 0x10) && !Player_InCsMode(globalCtx))) {
|
||||
this->dyna.actor.world.rot.z = this->dyna.actor.shape.rot.z;
|
||||
this->actionFunc = BgPoEvent_BlockReset;
|
||||
if (sPuzzleState == 0x10) {
|
||||
sPuzzleState = 0x40;
|
||||
if (sBgPoEventPuzzleState == 0x10) {
|
||||
sBgPoEventPuzzleState = 0x40;
|
||||
Audio_PlayActorSound2(&this->dyna.actor, NA_SE_EV_BLOCK_RISING);
|
||||
func_8002DF54(globalCtx, &player->actor, 8);
|
||||
}
|
||||
} else if (this->dyna.unk_150 != 0.0f) {
|
||||
if (this->direction == 0) {
|
||||
if (func_800435D8(globalCtx, &this->dyna, 0x1E, 0x32, -0x14) != 0) {
|
||||
sBlocksAtRest--;
|
||||
sBgPoEventBlocksAtRest--;
|
||||
this->direction = (this->dyna.unk_150 >= 0.0f) ? 1.0f : -1.0f;
|
||||
this->actionFunc = BgPoEvent_BlockPush;
|
||||
} else {
|
||||
|
@ -382,16 +382,16 @@ void BgPoEvent_BlockIdle(BgPoEvent* this, GlobalContext* globalCtx) {
|
|||
}
|
||||
}
|
||||
|
||||
static f32 blockPushDist = 0.0f;
|
||||
f32 sBgPoEventblockPushDist = 0.0f;
|
||||
void BgPoEvent_BlockPush(BgPoEvent* this, GlobalContext* globalCtx) {
|
||||
f32 displacement;
|
||||
s32 blockStop;
|
||||
Player* player = GET_PLAYER(globalCtx);
|
||||
|
||||
this->dyna.actor.speedXZ += 0.1f;
|
||||
this->dyna.actor.speedXZ += CVar_GetS32("gFasterBlockPush", 0) != 0 ? 0.5f : 0.1f;
|
||||
this->dyna.actor.speedXZ = CLAMP_MAX(this->dyna.actor.speedXZ, 2.0f);
|
||||
blockStop = Math_StepToF(&blockPushDist, 20.0f, this->dyna.actor.speedXZ);
|
||||
displacement = this->direction * blockPushDist;
|
||||
blockStop = Math_StepToF(&sBgPoEventblockPushDist, 20.0f, this->dyna.actor.speedXZ);
|
||||
displacement = this->direction * sBgPoEventblockPushDist;
|
||||
this->dyna.actor.world.pos.x = (Math_SinS(this->dyna.unk_158) * displacement) + this->dyna.actor.home.pos.x;
|
||||
this->dyna.actor.world.pos.z = (Math_CosS(this->dyna.unk_158) * displacement) + this->dyna.actor.home.pos.z;
|
||||
if (blockStop) {
|
||||
|
@ -402,10 +402,10 @@ void BgPoEvent_BlockPush(BgPoEvent* this, GlobalContext* globalCtx) {
|
|||
this->dyna.unk_150 = 0.0f;
|
||||
this->dyna.actor.home.pos.x = this->dyna.actor.world.pos.x;
|
||||
this->dyna.actor.home.pos.z = this->dyna.actor.world.pos.z;
|
||||
blockPushDist = 0.0f;
|
||||
sBgPoEventblockPushDist = 0.0f;
|
||||
this->dyna.actor.speedXZ = 0.0f;
|
||||
this->direction = 5;
|
||||
sBlocksAtRest++;
|
||||
this->direction = CVar_GetS32("gFasterBlockPush", 0) != 0 ? 3 : 5;
|
||||
sBgPoEventBlocksAtRest++;
|
||||
this->actionFunc = BgPoEvent_BlockIdle;
|
||||
if (this->type == 1) {
|
||||
return;
|
||||
|
@ -428,7 +428,7 @@ void BgPoEvent_BlockReset(BgPoEvent* this, GlobalContext* globalCtx) {
|
|||
|
||||
this->index = (this->index + 1) % 4;
|
||||
this->actionFunc = BgPoEvent_BlockFall;
|
||||
sPuzzleState = 0;
|
||||
sBgPoEventPuzzleState = 0;
|
||||
if (this->type == 1) {
|
||||
this->timer += 10;
|
||||
this->timer = CLAMP_MAX(this->timer, 120);
|
||||
|
@ -443,14 +443,14 @@ void BgPoEvent_BlockSolved(BgPoEvent* this, GlobalContext* globalCtx) {
|
|||
player->stateFlags2 &= ~0x10;
|
||||
}
|
||||
if (Math_StepToF(&this->dyna.actor.world.pos.y, 369.0f, 2.0f)) {
|
||||
sPuzzleState = 0x20;
|
||||
sBgPoEventPuzzleState = 0x20;
|
||||
Actor_Kill(&this->dyna.actor);
|
||||
}
|
||||
}
|
||||
|
||||
void BgPoEvent_AmyWait(BgPoEvent* this, GlobalContext* globalCtx) {
|
||||
if (this->collider.base.acFlags & AC_HIT) {
|
||||
sPuzzleState |= 0x20;
|
||||
sBgPoEventPuzzleState |= 0x20;
|
||||
this->timer = 5;
|
||||
Actor_SetColorFilter(&this->dyna.actor, 0x4000, 0xFF, 0, 5);
|
||||
Audio_PlayActorSound2(&this->dyna.actor, NA_SE_EN_PO_LAUGH2);
|
||||
|
@ -461,12 +461,12 @@ void BgPoEvent_AmyWait(BgPoEvent* this, GlobalContext* globalCtx) {
|
|||
void BgPoEvent_AmyPuzzle(BgPoEvent* this, GlobalContext* globalCtx) {
|
||||
Vec3f pos;
|
||||
|
||||
if (sPuzzleState == 0xF) {
|
||||
if (sBgPoEventPuzzleState == 0xF) {
|
||||
pos.x = this->dyna.actor.world.pos.x - 5.0f;
|
||||
pos.y = Rand_CenteredFloat(120.0f) + this->dyna.actor.world.pos.y;
|
||||
pos.z = Rand_CenteredFloat(120.0f) + this->dyna.actor.world.pos.z;
|
||||
EffectSsDeadDb_Spawn(globalCtx, &pos, &sZeroVec, &sZeroVec, 170, 0, 200, 255, 100, 170, 0, 255, 0, 1, 9, true);
|
||||
} else if (sPuzzleState == 0x20) {
|
||||
} else if (sBgPoEventPuzzleState == 0x20) {
|
||||
Actor_Kill(&this->dyna.actor);
|
||||
} else {
|
||||
DECR(this->timer);
|
||||
|
@ -476,14 +476,14 @@ void BgPoEvent_AmyPuzzle(BgPoEvent* this, GlobalContext* globalCtx) {
|
|||
s32 BgPoEvent_NextPainting(BgPoEvent* this) {
|
||||
if ((this->dyna.actor.parent != NULL) && (this->dyna.actor.child != NULL)) {
|
||||
if (Rand_ZeroOne() < 0.5f) {
|
||||
sPuzzleState = ((BgPoEvent*)this->dyna.actor.parent)->index;
|
||||
sBgPoEventPuzzleState = ((BgPoEvent*)this->dyna.actor.parent)->index;
|
||||
} else {
|
||||
sPuzzleState = ((BgPoEvent*)this->dyna.actor.child)->index;
|
||||
sBgPoEventPuzzleState = ((BgPoEvent*)this->dyna.actor.child)->index;
|
||||
}
|
||||
} else if (this->dyna.actor.parent != NULL) {
|
||||
sPuzzleState = ((BgPoEvent*)this->dyna.actor.parent)->index;
|
||||
sBgPoEventPuzzleState = ((BgPoEvent*)this->dyna.actor.parent)->index;
|
||||
} else if (this->dyna.actor.child != NULL) {
|
||||
sPuzzleState = ((BgPoEvent*)this->dyna.actor.child)->index;
|
||||
sBgPoEventPuzzleState = ((BgPoEvent*)this->dyna.actor.child)->index;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
@ -491,7 +491,7 @@ s32 BgPoEvent_NextPainting(BgPoEvent* this) {
|
|||
}
|
||||
|
||||
void BgPoEvent_PaintingEmpty(BgPoEvent* this, GlobalContext* globalCtx) {
|
||||
if (sPuzzleState == this->index) {
|
||||
if (sBgPoEventPuzzleState == this->index) {
|
||||
this->timer = 255;
|
||||
this->actionFunc = BgPoEvent_PaintingAppear;
|
||||
}
|
||||
|
@ -636,7 +636,7 @@ void BgPoEvent_Draw(Actor* thisx, GlobalContext* globalCtx) {
|
|||
}
|
||||
|
||||
void BgPoEvent_Reset(void) {
|
||||
sBlocksAtRest = 0;
|
||||
sPuzzleState = 0;
|
||||
blockPushDist = 0.0f;
|
||||
sBgPoEventBlocksAtRest = 0;
|
||||
sBgPoEventPuzzleState = 0;
|
||||
sBgPoEventblockPushDist = 0.0f;
|
||||
}
|
|
@ -45,7 +45,7 @@ static InitChainEntry sInitChain[] = {
|
|||
ICHAIN_VEC3F_DIV1000(scale, 100, ICHAIN_STOP),
|
||||
};
|
||||
|
||||
static u32 D_808A9508 = 0;
|
||||
u32 D_808A9508 = 0;
|
||||
void BgRelayObjects_Init(Actor* thisx, GlobalContext* globalCtx) {
|
||||
BgRelayObjects* this = (BgRelayObjects*)thisx;
|
||||
s32 pad;
|
||||
|
|
|
@ -260,7 +260,7 @@ void func_808B4194(BgSpot15Rrbox* this, GlobalContext* globalCtx) {
|
|||
s32 approxFResult;
|
||||
Actor* actor = &this->dyna.actor;
|
||||
|
||||
this->unk_174 += 0.5f;
|
||||
this->unk_174 += CVar_GetS32("gFasterBlockPush", 0) != 0 ? 1.0f : 0.5f;
|
||||
|
||||
this->unk_174 = CLAMP_MAX(this->unk_174, 2.0f);
|
||||
|
||||
|
@ -294,7 +294,7 @@ void func_808B4194(BgSpot15Rrbox* this, GlobalContext* globalCtx) {
|
|||
this->dyna.unk_150 = 0.0f;
|
||||
this->unk_178 = 0.0f;
|
||||
this->unk_174 = 0.0f;
|
||||
this->unk_168 = 10;
|
||||
this->unk_168 = CVar_GetS32("gFasterBlockPush", 0) != 0 ? 3 : 10;
|
||||
func_808B4084(this, globalCtx);
|
||||
}
|
||||
Audio_PlayActorSound2(actor, NA_SE_EV_ROCK_SLIDE - SFX_FLAG);
|
||||
|
|
|
@ -84,7 +84,7 @@ void func_808B7710(Actor* thisx, GlobalContext* globalCtx) {
|
|||
this->dyna.actor.colChkInfo.mass = MASS_IMMOVABLE;
|
||||
}
|
||||
|
||||
static s16 D_808B85D0 = 0;
|
||||
s16 D_808B85D0 = 0;
|
||||
void func_808B7770(BgSpot18Basket* this, GlobalContext* globalCtx, f32 arg2) {
|
||||
Vec3f acceleration;
|
||||
Vec3f velocity;
|
||||
|
|
|
@ -12,6 +12,8 @@
|
|||
#include "overlays/actors/ovl_Door_Warp1/z_door_warp1.h"
|
||||
#include "objects/gameplay_keep/gameplay_keep.h"
|
||||
|
||||
#include "soh/frame_interpolation.h"
|
||||
|
||||
#define FLAGS (ACTOR_FLAG_0 | ACTOR_FLAG_2 | ACTOR_FLAG_4 | ACTOR_FLAG_5)
|
||||
|
||||
typedef enum {
|
||||
|
@ -78,6 +80,7 @@ void BossFd_SpawnEmber(BossFdEffect* effect, Vec3f* position, Vec3f* velocity, V
|
|||
effect->scale = scale / 1000.0f;
|
||||
effect->alpha = 255;
|
||||
effect->timer1 = (s16)Rand_ZeroFloat(10.0f);
|
||||
effect->epoch++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -95,6 +98,7 @@ void BossFd_SpawnDebris(BossFdEffect* effect, Vec3f* position, Vec3f* velocity,
|
|||
effect->scale = scale / 1000.0f;
|
||||
effect->vFdFxRotX = Rand_ZeroFloat(100.0f);
|
||||
effect->vFdFxRotY = Rand_ZeroFloat(100.0f);
|
||||
effect->epoch++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -111,6 +115,7 @@ void BossFd_SpawnDust(BossFdEffect* effect, Vec3f* position, Vec3f* velocity, Ve
|
|||
effect->accel = *acceleration;
|
||||
effect->timer2 = 0;
|
||||
effect->scale = scale / 400.0f;
|
||||
effect->epoch++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -136,6 +141,7 @@ void BossFd_SpawnFireBreath(BossFdEffect* effect, Vec3f* position, Vec3f* veloci
|
|||
effect->timer2 = 0;
|
||||
effect->scale = scale / 400.0f;
|
||||
effect->kbAngle = kbAngle;
|
||||
effect->epoch++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -1522,6 +1528,7 @@ void BossFd_DrawEffects(BossFdEffect* effect, GlobalContext* globalCtx) {
|
|||
|
||||
for (i = 0; i < 180; i++, effect++) {
|
||||
if (effect->type == BFD_FX_EMBER) {
|
||||
FrameInterpolation_RecordOpenChild(effect, effect->epoch);
|
||||
if (!flag) {
|
||||
func_80093D84(globalCtx->state.gfxCtx);
|
||||
gSPDisplayList(POLY_XLU_DISP++, gVolvagiaEmberMaterialDL);
|
||||
|
@ -1536,6 +1543,7 @@ void BossFd_DrawEffects(BossFdEffect* effect, GlobalContext* globalCtx) {
|
|||
gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(gfxCtx, "../z_boss_fd.c", 4046),
|
||||
G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
|
||||
gSPDisplayList(POLY_XLU_DISP++, gVolvagiaEmberModelDL);
|
||||
FrameInterpolation_RecordCloseChild();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1543,6 +1551,7 @@ void BossFd_DrawEffects(BossFdEffect* effect, GlobalContext* globalCtx) {
|
|||
flag = false;
|
||||
for (i = 0; i < 180; i++, effect++) {
|
||||
if (effect->type == BFD_FX_DEBRIS) {
|
||||
FrameInterpolation_RecordOpenChild(effect, effect->epoch);
|
||||
if (!flag) {
|
||||
func_80093D18(globalCtx->state.gfxCtx);
|
||||
gSPDisplayList(POLY_OPA_DISP++, gVolvagiaDebrisMaterialDL);
|
||||
|
@ -1557,6 +1566,7 @@ void BossFd_DrawEffects(BossFdEffect* effect, GlobalContext* globalCtx) {
|
|||
gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(gfxCtx, "../z_boss_fd.c", 4068),
|
||||
G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
|
||||
gSPDisplayList(POLY_OPA_DISP++, gVolvagiaDebrisModelDL);
|
||||
FrameInterpolation_RecordCloseChild();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1564,6 +1574,7 @@ void BossFd_DrawEffects(BossFdEffect* effect, GlobalContext* globalCtx) {
|
|||
flag = false;
|
||||
for (i = 0; i < 180; i++, effect++) {
|
||||
if (effect->type == BFD_FX_DUST) {
|
||||
FrameInterpolation_RecordOpenChild(effect, effect->epoch);
|
||||
if (!flag) {
|
||||
POLY_XLU_DISP = Gfx_CallSetupDL(POLY_XLU_DISP, 0);
|
||||
gSPDisplayList(POLY_XLU_DISP++, gVolvagiaDustMaterialDL);
|
||||
|
@ -1580,6 +1591,7 @@ void BossFd_DrawEffects(BossFdEffect* effect, GlobalContext* globalCtx) {
|
|||
G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
|
||||
gSPSegment(POLY_XLU_DISP++, 0x08, SEGMENTED_TO_VIRTUAL(dustTex[effect->timer2]));
|
||||
gSPDisplayList(POLY_XLU_DISP++, gVolvagiaDustModelDL);
|
||||
FrameInterpolation_RecordCloseChild();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1587,6 +1599,7 @@ void BossFd_DrawEffects(BossFdEffect* effect, GlobalContext* globalCtx) {
|
|||
flag = false;
|
||||
for (i = 0; i < 180; i++, effect++) {
|
||||
if (effect->type == BFD_FX_FIRE_BREATH) {
|
||||
FrameInterpolation_RecordOpenChild(effect, effect->epoch);
|
||||
if (!flag) {
|
||||
POLY_XLU_DISP = Gfx_CallSetupDL(POLY_XLU_DISP, 0);
|
||||
gSPDisplayList(POLY_XLU_DISP++, gVolvagiaDustMaterialDL);
|
||||
|
@ -1603,6 +1616,7 @@ void BossFd_DrawEffects(BossFdEffect* effect, GlobalContext* globalCtx) {
|
|||
G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
|
||||
gSPSegment(POLY_XLU_DISP++, 0x08, SEGMENTED_TO_VIRTUAL(dustTex[effect->timer2]));
|
||||
gSPDisplayList(POLY_XLU_DISP++, gVolvagiaDustModelDL);
|
||||
FrameInterpolation_RecordCloseChild();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1610,6 +1624,7 @@ void BossFd_DrawEffects(BossFdEffect* effect, GlobalContext* globalCtx) {
|
|||
flag = false;
|
||||
for (i = 0; i < 180; i++, effect++) {
|
||||
if (effect->type == BFD_FX_SKULL_PIECE) {
|
||||
FrameInterpolation_RecordOpenChild(effect, effect->epoch);
|
||||
if (!flag) {
|
||||
func_80093D84(globalCtx->state.gfxCtx);
|
||||
gSPDisplayList(POLY_XLU_DISP++, gVolvagiaSkullPieceMaterialDL);
|
||||
|
@ -1624,6 +1639,7 @@ void BossFd_DrawEffects(BossFdEffect* effect, GlobalContext* globalCtx) {
|
|||
gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(gfxCtx, "../z_boss_fd.c", 4192),
|
||||
G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
|
||||
gSPDisplayList(POLY_XLU_DISP++, gVolvagiaSkullPieceModelDL);
|
||||
FrameInterpolation_RecordCloseChild();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -49,6 +49,7 @@ typedef struct {
|
|||
/* 0x30 */ f32 scale;
|
||||
/* 0x34 */ f32 bFdFxFloat1;
|
||||
/* 0x38 */ f32 bFdFxFloat2;
|
||||
u32 epoch;
|
||||
} BossFdEffect; // size = 0x3C
|
||||
|
||||
#define BOSSFD_EFFECT_COUNT 180
|
||||
|
|
|
@ -87,6 +87,7 @@ void BossFd2_SpawnDebris(GlobalContext* globalCtx, BossFdEffect* effect, Vec3f*
|
|||
effect->scale = scale / 1000.0f;
|
||||
effect->vFdFxRotX = Rand_ZeroFloat(100.0f);
|
||||
effect->vFdFxRotY = Rand_ZeroFloat(100.0f);
|
||||
effect->epoch++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -112,6 +113,7 @@ void BossFd2_SpawnFireBreath(GlobalContext* globalCtx, BossFdEffect* effect, Vec
|
|||
effect->timer2 = 0;
|
||||
effect->scale = scale / 400.0f;
|
||||
effect->kbAngle = kbAngle;
|
||||
effect->epoch++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -130,6 +132,7 @@ void BossFd2_SpawnEmber(GlobalContext* globalCtx, BossFdEffect* effect, Vec3f* p
|
|||
effect->scale = scale / 1000.0f;
|
||||
effect->alpha = 255;
|
||||
effect->timer1 = (s16)Rand_ZeroFloat(10.0f);
|
||||
effect->epoch++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -148,6 +151,7 @@ void BossFd2_SpawnSkullPiece(GlobalContext* globalCtx, BossFdEffect* effect, Vec
|
|||
effect->scale = scale / 1000.0f;
|
||||
effect->vFdFxRotX = Rand_ZeroFloat(100.0f);
|
||||
effect->vFdFxRotY = Rand_ZeroFloat(100.0f);
|
||||
effect->epoch++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -164,6 +168,7 @@ void BossFd2_SpawnDust(BossFdEffect* effect, Vec3f* position, Vec3f* velocity, V
|
|||
effect->accel = *acceleration;
|
||||
effect->timer2 = 0;
|
||||
effect->scale = scale / 400.0f;
|
||||
effect->epoch++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue