mirror of
https://github.com/HarbourMasters/2ship2harkinian.git
synced 2024-11-27 00:00:32 +00:00
Archive version checking and regeneration (#822)
* Add archive version checking and regeneration * update building docs and copy assets for visual studio
This commit is contained in:
parent
be70a5a123
commit
449a2ebc70
@ -22,7 +22,7 @@ It is recommended that you install Python and Git standalone, the install proces
|
|||||||
|
|
||||||
_Note: Be sure to either clone with the ``--recursive`` flag or do ``git submodule update --init`` after cloning to pull in the libultraship submodule!_
|
_Note: Be sure to either clone with the ``--recursive`` flag or do ``git submodule update --init`` after cloning to pull in the libultraship submodule!_
|
||||||
|
|
||||||
2. Place one or more [compatible](#compatible-roms) roms in the `OTRExporter` directory with namings of your choice
|
2. After setup and initial build, use the built-in O2R extraction to make your mm.o2r file.
|
||||||
|
|
||||||
_Note: Instructions assume using powershell_
|
_Note: Instructions assume using powershell_
|
||||||
```powershell
|
```powershell
|
||||||
@ -30,22 +30,17 @@ _Note: Instructions assume using powershell_
|
|||||||
cd 2ship2harkinian
|
cd 2ship2harkinian
|
||||||
|
|
||||||
# Setup cmake project
|
# Setup cmake project
|
||||||
& 'C:\Program Files\CMake\bin\cmake' -S . -B "build/x64" -G "Visual Studio 17 2022" -T v143 -A x64 # -DCMAKE_BUILD_TYPE:STRING=Release (if you're packaging)
|
# Add `-DCMAKE_BUILD_TYPE:STRING=Release` if you're packaging
|
||||||
# Extract assets & generate OTR (run this anytime you need to regenerate OTR)
|
& 'C:\Program Files\CMake\bin\cmake' -S . -B "build/x64" -G "Visual Studio 17 2022" -T v143 -A x64
|
||||||
& 'C:\Program Files\CMake\bin\cmake.exe' --build .\build\x64 --target ExtractAssets # --config Release (if you're packaging)
|
|
||||||
# Compile project
|
|
||||||
& 'C:\Program Files\CMake\bin\cmake.exe' --build .\build\x64 # --config Release (if you're packaging)
|
|
||||||
|
|
||||||
# Now you can run the executable in .\build\x64
|
# Generate 2ship.o2r
|
||||||
|
|
||||||
# If you need to clean the project you can run
|
|
||||||
& 'C:\Program Files\CMake\bin\cmake.exe' --build .\build\x64 --target clean
|
|
||||||
|
|
||||||
# If you need to regenerate the asset headers to check them into source
|
|
||||||
& 'C:\Program Files\CMake\bin\cmake.exe' --build .\build\x64 --target ExtractAssetHeaders
|
|
||||||
|
|
||||||
# If you need a newer 2ship.o2r only
|
|
||||||
& 'C:\Program Files\CMake\bin\cmake.exe' --build .\build\x64 --target Generate2ShipOtr
|
& 'C:\Program Files\CMake\bin\cmake.exe' --build .\build\x64 --target Generate2ShipOtr
|
||||||
|
|
||||||
|
# Compile project
|
||||||
|
# Add `--config Release` if you're packaging
|
||||||
|
& 'C:\Program Files\CMake\bin\cmake.exe' --build .\build\x64
|
||||||
|
|
||||||
|
# Now you can run the executable in .\build\x64 or run in Visual Studio
|
||||||
```
|
```
|
||||||
|
|
||||||
### Developing 2S2H
|
### Developing 2S2H
|
||||||
@ -76,6 +71,19 @@ cd "build/x64"
|
|||||||
& 'C:\Program Files\CMake\bin\cpack.exe' -G ZIP
|
& 'C:\Program Files\CMake\bin\cpack.exe' -G ZIP
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### Additional CMake Targets
|
||||||
|
#### Clean
|
||||||
|
```powershell
|
||||||
|
# If you need to clean the project you can run
|
||||||
|
C:\Program Files\CMake\bin\cmake.exe --build build-cmake --target clean
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Regenerate Asset Headers
|
||||||
|
```powershell
|
||||||
|
# If you need to regenerate the asset headers to check them into source
|
||||||
|
C:\Program Files\CMake\bin\cmake.exe --build build-cmake --target ExtractAssetHeaders
|
||||||
|
```
|
||||||
|
|
||||||
## Linux
|
## Linux
|
||||||
### Install dependencies
|
### Install dependencies
|
||||||
#### Debian/Ubuntu
|
#### Debian/Ubuntu
|
||||||
@ -124,13 +132,16 @@ cd 2ship2harkinian
|
|||||||
git submodule update --init
|
git submodule update --init
|
||||||
|
|
||||||
# Generate Ninja project
|
# Generate Ninja project
|
||||||
cmake -H. -Bbuild-cmake -GNinja # -DCMAKE_BUILD_TYPE:STRING=Release (if you're packaging) -DPython3_EXECUTABLE=$(which python3) (if you are using non-standard Python installations such as PyEnv)
|
# Add `-DCMAKE_BUILD_TYPE:STRING=Release` if you're packaging
|
||||||
|
# Add `-DPython3_EXECUTABLE=$(which python3)` if you are using non-standard Python installations such as PyEnv
|
||||||
|
cmake -H. -Bbuild-cmake -GNinja
|
||||||
|
|
||||||
# Generate 2ship.o2r
|
# Generate 2ship.o2r
|
||||||
cmake --build build-cmake --target Generate2ShipOtr
|
cmake --build build-cmake --target Generate2ShipOtr
|
||||||
|
|
||||||
# Compile the project
|
# Compile the project
|
||||||
cmake --build build-cmake # --config Release (if you're packaging)
|
# Add `--config Release` if you're packaging
|
||||||
|
cmake --build build-cmake
|
||||||
|
|
||||||
# Now you can run the executable in ./build-cmake/mm/2s2h.elf
|
# Now you can run the executable in ./build-cmake/mm/2s2h.elf
|
||||||
# To develop the project open the repository in VSCode (or your preferred editor)
|
# To develop the project open the repository in VSCode (or your preferred editor)
|
||||||
@ -157,7 +168,6 @@ cmake --build build-cmake --target clean
|
|||||||
#### Regenerate Asset Headers
|
#### Regenerate Asset Headers
|
||||||
```bash
|
```bash
|
||||||
# If you need to regenerate the asset headers to check them into source
|
# If you need to regenerate the asset headers to check them into source
|
||||||
cp <path to your ROM> OTRExporter
|
|
||||||
cmake --build build-cmake --target ExtractAssetHeaders
|
cmake --build build-cmake --target ExtractAssetHeaders
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -174,27 +184,21 @@ git clone https://github.com/HarbourMasters/2ship2harkinian.git
|
|||||||
cd 2ship2harkinian
|
cd 2ship2harkinian
|
||||||
# Clone the submodule libultraship
|
# Clone the submodule libultraship
|
||||||
git submodule update --init
|
git submodule update --init
|
||||||
# Copy the baserom to the OTRExporter folder
|
|
||||||
cp <path to your ROM> OTRExporter
|
|
||||||
# Generate Ninja project
|
# Generate Ninja project
|
||||||
cmake -H. -Bbuild-cmake -GNinja # -DCMAKE_BUILD_TYPE:STRING=Release (if you're packaging)
|
# Add `-DCMAKE_BUILD_TYPE:STRING=Release` if you're packaging
|
||||||
# Extract assets & generate OTR (run this anytime you need to regenerate OTR)
|
cmake -H. -Bbuild-cmake -GNinja
|
||||||
cmake --build build-cmake --target ExtractAssets
|
|
||||||
|
# Generate 2ship.o2r
|
||||||
|
cmake --build build-cmake --target Generate2ShipOtr
|
||||||
|
|
||||||
# Compile the project
|
# Compile the project
|
||||||
cmake --build build-cmake # --config Release (if you're packaging)
|
# Add `--config Release` if you're packaging
|
||||||
|
cmake --build build-cmake
|
||||||
|
|
||||||
# Now you can run the executable file:
|
# Now you can run the executable file:
|
||||||
./build-cmake/mm/2s2h-macos
|
./build-cmake/mm/2s2h-macos
|
||||||
# To develop the project open the repository in VSCode (or your preferred editor)
|
# To develop the project open the repository in VSCode (or your preferred editor)
|
||||||
|
|
||||||
# If you need to clean the project you can run
|
|
||||||
cmake --build build-cmake --target clean
|
|
||||||
|
|
||||||
# If you need to regenerate the asset headers to check them into source
|
|
||||||
cmake --build build-cmake --target ExtractAssetHeaders
|
|
||||||
|
|
||||||
# If you need a newer 2ship.o2r only
|
|
||||||
cmake --build build-cmake --target Generate2ShipOtr
|
|
||||||
```
|
```
|
||||||
|
|
||||||
### Generating a distributable
|
### Generating a distributable
|
||||||
@ -206,6 +210,19 @@ cd build-cmake
|
|||||||
cpack
|
cpack
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### Additional CMake Targets
|
||||||
|
#### Clean
|
||||||
|
```bash
|
||||||
|
# If you need to clean the project you can run
|
||||||
|
cmake --build build-cmake --target clean
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Regenerate Asset Headers
|
||||||
|
```bash
|
||||||
|
# If you need to regenerate the asset headers to check them into source
|
||||||
|
cmake --build build-cmake --target ExtractAssetHeaders
|
||||||
|
```
|
||||||
|
|
||||||
# Compatible Roms
|
# Compatible Roms
|
||||||
See [`supportedHashes.json`](supportedHashes.json)
|
See [`supportedHashes.json`](supportedHashes.json)
|
||||||
|
|
||||||
|
@ -10,7 +10,6 @@
|
|||||||
#include <File.h>
|
#include <File.h>
|
||||||
#include <DisplayList.h>
|
#include <DisplayList.h>
|
||||||
#include <Window.h>
|
#include <Window.h>
|
||||||
#include <GameVersions.h>
|
|
||||||
|
|
||||||
#include "z64animation.h"
|
#include "z64animation.h"
|
||||||
#include "z64bgcheck.h"
|
#include "z64bgcheck.h"
|
||||||
@ -27,6 +26,7 @@
|
|||||||
#include "macros.h"
|
#include "macros.h"
|
||||||
#include <utils/StringHelper.h>
|
#include <utils/StringHelper.h>
|
||||||
#include <nlohmann/json.hpp>
|
#include <nlohmann/json.hpp>
|
||||||
|
#include "build.h"
|
||||||
|
|
||||||
#include <Fast3D/gfx_pc.h>
|
#include <Fast3D/gfx_pc.h>
|
||||||
#include <Fast3D/gfx_rendering_api.h>
|
#include <Fast3D/gfx_rendering_api.h>
|
||||||
@ -145,10 +145,9 @@ OTRGlobals::OTRGlobals() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
std::unordered_set<uint32_t> ValidHashes = { OOT_PAL_MQ, OOT_NTSC_JP_MQ, OOT_NTSC_US_MQ, OOT_PAL_GC_MQ_DBG,
|
|
||||||
OOT_NTSC_US_10, OOT_NTSC_US_11, OOT_NTSC_US_12, OOT_PAL_10,
|
std::unordered_set<uint32_t> validHashes = { MM_NTSC_US_10, MM_NTSC_US_GC };
|
||||||
OOT_PAL_11, OOT_NTSC_JP_GC_CE, OOT_NTSC_JP_GC, OOT_NTSC_US_GC,
|
|
||||||
OOT_PAL_GC, OOT_PAL_GC_DBG1, OOT_PAL_GC_DBG2 };
|
|
||||||
// tell LUS to reserve 3 SoH specific threads (Game, Audio, Save)
|
// tell LUS to reserve 3 SoH specific threads (Game, Audio, Save)
|
||||||
context =
|
context =
|
||||||
Ship::Context::CreateInstance("2 Ship 2 Harkinian", appShortName, "2ship2harkinian.json", archiveFiles, {}, 3,
|
Ship::Context::CreateInstance("2 Ship 2 Harkinian", appShortName, "2ship2harkinian.json", archiveFiles, {}, 3,
|
||||||
@ -162,8 +161,6 @@ OTRGlobals::OTRGlobals() {
|
|||||||
(spdlog::level::level_enum)CVarGetInteger("gDeveloperTools.LogLevel", 1));
|
(spdlog::level::level_enum)CVarGetInteger("gDeveloperTools.LogLevel", 1));
|
||||||
Ship::Context::GetInstance()->GetLogger()->set_pattern("[%H:%M:%S.%e] [%s:%#] [%l] %v");
|
Ship::Context::GetInstance()->GetLogger()->set_pattern("[%H:%M:%S.%e] [%s:%#] [%l] %v");
|
||||||
|
|
||||||
// context = Ship::Context::CreateUninitializedInstance("Ship of Harkinian", appShortName, "shipofharkinian.json");
|
|
||||||
|
|
||||||
auto overlay = context->GetInstance()->GetWindow()->GetGui()->GetGameOverlay();
|
auto overlay = context->GetInstance()->GetWindow()->GetGui()->GetGameOverlay();
|
||||||
overlay->LoadFont("Press Start 2P", "fonts/PressStart2P-Regular.ttf", 12.0f);
|
overlay->LoadFont("Press Start 2P", "fonts/PressStart2P-Regular.ttf", 12.0f);
|
||||||
overlay->LoadFont("Fipps", "fonts/Fipps-Regular.otf", 32.0f);
|
overlay->LoadFont("Fipps", "fonts/Fipps-Regular.otf", 32.0f);
|
||||||
@ -230,59 +227,22 @@ OTRGlobals::OTRGlobals() {
|
|||||||
|
|
||||||
// gSaveStateMgr = std::make_shared<SaveStateMgr>();
|
// gSaveStateMgr = std::make_shared<SaveStateMgr>();
|
||||||
// gRandomizer = std::make_shared<Randomizer>();
|
// gRandomizer = std::make_shared<Randomizer>();
|
||||||
hasMasterQuest = hasOriginal = false;
|
|
||||||
|
|
||||||
// Move the camera strings from read only memory onto the heap (writable memory)
|
|
||||||
// This is in OTRGlobals right now because this is a place that will only ever be run once at the beginning of
|
|
||||||
// startup. We should probably find some code in db_camera that does initialization and only run once, and then
|
|
||||||
// dealloc on deinitialization.
|
|
||||||
// cameraStrings = (char**)malloc(sizeof(constCameraStrings));
|
|
||||||
// for (int32_t i = 0; i < sizeof(constCameraStrings) / sizeof(char*); i++) {
|
|
||||||
// // OTRTODO: never deallocated...
|
|
||||||
// auto dup = strdup(constCameraStrings[i]);
|
|
||||||
// cameraStrings[i] = dup;
|
|
||||||
//}
|
|
||||||
|
|
||||||
auto versions = context->GetResourceManager()->GetArchiveManager()->GetGameVersions();
|
auto versions = context->GetResourceManager()->GetArchiveManager()->GetGameVersions();
|
||||||
#if 0
|
|
||||||
for (uint32_t version : versions) {
|
for (uint32_t version : versions) {
|
||||||
if (!ValidHashes.contains(version)) {
|
if (!validHashes.contains(version)) {
|
||||||
#if defined(__SWITCH__)
|
#if defined(__SWITCH__)
|
||||||
SPDLOG_ERROR("Invalid OTR File!");
|
SPDLOG_ERROR("Invalid O2R File!");
|
||||||
#elif defined(__WIIU__)
|
#elif defined(__WIIU__)
|
||||||
Ship::WiiU::ThrowInvalidOTR();
|
Ship::WiiU::ThrowInvalidOTR();
|
||||||
#else
|
#else
|
||||||
SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "Invalid OTR File",
|
SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "Invalid O2R File",
|
||||||
"Attempted to load an invalid OTR file. Try regenerating.", nullptr);
|
"Attempted to load an invalid O2R file. Try regenerating.", nullptr);
|
||||||
SPDLOG_ERROR("Invalid OTR File!");
|
SPDLOG_ERROR("Invalid O2R File!");
|
||||||
#endif
|
#endif
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
switch (version) {
|
|
||||||
case OOT_PAL_MQ:
|
|
||||||
case OOT_NTSC_JP_MQ:
|
|
||||||
case OOT_NTSC_US_MQ:
|
|
||||||
case OOT_PAL_GC_MQ_DBG:
|
|
||||||
hasMasterQuest = true;
|
|
||||||
break;
|
|
||||||
case OOT_NTSC_US_10:
|
|
||||||
case OOT_NTSC_US_11:
|
|
||||||
case OOT_NTSC_US_12:
|
|
||||||
case OOT_PAL_10:
|
|
||||||
case OOT_PAL_11:
|
|
||||||
case OOT_NTSC_JP_GC_CE:
|
|
||||||
case OOT_NTSC_JP_GC:
|
|
||||||
case OOT_NTSC_US_GC:
|
|
||||||
case OOT_PAL_GC:
|
|
||||||
case OOT_PAL_GC_DBG1:
|
|
||||||
case OOT_PAL_GC_DBG2:
|
|
||||||
hasOriginal = true;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
fontMono = CreateFontWithSize(16.0f, "fonts/Inconsolata-Regular.ttf");
|
fontMono = CreateFontWithSize(16.0f, "fonts/Inconsolata-Regular.ttf");
|
||||||
fontMonoLarger = CreateFontWithSize(20.0f, "fonts/Inconsolata-Regular.ttf");
|
fontMonoLarger = CreateFontWithSize(20.0f, "fonts/Inconsolata-Regular.ttf");
|
||||||
@ -296,14 +256,6 @@ OTRGlobals::OTRGlobals() {
|
|||||||
OTRGlobals::~OTRGlobals() {
|
OTRGlobals::~OTRGlobals() {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool OTRGlobals::HasMasterQuest() {
|
|
||||||
return hasMasterQuest;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool OTRGlobals::HasOriginal() {
|
|
||||||
return hasOriginal;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t OTRGlobals::GetInterpolationFPS() {
|
uint32_t OTRGlobals::GetInterpolationFPS() {
|
||||||
if (Ship::Context::GetInstance()->GetWindow()->GetWindowBackend() == Ship::WindowBackend::FAST3D_DXGI_DX11) {
|
if (Ship::Context::GetInstance()->GetWindow()->GetWindowBackend() == Ship::WindowBackend::FAST3D_DXGI_DX11) {
|
||||||
return CVarGetInteger("gInterpolationFPS", 20);
|
return CVarGetInteger("gInterpolationFPS", 20);
|
||||||
@ -479,23 +431,198 @@ void Ben_ProcessDroppedFiles(std::string filePath) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" void InitOTR() {
|
typedef struct {
|
||||||
|
uint16_t major;
|
||||||
|
uint16_t minor;
|
||||||
|
uint16_t patch;
|
||||||
|
} ArchiveVersion;
|
||||||
|
|
||||||
|
// Read the port version from an archive file
|
||||||
|
ArchiveVersion ReadPortVersionFromArchive(std::string archivePath, bool isO2rType) {
|
||||||
|
ArchiveVersion version = {};
|
||||||
|
|
||||||
|
// Use a temporary archive instance to load the archive appropriately and read the version file
|
||||||
|
std::shared_ptr<Ship::Archive> archive;
|
||||||
|
if (isO2rType) {
|
||||||
|
archive = make_shared<Ship::O2rArchive>(archivePath);
|
||||||
|
} else {
|
||||||
|
archive = make_shared<Ship::OtrArchive>(archivePath);
|
||||||
|
}
|
||||||
|
if (archive->Open()) {
|
||||||
|
auto t = archive->LoadFile("portVersion", std::make_shared<Ship::ResourceInitData>());
|
||||||
|
if (t != nullptr && t->IsLoaded) {
|
||||||
|
auto stream = std::make_shared<Ship::MemoryStream>(t->Buffer->data(), t->Buffer->size());
|
||||||
|
auto reader = std::make_shared<Ship::BinaryReader>(stream);
|
||||||
|
Ship::Endianness endianness = (Ship::Endianness)reader->ReadUByte();
|
||||||
|
reader->SetEndianness(endianness);
|
||||||
|
version.major = reader->ReadUInt16();
|
||||||
|
version.minor = reader->ReadUInt16();
|
||||||
|
version.patch = reader->ReadUInt16();
|
||||||
|
}
|
||||||
|
archive->Close();
|
||||||
|
}
|
||||||
|
|
||||||
|
return version;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check that a 2ship.o2r exists and matches the version of 2ship running
|
||||||
|
// Otherwise show a message and exit
|
||||||
|
void Check2ShipArchiveVersion(std::string archivePath) {
|
||||||
|
std::string msg;
|
||||||
|
|
||||||
|
#if defined(__SWITCH__)
|
||||||
|
msg = "\x1b[4;2HPlease re-extract it from the download."
|
||||||
|
"\x1b[6;2HPress the Home button to exit...";
|
||||||
|
#elif defined(__WIIU__)
|
||||||
|
msg = "Please extract the 2ship.o2r from the 2 Ship 2 Harkinian download\nto your folder.\n\n"
|
||||||
|
"Press and hold the power button to shutdown...";
|
||||||
|
#else
|
||||||
|
msg = "Please extract the 2ship.o2r from the 2 Ship 2 Harkinian download to your folder.\n\nExiting...";
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (!std::filesystem::exists(archivePath)) {
|
||||||
#if not defined(__SWITCH__) && not defined(__WIIU__)
|
#if not defined(__SWITCH__) && not defined(__WIIU__)
|
||||||
if (!std::filesystem::exists(Ship::Context::LocateFileAcrossAppDirs("mm.o2r", appShortName)) &&
|
Extractor::ShowErrorBox("2ship.o2r file is missing", msg.c_str());
|
||||||
!std::filesystem::exists(Ship::Context::LocateFileAcrossAppDirs("mm.zip", appShortName)) &&
|
exit(1);
|
||||||
!std::filesystem::exists(Ship::Context::LocateFileAcrossAppDirs("mm.otr", appShortName))) {
|
#elif defined(__SWITCH__)
|
||||||
|
Ship::Switch::PrintErrorMessageToScreen(("\x1b[2;2HYou are missing the 2ship.o2r file." + msg).c_str());
|
||||||
|
#elif defined(__WIIU__)
|
||||||
|
OSFatal(("You are missing the 2ship.o2r file\n\n" + msg).c_str());
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
ArchiveVersion archiveVer = ReadPortVersionFromArchive(archivePath, true);
|
||||||
|
|
||||||
|
if (archiveVer.major != gBuildVersionMajor || archiveVer.minor != gBuildVersionMinor ||
|
||||||
|
archiveVer.patch != gBuildVersionPatch) {
|
||||||
|
#if not defined(__SWITCH__) && not defined(__WIIU__)
|
||||||
|
Extractor::ShowErrorBox("2ship.o2r file version does not match", msg.c_str());
|
||||||
|
exit(1);
|
||||||
|
#elif defined(__SWITCH__)
|
||||||
|
Ship::Switch::PrintErrorMessageToScreen(("\x1b[2;2HYou have an old 2ship.o2r file." + msg).c_str());
|
||||||
|
#elif defined(__WIIU__)
|
||||||
|
OSFatal(("You have an old 2ship.o2r file\n\n" + msg).c_str());
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Checks the program version stored in the o2r and compares the major/minor value to 2ship
|
||||||
|
// For Windows/Mac/Linux if the version doesn't match, offer to regenerate it
|
||||||
|
void DetectArchiveVersion(std::string fileName, bool isO2rType) {
|
||||||
|
bool isArchiveOld = false;
|
||||||
|
std::string archivePath = Ship::Context::LocateFileAcrossAppDirs(fileName, appShortName);
|
||||||
|
|
||||||
|
// Doesn't exist so nothing to do here
|
||||||
|
if (!std::filesystem::exists(archivePath)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ArchiveVersion archiveVer = ReadPortVersionFromArchive(archivePath, isO2rType);
|
||||||
|
|
||||||
|
// Check both major and minor for game archives
|
||||||
|
if (archiveVer.major != gBuildVersionMajor || archiveVer.minor != gBuildVersionMinor) {
|
||||||
|
isArchiveOld = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isArchiveOld) {
|
||||||
|
#if not defined(__SWITCH__) && not defined(__WIIU__)
|
||||||
|
char msgBuf[250];
|
||||||
|
char version[18]; // 5 digits for int16_max (x3) + separators + terminator
|
||||||
|
|
||||||
|
if (archiveVer.major != 0 || archiveVer.minor != 0 || archiveVer.patch != 0) {
|
||||||
|
snprintf(version, 18, "%d.%d.%d", archiveVer.major, archiveVer.minor, archiveVer.patch);
|
||||||
|
} else {
|
||||||
|
snprintf(version, 18, "no version found");
|
||||||
|
}
|
||||||
|
|
||||||
|
snprintf(msgBuf, 250,
|
||||||
|
"The %s file was generated with a different version of 2 Ship 2 Harkinian.\n"
|
||||||
|
"O2R version: %s\n\n"
|
||||||
|
"You must regenerate to be able to play, otherwise the program will exit.\n"
|
||||||
|
"Would you like to regenerate it now?",
|
||||||
|
fileName.c_str(), version);
|
||||||
|
|
||||||
|
if (Extractor::ShowYesNoBox("Old O2R File Found", msgBuf) == IDYES) {
|
||||||
|
std::string installPath = Ship::Context::GetAppBundlePath();
|
||||||
|
if (!std::filesystem::exists(installPath + "/assets/extractor")) {
|
||||||
|
Extractor::ShowErrorBox(
|
||||||
|
"Extractor assets not found",
|
||||||
|
"Unable to regenerate. Missing assets/extractor folder needed to generate O2R file.\n\nExiting...");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
Extractor extract;
|
||||||
|
if (!extract.Run(Ship::Context::GetAppDirectoryPath(appShortName))) {
|
||||||
|
Extractor::ShowErrorBox("Error", "An error occurred, no O2R file was generated.\n\nExiting...");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// We can only regenerate O2R archives, so we should just delete the old OTR file
|
||||||
|
if (!isO2rType) {
|
||||||
|
std::filesystem::remove(archivePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
extract.CallZapd(installPath, Ship::Context::GetAppDirectoryPath(appShortName));
|
||||||
|
|
||||||
|
// Rename the new O2R with the previously used extension
|
||||||
|
if (isO2rType) {
|
||||||
|
std::filesystem::rename(Ship::Context::LocateFileAcrossAppDirs("mm.o2r", appShortName), archivePath);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
#elif defined(__SWITCH__)
|
||||||
|
Ship::Switch::PrintErrorMessageToScreen("\x1b[2;2HYou've launched the 2Ship with an old game O2R file."
|
||||||
|
"\x1b[4;2HPlease regenerate a new game O2R and relaunch."
|
||||||
|
"\x1b[6;2HPress the Home button to exit...");
|
||||||
|
#elif defined(__WIIU__)
|
||||||
|
OSFatal("You've launched the 2Ship with an old a game O2R file.\n\n"
|
||||||
|
"Please generate a game O2R and relaunch.\n\n"
|
||||||
|
"Press and hold the Power button to shutdown...");
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C" void InitOTR() {
|
||||||
|
|
||||||
|
#ifdef __SWITCH__
|
||||||
|
Ship::Switch::Init(Ship::PreInitPhase);
|
||||||
|
#elif defined(__WIIU__)
|
||||||
|
Ship::WiiU::Init(appShortName);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// BENTODO: OTRExporter is filling the version file with garbage. Uncomment once fixed.
|
||||||
|
// Check2ShipArchiveVersion(Ship::Context::GetPathRelativeToAppBundle("2ship.o2r"));
|
||||||
|
|
||||||
|
std::string mmPathO2R = Ship::Context::LocateFileAcrossAppDirs("mm.o2r", appShortName);
|
||||||
|
std::string mmPathZIP = Ship::Context::LocateFileAcrossAppDirs("mm.zip", appShortName);
|
||||||
|
std::string mmPathOtr = Ship::Context::LocateFileAcrossAppDirs("mm.otr", appShortName);
|
||||||
|
|
||||||
|
// Check game archives in preferred order
|
||||||
|
if (std::filesystem::exists(mmPathO2R)) {
|
||||||
|
DetectArchiveVersion("mm.o2r", true);
|
||||||
|
} else if (std::filesystem::exists(mmPathZIP)) {
|
||||||
|
DetectArchiveVersion("mm.zip", true);
|
||||||
|
} else if (std::filesystem::exists(mmPathOtr)) {
|
||||||
|
DetectArchiveVersion("mm.otr", false);
|
||||||
|
}
|
||||||
|
|
||||||
|
#if not defined(__SWITCH__) && not defined(__WIIU__)
|
||||||
|
if (!std::filesystem::exists(mmPathO2R) && !std::filesystem::exists(mmPathZIP) &&
|
||||||
|
!std::filesystem::exists(mmPathOtr)) {
|
||||||
std::string installPath = Ship::Context::GetAppBundlePath();
|
std::string installPath = Ship::Context::GetAppBundlePath();
|
||||||
if (!std::filesystem::exists(installPath + "/assets/extractor")) {
|
if (!std::filesystem::exists(installPath + "/assets/extractor")) {
|
||||||
Extractor::ShowErrorBox(
|
Extractor::ShowErrorBox(
|
||||||
"Extractor assets not found",
|
"Extractor assets not found",
|
||||||
"No game O2R files found. Missing assets/extractor folder needed to generate O2R file. Exiting...");
|
"No game O2R file found. Missing assets/extractor folder needed to generate O2R file. Exiting...");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Extractor::ShowYesNoBox("No O2R Files", "No O2R files found. Generate one now?") == IDYES) {
|
if (Extractor::ShowYesNoBox("No O2R File", "No O2R files found. Generate one now?") == IDYES) {
|
||||||
Extractor extract;
|
Extractor extract;
|
||||||
if (!extract.Run()) {
|
if (!extract.Run(Ship::Context::GetAppDirectoryPath(appShortName))) {
|
||||||
Extractor::ShowErrorBox("Error", "An error occurred, no OTR file was generated. Exiting...");
|
Extractor::ShowErrorBox("Error", "An error occurred, no O2R file was generated. Exiting...");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
extract.CallZapd(installPath, Ship::Context::GetAppDirectoryPath(appShortName));
|
extract.CallZapd(installPath, Ship::Context::GetAppDirectoryPath(appShortName));
|
||||||
@ -505,12 +632,6 @@ extern "C" void InitOTR() {
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef __SWITCH__
|
|
||||||
Ship::Switch::Init(Ship::PreInitPhase);
|
|
||||||
#elif defined(__WIIU__)
|
|
||||||
Ship::WiiU::Init("soh");
|
|
||||||
#endif
|
|
||||||
|
|
||||||
OTRGlobals::Instance = new OTRGlobals();
|
OTRGlobals::Instance = new OTRGlobals();
|
||||||
GameInteractor::Instance = new GameInteractor();
|
GameInteractor::Instance = new GameInteractor();
|
||||||
LoadGuiTextures();
|
LoadGuiTextures();
|
||||||
@ -839,22 +960,8 @@ extern "C" uint32_t ResourceMgr_GetGamePlatform(int index) {
|
|||||||
Ship::Context::GetInstance()->GetResourceManager()->GetArchiveManager()->GetGameVersions()[index];
|
Ship::Context::GetInstance()->GetResourceManager()->GetArchiveManager()->GetGameVersions()[index];
|
||||||
|
|
||||||
switch (version) {
|
switch (version) {
|
||||||
case OOT_NTSC_US_10:
|
|
||||||
case OOT_NTSC_US_11:
|
|
||||||
case OOT_NTSC_US_12:
|
|
||||||
case OOT_PAL_10:
|
|
||||||
case OOT_PAL_11:
|
|
||||||
case MM_NTSC_US_10:
|
case MM_NTSC_US_10:
|
||||||
return GAME_PLATFORM_N64;
|
return GAME_PLATFORM_N64;
|
||||||
case OOT_NTSC_JP_GC:
|
|
||||||
case OOT_NTSC_US_GC:
|
|
||||||
case OOT_PAL_GC:
|
|
||||||
case OOT_NTSC_JP_MQ:
|
|
||||||
case OOT_NTSC_US_MQ:
|
|
||||||
case OOT_PAL_MQ:
|
|
||||||
case OOT_PAL_GC_DBG1:
|
|
||||||
case OOT_PAL_GC_DBG2:
|
|
||||||
case OOT_PAL_GC_MQ_DBG:
|
|
||||||
case MM_NTSC_US_GC:
|
case MM_NTSC_US_GC:
|
||||||
return GAME_PLATFORM_GC;
|
return GAME_PLATFORM_GC;
|
||||||
}
|
}
|
||||||
@ -865,24 +972,9 @@ extern "C" uint32_t ResourceMgr_GetGameRegion(int index) {
|
|||||||
Ship::Context::GetInstance()->GetResourceManager()->GetArchiveManager()->GetGameVersions()[index];
|
Ship::Context::GetInstance()->GetResourceManager()->GetArchiveManager()->GetGameVersions()[index];
|
||||||
|
|
||||||
switch (version) {
|
switch (version) {
|
||||||
case OOT_NTSC_US_10:
|
|
||||||
case OOT_NTSC_US_11:
|
|
||||||
case OOT_NTSC_US_12:
|
|
||||||
case OOT_NTSC_JP_GC:
|
|
||||||
case OOT_NTSC_US_GC:
|
|
||||||
case OOT_NTSC_JP_MQ:
|
|
||||||
case OOT_NTSC_US_MQ:
|
|
||||||
case MM_NTSC_US_10:
|
case MM_NTSC_US_10:
|
||||||
case MM_NTSC_US_GC:
|
case MM_NTSC_US_GC:
|
||||||
return GAME_REGION_NTSC;
|
return GAME_REGION_NTSC;
|
||||||
case OOT_PAL_10:
|
|
||||||
case OOT_PAL_11:
|
|
||||||
case OOT_PAL_GC:
|
|
||||||
case OOT_PAL_MQ:
|
|
||||||
case OOT_PAL_GC_DBG1:
|
|
||||||
case OOT_PAL_GC_DBG2:
|
|
||||||
case OOT_PAL_GC_MQ_DBG:
|
|
||||||
return GAME_REGION_PAL;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -36,16 +36,12 @@ class OTRGlobals {
|
|||||||
OTRGlobals();
|
OTRGlobals();
|
||||||
~OTRGlobals();
|
~OTRGlobals();
|
||||||
|
|
||||||
bool HasMasterQuest();
|
|
||||||
bool HasOriginal();
|
|
||||||
uint32_t GetInterpolationFPS();
|
uint32_t GetInterpolationFPS();
|
||||||
std::shared_ptr<std::vector<std::string>> ListFiles(std::string path);
|
std::shared_ptr<std::vector<std::string>> ListFiles(std::string path);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ImFont* CreateFontWithSize(float size, std::string fontPath = "");
|
ImFont* CreateFontWithSize(float size, std::string fontPath = "");
|
||||||
void CheckSaveFile(size_t sramSize) const;
|
void CheckSaveFile(size_t sramSize) const;
|
||||||
bool hasMasterQuest;
|
|
||||||
bool hasOriginal;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
uint32_t IsGameMasterQuest();
|
uint32_t IsGameMasterQuest();
|
||||||
|
@ -51,42 +51,18 @@
|
|||||||
|
|
||||||
extern "C" uint32_t CRC32C(unsigned char* data, size_t dataSize);
|
extern "C" uint32_t CRC32C(unsigned char* data, size_t dataSize);
|
||||||
|
|
||||||
static constexpr uint32_t OOT_PAL_GC = 0x09465AC3;
|
|
||||||
static constexpr uint32_t OOT_PAL_MQ = 0x1D4136F3;
|
|
||||||
static constexpr uint32_t OOT_PAL_GC_DBG1 = 0x871E1C92; // 03-21-2002 build
|
|
||||||
static constexpr uint32_t OOT_PAL_GC_DBG2 = 0x87121EFE; // 03-13-2002 build
|
|
||||||
static constexpr uint32_t OOT_PAL_GC_MQ_DBG = 0x917D18F6;
|
|
||||||
static constexpr uint32_t OOT_PAL_10 = 0xB044B569;
|
|
||||||
static constexpr uint32_t OOT_PAL_11 = 0xB2055FBD;
|
|
||||||
|
|
||||||
static constexpr uint32_t MM_US_10 = 0x5354631C;
|
static constexpr uint32_t MM_US_10 = 0x5354631C;
|
||||||
static constexpr uint32_t MM_US_GC = 0xB443EB08;
|
static constexpr uint32_t MM_US_GC = 0xB443EB08;
|
||||||
|
|
||||||
static const std::unordered_map<uint32_t, const char*> verMap = {
|
static const std::unordered_map<uint32_t, const char*> verMap = {
|
||||||
{ MM_US_10, "US 1.0" }, { MM_US_GC, "US GC" },
|
{ MM_US_10, "US 1.0" },
|
||||||
//{ OOT_PAL_GC, "PAL Gamecube" },
|
{ MM_US_GC, "US GC" },
|
||||||
//{ OOT_PAL_MQ, "PAL MQ" },
|
|
||||||
//{ OOT_PAL_GC_DBG1, "PAL Debug 1" },
|
|
||||||
//{ OOT_PAL_GC_DBG2, "PAL Debug 2" },
|
|
||||||
//{ OOT_PAL_GC_MQ_DBG, "PAL MQ Debug" },
|
|
||||||
//{ OOT_PAL_10, "PAL N64 1.0" },
|
|
||||||
//{ OOT_PAL_11, "PAL N64 1.1" },
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// TODO only check the first 54MB of the rom.
|
// TODO only check the first 54MB of the rom.
|
||||||
static constexpr std::array<const uint32_t, 10> goodCrcs = {
|
static constexpr std::array<const uint32_t, 10> goodCrcs = {
|
||||||
0x96F49400, // MM US 1.0 32MB
|
0x96F49400, // MM US 1.0 32MB
|
||||||
0xBB434787, // MM GC
|
0xBB434787, // MM GC
|
||||||
// 0xfa8c0555, // MQ DBG 64MB (Original overdump)
|
|
||||||
// 0x8652ac4c, // MQ DBG 64MB
|
|
||||||
// 0x5B8A1EB7, // MQ DBG 64MB (Empty overdump)
|
|
||||||
// 0x1f731ffe, // MQ DBG 54MB
|
|
||||||
// 0x044b3982, // NMQ DBG 54MB
|
|
||||||
// 0xEB15D7B9, // NMQ DBG 64MB
|
|
||||||
// 0xDA8E61BF, // GC PAL
|
|
||||||
// 0x7A2FAE68, // GC MQ PAL
|
|
||||||
// 0xFD9913B1, // N64 PAL 1.0
|
|
||||||
// 0xE033FBBA, // N64 PAL 1.1
|
|
||||||
};
|
};
|
||||||
|
|
||||||
enum class ButtonId : int {
|
enum class ButtonId : int {
|
||||||
@ -112,7 +88,13 @@ void Extractor::ShowSizeErrorBox() const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Extractor::ShowCrcErrorBox() const {
|
void Extractor::ShowCrcErrorBox() const {
|
||||||
ShowErrorBox("Rom CRC invalid", "Rom CRC did not match the list of known good roms. Please find another.");
|
ShowErrorBox("Rom CRC invalid",
|
||||||
|
"Rom CRC did not match the list of known compatible roms. Please find another.\n\n"
|
||||||
|
"Visit https://2ship.equipment/ to validate your ROM and see a list of compatible versions");
|
||||||
|
}
|
||||||
|
|
||||||
|
void Extractor::ShowCompressedErrorBox() const {
|
||||||
|
ShowErrorBox("File is Compressed", "The selected file appears to be compressed. Please extract before using.");
|
||||||
}
|
}
|
||||||
|
|
||||||
int Extractor::ShowRomPickBox(uint32_t verCrc) const {
|
int Extractor::ShowRomPickBox(uint32_t verCrc) const {
|
||||||
@ -225,7 +207,7 @@ void Extractor::GetRoms(std::vector<std::string>& roms) {
|
|||||||
//}
|
//}
|
||||||
#elif unix
|
#elif unix
|
||||||
// Open the directory of the app.
|
// Open the directory of the app.
|
||||||
DIR* d = opendir(".");
|
DIR* d = opendir(mSearchPath.c_str());
|
||||||
struct dirent* dir;
|
struct dirent* dir;
|
||||||
|
|
||||||
if (d != NULL) {
|
if (d != NULL) {
|
||||||
@ -247,7 +229,7 @@ void Extractor::GetRoms(std::vector<std::string>& roms) {
|
|||||||
}
|
}
|
||||||
closedir(d);
|
closedir(d);
|
||||||
#else
|
#else
|
||||||
for (const auto& file : std::filesystem::directory_iterator("./")) {
|
for (const auto& file : std::filesystem::directory_iterator(mSearchPath)) {
|
||||||
if (file.is_directory())
|
if (file.is_directory())
|
||||||
continue;
|
continue;
|
||||||
if ((file.path().extension() == ".n64") || (file.path().extension() == ".z64") ||
|
if ((file.path().extension() == ".n64") || (file.path().extension() == ".z64") ||
|
||||||
@ -297,7 +279,7 @@ bool Extractor::GetRomPathFromBox() {
|
|||||||
}
|
}
|
||||||
mCurrentRomPath = nameBuffer;
|
mCurrentRomPath = nameBuffer;
|
||||||
#else
|
#else
|
||||||
auto selection = pfd::open_file("Select a file", ".", { "N64 Roms", "*.z64 *.n64 *.v64" }).result();
|
auto selection = pfd::open_file("Select a file", mSearchPath, { "N64 Roms", "*.z64 *.n64 *.v64" }).result();
|
||||||
|
|
||||||
if (selection.empty()) {
|
if (selection.empty()) {
|
||||||
return false;
|
return false;
|
||||||
@ -318,11 +300,6 @@ size_t Extractor::GetCurRomSize() const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool Extractor::ValidateAndFixRom() {
|
bool Extractor::ValidateAndFixRom() {
|
||||||
// The MQ debug rom sometimes has the header patched to look like a US rom. Change it back
|
|
||||||
if (GetRomVerCrc() == OOT_PAL_GC_MQ_DBG) {
|
|
||||||
mRomData[0x3E] = 'P';
|
|
||||||
}
|
|
||||||
|
|
||||||
const uint32_t actualCrc = CRC32C(mRomData.get(), mCurRomSize);
|
const uint32_t actualCrc = CRC32C(mRomData.get(), mCurRomSize);
|
||||||
|
|
||||||
for (const uint32_t crc : goodCrcs) {
|
for (const uint32_t crc : goodCrcs) {
|
||||||
@ -333,6 +310,25 @@ bool Extractor::ValidateAndFixRom() {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// The file box will only allow selecting an n64 rom but typing in the file name will allow selecting anything.
|
||||||
|
bool Extractor::ValidateNotCompressed() const {
|
||||||
|
// ZIP file header
|
||||||
|
if (mRomData[0] == 'P' && mRomData[1] == 'K' && mRomData[2] == 0x03 && mRomData[3] == 0x04) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
// RAR file header. Only the first 4 bytes.
|
||||||
|
if (mRomData[0] == 'R' && mRomData[1] == 'a' && mRomData[2] == 'r' && mRomData[3] == 0x21) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
// 7z file header. 37 7A BC AF 27 1C
|
||||||
|
if (mRomData[0] == '7' && mRomData[1] == 'z' && mRomData[2] == 0xBC && mRomData[3] == 0xAF && mRomData[4] == 0x27 &&
|
||||||
|
mRomData[5] == 0x1C) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
bool Extractor::ValidateRomSize() const {
|
bool Extractor::ValidateRomSize() const {
|
||||||
if (mCurRomSize != MB32 && mCurRomSize != MB54 && mCurRomSize != MB64) {
|
if (mCurRomSize != MB32 && mCurRomSize != MB54 && mCurRomSize != MB64) {
|
||||||
return false;
|
return false;
|
||||||
@ -341,6 +337,10 @@ bool Extractor::ValidateRomSize() const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool Extractor::ValidateRom(bool skipCrcTextBox) {
|
bool Extractor::ValidateRom(bool skipCrcTextBox) {
|
||||||
|
if (!ValidateNotCompressed()) {
|
||||||
|
ShowCompressedErrorBox();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
if (!ValidateRomSize()) {
|
if (!ValidateRomSize()) {
|
||||||
ShowSizeErrorBox();
|
ShowSizeErrorBox();
|
||||||
return false;
|
return false;
|
||||||
@ -410,10 +410,12 @@ bool Extractor::ManuallySearchForRomMatchingType(RomSearchMode searchMode) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Extractor::Run(RomSearchMode searchMode) {
|
bool Extractor::Run(std::string searchPath, RomSearchMode searchMode) {
|
||||||
std::vector<std::string> roms;
|
std::vector<std::string> roms;
|
||||||
std::ifstream inFile;
|
std::ifstream inFile;
|
||||||
|
|
||||||
|
mSearchPath = searchPath;
|
||||||
|
|
||||||
GetRoms(roms);
|
GetRoms(roms);
|
||||||
FilterRoms(roms, searchMode);
|
FilterRoms(roms, searchMode);
|
||||||
|
|
||||||
@ -456,8 +458,10 @@ bool Extractor::Run(RomSearchMode searchMode) {
|
|||||||
if (rom == roms.back()) {
|
if (rom == roms.back()) {
|
||||||
ShowCrcErrorBox();
|
ShowCrcErrorBox();
|
||||||
} else {
|
} else {
|
||||||
ShowErrorBox("Rom CRC invalid",
|
ShowErrorBox(
|
||||||
"Rom CRC did not match the list of known good roms. Trying the next one...");
|
"Rom CRC invalid",
|
||||||
|
"Rom CRC did not match the list of known compatible roms. Trying the next one...\n\n"
|
||||||
|
"Visit https://2ship.equipment/ to validate your ROM and see a list of compatible versions");
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -480,34 +484,11 @@ bool Extractor::Run(RomSearchMode searchMode) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool Extractor::IsMasterQuest() const {
|
bool Extractor::IsMasterQuest() const {
|
||||||
switch (GetRomVerCrc()) {
|
return false;
|
||||||
case OOT_PAL_MQ:
|
|
||||||
case OOT_PAL_GC_MQ_DBG:
|
|
||||||
return true;
|
|
||||||
case OOT_PAL_10:
|
|
||||||
case OOT_PAL_11:
|
|
||||||
case OOT_PAL_GC:
|
|
||||||
case OOT_PAL_GC_DBG1:
|
|
||||||
return false;
|
|
||||||
default:
|
|
||||||
UNREACHABLE;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const char* Extractor::GetZapdVerStr() const {
|
const char* Extractor::GetZapdVerStr() const {
|
||||||
switch (GetRomVerCrc()) {
|
switch (GetRomVerCrc()) {
|
||||||
case OOT_PAL_GC:
|
|
||||||
return "GC_NMQ_PAL_F";
|
|
||||||
case OOT_PAL_MQ:
|
|
||||||
return "GC_MQ_PAL_F";
|
|
||||||
case OOT_PAL_GC_DBG1:
|
|
||||||
return "GC_NMQ_D";
|
|
||||||
case OOT_PAL_GC_MQ_DBG:
|
|
||||||
return "GC_MQ_D";
|
|
||||||
case OOT_PAL_10:
|
|
||||||
return "N64_PAL_10";
|
|
||||||
case OOT_PAL_11:
|
|
||||||
return "N64_PAL_11";
|
|
||||||
case MM_US_10:
|
case MM_US_10:
|
||||||
return "N64_US";
|
return "N64_US";
|
||||||
case MM_US_GC:
|
case MM_US_GC:
|
||||||
|
@ -28,6 +28,7 @@ enum class RomSearchMode {
|
|||||||
class Extractor {
|
class Extractor {
|
||||||
std::unique_ptr<unsigned char[]> mRomData = std::make_unique<unsigned char[]>(MB64);
|
std::unique_ptr<unsigned char[]> mRomData = std::make_unique<unsigned char[]>(MB64);
|
||||||
std::string mCurrentRomPath;
|
std::string mCurrentRomPath;
|
||||||
|
std::string mSearchPath;
|
||||||
size_t mCurRomSize = 0;
|
size_t mCurRomSize = 0;
|
||||||
|
|
||||||
bool GetRomPathFromBox();
|
bool GetRomPathFromBox();
|
||||||
@ -38,6 +39,7 @@ class Extractor {
|
|||||||
bool ValidateRomSize() const;
|
bool ValidateRomSize() const;
|
||||||
|
|
||||||
bool ValidateRom(bool skipCrcBox = false);
|
bool ValidateRom(bool skipCrcBox = false);
|
||||||
|
bool ValidateNotCompressed() const;
|
||||||
const char* GetZapdVerStr() const;
|
const char* GetZapdVerStr() const;
|
||||||
|
|
||||||
void SetRomInfo(const std::string& path);
|
void SetRomInfo(const std::string& path);
|
||||||
@ -46,6 +48,7 @@ class Extractor {
|
|||||||
void GetRoms(std::vector<std::string>& roms);
|
void GetRoms(std::vector<std::string>& roms);
|
||||||
void ShowSizeErrorBox() const;
|
void ShowSizeErrorBox() const;
|
||||||
void ShowCrcErrorBox() const;
|
void ShowCrcErrorBox() const;
|
||||||
|
void ShowCompressedErrorBox() const;
|
||||||
int ShowRomPickBox(uint32_t verCrc) const;
|
int ShowRomPickBox(uint32_t verCrc) const;
|
||||||
bool ManuallySearchForRom();
|
bool ManuallySearchForRom();
|
||||||
bool ManuallySearchForRomMatchingType(RomSearchMode searchMode);
|
bool ManuallySearchForRomMatchingType(RomSearchMode searchMode);
|
||||||
@ -56,7 +59,7 @@ class Extractor {
|
|||||||
static void ShowErrorBox(const char* title, const char* text);
|
static void ShowErrorBox(const char* title, const char* text);
|
||||||
bool IsMasterQuest() const;
|
bool IsMasterQuest() const;
|
||||||
|
|
||||||
bool Run(RomSearchMode searchMode = RomSearchMode::Both);
|
bool Run(std::string searchPath, RomSearchMode searchMode = RomSearchMode::Both);
|
||||||
bool CallZapd(std::string installPath, std::string exportdir);
|
bool CallZapd(std::string installPath, std::string exportdir);
|
||||||
const char* GetZapdStr();
|
const char* GetZapdStr();
|
||||||
std::string Mkdtemp();
|
std::string Mkdtemp();
|
||||||
|
@ -524,18 +524,22 @@ endif()
|
|||||||
################################################################################
|
################################################################################
|
||||||
# Pre build events
|
# Pre build events
|
||||||
################################################################################
|
################################################################################
|
||||||
|
if (CMAKE_GENERATOR MATCHES "Visual Studio")
|
||||||
|
set(VS_COPY_ASSETS_CMD ${CMAKE_COMMAND} -E copy_directory $<TARGET_FILE_DIR:2ship>/assets ${CMAKE_BINARY_DIR}/mm/assets)
|
||||||
|
endif()
|
||||||
if(NOT CMAKE_SYSTEM_NAME MATCHES "NintendoSwitch|CafeOS")
|
if(NOT CMAKE_SYSTEM_NAME MATCHES "NintendoSwitch|CafeOS")
|
||||||
add_custom_command(
|
add_custom_command(
|
||||||
TARGET ${PROJECT_NAME}
|
TARGET ${PROJECT_NAME}
|
||||||
POST_BUILD
|
POST_BUILD
|
||||||
COMMENT "Copying asset xmls..."
|
COMMENT "Copying asset xmls..."
|
||||||
COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_SOURCE_DIR}/mm/assets/extractor $<TARGET_FILE_DIR:2ship>/assets/extractor
|
COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_SOURCE_DIR}/mm/assets/extractor $<TARGET_FILE_DIR:2ship>/assets/extractor
|
||||||
COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_SOURCE_DIR}/mm/assets/xml $<TARGET_FILE_DIR:2ship>/assets/extractor/xmls
|
COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_SOURCE_DIR}/mm/assets/xml $<TARGET_FILE_DIR:2ship>/assets/extractor/xmls
|
||||||
COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_SOURCE_DIR}/OTRExporter/CFG/filelists $<TARGET_FILE_DIR:2ship>/assets/extractor/filelists
|
COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_SOURCE_DIR}/OTRExporter/CFG/filelists $<TARGET_FILE_DIR:2ship>/assets/extractor/filelists
|
||||||
COMMAND ${CMAKE_COMMAND} -E make_directory $<TARGET_FILE_DIR:2ship>/assets/extractor/symbols
|
COMMAND ${CMAKE_COMMAND} -E make_directory $<TARGET_FILE_DIR:2ship>/assets/extractor/symbols
|
||||||
COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_SOURCE_DIR}/OTRExporter/CFG/ActorList_MM.txt $<TARGET_FILE_DIR:2ship>/assets/extractor/symbols
|
COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_SOURCE_DIR}/OTRExporter/CFG/ActorList_MM.txt $<TARGET_FILE_DIR:2ship>/assets/extractor/symbols
|
||||||
COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_SOURCE_DIR}/OTRExporter/CFG/ObjectList_MM.txt $<TARGET_FILE_DIR:2ship>/assets/extractor/symbols
|
COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_SOURCE_DIR}/OTRExporter/CFG/ObjectList_MM.txt $<TARGET_FILE_DIR:2ship>/assets/extractor/symbols
|
||||||
COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_SOURCE_DIR}/OTRExporter/CFG/SymbolMap_MM.txt $<TARGET_FILE_DIR:2ship>/assets/extractor/symbols
|
COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_SOURCE_DIR}/OTRExporter/CFG/SymbolMap_MM.txt $<TARGET_FILE_DIR:2ship>/assets/extractor/symbols
|
||||||
|
COMMAND ${VS_COPY_ASSETS_CMD}
|
||||||
)
|
)
|
||||||
endif()
|
endif()
|
||||||
################################################################################
|
################################################################################
|
||||||
|
Loading…
Reference in New Issue
Block a user