Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Gamecube NTSC JP Support #510

Open
wants to merge 30 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
bd18f70
xmls -- todo: pause stuff, file select, message, bombers notebook, ti…
inspectredc Mar 8, 2024
99efe47
set language, add kanji, and fix param static
inspectredc Mar 8, 2024
b5ecc7e
jp file_choose implemented
inspectredc Mar 19, 2024
24f003f
jp message
inspectredc Mar 21, 2024
51a3f25
basic kaleido support
inspectredc Mar 22, 2024
656e832
fix playername save for jp
inspectredc Mar 22, 2024
5910aff
update xml changes
inspectredc Apr 26, 2024
369903d
add game version
inspectredc Apr 26, 2024
1dc321b
audio
inspectredc Apr 26, 2024
1473777
last few fixes to build
inspectredc Apr 26, 2024
b30fed8
10k lines of wonder
inspectredc Apr 26, 2024
90f7e68
Update BenPort.cpp
inspectredc May 21, 2024
9941dd7
remove mq
inspectredc May 22, 2024
432de0a
format
inspectredc May 22, 2024
5286fba
re-organise to get same diff
inspectredc May 22, 2024
5ac7264
recorrect msgbuf stuff
inspectredc May 22, 2024
794fb4f
last msgbuf diff
inspectredc May 22, 2024
86aa0d1
Merge branch 'develop' into jp-support
inspectredc May 27, 2024
dfe3914
build
inspectredc May 27, 2024
f706606
file select interpolation
inspectredc May 27, 2024
258cd57
Merge remote-tracking branch 'upstream/develop' into jp-support
inspectredc May 27, 2024
99f9975
Merge remote-tracking branch 'upstream/develop' into jp-support
inspectredc May 28, 2024
1d24e4d
Merge remote-tracking branch 'upstream/develop' into jp-support
inspectredc Jun 2, 2024
6152215
z_kanji
inspectredc Jun 3, 2024
d07516c
Merge branch 'develop' into jp-support
inspectredc Nov 13, 2024
5d2b26e
Fix Conflict Hopefully?
inspectredc Nov 13, 2024
8826f94
Merge branch 'develop' into jp-support
inspectredc Nov 13, 2024
a781c80
fix up benport
inspectredc Nov 13, 2024
4e68524
Merge branch 'jp-support' of https://github.com/inspectredc/2ship2har…
inspectredc Nov 13, 2024
ca3b973
typo
inspectredc Nov 13, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
21 changes: 17 additions & 4 deletions mm/2s2h/BenPort.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -145,9 +145,7 @@ OTRGlobals::OTRGlobals() {
}
}
}

std::unordered_set<uint32_t> validHashes = { MM_NTSC_US_10, MM_NTSC_US_GC };

std::unordered_set<uint32_t> ValidHashes = { MM_NTSC_US_10, MM_NTSC_US_GC, MM_NTSC_JP_GC };
// tell LUS to reserve 3 SoH specific threads (Game, Audio, Save)
context =
Ship::Context::CreateInstance("2 Ship 2 Harkinian", appShortName, "2ship2harkinian.json", archiveFiles, {}, 3,
Expand Down Expand Up @@ -230,7 +228,7 @@ OTRGlobals::OTRGlobals() {

auto versions = context->GetResourceManager()->GetArchiveManager()->GetGameVersions();
for (uint32_t version : versions) {
if (!validHashes.contains(version)) {
if (!ValidHashes.contains(version)) {
#if defined(__SWITCH__)
SPDLOG_ERROR("Invalid O2R File!");
#elif defined(__WIIU__)
Expand Down Expand Up @@ -963,6 +961,7 @@ extern "C" uint32_t ResourceMgr_GetGamePlatform(int index) {
case MM_NTSC_US_10:
return GAME_PLATFORM_N64;
case MM_NTSC_US_GC:
case MM_NTSC_JP_GC:
return GAME_PLATFORM_GC;
}
}
Expand All @@ -974,10 +973,24 @@ extern "C" uint32_t ResourceMgr_GetGameRegion(int index) {
switch (version) {
case MM_NTSC_US_10:
case MM_NTSC_US_GC:
case MM_NTSC_JP_GC:
return GAME_REGION_NTSC;
}
}

extern "C" uint32_t ResourceMgr_GetGameDefaultLanguage(int index) {
uint32_t version =
Ship::Context::GetInstance()->GetResourceManager()->GetArchiveManager()->GetGameVersions()[index];

switch (version) {
case MM_NTSC_US_10:
case MM_NTSC_US_GC:
return LANGUAGE_ENG;
case MM_NTSC_JP_GC:
return LANGUAGE_JPN;
}
}

extern "C" void ResourceMgr_LoadDirectory(const char* resName) {
Ship::Context::GetInstance()->GetResourceManager()->LoadDirectory(resName);
}
Expand Down
3 changes: 3 additions & 0 deletions mm/2s2h/BenPort.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

#define MM_NTSC_US_10 0x5354631C
#define MM_NTSC_US_GC 0xB443EB08
#define MM_NTSC_JP_GC 0x8473D0C1

#ifdef __cplusplus
#include <Context.h>
Expand Down Expand Up @@ -58,6 +59,7 @@ void DeinitOTR(void);
void VanillaItemTable_Init();
void OTRAudio_Init();
void OTRMessage_Init();
void OTRJPFontMessage_Init();
void InitAudio();
void Graph_StartFrame();
void Graph_ProcessGfxCommands(Gfx* commands);
Expand All @@ -71,6 +73,7 @@ uint32_t ResourceMgr_GetNumGameVersions();
uint32_t ResourceMgr_GetGameVersion(int index);
uint32_t ResourceMgr_GetGamePlatform(int index);
uint32_t ResourceMgr_GetGameRegion(int index);
uint32_t ResourceMgr_GetGameDefaultLanguage(int index);
void ResourceMgr_LoadDirectory(const char* resName);
char** ResourceMgr_ListFiles(const char* searchMask, int* resultSize);
uint8_t ResourceMgr_FileExists(const char* resName);
Expand Down
7 changes: 6 additions & 1 deletion mm/2s2h/DeveloperTools/BetterMapSelect.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#include "overlays/gamestates/ovl_file_choose/z_file_select.h"
#include "overlays/gamestates/ovl_select/z_select.h"
#include <libultraship/bridge.h>
#include "BenPort.h"

extern SceneSelectEntry sScenes[143];

Expand All @@ -21,7 +22,11 @@ void BetterMapSelect_LoadFileSelect(MapSelectState* mapSelectState) {
CVarSetInteger("gDeveloperTools.BetterMapSelect.PageDownIndex", mapSelectState->pageDownIndex);
CVarSave();
STOP_GAMESTATE(&mapSelectState->state);
SET_NEXT_GAMESTATE(&mapSelectState->state, FileSelect_Init, sizeof(FileSelectState));
if (ResourceMgr_GetGameDefaultLanguage(0) == LANGUAGE_JPN) {
SET_NEXT_GAMESTATE(&mapSelectState->state, FileSelect_JP_Init, sizeof(FileSelectState));
} else {
SET_NEXT_GAMESTATE(&mapSelectState->state, FileSelect_Init, sizeof(FileSelectState));
}
}

// 2S2H Added columns to scene table: entranceSceneId, betterMapSelectIndex, humanName
Expand Down
7 changes: 6 additions & 1 deletion mm/2s2h/Extractor/Extract.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -53,16 +53,19 @@ extern "C" uint32_t CRC32C(unsigned char* data, size_t dataSize);

static constexpr uint32_t MM_US_10 = 0x5354631C;
static constexpr uint32_t MM_US_GC = 0xB443EB08;
static constexpr uint32_t MM_JP_GC = 0x8473D0C1;

static const std::unordered_map<uint32_t, const char*> verMap = {
{ MM_US_10, "US 1.0" },
{ MM_US_GC, "US GC" },
{ MM_JP_GC, "JP GC" },
};

// TODO only check the first 54MB of the rom.
static constexpr std::array<const uint32_t, 10> goodCrcs = {
0x96F49400, // MM US 1.0 32MB
0xBB434787, // MM GC
0xBB434787, // MM US GC
0x2BD099FA, // MM JP GC
};

enum class ButtonId : int {
Expand Down Expand Up @@ -493,6 +496,8 @@ const char* Extractor::GetZapdVerStr() const {
return "N64_US";
case MM_US_GC:
return "GC_US";
case MM_JP_GC:
return "GC_JP";
default:
// We should never be in a state where this path happens.
UNREACHABLE;
Expand Down
4 changes: 1 addition & 3 deletions mm/2s2h/resource/importer/TextMMFactory.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,7 @@ std::shared_ptr<Ship::IResource> ResourceFactoryBinaryTextMMV0::ReadResource(std
entry.id = reader->ReadUInt16();
entry.textboxType = reader->ReadUByte();
entry.textboxYPos = reader->ReadUByte();
// BENTODO: the new ZAPD reads and exports this as an int16 for JP but nothing currently uses that and the game
// expects an int8. Use this for now.
entry.icon = (int8_t)reader->ReadUInt16();
entry.icon = reader->ReadUInt16();
entry.nextMessageID = reader->ReadUInt16();
entry.firstItemCost = reader->ReadUInt16();
entry.secondItemCost = reader->ReadUInt16();
Expand Down
2 changes: 1 addition & 1 deletion mm/2s2h/resource/type/TextMM.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ class MessageEntryMM {
uint16_t id;
uint8_t textboxType;
uint8_t textboxYPos;
uint8_t icon;
uint16_t icon;
uint16_t nextMessageID;
uint16_t firstItemCost;
uint16_t secondItemCost;
Expand Down
65 changes: 47 additions & 18 deletions mm/2s2h/z_message_OTR.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
extern "C" MessageTableEntry* sMessageTableNES;
extern "C" MessageTableEntry* sMessageTableCredits;

extern "C" MessageTableEntry* sJPMessageEntryTablePtr;

MessageTableEntry* OTRMessage_LoadTable(const char* filePath, bool isNES) {
auto file = std::static_pointer_cast<SOH::TextMM>(
Ship::Context::GetInstance()->GetResourceManager()->LoadResource(filePath));
Expand All @@ -22,27 +24,37 @@ MessageTableEntry* OTRMessage_LoadTable(const char* filePath, bool isNES) {
MessageTableEntry* table = (MessageTableEntry*)malloc(sizeof(MessageTableEntry) * (file->messages.size() + 1));

for (size_t i = 0; i < file->messages.size(); i++) {
uint8_t offset = isNES ? 11 : 12;
table[i].textId = file->messages[i].id;
table[i].typePos = (file->messages[i].textboxType << 4) | file->messages[i].textboxYPos;
table[i].segment = (const char*)malloc(file->messages[i].msg.size() + 11);

auto segment = (char*)table[i].segment;
table[i].segment = (const char*)malloc(file->messages[i].msg.size() + offset);

segment[0] = file->messages[i].textboxType;
segment[1] = file->messages[i].textboxYPos;
segment[2] = file->messages[i].icon;
segment[3] = (file->messages[i].nextMessageID & 0xFF00) >> 8;
segment[4] = (file->messages[i].nextMessageID & 0x00FF);
segment[5] = (file->messages[i].firstItemCost & 0xFF00) >> 8;
segment[6] = (file->messages[i].firstItemCost & 0x00FF);
segment[7] = (file->messages[i].secondItemCost & 0xFF00) >> 8;
segment[8] = (file->messages[i].secondItemCost & 0x00FF);
segment[9] = 0xFF;
segment[10] = 0xFF;
if (isNES) {
auto segment = (char*)table[i].segment;
segment[0] = file->messages[i].textboxType;
segment[1] = file->messages[i].textboxYPos;
segment[2] = (u8)file->messages[i].icon;
segment[3] = (file->messages[i].nextMessageID & 0xFF00) >> 8;
segment[4] = (file->messages[i].nextMessageID & 0x00FF);
segment[5] = (file->messages[i].firstItemCost & 0xFF00) >> 8;
segment[6] = (file->messages[i].firstItemCost & 0x00FF);
segment[7] = (file->messages[i].secondItemCost & 0xFF00) >> 8;
segment[8] = (file->messages[i].secondItemCost & 0x00FF);
segment[9] = 0xFF;
segment[10] = 0xFF;
} else {
uint16_t* segment = (uint16_t*)table[i].segment;
segment[0] = (file->messages[i].textboxType << 8) | file->messages[i].textboxYPos;
segment[1] = file->messages[i].icon;
segment[2] = file->messages[i].nextMessageID;
segment[3] = file->messages[i].firstItemCost;
segment[4] = file->messages[i].secondItemCost;
segment[5] = 0xFFFF;
}

memcpy((void*)(&table[i].segment[11]), file->messages[i].msg.c_str(), file->messages[i].msg.size());
memcpy((void*)(&table[i].segment[offset]), file->messages[i].msg.c_str(), file->messages[i].msg.size());

table[i].msgSize = file->messages[i].msg.size() + 11;
table[i].msgSize = file->messages[i].msg.size() + offset;

// if (isNES && file->messages[i].id == 0xFFFC)
//_message_0xFFFC_nes = (char*)file->messages[i].msg.c_str();
Expand All @@ -51,8 +63,25 @@ MessageTableEntry* OTRMessage_LoadTable(const char* filePath, bool isNES) {
return table;
}

extern "C" void OTRMessage_Init() {
sMessageTableNES = OTRMessage_LoadTable("text/message_data_static/message_data_static", true);
// File select screen does not have access to an initialised PlayState, so cannot use MessageContext's messageEntryTable
extern "C" void OTRJPFontMessage_Init() {
if (sJPMessageEntryTablePtr == NULL) {
sJPMessageEntryTablePtr = OTRMessage_LoadTable("text/message_data_static_jp/message_data_static_jp", false);
}
}

extern "C" void OTRMessage_Init(PlayState* play, bool isJP) {
// OTRTODO: Added a lot of null checks here so that we don't malloc the table multiple times causing a memory leak.
// We really ought to fix the implementation such that we aren't malloc'ing new tables.
// Once we fix the implementation, remove these NULL checks.
// if (play->msgCtx.messageEntryTableNes == NULL) {
// OTRTODO:
if (isJP) {
OTRJPFontMessage_Init();
} else {
sMessageTableNES = OTRMessage_LoadTable("text/message_data_static/message_data_static", true);
}
//}

auto file2 = std::static_pointer_cast<SOH::TextMM>(Ship::Context::GetInstance()->GetResourceManager()->LoadResource(
"text/staff_message_data_static/staff_message_data_static"));
Expand Down
8 changes: 8 additions & 0 deletions mm/assets/extractor/Config_GC_JP.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<Root>
<SymbolMap File="symbols/SymbolMap_MM.txt"/>
<ActorList File="symbols/ActorList_MM.txt"/>
<ObjectList File="symbols/ObjectList_MM.txt"/>
<EnumData File="EnumData.xml"/>
<ExternalXMLFolder Path="assets/extractor/xmls/GC_JP/"/>
<ExternalFile XmlPath="objects/gameplay_keep.xml" OutPath="objects/gameplay_keep/"/>
</Root>
Loading
Loading