diff options
| author | Lywx <kiritodev01@gmail.com> | 2025-01-15 19:43:08 -0600 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-01-15 19:43:08 -0600 |
| commit | beee77da2a199c73fef60f83cde8e2937fb67f2e (patch) | |
| tree | 90bdf7a5abc4da4d952cb4f910ba1cabc8b19c5e /src | |
| parent | 5aac47e2fafb99678fc21e7839ec0e9cc7d65f70 (diff) | |
| parent | 66db2a93282908d18abeba8b10b3c911e6b53210 (diff) | |
Merge pull request #131 from HarbourMasters/otr-ig-gen
Reimplemented built-in generation
Diffstat (limited to 'src')
| -rw-r--r-- | src/port/Engine.cpp | 85 | ||||
| -rw-r--r-- | src/port/Engine.h | 12 | ||||
| -rw-r--r-- | src/port/extractor/GameExtractor.cpp | 58 | ||||
| -rw-r--r-- | src/port/extractor/GameExtractor.h | 17 | ||||
| -rw-r--r-- | src/port/ui/UIWidgets.cpp | 7 |
5 files changed, 163 insertions, 16 deletions
diff --git a/src/port/Engine.cpp b/src/port/Engine.cpp index 9d577583..3cfa5086 100644 --- a/src/port/Engine.cpp +++ b/src/port/Engine.cpp @@ -2,6 +2,7 @@ #include "ui/ImguiUI.h" #include "StringHelper.h" +#include "extractor/GameExtractor.h" #include "libultraship/src/Context.h" #include "resource/type/ResourceType.h" #include "resource/importers/AnimFactory.h" @@ -40,14 +41,12 @@ #include "port/mods/PortEnhancements.h" #include <Fast3D/gfx_pc.h> -#include <SDL2/SDL.h> #include <filesystem> namespace fs = std::filesystem; extern "C" { bool prevAltAssets = false; -float gInterpolationStep = 0.0f; #include <sf64thread.h> #include <macros.h> #include "sf64audio_provisional.h" @@ -59,14 +58,32 @@ static GamePool MemoryPool = { .chunk = 1024 * 512, .cursor = 0, .length = 0, .m GameEngine::GameEngine() { std::vector<std::string> archiveFiles; - if (const std::string cube_path = Ship::Context::GetPathRelativeToAppDirectory("starship.o2r"); - std::filesystem::exists(cube_path)) { - archiveFiles.push_back(cube_path); + const std::string main_path = Ship::Context::GetPathRelativeToAppDirectory("sf64.o2r"); + const std::string assets_path = Ship::Context::GetPathRelativeToAppDirectory("starship.o2r"); + +#ifdef _WIN32 + AllocConsole(); +#endif + + if (std::filesystem::exists(main_path)) { + archiveFiles.push_back(main_path); + } else { + if (ShowYesNoBox("No O2R Files", "No O2R files found. Generate one now?") == IDYES) { + if(!GenAssetFile()){ + ShowMessage("Error", "An error occured, no O2R file was generated.\n\nExiting..."); + exit(1); + } else { + archiveFiles.push_back(main_path); + } + } else { + exit(1); + } } - if (const std::string sm64_otr_path = Ship::Context::GetPathRelativeToAppDirectory("sf64.o2r"); - std::filesystem::exists(sm64_otr_path)) { - archiveFiles.push_back(sm64_otr_path); + + if (std::filesystem::exists(assets_path)) { + archiveFiles.push_back(assets_path); } + if (const std::string patches_path = Ship::Context::GetPathRelativeToAppDirectory("mods"); !patches_path.empty() && std::filesystem::exists(patches_path)) { if (std::filesystem::is_directory(patches_path)) { @@ -187,6 +204,25 @@ GameEngine::GameEngine() { context->GetResourceManager()->SetAltAssetsEnabled(prevAltAssets); } +bool GameEngine::GenAssetFile() { + auto extractor = new GameExtractor(); + + if (!extractor->SelectGameFromUI()) { + ShowMessage("Error", "No ROM selected.\n\nExiting..."); + exit(1); + } + + auto game = extractor->ValidateChecksum(); + if (!game.has_value()) { + ShowMessage("Unsupported ROM", "The provided ROM is not supported.\n\nCheck the readme for a list of supported versions."); + exit(1); + } + + ShowMessage(("Found " + game.value()).c_str(), "The extraction process will now begin.\n\nThis may take a few minutes.", SDL_MESSAGEBOX_INFORMATION); + + return extractor->GenerateOTR(); +} + void GameEngine::Create() { const auto instance = Instance = new GameEngine(); instance->AudioInit(); @@ -421,6 +457,39 @@ uint32_t GameEngine::GetInterpolationFPS() { CVarGetInteger("gInterpolationFPS", 60)); } +void GameEngine::ShowMessage(const char* title, const char* message, SDL_MessageBoxFlags type) { +#if defined(__SWITCH__) + SPDLOG_ERROR(message); +#else + SDL_ShowSimpleMessageBox(type, title, message, nullptr); + SPDLOG_ERROR(message); +#endif +} + +int GameEngine::ShowYesNoBox(const char* title, const char* box) { + int ret; +#ifdef _WIN32 + ret = MessageBoxA(nullptr, box, title, MB_YESNO | MB_ICONQUESTION); +#else + SDL_MessageBoxData boxData = { 0 }; + SDL_MessageBoxButtonData buttons[2] = { { 0 } }; + + buttons[0].buttonid = IDYES; + buttons[0].text = "Yes"; + buttons[0].flags = SDL_MESSAGEBOX_BUTTON_RETURNKEY_DEFAULT; + buttons[1].buttonid = IDNO; + buttons[1].text = "No"; + buttons[1].flags = SDL_MESSAGEBOX_BUTTON_ESCAPEKEY_DEFAULT; + boxData.numbuttons = 2; + boxData.flags = SDL_MESSAGEBOX_INFORMATION; + boxData.message = box; + boxData.title = title; + boxData.buttons = buttons; + SDL_ShowMessageBox(&boxData, &ret); +#endif + return ret; +} + extern "C" uint32_t GameEngine_GetSampleRate() { auto player = Ship::Context::GetInstance()->GetAudio()->GetAudioPlayer(); if (player == nullptr) { diff --git a/src/port/Engine.h b/src/port/Engine.h index 62af3283..ef60f012 100644 --- a/src/port/Engine.h +++ b/src/port/Engine.h @@ -12,10 +12,16 @@ struct GamePool { #ifdef __cplusplus #include <vector> +#include <SDL2/SDL.h> #include <Fast3D/gfx_pc.h> #include "libultraship/src/Context.h" - +#ifndef IDYES +#define IDYES 6 +#endif +#ifndef IDNO +#define IDNO 7 +#endif class GameEngine { public: @@ -24,6 +30,7 @@ class GameEngine { std::shared_ptr<Ship::Context> context; GameEngine(); + static bool GenAssetFile(); static void Create(); void StartFrame() const; static void HandleAudioThread(); @@ -37,6 +44,9 @@ class GameEngine { static void Destroy(); static void ProcessGfxCommands(Gfx* commands); static uint32_t GetInterpolationFPS(); + + static int ShowYesNoBox(const char* title, const char* box); + static void ShowMessage(const char* title, const char* message, SDL_MessageBoxFlags type = SDL_MESSAGEBOX_ERROR); }; extern "C" void* GameEngine_Malloc(size_t size); diff --git a/src/port/extractor/GameExtractor.cpp b/src/port/extractor/GameExtractor.cpp new file mode 100644 index 00000000..3f167c86 --- /dev/null +++ b/src/port/extractor/GameExtractor.cpp @@ -0,0 +1,58 @@ +#include "GameExtractor.h" + +#include <fstream> + +#include "Context.h" +#include "spdlog/spdlog.h" +#include "portable-file-dialogs.h" +#include <port/Engine.h> + +std::unordered_map<std::string, std::string> mGameList = { + { "d8b1088520f7c5f81433292a9258c1184afa1457", "Star Fox 64 (U) (V1.0)" }, + { "63b69f0ef36306257481afc250f9bc304c7162b2", "Star Fox 64 (U) (V1.0) (Uncompressed)" }, + { "09f0d105f476b00efa5303a3ebc42e60a7753b7a", "Star Fox 64 (U) (V1.1)" }, + { "f7475fb11e7e6830f82883412638e8390791ab87", "Star Fox 64 (U) (V1.1) (Uncompressed)" }, +}; + +bool GameExtractor::SelectGameFromUI() { +#if !defined(__IOS__) || !defined(__ANDROID__) || !defined(__SWITCH__) + auto selection = pfd::open_file("Select a file", ".", { "N64 Roms", "*.z64 *.n64 *.v64" }).result(); + + if (selection.empty()) { + return false; + } + + this->mGamePath = selection[0]; +#else + this->mGamePath = Ship::Context::GetPathRelativeToAppDirectory("baserom.us.rev1.z64"); +#endif + + std::ifstream file(this->mGamePath, std::ios::binary); + this->mGameData = std::vector<uint8_t>( std::istreambuf_iterator( file ), {} ); + file.close(); + return true; +} + +std::optional<std::string> GameExtractor::ValidateChecksum() const { + const auto rom = new N64::Cartridge(this->mGameData); + rom->Initialize(); + auto hash = rom->GetHash(); + + if (mGameList.find(hash) == mGameList.end()) { + return std::nullopt; + } + + return mGameList[hash]; +} + +bool GameExtractor::GenerateOTR() const { + Companion::Instance = new Companion(this->mGameData, ArchiveType::O2R, false); + + try { + Companion::Instance->Init(ExportType::Binary); + } catch (const std::exception& e) { + return false; + } + + return true; +}
\ No newline at end of file diff --git a/src/port/extractor/GameExtractor.h b/src/port/extractor/GameExtractor.h new file mode 100644 index 00000000..a6423495 --- /dev/null +++ b/src/port/extractor/GameExtractor.h @@ -0,0 +1,17 @@ +#pragma once + +#include "Companion.h" +#include <filesystem> +#include <vector> +#include <cstdint> + +class GameExtractor { +public: + static bool GenAssetFile(); + std::optional<std::string> ValidateChecksum() const; + bool SelectGameFromUI(); + bool GenerateOTR() const; +private: + fs::path mGamePath; + std::vector<uint8_t> mGameData; +};
\ No newline at end of file diff --git a/src/port/ui/UIWidgets.cpp b/src/port/ui/UIWidgets.cpp index 3bac9f3a..00f6499b 100644 --- a/src/port/ui/UIWidgets.cpp +++ b/src/port/ui/UIWidgets.cpp @@ -1,10 +1,3 @@ -// -// UIWidgets.cpp -// soh -// -// Created by David Chavez on 25.08.22. -// - #include "UIWidgets.h" #include "libultraship/src/Context.h" |
