Add extraction support for ByteSwapped and LittleEndian formats (#3042)

* add extraction support for byteswapped and littleendian formats

* update linux/mac scripts to handle v64 and n64
This commit is contained in:
Adam Bird 2023-09-10 19:20:58 +02:00 committed by GitHub
parent 644ab7f498
commit a129371923
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 116 additions and 48 deletions

View File

@ -22,6 +22,7 @@
#include <Utils/Directory.h> #include <Utils/Directory.h>
#include <Utils/MemoryStream.h> #include <Utils/MemoryStream.h>
#include <Utils/BinaryWriter.h> #include <Utils/BinaryWriter.h>
#include <Utils/BitConverter.h>
#include <bit> #include <bit>
#include <mutex> #include <mutex>
@ -70,7 +71,10 @@ static void ExporterProgramEnd()
if (Globals::Instance->fileMode == ZFileMode::ExtractDirectory) if (Globals::Instance->fileMode == ZFileMode::ExtractDirectory)
{ {
std::string romPath = Globals::Instance->baseRomPath.string(); std::string romPath = Globals::Instance->baseRomPath.string();
const std::vector<uint8_t>& romData = DiskFile::ReadAllBytes(romPath); std::vector<uint8_t> romData = DiskFile::ReadAllBytes(romPath);
BitConverter::RomToBigEndian(romData.data(), romData.size());
crc = BitConverter::ToUInt32BE(romData, 0x10); crc = BitConverter::ToUInt32BE(romData, 0x10);
printf("Creating version file...\n"); printf("Creating version file...\n");

View File

@ -97,6 +97,8 @@ ZRom::ZRom(std::string romPath)
RomVersion version; RomVersion version;
romData = DiskFile::ReadAllBytes(romPath); romData = DiskFile::ReadAllBytes(romPath);
BitConverter::RomToBigEndian(romData.data(), romData.size());
version.crc = BitConverter::ToInt32BE(romData, 0x10); version.crc = BitConverter::ToInt32BE(romData, 0x10);
switch (version.crc) switch (version.crc)

View File

@ -26,10 +26,58 @@ while [[ (! -e "$SHIP_HOME"/oot.otr) || (! -e "$SHIP_HOME"/oot-mq.otr) ]]; do
ln -s "$HERE"/usr/bin/{assets,soh.elf,ZAPD} "$ASSETDIR" ln -s "$HERE"/usr/bin/{assets,soh.elf,ZAPD} "$ASSETDIR"
export OLDPWD="$PWD" export OLDPWD="$PWD"
mkdir -p "$ASSETDIR"/tmp mkdir -p "$ASSETDIR"/tmp
mkdir -p "$ASSETDIR"/Extract mkdir -p "$ASSETDIR"/Extract
ln -s "$romfile" "$ASSETDIR"/tmp/rom.z64 ln -s "$romfile" "$ASSETDIR"/tmp/rom.z64
cd "$ASSETDIR" cd "$ASSETDIR"
ROMHASH=$(sha1sum -b "$ASSETDIR"/tmp/rom.z64 | awk '{ print $1 }') ROMHASH=$(sha1sum -b "$ASSETDIR"/tmp/rom.z64 | awk '{ print $1 }')
# Remap v64 and n64 hashes to their z64 has equivalent
# ZAPD will handle converting the data into z64 format
case "$ROMHASH" in
a9059b56e761c9034fbe02fe4c24985aaa835dac) # v64
ROMHASH=cee6bc3c2a634b41728f2af8da54d9bf8cc14099
;;
24708102dc504d3f375a37f4ae4e149c167dc515) # n64
ROMHASH=cee6bc3c2a634b41728f2af8da54d9bf8cc14099
;;
580dd0bd1b6d2c51cc20a764eece84dba558964c) # v64
ROMHASH=0227d7c0074f2d0ac935631990da8ec5914597b4
;;
d6342c59007e57c1194661ec6880b2f078403f4e) # n64
ROMHASH=0227d7c0074f2d0ac935631990da8ec5914597b4
;;
663c34f1b2c05a09e5beffe4d0dcd440f7d49dc7) # v64
ROMHASH=cfbb98d392e4a9d39da8285d10cbef3974c2f012
;;
24c73d378b0620a380ce5ef9f2b186c6c157a68b) # n64
ROMHASH=cfbb98d392e4a9d39da8285d10cbef3974c2f012
;;
973bc6fe56010a8d646166a1182a81b4f13b8cf9) # v64
ROMHASH=50bebedad9e0f10746a52b07239e47fa6c284d03
;;
d327752c46edc70ff3668b9514083dbbee08927c) # v64
ROMHASH=50bebedad9e0f10746a52b07239e47fa6c284d03
;;
ecdeb1747560834e079c22243febea7f6f26ba3b) # v64
ROMHASH=079b855b943d6ad8bd1eb026c0ed169ecbdac7da
;;
f19f8662ec7abee29484a272a6fda53e39efe0f1) # n64
ROMHASH=079b855b943d6ad8bd1eb026c0ed169ecbdac7da
;;
ab519ce04a33818ce2c39b3c514a751d807a494a) # v64
ROMHASH=cfecfdc58d650e71a200c81f033de4e6d617a9f6
;;
c19a34f7646305e1755249fca2071e178bd7cd00) # n64
ROMHASH=cfecfdc58d650e71a200c81f033de4e6d617a9f6
;;
25e8ae79ea0839ca5c984473f7460d8040c36f9c) # v64
ROMHASH=517bd9714c73cb96c21e7c2ef640d7b55186102f
;;
166c02770d67fcc3954c443eb400a6a3573d3fc0) # n64
ROMHASH=517bd9714c73cb96c21e7c2ef640d7b55186102f
;;
esac
case "$ROMHASH" in case "$ROMHASH" in
cee6bc3c2a634b41728f2af8da54d9bf8cc14099) cee6bc3c2a634b41728f2af8da54d9bf8cc14099)
if [[ ! -e "$SHIP_HOME"/oot.otr ]]; then if [[ ! -e "$SHIP_HOME"/oot.otr ]]; then

View File

@ -7,6 +7,56 @@ export RESPATH="${SNAME%/MacOS*}/Resources"
export LIBPATH="${SNAME%/MacOS*}/Frameworks" export LIBPATH="${SNAME%/MacOS*}/Frameworks"
export DYLD_FALLBACK_LIBRARY_PATH="$LIBPATH" export DYLD_FALLBACK_LIBRARY_PATH="$LIBPATH"
remap_hashes ()
{
# Remap v64 and n64 hashes to their z64 has equivalent
# ZAPD will handle converting the data into z64 format
case "$ROMHASH" in
a9059b56e761c9034fbe02fe4c24985aaa835dac) # v64
ROMHASH=cee6bc3c2a634b41728f2af8da54d9bf8cc14099
;;
24708102dc504d3f375a37f4ae4e149c167dc515) # n64
ROMHASH=cee6bc3c2a634b41728f2af8da54d9bf8cc14099
;;
580dd0bd1b6d2c51cc20a764eece84dba558964c) # v64
ROMHASH=0227d7c0074f2d0ac935631990da8ec5914597b4
;;
d6342c59007e57c1194661ec6880b2f078403f4e) # n64
ROMHASH=0227d7c0074f2d0ac935631990da8ec5914597b4
;;
663c34f1b2c05a09e5beffe4d0dcd440f7d49dc7) # v64
ROMHASH=cfbb98d392e4a9d39da8285d10cbef3974c2f012
;;
24c73d378b0620a380ce5ef9f2b186c6c157a68b) # n64
ROMHASH=cfbb98d392e4a9d39da8285d10cbef3974c2f012
;;
973bc6fe56010a8d646166a1182a81b4f13b8cf9) # v64
ROMHASH=50bebedad9e0f10746a52b07239e47fa6c284d03
;;
d327752c46edc70ff3668b9514083dbbee08927c) # v64
ROMHASH=50bebedad9e0f10746a52b07239e47fa6c284d03
;;
ecdeb1747560834e079c22243febea7f6f26ba3b) # v64
ROMHASH=079b855b943d6ad8bd1eb026c0ed169ecbdac7da
;;
f19f8662ec7abee29484a272a6fda53e39efe0f1) # n64
ROMHASH=079b855b943d6ad8bd1eb026c0ed169ecbdac7da
;;
ab519ce04a33818ce2c39b3c514a751d807a494a) # v64
ROMHASH=cfecfdc58d650e71a200c81f033de4e6d617a9f6
;;
c19a34f7646305e1755249fca2071e178bd7cd00) # n64
ROMHASH=cfecfdc58d650e71a200c81f033de4e6d617a9f6
;;
25e8ae79ea0839ca5c984473f7460d8040c36f9c) # v64
ROMHASH=517bd9714c73cb96c21e7c2ef640d7b55186102f
;;
166c02770d67fcc3954c443eb400a6a3573d3fc0) # n64
ROMHASH=517bd9714c73cb96c21e7c2ef640d7b55186102f
;;
esac
}
if [ ! -e "$SHIP_HOME" ]; then mkdir "$SHIP_HOME"; fi if [ ! -e "$SHIP_HOME" ]; then mkdir "$SHIP_HOME"; fi
if [ ! -e "$SHIP_HOME"/mods ]; then if [ ! -e "$SHIP_HOME"/mods ]; then
@ -39,6 +89,9 @@ if [ ! -e "$SHIP_HOME"/oot.otr ] || [ ! -e "$SHIP_HOME"/oot-mq.otr ]; then
# If an invalid rom was selected, let the user know and ask to try again # If an invalid rom was selected, let the user know and ask to try again
ROMHASH="$(shasum "$DROPROM" | awk '{ print $1 }')" ROMHASH="$(shasum "$DROPROM" | awk '{ print $1 }')"
remap_hashes
case "$ROMHASH" in case "$ROMHASH" in
cee6bc3c2a634b41728f2af8da54d9bf8cc14099) cee6bc3c2a634b41728f2af8da54d9bf8cc14099)
ROM_TYPE=0;; ROM_TYPE=0;;
@ -118,6 +171,9 @@ if [ ! -e "$SHIP_HOME"/oot.otr ] || [ ! -e "$SHIP_HOME"/oot-mq.otr ]; then
# If an invalid rom was detected, let the user know # If an invalid rom was detected, let the user know
ROMHASH="$(shasum "$ASSETDIR"/tmp/rom.z64 | awk '{ print $1 }')" ROMHASH="$(shasum "$ASSETDIR"/tmp/rom.z64 | awk '{ print $1 }')"
remap_hashes
case "$ROMHASH" in case "$ROMHASH" in
cee6bc3c2a634b41728f2af8da54d9bf8cc14099) cee6bc3c2a634b41728f2af8da54d9bf8cc14099)
ROM=GC_NMQ_D ROM=GC_NMQ_D

View File

@ -1,42 +0,0 @@
#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

View File

@ -6,6 +6,7 @@
#endif #endif
#include "Extract.h" #include "Extract.h"
#include "portable-file-dialogs.h" #include "portable-file-dialogs.h"
#include <Utils/BitConverter.h>
#ifdef unix #ifdef unix
#include <dirent.h> #include <dirent.h>
@ -48,7 +49,6 @@
#include <string> #include <string>
extern "C" uint32_t CRC32C(unsigned char* data, size_t dataSize); 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 = 0x09465AC3;
static constexpr uint32_t OOT_PAL_GC_DBG1 = 0x871E1C92; // 03-21-2002 build static constexpr uint32_t OOT_PAL_GC_DBG1 = 0x871E1C92; // 03-21-2002 build
@ -181,7 +181,7 @@ void Extractor::FilterRoms(std::vector<std::string>& roms, RomSearchMode searchM
inFile.clear(); inFile.clear();
inFile.close(); inFile.close();
RomToBigEndian(mRomData.get(), mCurRomSize); BitConverter::RomToBigEndian(mRomData.get(), mCurRomSize);
// Rom doesn't claim to be valid // Rom doesn't claim to be valid
// Game type doesn't match search mode // Game type doesn't match search mode
@ -360,7 +360,7 @@ bool Extractor::ManuallySearchForRom() {
inFile.read((char*)mRomData.get(), mCurRomSize); inFile.read((char*)mRomData.get(), mCurRomSize);
inFile.close(); inFile.close();
RomToBigEndian(mRomData.get(), mCurRomSize); BitConverter::RomToBigEndian(mRomData.get(), mCurRomSize);
if (!ValidateRom()) { if (!ValidateRom()) {
return false; return false;
@ -435,7 +435,7 @@ bool Extractor::Run(RomSearchMode searchMode) {
inFile.read((char*)mRomData.get(), mCurRomSize); inFile.read((char*)mRomData.get(), mCurRomSize);
inFile.clear(); inFile.clear();
inFile.close(); inFile.close();
RomToBigEndian(mRomData.get(), mCurRomSize); BitConverter::RomToBigEndian(mRomData.get(), mCurRomSize);
int option = ShowRomPickBox(GetRomVerCrc()); int option = ShowRomPickBox(GetRomVerCrc());