Merge pull request #1039 from HarbourMasters/develop-zhora

zhora -> rando-next
This commit is contained in:
briaguya 2022-08-03 21:02:29 -07:00 committed by GitHub
commit 2d22099805
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
122 changed files with 1403 additions and 1202 deletions

View File

@ -14,3 +14,11 @@ namespace Ship {
constexpr int GetSampleRate() const { return 44100; }
};
}
#ifdef _WIN32
#include "WasapiAudioPlayer.h"
#elif defined(__linux)
#include "PulseAudioPlayer.h"
#else
#include "SDLAudioPlayer.h"
#endif

View File

@ -10,115 +10,116 @@
#include "Utils/StringHelper.h"
#include "Lib/ImGui/imgui_internal.h"
std::map<ImGuiKey, std::string> Bindings;
std::map<ImGuiKey, std::string> BindingToggle;
namespace Ship {
std::map<ImGuiKey, std::string> Bindings;
std::map<ImGuiKey, std::string> BindingToggle;
static bool HelpCommand(const std::vector<std::string>&) {
INFO("SoH Commands:");
for(const auto& cmd : SohImGui::console->Commands) {
INFO("%s", (" - " + cmd.first).c_str());
static bool HelpCommand(const std::vector<std::string>&) {
INFO("SoH Commands:");
for (const auto& cmd : SohImGui::console->Commands) {
INFO("%s", (" - " + cmd.first).c_str());
}
return CMD_SUCCESS;
}
return CMD_SUCCESS;
}
static bool ClearCommand(const std::vector<std::string>&) {
SohImGui::console->Log[SohImGui::console->selected_channel].clear();
return CMD_SUCCESS;
}
static bool ClearCommand(const std::vector<std::string>&) {
SohImGui::console->Log[SohImGui::console->selected_channel].clear();
return CMD_SUCCESS;
}
std::string toLowerCase(std::string in) {
std::string cpy(in);
std::transform(cpy.begin(), cpy.end(), cpy.begin(), ::tolower);
return cpy;
}
std::string toLowerCase(std::string in) {
std::string cpy(in);
std::transform(cpy.begin(), cpy.end(), cpy.begin(), ::tolower);
return cpy;
}
static bool BindCommand(const std::vector<std::string>& args) {
if(args.size() > 2) {
const ImGuiIO* io = &ImGui::GetIO();;
for (size_t k = 0; k < std::size(io->KeysData); k++) {
std::string key(ImGui::GetKeyName(k));
static bool BindCommand(const std::vector<std::string>& args) {
if (args.size() > 2) {
const ImGuiIO* io = &ImGui::GetIO();;
for (size_t k = 0; k < std::size(io->KeysData); k++) {
std::string key(ImGui::GetKeyName(k));
if(toLowerCase(args[1]) == toLowerCase(key)) {
std::vector<std::string> tmp;
const char* const delim = " ";
std::ostringstream imploded;
std::copy(args.begin() + 2, args.end(), std::ostream_iterator<std::string>(imploded, delim));
Bindings[k] = imploded.str();
INFO("Binding '%s' to %s", args[1].c_str(), Bindings[k].c_str());
break;
if (toLowerCase(args[1]) == toLowerCase(key)) {
std::vector<std::string> tmp;
const char* const delim = " ";
std::ostringstream imploded;
std::copy(args.begin() + 2, args.end(), std::ostream_iterator<std::string>(imploded, delim));
Bindings[k] = imploded.str();
INFO("Binding '%s' to %s", args[1].c_str(), Bindings[k].c_str());
break;
}
}
}
return CMD_SUCCESS;
}
static bool BindToggleCommand(const std::vector<std::string>& args) {
if (args.size() > 2) {
const ImGuiIO* io = &ImGui::GetIO();;
for (size_t k = 0; k < std::size(io->KeysData); k++) {
std::string key(ImGui::GetKeyName(k));
if (toLowerCase(args[1]) == toLowerCase(key)) {
BindingToggle[k] = args[2];
INFO("Binding toggle '%s' to %s", args[1].c_str(), BindingToggle[k].c_str());
break;
}
}
}
return CMD_SUCCESS;
}
std::string BuildUsage(const CommandEntry& entry) {
std::string usage;
for (const auto& arg : entry.arguments)
usage += StringHelper::Sprintf(arg.optional ? "[%s] " : "<%s> ", arg.info.c_str());
return usage;
}
void Console::Init() {
this->InputBuffer = new char[MAX_BUFFER_SIZE];
strcpy(this->InputBuffer, "");
this->FilterBuffer = new char[MAX_BUFFER_SIZE];
strcpy(this->FilterBuffer, "");
this->Commands["help"] = { HelpCommand, "Shows all the commands" };
this->Commands["clear"] = { ClearCommand, "Clear the console history" };
this->Commands["bind"] = { BindCommand, "Binds key to commands" };
this->Commands["bind-toggle"] = { BindToggleCommand, "Bind key as a bool toggle" };
}
void Console::Update() {
for (auto [key, cmd] : Bindings) {
if (ImGui::IsKeyPressed(key)) Dispatch(cmd);
}
for (auto [key, var] : BindingToggle) {
if (ImGui::IsKeyPressed(key)) {
CVar* cvar = CVar_Get(var.c_str());
Dispatch("set " + var + " " + std::to_string(cvar == nullptr ? 0 : !static_cast<bool>(cvar->value.valueS32)));
}
}
}
return CMD_SUCCESS;
}
static bool BindToggleCommand(const std::vector<std::string>& args) {
if (args.size() > 2) {
const ImGuiIO* io = &ImGui::GetIO();;
for (size_t k = 0; k < std::size(io->KeysData); k++) {
std::string key(ImGui::GetKeyName(k));
void Console::Draw() {
bool input_focus = false;
if (!this->opened) return;
if (toLowerCase(args[1]) == toLowerCase(key)) {
BindingToggle[k] = args[2];
INFO("Binding toggle '%s' to %s", args[1].c_str(), BindingToggle[k].c_str());
break;
}
}
}
return CMD_SUCCESS;
}
std::string BuildUsage(const CommandEntry& entry) {
std::string usage;
for (const auto& arg : entry.arguments)
usage += StringHelper::Sprintf(arg.optional ? "[%s] " : "<%s> ", arg.info.c_str());
return usage;
}
void Console::Init() {
this->InputBuffer = new char[MAX_BUFFER_SIZE];
strcpy(this->InputBuffer, "");
this->FilterBuffer = new char[MAX_BUFFER_SIZE];
strcpy(this->FilterBuffer, "");
this->Commands["help"] = { HelpCommand, "Shows all the commands" };
this->Commands["clear"] = { ClearCommand, "Clear the console history" };
this->Commands["bind"] = { BindCommand, "Binds key to commands" };
this->Commands["bind-toggle"] = { BindToggleCommand, "Bind key as a bool toggle" };
}
void Console::Update() {
for(auto [key, cmd] : Bindings) {
if (ImGui::IsKeyPressed(key)) Dispatch(cmd);
}
for (auto [key, var] : BindingToggle) {
if (ImGui::IsKeyPressed(key)) {
CVar* cvar = CVar_Get(var.c_str());
Dispatch("set " + var + " " + std::to_string(cvar == nullptr ? 0 : !static_cast<bool>(cvar->value.valueS32)));
}
}
}
void Console::Draw() {
bool input_focus = false;
if (!this->opened) return;
ImGui::SetNextWindowSize(ImVec2(520, 600), ImGuiCond_FirstUseEver);
ImGui::Begin("Console", nullptr, ImGuiWindowFlags_NoFocusOnAppearing);
ImGui::SetNextWindowSize(ImVec2(520, 600), ImGuiCond_FirstUseEver);
ImGui::Begin("Console", nullptr, ImGuiWindowFlags_NoFocusOnAppearing);
const ImVec2 pos = ImGui::GetWindowPos();
const ImVec2 size = ImGui::GetWindowSize();
// SohImGui::ShowCursor(ImGui::IsWindowHovered(ImGuiHoveredFlags_RootAndChildWindows | ImGuiHoveredFlags_RectOnly), SohImGui::Dialogues::dConsole);
// Renders autocomplete window
if(this->OpenAutocomplete) {
if (this->OpenAutocomplete) {
ImGui::SetNextWindowSize(ImVec2(350, std::min(static_cast<int>(this->Autocomplete.size()), 3) * 20.f), ImGuiCond_Once);
ImGui::SetNextWindowPos(ImVec2(pos.x + 8, pos.y + size.y - 1));
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(3, 3));
ImGui::Begin("##WndAutocomplete", nullptr, ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoMove );
ImGui::Begin("##WndAutocomplete", nullptr, ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoMove);
ImGui::BeginChild("AC_Child", ImVec2(0, 0), false, ImGuiWindowFlags_HorizontalScrollbar);
ImGui::PushStyleColor(ImGuiCol_FrameBgActive, ImVec4(.3f, .3f, .3f, 1.0f));
if (ImGui::BeginTable("AC_History", 1)) {
for (const auto &cmd : this->Autocomplete) {
std::string usage = BuildUsage(this->Commands[cmd]);
for (const auto& cmd : this->Autocomplete) {
std::string usage = BuildUsage(this->Commands[cmd]);
std::string preview = cmd + " - " + this->Commands[cmd].description;
std::string autocomplete = (usage == NULLSTR ? cmd : usage);
ImGui::TableNextRow();
@ -186,53 +187,53 @@ void Console::Draw() {
// Renders console history
const float footer_height_to_reserve = ImGui::GetStyle().ItemSpacing.y + ImGui::GetFrameHeightWithSpacing();
ImGui::BeginChild("ScrollingRegion", ImVec2(0, -footer_height_to_reserve), false, ImGuiWindowFlags_HorizontalScrollbar);
ImGui::PushStyleColor(ImGuiCol_FrameBgActive, ImVec4(.3f, .3f, .3f, 1.0f));
if (ImGui::BeginTable("History", 1)) {
ImGui::PushStyleColor(ImGuiCol_FrameBgActive, ImVec4(.3f, .3f, .3f, 1.0f));
if (ImGui::BeginTable("History", 1)) {
if (ImGui::IsKeyPressed(ImGui::GetKeyIndex(ImGuiKey_DownArrow)))
if (this->selectedId < (int)this->Log.size() - 1) ++this->selectedId;
if (ImGui::IsKeyPressed(ImGui::GetKeyIndex(ImGuiKey_UpArrow)))
if (this->selectedId > 0) --this->selectedId;
if (ImGui::IsKeyPressed(ImGui::GetKeyIndex(ImGuiKey_DownArrow)))
if (this->selectedId < (int)this->Log.size() - 1)++this->selectedId;
if (ImGui::IsKeyPressed(ImGui::GetKeyIndex(ImGuiKey_UpArrow)))
if (this->selectedId > 0)--this->selectedId;
const std::vector<ConsoleLine> channel = this->Log[this->selected_channel];
for (int i = 0; i < static_cast<int>(channel.size()); i++) {
ConsoleLine line = channel[i];
if(!this->filter.empty() && line.text.find(this->filter) == std::string::npos) continue;
if(this->level_filter != NULLSTR && line.priority != (std::find(priority_filters.begin(), priority_filters.end(), this->level_filter) - priority_filters.begin()) - 1) continue;
std::string id = line.text + "##" + std::to_string(i);
ImGui::TableNextRow();
ImGui::TableSetColumnIndex(0);
const bool is_selected = (this->selectedId == i) || std::find(this->selectedEntries.begin(), this->selectedEntries.end(), i) != this->selectedEntries.end();
ImGui::PushStyleColor(ImGuiCol_Text, this->priority_colors[line.priority]);
if (ImGui::Selectable(id.c_str(), is_selected)) {
if (ImGui::IsKeyDown(ImGui::GetKeyIndex(ImGuiKey_LeftCtrl)) && !is_selected)
this->selectedEntries.push_back(i);
const std::vector<ConsoleLine> channel = this->Log[this->selected_channel];
for (int i = 0; i < static_cast<int>(channel.size()); i++) {
ConsoleLine line = channel[i];
if (!this->filter.empty() && line.text.find(this->filter) == std::string::npos) continue;
if (this->level_filter != NULLSTR && line.priority != (std::find(priority_filters.begin(), priority_filters.end(), this->level_filter) - priority_filters.begin()) - 1) continue;
std::string id = line.text + "##" + std::to_string(i);
ImGui::TableNextRow();
ImGui::TableSetColumnIndex(0);
const bool is_selected = (this->selectedId == i) || std::find(this->selectedEntries.begin(), this->selectedEntries.end(), i) != this->selectedEntries.end();
ImGui::PushStyleColor(ImGuiCol_Text, this->priority_colors[line.priority]);
if (ImGui::Selectable(id.c_str(), is_selected)) {
if (ImGui::IsKeyDown(ImGui::GetKeyIndex(ImGuiKey_LeftCtrl)) && !is_selected)
this->selectedEntries.push_back(i);
else this->selectedEntries.clear();
this->selectedId = is_selected ? -1 : i;
}
ImGui::PopStyleColor();
if (is_selected) ImGui::SetItemDefaultFocus();
else this->selectedEntries.clear();
this->selectedId = is_selected ? -1 : i;
}
ImGui::EndTable();
ImGui::PopStyleColor();
if (is_selected) ImGui::SetItemDefaultFocus();
}
ImGui::PopStyleColor();
if (ImGui::GetScrollY() >= ImGui::GetScrollMaxY())
ImGui::SetScrollHereY(1.0f);
ImGui::EndTable();
}
ImGui::PopStyleColor();
if (ImGui::GetScrollY() >= ImGui::GetScrollMaxY())
ImGui::SetScrollHereY(1.0f);
ImGui::EndChild();
// Renders input textfield
constexpr ImGuiInputTextFlags flags = ImGuiInputTextFlags_EnterReturnsTrue | ImGuiInputTextFlags_CallbackEdit |
ImGuiInputTextFlags_CallbackCompletion | ImGuiInputTextFlags_CallbackHistory;
ImGuiInputTextFlags_CallbackCompletion | ImGuiInputTextFlags_CallbackHistory;
ImGui::PushItemWidth(-53);
if(ImGui::InputTextWithHint("##CMDInput", ">", this->InputBuffer, MAX_BUFFER_SIZE, flags, &Console::CallbackStub, this)) {
if (ImGui::InputTextWithHint("##CMDInput", ">", this->InputBuffer, MAX_BUFFER_SIZE, flags, &Console::CallbackStub, this)) {
input_focus = true;
if(this->InputBuffer[0] != '\0' && this->InputBuffer[0] != ' ')
if (this->InputBuffer[0] != '\0' && this->InputBuffer[0] != ' ')
this->Dispatch(std::string(this->InputBuffer));
memset(this->InputBuffer, 0, MAX_BUFFER_SIZE);
}
if(this->CMDHint != NULLSTR) {
if (this->CMDHint != NULLSTR) {
if (ImGui::IsItemFocused()) {
ImGui::SetNextWindowPos(ImVec2(pos.x, pos.y + size.y));
ImGui::SameLine();
@ -246,38 +247,38 @@ void Console::Draw() {
ImGui::SameLine();
ImGui::SetCursorPosX(ImGui::GetCursorPosX() + ImGui::GetContentRegionAvail().x - 50);
if(ImGui::Button("Submit") && !input_focus && this->InputBuffer[0] != '\0' && this->InputBuffer[0] != ' '){
this->Dispatch(std::string(this->InputBuffer));
if (ImGui::Button("Submit") && !input_focus && this->InputBuffer[0] != '\0' && this->InputBuffer[0] != ' ') {
this->Dispatch(std::string(this->InputBuffer));
memset(this->InputBuffer, 0, MAX_BUFFER_SIZE);
}
ImGui::SetItemDefaultFocus();
if (input_focus) ImGui::SetKeyboardFocusHere(-1);
ImGui::PopItemWidth();
ImGui::End();
}
void Console::Dispatch(const std::string& line) {
this->CMDHint = NULLSTR;
this->History.push_back(line);
this->Log[this->selected_channel].push_back({ "> " + line } );
const std::vector<std::string> cmd_args = StringHelper::Split(line, " ");
if (this->Commands.contains(cmd_args[0])) {
const CommandEntry entry = this->Commands[cmd_args[0]];
if(!entry.handler(cmd_args) && !entry.arguments.empty())
this->Log[this->selected_channel].push_back({ "[SOH] Usage: " + cmd_args[0] + " " + BuildUsage(entry), ERROR_LVL});
return;
ImGui::End();
}
this->Log[this->selected_channel].push_back({ "[SOH] Command not found", ERROR_LVL });
}
int Console::CallbackStub(ImGuiInputTextCallbackData* data) {
const auto instance = static_cast<Console*>(data->UserData);
const bool empty_history = instance->History.empty();
const int history_index = instance->HistoryIndex;
std::string history;
void Console::Dispatch(const std::string& line) {
this->CMDHint = NULLSTR;
this->History.push_back(line);
this->Log[this->selected_channel].push_back({ "> " + line });
const std::vector<std::string> cmd_args = StringHelper::Split(line, " ");
if (this->Commands.contains(cmd_args[0])) {
const CommandEntry entry = this->Commands[cmd_args[0]];
if (!entry.handler(cmd_args) && !entry.arguments.empty())
this->Log[this->selected_channel].push_back({ "[SOH] Usage: " + cmd_args[0] + " " + BuildUsage(entry), ERROR_LVL });
return;
}
this->Log[this->selected_channel].push_back({ "[SOH] Command not found", ERROR_LVL });
}
switch(data->EventKey) {
int Console::CallbackStub(ImGuiInputTextCallbackData* data) {
const auto instance = static_cast<Console*>(data->UserData);
const bool empty_history = instance->History.empty();
const int history_index = instance->HistoryIndex;
std::string history;
switch (data->EventKey) {
case ImGuiKey_Tab:
instance->Autocomplete.clear();
for (auto& [cmd, entry] : instance->Commands)
@ -287,7 +288,7 @@ int Console::CallbackStub(ImGuiInputTextCallbackData* data) {
break;
case ImGuiKey_UpArrow:
if (empty_history) break;
if(history_index < static_cast<int>(instance->History.size()) - 1) instance->HistoryIndex += 1;
if (history_index < static_cast<int>(instance->History.size()) - 1) instance->HistoryIndex += 1;
data->DeleteChars(0, data->BufTextLen);
data->InsertChars(0, instance->History[instance->HistoryIndex].c_str());
instance->CMDHint = NULLSTR;
@ -296,7 +297,7 @@ int Console::CallbackStub(ImGuiInputTextCallbackData* data) {
if (empty_history) break;
if (history_index > -1) instance->HistoryIndex -= 1;
data->DeleteChars(0, data->BufTextLen);
if(history_index >= 0)
if (history_index >= 0)
data->InsertChars(0, instance->History[history_index].c_str());
instance->CMDHint = NULLSTR;
break;
@ -316,16 +317,17 @@ int Console::CallbackStub(ImGuiInputTextCallbackData* data) {
}
instance->CMDHint = NULLSTR;
}
}
return 0;
}
return 0;
}
void Console::Append(const std::string& channel, Priority priority, 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->Log[channel].push_back({ std::string(buf), priority });
}
void Console::Append(const std::string& channel, Priority priority, 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->Log[channel].push_back({ std::string(buf), priority });
}
}

View File

@ -7,75 +7,77 @@
#include "Lib/ImGui/imgui.h"
#define LOG(msg, ...) SohImGui::console->Append("Main", Priority::LOG_LVL, msg, ##__VA_ARGS__)
#define INFO(msg, ...) SohImGui::console->Append("Main", Priority::INFO_LVL, msg, ##__VA_ARGS__)
#define WARNING(msg, ...) SohImGui::console->Append("Main", Priority::WARNING_LVL, msg, ##__VA_ARGS__)
#define ERROR(msg, ...) SohImGui::console->Append("Main", Priority::ERROR_LVL, msg, ##__VA_ARGS__)
#define CMD_SUCCESS true
#define CMD_FAILED false
#define MAX_BUFFER_SIZE 255
#define NULLSTR "None"
namespace Ship {
#define LOG(msg, ...) SohImGui::console->Append("Main", Ship::Priority::LOG_LVL, msg, ##__VA_ARGS__)
#define INFO(msg, ...) SohImGui::console->Append("Main", Ship::Priority::INFO_LVL, msg, ##__VA_ARGS__)
#define WARNING(msg, ...) SohImGui::console->Append("Main", Ship::Priority::WARNING_LVL, msg, ##__VA_ARGS__)
#define ERROR(msg, ...) SohImGui::console->Append("Main", Ship::Priority::ERROR_LVL, msg, ##__VA_ARGS__)
#define CMD_SUCCESS true
#define CMD_FAILED false
#define MAX_BUFFER_SIZE 255
#define NULLSTR "None"
typedef std::function<bool(std::vector<std::string> args)> CommandHandler;
typedef std::function<bool(std::vector<std::string> args)> CommandHandler;
enum Priority {
INFO_LVL,
LOG_LVL,
WARNING_LVL,
ERROR_LVL
};
enum class ArgumentType {
TEXT, NUMBER, PLAYER_POS, PLAYER_ROT
};
struct CommandArgument {
std::string info;
ArgumentType type = ArgumentType::NUMBER;
bool optional = false;
};
struct CommandEntry {
CommandHandler handler;
std::string description;
std::vector<CommandArgument> arguments;
};
struct ConsoleLine {
std::string text;
Priority priority = Priority::INFO_LVL;
std::string channel = "Main";
};
class Console {
int selectedId = -1;
std::vector<int> selectedEntries;
std::string filter;
std::string level_filter = NULLSTR;
std::vector<std::string> log_channels = { "Main", "SoH Logging"};
std::vector<std::string> priority_filters = { "None", "Info", "Log", "Warning", "Error" };
std::vector<ImVec4> priority_colors = {
ImVec4(1.0f, 1.0f, 1.0f, 1.0f),
ImVec4(0.2f, 1.0f, 0.2f, 1.0f),
ImVec4(0.9f, 0.8f, 0.4f, 0.01f),
ImVec4(1.0f, 0.2f, 0.2f, 1.0f)
enum Priority {
INFO_LVL,
LOG_LVL,
WARNING_LVL,
ERROR_LVL
};
public:
std::map<std::string, std::vector<ConsoleLine>> Log;
std::map<std::string, CommandEntry> Commands;
std::vector<std::string> Autocomplete;
std::vector<std::string> History;
std::string CMDHint = NULLSTR;
char* FilterBuffer = nullptr;
char* InputBuffer = nullptr;
bool OpenAutocomplete = false;
int HistoryIndex = -1;
std::string selected_channel = "Main";
bool opened = false;
void Init();
void Update();
void Draw();
void Append(const std::string& channel, Priority priority, const char* fmt, ...) IM_FMTARGS(4);
void Dispatch(const std::string& line);
static int CallbackStub(ImGuiInputTextCallbackData* data);
};
enum class ArgumentType {
TEXT, NUMBER, PLAYER_POS, PLAYER_ROT
};
struct CommandArgument {
std::string info;
ArgumentType type = ArgumentType::NUMBER;
bool optional = false;
};
struct CommandEntry {
CommandHandler handler;
std::string description;
std::vector<CommandArgument> arguments;
};
struct ConsoleLine {
std::string text;
Priority priority = Priority::INFO_LVL;
std::string channel = "Main";
};
class Console {
int selectedId = -1;
std::vector<int> selectedEntries;
std::string filter;
std::string level_filter = NULLSTR;
std::vector<std::string> log_channels = { "Main", "SoH Logging" };
std::vector<std::string> priority_filters = { "None", "Info", "Log", "Warning", "Error" };
std::vector<ImVec4> priority_colors = {
ImVec4(1.0f, 1.0f, 1.0f, 1.0f),
ImVec4(0.2f, 1.0f, 0.2f, 1.0f),
ImVec4(0.9f, 0.8f, 0.4f, 0.01f),
ImVec4(1.0f, 0.2f, 0.2f, 1.0f)
};
public:
std::map<std::string, std::vector<ConsoleLine>> Log;
std::map<std::string, CommandEntry> Commands;
std::vector<std::string> Autocomplete;
std::vector<std::string> History;
std::string CMDHint = NULLSTR;
char* FilterBuffer = nullptr;
char* InputBuffer = nullptr;
bool OpenAutocomplete = false;
int HistoryIndex = -1;
std::string selected_channel = "Main";
bool opened = false;
void Init();
void Update();
void Draw();
void Append(const std::string& channel, Priority priority, const char* fmt, ...) IM_FMTARGS(4);
void Dispatch(const std::string& line);
static int CallbackStub(ImGuiInputTextCallbackData* data);
};
}

View File

@ -7,148 +7,170 @@
#include "SDLController.h"
#include <Utils/StringHelper.h>
uint8_t* controllerBits;
namespace Ship {
uint8_t* controllerBits;
void Ship::ControlDeck::Init(uint8_t* bits) {
ScanPhysicalDevices();
controllerBits = bits;
}
void ControlDeck::Init(uint8_t* bits) {
ScanPhysicalDevices();
controllerBits = bits;
}
void Ship::ControlDeck::ScanPhysicalDevices() {
void ControlDeck::ScanPhysicalDevices() {
virtualDevices.clear();
physicalDevices.clear();
virtualDevices.clear();
physicalDevices.clear();
for (int i = 0; i < SDL_NumJoysticks(); i++) {
if (SDL_IsGameController(i)) {
auto sdl = std::make_shared<SDLController>(i);
sdl->Open();
physicalDevices.push_back(sdl);
}
}
for (int i = 0; i < SDL_NumJoysticks(); i++) {
if (SDL_IsGameController(i)) {
auto sdl = std::make_shared<SDLController>(i);
sdl->Open();
physicalDevices.push_back(sdl);
}
}
physicalDevices.push_back(std::make_shared<VirtualController>("Auto", "Auto", true));
physicalDevices.push_back(std::make_shared<KeyboardController>());
physicalDevices.push_back(std::make_shared<VirtualController>("Disconnected", "None", false));
physicalDevices.push_back(std::make_shared<VirtualController>("Auto", "Auto", true));
physicalDevices.push_back(std::make_shared<KeyboardController>());
physicalDevices.push_back(std::make_shared<VirtualController>("Disconnected", "None", false));
for (const auto& device : physicalDevices) {
for (int i = 0; i < MAXCONTROLLERS; i++) {
device->CreateDefaultBinding(i);
}
}
for (const auto& device : physicalDevices) {
for (int i = 0; i < MAXCONTROLLERS; i++) {
device->CreateDefaultBinding(i);
}
}
for (int i = 0; i < MAXCONTROLLERS; i++) {
virtualDevices.push_back(i == 0 ? 0 : static_cast<int>(physicalDevices.size()) - 1);
}
for (int i = 0; i < MAXCONTROLLERS; i++) {
virtualDevices.push_back(i == 0 ? 0 : static_cast<int>(physicalDevices.size()) - 1);
}
LoadControllerSettings();
}
LoadControllerSettings();
}
void Ship::ControlDeck::SetPhysicalDevice(int slot, int deviceSlot) {
const std::shared_ptr<Controller> backend = physicalDevices[deviceSlot];
virtualDevices[slot] = deviceSlot;
*controllerBits |= (backend->Connected()) << slot;
}
void ControlDeck::SetPhysicalDevice(int slot, int deviceSlot) {
const std::shared_ptr<Controller> backend = physicalDevices[deviceSlot];
virtualDevices[slot] = deviceSlot;
*controllerBits |= (backend->Connected()) << slot;
}
void Ship::ControlDeck::WriteToPad(OSContPad* pad) const {
for (size_t i = 0; i < virtualDevices.size(); i++) {
const std::shared_ptr<Controller> backend = physicalDevices[virtualDevices[i]];
if (backend->GetGuid() == "Auto") {
for (const auto& device : physicalDevices) {
device->Read(&pad[i], i);
}
continue;
}
backend->Read(&pad[i], i);
}
}
void ControlDeck::WriteToPad(OSContPad* pad) const {
for (size_t i = 0; i < virtualDevices.size(); i++) {
const std::shared_ptr<Controller> backend = physicalDevices[virtualDevices[i]];
if (backend->GetGuid() == "Auto") {
for (const auto& device : physicalDevices) {
device->Read(&pad[i], i);
}
continue;
}
backend->Read(&pad[i], i);
}
}
#define NESTED(key, ...) StringHelper::Sprintf("Controllers.%s.Slot_%d." key, device->GetGuid().c_str(), slot, __VA_ARGS__)
void Ship::ControlDeck::LoadControllerSettings() {
std::shared_ptr<Mercury> Config = GlobalCtx2::GetInstance()->GetConfig();
void ControlDeck::LoadControllerSettings() {
std::shared_ptr<Mercury> Config = GlobalCtx2::GetInstance()->GetConfig();
for (auto const& val : Config->rjson["Controllers"]["Deck"].items()) {
int slot = std::stoi(val.key().substr(5));
for (auto const& val : Config->rjson["Controllers"]["Deck"].items()) {
int slot = std::stoi(val.key().substr(5));
for (size_t dev = 0; dev < physicalDevices.size(); dev++) {
std::string guid = physicalDevices[dev]->GetGuid();
if(guid != val.value()) continue;
for (size_t dev = 0; dev < physicalDevices.size(); dev++) {
std::string guid = physicalDevices[dev]->GetGuid();
if (guid != val.value()) continue;
virtualDevices[slot] = dev;
}
}
virtualDevices[slot] = dev;
}
}
for (size_t i = 0; i < virtualDevices.size(); i++) {
std::shared_ptr<Controller> backend = physicalDevices[virtualDevices[i]];
Config->setString(StringHelper::Sprintf("Controllers.Deck.Slot_%d", (int)i), backend->GetGuid());
}
for (size_t i = 0; i < virtualDevices.size(); i++) {
std::shared_ptr<Controller> backend = physicalDevices[virtualDevices[i]];
Config->setString(StringHelper::Sprintf("Controllers.Deck.Slot_%d", (int)i), backend->GetGuid());
}
for (const auto& device : physicalDevices) {
for (const auto& device : physicalDevices) {
std::string guid = device->GetGuid();
std::string guid = device->GetGuid();
for (int slot = 0; slot < MAXCONTROLLERS; slot++) {
for (int slot = 0; slot < MAXCONTROLLERS; slot++) {
if (!(Config->rjson["Controllers"].contains(guid) && Config->rjson["Controllers"][guid].contains(StringHelper::Sprintf("Slot_%d", slot)))) continue;
if (!(Config->rjson["Controllers"].contains(guid) && Config->rjson["Controllers"][guid].contains(StringHelper::Sprintf("Slot_%d", slot)))) continue;
auto& profile = device->profiles[slot];
auto rawProfile = Config->rjson["Controllers"][guid][StringHelper::Sprintf("Slot_%d", slot)];
auto& profile = device->profiles[slot];
auto rawProfile = Config->rjson["Controllers"][guid][StringHelper::Sprintf("Slot_%d", slot)];
profile.Mappings.clear();
profile.Thresholds.clear();
profile.UseRumble = Config->getBool(NESTED("Rumble.Enabled", ""));
profile.RumbleStrength = Config->getFloat(NESTED("Rumble.Strength", ""));
profile.UseGyro = Config->getBool(NESTED("Gyro.Enabled", ""));
profile.Mappings.clear();
profile.Thresholds.clear();
profile.UseRumble = Config->getBool(NESTED("Rumble.Enabled", ""));
profile.RumbleStrength = Config->getFloat(NESTED("Rumble.Strength", ""));
profile.UseGyro = Config->getBool(NESTED("Gyro.Enabled", ""));
for (auto const& val : rawProfile["Thresholds"].items()) {
profile.Thresholds[static_cast<ControllerThresholds>(std::stoi(val.key()))] = val.value();
}
for (auto const& val : rawProfile["Thresholds"].items()) {
profile.Thresholds[static_cast<ControllerThresholds>(std::stoi(val.key()))] = val.value();
}
for (auto const& val : rawProfile["Mappings"].items()) {
device->SetButtonMapping(slot, std::stoi(val.key().substr(4)), val.value());
}
}
}
}
for (auto const& val : rawProfile["Mappings"].items()) {
device->SetButtonMapping(slot, std::stoi(val.key().substr(4)), val.value());
}
}
}
}
void Ship::ControlDeck::SaveControllerSettings() {
std::shared_ptr<Mercury> Config = GlobalCtx2::GetInstance()->GetConfig();
void ControlDeck::SaveControllerSettings() {
std::shared_ptr<Mercury> Config = GlobalCtx2::GetInstance()->GetConfig();
for (size_t i = 0; i < virtualDevices.size(); i++) {
std::shared_ptr<Controller> backend = physicalDevices[virtualDevices[i]];
Config->setString(StringHelper::Sprintf("Controllers.Deck.Slot_%d", (int)i), backend->GetGuid());
}
for (size_t i = 0; i < virtualDevices.size(); i++) {
std::shared_ptr<Controller> backend = physicalDevices[virtualDevices[i]];
Config->setString(StringHelper::Sprintf("Controllers.Deck.Slot_%d", (int)i), backend->GetGuid());
}
for (const auto& device : physicalDevices) {
for (const auto& device : physicalDevices) {
int slot = 0;
std::string guid = device->GetGuid();
int slot = 0;
std::string guid = device->GetGuid();
for (const auto& profile : device->profiles) {
for (const auto& profile : device->profiles) {
if (!device->Connected()) continue;
if (!device->Connected()) continue;
auto rawProfile = Config->rjson["Controllers"][guid][StringHelper::Sprintf("Slot_%d", slot)];
Config->setBool(NESTED("Rumble.Enabled", ""), profile.UseRumble);
Config->setFloat(NESTED("Rumble.Strength", ""), profile.RumbleStrength);
Config->setBool(NESTED("Gyro.Enabled", ""), profile.UseGyro);
auto rawProfile = Config->rjson["Controllers"][guid][StringHelper::Sprintf("Slot_%d", slot)];
Config->setBool(NESTED("Rumble.Enabled", ""), profile.UseRumble);
Config->setFloat(NESTED("Rumble.Strength", ""), profile.RumbleStrength);
Config->setBool(NESTED("Gyro.Enabled", ""), profile.UseGyro);
for (auto const& val : rawProfile["Mappings"].items()) {
Config->setInt(NESTED("Mappings.%s", val.key().c_str()), -1);
}
for (auto const& val : rawProfile["Mappings"].items()) {
Config->setInt(NESTED("Mappings.%s", val.key().c_str()), -1);
}
for (auto const& [key, val] : profile.Thresholds) {
Config->setFloat(NESTED("Thresholds.%d", key), val);
}
for (auto const& [key, val] : profile.Thresholds) {
Config->setFloat(NESTED("Thresholds.%d", key), val);
}
for (auto const& [key, val] : profile.Mappings) {
Config->setInt(NESTED("Mappings.BTN_%d", val), key);
}
for (auto const& [key, val] : profile.Mappings) {
Config->setInt(NESTED("Mappings.BTN_%d", val), key);
}
slot++;
}
}
slot++;
}
}
Config->save();
}
Config->save();
}
std::shared_ptr<Controller> ControlDeck::GetPhysicalDevice(int deviceSlot) {
return physicalDevices[deviceSlot];
}
size_t ControlDeck::GetNumPhysicalDevices() {
return physicalDevices.size();
}
int ControlDeck::GetVirtualDevice(int slot) {
return virtualDevices[slot];
}
size_t ControlDeck::GetNumVirtualDevices() {
return virtualDevices.size();
}
std::shared_ptr<Controller> ControlDeck::GetPhysicalDeviceFromVirtualSlot(int slot) {
return GetPhysicalDevice(GetVirtualDevice(slot));
}
}

View File

@ -2,19 +2,24 @@
#include "Controller.h"
#include <vector>
#include <string>
namespace Ship {
class ControlDeck {
public:
std::vector<int> virtualDevices;
std::vector<std::shared_ptr<Controller>> physicalDevices = {};
void Init(uint8_t* controllerBits);
void ScanPhysicalDevices();
void WriteToPad(OSContPad* pad) const;
void LoadControllerSettings();
void SaveControllerSettings();
void SetPhysicalDevice(int slot, int deviceSlot);
std::shared_ptr<Ship::Controller> GetPhysicalDevice(int deviceSlot);
std::shared_ptr<Ship::Controller> GetPhysicalDeviceFromVirtualSlot(int slot);
size_t GetNumPhysicalDevices();
int GetVirtualDevice(int slot);
size_t GetNumVirtualDevices();
private:
std::vector<int> virtualDevices;
std::vector<std::shared_ptr<Controller>> physicalDevices = {};
};
}

View File

@ -1,11 +1,9 @@
#include "Cvar.h"
#include <map>
#include <string>
#include <string.h>
#include <functional>
#include <memory>
#include <utility>
#include <PR/ultra64/gbi.h>
#include "imgui_internal.h"
std::map<std::string, std::unique_ptr<CVar>, std::less<>> cvars;
@ -96,7 +94,7 @@ extern "C" void CVar_SetS32(const char* name, int32_t value) {
cvar->value.valueS32 = value;
}
void CVar_SetFloat(const char* name, float value) {
extern "C" void CVar_SetFloat(const char* name, float value) {
auto& cvar = cvars[name];
if (!cvar) {
cvar = std::make_unique<CVar>();
@ -111,7 +109,11 @@ extern "C" void CVar_SetString(const char* name, const char* value) {
cvar = std::make_unique<CVar>();
}
cvar->type = CVarType::String;
cvar->value.valueStr = ImStrdup(value);
#ifdef _MSC_VER
cvar->value.valueStr = _strdup(value);
#else
cvar->value.valueStr = strdup(value);
#endif
}
extern "C" void CVar_RegisterRGBA(const char* name, Color_RGBA8 defaultValue) {

View File

@ -32,14 +32,13 @@ extern "C" CVar * CVar_Get(const char* name);
extern "C"
{
#endif
//#include <ultra64.h>
int32_t CVar_GetS32(const char* name, int32_t defaultValue);
float CVar_GetFloat(const char* name, float defaultValue);
void CVar_SetFloat(const char* name, float value);
const char* CVar_GetString(const char* name, const char* defaultValue);
void CVar_SetS32(const char* name, int32_t value);
void CVar_SetString(const char* name, const char* value);
Color_RGB8 CVar_GetRGB(const char* name, Color_RGB8 defaultValue);
Color_RGBA8 CVar_GetRGBA(const char* name, Color_RGBA8 defaultValue);
void CVar_SetRGBA(const char* name, Color_RGBA8 value);
@ -56,11 +55,8 @@ void CVar_RegisterRGBA(const char* name, Color_RGBA8 defaultValue);
#ifdef __cplusplus
#include <map>
#include <string>
#include <functional>
#include <memory>
//extern "C" CVar * CVar_Get(const char* name);
extern std::map<std::string, std::unique_ptr<CVar>, std::less<>> cvars;
void CVar_SetFloat(const char* name, float value);
#endif
#endif

View File

@ -1,16 +0,0 @@
#include "Environment.h"
#include <map>
#include <string>
std::map<std::string, std::string> environmentVars;
namespace SohUtils {
void saveEnvironmentVar(const std::string& key, const std::string& value) {
environmentVars[key] = value;
}
std::string getEnvironmentVar(const std::string& key) {
return environmentVars[key];
}
}

View File

@ -1,8 +0,0 @@
#pragma once
#include <string>
namespace SohUtils {
void saveEnvironmentVar(const std::string& key, const std::string& value);
std::string getEnvironmentVar(const std::string& key);
}

View File

@ -6,223 +6,229 @@
#include "ResourceMgr.h"
#include "Console.h"
#include "ImGuiImpl.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);
namespace Ship {
void 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);
void 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::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();
}
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;
}
void 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;
}
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;
void 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);
}
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;
else {
++it;
}
}
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 CVarType::Float:
this->TextDraw(30, textY, true, color, "%s %.2f", text, var->value.valueFloat);
break;
case CVarType::S32:
this->TextDraw(30, textY, true, color, "%s %d", text, var->value.valueS32);
break;
case CVarType::String:
this->TextDraw(30, textY, true, color, "%s %s", text, var->value.valueStr);
break;
case CVarType::RGBA:
this->TextDraw(30, textY, true, color, "#%08X", text, var->value.valueRGBA);
break;
}
free((void*) text);
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;
}
NeedsCleanup = false;
}
ImGui::End();
}
bool Ship::OverlayCommand(const std::vector<std::string>& args) {
if (args.size() < 3) {
return CMD_FAILED;
float GameOverlay::GetScreenWidth() {
const ImGuiViewport* viewport = ImGui::GetMainViewport();
return viewport->Size.x;
}
if (CVar_Get(args[2].c_str()) != nullptr) {
const char* key = args[2].c_str();
float GameOverlay::GetScreenHeight() {
const ImGuiViewport* viewport = ImGui::GetMainViewport();
return viewport->Size.y;
}
float GameOverlay::GetStringWidth(const char* text) {
return CalculateTextSize(text).x;
}
ImVec2 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;
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());
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;
}
return CMD_SUCCESS;
}
void 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 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 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 CVarType::Float:
this->TextDraw(30, textY, true, color, "%s %.2f", text, var->value.valueFloat);
break;
case CVarType::S32:
this->TextDraw(30, textY, true, color, "%s %d", text, var->value.valueS32);
break;
case CVarType::String:
this->TextDraw(30, textY, true, color, "%s %s", text, var->value.valueStr);
break;
case CVarType::RGBA:
this->TextDraw(30, textY, true, color, "#%08X", text, var->value.valueRGBA);
break;
}
free((void*)text);
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 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;
}
}

View File

@ -3,21 +3,21 @@
#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 {
enum class OverlayType {
TEXT, IMAGE, NOTIFICATION
};
struct Overlay {
OverlayType type;
const char* value;
float fadeTime;
float duration;
};
class GameOverlay {
public:
std::unordered_map<std::string, Overlay*> RegisteredOverlays;

View File

@ -41,8 +41,8 @@ namespace Game {
}
void InitSettings() {
ModInternal::RegisterHook<ModInternal::AudioInit>(UpdateAudio);
ModInternal::RegisterHook<ModInternal::GfxInit>([] {
Ship::RegisterHook<Ship::AudioInit>(UpdateAudio);
Ship::RegisterHook<Ship::GfxInit>([] {
gfx_get_current_rendering_api()->set_texture_filter((FilteringMode) CVar_GetS32("gTextureFilter", FILTER_THREE_POINT));
SohImGui::console->opened = CVar_GetS32("gConsoleEnabled", 0);
SohImGui::controller->Opened = CVar_GetS32("gControllerConfigurationEnabled", 0);

View File

@ -7,7 +7,6 @@
#include "spdlog/sinks/rotating_file_sink.h"
#include "spdlog/sinks/stdout_color_sinks.h"
#include "spdlog/sinks/sohconsole_sink.h"
#include "ModManager.h"
#ifdef __APPLE__
#include "OSXFolderManager.h"
#elif defined(__SWITCH__)
@ -16,7 +15,6 @@
namespace Ship {
std::weak_ptr<GlobalCtx2> GlobalCtx2::Context;
ModManager* INSTANCE;
std::shared_ptr<GlobalCtx2> GlobalCtx2::GetInstance() {
return Context.lock();
}
@ -56,7 +54,6 @@ namespace Ship {
GlobalCtx2::~GlobalCtx2() {
SPDLOG_INFO("destruct GlobalCtx2");
INSTANCE->Exit();
}
void GlobalCtx2::InitWindow() {
@ -84,8 +81,6 @@ namespace Ship {
#ifdef __SWITCH__
Ship::Switch::Init(PostInitPhase);
#endif
INSTANCE = new ModManager(ResMan);
INSTANCE->Init();
}
void GlobalCtx2::InitLogging() {

View File

@ -1,10 +0,0 @@
#include "Hooks.h"
#include <map>
#include <string>
#include <vector>
#include <stdarg.h>
#include <iostream>
void ModInternal_ExecuteAudioInitHooks() {
ModInternal::ExecuteHooks<ModInternal::AudioInit>();
}

View File

@ -1,15 +1,12 @@
#pragma once
#ifdef __cplusplus
#include <functional>
#include "UltraController.h"
#include "Controller.h"
#define DEFINE_HOOK(name, type) struct name { typedef std::function<type> fn; }
namespace ModInternal {
namespace Ship {
class Controller;
template <typename H>
struct RegisteredHooks {
@ -29,22 +26,9 @@ namespace ModInternal {
}
DEFINE_HOOK(ControllerRead, void(OSContPad* cont_pad));
DEFINE_HOOK(ControllerRawInput, void(Ship::Controller* backend, uint32_t raw));
DEFINE_HOOK(ControllerRawInput, void(Controller* backend, uint32_t raw));
DEFINE_HOOK(AudioInit, void());
DEFINE_HOOK(LoadTexture, void(const char* path, uint8_t** texture));
DEFINE_HOOK(GfxInit, void());
DEFINE_HOOK(ExitGame, void());
}
#endif
#ifdef __cplusplus
extern "C" {
#endif
void ModInternal_ExecuteAudioInitHooks();
#ifdef __cplusplus
}
#endif

View File

@ -8,7 +8,6 @@
#include <vector>
#include "Archive.h"
#include "Environment.h"
#include "GameSettings.h"
#include "Console.h"
#include "Hooks.h"
@ -16,7 +15,6 @@
#include "Lib/ImGui/imgui_internal.h"
#include "GlobalCtx2.h"
#include "ResourceMgr.h"
#include "TextureMod.h"
#include "Window.h"
#include "Cvar.h"
#include "GameOverlay.h"
@ -25,7 +23,7 @@
#include "Lib/stb/stb_image.h"
#include "Lib/Fast3D/gfx_rendering_api.h"
#include "Lib/spdlog/include/spdlog/common.h"
#include "Utils/StringHelper.h"
#include "UltraController.h"
#if __APPLE__
#include <SDL_hints.h>
@ -386,7 +384,7 @@ namespace SohImGui {
ImGui::GetStyle().ScaleAllSizes(2);
#endif
ModInternal::RegisterHook<ModInternal::GfxInit>([] {
Ship::RegisterHook<Ship::GfxInit>([] {
if (GlobalCtx2::GetInstance()->GetWindow()->IsFullscreen())
ShowCursor(CVar_GetS32("gOpenMenuBar", 0), Dialogues::dLoadSettings);
@ -403,7 +401,7 @@ namespace SohImGui {
LoadTexture("C-Down", "assets/ship_of_harkinian/buttons/CDown.png");
});
ModInternal::RegisterHook<ModInternal::ControllerRead>([](OSContPad* cont_pad) {
Ship::RegisterHook<Ship::ControllerRead>([](OSContPad* cont_pad) {
pads = cont_pad;
});
@ -792,7 +790,7 @@ namespace SohImGui {
bool menu_bar = CVar_GetS32("gOpenMenuBar", 0);
CVar_SetS32("gOpenMenuBar", !menu_bar);
needs_save = true;
GlobalCtx2::GetInstance()->GetWindow()->dwMenubar = menu_bar;
GlobalCtx2::GetInstance()->GetWindow()->SetMenuBar(menu_bar);
ShowCursor(menu_bar, Dialogues::dMenubar);
GlobalCtx2::GetInstance()->GetWindow()->GetControlDeck()->SaveControllerSettings();
if (CVar_GetS32("gControlNav", 0)) {
@ -1014,6 +1012,9 @@ namespace SohImGui {
Tooltip("Allow Link to put items away without having to wait around");
EnhancementCheckbox("Mask Select in Inventory", "gMaskSelect");
Tooltip("After completing the mask trading sub-quest, press A and any direction on the mask slot to change masks");
EnhancementCheckbox("Remember Save Location", "gRememberSaveLocation");
Tooltip("When loading a save, places Link at the last entrance he went through.\n"
"This doesn't work if the save was made in a grotto.");
ImGui::EndMenu();
}
@ -1414,6 +1415,9 @@ namespace SohImGui {
Tooltip("Prevents the Deku Shield from burning on contact with fire");
EnhancementCheckbox("Shield with Two-Handed Weapons", "gShieldTwoHanded");
Tooltip("This allows you to put up your shield with any two-handed weapon in hand except for Deku Sticks");
Tooltip("This allows you to put up your shield with any two-handed weapon in hand\nexcept for Deku Sticks");
EnhancementCheckbox("Time Sync", "gTimeSync");
Tooltip("This syncs the ingame time with the real world time");
{
static int32_t betaQuestEnabled = CVar_GetS32("gEnableBetaQuest", 0);
@ -1650,12 +1654,10 @@ namespace SohImGui {
pos = ImVec2(size.x / 2 - sw / 2, 0);
size = ImVec2(sw, size.y);
}
std::string fb_str = SohUtils::getEnvironmentVar("framebuffer");
if (!fb_str.empty()) {
uintptr_t fbuf = (uintptr_t)std::stoull(fb_str);
//ImGui::ImageSimple(reinterpret_cast<ImTextureID>(fbuf), pos, size);
if (gfxFramebuffer) {
//ImGui::ImageSimple(reinterpret_cast<ImTextureID>(gfxFramebuffer), pos, size);
ImGui::SetCursorPos(pos);
ImGui::Image(reinterpret_cast<ImTextureID>(fbuf), size);
ImGui::Image(reinterpret_cast<ImTextureID>(gfxFramebuffer), size);
}
ImGui::End();

View File

@ -69,7 +69,7 @@ namespace SohImGui {
WindowDrawFunc drawFunc;
} CustomWindow;
extern Console* console;
extern Ship::Console* console;
extern Ship::InputEditor* controller;
extern Ship::GameOverlay* overlay;
extern bool needs_save;
@ -92,7 +92,7 @@ namespace SohImGui {
void Render(void);
void CancelFrame(void);
void ShowCursor(bool hide, Dialogues w);
void BindCmd(const std::string& cmd, CommandEntry entry);
void BindCmd(const std::string& cmd, Ship::CommandEntry entry);
void AddWindow(const std::string& category, const std::string& name, WindowDrawFunc drawFunc, bool isEnabled=false, bool isHidden=false);
void LoadResource(const std::string& name, const std::string& path, const ImVec4& tint = ImVec4(1, 1, 1, 1));
void LoadPickersColors(ImVec4& ColorArray, const char* cvarname, const ImVec4& default_colors, bool has_alpha=false);

View File

@ -16,8 +16,8 @@ namespace Ship {
}
std::shared_ptr<Controller> GetControllerPerSlot(int slot) {
const std::vector<int> vDevices = Window::ControllerApi->virtualDevices;
return Window::ControllerApi->physicalDevices[vDevices[slot]];
auto controlDeck = Ship::GlobalCtx2::GetInstance()->GetWindow()->GetControlDeck();
return controlDeck->GetPhysicalDeviceFromVirtualSlot(slot);
}
void InputEditor::DrawButton(const char* label, int n64Btn) {
@ -82,20 +82,21 @@ namespace Ship {
}
void InputEditor::DrawControllerSchema() {
const std::vector<int> vDevices = Window::ControllerApi->virtualDevices;
const std::vector<std::shared_ptr<Controller>> devices = Window::ControllerApi->physicalDevices;
std::shared_ptr<Controller> Backend = devices[vDevices[CurrentPort]];
DeviceProfile& profile =Backend->profiles[CurrentPort];
auto controlDeck = Ship::GlobalCtx2::GetInstance()->GetWindow()->GetControlDeck();
auto Backend = controlDeck->GetPhysicalDeviceFromVirtualSlot(CurrentPort);
DeviceProfile& profile = Backend->profiles[CurrentPort];
float sensitivity = profile.Thresholds[SENSITIVITY];
bool IsKeyboard = Backend->GetGuid() == "Keyboard" || Backend->GetGuid() == "Auto" || !Backend->Connected();
const char* ControllerName = Backend->GetControllerName();
if (ControllerName != nullptr && ImGui::BeginCombo("##ControllerEntries", ControllerName)) {
for (uint8_t i = 0; i < devices.size(); i++) {
if (ImGui::Selectable(devices[i]->GetControllerName(), i == vDevices[CurrentPort])) {
Window::ControllerApi->SetPhysicalDevice(CurrentPort, i);
for (uint8_t i = 0; i < controlDeck->GetNumPhysicalDevices(); i++) {
std::string DeviceName = controlDeck->GetPhysicalDevice(i)->GetControllerName();
if (DeviceName != "Keyboard" && DeviceName != "Auto") {
DeviceName+="##"+std::to_string(i);
}
if (ImGui::Selectable(DeviceName.c_str(), i == controlDeck->GetVirtualDevice(CurrentPort))) {
controlDeck->SetPhysicalDevice(CurrentPort, i);
}
}
ImGui::EndCombo();
@ -104,7 +105,7 @@ namespace Ship {
ImGui::SameLine();
if(ImGui::Button("Refresh")) {
Window::ControllerApi->ScanPhysicalDevices();
controlDeck->ScanPhysicalDevices();
}
SohImGui::BeginGroupPanel("Buttons", ImVec2(150, 20));

View File

@ -1,7 +1,5 @@
#pragma once
#include <string>
#include "Lib/ImGui/imgui.h"
namespace Ship {

View File

@ -240,7 +240,7 @@ static LRESULT CALLBACK gfx_dxgi_wnd_proc(HWND h_wnd, UINT message, WPARAM w_par
dxgi.current_height = (uint32_t)(l_param >> 16);
break;
case WM_DESTROY:
ModInternal::ExecuteHooks<ModInternal::ExitGame>();
Ship::ExecuteHooks<Ship::ExitGame>();
exit(0);
case WM_PAINT:
if (dxgi.in_paint) {
@ -358,7 +358,6 @@ static void gfx_dxgi_show_cursor(bool hide) {
* @bug When menubar is open in windowed mode and you toggle fullscreen
* ShowCursor no longer responds. Debugging shows the bool to be correct.
**/
INFO("renderer: %s", hide ? "true" : "false");
ShowCursor(hide);
}

View File

@ -44,7 +44,6 @@
#include "gfx_cc.h"
#include "gfx_rendering_api.h"
#include "../../ImGuiImpl.h"
#include "../../Environment.h"
#include "../../GlobalCtx2.h"
#include "gfx_pc.h"

View File

@ -32,7 +32,6 @@
#include "../../luslog.h"
#include "../StrHash64.h"
#include "../../ImGuiImpl.h"
#include "../../Environment.h"
#include "../../GameVersions.h"
#include "../../ResourceMgr.h"
#include "../../Utils.h"
@ -49,6 +48,8 @@ extern "C" {
int ResourceMgr_OTRSigCheck(char* imgData);
}
uintptr_t gfxFramebuffer;
using namespace std;
#define SEG_ADDR(seg, addr) (addr | (seg << 24) | 1)
@ -1065,8 +1066,8 @@ static void gfx_sp_vertex(size_t n_vertices, size_t dest_index, const Vtx *verti
dotx /= 127.0f;
doty /= 127.0f;
dotx = math::clamp(dotx, -1.0f, 1.0f);
doty = math::clamp(doty, -1.0f, 1.0f);
dotx = Ship::Math::clamp(dotx, -1.0f, 1.0f);
doty = Ship::Math::clamp(doty, -1.0f, 1.0f);
if (rsp.geometry_mode & G_TEXTURE_GEN_LINEAR) {
// Not sure exactly what formula we should use to get accurate values
@ -1118,7 +1119,7 @@ static void gfx_sp_vertex(size_t n_vertices, size_t dest_index, const Vtx *verti
if (winv < 0.0f) winv = std::numeric_limits<int16_t>::max();
float fog_z = z * winv * rsp.fog_mul + rsp.fog_offset;
fog_z = math::clamp(fog_z, 0.0f, 255.0f);
fog_z = Ship::Math::clamp(fog_z, 0.0f, 255.0f);
d->color.a = fog_z; // Use alpha variable to store fog factor
} else {
d->color.a = v->cn[3];
@ -2698,7 +2699,7 @@ void gfx_init(struct GfxWindowManagerAPI *wapi, struct GfxRenderingAPI *rapi, co
//gfx_lookup_or_create_shader_program(precomp_shaders[i]);
}
ModInternal::ExecuteHooks<ModInternal::GfxInit>();
Ship::ExecuteHooks<Ship::GfxInit>();
}
struct GfxRenderingAPI *gfx_get_current_rendering_api(void) {
@ -2782,7 +2783,7 @@ void gfx_run(Gfx *commands, const std::unordered_map<Mtx *, MtxF>& mtx_replaceme
rendering_state.scissor = {};
gfx_run_dl(commands);
gfx_flush();
SohUtils::saveEnvironmentVar("framebuffer", string());
gfxFramebuffer = 0;
if (game_renders_to_framebuffer) {
gfx_rapi->start_draw_to_framebuffer(0, 1);
gfx_rapi->clear_framebuffer();
@ -2792,12 +2793,12 @@ void gfx_run(Gfx *commands, const std::unordered_map<Mtx *, MtxF>& mtx_replaceme
if (different_size) {
gfx_rapi->resolve_msaa_color_buffer(game_framebuffer_msaa_resolved, game_framebuffer);
SohUtils::saveEnvironmentVar("framebuffer", std::to_string((uintptr_t)gfx_rapi->get_framebuffer_texture_id(game_framebuffer_msaa_resolved)));
gfxFramebuffer = (uintptr_t)gfx_rapi->get_framebuffer_texture_id(game_framebuffer_msaa_resolved);
} else {
gfx_rapi->resolve_msaa_color_buffer(0, game_framebuffer);
}
} else {
SohUtils::saveEnvironmentVar("framebuffer", std::to_string((uintptr_t)gfx_rapi->get_framebuffer_texture_id(game_framebuffer)));
gfxFramebuffer = (uintptr_t)gfx_rapi->get_framebuffer_texture_id(game_framebuffer);
}
}
SohImGui::DrawFramebufferAndGameInput();

View File

@ -14,6 +14,8 @@
#define SCREEN_WIDTH 320
#define SCREEN_HEIGHT 240
extern uintptr_t gfxFramebuffer;
struct GfxRenderingAPI;
struct GfxWindowManagerAPI;

View File

@ -239,7 +239,7 @@ static void gfx_sdl_main_loop(void (*run_one_game_iter)(void)) {
#ifdef __SWITCH__
Ship::Switch::Exit();
#endif
ModInternal::ExecuteHooks<ModInternal::ExitGame>();
Ship::ExecuteHooks<Ship::ExitGame>();
}
static void gfx_sdl_get_dimensions(uint32_t *width, uint32_t *height) {
@ -309,7 +309,7 @@ static void gfx_sdl_handle_events(void) {
Game::SaveSettings();
break;
case SDL_QUIT:
ModInternal::ExecuteHooks<ModInternal::ExitGame>();
Ship::ExecuteHooks<Ship::ExitGame>();
SDL_Quit(); // bandaid fix for linux window closing issue
exit(0);
}

View File

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

View File

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

View File

@ -34,7 +34,7 @@ public:
protected:
void sink_it_(const details::log_msg &msg) override
{
const Priority priority = convert_to_soh(msg.level);
const Ship::Priority priority = convert_to_soh(msg.level);
memory_buf_t formatted;
if (use_raw_msg_)
{
@ -53,24 +53,25 @@ protected:
void flush_() override {}
private:
static Priority convert_to_soh(spdlog::level::level_enum level) {
static Ship::Priority convert_to_soh(spdlog::level::level_enum level)
{
switch (level) {
case spdlog::level::trace:
return Priority::INFO_LVL;
return Ship::Priority::INFO_LVL;
case spdlog::level::debug:
return Priority::LOG_LVL;
return Ship::Priority::LOG_LVL;
case spdlog::level::info:
return Priority::LOG_LVL;
return Ship::Priority::LOG_LVL;
case spdlog::level::warn:
return Priority::WARNING_LVL;
return Ship::Priority::WARNING_LVL;
case spdlog::level::err:
return Priority::ERROR_LVL;
return Ship::Priority::ERROR_LVL;
case spdlog::level::critical:
return Priority::ERROR_LVL;
return Ship::Priority::ERROR_LVL;
default:
break;
}
return Priority::LOG_LVL;
return Ship::Priority::LOG_LVL;
}
std::string tag_;

View File

@ -1,23 +0,0 @@
#include "ModManager.h"
#include "TextureMod.h"
#include "ModModule.h"
#include "ImGuiImpl.h"
namespace Ship {
std::vector<ModModule*> modules;
void ModManager::Init() {
// ResManager->GetArchive()->loa
// modules.push_back(new TextureModule(this));
// std::shared_ptr<Ship::Archive> archive = std::make_shared<Ship::Archive>("mods/TexMods.otr", "", false);
for (auto& mod : modules) {
mod->Init();
// mod->Open(archive);
}
}
void ModManager::Exit() {
for (auto& mod : modules)
mod->Exit();
}
}

View File

@ -1,12 +0,0 @@
#pragma once
#include "ResourceMgr.h"
namespace Ship {
class ModManager {
public:
std::shared_ptr<Ship::ResourceMgr> ResManager;
explicit ModManager(std::shared_ptr<Ship::ResourceMgr> manager) : ResManager(manager) {}
void Init();
void Exit();
};
}

View File

@ -1,19 +0,0 @@
#pragma once
#include "ModManager.h"
#include "Hooks.h"
#include "Console.h"
#include "Archive.h"
namespace Ship {
class ModModule {
protected:
ModManager* Manager;
public:
virtual ~ModModule() = default;
explicit ModModule(ModManager* Manager) : Manager(Manager) {}
virtual void Init() = 0;
virtual void Open(std::shared_ptr<Ship::Archive> archive) = 0;
virtual void Close(Ship::Archive archive) = 0;
virtual void Exit() = 0;
};
}

View File

@ -1,128 +0,0 @@
#include "TextureMod.h"
#if 0
#include <map>
#include <string>
#include <iostream>
#include <filesystem>
#include <functional>
#include "Lib/stb/stb_image.h"
#include "Lib/Fast3D/gfx_pc.h"
#define STB_IMAGE_WRITE_IMPLEMENTATION
#include "Lib/stb/stb_image_write.h"
#include "Lib/Fast3D/gfx_rendering_api.h"
#include "SohImGuiImpl.h"
namespace fs = std::filesystem;
namespace Ship {
void TextureModule::Init() {
BIND_HOOK(LOOKUP_TEXTURE, Hook_LookupTexture);
BIND_HOOK(GRAYOUT_TEXTURE, Hook_GrayScaleFilter);
BIND_HOOK(INVALIDATE_TEXTURE, Hook_InvalidateTexture);
SohImGui::BindCmd("reload", { .handler = [&](const std::vector<std::string>&) {
INFO("Reloading all textures!");
gfx_texture_cache_clear();
this->TexturePool.clear();
this->TextureCache.clear();
return true;
} });
}
void TextureModule::Open(std::shared_ptr<Ship::Archive> archive) {
this->LoadedOTRS.push_back(archive);
}
void TextureModule::Close(Ship::Archive otr) {
// Remove all loaded textures
// this->LoadedOTRS.erase(std::find(this->LoadedOTRS.begin(), this->LoadedOTRS.end(), otr));
}
void TextureModule::Hook_LookupTexture(HookEvent call) {
const auto raw_path = BIND_PTR("path", char*);
if (raw_path == nullptr) return;
const auto api = BIND_PTR("gfx_api", GfxRenderingAPI*);
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*);
const auto tile = BIND_VAR("tile", int*);
const auto palette = BIND_VAR("palette", uint32_t*);
const auto orig_addr = BIND_VAR("addr", const uint8_t**);
// INFO("The game is trying to load %s", path.c_str());
if (this->TextureCache.contains(path) && this->TextureCache[path][tile] != nullptr) {
*node = this->TextureCache[path][tile];
api->select_texture(tile, (*node)->second.texture_id);
call->cancelled = true;
return;
}
// OTRTODO: Implement loading order
TextureData* tex_data = nullptr;
if (!this->TexturePool.contains(path)) {
std::shared_ptr<Ship::File> raw_data = std::make_shared<Ship::File>();
this->Manager->ResManager->GetArchive()->LoadPatchFile(path, false, raw_data);
if (raw_data->bIsLoaded) {
char* tdata = new char[raw_data->dwBufferSize];
memcpy(tdata, raw_data->buffer.get(), raw_data->dwBufferSize);
tex_data = new TextureData({ .data = tdata, .size = raw_data->dwBufferSize });
INFO("Loaded %s", path.c_str());
this->TexturePool[path] = tex_data;
}
}
if (tex_data == nullptr)
return;
if (!this->TextureCache.contains(path)) this->TextureCache[path].resize(10);
TextureCacheKey key = { orig_addr, { }, static_cast<uint8_t>(fmt), static_cast<uint8_t>(siz), static_cast<uint8_t>(palette) };
TextureCacheValue value = { api->new_texture(), 0, 0, false };
const auto entry = new TextureCacheNode(key, value);
api->select_texture(tile, entry->second.texture_id);
api->set_sampler_parameters(tile, false, 0, 0);
*node = entry;
uint8_t* img_data = stbi_load_from_memory(reinterpret_cast<const stbi_uc*>(tex_data->data), tex_data->size, &tex_data->width, &tex_data->height, nullptr, 4);
if (!img_data)
return;
switch (tex_data->color_modifier) {
case GRAYSCALE: {
GrayOutTexture(img_data, tex_data->width, tex_data->height);
}
default:;
}
std::cout << "Uploading to the GPU" << std::endl;
api->upload_texture(img_data, tex_data->width, tex_data->height);
this->TextureCache[path][tile] = entry;
stbi_image_free(img_data);
call->cancelled = true;
}
void TextureModule::Hook_GrayScaleFilter(HookEvent event) {
// this->Exit();
}
void TextureModule::Hook_InvalidateTexture(HookEvent event) {
// this->Exit();
}
void TextureModule::Exit() {
TextureCache.clear();
TexturePool.clear();
LoadedOTRS.clear();
}
}
#endif

View File

@ -1,55 +0,0 @@
#pragma once
#include "ModModule.h"
#include <PR/ultra64/gbi.h>
#include "Lib/Fast3D/gfx_pc.h"
#if 0
namespace Ship {
enum TextureMod {
GRAYSCALE,
NONE
};
struct TextureData {
char* data;
uint32_t size;
int width;
int height;
char* loaded_data;
std::shared_ptr<Ship::Archive> parent;
TextureMod color_modifier = NONE;
};
class TextureModule : public ModModule {
public:
explicit TextureModule(ModManager* Manager) : ModModule(Manager) {}
private:
std::vector<std::shared_ptr<Ship::Archive>> LoadedOTRS;
std::map<std::string, TextureData*> TexturePool;
std::map<std::string, std::vector<TextureCacheNode*>> TextureCache;
void Init() override;
void Open(std::shared_ptr<Ship::Archive> archive) override;
void Close(Ship::Archive mod) override;
void Exit() override;
protected:
void Hook_LookupTexture(HookEvent event);
void Hook_GrayScaleFilter(HookEvent event);
void Hook_InvalidateTexture(HookEvent event);
};
inline void GrayOutTexture(uint8_t* data, int width, int height) {
for (int x = 0; x < width * height * 4; x += 4) {
int red = data[x];
int green = data[x + 1];
int blue = data[x + 2];
int gray = (red + green + blue) / 3;
data[x] = gray;
data[x + 1] = gray;
data[x + 2] = gray;
}
}
}
#endif

View File

@ -5,14 +5,14 @@
#define strdup _strdup
#endif
namespace math {
float clamp(float d, float min, float max) {
const float t = d < min ? min : d;
return t > max ? max : t;
namespace Ship {
namespace Math {
float clamp(float d, float min, float max) {
const float t = d < min ? min : d;
return t > max ? max : t;
}
}
}
namespace Utils {
std::vector<std::string> SplitText(const std::string text, char separator = ' ', bool keep_quotes = false) {
std::vector<std::string> args;
char* input = strdup(text.c_str());

View File

@ -3,10 +3,11 @@
#include <string>
#include <vector>
namespace math {
float clamp(float d, float min, float max);
}
namespace Ship {
namespace Math {
float clamp(float d, float min, float max);
}
namespace Utils {
std::vector<std::string> SplitText(const std::string& text, char separator, bool keep_quotes);
}
}

View File

@ -4,32 +4,34 @@
#include "Controller.h"
class VirtualController final : public Ship::Controller {
public:
VirtualController(const std::string& CUID, const std::string& KeyName, bool Connected) {
GUID = CUID;
isConnected = Connected;
ButtonName = KeyName;
}
namespace Ship {
class VirtualController final : public Controller {
public:
VirtualController(const std::string& CUID, const std::string& KeyName, bool Connected) {
GUID = CUID;
isConnected = Connected;
ButtonName = KeyName;
}
std::map<std::vector<std::string>, int32_t> ReadButtonPress();
void ReadFromSource(int32_t slot) override {}
const char* GetControllerName() override { return GUID.c_str(); }
const char* GetButtonName(int slot, int n64Button) override { return ButtonName.c_str(); }
void WriteToSource(int32_t slot, ControllerCallback* controller) override { }
bool Connected() const override { return isConnected; }
bool CanRumble() const override { return false; }
bool CanGyro() const override { return false; }
std::map<std::vector<std::string>, int32_t> ReadButtonPress();
void ReadFromSource(int32_t slot) override {}
const char* GetControllerName() override { return GUID.c_str(); }
const char* GetButtonName(int slot, int n64Button) override { return ButtonName.c_str(); }
void WriteToSource(int32_t slot, ControllerCallback* controller) override { }
bool Connected() const override { return isConnected; }
bool CanRumble() const override { return false; }
bool CanGyro() const override { return false; }
void ClearRawPress() override {}
int32_t ReadRawPress() override { return -1; }
bool HasPadConf() const { return true; }
std::optional<std::string> GetPadConfSection() { return "Unk"; }
void CreateDefaultBinding(int32_t slot) override {}
protected:
std::string ButtonName;
bool isConnected = false;
std::string GetControllerType() { return "Unk"; }
std::string GetConfSection() { return "Unk"; }
std::string GetBindingConfSection() { return "Unk"; }
};
void ClearRawPress() override {}
int32_t ReadRawPress() override { return -1; }
bool HasPadConf() const { return true; }
std::optional<std::string> GetPadConfSection() { return "Unk"; }
void CreateDefaultBinding(int32_t slot) override {}
protected:
std::string ButtonName;
bool isConnected = false;
std::string GetControllerType() { return "Unk"; }
std::string GetConfSection() { return "Unk"; }
std::string GetBindingConfSection() { return "Unk"; }
};
}

View File

@ -1,7 +1,6 @@
#include "Window.h"
#include "spdlog/spdlog.h"
#include "KeyboardController.h"
#include "SDLController.h"
#include "GlobalCtx2.h"
#include "DisplayList.h"
#include "Vertex.h"
@ -11,22 +10,18 @@
#include "Blob.h"
#include "Matrix.h"
#include "AudioPlayer.h"
#include "WasapiAudioPlayer.h"
#include "PulseAudioPlayer.h"
#include "SDLAudioPlayer.h"
#include "Hooks.h"
#include "UltraController.h"
#include "Lib/Fast3D/gfx_pc.h"
#include "Lib/Fast3D/gfx_sdl.h"
#include "Lib/Fast3D/gfx_opengl.h"
#include "stox.h"
#if __APPLE__
#include <SDL.h>
#else
#include <SDL2/SDL.h>
#endif
#include <map>
#include <string>
#include <chrono>
#include "Hooks.h"
#include "Console.h"
#include "Cvar.h"
@ -57,7 +52,7 @@ extern "C" {
}
#endif
Ship::Window::ControllerApi->Init(controllerBits);
Ship::GlobalCtx2::GetInstance()->GetWindow()->GetControlDeck()->Init(controllerBits);
return 0;
}
@ -77,10 +72,10 @@ extern "C" {
pad->gyro_y = 0;
if (!CVar_GetS32("gOpenMenuBar", 0)) {
Ship::Window::ControllerApi->WriteToPad(pad);
Ship::GlobalCtx2::GetInstance()->GetWindow()->GetControlDeck()->WriteToPad(pad);
}
ModInternal::ExecuteHooks<ModInternal::ControllerRead>(pad);
Ship::ExecuteHooks<Ship::ControllerRead>(pad);
}
const char* ResourceMgr_GetNameByCRC(uint64_t crc) {
@ -126,7 +121,7 @@ extern "C" {
if (hashStr != nullptr) {
const auto res = LOAD_TEX(hashStr->c_str());
ModInternal::ExecuteHooks<ModInternal::LoadTexture>(hashStr->c_str(), &res->imageData);
Ship::ExecuteHooks<Ship::LoadTexture>(hashStr->c_str(), &res->imageData);
return reinterpret_cast<char*>(res->imageData);
} else {
@ -153,7 +148,7 @@ extern "C" {
char* ResourceMgr_LoadTexByName(char* texPath) {
const auto res = LOAD_TEX(texPath);
ModInternal::ExecuteHooks<ModInternal::LoadTexture>(texPath, &res->imageData);
Ship::ExecuteHooks<Ship::LoadTexture>(texPath, &res->imageData);
return (char*)res->imageData;
}
@ -221,7 +216,7 @@ namespace Ship {
int32_t Window::lastScancode;
Window::Window(std::shared_ptr<GlobalCtx2> Context) : Context(Context), APlayer(nullptr) {
Window::Window(std::shared_ptr<GlobalCtx2> Context) : Context(Context), APlayer(nullptr), ControllerApi(nullptr) {
WmApi = nullptr;
RenderingApi = nullptr;
bIsFullscreen = false;
@ -259,8 +254,9 @@ namespace Ship {
std::shared_ptr<Mercury> pConf = GlobalCtx2::GetInstance()->GetConfig();
CreateDefaults();
InitializeAudioPlayer();
InitializeControlDeck();
SetAudioPlayer();
bIsFullscreen = pConf->getBool("Window.Fullscreen.Enabled", false);
if (bIsFullscreen) {
@ -279,7 +275,7 @@ namespace Ship {
WmApi->set_fullscreen_changed_callback(OnFullscreenChanged);
WmApi->set_keyboard_callbacks(KeyDown, KeyUp, AllKeysUp);
ModInternal::RegisterHook<ModInternal::ExitGame>([]() {
Ship::RegisterHook<Ship::ExitGame>([this]() {
ControllerApi->SaveControllerSettings();
});
}
@ -347,7 +343,8 @@ namespace Ship {
lastScancode = -1;
bool bIsProcessed = false;
const auto pad = dynamic_cast<KeyboardController*>(ControllerApi->physicalDevices[ControllerApi->physicalDevices.size() - 2].get());
auto controlDeck = GlobalCtx2::GetInstance()->GetWindow()->GetControlDeck();
const auto pad = dynamic_cast<KeyboardController*>(controlDeck->GetPhysicalDevice(controlDeck->GetNumPhysicalDevices() - 2).get());
if (pad != nullptr) {
if (pad->ReleaseButton(dwScancode)) {
bIsProcessed = true;
@ -359,8 +356,8 @@ namespace Ship {
bool Window::KeyDown(int32_t dwScancode) {
bool bIsProcessed = false;
const auto pad = dynamic_cast<KeyboardController*>(ControllerApi->physicalDevices[ControllerApi->physicalDevices.size() - 2].get());
auto controlDeck = GlobalCtx2::GetInstance()->GetWindow()->GetControlDeck();
const auto pad = dynamic_cast<KeyboardController*>(controlDeck->GetPhysicalDevice(controlDeck->GetNumPhysicalDevices() - 2).get());
if (pad != nullptr) {
if (pad->PressButton(dwScancode)) {
bIsProcessed = true;
@ -374,7 +371,8 @@ namespace Ship {
void Window::AllKeysUp(void) {
const auto pad = dynamic_cast<KeyboardController*>(ControllerApi->physicalDevices[ControllerApi->physicalDevices.size() - 2].get());
auto controlDeck = GlobalCtx2::GetInstance()->GetWindow()->GetControlDeck();
const auto pad = dynamic_cast<KeyboardController*>(controlDeck->GetPhysicalDevice(controlDeck->GetNumPhysicalDevices() - 2).get());
if (pad != nullptr) {
pad->ReleaseAllButtons();
}
@ -400,7 +398,7 @@ namespace Ship {
return dwHeight;
}
void Window::SetAudioPlayer() {
void Window::InitializeAudioPlayer() {
#ifdef _WIN32
APlayer = std::make_shared<WasapiAudioPlayer>();
#elif defined(__linux)
@ -409,4 +407,8 @@ namespace Ship {
APlayer = std::make_shared<SDLAudioPlayer>();
#endif
}
void Window::InitializeControlDeck() {
ControllerApi = std::make_shared<ControlDeck>();
}
}

View File

@ -16,7 +16,6 @@ namespace Ship {
class Window {
public:
static int32_t lastScancode;
inline static ControlDeck* ControllerApi = new ControlDeck;
Window(std::shared_ptr<GlobalCtx2> Context);
~Window();
@ -32,12 +31,12 @@ namespace Ship {
void ToggleFullscreen();
void SetFullscreen(bool bIsFullscreen);
void ShowCursor(bool hide);
bool IsFullscreen() { return bIsFullscreen; }
uint32_t GetCurrentWidth();
uint32_t GetCurrentHeight();
ControlDeck* GetControlDeck() { return ControllerApi; };
uint32_t dwMenubar;
uint32_t GetMenuBar() { return dwMenubar; }
void SetMenuBar(uint32_t dwMenuBar) { this->dwMenubar = dwMenuBar; }
std::shared_ptr<ControlDeck> GetControlDeck() { return ControllerApi; };
std::shared_ptr<GlobalCtx2> GetContext() { return Context.lock(); }
std::shared_ptr<AudioPlayer> GetAudioPlayer() { return APlayer; }
const char* GetKeyName(int scancode) { return WmApi->get_key_name(scancode); }
@ -48,15 +47,18 @@ namespace Ship {
static bool KeyUp(int32_t dwScancode);
static void AllKeysUp(void);
static void OnFullscreenChanged(bool bIsNowFullscreen);
void SetAudioPlayer();
void InitializeControlDeck();
void InitializeAudioPlayer();
std::weak_ptr<GlobalCtx2> Context;
std::shared_ptr<AudioPlayer> APlayer;
std::shared_ptr<ControlDeck> ControllerApi;
GfxRenderingAPI* RenderingApi;
GfxWindowManagerAPI* WmApi;
bool bIsFullscreen;
uint32_t dwWidth;
uint32_t dwHeight;
uint32_t dwMenubar;
};
}

View File

@ -258,7 +258,6 @@
<ClCompile Include="Blob.cpp" />
<ClCompile Include="ControlDeck.cpp" />
<ClCompile Include="Cvar.cpp" />
<ClCompile Include="Environment.cpp" />
<ClCompile Include="Factories\AudioFactory.cpp" />
<ClCompile Include="InputEditor.cpp" />
<ClCompile Include="GameOverlay.cpp" />
@ -268,7 +267,6 @@
<ClCompile Include="Lib\Mercury\Mercury.cpp" />
<ClCompile Include="luslog.cpp" />
<ClCompile Include="mixer.c" />
<ClCompile Include="ModManager.cpp" />
<ClCompile Include="SDLAudioPlayer.cpp" />
<ClCompile Include="Console.cpp" />
<ClCompile Include="Factories\AnimationFactory.cpp" />
@ -283,7 +281,6 @@
<ClCompile Include="Factories\VtxFactory.cpp" />
<ClCompile Include="Array.cpp" />
<ClCompile Include="Controller.cpp" />
<ClCompile Include="Hooks.cpp" />
<ClCompile Include="ImGuiImpl.cpp" />
<ClCompile Include="KeyboardController.cpp" />
<ClCompile Include="Factories\CollisionHeaderFactory.cpp" />
@ -334,7 +331,6 @@
<ClCompile Include="SkeletonLimb.cpp" />
<ClCompile Include="Text.cpp" />
<ClCompile Include="Texture.cpp" />
<ClCompile Include="TextureMod.cpp" />
<ClCompile Include="Utils.cpp" />
<ClCompile Include="Vertex.cpp" />
<ClCompile Include="WasapiAudioPlayer.cpp" />
@ -354,7 +350,6 @@
<ClInclude Include="color.h" />
<ClInclude Include="ControlDeck.h" />
<ClInclude Include="Cvar.h" />
<ClInclude Include="Environment.h" />
<ClInclude Include="Factories\AudioFactory.h" />
<ClInclude Include="InputEditor.h" />
<ClInclude Include="GameOverlay.h" />
@ -367,8 +362,6 @@
<ClInclude Include="Lib\stb\stb_image_write.h" />
<ClInclude Include="luslog.h" />
<ClInclude Include="mixer.h" />
<ClInclude Include="ModManager.h" />
<ClInclude Include="ModModule.h" />
<ClInclude Include="SDLAudioPlayer.h" />
<ClInclude Include="Console.h" />
<ClInclude Include="Factories\ArrayFactory.h" />
@ -407,7 +400,6 @@
<ClInclude Include="Matrix.h" />
<ClInclude Include="Path.h" />
<ClInclude Include="Text.h" />
<ClInclude Include="TextureMod.h" />
<ClInclude Include="Utils.h" />
<ClInclude Include="Vertex.h" />
<ClInclude Include="stox.h" />

View File

@ -67,27 +67,15 @@
<Filter Include="Source Files\Audio">
<UniqueIdentifier>{ccd6359f-e357-41ca-9b89-5f509dd30649}</UniqueIdentifier>
</Filter>
<Filter Include="Source Files\CustomImpl\Environment">
<UniqueIdentifier>{94ca4b98-cee2-48e6-a88b-68b8d2fed287}</UniqueIdentifier>
</Filter>
<Filter Include="Source Files\CustomImpl\Utils">
<UniqueIdentifier>{0dca2d94-45ba-4916-b03a-1dd5f949114c}</UniqueIdentifier>
</Filter>
<Filter Include="Source Files\ModManager">
<UniqueIdentifier>{8e970531-d0cd-4c29-9800-a7e6edc92036}</UniqueIdentifier>
</Filter>
<Filter Include="Source Files\ModManager\ModModule">
<UniqueIdentifier>{05f273a3-f147-430e-9853-aeef59e6288d}</UniqueIdentifier>
</Filter>
<Filter Include="Source Files\CustomImpl\Hooks">
<UniqueIdentifier>{cc8de11b-7305-4482-853f-7f0f843eef28}</UniqueIdentifier>
</Filter>
<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>
<Filter Include="Source Files\Lib\dr_libs">
<UniqueIdentifier>{db6e02cc-fc4c-4138-8219-1d281ad93ec2}</UniqueIdentifier>
</Filter>
@ -100,6 +88,9 @@
<Filter Include="Source Files\Controller\InputEditor">
<UniqueIdentifier>{010dc29b-d1f6-4793-a4e7-4156aa4fcdd6}</UniqueIdentifier>
</Filter>
<Filter Include="Source Files\GUI">
<UniqueIdentifier>{5d68254f-662d-4e8c-a57f-de0d8e1d4a58}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="Factories\MaterialFactory.cpp">
@ -303,12 +294,6 @@
<ClCompile Include="Lib\ImGui\backends\imgui_impl_sdl.cpp">
<Filter>Source Files\Lib\ImGui</Filter>
</ClCompile>
<ClCompile Include="ImGuiImpl.cpp">
<Filter>Source Files\CustomImpl</Filter>
</ClCompile>
<ClCompile Include="Console.cpp">
<Filter>Source Files\CustomImpl</Filter>
</ClCompile>
<ClCompile Include="Lib\ImGui\backends\imgui_impl_dx11.cpp">
<Filter>Source Files\Lib\ImGui</Filter>
</ClCompile>
@ -321,9 +306,6 @@
<ClCompile Include="SDLAudioPlayer.cpp">
<Filter>Source Files\Audio</Filter>
</ClCompile>
<ClCompile Include="Environment.cpp">
<Filter>Source Files\CustomImpl\Environment</Filter>
</ClCompile>
<ClCompile Include="Utils.cpp">
<Filter>Source Files\CustomImpl\Utils</Filter>
</ClCompile>
@ -333,24 +315,12 @@
<ClCompile Include="Cvar.cpp">
<Filter>Source Files\Globals</Filter>
</ClCompile>
<ClCompile Include="TextureMod.cpp">
<Filter>Source Files\ModManager\ModModule</Filter>
</ClCompile>
<ClCompile Include="ModManager.cpp">
<Filter>Source Files\ModManager</Filter>
</ClCompile>
<ClCompile Include="Hooks.cpp">
<Filter>Source Files\CustomImpl\Hooks</Filter>
</ClCompile>
<ClCompile Include="luslog.cpp">
<Filter>Source Files\Logging</Filter>
</ClCompile>
<ClCompile Include="GameSettings.cpp">
<Filter>Source Files\CustomImpl</Filter>
</ClCompile>
<ClCompile Include="GameOverlay.cpp">
<Filter>Source Files\CustomImpl\Overlay</Filter>
</ClCompile>
<ClCompile Include="Audio.cpp">
<Filter>Source Files\Resources\Files</Filter>
</ClCompile>
@ -366,6 +336,15 @@
<ClCompile Include="Lib\Mercury\Mercury.cpp">
<Filter>Source Files\Lib\Mercury</Filter>
</ClCompile>
<ClCompile Include="Console.cpp">
<Filter>Source Files\GUI</Filter>
</ClCompile>
<ClCompile Include="GameOverlay.cpp">
<Filter>Source Files\GUI</Filter>
</ClCompile>
<ClCompile Include="ImGuiImpl.cpp">
<Filter>Source Files\GUI</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="Lib\tinyxml2\tinyxml2.h">
@ -593,21 +572,12 @@
<ClInclude Include="Lib\ImGui\backends\imgui_impl_sdl.h">
<Filter>Source Files\Lib\ImGui</Filter>
</ClInclude>
<ClInclude Include="ImGuiImpl.h">
<Filter>Source Files\CustomImpl</Filter>
</ClInclude>
<ClInclude Include="Console.h">
<Filter>Source Files\CustomImpl</Filter>
</ClInclude>
<ClInclude Include="Lib\ImGui\backends\imgui_impl_dx11.h">
<Filter>Source Files\Lib\ImGui</Filter>
</ClInclude>
<ClInclude Include="Lib\ImGui\backends\imgui_impl_win32.h">
<Filter>Source Files\Lib\ImGui</Filter>
</ClInclude>
<ClInclude Include="Environment.h">
<Filter>Source Files\CustomImpl\Environment</Filter>
</ClInclude>
<ClInclude Include="Utils.h">
<Filter>Source Files\CustomImpl\Utils</Filter>
</ClInclude>
@ -632,15 +602,6 @@
<ClInclude Include="Lib\stb\stb_image_write.h">
<Filter>Source Files\Lib\stb</Filter>
</ClInclude>
<ClInclude Include="TextureMod.h">
<Filter>Source Files\ModManager\ModModule</Filter>
</ClInclude>
<ClInclude Include="ModManager.h">
<Filter>Source Files\ModManager</Filter>
</ClInclude>
<ClInclude Include="ModModule.h">
<Filter>Source Files\ModManager\ModModule</Filter>
</ClInclude>
<ClInclude Include="Hooks.h">
<Filter>Source Files\CustomImpl\Hooks</Filter>
</ClInclude>
@ -656,9 +617,6 @@
<ClInclude Include="color.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="GameOverlay.h">
<Filter>Source Files\CustomImpl\Overlay</Filter>
</ClInclude>
<ClInclude Include="Audio.h">
<Filter>Header Files\Resources\Files</Filter>
</ClInclude>
@ -686,5 +644,14 @@
<ClInclude Include="VirtualController.h">
<Filter>Source Files\Controller</Filter>
</ClInclude>
<ClInclude Include="Console.h">
<Filter>Source Files\GUI</Filter>
</ClInclude>
<ClInclude Include="GameOverlay.h">
<Filter>Source Files\GUI</Filter>
</ClInclude>
<ClInclude Include="ImGuiImpl.h">
<Filter>Source Files\GUI</Filter>
</ClInclude>
</ItemGroup>
</Project>

View File

@ -25,7 +25,8 @@ typedef struct {
/* 0x0C */ Vec3f position;
/* 0x18 */ Vec3s unkVelocity;
/* 0x1E */ Vec3s unkPosition;
} EffectSparkElement; // size = 0x24
/* 0x24 */ s32 epoch;
} EffectSparkElement; // size = 0x28
typedef struct {
/* 0x000 */ Vec3s position;
@ -117,7 +118,8 @@ typedef struct {
/* 0x10 */ f32 startX;
/* 0x14 */ s16 yaw;
/* 0x16 */ s16 pitch;
} EffectShieldParticleElement; // size = 0x18
/* 0x18 */ s32 epoch;
} EffectShieldParticleElement; // size = 0x1C
typedef struct {
/* 0x00 */ u8 numElements;

View File

@ -463,50 +463,49 @@ void DebugConsole_Init(void) {
CMD_REGISTER("kill", { KillPlayerHandler, "Commit suicide." });
CMD_REGISTER("map", { LoadSceneHandler, "Load up kak?" });
CMD_REGISTER("rupee", { RuppeHandler, "Set your rupee counter.", {
{"amount", ArgumentType::NUMBER }
{"amount", Ship::ArgumentType::NUMBER }
}});
CMD_REGISTER("bItem", { BHandler, "Set an item to the B button.", { { "Item ID", ArgumentType::NUMBER } } });
CMD_REGISTER("health", { SetPlayerHealthHandler, "Set the health of the player.", {
{"health", ArgumentType::NUMBER }
CMD_REGISTER("bItem", { BHandler, "Set an item to the B button.", { { "Item ID", Ship::ArgumentType::NUMBER } } });
CMD_REGISTER("health", { SetPlayerHealthHandler, "Set the health of the player.", { { "health", Ship::ArgumentType::NUMBER }
}});
CMD_REGISTER("spawn", { ActorSpawnHandler, "Spawn an actor.", {
{ "actor_id", ArgumentType::NUMBER },
{ "data", ArgumentType::NUMBER },
{ "x", ArgumentType::PLAYER_POS, true },
{ "y", ArgumentType::PLAYER_POS, true },
{ "z", ArgumentType::PLAYER_POS, true },
{ "rx", ArgumentType::PLAYER_ROT, true },
{ "ry", ArgumentType::PLAYER_ROT, true },
{ "rz", ArgumentType::PLAYER_ROT, true }
CMD_REGISTER("spawn", { ActorSpawnHandler, "Spawn an actor.", { { "actor_id", Ship::ArgumentType::NUMBER },
{ "data", Ship::ArgumentType::NUMBER },
{ "x", Ship::ArgumentType::PLAYER_POS, true },
{ "y", Ship::ArgumentType::PLAYER_POS, true },
{ "z", Ship::ArgumentType::PLAYER_POS, true },
{ "rx", Ship::ArgumentType::PLAYER_ROT, true },
{ "ry", Ship::ArgumentType::PLAYER_ROT, true },
{ "rz", Ship::ArgumentType::PLAYER_ROT, true }
}});
CMD_REGISTER("pos", { SetPosHandler, "Sets the position of the player.", {
{ "x", ArgumentType::PLAYER_POS, true },
{ "y", ArgumentType::PLAYER_POS, true },
{ "z", ArgumentType::PLAYER_POS, true }
CMD_REGISTER("pos", { SetPosHandler, "Sets the position of the player.", { { "x", Ship::ArgumentType::PLAYER_POS, true },
{ "y", Ship::ArgumentType::PLAYER_POS, true },
{ "z", Ship::ArgumentType::PLAYER_POS, true }
}});
CMD_REGISTER("set", { SetCVarHandler,
"Sets a console variable.",
{ { "varName", ArgumentType::TEXT }, { "varValue", ArgumentType::TEXT } } });
CMD_REGISTER("get", { GetCVarHandler, "Gets a console variable.", { { "varName", ArgumentType::TEXT } } });
{ { "varName", Ship::ArgumentType::TEXT }, { "varValue", Ship::ArgumentType::TEXT } } });
CMD_REGISTER("get", { GetCVarHandler, "Gets a console variable.", { { "varName", Ship::ArgumentType::TEXT } } });
CMD_REGISTER("reset", { ResetHandler, "Resets the game." });
CMD_REGISTER("ammo", { AmmoHandler, "Changes ammo of an item.",
{ { "item", ArgumentType::TEXT },
{ "count", ArgumentType::NUMBER } } });
{ { "item", Ship::ArgumentType::TEXT }, { "count", Ship::ArgumentType::NUMBER } } });
CMD_REGISTER("bottle", { BottleHandler,
"Changes item in a bottle slot.",
{ { "item", ArgumentType::TEXT }, { "slot", ArgumentType::NUMBER } } });
{ { "item", Ship::ArgumentType::TEXT }, { "slot", Ship::ArgumentType::NUMBER } } });
CMD_REGISTER("item", { ItemHandler,
"Sets item ID in arg 1 into slot arg 2. No boundary checks. Use with caution.",
{ { "slot", ArgumentType::NUMBER }, { "item id", ArgumentType::NUMBER } } });
CMD_REGISTER("entrance",
{ EntranceHandler, "Sends player to the entered entrance (hex)", { { "entrance", ArgumentType::NUMBER } } });
{ { "slot", Ship::ArgumentType::NUMBER }, { "item id", Ship::ArgumentType::NUMBER } } });
CMD_REGISTER("entrance", { EntranceHandler,
"Sends player to the entered entrance (hex)",
{ { "entrance", Ship::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, }
CMD_REGISTER("set_slot", { StateSlotSelectHandler, "Selects a SaveState slot", { {
"Slot number",
Ship::ArgumentType::NUMBER,
}
} });
DebugConsole_LoadCVars();
}
@ -568,20 +567,18 @@ void DebugConsole_LoadCVars() {
switch (value.type()) {
case nlohmann::detail::value_t::array:
break;
case nlohmann::detail::value_t::string:
if (StringHelper::StartsWith(value.get<std::string>(), "#"))
{
uint32_t val = std::stoul(&value.get<std::string>().c_str()[1], nullptr, 16);
case nlohmann::detail::value_t::object:
if (value["Type"].get<std::string>() == mercuryRGBAObjectType) {
Color_RGBA8 clr;
clr.r = val >> 24;
clr.g = val >> 16;
clr.b = val >> 8;
clr.a = val & 0xFF;
CVar_SetRGBA(item.key().c_str(), clr);
clr.r = value["R"].get<uint8_t>();
clr.g = value["G"].get<uint8_t>();
clr.b = value["B"].get<uint8_t>();
clr.a = value["A"].get<uint8_t>();
}
else
CVar_SetString(item.key().c_str(), value.get<std::string>().c_str());
break;
case nlohmann::detail::value_t::string:
CVar_SetString(item.key().c_str(), value.get<std::string>().c_str());
break;
case nlohmann::detail::value_t::boolean:
CVar_SetS32(item.key().c_str(), value.get<bool>());
@ -618,10 +615,13 @@ void DebugConsole_SaveCVars()
pConf->setFloat(key, cvar.second->value.valueFloat);
else if (cvar.second->type == CVarType::RGBA)
{
auto keyStr = key.c_str();
Color_RGBA8 clr = cvar.second->value.valueRGBA;
uint32_t val = (clr.r << 24) + (clr.g << 16) + (clr.b << 8) + clr.a;
std::string str = StringHelper::Sprintf("#%08X", val);
pConf->setString(key, str);
pConf->setUInt(StringHelper::Sprintf("%s.R", keyStr), clr.r);
pConf->setUInt(StringHelper::Sprintf("%s.G", keyStr), clr.r);
pConf->setUInt(StringHelper::Sprintf("%s.B", keyStr), clr.r);
pConf->setUInt(StringHelper::Sprintf("%s.A", keyStr), clr.r);
pConf->setString(StringHelper::Sprintf("%s.Type", keyStr), mercuryRGBAObjectType);
}
}

View File

@ -4,9 +4,7 @@
#include <algorithm>
#include <filesystem>
#include <locale>
#include <codecvt>
#include "GlobalCtx2.h"
#include "GameSettings.h"
#include "ResourceMgr.h"
#include "DisplayList.h"
#include "PlayerAnimation.h"
@ -22,11 +20,9 @@
#else
#include <time.h>
#endif
#include <Vertex.h>
#include <CollisionHeader.h>
#include <Array.h>
#include <Cutscene.h>
#include <Texture.h>
#include "Lib/stb/stb_image.h"
#define DRMP3_IMPLEMENTATION
#include "Lib/dr_libs/mp3.h"
@ -40,10 +36,10 @@
#include <soh/Enhancements/randomizer/randomizer_item_tracker.h>
#include "Enhancements/n64_weird_frame_data.inc"
#include "soh/frame_interpolation.h"
#include "Utils/BitConverter.h"
#include "variables.h"
#include "macros.h"
#include <Utils/StringHelper.h>
#include "Hooks.h"
#ifdef __APPLE__
#include <SDL_scancode.h>
@ -1306,10 +1302,11 @@ extern "C" uint32_t OTRGetCurrentHeight() {
}
extern "C" void OTRControllerCallback(ControllerCallback* controller) {
const auto controllers = Ship::Window::ControllerApi->virtualDevices;
auto controlDeck = Ship::GlobalCtx2::GetInstance()->GetWindow()->GetControlDeck();
for (int i = 0; i < controllers.size(); ++i) {
Ship::Window::ControllerApi->physicalDevices[controllers[i]]->WriteToSource(i, controller);
for (int i = 0; i < controlDeck->GetNumVirtualDevices(); ++i) {
auto physicalDevice = controlDeck->GetPhysicalDeviceFromVirtualSlot(i);
physicalDevice->WriteToSource(i, controller);
}
}
@ -1363,11 +1360,11 @@ extern "C" void AudioPlayer_Play(const uint8_t* buf, uint32_t len) {
}
extern "C" int Controller_ShouldRumble(size_t i) {
auto controlDeck = Ship::GlobalCtx2::GetInstance()->GetWindow()->GetControlDeck();
const auto controllers = Ship::Window::ControllerApi->virtualDevices;
for (const auto virtual_entry : controllers) {
if (Ship::Window::ControllerApi->physicalDevices[virtual_entry]->CanRumble()) {
for (int i = 0; i < controlDeck->GetNumVirtualDevices(); ++i) {
auto physicalDevice = controlDeck->GetPhysicalDeviceFromVirtualSlot(i);
if (physicalDevice->CanRumble()) {
return 1;
}
}
@ -1375,6 +1372,10 @@ extern "C" int Controller_ShouldRumble(size_t i) {
return 0;
}
extern "C" void Hooks_ExecuteAudioInit() {
Ship::ExecuteHooks<Ship::AudioInit>();
}
extern "C" void* getN64WeirdFrame(s32 i) {
char* weirdFrameBytes = reinterpret_cast<char*>(n64WeirdFrames);
return &weirdFrameBytes[i + sizeof(n64WeirdFrames)];
@ -1515,6 +1516,11 @@ extern "C" s32 Randomizer_GetItemIdFromKnownCheck(RandomizerCheck randomizerChec
return OTRGlobals::Instance->gRandomizer->GetRandomizedItemIdFromKnownCheck(randomizerCheck, ogId);
}
extern "C" bool Randomizer_ObtainedFreestandingIceTrap(RandomizerCheck randomizerCheck, GetItemID ogId, Actor* actor) {
return gSaveContext.n64ddFlag && (actor->parent != NULL) &&
Randomizer_GetItemIdFromKnownCheck(randomizerCheck, ogId) == GI_ICE_TRAP;
}
extern "C" bool Randomizer_ItemIsIceTrap(RandomizerCheck randomizerCheck, GetItemID ogId) {
return gSaveContext.n64ddFlag && Randomizer_GetItemIdFromKnownCheck(randomizerCheck, ogId) == GI_ICE_TRAP;
}

View File

@ -85,6 +85,7 @@ int AudioPlayer_GetDesiredBuffered(void);
void AudioPlayer_Play(const uint8_t* buf, uint32_t len);
void AudioMgr_CreateNextAudioBuffer(s16* samples, u32 num_samples);
int Controller_ShouldRumble(size_t i);
void Hooks_ExecuteAudioInit();
void* getN64WeirdFrame(s32 i);
Sprite* GetSeedTexture(uint8_t index);
void Randomizer_LoadSettings(const char* spoilerFileName);
@ -100,6 +101,7 @@ s16 Randomizer_GetItemModelFromId(s16 itemId);
s32 Randomizer_GetItemIDFromGetItemID(s32 getItemId);
s32 Randomizer_GetRandomizedItemId(GetItemID ogId, s16 actorId, s16 actorParams, s16 sceneNum);
s32 Randomizer_GetItemIdFromKnownCheck(RandomizerCheck randomizerCheck, GetItemID ogId);
bool Randomizer_ObtainedFreestandingIceTrap(RandomizerCheck randomizerCheck, GetItemID ogId, Actor* actor);
bool Randomizer_ItemIsIceTrap(RandomizerCheck randomizerCheck, GetItemID ogId);
#endif

View File

@ -1,6 +1,6 @@
#include "global.h"
#include "Hooks.h"
#include <string.h>
#include "soh/OTRGlobals.h"
void func_800C3C80(AudioMgr* audioMgr) {
AudioTask* task;
@ -108,7 +108,7 @@ void AudioMgr_Init(AudioMgr* audioMgr, void* stack, OSPri pri, OSId id, SchedCon
AudioLoad_SetDmaHandler(DmaMgr_DmaHandler);
Audio_InitSound();
osSendMesgPtr(&audioMgr->unk_C8, NULL, OS_MESG_BLOCK);
ModInternal_ExecuteAudioInitHooks();
Hooks_ExecuteAudioInit();
// Removed due to crash
//IrqMgr_AddClient(audioMgr->irqMgr, &irqClient, &audioMgr->unk_74);
hasInitialized = true;

View File

@ -55,13 +55,13 @@ void SpeedMeter_DrawTimeEntries(SpeedMeter* this, GraphicsContext* gfxCtx) {
uly = this->y;
lry = this->y + 2;
OPEN_DISPS(gfxCtx);
/*! @bug if gIrqMgrRetraceTime is 0, CLOSE_DISPS will never be reached */
if (gIrqMgrRetraceTime == 0) {
return;
}
OPEN_DISPS(gfxCtx);
sSpeedMeterTimeEntryPtr = &sSpeedMeterTimeEntryArray[0];
for (i = 0; i < ARRAY_COUNT(sSpeedMeterTimeEntryArray); i++) {
temp = ((f64) * (sSpeedMeterTimeEntryPtr->time) / gIrqMgrRetraceTime) * 64.0;

View File

@ -3961,6 +3961,8 @@ void Actor_DrawDoorLock(GlobalContext* globalCtx, s32 frame, s32 type) {
f32 chainsTranslateX;
f32 chainsTranslateY;
f32 rotZStep;
static s32 epoch = 0;
epoch++;
entry = &sDoorLocksInfo[type];
chainRotZ = entry->chainsRotZInit;
@ -3974,6 +3976,7 @@ void Actor_DrawDoorLock(GlobalContext* globalCtx, s32 frame, s32 type) {
chainsTranslateY = cosf(entry->chainAngle - chainRotZ) * (10 - frame) * 0.1f * entry->chainLength;
for (i = 0; i < 4; i++) {
FrameInterpolation_RecordOpenChild(entry, epoch + i * 25);
Matrix_Put(&baseMtxF);
Matrix_RotateZ(chainRotZ, MTXMODE_APPLY);
Matrix_Translate(chainsTranslateX, chainsTranslateY, 0.0f, MTXMODE_APPLY);
@ -3993,6 +3996,7 @@ void Actor_DrawDoorLock(GlobalContext* globalCtx, s32 frame, s32 type) {
}
chainRotZ += rotZStep;
FrameInterpolation_RecordCloseChild();
}
Matrix_Put(&baseMtxF);

View File

@ -47,6 +47,7 @@ void EffectShieldParticle_Init(void* thisx, void* initParamsx) {
elem->endXChange = elem->initialSpeed;
elem->yaw = Rand_ZeroOne() * 65534.0f;
elem->pitch = Rand_ZeroOne() * 65534.0f;
elem->epoch++;
}
this->lightDecay = initParams->lightDecay;
@ -156,7 +157,6 @@ void EffectShieldParticle_Draw(void* thisx, GraphicsContext* gfxCtx) {
Color_RGBA8 primColor;
Color_RGBA8 envColor;
FrameInterpolation_RecordOpenChild(this, 0);
OPEN_DISPS(gfxCtx);
if (this != NULL) {
@ -182,6 +182,8 @@ void EffectShieldParticle_Draw(void* thisx, GraphicsContext* gfxCtx) {
gDPPipeSync(POLY_XLU_DISP++);
for (elem = &this->elements[0]; elem < &this->elements[this->numElements]; elem++) {
FrameInterpolation_RecordOpenChild(elem, elem->epoch);
Mtx* mtx;
MtxF sp104;
MtxF spC4;
@ -212,9 +214,10 @@ void EffectShieldParticle_Draw(void* thisx, GraphicsContext* gfxCtx) {
gSPMatrix(POLY_XLU_DISP++, mtx, G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
gSPVertex(POLY_XLU_DISP++, sVertices, 4, 0);
gSP2Triangles(POLY_XLU_DISP++, 0, 1, 2, 0, 0, 3, 1, 0);
FrameInterpolation_RecordCloseChild();
}
}
CLOSE_DISPS(gfxCtx);
FrameInterpolation_RecordCloseChild();
}

View File

@ -89,6 +89,7 @@ void EffectSpark_Init(void* thisx, void* initParamsx) {
elem->unkPosition.x = Rand_ZeroOne() * 65534.0f;
elem->unkPosition.y = Rand_ZeroOne() * 65534.0f;
elem->unkPosition.z = Rand_ZeroOne() * 65534.0f;
elem->epoch++;
}
this->timer = 0;
@ -210,6 +211,8 @@ void EffectSpark_Draw(void* thisx, GraphicsContext* gfxCtx) {
Mtx* mtx;
f32 temp;
FrameInterpolation_RecordOpenChild(elem, elem->epoch);
SkinMatrix_SetTranslate(&spEC, elem->position.x, elem->position.y, elem->position.z);
temp = ((Rand_ZeroOne() * 2.5f) + 1.5f) / 64.0f;
SkinMatrix_SetScale(&spAC, temp, temp, 1.0f);
@ -264,6 +267,7 @@ void EffectSpark_Draw(void* thisx, GraphicsContext* gfxCtx) {
mtx = SkinMatrix_MtxFToNewMtx(gfxCtx, &sp12C);
if (mtx == NULL) {
FrameInterpolation_RecordCloseChild();
goto end;
}
@ -273,6 +277,8 @@ void EffectSpark_Draw(void* thisx, GraphicsContext* gfxCtx) {
}
gDPPipeSync(POLY_XLU_DISP++);
FrameInterpolation_RecordCloseChild();
}
end:

View File

@ -3,6 +3,7 @@
#include "vt.h"
#include "objects/gameplay_keep/gameplay_keep.h"
#include "objects/gameplay_field_keep/gameplay_field_keep.h"
#include "soh/frame_interpolation.h"
typedef enum {
/* 0 */ LENS_FLARE_CIRCLE0,
@ -950,7 +951,6 @@ void Environment_Update(GlobalContext* globalCtx, EnvironmentContext* envCtx, Li
Gfx* prevDisplayList;
OPEN_DISPS(globalCtx->state.gfxCtx);
prevDisplayList = POLY_OPA_DISP;
displayList = Graph_GfxPlusOne(POLY_OPA_DISP);
gSPDisplayList(OVERLAY_DISP++, displayList);
@ -1459,6 +1459,8 @@ void Environment_DrawLensFlare(GlobalContext* globalCtx, EnvironmentContext* env
LENS_FLARE_RING, LENS_FLARE_CIRCLE1, LENS_FLARE_CIRCLE1, LENS_FLARE_CIRCLE1, LENS_FLARE_CIRCLE1,
LENS_FLARE_CIRCLE1, LENS_FLARE_CIRCLE1, LENS_FLARE_CIRCLE1, LENS_FLARE_CIRCLE1, LENS_FLARE_CIRCLE1,
};
static s32 epoch = 0;
epoch++;
OPEN_DISPS(gfxCtx);
@ -1502,9 +1504,7 @@ void Environment_DrawLensFlare(GlobalContext* globalCtx, EnvironmentContext* env
unk88Target = cosAngle;
}
if (cosAngle < 0.0f) {
} else {
if (!(cosAngle < 0.0f)) {
if (arg9) {
u32 shrink = ShrinkWindow_GetCurrentVal();
func_800C016C(globalCtx, &pos, &screenPos);
@ -1517,6 +1517,8 @@ void Environment_DrawLensFlare(GlobalContext* globalCtx, EnvironmentContext* env
}
for (i = 0; i < ARRAY_COUNT(lensFlareTypes); i++) {
FrameInterpolation_RecordOpenChild("Lens Flare", epoch + i * 25);
Matrix_Translate(pos.x, pos.y, pos.z, MTXMODE_NEW);
if (arg9) {
@ -1573,6 +1575,8 @@ void Environment_DrawLensFlare(GlobalContext* globalCtx, EnvironmentContext* env
gSPDisplayList(POLY_XLU_DISP++, gLensFlareRingDL);
break;
}
FrameInterpolation_RecordCloseChild();
}
alphaScale = cosAngle - (1.5f - cosAngle);
@ -1638,6 +1642,8 @@ void Environment_DrawRain(GlobalContext* globalCtx, View* view, GraphicsContext*
Vec3f unused = { 0.0f, 0.0f, 0.0f };
Vec3f windDirection = { 0.0f, 0.0f, 0.0f };
Player* player = GET_PLAYER(globalCtx);
static s32 epoch = 0;
epoch++;
if (!(globalCtx->cameraPtrs[0]->unk_14C & 0x100) && (globalCtx->envCtx.unk_EE[2] == 0)) {
OPEN_DISPS(gfxCtx);
@ -1667,6 +1673,8 @@ void Environment_DrawRain(GlobalContext* globalCtx, View* view, GraphicsContext*
// draw rain drops
for (i = 0; i < globalCtx->envCtx.unk_EE[1]; i++) {
FrameInterpolation_RecordOpenChild("Rain Drop", epoch + i * 25);
temp2 = Rand_ZeroOne();
temp1 = Rand_ZeroOne();
temp3 = Rand_ZeroOne();
@ -1692,6 +1700,8 @@ void Environment_DrawRain(GlobalContext* globalCtx, View* view, GraphicsContext*
gSPMatrix(POLY_XLU_DISP++, MATRIX_NEWMTX(gfxCtx),
G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
gSPDisplayList(POLY_XLU_DISP++, gRaindropDL);
FrameInterpolation_RecordCloseChild();
}
// draw droplet rings on the ground
@ -1699,6 +1709,8 @@ void Environment_DrawRain(GlobalContext* globalCtx, View* view, GraphicsContext*
u8 firstDone = false;
for (i = 0; i < globalCtx->envCtx.unk_EE[1]; i++) {
FrameInterpolation_RecordOpenChild("Droplet Ring", epoch + i * 25);
if (!firstDone) {
func_80093D84(gfxCtx);
gDPSetEnvColor(POLY_XLU_DISP++, 155, 155, 155, 0);
@ -1719,6 +1731,8 @@ void Environment_DrawRain(GlobalContext* globalCtx, View* view, GraphicsContext*
gSPMatrix(POLY_XLU_DISP++, MATRIX_NEWMTX(gfxCtx),
G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
gSPDisplayList(POLY_XLU_DISP++, gEffShockwaveDL);
FrameInterpolation_RecordCloseChild();
}
}
@ -1911,10 +1925,14 @@ void Environment_DrawLightning(GlobalContext* globalCtx, s32 unused) {
s32 pad[2];
Vec3f unused1 = { 0.0f, 0.0f, 0.0f };
Vec3f unused2 = { 0.0f, 0.0f, 0.0f };
static s32 epoch = 0;
epoch++;
OPEN_DISPS(globalCtx->state.gfxCtx);
for (i = 0; i < ARRAY_COUNT(sLightningBolts); i++) {
FrameInterpolation_RecordOpenChild("Lightning Bolt", epoch + i * 25);
switch (sLightningBolts[i].state) {
case LIGHTNING_BOLT_START:
dx = globalCtx->view.lookAt.x - globalCtx->view.eye.x;
@ -1969,6 +1987,8 @@ void Environment_DrawLightning(GlobalContext* globalCtx, s32 unused) {
gSPMatrix(POLY_XLU_DISP++, SEG_ADDR(1, 0), G_MTX_NOPUSH | G_MTX_MUL | G_MTX_MODELVIEW);
gSPDisplayList(POLY_XLU_DISP++, gEffLightningDL);
}
FrameInterpolation_RecordCloseChild();
}
CLOSE_DISPS(globalCtx->state.gfxCtx);

View File

@ -1,5 +1,6 @@
#include "global.h"
#include "textures/parameter_static/parameter_static.h"
#include "soh/frame_interpolation.h"
s16 Top_LM_Margin = 0;
s16 Left_LM_Margin = 0;
@ -412,6 +413,8 @@ void HealthMeter_Draw(GlobalContext* globalCtx) {
s32 curCombineModeSet = 0;
u8* curBgImgLoaded = NULL;
s32 ddHeartCountMinusOne = gSaveContext.inventory.defenseHearts - 1;
static s32 epoch = 0;
epoch++;
OPEN_DISPS(gfxCtx);
@ -449,6 +452,8 @@ void HealthMeter_Draw(GlobalContext* globalCtx) {
}
for (i = 0; i < totalHeartCount; i++) {
FrameInterpolation_RecordOpenChild("HealthMeter Heart", epoch + i * 25);
if ((ddHeartCountMinusOne < 0) || (i > ddHeartCountMinusOne)) {
if (i < fullHeartCount) {
if (curColorSet != 0) {
@ -624,6 +629,8 @@ void HealthMeter_Draw(GlobalContext* globalCtx) {
offsetX = PosX_original;
}
}
FrameInterpolation_RecordCloseChild();
}
CLOSE_DISPS(gfxCtx);

View File

@ -2751,7 +2751,7 @@ void Message_DrawMain(GlobalContext* globalCtx, Gfx** p) {
if (msgCtx->lastPlayedSong < OCARINA_SONG_SARIAS &&
(msgCtx->ocarinaAction < OCARINA_ACTION_PLAYBACK_MINUET ||
msgCtx->ocarinaAction >= OCARINA_ACTION_PLAYBACK_SARIA)) {
if (msgCtx->disableWarpSongs || interfaceCtx->restrictions.warpSongs == 3) {
if (msgCtx->disableWarpSongs || (interfaceCtx->restrictions.warpSongs == 3 && !gSaveContext.n64ddFlag)) {
Message_StartTextbox(globalCtx, 0x88C, NULL); // "You can't warp here!"
globalCtx->msgCtx.ocarinaMode = OCARINA_MODE_04;
} else if ((gSaveContext.eventInf[0] & 0xF) != 1) {

View File

@ -1384,6 +1384,12 @@ void Inventory_SwapAgeEquipment(void) {
u16 temp;
if (LINK_AGE_IN_YEARS == YEARS_CHILD) {
// When becoming adult, remove swordless flag since we'll get master sword
// Only in rando to keep swordless link bugs in vanilla
if (gSaveContext.n64ddFlag) {
gSaveContext.infTable[29] &= ~1;
}
for (i = 0; i < ARRAY_COUNT(gSaveContext.equips.buttonItems); i++) {
if (i != 0) {
gSaveContext.childEquips.buttonItems[i] = gSaveContext.equips.buttonItems[i];
@ -1444,6 +1450,12 @@ void Inventory_SwapAgeEquipment(void) {
gSaveContext.equips.equipment = gSaveContext.adultEquips.equipment;
}
} else {
// When becoming child, set swordless flag if player doesn't have kokiri sword
// Only in rando to keep swordless link bugs in vanilla
if (gSaveContext.n64ddFlag && (1 << 0 & gSaveContext.inventory.equipment) == 0) {
gSaveContext.infTable[29] |= 1;
}
for (i = 0; i < ARRAY_COUNT(gSaveContext.equips.buttonItems); i++) {
gSaveContext.adultEquips.buttonItems[i] = gSaveContext.equips.buttonItems[i];
@ -3352,8 +3364,8 @@ void Interface_DrawItemButtons(GlobalContext* globalCtx) {
const s16 C_Right_BTN_Pos_ori[] = { C_RIGHT_BUTTON_X+X_Margins_CR, C_RIGHT_BUTTON_Y+Y_Margins_CR };
const s16 C_Up_BTN_Pos_ori[] = { C_UP_BUTTON_X+X_Margins_CU, C_UP_BUTTON_Y+Y_Margins_CU };
const s16 C_Down_BTN_Pos_ori[] = { C_DOWN_BUTTON_X+X_Margins_CD, C_DOWN_BUTTON_Y+Y_Margins_CD };
s16 LabelX_Navi=8;
s16 LabelY_Navi=4 - !!CVar_GetS32("gNaviTextFix", 0);
s16 LabelX_Navi=7 + !!CVar_GetS32("gNaviTextFix", 0);
s16 LabelY_Navi=4;
s16 C_Left_BTN_Pos[2]; //(X,Y)
s16 C_Right_BTN_Pos[2];
s16 C_Up_BTN_Pos[2];

View File

@ -7,6 +7,8 @@
#include "../libultraship/ImGuiImpl.h"
#include "soh/frame_interpolation.h"
#include <time.h>
void* D_8012D1F0 = NULL;
//UNK_TYPE D_8012D1F4 = 0; // unused
Input* D_8012D1F8 = NULL;
@ -201,7 +203,8 @@ void GivePlayerRandoRewardSongOfTime(GlobalContext* globalCtx, RandomizerCheck c
!Flags_GetTreasure(globalCtx, 0x1F) && gSaveContext.nextTransition == 0xFF) {
GetItemID getItemId = Randomizer_GetItemIdFromKnownCheck(check, GI_SONG_OF_TIME);
GiveItemWithoutActor(globalCtx, getItemId);
Flags_SetTreasure(globalCtx, 0x1F);
player->pendingFlag.flagID = 0x1F;
player->pendingFlag.flagType = FLAG_SCENE_TREASURE;
}
}
@ -1444,6 +1447,18 @@ void Gameplay_Draw(GlobalContext* globalCtx) {
CLOSE_DISPS(gfxCtx);
}
time_t Gameplay_GetRealTime() {
time_t t1, t2;
struct tm* tms;
time(&t1);
tms = localtime(&t1);
tms->tm_hour = 0;
tms->tm_min = 0;
tms->tm_sec = 0;
t2 = mktime(tms);
return t1 - t2;
}
void Gameplay_Main(GameState* thisx) {
GlobalContext* globalCtx = (GlobalContext*)thisx;
@ -1487,6 +1502,20 @@ void Gameplay_Main(GameState* thisx) {
if (1 && HREG(63)) {
LOG_NUM("1", 1);
}
if (CVar_GetS32("gTimeSync", 0)) {
const int maxRealDaySeconds = 86400;
const int maxInGameDayTicks = 65536;
int secs = (int)Gameplay_GetRealTime();
float percent = (float)secs / (float)maxRealDaySeconds;
int newIngameTime = maxInGameDayTicks * percent;
gSaveContext.dayTime = newIngameTime;
}
}
// original name: "Game_play_demo_mode_check"

View File

@ -442,62 +442,65 @@ void Sram_OpenSave() {
Save_LoadFile();
switch (gSaveContext.savedSceneNum) {
case SCENE_YDAN:
case SCENE_DDAN:
case SCENE_BDAN:
case SCENE_BMORI1:
case SCENE_HIDAN:
case SCENE_MIZUSIN:
case SCENE_JYASINZOU:
case SCENE_HAKADAN:
case SCENE_HAKADANCH:
case SCENE_ICE_DOUKUTO:
case SCENE_GANON:
case SCENE_MEN:
case SCENE_GERUDOWAY:
case SCENE_GANONTIKA:
gSaveContext.entranceIndex = dungeonEntrances[gSaveContext.savedSceneNum];
break;
case SCENE_YDAN_BOSS:
gSaveContext.entranceIndex = 0;
break;
case SCENE_DDAN_BOSS:
gSaveContext.entranceIndex = 4;
break;
case SCENE_BDAN_BOSS:
gSaveContext.entranceIndex = 0x28;
break;
case SCENE_MORIBOSSROOM:
gSaveContext.entranceIndex = 0x169;
break;
case SCENE_FIRE_BS:
gSaveContext.entranceIndex = 0x165;
break;
case SCENE_MIZUSIN_BS:
gSaveContext.entranceIndex = 0x10;
break;
case SCENE_JYASINBOSS:
gSaveContext.entranceIndex = 0x82;
break;
case SCENE_HAKADAN_BS:
gSaveContext.entranceIndex = 0x37;
break;
case SCENE_GANON_SONOGO:
case SCENE_GANONTIKA_SONOGO:
case SCENE_GANON_BOSS:
case SCENE_GANON_FINAL:
case SCENE_GANON_DEMO:
gSaveContext.entranceIndex = 0x41B;
break;
if (!CVar_GetS32("gRememberSaveLocation", 0) || gSaveContext.savedSceneNum == SCENE_YOUSEI_IZUMI_TATE ||
gSaveContext.savedSceneNum == SCENE_KAKUSIANA) {
switch (gSaveContext.savedSceneNum) {
case SCENE_YDAN:
case SCENE_DDAN:
case SCENE_BDAN:
case SCENE_BMORI1:
case SCENE_HIDAN:
case SCENE_MIZUSIN:
case SCENE_JYASINZOU:
case SCENE_HAKADAN:
case SCENE_HAKADANCH:
case SCENE_ICE_DOUKUTO:
case SCENE_GANON:
case SCENE_MEN:
case SCENE_GERUDOWAY:
case SCENE_GANONTIKA:
gSaveContext.entranceIndex = dungeonEntrances[gSaveContext.savedSceneNum];
break;
case SCENE_YDAN_BOSS:
gSaveContext.entranceIndex = 0;
break;
case SCENE_DDAN_BOSS:
gSaveContext.entranceIndex = 4;
break;
case SCENE_BDAN_BOSS:
gSaveContext.entranceIndex = 0x28;
break;
case SCENE_MORIBOSSROOM:
gSaveContext.entranceIndex = 0x169;
break;
case SCENE_FIRE_BS:
gSaveContext.entranceIndex = 0x165;
break;
case SCENE_MIZUSIN_BS:
gSaveContext.entranceIndex = 0x10;
break;
case SCENE_JYASINBOSS:
gSaveContext.entranceIndex = 0x82;
break;
case SCENE_HAKADAN_BS:
gSaveContext.entranceIndex = 0x37;
break;
case SCENE_GANON_SONOGO:
case SCENE_GANONTIKA_SONOGO:
case SCENE_GANON_BOSS:
case SCENE_GANON_FINAL:
case SCENE_GANON_DEMO:
gSaveContext.entranceIndex = 0x41B;
break;
default:
if (gSaveContext.savedSceneNum != SCENE_LINK_HOME) {
gSaveContext.entranceIndex = (LINK_AGE_IN_YEARS == YEARS_CHILD) ? 0xBB : 0x5F4;
} else {
gSaveContext.entranceIndex = 0xBB;
}
break;
default:
if (gSaveContext.savedSceneNum != SCENE_LINK_HOME) {
gSaveContext.entranceIndex = (LINK_AGE_IN_YEARS == YEARS_CHILD) ? 0xBB : 0x5F4;
} else {
gSaveContext.entranceIndex = 0xBB;
}
break;
}
}
osSyncPrintf("scene_no = %d\n", gSaveContext.entranceIndex);

View File

@ -10,6 +10,7 @@
#include "overlays/actors/ovl_Demo_Effect/z_demo_effect.h"
#include "scenes/indoors/yousei_izumi_yoko/yousei_izumi_yoko_scene.h"
#include "scenes/indoors/daiyousei_izumi/daiyousei_izumi_scene.h"
#include "soh/frame_interpolation.h"
#define FLAGS (ACTOR_FLAG_4 | ACTOR_FLAG_5 | ACTOR_FLAG_25)
@ -960,6 +961,7 @@ void BgDyYoseizo_ParticleInit(BgDyYoseizo* this, Vec3f* initPos, Vec3f* initVelo
particle->pitch = 0.0f;
particle->yaw = Rand_CenteredFloat(30000.0f);
particle->roll = 0.0f;
particle->epoch++;
return;
}
}
@ -1039,6 +1041,8 @@ void BgDyYoseizo_ParticleDraw(BgDyYoseizo* this, GlobalContext* globalCtx) {
func_80093D84(globalCtx->state.gfxCtx);
for (i = 0; i < 200; i++, particle++) {
FrameInterpolation_RecordOpenChild(particle, particle->epoch);
if (particle->alive == 1) {
if (phi_s3 == 0) {
gSPDisplayList(POLY_XLU_DISP++, SEGMENTED_TO_VIRTUAL(gGreatFairyParticleAppearDL));
@ -1060,6 +1064,8 @@ void BgDyYoseizo_ParticleDraw(BgDyYoseizo* this, GlobalContext* globalCtx) {
G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
gSPDisplayList(POLY_XLU_DISP++, SEGMENTED_TO_VIRTUAL(gGreatFairyParticleAliveDL));
}
FrameInterpolation_RecordCloseChild();
}
CLOSE_DISPS(gfxCtx);

View File

@ -24,7 +24,8 @@ typedef struct {
/* 0x36 */ f32 pitch;
/* 0x36 */ f32 yaw;
/* 0x40 */ f32 roll;
} BgDyYoseizoParticle; // size = 0x44
/* 0x44 */ s32 epoch;
} BgDyYoseizoParticle; // size = 0x48
typedef struct BgDyYoseizo {
/* 0x0000 */ Actor actor;

View File

@ -1,6 +1,7 @@
#include "z_bg_jya_megami.h"
#include "overlays/effects/ovl_Effect_Ss_Kakera/z_eff_ss_kakera.h"
#include "objects/object_jya_obj/object_jya_obj.h"
#include "soh/frame_interpolation.h"
#define FLAGS 0
@ -217,6 +218,7 @@ void BgJyaMegami_SetupExplode(BgJyaMegami* this) {
for (i = 0; i < ARRAY_COUNT(this->pieces); i++) {
Math_Vec3f_Copy(&this->pieces[i].pos, &this->dyna.actor.world.pos);
this->pieces[i].vel.x = sPiecesInit[i].velX;
this->pieces[i].epoch++;
}
this->explosionTimer = 0;
}
@ -326,6 +328,9 @@ void BgJyaMegami_DrawExplode(BgJyaMegami* this, GlobalContext* globalCtx) {
for (i = 0; i < ARRAY_COUNT(this->pieces); i++) {
piece = &this->pieces[i];
FrameInterpolation_RecordOpenChild(piece, piece->epoch);
Matrix_Translate(piece->pos.x + sPiecesInit[i].unk_00.x, piece->pos.y + sPiecesInit[i].unk_00.y,
piece->pos.z + sPiecesInit[i].unk_00.z, MTXMODE_NEW);
Matrix_RotateY(piece->rotVelY * (M_PI / 0x8000), MTXMODE_APPLY);
@ -337,6 +342,8 @@ void BgJyaMegami_DrawExplode(BgJyaMegami* this, GlobalContext* globalCtx) {
gSPMatrix(POLY_OPA_DISP++, MATRIX_NEWMTX(globalCtx->state.gfxCtx),
G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
gSPDisplayList(POLY_OPA_DISP++, sDLists[i]);
FrameInterpolation_RecordCloseChild();
}
CLOSE_DISPS(globalCtx->state.gfxCtx);

View File

@ -13,7 +13,8 @@ typedef struct {
/* 0x0C */ Vec3f vel;
/* 0x18 */ s16 rotVelX;
/* 0x1A */ s16 rotVelY;
} BgJyaMegamiPiece; // size = 0x1C
/* 0x1C */ s32 epoch;
} BgJyaMegamiPiece; // size = 0x20
typedef struct BgJyaMegami {
/* 0x0000 */ DynaPolyActor dyna;

View File

@ -7,6 +7,7 @@
#include "z_bg_spot00_hanebasi.h"
#include "objects/object_spot00_objects/object_spot00_objects.h"
#include "objects/gameplay_keep/gameplay_keep.h"
#include "soh/frame_interpolation.h"
#define FLAGS ACTOR_FLAG_4
@ -260,6 +261,8 @@ void BgSpot00Hanebasi_DrawTorches(Actor* thisx, GlobalContext* globalCtx2) {
GlobalContext* globalCtx = globalCtx2;
f32 angle;
s32 i;
static s32 epoch = 0;
epoch++;
OPEN_DISPS(globalCtx->state.gfxCtx);
@ -276,6 +279,8 @@ void BgSpot00Hanebasi_DrawTorches(Actor* thisx, GlobalContext* globalCtx2) {
gDPSetEnvColor(POLY_XLU_DISP++, 255, 0, 0, 0);
for (i = 0; i < 2; i++) {
FrameInterpolation_RecordOpenChild("Hanebasi Torch", epoch + i * 25);
gSPSegment(POLY_XLU_DISP++, 0x08,
Gfx_TwoTexScroll(globalCtx->state.gfxCtx, 0, 0, 0, 32, 64, 1, 0,
((globalCtx->gameplayFrames + i) * -20) & 0x1FF, 32, 128));
@ -287,6 +292,8 @@ void BgSpot00Hanebasi_DrawTorches(Actor* thisx, GlobalContext* globalCtx2) {
gSPMatrix(POLY_XLU_DISP++, MATRIX_NEWMTX(globalCtx->state.gfxCtx),
G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
gSPDisplayList(POLY_XLU_DISP++, gEffFire1DL);
FrameInterpolation_RecordCloseChild();
}
CLOSE_DISPS(globalCtx->state.gfxCtx);

View File

@ -2,6 +2,7 @@
#include "objects/object_kingdodongo/object_kingdodongo.h"
#include "overlays/actors/ovl_Door_Warp1/z_door_warp1.h"
#include "scenes/dungeons/ddan_boss/ddan_boss_room_1.h"
#include "soh/frame_interpolation.h"
#define FLAGS (ACTOR_FLAG_0 | ACTOR_FLAG_2 | ACTOR_FLAG_4 | ACTOR_FLAG_5)
@ -150,6 +151,7 @@ void func_808C17C8(GlobalContext* globalCtx, Vec3f* arg1, Vec3f* arg2, Vec3f* ar
for (i = 0; i < arg5; i++, eff++) {
if (eff->unk_24 == 0) {
eff->epoch++;
eff->unk_24 = 1;
eff->unk_00 = *arg1;
eff->unk_0C = *arg2;
@ -1703,6 +1705,7 @@ void BossDodongo_DrawEffects(GlobalContext* globalCtx) {
#endif
for (i = 0; i < 80; i++, eff++) {
FrameInterpolation_RecordOpenChild(eff, eff->epoch);
if (eff->unk_24 == 1) {
gDPPipeSync(POLY_XLU_DISP++);
@ -1719,6 +1722,7 @@ void BossDodongo_DrawEffects(GlobalContext* globalCtx) {
G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
gSPDisplayList(POLY_XLU_DISP++, object_kingdodongo_DL_009DD0);
}
FrameInterpolation_RecordCloseChild();
}
CLOSE_DISPS(gfxCtx);

View File

@ -17,7 +17,8 @@ typedef struct {
/* 0x26 */ Color_RGB8 color;
/* 0x2A */ s16 alpha;
/* 0x2C */ f32 unk_2C;
} BossDodongoEffect; // Size = 0x30
/* 0x30 */ s32 epoch;
} BossDodongoEffect; // Size = 0x34
typedef struct BossDodongo {
/* 0x0000 */ Actor actor;

View File

@ -1835,6 +1835,8 @@ void BossFd_DrawBody(GlobalContext* globalCtx, BossFd* this) {
s16 i;
f32 temp_float;
Mtx* tempMat = Graph_Alloc(globalCtx->state.gfxCtx, 18 * sizeof(Mtx));
static s32 epoch = 0;
epoch++;
OPEN_DISPS(globalCtx->state.gfxCtx);
if (this->skinSegments != 0) {
@ -1876,6 +1878,8 @@ void BossFd_DrawBody(GlobalContext* globalCtx, BossFd* this) {
Matrix_Push();
for (i = 0; i < 18; i++, tempMat++) {
FrameInterpolation_RecordOpenChild(tempMat, epoch + i * 25);
segIndex = (this->work[BFD_LEAD_BODY_SEG] + sBodyIndex[i + 1]) % 100;
Matrix_Translate(this->bodySegsPos[segIndex].x, this->bodySegsPos[segIndex].y, this->bodySegsPos[segIndex].z,
MTXMODE_NEW);
@ -1938,6 +1942,8 @@ void BossFd_DrawBody(GlobalContext* globalCtx, BossFd* this) {
if (i > 0) {
Collider_UpdateSpheres(i + 1, &this->collider);
}
FrameInterpolation_RecordCloseChild();
}
Matrix_Pop();
osSyncPrintf("BH\n");

View File

@ -9,6 +9,7 @@
#include "overlays/actors/ovl_Boss_Fd/z_boss_fd.h"
#include "overlays/actors/ovl_Door_Warp1/z_door_warp1.h"
#include "vt.h"
#include "soh/frame_interpolation.h"
#define FLAGS (ACTOR_FLAG_0 | ACTOR_FLAG_2 | ACTOR_FLAG_4 | ACTOR_FLAG_5)
@ -1146,6 +1147,8 @@ void BossFd2_UpdateMane(BossFd2* this, GlobalContext* globalCtx, Vec3f* head, Ve
}
for (i = 0; i < 9; i++) {
FrameInterpolation_RecordOpenChild(this, this->epoch + i * 25);
Matrix_Translate((pos + i)->x, (pos + i)->y, (pos + i)->z, MTXMODE_NEW);
Matrix_RotateY((rot + i)->y, MTXMODE_APPLY);
Matrix_RotateX((rot + i)->x, MTXMODE_APPLY);
@ -1155,6 +1158,8 @@ void BossFd2_UpdateMane(BossFd2* this, GlobalContext* globalCtx, Vec3f* head, Ve
gSPMatrix(POLY_XLU_DISP++, MATRIX_NEWMTX(globalCtx->state.gfxCtx),
G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
gSPDisplayList(POLY_XLU_DISP++, gHoleVolvagiaManeModelDL);
FrameInterpolation_RecordCloseChild();
}
Matrix_Pop();
CLOSE_DISPS(globalCtx->state.gfxCtx);

View File

@ -87,6 +87,7 @@ typedef struct BossFd2 {
/* 0x1394 */ BossFd2Cam camData;
/* 0x141C */ ColliderJntSph collider;
/* 0x143C */ ColliderJntSphElement elements[9];
} BossFd2; // size = 0x167C
/* 0x167C */ s32 epoch;
} BossFd2; // size = 0x1680
#endif

View File

@ -3356,6 +3356,8 @@ void BossGanon_DrawShock(BossGanon* this, GlobalContext* globalCtx) {
s32 pad;
GraphicsContext* gfxCtx = globalCtx->state.gfxCtx;
s16 i;
static s32 epoch = 0;
epoch++;
OPEN_DISPS(gfxCtx);
@ -3369,6 +3371,8 @@ void BossGanon_DrawShock(BossGanon* this, GlobalContext* globalCtx) {
Player* player = GET_PLAYER(globalCtx);
for (i = 0; i < ARRAY_COUNT(player->bodyPartsPos); i++) {
FrameInterpolation_RecordOpenChild("Ganondorf Shock 0", epoch + i * 25);
Matrix_Translate(player->bodyPartsPos[i].x, player->bodyPartsPos[i].y, player->bodyPartsPos[i].z,
MTXMODE_NEW);
Matrix_ReplaceRotation(&globalCtx->billboardMtxF);
@ -3377,9 +3381,13 @@ void BossGanon_DrawShock(BossGanon* this, GlobalContext* globalCtx) {
gSPMatrix(POLY_XLU_DISP++, MATRIX_NEWMTX(gfxCtx),
G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
gSPDisplayList(POLY_XLU_DISP++, gDorfSquareDL);
FrameInterpolation_RecordCloseChild();
}
} else {
for (i = 1; i < 15; i++) {
FrameInterpolation_RecordOpenChild("Ganondorf Shock 1", epoch + i * 25);
Matrix_Translate(this->unk_2EC[i].x, this->unk_2EC[i].y, this->unk_2EC[i].z, MTXMODE_NEW);
Matrix_ReplaceRotation(&globalCtx->billboardMtxF);
Matrix_Scale(this->unk_49C[i], this->unk_49C[i], this->unk_49C[i], MTXMODE_APPLY);
@ -3401,6 +3409,8 @@ void BossGanon_DrawShock(BossGanon* this, GlobalContext* globalCtx) {
} else {
gSPDisplayList(POLY_XLU_DISP++, gDorfSquareDL);
}
FrameInterpolation_RecordCloseChild();
}
}
}
@ -3443,9 +3453,9 @@ void BossGanon_DrawHandLightBall(BossGanon* this, GlobalContext* globalCtx) {
gSPMatrix(POLY_XLU_DISP++, MATRIX_NEWMTX(globalCtx->state.gfxCtx),
G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
gSPDisplayList(POLY_XLU_DISP++, gDorfLightCoreDL);
CLOSE_DISPS(gfxCtx);
}
CLOSE_DISPS(gfxCtx);
}
void BossGanon_DrawBigMagicCharge(BossGanon* this, GlobalContext* globalCtx) {
@ -3453,6 +3463,8 @@ void BossGanon_DrawBigMagicCharge(BossGanon* this, GlobalContext* globalCtx) {
f32 yRot;
GraphicsContext* gfxCtx = globalCtx->state.gfxCtx;
s16 i;
static s32 epoch = 0;
epoch++;
OPEN_DISPS(gfxCtx);
@ -3513,6 +3525,8 @@ void BossGanon_DrawBigMagicCharge(BossGanon* this, GlobalContext* globalCtx) {
yRot = BINANG_TO_RAD(this->actor.yawTowardsPlayer);
for (i = 0; i < this->unk_1AC; i++) {
FrameInterpolation_RecordOpenChild("Ganondorf Big Magic", epoch + i * 25);
f32 xzRot = (BossGanon_RandZeroOne() - 0.5f) * M_PI * 1.5f;
gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, 255, 255, 255, (s8)this->unk_294[i]);
@ -3527,10 +3541,12 @@ void BossGanon_DrawBigMagicCharge(BossGanon* this, GlobalContext* globalCtx) {
gSPDisplayList(POLY_XLU_DISP++, gDorfLightRayTriDL);
Matrix_Pop();
}
CLOSE_DISPS(gfxCtx);
FrameInterpolation_RecordCloseChild();
}
}
CLOSE_DISPS(gfxCtx);
}
void BossGanon_DrawTriforce(BossGanon* this, GlobalContext* globalCtx) {
@ -4142,6 +4158,8 @@ void BossGanon_LightBall_Draw(Actor* thisx, GlobalContext* globalCtx) {
s16 i;
f32 alpha;
s32 pad;
static s32 epoch = 0;
epoch++;
OPEN_DISPS(globalCtx->state.gfxCtx);
@ -4166,6 +4184,8 @@ void BossGanon_LightBall_Draw(Actor* thisx, GlobalContext* globalCtx) {
if (this->unk_1A8 == 1) {
for (i = 0; i < 8; i++) {
FrameInterpolation_RecordOpenChild("Ganondorf Light Ball 0", epoch + i * 25);
Matrix_Push();
Matrix_RotateY(i * (M_PI / 8), MTXMODE_APPLY);
Matrix_RotateZ(this->fwork[GDF_FWORK_0], MTXMODE_APPLY);
@ -4174,6 +4194,8 @@ void BossGanon_LightBall_Draw(Actor* thisx, GlobalContext* globalCtx) {
gSPDisplayList(POLY_XLU_DISP++, gDorfSquareDL);
Matrix_Pop();
FrameInterpolation_RecordCloseChild();
}
} else if (this->unk_1A8 == 0) {
Matrix_ReplaceRotation(&globalCtx->billboardMtxF);

View File

@ -5,6 +5,7 @@
#include "objects/object_ganon2/object_ganon2.h"
#include "objects/object_ganon_anime3/object_ganon_anime3.h"
#include "objects/object_geff/object_geff.h"
#include "soh/frame_interpolation.h"
#include <string.h>
@ -2463,6 +2464,8 @@ void func_80904340(BossGanon2* this, GlobalContext* globalCtx) {
f32 angle;
f32 sin;
f32 cos;
static s32 epoch = 0;
epoch++;
OPEN_DISPS(globalCtx->state.gfxCtx);
Matrix_Push();
@ -2485,6 +2488,7 @@ void func_80904340(BossGanon2* this, GlobalContext* globalCtx) {
rand = BossGanon2_RandZeroOne();
for (i = 0; i < 5; i++) {
FrameInterpolation_RecordOpenChild("Ganon 80904340", epoch + i * 25);
angle = (i * (2 * M_PI / 5)) + (rand * M_PI);
sin = 5000.0f * sinf(angle);
cos = 5000.0f * cosf(angle);
@ -2500,6 +2504,7 @@ void func_80904340(BossGanon2* this, GlobalContext* globalCtx) {
gSPMatrix(POLY_XLU_DISP++, MATRIX_NEWMTX(globalCtx->state.gfxCtx),
G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
gSPDisplayList(POLY_XLU_DISP++, SEGMENTED_TO_VIRTUAL(ovl_Boss_Ganon2_DL_00D798));
FrameInterpolation_RecordCloseChild();
}
}
@ -2632,6 +2637,8 @@ void BossGanon2_PostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dLis
void func_80904D88(BossGanon2* this, GlobalContext* globalCtx) {
s32 pad;
s16 i;
static s32 epoch = 0;
epoch++;
OPEN_DISPS(globalCtx->state.gfxCtx);
@ -2647,6 +2654,8 @@ void func_80904D88(BossGanon2* this, GlobalContext* globalCtx) {
gSPDisplayList(POLY_XLU_DISP++, ovl_Boss_Ganon2_DL_00B308);
for (i = 0; i < 15; i++) {
FrameInterpolation_RecordOpenChild("Ganon 80904D88", epoch + i * 25);
Matrix_Translate(this->unk_234[i].x, this->unk_234[i].y, this->unk_234[i].z, MTXMODE_NEW);
Matrix_ReplaceRotation(&globalCtx->billboardMtxF);
Matrix_Scale(this->unk_30C, this->unk_30C, this->unk_30C, MTXMODE_APPLY);
@ -2654,6 +2663,8 @@ void func_80904D88(BossGanon2* this, GlobalContext* globalCtx) {
gSPMatrix(POLY_XLU_DISP++, MATRIX_NEWMTX(globalCtx->state.gfxCtx),
G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
gSPDisplayList(POLY_XLU_DISP++, ovl_Boss_Ganon2_DL_00B378);
FrameInterpolation_RecordCloseChild();
}
}
@ -2690,6 +2701,8 @@ void func_80904FC8(BossGanon2* this, GlobalContext* globalCtx) {
void func_8090523C(BossGanon2* this, GlobalContext* globalCtx) {
Player* player;
f32 phi_f20;
static s32 epoch = 0;
epoch++;
OPEN_DISPS(globalCtx->state.gfxCtx);
@ -2703,6 +2716,8 @@ void func_8090523C(BossGanon2* this, GlobalContext* globalCtx) {
gSPDisplayList(POLY_XLU_DISP++, ovl_Boss_Ganon2_DL_00B308);
for (i = 0; i < 11; i++) {
FrameInterpolation_RecordOpenChild("Ganon 8090523C", epoch + i * 25);
Matrix_Mult(&player->mf_9E0, MTXMODE_NEW);
Matrix_Translate((i * 250.0f) + 900.0f, 350.0f, 0.0f, MTXMODE_APPLY);
@ -2718,6 +2733,8 @@ void func_8090523C(BossGanon2* this, GlobalContext* globalCtx) {
gSPMatrix(POLY_XLU_DISP++, MATRIX_NEWMTX(globalCtx->state.gfxCtx),
G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
gSPDisplayList(POLY_XLU_DISP++, SEGMENTED_TO_VIRTUAL(ovl_Boss_Ganon2_DL_00B378));
FrameInterpolation_RecordCloseChild();
}
}
@ -2916,6 +2933,8 @@ void func_809060E8(GlobalContext* globalCtx) {
BossGanon2Effect* effect;
s16 i;
BossGanon2Effect* effects;
static s32 epoch = 0;
epoch++;
effects = effect = globalCtx->specialEffects;
@ -2925,6 +2944,8 @@ void func_809060E8(GlobalContext* globalCtx) {
for (i = 0; i < 1; i++) {
if (effect->type == 1) {
FrameInterpolation_RecordOpenChild("Ganon 809060E8 0", epoch + i * 25);
Vec3f spA0;
f32 temp_f0;
f32 angle;
@ -2958,6 +2979,8 @@ void func_809060E8(GlobalContext* globalCtx) {
gSPMatrix(POLY_XLU_DISP++, MATRIX_NEWMTX(globalCtx->state.gfxCtx),
G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
gSPDisplayList(POLY_XLU_DISP++, ovl_Boss_Ganon2_DL_00F188);
FrameInterpolation_RecordCloseChild();
}
}
@ -2965,6 +2988,8 @@ void func_809060E8(GlobalContext* globalCtx) {
for (i = 0; i < ARRAY_COUNT(sBossGanon2Particles); i++, effect++) {
if (effect->type == 2) {
FrameInterpolation_RecordOpenChild("Ganon 809060E8 1", epoch + i * 25);
if (!usingObjectGEff) {
BossGanon2_SetObjectSegment(NULL, globalCtx, OBJECT_GEFF, true);
usingObjectGEff++;
@ -2977,6 +3002,8 @@ void func_809060E8(GlobalContext* globalCtx) {
gSPMatrix(POLY_OPA_DISP++, MATRIX_NEWMTX(globalCtx->state.gfxCtx),
G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
gSPDisplayList(POLY_OPA_DISP++, gGanonRubbleDL);
FrameInterpolation_RecordCloseChild();
}
}

View File

@ -348,6 +348,7 @@ void BossMo_Init(Actor* thisx, GlobalContext* globalCtx2) {
globalCtx->specialEffects = sEffects;
for (i = 0; i < ARRAY_COUNT(sEffects); i++) {
sEffects[i].type = MO_FX_NONE;
sEffects[i].epoch++;
}
this->actor.world.pos.x = 200.0f;
this->actor.world.pos.y = MO_WATER_LEVEL(globalCtx) + 50.0f;
@ -2442,6 +2443,8 @@ void BossMo_DrawTentacle(BossMo* this, GlobalContext* globalCtx) {
f32 phi_f20;
f32 phi_f22;
Vec3f sp110;
static s32 epoch = 0;
epoch++;
OPEN_DISPS(globalCtx->state.gfxCtx);
@ -2462,6 +2465,8 @@ void BossMo_DrawTentacle(BossMo* this, GlobalContext* globalCtx) {
BossMo_InitRand(1, 29100, 9786);
for (i = 0; i < 41; i++, matrix++) {
FrameInterpolation_RecordOpenChild("Morpha Tentacle", epoch + i * 25);
s32 pad;
s32 pad2;
@ -2559,6 +2564,8 @@ void BossMo_DrawTentacle(BossMo* this, GlobalContext* globalCtx) {
if ((i < 38) && ((i & 1) == 1)) {
BossMo_UpdateTentColliders(this, i / 2, &this->tentCollider, &this->tentPos[i]);
}
FrameInterpolation_RecordCloseChild();
}
Matrix_Pop();

View File

@ -9,6 +9,7 @@
#include "objects/gameplay_keep/gameplay_keep.h"
#include "overlays/actors/ovl_Bg_Sst_Floor/z_bg_sst_floor.h"
#include "overlays/actors/ovl_Door_Warp1/z_door_warp1.h"
#include "soh/frame_interpolation.h"
#define FLAGS (ACTOR_FLAG_0 | ACTOR_FLAG_2 | ACTOR_FLAG_4 | ACTOR_FLAG_5 | ACTOR_FLAG_10)
@ -2705,6 +2706,8 @@ s32 BossSst_OverrideHandTrailDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx**
void BossSst_DrawHand(Actor* thisx, GlobalContext* globalCtx) {
BossSst* this = (BossSst*)thisx;
static s32 epoch = 0;
epoch++;
OPEN_DISPS(globalCtx->state.gfxCtx);
@ -2738,6 +2741,8 @@ void BossSst_DrawHand(Actor* thisx, GlobalContext* globalCtx) {
for (i = 0; i < end; i++) {
if (Math3D_Vec3fDistSq(&trail2->world.pos, &trail->world.pos) > 900.0f) {
FrameInterpolation_RecordOpenChild(trail, 0);
Matrix_SetTranslateRotateYXZ(trail->world.pos.x, trail->world.pos.y, trail->world.pos.z,
&trail->world.rot);
Matrix_Scale(0.02f, 0.02f, 0.02f, MTXMODE_APPLY);
@ -2749,6 +2754,8 @@ void BossSst_DrawHand(Actor* thisx, GlobalContext* globalCtx) {
POLY_XLU_DISP = SkelAnime_DrawFlex(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable,
this->skelAnime.dListCount, BossSst_OverrideHandTrailDraw, NULL,
trail, POLY_XLU_DISP);
FrameInterpolation_RecordCloseChild();
}
idx = (idx + 5) % 7;
trail2 = trail;
@ -2955,6 +2962,8 @@ void BossSst_SpawnHeadShadow(BossSst* this) {
shadow->scale = 1450;
shadow->alpha = 254;
shadow->status = 65;
shadow->epoch++;
}
this->effects[3].status = -1;
@ -2968,6 +2977,7 @@ void BossSst_SpawnHandShadow(BossSst* this) {
this->effects[0].scale = 2300;
this->effects[0].alpha = 254;
this->effects[0].status = 5;
this->effects[0].epoch++;
this->effects[1].status = -1;
}
@ -2981,6 +2991,7 @@ void BossSst_SpawnShockwave(BossSst* this) {
for (i = 0; i < 3; i++) {
BossSstEffect* shockwave = &this->effects[i];
shockwave->epoch++;
Math_Vec3f_Copy(&shockwave->pos, &this->actor.world.pos);
shockwave->move = (i + 9) * 2;
@ -3035,6 +3046,8 @@ void BossSst_SpawnIceCrystal(BossSst* this, s32 index) {
if ((index % 2) == 0) {
Audio_PlayActorSound2(&this->actor, NA_SE_PL_FREEZE_S);
}
ice->epoch++;
}
void BossSst_SpawnIceShard(BossSst* this) {
@ -3050,6 +3063,7 @@ void BossSst_SpawnIceShard(BossSst* this) {
for (i = 0; i < 18; i++) {
BossSstEffect* ice = &this->effects[i];
ice->epoch++;
Math_Vec3f_Copy(&ice->pos, &spawnPos);
ice->status = 1;
@ -3165,6 +3179,8 @@ void BossSst_DrawEffect(Actor* thisx, GlobalContext* globalCtx) {
for (i = 0; i < 18; i++) {
effect = &this->effects[i];
FrameInterpolation_RecordOpenChild(effect, effect->epoch);
if (effect->move) {
func_8003435C(&effect->pos, globalCtx);
if (this->effects[0].status != 0) {
@ -3182,6 +3198,8 @@ void BossSst_DrawEffect(Actor* thisx, GlobalContext* globalCtx) {
G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
gSPDisplayList(POLY_XLU_DISP++, gBongoIceShardDL);
}
FrameInterpolation_RecordCloseChild();
}
} else if (this->effectMode == BONGO_SHOCKWAVE) {
f32 scaleY = 0.005f;
@ -3193,6 +3211,7 @@ void BossSst_DrawEffect(Actor* thisx, GlobalContext* globalCtx) {
for (i = 0; i < 3; i++, scaleY -= 0.001f) {
effect = &this->effects[i];
FrameInterpolation_RecordOpenChild(effect, effect->epoch);
if (effect->move != 0) {
Matrix_Translate(effect->pos.x, effect->pos.y, effect->pos.z, MTXMODE_NEW);
@ -3205,6 +3224,8 @@ void BossSst_DrawEffect(Actor* thisx, GlobalContext* globalCtx) {
G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
gSPDisplayList(POLY_XLU_DISP++, gEffFireCircleDL);
}
FrameInterpolation_RecordCloseChild();
}
} else if (this->effectMode == BONGO_SHADOW) {
gDPSetPrimColor(POLY_XLU_DISP++, 0x00, 0x80, 10, 10, 80, 0);
@ -3212,12 +3233,16 @@ void BossSst_DrawEffect(Actor* thisx, GlobalContext* globalCtx) {
effect = &this->effects[0];
while (effect->status != -1) {
FrameInterpolation_RecordOpenChild(effect, effect->epoch);
Matrix_Translate(effect->pos.x, effect->pos.y, effect->pos.z, MTXMODE_NEW);
Matrix_Scale(effect->scale * 0.001f, 1.0f, effect->scale * 0.001f, MTXMODE_APPLY);
gSPMatrix(POLY_XLU_DISP++, MATRIX_NEWMTX(globalCtx->state.gfxCtx),
G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
gSPDisplayList(POLY_XLU_DISP++, sShadowDList);
FrameInterpolation_RecordCloseChild();
effect++;
}
}

View File

@ -17,7 +17,8 @@ typedef struct {
/* 0x0020 */ s16 move;
/* 0x0022 */ s16 status;
/* 0x0024 */ u8 alpha;
} BossSstEffect; // size = 0x28
/* 0x0028 */ s32 epoch;
} BossSstEffect; // size = 0x2C
typedef struct {
/* 0x0000 */ PosRot world;

View File

@ -2,6 +2,7 @@
#include "objects/gameplay_keep/gameplay_keep.h"
#include "objects/object_tw/object_tw.h"
#include "overlays/actors/ovl_Door_Warp1/z_door_warp1.h"
#include "soh/frame_interpolation.h"
#include <string.h>
@ -467,6 +468,7 @@ void BossTw_Init(Actor* thisx, GlobalContext* globalCtx2) {
for (i = 0; i < ARRAY_COUNT(sTwEffects); i++) {
sTwEffects[i].type = TWEFF_NONE;
sTwEffects[i].epoch++;
}
}
@ -3327,6 +3329,8 @@ void func_80942180(BossTw* this, GlobalContext* globalCtx) {
void func_809426F0(BossTw* this, GlobalContext* globalCtx) {
s32 pad;
s16 i;
static s32 epoch = 0;
epoch++;
OPEN_DISPS(globalCtx->state.gfxCtx);
@ -3360,6 +3364,8 @@ void func_809426F0(BossTw* this, GlobalContext* globalCtx) {
}
for (i = 0; i < 8; i++) {
FrameInterpolation_RecordOpenChild("Twinrova 809426F0", epoch + i * 25);
Matrix_Push();
Matrix_Translate(0.0f, 0.0f, 5000.0f, MTXMODE_APPLY);
Matrix_RotateZ(((i * M_PI) * 2.0f * 0.125f) + this->flameRotation, MTXMODE_APPLY);
@ -3373,6 +3379,8 @@ void func_809426F0(BossTw* this, GlobalContext* globalCtx) {
G_MTX_LOAD | G_MTX_MODELVIEW | G_MTX_NOPUSH);
gSPDisplayList(POLY_XLU_DISP++, SEGMENTED_TO_VIRTUAL(object_tw_DL_01A430));
Matrix_Pop();
FrameInterpolation_RecordCloseChild();
}
CLOSE_DISPS(globalCtx->state.gfxCtx);
@ -4410,6 +4418,8 @@ void BossTw_BlastDraw(Actor* thisx, GlobalContext* globalCtx2) {
f32 scaleFactor;
s16 tailIdx;
s16 i;
static s32 epoch = 0;
epoch++;
OPEN_DISPS(globalCtx->state.gfxCtx);
@ -4420,6 +4430,8 @@ void BossTw_BlastDraw(Actor* thisx, GlobalContext* globalCtx2) {
gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, 200, 20, 0, (s8)this->workf[TAIL_ALPHA]);
gDPSetEnvColor(POLY_XLU_DISP++, 255, 215, 255, 128);
for (i = 9; i >= 0; i--) {
FrameInterpolation_RecordOpenChild("Twinrova Fire Blast", epoch + i * 25);
gSPSegment(POLY_XLU_DISP++, 8,
Gfx_TwoTexScroll(
globalCtx->state.gfxCtx, 0, ((this->work[CS_TIMER_1] * 3) + (i * 10)) & 0x7F,
@ -4434,6 +4446,8 @@ void BossTw_BlastDraw(Actor* thisx, GlobalContext* globalCtx2) {
gSPMatrix(POLY_XLU_DISP++, MATRIX_NEWMTX(globalCtx->state.gfxCtx),
G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
gSPDisplayList(POLY_XLU_DISP++, SEGMENTED_TO_VIRTUAL(object_tw_DL_01A430));
FrameInterpolation_RecordCloseChild();
}
break;
@ -4444,6 +4458,8 @@ void BossTw_BlastDraw(Actor* thisx, GlobalContext* globalCtx2) {
gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, 195, 225, 235, (s8)this->workf[TAIL_ALPHA]);
gSPDisplayList(POLY_XLU_DISP++, SEGMENTED_TO_VIRTUAL(object_tw_DL_01A998));
for (i = 9; i >= 0; i--) {
FrameInterpolation_RecordOpenChild("Twinrova Ice Blast", epoch + i * 25);
gSPSegment(POLY_XLU_DISP++, 8,
Gfx_TwoTexScroll(
globalCtx->state.gfxCtx, 0, ((this->work[CS_TIMER_1] * 3) + (i * 0xA)) & 0x7F,
@ -4458,6 +4474,8 @@ void BossTw_BlastDraw(Actor* thisx, GlobalContext* globalCtx2) {
gSPMatrix(POLY_XLU_DISP++, MATRIX_NEWMTX(globalCtx->state.gfxCtx),
G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
gSPDisplayList(POLY_XLU_DISP++, SEGMENTED_TO_VIRTUAL(object_tw_DL_01AB00));
FrameInterpolation_RecordCloseChild();
}
break;
@ -4474,6 +4492,8 @@ void BossTw_DrawDeathBall(Actor* thisx, GlobalContext* globalCtx2) {
f32 scaleFactor;
s16 tailIdx;
s16 i;
static s32 epoch = 0;
epoch++;
OPEN_DISPS(globalCtx->state.gfxCtx);
@ -4484,6 +4504,8 @@ void BossTw_DrawDeathBall(Actor* thisx, GlobalContext* globalCtx2) {
gDPSetEnvColor(POLY_XLU_DISP++, 255, 215, 255, 128);
for (i = 9; i >= 0; i--) {
FrameInterpolation_RecordOpenChild("Twinrova Death Ball 0", epoch + i * 25);
gSPSegment(POLY_XLU_DISP++, 8,
Gfx_TwoTexScroll(globalCtx->state.gfxCtx, 0, (((this->work[CS_TIMER_1] * 3) + (i * 0xA))) & 0x7F,
(u8)((-this->work[CS_TIMER_1] * 0xF) + (i * 50)), 0x20, 0x40, 1, 0, 0, 0x20,
@ -4498,12 +4520,16 @@ void BossTw_DrawDeathBall(Actor* thisx, GlobalContext* globalCtx2) {
gSPMatrix(POLY_XLU_DISP++, MATRIX_NEWMTX(globalCtx->state.gfxCtx),
G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
gSPDisplayList(POLY_XLU_DISP++, SEGMENTED_TO_VIRTUAL(object_tw_DL_01A430));
FrameInterpolation_RecordCloseChild();
}
} else {
gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, 195, 225, 235, (s8)this->workf[TAIL_ALPHA]);
gSPDisplayList(POLY_XLU_DISP++, SEGMENTED_TO_VIRTUAL(object_tw_DL_01A998));
for (i = 9; i >= 0; i--) {
FrameInterpolation_RecordOpenChild("Twinrova Death Ball 1", epoch + i * 25);
gSPSegment(POLY_XLU_DISP++, 8,
Gfx_TwoTexScroll(globalCtx->state.gfxCtx, 0, (((this->work[CS_TIMER_1] * 3) + (i * 0xA))) & 0x7F,
(u8)((-this->work[CS_TIMER_1] * 0xF) + (i * 50)), 0x20, 0x40, 1, 0, 0, 0x20,
@ -4518,6 +4544,8 @@ void BossTw_DrawDeathBall(Actor* thisx, GlobalContext* globalCtx2) {
gSPMatrix(POLY_XLU_DISP++, MATRIX_NEWMTX(globalCtx->state.gfxCtx),
G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
gSPDisplayList(POLY_XLU_DISP++, SEGMENTED_TO_VIRTUAL(object_tw_DL_01AB00));
FrameInterpolation_RecordCloseChild();
}
}
@ -4883,6 +4911,8 @@ void BossTw_DrawEffects(GlobalContext* globalCtx) {
for (i = 0; i < ARRAY_COUNT(sTwEffects); i++) {
if (currentEffect->type == 1) {
FrameInterpolation_RecordOpenChild(currentEffect, currentEffect->epoch);
if (sp18F == 0) {
gSPDisplayList(POLY_XLU_DISP++, object_tw_DL_01A528);
sp18F++;
@ -4896,8 +4926,9 @@ void BossTw_DrawEffects(GlobalContext* globalCtx) {
gSPMatrix(POLY_XLU_DISP++, MATRIX_NEWMTX(gfxCtx),
G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
gSPDisplayList(POLY_XLU_DISP++, object_tw_DL_01A5A8);
}
FrameInterpolation_RecordCloseChild();
}
currentEffect++;
}
@ -4906,6 +4937,8 @@ void BossTw_DrawEffects(GlobalContext* globalCtx) {
for (i = 0; i < ARRAY_COUNT(sTwEffects); i++) {
if (currentEffect->type == 3) {
FrameInterpolation_RecordOpenChild(currentEffect, currentEffect->epoch);
if (sp18F == 0) {
gSPDisplayList(POLY_XLU_DISP++, SEGMENTED_TO_VIRTUAL(object_tw_DL_01A998));
sp18F++;
@ -4921,6 +4954,8 @@ void BossTw_DrawEffects(GlobalContext* globalCtx) {
gSPMatrix(POLY_XLU_DISP++, MATRIX_NEWMTX(gfxCtx),
G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
gSPDisplayList(POLY_XLU_DISP++, SEGMENTED_TO_VIRTUAL(object_tw_DL_01AB00));
FrameInterpolation_RecordCloseChild();
}
currentEffect++;
}
@ -4930,6 +4965,8 @@ void BossTw_DrawEffects(GlobalContext* globalCtx) {
for (i = 0; i < ARRAY_COUNT(sTwEffects); i++) {
if (currentEffect->type == 2) {
FrameInterpolation_RecordOpenChild(currentEffect, currentEffect->epoch);
if (sp18F == 0) {
gDPPipeSync(POLY_XLU_DISP++);
gDPSetEnvColor(POLY_XLU_DISP++, 255, 215, 255, 128);
@ -4946,6 +4983,8 @@ void BossTw_DrawEffects(GlobalContext* globalCtx) {
gSPMatrix(POLY_XLU_DISP++, MATRIX_NEWMTX(gfxCtx),
G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
gSPDisplayList(POLY_XLU_DISP++, SEGMENTED_TO_VIRTUAL(object_tw_DL_01A430));
FrameInterpolation_RecordCloseChild();
}
currentEffect++;
@ -4956,6 +4995,8 @@ void BossTw_DrawEffects(GlobalContext* globalCtx) {
for (i = 0; i < ARRAY_COUNT(sTwEffects); i++) {
if (currentEffect->type == 4) {
FrameInterpolation_RecordOpenChild(currentEffect, currentEffect->epoch);
if (sp18F == 0) {
sp18F++;
}
@ -4991,6 +5032,8 @@ void BossTw_DrawEffects(GlobalContext* globalCtx) {
gDPSetRenderMode(POLY_XLU_DISP++, G_RM_PASS, G_RM_AA_ZB_XLU_SURF2);
gSPClearGeometryMode(POLY_XLU_DISP++, G_CULL_BACK | G_FOG);
gSPDisplayList(POLY_XLU_DISP++, SEGMENTED_TO_VIRTUAL(object_tw_DL_01A790));
FrameInterpolation_RecordCloseChild();
}
currentEffect++;
@ -5004,6 +5047,8 @@ void BossTw_DrawEffects(GlobalContext* globalCtx) {
Vec3f off;
if (currentEffect->type == TWEFF_PLYR_FRZ) {
FrameInterpolation_RecordOpenChild(currentEffect, currentEffect->epoch);
if (sp18F == 0) {
gSPDisplayList(POLY_XLU_DISP++, SEGMENTED_TO_VIRTUAL(object_tw_DL_01AA50));
gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, 195, 225, 235, 255);
@ -5037,6 +5082,8 @@ void BossTw_DrawEffects(GlobalContext* globalCtx) {
G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
gSPDisplayList(POLY_XLU_DISP++, SEGMENTED_TO_VIRTUAL(object_tw_DL_01AB00));
}
FrameInterpolation_RecordCloseChild();
}
currentEffect++;
@ -5047,6 +5094,8 @@ void BossTw_DrawEffects(GlobalContext* globalCtx) {
for (i = 0; i < ARRAY_COUNT(sTwEffects); i++) {
if (currentEffect->type >= 6) {
FrameInterpolation_RecordOpenChild(currentEffect, currentEffect->epoch);
if (currentEffect->work[EFF_ARGS] == 0) {
gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, 195, 225, 235, currentEffect->alpha);
gSPDisplayList(POLY_XLU_DISP++, SEGMENTED_TO_VIRTUAL(object_tw_DL_01A998));
@ -5070,6 +5119,8 @@ void BossTw_DrawEffects(GlobalContext* globalCtx) {
} else {
gSPDisplayList(POLY_XLU_DISP++, SEGMENTED_TO_VIRTUAL(object_tw_DL_01A430));
}
FrameInterpolation_RecordCloseChild();
}
currentEffect++;

View File

@ -43,6 +43,7 @@ typedef struct {
/* 0x002E */ s16 work[EFF_WORK_MAX];
/* 0x0034 */ f32 workf[EFF_FWORK_MAX];
/* 0x0044 */ Actor* target;
s32 epoch;
} BossTwEffect;
typedef enum {

View File

@ -4006,6 +4006,8 @@ void BossVa_DrawDoor(GlobalContext* globalCtx, s16 scale) {
f32 yScale;
f32 segAngle = 0.0f;
s32 i;
static s32 epoch = 0;
epoch++;
OPEN_DISPS(globalCtx->state.gfxCtx);
@ -4023,6 +4025,8 @@ void BossVa_DrawDoor(GlobalContext* globalCtx, s16 scale) {
Matrix_Get(&doorMtx);
for (i = 0; i < 8; i++, segAngle -= M_PI / 4) {
FrameInterpolation_RecordOpenChild("Barinade Door", epoch + i * 25);
Matrix_Put(&doorMtx);
Matrix_RotateZ(segAngle, MTXMODE_APPLY);
Matrix_Translate(0.0f, doorPieceLength[i] * yScale, 0.0f, MTXMODE_APPLY);
@ -4030,6 +4034,8 @@ void BossVa_DrawDoor(GlobalContext* globalCtx, s16 scale) {
gSPMatrix(POLY_OPA_DISP++, MATRIX_NEWMTX(globalCtx->state.gfxCtx),
G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
gSPDisplayList(POLY_OPA_DISP++, doorPieceDispList[i]);
FrameInterpolation_RecordCloseChild();
}
CLOSE_DISPS(globalCtx->state.gfxCtx);

View File

@ -10,6 +10,7 @@
#include "objects/object_demo_6k/object_demo_6k.h"
#include "objects/object_gnd_magic/object_gnd_magic.h"
#include "overlays/actors/ovl_Eff_Dust/z_eff_dust.h"
#include "soh/frame_interpolation.h"
#define FLAGS ACTOR_FLAG_4
@ -563,9 +564,10 @@ void func_80967FFC(Actor* thisx, GlobalContext* globalCtx) {
Demo6K* this = (Demo6K*)thisx;
s32 pad;
u16 timer1 = this->timer1;
static s32 epoch = 0;
epoch++;
OPEN_DISPS(globalCtx->state.gfxCtx);
func_80093D84(globalCtx->state.gfxCtx);
Matrix_RotateX(-M_PI / 2, MTXMODE_APPLY);
gSPSegment(POLY_XLU_DISP++, 0x08,
@ -584,6 +586,8 @@ void func_80967FFC(Actor* thisx, GlobalContext* globalCtx) {
Matrix_RotateZ(-M_PI / 2, MTXMODE_APPLY);
for (i = 0; i < 6; i++) {
FrameInterpolation_RecordOpenChild("Demo6K 80967FFC", epoch + i * 25);
Matrix_RotateZ(M_PI / 3, MTXMODE_APPLY);
gSPMatrix(POLY_XLU_DISP++, MATRIX_NEWMTX(globalCtx->state.gfxCtx),
G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
@ -591,6 +595,8 @@ void func_80967FFC(Actor* thisx, GlobalContext* globalCtx) {
gDPSetPrimColor(POLY_XLU_DISP++, 0, 0x80, colors[i][0].r, colors[i][0].g, colors[i][0].b, 255);
gDPSetEnvColor(POLY_XLU_DISP++, colors[i][1].r, colors[i][1].g, colors[i][1].b, 255);
gSPDisplayList(POLY_XLU_DISP++, object_demo_6k_DL_0022B0);
FrameInterpolation_RecordCloseChild();
}
// required to avoid optimizing out i
@ -689,6 +695,8 @@ void func_809688C4(Actor* thisx, GlobalContext* globalCtx2) {
GlobalContext* globalCtx = globalCtx2;
u32 frames = globalCtx->state.frames;
s32 i;
static s32 epoch = 0;
epoch++;
if ((i = (globalCtx->csCtx.state != CS_STATE_IDLE) && (globalCtx->csCtx.npcActions[1] != NULL)) &&
(globalCtx->csCtx.npcActions[1]->action != 1)) {
@ -699,6 +707,8 @@ void func_809688C4(Actor* thisx, GlobalContext* globalCtx2) {
Matrix_RotateY((s16)(Camera_GetCamDirYaw(GET_ACTIVE_CAM(globalCtx)) + 0x8000) * (M_PI / 0x8000), MTXMODE_APPLY);
for (i = 0; i < 16; i++) {
FrameInterpolation_RecordOpenChild("Demo6K 809688C4", epoch + i * 25);
gDPPipeSync(POLY_XLU_DISP++);
gDPSetEnvColor(POLY_XLU_DISP++, sEnvColors[this->unk_274[i]].r, sEnvColors[this->unk_274[i]].g,
sEnvColors[this->unk_274[i]].b, 255);
@ -712,6 +722,8 @@ void func_809688C4(Actor* thisx, GlobalContext* globalCtx2) {
G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
gSPDisplayList(POLY_XLU_DISP++, gEffFlash1DL);
Matrix_Pop();
FrameInterpolation_RecordCloseChild();
}
gSPDisplayList(POLY_XLU_DISP++, gEffFlash1DL);

View File

@ -3,6 +3,7 @@
#include "objects/gameplay_keep/gameplay_keep.h"
#include "objects/object_efc_star_field/object_efc_star_field.h"
#include "objects/object_toki_objects/object_toki_objects.h"
#include "soh/frame_interpolation.h"
#define FLAGS (ACTOR_FLAG_4 | ACTOR_FLAG_5)
@ -521,6 +522,8 @@ void DemoKankyo_DrawRain(Actor* thisx, GlobalContext* globalCtx) {
f32 translateY;
f32 translateZ;
s16 j;
static s32 epoch = 0;
epoch++;
OPEN_DISPS(globalCtx->state.gfxCtx);
@ -594,6 +597,8 @@ void DemoKankyo_DrawRain(Actor* thisx, GlobalContext* globalCtx) {
Matrix_Scale(sRainScale * 0.001f, sRainScale * 0.001f, sRainScale * 0.001f, MTXMODE_APPLY);
for (j = 0; j < 5; j++) {
FrameInterpolation_RecordOpenChild("Kankyo Rain", epoch + i * j * 25);
s32 pad1;
if (globalCtx->sceneNum != SCENE_TOKINOMA) {
@ -623,6 +628,8 @@ void DemoKankyo_DrawRain(Actor* thisx, GlobalContext* globalCtx) {
G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
POLY_XLU_DISP = Gfx_CallSetupDL(POLY_XLU_DISP, 0x14);
gSPDisplayList(POLY_XLU_DISP++, object_efc_star_field_DL_000080);
FrameInterpolation_RecordCloseChild();
}
}
CLOSE_DISPS(globalCtx->state.gfxCtx);
@ -656,10 +663,14 @@ void DemoKankyo_DrawClouds(Actor* thisx, GlobalContext* globalCtx) {
f32 dx;
f32 dy;
f32 dz;
static s32 epoch = 0;
epoch++;
OPEN_DISPS(globalCtx->state.gfxCtx);
for (i = 0; i < 30; i++) {
FrameInterpolation_RecordOpenChild("Kankyo Clouds", epoch + i * 25);
dx = -(Math_SinS(this->unk_150[i].unk_20 - 0x8000) * 120.0f) * (30.0f + (i / 30.0f) * 10.0f);
dy = Math_CosS(this->unk_150[i].unk_20 - 0x8000) * 5.0f + 1200.0f;
dz = (Math_CosS(this->unk_150[i].unk_20 - 0x8000) * 120.0f) * (30.0f + (i / 30.0f) * 10.0f);
@ -681,6 +692,8 @@ void DemoKankyo_DrawClouds(Actor* thisx, GlobalContext* globalCtx) {
gSPMatrix(POLY_XLU_DISP++, SEG_ADDR(1, 0), G_MTX_NOPUSH | G_MTX_MUL | G_MTX_MODELVIEW);
gSPDisplayList(POLY_XLU_DISP++, gEffDustDL);
FrameInterpolation_RecordCloseChild();
}
CLOSE_DISPS(globalCtx->state.gfxCtx);
@ -771,6 +784,8 @@ void DemoKankyo_DrawWarpSparkles(Actor* thisx, GlobalContext* globalCtx) {
f32 translateZ;
PosRot posRot;
u8 linkAge = gSaveContext.linkAge;
static s32 epoch = 0;
epoch++;
OPEN_DISPS(globalCtx->state.gfxCtx);
@ -778,6 +793,8 @@ void DemoKankyo_DrawWarpSparkles(Actor* thisx, GlobalContext* globalCtx) {
this->sparkleCounter += 2;
}
for (i = this->sparkleCounter - 1; i >= 0; i--) {
FrameInterpolation_RecordOpenChild("Kankyo Warp Sparkles", epoch + i * 25);
temp_f22 = 1.0f - (i / (f32)this->sparkleCounter);
switch (this->unk_150[i].unk_22) {
@ -891,6 +908,8 @@ void DemoKankyo_DrawWarpSparkles(Actor* thisx, GlobalContext* globalCtx) {
gSPDisplayList(POLY_XLU_DISP++, disp);
this->unk_150[i].unk_24 += 0x190;
}
FrameInterpolation_RecordCloseChild();
}
CLOSE_DISPS(globalCtx->state.gfxCtx);
@ -914,6 +933,8 @@ void DemoKankyo_DrawSparkles(Actor* thisx, GlobalContext* globalCtx) {
f32 scale;
s16 i;
PosRot posRot;
static s32 epoch = 0;
epoch++;
OPEN_DISPS(globalCtx->state.gfxCtx);
@ -922,6 +943,8 @@ void DemoKankyo_DrawSparkles(Actor* thisx, GlobalContext* globalCtx) {
}
for (i = this->sparkleCounter - 1; i >= 0; i--) {
FrameInterpolation_RecordOpenChild("Kankyo Sparkles", epoch + i * 25);
temp_f20 = 1.0f - (i / (f32)this->sparkleCounter);
switch (this->unk_150[i].unk_22) {
@ -993,6 +1016,8 @@ void DemoKankyo_DrawSparkles(Actor* thisx, GlobalContext* globalCtx) {
gSPDisplayList(POLY_XLU_DISP++, gEffFlash1DL);
this->unk_150[i].unk_24 += 0x190;
}
FrameInterpolation_RecordCloseChild();
}
CLOSE_DISPS(globalCtx->state.gfxCtx);

View File

@ -1,5 +1,6 @@
#include "z_efc_erupc.h"
#include "objects/object_efc_erupc/object_efc_erupc.h"
#include "soh/frame_interpolation.h"
#define FLAGS (ACTOR_FLAG_4 | ACTOR_FLAG_5)
@ -167,6 +168,8 @@ void EfcErupc_DrawParticles(EfcErupcParticles* particles, GlobalContext* globalC
OPEN_DISPS(gfxCtx);
for (i = 0; i < EFC_ERUPC_NUM_PARTICLES; i++, particles++) {
FrameInterpolation_RecordOpenChild(particles, particles->epoch);
if (particles->isActive) {
func_80093D84(globalCtx->state.gfxCtx);
gSPDisplayList(POLY_XLU_DISP++, object_efc_erupc_DL_002760);
@ -181,7 +184,10 @@ void EfcErupc_DrawParticles(EfcErupcParticles* particles, GlobalContext* globalC
G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
gSPDisplayList(POLY_XLU_DISP++, object_efc_erupc_DL_0027D8);
}
FrameInterpolation_RecordCloseChild();
}
CLOSE_DISPS(gfxCtx);
}
@ -249,5 +255,6 @@ void EfcErupc_InitParticles(EfcErupcParticles* particles) {
for (i = 0; i < EFC_ERUPC_NUM_PARTICLES; i++, particles++) {
particles->isActive = false;
particles->epoch++;
}
}

View File

@ -19,7 +19,8 @@ typedef struct {
/* 0x30 */ char unk_2C[4];
/* 0x34 */ f32 scale;
/* 0x38 */ char unk_34[8];
} EfcErupcParticles; // size 0x3C
/* 0x3C */ s32 epoch;
} EfcErupcParticles; // size 0x40
#define EFC_ERUPC_NUM_PARTICLES 100

View File

@ -6,6 +6,7 @@
#include "z_eff_dust.h"
#include "objects/gameplay_keep/gameplay_keep.h"
#include "soh/frame_interpolation.h"
#define FLAGS (ACTOR_FLAG_4 | ACTOR_FLAG_5)
@ -268,6 +269,8 @@ void EffDust_DrawFunc_8099E4F4(Actor* thisx, GlobalContext* globalCtx2) {
f32* distanceTraveled;
s32 i;
f32 aux;
static s32 epoch = 0;
epoch++;
OPEN_DISPS(gfxCtx);
@ -283,6 +286,8 @@ void EffDust_DrawFunc_8099E4F4(Actor* thisx, GlobalContext* globalCtx2) {
gSPSegment(POLY_XLU_DISP++, 0x08, sEmptyDL);
for (i = 0; i < 64; i++) {
FrameInterpolation_RecordOpenChild("Dust 8099E4F4", epoch + i * 25);
if (*distanceTraveled < 1.0f) {
aux = 1.0f - (*distanceTraveled * *distanceTraveled);
Matrix_Translate(this->actor.world.pos.x + (initialPositions->x * ((this->dx * aux) + (1.0f - this->dx))),
@ -298,6 +303,8 @@ void EffDust_DrawFunc_8099E4F4(Actor* thisx, GlobalContext* globalCtx2) {
gSPDisplayList(POLY_XLU_DISP++, SEGMENTED_TO_VIRTUAL(gEffSparklesDL));
}
FrameInterpolation_RecordCloseChild();
initialPositions++;
distanceTraveled++;
}
@ -314,6 +321,8 @@ void EffDust_DrawFunc_8099E784(Actor* thisx, GlobalContext* globalCtx2) {
s32 i;
f32 aux;
Player* player = GET_PLAYER(globalCtx);
static s32 epoch = 0;
epoch++;
OPEN_DISPS(gfxCtx);
@ -333,6 +342,8 @@ void EffDust_DrawFunc_8099E784(Actor* thisx, GlobalContext* globalCtx2) {
gSPSegment(POLY_XLU_DISP++, 0x08, sEmptyDL);
for (i = 0; i < 64; i++) {
FrameInterpolation_RecordOpenChild("Dust 8099E784", epoch + i * 25);
if (*distanceTraveled < 1.0f) {
gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, 255, 255, 255, *distanceTraveled * 255);
@ -357,6 +368,8 @@ void EffDust_DrawFunc_8099E784(Actor* thisx, GlobalContext* globalCtx2) {
gSPDisplayList(POLY_XLU_DISP++, SEGMENTED_TO_VIRTUAL(gEffSparklesDL));
}
FrameInterpolation_RecordCloseChild();
initialPositions++;
distanceTraveled++;
}

View File

@ -7,6 +7,7 @@
#include "z_en_anubice_fire.h"
#include "objects/gameplay_keep/gameplay_keep.h"
#include "objects/object_anubice/object_anubice.h"
#include "soh/frame_interpolation.h"
#define FLAGS ACTOR_FLAG_4
@ -62,6 +63,7 @@ void EnAnubiceFire_Init(Actor* thisx, GlobalContext* globalCtx) {
this->unk_15A = 30;
this->unk_154 = 2.0f;
this->scale = 0.0f;
this->epoch++;
for (i = 0; i < 6; i++) {
this->unk_160[i] = this->actor.world.pos;
@ -230,6 +232,8 @@ void EnAnubiceFire_Draw(Actor* thisx, GlobalContext* globalCtx) {
Matrix_Push();
for (i = this->unk_15E; i < 6; ++i) {
FrameInterpolation_RecordOpenChild(this, this->epoch + i * 25);
f32 scale = this->actor.scale.x - (i * 0.2f);
if (scale < 0.0f) {
@ -248,6 +252,8 @@ void EnAnubiceFire_Draw(Actor* thisx, GlobalContext* globalCtx) {
gSPDisplayList(POLY_XLU_DISP++, gAnubiceFireAttackDL);
}
FrameInterpolation_RecordCloseChild();
if (this->scale < 0.1f) {
break;
}

View File

@ -19,6 +19,7 @@ typedef struct EnAnubiceFire {
/* 0x015E */ s16 unk_15E;
/* 0x0178 */ Vec3f unk_160[6];
/* 0x01A8 */ ColliderCylinder cylinder;
} EnAnubiceFire; // size = 0x01F4
/* 0x01F4 */ s32 epoch;
} EnAnubiceFire; // size = 0x01F8
#endif

View File

@ -6,6 +6,7 @@
#include "z_en_ba.h"
#include "objects/object_bxa/object_bxa.h"
#include "soh/frame_interpolation.h"
#define FLAGS (ACTOR_FLAG_0 | ACTOR_FLAG_2 | ACTOR_FLAG_4)
@ -107,6 +108,7 @@ void EnBa_Init(Actor* thisx, GlobalContext* globalCtx) {
this->actor.targetMode = 4;
this->upperParams = (thisx->params >> 8) & 0xFF;
thisx->params &= 0xFF;
this->epoch++;
if (this->actor.params < EN_BA_DEAD_BLOB) {
if (Flags_GetSwitch(globalCtx, this->upperParams)) {
@ -489,6 +491,8 @@ void EnBa_Draw(Actor* thisx, GlobalContext* globalCtx) {
Gfx_TwoTexScroll(globalCtx->state.gfxCtx, 0, 0, 0, 16, 16, 1, 0,
(globalCtx->gameplayFrames * -10) % 128, 32, 32));
for (i = 0; i < 14; i++, mtx++) {
FrameInterpolation_RecordOpenChild(this, this->epoch + i * 25);
Matrix_Translate(this->unk158[i].x, this->unk158[i].y, this->unk158[i].z, MTXMODE_NEW);
Matrix_RotateZYX(this->unk2A8[i].x, this->unk2A8[i].y, this->unk2A8[i].z, MTXMODE_APPLY);
Matrix_Scale(this->unk200[i].x, this->unk200[i].y, this->unk200[i].z, MTXMODE_APPLY);
@ -504,6 +508,8 @@ void EnBa_Draw(Actor* thisx, GlobalContext* globalCtx) {
}
}
MATRIX_TOMTX(mtx);
FrameInterpolation_RecordCloseChild();
}
Matrix_Pop();
gSPMatrix(POLY_OPA_DISP++, MATRIX_NEWMTX(globalCtx->state.gfxCtx),

View File

@ -32,6 +32,7 @@ typedef struct EnBa {
/* 0x031C */ s16 unk31C;
/* 0x0320 */ ColliderJntSph collider;
/* 0x0340 */ ColliderJntSphElement colliderItems[2];
} EnBa; // size = 0x03C0
/* 0x03C0 */ s32 epoch;
} EnBa; // size = 0x03C4
#endif

View File

@ -6,6 +6,7 @@
#include "z_en_bx.h"
#include "objects/object_bxa/object_bxa.h"
#include "soh/frame_interpolation.h"
#define FLAGS ACTOR_FLAG_4
@ -103,6 +104,7 @@ void EnBx_Init(Actor* thisx, GlobalContext* globalCtx) {
Actor_Kill(&this->actor);
}
thisx->params &= 0xFF;
this->epoch++;
}
void EnBx_Destroy(Actor* thisx, GlobalContext* globalCtx) {
@ -235,10 +237,14 @@ void EnBx_Draw(Actor* thisx, GlobalContext* globalCtx) {
}
for (i = 0; i < 4; i++, mtx++) {
FrameInterpolation_RecordOpenChild(this, this->epoch + i * 25);
Matrix_Translate(this->unk_154[i].x, this->unk_154[i].y, this->unk_154[i].z, MTXMODE_NEW);
Matrix_RotateZYX(this->unk_1B4[i].x, this->unk_1B4[i].y, this->unk_1B4[i].z, MTXMODE_APPLY);
Matrix_Scale(this->unk_184[i].x, this->unk_184[i].y, this->unk_184[i].z, MTXMODE_APPLY);
MATRIX_TOMTX(mtx);
FrameInterpolation_RecordCloseChild();
}
gSPDisplayList(POLY_OPA_DISP++, object_bxa_DL_0022F0);

View File

@ -16,6 +16,7 @@ typedef struct EnBx {
/* 0x01B4 */ Vec3s unk_1B4[4];
/* 0x01CC */ ColliderCylinder collider;
/* 0x0218 */ ColliderQuad colliderQuad;
} EnBx; // size = 0x0298
/* 0x0298 */ s32 epoch;
} EnBx; // size = 0x029C
#endif

View File

@ -2,6 +2,8 @@
#include <string.h>
#include "soh/frame_interpolation.h"
#define FLAGS (ACTOR_FLAG_0 | ACTOR_FLAG_2 | ACTOR_FLAG_4 | ACTOR_FLAG_5)
void EnClearTag_Init(Actor* thisx, GlobalContext* globalCtx);
@ -278,6 +280,7 @@ void EnClearTag_Init(Actor* thisx, GlobalContext* globalCtx) {
globalCtx->specialEffects = &sClearTagEffects[0];
for (i = 0; i < CLEAR_TAG_EFFECT_MAX_COUNT; i++) {
sClearTagEffects[i].type = CLEAR_TAG_EFFECT_AVAILABLE;
sClearTagEffects[i].epoch++;
}
this->drawMode = CLEAR_TAG_DRAW_MODE_ALL;
}
@ -902,6 +905,8 @@ void EnClearTag_DrawEffects(GlobalContext* globalCtx) {
// Draw all Debris effects.
for (i = 0; i < CLEAR_TAG_EFFECT_MAX_COUNT; i++, effect++) {
FrameInterpolation_RecordOpenChild(effect, effect->epoch);
if (effect->type == CLEAR_TAG_EFFECT_DEBRIS) {
// Apply the debris effect material if it has not already been applied.
if (!isMaterialApplied) {
@ -918,6 +923,8 @@ void EnClearTag_DrawEffects(GlobalContext* globalCtx) {
G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
gSPDisplayList(POLY_OPA_DISP++, gArwingDebrisEffectDL);
}
FrameInterpolation_RecordCloseChild();
}
// Draw all ground flash effects.
@ -925,6 +932,8 @@ void EnClearTag_DrawEffects(GlobalContext* globalCtx) {
isMaterialApplied = false;
for (i = 0; i < CLEAR_TAG_EFFECT_MAX_COUNT; i++, effect++) {
if (effect->type == CLEAR_TAG_EFFECT_FLASH) {
FrameInterpolation_RecordOpenChild(effect, effect->epoch);
// Apply the flash ground effect material if it has not already been applied.
if (!isMaterialApplied) {
gDPPipeSync(POLY_XLU_DISP++);
@ -941,6 +950,8 @@ void EnClearTag_DrawEffects(GlobalContext* globalCtx) {
gSPMatrix(POLY_XLU_DISP++, MATRIX_NEWMTX(gfxCtx),
G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
gSPDisplayList(POLY_XLU_DISP++, gArwingFlashEffectGroundDL);
FrameInterpolation_RecordCloseChild();
}
}
@ -949,6 +960,8 @@ void EnClearTag_DrawEffects(GlobalContext* globalCtx) {
isMaterialApplied = false;
for (i = 0; i < CLEAR_TAG_EFFECT_MAX_COUNT; i++, effect++) {
if (effect->type == CLEAR_TAG_EFFECT_SMOKE) {
FrameInterpolation_RecordOpenChild(effect, effect->epoch);
// Apply the smoke effect material if it has not already been applied.
if (!isMaterialApplied) {
gSPDisplayList(POLY_XLU_DISP++, gArwingFireEffectMaterialDL);
@ -970,6 +983,8 @@ void EnClearTag_DrawEffects(GlobalContext* globalCtx) {
gSPMatrix(POLY_XLU_DISP++, MATRIX_NEWMTX(gfxCtx),
G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
gSPDisplayList(POLY_XLU_DISP++, gArwingFireEffectDL);
FrameInterpolation_RecordCloseChild();
}
}
@ -978,6 +993,8 @@ void EnClearTag_DrawEffects(GlobalContext* globalCtx) {
isMaterialApplied = false;
for (i = 0; i < CLEAR_TAG_EFFECT_MAX_COUNT; i++, effect++) {
if (effect->type == CLEAR_TAG_EFFECT_FIRE) {
FrameInterpolation_RecordOpenChild(effect, effect->epoch);
// Apply the fire effect material if it has not already been applied.
if (!isMaterialApplied) {
gSPDisplayList(POLY_XLU_DISP++, gArwingFireEffectMaterialDL);
@ -996,6 +1013,8 @@ void EnClearTag_DrawEffects(GlobalContext* globalCtx) {
gSPMatrix(POLY_XLU_DISP++, MATRIX_NEWMTX(gfxCtx),
G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
gSPDisplayList(POLY_XLU_DISP++, gArwingFireEffectDL);
FrameInterpolation_RecordCloseChild();
}
}
@ -1004,6 +1023,8 @@ void EnClearTag_DrawEffects(GlobalContext* globalCtx) {
isMaterialApplied = false;
for (i = 0; i < CLEAR_TAG_EFFECT_MAX_COUNT; i++, effect++) {
if (effect->type == CLEAR_TAG_EFFECT_FLASH) {
FrameInterpolation_RecordOpenChild(effect, effect->epoch);
// Apply the flash billboard effect material if it has not already been applied.
if (!isMaterialApplied) {
gDPPipeSync(POLY_XLU_DISP++);
@ -1019,6 +1040,8 @@ void EnClearTag_DrawEffects(GlobalContext* globalCtx) {
gSPMatrix(POLY_XLU_DISP++, MATRIX_NEWMTX(gfxCtx),
G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
gSPDisplayList(POLY_XLU_DISP++, gArwingFlashEffectDL);
FrameInterpolation_RecordCloseChild();
}
}

View File

@ -88,7 +88,8 @@ typedef struct EnClearTagEffect {
/* 0x0058 */ f32 rotationX;
/* 0x005C */ f32 floorHeight;
/* 0x0060 */ Vec3f floorTangent;
} EnClearTagEffect; // size = 0x6C
/* 0x006C */ s32 epoch;
} EnClearTagEffect; // size = 0x70
#define CLEAR_TAG_EFFECT_MAX_COUNT 100

View File

@ -2,6 +2,7 @@
#include "overlays/actors/ovl_En_Fire_Rock/z_en_fire_rock.h"
#include "vt.h"
#include "objects/object_efc_star_field/object_efc_star_field.h"
#include "soh/frame_interpolation.h"
#define FLAGS (ACTOR_FLAG_4 | ACTOR_FLAG_5)
@ -303,6 +304,7 @@ void EnEncount2_ParticleInit(EnEncount2* this, Vec3f* particlePos, f32 scale) {
particle->moveDirection.y = -20.0f;
particle->moveDirection.z = Rand_CenteredFloat(20.0f);
particle->isAlive = 1;
particle->epoch++;
break;
}
}
@ -354,6 +356,8 @@ void EnEncount2_ParticleDraw(Actor* thisx, GlobalContext* globalCtx) {
gSPSegment(POLY_OPA_DISP++, 0x06, globalCtx->objectCtx.status[objBankIndex].segment);
for (i = 0; i < ARRAY_COUNT(this->particles); particle++, i++) {
FrameInterpolation_RecordOpenChild(particle, particle->epoch);
if (particle->isAlive) {
Matrix_Translate(particle->pos.x, particle->pos.y, particle->pos.z, MTXMODE_NEW);
Matrix_RotateX(particle->rot.x * (M_PI / 180.0f), MTXMODE_APPLY);
@ -366,6 +370,8 @@ void EnEncount2_ParticleDraw(Actor* thisx, GlobalContext* globalCtx) {
G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
gSPDisplayList(POLY_OPA_DISP++, object_efc_star_field_DL_000DE0);
}
FrameInterpolation_RecordCloseChild();
}
}

View File

@ -14,7 +14,8 @@ typedef struct {
/* 0x0010 */ u8 isAlive;
/* 0x0014 */ Vec3f moveDirection;
/* 0x0020 */ Vec3f rot;
} EnEncount2Particle; // size = 0x2C
/* 0x002C */ s32 epoch;
} EnEncount2Particle; // size = 0x30
typedef struct EnEncount2 {
/* 0x0000 */ Actor actor;

View File

@ -7,6 +7,7 @@
#include "z_en_fd.h"
#include "objects/gameplay_keep/gameplay_keep.h"
#include "objects/object_fw/object_fw.h"
#include "soh/frame_interpolation.h"
#define FLAGS (ACTOR_FLAG_0 | ACTOR_FLAG_2 | ACTOR_FLAG_4 | ACTOR_FLAG_9)
@ -812,6 +813,7 @@ void EnFd_AddEffect(EnFd* this, u8 type, Vec3f* pos, Vec3f* velocity, Vec3f* acc
eff->color.a = 255;
eff->timer = (s16)(Rand_ZeroOne() * 10.0f);
}
eff->epoch++;
return;
}
}
@ -886,6 +888,8 @@ void EnFd_DrawFlames(EnFd* this, GlobalContext* globalCtx) {
func_80093D84(globalCtx->state.gfxCtx);
for (i = 0; i < ARRAY_COUNT(this->effects); i++, eff++) {
if (eff->type == FD_EFFECT_FLAME) {
FrameInterpolation_RecordOpenChild(eff, eff->epoch);
if (!firstDone) {
POLY_XLU_DISP = Gfx_CallSetupDL(POLY_XLU_DISP, 0);
gSPDisplayList(POLY_XLU_DISP++, gFlareDancerDL_7928);
@ -902,8 +906,11 @@ void EnFd_DrawFlames(EnFd* this, GlobalContext* globalCtx) {
idx = eff->timer * (8.0f / eff->initialTimer);
gSPSegment(POLY_XLU_DISP++, 0x8, SEGMENTED_TO_VIRTUAL(dustTextures[idx]));
gSPDisplayList(POLY_XLU_DISP++, gFlareDancerSquareParticleDL);
FrameInterpolation_RecordCloseChild();
}
}
CLOSE_DISPS(globalCtx->state.gfxCtx);
}
@ -919,6 +926,8 @@ void EnFd_DrawDots(EnFd* this, GlobalContext* globalCtx) {
for (i = 0; i < ARRAY_COUNT(this->effects); i++, eff++) {
if (eff->type == FD_EFFECT_DOT) {
FrameInterpolation_RecordOpenChild(eff, eff->epoch);
if (!firstDone) {
func_80093D84(globalCtx->state.gfxCtx);
gSPDisplayList(POLY_XLU_DISP++, gFlareDancerDL_79F8);
@ -933,6 +942,8 @@ void EnFd_DrawDots(EnFd* this, GlobalContext* globalCtx) {
gSPMatrix(POLY_XLU_DISP++, MATRIX_NEWMTX(globalCtx->state.gfxCtx),
G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
gSPDisplayList(POLY_XLU_DISP++, gFlareDancerTriangleParticleDL);
FrameInterpolation_RecordCloseChild();
}
}

View File

@ -25,6 +25,7 @@ typedef struct {
/* 0x0014 */ Vec3f pos;
/* 0x0020 */ Vec3f velocity;
/* 0x002C */ Vec3f accel;
s32 epoch;
} EnFdEffect; // size = 0x38
typedef struct EnFd {

View File

@ -8,6 +8,7 @@
#include "objects/object_fw/object_fw.h"
#include "overlays/actors/ovl_En_Bom/z_en_bom.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_9)
@ -421,6 +422,7 @@ void EnFw_AddDust(EnFw* this, Vec3f* initialPos, Vec3f* initialSpeed, Vec3f* acc
eff->pos = *initialPos;
eff->accel = *accel;
eff->velocity = *initialSpeed;
eff->epoch++;
return;
}
}
@ -464,6 +466,8 @@ void EnFw_DrawDust(EnFw* this, GlobalContext* globalCtx) {
func_80093D84(globalCtx->state.gfxCtx);
for (i = 0; i < ARRAY_COUNT(this->effects); i++, eff++) {
FrameInterpolation_RecordOpenChild(eff, eff->epoch);
if (eff->type != 0) {
if (!firstDone) {
POLY_XLU_DISP = Gfx_CallSetupDL(POLY_XLU_DISP, 0U);
@ -484,6 +488,8 @@ void EnFw_DrawDust(EnFw* this, GlobalContext* globalCtx) {
gSPSegment(POLY_XLU_DISP++, 0x8, SEGMENTED_TO_VIRTUAL(dustTextures[idx]));
gSPDisplayList(POLY_XLU_DISP++, gFlareDancerSquareParticleDL);
}
FrameInterpolation_RecordCloseChild();
}
CLOSE_DISPS(globalCtx->state.gfxCtx);

View File

@ -19,6 +19,7 @@ typedef struct {
/* 0x0014 */ Vec3f pos;
/* 0x0020 */ Vec3f velocity;
/* 0x002C */ Vec3f accel;
s32 epoch;
} EnFwEffect;
typedef struct EnFw {

View File

@ -1,5 +1,6 @@
#include "z_en_fz.h"
#include "objects/object_fz/object_fz.h"
#include "soh/frame_interpolation.h"
#define FLAGS (ACTOR_FLAG_0 | ACTOR_FLAG_2 | ACTOR_FLAG_4 | ACTOR_FLAG_10)
@ -756,6 +757,7 @@ void EnFz_SpawnIceSmokeNoFreeze(EnFz* this, Vec3f* pos, Vec3f* velocity, Vec3f*
iceSmoke->xyScale = xyScale / 1000.0f;
iceSmoke->primAlpha = 0;
iceSmoke->timer = 0;
iceSmoke->epoch++;
break;
}
@ -780,6 +782,7 @@ void EnFz_SpawnIceSmokeFreeze(EnFz* this, Vec3f* pos, Vec3f* velocity, Vec3f* ac
iceSmoke->primAlpha = primAlpha;
iceSmoke->timer = 0;
iceSmoke->isTimerMod8 = isTimerMod8;
iceSmoke->epoch++;
break;
}
@ -864,6 +867,8 @@ void EnFz_DrawIceSmoke(EnFz* this, GlobalContext* globalCtx) {
func_80093D84(globalCtx->state.gfxCtx);
for (i = 0; i < ARRAY_COUNT(this->iceSmoke); i++) {
FrameInterpolation_RecordOpenChild(iceSmoke, iceSmoke->epoch);
if (iceSmoke->type > 0) {
gDPPipeSync(POLY_XLU_DISP++);
@ -884,6 +889,8 @@ void EnFz_DrawIceSmoke(EnFz* this, GlobalContext* globalCtx) {
gSPDisplayList(POLY_XLU_DISP++, SEGMENTED_TO_VIRTUAL(gFreezardSteamDL));
}
FrameInterpolation_RecordCloseChild();
iceSmoke++;
}

View File

@ -21,6 +21,7 @@ typedef struct {
/* 0x0030 */ f32 xyScale; //
/* 0x0034 */ f32 xyScaleTarget;
/* 0x0038 */ u8 isTimerMod8; // conditional, used to run CollisionCheck_SetAT
s32 epoch;
} EnFzEffectSsIceSmoke; // size = 0x3C
typedef struct EnFz {

View File

@ -12,6 +12,7 @@
#include "objects/gameplay_keep/gameplay_keep.h"
#include "objects/object_tsubo/object_tsubo.h"
#include "objects/object_gi_rupy/object_gi_rupy.h"
#include "soh/frame_interpolation.h"
#define FLAGS (ACTOR_FLAG_4 | ACTOR_FLAG_5)
@ -533,6 +534,7 @@ void EnGSwitch_SpawnEffects(EnGSwitch* this, Vec3f* pos, s16 scale, s16 colorIdx
f32 pitch;
f32 yaw;
effect->epoch++;
effect->pos = *pos;
effect->scale = scale;
effect->colorIdx = colorIdx;
@ -590,6 +592,7 @@ void EnGSwitch_DrawEffects(EnGSwitch* this, GlobalContext* globalCtx) {
func_80093D18(globalCtx->state.gfxCtx);
for (i = 0; i < this->numEffects; i++, effect++) {
if (effect->flag) {
FrameInterpolation_RecordOpenChild(effect, effect->epoch);
scale = effect->scale / 10000.0f;
Matrix_Translate(effect->pos.x, effect->pos.y, effect->pos.z, MTXMODE_NEW);
Matrix_Scale(scale, scale, scale, MTXMODE_APPLY);
@ -600,6 +603,7 @@ void EnGSwitch_DrawEffects(EnGSwitch* this, GlobalContext* globalCtx) {
G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
gSPSegment(POLY_OPA_DISP++, 0x08, SEGMENTED_TO_VIRTUAL(sRupeeTextures[effect->colorIdx]));
gSPDisplayList(POLY_OPA_DISP++, gRupeeDL);
FrameInterpolation_RecordCloseChild();
}
}
CLOSE_DISPS(gfxCtx);

View File

@ -32,6 +32,7 @@ typedef struct {
/* 0x12 */ u8 flag;
/* 0x14 */ Vec3f velocity;
/* 0x20 */ Vec3f rot;
s32 epoch;
} EnGSwitchEffect; // size = 0x2C
typedef struct EnGSwitch {

View File

@ -6,6 +6,7 @@
#include "z_en_gb.h"
#include "objects/object_ps/object_ps.h"
#include "soh/frame_interpolation.h"
#define FLAGS (ACTOR_FLAG_0 | ACTOR_FLAG_3)
@ -184,6 +185,7 @@ void EnGb_Init(Actor* thisx, GlobalContext* globalCtx) {
this->actionTimer = (s16)Rand_ZeroFloat(100.0f) + 100;
for (i = 0; i < ARRAY_COUNT(sCagedSoulPositions); i++) {
this->cagedSouls[i].epoch++;
this->cagedSouls[i].infoIdx = (s32)Rand_ZeroFloat(30.0f) % 3;
this->cagedSouls[i].unk_14.x = this->cagedSouls[i].translation.x =
sCagedSoulPositions[i].x + this->dyna.actor.world.pos.x;
@ -524,6 +526,7 @@ void EnGb_DrawCagedSouls(EnGb* this, GlobalContext* globalCtx) {
for (i = 0; i < 4; i++) {
s32 idx = this->cagedSouls[i].infoIdx;
FrameInterpolation_RecordOpenChild(&this->cagedSouls[i], this->cagedSouls[i].epoch);
gSPSegment(POLY_XLU_DISP++, 0x08,
Gfx_TwoTexScroll(globalCtx->state.gfxCtx, 0, 0, 0, 32, 64, 1, 0,
(u32)(sCagedSoulInfo[idx].timerMultiplier * this->frameTimer) % 512, 32, 128));
@ -548,6 +551,7 @@ void EnGb_DrawCagedSouls(EnGb* this, GlobalContext* globalCtx) {
gSPDisplayList(POLY_XLU_DISP++, gPoeSellerCagedSoulDL);
Matrix_Pop();
FrameInterpolation_RecordCloseChild();
}
CLOSE_DISPS(globalCtx->state.gfxCtx);

View File

@ -27,6 +27,7 @@ typedef struct {
/* 0x20 */ f32 unk_20;
/* 0x24 */ f32 unk_24;
/* 0x28 */ f32 unk_28;
s32 epoch;
} EnGbCagedSoul; // size = 0x2C
typedef struct EnGb {

View File

@ -2,6 +2,7 @@
#include "overlays/actors/ovl_En_Bom/z_en_bom.h"
#include "objects/gameplay_keep/gameplay_keep.h"
#include "objects/object_oF1d_map/object_oF1d_map.h"
#include "soh/frame_interpolation.h"
#define FLAGS (ACTOR_FLAG_0 | ACTOR_FLAG_3 | ACTOR_FLAG_4 | ACTOR_FLAG_5)
@ -1133,11 +1134,9 @@ void EnGo_Draw(Actor* thisx, GlobalContext* globalCtx) {
if (this->actionFunc == EnGo_CurledUp) {
EnGo_DrawCurledUp(this, globalCtx);
return; // needed for match?
} else if (this->actionFunc == EnGo_GoronLinkRolling || this->actionFunc == func_80A3FEB4 ||
this->actionFunc == EnGo_StopRolling || this->actionFunc == func_80A3FEB4) {
EnGo_DrawRolling(this, globalCtx);
return; // needed for match?
} else {
func_800943C8(globalCtx->state.gfxCtx);
@ -1146,9 +1145,9 @@ void EnGo_Draw(Actor* thisx, GlobalContext* globalCtx) {
SkelAnime_DrawFlexOpa(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable,
this->skelAnime.dListCount, EnGo_OverrideLimbDraw, EnGo_PostLimbDraw, &this->actor);
CLOSE_DISPS(globalCtx->state.gfxCtx);
EnGo_DrawDust(this, globalCtx);
}
CLOSE_DISPS(globalCtx->state.gfxCtx);
}
void EnGo_AddDust(EnGo* this, Vec3f* pos, Vec3f* velocity, Vec3f* accel, u8 initialTimer, f32 scale, f32 scaleStep) {
@ -1158,6 +1157,7 @@ void EnGo_AddDust(EnGo* this, Vec3f* pos, Vec3f* velocity, Vec3f* accel, u8 init
for (i = 0; i < ARRAY_COUNT(this->dustEffects); i++, dustEffect++) {
if (dustEffect->type != 1) {
dustEffect->epoch++;
dustEffect->scale = scale;
dustEffect->scaleStep = scaleStep;
timer = initialTimer;
@ -1218,6 +1218,7 @@ void EnGo_DrawDust(EnGo* this, GlobalContext* globalCtx) {
firstDone = true;
}
FrameInterpolation_RecordOpenChild(dustEffect, dustEffect->epoch);
alpha = dustEffect->timer * (255.0f / dustEffect->initialTimer);
gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, 170, 130, 90, alpha);
gDPPipeSync(POLY_XLU_DISP++);
@ -1230,6 +1231,7 @@ void EnGo_DrawDust(EnGo* this, GlobalContext* globalCtx) {
index = dustEffect->timer * (8.0f / dustEffect->initialTimer);
gSPSegment(POLY_XLU_DISP++, 0x08, SEGMENTED_TO_VIRTUAL(dustTex[index]));
gSPDisplayList(POLY_XLU_DISP++, gGoronDL_00FD50);
FrameInterpolation_RecordCloseChild();
}
}
CLOSE_DISPS(globalCtx->state.gfxCtx);

View File

@ -34,6 +34,7 @@ typedef struct {
/* 0x0014 */ Vec3f pos;
/* 0x0020 */ Vec3f velocity;
/* 0x002C */ Vec3f accel;
s32 epoch;
} EnGoEffect; // size = 0x38
typedef struct EnGo {

View File

@ -2,6 +2,7 @@
#include "overlays/actors/ovl_En_Bom/z_en_bom.h"
#include "objects/gameplay_keep/gameplay_keep.h"
#include "objects/object_oF1d_map/object_oF1d_map.h"
#include "soh/frame_interpolation.h"
#define FLAGS (ACTOR_FLAG_0 | ACTOR_FLAG_3 | ACTOR_FLAG_4 | ACTOR_FLAG_5)
@ -140,8 +141,6 @@ typedef enum {
/* 10 */ ENGO2_ANIM_10,
/* 11 */ ENGO2_ANIM_11,
/* 12 */ ENGO2_ANIM_12,
/* 13 */ ENGO2_ANIM_13, // Fixed Goron Wakeup Animation
/* 14 */ ENGO2_ANIM_14 // Fixed Biggoron Wakeup Animation
} EnGo2Animation;
static AnimationInfo sAnimationInfo[] = {
@ -151,8 +150,7 @@ static AnimationInfo sAnimationInfo[] = {
{ &gGoronAnim_002D80, 1.0f, 0.0f, -1.0f, 0x02, -8.0f }, { &gGoronAnim_00161C, 1.0f, 0.0f, -1.0f, 0x00, -8.0f },
{ &gGoronAnim_001A00, 1.0f, 0.0f, -1.0f, 0x00, -8.0f }, { &gGoronAnim_0021D0, 1.0f, 0.0f, -1.0f, 0x00, -8.0f },
{ &gGoronAnim_004930, 0.0f, 0.0f, -1.0f, 0x01, -8.0f }, { &gGoronAnim_000750, 1.0f, 0.0f, -1.0f, 0x00, -8.0f },
{ &gGoronAnim_000D5C, 1.0f, 0.0f, -1.0f, 0x00, -8.0f }, { &gGoronAnim_004930, 0.0f, 0.0f, -1.0f, 0x00, 0.0f },
{ &gGoronAnim_004930, 0.0f, 1.0f, -1.0f, 0x01, 0.0f },
{ &gGoronAnim_000D5C, 1.0f, 0.0f, -1.0f, 0x00, -8.0f },
};
static EnGo2DustEffectData sDustEffectData[2][4] = {
@ -179,6 +177,7 @@ void EnGo2_AddDust(EnGo2* this, Vec3f* pos, Vec3f* velocity, Vec3f* accel, u8 in
for (i = 0; i < ARRAY_COUNT(this->dustEffects); i++, dustEffect++) {
if (dustEffect->type != 1) {
dustEffect->epoch++;
dustEffect->scale = scale;
dustEffect->scaleStep = scaleStep;
timer = initialTimer;
@ -239,6 +238,7 @@ void EnGo2_DrawDust(EnGo2* this, GlobalContext* globalCtx) {
firstDone = true;
}
FrameInterpolation_RecordOpenChild(dustEffect, dustEffect->epoch);
alpha = dustEffect->timer * (255.0f / dustEffect->initialTimer);
gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, 170, 130, 90, alpha);
gDPPipeSync(POLY_XLU_DISP++);
@ -250,6 +250,7 @@ void EnGo2_DrawDust(EnGo2* this, GlobalContext* globalCtx) {
index = dustEffect->timer * (8.0f / dustEffect->initialTimer);
gSPSegment(POLY_XLU_DISP++, 0x08, SEGMENTED_TO_VIRTUAL(sDustTex[index]));
gSPDisplayList(POLY_XLU_DISP++, gGoronDL_00FD50);
FrameInterpolation_RecordCloseChild();
}
}
@ -1344,10 +1345,10 @@ void EnGo2_WakeUp(EnGo2* this, GlobalContext* globalCtx) {
}
if ((this->actor.params & 0x1F) == GORON_DMT_BIGGORON) {
OnePointCutscene_Init(globalCtx, 4200, -99, &this->actor, MAIN_CAM);
Animation_ChangeByInfo(&this->skelAnime, sAnimationInfo, ((CVar_GetS32("gGoronSpeen", 0) == 1) ? ENGO2_ANIM_10 : ENGO2_ANIM_14));
Animation_ChangeByInfo(&this->skelAnime, sAnimationInfo, ENGO2_ANIM_10);
this->skelAnime.playSpeed = 0.5f;
} else {
Animation_ChangeByInfo(&this->skelAnime, sAnimationInfo, ((CVar_GetS32("gGoronSpeen", 0) == 1) ? ENGO2_ANIM_1 : ENGO2_ANIM_13));
Animation_ChangeByInfo(&this->skelAnime, sAnimationInfo, ENGO2_ANIM_1);
this->skelAnime.playSpeed = 1.0f;
}
this->actionFunc = func_80A46B40;

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