mirror of
https://github.com/izzy2lost/2ship2harkinian-Android.git
synced 2026-06-19 01:20:08 -07:00
Add support for dropping various save formats into the game window (#404)
This commit is contained in:
+1
-1
Submodule libultraship updated: ff5245f505...6bbc13433a
@@ -54,6 +54,7 @@ CrowdControl* CrowdControl::Instance;
|
||||
#include "2s2h/Enhancements/GfxPatcher/AuthenticGfxPatches.h"
|
||||
#include "2s2h/DeveloperTools/DebugConsole.h"
|
||||
#include "2s2h/DeveloperTools/DeveloperTools.h"
|
||||
#include "2s2h/SaveManager/SaveManager.h"
|
||||
|
||||
// Resource Types/Factories
|
||||
#include "resource/type/Array.h"
|
||||
@@ -402,6 +403,52 @@ extern "C" void OTRExtScanner() {
|
||||
}
|
||||
}
|
||||
|
||||
std::string SanitizePath(std::string stringValue) {
|
||||
// Add backslashes.
|
||||
for (auto i = stringValue.begin();;) {
|
||||
auto const pos =
|
||||
std::find_if(i, stringValue.end(), [](char const c) { return '\\' == c || '\'' == c || '"' == c; });
|
||||
if (pos == stringValue.end()) {
|
||||
break;
|
||||
}
|
||||
i = std::next(stringValue.insert(pos, '\\'), 2);
|
||||
}
|
||||
|
||||
// Removes others.
|
||||
stringValue.erase(std::remove_if(stringValue.begin(), stringValue.end(),
|
||||
[](char const c) { return '\n' == c || '\r' == c || '\0' == c || '\x1A' == c; }),
|
||||
stringValue.end());
|
||||
|
||||
return stringValue;
|
||||
}
|
||||
|
||||
void Ben_ProcessDroppedFiles(std::string filePath) {
|
||||
SPDLOG_INFO("Processing dropped file: {}", filePath);
|
||||
|
||||
bool handled = false;
|
||||
|
||||
if (!handled) {
|
||||
handled = SaveManager_HandleFileDropped(filePath);
|
||||
}
|
||||
|
||||
if (!handled) {
|
||||
handled = BinarySaveConverter_HandleFileDropped(filePath);
|
||||
}
|
||||
|
||||
// if (!handled) {
|
||||
// handled = Randomizer_HandleFileDropped(filePath);
|
||||
// }
|
||||
|
||||
// if (!handled) {
|
||||
// handled = Presets_HandleFileDropped(filePath);
|
||||
// }
|
||||
|
||||
if (!handled) {
|
||||
auto gui = Ship::Context::GetInstance()->GetWindow()->GetGui();
|
||||
gui->GetGameOverlay()->TextDrawNotification(30.0f, true, "Unsupported file dropped, ignoring");
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" void InitOTR() {
|
||||
#if not defined(__SWITCH__) && not defined(__WIIU__)
|
||||
if (!std::filesystem::exists(Ship::Context::LocateFileAcrossAppDirs("mm.zip", appShortName))) {
|
||||
@@ -444,6 +491,9 @@ extern "C" void InitOTR() {
|
||||
// OTRMessage_Init();
|
||||
OTRAudio_Init();
|
||||
// OTRExtScanner();
|
||||
|
||||
GameInteractor::Instance->RegisterGameHook<GameInteractor::OnFileDropped>(Ben_ProcessDroppedFiles);
|
||||
|
||||
time_t now = time(NULL);
|
||||
tm* tm_now = localtime(&now);
|
||||
if (tm_now->tm_mon == 11 && tm_now->tm_mday >= 24 && tm_now->tm_mday <= 25) {
|
||||
@@ -614,6 +664,16 @@ extern "C" void Graph_StartFrame() {
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (CVarGetInteger(CVAR_NEW_FILE_DROPPED, 0)) {
|
||||
std::string filePath = SanitizePath(CVarGetString(CVAR_DROPPED_FILE, ""));
|
||||
if (!filePath.empty()) {
|
||||
GameInteractor::Instance->ExecuteHooks<GameInteractor::OnFileDropped>(filePath);
|
||||
}
|
||||
CVarClear(CVAR_NEW_FILE_DROPPED);
|
||||
CVarClear(CVAR_DROPPED_FILE);
|
||||
}
|
||||
|
||||
OTRGlobals::Instance->context->GetWindow()->StartFrame();
|
||||
}
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
#define GAME_INTERACTOR_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
#include <string>
|
||||
extern "C" {
|
||||
#endif
|
||||
#include "z64actor.h"
|
||||
@@ -241,6 +242,8 @@ class GameInteractor {
|
||||
}
|
||||
};
|
||||
|
||||
DEFINE_HOOK(OnFileDropped, (std::string path));
|
||||
|
||||
DEFINE_HOOK(OnGameStateMainFinish, ());
|
||||
DEFINE_HOOK(OnGameStateDrawFinish, ());
|
||||
DEFINE_HOOK(OnGameStateUpdate, ());
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -8,6 +8,11 @@
|
||||
#include "macros.h"
|
||||
#include "BenJsonConversions.hpp"
|
||||
|
||||
extern "C" {
|
||||
#include "src/overlays/gamestates/ovl_file_choose/z_file_select.h"
|
||||
extern FileSelectState* gFileSelectState;
|
||||
}
|
||||
|
||||
// This entire thing is temporary until we have a more robust save system that
|
||||
// supports backwards compatability, migrations, threaded saving, save sections, etc.
|
||||
typedef enum FlashSlotFile {
|
||||
@@ -99,6 +104,79 @@ int SaveManager_ReadSaveFile(std::filesystem::path fileName, nlohmann::json& j)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int SaveManager_GetOpenFileSlot() {
|
||||
std::string fileName = "save_0.sav";
|
||||
if (!std::filesystem::exists(savesFolderPath / fileName)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
fileName = "save_2.sav";
|
||||
if (!std::filesystem::exists(savesFolderPath / fileName)) {
|
||||
return 2;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
bool SaveManager_HandleFileDropped(std::string filePath) {
|
||||
try {
|
||||
std::ifstream fileStream(filePath);
|
||||
|
||||
if (!fileStream.is_open()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check if first byte is "{"
|
||||
if (fileStream.peek() != '{') {
|
||||
return false;
|
||||
}
|
||||
|
||||
nlohmann::json j;
|
||||
try {
|
||||
fileStream >> j;
|
||||
} catch (nlohmann::json::parse_error& e) {
|
||||
SPDLOG_ERROR("Failed to parse JSON: {}", e.what());
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!j.contains("type") || j["type"] != "2S2H_SAVE") {
|
||||
SPDLOG_ERROR("Invalid save file type");
|
||||
return false;
|
||||
}
|
||||
|
||||
int saveSlot = SaveManager_GetOpenFileSlot();
|
||||
if (saveSlot == -1) {
|
||||
SPDLOG_ERROR("No save slot available");
|
||||
auto gui = Ship::Context::GetInstance()->GetWindow()->GetGui();
|
||||
gui->GetGameOverlay()->TextDrawNotification(30.0f, true, "No save slot available");
|
||||
return true;
|
||||
}
|
||||
|
||||
std::string fileName = "save_" + std::to_string(saveSlot) + ".sav";
|
||||
|
||||
SaveManager_WriteSaveFile(fileName, j);
|
||||
|
||||
if (gFileSelectState != NULL) {
|
||||
func_801457CC(&gFileSelectState->state, &gFileSelectState->sramCtx);
|
||||
if (gFileSelectState->menuMode == FS_MENU_MODE_CONFIG && gFileSelectState->configMode == CM_MAIN_MENU) {
|
||||
gFileSelectState->configMode = CM_FADE_IN_START;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
} catch (std::exception& e) {
|
||||
SPDLOG_ERROR("Failed to load file: {}", e.what());
|
||||
auto gui = Ship::Context::GetInstance()->GetWindow()->GetGui();
|
||||
gui->GetGameOverlay()->TextDrawNotification(30.0f, true, "Failed to load file");
|
||||
return false;
|
||||
} catch (...) {
|
||||
SPDLOG_ERROR("Failed to load file");
|
||||
auto gui = Ship::Context::GetInstance()->GetWindow()->GetGui();
|
||||
gui->GetGameOverlay()->TextDrawNotification(30.0f, true, "Failed to load file");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" void SaveManager_SysFlashrom_WriteData(u8* saveBuffer, u32 pageNum, u32 pageCount) {
|
||||
FlashSlotFile flashSlotFile = FLASH_SLOT_FILE_UNAVAILABLE;
|
||||
bool isBackup = false;
|
||||
@@ -132,6 +210,7 @@ extern "C" void SaveManager_SysFlashrom_WriteData(u8* saveBuffer, u32 pageNum, u
|
||||
|
||||
j["save"] = save;
|
||||
j["version"] = CURRENT_SAVE_VERSION;
|
||||
j["type"] = "2S2H_SAVE";
|
||||
|
||||
SaveManager_WriteSaveFile(fileName, j);
|
||||
} else {
|
||||
@@ -156,6 +235,7 @@ extern "C" void SaveManager_SysFlashrom_WriteData(u8* saveBuffer, u32 pageNum, u
|
||||
nlohmann::json j = saveContext;
|
||||
|
||||
j["version"] = CURRENT_SAVE_VERSION;
|
||||
j["type"] = "2S2H_SAVE";
|
||||
|
||||
SaveManager_WriteSaveFile(fileName, j);
|
||||
} else {
|
||||
|
||||
@@ -4,7 +4,12 @@
|
||||
|
||||
#include <libultraship/libultraship.h>
|
||||
|
||||
#ifndef __cplusplus
|
||||
#ifdef __cplusplus
|
||||
bool SaveManager_HandleFileDropped(std::string filePath);
|
||||
bool BinarySaveConverter_HandleFileDropped(std::string filePath);
|
||||
int SaveManager_GetOpenFileSlot();
|
||||
void SaveManager_WriteSaveFile(std::filesystem::path fileName, nlohmann::json j);
|
||||
#else
|
||||
void SaveManager_SysFlashrom_WriteData(u8* addr, u32 pageNum, u32 pageCount);
|
||||
s32 SaveManager_SysFlashrom_ReadData(void* addr, u32 pageNum, u32 pageCount);
|
||||
#endif
|
||||
|
||||
@@ -4,7 +4,8 @@
|
||||
#include "libc/stdarg.h"
|
||||
#include <string.h>
|
||||
|
||||
#ifndef __GNUC__
|
||||
// 2S2H This file might just outright get removed soon. Ifdeffing for now
|
||||
#if 0
|
||||
//void bcopy(void* __src, void* __dest, int __n);
|
||||
//int bcmp(void* __s1, void* __s2, int __n);
|
||||
//void bzero(void* begin, int length);
|
||||
|
||||
@@ -21,6 +21,8 @@ f32 D_808144F14 = 8.0f;
|
||||
f32 D_808144F18 = 100.0f;
|
||||
s32 D_808144F1C = 0;
|
||||
|
||||
FileSelectState* gFileSelectState = NULL;
|
||||
|
||||
static Gfx sScreenFillSetupDL[] = {
|
||||
gsDPPipeSync(),
|
||||
gsSPClearGeometryMode(G_ZBUFFER | G_SHADE | G_CULL_BOTH | G_FOG | G_LIGHTING | G_TEXTURE_GEN |
|
||||
@@ -2533,11 +2535,13 @@ void FileSelect_InitContext(GameState* thisx) {
|
||||
|
||||
void FileSelect_Destroy(GameState* this) {
|
||||
ShrinkWindow_Destroy();
|
||||
gFileSelectState = NULL;
|
||||
}
|
||||
|
||||
void FileSelect_Init(GameState* thisx) {
|
||||
s32 pad;
|
||||
FileSelectState* this = (FileSelectState*)thisx;
|
||||
gFileSelectState = this;
|
||||
size_t size;
|
||||
|
||||
GameState_SetFramerateDivisor(&this->state, 1);
|
||||
|
||||
Reference in New Issue
Block a user