XXX4Fans
Cuyler from patreon
Cuyler

patreon


December 2019 Patch Release [Patch 23]

Hey again everyone! I hope you all enjoyed the holiday season! As many of you may know, I released the first public in-progress patch earlier in January. I do want to make it clear that I have no intention of releasing the monthly patches to the public. I simply wanted to show the progress that had been made in the past two years!

That's not the only exciting news for this month! You may remember that last month I spoke briefly about a tool that would transform my ability to work on the translation. I'm excited to say that I finished it in late December! The tool is called GCReLink. I'll be talking in depth about its features and what it can do for the translation below.

What is GCReLink?

GCReLink at its core, is a tool that unpacks and repacks GameCube Relocatable Modules into its component files. That is to say, in a way, it is a de-linker and a re-linker. In an earlier patch release post, I discussed how relocatable modules are a pain to edit due to relocations and size constraints. This tool completely resolves both of those problems! Since all the files are unpacked into smaller ones, I can simply edit the file(s) I'm after, adjust relocations if needed, and then rebuild it into a new relocatable module! It's an amazing tool that has already allowed for one cool forward-port that I'll talk about in the change log.

Technical Details

A word of forewarning: this will get fairly technical and low-level. Feel free to skip this section! Before we get into how GCReLink functions, I'll go over relocatable modules again. Relocatable modules are units of grouped code and data which can be loaded or unloaded as needed. They were a necessity for creating good games since the GC has a very limited amount of RAM (24MB main RAM). Animal Forest e+ uses them for most of the non-engine game code and data, however it only swaps out the indoors and outdoors data dynamically. (Note: this is why you can no longer remove the disc while playing!) Now, relocatable modules have two main components: code/data sections, and the relocation data. The sections have a predefined size and offset. The relocations are a bit more interesting. They tell the GameCube's OS what other code or data is required from other relocatable modules, and tell it where that must be placed in the module. An example of this would be: moduleA requires a function getPlayerPointer which is contained in moduleB. The GC OS will load the address (pointer) of moduleB->getPlayerPointer to the place in moduleA where it is needed. There are tens of thousands of relocations in e+, so hand editing isn't really feasible.

Here's what a relocation looks like in a relocatable module:

Now, here's what the same relocation looks like after de-linked by GCReLink:

The difference is like night and day. It's much easier to read the text-based format that GCReLink outputs during the un-linking phase. Oh, and it's super simple to add/remove relocations! GCReLink also un-links same-module function calls (and re-links them when rebuilding) to allow for reordering of functions.

Now lets get into the worse of the two problems that delayed this program: data blobs. A data Binary Large OBject (data BLOB) is a group of sub-files output in a specific order by a compiler. The compiler treats those files as a single file even when originally they were separate. GCReLink un-links all files, including ones that make up the data blobs. Without preserving the order of data blobs, functions which use them will no longer get the right files. This will certainly crash whatever game you've rebuilt. This took me over a week to work out, but after preserving file order, this problem went away. I'm still looking into ways to un-link and re-link data blobs, but it is no small task.

And finally, lets talk about the other problem I experienced: alignment. Some features in the GameCube require specific files to be aligned to a specific offset. Alignment is simply the act of aligning the offset of a data item to a specific place in memory. For example, a file aligned to 32 bytes (0x20) would only be placed at an address in memory that is fully divisible by 32. (Meaning that there is no remainder in the operation: address / 32). Originally I wasn't respecting alignment. That led to the interesting bug I posted about on Twitter back in December:

After fixing alignment, ground textures were restored:


If you're interested in learning more about GCReLink, you can find the source here on my GitHub:  https://github.com/Cuyler36/GCReLink

Now, let's move onto the change log!

Change Log

Next Month

My spring semester starts on the 21st, so I'm not sure how much will be able to be done. However I want to try and focus on things that couldn't be done before. Letters and messageboard posts need extra steps to translate them still. I'll be working on that and also translating as many dialogs as I can. I'll also be adding in the missing $20 tier patrons for credits and fixing the text sizes! See you all in February!


Related Creators