mirror of
https://github.com/HarbourMasters/Shipwright.git
synced 2024-11-28 12:22:20 -05:00
Implement built in Extractor for Windows (#2730)
* wip * const * split zapd into two targets * Workingish. * fix working dir and copy xmls on build (#2) * dont change current working dir with dialog prompts * copy asset xmls to target dir * make zpadlib public * Messagebox. * Check for WIN32 * threading * Cleanups to the exporter and main. * Multi extraction. * Fix byteswap header includes. * Fix another byteswap include. * fix again. * stddef size_t * Add other targets for ZAPDLib * Non windows. * IDYES IDNO * Linux fixes * hopefully remove switch and wiiu from building extractor * Please? * validate roms and add another valid rom * ifdef out extract.h for switch and wiiu * Maybe update lux * Remove ZAPDlib from switch and WiiU * more rules * Update soh/soh/Extractor/Extract.cpp Co-authored-by: briaguya <70942617+briaguya-ai@users.noreply.github.com> * Update ZAPDTR/ZAPD/ExecutableMain.cpp Co-authored-by: briaguya <70942617+briaguya-ai@users.noreply.github.com> * Update ZAPDTR/ZAPD/CMakeLists.txt Co-authored-by: briaguya <70942617+briaguya-ai@users.noreply.github.com> * Update ZAPDTR/ZAPD/GameConfig.cpp Co-authored-by: briaguya <70942617+briaguya-ai@users.noreply.github.com> * Update ZAPDTR/ZAPD/Globals.cpp Co-authored-by: briaguya <70942617+briaguya-ai@users.noreply.github.com> * Update ZAPDTR/ZAPD/Main.cpp Co-authored-by: briaguya <70942617+briaguya-ai@users.noreply.github.com> * Update soh/CMakeLists.txt Co-authored-by: briaguya <70942617+briaguya-ai@users.noreply.github.com> * Update soh/soh/Extractor/Extract.cpp Co-authored-by: briaguya <70942617+briaguya-ai@users.noreply.github.com> * Update soh/soh/Extractor/Extract.cpp Co-authored-by: briaguya <70942617+briaguya-ai@users.noreply.github.com> * Update soh/soh/Extractor/Extract.cpp Co-authored-by: briaguya <70942617+briaguya-ai@users.noreply.github.com> * the last fix * Add context to a comment --------- Co-authored-by: Adam Bird <archez39@me.com> Co-authored-by: Adam Bird <Archez@users.noreply.github.com> Co-authored-by: briaguya <70942617+briaguya-ai@users.noreply.github.com>
This commit is contained in:
parent
44d3f1ccbb
commit
aea46e7cb2
@ -111,7 +111,7 @@ add_custom_target(
|
|||||||
# CMake versions prior to 3.17 do not have the rm command, use remove instead for older versions
|
# CMake versions prior to 3.17 do not have the rm command, use remove instead for older versions
|
||||||
COMMAND ${CMAKE_COMMAND} -E $<IF:$<VERSION_LESS:${CMAKE_VERSION},3.17>,remove,rm> -f oot.otr oot-mq.otr soh.otr
|
COMMAND ${CMAKE_COMMAND} -E $<IF:$<VERSION_LESS:${CMAKE_VERSION},3.17>,remove,rm> -f oot.otr oot-mq.otr soh.otr
|
||||||
COMMAND ${Python3_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/OTRExporter/extract_assets.py -z "$<TARGET_FILE:ZAPD>" --non-interactive
|
COMMAND ${Python3_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/OTRExporter/extract_assets.py -z "$<TARGET_FILE:ZAPD>" --non-interactive
|
||||||
COMMAND ${CMAKE_COMMAND} -DSYSTEM_NAME=${CMAKE_SYSTEM_NAME} -DTARGET_DIR="$<TARGET_FILE_DIR:soh>" -DSOURCE_DIR=${CMAKE_CURRENT_SOURCE_DIR} -DBINARY_DIR=${CMAKE_BINARY_DIR} -P ${CMAKE_CURRENT_SOURCE_DIR}/copy-existing-otrs.cmake
|
COMMAND ${CMAKE_COMMAND} -DSYSTEM_NAME=${CMAKE_SYSTEM_NAME} -DTARGET_DIR="$<TARGET_FILE_DIR:ZAPD>" -DSOURCE_DIR=${CMAKE_CURRENT_SOURCE_DIR} -DBINARY_DIR=${CMAKE_BINARY_DIR} -P ${CMAKE_CURRENT_SOURCE_DIR}/copy-existing-otrs.cmake
|
||||||
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/OTRExporter
|
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/OTRExporter
|
||||||
COMMENT "Running asset extraction..."
|
COMMENT "Running asset extraction..."
|
||||||
DEPENDS ZAPD
|
DEPENDS ZAPD
|
||||||
|
@ -107,8 +107,13 @@ static void ExporterProgramEnd()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
otrArchive = nullptr;
|
otrArchive = nullptr;
|
||||||
|
delete fileWriter;
|
||||||
|
files.clear();
|
||||||
|
|
||||||
// Add any additional files that need to be manually copied...
|
// Add any additional files that need to be manually copied...
|
||||||
|
if (File::Exists("soh.otr")) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
const auto& lst = Directory::ListFiles("Extract");
|
const auto& lst = Directory::ListFiles("Extract");
|
||||||
std::shared_ptr<Ship::Archive> sohOtr = Ship::Archive::CreateArchive("soh.otr", 4096);
|
std::shared_ptr<Ship::Archive> sohOtr = Ship::Archive::CreateArchive("soh.otr", 4096);
|
||||||
//sohOtr->AddFile("version", (uintptr_t)versionStream->ToVector().data(), versionStream->GetLength());
|
//sohOtr->AddFile("version", (uintptr_t)versionStream->ToVector().data(), versionStream->GetLength());
|
||||||
@ -273,7 +278,7 @@ void AddFile(std::string fName, std::vector<char> data)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ImportExporters()
|
void ImportExporters()
|
||||||
{
|
{
|
||||||
// In this example we set up a new exporter called "EXAMPLE".
|
// In this example we set up a new exporter called "EXAMPLE".
|
||||||
// By running ZAPD with the argument -se EXAMPLE, we tell it that we want to use this exporter for our resources.
|
// By running ZAPD with the argument -se EXAMPLE, we tell it that we want to use this exporter for our resources.
|
||||||
@ -312,6 +317,3 @@ static void ImportExporters()
|
|||||||
|
|
||||||
InitVersionInfo();
|
InitVersionInfo();
|
||||||
}
|
}
|
||||||
|
|
||||||
// When ZAPD starts up, it will automatically call the below function, which in turn sets up our exporters.
|
|
||||||
REGISTER_EXPORTER(ImportExporters);
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
set(PROJECT_NAME ZAPD)
|
set(PROJECT_NAME ZAPDLib)
|
||||||
|
|
||||||
set(CMAKE_CXX_STANDARD 20 CACHE STRING "The C++ standard to use")
|
set(CMAKE_CXX_STANDARD 20 CACHE STRING "The C++ standard to use")
|
||||||
#set(CMAKE_C_STANDARD 11 CACHE STRING "The C standard to use")
|
#set(CMAKE_C_STANDARD 11 CACHE STRING "The C standard to use")
|
||||||
@ -260,10 +260,17 @@ set(ALL_FILES
|
|||||||
################################################################################
|
################################################################################
|
||||||
# Target
|
# Target
|
||||||
################################################################################
|
################################################################################
|
||||||
add_executable(${PROJECT_NAME} ${ALL_FILES})
|
|
||||||
|
add_library(${PROJECT_NAME} STATIC ${ALL_FILES})
|
||||||
|
|
||||||
|
add_executable(ZAPD ExecutableMain.cpp)
|
||||||
|
target_link_libraries(ZAPD ${PROJECT_NAME})
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if (CMAKE_SYSTEM_NAME STREQUAL "Windows")
|
if (CMAKE_SYSTEM_NAME STREQUAL "Windows")
|
||||||
use_props(${PROJECT_NAME} "${CMAKE_CONFIGURATION_TYPES}" "${DEFAULT_CXX_PROPS}")
|
use_props(${PROJECT_NAME} "${CMAKE_CONFIGURATION_TYPES}" "${DEFAULT_CXX_PROPS}")
|
||||||
|
use_props(ZAPD "${CMAKE_CONFIGURATION_TYPES}" "${DEFAULT_CXX_PROPS}")
|
||||||
endif()
|
endif()
|
||||||
################################################################################
|
################################################################################
|
||||||
# Includes for CMake from *.props
|
# Includes for CMake from *.props
|
||||||
@ -282,7 +289,7 @@ if (CMAKE_SYSTEM_NAME STREQUAL "Windows")
|
|||||||
)
|
)
|
||||||
endif()
|
endif()
|
||||||
elseif (CMAKE_SYSTEM_NAME MATCHES "Linux|Darwin")
|
elseif (CMAKE_SYSTEM_NAME MATCHES "Linux|Darwin")
|
||||||
set_target_properties(${PROJECT_NAME} PROPERTIES
|
set_target_properties(ZAPD PROPERTIES
|
||||||
OUTPUT_NAME "ZAPD.out"
|
OUTPUT_NAME "ZAPD.out"
|
||||||
)
|
)
|
||||||
endif()
|
endif()
|
||||||
@ -290,7 +297,8 @@ endif()
|
|||||||
# MSVC runtime library
|
# MSVC runtime library
|
||||||
################################################################################
|
################################################################################
|
||||||
if (CMAKE_SYSTEM_NAME STREQUAL "Windows")
|
if (CMAKE_SYSTEM_NAME STREQUAL "Windows")
|
||||||
get_property(MSVC_RUNTIME_LIBRARY_DEFAULT TARGET ${PROJECT_NAME} PROPERTY MSVC_RUNTIME_LIBRARY)
|
foreach(ZTarget ${PROJECT_NAME} ZAPD)
|
||||||
|
get_property(MSVC_RUNTIME_LIBRARY_DEFAULT TARGET ${ZTarget} PROPERTY MSVC_RUNTIME_LIBRARY)
|
||||||
if("${CMAKE_VS_PLATFORM_NAME}" STREQUAL "x64")
|
if("${CMAKE_VS_PLATFORM_NAME}" STREQUAL "x64")
|
||||||
string(CONCAT "MSVC_RUNTIME_LIBRARY_STR"
|
string(CONCAT "MSVC_RUNTIME_LIBRARY_STR"
|
||||||
$<$<CONFIG:Debug>:
|
$<$<CONFIG:Debug>:
|
||||||
@ -302,7 +310,8 @@ if (CMAKE_SYSTEM_NAME STREQUAL "Windows")
|
|||||||
$<$<NOT:$<OR:$<CONFIG:Debug>,$<CONFIG:Release>>>:${MSVC_RUNTIME_LIBRARY_DEFAULT}>
|
$<$<NOT:$<OR:$<CONFIG:Debug>,$<CONFIG:Release>>>:${MSVC_RUNTIME_LIBRARY_DEFAULT}>
|
||||||
)
|
)
|
||||||
endif()
|
endif()
|
||||||
set_target_properties(${PROJECT_NAME} PROPERTIES MSVC_RUNTIME_LIBRARY ${MSVC_RUNTIME_LIBRARY_STR})
|
set_target_properties(${ZTarget} PROPERTIES MSVC_RUNTIME_LIBRARY ${MSVC_RUNTIME_LIBRARY_STR})
|
||||||
|
endforeach()
|
||||||
endif()
|
endif()
|
||||||
################################################################################
|
################################################################################
|
||||||
# Compile definitions
|
# Compile definitions
|
||||||
@ -404,7 +413,7 @@ if(MSVC)
|
|||||||
endif()
|
endif()
|
||||||
|
|
||||||
if ("${CMAKE_CXX_COMPILER_ID}" MATCHES "GNU|Clang|AppleClang")
|
if ("${CMAKE_CXX_COMPILER_ID}" MATCHES "GNU|Clang|AppleClang")
|
||||||
target_compile_options(${PROJECT_NAME} PRIVATE
|
target_compile_options(${PROJECT_NAME} PUBLIC
|
||||||
-Wall -Wextra -Wno-error
|
-Wall -Wextra -Wno-error
|
||||||
-Wno-unused-parameter
|
-Wno-unused-parameter
|
||||||
-Wno-unused-function
|
-Wno-unused-function
|
||||||
@ -417,11 +426,11 @@ if ("${CMAKE_CXX_COMPILER_ID}" MATCHES "GNU|Clang|AppleClang")
|
|||||||
)
|
)
|
||||||
|
|
||||||
if (CMAKE_SYSTEM_NAME STREQUAL "Darwin")
|
if (CMAKE_SYSTEM_NAME STREQUAL "Darwin")
|
||||||
target_link_options(${PROJECT_NAME} PRIVATE
|
target_link_options(${PROJECT_NAME} PUBLIC
|
||||||
-pthread
|
-pthread
|
||||||
)
|
)
|
||||||
else()
|
else()
|
||||||
target_link_options(${PROJECT_NAME} PRIVATE
|
target_link_options(${PROJECT_NAME} PUBLIC
|
||||||
-pthread
|
-pthread
|
||||||
-Wl,-export-dynamic
|
-Wl,-export-dynamic
|
||||||
)
|
)
|
||||||
@ -491,7 +500,7 @@ endif()
|
|||||||
|
|
||||||
if(CMAKE_SYSTEM_NAME MATCHES "NintendoSwitch|CafeOS")
|
if(CMAKE_SYSTEM_NAME MATCHES "NintendoSwitch|CafeOS")
|
||||||
add_library(pathconf OBJECT pathconf.c)
|
add_library(pathconf OBJECT pathconf.c)
|
||||||
target_link_libraries(${PROJECT_NAME} PRIVATE "${ADDITIONAL_LIBRARY_DEPENDENCIES}" $<TARGET_OBJECTS:pathconf> )
|
target_link_libraries(${PROJECT_NAME} PUBLIC "${ADDITIONAL_LIBRARY_DEPENDENCIES}" $<TARGET_OBJECTS:pathconf> )
|
||||||
else()
|
else()
|
||||||
target_link_libraries(${PROJECT_NAME} PRIVATE "${ADDITIONAL_LIBRARY_DEPENDENCIES}")
|
target_link_libraries(${PROJECT_NAME} PUBLIC "${ADDITIONAL_LIBRARY_DEPENDENCIES}")
|
||||||
endif()
|
endif()
|
||||||
|
5
ZAPDTR/ZAPD/ExecutableMain.cpp
Normal file
5
ZAPDTR/ZAPD/ExecutableMain.cpp
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
extern "C" int zapd_main(int argc, char* argv[]);
|
||||||
|
|
||||||
|
int main(int argc, char* argv[]) {
|
||||||
|
return zapd_main(argc, argv);
|
||||||
|
}
|
@ -27,11 +27,14 @@ Globals::Globals()
|
|||||||
|
|
||||||
Globals::~Globals()
|
Globals::~Globals()
|
||||||
{
|
{
|
||||||
auto& exporters = GetExporterMap();
|
for (const auto& w : workerData)
|
||||||
|
|
||||||
for (auto& it : exporters)
|
|
||||||
{
|
{
|
||||||
delete it.second;
|
delete w.second;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rom != nullptr)
|
||||||
|
{
|
||||||
|
delete rom;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -67,7 +67,7 @@ public:
|
|||||||
bool buildRawTexture = false;
|
bool buildRawTexture = false;
|
||||||
bool onlyGenSohOtr = false;
|
bool onlyGenSohOtr = false;
|
||||||
|
|
||||||
ZRom* rom;
|
ZRom* rom = nullptr;
|
||||||
std::vector<ZFile*> files;
|
std::vector<ZFile*> files;
|
||||||
std::vector<ZFile*> externalFiles;
|
std::vector<ZFile*> externalFiles;
|
||||||
std::vector<int32_t> segments;
|
std::vector<int32_t> segments;
|
||||||
|
@ -4,9 +4,71 @@
|
|||||||
#include "Utils/File.h"
|
#include "Utils/File.h"
|
||||||
#include "Utils/Path.h"
|
#include "Utils/Path.h"
|
||||||
#include "WarningHandler.h"
|
#include "WarningHandler.h"
|
||||||
|
|
||||||
#include "ZAnimation.h"
|
#include "ZAnimation.h"
|
||||||
|
ZNormalAnimation nAnim(nullptr);
|
||||||
|
ZCurveAnimation cAnim(nullptr);
|
||||||
|
ZLinkAnimation lAnim(nullptr);
|
||||||
|
ZLegacyAnimation lAnim2(nullptr);
|
||||||
|
|
||||||
|
#include "ZArray.h"
|
||||||
|
ZArray arr(nullptr);
|
||||||
|
|
||||||
|
#include "ZAudio.h"
|
||||||
|
ZAudio audio(nullptr);
|
||||||
|
|
||||||
#include "ZBackground.h"
|
#include "ZBackground.h"
|
||||||
|
ZBackground back(nullptr);
|
||||||
|
|
||||||
#include "ZBlob.h"
|
#include "ZBlob.h"
|
||||||
|
ZBlob blob(nullptr);
|
||||||
|
|
||||||
|
#include "ZCollision.h"
|
||||||
|
ZCollisionHeader colHeader(nullptr);
|
||||||
|
|
||||||
|
#include "ZCutscene.h"
|
||||||
|
ZCutscene cs(nullptr);
|
||||||
|
|
||||||
|
#include "ZLimb.h"
|
||||||
|
ZLimb limb(nullptr);
|
||||||
|
|
||||||
|
#include "ZMtx.h"
|
||||||
|
ZMtx mtx(nullptr);
|
||||||
|
|
||||||
|
#include "ZPath.h"
|
||||||
|
ZPath path(nullptr);
|
||||||
|
|
||||||
|
#include "ZPlayerAnimationData.h"
|
||||||
|
ZPlayerAnimationData pAnimData(nullptr);
|
||||||
|
|
||||||
|
#include "ZScalar.h"
|
||||||
|
ZScalar scalar(nullptr);
|
||||||
|
|
||||||
|
#include "ZSkeleton.h"
|
||||||
|
ZLimbTable limbTbl(nullptr);
|
||||||
|
ZSkeleton skel(nullptr);
|
||||||
|
|
||||||
|
#include "ZString.h"
|
||||||
|
ZString str(nullptr);
|
||||||
|
|
||||||
|
#include "ZSymbol.h"
|
||||||
|
ZSymbol sym(nullptr);
|
||||||
|
|
||||||
|
#include "ZText.h"
|
||||||
|
ZText txt(nullptr);
|
||||||
|
|
||||||
|
#include "ZTexture.h"
|
||||||
|
ZTexture tex(nullptr);
|
||||||
|
|
||||||
|
#include "ZVector.h"
|
||||||
|
ZVector vec(nullptr);
|
||||||
|
|
||||||
|
#include "ZVtx.h"
|
||||||
|
ZVtx vtx(nullptr);
|
||||||
|
|
||||||
|
#include "ZRoom/ZRoom.h"
|
||||||
|
ZRoom room(nullptr);
|
||||||
|
|
||||||
#include "ZFile.h"
|
#include "ZFile.h"
|
||||||
#include "ZTexture.h"
|
#include "ZTexture.h"
|
||||||
|
|
||||||
@ -29,29 +91,6 @@
|
|||||||
const char gBuildHash[] = "";
|
const char gBuildHash[] = "";
|
||||||
|
|
||||||
// LINUX_TODO: remove, those are because of soh <-> lus dependency problems
|
// LINUX_TODO: remove, those are because of soh <-> lus dependency problems
|
||||||
float divisor_num = 0.0f;
|
|
||||||
|
|
||||||
extern "C" void Audio_SetGameVolume(int player_id, float volume)
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
extern "C" int ResourceMgr_OTRSigCheck(char* imgData)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void DebugConsole_SaveCVars()
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void DebugConsole_LoadCVars()
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool Parse(const fs::path& xmlFilePath, const fs::path& basePath, const fs::path& outPath,
|
bool Parse(const fs::path& xmlFilePath, const fs::path& basePath, const fs::path& outPath,
|
||||||
ZFileMode fileMode, int workerID);
|
ZFileMode fileMode, int workerID);
|
||||||
@ -119,7 +158,9 @@ void ErrorHandler(int sig)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
int main(int argc, char* argv[])
|
extern void ImportExporters();
|
||||||
|
|
||||||
|
extern "C" int zapd_main(int argc, char* argv[])
|
||||||
{
|
{
|
||||||
// Syntax: ZAPD.out [mode (btex/bovl/e)] (Arbritrary Number of Arguments)
|
// Syntax: ZAPD.out [mode (btex/bovl/e)] (Arbritrary Number of Arguments)
|
||||||
|
|
||||||
@ -242,6 +283,7 @@ int main(int argc, char* argv[])
|
|||||||
}
|
}
|
||||||
else if (arg == "-se" || arg == "--set-exporter") // Set Current Exporter
|
else if (arg == "-se" || arg == "--set-exporter") // Set Current Exporter
|
||||||
{
|
{
|
||||||
|
ImportExporters();
|
||||||
Globals::Instance->currentExporter = argv[++i];
|
Globals::Instance->currentExporter = argv[++i];
|
||||||
}
|
}
|
||||||
else if (arg == "--gcc-compat") // GCC compatibility
|
else if (arg == "--gcc-compat") // GCC compatibility
|
||||||
@ -434,6 +476,9 @@ int main(int argc, char* argv[])
|
|||||||
exporterSet->endProgramFunc();
|
exporterSet->endProgramFunc();
|
||||||
|
|
||||||
end:
|
end:
|
||||||
|
delete exporterSet;
|
||||||
|
|
||||||
|
//Globals::Instance->GetExporterSet() = nullptr; //TODO NULL this out. Compiler complains about lvalue assignment.
|
||||||
|
|
||||||
delete g;
|
delete g;
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -96,6 +96,10 @@ if (NOT TARGET ZAPDUtils)
|
|||||||
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/../ZAPDTR/ZAPDUtils ${CMAKE_BINARY_DIR}/ZAPDUtils)
|
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/../ZAPDTR/ZAPDUtils ${CMAKE_BINARY_DIR}/ZAPDUtils)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
if (NOT TARGET ZAPDLib)
|
||||||
|
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/../ZAPDTR/ZAPD ${CMAKE_BINARY_DIR}/ZAPD)
|
||||||
|
endif()
|
||||||
|
|
||||||
set(PROJECT_NAME soh)
|
set(PROJECT_NAME soh)
|
||||||
|
|
||||||
################################################################################
|
################################################################################
|
||||||
@ -176,6 +180,23 @@ if (CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
|
|||||||
endif()
|
endif()
|
||||||
# }}}
|
# }}}
|
||||||
|
|
||||||
|
if(NOT CMAKE_SYSTEM_NAME MATCHES "NintendoSwitch|CafeOS")
|
||||||
|
# soh/Extractor {{{
|
||||||
|
file(GLOB_RECURSE soh__Extractor RELATIVE ${CMAKE_CURRENT_SOURCE_DIR}
|
||||||
|
"soh/Extractor/*.c"
|
||||||
|
"soh/Extractor/*.cpp"
|
||||||
|
"soh/Extractor/*.h"
|
||||||
|
"soh/Extractor/*.hpp"
|
||||||
|
)
|
||||||
|
# }}}
|
||||||
|
else()
|
||||||
|
file(GLOB_RECURSE soh__Extractor RELATIVE ${CMAKE_CURRENT_SOURCE_DIR}
|
||||||
|
"soh/Extractor/*.h"
|
||||||
|
"soh/Extractor/*.hpp"
|
||||||
|
)
|
||||||
|
# }}}
|
||||||
|
endif()
|
||||||
|
|
||||||
# soh/resource {{{
|
# soh/resource {{{
|
||||||
file(GLOB_RECURSE soh__Resource RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "soh/resource/*.cpp" "soh/resource/*.h")
|
file(GLOB_RECURSE soh__Resource RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "soh/resource/*.cpp" "soh/resource/*.h")
|
||||||
|
|
||||||
@ -224,6 +245,7 @@ set(ALL_FILES
|
|||||||
${Header_Files__include}
|
${Header_Files__include}
|
||||||
${soh__}
|
${soh__}
|
||||||
${soh__Enhancements}
|
${soh__Enhancements}
|
||||||
|
${soh__Extractor}
|
||||||
${soh__Resource}
|
${soh__Resource}
|
||||||
${src__}
|
${src__}
|
||||||
)
|
)
|
||||||
@ -599,6 +621,17 @@ if (CMAKE_SYSTEM_NAME STREQUAL "Windows")
|
|||||||
COMMAND $<CONFIG:Debug> copy /b $<SHELL_PATH:${CMAKE_BINARY_DIR}/>build.c +,,
|
COMMAND $<CONFIG:Debug> copy /b $<SHELL_PATH:${CMAKE_BINARY_DIR}/>build.c +,,
|
||||||
)
|
)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
if(NOT CMAKE_SYSTEM_NAME MATCHES "NintendoSwitch|CafeOS")
|
||||||
|
add_custom_command(
|
||||||
|
TARGET ${PROJECT_NAME}
|
||||||
|
POST_BUILD
|
||||||
|
COMMENT "Copying asset xmls..."
|
||||||
|
COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_SOURCE_DIR}/OTRGui/assets $<TARGET_FILE_DIR:soh>/assets
|
||||||
|
COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_SOURCE_DIR}/soh/assets/xml $<TARGET_FILE_DIR:soh>/assets/extractor/xmls
|
||||||
|
COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_SOURCE_DIR}/OTRExporter/assets $<TARGET_FILE_DIR:soh>/Extract/assets
|
||||||
|
)
|
||||||
|
endif()
|
||||||
################################################################################
|
################################################################################
|
||||||
# Dependencies
|
# Dependencies
|
||||||
################################################################################
|
################################################################################
|
||||||
@ -606,12 +639,18 @@ add_dependencies(${PROJECT_NAME}
|
|||||||
ZAPDUtils
|
ZAPDUtils
|
||||||
libultraship
|
libultraship
|
||||||
)
|
)
|
||||||
|
if(NOT CMAKE_SYSTEM_NAME MATCHES "NintendoSwitch|CafeOS")
|
||||||
|
add_dependencies(${PROJECT_NAME}
|
||||||
|
ZAPDLib
|
||||||
|
)
|
||||||
|
endif()
|
||||||
|
|
||||||
if (CMAKE_SYSTEM_NAME STREQUAL "Windows")
|
if (CMAKE_SYSTEM_NAME STREQUAL "Windows")
|
||||||
if("${CMAKE_VS_PLATFORM_NAME}" STREQUAL "x64")
|
if("${CMAKE_VS_PLATFORM_NAME}" STREQUAL "x64")
|
||||||
set(ADDITIONAL_LIBRARY_DEPENDENCIES
|
set(ADDITIONAL_LIBRARY_DEPENDENCIES
|
||||||
"libultraship;"
|
"libultraship;"
|
||||||
"ZAPDUtils;"
|
"ZAPDUtils;"
|
||||||
|
"ZAPDLib;"
|
||||||
"glu32;"
|
"glu32;"
|
||||||
"SDL2::SDL2;"
|
"SDL2::SDL2;"
|
||||||
"SDL2::SDL2main;"
|
"SDL2::SDL2main;"
|
||||||
@ -626,6 +665,7 @@ if (CMAKE_SYSTEM_NAME STREQUAL "Windows")
|
|||||||
set(ADDITIONAL_LIBRARY_DEPENDENCIES
|
set(ADDITIONAL_LIBRARY_DEPENDENCIES
|
||||||
"libultraship;"
|
"libultraship;"
|
||||||
"ZAPDUtils;"
|
"ZAPDUtils;"
|
||||||
|
"ZAPDLib;"
|
||||||
"glu32;"
|
"glu32;"
|
||||||
"SDL2::SDL2;"
|
"SDL2::SDL2;"
|
||||||
"SDL2::SDL2main;"
|
"SDL2::SDL2main;"
|
||||||
@ -651,7 +691,6 @@ elseif(CMAKE_SYSTEM_NAME STREQUAL "CafeOS")
|
|||||||
find_package(SDL2 REQUIRED)
|
find_package(SDL2 REQUIRED)
|
||||||
set(ADDITIONAL_LIBRARY_DEPENDENCIES
|
set(ADDITIONAL_LIBRARY_DEPENDENCIES
|
||||||
"libultraship;"
|
"libultraship;"
|
||||||
"ZAPDUtils;"
|
|
||||||
SDL2::SDL2-static
|
SDL2::SDL2-static
|
||||||
|
|
||||||
"$<$<CONFIG:Debug>:-Wl,--wrap=abort>"
|
"$<$<CONFIG:Debug>:-Wl,--wrap=abort>"
|
||||||
@ -666,6 +705,7 @@ else()
|
|||||||
set(ADDITIONAL_LIBRARY_DEPENDENCIES
|
set(ADDITIONAL_LIBRARY_DEPENDENCIES
|
||||||
"libultraship;"
|
"libultraship;"
|
||||||
"ZAPDUtils;"
|
"ZAPDUtils;"
|
||||||
|
"ZAPDLib;"
|
||||||
SDL2::SDL2
|
SDL2::SDL2
|
||||||
"$<$<BOOL:${BUILD_CROWD_CONTROL}>:SDL2_net::SDL2_net>"
|
"$<$<BOOL:${BUILD_CROWD_CONTROL}>:SDL2_net::SDL2_net>"
|
||||||
${CMAKE_DL_LIBS}
|
${CMAKE_DL_LIBS}
|
||||||
|
42
soh/soh/Extractor/EndianCvt.c
Normal file
42
soh/soh/Extractor/EndianCvt.c
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
#include <stdint.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
#define BSWAP32 _byteswap_ulong
|
||||||
|
#define BSWAP16 _byteswap_ushort
|
||||||
|
#elif __has_include(<byteswap.h>)
|
||||||
|
#include <byteswap.h>
|
||||||
|
#define BSWAP32 bswap_32
|
||||||
|
#define BSWAP16 bswap_16
|
||||||
|
#else
|
||||||
|
#define BSWAP16(value) ((((value)&0xff) << 8) | ((value) >> 8))
|
||||||
|
|
||||||
|
#define BSWAP32(value) \
|
||||||
|
(((uint32_t)BSWAP16((uint16_t)((value)&0xffff)) << 16) | (uint32_t)BSWAP16((uint16_t)((value) >> 16)))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
void RomToBigEndian(void* rom, size_t romSize) {
|
||||||
|
uint8_t firstbyte = ((uint8_t*)rom)[0];
|
||||||
|
|
||||||
|
switch (firstbyte) {
|
||||||
|
case 0x80: // BE
|
||||||
|
return; // Already BE, no need to swap
|
||||||
|
case 0x37:
|
||||||
|
for (size_t pos = 0; pos < (romSize / 2); pos++) {
|
||||||
|
((uint16_t*)rom)[pos] = BSWAP16(((uint16_t*)rom)[pos]);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
case 0x40:
|
||||||
|
for (size_t pos = 0; pos < (romSize / 4); pos++) {
|
||||||
|
((uint32_t*)rom)[pos] = BSWAP32(((uint32_t*)rom)[pos]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
476
soh/soh/Extractor/Extract.cpp
Normal file
476
soh/soh/Extractor/Extract.cpp
Normal file
@ -0,0 +1,476 @@
|
|||||||
|
#ifdef _WIN32
|
||||||
|
#include <Windows.h>
|
||||||
|
#include <winuser.h>
|
||||||
|
#include <shlwapi.h>
|
||||||
|
#pragma comment(lib, "Shlwapi.lib")
|
||||||
|
#endif
|
||||||
|
#include "Extract.h"
|
||||||
|
#include "portable-file-dialogs.h"
|
||||||
|
|
||||||
|
#ifdef unix
|
||||||
|
#include <dirent.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
#define BSWAP32 _byteswap_ulong
|
||||||
|
#define BSWAP16 _byteswap_ushort
|
||||||
|
#elif __has_include(<byteswap.h>)
|
||||||
|
#include <byteswap.h>
|
||||||
|
#define BSWAP32 bswap_32
|
||||||
|
#define BSWAP16 bswap_16
|
||||||
|
#else
|
||||||
|
#define BSWAP16(value) ((((value)&0xff) << 8) | ((value) >> 8))
|
||||||
|
|
||||||
|
#define BSWAP32(value) \
|
||||||
|
(((uint32_t)BSWAP16((uint16_t)((value)&0xffff)) << 16) | (uint32_t)BSWAP16((uint16_t)((value) >> 16)))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(_MSC_VER)
|
||||||
|
#define UNREACHABLE __assume(0)
|
||||||
|
#elif __llvm__
|
||||||
|
#define UNREACHABLE __builtin_assume(0)
|
||||||
|
#else
|
||||||
|
#define UNREACHABLE __builtin_unreachable();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#include <SDL2/SDL_messagebox.h>
|
||||||
|
|
||||||
|
#include <array>
|
||||||
|
#include <fstream>
|
||||||
|
#include <filesystem>
|
||||||
|
#include <unordered_map>
|
||||||
|
|
||||||
|
extern "C" uint32_t CRC32C(unsigned char* data, size_t dataSize);
|
||||||
|
extern "C" void RomToBigEndian(void* rom, size_t romSize);
|
||||||
|
|
||||||
|
static constexpr uint32_t OOT_PAL_GC = 0x09465AC3;
|
||||||
|
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 const std::unordered_map<uint32_t, const char*> verMap = {
|
||||||
|
{ OOT_PAL_GC, "Pal Gamecube" },
|
||||||
|
{ OOT_PAL_GC_DBG1, "PAL Debug 1" },
|
||||||
|
{ OOT_PAL_GC_DBG2, "PAL Debug 2" },
|
||||||
|
{ OOT_PAL_GC_MQ_DBG, "PAL MQ Debug" },
|
||||||
|
};
|
||||||
|
|
||||||
|
// TODO only check the first 54MB of the rom.
|
||||||
|
static constexpr std::array<const uint32_t, 7> goodCrcs = {
|
||||||
|
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
|
||||||
|
};
|
||||||
|
|
||||||
|
enum class ButtonId : int {
|
||||||
|
YES,
|
||||||
|
NO,
|
||||||
|
FIND,
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
void Extractor::ShowErrorBox(const char* title, const char* text) {
|
||||||
|
#ifdef _WIN32
|
||||||
|
MessageBoxA(nullptr, text, title, MB_OK | MB_ICONERROR);
|
||||||
|
#else
|
||||||
|
SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, title, text, nullptr);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void Extractor::ShowSizeErrorBox() const {
|
||||||
|
std::unique_ptr<char[]> boxBuffer = std::make_unique<char[]>(mCurrentRomPath.size() + 100);
|
||||||
|
snprintf(boxBuffer.get(), mCurrentRomPath.size() + 100,
|
||||||
|
"The rom file %s was not a valid size. Was %zu MB, expecting 32, 54, or 64MB.", mCurrentRomPath.c_str(),
|
||||||
|
mCurRomSize / MB_BASE);
|
||||||
|
ShowErrorBox("Invalid Rom Size", boxBuffer.get());
|
||||||
|
}
|
||||||
|
|
||||||
|
void Extractor::ShowCrcErrorBox() const {
|
||||||
|
ShowErrorBox("Rom CRC invalid", "Rom CRC did not match the list of known good roms. Please find another.");
|
||||||
|
}
|
||||||
|
|
||||||
|
int Extractor::ShowRomPickBox(uint32_t verCrc) const {
|
||||||
|
std::unique_ptr<char[]> boxBuffer = std::make_unique<char[]>(mCurrentRomPath.size() + 100);
|
||||||
|
SDL_MessageBoxData boxData = { 0 };
|
||||||
|
SDL_MessageBoxButtonData buttons[3] = { { 0 } };
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
buttons[0].buttonid = 0;
|
||||||
|
buttons[0].text = "Yes";
|
||||||
|
buttons[0].flags = SDL_MESSAGEBOX_BUTTON_RETURNKEY_DEFAULT;
|
||||||
|
buttons[1].buttonid = 1;
|
||||||
|
buttons[1].text = "No";
|
||||||
|
buttons[1].flags = SDL_MESSAGEBOX_BUTTON_ESCAPEKEY_DEFAULT;
|
||||||
|
buttons[2].buttonid = 2;
|
||||||
|
buttons[2].text = "Find ROM";
|
||||||
|
boxData.numbuttons = 3;
|
||||||
|
boxData.flags = SDL_MESSAGEBOX_INFORMATION;
|
||||||
|
boxData.message = boxBuffer.get();
|
||||||
|
boxData.title = "Rom Detected";
|
||||||
|
boxData.window = nullptr;
|
||||||
|
|
||||||
|
boxData.buttons = buttons;
|
||||||
|
snprintf(boxBuffer.get(), mCurrentRomPath.size() + 100,
|
||||||
|
"Rom detected: %s, Header CRC32: %8X. It appears to be: %s. Use this rom?", mCurrentRomPath.c_str(),
|
||||||
|
verCrc, verMap.at(verCrc));
|
||||||
|
|
||||||
|
SDL_ShowMessageBox(&boxData, &ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
int Extractor::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;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Extractor::SetRomInfo(const std::string& path) {
|
||||||
|
mCurrentRomPath = path;
|
||||||
|
mCurRomSize = GetCurRomSize();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Extractor::GetRoms(std::vector<std::string>& roms) {
|
||||||
|
#ifdef _WIN32
|
||||||
|
WIN32_FIND_DATAA ffd;
|
||||||
|
HANDLE h = FindFirstFileA(".\\*", &ffd);
|
||||||
|
|
||||||
|
do {
|
||||||
|
if (!(ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) {
|
||||||
|
char* ext = PathFindExtensionA(ffd.cFileName);
|
||||||
|
|
||||||
|
// Check for any standard N64 rom file extensions.
|
||||||
|
if ((strcmp(ext, ".z64") == 0) || (strcmp(ext, ".n64") == 0) || (strcmp(ext, ".v64") == 0))
|
||||||
|
roms.push_back(ffd.cFileName);
|
||||||
|
}
|
||||||
|
} while (FindNextFileA(h, &ffd) != 0);
|
||||||
|
// if (h != nullptr) {
|
||||||
|
// CloseHandle(h);
|
||||||
|
//}
|
||||||
|
#elif unix
|
||||||
|
// Open the directory of the app.
|
||||||
|
DIR* d = opendir(".");
|
||||||
|
struct dirent* dir;
|
||||||
|
|
||||||
|
if (d != NULL) {
|
||||||
|
// Go through each file in the directory
|
||||||
|
while ((dir = readdir(d)) != NULL) {
|
||||||
|
struct stat path;
|
||||||
|
|
||||||
|
// Check if current entry is not folder
|
||||||
|
stat(dir->d_name, &path);
|
||||||
|
if (S_ISREG(path.st_mode)) {
|
||||||
|
|
||||||
|
// Get the position of the extension character.
|
||||||
|
char* ext = strchr(dir->d_name, '.');
|
||||||
|
if (ext != NULL && (strcmp(ext, ".z64") == 0) && (strcmp(ext, ".n64") == 0) &&
|
||||||
|
(strcmp(ext, ".v64") == 0)) {
|
||||||
|
roms.push_back(dir->d_name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
closedir(d);
|
||||||
|
#else
|
||||||
|
for (const auto& file : std::filesystem::directory_iterator("./")) {
|
||||||
|
if (file.is_directory())
|
||||||
|
continue;
|
||||||
|
if ((file.path().extension() == ".n64") || (file.path().extension() == ".z64") ||
|
||||||
|
(file.path().extension() == ".v64")) {
|
||||||
|
roms.push_back((file.path()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Extractor::GetRomPathFromBox() {
|
||||||
|
#ifdef _WIN32
|
||||||
|
OPENFILENAMEA box = { 0 };
|
||||||
|
char nameBuffer[512];
|
||||||
|
nameBuffer[0] = 0;
|
||||||
|
|
||||||
|
box.lStructSize = sizeof(box);
|
||||||
|
box.lpstrFile = nameBuffer;
|
||||||
|
box.nMaxFile = sizeof(nameBuffer) / sizeof(nameBuffer[0]);
|
||||||
|
box.lpstrTitle = "Open Rom";
|
||||||
|
box.Flags = OFN_NOCHANGEDIR | OFN_ENABLESIZING | OFN_FILEMUSTEXIST | OFN_LONGNAMES | OFN_PATHMUSTEXIST | OFN_HIDEREADONLY;
|
||||||
|
box.lpstrFilter = "N64 Roms\0*.z64;*.v64;*.n64\0\0";
|
||||||
|
if (!GetOpenFileNameA(&box)) {
|
||||||
|
DWORD err = CommDlgExtendedError();
|
||||||
|
// GetOpenFileName will return 0 but no error is set if the user just closes the box.
|
||||||
|
if (err != 0) {
|
||||||
|
const char* errStr = nullptr;
|
||||||
|
switch (err) {
|
||||||
|
case FNERR_BUFFERTOOSMALL:
|
||||||
|
errStr = "Path buffer too small. Move file closer to root of your drive";
|
||||||
|
break;
|
||||||
|
case FNERR_INVALIDFILENAME:
|
||||||
|
errStr = "File name for rom provided is invalid.";
|
||||||
|
break;
|
||||||
|
case FNERR_SUBCLASSFAILURE:
|
||||||
|
errStr = "Failed to open a filebox because there is not enough RAM to do so.";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
MessageBoxA(nullptr, "Box Error", errStr, MB_OK | MB_ICONERROR);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// The box was closed without something being selected.
|
||||||
|
if (nameBuffer[0] == 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
mCurrentRomPath = nameBuffer;
|
||||||
|
#else
|
||||||
|
auto selection = pfd::open_file("Select a file", ".", { "N64 Roms", "*.z64 *.n64 *.v64" }).result();
|
||||||
|
|
||||||
|
if (selection.empty()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
mCurrentRomPath = selection[0];
|
||||||
|
#endif
|
||||||
|
mCurRomSize = GetCurRomSize();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
uint32_t Extractor::GetRomVerCrc() const {
|
||||||
|
return BSWAP32(((uint32_t*)mRomData.get())[4]);
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t Extractor::GetCurRomSize() const {
|
||||||
|
return std::filesystem::file_size(mCurrentRomPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
for (const uint32_t crc : goodCrcs) {
|
||||||
|
if (actualCrc == crc) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Extractor::ValidateRomSize() const {
|
||||||
|
if (mCurRomSize != MB32 && mCurRomSize != MB54 && mCurRomSize != MB64) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Extractor::ValidateRom(bool skipCrcTextBox) {
|
||||||
|
if (!ValidateRomSize()) {
|
||||||
|
ShowSizeErrorBox();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!ValidateAndFixRom()) {
|
||||||
|
if (!skipCrcTextBox) {
|
||||||
|
ShowCrcErrorBox();
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Extractor::Run() {
|
||||||
|
std::vector<std::string> roms;
|
||||||
|
std::ifstream inFile;
|
||||||
|
uint32_t verCrc;
|
||||||
|
|
||||||
|
GetRoms(roms);
|
||||||
|
|
||||||
|
if (roms.empty()) {
|
||||||
|
int ret = ShowYesNoBox("No roms found", "No roms found. Look for one?");
|
||||||
|
|
||||||
|
switch (ret) {
|
||||||
|
case IDYES:
|
||||||
|
if (!GetRomPathFromBox()) {
|
||||||
|
ShowErrorBox("No rom selected", "No rom selected. Exiting");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
inFile.open(mCurrentRomPath, std::ios::in | std::ios::binary);
|
||||||
|
if (!inFile.is_open()) {
|
||||||
|
return false; // TODO Handle error
|
||||||
|
}
|
||||||
|
inFile.read((char*)mRomData.get(), mCurRomSize);
|
||||||
|
if (!ValidateRom()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case IDNO:
|
||||||
|
ShowErrorBox("No rom selected", "No rom selected. Exiting");
|
||||||
|
return false;
|
||||||
|
default:
|
||||||
|
UNREACHABLE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const auto& rom : roms) {
|
||||||
|
int option;
|
||||||
|
|
||||||
|
SetRomInfo(rom);
|
||||||
|
if (inFile.is_open()) {
|
||||||
|
inFile.close();
|
||||||
|
}
|
||||||
|
inFile.open(rom, std::ios::in | std::ios::binary);
|
||||||
|
if (!ValidateRomSize()) {
|
||||||
|
ShowSizeErrorBox();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
inFile.read((char*)mRomData.get(), mCurRomSize);
|
||||||
|
RomToBigEndian(mRomData.get(), mCurRomSize);
|
||||||
|
verCrc = GetRomVerCrc();
|
||||||
|
|
||||||
|
// Rom doesn't claim to be valid
|
||||||
|
if (!verMap.contains(verCrc)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
option = ShowRomPickBox(verCrc);
|
||||||
|
if (option == (int)ButtonId::YES) {
|
||||||
|
if (!ValidateRom(true)) {
|
||||||
|
if (rom == roms.back()) {
|
||||||
|
ShowCrcErrorBox();
|
||||||
|
} else {
|
||||||
|
ShowErrorBox("Rom CRC invalid",
|
||||||
|
"Rom CRC did not match the list of known good roms. Trying the next one...");
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
} else if (option == (int)ButtonId::FIND) {
|
||||||
|
if (!GetRomPathFromBox()) {
|
||||||
|
ShowErrorBox("No rom selected", "No Rom selected. Exiting");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
inFile.open(mCurrentRomPath, std::ios::in | std::ios::binary);
|
||||||
|
if (!inFile.is_open()) {
|
||||||
|
return false; // TODO Handle error
|
||||||
|
}
|
||||||
|
inFile.read((char*)mRomData.get(), mCurRomSize);
|
||||||
|
if (!ValidateRom()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
} else if (option == (int)ButtonId::NO) {
|
||||||
|
inFile.close();
|
||||||
|
if (rom == roms.back()) {
|
||||||
|
ShowErrorBox("No rom provided", "No rom provided. Exiting");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Extractor::IsMasterQuest() const {
|
||||||
|
switch (GetRomVerCrc()) {
|
||||||
|
case OOT_PAL_GC_MQ_DBG:
|
||||||
|
return true;
|
||||||
|
case OOT_PAL_GC:
|
||||||
|
case OOT_PAL_GC_DBG1:
|
||||||
|
return false;
|
||||||
|
default:
|
||||||
|
UNREACHABLE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* Extractor::GetZapdVerStr() const {
|
||||||
|
switch (GetRomVerCrc()) {
|
||||||
|
case OOT_PAL_GC:
|
||||||
|
return "GC_NMQ_PAL_F";
|
||||||
|
case OOT_PAL_GC_DBG1:
|
||||||
|
return "GC_NMQ_D";
|
||||||
|
case OOT_PAL_GC_MQ_DBG:
|
||||||
|
return "GC_MQ_D";
|
||||||
|
default:
|
||||||
|
// We should never be in a state where this path happens.
|
||||||
|
UNREACHABLE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C" int zapd_main(int argc, char** argv);
|
||||||
|
|
||||||
|
bool Extractor::CallZapd() {
|
||||||
|
constexpr int argc = 16;
|
||||||
|
char xmlPath[100];
|
||||||
|
char baseromPath[100];
|
||||||
|
char confPath[100];
|
||||||
|
std::array<const char*, argc> argv;
|
||||||
|
const char* version = GetZapdVerStr();
|
||||||
|
|
||||||
|
snprintf(xmlPath, 100, "assets/extractor/xmls/%s", version);
|
||||||
|
snprintf(baseromPath, 100, "%s", mCurrentRomPath.c_str());
|
||||||
|
snprintf(confPath, 100, "assets/extractor/Config_%s.xml", version);
|
||||||
|
|
||||||
|
argv[0] = "ZAPD";
|
||||||
|
argv[1] = "ed";
|
||||||
|
argv[2] = "-i";
|
||||||
|
argv[3] = xmlPath;
|
||||||
|
argv[4] = "-b";
|
||||||
|
argv[5] = baseromPath;
|
||||||
|
argv[6] = "-fl";
|
||||||
|
argv[7] = "assets/extractor/filelists";
|
||||||
|
argv[8] = "-gsf";
|
||||||
|
argv[9] = "1";
|
||||||
|
argv[10] = "-rconf";
|
||||||
|
argv[11] = confPath;
|
||||||
|
argv[12] = "-se";
|
||||||
|
argv[13] = "OTR";
|
||||||
|
argv[14] = "--otrfile";
|
||||||
|
argv[15] = IsMasterQuest() ? "oot-mq.otr" : "oot.otr";
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
// Grab a handle to the command window.
|
||||||
|
HWND cmdWindow = GetConsoleWindow();
|
||||||
|
|
||||||
|
// Normally the command window is hidden. We want the window to be shown here so the user can see the progess of the extraction.
|
||||||
|
ShowWindow(cmdWindow, SW_SHOW);
|
||||||
|
SetWindowPos(cmdWindow, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
zapd_main(argc, (char**)argv.data());
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
// Hide the command window again.
|
||||||
|
ShowWindow(cmdWindow, SW_HIDE);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
54
soh/soh/Extractor/Extract.h
Normal file
54
soh/soh/Extractor/Extract.h
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
#ifndef EXTRACT_H
|
||||||
|
#define EXTRACT_H
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <string>
|
||||||
|
#include <memory>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
// Values come from windows.h
|
||||||
|
#ifndef IDYES
|
||||||
|
#define IDYES 6
|
||||||
|
#endif
|
||||||
|
#ifndef IDNO
|
||||||
|
#define IDNO 7
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static constexpr size_t MB_BASE = 1024 * 1024;
|
||||||
|
static constexpr size_t MB32 = 32 * MB_BASE;
|
||||||
|
static constexpr size_t MB54 = 54 * MB_BASE;
|
||||||
|
static constexpr size_t MB64 = 64 * MB_BASE;
|
||||||
|
|
||||||
|
class Extractor {
|
||||||
|
std::unique_ptr<unsigned char[]> mRomData = std::make_unique<unsigned char[]>(MB64);
|
||||||
|
std::string mCurrentRomPath;
|
||||||
|
size_t mCurRomSize = 0;
|
||||||
|
|
||||||
|
bool GetRomPathFromBox();
|
||||||
|
|
||||||
|
uint32_t GetRomVerCrc() const;
|
||||||
|
size_t GetCurRomSize() const;
|
||||||
|
bool ValidateAndFixRom();
|
||||||
|
bool ValidateRomSize() const;
|
||||||
|
|
||||||
|
bool ValidateRom(bool skipCrcBox = false);
|
||||||
|
const char* GetZapdVerStr() const;
|
||||||
|
bool IsMasterQuest() const;
|
||||||
|
|
||||||
|
void SetRomInfo(const std::string& path);
|
||||||
|
|
||||||
|
void GetRoms(std::vector<std::string>& roms);
|
||||||
|
void ShowSizeErrorBox() const;
|
||||||
|
void ShowCrcErrorBox() const;
|
||||||
|
int ShowRomPickBox(uint32_t verCrc) const;
|
||||||
|
|
||||||
|
public:
|
||||||
|
//TODO create some kind of abstraction for message boxes.
|
||||||
|
static int ShowYesNoBox(const char* title, const char* text);
|
||||||
|
static void ShowErrorBox(const char* title, const char* text);
|
||||||
|
|
||||||
|
bool Run();
|
||||||
|
bool CallZapd();
|
||||||
|
const char* GetZapdStr();
|
||||||
|
};
|
||||||
|
#endif
|
110
soh/soh/Extractor/FastCrc32C.c
Normal file
110
soh/soh/Extractor/FastCrc32C.c
Normal file
@ -0,0 +1,110 @@
|
|||||||
|
#include <stdint.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
#include <immintrin.h>
|
||||||
|
#elif ((defined(__GNUC__) && defined(__x86_64__) || defined(__i386__)) && defined(__SSE4_2__))
|
||||||
|
#include <nmmintrin.h>
|
||||||
|
#elif defined(__aarch64__) && defined(__ARM_FEATURE_CRC32)
|
||||||
|
// Nothing cause its a compiler builtin
|
||||||
|
#else
|
||||||
|
#define USE_CRC_TABLE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(__aarch64__) && defined(__ARM_FEATURE_CRC32)
|
||||||
|
#define INTRIN_CRC32_64(crc, value) __asm__("crc32cx %w[c], %w[c], %x[v]" : [c] "+r"(crc) : [v] "r"(value))
|
||||||
|
#define INTRIN_CRC32_32(crc, value) __asm__("crc32cw %w[c], %w[c], %w[v]" : [c] "+r"(crc) : [v] "r"(value))
|
||||||
|
#define INTRIN_CRC32_16(crc, value) __asm__("crc32ch %w[c], %w[c], %w[v]" : [c] "+r"(crc) : [v] "r"(value))
|
||||||
|
#define INTRIN_CRC32_8(crc, value) __asm__("crc32cb %w[c], %w[c], %w[v]" : [c] "+r"(crc) : [v] "r"(value))
|
||||||
|
#elif defined(__SSE4_2__) || defined(_MSC_VER)
|
||||||
|
#define INTRIN_CRC32_64(crc, data) crc = _mm_crc32_u64(crc, data)
|
||||||
|
#define INTRIN_CRC32_32(crc, data) crc = _mm_crc32_u32(crc, data)
|
||||||
|
#define INTRIN_CRC32_16(crc, data) crc = _mm_crc32_u16(crc, data)
|
||||||
|
#define INTRIN_CRC32_8(crc, data) crc = _mm_crc32_u8(crc, data)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef USE_CRC_TABLE
|
||||||
|
static const uint32_t crc32Table[256] = {
|
||||||
|
0x00000000L, 0xF26B8303L, 0xE13B70F7L, 0x1350F3F4L, 0xC79A971FL, 0x35F1141CL, 0x26A1E7E8L, 0xD4CA64EBL, 0x8AD958CFL,
|
||||||
|
0x78B2DBCCL, 0x6BE22838L, 0x9989AB3BL, 0x4D43CFD0L, 0xBF284CD3L, 0xAC78BF27L, 0x5E133C24L, 0x105EC76FL, 0xE235446CL,
|
||||||
|
0xF165B798L, 0x030E349BL, 0xD7C45070L, 0x25AFD373L, 0x36FF2087L, 0xC494A384L, 0x9A879FA0L, 0x68EC1CA3L, 0x7BBCEF57L,
|
||||||
|
0x89D76C54L, 0x5D1D08BFL, 0xAF768BBCL, 0xBC267848L, 0x4E4DFB4BL, 0x20BD8EDEL, 0xD2D60DDDL, 0xC186FE29L, 0x33ED7D2AL,
|
||||||
|
0xE72719C1L, 0x154C9AC2L, 0x061C6936L, 0xF477EA35L, 0xAA64D611L, 0x580F5512L, 0x4B5FA6E6L, 0xB93425E5L, 0x6DFE410EL,
|
||||||
|
0x9F95C20DL, 0x8CC531F9L, 0x7EAEB2FAL, 0x30E349B1L, 0xC288CAB2L, 0xD1D83946L, 0x23B3BA45L, 0xF779DEAEL, 0x05125DADL,
|
||||||
|
0x1642AE59L, 0xE4292D5AL, 0xBA3A117EL, 0x4851927DL, 0x5B016189L, 0xA96AE28AL, 0x7DA08661L, 0x8FCB0562L, 0x9C9BF696L,
|
||||||
|
0x6EF07595L, 0x417B1DBCL, 0xB3109EBFL, 0xA0406D4BL, 0x522BEE48L, 0x86E18AA3L, 0x748A09A0L, 0x67DAFA54L, 0x95B17957L,
|
||||||
|
0xCBA24573L, 0x39C9C670L, 0x2A993584L, 0xD8F2B687L, 0x0C38D26CL, 0xFE53516FL, 0xED03A29BL, 0x1F682198L, 0x5125DAD3L,
|
||||||
|
0xA34E59D0L, 0xB01EAA24L, 0x42752927L, 0x96BF4DCCL, 0x64D4CECFL, 0x77843D3BL, 0x85EFBE38L, 0xDBFC821CL, 0x2997011FL,
|
||||||
|
0x3AC7F2EBL, 0xC8AC71E8L, 0x1C661503L, 0xEE0D9600L, 0xFD5D65F4L, 0x0F36E6F7L, 0x61C69362L, 0x93AD1061L, 0x80FDE395L,
|
||||||
|
0x72966096L, 0xA65C047DL, 0x5437877EL, 0x4767748AL, 0xB50CF789L, 0xEB1FCBADL, 0x197448AEL, 0x0A24BB5AL, 0xF84F3859L,
|
||||||
|
0x2C855CB2L, 0xDEEEDFB1L, 0xCDBE2C45L, 0x3FD5AF46L, 0x7198540DL, 0x83F3D70EL, 0x90A324FAL, 0x62C8A7F9L, 0xB602C312L,
|
||||||
|
0x44694011L, 0x5739B3E5L, 0xA55230E6L, 0xFB410CC2L, 0x092A8FC1L, 0x1A7A7C35L, 0xE811FF36L, 0x3CDB9BDDL, 0xCEB018DEL,
|
||||||
|
0xDDE0EB2AL, 0x2F8B6829L, 0x82F63B78L, 0x709DB87BL, 0x63CD4B8FL, 0x91A6C88CL, 0x456CAC67L, 0xB7072F64L, 0xA457DC90L,
|
||||||
|
0x563C5F93L, 0x082F63B7L, 0xFA44E0B4L, 0xE9141340L, 0x1B7F9043L, 0xCFB5F4A8L, 0x3DDE77ABL, 0x2E8E845FL, 0xDCE5075CL,
|
||||||
|
0x92A8FC17L, 0x60C37F14L, 0x73938CE0L, 0x81F80FE3L, 0x55326B08L, 0xA759E80BL, 0xB4091BFFL, 0x466298FCL, 0x1871A4D8L,
|
||||||
|
0xEA1A27DBL, 0xF94AD42FL, 0x0B21572CL, 0xDFEB33C7L, 0x2D80B0C4L, 0x3ED04330L, 0xCCBBC033L, 0xA24BB5A6L, 0x502036A5L,
|
||||||
|
0x4370C551L, 0xB11B4652L, 0x65D122B9L, 0x97BAA1BAL, 0x84EA524EL, 0x7681D14DL, 0x2892ED69L, 0xDAF96E6AL, 0xC9A99D9EL,
|
||||||
|
0x3BC21E9DL, 0xEF087A76L, 0x1D63F975L, 0x0E330A81L, 0xFC588982L, 0xB21572C9L, 0x407EF1CAL, 0x532E023EL, 0xA145813DL,
|
||||||
|
0x758FE5D6L, 0x87E466D5L, 0x94B49521L, 0x66DF1622L, 0x38CC2A06L, 0xCAA7A905L, 0xD9F75AF1L, 0x2B9CD9F2L, 0xFF56BD19L,
|
||||||
|
0x0D3D3E1AL, 0x1E6DCDEEL, 0xEC064EEDL, 0xC38D26C4L, 0x31E6A5C7L, 0x22B65633L, 0xD0DDD530L, 0x0417B1DBL, 0xF67C32D8L,
|
||||||
|
0xE52CC12CL, 0x1747422FL, 0x49547E0BL, 0xBB3FFD08L, 0xA86F0EFCL, 0x5A048DFFL, 0x8ECEE914L, 0x7CA56A17L, 0x6FF599E3L,
|
||||||
|
0x9D9E1AE0L, 0xD3D3E1ABL, 0x21B862A8L, 0x32E8915CL, 0xC083125FL, 0x144976B4L, 0xE622F5B7L, 0xF5720643L, 0x07198540L,
|
||||||
|
0x590AB964L, 0xAB613A67L, 0xB831C993L, 0x4A5A4A90L, 0x9E902E7BL, 0x6CFBAD78L, 0x7FAB5E8CL, 0x8DC0DD8FL, 0xE330A81AL,
|
||||||
|
0x115B2B19L, 0x020BD8EDL, 0xF0605BEEL, 0x24AA3F05L, 0xD6C1BC06L, 0xC5914FF2L, 0x37FACCF1L, 0x69E9F0D5L, 0x9B8273D6L,
|
||||||
|
0x88D28022L, 0x7AB90321L, 0xAE7367CAL, 0x5C18E4C9L, 0x4F48173DL, 0xBD23943EL, 0xF36E6F75L, 0x0105EC76L, 0x12551F82L,
|
||||||
|
0xE03E9C81L, 0x34F4F86AL, 0xC69F7B69L, 0xD5CF889DL, 0x27A40B9EL, 0x79B737BAL, 0x8BDCB4B9L, 0x988C474DL, 0x6AE7C44EL,
|
||||||
|
0xBE2DA0A5L, 0x4C4623A6L, 0x5F16D052L, 0xAD7D5351L
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef USE_CRC_TABLE
|
||||||
|
uint32_t CRC32C(unsigned char* data, size_t dataSize) {
|
||||||
|
uint32_t ret = 0xFFFFFFFF;
|
||||||
|
int64_t sizeSigned = dataSize;
|
||||||
|
|
||||||
|
#if defined(_M_X64) || defined(__x86_64__) || defined(__aarch64__)
|
||||||
|
while ((sizeSigned -= sizeof(uint64_t)) >= 0) {
|
||||||
|
INTRIN_CRC32_64(ret, *(uint64_t*)data);
|
||||||
|
data += sizeof(uint64_t);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sizeSigned & sizeof(uint32_t)) {
|
||||||
|
INTRIN_CRC32_32(ret, *(uint32_t*)data);
|
||||||
|
|
||||||
|
data += sizeof(uint32_t);
|
||||||
|
}
|
||||||
|
#elif defined(_M_IX86) || defined(__i386__)
|
||||||
|
while ((sizeSigned -= sizeof(uint32_t)) >= 0) {
|
||||||
|
INTRIN_CRC32_32(ret, *(uint32_t*)data);
|
||||||
|
data += sizeof(uint32_t);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
if (sizeSigned & sizeof(uint16_t)) {
|
||||||
|
INTRIN_CRC32_16(ret, *(uint16_t*)data);
|
||||||
|
data += sizeof(uint16_t);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sizeSigned & sizeof(uint8_t)) {
|
||||||
|
INTRIN_CRC32_8(ret, *data);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ~ret;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
uint32_t CRC32C(const void* buf, size_t size) {
|
||||||
|
const uint8_t* p = buf;
|
||||||
|
uint32_t crc = 0xFFFFFFFF;
|
||||||
|
|
||||||
|
while (size--)
|
||||||
|
crc = crc32Table[(crc ^ *p++) & 0xff] ^ (crc >> 8);
|
||||||
|
|
||||||
|
return ~crc;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
1887
soh/soh/Extractor/portable-file-dialogs.h
Normal file
1887
soh/soh/Extractor/portable-file-dialogs.h
Normal file
File diff suppressed because it is too large
Load Diff
@ -49,6 +49,10 @@
|
|||||||
#include <Hooks.h>
|
#include <Hooks.h>
|
||||||
#include "Enhancements/custom-message/CustomMessageManager.h"
|
#include "Enhancements/custom-message/CustomMessageManager.h"
|
||||||
|
|
||||||
|
#if not defined (__SWITCH__) && not defined(__WIIU__)
|
||||||
|
#include "Extractor/Extract.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <Fast3D/gfx_pc.h>
|
#include <Fast3D/gfx_pc.h>
|
||||||
#include <Fast3D/gfx_rendering_api.h>
|
#include <Fast3D/gfx_rendering_api.h>
|
||||||
|
|
||||||
@ -703,6 +707,28 @@ extern "C" void OTRExtScanner() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
extern "C" void InitOTR() {
|
extern "C" void InitOTR() {
|
||||||
|
#if not defined (__SWITCH__) && not defined(__WIIU__)
|
||||||
|
if (!std::filesystem::exists(Ship::Window::GetPathRelativeToAppDirectory("oot-mq.otr")) &&
|
||||||
|
!std::filesystem::exists(Ship::Window::GetPathRelativeToAppDirectory("oot.otr"))){
|
||||||
|
if (Extractor::ShowYesNoBox("No OTR Files", "No OTR files found. Generate one now?") == IDYES) {
|
||||||
|
Extractor extract;
|
||||||
|
if (!extract.Run()) {
|
||||||
|
Extractor::ShowErrorBox("Error", "An error occured, no OTR file was generated. Exiting...");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
extract.CallZapd();
|
||||||
|
}
|
||||||
|
if (Extractor::ShowYesNoBox("Extraction Complete", "ROM Extracted. Extract another?") == IDYES) {
|
||||||
|
Extractor extract;
|
||||||
|
if (!extract.Run()) {
|
||||||
|
Extractor::ShowErrorBox("Error", "An error occured, an OTR file may have been generated by a different step. Continuing...");
|
||||||
|
} else {
|
||||||
|
extract.CallZapd();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef __SWITCH__
|
#ifdef __SWITCH__
|
||||||
Ship::Switch::Init(Ship::PreInitPhase);
|
Ship::Switch::Init(Ship::PreInitPhase);
|
||||||
#elif defined(__WIIU__)
|
#elif defined(__WIIU__)
|
||||||
|
@ -10,7 +10,6 @@
|
|||||||
#include <libultraship/bridge.h>
|
#include <libultraship/bridge.h>
|
||||||
#include "soh/CrashHandlerExp.h"
|
#include "soh/CrashHandlerExp.h"
|
||||||
|
|
||||||
|
|
||||||
s32 gScreenWidth = SCREEN_WIDTH;
|
s32 gScreenWidth = SCREEN_WIDTH;
|
||||||
s32 gScreenHeight = SCREEN_HEIGHT;
|
s32 gScreenHeight = SCREEN_HEIGHT;
|
||||||
size_t gSystemHeapSize = 0;
|
size_t gSystemHeapSize = 0;
|
||||||
@ -44,11 +43,21 @@ void Main_LogSystemHeap(void) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
int APIENTRY WinMain(HINSTANCE hInst, HINSTANCE hInstPrev, PSTR cmdline, int cmdshow)
|
int SDL_main(int argc, char** argv)
|
||||||
#else
|
|
||||||
int main(int argc, char** argv)
|
|
||||||
#endif
|
|
||||||
{
|
{
|
||||||
|
AllocConsole();
|
||||||
|
(void)freopen("CONIN$", "r", stdin);
|
||||||
|
(void)freopen("CONOUT$", "w", stdout);
|
||||||
|
(void)freopen("CONOUT$", "w", stderr);
|
||||||
|
#ifndef _DEBUG
|
||||||
|
ShowWindow(GetConsoleWindow(), SW_HIDE);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#else //_WIN32
|
||||||
|
int main(int argc, char** argv)
|
||||||
|
{
|
||||||
|
#endif
|
||||||
|
|
||||||
GameConsole_Init();
|
GameConsole_Init();
|
||||||
InitOTR();
|
InitOTR();
|
||||||
// TODO: Was moved to below InitOTR because it requires window to be setup. But will be late to catch crashes.
|
// TODO: Was moved to below InitOTR because it requires window to be setup. But will be late to catch crashes.
|
||||||
|
Loading…
Reference in New Issue
Block a user