Merge branch 'develop-zhora' into z-to-rn

This commit is contained in:
briaguya
2022-08-23 21:05:35 -04:00
73 changed files with 2501 additions and 1802 deletions
-1
View File
@@ -10,7 +10,6 @@
#include <string>
#include <vector>
#include "Resource.h"
//#include "Lib/StrHash64.h"
#include "StormLib.h"
+4 -2
View File
@@ -133,8 +133,6 @@ source_group("Source Files\\CustomImpl\\Utils" FILES ${Source_Files__CustomImpl_
set(Source_Files__Globals
"Cvar.cpp"
"Cvar.h"
"GlobalCtx2.cpp"
"GlobalCtx2.h"
"LUSMacros.h"
"Window.cpp"
"Window.h"
@@ -569,6 +567,10 @@ target_include_directories(${PROJECT_NAME} PRIVATE
if(MSVC)
if("${CMAKE_VS_PLATFORM_NAME}" STREQUAL "x64")
target_compile_options(${PROJECT_NAME} PRIVATE
$<$<CONFIG:Debug>:
/Od;
/Oi-
>
$<$<CONFIG:Release>:
/std:c++latest;
/Oi;
+1 -1
View File
@@ -1,12 +1,12 @@
#include "Console.h"
#include "Cvar.h"
#include "GlobalCtx2.h"
#include "ImGuiImpl.h"
#include "Lib/ImGui/imgui.h"
#include "Utils/StringHelper.h"
#include "Lib/ImGui/imgui_internal.h"
#include "Utils.h"
#include <sstream>
namespace Ship {
std::string BuildUsage(const CommandEntry& entry) {
-2
View File
@@ -6,8 +6,6 @@
#include <functional>
#include "Lib/ImGui/imgui.h"
#define NOGDI
#define WIN32_LEAN_AND_MEAN
#include "spdlog/spdlog.h"
namespace Ship {
+2 -2
View File
@@ -96,7 +96,7 @@ namespace Ship {
#define NESTED(key, ...) StringHelper::Sprintf("Controllers.%s.Slot_%d." key, device->GetGuid().c_str(), virtualSlot, __VA_ARGS__)
void ControlDeck::LoadControllerSettings() {
std::shared_ptr<Mercury> Config = GlobalCtx2::GetInstance()->GetConfig();
std::shared_ptr<Mercury> Config = Window::GetInstance()->GetConfig();
for (auto const& val : Config->rjson["Controllers"]["Deck"].items()) {
int32_t slot = std::stoi(val.key().substr(5));
@@ -182,7 +182,7 @@ namespace Ship {
}
void ControlDeck::SaveControllerSettings() {
std::shared_ptr<Mercury> Config = GlobalCtx2::GetInstance()->GetConfig();
std::shared_ptr<Mercury> Config = Window::GetInstance()->GetConfig();
for (size_t i = 0; i < virtualDevices.size(); i++) {
std::shared_ptr<Controller> backend = physicalDevices[virtualDevices[i]];
+4 -4
View File
@@ -5,7 +5,7 @@
#include <memory>
#include <utility>
#include <Utils/File.h>
#include "GlobalCtx2.h"
#include "Window.h"
std::map<std::string, std::unique_ptr<CVar>, std::less<>> cvars;
@@ -144,7 +144,7 @@ template <typename Numeric> bool is_number(const std::string& s) {
}
void CVar_LoadLegacy() {
auto cvarsConfig = Ship::GlobalCtx2::GetPathRelativeToAppDirectory("cvars.cfg");
auto cvarsConfig = Ship::Window::GetPathRelativeToAppDirectory("cvars.cfg");
if (File::Exists(cvarsConfig)) {
const auto lines = File::ReadAllLines(cvarsConfig);
@@ -191,7 +191,7 @@ void CVar_LoadLegacy() {
extern "C" void CVar_Load() {
std::shared_ptr<Mercury> pConf = Ship::GlobalCtx2::GetInstance()->GetConfig();
std::shared_ptr<Mercury> pConf = Ship::Window::GetInstance()->GetConfig();
pConf->reload();
for (const auto& item : pConf->rjson["CVars"].items()) {
@@ -235,7 +235,7 @@ extern "C" void CVar_Load() {
extern "C" void CVar_Save()
{
std::shared_ptr<Mercury> pConf = Ship::GlobalCtx2::GetInstance()->GetConfig();
std::shared_ptr<Mercury> pConf = Ship::Window::GetInstance()->GetConfig();
for (const auto& cvar : cvars) {
const std::string key = StringHelper::Sprintf("CVars.%s", cvar.first.c_str());
+2 -1
View File
@@ -2,7 +2,8 @@
#include <string>
#include <memory>
#include "GlobalCtx2.h"
#include <mutex>
#include <condition_variable>
namespace Ship {
class Archive;
+1 -1
View File
@@ -45,7 +45,7 @@ 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<Archive> base = Window::GetInstance()->GetResourceManager()->GetArchive();
std::shared_ptr<File> font = std::make_shared<File>();
base->LoadFile(path, false, font);
if (font->bIsLoaded) {
-149
View File
@@ -1,149 +0,0 @@
#include "GlobalCtx2.h"
#include <iostream>
#include <vector>
#include "ResourceMgr.h"
#include "Window.h"
#include "spdlog/async.h"
#include "spdlog/sinks/rotating_file_sink.h"
#include "spdlog/sinks/stdout_color_sinks.h"
#include "spdlog/sinks/sohconsole_sink.h"
#ifdef __APPLE__
#include "OSXFolderManager.h"
#elif defined(__SWITCH__)
#include "SwitchImpl.h"
#elif defined(__WIIU__)
#include "WiiUImpl.h"
#endif
namespace Ship {
std::weak_ptr<GlobalCtx2> GlobalCtx2::Context;
std::shared_ptr<GlobalCtx2> GlobalCtx2::GetInstance() {
return Context.lock();
}
std::shared_ptr<GlobalCtx2> GlobalCtx2::CreateInstance(const std::string& Name) {
if (Context.expired()) {
auto Shared = std::make_shared<GlobalCtx2>(Name);
Context = Shared;
Shared->InitWindow();
return Shared;
} else {
SPDLOG_DEBUG("Trying to create a context when it already exists.");
}
return GetInstance();
}
std::string GlobalCtx2::GetAppDirectoryPath() {
#ifdef __APPLE__
FolderManager folderManager;
std::string fpath = std::string(folderManager.pathForDirectory(NSApplicationSupportDirectory, NSUserDomainMask));
fpath.append("/com.shipofharkinian.soh");
return fpath;
#endif
return ".";
}
std::string GlobalCtx2::GetPathRelativeToAppDirectory(const char* path) {
return GlobalCtx2::GetAppDirectoryPath() + "/" + path;
}
GlobalCtx2::GlobalCtx2(std::string Name) : Name(std::move(Name)) {
}
GlobalCtx2::~GlobalCtx2() {
SPDLOG_INFO("destruct GlobalCtx2");
}
void GlobalCtx2::InitWindow() {
InitLogging();
Config = std::make_shared<Mercury>(GetPathRelativeToAppDirectory("shipofharkinian.json"));
MainPath = Config->getString("Game.Main Archive", GetPathRelativeToAppDirectory("oot.otr"));
PatchesPath = Config->getString("Game.Patches Archive", GetAppDirectoryPath() + "/mods");
ResMan = std::make_shared<ResourceMgr>(GetInstance(), MainPath, PatchesPath);
Win = std::make_shared<Window>(GetInstance());
if (!ResMan->DidLoadSuccessfully())
{
#ifdef _WIN32
MessageBox(nullptr, L"Main OTR file not found!", L"Uh oh", MB_OK);
#elif defined(__SWITCH__)
printf("Main OTR file not found!\n");
#elif defined(__WIIU__)
Ship::WiiU::ThrowMissingOTR(MainPath.c_str());
#else
SPDLOG_ERROR("Main OTR file not found!");
#endif
exit(1);
}
#ifdef __SWITCH__
Ship::Switch::Init(PostInitPhase);
#endif
}
void GlobalCtx2::InitLogging() {
try {
// Setup Logging
spdlog::init_thread_pool(8192, 1);
std::vector<spdlog::sink_ptr> Sinks;
auto SohConsoleSink = std::make_shared<spdlog::sinks::soh_sink_mt>();
SohConsoleSink->set_level(spdlog::level::trace);
Sinks.push_back(SohConsoleSink);
#if (!defined(_WIN32) && !defined(__WIIU__)) || defined(_DEBUG)
auto ConsoleSink = std::make_shared<spdlog::sinks::stdout_color_sink_mt>();
ConsoleSink->set_level(spdlog::level::trace);
Sinks.push_back(ConsoleSink);
#endif
#ifndef __WIIU__
auto logPath = GetPathRelativeToAppDirectory(("logs/" + GetName() + ".log").c_str());
auto FileSink = std::make_shared<spdlog::sinks::rotating_file_sink_mt>(logPath, 1024 * 1024 * 10, 10);
FileSink->set_level(spdlog::level::trace);
Sinks.push_back(FileSink);
#endif
Logger = std::make_shared<spdlog::async_logger>(GetName(), Sinks.begin(), Sinks.end(), spdlog::thread_pool(), spdlog::async_overflow_policy::block);
GetLogger()->set_level(spdlog::level::trace);
#ifndef __WIIU__
GetLogger()->set_pattern("[%Y-%m-%d %H:%M:%S.%e] [%@] [%l] %v");
#else
GetLogger()->set_pattern("[%s:%#] [%l] %v");
#endif
spdlog::register_logger(GetLogger());
spdlog::set_default_logger(GetLogger());
}
catch (const spdlog::spdlog_ex& ex) {
std::cout << "Log initialization failed: " << ex.what() << std::endl;
}
}
void GlobalCtx2::WriteSaveFile(const std::filesystem::path& savePath, const uintptr_t addr, void* dramAddr, const size_t size) {
std::ofstream saveFile = std::ofstream(savePath, std::fstream::in | std::fstream::out | std::fstream::binary);
saveFile.seekp(addr);
saveFile.write((char*)dramAddr, size);
saveFile.close();
}
void GlobalCtx2::ReadSaveFile(std::filesystem::path savePath, uintptr_t addr, void* dramAddr, size_t size) {
std::ifstream saveFile = std::ifstream(savePath, std::fstream::in | std::fstream::out | std::fstream::binary);
// If the file doesn't exist, initialize DRAM
if (saveFile.good()) {
saveFile.seekg(addr);
saveFile.read((char*)dramAddr, size);
} else {
memset(dramAddr, 0, size);
}
saveFile.close();
}
}
-54
View File
@@ -1,54 +0,0 @@
#ifndef GLOBAL_CTX_2
#define GLOBAL_CTX_2
#pragma once
#ifdef __cplusplus
#include <filesystem>
#include <memory>
#include <fstream>
#include "spdlog/spdlog.h"
#include "Lib/Mercury/Mercury.h"
namespace Ship {
class ResourceMgr;
class Window;
class GlobalCtx2 {
public:
static std::shared_ptr<GlobalCtx2> GetInstance();
static std::shared_ptr<GlobalCtx2> CreateInstance(const std::string& Name);
std::string GetName() { return Name; }
std::shared_ptr<Window> GetWindow() { return Win; }
std::shared_ptr<ResourceMgr> GetResourceManager() { return ResMan; }
std::shared_ptr<spdlog::logger> GetLogger() { return Logger; }
std::shared_ptr<Mercury> GetConfig() { return Config; }
static std::string GetAppDirectoryPath();
static std::string GetPathRelativeToAppDirectory(const char* path);
void WriteSaveFile(const std::filesystem::path& savePath, uintptr_t addr, void* dramAddr, size_t size);
void ReadSaveFile(std::filesystem::path savePath, uintptr_t addr, void* dramAddr, size_t size);
GlobalCtx2(std::string Name);
~GlobalCtx2();
protected:
void InitWindow();
void InitLogging();
private:
static std::weak_ptr <GlobalCtx2> Context;
std::shared_ptr<spdlog::logger> Logger;
std::shared_ptr<Window> Win;
std::shared_ptr<Mercury> Config; // Config needs to be after the Window because we call the Window during it's destructor.
std::shared_ptr<ResourceMgr> ResMan;
std::string Name;
std::string MainPath;
std::string PatchesPath;
};
}
#endif
#endif
+157 -40
View File
@@ -18,7 +18,6 @@
#include "Hooks.h"
#define IMGUI_DEFINE_MATH_OPERATORS
#include "Lib/ImGui/imgui_internal.h"
#include "GlobalCtx2.h"
#include "ResourceMgr.h"
#include "Window.h"
#include "Cvar.h"
@@ -42,8 +41,10 @@
#if __APPLE__
#include <SDL_hints.h>
#include <SDL_video.h>
#else
#include <SDL2/SDL_hints.h>
#include <SDL2/SDL_video.h>
#endif
#ifdef __SWITCH__
@@ -164,8 +165,14 @@ namespace SohImGui {
} else {
console->Close();
}
SohImGui::controller->Opened = CVar_GetS32("gControllerConfigurationEnabled", 0);
UpdateAudio();
if (CVar_GetS32("gControllerConfigurationEnabled", 0)) {
controller->Open();
} else {
controller->Close();
}
UpdateAudio();
});
}
@@ -338,6 +345,8 @@ namespace SohImGui {
switch (impl.backend) {
case Backend::DX11:
return true;
case Backend::SDL:
return true;
default:
return false;
}
@@ -345,27 +354,27 @@ namespace SohImGui {
void ShowCursor(bool hide, Dialogues d) {
if (d == Dialogues::dLoadSettings) {
GlobalCtx2::GetInstance()->GetWindow()->ShowCursor(hide);
Window::GetInstance()->ShowCursor(hide);
return;
}
if (d == Dialogues::dConsole && CVar_GetS32("gOpenMenuBar", 0)) {
return;
}
if (!GlobalCtx2::GetInstance()->GetWindow()->IsFullscreen()) {
if (!Window::GetInstance()->IsFullscreen()) {
oldCursorState = false;
return;
}
if (oldCursorState != hide) {
oldCursorState = hide;
GlobalCtx2::GetInstance()->GetWindow()->ShowCursor(hide);
Window::GetInstance()->ShowCursor(hide);
}
}
void LoadTexture(const std::string& name, const std::string& path) {
GfxRenderingAPI* api = gfx_get_current_rendering_api();
const auto res = GlobalCtx2::GetInstance()->GetResourceManager()->LoadFile(path);
const auto res = Window::GetInstance()->GetResourceManager()->LoadFile(path);
const auto asset = new GameAsset{ api->new_texture() };
uint8_t* img_data = stbi_load_from_memory(reinterpret_cast<const stbi_uc*>(res->buffer.get()), res->dwBufferSize, &asset->width, &asset->height, nullptr, 4);
@@ -401,7 +410,7 @@ namespace SohImGui {
void LoadResource(const std::string& name, const std::string& path, const ImVec4& tint) {
GfxRenderingAPI* api = gfx_get_current_rendering_api();
const auto res = static_cast<Ship::Texture*>(GlobalCtx2::GetInstance()->GetResourceManager()->LoadResource(path).get());
const auto res = static_cast<Ship::Texture*>(Window::GetInstance()->GetResourceManager()->LoadResource(path).get());
std::vector<uint8_t> texBuffer;
texBuffer.reserve(res->width * res->height * 4);
@@ -466,7 +475,7 @@ namespace SohImGui {
io->DisplaySize.y = window_impl.gx2.height;
#endif
lastBackendID = GetBackendID(GlobalCtx2::GetInstance()->GetConfig());
lastBackendID = GetBackendID(Window::GetInstance()->GetConfig());
if (CVar_GetS32("gOpenMenuBar", 0) != 1) {
#if defined(__SWITCH__) || defined(__WIIU__)
SohImGui::overlay->TextDrawNotification(30.0f, true, "Press - to access enhancements menu");
@@ -475,8 +484,8 @@ namespace SohImGui {
#endif
}
auto imguiIniPath = Ship::GlobalCtx2::GetPathRelativeToAppDirectory("imgui.ini");
auto imguiLogPath = Ship::GlobalCtx2::GetPathRelativeToAppDirectory("imgui_log.txt");
auto imguiIniPath = Ship::Window::GetPathRelativeToAppDirectory("imgui.ini");
auto imguiLogPath = Ship::Window::GetPathRelativeToAppDirectory("imgui_log.txt");
io->IniFilename = strcpy(new char[imguiIniPath.length() + 1], imguiIniPath.c_str());
io->LogFilename = strcpy(new char[imguiLogPath.length() + 1], imguiLogPath.c_str());
@@ -500,7 +509,7 @@ namespace SohImGui {
#endif
Ship::RegisterHook<Ship::GfxInit>([] {
if (GlobalCtx2::GetInstance()->GetWindow()->IsFullscreen())
if (Window::GetInstance()->IsFullscreen())
ShowCursor(CVar_GetS32("gOpenMenuBar", 0), Dialogues::dLoadSettings);
LoadTexture("Game_Icon", "assets/ship_of_harkinian/icons/gSohIcon.png");
@@ -600,13 +609,101 @@ namespace SohImGui {
ImGui::Text("%s", text);
}
void EnhancementCheckbox(const char* text, const char* cvarName)
void RenderCross(ImDrawList* draw_list, ImVec2 pos, ImU32 col, float sz)
{
float thickness = ImMax(sz / 5.0f, 1.0f);
sz -= thickness * 0.5f;
pos += ImVec2(thickness * 0.25f, thickness * 0.25f);
draw_list->PathLineTo(ImVec2(pos.x, pos.y));
draw_list->PathLineTo(ImVec2(pos.x + sz, pos.y + sz));
draw_list->PathStroke(col, 0, thickness);
draw_list->PathLineTo(ImVec2(pos.x + sz, pos.y));
draw_list->PathLineTo(ImVec2(pos.x, pos.y + sz));
draw_list->PathStroke(col, 0, thickness);
}
bool CustomCheckbox(const char* label, bool* v, bool disabled, ImGuiCheckboxGraphics disabledGraphic) {
ImGuiWindow* window = ImGui::GetCurrentWindow();
if (window->SkipItems)
return false;
ImGuiContext& g = *GImGui;
const ImGuiStyle& style = g.Style;
const ImGuiID id = window->GetID(label);
const ImVec2 label_size = ImGui::CalcTextSize(label, NULL, true);
const float square_sz = ImGui::GetFrameHeight();
const ImVec2 pos = window->DC.CursorPos;
const ImRect total_bb(pos, pos + ImVec2(square_sz + (label_size.x > 0.0f ? style.ItemInnerSpacing.x + label_size.x : 0.0f), label_size.y + style.FramePadding.y * 2.0f));
ImGui::ItemSize(total_bb, style.FramePadding.y);
if (!ImGui::ItemAdd(total_bb, id))
{
IMGUI_TEST_ENGINE_ITEM_INFO(id, label, g.LastItemData.StatusFlags | ImGuiItemStatusFlags_Checkable | (*v ? ImGuiItemStatusFlags_Checked : 0));
return false;
}
bool hovered, held;
bool pressed = ImGui::ButtonBehavior(total_bb, id, &hovered, &held);
if (pressed)
{
*v = !(*v);
ImGui::MarkItemEdited(id);
}
const ImRect check_bb(pos, pos + ImVec2(square_sz, square_sz));
ImGui::RenderNavHighlight(total_bb, id);
ImGui::RenderFrame(check_bb.Min, check_bb.Max, ImGui::GetColorU32((held && hovered) ? ImGuiCol_FrameBgActive : hovered ? ImGuiCol_FrameBgHovered : ImGuiCol_FrameBg), true, style.FrameRounding);
ImU32 check_col = ImGui::GetColorU32(ImGuiCol_CheckMark);
ImU32 cross_col = ImGui::GetColorU32(ImVec4(0.50f, 0.50f, 0.50f, 1.00f));
bool mixed_value = (g.LastItemData.InFlags & ImGuiItemFlags_MixedValue) != 0;
if (mixed_value)
{
// Undocumented tristate/mixed/indeterminate checkbox (#2644)
// This may seem awkwardly designed because the aim is to make ImGuiItemFlags_MixedValue supported by all widgets (not just checkbox)
ImVec2 pad(ImMax(1.0f, IM_FLOOR(square_sz / 3.6f)), ImMax(1.0f, IM_FLOOR(square_sz / 3.6f)));
window->DrawList->AddRectFilled(check_bb.Min + pad, check_bb.Max - pad, check_col, style.FrameRounding);
}
else if ((!disabled && *v) || (disabled && disabledGraphic == ImGuiCheckboxGraphics::Checkmark))
{
const float pad = ImMax(1.0f, IM_FLOOR(square_sz / 6.0f));
ImGui::RenderCheckMark(window->DrawList, check_bb.Min + ImVec2(pad, pad), check_col, square_sz - pad * 2.0f);
}
else if (disabled && disabledGraphic == ImGuiCheckboxGraphics::Cross) {
const float pad = ImMax(1.0f, IM_FLOOR(square_sz / 6.0f));
RenderCross(window->DrawList, check_bb.Min + ImVec2(pad, pad), cross_col, square_sz - pad * 2.0f);
}
ImVec2 label_pos = ImVec2(check_bb.Max.x + style.ItemInnerSpacing.x, check_bb.Min.y + style.FramePadding.y);
if (g.LogEnabled)
ImGui::LogRenderedText(&label_pos, mixed_value ? "[~]" : *v ? "[x]" : "[ ]");
if (label_size.x > 0.0f)
ImGui::RenderText(label_pos, label);
IMGUI_TEST_ENGINE_ITEM_INFO(id, label, g.LastItemData.StatusFlags | ImGuiItemStatusFlags_Checkable | (*v ? ImGuiItemStatusFlags_Checked : 0));
return pressed;
}
void EnhancementCheckbox(const char* text, const char* cvarName, bool disabled, const char* disabledTooltipText, ImGuiCheckboxGraphics disabledGraphic)
{
if (disabled) {
ImGui::PushItemFlag(ImGuiItemFlags_Disabled, true);
ImGui::PushStyleVar(ImGuiStyleVar_Alpha, ImGui::GetStyle().Alpha * 0.5f);
}
bool val = (bool)CVar_GetS32(cvarName, 0);
if (ImGui::Checkbox(text, &val)) {
if (CustomCheckbox(text, &val, disabled, disabledGraphic)) {
CVar_SetS32(cvarName, val);
needs_save = true;
}
if (disabled) {
ImGui::PopStyleVar(1);
if (ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled) && disabledTooltipText != "") {
ImGui::SetTooltip("%s", disabledTooltipText);
}
ImGui::PopItemFlag();
}
}
void EnhancementButton(const char* text, const char* cvarName)
@@ -753,12 +850,7 @@ namespace SohImGui {
}
void RandomizeColor(const char* cvarName, ImVec4* colors) {
std::string Cvar_Red = cvarName;
Cvar_Red += "R";
std::string Cvar_Green = cvarName;
Cvar_Green += "G";
std::string Cvar_Blue = cvarName;
Cvar_Blue += "B";
Color_RGBA8 NewColors = {0,0,0,255};
std::string Cvar_RBM = cvarName;
Cvar_RBM += "RBM";
std::string MakeInvisible = "##";
@@ -773,9 +865,10 @@ namespace SohImGui {
colors->x = (float)RND_R / 255;
colors->y = (float)RND_G / 255;
colors->z = (float)RND_B / 255;
CVar_SetS32(Cvar_Red.c_str(), ClampFloatToInt(colors->x * 255, 0, 255));
CVar_SetS32(Cvar_Green.c_str(), ClampFloatToInt(colors->y * 255, 0, 255));
CVar_SetS32(Cvar_Blue.c_str(), ClampFloatToInt(colors->z * 255, 0, 255));
NewColors.r = ClampFloatToInt(colors->x * 255, 0, 255);
NewColors.g = ClampFloatToInt(colors->y * 255, 0, 255);
NewColors.b = ClampFloatToInt(colors->z * 255, 0, 255);
CVar_SetRGBA(cvarName, NewColors);
CVar_SetS32(Cvar_RBM.c_str(), 0); //On click disable rainbow mode.
needs_save = true;
}
@@ -802,16 +895,16 @@ namespace SohImGui {
MakeInvisible += cvarName;
MakeInvisible += "Reset";
if (ImGui::Button(MakeInvisible.c_str())) {
colors->x = defaultcolors.x / 255;
colors->y = defaultcolors.y / 255;
colors->z = defaultcolors.z / 255;
if (has_alpha) { colors->w = defaultcolors.w / 255; };
colors->x = defaultcolors.x;
colors->y = defaultcolors.y;
colors->z = defaultcolors.z;
if (has_alpha) { colors->w = defaultcolors.w; };
Color_RGBA8 colorsRGBA;
colorsRGBA.r = defaultcolors.x / 255;
colorsRGBA.g = defaultcolors.y / 255;
colorsRGBA.b = defaultcolors.z / 255;
if (has_alpha) { colorsRGBA.a = defaultcolors.w / 255; };
colorsRGBA.r = defaultcolors.x;
colorsRGBA.g = defaultcolors.y;
colorsRGBA.b = defaultcolors.z;
if (has_alpha) { colorsRGBA.a = defaultcolors.w; };
CVar_SetRGBA(cvarName, colorsRGBA);
CVar_SetS32(Cvar_RBM.c_str(), 0); //On click disable rainbow mode.
@@ -883,8 +976,8 @@ namespace SohImGui {
ImGuiWMNewFrame();
ImGui::NewFrame();
const std::shared_ptr<Window> wnd = GlobalCtx2::GetInstance()->GetWindow();
const std::shared_ptr<Mercury> pConf = GlobalCtx2::GetInstance()->GetConfig();
const std::shared_ptr<Window> wnd = Window::GetInstance();
const std::shared_ptr<Mercury> pConf = Window::GetInstance()->GetConfig();
ImGuiWindowFlags window_flags = ImGuiWindowFlags_NoDocking | ImGuiWindowFlags_NoBackground |
ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoMove |
@@ -921,9 +1014,9 @@ namespace SohImGui {
bool menu_bar = CVar_GetS32("gOpenMenuBar", 0);
CVar_SetS32("gOpenMenuBar", !menu_bar);
needs_save = true;
GlobalCtx2::GetInstance()->GetWindow()->SetMenuBar(menu_bar);
Window::GetInstance()->SetMenuBar(menu_bar);
ShowCursor(menu_bar, Dialogues::dMenubar);
GlobalCtx2::GetInstance()->GetWindow()->GetControlDeck()->SaveControllerSettings();
Window::GetInstance()->GetControlDeck()->SaveControllerSettings();
if (CVar_GetS32("gControlNav", 0) && CVar_GetS32("gOpenMenuBar", 0)) {
io->ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad | ImGuiConfigFlags_NavEnableKeyboard;
} else {
@@ -1009,7 +1102,11 @@ namespace SohImGui {
bool currentValue = CVar_GetS32("gControllerConfigurationEnabled", 0);
CVar_SetS32("gControllerConfigurationEnabled", !currentValue);
needs_save = true;
controller->Opened = CVar_GetS32("gControllerConfigurationEnabled", 0);
if (CVar_GetS32("gControllerConfigurationEnabled", 0)) {
controller->Open();
} else {
controller->Close();
}
}
ImGui::PopStyleColor(1);
ImGui::PopStyleVar(3);
@@ -1214,6 +1311,8 @@ namespace SohImGui {
Tooltip("The default response to Kaepora Gaebora is always that you understood what he said");
PaddedEnhancementCheckbox("Fast Ocarina Playback", "gFastOcarinaPlayback", true, false);
Tooltip("Skip the part where the Ocarina playback is called when you play a song");
PaddedEnhancementCheckbox("Skip Scarecrow Song", "gSkipScarecrow", true, false);
Tooltip("Pierre appears when Ocarina is pulled out. Requires learning scarecrow song.");
PaddedEnhancementCheckbox("Instant Putaway", "gInstantPutaway", true, false);
Tooltip("Allow Link to put items away without having to wait around");
PaddedEnhancementCheckbox("Instant Boomerang Recall", "gFastBoomerang", true, false);
@@ -1268,6 +1367,8 @@ namespace SohImGui {
);
PaddedEnhancementCheckbox("No Random Drops", "gNoRandomDrops", true, false);
Tooltip("Disables random drops, except from the Goron Pot, Dampe, and bosses");
PaddedEnhancementCheckbox("Enable Bombchu Drops", "gBombchuDrops", true, false);
Tooltip("Bombchus will sometimes drop in place of bombs");
PaddedEnhancementCheckbox("No Heart Drops", "gNoHeartDrops", true, false);
Tooltip("Disables heart drops, but not heart placements, like from a Deku Scrub running off\nThis simulates Hero Mode from other games in the series");
PaddedEnhancementCheckbox("Always Win Goron Pot", "gGoronPot", true, false);
@@ -1502,6 +1603,7 @@ namespace SohImGui {
Tooltip("Restores N64 Weird Frames allowing weirdshots to behave the same as N64");
PaddedEnhancementCheckbox("Bombchus out of bounds", "gBombchusOOB", true, false);
Tooltip("Allows bombchus to explode out of bounds\nSimilar to GameCube and Wii VC");
PaddedEnhancementCheckbox("Restore old Gold Skulltula cutscene", "gGsCutscene", true, false);
ImGui::EndMenu();
}
@@ -2157,6 +2259,8 @@ namespace SohImGui {
CVar_SetS32("gNoRandomDrops", 0);
// No Heart Drops
CVar_SetS32("gNoHeartDrops", 0);
// Enable Bombchu Drops
CVar_SetS32("gBombchuDrops", 0);
// Always Win Goron Pot
CVar_SetS32("gGoronPot", 0);
@@ -2288,6 +2392,7 @@ namespace SohImGui {
// Bombchus out of bounds
CVar_SetS32("gBombchusOOB", 0);
CVar_SetS32("gGsCutscene", 0);
// Autosave
CVar_SetS32("gAutosave", 0);
}
@@ -2407,6 +2512,8 @@ namespace SohImGui {
CVar_SetS32("gVisualAgony", 1);
// Pull grave during the day
CVar_SetS32("gDayGravePull", 1);
// Pull out Ocarina to Summon Scarecrow
CVar_SetS32("gSkipScarecrow", 0);
// Pause link animation (0 to 16)
CVar_SetS32("gPauseLiveLink", 16);
@@ -2418,8 +2525,18 @@ namespace SohImGui {
ImGui::Render();
ImGuiRenderDrawData(ImGui::GetDrawData());
if (UseViewports()) {
ImGui::UpdatePlatformWindows();
ImGui::RenderPlatformWindowsDefault();
if (impl.backend == Backend::SDL) {
SDL_Window* backup_current_window = SDL_GL_GetCurrentWindow();
SDL_GLContext backup_current_context = SDL_GL_GetCurrentContext();
ImGui::UpdatePlatformWindows();
ImGui::RenderPlatformWindowsDefault();
SDL_GL_MakeCurrent(backup_current_window, backup_current_context);
} else {
ImGui::UpdatePlatformWindows();
ImGui::RenderPlatformWindowsDefault();
}
}
}
@@ -2650,11 +2767,11 @@ namespace SohImGui {
}
}
void PaddedEnhancementCheckbox(const char* text, const char* cvarName, bool padTop, bool padBottom) {
void PaddedEnhancementCheckbox(const char* text, const char* cvarName, bool padTop, bool padBottom, bool disabled, const char* disabledTooltipText, ImGuiCheckboxGraphics disabledGraphic) {
if (padTop) {
ImGui::Dummy(ImVec2(0.0f, 0.0f));
}
EnhancementCheckbox(text, cvarName);
EnhancementCheckbox(text, cvarName, disabled, disabledTooltipText, disabledGraphic);
if (padBottom) {
ImGui::Dummy(ImVec2(0.0f, 0.0f));
}
+10 -2
View File
@@ -34,6 +34,14 @@ namespace SohImGui {
dLoadSettings,
};
// Enumeration for disabled checkbox graphics
enum class ImGuiCheckboxGraphics
{
Cross,
Checkmark,
None
};
typedef struct {
Backend backend;
union {
@@ -86,7 +94,7 @@ namespace SohImGui {
void Tooltip(const char* text);
void EnhancementRadioButton(const char* text, const char* cvarName, int id);
void EnhancementCheckbox(const char* text, const char* cvarName);
void EnhancementCheckbox(const char* text, const char* cvarName, bool disabled = false, const char* disabledTooltipText = "", ImGuiCheckboxGraphics disabledGraphic = ImGuiCheckboxGraphics::Cross);
void EnhancementButton(const char* text, const char* cvarName);
void EnhancementSliderInt(const char* text, const char* id, const char* cvarName, int min, int max, const char* format, int defaultValue = 0, bool PlusMinusButton = false);
void EnhancementSliderFloat(const char* text, const char* id, const char* cvarName, float min, float max, const char* format, float defaultValue, bool isPercentage, bool PlusMinusButton = false);
@@ -123,7 +131,7 @@ namespace SohImGui {
void InsertPadding(float extraVerticalPadding = 0.0f);
void PaddedSeparator(bool padTop = true, bool padBottom = true, float extraVerticalTopPadding = 0.0f, float extraVerticalBottomPadding = 0.0f);
void PaddedEnhancementSliderInt(const char* text, const char* id, const char* cvarName, int min, int max, const char* format, int defaultValue = 0, bool PlusMinusButton = false, bool padTop = true, bool padBottom = true);
void PaddedEnhancementCheckbox(const char* text, const char* cvarName, bool padTop = true, bool padBottom = true);
void PaddedEnhancementCheckbox(const char* text, const char* cvarName, bool padTop = true, bool padBottom = true, bool disabled = false, const char* disabledTooltipText = "", ImGuiCheckboxGraphics disabledGraphic = ImGuiCheckboxGraphics::Cross);
void PaddedText(const char* text, bool padTop = true, bool padBottom = true);
std::string GetWindowButtonText(const char* text, bool menuOpen);
}
+15 -3
View File
@@ -16,11 +16,11 @@ namespace Ship {
}
std::shared_ptr<Controller> GetControllerPerSlot(int slot) {
auto controlDeck = Ship::GlobalCtx2::GetInstance()->GetWindow()->GetControlDeck();
auto controlDeck = Ship::Window::GetInstance()->GetControlDeck();
return controlDeck->GetPhysicalDeviceFromVirtualSlot(slot);
}
void InputEditor::DrawButton(const char* label, int n64Btn) {
void InputEditor::DrawButton(const char* label, int32_t n64Btn) {
const std::shared_ptr<Controller> backend = GetControllerPerSlot(CurrentPort);
float size = 40;
@@ -85,7 +85,7 @@ namespace Ship {
}
void InputEditor::DrawControllerSchema() {
auto controlDeck = Ship::GlobalCtx2::GetInstance()->GetWindow()->GetControlDeck();
auto controlDeck = Ship::Window::GetInstance()->GetControlDeck();
auto Backend = controlDeck->GetPhysicalDeviceFromVirtualSlot(CurrentPort);
auto profile = Backend->getProfile(CurrentPort);
bool IsKeyboard = Backend->GetGuid() == "Keyboard" || Backend->GetGuid() == "Auto" || !Backend->Connected();
@@ -357,4 +357,16 @@ namespace Ship {
ImGui::End();
}
bool InputEditor::IsOpened() {
return Opened;
}
void InputEditor::Open() {
Opened = true;
}
void InputEditor::Close() {
Opened = false;
}
}
+8 -4
View File
@@ -1,18 +1,22 @@
#pragma once
#include "stdint.h"
#include "Lib/ImGui/imgui.h"
namespace Ship {
class InputEditor {
int CurrentPort = 0;
int BtnReading = -1;
public:
int32_t CurrentPort = 0;
int32_t BtnReading = -1;
bool Opened = false;
public:
void Init();
void DrawButton(const char* label, int n64Btn);
void DrawButton(const char* label, int32_t n64Btn);
void DrawVirtualStick(const char* label, ImVec2 stick);
void DrawControllerSchema();
void DrawHud();
bool IsOpened();
void Open();
void Close();
};
}
@@ -7,7 +7,7 @@
#endif
#include "Hooks.h"
#include "GlobalCtx2.h"
#include "Window.h"
namespace Ship {
@@ -70,7 +70,7 @@ namespace Ship {
});
if (find == Mappings.end()) return "Unknown";
const char* name = GlobalCtx2::GetInstance()->GetWindow()->GetKeyName(find->first);
const char* name = Window::GetInstance()->GetKeyName(find->first);
return strlen(name) == 0 ? "Unknown" : name;
}
@@ -16,7 +16,6 @@
#include "gfx_cc.h"
#include "gfx_rendering_api.h"
#include "../../GlobalCtx2.h"
#include "gfx_pc.h"
#include "gfx_wiiu.h"
@@ -44,7 +44,7 @@
#include "gfx_cc.h"
#include "gfx_rendering_api.h"
#include "../../ImGuiImpl.h"
#include "../../GlobalCtx2.h"
#include "../../Window.h"
#include "gfx_pc.h"
using namespace std;
@@ -15,6 +15,7 @@
#ifndef _LANGUAGE_C
#define _LANGUAGE_C
#endif
#include <PR/ultra64/types.h>
#include <PR/ultra64/gbi.h>
#include <PR/ultra64/gs2dex.h>
#include <string>
@@ -36,6 +37,7 @@
#include "../../ResourceMgr.h"
#include "../../Utils.h"
// OTRTODO: fix header files for these
extern "C" {
const char* ResourceMgr_GetNameByCRC(uint64_t crc);
@@ -2171,7 +2173,7 @@ static void gfx_run_dl(Gfx* cmd) {
uintptr_t mtxAddr = cmd->words.w1;
// OTRTODO: Temp way of dealing with gMtxClear. Need something more elegant in the future...
uint32_t gameVersion = Ship::GlobalCtx2::GetInstance()->GetResourceManager()->GetGameVersion();
uint32_t gameVersion = Ship::Window::GetInstance()->GetResourceManager()->GetGameVersion();
if (gameVersion == OOT_PAL_GC) {
if (mtxAddr == SEG_ADDR(0, 0x0FBC20)) {
mtxAddr = clearMtx;
@@ -8,6 +8,7 @@
#include <list>
#include <cstddef>
#include "U64/PR/ultra64/gbi.h"
#include "U64/PR/ultra64/types.h"
// TODO figure out why changing these to 640x480 makes the game only render in a quarter of the window
@@ -189,6 +189,7 @@ static void gfx_sdl_init(const char *game_name, bool start_in_fullscreen, uint32
}
#endif
SDL_GL_MakeCurrent(wnd, ctx);
SDL_GL_SetSwapInterval(1);
SohImGui::WindowImpl window_impl;
+1
View File
@@ -1,4 +1,5 @@
#include "Resource.h"
#include "StrHash.h"
namespace Ship
{
+10 -16
View File
@@ -3,15 +3,14 @@
#include <stdint.h>
#include "Utils/BinaryReader.h"
#include "Utils/BinaryWriter.h"
#include "GlobalCtx2.h"
#include "StrHash.h"
#include "File.h"
#include "Lib/tinyxml2/tinyxml2.h"
#include "spdlog/spdlog.h"
namespace Ship
{
enum class ResourceType
{
namespace Ship {
class ResourceMgr;
enum class ResourceType {
Archive = 0x4F415243, // OARC (UNUSED)
Model = 0x4F4D444C, // OMDL (WIP)
Texture = 0x4F544558, // OTEX
@@ -36,8 +35,7 @@ namespace Ship
AudioSequence = 0x4F534551, // OSEQ
};
enum class DataType
{
enum class DataType {
U8 = 0,
S8 = 1,
U16 = 2,
@@ -51,8 +49,7 @@ namespace Ship
F64 = 10
};
enum class Version
{
enum class Version {
// BR
Deckard = 0,
Roy = 1,
@@ -61,15 +58,13 @@ namespace Ship
// ...
};
struct Patch
{
struct Patch {
uint64_t crc;
uint32_t index;
uintptr_t origData;
};
class Resource
{
class Resource {
public:
ResourceMgr* resMgr;
uint64_t id; // Unique Resource ID
@@ -81,8 +76,7 @@ namespace Ship
virtual ~Resource();
};
class ResourceFile
{
class ResourceFile {
public:
Endianness endianness; // 0x00 - Endianness of the file
uint32_t resourceType; // 0x01 - 4 byte MAGIC
+28 -40
View File
@@ -9,13 +9,14 @@
namespace Ship {
ResourceMgr::ResourceMgr(std::shared_ptr<GlobalCtx2> Context, const std::string& MainPath, const std::string& PatchesPath) : Context(Context), bIsRunning(false), FileLoadThread(nullptr) {
ResourceMgr::ResourceMgr(std::shared_ptr<Window> Context, const std::string& MainPath, const std::string& PatchesPath) : Context(Context), bIsRunning(false), FileLoadThread(nullptr) {
OTR = std::make_shared<Archive>(MainPath, PatchesPath, false);
gameVersion = OOT_UNKNOWN;
if (OTR->IsMainMPQValid())
if (OTR->IsMainMPQValid()) {
Start();
}
}
ResourceMgr::~ResourceMgr() {
@@ -87,10 +88,11 @@ namespace Ship {
OTR->LoadFile(ToLoad->path, true, ToLoad);
if (!ToLoad->bHasLoadError)
if (!ToLoad->bHasLoadError) {
FileCache[ToLoad->path] = ToLoad->bIsLoaded && !ToLoad->bHasLoadError ? ToLoad : nullptr;
}
SPDLOG_DEBUG("Loaded File {} on ResourceMgr thread", ToLoad->path);
SPDLOG_TRACE("Loaded File {} on ResourceMgr thread", ToLoad->path);
ToLoad->FileLoadNotifier.notify_all();
}
@@ -123,12 +125,10 @@ namespace Ship {
}
}
if (!ToLoad->file->bHasLoadError)
{
if (!ToLoad->file->bHasLoadError) {
auto UnmanagedRes = ResourceLoader::LoadResource(ToLoad->file);
if (UnmanagedRes != nullptr)
{
if (UnmanagedRes != nullptr) {
UnmanagedRes->resMgr = this;
auto Res = std::shared_ptr<Resource>(UnmanagedRes);
@@ -142,17 +142,14 @@ namespace Ship {
SPDLOG_DEBUG("Loaded Resource {} on ResourceMgr thread", ToLoad->file->path);
Res->file = nullptr;
}
else {
} else {
ToLoad->bHasResourceLoaded = false;
ToLoad->resource = nullptr;
SPDLOG_ERROR("Resource load FAILED {} on ResourceMgr thread", ToLoad->file->path);
}
}
}
else
{
} else {
ToLoad->bHasResourceLoaded = false;
ToLoad->resource = nullptr;
}
@@ -163,13 +160,11 @@ namespace Ship {
SPDLOG_INFO("Resource Manager LoadResourceThread ended");
}
uint32_t ResourceMgr::GetGameVersion()
{
uint32_t ResourceMgr::GetGameVersion() {
return gameVersion;
}
void ResourceMgr::SetGameVersion(uint32_t newGameVersion)
{
void ResourceMgr::SetGameVersion(uint32_t newGameVersion) {
gameVersion = newGameVersion;
}
@@ -206,24 +201,23 @@ namespace Ship {
auto resCacheFind = ResourceCache.find(FilePath);
if (resCacheFind != ResourceCache.end() &&
resCacheFind->second.use_count() > 0)
{
resCacheFind->second.use_count() > 0) {
return resCacheFind->second;
}
else
} else {
return nullptr;
}
}
std::shared_ptr<Resource> ResourceMgr::LoadResource(const char* FilePath) {
auto Res = LoadResourceAsync(FilePath);
if (std::holds_alternative<std::shared_ptr<Resource>>(Res))
if (std::holds_alternative<std::shared_ptr<Resource>>(Res)) {
return std::get<std::shared_ptr<Resource>>(Res);
}
auto& Promise = std::get<std::shared_ptr<ResourcePromise>>(Res);
if (!Promise->bHasResourceLoaded)
{
if (!Promise->bHasResourceLoaded) {
std::unique_lock<std::mutex> Lock(Promise->resourceLoadMutex);
while (!Promise->bHasResourceLoaded) {
Promise->resourceLoadNotifier.wait(Lock);
@@ -234,8 +228,9 @@ namespace Ship {
}
std::variant<std::shared_ptr<Resource>, std::shared_ptr<ResourcePromise>> ResourceMgr::LoadResourceAsync(const char* FilePath) {
if (FilePath[0] == '_' && FilePath[1] == '_' && FilePath[2] == 'O' && FilePath[3] == 'T' && FilePath[4] == 'R' && FilePath[5] == '_' && FilePath[6] == '_')
if (FilePath[0] == '_' && FilePath[1] == '_' && FilePath[2] == 'O' && FilePath[3] == 'T' && FilePath[4] == 'R' && FilePath[5] == '_' && FilePath[6] == '_') {
FilePath += 7;
}
const std::lock_guard<std::mutex> ResLock(ResourceLoadMutex);
auto resCacheFind = ResourceCache.find(FilePath);
@@ -248,21 +243,16 @@ namespace Ship {
std::shared_ptr<File> FileData = LoadFile(FilePath);
Promise->file = FileData;
if (Promise->file->bHasLoadError)
{
if (Promise->file->bHasLoadError) {
Promise->bHasResourceLoaded = true;
}
else
{
} else {
Promise->bHasResourceLoaded = false;
ResourceLoadQueue.push(Promise);
ResourceLoadNotifier.notify_all();
}
return Promise;
}
else
{
} else {
return resCacheFind->second;
}
}
@@ -273,8 +263,7 @@ namespace Ship {
for (DWORD i = 0; i < fileList.size(); i++) {
auto resource = LoadResourceAsync(fileList.operator[](i).cFileName);
if (std::holds_alternative<std::shared_ptr<Resource>>(resource))
{
if (std::holds_alternative<std::shared_ptr<Resource>>(resource)) {
auto promise = std::make_shared<ResourcePromise>();
promise->bHasResourceLoaded = true;
promise->resource = std::get<std::shared_ptr<Resource>>(resource);
@@ -304,8 +293,7 @@ namespace Ship {
return LoadedList;
}
std::shared_ptr<std::vector<std::shared_ptr<Resource>>> ResourceMgr::DirtyDirectory(std::string SearchMask)
{
std::shared_ptr<std::vector<std::shared_ptr<Resource>>> ResourceMgr::DirtyDirectory(const std::string& SearchMask) {
auto PromiseList = CacheDirectoryAsync(SearchMask);
auto LoadedList = std::make_shared<std::vector<std::shared_ptr<Resource>>>();
@@ -317,8 +305,9 @@ namespace Ship {
Promise->resourceLoadNotifier.wait(Lock);
}
if (Promise->resource != nullptr)
if (Promise->resource != nullptr) {
Promise->resource->isDirty = true;
}
LoadedList->push_back(Promise->resource);
}
@@ -326,8 +315,7 @@ namespace Ship {
return LoadedList;
}
std::shared_ptr<std::vector<std::string>> ResourceMgr::ListFiles(std::string SearchMask)
{
std::shared_ptr<std::vector<std::string>> ResourceMgr::ListFiles(std::string SearchMask) {
auto result = std::make_shared<std::vector<std::string>>();
auto fileList = OTR->ListFiles(SearchMask);
+10 -10
View File
@@ -5,26 +5,26 @@
#include <thread>
#include <queue>
#include <variant>
#include "Window.h"
#include "Resource.h"
#include "GlobalCtx2.h"
#include "Archive.h"
#include "File.h"
namespace Ship
{
class Archive;
class File;
namespace Ship {
class Window;
// Resource manager caches any and all files it comes across into memory. This will be unoptimal in the future when modifications have gigabytes of assets.
// It works with the original game's assets because the entire ROM is 64MB and fits into RAM of any semi-modern PC.
class ResourceMgr {
public:
ResourceMgr(std::shared_ptr<GlobalCtx2> Context, const std::string& MainPath, const std::string& PatchesPath);
ResourceMgr(std::shared_ptr<Window> Context, const std::string& MainPath, const std::string& PatchesPath);
~ResourceMgr();
bool IsRunning();
bool DidLoadSuccessfully();
std::shared_ptr<Archive> GetArchive() { return OTR; }
std::shared_ptr<GlobalCtx2> GetContext() { return Context.lock(); }
std::shared_ptr<Window> GetContext() { return Context; }
const std::string* HashToString(uint64_t Hash) const;
@@ -34,13 +34,13 @@ namespace Ship
void SetGameVersion(uint32_t newGameVersion);
std::shared_ptr<File> LoadFileAsync(const std::string& FilePath);
std::shared_ptr<File> LoadFile(const std::string& FilePath);
std::shared_ptr<Ship::Resource> GetCachedFile(const char* FilePath) const;
std::shared_ptr<Resource> GetCachedFile(const char* FilePath) const;
std::shared_ptr<Resource> LoadResource(const char* FilePath);
std::shared_ptr<Resource> LoadResource(const std::string& FilePath) { return LoadResource(FilePath.c_str()); }
std::variant<std::shared_ptr<Resource>, std::shared_ptr<ResourcePromise>> LoadResourceAsync(const char* FilePath);
std::shared_ptr<std::vector<std::shared_ptr<Resource>>> CacheDirectory(const std::string& SearchMask);
std::shared_ptr<std::vector<std::shared_ptr<ResourcePromise>>> CacheDirectoryAsync(const std::string& SearchMask);
std::shared_ptr<std::vector<std::shared_ptr<Resource>>> DirtyDirectory(std::string SearchMask);
std::shared_ptr<std::vector<std::shared_ptr<Resource>>> DirtyDirectory(const std::string& SearchMask);
std::shared_ptr<std::vector<std::string>> ListFiles(std::string SearchMask);
protected:
@@ -50,7 +50,7 @@ namespace Ship
void LoadResourceThread();
private:
std::weak_ptr<GlobalCtx2> Context;
std::shared_ptr<Window> Context;
volatile bool bIsRunning;
std::unordered_map<std::string, std::shared_ptr<File>> FileCache;
std::unordered_map<std::string, std::shared_ptr<Resource>> ResourceCache;
+1 -1
View File
@@ -1,5 +1,5 @@
#include "SDLController.h"
#include "GlobalCtx2.h"
#include "spdlog/spdlog.h"
#include "Window.h"
#include <Utils/StringHelper.h>
@@ -1,6 +1,5 @@
#ifdef __WIIU__
#include "WiiUController.h"
#include "GlobalCtx2.h"
#include "Window.h"
#include "ImGuiImpl.h"
@@ -1,6 +1,5 @@
#ifdef __WIIU__
#include "WiiUGamepad.h"
#include "GlobalCtx2.h"
#include "ImGuiImpl.h"
#include "WiiUImpl.h"
+1 -1
View File
@@ -114,7 +114,7 @@ void Update() {
// rescan devices if connection state changed
if (rescan) {
Ship::GlobalCtx2::GetInstance()->GetWindow()->GetControlDeck()->ScanPhysicalDevices();
Window::GetInstance()->GetControlDeck()->ScanPhysicalDevices();
}
}
+211 -83
View File
@@ -1,23 +1,18 @@
#include <string>
#include <chrono>
#include <fstream>
#include <iostream>
#include "Window.h"
#include "spdlog/spdlog.h"
#include "KeyboardController.h"
#include "GlobalCtx2.h"
#include "DisplayList.h"
#include "Vertex.h"
#include "Array.h"
#include "ResourceMgr.h"
#include "KeyboardController.h"
#include "UltraController.h"
#include "DisplayList.h"
#include "Console.h"
#include "Array.h"
#include "Texture.h"
#include "Blob.h"
#include "Matrix.h"
#include "AudioPlayer.h"
#include "Hooks.h"
#include "UltraController.h"
#include <SDL2/SDL.h>
#include <string>
#include <chrono>
#include "Console.h"
#include "ImGuiImpl.h"
#include "PR/ultra64/gbi.h"
#include "Lib/Fast3D/gfx_pc.h"
#include "Lib/Fast3D/gfx_sdl.h"
#include "Lib/Fast3D/gfx_dxgi.h"
@@ -27,12 +22,25 @@
#include "Lib/Fast3D/gfx_direct3d12.h"
#include "Lib/Fast3D/gfx_wiiu.h"
#include "Lib/Fast3D/gfx_gx2.h"
#include "Lib/Fast3D/gfx_rendering_api.h"
#include "Lib/Fast3D/gfx_window_manager_api.h"
#include <string>
#include <SDL2/SDL.h>
#include "ImGuiImpl.h"
#include "spdlog/async.h"
#include "spdlog/sinks/rotating_file_sink.h"
#include "spdlog/sinks/stdout_color_sinks.h"
#include "spdlog/sinks/sohconsole_sink.h"
#include "PR/ultra64/gbi.h"
#ifdef __APPLE__
#include "OSXFolderManager.h"
#elif defined(__SWITCH__)
#include "SwitchImpl.h"
#elif defined(__WIIU__)
#include "WiiUImpl.h"
#endif
#include <iostream>
#define LOAD_TEX(texPath) static_cast<Ship::Texture*>(Ship::GlobalCtx2::GetInstance()->GetResourceManager()->LoadResource(texPath).get());
#define LOAD_TEX(texPath) static_cast<Ship::Texture*>(Ship::Window::GetInstance()->GetResourceManager()->LoadResource(texPath).get());
extern "C" {
struct OSMesgQueue;
@@ -59,7 +67,7 @@ extern "C" {
#endif
#endif
Ship::GlobalCtx2::GetInstance()->GetWindow()->GetControlDeck()->Init(controllerBits);
Ship::Window::GetInstance()->GetControlDeck()->Init(controllerBits);
return 0;
}
@@ -78,22 +86,22 @@ extern "C" {
pad->gyro_x = 0;
pad->gyro_y = 0;
if (SohImGui::controller->Opened) return;
if (SohImGui::controller->IsOpened()) return;
Ship::GlobalCtx2::GetInstance()->GetWindow()->GetControlDeck()->WriteToPad(pad);
Ship::Window::GetInstance()->GetControlDeck()->WriteToPad(pad);
Ship::ExecuteHooks<Ship::ControllerRead>(pad);
}
const char* ResourceMgr_GetNameByCRC(uint64_t crc) {
const std::string* hashStr = Ship::GlobalCtx2::GetInstance()->GetResourceManager()->HashToString(crc);
const std::string* hashStr = Ship::Window::GetInstance()->GetResourceManager()->HashToString(crc);
return hashStr != nullptr ? hashStr->c_str() : nullptr;
}
Vtx* ResourceMgr_LoadVtxByCRC(uint64_t crc) {
const std::string* hashStr = Ship::GlobalCtx2::GetInstance()->GetResourceManager()->HashToString(crc);
const std::string* hashStr = Ship::Window::GetInstance()->GetResourceManager()->HashToString(crc);
if (hashStr != nullptr) {
auto res = std::static_pointer_cast<Ship::Array>(Ship::GlobalCtx2::GetInstance()->GetResourceManager()->LoadResource(hashStr->c_str()));
auto res = std::static_pointer_cast<Ship::Array>(Ship::Window::GetInstance()->GetResourceManager()->LoadResource(hashStr->c_str()));
return (Vtx*)res->vertices.data();
}
@@ -101,10 +109,10 @@ extern "C" {
}
int32_t* ResourceMgr_LoadMtxByCRC(uint64_t crc) {
const std::string* hashStr = Ship::GlobalCtx2::GetInstance()->GetResourceManager()->HashToString(crc);
const std::string* hashStr = Ship::Window::GetInstance()->GetResourceManager()->HashToString(crc);
if (hashStr != nullptr) {
auto res = std::static_pointer_cast<Ship::Matrix>(Ship::GlobalCtx2::GetInstance()->GetResourceManager()->LoadResource(hashStr->c_str()));
auto res = std::static_pointer_cast<Ship::Matrix>(Ship::Window::GetInstance()->GetResourceManager()->LoadResource(hashStr->c_str()));
return (int32_t*)res->mtx.data();
}
@@ -112,10 +120,10 @@ extern "C" {
}
Gfx* ResourceMgr_LoadGfxByCRC(uint64_t crc) {
const std::string* hashStr = Ship::GlobalCtx2::GetInstance()->GetResourceManager()->HashToString(crc);
const std::string* hashStr = Ship::Window::GetInstance()->GetResourceManager()->HashToString(crc);
if (hashStr != nullptr) {
auto res = std::static_pointer_cast<Ship::DisplayList>(Ship::GlobalCtx2::GetInstance()->GetResourceManager()->LoadResource(hashStr->c_str()));
auto res = std::static_pointer_cast<Ship::DisplayList>(Ship::Window::GetInstance()->GetResourceManager()->LoadResource(hashStr->c_str()));
return (Gfx*)&res->instructions[0];
} else {
return nullptr;
@@ -123,7 +131,7 @@ extern "C" {
}
char* ResourceMgr_LoadTexByCRC(uint64_t crc) {
const std::string* hashStr = Ship::GlobalCtx2::GetInstance()->GetResourceManager()->HashToString(crc);
const std::string* hashStr = Ship::Window::GetInstance()->GetResourceManager()->HashToString(crc);
if (hashStr != nullptr) {
const auto res = LOAD_TEX(hashStr->c_str());
@@ -137,11 +145,11 @@ extern "C" {
void ResourceMgr_RegisterResourcePatch(uint64_t hash, uint32_t instrIndex, uintptr_t origData)
{
const std::string* hashStr = Ship::GlobalCtx2::GetInstance()->GetResourceManager()->HashToString(hash);
const std::string* hashStr = Ship::Window::GetInstance()->GetResourceManager()->HashToString(hash);
if (hashStr != nullptr)
{
auto res = (Ship::Texture*)Ship::GlobalCtx2::GetInstance()->GetResourceManager()->LoadResource(hashStr->c_str()).get();
auto res = (Ship::Texture*)Ship::Window::GetInstance()->GetResourceManager()->LoadResource(hashStr->c_str()).get();
Ship::Patch patch;
patch.crc = hash;
@@ -201,7 +209,7 @@ extern "C" {
}
char* ResourceMgr_LoadBlobByName(char* blobPath) {
auto res = (Ship::Blob*)Ship::GlobalCtx2::GetInstance()->GetResourceManager()->LoadResource(blobPath).get();
auto res = (Ship::Blob*)Ship::Window::GetInstance()->GetResourceManager()->LoadResource(blobPath).get();
return (char*)res->data.data();
}
@@ -217,7 +225,26 @@ extern "C" {
namespace Ship {
Window::Window(std::shared_ptr<GlobalCtx2> Context) : Context(Context), APlayer(nullptr), ControllerApi(nullptr) {
std::weak_ptr<Window> Window::Context;
std::shared_ptr<Window> Window::GetInstance() {
return Context.lock();
}
std::shared_ptr<Window> Window::CreateInstance(const std::string Name) {
if (Context.expired()) {
auto Shared = std::make_shared<Window>(Name);
Context = Shared;
Shared->Initialize();
return Shared;
}
SPDLOG_DEBUG("Trying to create a context when it already exists. Returning existing.");
return GetInstance();
}
Window::Window(std::string Name) : Name(std::move(Name)), APlayer(nullptr), ControllerApi(nullptr), ResMan(nullptr), Logger(nullptr), Config(nullptr) {
WmApi = nullptr;
RenderingApi = nullptr;
bIsFullscreen = false;
@@ -226,77 +253,91 @@ namespace Ship {
}
Window::~Window() {
SPDLOG_INFO("destruct window");
SPDLOG_DEBUG("destruct window");
}
void Window::CreateDefaults() {
const std::shared_ptr<Mercury> pConf = GlobalCtx2::GetInstance()->GetConfig();
if (pConf->isNewInstance) {
pConf->setInt("Window.Width", 640);
pConf->setInt("Window.Height", 480);
pConf->setBool("Window.Options", false);
pConf->setString("Window.GfxBackend", "");
if (GetConfig()->isNewInstance) {
GetConfig()->setInt("Window.Width", 640);
GetConfig()->setInt("Window.Height", 480);
GetConfig()->setBool("Window.Options", false);
GetConfig()->setString("Window.GfxBackend", "");
pConf->setBool("Window.Fullscreen.Enabled", false);
pConf->setInt("Window.Fullscreen.Width", 1920);
pConf->setInt("Window.Fullscreen.Height", 1080);
GetConfig()->setBool("Window.Fullscreen.Enabled", false);
GetConfig()->setInt("Window.Fullscreen.Width", 1920);
GetConfig()->setInt("Window.Fullscreen.Height", 1080);
pConf->setString("Game.SaveName", "");
pConf->setString("Game.Main Archive", "");
pConf->setString("Game.Patches Archive", "");
GetConfig()->setString("Game.SaveName", "");
GetConfig()->setString("Game.Main Archive", "");
GetConfig()->setString("Game.Patches Archive", "");
pConf->setInt("Shortcuts.Fullscreen", 0x044);
pConf->setInt("Shortcuts.Console", 0x029);
pConf->save();
GetConfig()->setInt("Shortcuts.Fullscreen", 0x044);
GetConfig()->setInt("Shortcuts.Console", 0x029);
GetConfig()->save();
}
}
void Window::Init() {
std::shared_ptr<Mercury> pConf = GlobalCtx2::GetInstance()->GetConfig();
void Window::Initialize() {
InitializeLogging();
InitializeConfiguration();
InitializeResourceManager();
CreateDefaults();
InitializeAudioPlayer();
InitializeControlDeck();
bIsFullscreen = pConf->getBool("Window.Fullscreen.Enabled", false);
bIsFullscreen = GetConfig()->getBool("Window.Fullscreen.Enabled", false);
if (bIsFullscreen) {
dwWidth = pConf->getInt("Window.Fullscreen.Width", 1920);
dwHeight = pConf->getInt("Window.Fullscreen.Height", 1080);
dwWidth = GetConfig()->getInt("Window.Fullscreen.Width", 1920);
dwHeight = GetConfig()->getInt("Window.Fullscreen.Height", 1080);
} else {
dwWidth = pConf->getInt("Window.Width", 640);
dwHeight = pConf->getInt("Window.Height", 480);
dwWidth = GetConfig()->getInt("Window.Width", 640);
dwHeight = GetConfig()->getInt("Window.Height", 480);
}
dwMenubar = pConf->getBool("Window.Options", false);
gfxBackend = pConf->getString("Window.GfxBackend");
dwMenubar = GetConfig()->getBool("Window.Options", false);
const std::string& gfx_backend = GetConfig()->getString("Window.GfxBackend");
InitializeWindowManager();
gfx_init(WmApi, RenderingApi, GetContext()->GetName().c_str(), bIsFullscreen, dwWidth, dwHeight);
gfx_init(WmApi, RenderingApi, GetName().c_str(), bIsFullscreen, dwWidth, dwHeight);
WmApi->set_fullscreen_changed_callback(OnFullscreenChanged);
WmApi->set_keyboard_callbacks(KeyDown, KeyUp, AllKeysUp);
Ship::RegisterHook<Ship::ExitGame>([this]() {
Ship::RegisterHook<ExitGame>([this]() {
ControllerApi->SaveControllerSettings();
});
}
std::string Window::GetAppDirectoryPath() {
#ifdef __APPLE__
FolderManager folderManager;
std::string fpath = std::string(folderManager.pathForDirectory(NSApplicationSupportDirectory, NSUserDomainMask));
fpath.append("/com.shipofharkinian.soh");
return fpath;
#endif
#ifdef __linux__
char* fpath = std::getenv("SHIP_HOME");
if (fpath != NULL)
return std::string(fpath);
#endif
return ".";
}
std::string Window::GetPathRelativeToAppDirectory(const char* path) {
return GetAppDirectoryPath() + "/" + path;
}
void Window::StartFrame() {
gfx_start_frame();
}
void Window::RunCommands(Gfx* Commands, const std::vector<std::unordered_map<Mtx*, MtxF>>& mtx_replacements) {
for (const auto& m : mtx_replacements) {
gfx_run(Commands, m);
gfx_end_frame();
}
}
void Window::SetTargetFps(int fps) {
void Window::SetTargetFps(int32_t fps) {
gfx_set_target_fps(fps);
}
void Window::SetMaximumFrameLatency(int latency) {
void Window::SetMaximumFrameLatency(int32_t latency) {
gfx_set_maximum_frame_latency(latency);
}
@@ -329,17 +370,17 @@ namespace Ship {
void Window::MainLoop(void (*MainFunction)(void)) {
WmApi->main_loop(MainFunction);
}
bool Window::KeyUp(int32_t dwScancode) {
std::shared_ptr<Mercury> pConf = GlobalCtx2::GetInstance()->GetConfig();
if (dwScancode == pConf->getInt("Shortcuts.Fullscreen", 0x044)) {
GlobalCtx2::GetInstance()->GetWindow()->ToggleFullscreen();
bool Window::KeyUp(int32_t dwScancode) {
if (dwScancode == GetInstance()->GetConfig()->getInt("Shortcuts.Fullscreen", 0x044)) {
GetInstance()->ToggleFullscreen();
}
GlobalCtx2::GetInstance()->GetWindow()->SetLastScancode(-1);
GetInstance()->SetLastScancode(-1);
bool bIsProcessed = false;
auto controlDeck = GlobalCtx2::GetInstance()->GetWindow()->GetControlDeck();
auto controlDeck = GetInstance()->GetControlDeck();
const auto pad = dynamic_cast<KeyboardController*>(controlDeck->GetPhysicalDevice(controlDeck->GetNumPhysicalDevices() - 2).get());
if (pad != nullptr) {
if (pad->ReleaseButton(dwScancode)) {
@@ -352,7 +393,7 @@ namespace Ship {
bool Window::KeyDown(int32_t dwScancode) {
bool bIsProcessed = false;
auto controlDeck = GlobalCtx2::GetInstance()->GetWindow()->GetControlDeck();
auto controlDeck = GetInstance()->GetControlDeck();
const auto pad = dynamic_cast<KeyboardController*>(controlDeck->GetPhysicalDevice(controlDeck->GetNumPhysicalDevices() - 2).get());
if (pad != nullptr) {
if (pad->PressButton(dwScancode)) {
@@ -360,14 +401,14 @@ namespace Ship {
}
}
GlobalCtx2::GetInstance()->GetWindow()->SetLastScancode(dwScancode);
GetInstance()->SetLastScancode(dwScancode);
return bIsProcessed;
}
void Window::AllKeysUp(void) {
auto controlDeck = GlobalCtx2::GetInstance()->GetWindow()->GetControlDeck();
auto controlDeck = Window::GetInstance()->GetControlDeck();
const auto pad = dynamic_cast<KeyboardController*>(controlDeck->GetPhysicalDevice(controlDeck->GetNumPhysicalDevices() - 2).get());
if (pad != nullptr) {
pad->ReleaseAllButtons();
@@ -375,15 +416,13 @@ namespace Ship {
}
void Window::OnFullscreenChanged(bool bIsFullscreen) {
std::shared_ptr<Mercury> pConf = GlobalCtx2::GetInstance()->GetConfig();
std::shared_ptr<Mercury> pConf = Window::GetInstance()->GetConfig();
GlobalCtx2::GetInstance()->GetWindow()->bIsFullscreen = bIsFullscreen;
Window::GetInstance()->bIsFullscreen = bIsFullscreen;
pConf->setBool("Window.Fullscreen.Enabled", bIsFullscreen);
GlobalCtx2::GetInstance()->GetWindow()->ShowCursor(!bIsFullscreen);
Window::GetInstance()->ShowCursor(!bIsFullscreen);
}
uint32_t Window::GetCurrentWidth() {
WmApi->get_dimensions(&dwWidth, &dwHeight);
return dwWidth;
@@ -453,4 +492,93 @@ namespace Ship {
void Window::InitializeControlDeck() {
ControllerApi = std::make_shared<ControlDeck>();
}
void Window::InitializeLogging() {
try {
// Setup Logging
spdlog::init_thread_pool(8192, 1);
std::vector<spdlog::sink_ptr> Sinks;
auto SohConsoleSink = std::make_shared<spdlog::sinks::soh_sink_mt>();
SohConsoleSink->set_level(spdlog::level::trace);
Sinks.push_back(SohConsoleSink);
#if (!defined(_WIN32) && !defined(__WIIU__)) || defined(_DEBUG)
auto ConsoleSink = std::make_shared<spdlog::sinks::stdout_color_sink_mt>();
ConsoleSink->set_level(spdlog::level::trace);
Sinks.push_back(ConsoleSink);
#endif
#ifndef __WIIU__
auto logPath = GetPathRelativeToAppDirectory(("logs/" + GetName() + ".log").c_str());
auto FileSink = std::make_shared<spdlog::sinks::rotating_file_sink_mt>(logPath, 1024 * 1024 * 10, 10);
FileSink->set_level(spdlog::level::trace);
Sinks.push_back(FileSink);
#endif
Logger = std::make_shared<spdlog::async_logger>(GetName(), Sinks.begin(), Sinks.end(), spdlog::thread_pool(), spdlog::async_overflow_policy::block);
GetLogger()->set_level(spdlog::level::trace);
#ifndef __WIIU__
GetLogger()->set_pattern("[%Y-%m-%d %H:%M:%S.%e] [%@] [%l] %v");
#else
GetLogger()->set_pattern("[%s:%#] [%l] %v");
#endif
spdlog::register_logger(GetLogger());
spdlog::set_default_logger(GetLogger());
}
catch (const spdlog::spdlog_ex& ex) {
std::cout << "Log initialization failed: " << ex.what() << std::endl;
}
}
void Window::InitializeResourceManager() {
MainPath = Config->getString("Game.Main Archive", GetPathRelativeToAppDirectory("oot.otr"));
PatchesPath = Config->getString("Game.Patches Archive", GetAppDirectoryPath() + "/mods");
ResMan = std::make_shared<ResourceMgr>(GetInstance(), MainPath, PatchesPath);
if (!ResMan->DidLoadSuccessfully())
{
#ifdef _WIN32
MessageBox(nullptr, L"Main OTR file not found!", L"Uh oh", MB_OK);
#elif defined(__SWITCH__)
printf("Main OTR file not found!\n");
#elif defined(__WIIU__)
Ship::WiiU::ThrowMissingOTR(MainPath.c_str());
#else
SPDLOG_ERROR("Main OTR file not found!");
#endif
exit(1);
}
#ifdef __SWITCH__
Ship::Switch::Init(PostInitPhase);
#endif
}
void Window::InitializeConfiguration() {
Config = std::make_shared<Mercury>(GetPathRelativeToAppDirectory("shipofharkinian.json"));
}
void Window::WriteSaveFile(const std::filesystem::path& savePath, const uintptr_t addr, void* dramAddr, const size_t size) {
std::ofstream saveFile = std::ofstream(savePath, std::fstream::in | std::fstream::out | std::fstream::binary);
saveFile.seekp(addr);
saveFile.write((char*)dramAddr, size);
saveFile.close();
}
void Window::ReadSaveFile(std::filesystem::path savePath, uintptr_t addr, void* dramAddr, size_t size) {
std::ifstream saveFile = std::ifstream(savePath, std::fstream::in | std::fstream::out | std::fstream::binary);
// If the file doesn't exist, initialize DRAM
if (saveFile.good()) {
saveFile.seekg(addr);
saveFile.read((char*)dramAddr, size);
}
else {
memset(dramAddr, 0, size);
}
saveFile.close();
}
}
+40 -18
View File
@@ -1,27 +1,36 @@
#pragma once
#include <memory>
#include "PR/ultra64/gbi.h"
#include "Lib/Fast3D/gfx_pc.h"
#include "Controller.h"
#include "GlobalCtx2.h"
#include "ControlDeck.h"
#include <memory>
#include <filesystem>
#include "spdlog/spdlog.h"
#include "ControlDeck.h"
#include "AudioPlayer.h"
#include "Lib/Fast3D/gfx_window_manager_api.h"
#include "Lib/Mercury/Mercury.h"
struct GfxRenderingAPI;
struct GfxWindowManagerAPI;
namespace Ship {
class AudioPlayer;
class ResourceMgr;
class Window {
public:
Window(std::shared_ptr<GlobalCtx2> Context);
static std::shared_ptr<Window> GetInstance();
static std::shared_ptr<Window> CreateInstance(const std::string Name);
static std::string GetAppDirectoryPath();
static std::string GetPathRelativeToAppDirectory(const char* path);
Window(std::string Name);
~Window();
void WriteSaveFile(const std::filesystem::path& savePath, uintptr_t addr, void* dramAddr, size_t size);
void ReadSaveFile(std::filesystem::path savePath, uintptr_t addr, void* dramAddr, size_t size);
void CreateDefaults();
void MainLoop(void (*MainFunction)(void));
void Init();
void Initialize();
void StartFrame();
void RunCommands(Gfx* Commands, const std::vector<std::unordered_map<Mtx*, MtxF>>& mtx_replacements);
void SetTargetFps(int fps);
void SetMaximumFrameLatency(int latency);
void SetTargetFps(int32_t fps);
void SetMaximumFrameLatency(int32_t latency);
void GetPixelDepthPrepare(float x, float y);
uint16_t GetPixelDepth(float x, float y);
void ToggleFullscreen();
@@ -32,29 +41,39 @@ namespace Ship {
uint32_t GetCurrentHeight();
uint32_t GetMenuBar() { return dwMenubar; }
void SetMenuBar(uint32_t dwMenuBar) { this->dwMenubar = dwMenuBar; }
std::string GetName() { return Name; }
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); }
int32_t GetLastScancode() { return lastScancode; };
void SetLastScancode(int32_t scanCode) { lastScancode = scanCode; };
std::shared_ptr<ResourceMgr> GetResourceManager() { return ResMan; }
std::shared_ptr<Mercury> GetConfig() { return Config; }
std::shared_ptr<spdlog::logger> GetLogger() { return Logger; }
const char* GetKeyName(int32_t scancode) { return WmApi->get_key_name(scancode); }
int32_t GetLastScancode() { return lastScancode; }
void SetLastScancode(int32_t scanCode) { lastScancode = scanCode; }
protected:
Window() = default;
private:
static bool KeyDown(int32_t dwScancode);
static bool KeyUp(int32_t dwScancode);
static void AllKeysUp(void);
static void OnFullscreenChanged(bool bIsNowFullscreen);
static std::weak_ptr<Window> Context;
void InitializeConfiguration();
void InitializeControlDeck();
void InitializeAudioPlayer();
void InitializeLogging();
void InitializeResourceManager();
void InitializeWindowManager();
std::weak_ptr<GlobalCtx2> Context;
std::shared_ptr<spdlog::logger> Logger;
std::shared_ptr<Mercury> Config; // Config needs to be after the Window because we call the Window during it's destructor.
std::shared_ptr<ResourceMgr> ResMan;
std::shared_ptr<AudioPlayer> APlayer;
std::shared_ptr<ControlDeck> ControllerApi;
std::string gfxBackend;
std::string gfxBackend;
GfxRenderingAPI* RenderingApi;
GfxWindowManagerAPI* WmApi;
bool bIsFullscreen;
@@ -62,5 +81,8 @@ namespace Ship {
uint32_t dwHeight;
uint32_t dwMenubar;
int32_t lastScancode;
std::string Name;
std::string MainPath;
std::string PatchesPath;
};
}