LUS Cleanup: Merge Window and GlobalCtx2 classes. (#1259)

* Merges GlobalCtx2 and Window classes.

* Includes condition variable in File.

* add mac specific include

* sstream to get past "implicit instantiation of undefined template" error

* switch/wiiu includes

* that file doesn't exist

* more wii u globalctx2 stuff

Co-authored-by: briaguya <briaguya@alice>
pull/1275/head
Kenix3 2022-08-21 21:08:01 -04:00 committed by GitHub
parent ad8179287e
commit 51e4485966
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
35 changed files with 349 additions and 419 deletions

View File

@ -1,7 +1,5 @@
#pragma once
#include <cstdint>
struct Vec3f
{
float x, y, z;

View File

@ -10,7 +10,6 @@
#include <string>
#include <vector>
#include "Resource.h"
//#include "Lib/StrHash64.h"
#include "StormLib.h"

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"

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) {

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 {

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]];

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

View File

@ -2,7 +2,8 @@
#include <string>
#include <memory>
#include "GlobalCtx2.h"
#include <mutex>
#include <condition_variable>
namespace Ship {
class Archive;

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) {

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();
}
}

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

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"
@ -345,27 +344,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 +400,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 +465,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 +474,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 +499,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");
@ -883,8 +882,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 +920,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 {

View File

@ -16,7 +16,7 @@ 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);
}
@ -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();

View File

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

View File

@ -16,7 +16,6 @@
#include "gfx_cc.h"
#include "gfx_rendering_api.h"
#include "../../GlobalCtx2.h"
#include "gfx_pc.h"
#include "gfx_wiiu.h"

View File

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

View File

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

View File

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

View File

@ -1,4 +1,5 @@
#include "Resource.h"
#include "StrHash.h"
namespace Ship
{

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

View File

@ -9,7 +9,7 @@
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;

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,7 +34,7 @@ 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);
@ -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;

View File

@ -1,5 +1,5 @@
#include "SDLController.h"
#include "GlobalCtx2.h"
#include "spdlog/spdlog.h"
#include "Window.h"
#include <Utils/StringHelper.h>

View File

@ -1,6 +1,5 @@
#ifdef __WIIU__
#include "WiiUController.h"
#include "GlobalCtx2.h"
#include "Window.h"
#include "ImGuiImpl.h"

View File

@ -1,6 +1,5 @@
#ifdef __WIIU__
#include "WiiUGamepad.h"
#include "GlobalCtx2.h"
#include "ImGuiImpl.h"
#include "WiiUImpl.h"

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();
}
}

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;
}
@ -80,20 +88,20 @@ extern "C" {
if (SohImGui::controller->Opened) 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,85 @@ 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
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 +364,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 +387,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 +395,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 +410,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 +486,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*)