<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://www.lumasworkshop.com/w/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Shibboleet</id>
	<title>Luma&#039;s Workshop - User contributions [en]</title>
	<link rel="self" type="application/atom+xml" href="https://www.lumasworkshop.com/w/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Shibboleet"/>
	<link rel="alternate" type="text/html" href="https://www.lumasworkshop.com/wiki/Special:Contributions/Shibboleet"/>
	<updated>2026-06-04T07:16:19Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.41.0</generator>
	<entry>
		<id>https://www.lumasworkshop.com/w/index.php?title=Memory_Map&amp;diff=1023</id>
		<title>Memory Map</title>
		<link rel="alternate" type="text/html" href="https://www.lumasworkshop.com/w/index.php?title=Memory_Map&amp;diff=1023"/>
		<updated>2026-04-26T21:13:08Z</updated>

		<summary type="html">&lt;p&gt;Shibboleet: /* Broadway / IOS Global Memory Locations */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Start Address&lt;br /&gt;
! End Address&lt;br /&gt;
! Physical Address&lt;br /&gt;
! Physical End Address&lt;br /&gt;
! Size&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x80000000&lt;br /&gt;
| 0x817FFFFF&lt;br /&gt;
| 0x00000000&lt;br /&gt;
| 0x017FFFFF&lt;br /&gt;
| 24 MB&lt;br /&gt;
| MEM1 Memory (Cached)&lt;br /&gt;
|-&lt;br /&gt;
| 0xC0000000&lt;br /&gt;
| 0xC17FFFFF&lt;br /&gt;
| 0x00000000&lt;br /&gt;
| 0x017FFFFF&lt;br /&gt;
| 24 MB&lt;br /&gt;
| MEM1 Memory (Uncached)&lt;br /&gt;
|-&lt;br /&gt;
| 0x90000000&lt;br /&gt;
| 0x93FFFFFF&lt;br /&gt;
| 0x10000000&lt;br /&gt;
| 0x13FFFFFF&lt;br /&gt;
| 64 MB&lt;br /&gt;
| MEM2 Memory (Cached)&lt;br /&gt;
|-&lt;br /&gt;
| 0xD0000000&lt;br /&gt;
| 0xD3FFFFFF&lt;br /&gt;
| 0x10000000&lt;br /&gt;
| 0x13FFFFFF&lt;br /&gt;
| 64 MB&lt;br /&gt;
| MEM2 Memory (Uncached)&lt;br /&gt;
|-&lt;br /&gt;
| 0xCD000000&lt;br /&gt;
| 0xCD008000&lt;br /&gt;
| 0x0D000000&lt;br /&gt;
| 0x0D008000&lt;br /&gt;
| 32 KB&lt;br /&gt;
| |Hollywood Registers (shared with Starlet)&lt;br /&gt;
|-&lt;br /&gt;
| 0xCC000000&lt;br /&gt;
| 0xCC008003&lt;br /&gt;
| 0x0C000000&lt;br /&gt;
| 0x0C008003&lt;br /&gt;
| 32 KB&lt;br /&gt;
| Broadway hardware registers&lt;br /&gt;
|-&lt;br /&gt;
| 0xC8000000&lt;br /&gt;
| 0xC8300000&lt;br /&gt;
| 0x08000000&lt;br /&gt;
| 0x08300000&lt;br /&gt;
| 3MB&lt;br /&gt;
| GX Embedded FrameBuffer (EFB)&lt;br /&gt;
|-&lt;br /&gt;
| Not Mapped&lt;br /&gt;
| Not Mapped&lt;br /&gt;
| 0xFFF00100&lt;br /&gt;
| 0xFFF0013F&lt;br /&gt;
| 64 bytes&lt;br /&gt;
| EXI boot code mirror&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Broadway / IOS Global Memory Locations ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Address&lt;br /&gt;
! Size&lt;br /&gt;
! (Typical) Value&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x80000000&lt;br /&gt;
| 4&lt;br /&gt;
| 0x52535045&lt;br /&gt;
| Game Code &#039;RSPE&#039; (Wii Sports)&lt;br /&gt;
|-&lt;br /&gt;
| 0x80000004&lt;br /&gt;
| 2&lt;br /&gt;
| 0x3031 (01)&lt;br /&gt;
| Maker code&lt;br /&gt;
|-&lt;br /&gt;
| 0x80000006&lt;br /&gt;
| 1&lt;br /&gt;
| 0&lt;br /&gt;
| Disc Number (multidisc games)&lt;br /&gt;
|-&lt;br /&gt;
| 0x80000007&lt;br /&gt;
| 1&lt;br /&gt;
| ?&lt;br /&gt;
| Disc Version&lt;br /&gt;
|-&lt;br /&gt;
| 0x80000008&lt;br /&gt;
| 1&lt;br /&gt;
| ?&lt;br /&gt;
| Disc Streaming flag&lt;br /&gt;
|-&lt;br /&gt;
| 0x80000009&lt;br /&gt;
| 1&lt;br /&gt;
| ?&lt;br /&gt;
| Disc Streaming buffer size&lt;br /&gt;
|-&lt;br /&gt;
| 0x80000018&lt;br /&gt;
| 4&lt;br /&gt;
| 0x5D1C9EA3&lt;br /&gt;
| Disc layout magic (Wii)&lt;br /&gt;
|-&lt;br /&gt;
| 0x8000001C&lt;br /&gt;
| 4&lt;br /&gt;
| 0xC2339F3D&lt;br /&gt;
| Disc layout magic (GC)&lt;br /&gt;
|-&lt;br /&gt;
| 0x80000020&lt;br /&gt;
| 4&lt;br /&gt;
| 0x0D15EA5E&lt;br /&gt;
| Nintendo Standard Boot Code.&lt;br /&gt;
|-&lt;br /&gt;
| 0x80000024&lt;br /&gt;
| 4&lt;br /&gt;
| 0x00000001&lt;br /&gt;
| Version (set by apploader)&lt;br /&gt;
|-&lt;br /&gt;
| 0x80000028&lt;br /&gt;
| 4&lt;br /&gt;
| 0x01800000&lt;br /&gt;
| Memory Size (Physical) 24MB&lt;br /&gt;
|-&lt;br /&gt;
| 0x8000002C&lt;br /&gt;
| 4&lt;br /&gt;
| 0x00000023&lt;br /&gt;
| Production Board Model&lt;br /&gt;
|-&lt;br /&gt;
| 0x80000030&lt;br /&gt;
| 4&lt;br /&gt;
| 0x00000000&lt;br /&gt;
| Arena Low&lt;br /&gt;
|-&lt;br /&gt;
| 0x80000034&lt;br /&gt;
| 4&lt;br /&gt;
| 0x817FEC60&lt;br /&gt;
| Arena High&lt;br /&gt;
|-&lt;br /&gt;
| 0x80000038&lt;br /&gt;
| 4&lt;br /&gt;
| 0x817FEC60&lt;br /&gt;
| Start of FST (varies in all games)&lt;br /&gt;
|-&lt;br /&gt;
| 0x8000003C&lt;br /&gt;
| 4&lt;br /&gt;
| 0x00001394&lt;br /&gt;
| Maximum FST Size (varies in all games)&lt;br /&gt;
|-&lt;br /&gt;
| 0x80000040&lt;br /&gt;
| 4&lt;br /&gt;
| ?&lt;br /&gt;
| Beginning of the DB global struct&lt;br /&gt;
|-&lt;br /&gt;
| 0x80000044&lt;br /&gt;
| 4&lt;br /&gt;
| ?&lt;br /&gt;
| DB marked exception mask&lt;br /&gt;
|-&lt;br /&gt;
| 0x80000048&lt;br /&gt;
| 4&lt;br /&gt;
| 0x81340000&lt;br /&gt;
| DB exception destination&lt;br /&gt;
|-&lt;br /&gt;
| 0x8000004C&lt;br /&gt;
| 4&lt;br /&gt;
| ?&lt;br /&gt;
| DB return address&lt;br /&gt;
|-&lt;br /&gt;
| 0x80000060&lt;br /&gt;
| 0x24&lt;br /&gt;
| OSDBIntegrator [http://hitmen.c02.at/files/yagcd/yagcd/chap4.html#sec4.2.1.3 Debugger Hook]&lt;br /&gt;
| Hook to be jumped to by debugged exceptions, but is disabled in production software. If nothing is written to it, SDK titles will write the 0x20 bytes of instructions here.&lt;br /&gt;
|-&lt;br /&gt;
| 0x800000C0&lt;br /&gt;
| 4&lt;br /&gt;
| ?&lt;br /&gt;
| Current OSContext instance (real mode)&lt;br /&gt;
|-&lt;br /&gt;
| 0x800000C4&lt;br /&gt;
| 4&lt;br /&gt;
| 0xffffff00&lt;br /&gt;
| User interrupt mask&lt;br /&gt;
|-&lt;br /&gt;
| 0x800000C8&lt;br /&gt;
| 4&lt;br /&gt;
| 0&lt;br /&gt;
| Revolution OS interrupt mask&lt;br /&gt;
|-&lt;br /&gt;
| 0x800000CC&lt;br /&gt;
| 4&lt;br /&gt;
| 0&lt;br /&gt;
| Value indicating the current video mode. 0 = NTSC, 1 = PAL, 2 = MPAL&lt;br /&gt;
|-&lt;br /&gt;
| 0x800000D4&lt;br /&gt;
| 4&lt;br /&gt;
| ?&lt;br /&gt;
| Current OSContext instance (translated mode)&lt;br /&gt;
|-&lt;br /&gt;
| 0x800000D8&lt;br /&gt;
| 4&lt;br /&gt;
| 0&lt;br /&gt;
| OSContext to save FPRs to (NULL if floating point mode hasn&#039;t been used since the last interrupt)&lt;br /&gt;
|-&lt;br /&gt;
| 0x800000DC&lt;br /&gt;
| 4&lt;br /&gt;
| ?&lt;br /&gt;
| Pointer to the earliest created OSThread&lt;br /&gt;
|-&lt;br /&gt;
| 0x800000E0&lt;br /&gt;
| 4&lt;br /&gt;
| ?&lt;br /&gt;
| Pointer to the most recently created OSThread&lt;br /&gt;
|-&lt;br /&gt;
| 0x800000E4&lt;br /&gt;
| 4&lt;br /&gt;
| ?&lt;br /&gt;
| Pointer to the current OSThread&lt;br /&gt;
|-&lt;br /&gt;
| 0x800000EC&lt;br /&gt;
| 4&lt;br /&gt;
| 0x81800000&lt;br /&gt;
| Dev Debugger Monitor Address (If present)&lt;br /&gt;
|-&lt;br /&gt;
| 0x800000F0&lt;br /&gt;
| 4&lt;br /&gt;
| 0x01800000&lt;br /&gt;
| Simulated Memory Size&lt;br /&gt;
|-&lt;br /&gt;
| 0x800000F4&lt;br /&gt;
| 4&lt;br /&gt;
| 0x817FDF80&lt;br /&gt;
| Pointer to data read from partition&#039;s bi2.bin, set by apploader, or the emulated bi2.bin created by the NAND Boot Program&lt;br /&gt;
|-&lt;br /&gt;
| 0x800000F8&lt;br /&gt;
| 4&lt;br /&gt;
| 0x0E7BE2C0&lt;br /&gt;
| Console Bus Speed&lt;br /&gt;
|-&lt;br /&gt;
| 0x800000FC&lt;br /&gt;
| 4&lt;br /&gt;
| 0x2B73A840&lt;br /&gt;
| Console CPU Speed&lt;br /&gt;
|-&lt;br /&gt;
| 0x80000100&lt;br /&gt;
| 0x1700&lt;br /&gt;
| &lt;br /&gt;
| Exception handlers (0x100 bytes reserved for each handler)&lt;br /&gt;
|- style=&amp;quot;background-color: #fdd;&amp;quot;&lt;br /&gt;
| 0x80001800&lt;br /&gt;
| 0x1800&lt;br /&gt;
| &lt;br /&gt;
| Unused exception handler area, the SDK does not use or clear it. Custom code uses this memory region for the loader.&lt;br /&gt;
|-&lt;br /&gt;
| 0x80003000&lt;br /&gt;
| 0x3c&lt;br /&gt;
| ?&lt;br /&gt;
| Exception vector area&lt;br /&gt;
|-&lt;br /&gt;
| 0x80003040&lt;br /&gt;
| 4&lt;br /&gt;
| ?&lt;br /&gt;
| __OSInterrupt table.&lt;br /&gt;
|-&lt;br /&gt;
| 0x800030C0&lt;br /&gt;
| 8&lt;br /&gt;
| ?&lt;br /&gt;
| EXI Probe start times, for both channels 0 and 1.&lt;br /&gt;
|-&lt;br /&gt;
| 0x800030C8&lt;br /&gt;
| 4&lt;br /&gt;
| ?&lt;br /&gt;
| Related to Nintendo&#039;s dynamic linking system (REL). Pointer to the first loaded REL file.&lt;br /&gt;
|-&lt;br /&gt;
| 0x800030CC&lt;br /&gt;
| 4&lt;br /&gt;
| ?&lt;br /&gt;
| Related to Nintendo&#039;s dynamic linking system (REL). Pointer to the last loaded REL file.&lt;br /&gt;
|-&lt;br /&gt;
| 0x800030D0&lt;br /&gt;
| 4&lt;br /&gt;
| 0&lt;br /&gt;
| Pointer to a REL module name table, or 0.  Added to the name offset in each REL file.&lt;br /&gt;
|-&lt;br /&gt;
| 0x800030D8&lt;br /&gt;
| 8&lt;br /&gt;
| 0x005498F053407000&lt;br /&gt;
| System time, measured as time since January 1st 2000 in units of 1/40500000th of a second.&lt;br /&gt;
|-&lt;br /&gt;
| 0x800030E4&lt;br /&gt;
| 2&lt;br /&gt;
| ?&lt;br /&gt;
| __OSPADButton. Apploader puts button state of GCN port 4 at game start here for Gamecube NR disc support&lt;br /&gt;
|-&lt;br /&gt;
| 0x800030E6&lt;br /&gt;
| 2&lt;br /&gt;
| ?&lt;br /&gt;
| DVD Device Code Address&lt;br /&gt;
|-&lt;br /&gt;
| 0x800030E8&lt;br /&gt;
| 4&lt;br /&gt;
| ?&lt;br /&gt;
| Debug-related info&lt;br /&gt;
|-&lt;br /&gt;
| 0x800030F0&lt;br /&gt;
| 4&lt;br /&gt;
| 0x00000000&lt;br /&gt;
| DOL Execute Parameters&lt;br /&gt;
|-&lt;br /&gt;
| 0x800030F4&lt;br /&gt;
| 4&lt;br /&gt;
| ?&lt;br /&gt;
| Current TGC Offset in the Apploader.&lt;br /&gt;
|-&lt;br /&gt;
| 0x80003100&lt;br /&gt;
| 4&lt;br /&gt;
| ?&lt;br /&gt;
| Physical MEM1 size&lt;br /&gt;
|-&lt;br /&gt;
| 0x80003104&lt;br /&gt;
| 4&lt;br /&gt;
| ?&lt;br /&gt;
| Simulated MEM1 size&lt;br /&gt;
|-&lt;br /&gt;
| 0x8000310C&lt;br /&gt;
| 4&lt;br /&gt;
| ?&lt;br /&gt;
| MEM1 Arena Start (start of usable memory by the game)&lt;br /&gt;
|-&lt;br /&gt;
| 0x80003110&lt;br /&gt;
| 4&lt;br /&gt;
| ?&lt;br /&gt;
| MEM1 Arena End (end of usable memory by the game)&lt;br /&gt;
|-&lt;br /&gt;
| 0x80003118&lt;br /&gt;
| 4&lt;br /&gt;
| 0x04000000&lt;br /&gt;
| Physical MEM2 size. (0x3118-0x314C are set by IOS upon reload.)&lt;br /&gt;
|-&lt;br /&gt;
| 0x8000311C&lt;br /&gt;
| 4&lt;br /&gt;
| 0x04000000&lt;br /&gt;
| Simulated MEM2 size.&lt;br /&gt;
|-&lt;br /&gt;
| 0x80003120&lt;br /&gt;
| 4&lt;br /&gt;
| 0x93400000&lt;br /&gt;
| End of MEM2 addressable to PPC.&lt;br /&gt;
|-&lt;br /&gt;
| 0x80003124&lt;br /&gt;
| 4&lt;br /&gt;
| 0x90000800&lt;br /&gt;
| Usable MEM2 Start (start of usable memory by the game)&lt;br /&gt;
|-&lt;br /&gt;
| 0x80003128&lt;br /&gt;
| 4&lt;br /&gt;
| 0x933E0000&lt;br /&gt;
| Usable MEM2 End (end of usable memory by the game)&lt;br /&gt;
|-&lt;br /&gt;
| 0x80003130&lt;br /&gt;
| 4&lt;br /&gt;
| 0x933E0000&lt;br /&gt;
| IOS IPC Buffer Start&lt;br /&gt;
|-&lt;br /&gt;
| 0x80003134&lt;br /&gt;
| 4&lt;br /&gt;
| 0x93400000&lt;br /&gt;
| IOS IPC Buffer End&lt;br /&gt;
|-&lt;br /&gt;
| 0x80003138&lt;br /&gt;
| 4&lt;br /&gt;
| 0x00000011&lt;br /&gt;
| Hollywood Version&lt;br /&gt;
|-&lt;br /&gt;
| 0x80003140&lt;br /&gt;
| 4&lt;br /&gt;
| 0x00090204&lt;br /&gt;
| IOS version (090204 = IOS9, v2.4)&lt;br /&gt;
|-&lt;br /&gt;
| 0x80003144&lt;br /&gt;
| 4&lt;br /&gt;
| 0x00062507&lt;br /&gt;
| IOS Build Date (62507 = 06/25/07 = June 25, 2007)&lt;br /&gt;
|-&lt;br /&gt;
| 0x80003148&lt;br /&gt;
| 4&lt;br /&gt;
| 0x93600000&lt;br /&gt;
| IOS Reserved Heap Start&lt;br /&gt;
|-&lt;br /&gt;
| 0x8000314C&lt;br /&gt;
| 4&lt;br /&gt;
| 0x93620000&lt;br /&gt;
| IOS Reserved Heap End&lt;br /&gt;
|-&lt;br /&gt;
| 0x80003158&lt;br /&gt;
| 4&lt;br /&gt;
| 0x0000FF16&lt;br /&gt;
| GDDR Vendor Code&lt;br /&gt;
|-&lt;br /&gt;
| 0x8000315C&lt;br /&gt;
| 1&lt;br /&gt;
| 0x80&lt;br /&gt;
| During the boot process, u32 0x315c is first set to 0xdeadbeef by IOS in the boot_ppc syscall. The value is set to 0x80 by the NAND Boot Program to indicate that it was loaded by the boot program (and probably 0x81 by apploaders)&lt;br /&gt;
|-&lt;br /&gt;
| 0x8000315D&lt;br /&gt;
| 1&lt;br /&gt;
| 0?&lt;br /&gt;
| &amp;quot;Enable legacy DI&amp;quot; mode? 0x81 = false, anything else means true (though typically set to 0x80). Required to be set when loading Gamecube apploader.&lt;br /&gt;
|-&lt;br /&gt;
| 0x8000315E&lt;br /&gt;
| 2&lt;br /&gt;
| 0x0113&lt;br /&gt;
| &amp;quot;Devkit boot program version&amp;quot;, written to by the system menu. The value carries over to disc games. 0x0113 appears to mean v1.13.&lt;br /&gt;
|-&lt;br /&gt;
| 0x80003160&lt;br /&gt;
| 4&lt;br /&gt;
| 0x00000000&lt;br /&gt;
| Init semaphore (1-2 main() waits for this to clear)&lt;br /&gt;
|-&lt;br /&gt;
| 0x80003164&lt;br /&gt;
| 4&lt;br /&gt;
| 0x00000000&lt;br /&gt;
| GC (MIOS) mode flag, set to 1 by boot2 when MIOS triggers a shutdown; the System Menu reads this and turns off the console if it is set to 1 and :/title/00000001/00000002/data/state.dat|state.dat is set appropriately.&lt;br /&gt;
|-&lt;br /&gt;
| 0x80003180&lt;br /&gt;
| 4&lt;br /&gt;
| 0x52535045&lt;br /&gt;
| Game ID &#039;RSPE&#039; Wii Sports ID. If these 4 bytes don&#039;t match the ID at 80000000, WC24 mode in games is disabled.&lt;br /&gt;
|-&lt;br /&gt;
| 0x80003184&lt;br /&gt;
| 1&lt;br /&gt;
| 0x80&lt;br /&gt;
| Application type.  0x80 for disc games, 0x81 for channels.&lt;br /&gt;
|-&lt;br /&gt;
| 0x80003186&lt;br /&gt;
| 1&lt;br /&gt;
| 0x00&lt;br /&gt;
| Application type 2.  Appears to be set to the when a game loads a channel (e.g. Mario Kart Wii loading the region select menu will result in this being 0x80 from the disc and the main application type being 0x81, or the Wii Fit channel transitioning to the Wii Fit disc will result in this being 0x81 and the main type being 0x80).&lt;br /&gt;
|-&lt;br /&gt;
| 0x80003187&lt;br /&gt;
| 1&lt;br /&gt;
| 0x00&lt;br /&gt;
| Determines if the current application needs a TMD Ticket to launch. (0x00 = Not Locked, 0x80 = Locked)&lt;br /&gt;
|-&lt;br /&gt;
| 0x80003188&lt;br /&gt;
| 4&lt;br /&gt;
| 0x00351011&lt;br /&gt;
| Minimum IOS version (2 bytes for the major version, 2 bytes for the title version)&lt;br /&gt;
|-&lt;br /&gt;
| 0x8000318C&lt;br /&gt;
| 4&lt;br /&gt;
| 0x00000000&lt;br /&gt;
| Title Booted from NAND (Launch Code)&lt;br /&gt;
|-&lt;br /&gt;
| 0x80003190&lt;br /&gt;
| 4&lt;br /&gt;
| 0x00000000&lt;br /&gt;
| Title Booted from NAND (Return Code)&lt;br /&gt;
|-&lt;br /&gt;
| 0x80003194&lt;br /&gt;
| 4&lt;br /&gt;
| 0x00000000&lt;br /&gt;
| While reading a disc, the system menu reads the first partition table (0x20 bytes from 0x00040020) and stores a pointer to the data partition entry. When launching the disc game, it copies the partition type to 0x3194. The partition type for data partitions is 0, so typically this location always has 0.&lt;br /&gt;
|-&lt;br /&gt;
| 0x80003198&lt;br /&gt;
| 4&lt;br /&gt;
| data partition offset&lt;br /&gt;
| While reading a disc, the system menu reads the first partition table (0x20 bytes from 0x00040020) and stores a pointer to the data partition entry. When launching the disc game, it copies the partition offset to 0x3198.&lt;br /&gt;
|-&lt;br /&gt;
| 0x8000319C&lt;br /&gt;
| 1&lt;br /&gt;
| 0x80&lt;br /&gt;
| Set by the apploader to 0x80 for single-layer discs and 0x81 for dual-layer discs (determined by whether 0x7ed40000 is the value at offset 0x30 in the partition&#039;s bi2.bin; it seems that that value is 0 for single-layer discs).  Early titles&#039; apploaders do not set it at all, leaving the value as 0.  This controls the out-of-bounds Error #001 read for titles that do make such a read: they try to read at 0x7ed40000 for dual-layer discs and 0x460a0000 for single-layer discs.&lt;br /&gt;
|- style=&amp;quot;background-color: #fdd;&amp;quot;&lt;br /&gt;
| 0x80003400&lt;br /&gt;
| 0x400&lt;br /&gt;
| &lt;br /&gt;
| &amp;quot;BS1&amp;quot; boot code&lt;br /&gt;
|- style=&amp;quot;background-color: #eed;&amp;quot;&lt;br /&gt;
| 0x80003F00&lt;br /&gt;
| 0x132c100 (~19.2MB)&lt;br /&gt;
| &lt;br /&gt;
| Standard application executable area&lt;br /&gt;
|- style=&amp;quot;background-color: #fdd;&amp;quot;&lt;br /&gt;
| 0x81330000&lt;br /&gt;
| 0x4d0000 (~4.8MB)&lt;br /&gt;
| &lt;br /&gt;
| Loader executable area, also used by a NAND Boot Program&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
By convention, applications should use the 0x80003F00 – 0x81330000 area for executable code and data loaded as part of their ELF/DOL, while loaders should use from 0x81330000 onwards. Applications can use the loader area and MEM2 as data work space once they are running, but they should restrict the sections contained in the DOL or ELF to the executable area only, since MEM2 is reserved as work area for the loader at that time. To preserve &amp;quot;return to loader&amp;quot; functionality, applications should never use the 0x80001800-0x80003000 area.&lt;/div&gt;</summary>
		<author><name>Shibboleet</name></author>
	</entry>
	<entry>
		<id>https://www.lumasworkshop.com/w/index.php?title=Memory_Map&amp;diff=1022</id>
		<title>Memory Map</title>
		<link rel="alternate" type="text/html" href="https://www.lumasworkshop.com/w/index.php?title=Memory_Map&amp;diff=1022"/>
		<updated>2026-04-26T21:10:38Z</updated>

		<summary type="html">&lt;p&gt;Shibboleet: add TGC offset for apploader&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Start Address&lt;br /&gt;
! End Address&lt;br /&gt;
! Physical Address&lt;br /&gt;
! Physical End Address&lt;br /&gt;
! Size&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x80000000&lt;br /&gt;
| 0x817FFFFF&lt;br /&gt;
| 0x00000000&lt;br /&gt;
| 0x017FFFFF&lt;br /&gt;
| 24 MB&lt;br /&gt;
| MEM1 Memory (Cached)&lt;br /&gt;
|-&lt;br /&gt;
| 0xC0000000&lt;br /&gt;
| 0xC17FFFFF&lt;br /&gt;
| 0x00000000&lt;br /&gt;
| 0x017FFFFF&lt;br /&gt;
| 24 MB&lt;br /&gt;
| MEM1 Memory (Uncached)&lt;br /&gt;
|-&lt;br /&gt;
| 0x90000000&lt;br /&gt;
| 0x93FFFFFF&lt;br /&gt;
| 0x10000000&lt;br /&gt;
| 0x13FFFFFF&lt;br /&gt;
| 64 MB&lt;br /&gt;
| MEM2 Memory (Cached)&lt;br /&gt;
|-&lt;br /&gt;
| 0xD0000000&lt;br /&gt;
| 0xD3FFFFFF&lt;br /&gt;
| 0x10000000&lt;br /&gt;
| 0x13FFFFFF&lt;br /&gt;
| 64 MB&lt;br /&gt;
| MEM2 Memory (Uncached)&lt;br /&gt;
|-&lt;br /&gt;
| 0xCD000000&lt;br /&gt;
| 0xCD008000&lt;br /&gt;
| 0x0D000000&lt;br /&gt;
| 0x0D008000&lt;br /&gt;
| 32 KB&lt;br /&gt;
| |Hollywood Registers (shared with Starlet)&lt;br /&gt;
|-&lt;br /&gt;
| 0xCC000000&lt;br /&gt;
| 0xCC008003&lt;br /&gt;
| 0x0C000000&lt;br /&gt;
| 0x0C008003&lt;br /&gt;
| 32 KB&lt;br /&gt;
| Broadway hardware registers&lt;br /&gt;
|-&lt;br /&gt;
| 0xC8000000&lt;br /&gt;
| 0xC8300000&lt;br /&gt;
| 0x08000000&lt;br /&gt;
| 0x08300000&lt;br /&gt;
| 3MB&lt;br /&gt;
| GX Embedded FrameBuffer (EFB)&lt;br /&gt;
|-&lt;br /&gt;
| Not Mapped&lt;br /&gt;
| Not Mapped&lt;br /&gt;
| 0xFFF00100&lt;br /&gt;
| 0xFFF0013F&lt;br /&gt;
| 64 bytes&lt;br /&gt;
| EXI boot code mirror&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Broadway / IOS Global Memory Locations ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Address&lt;br /&gt;
! Size&lt;br /&gt;
! (Typical) Value&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x80000000&lt;br /&gt;
| 4&lt;br /&gt;
| 0x52535045&lt;br /&gt;
| Game Code &#039;RSPE&#039; (Wii Sports)&lt;br /&gt;
|-&lt;br /&gt;
| 0x80000004&lt;br /&gt;
| 2&lt;br /&gt;
| 0x3031 (01)&lt;br /&gt;
| Maker code&lt;br /&gt;
|-&lt;br /&gt;
| 0x80000006&lt;br /&gt;
| 1&lt;br /&gt;
| 0&lt;br /&gt;
| Disc Number (multidisc games)&lt;br /&gt;
|-&lt;br /&gt;
| 0x80000007&lt;br /&gt;
| 1&lt;br /&gt;
| ?&lt;br /&gt;
| Disc Version&lt;br /&gt;
|-&lt;br /&gt;
| 0x80000008&lt;br /&gt;
| 1&lt;br /&gt;
| ?&lt;br /&gt;
| Disc Streaming flag&lt;br /&gt;
|-&lt;br /&gt;
| 0x80000009&lt;br /&gt;
| 1&lt;br /&gt;
| ?&lt;br /&gt;
| Disc Streaming buffer size&lt;br /&gt;
|-&lt;br /&gt;
| 0x80000018&lt;br /&gt;
| 4&lt;br /&gt;
| 0x5D1C9EA3&lt;br /&gt;
| Disc layout magic (Wii)&lt;br /&gt;
|-&lt;br /&gt;
| 0x8000001C&lt;br /&gt;
| 4&lt;br /&gt;
| 0xC2339F3D&lt;br /&gt;
| Disc layout magic (GC)&lt;br /&gt;
|-&lt;br /&gt;
| 0x80000020&lt;br /&gt;
| 4&lt;br /&gt;
| 0x0D15EA5E&lt;br /&gt;
| Nintendo Standard Boot Code.&lt;br /&gt;
|-&lt;br /&gt;
| 0x80000024&lt;br /&gt;
| 4&lt;br /&gt;
| 0x00000001&lt;br /&gt;
| Version (set by apploader)&lt;br /&gt;
|-&lt;br /&gt;
| 0x80000028&lt;br /&gt;
| 4&lt;br /&gt;
| 0x01800000&lt;br /&gt;
| Memory Size (Physical) 24MB&lt;br /&gt;
|-&lt;br /&gt;
| 0x8000002C&lt;br /&gt;
| 4&lt;br /&gt;
| 0x00000023&lt;br /&gt;
| Production Board Model&lt;br /&gt;
|-&lt;br /&gt;
| 0x80000030&lt;br /&gt;
| 4&lt;br /&gt;
| 0x00000000&lt;br /&gt;
| Arena Low&lt;br /&gt;
|-&lt;br /&gt;
| 0x80000034&lt;br /&gt;
| 4&lt;br /&gt;
| 0x817FEC60&lt;br /&gt;
| Arena High&lt;br /&gt;
|-&lt;br /&gt;
| 0x80000038&lt;br /&gt;
| 4&lt;br /&gt;
| 0x817FEC60&lt;br /&gt;
| Start of FST (varies in all games)&lt;br /&gt;
|-&lt;br /&gt;
| 0x8000003C&lt;br /&gt;
| 4&lt;br /&gt;
| 0x00001394&lt;br /&gt;
| Maximum FST Size (varies in all games)&lt;br /&gt;
|-&lt;br /&gt;
| 0x80000040&lt;br /&gt;
| 4&lt;br /&gt;
| ?&lt;br /&gt;
| Beginning of the DB global struct&lt;br /&gt;
|-&lt;br /&gt;
| 0x80000044&lt;br /&gt;
| 4&lt;br /&gt;
| ?&lt;br /&gt;
| DB marked exception mask&lt;br /&gt;
|-&lt;br /&gt;
| 0x80000048&lt;br /&gt;
| 4&lt;br /&gt;
| 0x81340000&lt;br /&gt;
| DB exception destination&lt;br /&gt;
|-&lt;br /&gt;
| 0x8000004C&lt;br /&gt;
| 4&lt;br /&gt;
| ?&lt;br /&gt;
| DB return address&lt;br /&gt;
|-&lt;br /&gt;
| 0x80000060&lt;br /&gt;
| 0x24&lt;br /&gt;
| OSDBIntegrator [http://hitmen.c02.at/files/yagcd/yagcd/chap4.html#sec4.2.1.3 Debugger Hook]&lt;br /&gt;
| Hook to be jumped to by debugged exceptions, but is disabled in production software. If nothing is written to it, SDK titles will write the 0x20 bytes of instructions here.&lt;br /&gt;
|-&lt;br /&gt;
| 0x800000C0&lt;br /&gt;
| 4&lt;br /&gt;
| ?&lt;br /&gt;
| Current OSContext instance (real mode)&lt;br /&gt;
|-&lt;br /&gt;
| 0x800000C4&lt;br /&gt;
| 4&lt;br /&gt;
| 0xffffff00&lt;br /&gt;
| User interrupt mask&lt;br /&gt;
|-&lt;br /&gt;
| 0x800000C8&lt;br /&gt;
| 4&lt;br /&gt;
| 0&lt;br /&gt;
| Revolution OS interrupt mask&lt;br /&gt;
|-&lt;br /&gt;
| 0x800000CC&lt;br /&gt;
| 4&lt;br /&gt;
| 0&lt;br /&gt;
| Value indicating the current video mode. 0 = NTSC, 1 = PAL, 2 = MPAL&lt;br /&gt;
|-&lt;br /&gt;
| 0x800000D4&lt;br /&gt;
| 4&lt;br /&gt;
| ?&lt;br /&gt;
| Current OSContext instance (translated mode)&lt;br /&gt;
|-&lt;br /&gt;
| 0x800000D8&lt;br /&gt;
| 4&lt;br /&gt;
| 0&lt;br /&gt;
| OSContext to save FPRs to (NULL if floating point mode hasn&#039;t been used since the last interrupt)&lt;br /&gt;
|-&lt;br /&gt;
| 0x800000DC&lt;br /&gt;
| 4&lt;br /&gt;
| ?&lt;br /&gt;
| Pointer to the earliest created OSThread&lt;br /&gt;
|-&lt;br /&gt;
| 0x800000E0&lt;br /&gt;
| 4&lt;br /&gt;
| ?&lt;br /&gt;
| Pointer to the most recently created OSThread&lt;br /&gt;
|-&lt;br /&gt;
| 0x800000E4&lt;br /&gt;
| 4&lt;br /&gt;
| ?&lt;br /&gt;
| Pointer to the current OSThread&lt;br /&gt;
|-&lt;br /&gt;
| 0x800000EC&lt;br /&gt;
| 4&lt;br /&gt;
| 0x81800000&lt;br /&gt;
| Dev Debugger Monitor Address (If present)&lt;br /&gt;
|-&lt;br /&gt;
| 0x800000F0&lt;br /&gt;
| 4&lt;br /&gt;
| 0x01800000&lt;br /&gt;
| Simulated Memory Size&lt;br /&gt;
|-&lt;br /&gt;
| 0x800000F4&lt;br /&gt;
| 4&lt;br /&gt;
| 0x817FDF80&lt;br /&gt;
| Pointer to data read from partition&#039;s bi2.bin, set by apploader, or the emulated bi2.bin created by the NAND Boot Program&lt;br /&gt;
|-&lt;br /&gt;
| 0x800000F8&lt;br /&gt;
| 4&lt;br /&gt;
| 0x0E7BE2C0&lt;br /&gt;
| Console Bus Speed&lt;br /&gt;
|-&lt;br /&gt;
| 0x800000FC&lt;br /&gt;
| 4&lt;br /&gt;
| 0x2B73A840&lt;br /&gt;
| Console CPU Speed&lt;br /&gt;
|-&lt;br /&gt;
| 0x80000100&lt;br /&gt;
| 0x1700&lt;br /&gt;
| &lt;br /&gt;
| Exception handlers (0x100 bytes reserved for each handler)&lt;br /&gt;
|- style=&amp;quot;background-color: #fdd;&amp;quot;&lt;br /&gt;
| 0x80001800&lt;br /&gt;
| 0x1800&lt;br /&gt;
| &lt;br /&gt;
| Unused exception handler area, the SDK does not use or clear it. Custom code uses this memory region for the loader.&lt;br /&gt;
|-&lt;br /&gt;
| 0x80003000&lt;br /&gt;
| 0x3c&lt;br /&gt;
| ?&lt;br /&gt;
| Exception vector area&lt;br /&gt;
|-&lt;br /&gt;
| 0x80003040&lt;br /&gt;
| 4&lt;br /&gt;
| ?&lt;br /&gt;
| __OSInterrupt table.&lt;br /&gt;
|-&lt;br /&gt;
| 0x800030C0&lt;br /&gt;
| 8&lt;br /&gt;
| ?&lt;br /&gt;
| EXI Probe start times, for both channels 0 and 1.&lt;br /&gt;
|-&lt;br /&gt;
| 0x800030C8&lt;br /&gt;
| 4&lt;br /&gt;
| ?&lt;br /&gt;
| Related to Nintendo&#039;s dynamic linking system (REL). Pointer to the first loaded REL file.&lt;br /&gt;
|-&lt;br /&gt;
| 0x800030CC&lt;br /&gt;
| 4&lt;br /&gt;
| ?&lt;br /&gt;
| Related to Nintendo&#039;s dynamic linking system (REL). Pointer to the last loaded REL file.&lt;br /&gt;
|-&lt;br /&gt;
| 0x800030D0&lt;br /&gt;
| 4&lt;br /&gt;
| 0&lt;br /&gt;
| Pointer to a REL module name table, or 0.  Added to the name offset in each REL file.&lt;br /&gt;
|-&lt;br /&gt;
| 0x800030D8&lt;br /&gt;
| 8&lt;br /&gt;
| 0x005498F053407000&lt;br /&gt;
| System time, measured as time since January 1st 2000 in units of 1/40500000th of a second.&lt;br /&gt;
|-&lt;br /&gt;
| 0x800030E4&lt;br /&gt;
| 2&lt;br /&gt;
| ?&lt;br /&gt;
| __OSPADButton. Apploader puts button state of GCN port 4 at game start here for Gamecube NR disc support&lt;br /&gt;
|-&lt;br /&gt;
| 0x800030E6&lt;br /&gt;
| 2&lt;br /&gt;
| ?&lt;br /&gt;
| DVD Device Code Address&lt;br /&gt;
|-&lt;br /&gt;
| 0x800030E8&lt;br /&gt;
| 4&lt;br /&gt;
| ?&lt;br /&gt;
| Debug-related info&lt;br /&gt;
|-&lt;br /&gt;
| 0x800030F0&lt;br /&gt;
| 4&lt;br /&gt;
| 0x00000000&lt;br /&gt;
| DOL Execute Parameters&lt;br /&gt;
|-&lt;br /&gt;
| 0x800030F4&lt;br /&gt;
| 4&lt;br /&gt;
| 0x00000000&lt;br /&gt;
| Current TGC Offset in the Apploader.&lt;br /&gt;
|-&lt;br /&gt;
| 0x80003100&lt;br /&gt;
| 4&lt;br /&gt;
| ?&lt;br /&gt;
| Physical MEM1 size&lt;br /&gt;
|-&lt;br /&gt;
| 0x80003104&lt;br /&gt;
| 4&lt;br /&gt;
| ?&lt;br /&gt;
| Simulated MEM1 size&lt;br /&gt;
|-&lt;br /&gt;
| 0x8000310C&lt;br /&gt;
| 4&lt;br /&gt;
| ?&lt;br /&gt;
| MEM1 Arena Start (start of usable memory by the game)&lt;br /&gt;
|-&lt;br /&gt;
| 0x80003110&lt;br /&gt;
| 4&lt;br /&gt;
| ?&lt;br /&gt;
| MEM1 Arena End (end of usable memory by the game)&lt;br /&gt;
|-&lt;br /&gt;
| 0x80003118&lt;br /&gt;
| 4&lt;br /&gt;
| 0x04000000&lt;br /&gt;
| Physical MEM2 size. (0x3118-0x314C are set by IOS upon reload.)&lt;br /&gt;
|-&lt;br /&gt;
| 0x8000311C&lt;br /&gt;
| 4&lt;br /&gt;
| 0x04000000&lt;br /&gt;
| Simulated MEM2 size.&lt;br /&gt;
|-&lt;br /&gt;
| 0x80003120&lt;br /&gt;
| 4&lt;br /&gt;
| 0x93400000&lt;br /&gt;
| End of MEM2 addressable to PPC.&lt;br /&gt;
|-&lt;br /&gt;
| 0x80003124&lt;br /&gt;
| 4&lt;br /&gt;
| 0x90000800&lt;br /&gt;
| Usable MEM2 Start (start of usable memory by the game)&lt;br /&gt;
|-&lt;br /&gt;
| 0x80003128&lt;br /&gt;
| 4&lt;br /&gt;
| 0x933E0000&lt;br /&gt;
| Usable MEM2 End (end of usable memory by the game)&lt;br /&gt;
|-&lt;br /&gt;
| 0x80003130&lt;br /&gt;
| 4&lt;br /&gt;
| 0x933E0000&lt;br /&gt;
| IOS IPC Buffer Start&lt;br /&gt;
|-&lt;br /&gt;
| 0x80003134&lt;br /&gt;
| 4&lt;br /&gt;
| 0x93400000&lt;br /&gt;
| IOS IPC Buffer End&lt;br /&gt;
|-&lt;br /&gt;
| 0x80003138&lt;br /&gt;
| 4&lt;br /&gt;
| 0x00000011&lt;br /&gt;
| Hollywood Version&lt;br /&gt;
|-&lt;br /&gt;
| 0x80003140&lt;br /&gt;
| 4&lt;br /&gt;
| 0x00090204&lt;br /&gt;
| IOS version (090204 = IOS9, v2.4)&lt;br /&gt;
|-&lt;br /&gt;
| 0x80003144&lt;br /&gt;
| 4&lt;br /&gt;
| 0x00062507&lt;br /&gt;
| IOS Build Date (62507 = 06/25/07 = June 25, 2007)&lt;br /&gt;
|-&lt;br /&gt;
| 0x80003148&lt;br /&gt;
| 4&lt;br /&gt;
| 0x93600000&lt;br /&gt;
| IOS Reserved Heap Start&lt;br /&gt;
|-&lt;br /&gt;
| 0x8000314C&lt;br /&gt;
| 4&lt;br /&gt;
| 0x93620000&lt;br /&gt;
| IOS Reserved Heap End&lt;br /&gt;
|-&lt;br /&gt;
| 0x80003158&lt;br /&gt;
| 4&lt;br /&gt;
| 0x0000FF16&lt;br /&gt;
| GDDR Vendor Code&lt;br /&gt;
|-&lt;br /&gt;
| 0x8000315C&lt;br /&gt;
| 1&lt;br /&gt;
| 0x80&lt;br /&gt;
| During the boot process, u32 0x315c is first set to 0xdeadbeef by IOS in the boot_ppc syscall. The value is set to 0x80 by the NAND Boot Program to indicate that it was loaded by the boot program (and probably 0x81 by apploaders)&lt;br /&gt;
|-&lt;br /&gt;
| 0x8000315D&lt;br /&gt;
| 1&lt;br /&gt;
| 0?&lt;br /&gt;
| &amp;quot;Enable legacy DI&amp;quot; mode? 0x81 = false, anything else means true (though typically set to 0x80). Required to be set when loading Gamecube apploader.&lt;br /&gt;
|-&lt;br /&gt;
| 0x8000315E&lt;br /&gt;
| 2&lt;br /&gt;
| 0x0113&lt;br /&gt;
| &amp;quot;Devkit boot program version&amp;quot;, written to by the system menu. The value carries over to disc games. 0x0113 appears to mean v1.13.&lt;br /&gt;
|-&lt;br /&gt;
| 0x80003160&lt;br /&gt;
| 4&lt;br /&gt;
| 0x00000000&lt;br /&gt;
| Init semaphore (1-2 main() waits for this to clear)&lt;br /&gt;
|-&lt;br /&gt;
| 0x80003164&lt;br /&gt;
| 4&lt;br /&gt;
| 0x00000000&lt;br /&gt;
| GC (MIOS) mode flag, set to 1 by boot2 when MIOS triggers a shutdown; the System Menu reads this and turns off the console if it is set to 1 and :/title/00000001/00000002/data/state.dat|state.dat is set appropriately.&lt;br /&gt;
|-&lt;br /&gt;
| 0x80003180&lt;br /&gt;
| 4&lt;br /&gt;
| 0x52535045&lt;br /&gt;
| Game ID &#039;RSPE&#039; Wii Sports ID. If these 4 bytes don&#039;t match the ID at 80000000, WC24 mode in games is disabled.&lt;br /&gt;
|-&lt;br /&gt;
| 0x80003184&lt;br /&gt;
| 1&lt;br /&gt;
| 0x80&lt;br /&gt;
| Application type.  0x80 for disc games, 0x81 for channels.&lt;br /&gt;
|-&lt;br /&gt;
| 0x80003186&lt;br /&gt;
| 1&lt;br /&gt;
| 0x00&lt;br /&gt;
| Application type 2.  Appears to be set to the when a game loads a channel (e.g. Mario Kart Wii loading the region select menu will result in this being 0x80 from the disc and the main application type being 0x81, or the Wii Fit channel transitioning to the Wii Fit disc will result in this being 0x81 and the main type being 0x80).&lt;br /&gt;
|-&lt;br /&gt;
| 0x80003188&lt;br /&gt;
| 4&lt;br /&gt;
| 0x00351011&lt;br /&gt;
| Minimum IOS version (2 bytes for the major version, 2 bytes for the title version)&lt;br /&gt;
|-&lt;br /&gt;
| 0x8000318C&lt;br /&gt;
| 4&lt;br /&gt;
| 0x00000000&lt;br /&gt;
| Title Booted from NAND (Launch Code)&lt;br /&gt;
|-&lt;br /&gt;
| 0x80003190&lt;br /&gt;
| 4&lt;br /&gt;
| 0x00000000&lt;br /&gt;
| Title Booted from NAND (Return Code)&lt;br /&gt;
|-&lt;br /&gt;
| 0x80003194&lt;br /&gt;
| 4&lt;br /&gt;
| 0x00000000&lt;br /&gt;
| While reading a disc, the system menu reads the first partition table (0x20 bytes from 0x00040020) and stores a pointer to the data partition entry. When launching the disc game, it copies the partition type to 0x3194. The partition type for data partitions is 0, so typically this location always has 0.&lt;br /&gt;
|-&lt;br /&gt;
| 0x80003198&lt;br /&gt;
| 4&lt;br /&gt;
| data partition offset&lt;br /&gt;
| While reading a disc, the system menu reads the first partition table (0x20 bytes from 0x00040020) and stores a pointer to the data partition entry. When launching the disc game, it copies the partition offset to 0x3198.&lt;br /&gt;
|-&lt;br /&gt;
| 0x8000319C&lt;br /&gt;
| 1&lt;br /&gt;
| 0x80&lt;br /&gt;
| Set by the apploader to 0x80 for single-layer discs and 0x81 for dual-layer discs (determined by whether 0x7ed40000 is the value at offset 0x30 in the partition&#039;s bi2.bin; it seems that that value is 0 for single-layer discs).  Early titles&#039; apploaders do not set it at all, leaving the value as 0.  This controls the out-of-bounds Error #001 read for titles that do make such a read: they try to read at 0x7ed40000 for dual-layer discs and 0x460a0000 for single-layer discs.&lt;br /&gt;
|- style=&amp;quot;background-color: #fdd;&amp;quot;&lt;br /&gt;
| 0x80003400&lt;br /&gt;
| 0x400&lt;br /&gt;
| &lt;br /&gt;
| &amp;quot;BS1&amp;quot; boot code&lt;br /&gt;
|- style=&amp;quot;background-color: #eed;&amp;quot;&lt;br /&gt;
| 0x80003F00&lt;br /&gt;
| 0x132c100 (~19.2MB)&lt;br /&gt;
| &lt;br /&gt;
| Standard application executable area&lt;br /&gt;
|- style=&amp;quot;background-color: #fdd;&amp;quot;&lt;br /&gt;
| 0x81330000&lt;br /&gt;
| 0x4d0000 (~4.8MB)&lt;br /&gt;
| &lt;br /&gt;
| Loader executable area, also used by a NAND Boot Program&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
By convention, applications should use the 0x80003F00 – 0x81330000 area for executable code and data loaded as part of their ELF/DOL, while loaders should use from 0x81330000 onwards. Applications can use the loader area and MEM2 as data work space once they are running, but they should restrict the sections contained in the DOL or ELF to the executable area only, since MEM2 is reserved as work area for the loader at that time. To preserve &amp;quot;return to loader&amp;quot; functionality, applications should never use the 0x80001800-0x80003000 area.&lt;/div&gt;</summary>
		<author><name>Shibboleet</name></author>
	</entry>
	<entry>
		<id>https://www.lumasworkshop.com/w/index.php?title=Memory_Map&amp;diff=1021</id>
		<title>Memory Map</title>
		<link rel="alternate" type="text/html" href="https://www.lumasworkshop.com/w/index.php?title=Memory_Map&amp;diff=1021"/>
		<updated>2026-04-26T21:09:14Z</updated>

		<summary type="html">&lt;p&gt;Shibboleet: Created page with &amp;quot; {| class=&amp;quot;wikitable&amp;quot; |- ! Start Address ! End Address ! Physical Address ! Physical End Address ! Size ! Description |- | 0x80000000 | 0x817FFFFF | 0x00000000 | 0x017FFFFF | 24 MB | MEM1 Memory (Cached) |- | 0xC0000000 | 0xC17FFFFF | 0x00000000 | 0x017FFFFF | 24 MB | MEM1 Memory (Uncached) |- | 0x90000000 | 0x93FFFFFF | 0x10000000 | 0x13FFFFFF | 64 MB | MEM2 Memory (Cached) |- | 0xD0000000 | 0xD3FFFFFF | 0x10000000 | 0x13FFFFFF | 64 MB | MEM2 Memory (Uncached) |- | 0xCD...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Start Address&lt;br /&gt;
! End Address&lt;br /&gt;
! Physical Address&lt;br /&gt;
! Physical End Address&lt;br /&gt;
! Size&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x80000000&lt;br /&gt;
| 0x817FFFFF&lt;br /&gt;
| 0x00000000&lt;br /&gt;
| 0x017FFFFF&lt;br /&gt;
| 24 MB&lt;br /&gt;
| MEM1 Memory (Cached)&lt;br /&gt;
|-&lt;br /&gt;
| 0xC0000000&lt;br /&gt;
| 0xC17FFFFF&lt;br /&gt;
| 0x00000000&lt;br /&gt;
| 0x017FFFFF&lt;br /&gt;
| 24 MB&lt;br /&gt;
| MEM1 Memory (Uncached)&lt;br /&gt;
|-&lt;br /&gt;
| 0x90000000&lt;br /&gt;
| 0x93FFFFFF&lt;br /&gt;
| 0x10000000&lt;br /&gt;
| 0x13FFFFFF&lt;br /&gt;
| 64 MB&lt;br /&gt;
| MEM2 Memory (Cached)&lt;br /&gt;
|-&lt;br /&gt;
| 0xD0000000&lt;br /&gt;
| 0xD3FFFFFF&lt;br /&gt;
| 0x10000000&lt;br /&gt;
| 0x13FFFFFF&lt;br /&gt;
| 64 MB&lt;br /&gt;
| MEM2 Memory (Uncached)&lt;br /&gt;
|-&lt;br /&gt;
| 0xCD000000&lt;br /&gt;
| 0xCD008000&lt;br /&gt;
| 0x0D000000&lt;br /&gt;
| 0x0D008000&lt;br /&gt;
| 32 KB&lt;br /&gt;
| |Hollywood Registers (shared with Starlet)&lt;br /&gt;
|-&lt;br /&gt;
| 0xCC000000&lt;br /&gt;
| 0xCC008003&lt;br /&gt;
| 0x0C000000&lt;br /&gt;
| 0x0C008003&lt;br /&gt;
| 32 KB&lt;br /&gt;
| Broadway hardware registers&lt;br /&gt;
|-&lt;br /&gt;
| 0xC8000000&lt;br /&gt;
| 0xC8300000&lt;br /&gt;
| 0x08000000&lt;br /&gt;
| 0x08300000&lt;br /&gt;
| 3MB&lt;br /&gt;
| GX Embedded FrameBuffer (EFB)&lt;br /&gt;
|-&lt;br /&gt;
| Not Mapped&lt;br /&gt;
| Not Mapped&lt;br /&gt;
| 0xFFF00100&lt;br /&gt;
| 0xFFF0013F&lt;br /&gt;
| 64 bytes&lt;br /&gt;
| EXI boot code mirror&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Broadway / IOS Global Memory Locations ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Address&lt;br /&gt;
! Size&lt;br /&gt;
! (Typical) Value&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x80000000&lt;br /&gt;
| 4&lt;br /&gt;
| 0x52535045&lt;br /&gt;
| Game Code &#039;RSPE&#039; (Wii Sports)&lt;br /&gt;
|-&lt;br /&gt;
| 0x80000004&lt;br /&gt;
| 2&lt;br /&gt;
| 0x3031 (01)&lt;br /&gt;
| Maker code&lt;br /&gt;
|-&lt;br /&gt;
| 0x80000006&lt;br /&gt;
| 1&lt;br /&gt;
| 0&lt;br /&gt;
| Disc Number (multidisc games)&lt;br /&gt;
|-&lt;br /&gt;
| 0x80000007&lt;br /&gt;
| 1&lt;br /&gt;
| ?&lt;br /&gt;
| Disc Version&lt;br /&gt;
|-&lt;br /&gt;
| 0x80000008&lt;br /&gt;
| 1&lt;br /&gt;
| ?&lt;br /&gt;
| Disc Streaming flag&lt;br /&gt;
|-&lt;br /&gt;
| 0x80000009&lt;br /&gt;
| 1&lt;br /&gt;
| ?&lt;br /&gt;
| Disc Streaming buffer size&lt;br /&gt;
|-&lt;br /&gt;
| 0x80000018&lt;br /&gt;
| 4&lt;br /&gt;
| 0x5D1C9EA3&lt;br /&gt;
| Disc layout magic (Wii)&lt;br /&gt;
|-&lt;br /&gt;
| 0x8000001C&lt;br /&gt;
| 4&lt;br /&gt;
| 0xC2339F3D&lt;br /&gt;
| Disc layout magic (GC)&lt;br /&gt;
|-&lt;br /&gt;
| 0x80000020&lt;br /&gt;
| 4&lt;br /&gt;
| 0x0D15EA5E&lt;br /&gt;
| Nintendo Standard Boot Code.&lt;br /&gt;
|-&lt;br /&gt;
| 0x80000024&lt;br /&gt;
| 4&lt;br /&gt;
| 0x00000001&lt;br /&gt;
| Version (set by apploader)&lt;br /&gt;
|-&lt;br /&gt;
| 0x80000028&lt;br /&gt;
| 4&lt;br /&gt;
| 0x01800000&lt;br /&gt;
| Memory Size (Physical) 24MB&lt;br /&gt;
|-&lt;br /&gt;
| 0x8000002C&lt;br /&gt;
| 4&lt;br /&gt;
| 0x00000023&lt;br /&gt;
| Production Board Model&lt;br /&gt;
|-&lt;br /&gt;
| 0x80000030&lt;br /&gt;
| 4&lt;br /&gt;
| 0x00000000&lt;br /&gt;
| Arena Low&lt;br /&gt;
|-&lt;br /&gt;
| 0x80000034&lt;br /&gt;
| 4&lt;br /&gt;
| 0x817FEC60&lt;br /&gt;
| Arena High&lt;br /&gt;
|-&lt;br /&gt;
| 0x80000038&lt;br /&gt;
| 4&lt;br /&gt;
| 0x817FEC60&lt;br /&gt;
| Start of FST (varies in all games)&lt;br /&gt;
|-&lt;br /&gt;
| 0x8000003C&lt;br /&gt;
| 4&lt;br /&gt;
| 0x00001394&lt;br /&gt;
| Maximum FST Size (varies in all games)&lt;br /&gt;
|-&lt;br /&gt;
| 0x80000040&lt;br /&gt;
| 4&lt;br /&gt;
| ?&lt;br /&gt;
| Beginning of the DB global struct&lt;br /&gt;
|-&lt;br /&gt;
| 0x80000044&lt;br /&gt;
| 4&lt;br /&gt;
| ?&lt;br /&gt;
| DB marked exception mask&lt;br /&gt;
|-&lt;br /&gt;
| 0x80000048&lt;br /&gt;
| 4&lt;br /&gt;
| 0x81340000&lt;br /&gt;
| DB exception destination&lt;br /&gt;
|-&lt;br /&gt;
| 0x8000004C&lt;br /&gt;
| 4&lt;br /&gt;
| ?&lt;br /&gt;
| DB return address&lt;br /&gt;
|-&lt;br /&gt;
| 0x80000060&lt;br /&gt;
| 0x24&lt;br /&gt;
| OSDBIntegrator [http://hitmen.c02.at/files/yagcd/yagcd/chap4.html#sec4.2.1.3 Debugger Hook]&lt;br /&gt;
| Hook to be jumped to by debugged exceptions, but is disabled in production software. If nothing is written to it, SDK titles will write the 0x20 bytes of instructions here.&lt;br /&gt;
|-&lt;br /&gt;
| 0x800000C0&lt;br /&gt;
| 4&lt;br /&gt;
| ?&lt;br /&gt;
| Current OSContext instance (real mode)&lt;br /&gt;
|-&lt;br /&gt;
| 0x800000C4&lt;br /&gt;
| 4&lt;br /&gt;
| 0xffffff00&lt;br /&gt;
| User interrupt mask&lt;br /&gt;
|-&lt;br /&gt;
| 0x800000C8&lt;br /&gt;
| 4&lt;br /&gt;
| 0&lt;br /&gt;
| Revolution OS interrupt mask&lt;br /&gt;
|-&lt;br /&gt;
| 0x800000CC&lt;br /&gt;
| 4&lt;br /&gt;
| 0&lt;br /&gt;
| Value indicating the current video mode. 0 = NTSC, 1 = PAL, 2 = MPAL&lt;br /&gt;
|-&lt;br /&gt;
| 0x800000D4&lt;br /&gt;
| 4&lt;br /&gt;
| ?&lt;br /&gt;
| Current OSContext instance (translated mode)&lt;br /&gt;
|-&lt;br /&gt;
| 0x800000D8&lt;br /&gt;
| 4&lt;br /&gt;
| 0&lt;br /&gt;
| OSContext to save FPRs to (NULL if floating point mode hasn&#039;t been used since the last interrupt)&lt;br /&gt;
|-&lt;br /&gt;
| 0x800000DC&lt;br /&gt;
| 4&lt;br /&gt;
| ?&lt;br /&gt;
| Pointer to the earliest created OSThread&lt;br /&gt;
|-&lt;br /&gt;
| 0x800000E0&lt;br /&gt;
| 4&lt;br /&gt;
| ?&lt;br /&gt;
| Pointer to the most recently created OSThread&lt;br /&gt;
|-&lt;br /&gt;
| 0x800000E4&lt;br /&gt;
| 4&lt;br /&gt;
| ?&lt;br /&gt;
| Pointer to the current OSThread&lt;br /&gt;
|-&lt;br /&gt;
| 0x800000EC&lt;br /&gt;
| 4&lt;br /&gt;
| 0x81800000&lt;br /&gt;
| Dev Debugger Monitor Address (If present)&lt;br /&gt;
|-&lt;br /&gt;
| 0x800000F0&lt;br /&gt;
| 4&lt;br /&gt;
| 0x01800000&lt;br /&gt;
| Simulated Memory Size&lt;br /&gt;
|-&lt;br /&gt;
| 0x800000F4&lt;br /&gt;
| 4&lt;br /&gt;
| 0x817FDF80&lt;br /&gt;
| Pointer to data read from partition&#039;s bi2.bin, set by apploader, or the emulated bi2.bin created by the NAND Boot Program&lt;br /&gt;
|-&lt;br /&gt;
| 0x800000F8&lt;br /&gt;
| 4&lt;br /&gt;
| 0x0E7BE2C0&lt;br /&gt;
| Console Bus Speed&lt;br /&gt;
|-&lt;br /&gt;
| 0x800000FC&lt;br /&gt;
| 4&lt;br /&gt;
| 0x2B73A840&lt;br /&gt;
| Console CPU Speed&lt;br /&gt;
|-&lt;br /&gt;
| 0x80000100&lt;br /&gt;
| 0x1700&lt;br /&gt;
| &lt;br /&gt;
| Exception handlers (0x100 bytes reserved for each handler)&lt;br /&gt;
|- style=&amp;quot;background-color: #fdd;&amp;quot;&lt;br /&gt;
| 0x80001800&lt;br /&gt;
| 0x1800&lt;br /&gt;
| &lt;br /&gt;
| Unused exception handler area, the SDK does not use or clear it. Custom code uses this memory region for the loader.&lt;br /&gt;
|-&lt;br /&gt;
| 0x80003000&lt;br /&gt;
| 0x3c&lt;br /&gt;
| ?&lt;br /&gt;
| Exception vector area&lt;br /&gt;
|-&lt;br /&gt;
| 0x80003040&lt;br /&gt;
| 4&lt;br /&gt;
| ?&lt;br /&gt;
| __OSInterrupt table.&lt;br /&gt;
|-&lt;br /&gt;
| 0x800030C0&lt;br /&gt;
| 8&lt;br /&gt;
| ?&lt;br /&gt;
| EXI Probe start times, for both channels 0 and 1.&lt;br /&gt;
|-&lt;br /&gt;
| 0x800030C8&lt;br /&gt;
| 4&lt;br /&gt;
| ?&lt;br /&gt;
| Related to Nintendo&#039;s dynamic linking system (REL). Pointer to the first loaded REL file.&lt;br /&gt;
|-&lt;br /&gt;
| 0x800030CC&lt;br /&gt;
| 4&lt;br /&gt;
| ?&lt;br /&gt;
| Related to Nintendo&#039;s dynamic linking system (REL). Pointer to the last loaded REL file.&lt;br /&gt;
|-&lt;br /&gt;
| 0x800030D0&lt;br /&gt;
| 4&lt;br /&gt;
| 0&lt;br /&gt;
| Pointer to a REL module name table, or 0.  Added to the name offset in each REL file.&lt;br /&gt;
|-&lt;br /&gt;
| 0x800030D8&lt;br /&gt;
| 8&lt;br /&gt;
| 0x005498F053407000&lt;br /&gt;
| System time, measured as time since January 1st 2000 in units of 1/40500000th of a second.&lt;br /&gt;
|-&lt;br /&gt;
| 0x800030E4&lt;br /&gt;
| 2&lt;br /&gt;
| ?&lt;br /&gt;
| __OSPADButton. Apploader puts button state of GCN port 4 at game start here for Gamecube NR disc support&lt;br /&gt;
|-&lt;br /&gt;
| 0x800030E6&lt;br /&gt;
| 2&lt;br /&gt;
| ?&lt;br /&gt;
| DVD Device Code Address&lt;br /&gt;
|-&lt;br /&gt;
| 0x800030E8&lt;br /&gt;
| 4&lt;br /&gt;
| ?&lt;br /&gt;
| Debug-related info&lt;br /&gt;
|-&lt;br /&gt;
| 0x800030F0&lt;br /&gt;
| 4&lt;br /&gt;
| 0x00000000&lt;br /&gt;
| DOL Execute Parameters&lt;br /&gt;
|-&lt;br /&gt;
| 0x80003100&lt;br /&gt;
| 4&lt;br /&gt;
| ?&lt;br /&gt;
| Physical MEM1 size&lt;br /&gt;
|-&lt;br /&gt;
| 0x80003104&lt;br /&gt;
| 4&lt;br /&gt;
| ?&lt;br /&gt;
| Simulated MEM1 size&lt;br /&gt;
|-&lt;br /&gt;
| 0x8000310C&lt;br /&gt;
| 4&lt;br /&gt;
| ?&lt;br /&gt;
| MEM1 Arena Start (start of usable memory by the game)&lt;br /&gt;
|-&lt;br /&gt;
| 0x80003110&lt;br /&gt;
| 4&lt;br /&gt;
| ?&lt;br /&gt;
| MEM1 Arena End (end of usable memory by the game)&lt;br /&gt;
|-&lt;br /&gt;
| 0x80003118&lt;br /&gt;
| 4&lt;br /&gt;
| 0x04000000&lt;br /&gt;
| Physical MEM2 size. (0x3118-0x314C are set by IOS upon reload.)&lt;br /&gt;
|-&lt;br /&gt;
| 0x8000311C&lt;br /&gt;
| 4&lt;br /&gt;
| 0x04000000&lt;br /&gt;
| Simulated MEM2 size.&lt;br /&gt;
|-&lt;br /&gt;
| 0x80003120&lt;br /&gt;
| 4&lt;br /&gt;
| 0x93400000&lt;br /&gt;
| End of MEM2 addressable to PPC.&lt;br /&gt;
|-&lt;br /&gt;
| 0x80003124&lt;br /&gt;
| 4&lt;br /&gt;
| 0x90000800&lt;br /&gt;
| Usable MEM2 Start (start of usable memory by the game)&lt;br /&gt;
|-&lt;br /&gt;
| 0x80003128&lt;br /&gt;
| 4&lt;br /&gt;
| 0x933E0000&lt;br /&gt;
| Usable MEM2 End (end of usable memory by the game)&lt;br /&gt;
|-&lt;br /&gt;
| 0x80003130&lt;br /&gt;
| 4&lt;br /&gt;
| 0x933E0000&lt;br /&gt;
| IOS IPC Buffer Start&lt;br /&gt;
|-&lt;br /&gt;
| 0x80003134&lt;br /&gt;
| 4&lt;br /&gt;
| 0x93400000&lt;br /&gt;
| IOS IPC Buffer End&lt;br /&gt;
|-&lt;br /&gt;
| 0x80003138&lt;br /&gt;
| 4&lt;br /&gt;
| 0x00000011&lt;br /&gt;
| Hollywood Version&lt;br /&gt;
|-&lt;br /&gt;
| 0x80003140&lt;br /&gt;
| 4&lt;br /&gt;
| 0x00090204&lt;br /&gt;
| IOS version (090204 = IOS9, v2.4)&lt;br /&gt;
|-&lt;br /&gt;
| 0x80003144&lt;br /&gt;
| 4&lt;br /&gt;
| 0x00062507&lt;br /&gt;
| IOS Build Date (62507 = 06/25/07 = June 25, 2007)&lt;br /&gt;
|-&lt;br /&gt;
| 0x80003148&lt;br /&gt;
| 4&lt;br /&gt;
| 0x93600000&lt;br /&gt;
| IOS Reserved Heap Start&lt;br /&gt;
|-&lt;br /&gt;
| 0x8000314C&lt;br /&gt;
| 4&lt;br /&gt;
| 0x93620000&lt;br /&gt;
| IOS Reserved Heap End&lt;br /&gt;
|-&lt;br /&gt;
| 0x80003158&lt;br /&gt;
| 4&lt;br /&gt;
| 0x0000FF16&lt;br /&gt;
| GDDR Vendor Code&lt;br /&gt;
|-&lt;br /&gt;
| 0x8000315C&lt;br /&gt;
| 1&lt;br /&gt;
| 0x80&lt;br /&gt;
| During the boot process, u32 0x315c is first set to 0xdeadbeef by IOS in the boot_ppc syscall. The value is set to 0x80 by the NAND Boot Program to indicate that it was loaded by the boot program (and probably 0x81 by apploaders)&lt;br /&gt;
|-&lt;br /&gt;
| 0x8000315D&lt;br /&gt;
| 1&lt;br /&gt;
| 0?&lt;br /&gt;
| &amp;quot;Enable legacy DI&amp;quot; mode? 0x81 = false, anything else means true (though typically set to 0x80). Required to be set when loading Gamecube apploader.&lt;br /&gt;
|-&lt;br /&gt;
| 0x8000315E&lt;br /&gt;
| 2&lt;br /&gt;
| 0x0113&lt;br /&gt;
| &amp;quot;Devkit boot program version&amp;quot;, written to by the system menu. The value carries over to disc games. 0x0113 appears to mean v1.13.&lt;br /&gt;
|-&lt;br /&gt;
| 0x80003160&lt;br /&gt;
| 4&lt;br /&gt;
| 0x00000000&lt;br /&gt;
| Init semaphore (1-2 main() waits for this to clear)&lt;br /&gt;
|-&lt;br /&gt;
| 0x80003164&lt;br /&gt;
| 4&lt;br /&gt;
| 0x00000000&lt;br /&gt;
| GC (MIOS) mode flag, set to 1 by boot2 when MIOS triggers a shutdown; the System Menu reads this and turns off the console if it is set to 1 and :/title/00000001/00000002/data/state.dat|state.dat is set appropriately.&lt;br /&gt;
|-&lt;br /&gt;
| 0x80003180&lt;br /&gt;
| 4&lt;br /&gt;
| 0x52535045&lt;br /&gt;
| Game ID &#039;RSPE&#039; Wii Sports ID. If these 4 bytes don&#039;t match the ID at 80000000, WC24 mode in games is disabled.&lt;br /&gt;
|-&lt;br /&gt;
| 0x80003184&lt;br /&gt;
| 1&lt;br /&gt;
| 0x80&lt;br /&gt;
| Application type.  0x80 for disc games, 0x81 for channels.&lt;br /&gt;
|-&lt;br /&gt;
| 0x80003186&lt;br /&gt;
| 1&lt;br /&gt;
| 0x00&lt;br /&gt;
| Application type 2.  Appears to be set to the when a game loads a channel (e.g. Mario Kart Wii loading the region select menu will result in this being 0x80 from the disc and the main application type being 0x81, or the Wii Fit channel transitioning to the Wii Fit disc will result in this being 0x81 and the main type being 0x80).&lt;br /&gt;
|-&lt;br /&gt;
| 0x80003188&lt;br /&gt;
| 4&lt;br /&gt;
| 0x00351011&lt;br /&gt;
| Minimum IOS version (2 bytes for the major version, 2 bytes for the title version)&lt;br /&gt;
|-&lt;br /&gt;
| 0x8000318C&lt;br /&gt;
| 4&lt;br /&gt;
| 0x00000000&lt;br /&gt;
| Title Booted from NAND (Launch Code)&lt;br /&gt;
|-&lt;br /&gt;
| 0x80003190&lt;br /&gt;
| 4&lt;br /&gt;
| 0x00000000&lt;br /&gt;
| Title Booted from NAND (Return Code)&lt;br /&gt;
|-&lt;br /&gt;
| 0x80003194&lt;br /&gt;
| 4&lt;br /&gt;
| 0x00000000&lt;br /&gt;
| While reading a disc, the system menu reads the first partition table (0x20 bytes from 0x00040020) and stores a pointer to the data partition entry. When launching the disc game, it copies the partition type to 0x3194. The partition type for data partitions is 0, so typically this location always has 0.&lt;br /&gt;
|-&lt;br /&gt;
| 0x80003198&lt;br /&gt;
| 4&lt;br /&gt;
| data partition offset&lt;br /&gt;
| While reading a disc, the system menu reads the first partition table (0x20 bytes from 0x00040020) and stores a pointer to the data partition entry. When launching the disc game, it copies the partition offset to 0x3198.&lt;br /&gt;
|-&lt;br /&gt;
| 0x8000319C&lt;br /&gt;
| 1&lt;br /&gt;
| 0x80&lt;br /&gt;
| Set by the apploader to 0x80 for single-layer discs and 0x81 for dual-layer discs (determined by whether 0x7ed40000 is the value at offset 0x30 in the partition&#039;s bi2.bin; it seems that that value is 0 for single-layer discs).  Early titles&#039; apploaders do not set it at all, leaving the value as 0.  This controls the out-of-bounds Error #001 read for titles that do make such a read: they try to read at 0x7ed40000 for dual-layer discs and 0x460a0000 for single-layer discs.&lt;br /&gt;
|- style=&amp;quot;background-color: #fdd;&amp;quot;&lt;br /&gt;
| 0x80003400&lt;br /&gt;
| 0x400&lt;br /&gt;
| &lt;br /&gt;
| &amp;quot;BS1&amp;quot; boot code&lt;br /&gt;
|- style=&amp;quot;background-color: #eed;&amp;quot;&lt;br /&gt;
| 0x80003F00&lt;br /&gt;
| 0x132c100 (~19.2MB)&lt;br /&gt;
| &lt;br /&gt;
| Standard application executable area&lt;br /&gt;
|- style=&amp;quot;background-color: #fdd;&amp;quot;&lt;br /&gt;
| 0x81330000&lt;br /&gt;
| 0x4d0000 (~4.8MB)&lt;br /&gt;
| &lt;br /&gt;
| Loader executable area, also used by a NAND Boot Program&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
By convention, applications should use the 0x80003F00 – 0x81330000 area for executable code and data loaded as part of their ELF/DOL, while loaders should use from 0x81330000 onwards. Applications can use the loader area and MEM2 as data work space once they are running, but they should restrict the sections contained in the DOL or ELF to the executable area only, since MEM2 is reserved as work area for the loader at that time. To preserve &amp;quot;return to loader&amp;quot; functionality, applications should never use the 0x80001800-0x80003000 area.&lt;/div&gt;</summary>
		<author><name>Shibboleet</name></author>
	</entry>
	<entry>
		<id>https://www.lumasworkshop.com/w/index.php?title=Decompiling&amp;diff=876</id>
		<title>Decompiling</title>
		<link rel="alternate" type="text/html" href="https://www.lumasworkshop.com/w/index.php?title=Decompiling&amp;diff=876"/>
		<updated>2025-05-20T18:29:17Z</updated>

		<summary type="html">&lt;p&gt;Shibboleet: /* Getting Set Up */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Guides]]&lt;br /&gt;
[[Category:Decompiling]]&lt;br /&gt;
{{WIP}}&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
&#039;&#039;Decompiling&#039;&#039; is the process of taking assembly code and turning it back into a higher level language such as C or C++. It is essentially the reverse of &#039;&#039;compiling&#039;&#039;. &#039;&#039;Matching decompilation&#039;&#039; is the process of decompiling, but having the compiled code match the original assembly 1:1. While matching decompilation is harder than normal decompiling, it can become easier when you understand the patterns of the compiler used. This page aims to let new people understand how this process works, and hopefully be able to get new people into decompilation! While you do not need to be an expert at C or C++ to decompile, it is recommended that you have some experience before attempting decompilation. It is also very recommended that you have some prior knowledge of PowerPC assembly, as that is the key to understanding how a function works. [https://www.nxp.com/docs/en/reference-manual/MPC82XINSET.pdf This document] is a good way to learn or refresh knowledge of the PowerPC architecture. [https://www.warthman.com/images/IBM_PPC_Compiler_Writer%27s_Guide-cwg.pdf This document] is also good to learn some of the patterns that CodeWarrior does.&lt;br /&gt;
&lt;br /&gt;
== Getting Set Up ==&lt;br /&gt;
To begin decompiling &#039;&#039;Super Mario Galaxy&#039;&#039;, you first need to set up the environment. You will need the following tools:&lt;br /&gt;
* [https://gitforwindows.org/ Git (Windows)]&lt;br /&gt;
* Any IDE ([https://code.visualstudio.com/ Visual Studio Code Recommended])&lt;br /&gt;
* [https://www.python.org/downloads/release/python-397/ Python 3.9.7]&lt;br /&gt;
* IDA Pro (recommended) or Ghidra (Not recommended)&lt;br /&gt;
* [https://shibbo.net/smg/RMGK01_01(1).i64 SMG1 Korean IDB (For IDA)]&lt;br /&gt;
* A &#039;&#039;Super Mario Galaxy&#039;&#039; Korean region DOL.&lt;br /&gt;
* [https://github.com/ninja-build/ninja/releases Ninja]&lt;br /&gt;
&lt;br /&gt;
After you have acquired all of these, setting up [https://github.com/shibbo/Petari Petari] is very simple.&lt;br /&gt;
&lt;br /&gt;
# With a new command prompt open, type in &#039;&#039;&#039;git clone https://github.com/shibbo/Petari&#039;&#039;&#039;. This will clone the repository into a directory called &amp;quot;Petari&amp;quot;.&lt;br /&gt;
# In this new &amp;quot;Petari&amp;quot; folder, place the SMG1 Korean &#039;&#039;&#039;main.dol&#039;&#039;&#039; into &#039;&#039;&#039;orig/RMGK01/main.dol&#039;&#039;&#039;.&lt;br /&gt;
# Open a new command prompt in the &amp;quot;Petari&amp;quot; folder.&lt;br /&gt;
# Run the command &#039;&#039;&#039;&#039;ninja&#039;&#039;&#039;. This will download the decompilation toolkit (dtk) and &amp;quot;split&amp;quot; the binary, then compile the code.&lt;br /&gt;
&lt;br /&gt;
== Environment ==&lt;br /&gt;
To properly utilize and use &#039;&#039;Petari&#039;&#039;, it is necessary to understand the structure of the environment. Petari is structured in a way that makes it easy to access and use.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Folder Name !! Description&lt;br /&gt;
|-&lt;br /&gt;
| assets || Just assets for the README.&lt;br /&gt;
|-&lt;br /&gt;
| build || The folder that gets created when &#039;&#039;&#039;ninja&#039;&#039;&#039; is ran. Contains the compiled object files and the compilers.&lt;br /&gt;
|-&lt;br /&gt;
| config || Contains the configurations for each SMG1 version for decompilation and splitting.&lt;br /&gt;
|-&lt;br /&gt;
| docs || Documents relating to using &#039;&#039;&#039;dtk&#039;&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
| include || Contains all of the header files for &#039;&#039;Super Mario Galaxy&#039;&#039; specific code.&lt;br /&gt;
|-&lt;br /&gt;
| md || Documentation for completed functions.&lt;br /&gt;
|-&lt;br /&gt;
| orig || Contains the DOLs for each game version for splitting and matching.&lt;br /&gt;
|-&lt;br /&gt;
| src || Contains all of the source files for &#039;&#039;&#039;Super Mario Galaxy&#039;&#039;&#039; and its libraries.&lt;br /&gt;
|-&lt;br /&gt;
| tools || Misc tools that dtk uses.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Libraries ==&lt;br /&gt;
&#039;&#039;Super Mario Galaxy&#039;&#039; uses a lot of libraries for certain functionality such as heaps, layouts, OS specific code, and more. Each library described in the table below are &#039;&#039;&#039;statically linked&#039;&#039;&#039; to the game, so every library&#039;s used code is inside of the &#039;&#039;main.dol&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
=== Non-SMG Libraries ===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Name !! Language !! Description&lt;br /&gt;
|-&lt;br /&gt;
| JSystem || C++ || Contains classes for backend things, such as heaps and linked lists.&lt;br /&gt;
|-&lt;br /&gt;
| MetroTRK || C || Target Resident Kernel, for debugging.&lt;br /&gt;
|-&lt;br /&gt;
| MSL_C || C &amp;amp; C++ || Contains standard library functions and types.&lt;br /&gt;
|-&lt;br /&gt;
| nw4r || C++ || Contains classes for sounds, layouts, and more. (SMG only uses the layouts and some math functions)&lt;br /&gt;
|-&lt;br /&gt;
| Runtime || C &amp;amp; C++ || Contains functions that relate to CodeWarrior&#039;s runtime code generation (ctor / dtor lists, etc)&lt;br /&gt;
|-&lt;br /&gt;
| RVL_SDK || C || Contains functions that relate to the Wii&#039;s &amp;quot;OS&amp;quot;.&lt;br /&gt;
|-&lt;br /&gt;
| RVLFaceLib || C || Contains functions that relate to Miis.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== SMG Libraries ===&lt;br /&gt;
All of &#039;&#039;Super Mario Galaxy&#039;&#039;&#039;s libraries are written in C++.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Header text !! Header text&lt;br /&gt;
|-&lt;br /&gt;
| Animation || Library for animation playing.&lt;br /&gt;
|-&lt;br /&gt;
| AreaObj || Library for invisible areas that can be accessed by players in the game.&lt;br /&gt;
|-&lt;br /&gt;
| AudioLib || N/A&lt;br /&gt;
|-&lt;br /&gt;
| Boss || Library for all of the bosses and mini-bosses in the game.&lt;br /&gt;
|-&lt;br /&gt;
| Camera || Library for all camera types.&lt;br /&gt;
|-&lt;br /&gt;
| Demo || Library for all cutscenes.&lt;br /&gt;
|-&lt;br /&gt;
| Effect || Library for all effect rendering.&lt;br /&gt;
|-&lt;br /&gt;
| Enemy || Library for all enemies.&lt;br /&gt;
|-&lt;br /&gt;
| GameAudio || N/A&lt;br /&gt;
|-&lt;br /&gt;
| Gravity || Library for all of the gravity types in the game.&lt;br /&gt;
|-&lt;br /&gt;
| LiveActor || Library for LiveActor, which is an actor that can switch states.&lt;br /&gt;
|-&lt;br /&gt;
| Map || Library for map classes that do not directly interact with the player. (ie switches)&lt;br /&gt;
|-&lt;br /&gt;
| MapObj || Library for all of the map objects in the game.&lt;br /&gt;
|-&lt;br /&gt;
| NameObj || Library for the most basic form of an object in the game.&lt;br /&gt;
|-&lt;br /&gt;
| NPC || Library for all of the non-playable characters.&lt;br /&gt;
|-&lt;br /&gt;
| NWC24 || Library for the mail system in the game.&lt;br /&gt;
|-&lt;br /&gt;
| Player || Library for all of the player related functions.&lt;br /&gt;
|-&lt;br /&gt;
| RhythmLib || N/A&lt;br /&gt;
|-&lt;br /&gt;
| Ride || Library for all of the actors that can be controlled by the player.&lt;br /&gt;
|-&lt;br /&gt;
| Scene || Library for all of the game scene related code.&lt;br /&gt;
|-&lt;br /&gt;
| Screen || Library for all of the layouts in the game.&lt;br /&gt;
|-&lt;br /&gt;
| Speaker || Library for the sound effect playing done on the Wiimote.&lt;br /&gt;
|-&lt;br /&gt;
| System || Library for a lot of the game&#039;s backend systems.&lt;br /&gt;
|-&lt;br /&gt;
| Util || Library for utility functions and classes.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Basics ==&lt;br /&gt;
To properly decompile, it is vital to know how a lot of the assembly will translate into C / C++ code. Here are a couple of patterns that you will see when decompiling code.&lt;br /&gt;
&lt;br /&gt;
== Splitting ==&lt;br /&gt;
&#039;&#039;Splitting&#039;&#039; refers to &amp;quot;splitting&amp;quot; up each object file with its respective segments to properly build a matching object. This can be code / data, or just data.&lt;br /&gt;
&lt;br /&gt;
A simple split looks like this:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Game/NameObj/NameObj.cpp:&lt;br /&gt;
	.text       start:0x802616B4 end:0x802618B4&lt;br /&gt;
	.data       start:0x805A7758 end:0x805A7780&lt;br /&gt;
	.sbss       start:0x806B5BE0 end:0x806B5BE8&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Each segment needs a &#039;&#039;&#039;start&#039;&#039;&#039; and an &#039;&#039;&#039;end&#039;&#039;&#039; address, and the &#039;&#039;&#039;end&#039;&#039;&#039; address always needs to be larger than the &#039;&#039;&#039;start&#039;&#039;&#039; address. You can use IDA (or Ghidra) to see what segment a specific set of code / data belongs to. For this specific split:&lt;br /&gt;
* &#039;&#039;&#039;.text&#039;&#039;&#039; begins at &#039;&#039;&#039;0x802616B4&#039;&#039;&#039; and ends at &#039;&#039;&#039;0x802618B4&#039;&#039;&#039;.&lt;br /&gt;
* &#039;&#039;&#039;.data&#039;&#039;&#039; begins at &#039;&#039;&#039;0x805A7758&#039;&#039;&#039; and ends at &#039;&#039;&#039;0x805A7780&#039;&#039;&#039;.&lt;br /&gt;
* &#039;&#039;&#039;.sbss&#039;&#039;&#039; begins at &#039;&#039;&#039;0x806B5BE0&#039;&#039;&#039; and ends at &#039;&#039;&#039;0x806B5BE8&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
You can change these splits by changing &#039;&#039;&#039;config/RMGKXX/splits.txt&#039;&#039;&#039; where &#039;&#039;&#039;XX&#039;&#039;&#039; is the version of the Korean version you are using. It is worth noting that any data addresses (ie .data, .bss, .sdata) need to be rounded to the nearest 8th byte, as they are 8-byte aligned.&lt;br /&gt;
&lt;br /&gt;
== Class Mapping ==&lt;br /&gt;
=== Base Class ===&lt;br /&gt;
The first step to decompiling a class is to map out the class itself. You need to be sure that you document every member, its type (as close as you can guess), its virtual functions, and more. The easiest way to achieve this is to look at the class&#039;s &#039;&#039;constructor&#039;&#039;. Seen below, is an example of a &#039;&#039;constructor&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
[[Image:NameObj_Ctor.png|frameless|700px|The constructor for &#039;&#039;NameObj&#039;&#039;.]]&lt;br /&gt;
&lt;br /&gt;
There are a couple of takeaways from this screenshot:&lt;br /&gt;
* The constructor passes an argument, which is a &#039;&#039;&#039;const char *&#039;&#039;&#039; (contained in r4) and is stored in (r3 + 0x4).&lt;br /&gt;
* (r3 + 0x0) is where the vtable is &#039;&#039;usually&#039;&#039; stored when a class has virtual functions. There are rare execptions.&lt;br /&gt;
* (r3 + 0x8) is stored with a &#039;&#039;&#039;sth&#039;&#039;&#039;, which means that it is a &#039;&#039;&#039;short&#039;&#039;&#039; datatype.&lt;br /&gt;
* (r3 + 0xA) is also stored with a &#039;&#039;&#039;sth&#039;&#039;&#039;, but with a &#039;&#039;&#039;-1&#039;&#039;&#039; value, so we know for sure that this type is &#039;&#039;signed&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Keep in mind that a constructor does not have to initialize every single member variable in the class! So there could be other members in a class that aren&#039;t mentioned in the constructor at all. After you look at the constructor, look around at the &#039;&#039;member functions&#039;&#039; to see if they use any members that are not initialized in the constructor. You can always verify if your class setup is correct when you can find where this class is created using the &#039;&#039;&#039;new&#039;&#039;&#039; operator. Check if the size passed to the &#039;&#039;&#039;new&#039;&#039;&#039; call matches the size of the class that you have mapped. If it is smaller, you are missing members. If it is bigger, you have too many! Remember that the vtable is implicitly stored at &#039;&#039;&#039;(this + 0x0)&#039;&#039;&#039;, so you do not have to explicitly define it. With all of these members documented, our class setup looks a little like this so far:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class NameObj {&lt;br /&gt;
public:&lt;br /&gt;
    NameObj(const char *pName);&lt;br /&gt;
&lt;br /&gt;
    /* remember that the vtable will be placed here once we define our virtuals! */&lt;br /&gt;
    /* 0x4 */   const char* mName;&lt;br /&gt;
    /* 0x8 */   volatile u16 mFlags;&lt;br /&gt;
    /* 0xA */   s16 mExecutorIdx;&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
After the members comes the &#039;&#039;&#039;vtable&#039;&#039;&#039;, or &#039;&#039;virtual table&#039;&#039;. It is an array of function pointers that can be overridden by classes that inherit the parent class. The vtable for &#039;&#039;&#039;NameObj&#039;&#039;&#039; looks like this:&lt;br /&gt;
[[Image:NameObj_Vtable.png|frameless|700px|The vtable for &#039;&#039;NameObj&#039;&#039;.]]&lt;br /&gt;
&lt;br /&gt;
To document the vtable, you simply document every single function placed here that contains the class name of the class you are currently decompiling. Since &#039;&#039;NameObj&#039;&#039; is a base class, every single function here is going to be defined. If a class overrides a function, you will only document the functions that are overridden. After documenting the vtable, our class looks something like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class NameObj {&lt;br /&gt;
public:&lt;br /&gt;
    NameObj(const char *pName);&lt;br /&gt;
&lt;br /&gt;
    virtual ~NameObj();&lt;br /&gt;
    virtual void init(const JMapInfoIter &amp;amp;rIter);&lt;br /&gt;
    virtual void initAfterPlacement();&lt;br /&gt;
    virtual void movement();&lt;br /&gt;
    virtual void draw() const;&lt;br /&gt;
    virtual void calcAnim();&lt;br /&gt;
    virtual void calcViewAndEntry();&lt;br /&gt;
&lt;br /&gt;
    /* remember that the vtable will be placed here once we define our virtuals! */&lt;br /&gt;
    /* 0x4 */   const char* mName;&lt;br /&gt;
    /* 0x8 */   volatile u16 mFlags;&lt;br /&gt;
    /* 0xA */   s16 mExecutorIdx;&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Once the vtable is complete, you want to document all of the member functions that are in the class. Since &#039;&#039;Super Mario Galaxy 1&#039;&#039; has a symbol map, we can easily find the member functions that &#039;&#039;NameObj&#039;&#039; contains. Once you have figured out their return types and their arguments, you can finish mapping out a class! After finding all of &#039;&#039;NameObj&#039;&#039;&#039;s member functions, the class looks like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class NameObj {&lt;br /&gt;
public:&lt;br /&gt;
    NameObj(const char *pName);&lt;br /&gt;
&lt;br /&gt;
    virtual ~NameObj();&lt;br /&gt;
    virtual void init(const JMapInfoIter &amp;amp;rIter);&lt;br /&gt;
    virtual void initAfterPlacement();&lt;br /&gt;
    virtual void movement();&lt;br /&gt;
    virtual void draw() const;&lt;br /&gt;
    virtual void calcAnim();&lt;br /&gt;
    virtual void calcViewAndEntry();&lt;br /&gt;
&lt;br /&gt;
    void initWithoutIter();&lt;br /&gt;
    void setName(const char *pName);&lt;br /&gt;
    void executeMovement();&lt;br /&gt;
    void requestSuspend();&lt;br /&gt;
    void requestResume();&lt;br /&gt;
    void syncWithFlags();&lt;br /&gt;
&lt;br /&gt;
    /* remember that the vtable will be placed here once we define our virtuals! */&lt;br /&gt;
    /* 0x4 */   const char* mName;&lt;br /&gt;
    /* 0x8 */   volatile u16 mFlags;&lt;br /&gt;
    /* 0xA */   s16 mExecutorIdx;&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Inheriting Class ===&lt;br /&gt;
The process of mapping a class that inherits another class is mainly the same as mapping a base class, except there are things to watch out for so you don&#039;t accidentally duplicate a member variable. The first step is to look at the &#039;&#039;constructor&#039;&#039; of the class you want to map:&lt;br /&gt;
&lt;br /&gt;
[[Image:TripodBossCoin_Ctor.png|frameless|700px|The constructor for &#039;&#039;TripodBossCoin&#039;&#039;.]]&lt;br /&gt;
&lt;br /&gt;
There are a few takeaways from this by looking at the constructor:&lt;br /&gt;
* The class inherits NameObj. Since &#039;&#039;NameObj&#039;&#039; is 0xC bytes long, we know that any member variables for &#039;&#039;TripodBossCoin&#039;&#039; start at &#039;&#039;&#039;0xC&#039;&#039;&#039;.&lt;br /&gt;
* The vtable pointer &#039;&#039;&#039;(this + 0x0)&#039;&#039;&#039; from &#039;&#039;NameObj&#039;&#039; is overridden with the vtable for &#039;&#039;TripodBossCoin&#039;&#039; implicitly.&lt;br /&gt;
* &#039;&#039;&#039;(this + 0xC)&#039;&#039;&#039; is a 32-bit integer initialized to 0. It is not possible to determine if it is signed or not from this store alone.&lt;br /&gt;
* &#039;&#039;&#039;(this + 0x10)&#039;&#039;&#039; is the same scenario as &#039;&#039;&#039;(this + 0xC)&#039;&#039;&#039;.&lt;br /&gt;
* There is a direct instance of &#039;&#039;JGeometry::TMatrix34&amp;lt;JGeometry::SMatrix34C&amp;lt;f32&amp;gt;&#039;&#039; at 0x14. (in Petari &amp;amp; Syati this is typedef&#039;d as &#039;&#039;TMtx34f&#039;&#039;). Since &#039;&#039;TMtx34f&#039;&#039; is 0x30 in size, the next member variable is at 0x14 + 0x30, which is &#039;&#039;&#039;0x44&#039;&#039;&#039;.&lt;br /&gt;
* &#039;&#039;&#039;(this + 0x44)&#039;&#039;&#039; is a signed 32-bit integer, due to &#039;&#039;&#039;-1&#039;&#039;&#039; being stored to it.&lt;br /&gt;
&lt;br /&gt;
After these observations, our class looks like this:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class TripodBossCoin : public NameObj {&lt;br /&gt;
public:&lt;br /&gt;
	TripodBossCoin(const char *);&lt;br /&gt;
	&lt;br /&gt;
	u32 _C;&lt;br /&gt;
	u32 _10;&lt;br /&gt;
	TMtx34f _14;&lt;br /&gt;
	s32 _44;&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Next are the virtuals. The process is a little different from a base class. Let&#039;s take a look at the vtable for &#039;&#039;TripodBossCoin&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
[[Image:TripodBossCoin_Vtable.png|frameless|700px|The vtable for &#039;&#039;TripodBossCoin&#039;&#039;.]]&lt;br /&gt;
&lt;br /&gt;
The biggest takeaway from this screenshot is that only three virtuals are overriden by &#039;&#039;TripodBossCoin&#039;&#039;. And those three functions are &#039;&#039;&#039;TripodBossCoin::~TripodBossCoin()&#039;&#039;&#039;, &#039;&#039;&#039;TripodBossCoin::init()&#039;&#039;&#039; and &#039;&#039;&#039;TripodBossCoin::movement()&#039;&#039;&#039;. So we define them as such:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class TripodBossCoin : public NameObj {&lt;br /&gt;
public:&lt;br /&gt;
	TripodBossCoin(const char *);&lt;br /&gt;
&lt;br /&gt;
    virtual ~TripodBossCoin();&lt;br /&gt;
    virtual void init(const JMapInfoIter &amp;amp;);&lt;br /&gt;
    virtual void movement();&lt;br /&gt;
	&lt;br /&gt;
	u32 _C;&lt;br /&gt;
	u32 _10;&lt;br /&gt;
	TMtx34f _14;&lt;br /&gt;
	s32 _44;&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
It is worth noting that the &#039;&#039;&#039;override&#039;&#039;&#039; keyword was not a part of the C++ standard at this point in time, so all overrides are implicit. After all of this is done, you simply have to repeat the process for base classes and document the member functions that are a part of the class.&lt;br /&gt;
&lt;br /&gt;
=== Loops ===&lt;br /&gt;
==== Predefined bounds ====&lt;br /&gt;
Let&#039;s take a simple loop that stores &amp;lt;i&amp;gt;nullptr&amp;lt;/i&amp;gt; in each 8 elements of a pointer array.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class TestClass {&lt;br /&gt;
public:&lt;br /&gt;
    TestClass();&lt;br /&gt;
&lt;br /&gt;
     int* mPointers[8];&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
TestClass::TestClass() {&lt;br /&gt;
    for (int i = 0; i &amp;lt; 8; i++) {&lt;br /&gt;
        mPointers[i] = nullptr;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The output assembly would look something like:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
li r0, 8 # there are 8 elements in this loop&lt;br /&gt;
li r5, 0 # the value to store in the element (nullptr)&lt;br /&gt;
li r4, 0 # the current element offset in the loop&lt;br /&gt;
mtctr r0 # move the number of iterations into the counter register (8)&lt;br /&gt;
&lt;br /&gt;
loop:&lt;br /&gt;
    stwx r5, r3, r4 # store 0 (r5) into the array at r3 (this) + r4 (our current offset, which is i * 4)&lt;br /&gt;
    addi r4, r4, 4 # increment our offset by sizeof(int) since integers are 32-bits&lt;br /&gt;
    bdnz+ loop # branch back to our loop again&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Variable Length Bounds ====&lt;br /&gt;
Let&#039;s take a simple loop that stores &amp;lt;i&amp;gt;nullptr&amp;lt;/i&amp;gt; in each element of a variable-length array. We will have a class with two members, one that contains the pointer array itself, and another that stores the number of pointers.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class TestClass {&lt;br /&gt;
public:&lt;br /&gt;
    TestClass();&lt;br /&gt;
&lt;br /&gt;
     int** mPointers;&lt;br /&gt;
     int mNumPointers;&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
TestClass::TestClass() {&lt;br /&gt;
    mNumPointers = 8;&lt;br /&gt;
    for (int i = 0; i &amp;lt; mNumPointers ; i++) {&lt;br /&gt;
        mPointers[i] = nullptr;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Because we do not know how many pointers we have stored, we cannot use the counter register like we did with a fixed-size array. Instead, the compiler will use a cmpw (signed integer) or cmplw (unsigned) instruction to compare the current iteration to how many pointers are stored in the class.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
li r0, 8 # there are 8 elements in this loop&lt;br /&gt;
li r7, 0 # the value to store in the element (nullptr)&lt;br /&gt;
stw r0, 4(r3) # r3 + 4 is the offset to our member variable &amp;quot;mNumPointers&amp;quot;&lt;br /&gt;
mr r6, r7 # simple copy of the 0 value so we can also use it for our counter&lt;br /&gt;
li r4, 0 # load 0 into our offset&lt;br /&gt;
b loop # branch into our loop&lt;br /&gt;
&lt;br /&gt;
loop:&lt;br /&gt;
    lwz r5, 0(r3) # load our pointer array from this + 0&lt;br /&gt;
    addi r7, r7, 1 # increment our index by 1&lt;br /&gt;
    stwx r6, r5, r4 # store our nullptr value (r6) into r5 + r4 (ptrArray + currentOffset)&lt;br /&gt;
    addi r4, r4, 4 # increment our offset by sizeof(int) since integers are 32-bits&lt;br /&gt;
    lwz r0, 4(r3) # load our number of pointers we will increment by (mNumPointers)&lt;br /&gt;
    cmpw r7, r0 # compare our number of pointers to the current index in our loop&lt;br /&gt;
    blt+ loop # branch if the number is less than mNumPointers&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Structure Access In Arrays (Pointer Array) ====&lt;br /&gt;
More complex forms of loops comes into play when you are iterating through structures and storing / loading members from those structures. Let&#039;s take this class for example:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
struct TestStruct {&lt;br /&gt;
    int SomeMember;&lt;br /&gt;
    int AnotherMember;&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
class TestClass {&lt;br /&gt;
public:&lt;br /&gt;
    TestClass();&lt;br /&gt;
&lt;br /&gt;
    void storeVals();&lt;br /&gt;
&lt;br /&gt;
     TestStruct** mStructures;&lt;br /&gt;
     int mNumStructures;&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
For the sake of simplicity, let&#039;s assume that the TestClass constructor initializes the number of structures to 8, and constructs them accordingly. With that in mind, let&#039;s see how a struct store will work.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void TestClass::storeVals() {&lt;br /&gt;
    for (int i = 0; i &amp;lt; mNumStructures; i++) {&lt;br /&gt;
        mStructures[i]-&amp;gt;AnotherMember = 5;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
The output assembly would look something like:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
li r7, 0 # our &amp;quot;i&amp;quot; used in the loop, starts at 0&lt;br /&gt;
li r4, 0 # our current offset into the array&lt;br /&gt;
li r6, 5 # the value we are storing into the array&lt;br /&gt;
b loop&lt;br /&gt;
&lt;br /&gt;
loop:&lt;br /&gt;
    lwz r5, 0(r3) # load the array pointer&lt;br /&gt;
    addi r7, r7, 1 # increment our current index (i) by 1&lt;br /&gt;
    lwzx r5, r5, r4 # load the current structure, mStructures[i] where r4 is the current offset&lt;br /&gt;
    addi r4, r4, 4 # increment our offset by sizeof(TestStruct*), which is 4&lt;br /&gt;
    stw r6, 4(r5) # store our value (5) into (mStructures[i] + 4), which is our AnotherMember&lt;br /&gt;
    lwz r0, 4(r3) # load the number of structures from TestClass&lt;br /&gt;
    cmpw r7, r0 # compare the current index to our value in TestClass&lt;br /&gt;
    blt+ loop # loop back if it is less than the value&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Structure Access In Arrays (Direct Array) ====&lt;br /&gt;
Let&#039;s take the previous example and modify it a little. Instead of making an array of pointers to the struct instances, let&#039;s store the array &amp;lt;i&amp;gt;directly&amp;lt;/i&amp;gt; into our class instance.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
struct TestStruct {&lt;br /&gt;
    int SomeMember;&lt;br /&gt;
    int AnotherMember;&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
class TestClass {&lt;br /&gt;
public:&lt;br /&gt;
    TestClass();&lt;br /&gt;
&lt;br /&gt;
    void storeVals();&lt;br /&gt;
&lt;br /&gt;
     TestStruct mStructures[8];&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Again, let us assume that the array has already been constructed and everything is initialized as it should be.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void TestClass::storeVals() {&lt;br /&gt;
    for (int i = 0; i &amp;lt; 8; i++) {&lt;br /&gt;
        mStructures[i].AnotherMember = 5;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
The output assembly would look something like:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
li r0, 8 # load our number of iterations (8)&lt;br /&gt;
li r4, 0 # current offset into the array. initialized at 0&lt;br /&gt;
li r6, 5 # the value to store into the array&lt;br /&gt;
mtctr r0 # move the number of iterations into the counter register&lt;br /&gt;
&lt;br /&gt;
loop:&lt;br /&gt;
    add r5, r3, r4 # jump to the offset into the array. r5 = (this + 0) + r4&lt;br /&gt;
    addi r4, r4, 8 # increment our current offset by sizeof(TestStruct), which is 8&lt;br /&gt;
    stw r6, 4(r5) # store our constant value (5) into the loaded struct + 4 (AnotherMember)&lt;br /&gt;
    bdnz+ loop # branch back to the loop if the counter is not 8&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Actor Decompiling ==&lt;br /&gt;
An &#039;&#039;actor&#039;&#039; is how the game refers to something that is present in a &#039;&#039;scene&#039;&#039; (ie a Goomba or a Coin). The approach to decompiling an actor is rather repetitive, but can change based on the actor itself. However, most of them follow a straightforward structure. They contain a constructor that takes in a &#039;&#039;&#039;const char *&#039;&#039;&#039; pointer (which is the name of the actor) and passes that to the parent class, which can range from &#039;&#039;LiveActor&#039;&#039; to &#039;&#039;MapObjActor&#039;&#039;. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Operator Overloads ==&lt;br /&gt;
There are specific ways that CodeWarrior mangles symbols when overloading operators for classes.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Operator !! Mangled Symbol&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;+&amp;quot; || &amp;quot;pl&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;-&amp;quot; || &amp;quot;mi&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;*&amp;quot; || &amp;quot;ml&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;/&amp;quot; || &amp;quot;dv&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;%&amp;quot; || &amp;quot;md&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;^&amp;quot; || &amp;quot;er&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;/=&amp;quot; || &amp;quot;adv&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;&amp;amp;&amp;quot; || &amp;quot;ad&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;&amp;amp;verbar;&amp;quot; || &amp;quot;or&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;~&amp;quot; || &amp;quot;co&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;!&amp;quot; || &amp;quot;nt&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;=&amp;quot; || &amp;quot;as&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;&amp;lt;&amp;quot; || &amp;quot;lt&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;&amp;gt;&amp;quot; || &amp;quot;gt&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;+=&amp;quot; || &amp;quot;apl&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;-=&amp;quot; || &amp;quot;ami&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;*=&amp;quot; || &amp;quot;amu&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;%=&amp;quot; || &amp;quot;amd&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;^=&amp;quot; || &amp;quot;aer&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;&amp;amp;=&amp;quot; || &amp;quot;aad&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;&amp;amp;verbar;=&amp;quot; || &amp;quot;aor&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;&amp;lt;&amp;lt;&amp;quot; || &amp;quot;ls&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;&amp;gt;&amp;gt;&amp;quot; || &amp;quot;rs&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;&amp;gt;&amp;gt;=&amp;quot; || &amp;quot;ars&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;&amp;lt;&amp;lt;=&amp;quot; || &amp;quot;als&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;==&amp;quot; || &amp;quot;eq&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;!=&amp;quot; || &amp;quot;ne&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;&amp;lt;=&amp;quot; || &amp;quot;le&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;&amp;gt;=&amp;quot; || &amp;quot;ge&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;&amp;amp;&amp;amp;&amp;quot; || &amp;quot;aa&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;&amp;amp;verbar;&amp;amp;verbar;&amp;quot; || &amp;quot;oo&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;++&amp;quot; || &amp;quot;pp&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;--&amp;quot; || &amp;quot;mm&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;()&amp;quot; || &amp;quot;cl&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;[]&amp;quot; || &amp;quot;vc&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;-&amp;gt;&amp;quot; || &amp;quot;rf&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;,&amp;quot; || &amp;quot;cm&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;-&amp;gt;*&amp;quot; || &amp;quot;rm&amp;quot;&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Shibboleet</name></author>
	</entry>
	<entry>
		<id>https://www.lumasworkshop.com/w/index.php?title=Decompiling&amp;diff=875</id>
		<title>Decompiling</title>
		<link rel="alternate" type="text/html" href="https://www.lumasworkshop.com/w/index.php?title=Decompiling&amp;diff=875"/>
		<updated>2025-05-20T18:29:00Z</updated>

		<summary type="html">&lt;p&gt;Shibboleet: /* Getting Set Up */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Guides]]&lt;br /&gt;
[[Category:Decompiling]]&lt;br /&gt;
{{WIP}}&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
&#039;&#039;Decompiling&#039;&#039; is the process of taking assembly code and turning it back into a higher level language such as C or C++. It is essentially the reverse of &#039;&#039;compiling&#039;&#039;. &#039;&#039;Matching decompilation&#039;&#039; is the process of decompiling, but having the compiled code match the original assembly 1:1. While matching decompilation is harder than normal decompiling, it can become easier when you understand the patterns of the compiler used. This page aims to let new people understand how this process works, and hopefully be able to get new people into decompilation! While you do not need to be an expert at C or C++ to decompile, it is recommended that you have some experience before attempting decompilation. It is also very recommended that you have some prior knowledge of PowerPC assembly, as that is the key to understanding how a function works. [https://www.nxp.com/docs/en/reference-manual/MPC82XINSET.pdf This document] is a good way to learn or refresh knowledge of the PowerPC architecture. [https://www.warthman.com/images/IBM_PPC_Compiler_Writer%27s_Guide-cwg.pdf This document] is also good to learn some of the patterns that CodeWarrior does.&lt;br /&gt;
&lt;br /&gt;
== Getting Set Up ==&lt;br /&gt;
To begin decompiling &#039;&#039;Super Mario Galaxy&#039;&#039;, you first need to set up the environment. You will need the following tools:&lt;br /&gt;
* [https://gitforwindows.org/ Git (Windows)]&lt;br /&gt;
* Any IDE ([https://code.visualstudio.com/ Visual Studio Code Recommended])&lt;br /&gt;
* [https://www.python.org/downloads/release/python-397/ Python 3.9.7]&lt;br /&gt;
* IDA Pro (recommended) or Ghidra (Not recommended)&lt;br /&gt;
* [https://shibbo.net/smg/RMGK01_01.i64 SMG1 Korean IDB (For IDA)]&lt;br /&gt;
* A &#039;&#039;Super Mario Galaxy&#039;&#039; Korean region DOL.&lt;br /&gt;
* [https://github.com/ninja-build/ninja/releases Ninja]&lt;br /&gt;
&lt;br /&gt;
After you have acquired all of these, setting up [https://github.com/shibbo/Petari Petari] is very simple.&lt;br /&gt;
&lt;br /&gt;
# With a new command prompt open, type in &#039;&#039;&#039;git clone https://github.com/shibbo/Petari&#039;&#039;&#039;. This will clone the repository into a directory called &amp;quot;Petari&amp;quot;.&lt;br /&gt;
# In this new &amp;quot;Petari&amp;quot; folder, place the SMG1 Korean &#039;&#039;&#039;main.dol&#039;&#039;&#039; into &#039;&#039;&#039;orig/RMGK01/main.dol&#039;&#039;&#039;.&lt;br /&gt;
# Open a new command prompt in the &amp;quot;Petari&amp;quot; folder.&lt;br /&gt;
# Run the command &#039;&#039;&#039;&#039;ninja&#039;&#039;&#039;. This will download the decompilation toolkit (dtk) and &amp;quot;split&amp;quot; the binary, then compile the code.&lt;br /&gt;
&lt;br /&gt;
== Environment ==&lt;br /&gt;
To properly utilize and use &#039;&#039;Petari&#039;&#039;, it is necessary to understand the structure of the environment. Petari is structured in a way that makes it easy to access and use.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Folder Name !! Description&lt;br /&gt;
|-&lt;br /&gt;
| assets || Just assets for the README.&lt;br /&gt;
|-&lt;br /&gt;
| build || The folder that gets created when &#039;&#039;&#039;ninja&#039;&#039;&#039; is ran. Contains the compiled object files and the compilers.&lt;br /&gt;
|-&lt;br /&gt;
| config || Contains the configurations for each SMG1 version for decompilation and splitting.&lt;br /&gt;
|-&lt;br /&gt;
| docs || Documents relating to using &#039;&#039;&#039;dtk&#039;&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
| include || Contains all of the header files for &#039;&#039;Super Mario Galaxy&#039;&#039; specific code.&lt;br /&gt;
|-&lt;br /&gt;
| md || Documentation for completed functions.&lt;br /&gt;
|-&lt;br /&gt;
| orig || Contains the DOLs for each game version for splitting and matching.&lt;br /&gt;
|-&lt;br /&gt;
| src || Contains all of the source files for &#039;&#039;&#039;Super Mario Galaxy&#039;&#039;&#039; and its libraries.&lt;br /&gt;
|-&lt;br /&gt;
| tools || Misc tools that dtk uses.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Libraries ==&lt;br /&gt;
&#039;&#039;Super Mario Galaxy&#039;&#039; uses a lot of libraries for certain functionality such as heaps, layouts, OS specific code, and more. Each library described in the table below are &#039;&#039;&#039;statically linked&#039;&#039;&#039; to the game, so every library&#039;s used code is inside of the &#039;&#039;main.dol&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
=== Non-SMG Libraries ===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Name !! Language !! Description&lt;br /&gt;
|-&lt;br /&gt;
| JSystem || C++ || Contains classes for backend things, such as heaps and linked lists.&lt;br /&gt;
|-&lt;br /&gt;
| MetroTRK || C || Target Resident Kernel, for debugging.&lt;br /&gt;
|-&lt;br /&gt;
| MSL_C || C &amp;amp; C++ || Contains standard library functions and types.&lt;br /&gt;
|-&lt;br /&gt;
| nw4r || C++ || Contains classes for sounds, layouts, and more. (SMG only uses the layouts and some math functions)&lt;br /&gt;
|-&lt;br /&gt;
| Runtime || C &amp;amp; C++ || Contains functions that relate to CodeWarrior&#039;s runtime code generation (ctor / dtor lists, etc)&lt;br /&gt;
|-&lt;br /&gt;
| RVL_SDK || C || Contains functions that relate to the Wii&#039;s &amp;quot;OS&amp;quot;.&lt;br /&gt;
|-&lt;br /&gt;
| RVLFaceLib || C || Contains functions that relate to Miis.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== SMG Libraries ===&lt;br /&gt;
All of &#039;&#039;Super Mario Galaxy&#039;&#039;&#039;s libraries are written in C++.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Header text !! Header text&lt;br /&gt;
|-&lt;br /&gt;
| Animation || Library for animation playing.&lt;br /&gt;
|-&lt;br /&gt;
| AreaObj || Library for invisible areas that can be accessed by players in the game.&lt;br /&gt;
|-&lt;br /&gt;
| AudioLib || N/A&lt;br /&gt;
|-&lt;br /&gt;
| Boss || Library for all of the bosses and mini-bosses in the game.&lt;br /&gt;
|-&lt;br /&gt;
| Camera || Library for all camera types.&lt;br /&gt;
|-&lt;br /&gt;
| Demo || Library for all cutscenes.&lt;br /&gt;
|-&lt;br /&gt;
| Effect || Library for all effect rendering.&lt;br /&gt;
|-&lt;br /&gt;
| Enemy || Library for all enemies.&lt;br /&gt;
|-&lt;br /&gt;
| GameAudio || N/A&lt;br /&gt;
|-&lt;br /&gt;
| Gravity || Library for all of the gravity types in the game.&lt;br /&gt;
|-&lt;br /&gt;
| LiveActor || Library for LiveActor, which is an actor that can switch states.&lt;br /&gt;
|-&lt;br /&gt;
| Map || Library for map classes that do not directly interact with the player. (ie switches)&lt;br /&gt;
|-&lt;br /&gt;
| MapObj || Library for all of the map objects in the game.&lt;br /&gt;
|-&lt;br /&gt;
| NameObj || Library for the most basic form of an object in the game.&lt;br /&gt;
|-&lt;br /&gt;
| NPC || Library for all of the non-playable characters.&lt;br /&gt;
|-&lt;br /&gt;
| NWC24 || Library for the mail system in the game.&lt;br /&gt;
|-&lt;br /&gt;
| Player || Library for all of the player related functions.&lt;br /&gt;
|-&lt;br /&gt;
| RhythmLib || N/A&lt;br /&gt;
|-&lt;br /&gt;
| Ride || Library for all of the actors that can be controlled by the player.&lt;br /&gt;
|-&lt;br /&gt;
| Scene || Library for all of the game scene related code.&lt;br /&gt;
|-&lt;br /&gt;
| Screen || Library for all of the layouts in the game.&lt;br /&gt;
|-&lt;br /&gt;
| Speaker || Library for the sound effect playing done on the Wiimote.&lt;br /&gt;
|-&lt;br /&gt;
| System || Library for a lot of the game&#039;s backend systems.&lt;br /&gt;
|-&lt;br /&gt;
| Util || Library for utility functions and classes.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Basics ==&lt;br /&gt;
To properly decompile, it is vital to know how a lot of the assembly will translate into C / C++ code. Here are a couple of patterns that you will see when decompiling code.&lt;br /&gt;
&lt;br /&gt;
== Splitting ==&lt;br /&gt;
&#039;&#039;Splitting&#039;&#039; refers to &amp;quot;splitting&amp;quot; up each object file with its respective segments to properly build a matching object. This can be code / data, or just data.&lt;br /&gt;
&lt;br /&gt;
A simple split looks like this:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Game/NameObj/NameObj.cpp:&lt;br /&gt;
	.text       start:0x802616B4 end:0x802618B4&lt;br /&gt;
	.data       start:0x805A7758 end:0x805A7780&lt;br /&gt;
	.sbss       start:0x806B5BE0 end:0x806B5BE8&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Each segment needs a &#039;&#039;&#039;start&#039;&#039;&#039; and an &#039;&#039;&#039;end&#039;&#039;&#039; address, and the &#039;&#039;&#039;end&#039;&#039;&#039; address always needs to be larger than the &#039;&#039;&#039;start&#039;&#039;&#039; address. You can use IDA (or Ghidra) to see what segment a specific set of code / data belongs to. For this specific split:&lt;br /&gt;
* &#039;&#039;&#039;.text&#039;&#039;&#039; begins at &#039;&#039;&#039;0x802616B4&#039;&#039;&#039; and ends at &#039;&#039;&#039;0x802618B4&#039;&#039;&#039;.&lt;br /&gt;
* &#039;&#039;&#039;.data&#039;&#039;&#039; begins at &#039;&#039;&#039;0x805A7758&#039;&#039;&#039; and ends at &#039;&#039;&#039;0x805A7780&#039;&#039;&#039;.&lt;br /&gt;
* &#039;&#039;&#039;.sbss&#039;&#039;&#039; begins at &#039;&#039;&#039;0x806B5BE0&#039;&#039;&#039; and ends at &#039;&#039;&#039;0x806B5BE8&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
You can change these splits by changing &#039;&#039;&#039;config/RMGKXX/splits.txt&#039;&#039;&#039; where &#039;&#039;&#039;XX&#039;&#039;&#039; is the version of the Korean version you are using. It is worth noting that any data addresses (ie .data, .bss, .sdata) need to be rounded to the nearest 8th byte, as they are 8-byte aligned.&lt;br /&gt;
&lt;br /&gt;
== Class Mapping ==&lt;br /&gt;
=== Base Class ===&lt;br /&gt;
The first step to decompiling a class is to map out the class itself. You need to be sure that you document every member, its type (as close as you can guess), its virtual functions, and more. The easiest way to achieve this is to look at the class&#039;s &#039;&#039;constructor&#039;&#039;. Seen below, is an example of a &#039;&#039;constructor&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
[[Image:NameObj_Ctor.png|frameless|700px|The constructor for &#039;&#039;NameObj&#039;&#039;.]]&lt;br /&gt;
&lt;br /&gt;
There are a couple of takeaways from this screenshot:&lt;br /&gt;
* The constructor passes an argument, which is a &#039;&#039;&#039;const char *&#039;&#039;&#039; (contained in r4) and is stored in (r3 + 0x4).&lt;br /&gt;
* (r3 + 0x0) is where the vtable is &#039;&#039;usually&#039;&#039; stored when a class has virtual functions. There are rare execptions.&lt;br /&gt;
* (r3 + 0x8) is stored with a &#039;&#039;&#039;sth&#039;&#039;&#039;, which means that it is a &#039;&#039;&#039;short&#039;&#039;&#039; datatype.&lt;br /&gt;
* (r3 + 0xA) is also stored with a &#039;&#039;&#039;sth&#039;&#039;&#039;, but with a &#039;&#039;&#039;-1&#039;&#039;&#039; value, so we know for sure that this type is &#039;&#039;signed&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Keep in mind that a constructor does not have to initialize every single member variable in the class! So there could be other members in a class that aren&#039;t mentioned in the constructor at all. After you look at the constructor, look around at the &#039;&#039;member functions&#039;&#039; to see if they use any members that are not initialized in the constructor. You can always verify if your class setup is correct when you can find where this class is created using the &#039;&#039;&#039;new&#039;&#039;&#039; operator. Check if the size passed to the &#039;&#039;&#039;new&#039;&#039;&#039; call matches the size of the class that you have mapped. If it is smaller, you are missing members. If it is bigger, you have too many! Remember that the vtable is implicitly stored at &#039;&#039;&#039;(this + 0x0)&#039;&#039;&#039;, so you do not have to explicitly define it. With all of these members documented, our class setup looks a little like this so far:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class NameObj {&lt;br /&gt;
public:&lt;br /&gt;
    NameObj(const char *pName);&lt;br /&gt;
&lt;br /&gt;
    /* remember that the vtable will be placed here once we define our virtuals! */&lt;br /&gt;
    /* 0x4 */   const char* mName;&lt;br /&gt;
    /* 0x8 */   volatile u16 mFlags;&lt;br /&gt;
    /* 0xA */   s16 mExecutorIdx;&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
After the members comes the &#039;&#039;&#039;vtable&#039;&#039;&#039;, or &#039;&#039;virtual table&#039;&#039;. It is an array of function pointers that can be overridden by classes that inherit the parent class. The vtable for &#039;&#039;&#039;NameObj&#039;&#039;&#039; looks like this:&lt;br /&gt;
[[Image:NameObj_Vtable.png|frameless|700px|The vtable for &#039;&#039;NameObj&#039;&#039;.]]&lt;br /&gt;
&lt;br /&gt;
To document the vtable, you simply document every single function placed here that contains the class name of the class you are currently decompiling. Since &#039;&#039;NameObj&#039;&#039; is a base class, every single function here is going to be defined. If a class overrides a function, you will only document the functions that are overridden. After documenting the vtable, our class looks something like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class NameObj {&lt;br /&gt;
public:&lt;br /&gt;
    NameObj(const char *pName);&lt;br /&gt;
&lt;br /&gt;
    virtual ~NameObj();&lt;br /&gt;
    virtual void init(const JMapInfoIter &amp;amp;rIter);&lt;br /&gt;
    virtual void initAfterPlacement();&lt;br /&gt;
    virtual void movement();&lt;br /&gt;
    virtual void draw() const;&lt;br /&gt;
    virtual void calcAnim();&lt;br /&gt;
    virtual void calcViewAndEntry();&lt;br /&gt;
&lt;br /&gt;
    /* remember that the vtable will be placed here once we define our virtuals! */&lt;br /&gt;
    /* 0x4 */   const char* mName;&lt;br /&gt;
    /* 0x8 */   volatile u16 mFlags;&lt;br /&gt;
    /* 0xA */   s16 mExecutorIdx;&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Once the vtable is complete, you want to document all of the member functions that are in the class. Since &#039;&#039;Super Mario Galaxy 1&#039;&#039; has a symbol map, we can easily find the member functions that &#039;&#039;NameObj&#039;&#039; contains. Once you have figured out their return types and their arguments, you can finish mapping out a class! After finding all of &#039;&#039;NameObj&#039;&#039;&#039;s member functions, the class looks like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class NameObj {&lt;br /&gt;
public:&lt;br /&gt;
    NameObj(const char *pName);&lt;br /&gt;
&lt;br /&gt;
    virtual ~NameObj();&lt;br /&gt;
    virtual void init(const JMapInfoIter &amp;amp;rIter);&lt;br /&gt;
    virtual void initAfterPlacement();&lt;br /&gt;
    virtual void movement();&lt;br /&gt;
    virtual void draw() const;&lt;br /&gt;
    virtual void calcAnim();&lt;br /&gt;
    virtual void calcViewAndEntry();&lt;br /&gt;
&lt;br /&gt;
    void initWithoutIter();&lt;br /&gt;
    void setName(const char *pName);&lt;br /&gt;
    void executeMovement();&lt;br /&gt;
    void requestSuspend();&lt;br /&gt;
    void requestResume();&lt;br /&gt;
    void syncWithFlags();&lt;br /&gt;
&lt;br /&gt;
    /* remember that the vtable will be placed here once we define our virtuals! */&lt;br /&gt;
    /* 0x4 */   const char* mName;&lt;br /&gt;
    /* 0x8 */   volatile u16 mFlags;&lt;br /&gt;
    /* 0xA */   s16 mExecutorIdx;&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Inheriting Class ===&lt;br /&gt;
The process of mapping a class that inherits another class is mainly the same as mapping a base class, except there are things to watch out for so you don&#039;t accidentally duplicate a member variable. The first step is to look at the &#039;&#039;constructor&#039;&#039; of the class you want to map:&lt;br /&gt;
&lt;br /&gt;
[[Image:TripodBossCoin_Ctor.png|frameless|700px|The constructor for &#039;&#039;TripodBossCoin&#039;&#039;.]]&lt;br /&gt;
&lt;br /&gt;
There are a few takeaways from this by looking at the constructor:&lt;br /&gt;
* The class inherits NameObj. Since &#039;&#039;NameObj&#039;&#039; is 0xC bytes long, we know that any member variables for &#039;&#039;TripodBossCoin&#039;&#039; start at &#039;&#039;&#039;0xC&#039;&#039;&#039;.&lt;br /&gt;
* The vtable pointer &#039;&#039;&#039;(this + 0x0)&#039;&#039;&#039; from &#039;&#039;NameObj&#039;&#039; is overridden with the vtable for &#039;&#039;TripodBossCoin&#039;&#039; implicitly.&lt;br /&gt;
* &#039;&#039;&#039;(this + 0xC)&#039;&#039;&#039; is a 32-bit integer initialized to 0. It is not possible to determine if it is signed or not from this store alone.&lt;br /&gt;
* &#039;&#039;&#039;(this + 0x10)&#039;&#039;&#039; is the same scenario as &#039;&#039;&#039;(this + 0xC)&#039;&#039;&#039;.&lt;br /&gt;
* There is a direct instance of &#039;&#039;JGeometry::TMatrix34&amp;lt;JGeometry::SMatrix34C&amp;lt;f32&amp;gt;&#039;&#039; at 0x14. (in Petari &amp;amp; Syati this is typedef&#039;d as &#039;&#039;TMtx34f&#039;&#039;). Since &#039;&#039;TMtx34f&#039;&#039; is 0x30 in size, the next member variable is at 0x14 + 0x30, which is &#039;&#039;&#039;0x44&#039;&#039;&#039;.&lt;br /&gt;
* &#039;&#039;&#039;(this + 0x44)&#039;&#039;&#039; is a signed 32-bit integer, due to &#039;&#039;&#039;-1&#039;&#039;&#039; being stored to it.&lt;br /&gt;
&lt;br /&gt;
After these observations, our class looks like this:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class TripodBossCoin : public NameObj {&lt;br /&gt;
public:&lt;br /&gt;
	TripodBossCoin(const char *);&lt;br /&gt;
	&lt;br /&gt;
	u32 _C;&lt;br /&gt;
	u32 _10;&lt;br /&gt;
	TMtx34f _14;&lt;br /&gt;
	s32 _44;&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Next are the virtuals. The process is a little different from a base class. Let&#039;s take a look at the vtable for &#039;&#039;TripodBossCoin&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
[[Image:TripodBossCoin_Vtable.png|frameless|700px|The vtable for &#039;&#039;TripodBossCoin&#039;&#039;.]]&lt;br /&gt;
&lt;br /&gt;
The biggest takeaway from this screenshot is that only three virtuals are overriden by &#039;&#039;TripodBossCoin&#039;&#039;. And those three functions are &#039;&#039;&#039;TripodBossCoin::~TripodBossCoin()&#039;&#039;&#039;, &#039;&#039;&#039;TripodBossCoin::init()&#039;&#039;&#039; and &#039;&#039;&#039;TripodBossCoin::movement()&#039;&#039;&#039;. So we define them as such:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class TripodBossCoin : public NameObj {&lt;br /&gt;
public:&lt;br /&gt;
	TripodBossCoin(const char *);&lt;br /&gt;
&lt;br /&gt;
    virtual ~TripodBossCoin();&lt;br /&gt;
    virtual void init(const JMapInfoIter &amp;amp;);&lt;br /&gt;
    virtual void movement();&lt;br /&gt;
	&lt;br /&gt;
	u32 _C;&lt;br /&gt;
	u32 _10;&lt;br /&gt;
	TMtx34f _14;&lt;br /&gt;
	s32 _44;&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
It is worth noting that the &#039;&#039;&#039;override&#039;&#039;&#039; keyword was not a part of the C++ standard at this point in time, so all overrides are implicit. After all of this is done, you simply have to repeat the process for base classes and document the member functions that are a part of the class.&lt;br /&gt;
&lt;br /&gt;
=== Loops ===&lt;br /&gt;
==== Predefined bounds ====&lt;br /&gt;
Let&#039;s take a simple loop that stores &amp;lt;i&amp;gt;nullptr&amp;lt;/i&amp;gt; in each 8 elements of a pointer array.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class TestClass {&lt;br /&gt;
public:&lt;br /&gt;
    TestClass();&lt;br /&gt;
&lt;br /&gt;
     int* mPointers[8];&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
TestClass::TestClass() {&lt;br /&gt;
    for (int i = 0; i &amp;lt; 8; i++) {&lt;br /&gt;
        mPointers[i] = nullptr;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The output assembly would look something like:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
li r0, 8 # there are 8 elements in this loop&lt;br /&gt;
li r5, 0 # the value to store in the element (nullptr)&lt;br /&gt;
li r4, 0 # the current element offset in the loop&lt;br /&gt;
mtctr r0 # move the number of iterations into the counter register (8)&lt;br /&gt;
&lt;br /&gt;
loop:&lt;br /&gt;
    stwx r5, r3, r4 # store 0 (r5) into the array at r3 (this) + r4 (our current offset, which is i * 4)&lt;br /&gt;
    addi r4, r4, 4 # increment our offset by sizeof(int) since integers are 32-bits&lt;br /&gt;
    bdnz+ loop # branch back to our loop again&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Variable Length Bounds ====&lt;br /&gt;
Let&#039;s take a simple loop that stores &amp;lt;i&amp;gt;nullptr&amp;lt;/i&amp;gt; in each element of a variable-length array. We will have a class with two members, one that contains the pointer array itself, and another that stores the number of pointers.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class TestClass {&lt;br /&gt;
public:&lt;br /&gt;
    TestClass();&lt;br /&gt;
&lt;br /&gt;
     int** mPointers;&lt;br /&gt;
     int mNumPointers;&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
TestClass::TestClass() {&lt;br /&gt;
    mNumPointers = 8;&lt;br /&gt;
    for (int i = 0; i &amp;lt; mNumPointers ; i++) {&lt;br /&gt;
        mPointers[i] = nullptr;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Because we do not know how many pointers we have stored, we cannot use the counter register like we did with a fixed-size array. Instead, the compiler will use a cmpw (signed integer) or cmplw (unsigned) instruction to compare the current iteration to how many pointers are stored in the class.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
li r0, 8 # there are 8 elements in this loop&lt;br /&gt;
li r7, 0 # the value to store in the element (nullptr)&lt;br /&gt;
stw r0, 4(r3) # r3 + 4 is the offset to our member variable &amp;quot;mNumPointers&amp;quot;&lt;br /&gt;
mr r6, r7 # simple copy of the 0 value so we can also use it for our counter&lt;br /&gt;
li r4, 0 # load 0 into our offset&lt;br /&gt;
b loop # branch into our loop&lt;br /&gt;
&lt;br /&gt;
loop:&lt;br /&gt;
    lwz r5, 0(r3) # load our pointer array from this + 0&lt;br /&gt;
    addi r7, r7, 1 # increment our index by 1&lt;br /&gt;
    stwx r6, r5, r4 # store our nullptr value (r6) into r5 + r4 (ptrArray + currentOffset)&lt;br /&gt;
    addi r4, r4, 4 # increment our offset by sizeof(int) since integers are 32-bits&lt;br /&gt;
    lwz r0, 4(r3) # load our number of pointers we will increment by (mNumPointers)&lt;br /&gt;
    cmpw r7, r0 # compare our number of pointers to the current index in our loop&lt;br /&gt;
    blt+ loop # branch if the number is less than mNumPointers&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Structure Access In Arrays (Pointer Array) ====&lt;br /&gt;
More complex forms of loops comes into play when you are iterating through structures and storing / loading members from those structures. Let&#039;s take this class for example:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
struct TestStruct {&lt;br /&gt;
    int SomeMember;&lt;br /&gt;
    int AnotherMember;&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
class TestClass {&lt;br /&gt;
public:&lt;br /&gt;
    TestClass();&lt;br /&gt;
&lt;br /&gt;
    void storeVals();&lt;br /&gt;
&lt;br /&gt;
     TestStruct** mStructures;&lt;br /&gt;
     int mNumStructures;&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
For the sake of simplicity, let&#039;s assume that the TestClass constructor initializes the number of structures to 8, and constructs them accordingly. With that in mind, let&#039;s see how a struct store will work.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void TestClass::storeVals() {&lt;br /&gt;
    for (int i = 0; i &amp;lt; mNumStructures; i++) {&lt;br /&gt;
        mStructures[i]-&amp;gt;AnotherMember = 5;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
The output assembly would look something like:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
li r7, 0 # our &amp;quot;i&amp;quot; used in the loop, starts at 0&lt;br /&gt;
li r4, 0 # our current offset into the array&lt;br /&gt;
li r6, 5 # the value we are storing into the array&lt;br /&gt;
b loop&lt;br /&gt;
&lt;br /&gt;
loop:&lt;br /&gt;
    lwz r5, 0(r3) # load the array pointer&lt;br /&gt;
    addi r7, r7, 1 # increment our current index (i) by 1&lt;br /&gt;
    lwzx r5, r5, r4 # load the current structure, mStructures[i] where r4 is the current offset&lt;br /&gt;
    addi r4, r4, 4 # increment our offset by sizeof(TestStruct*), which is 4&lt;br /&gt;
    stw r6, 4(r5) # store our value (5) into (mStructures[i] + 4), which is our AnotherMember&lt;br /&gt;
    lwz r0, 4(r3) # load the number of structures from TestClass&lt;br /&gt;
    cmpw r7, r0 # compare the current index to our value in TestClass&lt;br /&gt;
    blt+ loop # loop back if it is less than the value&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Structure Access In Arrays (Direct Array) ====&lt;br /&gt;
Let&#039;s take the previous example and modify it a little. Instead of making an array of pointers to the struct instances, let&#039;s store the array &amp;lt;i&amp;gt;directly&amp;lt;/i&amp;gt; into our class instance.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
struct TestStruct {&lt;br /&gt;
    int SomeMember;&lt;br /&gt;
    int AnotherMember;&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
class TestClass {&lt;br /&gt;
public:&lt;br /&gt;
    TestClass();&lt;br /&gt;
&lt;br /&gt;
    void storeVals();&lt;br /&gt;
&lt;br /&gt;
     TestStruct mStructures[8];&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Again, let us assume that the array has already been constructed and everything is initialized as it should be.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void TestClass::storeVals() {&lt;br /&gt;
    for (int i = 0; i &amp;lt; 8; i++) {&lt;br /&gt;
        mStructures[i].AnotherMember = 5;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
The output assembly would look something like:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
li r0, 8 # load our number of iterations (8)&lt;br /&gt;
li r4, 0 # current offset into the array. initialized at 0&lt;br /&gt;
li r6, 5 # the value to store into the array&lt;br /&gt;
mtctr r0 # move the number of iterations into the counter register&lt;br /&gt;
&lt;br /&gt;
loop:&lt;br /&gt;
    add r5, r3, r4 # jump to the offset into the array. r5 = (this + 0) + r4&lt;br /&gt;
    addi r4, r4, 8 # increment our current offset by sizeof(TestStruct), which is 8&lt;br /&gt;
    stw r6, 4(r5) # store our constant value (5) into the loaded struct + 4 (AnotherMember)&lt;br /&gt;
    bdnz+ loop # branch back to the loop if the counter is not 8&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Actor Decompiling ==&lt;br /&gt;
An &#039;&#039;actor&#039;&#039; is how the game refers to something that is present in a &#039;&#039;scene&#039;&#039; (ie a Goomba or a Coin). The approach to decompiling an actor is rather repetitive, but can change based on the actor itself. However, most of them follow a straightforward structure. They contain a constructor that takes in a &#039;&#039;&#039;const char *&#039;&#039;&#039; pointer (which is the name of the actor) and passes that to the parent class, which can range from &#039;&#039;LiveActor&#039;&#039; to &#039;&#039;MapObjActor&#039;&#039;. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Operator Overloads ==&lt;br /&gt;
There are specific ways that CodeWarrior mangles symbols when overloading operators for classes.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Operator !! Mangled Symbol&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;+&amp;quot; || &amp;quot;pl&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;-&amp;quot; || &amp;quot;mi&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;*&amp;quot; || &amp;quot;ml&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;/&amp;quot; || &amp;quot;dv&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;%&amp;quot; || &amp;quot;md&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;^&amp;quot; || &amp;quot;er&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;/=&amp;quot; || &amp;quot;adv&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;&amp;amp;&amp;quot; || &amp;quot;ad&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;&amp;amp;verbar;&amp;quot; || &amp;quot;or&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;~&amp;quot; || &amp;quot;co&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;!&amp;quot; || &amp;quot;nt&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;=&amp;quot; || &amp;quot;as&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;&amp;lt;&amp;quot; || &amp;quot;lt&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;&amp;gt;&amp;quot; || &amp;quot;gt&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;+=&amp;quot; || &amp;quot;apl&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;-=&amp;quot; || &amp;quot;ami&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;*=&amp;quot; || &amp;quot;amu&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;%=&amp;quot; || &amp;quot;amd&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;^=&amp;quot; || &amp;quot;aer&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;&amp;amp;=&amp;quot; || &amp;quot;aad&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;&amp;amp;verbar;=&amp;quot; || &amp;quot;aor&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;&amp;lt;&amp;lt;&amp;quot; || &amp;quot;ls&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;&amp;gt;&amp;gt;&amp;quot; || &amp;quot;rs&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;&amp;gt;&amp;gt;=&amp;quot; || &amp;quot;ars&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;&amp;lt;&amp;lt;=&amp;quot; || &amp;quot;als&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;==&amp;quot; || &amp;quot;eq&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;!=&amp;quot; || &amp;quot;ne&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;&amp;lt;=&amp;quot; || &amp;quot;le&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;&amp;gt;=&amp;quot; || &amp;quot;ge&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;&amp;amp;&amp;amp;&amp;quot; || &amp;quot;aa&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;&amp;amp;verbar;&amp;amp;verbar;&amp;quot; || &amp;quot;oo&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;++&amp;quot; || &amp;quot;pp&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;--&amp;quot; || &amp;quot;mm&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;()&amp;quot; || &amp;quot;cl&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;[]&amp;quot; || &amp;quot;vc&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;-&amp;gt;&amp;quot; || &amp;quot;rf&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;,&amp;quot; || &amp;quot;cm&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;-&amp;gt;*&amp;quot; || &amp;quot;rm&amp;quot;&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Shibboleet</name></author>
	</entry>
	<entry>
		<id>https://www.lumasworkshop.com/w/index.php?title=Decompiling&amp;diff=874</id>
		<title>Decompiling</title>
		<link rel="alternate" type="text/html" href="https://www.lumasworkshop.com/w/index.php?title=Decompiling&amp;diff=874"/>
		<updated>2025-05-20T17:56:44Z</updated>

		<summary type="html">&lt;p&gt;Shibboleet: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Guides]]&lt;br /&gt;
[[Category:Decompiling]]&lt;br /&gt;
{{WIP}}&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
&#039;&#039;Decompiling&#039;&#039; is the process of taking assembly code and turning it back into a higher level language such as C or C++. It is essentially the reverse of &#039;&#039;compiling&#039;&#039;. &#039;&#039;Matching decompilation&#039;&#039; is the process of decompiling, but having the compiled code match the original assembly 1:1. While matching decompilation is harder than normal decompiling, it can become easier when you understand the patterns of the compiler used. This page aims to let new people understand how this process works, and hopefully be able to get new people into decompilation! While you do not need to be an expert at C or C++ to decompile, it is recommended that you have some experience before attempting decompilation. It is also very recommended that you have some prior knowledge of PowerPC assembly, as that is the key to understanding how a function works. [https://www.nxp.com/docs/en/reference-manual/MPC82XINSET.pdf This document] is a good way to learn or refresh knowledge of the PowerPC architecture. [https://www.warthman.com/images/IBM_PPC_Compiler_Writer%27s_Guide-cwg.pdf This document] is also good to learn some of the patterns that CodeWarrior does.&lt;br /&gt;
&lt;br /&gt;
== Getting Set Up ==&lt;br /&gt;
To begin decompiling &#039;&#039;Super Mario Galaxy&#039;&#039;, you first need to set up the environment. You will need the following tools:&lt;br /&gt;
* [https://gitforwindows.org/ Git (Windows)]&lt;br /&gt;
* Any IDE ([https://code.visualstudio.com/ Visual Studio Code Recommended])&lt;br /&gt;
* [https://www.python.org/downloads/release/python-397/ Python 3.9.7]&lt;br /&gt;
* IDA Pro (recommended) or Ghidra (Not recommended)&lt;br /&gt;
* [https://shibbo.net/smg/RMGK01_01.idb SMG1 Korean IDB (For IDA)]&lt;br /&gt;
* A &#039;&#039;Super Mario Galaxy&#039;&#039; Korean region DOL.&lt;br /&gt;
* [https://github.com/ninja-build/ninja/releases Ninja]&lt;br /&gt;
&lt;br /&gt;
After you have acquired all of these, setting up [https://github.com/shibbo/Petari Petari] is very simple.&lt;br /&gt;
&lt;br /&gt;
# With a new command prompt open, type in &#039;&#039;&#039;git clone https://github.com/shibbo/Petari&#039;&#039;&#039;. This will clone the repository into a directory called &amp;quot;Petari&amp;quot;.&lt;br /&gt;
# In this new &amp;quot;Petari&amp;quot; folder, place the SMG1 Korean &#039;&#039;&#039;main.dol&#039;&#039;&#039; into &#039;&#039;&#039;orig/RMGK01/main.dol&#039;&#039;&#039;.&lt;br /&gt;
# Open a new command prompt in the &amp;quot;Petari&amp;quot; folder.&lt;br /&gt;
# Run the command &#039;&#039;&#039;&#039;ninja&#039;&#039;&#039;. This will download the decompilation toolkit (dtk) and &amp;quot;split&amp;quot; the binary, then compile the code.&lt;br /&gt;
&lt;br /&gt;
== Environment ==&lt;br /&gt;
To properly utilize and use &#039;&#039;Petari&#039;&#039;, it is necessary to understand the structure of the environment. Petari is structured in a way that makes it easy to access and use.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Folder Name !! Description&lt;br /&gt;
|-&lt;br /&gt;
| assets || Just assets for the README.&lt;br /&gt;
|-&lt;br /&gt;
| build || The folder that gets created when &#039;&#039;&#039;ninja&#039;&#039;&#039; is ran. Contains the compiled object files and the compilers.&lt;br /&gt;
|-&lt;br /&gt;
| config || Contains the configurations for each SMG1 version for decompilation and splitting.&lt;br /&gt;
|-&lt;br /&gt;
| docs || Documents relating to using &#039;&#039;&#039;dtk&#039;&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
| include || Contains all of the header files for &#039;&#039;Super Mario Galaxy&#039;&#039; specific code.&lt;br /&gt;
|-&lt;br /&gt;
| md || Documentation for completed functions.&lt;br /&gt;
|-&lt;br /&gt;
| orig || Contains the DOLs for each game version for splitting and matching.&lt;br /&gt;
|-&lt;br /&gt;
| src || Contains all of the source files for &#039;&#039;&#039;Super Mario Galaxy&#039;&#039;&#039; and its libraries.&lt;br /&gt;
|-&lt;br /&gt;
| tools || Misc tools that dtk uses.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Libraries ==&lt;br /&gt;
&#039;&#039;Super Mario Galaxy&#039;&#039; uses a lot of libraries for certain functionality such as heaps, layouts, OS specific code, and more. Each library described in the table below are &#039;&#039;&#039;statically linked&#039;&#039;&#039; to the game, so every library&#039;s used code is inside of the &#039;&#039;main.dol&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
=== Non-SMG Libraries ===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Name !! Language !! Description&lt;br /&gt;
|-&lt;br /&gt;
| JSystem || C++ || Contains classes for backend things, such as heaps and linked lists.&lt;br /&gt;
|-&lt;br /&gt;
| MetroTRK || C || Target Resident Kernel, for debugging.&lt;br /&gt;
|-&lt;br /&gt;
| MSL_C || C &amp;amp; C++ || Contains standard library functions and types.&lt;br /&gt;
|-&lt;br /&gt;
| nw4r || C++ || Contains classes for sounds, layouts, and more. (SMG only uses the layouts and some math functions)&lt;br /&gt;
|-&lt;br /&gt;
| Runtime || C &amp;amp; C++ || Contains functions that relate to CodeWarrior&#039;s runtime code generation (ctor / dtor lists, etc)&lt;br /&gt;
|-&lt;br /&gt;
| RVL_SDK || C || Contains functions that relate to the Wii&#039;s &amp;quot;OS&amp;quot;.&lt;br /&gt;
|-&lt;br /&gt;
| RVLFaceLib || C || Contains functions that relate to Miis.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== SMG Libraries ===&lt;br /&gt;
All of &#039;&#039;Super Mario Galaxy&#039;&#039;&#039;s libraries are written in C++.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Header text !! Header text&lt;br /&gt;
|-&lt;br /&gt;
| Animation || Library for animation playing.&lt;br /&gt;
|-&lt;br /&gt;
| AreaObj || Library for invisible areas that can be accessed by players in the game.&lt;br /&gt;
|-&lt;br /&gt;
| AudioLib || N/A&lt;br /&gt;
|-&lt;br /&gt;
| Boss || Library for all of the bosses and mini-bosses in the game.&lt;br /&gt;
|-&lt;br /&gt;
| Camera || Library for all camera types.&lt;br /&gt;
|-&lt;br /&gt;
| Demo || Library for all cutscenes.&lt;br /&gt;
|-&lt;br /&gt;
| Effect || Library for all effect rendering.&lt;br /&gt;
|-&lt;br /&gt;
| Enemy || Library for all enemies.&lt;br /&gt;
|-&lt;br /&gt;
| GameAudio || N/A&lt;br /&gt;
|-&lt;br /&gt;
| Gravity || Library for all of the gravity types in the game.&lt;br /&gt;
|-&lt;br /&gt;
| LiveActor || Library for LiveActor, which is an actor that can switch states.&lt;br /&gt;
|-&lt;br /&gt;
| Map || Library for map classes that do not directly interact with the player. (ie switches)&lt;br /&gt;
|-&lt;br /&gt;
| MapObj || Library for all of the map objects in the game.&lt;br /&gt;
|-&lt;br /&gt;
| NameObj || Library for the most basic form of an object in the game.&lt;br /&gt;
|-&lt;br /&gt;
| NPC || Library for all of the non-playable characters.&lt;br /&gt;
|-&lt;br /&gt;
| NWC24 || Library for the mail system in the game.&lt;br /&gt;
|-&lt;br /&gt;
| Player || Library for all of the player related functions.&lt;br /&gt;
|-&lt;br /&gt;
| RhythmLib || N/A&lt;br /&gt;
|-&lt;br /&gt;
| Ride || Library for all of the actors that can be controlled by the player.&lt;br /&gt;
|-&lt;br /&gt;
| Scene || Library for all of the game scene related code.&lt;br /&gt;
|-&lt;br /&gt;
| Screen || Library for all of the layouts in the game.&lt;br /&gt;
|-&lt;br /&gt;
| Speaker || Library for the sound effect playing done on the Wiimote.&lt;br /&gt;
|-&lt;br /&gt;
| System || Library for a lot of the game&#039;s backend systems.&lt;br /&gt;
|-&lt;br /&gt;
| Util || Library for utility functions and classes.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Basics ==&lt;br /&gt;
To properly decompile, it is vital to know how a lot of the assembly will translate into C / C++ code. Here are a couple of patterns that you will see when decompiling code.&lt;br /&gt;
&lt;br /&gt;
== Splitting ==&lt;br /&gt;
&#039;&#039;Splitting&#039;&#039; refers to &amp;quot;splitting&amp;quot; up each object file with its respective segments to properly build a matching object. This can be code / data, or just data.&lt;br /&gt;
&lt;br /&gt;
A simple split looks like this:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Game/NameObj/NameObj.cpp:&lt;br /&gt;
	.text       start:0x802616B4 end:0x802618B4&lt;br /&gt;
	.data       start:0x805A7758 end:0x805A7780&lt;br /&gt;
	.sbss       start:0x806B5BE0 end:0x806B5BE8&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Each segment needs a &#039;&#039;&#039;start&#039;&#039;&#039; and an &#039;&#039;&#039;end&#039;&#039;&#039; address, and the &#039;&#039;&#039;end&#039;&#039;&#039; address always needs to be larger than the &#039;&#039;&#039;start&#039;&#039;&#039; address. You can use IDA (or Ghidra) to see what segment a specific set of code / data belongs to. For this specific split:&lt;br /&gt;
* &#039;&#039;&#039;.text&#039;&#039;&#039; begins at &#039;&#039;&#039;0x802616B4&#039;&#039;&#039; and ends at &#039;&#039;&#039;0x802618B4&#039;&#039;&#039;.&lt;br /&gt;
* &#039;&#039;&#039;.data&#039;&#039;&#039; begins at &#039;&#039;&#039;0x805A7758&#039;&#039;&#039; and ends at &#039;&#039;&#039;0x805A7780&#039;&#039;&#039;.&lt;br /&gt;
* &#039;&#039;&#039;.sbss&#039;&#039;&#039; begins at &#039;&#039;&#039;0x806B5BE0&#039;&#039;&#039; and ends at &#039;&#039;&#039;0x806B5BE8&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
You can change these splits by changing &#039;&#039;&#039;config/RMGKXX/splits.txt&#039;&#039;&#039; where &#039;&#039;&#039;XX&#039;&#039;&#039; is the version of the Korean version you are using. It is worth noting that any data addresses (ie .data, .bss, .sdata) need to be rounded to the nearest 8th byte, as they are 8-byte aligned.&lt;br /&gt;
&lt;br /&gt;
== Class Mapping ==&lt;br /&gt;
=== Base Class ===&lt;br /&gt;
The first step to decompiling a class is to map out the class itself. You need to be sure that you document every member, its type (as close as you can guess), its virtual functions, and more. The easiest way to achieve this is to look at the class&#039;s &#039;&#039;constructor&#039;&#039;. Seen below, is an example of a &#039;&#039;constructor&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
[[Image:NameObj_Ctor.png|frameless|700px|The constructor for &#039;&#039;NameObj&#039;&#039;.]]&lt;br /&gt;
&lt;br /&gt;
There are a couple of takeaways from this screenshot:&lt;br /&gt;
* The constructor passes an argument, which is a &#039;&#039;&#039;const char *&#039;&#039;&#039; (contained in r4) and is stored in (r3 + 0x4).&lt;br /&gt;
* (r3 + 0x0) is where the vtable is &#039;&#039;usually&#039;&#039; stored when a class has virtual functions. There are rare execptions.&lt;br /&gt;
* (r3 + 0x8) is stored with a &#039;&#039;&#039;sth&#039;&#039;&#039;, which means that it is a &#039;&#039;&#039;short&#039;&#039;&#039; datatype.&lt;br /&gt;
* (r3 + 0xA) is also stored with a &#039;&#039;&#039;sth&#039;&#039;&#039;, but with a &#039;&#039;&#039;-1&#039;&#039;&#039; value, so we know for sure that this type is &#039;&#039;signed&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Keep in mind that a constructor does not have to initialize every single member variable in the class! So there could be other members in a class that aren&#039;t mentioned in the constructor at all. After you look at the constructor, look around at the &#039;&#039;member functions&#039;&#039; to see if they use any members that are not initialized in the constructor. You can always verify if your class setup is correct when you can find where this class is created using the &#039;&#039;&#039;new&#039;&#039;&#039; operator. Check if the size passed to the &#039;&#039;&#039;new&#039;&#039;&#039; call matches the size of the class that you have mapped. If it is smaller, you are missing members. If it is bigger, you have too many! Remember that the vtable is implicitly stored at &#039;&#039;&#039;(this + 0x0)&#039;&#039;&#039;, so you do not have to explicitly define it. With all of these members documented, our class setup looks a little like this so far:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class NameObj {&lt;br /&gt;
public:&lt;br /&gt;
    NameObj(const char *pName);&lt;br /&gt;
&lt;br /&gt;
    /* remember that the vtable will be placed here once we define our virtuals! */&lt;br /&gt;
    /* 0x4 */   const char* mName;&lt;br /&gt;
    /* 0x8 */   volatile u16 mFlags;&lt;br /&gt;
    /* 0xA */   s16 mExecutorIdx;&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
After the members comes the &#039;&#039;&#039;vtable&#039;&#039;&#039;, or &#039;&#039;virtual table&#039;&#039;. It is an array of function pointers that can be overridden by classes that inherit the parent class. The vtable for &#039;&#039;&#039;NameObj&#039;&#039;&#039; looks like this:&lt;br /&gt;
[[Image:NameObj_Vtable.png|frameless|700px|The vtable for &#039;&#039;NameObj&#039;&#039;.]]&lt;br /&gt;
&lt;br /&gt;
To document the vtable, you simply document every single function placed here that contains the class name of the class you are currently decompiling. Since &#039;&#039;NameObj&#039;&#039; is a base class, every single function here is going to be defined. If a class overrides a function, you will only document the functions that are overridden. After documenting the vtable, our class looks something like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class NameObj {&lt;br /&gt;
public:&lt;br /&gt;
    NameObj(const char *pName);&lt;br /&gt;
&lt;br /&gt;
    virtual ~NameObj();&lt;br /&gt;
    virtual void init(const JMapInfoIter &amp;amp;rIter);&lt;br /&gt;
    virtual void initAfterPlacement();&lt;br /&gt;
    virtual void movement();&lt;br /&gt;
    virtual void draw() const;&lt;br /&gt;
    virtual void calcAnim();&lt;br /&gt;
    virtual void calcViewAndEntry();&lt;br /&gt;
&lt;br /&gt;
    /* remember that the vtable will be placed here once we define our virtuals! */&lt;br /&gt;
    /* 0x4 */   const char* mName;&lt;br /&gt;
    /* 0x8 */   volatile u16 mFlags;&lt;br /&gt;
    /* 0xA */   s16 mExecutorIdx;&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Once the vtable is complete, you want to document all of the member functions that are in the class. Since &#039;&#039;Super Mario Galaxy 1&#039;&#039; has a symbol map, we can easily find the member functions that &#039;&#039;NameObj&#039;&#039; contains. Once you have figured out their return types and their arguments, you can finish mapping out a class! After finding all of &#039;&#039;NameObj&#039;&#039;&#039;s member functions, the class looks like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class NameObj {&lt;br /&gt;
public:&lt;br /&gt;
    NameObj(const char *pName);&lt;br /&gt;
&lt;br /&gt;
    virtual ~NameObj();&lt;br /&gt;
    virtual void init(const JMapInfoIter &amp;amp;rIter);&lt;br /&gt;
    virtual void initAfterPlacement();&lt;br /&gt;
    virtual void movement();&lt;br /&gt;
    virtual void draw() const;&lt;br /&gt;
    virtual void calcAnim();&lt;br /&gt;
    virtual void calcViewAndEntry();&lt;br /&gt;
&lt;br /&gt;
    void initWithoutIter();&lt;br /&gt;
    void setName(const char *pName);&lt;br /&gt;
    void executeMovement();&lt;br /&gt;
    void requestSuspend();&lt;br /&gt;
    void requestResume();&lt;br /&gt;
    void syncWithFlags();&lt;br /&gt;
&lt;br /&gt;
    /* remember that the vtable will be placed here once we define our virtuals! */&lt;br /&gt;
    /* 0x4 */   const char* mName;&lt;br /&gt;
    /* 0x8 */   volatile u16 mFlags;&lt;br /&gt;
    /* 0xA */   s16 mExecutorIdx;&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Inheriting Class ===&lt;br /&gt;
The process of mapping a class that inherits another class is mainly the same as mapping a base class, except there are things to watch out for so you don&#039;t accidentally duplicate a member variable. The first step is to look at the &#039;&#039;constructor&#039;&#039; of the class you want to map:&lt;br /&gt;
&lt;br /&gt;
[[Image:TripodBossCoin_Ctor.png|frameless|700px|The constructor for &#039;&#039;TripodBossCoin&#039;&#039;.]]&lt;br /&gt;
&lt;br /&gt;
There are a few takeaways from this by looking at the constructor:&lt;br /&gt;
* The class inherits NameObj. Since &#039;&#039;NameObj&#039;&#039; is 0xC bytes long, we know that any member variables for &#039;&#039;TripodBossCoin&#039;&#039; start at &#039;&#039;&#039;0xC&#039;&#039;&#039;.&lt;br /&gt;
* The vtable pointer &#039;&#039;&#039;(this + 0x0)&#039;&#039;&#039; from &#039;&#039;NameObj&#039;&#039; is overridden with the vtable for &#039;&#039;TripodBossCoin&#039;&#039; implicitly.&lt;br /&gt;
* &#039;&#039;&#039;(this + 0xC)&#039;&#039;&#039; is a 32-bit integer initialized to 0. It is not possible to determine if it is signed or not from this store alone.&lt;br /&gt;
* &#039;&#039;&#039;(this + 0x10)&#039;&#039;&#039; is the same scenario as &#039;&#039;&#039;(this + 0xC)&#039;&#039;&#039;.&lt;br /&gt;
* There is a direct instance of &#039;&#039;JGeometry::TMatrix34&amp;lt;JGeometry::SMatrix34C&amp;lt;f32&amp;gt;&#039;&#039; at 0x14. (in Petari &amp;amp; Syati this is typedef&#039;d as &#039;&#039;TMtx34f&#039;&#039;). Since &#039;&#039;TMtx34f&#039;&#039; is 0x30 in size, the next member variable is at 0x14 + 0x30, which is &#039;&#039;&#039;0x44&#039;&#039;&#039;.&lt;br /&gt;
* &#039;&#039;&#039;(this + 0x44)&#039;&#039;&#039; is a signed 32-bit integer, due to &#039;&#039;&#039;-1&#039;&#039;&#039; being stored to it.&lt;br /&gt;
&lt;br /&gt;
After these observations, our class looks like this:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class TripodBossCoin : public NameObj {&lt;br /&gt;
public:&lt;br /&gt;
	TripodBossCoin(const char *);&lt;br /&gt;
	&lt;br /&gt;
	u32 _C;&lt;br /&gt;
	u32 _10;&lt;br /&gt;
	TMtx34f _14;&lt;br /&gt;
	s32 _44;&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Next are the virtuals. The process is a little different from a base class. Let&#039;s take a look at the vtable for &#039;&#039;TripodBossCoin&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
[[Image:TripodBossCoin_Vtable.png|frameless|700px|The vtable for &#039;&#039;TripodBossCoin&#039;&#039;.]]&lt;br /&gt;
&lt;br /&gt;
The biggest takeaway from this screenshot is that only three virtuals are overriden by &#039;&#039;TripodBossCoin&#039;&#039;. And those three functions are &#039;&#039;&#039;TripodBossCoin::~TripodBossCoin()&#039;&#039;&#039;, &#039;&#039;&#039;TripodBossCoin::init()&#039;&#039;&#039; and &#039;&#039;&#039;TripodBossCoin::movement()&#039;&#039;&#039;. So we define them as such:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class TripodBossCoin : public NameObj {&lt;br /&gt;
public:&lt;br /&gt;
	TripodBossCoin(const char *);&lt;br /&gt;
&lt;br /&gt;
    virtual ~TripodBossCoin();&lt;br /&gt;
    virtual void init(const JMapInfoIter &amp;amp;);&lt;br /&gt;
    virtual void movement();&lt;br /&gt;
	&lt;br /&gt;
	u32 _C;&lt;br /&gt;
	u32 _10;&lt;br /&gt;
	TMtx34f _14;&lt;br /&gt;
	s32 _44;&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
It is worth noting that the &#039;&#039;&#039;override&#039;&#039;&#039; keyword was not a part of the C++ standard at this point in time, so all overrides are implicit. After all of this is done, you simply have to repeat the process for base classes and document the member functions that are a part of the class.&lt;br /&gt;
&lt;br /&gt;
=== Loops ===&lt;br /&gt;
==== Predefined bounds ====&lt;br /&gt;
Let&#039;s take a simple loop that stores &amp;lt;i&amp;gt;nullptr&amp;lt;/i&amp;gt; in each 8 elements of a pointer array.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class TestClass {&lt;br /&gt;
public:&lt;br /&gt;
    TestClass();&lt;br /&gt;
&lt;br /&gt;
     int* mPointers[8];&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
TestClass::TestClass() {&lt;br /&gt;
    for (int i = 0; i &amp;lt; 8; i++) {&lt;br /&gt;
        mPointers[i] = nullptr;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The output assembly would look something like:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
li r0, 8 # there are 8 elements in this loop&lt;br /&gt;
li r5, 0 # the value to store in the element (nullptr)&lt;br /&gt;
li r4, 0 # the current element offset in the loop&lt;br /&gt;
mtctr r0 # move the number of iterations into the counter register (8)&lt;br /&gt;
&lt;br /&gt;
loop:&lt;br /&gt;
    stwx r5, r3, r4 # store 0 (r5) into the array at r3 (this) + r4 (our current offset, which is i * 4)&lt;br /&gt;
    addi r4, r4, 4 # increment our offset by sizeof(int) since integers are 32-bits&lt;br /&gt;
    bdnz+ loop # branch back to our loop again&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Variable Length Bounds ====&lt;br /&gt;
Let&#039;s take a simple loop that stores &amp;lt;i&amp;gt;nullptr&amp;lt;/i&amp;gt; in each element of a variable-length array. We will have a class with two members, one that contains the pointer array itself, and another that stores the number of pointers.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class TestClass {&lt;br /&gt;
public:&lt;br /&gt;
    TestClass();&lt;br /&gt;
&lt;br /&gt;
     int** mPointers;&lt;br /&gt;
     int mNumPointers;&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
TestClass::TestClass() {&lt;br /&gt;
    mNumPointers = 8;&lt;br /&gt;
    for (int i = 0; i &amp;lt; mNumPointers ; i++) {&lt;br /&gt;
        mPointers[i] = nullptr;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Because we do not know how many pointers we have stored, we cannot use the counter register like we did with a fixed-size array. Instead, the compiler will use a cmpw (signed integer) or cmplw (unsigned) instruction to compare the current iteration to how many pointers are stored in the class.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
li r0, 8 # there are 8 elements in this loop&lt;br /&gt;
li r7, 0 # the value to store in the element (nullptr)&lt;br /&gt;
stw r0, 4(r3) # r3 + 4 is the offset to our member variable &amp;quot;mNumPointers&amp;quot;&lt;br /&gt;
mr r6, r7 # simple copy of the 0 value so we can also use it for our counter&lt;br /&gt;
li r4, 0 # load 0 into our offset&lt;br /&gt;
b loop # branch into our loop&lt;br /&gt;
&lt;br /&gt;
loop:&lt;br /&gt;
    lwz r5, 0(r3) # load our pointer array from this + 0&lt;br /&gt;
    addi r7, r7, 1 # increment our index by 1&lt;br /&gt;
    stwx r6, r5, r4 # store our nullptr value (r6) into r5 + r4 (ptrArray + currentOffset)&lt;br /&gt;
    addi r4, r4, 4 # increment our offset by sizeof(int) since integers are 32-bits&lt;br /&gt;
    lwz r0, 4(r3) # load our number of pointers we will increment by (mNumPointers)&lt;br /&gt;
    cmpw r7, r0 # compare our number of pointers to the current index in our loop&lt;br /&gt;
    blt+ loop # branch if the number is less than mNumPointers&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Structure Access In Arrays (Pointer Array) ====&lt;br /&gt;
More complex forms of loops comes into play when you are iterating through structures and storing / loading members from those structures. Let&#039;s take this class for example:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
struct TestStruct {&lt;br /&gt;
    int SomeMember;&lt;br /&gt;
    int AnotherMember;&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
class TestClass {&lt;br /&gt;
public:&lt;br /&gt;
    TestClass();&lt;br /&gt;
&lt;br /&gt;
    void storeVals();&lt;br /&gt;
&lt;br /&gt;
     TestStruct** mStructures;&lt;br /&gt;
     int mNumStructures;&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
For the sake of simplicity, let&#039;s assume that the TestClass constructor initializes the number of structures to 8, and constructs them accordingly. With that in mind, let&#039;s see how a struct store will work.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void TestClass::storeVals() {&lt;br /&gt;
    for (int i = 0; i &amp;lt; mNumStructures; i++) {&lt;br /&gt;
        mStructures[i]-&amp;gt;AnotherMember = 5;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
The output assembly would look something like:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
li r7, 0 # our &amp;quot;i&amp;quot; used in the loop, starts at 0&lt;br /&gt;
li r4, 0 # our current offset into the array&lt;br /&gt;
li r6, 5 # the value we are storing into the array&lt;br /&gt;
b loop&lt;br /&gt;
&lt;br /&gt;
loop:&lt;br /&gt;
    lwz r5, 0(r3) # load the array pointer&lt;br /&gt;
    addi r7, r7, 1 # increment our current index (i) by 1&lt;br /&gt;
    lwzx r5, r5, r4 # load the current structure, mStructures[i] where r4 is the current offset&lt;br /&gt;
    addi r4, r4, 4 # increment our offset by sizeof(TestStruct*), which is 4&lt;br /&gt;
    stw r6, 4(r5) # store our value (5) into (mStructures[i] + 4), which is our AnotherMember&lt;br /&gt;
    lwz r0, 4(r3) # load the number of structures from TestClass&lt;br /&gt;
    cmpw r7, r0 # compare the current index to our value in TestClass&lt;br /&gt;
    blt+ loop # loop back if it is less than the value&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Structure Access In Arrays (Direct Array) ====&lt;br /&gt;
Let&#039;s take the previous example and modify it a little. Instead of making an array of pointers to the struct instances, let&#039;s store the array &amp;lt;i&amp;gt;directly&amp;lt;/i&amp;gt; into our class instance.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
struct TestStruct {&lt;br /&gt;
    int SomeMember;&lt;br /&gt;
    int AnotherMember;&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
class TestClass {&lt;br /&gt;
public:&lt;br /&gt;
    TestClass();&lt;br /&gt;
&lt;br /&gt;
    void storeVals();&lt;br /&gt;
&lt;br /&gt;
     TestStruct mStructures[8];&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Again, let us assume that the array has already been constructed and everything is initialized as it should be.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void TestClass::storeVals() {&lt;br /&gt;
    for (int i = 0; i &amp;lt; 8; i++) {&lt;br /&gt;
        mStructures[i].AnotherMember = 5;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
The output assembly would look something like:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
li r0, 8 # load our number of iterations (8)&lt;br /&gt;
li r4, 0 # current offset into the array. initialized at 0&lt;br /&gt;
li r6, 5 # the value to store into the array&lt;br /&gt;
mtctr r0 # move the number of iterations into the counter register&lt;br /&gt;
&lt;br /&gt;
loop:&lt;br /&gt;
    add r5, r3, r4 # jump to the offset into the array. r5 = (this + 0) + r4&lt;br /&gt;
    addi r4, r4, 8 # increment our current offset by sizeof(TestStruct), which is 8&lt;br /&gt;
    stw r6, 4(r5) # store our constant value (5) into the loaded struct + 4 (AnotherMember)&lt;br /&gt;
    bdnz+ loop # branch back to the loop if the counter is not 8&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Actor Decompiling ==&lt;br /&gt;
An &#039;&#039;actor&#039;&#039; is how the game refers to something that is present in a &#039;&#039;scene&#039;&#039; (ie a Goomba or a Coin). The approach to decompiling an actor is rather repetitive, but can change based on the actor itself. However, most of them follow a straightforward structure. They contain a constructor that takes in a &#039;&#039;&#039;const char *&#039;&#039;&#039; pointer (which is the name of the actor) and passes that to the parent class, which can range from &#039;&#039;LiveActor&#039;&#039; to &#039;&#039;MapObjActor&#039;&#039;. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Operator Overloads ==&lt;br /&gt;
There are specific ways that CodeWarrior mangles symbols when overloading operators for classes.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Operator !! Mangled Symbol&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;+&amp;quot; || &amp;quot;pl&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;-&amp;quot; || &amp;quot;mi&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;*&amp;quot; || &amp;quot;ml&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;/&amp;quot; || &amp;quot;dv&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;%&amp;quot; || &amp;quot;md&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;^&amp;quot; || &amp;quot;er&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;/=&amp;quot; || &amp;quot;adv&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;&amp;amp;&amp;quot; || &amp;quot;ad&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;&amp;amp;verbar;&amp;quot; || &amp;quot;or&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;~&amp;quot; || &amp;quot;co&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;!&amp;quot; || &amp;quot;nt&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;=&amp;quot; || &amp;quot;as&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;&amp;lt;&amp;quot; || &amp;quot;lt&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;&amp;gt;&amp;quot; || &amp;quot;gt&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;+=&amp;quot; || &amp;quot;apl&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;-=&amp;quot; || &amp;quot;ami&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;*=&amp;quot; || &amp;quot;amu&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;%=&amp;quot; || &amp;quot;amd&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;^=&amp;quot; || &amp;quot;aer&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;&amp;amp;=&amp;quot; || &amp;quot;aad&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;&amp;amp;verbar;=&amp;quot; || &amp;quot;aor&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;&amp;lt;&amp;lt;&amp;quot; || &amp;quot;ls&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;&amp;gt;&amp;gt;&amp;quot; || &amp;quot;rs&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;&amp;gt;&amp;gt;=&amp;quot; || &amp;quot;ars&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;&amp;lt;&amp;lt;=&amp;quot; || &amp;quot;als&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;==&amp;quot; || &amp;quot;eq&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;!=&amp;quot; || &amp;quot;ne&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;&amp;lt;=&amp;quot; || &amp;quot;le&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;&amp;gt;=&amp;quot; || &amp;quot;ge&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;&amp;amp;&amp;amp;&amp;quot; || &amp;quot;aa&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;&amp;amp;verbar;&amp;amp;verbar;&amp;quot; || &amp;quot;oo&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;++&amp;quot; || &amp;quot;pp&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;--&amp;quot; || &amp;quot;mm&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;()&amp;quot; || &amp;quot;cl&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;[]&amp;quot; || &amp;quot;vc&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;-&amp;gt;&amp;quot; || &amp;quot;rf&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;,&amp;quot; || &amp;quot;cm&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;-&amp;gt;*&amp;quot; || &amp;quot;rm&amp;quot;&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Shibboleet</name></author>
	</entry>
	<entry>
		<id>https://www.lumasworkshop.com/w/index.php?title=Decompiling&amp;diff=866</id>
		<title>Decompiling</title>
		<link rel="alternate" type="text/html" href="https://www.lumasworkshop.com/w/index.php?title=Decompiling&amp;diff=866"/>
		<updated>2025-05-06T17:19:26Z</updated>

		<summary type="html">&lt;p&gt;Shibboleet: /* Splitting */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Guides]]&lt;br /&gt;
[[Category:Decompiling]]&lt;br /&gt;
{{WIP}}&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
&#039;&#039;Decompiling&#039;&#039; is the process of taking assembly code and turning it back into a higher level language such as C or C++. It is essentially the reverse of &#039;&#039;compiling&#039;&#039;. &#039;&#039;Matching decompilation&#039;&#039; is the process of decompiling, but having the compiled code match the original assembly 1:1. While matching decompilation is harder than normal decompiling, it can become easier when you understand the patterns of the compiler used. This page aims to let new people understand how this process works, and hopefully be able to get new people into decompilation! While you do not need to be an expert at C or C++ to decompile, it is recommended that you have some experience before attempting decompilation. It is also very recommended that you have some prior knowledge of PowerPC assembly, as that is the key to understanding how a function works. [https://www.nxp.com/docs/en/reference-manual/MPC82XINSET.pdf This document] is a good way to learn or refresh knowledge of the PowerPC architecture. [https://www.warthman.com/images/IBM_PPC_Compiler_Writer%27s_Guide-cwg.pdf This document] is also good to learn some of the patterns that CodeWarrior does.&lt;br /&gt;
&lt;br /&gt;
== Getting Set Up ==&lt;br /&gt;
To begin decompiling &#039;&#039;Super Mario Galaxy&#039;&#039;, you first need to set up the environment. You will need the following tools:&lt;br /&gt;
* [https://gitforwindows.org/ Git (Windows)]&lt;br /&gt;
* Any IDE ([https://code.visualstudio.com/ Visual Studio Code Recommended])&lt;br /&gt;
* [https://www.python.org/downloads/release/python-397/ Python 3.9.7]&lt;br /&gt;
* IDA Pro (recommended) or Ghidra (Not recommended)&lt;br /&gt;
* [https://shibbo.net/smg/RMGK01_01.idb SMG1 Korean IDB (For IDA)]&lt;br /&gt;
* A &#039;&#039;Super Mario Galaxy&#039;&#039; Korean region DOL.&lt;br /&gt;
* [https://github.com/ninja-build/ninja/releases Ninja]&lt;br /&gt;
&lt;br /&gt;
After you have acquired all of these, setting up [https://github.com/shibbo/Petari Petari] is very simple.&lt;br /&gt;
&lt;br /&gt;
# With a new command prompt open, type in &#039;&#039;&#039;git clone https://github.com/shibbo/Petari&#039;&#039;&#039;. This will clone the repository into a directory called &amp;quot;Petari&amp;quot;.&lt;br /&gt;
# In this new &amp;quot;Petari&amp;quot; folder, place the SMG1 Korean &#039;&#039;&#039;main.dol&#039;&#039;&#039; into &#039;&#039;&#039;orig/RMGK01/main.dol&#039;&#039;&#039;.&lt;br /&gt;
# Open a new command prompt in the &amp;quot;Petari&amp;quot; folder.&lt;br /&gt;
# Run the command &#039;&#039;&#039;&#039;ninja&#039;&#039;&#039;. This will download the decompilation toolkit (dtk) and &amp;quot;split&amp;quot; the binary, then compile the code.&lt;br /&gt;
&lt;br /&gt;
== Environment ==&lt;br /&gt;
To properly utilize and use &#039;&#039;Petari&#039;&#039;, it is necessary to understand the structure of the environment. Petari is structured in a way that makes it easy to access and use.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Folder Name !! Description&lt;br /&gt;
|-&lt;br /&gt;
| assets || Just assets for the README.&lt;br /&gt;
|-&lt;br /&gt;
| build || The folder that gets created when &#039;&#039;&#039;ninja&#039;&#039;&#039; is ran. Contains the compiled object files and the compilers.&lt;br /&gt;
|-&lt;br /&gt;
| config || Contains the configurations for each SMG1 version for decompilation and splitting.&lt;br /&gt;
|-&lt;br /&gt;
| docs || Documents relating to using &#039;&#039;&#039;dtk&#039;&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
| include || Contains all of the header files for &#039;&#039;Super Mario Galaxy&#039;&#039; specific code.&lt;br /&gt;
|-&lt;br /&gt;
| md || Documentation for completed functions.&lt;br /&gt;
|-&lt;br /&gt;
| orig || Contains the DOLs for each game version for splitting and matching.&lt;br /&gt;
|-&lt;br /&gt;
| src || Contains all of the source files for &#039;&#039;&#039;Super Mario Galaxy&#039;&#039;&#039; and its libraries.&lt;br /&gt;
|-&lt;br /&gt;
| tools || Misc tools that dtk uses.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Libraries ==&lt;br /&gt;
&#039;&#039;Super Mario Galaxy&#039;&#039; uses a lot of libraries for certain functionality such as heaps, layouts, OS specific code, and more. Each library described in the table below are &#039;&#039;&#039;statically linked&#039;&#039;&#039; to the game, so every library&#039;s used code is inside of the &#039;&#039;main.dol&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
=== Non-SMG Libraries ===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Name !! Language !! Description&lt;br /&gt;
|-&lt;br /&gt;
| JSystem || C++ || Contains classes for backend things, such as heaps and linked lists.&lt;br /&gt;
|-&lt;br /&gt;
| MetroTRK || C || Target Resident Kernel, for debugging.&lt;br /&gt;
|-&lt;br /&gt;
| MSL_C || C &amp;amp; C++ || Contains standard library functions and types.&lt;br /&gt;
|-&lt;br /&gt;
| nw4r || C++ || Contains classes for sounds, layouts, and more. (SMG only uses the layouts and some math functions)&lt;br /&gt;
|-&lt;br /&gt;
| Runtime || C &amp;amp; C++ || Contains functions that relate to CodeWarrior&#039;s runtime code generation (ctor / dtor lists, etc)&lt;br /&gt;
|-&lt;br /&gt;
| RVL_SDK || C || Contains functions that relate to the Wii&#039;s &amp;quot;OS&amp;quot;.&lt;br /&gt;
|-&lt;br /&gt;
| RVLFaceLib || C || Contains functions that relate to Miis.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== SMG Libraries ===&lt;br /&gt;
All of &#039;&#039;Super Mario Galaxy&#039;&#039;&#039;s libraries are written in C++.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Header text !! Header text&lt;br /&gt;
|-&lt;br /&gt;
| Animation || Library for animation playing.&lt;br /&gt;
|-&lt;br /&gt;
| AreaObj || Library for invisible areas that can be accessed by players in the game.&lt;br /&gt;
|-&lt;br /&gt;
| AudioLib || N/A&lt;br /&gt;
|-&lt;br /&gt;
| Boss || Library for all of the bosses and mini-bosses in the game.&lt;br /&gt;
|-&lt;br /&gt;
| Camera || Library for all camera types.&lt;br /&gt;
|-&lt;br /&gt;
| Demo || Library for all cutscenes.&lt;br /&gt;
|-&lt;br /&gt;
| Effect || Library for all effect rendering.&lt;br /&gt;
|-&lt;br /&gt;
| Enemy || Library for all enemies.&lt;br /&gt;
|-&lt;br /&gt;
| GameAudio || N/A&lt;br /&gt;
|-&lt;br /&gt;
| Gravity || Library for all of the gravity types in the game.&lt;br /&gt;
|-&lt;br /&gt;
| LiveActor || Library for LiveActor, which is an actor that can switch states.&lt;br /&gt;
|-&lt;br /&gt;
| Map || Library for map classes that do not directly interact with the player. (ie switches)&lt;br /&gt;
|-&lt;br /&gt;
| MapObj || Library for all of the map objects in the game.&lt;br /&gt;
|-&lt;br /&gt;
| NameObj || Library for the most basic form of an object in the game.&lt;br /&gt;
|-&lt;br /&gt;
| NPC || Library for all of the non-playable characters.&lt;br /&gt;
|-&lt;br /&gt;
| NWC24 || Library for the mail system in the game.&lt;br /&gt;
|-&lt;br /&gt;
| Player || Library for all of the player related functions.&lt;br /&gt;
|-&lt;br /&gt;
| RhythmLib || N/A&lt;br /&gt;
|-&lt;br /&gt;
| Ride || Library for all of the actors that can be controlled by the player.&lt;br /&gt;
|-&lt;br /&gt;
| Scene || Library for all of the game scene related code.&lt;br /&gt;
|-&lt;br /&gt;
| Screen || Library for all of the layouts in the game.&lt;br /&gt;
|-&lt;br /&gt;
| Speaker || Library for the sound effect playing done on the Wiimote.&lt;br /&gt;
|-&lt;br /&gt;
| System || Library for a lot of the game&#039;s backend systems.&lt;br /&gt;
|-&lt;br /&gt;
| Util || Library for utility functions and classes.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Basics ==&lt;br /&gt;
To properly decompile, it is vital to know how a lot of the assembly will translate into C / C++ code. Here are a couple of patterns that you will see when decompiling code.&lt;br /&gt;
&lt;br /&gt;
== Splitting ==&lt;br /&gt;
&#039;&#039;Splitting&#039;&#039; refers to &amp;quot;splitting&amp;quot; up each object file with its respective segments to properly build a matching object. This can be code / data, or just data.&lt;br /&gt;
&lt;br /&gt;
A simple split looks like this:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Game/NameObj/NameObj.cpp:&lt;br /&gt;
	.text       start:0x802616B4 end:0x802618B4&lt;br /&gt;
	.data       start:0x805A7758 end:0x805A7780&lt;br /&gt;
	.sbss       start:0x806B5BE0 end:0x806B5BE8&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Each segment needs a &#039;&#039;&#039;start&#039;&#039;&#039; and an &#039;&#039;&#039;end&#039;&#039;&#039; address, and the &#039;&#039;&#039;end&#039;&#039;&#039; address always needs to be larger than the &#039;&#039;&#039;start&#039;&#039;&#039; address. You can use IDA (or Ghidra) to see what segment a specific set of code / data belongs to. For this specific split:&lt;br /&gt;
* &#039;&#039;&#039;.text&#039;&#039;&#039; begins at &#039;&#039;&#039;0x802616B4&#039;&#039;&#039; and ends at &#039;&#039;&#039;0x802618B4&#039;&#039;&#039;.&lt;br /&gt;
* &#039;&#039;&#039;.data&#039;&#039;&#039; begins at &#039;&#039;&#039;0x805A7758&#039;&#039;&#039; and ends at &#039;&#039;&#039;0x805A7780&#039;&#039;&#039;.&lt;br /&gt;
* &#039;&#039;&#039;.sbss&#039;&#039;&#039; begins at &#039;&#039;&#039;0x806B5BE0&#039;&#039;&#039; and ends at &#039;&#039;&#039;0x806B5BE8&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
You can change these splits by changing &#039;&#039;&#039;config/RMGKXX/splits.txt&#039;&#039;&#039; where &#039;&#039;&#039;XX&#039;&#039;&#039; is the version of the Korean version you are using. It is worth noting that any data addresses (ie .data, .bss, .sdata) need to be rounded to the nearest 8th byte, as they are 8-byte aligned.&lt;br /&gt;
&lt;br /&gt;
== Class Mapping ==&lt;br /&gt;
=== Base Class ===&lt;br /&gt;
The first step to decompiling a class is to map out the class itself. You need to be sure that you document every member, its type (as close as you can guess), its virtual functions, and more. The easiest way to achieve this is to look at the class&#039;s &#039;&#039;constructor&#039;&#039;. Seen below, is an example of a &#039;&#039;constructor&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
[[Image:NameObj_Ctor.png|frameless|700px|The constructor for &#039;&#039;NameObj&#039;&#039;.]]&lt;br /&gt;
&lt;br /&gt;
There are a couple of takeaways from this screenshot:&lt;br /&gt;
* The constructor passes an argument, which is a &#039;&#039;&#039;const char *&#039;&#039;&#039; (contained in r4) and is stored in (r3 + 0x4).&lt;br /&gt;
* (r3 + 0x0) is where the vtable is &#039;&#039;usually&#039;&#039; stored when a class has virtual functions. There are rare execptions.&lt;br /&gt;
* (r3 + 0x8) is stored with a &#039;&#039;&#039;sth&#039;&#039;&#039;, which means that it is a &#039;&#039;&#039;short&#039;&#039;&#039; datatype.&lt;br /&gt;
* (r3 + 0xA) is also stored with a &#039;&#039;&#039;sth&#039;&#039;&#039;, but with a &#039;&#039;&#039;-1&#039;&#039;&#039; value, so we know for sure that this type is &#039;&#039;signed&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Keep in mind that a constructor does not have to initialize every single member variable in the class! So there could be other members in a class that aren&#039;t mentioned in the constructor at all. After you look at the constructor, look around at the &#039;&#039;member functions&#039;&#039; to see if they use any members that are not initialized in the constructor. You can always verify if your class setup is correct when you can find where this class is created using the &#039;&#039;&#039;new&#039;&#039;&#039; operator. Check if the size passed to the &#039;&#039;&#039;new&#039;&#039;&#039; call matches the size of the class that you have mapped. If it is smaller, you are missing members. If it is bigger, you have too many! Remember that the vtable is implicitly stored at &#039;&#039;&#039;(this + 0x0)&#039;&#039;&#039;, so you do not have to explicitly define it. With all of these members documented, our class setup looks a little like this so far:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class NameObj {&lt;br /&gt;
public:&lt;br /&gt;
    NameObj(const char *pName);&lt;br /&gt;
&lt;br /&gt;
    /* remember that the vtable will be placed here once we define our virtuals! */&lt;br /&gt;
    /* 0x4 */   const char* mName;&lt;br /&gt;
    /* 0x8 */   volatile u16 mFlags;&lt;br /&gt;
    /* 0xA */   s16 mExecutorIdx;&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
After the members comes the &#039;&#039;&#039;vtable&#039;&#039;&#039;, or &#039;&#039;virtual table&#039;&#039;. It is an array of function pointers that can be overridden by classes that inherit the parent class. The vtable for &#039;&#039;&#039;NameObj&#039;&#039;&#039; looks like this:&lt;br /&gt;
[[Image:NameObj_Vtable.png|frameless|700px|The vtable for &#039;&#039;NameObj&#039;&#039;.]]&lt;br /&gt;
&lt;br /&gt;
To document the vtable, you simply document every single function placed here that contains the class name of the class you are currently decompiling. Since &#039;&#039;NameObj&#039;&#039; is a base class, every single function here is going to be defined. If a class overrides a function, you will only document the functions that are overridden. After documenting the vtable, our class looks something like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class NameObj {&lt;br /&gt;
public:&lt;br /&gt;
    NameObj(const char *pName);&lt;br /&gt;
&lt;br /&gt;
    virtual ~NameObj();&lt;br /&gt;
    virtual void init(const JMapInfoIter &amp;amp;rIter);&lt;br /&gt;
    virtual void initAfterPlacement();&lt;br /&gt;
    virtual void movement();&lt;br /&gt;
    virtual void draw() const;&lt;br /&gt;
    virtual void calcAnim();&lt;br /&gt;
    virtual void calcViewAndEntry();&lt;br /&gt;
&lt;br /&gt;
    /* remember that the vtable will be placed here once we define our virtuals! */&lt;br /&gt;
    /* 0x4 */   const char* mName;&lt;br /&gt;
    /* 0x8 */   volatile u16 mFlags;&lt;br /&gt;
    /* 0xA */   s16 mExecutorIdx;&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Once the vtable is complete, you want to document all of the member functions that are in the class. Since &#039;&#039;Super Mario Galaxy 1&#039;&#039; has a symbol map, we can easily find the member functions that &#039;&#039;NameObj&#039;&#039; contains. Once you have figured out their return types and their arguments, you can finish mapping out a class! After finding all of &#039;&#039;NameObj&#039;&#039;&#039;s member functions, the class looks like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class NameObj {&lt;br /&gt;
public:&lt;br /&gt;
    NameObj(const char *pName);&lt;br /&gt;
&lt;br /&gt;
    virtual ~NameObj();&lt;br /&gt;
    virtual void init(const JMapInfoIter &amp;amp;rIter);&lt;br /&gt;
    virtual void initAfterPlacement();&lt;br /&gt;
    virtual void movement();&lt;br /&gt;
    virtual void draw() const;&lt;br /&gt;
    virtual void calcAnim();&lt;br /&gt;
    virtual void calcViewAndEntry();&lt;br /&gt;
&lt;br /&gt;
    void initWithoutIter();&lt;br /&gt;
    void setName(const char *pName);&lt;br /&gt;
    void executeMovement();&lt;br /&gt;
    void requestSuspend();&lt;br /&gt;
    void requestResume();&lt;br /&gt;
    void syncWithFlags();&lt;br /&gt;
&lt;br /&gt;
    /* remember that the vtable will be placed here once we define our virtuals! */&lt;br /&gt;
    /* 0x4 */   const char* mName;&lt;br /&gt;
    /* 0x8 */   volatile u16 mFlags;&lt;br /&gt;
    /* 0xA */   s16 mExecutorIdx;&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Inheriting Class ===&lt;br /&gt;
The process of mapping a class that inherits another class is mainly the same as mapping a base class, except there are things to watch out for so you don&#039;t accidentally duplicate a member variable. The first step is to look at the &#039;&#039;constructor&#039;&#039; of the class you want to map:&lt;br /&gt;
&lt;br /&gt;
[[Image:TripodBossCoin_Ctor.png|frameless|700px|The constructor for &#039;&#039;TripodBossCoin&#039;&#039;.]]&lt;br /&gt;
&lt;br /&gt;
There are a few takeaways from this by looking at the constructor:&lt;br /&gt;
* The class inherits NameObj. Since &#039;&#039;NameObj&#039;&#039; is 0xC bytes long, we know that any member variables for &#039;&#039;TripodBossCoin&#039;&#039; start at &#039;&#039;&#039;0xC&#039;&#039;&#039;.&lt;br /&gt;
* The vtable pointer &#039;&#039;&#039;(this + 0x0)&#039;&#039;&#039; from &#039;&#039;NameObj&#039;&#039; is overridden with the vtable for &#039;&#039;TripodBossCoin&#039;&#039; implicitly.&lt;br /&gt;
* &#039;&#039;&#039;(this + 0xC)&#039;&#039;&#039; is a 32-bit integer initialized to 0. It is not possible to determine if it is signed or not from this store alone.&lt;br /&gt;
* &#039;&#039;&#039;(this + 0x10)&#039;&#039;&#039; is the same scenario as &#039;&#039;&#039;(this + 0xC)&#039;&#039;&#039;.&lt;br /&gt;
* There is a direct instance of &#039;&#039;JGeometry::TMatrix34&amp;lt;JGeometry::SMatrix34C&amp;lt;f32&amp;gt;&#039;&#039; at 0x14. (in Petari &amp;amp; Syati this is typedef&#039;d as &#039;&#039;TMtx34f&#039;&#039;). Since &#039;&#039;TMtx34f&#039;&#039; is 0x30 in size, the next member variable is at 0x14 + 0x30, which is &#039;&#039;&#039;0x44&#039;&#039;&#039;.&lt;br /&gt;
* &#039;&#039;&#039;(this + 0x44)&#039;&#039;&#039; is a signed 32-bit integer, due to &#039;&#039;&#039;-1&#039;&#039;&#039; being stored to it.&lt;br /&gt;
&lt;br /&gt;
After these observations, our class looks like this:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class TripodBossCoin : public NameObj {&lt;br /&gt;
public:&lt;br /&gt;
	TripodBossCoin(const char *);&lt;br /&gt;
	&lt;br /&gt;
	u32 _C;&lt;br /&gt;
	u32 _10;&lt;br /&gt;
	TMtx34f _14;&lt;br /&gt;
	s32 _44;&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Next are the virtuals. The process is a little different from a base class. Let&#039;s take a look at the vtable for &#039;&#039;TripodBossCoin&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
[[Image:TripodBossCoin_Vtable.png|frameless|700px|The vtable for &#039;&#039;TripodBossCoin&#039;&#039;.]]&lt;br /&gt;
&lt;br /&gt;
The biggest takeaway from this screenshot is that only three virtuals are overriden by &#039;&#039;TripodBossCoin&#039;&#039;. And those three functions are &#039;&#039;&#039;TripodBossCoin::~TripodBossCoin()&#039;&#039;&#039;, &#039;&#039;&#039;TripodBossCoin::init()&#039;&#039;&#039; and &#039;&#039;&#039;TripodBossCoin::movement()&#039;&#039;&#039;. So we define them as such:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class TripodBossCoin : public NameObj {&lt;br /&gt;
public:&lt;br /&gt;
	TripodBossCoin(const char *);&lt;br /&gt;
&lt;br /&gt;
    virtual ~TripodBossCoin();&lt;br /&gt;
    virtual void init(const JMapInfoIter &amp;amp;);&lt;br /&gt;
    virtual void movement();&lt;br /&gt;
	&lt;br /&gt;
	u32 _C;&lt;br /&gt;
	u32 _10;&lt;br /&gt;
	TMtx34f _14;&lt;br /&gt;
	s32 _44;&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
It is worth noting that the &#039;&#039;&#039;override&#039;&#039;&#039; keyword was not a part of the C++ standard at this point in time, so all overrides are implicit. After all of this is done, you simply have to repeat the process for base classes and document the member functions that are a part of the class.&lt;br /&gt;
&lt;br /&gt;
=== Loops ===&lt;br /&gt;
==== Predefined bounds ====&lt;br /&gt;
Let&#039;s take a simple loop that stores &amp;lt;i&amp;gt;nullptr&amp;lt;/i&amp;gt; in each 8 elements of a pointer array.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class TestClass {&lt;br /&gt;
public:&lt;br /&gt;
    TestClass();&lt;br /&gt;
&lt;br /&gt;
     int* mPointers[8];&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
TestClass::TestClass() {&lt;br /&gt;
    for (int i = 0; i &amp;lt; 8; i++) {&lt;br /&gt;
        mPointers[i] = nullptr;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The output assembly would look something like:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
li r0, 8 # there are 8 elements in this loop&lt;br /&gt;
li r5, 0 # the value to store in the element (nullptr)&lt;br /&gt;
li r4, 0 # the current element offset in the loop&lt;br /&gt;
mtctr r0 # move the number of iterations into the counter register (8)&lt;br /&gt;
&lt;br /&gt;
loop:&lt;br /&gt;
    stwx r5, r3, r4 # store 0 (r5) into the array at r3 (this) + r4 (our current offset, which is i * 4)&lt;br /&gt;
    addi r4, r4, 4 # increment our offset by sizeof(int) since integers are 32-bits&lt;br /&gt;
    bdnz+ loop # branch back to our loop again&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Variable Length Bounds ====&lt;br /&gt;
Let&#039;s take a simple loop that stores &amp;lt;i&amp;gt;nullptr&amp;lt;/i&amp;gt; in each element of a variable-length array. We will have a class with two members, one that contains the pointer array itself, and another that stores the number of pointers.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class TestClass {&lt;br /&gt;
public:&lt;br /&gt;
    TestClass();&lt;br /&gt;
&lt;br /&gt;
     int** mPointers;&lt;br /&gt;
     int mNumPointers;&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
TestClass::TestClass() {&lt;br /&gt;
    mNumPointers = 8;&lt;br /&gt;
    for (int i = 0; i &amp;lt; mNumPointers ; i++) {&lt;br /&gt;
        mPointers[i] = nullptr;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Because we do not know how many pointers we have stored, we cannot use the counter register like we did with a fixed-size array. Instead, the compiler will use a cmpw (signed integer) or cmplw (unsigned) instruction to compare the current iteration to how many pointers are stored in the class.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
li r0, 8 # there are 8 elements in this loop&lt;br /&gt;
li r7, 0 # the value to store in the element (nullptr)&lt;br /&gt;
stw r0, 4(r3) # r3 + 4 is the offset to our member variable &amp;quot;mNumPointers&amp;quot;&lt;br /&gt;
mr r6, r7 # simple copy of the 0 value so we can also use it for our counter&lt;br /&gt;
li r4, 0 # load 0 into our offset&lt;br /&gt;
b loop # branch into our loop&lt;br /&gt;
&lt;br /&gt;
loop:&lt;br /&gt;
    lwz r5, 0(r3) # load our pointer array from this + 0&lt;br /&gt;
    addi r7, r7, 1 # increment our index by 1&lt;br /&gt;
    stwx r6, r5, r4 # store our nullptr value (r6) into r5 + r4 (ptrArray + currentOffset)&lt;br /&gt;
    addi r4, r4, 4 # increment our offset by sizeof(int) since integers are 32-bits&lt;br /&gt;
    lwz r0, 4(r3) # load our number of pointers we will increment by (mNumPointers)&lt;br /&gt;
    cmpw r7, r0 # compare our number of pointers to the current index in our loop&lt;br /&gt;
    blt+ loop # branch if the number is less than mNumPointers&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Structure Access In Arrays (Pointer Array) ====&lt;br /&gt;
More complex forms of loops comes into play when you are iterating through structures and storing / loading members from those structures. Let&#039;s take this class for example:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
struct TestStruct {&lt;br /&gt;
    int SomeMember;&lt;br /&gt;
    int AnotherMember;&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
class TestClass {&lt;br /&gt;
public:&lt;br /&gt;
    TestClass();&lt;br /&gt;
&lt;br /&gt;
    void storeVals();&lt;br /&gt;
&lt;br /&gt;
     TestStruct** mStructures;&lt;br /&gt;
     int mNumStructures;&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
For the sake of simplicity, let&#039;s assume that the TestClass constructor initializes the number of structures to 8, and constructs them accordingly. With that in mind, let&#039;s see how a struct store will work.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void TestClass::storeVals() {&lt;br /&gt;
    for (int i = 0; i &amp;lt; mNumStructures; i++) {&lt;br /&gt;
        mStructures[i]-&amp;gt;AnotherMember = 5;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
The output assembly would look something like:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
li r7, 0 # our &amp;quot;i&amp;quot; used in the loop, starts at 0&lt;br /&gt;
li r4, 0 # our current offset into the array&lt;br /&gt;
li r6, 5 # the value we are storing into the array&lt;br /&gt;
b loop&lt;br /&gt;
&lt;br /&gt;
loop:&lt;br /&gt;
    lwz r5, 0(r3) # load the array pointer&lt;br /&gt;
    addi r7, r7, 1 # increment our current index (i) by 1&lt;br /&gt;
    lwzx r5, r5, r4 # load the current structure, mStructures[i] where r4 is the current offset&lt;br /&gt;
    addi r4, r4, 4 # increment our offset by sizeof(TestStruct*), which is 4&lt;br /&gt;
    stw r6, 4(r5) # store our value (5) into (mStructures[i] + 4), which is our AnotherMember&lt;br /&gt;
    lwz r0, 4(r3) # load the number of structures from TestClass&lt;br /&gt;
    cmpw r7, r0 # compare the current index to our value in TestClass&lt;br /&gt;
    blt+ loop # loop back if it is less than the value&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Structure Access In Arrays (Direct Array) ====&lt;br /&gt;
Let&#039;s take the previous example and modify it a little. Instead of making an array of pointers to the struct instances, let&#039;s store the array &amp;lt;i&amp;gt;directly&amp;lt;/i&amp;gt; into our class instance.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
struct TestStruct {&lt;br /&gt;
    int SomeMember;&lt;br /&gt;
    int AnotherMember;&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
class TestClass {&lt;br /&gt;
public:&lt;br /&gt;
    TestClass();&lt;br /&gt;
&lt;br /&gt;
    void storeVals();&lt;br /&gt;
&lt;br /&gt;
     TestStruct mStructures[8];&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Again, let us assume that the array has already been constructed and everything is initialized as it should be.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void TestClass::storeVals() {&lt;br /&gt;
    for (int i = 0; i &amp;lt; 8; i++) {&lt;br /&gt;
        mStructures[i].AnotherMember = 5;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
The output assembly would look something like:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
li r0, 8 # load our number of iterations (8)&lt;br /&gt;
li r4, 0 # current offset into the array. initialized at 0&lt;br /&gt;
li r6, 5 # the value to store into the array&lt;br /&gt;
mtctr r0 # move the number of iterations into the counter register&lt;br /&gt;
&lt;br /&gt;
loop:&lt;br /&gt;
    add r5, r3, r4 # jump to the offset into the array. r5 = (this + 0) + r4&lt;br /&gt;
    addi r4, r4, 8 # increment our current offset by sizeof(TestStruct), which is 8&lt;br /&gt;
    stw r6, 4(r5) # store our constant value (5) into the loaded struct + 4 (AnotherMember)&lt;br /&gt;
    bdnz+ loop # branch back to the loop if the counter is not 8&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Operator Overloads ==&lt;br /&gt;
There are specific ways that CodeWarrior mangles symbols when overloading operators for classes.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Operator !! Mangled Symbol&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;+&amp;quot; || &amp;quot;pl&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;-&amp;quot; || &amp;quot;mi&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;*&amp;quot; || &amp;quot;ml&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;/&amp;quot; || &amp;quot;dv&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;%&amp;quot; || &amp;quot;md&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;^&amp;quot; || &amp;quot;er&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;/=&amp;quot; || &amp;quot;adv&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;&amp;amp;&amp;quot; || &amp;quot;ad&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;&amp;amp;verbar;&amp;quot; || &amp;quot;or&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;~&amp;quot; || &amp;quot;co&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;!&amp;quot; || &amp;quot;nt&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;=&amp;quot; || &amp;quot;as&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;&amp;lt;&amp;quot; || &amp;quot;lt&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;&amp;gt;&amp;quot; || &amp;quot;gt&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;+=&amp;quot; || &amp;quot;apl&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;-=&amp;quot; || &amp;quot;ami&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;*=&amp;quot; || &amp;quot;amu&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;%=&amp;quot; || &amp;quot;amd&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;^=&amp;quot; || &amp;quot;aer&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;&amp;amp;=&amp;quot; || &amp;quot;aad&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;&amp;amp;verbar;=&amp;quot; || &amp;quot;aor&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;&amp;lt;&amp;lt;&amp;quot; || &amp;quot;ls&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;&amp;gt;&amp;gt;&amp;quot; || &amp;quot;rs&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;&amp;gt;&amp;gt;=&amp;quot; || &amp;quot;ars&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;&amp;lt;&amp;lt;=&amp;quot; || &amp;quot;als&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;==&amp;quot; || &amp;quot;eq&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;!=&amp;quot; || &amp;quot;ne&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;&amp;lt;=&amp;quot; || &amp;quot;le&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;&amp;gt;=&amp;quot; || &amp;quot;ge&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;&amp;amp;&amp;amp;&amp;quot; || &amp;quot;aa&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;&amp;amp;verbar;&amp;amp;verbar;&amp;quot; || &amp;quot;oo&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;++&amp;quot; || &amp;quot;pp&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;--&amp;quot; || &amp;quot;mm&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;()&amp;quot; || &amp;quot;cl&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;[]&amp;quot; || &amp;quot;vc&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;-&amp;gt;&amp;quot; || &amp;quot;rf&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;,&amp;quot; || &amp;quot;cm&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;-&amp;gt;*&amp;quot; || &amp;quot;rm&amp;quot;&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Shibboleet</name></author>
	</entry>
	<entry>
		<id>https://www.lumasworkshop.com/w/index.php?title=Decompiling&amp;diff=865</id>
		<title>Decompiling</title>
		<link rel="alternate" type="text/html" href="https://www.lumasworkshop.com/w/index.php?title=Decompiling&amp;diff=865"/>
		<updated>2025-05-06T17:19:01Z</updated>

		<summary type="html">&lt;p&gt;Shibboleet: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Guides]]&lt;br /&gt;
[[Category:Decompiling]]&lt;br /&gt;
{{WIP}}&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
&#039;&#039;Decompiling&#039;&#039; is the process of taking assembly code and turning it back into a higher level language such as C or C++. It is essentially the reverse of &#039;&#039;compiling&#039;&#039;. &#039;&#039;Matching decompilation&#039;&#039; is the process of decompiling, but having the compiled code match the original assembly 1:1. While matching decompilation is harder than normal decompiling, it can become easier when you understand the patterns of the compiler used. This page aims to let new people understand how this process works, and hopefully be able to get new people into decompilation! While you do not need to be an expert at C or C++ to decompile, it is recommended that you have some experience before attempting decompilation. It is also very recommended that you have some prior knowledge of PowerPC assembly, as that is the key to understanding how a function works. [https://www.nxp.com/docs/en/reference-manual/MPC82XINSET.pdf This document] is a good way to learn or refresh knowledge of the PowerPC architecture. [https://www.warthman.com/images/IBM_PPC_Compiler_Writer%27s_Guide-cwg.pdf This document] is also good to learn some of the patterns that CodeWarrior does.&lt;br /&gt;
&lt;br /&gt;
== Getting Set Up ==&lt;br /&gt;
To begin decompiling &#039;&#039;Super Mario Galaxy&#039;&#039;, you first need to set up the environment. You will need the following tools:&lt;br /&gt;
* [https://gitforwindows.org/ Git (Windows)]&lt;br /&gt;
* Any IDE ([https://code.visualstudio.com/ Visual Studio Code Recommended])&lt;br /&gt;
* [https://www.python.org/downloads/release/python-397/ Python 3.9.7]&lt;br /&gt;
* IDA Pro (recommended) or Ghidra (Not recommended)&lt;br /&gt;
* [https://shibbo.net/smg/RMGK01_01.idb SMG1 Korean IDB (For IDA)]&lt;br /&gt;
* A &#039;&#039;Super Mario Galaxy&#039;&#039; Korean region DOL.&lt;br /&gt;
* [https://github.com/ninja-build/ninja/releases Ninja]&lt;br /&gt;
&lt;br /&gt;
After you have acquired all of these, setting up [https://github.com/shibbo/Petari Petari] is very simple.&lt;br /&gt;
&lt;br /&gt;
# With a new command prompt open, type in &#039;&#039;&#039;git clone https://github.com/shibbo/Petari&#039;&#039;&#039;. This will clone the repository into a directory called &amp;quot;Petari&amp;quot;.&lt;br /&gt;
# In this new &amp;quot;Petari&amp;quot; folder, place the SMG1 Korean &#039;&#039;&#039;main.dol&#039;&#039;&#039; into &#039;&#039;&#039;orig/RMGK01/main.dol&#039;&#039;&#039;.&lt;br /&gt;
# Open a new command prompt in the &amp;quot;Petari&amp;quot; folder.&lt;br /&gt;
# Run the command &#039;&#039;&#039;&#039;ninja&#039;&#039;&#039;. This will download the decompilation toolkit (dtk) and &amp;quot;split&amp;quot; the binary, then compile the code.&lt;br /&gt;
&lt;br /&gt;
== Environment ==&lt;br /&gt;
To properly utilize and use &#039;&#039;Petari&#039;&#039;, it is necessary to understand the structure of the environment. Petari is structured in a way that makes it easy to access and use.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Folder Name !! Description&lt;br /&gt;
|-&lt;br /&gt;
| assets || Just assets for the README.&lt;br /&gt;
|-&lt;br /&gt;
| build || The folder that gets created when &#039;&#039;&#039;ninja&#039;&#039;&#039; is ran. Contains the compiled object files and the compilers.&lt;br /&gt;
|-&lt;br /&gt;
| config || Contains the configurations for each SMG1 version for decompilation and splitting.&lt;br /&gt;
|-&lt;br /&gt;
| docs || Documents relating to using &#039;&#039;&#039;dtk&#039;&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
| include || Contains all of the header files for &#039;&#039;Super Mario Galaxy&#039;&#039; specific code.&lt;br /&gt;
|-&lt;br /&gt;
| md || Documentation for completed functions.&lt;br /&gt;
|-&lt;br /&gt;
| orig || Contains the DOLs for each game version for splitting and matching.&lt;br /&gt;
|-&lt;br /&gt;
| src || Contains all of the source files for &#039;&#039;&#039;Super Mario Galaxy&#039;&#039;&#039; and its libraries.&lt;br /&gt;
|-&lt;br /&gt;
| tools || Misc tools that dtk uses.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Libraries ==&lt;br /&gt;
&#039;&#039;Super Mario Galaxy&#039;&#039; uses a lot of libraries for certain functionality such as heaps, layouts, OS specific code, and more. Each library described in the table below are &#039;&#039;&#039;statically linked&#039;&#039;&#039; to the game, so every library&#039;s used code is inside of the &#039;&#039;main.dol&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
=== Non-SMG Libraries ===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Name !! Language !! Description&lt;br /&gt;
|-&lt;br /&gt;
| JSystem || C++ || Contains classes for backend things, such as heaps and linked lists.&lt;br /&gt;
|-&lt;br /&gt;
| MetroTRK || C || Target Resident Kernel, for debugging.&lt;br /&gt;
|-&lt;br /&gt;
| MSL_C || C &amp;amp; C++ || Contains standard library functions and types.&lt;br /&gt;
|-&lt;br /&gt;
| nw4r || C++ || Contains classes for sounds, layouts, and more. (SMG only uses the layouts and some math functions)&lt;br /&gt;
|-&lt;br /&gt;
| Runtime || C &amp;amp; C++ || Contains functions that relate to CodeWarrior&#039;s runtime code generation (ctor / dtor lists, etc)&lt;br /&gt;
|-&lt;br /&gt;
| RVL_SDK || C || Contains functions that relate to the Wii&#039;s &amp;quot;OS&amp;quot;.&lt;br /&gt;
|-&lt;br /&gt;
| RVLFaceLib || C || Contains functions that relate to Miis.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== SMG Libraries ===&lt;br /&gt;
All of &#039;&#039;Super Mario Galaxy&#039;&#039;&#039;s libraries are written in C++.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Header text !! Header text&lt;br /&gt;
|-&lt;br /&gt;
| Animation || Library for animation playing.&lt;br /&gt;
|-&lt;br /&gt;
| AreaObj || Library for invisible areas that can be accessed by players in the game.&lt;br /&gt;
|-&lt;br /&gt;
| AudioLib || N/A&lt;br /&gt;
|-&lt;br /&gt;
| Boss || Library for all of the bosses and mini-bosses in the game.&lt;br /&gt;
|-&lt;br /&gt;
| Camera || Library for all camera types.&lt;br /&gt;
|-&lt;br /&gt;
| Demo || Library for all cutscenes.&lt;br /&gt;
|-&lt;br /&gt;
| Effect || Library for all effect rendering.&lt;br /&gt;
|-&lt;br /&gt;
| Enemy || Library for all enemies.&lt;br /&gt;
|-&lt;br /&gt;
| GameAudio || N/A&lt;br /&gt;
|-&lt;br /&gt;
| Gravity || Library for all of the gravity types in the game.&lt;br /&gt;
|-&lt;br /&gt;
| LiveActor || Library for LiveActor, which is an actor that can switch states.&lt;br /&gt;
|-&lt;br /&gt;
| Map || Library for map classes that do not directly interact with the player. (ie switches)&lt;br /&gt;
|-&lt;br /&gt;
| MapObj || Library for all of the map objects in the game.&lt;br /&gt;
|-&lt;br /&gt;
| NameObj || Library for the most basic form of an object in the game.&lt;br /&gt;
|-&lt;br /&gt;
| NPC || Library for all of the non-playable characters.&lt;br /&gt;
|-&lt;br /&gt;
| NWC24 || Library for the mail system in the game.&lt;br /&gt;
|-&lt;br /&gt;
| Player || Library for all of the player related functions.&lt;br /&gt;
|-&lt;br /&gt;
| RhythmLib || N/A&lt;br /&gt;
|-&lt;br /&gt;
| Ride || Library for all of the actors that can be controlled by the player.&lt;br /&gt;
|-&lt;br /&gt;
| Scene || Library for all of the game scene related code.&lt;br /&gt;
|-&lt;br /&gt;
| Screen || Library for all of the layouts in the game.&lt;br /&gt;
|-&lt;br /&gt;
| Speaker || Library for the sound effect playing done on the Wiimote.&lt;br /&gt;
|-&lt;br /&gt;
| System || Library for a lot of the game&#039;s backend systems.&lt;br /&gt;
|-&lt;br /&gt;
| Util || Library for utility functions and classes.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Basics ==&lt;br /&gt;
To properly decompile, it is vital to know how a lot of the assembly will translate into C / C++ code. Here are a couple of patterns that you will see when decompiling code.&lt;br /&gt;
&lt;br /&gt;
== Splitting ==&lt;br /&gt;
&#039;&#039;Splitting&#039;&#039; refers to &amp;quot;splitting&amp;quot; up each object file with its respective segments to properly build a matching object. This can be code / data, or just data.&lt;br /&gt;
&lt;br /&gt;
A simple split looks like this:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Game/NameObj/NameObj.cpp:&lt;br /&gt;
	.text       start:0x802616B4 end:0x802618B4&lt;br /&gt;
	.data       start:0x805A7758 end:0x805A7780&lt;br /&gt;
	.sbss       start:0x806B5BE0 end:0x806B5BE8&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Each segment needs a &#039;&#039;&#039;start&#039;&#039;&#039; and an &#039;&#039;&#039;end address, and the &#039;&#039;&#039;end&#039;&#039;&#039; address always needs to be larger than the &#039;&#039;&#039;start&#039;&#039;&#039; address. You can use IDA (or Ghidra) to see what segment a specific set of code / data belongs to. For this specific split:&lt;br /&gt;
* &#039;&#039;&#039;.text&#039;&#039;&#039; begins at &#039;&#039;&#039;0x802616B4&#039;&#039;&#039; and ends at &#039;&#039;&#039;0x802618B4&#039;&#039;&#039;.&lt;br /&gt;
* &#039;&#039;&#039;.data&#039;&#039;&#039; begins at &#039;&#039;&#039;0x805A7758&#039;&#039;&#039; and ends at &#039;&#039;&#039;0x805A7780&#039;&#039;&#039;.&lt;br /&gt;
* &#039;&#039;&#039;.sbss&#039;&#039;&#039; begins at &#039;&#039;&#039;0x806B5BE0&#039;&#039;&#039; and ends at &#039;&#039;&#039;0x806B5BE8&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
You can change these splits by changing &#039;&#039;&#039;config/RMGKXX/splits.txt&#039;&#039;&#039; where &#039;&#039;&#039;XX&#039;&#039;&#039; is the version of the Korean version you are using. It is worth noting that any data addresses (ie .data, .bss, .sdata) need to be rounded to the nearest 8th byte, as they are 8-byte aligned.&lt;br /&gt;
&lt;br /&gt;
== Class Mapping ==&lt;br /&gt;
=== Base Class ===&lt;br /&gt;
The first step to decompiling a class is to map out the class itself. You need to be sure that you document every member, its type (as close as you can guess), its virtual functions, and more. The easiest way to achieve this is to look at the class&#039;s &#039;&#039;constructor&#039;&#039;. Seen below, is an example of a &#039;&#039;constructor&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
[[Image:NameObj_Ctor.png|frameless|700px|The constructor for &#039;&#039;NameObj&#039;&#039;.]]&lt;br /&gt;
&lt;br /&gt;
There are a couple of takeaways from this screenshot:&lt;br /&gt;
* The constructor passes an argument, which is a &#039;&#039;&#039;const char *&#039;&#039;&#039; (contained in r4) and is stored in (r3 + 0x4).&lt;br /&gt;
* (r3 + 0x0) is where the vtable is &#039;&#039;usually&#039;&#039; stored when a class has virtual functions. There are rare execptions.&lt;br /&gt;
* (r3 + 0x8) is stored with a &#039;&#039;&#039;sth&#039;&#039;&#039;, which means that it is a &#039;&#039;&#039;short&#039;&#039;&#039; datatype.&lt;br /&gt;
* (r3 + 0xA) is also stored with a &#039;&#039;&#039;sth&#039;&#039;&#039;, but with a &#039;&#039;&#039;-1&#039;&#039;&#039; value, so we know for sure that this type is &#039;&#039;signed&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Keep in mind that a constructor does not have to initialize every single member variable in the class! So there could be other members in a class that aren&#039;t mentioned in the constructor at all. After you look at the constructor, look around at the &#039;&#039;member functions&#039;&#039; to see if they use any members that are not initialized in the constructor. You can always verify if your class setup is correct when you can find where this class is created using the &#039;&#039;&#039;new&#039;&#039;&#039; operator. Check if the size passed to the &#039;&#039;&#039;new&#039;&#039;&#039; call matches the size of the class that you have mapped. If it is smaller, you are missing members. If it is bigger, you have too many! Remember that the vtable is implicitly stored at &#039;&#039;&#039;(this + 0x0)&#039;&#039;&#039;, so you do not have to explicitly define it. With all of these members documented, our class setup looks a little like this so far:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class NameObj {&lt;br /&gt;
public:&lt;br /&gt;
    NameObj(const char *pName);&lt;br /&gt;
&lt;br /&gt;
    /* remember that the vtable will be placed here once we define our virtuals! */&lt;br /&gt;
    /* 0x4 */   const char* mName;&lt;br /&gt;
    /* 0x8 */   volatile u16 mFlags;&lt;br /&gt;
    /* 0xA */   s16 mExecutorIdx;&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
After the members comes the &#039;&#039;&#039;vtable&#039;&#039;&#039;, or &#039;&#039;virtual table&#039;&#039;. It is an array of function pointers that can be overridden by classes that inherit the parent class. The vtable for &#039;&#039;&#039;NameObj&#039;&#039;&#039; looks like this:&lt;br /&gt;
[[Image:NameObj_Vtable.png|frameless|700px|The vtable for &#039;&#039;NameObj&#039;&#039;.]]&lt;br /&gt;
&lt;br /&gt;
To document the vtable, you simply document every single function placed here that contains the class name of the class you are currently decompiling. Since &#039;&#039;NameObj&#039;&#039; is a base class, every single function here is going to be defined. If a class overrides a function, you will only document the functions that are overridden. After documenting the vtable, our class looks something like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class NameObj {&lt;br /&gt;
public:&lt;br /&gt;
    NameObj(const char *pName);&lt;br /&gt;
&lt;br /&gt;
    virtual ~NameObj();&lt;br /&gt;
    virtual void init(const JMapInfoIter &amp;amp;rIter);&lt;br /&gt;
    virtual void initAfterPlacement();&lt;br /&gt;
    virtual void movement();&lt;br /&gt;
    virtual void draw() const;&lt;br /&gt;
    virtual void calcAnim();&lt;br /&gt;
    virtual void calcViewAndEntry();&lt;br /&gt;
&lt;br /&gt;
    /* remember that the vtable will be placed here once we define our virtuals! */&lt;br /&gt;
    /* 0x4 */   const char* mName;&lt;br /&gt;
    /* 0x8 */   volatile u16 mFlags;&lt;br /&gt;
    /* 0xA */   s16 mExecutorIdx;&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Once the vtable is complete, you want to document all of the member functions that are in the class. Since &#039;&#039;Super Mario Galaxy 1&#039;&#039; has a symbol map, we can easily find the member functions that &#039;&#039;NameObj&#039;&#039; contains. Once you have figured out their return types and their arguments, you can finish mapping out a class! After finding all of &#039;&#039;NameObj&#039;&#039;&#039;s member functions, the class looks like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class NameObj {&lt;br /&gt;
public:&lt;br /&gt;
    NameObj(const char *pName);&lt;br /&gt;
&lt;br /&gt;
    virtual ~NameObj();&lt;br /&gt;
    virtual void init(const JMapInfoIter &amp;amp;rIter);&lt;br /&gt;
    virtual void initAfterPlacement();&lt;br /&gt;
    virtual void movement();&lt;br /&gt;
    virtual void draw() const;&lt;br /&gt;
    virtual void calcAnim();&lt;br /&gt;
    virtual void calcViewAndEntry();&lt;br /&gt;
&lt;br /&gt;
    void initWithoutIter();&lt;br /&gt;
    void setName(const char *pName);&lt;br /&gt;
    void executeMovement();&lt;br /&gt;
    void requestSuspend();&lt;br /&gt;
    void requestResume();&lt;br /&gt;
    void syncWithFlags();&lt;br /&gt;
&lt;br /&gt;
    /* remember that the vtable will be placed here once we define our virtuals! */&lt;br /&gt;
    /* 0x4 */   const char* mName;&lt;br /&gt;
    /* 0x8 */   volatile u16 mFlags;&lt;br /&gt;
    /* 0xA */   s16 mExecutorIdx;&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Inheriting Class ===&lt;br /&gt;
The process of mapping a class that inherits another class is mainly the same as mapping a base class, except there are things to watch out for so you don&#039;t accidentally duplicate a member variable. The first step is to look at the &#039;&#039;constructor&#039;&#039; of the class you want to map:&lt;br /&gt;
&lt;br /&gt;
[[Image:TripodBossCoin_Ctor.png|frameless|700px|The constructor for &#039;&#039;TripodBossCoin&#039;&#039;.]]&lt;br /&gt;
&lt;br /&gt;
There are a few takeaways from this by looking at the constructor:&lt;br /&gt;
* The class inherits NameObj. Since &#039;&#039;NameObj&#039;&#039; is 0xC bytes long, we know that any member variables for &#039;&#039;TripodBossCoin&#039;&#039; start at &#039;&#039;&#039;0xC&#039;&#039;&#039;.&lt;br /&gt;
* The vtable pointer &#039;&#039;&#039;(this + 0x0)&#039;&#039;&#039; from &#039;&#039;NameObj&#039;&#039; is overridden with the vtable for &#039;&#039;TripodBossCoin&#039;&#039; implicitly.&lt;br /&gt;
* &#039;&#039;&#039;(this + 0xC)&#039;&#039;&#039; is a 32-bit integer initialized to 0. It is not possible to determine if it is signed or not from this store alone.&lt;br /&gt;
* &#039;&#039;&#039;(this + 0x10)&#039;&#039;&#039; is the same scenario as &#039;&#039;&#039;(this + 0xC)&#039;&#039;&#039;.&lt;br /&gt;
* There is a direct instance of &#039;&#039;JGeometry::TMatrix34&amp;lt;JGeometry::SMatrix34C&amp;lt;f32&amp;gt;&#039;&#039; at 0x14. (in Petari &amp;amp; Syati this is typedef&#039;d as &#039;&#039;TMtx34f&#039;&#039;). Since &#039;&#039;TMtx34f&#039;&#039; is 0x30 in size, the next member variable is at 0x14 + 0x30, which is &#039;&#039;&#039;0x44&#039;&#039;&#039;.&lt;br /&gt;
* &#039;&#039;&#039;(this + 0x44)&#039;&#039;&#039; is a signed 32-bit integer, due to &#039;&#039;&#039;-1&#039;&#039;&#039; being stored to it.&lt;br /&gt;
&lt;br /&gt;
After these observations, our class looks like this:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class TripodBossCoin : public NameObj {&lt;br /&gt;
public:&lt;br /&gt;
	TripodBossCoin(const char *);&lt;br /&gt;
	&lt;br /&gt;
	u32 _C;&lt;br /&gt;
	u32 _10;&lt;br /&gt;
	TMtx34f _14;&lt;br /&gt;
	s32 _44;&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Next are the virtuals. The process is a little different from a base class. Let&#039;s take a look at the vtable for &#039;&#039;TripodBossCoin&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
[[Image:TripodBossCoin_Vtable.png|frameless|700px|The vtable for &#039;&#039;TripodBossCoin&#039;&#039;.]]&lt;br /&gt;
&lt;br /&gt;
The biggest takeaway from this screenshot is that only three virtuals are overriden by &#039;&#039;TripodBossCoin&#039;&#039;. And those three functions are &#039;&#039;&#039;TripodBossCoin::~TripodBossCoin()&#039;&#039;&#039;, &#039;&#039;&#039;TripodBossCoin::init()&#039;&#039;&#039; and &#039;&#039;&#039;TripodBossCoin::movement()&#039;&#039;&#039;. So we define them as such:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class TripodBossCoin : public NameObj {&lt;br /&gt;
public:&lt;br /&gt;
	TripodBossCoin(const char *);&lt;br /&gt;
&lt;br /&gt;
    virtual ~TripodBossCoin();&lt;br /&gt;
    virtual void init(const JMapInfoIter &amp;amp;);&lt;br /&gt;
    virtual void movement();&lt;br /&gt;
	&lt;br /&gt;
	u32 _C;&lt;br /&gt;
	u32 _10;&lt;br /&gt;
	TMtx34f _14;&lt;br /&gt;
	s32 _44;&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
It is worth noting that the &#039;&#039;&#039;override&#039;&#039;&#039; keyword was not a part of the C++ standard at this point in time, so all overrides are implicit. After all of this is done, you simply have to repeat the process for base classes and document the member functions that are a part of the class.&lt;br /&gt;
&lt;br /&gt;
=== Loops ===&lt;br /&gt;
==== Predefined bounds ====&lt;br /&gt;
Let&#039;s take a simple loop that stores &amp;lt;i&amp;gt;nullptr&amp;lt;/i&amp;gt; in each 8 elements of a pointer array.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class TestClass {&lt;br /&gt;
public:&lt;br /&gt;
    TestClass();&lt;br /&gt;
&lt;br /&gt;
     int* mPointers[8];&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
TestClass::TestClass() {&lt;br /&gt;
    for (int i = 0; i &amp;lt; 8; i++) {&lt;br /&gt;
        mPointers[i] = nullptr;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The output assembly would look something like:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
li r0, 8 # there are 8 elements in this loop&lt;br /&gt;
li r5, 0 # the value to store in the element (nullptr)&lt;br /&gt;
li r4, 0 # the current element offset in the loop&lt;br /&gt;
mtctr r0 # move the number of iterations into the counter register (8)&lt;br /&gt;
&lt;br /&gt;
loop:&lt;br /&gt;
    stwx r5, r3, r4 # store 0 (r5) into the array at r3 (this) + r4 (our current offset, which is i * 4)&lt;br /&gt;
    addi r4, r4, 4 # increment our offset by sizeof(int) since integers are 32-bits&lt;br /&gt;
    bdnz+ loop # branch back to our loop again&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Variable Length Bounds ====&lt;br /&gt;
Let&#039;s take a simple loop that stores &amp;lt;i&amp;gt;nullptr&amp;lt;/i&amp;gt; in each element of a variable-length array. We will have a class with two members, one that contains the pointer array itself, and another that stores the number of pointers.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class TestClass {&lt;br /&gt;
public:&lt;br /&gt;
    TestClass();&lt;br /&gt;
&lt;br /&gt;
     int** mPointers;&lt;br /&gt;
     int mNumPointers;&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
TestClass::TestClass() {&lt;br /&gt;
    mNumPointers = 8;&lt;br /&gt;
    for (int i = 0; i &amp;lt; mNumPointers ; i++) {&lt;br /&gt;
        mPointers[i] = nullptr;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Because we do not know how many pointers we have stored, we cannot use the counter register like we did with a fixed-size array. Instead, the compiler will use a cmpw (signed integer) or cmplw (unsigned) instruction to compare the current iteration to how many pointers are stored in the class.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
li r0, 8 # there are 8 elements in this loop&lt;br /&gt;
li r7, 0 # the value to store in the element (nullptr)&lt;br /&gt;
stw r0, 4(r3) # r3 + 4 is the offset to our member variable &amp;quot;mNumPointers&amp;quot;&lt;br /&gt;
mr r6, r7 # simple copy of the 0 value so we can also use it for our counter&lt;br /&gt;
li r4, 0 # load 0 into our offset&lt;br /&gt;
b loop # branch into our loop&lt;br /&gt;
&lt;br /&gt;
loop:&lt;br /&gt;
    lwz r5, 0(r3) # load our pointer array from this + 0&lt;br /&gt;
    addi r7, r7, 1 # increment our index by 1&lt;br /&gt;
    stwx r6, r5, r4 # store our nullptr value (r6) into r5 + r4 (ptrArray + currentOffset)&lt;br /&gt;
    addi r4, r4, 4 # increment our offset by sizeof(int) since integers are 32-bits&lt;br /&gt;
    lwz r0, 4(r3) # load our number of pointers we will increment by (mNumPointers)&lt;br /&gt;
    cmpw r7, r0 # compare our number of pointers to the current index in our loop&lt;br /&gt;
    blt+ loop # branch if the number is less than mNumPointers&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Structure Access In Arrays (Pointer Array) ====&lt;br /&gt;
More complex forms of loops comes into play when you are iterating through structures and storing / loading members from those structures. Let&#039;s take this class for example:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
struct TestStruct {&lt;br /&gt;
    int SomeMember;&lt;br /&gt;
    int AnotherMember;&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
class TestClass {&lt;br /&gt;
public:&lt;br /&gt;
    TestClass();&lt;br /&gt;
&lt;br /&gt;
    void storeVals();&lt;br /&gt;
&lt;br /&gt;
     TestStruct** mStructures;&lt;br /&gt;
     int mNumStructures;&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
For the sake of simplicity, let&#039;s assume that the TestClass constructor initializes the number of structures to 8, and constructs them accordingly. With that in mind, let&#039;s see how a struct store will work.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void TestClass::storeVals() {&lt;br /&gt;
    for (int i = 0; i &amp;lt; mNumStructures; i++) {&lt;br /&gt;
        mStructures[i]-&amp;gt;AnotherMember = 5;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
The output assembly would look something like:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
li r7, 0 # our &amp;quot;i&amp;quot; used in the loop, starts at 0&lt;br /&gt;
li r4, 0 # our current offset into the array&lt;br /&gt;
li r6, 5 # the value we are storing into the array&lt;br /&gt;
b loop&lt;br /&gt;
&lt;br /&gt;
loop:&lt;br /&gt;
    lwz r5, 0(r3) # load the array pointer&lt;br /&gt;
    addi r7, r7, 1 # increment our current index (i) by 1&lt;br /&gt;
    lwzx r5, r5, r4 # load the current structure, mStructures[i] where r4 is the current offset&lt;br /&gt;
    addi r4, r4, 4 # increment our offset by sizeof(TestStruct*), which is 4&lt;br /&gt;
    stw r6, 4(r5) # store our value (5) into (mStructures[i] + 4), which is our AnotherMember&lt;br /&gt;
    lwz r0, 4(r3) # load the number of structures from TestClass&lt;br /&gt;
    cmpw r7, r0 # compare the current index to our value in TestClass&lt;br /&gt;
    blt+ loop # loop back if it is less than the value&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Structure Access In Arrays (Direct Array) ====&lt;br /&gt;
Let&#039;s take the previous example and modify it a little. Instead of making an array of pointers to the struct instances, let&#039;s store the array &amp;lt;i&amp;gt;directly&amp;lt;/i&amp;gt; into our class instance.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
struct TestStruct {&lt;br /&gt;
    int SomeMember;&lt;br /&gt;
    int AnotherMember;&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
class TestClass {&lt;br /&gt;
public:&lt;br /&gt;
    TestClass();&lt;br /&gt;
&lt;br /&gt;
    void storeVals();&lt;br /&gt;
&lt;br /&gt;
     TestStruct mStructures[8];&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Again, let us assume that the array has already been constructed and everything is initialized as it should be.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void TestClass::storeVals() {&lt;br /&gt;
    for (int i = 0; i &amp;lt; 8; i++) {&lt;br /&gt;
        mStructures[i].AnotherMember = 5;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
The output assembly would look something like:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
li r0, 8 # load our number of iterations (8)&lt;br /&gt;
li r4, 0 # current offset into the array. initialized at 0&lt;br /&gt;
li r6, 5 # the value to store into the array&lt;br /&gt;
mtctr r0 # move the number of iterations into the counter register&lt;br /&gt;
&lt;br /&gt;
loop:&lt;br /&gt;
    add r5, r3, r4 # jump to the offset into the array. r5 = (this + 0) + r4&lt;br /&gt;
    addi r4, r4, 8 # increment our current offset by sizeof(TestStruct), which is 8&lt;br /&gt;
    stw r6, 4(r5) # store our constant value (5) into the loaded struct + 4 (AnotherMember)&lt;br /&gt;
    bdnz+ loop # branch back to the loop if the counter is not 8&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Operator Overloads ==&lt;br /&gt;
There are specific ways that CodeWarrior mangles symbols when overloading operators for classes.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Operator !! Mangled Symbol&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;+&amp;quot; || &amp;quot;pl&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;-&amp;quot; || &amp;quot;mi&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;*&amp;quot; || &amp;quot;ml&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;/&amp;quot; || &amp;quot;dv&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;%&amp;quot; || &amp;quot;md&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;^&amp;quot; || &amp;quot;er&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;/=&amp;quot; || &amp;quot;adv&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;&amp;amp;&amp;quot; || &amp;quot;ad&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;&amp;amp;verbar;&amp;quot; || &amp;quot;or&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;~&amp;quot; || &amp;quot;co&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;!&amp;quot; || &amp;quot;nt&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;=&amp;quot; || &amp;quot;as&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;&amp;lt;&amp;quot; || &amp;quot;lt&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;&amp;gt;&amp;quot; || &amp;quot;gt&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;+=&amp;quot; || &amp;quot;apl&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;-=&amp;quot; || &amp;quot;ami&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;*=&amp;quot; || &amp;quot;amu&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;%=&amp;quot; || &amp;quot;amd&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;^=&amp;quot; || &amp;quot;aer&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;&amp;amp;=&amp;quot; || &amp;quot;aad&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;&amp;amp;verbar;=&amp;quot; || &amp;quot;aor&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;&amp;lt;&amp;lt;&amp;quot; || &amp;quot;ls&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;&amp;gt;&amp;gt;&amp;quot; || &amp;quot;rs&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;&amp;gt;&amp;gt;=&amp;quot; || &amp;quot;ars&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;&amp;lt;&amp;lt;=&amp;quot; || &amp;quot;als&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;==&amp;quot; || &amp;quot;eq&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;!=&amp;quot; || &amp;quot;ne&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;&amp;lt;=&amp;quot; || &amp;quot;le&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;&amp;gt;=&amp;quot; || &amp;quot;ge&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;&amp;amp;&amp;amp;&amp;quot; || &amp;quot;aa&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;&amp;amp;verbar;&amp;amp;verbar;&amp;quot; || &amp;quot;oo&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;++&amp;quot; || &amp;quot;pp&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;--&amp;quot; || &amp;quot;mm&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;()&amp;quot; || &amp;quot;cl&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;[]&amp;quot; || &amp;quot;vc&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;-&amp;gt;&amp;quot; || &amp;quot;rf&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;,&amp;quot; || &amp;quot;cm&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;-&amp;gt;*&amp;quot; || &amp;quot;rm&amp;quot;&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Shibboleet</name></author>
	</entry>
	<entry>
		<id>https://www.lumasworkshop.com/w/index.php?title=Decompiling&amp;diff=864</id>
		<title>Decompiling</title>
		<link rel="alternate" type="text/html" href="https://www.lumasworkshop.com/w/index.php?title=Decompiling&amp;diff=864"/>
		<updated>2025-05-06T17:10:51Z</updated>

		<summary type="html">&lt;p&gt;Shibboleet: /* Getting Set Up */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Guides]]&lt;br /&gt;
[[Category:Decompiling]]&lt;br /&gt;
{{WIP}}&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
&#039;&#039;Decompiling&#039;&#039; is the process of taking assembly code and turning it back into a higher level language such as C or C++. It is essentially the reverse of &#039;&#039;compiling&#039;&#039;. &#039;&#039;Matching decompilation&#039;&#039; is the process of decompiling, but having the compiled code match the original assembly 1:1. While matching decompilation is harder than normal decompiling, it can become easier when you understand the patterns of the compiler used. This page aims to let new people understand how this process works, and hopefully be able to get new people into decompilation! While you do not need to be an expert at C or C++ to decompile, it is recommended that you have some experience before attempting decompilation. It is also very recommended that you have some prior knowledge of PowerPC assembly, as that is the key to understanding how a function works. [https://www.nxp.com/docs/en/reference-manual/MPC82XINSET.pdf This document] is a good way to learn or refresh knowledge of the PowerPC architecture. [https://www.warthman.com/images/IBM_PPC_Compiler_Writer%27s_Guide-cwg.pdf This document] is also good to learn some of the patterns that CodeWarrior does.&lt;br /&gt;
&lt;br /&gt;
== Getting Set Up ==&lt;br /&gt;
To begin decompiling &#039;&#039;Super Mario Galaxy&#039;&#039;, you first need to set up the environment. You will need the following tools:&lt;br /&gt;
* [https://gitforwindows.org/ Git (Windows)]&lt;br /&gt;
* Any IDE ([https://code.visualstudio.com/ Visual Studio Code Recommended])&lt;br /&gt;
* [https://www.python.org/downloads/release/python-397/ Python 3.9.7]&lt;br /&gt;
* IDA Pro (recommended) or Ghidra (Not recommended)&lt;br /&gt;
* [https://shibbo.net/smg/RMGK01_01.idb SMG1 Korean IDB (For IDA)]&lt;br /&gt;
* A &#039;&#039;Super Mario Galaxy&#039;&#039; Korean region DOL.&lt;br /&gt;
* [https://github.com/ninja-build/ninja/releases Ninja]&lt;br /&gt;
&lt;br /&gt;
After you have acquired all of these, setting up [https://github.com/shibbo/Petari Petari] is very simple.&lt;br /&gt;
&lt;br /&gt;
# With a new command prompt open, type in &#039;&#039;&#039;git clone https://github.com/shibbo/Petari&#039;&#039;&#039;. This will clone the repository into a directory called &amp;quot;Petari&amp;quot;.&lt;br /&gt;
# In this new &amp;quot;Petari&amp;quot; folder, place the SMG1 Korean &#039;&#039;&#039;main.dol&#039;&#039;&#039; into &#039;&#039;&#039;orig/RMGK01/main.dol&#039;&#039;&#039;.&lt;br /&gt;
# Open a new command prompt in the &amp;quot;Petari&amp;quot; folder.&lt;br /&gt;
# Run the command &#039;&#039;&#039;&#039;ninja&#039;&#039;&#039;. This will download the decompilation toolkit (dtk) and &amp;quot;split&amp;quot; the binary, then compile the code.&lt;br /&gt;
&lt;br /&gt;
== Environment ==&lt;br /&gt;
To properly utilize and use &#039;&#039;Petari&#039;&#039;, it is necessary to understand the structure of the environment. Petari is structured in a way that makes it easy to access and use.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Folder Name !! Description&lt;br /&gt;
|-&lt;br /&gt;
| assets || Just assets for the README.&lt;br /&gt;
|-&lt;br /&gt;
| build || The folder that gets created when &#039;&#039;&#039;ninja&#039;&#039;&#039; is ran. Contains the compiled object files and the compilers.&lt;br /&gt;
|-&lt;br /&gt;
| config || Contains the configurations for each SMG1 version for decompilation and splitting.&lt;br /&gt;
|-&lt;br /&gt;
| docs || Documents relating to using &#039;&#039;&#039;dtk&#039;&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
| include || Contains all of the header files for &#039;&#039;Super Mario Galaxy&#039;&#039; specific code.&lt;br /&gt;
|-&lt;br /&gt;
| md || Documentation for completed functions.&lt;br /&gt;
|-&lt;br /&gt;
| orig || Contains the DOLs for each game version for splitting and matching.&lt;br /&gt;
|-&lt;br /&gt;
| src || Contains all of the source files for &#039;&#039;&#039;Super Mario Galaxy&#039;&#039;&#039; and its libraries.&lt;br /&gt;
|-&lt;br /&gt;
| tools || Misc tools that dtk uses.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Libraries ==&lt;br /&gt;
&#039;&#039;Super Mario Galaxy&#039;&#039; uses a lot of libraries for certain functionality such as heaps, layouts, OS specific code, and more. Each library described in the table below are &#039;&#039;&#039;statically linked&#039;&#039;&#039; to the game, so every library&#039;s used code is inside of the &#039;&#039;main.dol&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
=== Non-SMG Libraries ===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Name !! Language !! Description&lt;br /&gt;
|-&lt;br /&gt;
| JSystem || C++ || Contains classes for backend things, such as heaps and linked lists.&lt;br /&gt;
|-&lt;br /&gt;
| MetroTRK || C || Target Resident Kernel, for debugging.&lt;br /&gt;
|-&lt;br /&gt;
| MSL_C || C &amp;amp; C++ || Contains standard library functions and types.&lt;br /&gt;
|-&lt;br /&gt;
| nw4r || C++ || Contains classes for sounds, layouts, and more. (SMG only uses the layouts and some math functions)&lt;br /&gt;
|-&lt;br /&gt;
| Runtime || C &amp;amp; C++ || Contains functions that relate to CodeWarrior&#039;s runtime code generation (ctor / dtor lists, etc)&lt;br /&gt;
|-&lt;br /&gt;
| RVL_SDK || C || Contains functions that relate to the Wii&#039;s &amp;quot;OS&amp;quot;.&lt;br /&gt;
|-&lt;br /&gt;
| RVLFaceLib || C || Contains functions that relate to Miis.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== SMG Libraries ===&lt;br /&gt;
All of &#039;&#039;Super Mario Galaxy&#039;&#039;&#039;s libraries are written in C++.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Header text !! Header text&lt;br /&gt;
|-&lt;br /&gt;
| Animation || Library for animation playing.&lt;br /&gt;
|-&lt;br /&gt;
| AreaObj || Library for invisible areas that can be accessed by players in the game.&lt;br /&gt;
|-&lt;br /&gt;
| AudioLib || N/A&lt;br /&gt;
|-&lt;br /&gt;
| Boss || Library for all of the bosses and mini-bosses in the game.&lt;br /&gt;
|-&lt;br /&gt;
| Camera || Library for all camera types.&lt;br /&gt;
|-&lt;br /&gt;
| Demo || Library for all cutscenes.&lt;br /&gt;
|-&lt;br /&gt;
| Effect || Library for all effect rendering.&lt;br /&gt;
|-&lt;br /&gt;
| Enemy || Library for all enemies.&lt;br /&gt;
|-&lt;br /&gt;
| GameAudio || N/A&lt;br /&gt;
|-&lt;br /&gt;
| Gravity || Library for all of the gravity types in the game.&lt;br /&gt;
|-&lt;br /&gt;
| LiveActor || Library for LiveActor, which is an actor that can switch states.&lt;br /&gt;
|-&lt;br /&gt;
| Map || Library for map classes that do not directly interact with the player. (ie switches)&lt;br /&gt;
|-&lt;br /&gt;
| MapObj || Library for all of the map objects in the game.&lt;br /&gt;
|-&lt;br /&gt;
| NameObj || Library for the most basic form of an object in the game.&lt;br /&gt;
|-&lt;br /&gt;
| NPC || Library for all of the non-playable characters.&lt;br /&gt;
|-&lt;br /&gt;
| NWC24 || Library for the mail system in the game.&lt;br /&gt;
|-&lt;br /&gt;
| Player || Library for all of the player related functions.&lt;br /&gt;
|-&lt;br /&gt;
| RhythmLib || N/A&lt;br /&gt;
|-&lt;br /&gt;
| Ride || Library for all of the actors that can be controlled by the player.&lt;br /&gt;
|-&lt;br /&gt;
| Scene || Library for all of the game scene related code.&lt;br /&gt;
|-&lt;br /&gt;
| Screen || Library for all of the layouts in the game.&lt;br /&gt;
|-&lt;br /&gt;
| Speaker || Library for the sound effect playing done on the Wiimote.&lt;br /&gt;
|-&lt;br /&gt;
| System || Library for a lot of the game&#039;s backend systems.&lt;br /&gt;
|-&lt;br /&gt;
| Util || Library for utility functions and classes.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Basics ==&lt;br /&gt;
To properly decompile, it is vital to know how a lot of the assembly will translate into C / C++ code. Here are a couple of patterns that you will see when decompiling code.&lt;br /&gt;
&lt;br /&gt;
== Class Mapping ==&lt;br /&gt;
=== Base Class ===&lt;br /&gt;
The first step to decompiling a class is to map out the class itself. You need to be sure that you document every member, its type (as close as you can guess), its virtual functions, and more. The easiest way to achieve this is to look at the class&#039;s &#039;&#039;constructor&#039;&#039;. Seen below, is an example of a &#039;&#039;constructor&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
[[Image:NameObj_Ctor.png|frameless|700px|The constructor for &#039;&#039;NameObj&#039;&#039;.]]&lt;br /&gt;
&lt;br /&gt;
There are a couple of takeaways from this screenshot:&lt;br /&gt;
* The constructor passes an argument, which is a &#039;&#039;&#039;const char *&#039;&#039;&#039; (contained in r4) and is stored in (r3 + 0x4).&lt;br /&gt;
* (r3 + 0x0) is where the vtable is &#039;&#039;usually&#039;&#039; stored when a class has virtual functions. There are rare execptions.&lt;br /&gt;
* (r3 + 0x8) is stored with a &#039;&#039;&#039;sth&#039;&#039;&#039;, which means that it is a &#039;&#039;&#039;short&#039;&#039;&#039; datatype.&lt;br /&gt;
* (r3 + 0xA) is also stored with a &#039;&#039;&#039;sth&#039;&#039;&#039;, but with a &#039;&#039;&#039;-1&#039;&#039;&#039; value, so we know for sure that this type is &#039;&#039;signed&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Keep in mind that a constructor does not have to initialize every single member variable in the class! So there could be other members in a class that aren&#039;t mentioned in the constructor at all. After you look at the constructor, look around at the &#039;&#039;member functions&#039;&#039; to see if they use any members that are not initialized in the constructor. You can always verify if your class setup is correct when you can find where this class is created using the &#039;&#039;&#039;new&#039;&#039;&#039; operator. Check if the size passed to the &#039;&#039;&#039;new&#039;&#039;&#039; call matches the size of the class that you have mapped. If it is smaller, you are missing members. If it is bigger, you have too many! Remember that the vtable is implicitly stored at &#039;&#039;&#039;(this + 0x0)&#039;&#039;&#039;, so you do not have to explicitly define it. With all of these members documented, our class setup looks a little like this so far:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class NameObj {&lt;br /&gt;
public:&lt;br /&gt;
    NameObj(const char *pName);&lt;br /&gt;
&lt;br /&gt;
    /* remember that the vtable will be placed here once we define our virtuals! */&lt;br /&gt;
    /* 0x4 */   const char* mName;&lt;br /&gt;
    /* 0x8 */   volatile u16 mFlags;&lt;br /&gt;
    /* 0xA */   s16 mExecutorIdx;&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
After the members comes the &#039;&#039;&#039;vtable&#039;&#039;&#039;, or &#039;&#039;virtual table&#039;&#039;. It is an array of function pointers that can be overridden by classes that inherit the parent class. The vtable for &#039;&#039;&#039;NameObj&#039;&#039;&#039; looks like this:&lt;br /&gt;
[[Image:NameObj_Vtable.png|frameless|700px|The vtable for &#039;&#039;NameObj&#039;&#039;.]]&lt;br /&gt;
&lt;br /&gt;
To document the vtable, you simply document every single function placed here that contains the class name of the class you are currently decompiling. Since &#039;&#039;NameObj&#039;&#039; is a base class, every single function here is going to be defined. If a class overrides a function, you will only document the functions that are overridden. After documenting the vtable, our class looks something like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class NameObj {&lt;br /&gt;
public:&lt;br /&gt;
    NameObj(const char *pName);&lt;br /&gt;
&lt;br /&gt;
    virtual ~NameObj();&lt;br /&gt;
    virtual void init(const JMapInfoIter &amp;amp;rIter);&lt;br /&gt;
    virtual void initAfterPlacement();&lt;br /&gt;
    virtual void movement();&lt;br /&gt;
    virtual void draw() const;&lt;br /&gt;
    virtual void calcAnim();&lt;br /&gt;
    virtual void calcViewAndEntry();&lt;br /&gt;
&lt;br /&gt;
    /* remember that the vtable will be placed here once we define our virtuals! */&lt;br /&gt;
    /* 0x4 */   const char* mName;&lt;br /&gt;
    /* 0x8 */   volatile u16 mFlags;&lt;br /&gt;
    /* 0xA */   s16 mExecutorIdx;&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Once the vtable is complete, you want to document all of the member functions that are in the class. Since &#039;&#039;Super Mario Galaxy 1&#039;&#039; has a symbol map, we can easily find the member functions that &#039;&#039;NameObj&#039;&#039; contains. Once you have figured out their return types and their arguments, you can finish mapping out a class! After finding all of &#039;&#039;NameObj&#039;&#039;&#039;s member functions, the class looks like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class NameObj {&lt;br /&gt;
public:&lt;br /&gt;
    NameObj(const char *pName);&lt;br /&gt;
&lt;br /&gt;
    virtual ~NameObj();&lt;br /&gt;
    virtual void init(const JMapInfoIter &amp;amp;rIter);&lt;br /&gt;
    virtual void initAfterPlacement();&lt;br /&gt;
    virtual void movement();&lt;br /&gt;
    virtual void draw() const;&lt;br /&gt;
    virtual void calcAnim();&lt;br /&gt;
    virtual void calcViewAndEntry();&lt;br /&gt;
&lt;br /&gt;
    void initWithoutIter();&lt;br /&gt;
    void setName(const char *pName);&lt;br /&gt;
    void executeMovement();&lt;br /&gt;
    void requestSuspend();&lt;br /&gt;
    void requestResume();&lt;br /&gt;
    void syncWithFlags();&lt;br /&gt;
&lt;br /&gt;
    /* remember that the vtable will be placed here once we define our virtuals! */&lt;br /&gt;
    /* 0x4 */   const char* mName;&lt;br /&gt;
    /* 0x8 */   volatile u16 mFlags;&lt;br /&gt;
    /* 0xA */   s16 mExecutorIdx;&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Inheriting Class ===&lt;br /&gt;
The process of mapping a class that inherits another class is mainly the same as mapping a base class, except there are things to watch out for so you don&#039;t accidentally duplicate a member variable. The first step is to look at the &#039;&#039;constructor&#039;&#039; of the class you want to map:&lt;br /&gt;
&lt;br /&gt;
[[Image:TripodBossCoin_Ctor.png|frameless|700px|The constructor for &#039;&#039;TripodBossCoin&#039;&#039;.]]&lt;br /&gt;
&lt;br /&gt;
There are a few takeaways from this by looking at the constructor:&lt;br /&gt;
* The class inherits NameObj. Since &#039;&#039;NameObj&#039;&#039; is 0xC bytes long, we know that any member variables for &#039;&#039;TripodBossCoin&#039;&#039; start at &#039;&#039;&#039;0xC&#039;&#039;&#039;.&lt;br /&gt;
* The vtable pointer &#039;&#039;&#039;(this + 0x0)&#039;&#039;&#039; from &#039;&#039;NameObj&#039;&#039; is overridden with the vtable for &#039;&#039;TripodBossCoin&#039;&#039; implicitly.&lt;br /&gt;
* &#039;&#039;&#039;(this + 0xC)&#039;&#039;&#039; is a 32-bit integer initialized to 0. It is not possible to determine if it is signed or not from this store alone.&lt;br /&gt;
* &#039;&#039;&#039;(this + 0x10)&#039;&#039;&#039; is the same scenario as &#039;&#039;&#039;(this + 0xC)&#039;&#039;&#039;.&lt;br /&gt;
* There is a direct instance of &#039;&#039;JGeometry::TMatrix34&amp;lt;JGeometry::SMatrix34C&amp;lt;f32&amp;gt;&#039;&#039; at 0x14. (in Petari &amp;amp; Syati this is typedef&#039;d as &#039;&#039;TMtx34f&#039;&#039;). Since &#039;&#039;TMtx34f&#039;&#039; is 0x30 in size, the next member variable is at 0x14 + 0x30, which is &#039;&#039;&#039;0x44&#039;&#039;&#039;.&lt;br /&gt;
* &#039;&#039;&#039;(this + 0x44)&#039;&#039;&#039; is a signed 32-bit integer, due to &#039;&#039;&#039;-1&#039;&#039;&#039; being stored to it.&lt;br /&gt;
&lt;br /&gt;
After these observations, our class looks like this:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class TripodBossCoin : public NameObj {&lt;br /&gt;
public:&lt;br /&gt;
	TripodBossCoin(const char *);&lt;br /&gt;
	&lt;br /&gt;
	u32 _C;&lt;br /&gt;
	u32 _10;&lt;br /&gt;
	TMtx34f _14;&lt;br /&gt;
	s32 _44;&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Next are the virtuals. The process is a little different from a base class. Let&#039;s take a look at the vtable for &#039;&#039;TripodBossCoin&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
[[Image:TripodBossCoin_Vtable.png|frameless|700px|The vtable for &#039;&#039;TripodBossCoin&#039;&#039;.]]&lt;br /&gt;
&lt;br /&gt;
The biggest takeaway from this screenshot is that only three virtuals are overriden by &#039;&#039;TripodBossCoin&#039;&#039;. And those three functions are &#039;&#039;&#039;TripodBossCoin::~TripodBossCoin()&#039;&#039;&#039;, &#039;&#039;&#039;TripodBossCoin::init()&#039;&#039;&#039; and &#039;&#039;&#039;TripodBossCoin::movement()&#039;&#039;&#039;. So we define them as such:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class TripodBossCoin : public NameObj {&lt;br /&gt;
public:&lt;br /&gt;
	TripodBossCoin(const char *);&lt;br /&gt;
&lt;br /&gt;
    virtual ~TripodBossCoin();&lt;br /&gt;
    virtual void init(const JMapInfoIter &amp;amp;);&lt;br /&gt;
    virtual void movement();&lt;br /&gt;
	&lt;br /&gt;
	u32 _C;&lt;br /&gt;
	u32 _10;&lt;br /&gt;
	TMtx34f _14;&lt;br /&gt;
	s32 _44;&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
It is worth noting that the &#039;&#039;&#039;override&#039;&#039;&#039; keyword was not a part of the C++ standard at this point in time, so all overrides are implicit. After all of this is done, you simply have to repeat the process for base classes and document the member functions that are a part of the class.&lt;br /&gt;
&lt;br /&gt;
=== Loops ===&lt;br /&gt;
==== Predefined bounds ====&lt;br /&gt;
Let&#039;s take a simple loop that stores &amp;lt;i&amp;gt;nullptr&amp;lt;/i&amp;gt; in each 8 elements of a pointer array.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class TestClass {&lt;br /&gt;
public:&lt;br /&gt;
    TestClass();&lt;br /&gt;
&lt;br /&gt;
     int* mPointers[8];&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
TestClass::TestClass() {&lt;br /&gt;
    for (int i = 0; i &amp;lt; 8; i++) {&lt;br /&gt;
        mPointers[i] = nullptr;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The output assembly would look something like:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
li r0, 8 # there are 8 elements in this loop&lt;br /&gt;
li r5, 0 # the value to store in the element (nullptr)&lt;br /&gt;
li r4, 0 # the current element offset in the loop&lt;br /&gt;
mtctr r0 # move the number of iterations into the counter register (8)&lt;br /&gt;
&lt;br /&gt;
loop:&lt;br /&gt;
    stwx r5, r3, r4 # store 0 (r5) into the array at r3 (this) + r4 (our current offset, which is i * 4)&lt;br /&gt;
    addi r4, r4, 4 # increment our offset by sizeof(int) since integers are 32-bits&lt;br /&gt;
    bdnz+ loop # branch back to our loop again&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Variable Length Bounds ====&lt;br /&gt;
Let&#039;s take a simple loop that stores &amp;lt;i&amp;gt;nullptr&amp;lt;/i&amp;gt; in each element of a variable-length array. We will have a class with two members, one that contains the pointer array itself, and another that stores the number of pointers.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class TestClass {&lt;br /&gt;
public:&lt;br /&gt;
    TestClass();&lt;br /&gt;
&lt;br /&gt;
     int** mPointers;&lt;br /&gt;
     int mNumPointers;&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
TestClass::TestClass() {&lt;br /&gt;
    mNumPointers = 8;&lt;br /&gt;
    for (int i = 0; i &amp;lt; mNumPointers ; i++) {&lt;br /&gt;
        mPointers[i] = nullptr;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Because we do not know how many pointers we have stored, we cannot use the counter register like we did with a fixed-size array. Instead, the compiler will use a cmpw (signed integer) or cmplw (unsigned) instruction to compare the current iteration to how many pointers are stored in the class.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
li r0, 8 # there are 8 elements in this loop&lt;br /&gt;
li r7, 0 # the value to store in the element (nullptr)&lt;br /&gt;
stw r0, 4(r3) # r3 + 4 is the offset to our member variable &amp;quot;mNumPointers&amp;quot;&lt;br /&gt;
mr r6, r7 # simple copy of the 0 value so we can also use it for our counter&lt;br /&gt;
li r4, 0 # load 0 into our offset&lt;br /&gt;
b loop # branch into our loop&lt;br /&gt;
&lt;br /&gt;
loop:&lt;br /&gt;
    lwz r5, 0(r3) # load our pointer array from this + 0&lt;br /&gt;
    addi r7, r7, 1 # increment our index by 1&lt;br /&gt;
    stwx r6, r5, r4 # store our nullptr value (r6) into r5 + r4 (ptrArray + currentOffset)&lt;br /&gt;
    addi r4, r4, 4 # increment our offset by sizeof(int) since integers are 32-bits&lt;br /&gt;
    lwz r0, 4(r3) # load our number of pointers we will increment by (mNumPointers)&lt;br /&gt;
    cmpw r7, r0 # compare our number of pointers to the current index in our loop&lt;br /&gt;
    blt+ loop # branch if the number is less than mNumPointers&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Structure Access In Arrays (Pointer Array) ====&lt;br /&gt;
More complex forms of loops comes into play when you are iterating through structures and storing / loading members from those structures. Let&#039;s take this class for example:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
struct TestStruct {&lt;br /&gt;
    int SomeMember;&lt;br /&gt;
    int AnotherMember;&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
class TestClass {&lt;br /&gt;
public:&lt;br /&gt;
    TestClass();&lt;br /&gt;
&lt;br /&gt;
    void storeVals();&lt;br /&gt;
&lt;br /&gt;
     TestStruct** mStructures;&lt;br /&gt;
     int mNumStructures;&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
For the sake of simplicity, let&#039;s assume that the TestClass constructor initializes the number of structures to 8, and constructs them accordingly. With that in mind, let&#039;s see how a struct store will work.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void TestClass::storeVals() {&lt;br /&gt;
    for (int i = 0; i &amp;lt; mNumStructures; i++) {&lt;br /&gt;
        mStructures[i]-&amp;gt;AnotherMember = 5;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
The output assembly would look something like:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
li r7, 0 # our &amp;quot;i&amp;quot; used in the loop, starts at 0&lt;br /&gt;
li r4, 0 # our current offset into the array&lt;br /&gt;
li r6, 5 # the value we are storing into the array&lt;br /&gt;
b loop&lt;br /&gt;
&lt;br /&gt;
loop:&lt;br /&gt;
    lwz r5, 0(r3) # load the array pointer&lt;br /&gt;
    addi r7, r7, 1 # increment our current index (i) by 1&lt;br /&gt;
    lwzx r5, r5, r4 # load the current structure, mStructures[i] where r4 is the current offset&lt;br /&gt;
    addi r4, r4, 4 # increment our offset by sizeof(TestStruct*), which is 4&lt;br /&gt;
    stw r6, 4(r5) # store our value (5) into (mStructures[i] + 4), which is our AnotherMember&lt;br /&gt;
    lwz r0, 4(r3) # load the number of structures from TestClass&lt;br /&gt;
    cmpw r7, r0 # compare the current index to our value in TestClass&lt;br /&gt;
    blt+ loop # loop back if it is less than the value&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Structure Access In Arrays (Direct Array) ====&lt;br /&gt;
Let&#039;s take the previous example and modify it a little. Instead of making an array of pointers to the struct instances, let&#039;s store the array &amp;lt;i&amp;gt;directly&amp;lt;/i&amp;gt; into our class instance.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
struct TestStruct {&lt;br /&gt;
    int SomeMember;&lt;br /&gt;
    int AnotherMember;&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
class TestClass {&lt;br /&gt;
public:&lt;br /&gt;
    TestClass();&lt;br /&gt;
&lt;br /&gt;
    void storeVals();&lt;br /&gt;
&lt;br /&gt;
     TestStruct mStructures[8];&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Again, let us assume that the array has already been constructed and everything is initialized as it should be.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void TestClass::storeVals() {&lt;br /&gt;
    for (int i = 0; i &amp;lt; 8; i++) {&lt;br /&gt;
        mStructures[i].AnotherMember = 5;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
The output assembly would look something like:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
li r0, 8 # load our number of iterations (8)&lt;br /&gt;
li r4, 0 # current offset into the array. initialized at 0&lt;br /&gt;
li r6, 5 # the value to store into the array&lt;br /&gt;
mtctr r0 # move the number of iterations into the counter register&lt;br /&gt;
&lt;br /&gt;
loop:&lt;br /&gt;
    add r5, r3, r4 # jump to the offset into the array. r5 = (this + 0) + r4&lt;br /&gt;
    addi r4, r4, 8 # increment our current offset by sizeof(TestStruct), which is 8&lt;br /&gt;
    stw r6, 4(r5) # store our constant value (5) into the loaded struct + 4 (AnotherMember)&lt;br /&gt;
    bdnz+ loop # branch back to the loop if the counter is not 8&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Operator Overloads ==&lt;br /&gt;
There are specific ways that CodeWarrior mangles symbols when overloading operators for classes.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Operator !! Mangled Symbol&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;+&amp;quot; || &amp;quot;pl&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;-&amp;quot; || &amp;quot;mi&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;*&amp;quot; || &amp;quot;ml&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;/&amp;quot; || &amp;quot;dv&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;%&amp;quot; || &amp;quot;md&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;^&amp;quot; || &amp;quot;er&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;/=&amp;quot; || &amp;quot;adv&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;&amp;amp;&amp;quot; || &amp;quot;ad&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;&amp;amp;verbar;&amp;quot; || &amp;quot;or&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;~&amp;quot; || &amp;quot;co&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;!&amp;quot; || &amp;quot;nt&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;=&amp;quot; || &amp;quot;as&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;&amp;lt;&amp;quot; || &amp;quot;lt&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;&amp;gt;&amp;quot; || &amp;quot;gt&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;+=&amp;quot; || &amp;quot;apl&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;-=&amp;quot; || &amp;quot;ami&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;*=&amp;quot; || &amp;quot;amu&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;%=&amp;quot; || &amp;quot;amd&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;^=&amp;quot; || &amp;quot;aer&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;&amp;amp;=&amp;quot; || &amp;quot;aad&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;&amp;amp;verbar;=&amp;quot; || &amp;quot;aor&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;&amp;lt;&amp;lt;&amp;quot; || &amp;quot;ls&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;&amp;gt;&amp;gt;&amp;quot; || &amp;quot;rs&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;&amp;gt;&amp;gt;=&amp;quot; || &amp;quot;ars&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;&amp;lt;&amp;lt;=&amp;quot; || &amp;quot;als&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;==&amp;quot; || &amp;quot;eq&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;!=&amp;quot; || &amp;quot;ne&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;&amp;lt;=&amp;quot; || &amp;quot;le&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;&amp;gt;=&amp;quot; || &amp;quot;ge&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;&amp;amp;&amp;amp;&amp;quot; || &amp;quot;aa&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;&amp;amp;verbar;&amp;amp;verbar;&amp;quot; || &amp;quot;oo&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;++&amp;quot; || &amp;quot;pp&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;--&amp;quot; || &amp;quot;mm&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;()&amp;quot; || &amp;quot;cl&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;[]&amp;quot; || &amp;quot;vc&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;-&amp;gt;&amp;quot; || &amp;quot;rf&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;,&amp;quot; || &amp;quot;cm&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;-&amp;gt;*&amp;quot; || &amp;quot;rm&amp;quot;&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Shibboleet</name></author>
	</entry>
	<entry>
		<id>https://www.lumasworkshop.com/w/index.php?title=Decompiling&amp;diff=863</id>
		<title>Decompiling</title>
		<link rel="alternate" type="text/html" href="https://www.lumasworkshop.com/w/index.php?title=Decompiling&amp;diff=863"/>
		<updated>2025-05-06T17:09:52Z</updated>

		<summary type="html">&lt;p&gt;Shibboleet: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Guides]]&lt;br /&gt;
[[Category:Decompiling]]&lt;br /&gt;
{{WIP}}&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
&#039;&#039;Decompiling&#039;&#039; is the process of taking assembly code and turning it back into a higher level language such as C or C++. It is essentially the reverse of &#039;&#039;compiling&#039;&#039;. &#039;&#039;Matching decompilation&#039;&#039; is the process of decompiling, but having the compiled code match the original assembly 1:1. While matching decompilation is harder than normal decompiling, it can become easier when you understand the patterns of the compiler used. This page aims to let new people understand how this process works, and hopefully be able to get new people into decompilation! While you do not need to be an expert at C or C++ to decompile, it is recommended that you have some experience before attempting decompilation. It is also very recommended that you have some prior knowledge of PowerPC assembly, as that is the key to understanding how a function works. [https://www.nxp.com/docs/en/reference-manual/MPC82XINSET.pdf This document] is a good way to learn or refresh knowledge of the PowerPC architecture. [https://www.warthman.com/images/IBM_PPC_Compiler_Writer%27s_Guide-cwg.pdf This document] is also good to learn some of the patterns that CodeWarrior does.&lt;br /&gt;
&lt;br /&gt;
== Getting Set Up ==&lt;br /&gt;
To begin decompiling &#039;&#039;Super Mario Galaxy&#039;&#039;, you first need to set up the environment. You will need the following tools:&lt;br /&gt;
* [https://gitforwindows.org/ Git (Windows)]&lt;br /&gt;
* Any IDE ([https://code.visualstudio.com/ Visual Studio Code Recommended])&lt;br /&gt;
* [https://www.python.org/downloads/release/python-397/ Python 3.9.7]&lt;br /&gt;
* IDA Pro (recommended) or Ghidra (Not recommended)&lt;br /&gt;
* [https://shibbo.net/smg/RMGK01_01.idb SMG1 Korean IDB (For IDA)]&lt;br /&gt;
* A &#039;&#039;Super Mario Galaxy&#039;&#039; Korean region DOL.&lt;br /&gt;
&lt;br /&gt;
After you have acquired all of these, setting up [https://github.com/shibbo/Petari Petari] is very simple.&lt;br /&gt;
&lt;br /&gt;
# With a new command prompt open, type in &#039;&#039;&#039;git clone https://github.com/shibbo/Petari&#039;&#039;&#039;. This will clone the repository into a directory called &amp;quot;Petari&amp;quot;.&lt;br /&gt;
# In this new &amp;quot;Petari&amp;quot; folder, place the SMG1 Korean &#039;&#039;&#039;main.dol&#039;&#039;&#039; into &#039;&#039;&#039;orig/RMGK01/main.dol&#039;&#039;&#039;.&lt;br /&gt;
# Open a new command prompt in the &amp;quot;Petari&amp;quot; folder.&lt;br /&gt;
# Run the command &#039;&#039;&#039;&#039;ninja&#039;&#039;&#039;. This will download the decompilation toolkit (dtk) and &amp;quot;split&amp;quot; the binary, then compile the code.&lt;br /&gt;
&lt;br /&gt;
== Environment ==&lt;br /&gt;
To properly utilize and use &#039;&#039;Petari&#039;&#039;, it is necessary to understand the structure of the environment. Petari is structured in a way that makes it easy to access and use.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Folder Name !! Description&lt;br /&gt;
|-&lt;br /&gt;
| assets || Just assets for the README.&lt;br /&gt;
|-&lt;br /&gt;
| build || The folder that gets created when &#039;&#039;&#039;ninja&#039;&#039;&#039; is ran. Contains the compiled object files and the compilers.&lt;br /&gt;
|-&lt;br /&gt;
| config || Contains the configurations for each SMG1 version for decompilation and splitting.&lt;br /&gt;
|-&lt;br /&gt;
| docs || Documents relating to using &#039;&#039;&#039;dtk&#039;&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
| include || Contains all of the header files for &#039;&#039;Super Mario Galaxy&#039;&#039; specific code.&lt;br /&gt;
|-&lt;br /&gt;
| md || Documentation for completed functions.&lt;br /&gt;
|-&lt;br /&gt;
| orig || Contains the DOLs for each game version for splitting and matching.&lt;br /&gt;
|-&lt;br /&gt;
| src || Contains all of the source files for &#039;&#039;&#039;Super Mario Galaxy&#039;&#039;&#039; and its libraries.&lt;br /&gt;
|-&lt;br /&gt;
| tools || Misc tools that dtk uses.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Libraries ==&lt;br /&gt;
&#039;&#039;Super Mario Galaxy&#039;&#039; uses a lot of libraries for certain functionality such as heaps, layouts, OS specific code, and more. Each library described in the table below are &#039;&#039;&#039;statically linked&#039;&#039;&#039; to the game, so every library&#039;s used code is inside of the &#039;&#039;main.dol&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
=== Non-SMG Libraries ===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Name !! Language !! Description&lt;br /&gt;
|-&lt;br /&gt;
| JSystem || C++ || Contains classes for backend things, such as heaps and linked lists.&lt;br /&gt;
|-&lt;br /&gt;
| MetroTRK || C || Target Resident Kernel, for debugging.&lt;br /&gt;
|-&lt;br /&gt;
| MSL_C || C &amp;amp; C++ || Contains standard library functions and types.&lt;br /&gt;
|-&lt;br /&gt;
| nw4r || C++ || Contains classes for sounds, layouts, and more. (SMG only uses the layouts and some math functions)&lt;br /&gt;
|-&lt;br /&gt;
| Runtime || C &amp;amp; C++ || Contains functions that relate to CodeWarrior&#039;s runtime code generation (ctor / dtor lists, etc)&lt;br /&gt;
|-&lt;br /&gt;
| RVL_SDK || C || Contains functions that relate to the Wii&#039;s &amp;quot;OS&amp;quot;.&lt;br /&gt;
|-&lt;br /&gt;
| RVLFaceLib || C || Contains functions that relate to Miis.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== SMG Libraries ===&lt;br /&gt;
All of &#039;&#039;Super Mario Galaxy&#039;&#039;&#039;s libraries are written in C++.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Header text !! Header text&lt;br /&gt;
|-&lt;br /&gt;
| Animation || Library for animation playing.&lt;br /&gt;
|-&lt;br /&gt;
| AreaObj || Library for invisible areas that can be accessed by players in the game.&lt;br /&gt;
|-&lt;br /&gt;
| AudioLib || N/A&lt;br /&gt;
|-&lt;br /&gt;
| Boss || Library for all of the bosses and mini-bosses in the game.&lt;br /&gt;
|-&lt;br /&gt;
| Camera || Library for all camera types.&lt;br /&gt;
|-&lt;br /&gt;
| Demo || Library for all cutscenes.&lt;br /&gt;
|-&lt;br /&gt;
| Effect || Library for all effect rendering.&lt;br /&gt;
|-&lt;br /&gt;
| Enemy || Library for all enemies.&lt;br /&gt;
|-&lt;br /&gt;
| GameAudio || N/A&lt;br /&gt;
|-&lt;br /&gt;
| Gravity || Library for all of the gravity types in the game.&lt;br /&gt;
|-&lt;br /&gt;
| LiveActor || Library for LiveActor, which is an actor that can switch states.&lt;br /&gt;
|-&lt;br /&gt;
| Map || Library for map classes that do not directly interact with the player. (ie switches)&lt;br /&gt;
|-&lt;br /&gt;
| MapObj || Library for all of the map objects in the game.&lt;br /&gt;
|-&lt;br /&gt;
| NameObj || Library for the most basic form of an object in the game.&lt;br /&gt;
|-&lt;br /&gt;
| NPC || Library for all of the non-playable characters.&lt;br /&gt;
|-&lt;br /&gt;
| NWC24 || Library for the mail system in the game.&lt;br /&gt;
|-&lt;br /&gt;
| Player || Library for all of the player related functions.&lt;br /&gt;
|-&lt;br /&gt;
| RhythmLib || N/A&lt;br /&gt;
|-&lt;br /&gt;
| Ride || Library for all of the actors that can be controlled by the player.&lt;br /&gt;
|-&lt;br /&gt;
| Scene || Library for all of the game scene related code.&lt;br /&gt;
|-&lt;br /&gt;
| Screen || Library for all of the layouts in the game.&lt;br /&gt;
|-&lt;br /&gt;
| Speaker || Library for the sound effect playing done on the Wiimote.&lt;br /&gt;
|-&lt;br /&gt;
| System || Library for a lot of the game&#039;s backend systems.&lt;br /&gt;
|-&lt;br /&gt;
| Util || Library for utility functions and classes.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Basics ==&lt;br /&gt;
To properly decompile, it is vital to know how a lot of the assembly will translate into C / C++ code. Here are a couple of patterns that you will see when decompiling code.&lt;br /&gt;
&lt;br /&gt;
== Class Mapping ==&lt;br /&gt;
=== Base Class ===&lt;br /&gt;
The first step to decompiling a class is to map out the class itself. You need to be sure that you document every member, its type (as close as you can guess), its virtual functions, and more. The easiest way to achieve this is to look at the class&#039;s &#039;&#039;constructor&#039;&#039;. Seen below, is an example of a &#039;&#039;constructor&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
[[Image:NameObj_Ctor.png|frameless|700px|The constructor for &#039;&#039;NameObj&#039;&#039;.]]&lt;br /&gt;
&lt;br /&gt;
There are a couple of takeaways from this screenshot:&lt;br /&gt;
* The constructor passes an argument, which is a &#039;&#039;&#039;const char *&#039;&#039;&#039; (contained in r4) and is stored in (r3 + 0x4).&lt;br /&gt;
* (r3 + 0x0) is where the vtable is &#039;&#039;usually&#039;&#039; stored when a class has virtual functions. There are rare execptions.&lt;br /&gt;
* (r3 + 0x8) is stored with a &#039;&#039;&#039;sth&#039;&#039;&#039;, which means that it is a &#039;&#039;&#039;short&#039;&#039;&#039; datatype.&lt;br /&gt;
* (r3 + 0xA) is also stored with a &#039;&#039;&#039;sth&#039;&#039;&#039;, but with a &#039;&#039;&#039;-1&#039;&#039;&#039; value, so we know for sure that this type is &#039;&#039;signed&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Keep in mind that a constructor does not have to initialize every single member variable in the class! So there could be other members in a class that aren&#039;t mentioned in the constructor at all. After you look at the constructor, look around at the &#039;&#039;member functions&#039;&#039; to see if they use any members that are not initialized in the constructor. You can always verify if your class setup is correct when you can find where this class is created using the &#039;&#039;&#039;new&#039;&#039;&#039; operator. Check if the size passed to the &#039;&#039;&#039;new&#039;&#039;&#039; call matches the size of the class that you have mapped. If it is smaller, you are missing members. If it is bigger, you have too many! Remember that the vtable is implicitly stored at &#039;&#039;&#039;(this + 0x0)&#039;&#039;&#039;, so you do not have to explicitly define it. With all of these members documented, our class setup looks a little like this so far:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class NameObj {&lt;br /&gt;
public:&lt;br /&gt;
    NameObj(const char *pName);&lt;br /&gt;
&lt;br /&gt;
    /* remember that the vtable will be placed here once we define our virtuals! */&lt;br /&gt;
    /* 0x4 */   const char* mName;&lt;br /&gt;
    /* 0x8 */   volatile u16 mFlags;&lt;br /&gt;
    /* 0xA */   s16 mExecutorIdx;&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
After the members comes the &#039;&#039;&#039;vtable&#039;&#039;&#039;, or &#039;&#039;virtual table&#039;&#039;. It is an array of function pointers that can be overridden by classes that inherit the parent class. The vtable for &#039;&#039;&#039;NameObj&#039;&#039;&#039; looks like this:&lt;br /&gt;
[[Image:NameObj_Vtable.png|frameless|700px|The vtable for &#039;&#039;NameObj&#039;&#039;.]]&lt;br /&gt;
&lt;br /&gt;
To document the vtable, you simply document every single function placed here that contains the class name of the class you are currently decompiling. Since &#039;&#039;NameObj&#039;&#039; is a base class, every single function here is going to be defined. If a class overrides a function, you will only document the functions that are overridden. After documenting the vtable, our class looks something like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class NameObj {&lt;br /&gt;
public:&lt;br /&gt;
    NameObj(const char *pName);&lt;br /&gt;
&lt;br /&gt;
    virtual ~NameObj();&lt;br /&gt;
    virtual void init(const JMapInfoIter &amp;amp;rIter);&lt;br /&gt;
    virtual void initAfterPlacement();&lt;br /&gt;
    virtual void movement();&lt;br /&gt;
    virtual void draw() const;&lt;br /&gt;
    virtual void calcAnim();&lt;br /&gt;
    virtual void calcViewAndEntry();&lt;br /&gt;
&lt;br /&gt;
    /* remember that the vtable will be placed here once we define our virtuals! */&lt;br /&gt;
    /* 0x4 */   const char* mName;&lt;br /&gt;
    /* 0x8 */   volatile u16 mFlags;&lt;br /&gt;
    /* 0xA */   s16 mExecutorIdx;&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Once the vtable is complete, you want to document all of the member functions that are in the class. Since &#039;&#039;Super Mario Galaxy 1&#039;&#039; has a symbol map, we can easily find the member functions that &#039;&#039;NameObj&#039;&#039; contains. Once you have figured out their return types and their arguments, you can finish mapping out a class! After finding all of &#039;&#039;NameObj&#039;&#039;&#039;s member functions, the class looks like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class NameObj {&lt;br /&gt;
public:&lt;br /&gt;
    NameObj(const char *pName);&lt;br /&gt;
&lt;br /&gt;
    virtual ~NameObj();&lt;br /&gt;
    virtual void init(const JMapInfoIter &amp;amp;rIter);&lt;br /&gt;
    virtual void initAfterPlacement();&lt;br /&gt;
    virtual void movement();&lt;br /&gt;
    virtual void draw() const;&lt;br /&gt;
    virtual void calcAnim();&lt;br /&gt;
    virtual void calcViewAndEntry();&lt;br /&gt;
&lt;br /&gt;
    void initWithoutIter();&lt;br /&gt;
    void setName(const char *pName);&lt;br /&gt;
    void executeMovement();&lt;br /&gt;
    void requestSuspend();&lt;br /&gt;
    void requestResume();&lt;br /&gt;
    void syncWithFlags();&lt;br /&gt;
&lt;br /&gt;
    /* remember that the vtable will be placed here once we define our virtuals! */&lt;br /&gt;
    /* 0x4 */   const char* mName;&lt;br /&gt;
    /* 0x8 */   volatile u16 mFlags;&lt;br /&gt;
    /* 0xA */   s16 mExecutorIdx;&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Inheriting Class ===&lt;br /&gt;
The process of mapping a class that inherits another class is mainly the same as mapping a base class, except there are things to watch out for so you don&#039;t accidentally duplicate a member variable. The first step is to look at the &#039;&#039;constructor&#039;&#039; of the class you want to map:&lt;br /&gt;
&lt;br /&gt;
[[Image:TripodBossCoin_Ctor.png|frameless|700px|The constructor for &#039;&#039;TripodBossCoin&#039;&#039;.]]&lt;br /&gt;
&lt;br /&gt;
There are a few takeaways from this by looking at the constructor:&lt;br /&gt;
* The class inherits NameObj. Since &#039;&#039;NameObj&#039;&#039; is 0xC bytes long, we know that any member variables for &#039;&#039;TripodBossCoin&#039;&#039; start at &#039;&#039;&#039;0xC&#039;&#039;&#039;.&lt;br /&gt;
* The vtable pointer &#039;&#039;&#039;(this + 0x0)&#039;&#039;&#039; from &#039;&#039;NameObj&#039;&#039; is overridden with the vtable for &#039;&#039;TripodBossCoin&#039;&#039; implicitly.&lt;br /&gt;
* &#039;&#039;&#039;(this + 0xC)&#039;&#039;&#039; is a 32-bit integer initialized to 0. It is not possible to determine if it is signed or not from this store alone.&lt;br /&gt;
* &#039;&#039;&#039;(this + 0x10)&#039;&#039;&#039; is the same scenario as &#039;&#039;&#039;(this + 0xC)&#039;&#039;&#039;.&lt;br /&gt;
* There is a direct instance of &#039;&#039;JGeometry::TMatrix34&amp;lt;JGeometry::SMatrix34C&amp;lt;f32&amp;gt;&#039;&#039; at 0x14. (in Petari &amp;amp; Syati this is typedef&#039;d as &#039;&#039;TMtx34f&#039;&#039;). Since &#039;&#039;TMtx34f&#039;&#039; is 0x30 in size, the next member variable is at 0x14 + 0x30, which is &#039;&#039;&#039;0x44&#039;&#039;&#039;.&lt;br /&gt;
* &#039;&#039;&#039;(this + 0x44)&#039;&#039;&#039; is a signed 32-bit integer, due to &#039;&#039;&#039;-1&#039;&#039;&#039; being stored to it.&lt;br /&gt;
&lt;br /&gt;
After these observations, our class looks like this:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class TripodBossCoin : public NameObj {&lt;br /&gt;
public:&lt;br /&gt;
	TripodBossCoin(const char *);&lt;br /&gt;
	&lt;br /&gt;
	u32 _C;&lt;br /&gt;
	u32 _10;&lt;br /&gt;
	TMtx34f _14;&lt;br /&gt;
	s32 _44;&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Next are the virtuals. The process is a little different from a base class. Let&#039;s take a look at the vtable for &#039;&#039;TripodBossCoin&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
[[Image:TripodBossCoin_Vtable.png|frameless|700px|The vtable for &#039;&#039;TripodBossCoin&#039;&#039;.]]&lt;br /&gt;
&lt;br /&gt;
The biggest takeaway from this screenshot is that only three virtuals are overriden by &#039;&#039;TripodBossCoin&#039;&#039;. And those three functions are &#039;&#039;&#039;TripodBossCoin::~TripodBossCoin()&#039;&#039;&#039;, &#039;&#039;&#039;TripodBossCoin::init()&#039;&#039;&#039; and &#039;&#039;&#039;TripodBossCoin::movement()&#039;&#039;&#039;. So we define them as such:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class TripodBossCoin : public NameObj {&lt;br /&gt;
public:&lt;br /&gt;
	TripodBossCoin(const char *);&lt;br /&gt;
&lt;br /&gt;
    virtual ~TripodBossCoin();&lt;br /&gt;
    virtual void init(const JMapInfoIter &amp;amp;);&lt;br /&gt;
    virtual void movement();&lt;br /&gt;
	&lt;br /&gt;
	u32 _C;&lt;br /&gt;
	u32 _10;&lt;br /&gt;
	TMtx34f _14;&lt;br /&gt;
	s32 _44;&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
It is worth noting that the &#039;&#039;&#039;override&#039;&#039;&#039; keyword was not a part of the C++ standard at this point in time, so all overrides are implicit. After all of this is done, you simply have to repeat the process for base classes and document the member functions that are a part of the class.&lt;br /&gt;
&lt;br /&gt;
=== Loops ===&lt;br /&gt;
==== Predefined bounds ====&lt;br /&gt;
Let&#039;s take a simple loop that stores &amp;lt;i&amp;gt;nullptr&amp;lt;/i&amp;gt; in each 8 elements of a pointer array.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class TestClass {&lt;br /&gt;
public:&lt;br /&gt;
    TestClass();&lt;br /&gt;
&lt;br /&gt;
     int* mPointers[8];&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
TestClass::TestClass() {&lt;br /&gt;
    for (int i = 0; i &amp;lt; 8; i++) {&lt;br /&gt;
        mPointers[i] = nullptr;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The output assembly would look something like:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
li r0, 8 # there are 8 elements in this loop&lt;br /&gt;
li r5, 0 # the value to store in the element (nullptr)&lt;br /&gt;
li r4, 0 # the current element offset in the loop&lt;br /&gt;
mtctr r0 # move the number of iterations into the counter register (8)&lt;br /&gt;
&lt;br /&gt;
loop:&lt;br /&gt;
    stwx r5, r3, r4 # store 0 (r5) into the array at r3 (this) + r4 (our current offset, which is i * 4)&lt;br /&gt;
    addi r4, r4, 4 # increment our offset by sizeof(int) since integers are 32-bits&lt;br /&gt;
    bdnz+ loop # branch back to our loop again&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Variable Length Bounds ====&lt;br /&gt;
Let&#039;s take a simple loop that stores &amp;lt;i&amp;gt;nullptr&amp;lt;/i&amp;gt; in each element of a variable-length array. We will have a class with two members, one that contains the pointer array itself, and another that stores the number of pointers.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class TestClass {&lt;br /&gt;
public:&lt;br /&gt;
    TestClass();&lt;br /&gt;
&lt;br /&gt;
     int** mPointers;&lt;br /&gt;
     int mNumPointers;&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
TestClass::TestClass() {&lt;br /&gt;
    mNumPointers = 8;&lt;br /&gt;
    for (int i = 0; i &amp;lt; mNumPointers ; i++) {&lt;br /&gt;
        mPointers[i] = nullptr;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Because we do not know how many pointers we have stored, we cannot use the counter register like we did with a fixed-size array. Instead, the compiler will use a cmpw (signed integer) or cmplw (unsigned) instruction to compare the current iteration to how many pointers are stored in the class.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
li r0, 8 # there are 8 elements in this loop&lt;br /&gt;
li r7, 0 # the value to store in the element (nullptr)&lt;br /&gt;
stw r0, 4(r3) # r3 + 4 is the offset to our member variable &amp;quot;mNumPointers&amp;quot;&lt;br /&gt;
mr r6, r7 # simple copy of the 0 value so we can also use it for our counter&lt;br /&gt;
li r4, 0 # load 0 into our offset&lt;br /&gt;
b loop # branch into our loop&lt;br /&gt;
&lt;br /&gt;
loop:&lt;br /&gt;
    lwz r5, 0(r3) # load our pointer array from this + 0&lt;br /&gt;
    addi r7, r7, 1 # increment our index by 1&lt;br /&gt;
    stwx r6, r5, r4 # store our nullptr value (r6) into r5 + r4 (ptrArray + currentOffset)&lt;br /&gt;
    addi r4, r4, 4 # increment our offset by sizeof(int) since integers are 32-bits&lt;br /&gt;
    lwz r0, 4(r3) # load our number of pointers we will increment by (mNumPointers)&lt;br /&gt;
    cmpw r7, r0 # compare our number of pointers to the current index in our loop&lt;br /&gt;
    blt+ loop # branch if the number is less than mNumPointers&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Structure Access In Arrays (Pointer Array) ====&lt;br /&gt;
More complex forms of loops comes into play when you are iterating through structures and storing / loading members from those structures. Let&#039;s take this class for example:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
struct TestStruct {&lt;br /&gt;
    int SomeMember;&lt;br /&gt;
    int AnotherMember;&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
class TestClass {&lt;br /&gt;
public:&lt;br /&gt;
    TestClass();&lt;br /&gt;
&lt;br /&gt;
    void storeVals();&lt;br /&gt;
&lt;br /&gt;
     TestStruct** mStructures;&lt;br /&gt;
     int mNumStructures;&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
For the sake of simplicity, let&#039;s assume that the TestClass constructor initializes the number of structures to 8, and constructs them accordingly. With that in mind, let&#039;s see how a struct store will work.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void TestClass::storeVals() {&lt;br /&gt;
    for (int i = 0; i &amp;lt; mNumStructures; i++) {&lt;br /&gt;
        mStructures[i]-&amp;gt;AnotherMember = 5;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
The output assembly would look something like:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
li r7, 0 # our &amp;quot;i&amp;quot; used in the loop, starts at 0&lt;br /&gt;
li r4, 0 # our current offset into the array&lt;br /&gt;
li r6, 5 # the value we are storing into the array&lt;br /&gt;
b loop&lt;br /&gt;
&lt;br /&gt;
loop:&lt;br /&gt;
    lwz r5, 0(r3) # load the array pointer&lt;br /&gt;
    addi r7, r7, 1 # increment our current index (i) by 1&lt;br /&gt;
    lwzx r5, r5, r4 # load the current structure, mStructures[i] where r4 is the current offset&lt;br /&gt;
    addi r4, r4, 4 # increment our offset by sizeof(TestStruct*), which is 4&lt;br /&gt;
    stw r6, 4(r5) # store our value (5) into (mStructures[i] + 4), which is our AnotherMember&lt;br /&gt;
    lwz r0, 4(r3) # load the number of structures from TestClass&lt;br /&gt;
    cmpw r7, r0 # compare the current index to our value in TestClass&lt;br /&gt;
    blt+ loop # loop back if it is less than the value&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Structure Access In Arrays (Direct Array) ====&lt;br /&gt;
Let&#039;s take the previous example and modify it a little. Instead of making an array of pointers to the struct instances, let&#039;s store the array &amp;lt;i&amp;gt;directly&amp;lt;/i&amp;gt; into our class instance.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
struct TestStruct {&lt;br /&gt;
    int SomeMember;&lt;br /&gt;
    int AnotherMember;&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
class TestClass {&lt;br /&gt;
public:&lt;br /&gt;
    TestClass();&lt;br /&gt;
&lt;br /&gt;
    void storeVals();&lt;br /&gt;
&lt;br /&gt;
     TestStruct mStructures[8];&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Again, let us assume that the array has already been constructed and everything is initialized as it should be.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void TestClass::storeVals() {&lt;br /&gt;
    for (int i = 0; i &amp;lt; 8; i++) {&lt;br /&gt;
        mStructures[i].AnotherMember = 5;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
The output assembly would look something like:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
li r0, 8 # load our number of iterations (8)&lt;br /&gt;
li r4, 0 # current offset into the array. initialized at 0&lt;br /&gt;
li r6, 5 # the value to store into the array&lt;br /&gt;
mtctr r0 # move the number of iterations into the counter register&lt;br /&gt;
&lt;br /&gt;
loop:&lt;br /&gt;
    add r5, r3, r4 # jump to the offset into the array. r5 = (this + 0) + r4&lt;br /&gt;
    addi r4, r4, 8 # increment our current offset by sizeof(TestStruct), which is 8&lt;br /&gt;
    stw r6, 4(r5) # store our constant value (5) into the loaded struct + 4 (AnotherMember)&lt;br /&gt;
    bdnz+ loop # branch back to the loop if the counter is not 8&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Operator Overloads ==&lt;br /&gt;
There are specific ways that CodeWarrior mangles symbols when overloading operators for classes.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Operator !! Mangled Symbol&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;+&amp;quot; || &amp;quot;pl&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;-&amp;quot; || &amp;quot;mi&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;*&amp;quot; || &amp;quot;ml&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;/&amp;quot; || &amp;quot;dv&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;%&amp;quot; || &amp;quot;md&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;^&amp;quot; || &amp;quot;er&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;/=&amp;quot; || &amp;quot;adv&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;&amp;amp;&amp;quot; || &amp;quot;ad&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;&amp;amp;verbar;&amp;quot; || &amp;quot;or&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;~&amp;quot; || &amp;quot;co&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;!&amp;quot; || &amp;quot;nt&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;=&amp;quot; || &amp;quot;as&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;&amp;lt;&amp;quot; || &amp;quot;lt&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;&amp;gt;&amp;quot; || &amp;quot;gt&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;+=&amp;quot; || &amp;quot;apl&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;-=&amp;quot; || &amp;quot;ami&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;*=&amp;quot; || &amp;quot;amu&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;%=&amp;quot; || &amp;quot;amd&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;^=&amp;quot; || &amp;quot;aer&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;&amp;amp;=&amp;quot; || &amp;quot;aad&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;&amp;amp;verbar;=&amp;quot; || &amp;quot;aor&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;&amp;lt;&amp;lt;&amp;quot; || &amp;quot;ls&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;&amp;gt;&amp;gt;&amp;quot; || &amp;quot;rs&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;&amp;gt;&amp;gt;=&amp;quot; || &amp;quot;ars&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;&amp;lt;&amp;lt;=&amp;quot; || &amp;quot;als&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;==&amp;quot; || &amp;quot;eq&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;!=&amp;quot; || &amp;quot;ne&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;&amp;lt;=&amp;quot; || &amp;quot;le&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;&amp;gt;=&amp;quot; || &amp;quot;ge&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;&amp;amp;&amp;amp;&amp;quot; || &amp;quot;aa&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;&amp;amp;verbar;&amp;amp;verbar;&amp;quot; || &amp;quot;oo&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;++&amp;quot; || &amp;quot;pp&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;--&amp;quot; || &amp;quot;mm&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;()&amp;quot; || &amp;quot;cl&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;[]&amp;quot; || &amp;quot;vc&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;-&amp;gt;&amp;quot; || &amp;quot;rf&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;,&amp;quot; || &amp;quot;cm&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;-&amp;gt;*&amp;quot; || &amp;quot;rm&amp;quot;&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Shibboleet</name></author>
	</entry>
	<entry>
		<id>https://www.lumasworkshop.com/w/index.php?title=THP_(File_Format)&amp;diff=859</id>
		<title>THP (File Format)</title>
		<link rel="alternate" type="text/html" href="https://www.lumasworkshop.com/w/index.php?title=THP_(File_Format)&amp;diff=859"/>
		<updated>2025-04-22T18:52:32Z</updated>

		<summary type="html">&lt;p&gt;Shibboleet: clarify what THP stands for&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:File formats]]&lt;br /&gt;
{{SDK Reference}}&lt;br /&gt;
&#039;&#039;&#039;THP&#039;&#039;&#039; stands for &#039;&#039;&#039;T&#039;&#039;&#039;ecmo &#039;&#039;&#039;H&#039;&#039;&#039;ome &#039;&#039;&#039;P&#039;&#039;&#039;roduction. It&#039;s mainly used for prerendered cutscenes and other prerendered videos. This format was also used on the Nintendo GameCube.&lt;br /&gt;
&lt;br /&gt;
= Format Specifications =&lt;br /&gt;
Below you&#039;ll find helpful tables on how the file is structured&lt;br /&gt;
== Header ==&lt;br /&gt;
Each THP starts with a &#039;&#039;header&#039;&#039;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; &lt;br /&gt;
! Offset !! Type !! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x00 || String || &amp;quot;THP0&amp;quot; in ASCII&lt;br /&gt;
|-&lt;br /&gt;
| 0x04 || UInt32 || &#039;&#039;Version Number&#039;&#039;. SMG uses 0x1048832&lt;br /&gt;
|-&lt;br /&gt;
| 0x08 || UInt32 || The Maximum Frame data size&lt;br /&gt;
|-&lt;br /&gt;
| 0x0C || UInt32 || Max no. of Audio Samples. SMG uses 0x570556416&lt;br /&gt;
|-&lt;br /&gt;
| 0x10 || Float || Frame Rate. Defaults to 29.97 in &#039;&#039;THPConv.exe&#039;&#039;. SMG uses 59.97 (the max value)&lt;br /&gt;
|-&lt;br /&gt;
| 0x14 || UInt32 || Total number of frames&lt;br /&gt;
|-&lt;br /&gt;
| 0x18 || UInt32 || The length of the first frame&lt;br /&gt;
|-&lt;br /&gt;
| 0x1C || UInt32 || The length of ALL frames&lt;br /&gt;
|-&lt;br /&gt;
| 0x20 || UInt32 || Offset to components&lt;br /&gt;
|-&lt;br /&gt;
| 0x24 || UInt32 || Offset to FrameOffsetData&lt;br /&gt;
|-&lt;br /&gt;
| 0x28 || UInt32 || First frame offset&lt;br /&gt;
|-&lt;br /&gt;
| 0x2C || UInt32 || Last frame offset&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
== Frame Comp Info ==&lt;br /&gt;
This section is for the Component structure&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; &lt;br /&gt;
! Offset !! Type !! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x00 || UInt32 || Number of components in this frame. Max is 16&lt;br /&gt;
|-&lt;br /&gt;
| 0x04 || UInt8[16] || Component types (0 = video, 1 = audio, -1 = none)&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
== Video ==&lt;br /&gt;
This section contains the video data.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Offset !! Type !! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x00 || UInt32 || Width. SMG uses 640&lt;br /&gt;
|-&lt;br /&gt;
| 0x04 || UInt32 || Height. SMG uses 368&lt;br /&gt;
|-&lt;br /&gt;
| 0x08 || UInt32 || Video format (Only used in certain versions)&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Audio ==&lt;br /&gt;
This sections contains the audio data.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Offset !! Type !! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x00 || UInt32 || Number of Audio Channels (Min is 0, Max is 2)&lt;br /&gt;
|-&lt;br /&gt;
| 0x04 || UInt32 || Frequency&lt;br /&gt;
|-&lt;br /&gt;
| 0x08 || UInt32 || Number of samples played&lt;br /&gt;
|-&lt;br /&gt;
| 0x0C || UInt32 || Number of tracks (Only used in certain versions)&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
== Frame ==&lt;br /&gt;
A frame starts with a frame &#039;&#039;header&#039;&#039;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Offset !! Type !! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x00 || UInt32 || Total size of the next frame&lt;br /&gt;
|-&lt;br /&gt;
| 0x04 || UInt32 || Total size of previous frame&lt;br /&gt;
|-&lt;br /&gt;
| 0x08 || UInt32 || Total size of the current frame&lt;br /&gt;
|-&lt;br /&gt;
| 0x0C || UInt32 || Audio size (Only if there is audio in the current frame)&lt;br /&gt;
|-&lt;br /&gt;
| 0x0C or 0x10 || colspan=&amp;quot;2&amp;quot; style=&amp;quot;text-align:center; background: #d0d0d0;&amp;quot; | Image Data&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
=== Video ===&lt;br /&gt;
Video data&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Offset !! Type !! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x00 || Int8[&#039;&#039;&#039;I&#039;&#039;&#039;] || Image Data&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;I&#039;&#039;&#039; || colspan=&amp;quot;2&amp;quot; style=&amp;quot;text-align:center; background: #d0d0d0;&amp;quot; | End of Image Data&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
=== Audio ===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Offset !! Type !! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x00 || UInt32 || Channel size&lt;br /&gt;
|-&lt;br /&gt;
| 0x04 || UInt32 || Number of samples&lt;br /&gt;
|-&lt;br /&gt;
| 0x08 || Int16[16] || Table 1&lt;br /&gt;
|-&lt;br /&gt;
| 0x28 || Int16[16] || Table 2&lt;br /&gt;
|-&lt;br /&gt;
| 0x48 || Int16 || Channel 1 previous 1&lt;br /&gt;
|-&lt;br /&gt;
| 0x4A || Int16 || Channel 1 previous 2&lt;br /&gt;
|-&lt;br /&gt;
| 0x4C || Int16 || Channel 2 previous 1&lt;br /&gt;
|-&lt;br /&gt;
| 0x4E || Int16 || Channel 2 previous 2&lt;br /&gt;
|-&lt;br /&gt;
| 0x50 || colspan=&amp;quot;2&amp;quot; style=&amp;quot;text-align:center; background: #d0d0d0;&amp;quot; | Audio Data&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Offset !! Type !! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x00 || Int8[&#039;&#039;&#039;M&#039;&#039;&#039;] || Audio Data&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;M&#039;&#039;&#039; || colspan=&amp;quot;2&amp;quot; style=&amp;quot;text-align:center; background: #d0d0d0;&amp;quot; | End of Audio Data&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
= Tools =&lt;br /&gt;
The following tools can handle THP files:&lt;br /&gt;
* [https://github.com/soopercool101/BrawlCrate BrawlCrate] (Can only view the files)&lt;br /&gt;
* [https://www.ffmpeg.org/ ffmpeg] (Can convert THP videos to other video formats)&lt;br /&gt;
* [https://sites.google.com/site/wiiflowiki4/trailers/thp-video-convertor Wiiflow THP Video Converter] (Creates thp videos. Only supports 30 fps)&lt;br /&gt;
* [https://github.com/Lord-Giganticus/THP-Conveter THP-Converter] (Can convert to and from THP files using other programs)&lt;br /&gt;
* [[THPConv.exe]] (Nintendo&#039;s internal program to make thp videos, used by other programs)&lt;/div&gt;</summary>
		<author><name>Shibboleet</name></author>
	</entry>
	<entry>
		<id>https://www.lumasworkshop.com/w/index.php?title=Paired_Singles&amp;diff=831</id>
		<title>Paired Singles</title>
		<link rel="alternate" type="text/html" href="https://www.lumasworkshop.com/w/index.php?title=Paired_Singles&amp;diff=831"/>
		<updated>2025-02-16T23:16:21Z</updated>

		<summary type="html">&lt;p&gt;Shibboleet: Created page with &amp;quot;&amp;#039;&amp;#039;Paired Singles&amp;#039;&amp;#039; are a part of the Broadway / Gekko processor that allows for two single-precision floating point values to be stored in a single register. This allows for faster vector and matrix math. &amp;#039;&amp;#039;Paired Singles&amp;#039;&amp;#039; are handwritten assembly code; they cannot be generated by the compiler &amp;#039;&amp;#039;&amp;#039;unless&amp;#039;&amp;#039;&amp;#039; it is for pushing / popping the stack frame in a functions prologue or epilogue. The &amp;#039;&amp;#039;Super Mario Galaxy&amp;#039;&amp;#039; games do not use very many different paired single instruc...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;Paired Singles&#039;&#039; are a part of the Broadway / Gekko processor that allows for two single-precision floating point values to be stored in a single register. This allows for faster vector and matrix math. &#039;&#039;Paired Singles&#039;&#039; are handwritten assembly code; they cannot be generated by the compiler &#039;&#039;&#039;unless&#039;&#039;&#039; it is for pushing / popping the stack frame in a functions prologue or epilogue. The &#039;&#039;Super Mario Galaxy&#039;&#039; games do not use very many different paired single instructions, so this page only covers the ones used by the game.&lt;br /&gt;
&lt;br /&gt;
== Loading And Storing ==&lt;br /&gt;
=== psq_l ===&lt;br /&gt;
Loads a paired single into the destination register &#039;&#039;&#039;FRD&#039;&#039;&#039;.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
psq_l FRD, D(RA), W, I&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Name !! Description&lt;br /&gt;
|-&lt;br /&gt;
| FRD|| Destination register for the paired single loaded.&lt;br /&gt;
|-&lt;br /&gt;
| D(RA)|| Memory address, where &#039;&#039;&#039;D&#039;&#039;&#039; is the offset, and &#039;&#039;&#039;RA&#039;&#039;&#039; is the source register.&lt;br /&gt;
|-&lt;br /&gt;
| W || Size of the paired single. &#039;&#039;&#039;0&#039;&#039;&#039; loads the first two floats where &#039;&#039;&#039;1&#039;&#039;&#039; only loads the third.&lt;br /&gt;
|-&lt;br /&gt;
| I || Determines the type of register to load from. Only used as &#039;&#039;&#039;0&#039;&#039;&#039; (floating point).&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Math ==&lt;br /&gt;
=== ps_madd ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
ps_madd FRT, FRA, FRB, FRC&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\text{FRT}_{\text{high}} = (\text{FRA}_{\text{high}} \times \text{FRB}_{\text{high}}) + \text{FRC}_{\text{high}}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\text{FRT}_{\text{low}} = (\text{FRA}_{\text{low}} \times \text{FRB}_{\text{low}}) + \text{FRC}_{\text{low}}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;/div&gt;</summary>
		<author><name>Shibboleet</name></author>
	</entry>
	<entry>
		<id>https://www.lumasworkshop.com/w/index.php?title=SMG1_to_SMG2_Code_Changes&amp;diff=771</id>
		<title>SMG1 to SMG2 Code Changes</title>
		<link rel="alternate" type="text/html" href="https://www.lumasworkshop.com/w/index.php?title=SMG1_to_SMG2_Code_Changes&amp;diff=771"/>
		<updated>2024-12-17T01:48:51Z</updated>

		<summary type="html">&lt;p&gt;Shibboleet: Created page with &amp;quot;Between the game &amp;#039;&amp;#039;Super Mario Galaxy&amp;#039;&amp;#039; and &amp;#039;&amp;#039;Super Mario Galaxy 2&amp;#039;&amp;#039;, a few changes were made under the hood to make things easier to work with in the codebase. This page will be listing those changes that the developers made.  == NameObj == &amp;#039;&amp;#039;NameObj&amp;#039;&amp;#039; is the most basic form of an object in the game. It contains an executor index, the execution flags, and the name of the object. &amp;lt;pre&amp;gt; class NameObj { public:   NameObj(const char *pName);    virtual ~NameObj();   virtual...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Between the game &#039;&#039;Super Mario Galaxy&#039;&#039; and &#039;&#039;Super Mario Galaxy 2&#039;&#039;, a few changes were made under the hood to make things easier to work with in the codebase. This page will be listing those changes that the developers made.&lt;br /&gt;
&lt;br /&gt;
== NameObj ==&lt;br /&gt;
&#039;&#039;NameObj&#039;&#039; is the most basic form of an object in the game. It contains an executor index, the execution flags, and the name of the object.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class NameObj {&lt;br /&gt;
public:&lt;br /&gt;
  NameObj(const char *pName);&lt;br /&gt;
&lt;br /&gt;
  virtual ~NameObj();&lt;br /&gt;
  virtual void init(const JMapInfoIter &amp;amp;rIter);&lt;br /&gt;
  virtual void initAfterPlacement();&lt;br /&gt;
  virtual void movement();&lt;br /&gt;
  virtual void draw() const;&lt;br /&gt;
  virtual void calcAnim();&lt;br /&gt;
  virtual void calcViewAndEntry();&lt;br /&gt;
&lt;br /&gt;
  /* 0x4 */ const char *mName;&lt;br /&gt;
  /* 0x8 */ volatile u16 mFlags;&lt;br /&gt;
  /* 0xA */ s16 mExecutorIdx; &lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
However, &#039;&#039;Super Mario Galaxy 2&#039;&#039; changes the base object a little. It adds a &#039;&#039;JMapLinkInfo&#039;&#039; instance to the NameObj for easier linking using the new &#039;&#039;LinkID&#039;&#039; attribute introduced in the JMap. It also introduces two new virtual functions, &#039;&#039;NameObj::startMovement&#039;&#039; and &#039;&#039;NameObj::endMovement&#039;&#039; which are called before and after a movement is executed.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class NameObj {&lt;br /&gt;
public:&lt;br /&gt;
    NameObj(const char *);&lt;br /&gt;
&lt;br /&gt;
    virtual ~NameObj();&lt;br /&gt;
    virtual void init(const JMapInfoIter &amp;amp;);&lt;br /&gt;
    virtual void initAfterPlacement();&lt;br /&gt;
    virtual void movement();&lt;br /&gt;
    virtual void draw() const;&lt;br /&gt;
    virtual void calcAnim();&lt;br /&gt;
    virtual void calcViewAndEntry();&lt;br /&gt;
    virtual void startMovement();&lt;br /&gt;
    virtual void endMovement();&lt;br /&gt;
&lt;br /&gt;
    const char* mName;          // 0x04&lt;br /&gt;
    vu16 mFlags;                // 0x08&lt;br /&gt;
    s16 mExecutorIdx;           // 0x0A&lt;br /&gt;
    JMapLinkInfo mLinkInfo;     // 0x0C&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== StageSwitchContainer ==&lt;br /&gt;
&#039;&#039;StageSwitchContainer&#039;&#039; is the class that controls the switches for a specific galaxy. They are very similar in both games, with a small change (mainly for code cleanliness) made to how it works.&lt;br /&gt;
&lt;br /&gt;
In &#039;&#039;Super Mario Galaxy&#039;&#039;, the &#039;&#039;StageSwitchContainer&#039;&#039; class stores an array of &#039;&#039;StageSwitch::ContainerSwitch&#039;&#039; instances that contained &amp;quot;data&amp;quot; (which is the Zone ID it is contained in) and the &#039;&#039;ZoneSwitch&#039;&#039; pointer which contained the actual switch data itself.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class StageSwitchContainer : public NameObj {&lt;br /&gt;
public:&lt;br /&gt;
    struct ContainerSwitch {&lt;br /&gt;
        s32 mData;              // 0x0&lt;br /&gt;
        ZoneSwitch* mSwitch;    // 0x4&lt;br /&gt;
    };&lt;br /&gt;
    ContainerSwitch mSwitches[20];  // 0xC&lt;br /&gt;
    s32 mCount;                     // 0xAC&lt;br /&gt;
    ZoneSwitch* mGlobalSwitches;    // 0xB0&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The developers probably realized that the zone ID here does not need to be stored in conjunction with the switch, it can just be stored &#039;&#039;inside&#039;&#039; of the switch instance. So, they added the Zone ID attribute into &#039;&#039;ZoneSwitch&#039;&#039; and made the array smaller, as well as making it a pointer array of &#039;&#039;ZoneSwitch&#039;&#039; instances.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class StageSwitchContainer : public NameObj {&lt;br /&gt;
public:&lt;br /&gt;
    ZoneSwitch* mZoneSwitches[0x10];     // 0x14&lt;br /&gt;
    s32 mSwitchCount;                   // 0x54&lt;br /&gt;
    ZoneSwitch* mParentZone;            // 0x58&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Shibboleet</name></author>
	</entry>
	<entry>
		<id>https://www.lumasworkshop.com/w/index.php?title=Decompiling&amp;diff=182</id>
		<title>Decompiling</title>
		<link rel="alternate" type="text/html" href="https://www.lumasworkshop.com/w/index.php?title=Decompiling&amp;diff=182"/>
		<updated>2024-04-06T12:45:01Z</updated>

		<summary type="html">&lt;p&gt;Shibboleet: Class Mapping -- inheriting&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Guides]]&lt;br /&gt;
[[Category:Decompiling]]&lt;br /&gt;
{{WIP}}&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
&#039;&#039;Decompiling&#039;&#039; is the process of taking assembly code and turning it back into a higher level language such as C or C++. It is essentially the reverse of &#039;&#039;compiling&#039;&#039;. &#039;&#039;Matching decompilation&#039;&#039; is the process of decompiling, but having the compiled code match the original assembly 1:1. While matching decompilation is harder than normal decompiling, it can become easier when you understand the patterns of the compiler used. This page aims to let new people understand how this process works, and hopefully be able to get new people into decompilation! While you do not need to be an expert at C or C++ to decompile, it is recommended that you have some experience before attempting decompilation. It is also very recommended that you have some prior knowledge of PowerPC assembly, as that is the key to understanding how a function works. [https://www.nxp.com/docs/en/reference-manual/MPC82XINSET.pdf This document] is a good way to learn or refresh knowledge of the PowerPC architecture. [https://www.warthman.com/images/IBM_PPC_Compiler_Writer%27s_Guide-cwg.pdf This document] is also good to learn some of the patterns that CodeWarrior does.&lt;br /&gt;
&lt;br /&gt;
== Getting Set Up ==&lt;br /&gt;
To begin decompiling &#039;&#039;Super Mario Galaxy&#039;&#039;, you first need to set up the environment. You will need the following tools:&lt;br /&gt;
* [https://gitforwindows.org/ Git (Windows)]&lt;br /&gt;
* Any IDE ([https://code.visualstudio.com/ Visual Studio Recommended])&lt;br /&gt;
* [https://www.python.org/downloads/release/python-397/ Python 3.9.7]&lt;br /&gt;
* IDA Pro (recommended) or Ghidra (Not recommended)&lt;br /&gt;
* [https://shibbo.net/smg/RMGK01_01.idb SMG1 Korean IDB (For IDA)]&lt;br /&gt;
* A &#039;&#039;Super Mario Galaxy&#039;&#039; Korean region DOL.&lt;br /&gt;
&lt;br /&gt;
After you have acquired all of these, setting up [https://github.com/shibbo/Petari Petari] is very simple.&lt;br /&gt;
&lt;br /&gt;
# With a new command prompt open, type in &#039;&#039;&#039;git clone https://github.com/shibbo/Petari&#039;&#039;&#039;. This will clone the repository into a directory called &amp;quot;Petari&amp;quot;.&lt;br /&gt;
# In this new &amp;quot;Petari&amp;quot; folder, place the SMG1 Korean &#039;&#039;&#039;main.dol&#039;&#039;&#039; into this folder, and rename it to &#039;&#039;&#039;baserom.dol&#039;&#039;&#039;.&lt;br /&gt;
# Open a new command prompt in the &amp;quot;Petari&amp;quot; folder.&lt;br /&gt;
# Run the command &#039;&#039;&#039;python setup.py&#039;&#039;&#039;. This will verify your DOL and install all of the libraries used, and the compilers we use to compile the code.&lt;br /&gt;
# Run the command &#039;&#039;&#039;python build.py&#039;&#039;&#039;. This will build the entire project. If you see any warnings, do not worry about them.&lt;br /&gt;
&lt;br /&gt;
== Environment ==&lt;br /&gt;
To properly utilize and use &#039;&#039;Petari&#039;&#039;, it is necessary to understand the structure of the environment. Petari is structured in a way that makes it easy to access and use.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Folder Name !! Description&lt;br /&gt;
|-&lt;br /&gt;
| archive || The folder that gets created when &#039;&#039;&#039;build.py -link&#039;&#039;&#039; is ran. Contains an archive of the object files in each library.&lt;br /&gt;
|-&lt;br /&gt;
| build || The folder that gets created when &#039;&#039;&#039;build.py&#039;&#039;&#039; is ran. Contains the compiled object files.&lt;br /&gt;
|-&lt;br /&gt;
| csv || Contains CSV files that store the status of functions being matched.&lt;br /&gt;
|-&lt;br /&gt;
| data || Contains map files and the percentage badges for the GitHub repo.&lt;br /&gt;
|-&lt;br /&gt;
| docs || The folder that gets created when &#039;&#039;&#039;progress.py&#039;&#039;&#039; is ran. Contains all of the Markdown documentation for matching status.&lt;br /&gt;
|-&lt;br /&gt;
| include || Contains all of the header files for &#039;&#039;Super Mario Galaxy&#039;&#039; specific code.&lt;br /&gt;
|-&lt;br /&gt;
| libs || Contains this folder structure but for different libraries used by the game.&lt;br /&gt;
|-&lt;br /&gt;
| scripts || Various scripts used in IDA for generating headers.&lt;br /&gt;
|-&lt;br /&gt;
| source || Contains all of the source files for &#039;&#039;Super Mario Galaxy&#039;&#039; specific code.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Libraries ==&lt;br /&gt;
&#039;&#039;Super Mario Galaxy&#039;&#039; uses a lot of libraries for certain functionality such as heaps, layouts, OS specific code, and more. Each library described in the table below are &#039;&#039;&#039;statically linked&#039;&#039;&#039; to the game, so every library&#039;s used code is inside of the &#039;&#039;main.dol&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
=== Non-SMG Libraries ===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Name !! Language !! Description&lt;br /&gt;
|-&lt;br /&gt;
| JSystem || C++ || Contains classes for backend things, such as heaps and linked lists.&lt;br /&gt;
|-&lt;br /&gt;
| MetroTRK || C || Target Resident Kernel, for debugging.&lt;br /&gt;
|-&lt;br /&gt;
| MSL_C || C &amp;amp; C++ || Contains standard library functions and types.&lt;br /&gt;
|-&lt;br /&gt;
| nw4r || C++ || Contains classes for sounds, layouts, and more. (SMG only uses the layouts and some math functions)&lt;br /&gt;
|-&lt;br /&gt;
| Runtime || C &amp;amp; C++ || Contains functions that relate to CodeWarrior&#039;s runtime code generation (ctor / dtor lists, etc)&lt;br /&gt;
|-&lt;br /&gt;
| RVL_SDK || C || Contains functions that relate to the Wii&#039;s &amp;quot;OS&amp;quot;.&lt;br /&gt;
|-&lt;br /&gt;
| RVLFaceLib || C || Contains functions that relate to Miis.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== SMG Libraries ===&lt;br /&gt;
All of &#039;&#039;Super Mario Galaxy&#039;&#039;&#039;s libraries are written in C++.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Header text !! Header text&lt;br /&gt;
|-&lt;br /&gt;
| Animation || Library for animation playing.&lt;br /&gt;
|-&lt;br /&gt;
| AreaObj || Library for invisible areas that can be accessed by players in the game.&lt;br /&gt;
|-&lt;br /&gt;
| AudioLib || N/A&lt;br /&gt;
|-&lt;br /&gt;
| Boss || Library for all of the bosses and mini-bosses in the game.&lt;br /&gt;
|-&lt;br /&gt;
| Camera || Library for all camera types.&lt;br /&gt;
|-&lt;br /&gt;
| Demo || Library for all cutscenes.&lt;br /&gt;
|-&lt;br /&gt;
| Effect || Library for all effect rendering.&lt;br /&gt;
|-&lt;br /&gt;
| Enemy || Library for all enemies.&lt;br /&gt;
|-&lt;br /&gt;
| GameAudio || N/A&lt;br /&gt;
|-&lt;br /&gt;
| Gravity || Library for all of the gravity types in the game.&lt;br /&gt;
|-&lt;br /&gt;
| LiveActor || Library for LiveActor, which is an actor that can switch states.&lt;br /&gt;
|-&lt;br /&gt;
| Map || Library for map classes that do not directly interact with the player. (ie switches)&lt;br /&gt;
|-&lt;br /&gt;
| MapObj || Library for all of the map objects in the game.&lt;br /&gt;
|-&lt;br /&gt;
| NameObj || Library for the most basic form of an object in the game.&lt;br /&gt;
|-&lt;br /&gt;
| NPC || Library for all of the non-playable characters.&lt;br /&gt;
|-&lt;br /&gt;
| NWC24 || Library for the mail system in the game.&lt;br /&gt;
|-&lt;br /&gt;
| Player || Library for all of the player related functions.&lt;br /&gt;
|-&lt;br /&gt;
| RhythmLib || N/A&lt;br /&gt;
|-&lt;br /&gt;
| Ride || Library for all of the actors that can be controlled by the player.&lt;br /&gt;
|-&lt;br /&gt;
| Scene || Library for all of the game scene related code.&lt;br /&gt;
|-&lt;br /&gt;
| Screen || Library for all of the layouts in the game.&lt;br /&gt;
|-&lt;br /&gt;
| Speaker || Library for the sound effect playing done on the Wiimote.&lt;br /&gt;
|-&lt;br /&gt;
| System || Library for a lot of the game&#039;s backend systems.&lt;br /&gt;
|-&lt;br /&gt;
| Util || Library for utility functions and classes.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Basics ==&lt;br /&gt;
To properly decompile, it is vital to know how a lot of the assembly will translate into C / C++ code. Here are a couple of patterns that you will see when decompiling code.&lt;br /&gt;
&lt;br /&gt;
== Class Mapping ==&lt;br /&gt;
=== Base Class ===&lt;br /&gt;
The first step to decompiling a class is to map out the class itself. You need to be sure that you document every member, its type (as close as you can guess), its virtual functions, and more. The easiest way to achieve this is to look at the class&#039;s &#039;&#039;constructor&#039;&#039;. Seen below, is an example of a &#039;&#039;constructor&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
[[Image:NameObj_Ctor.png|frameless|700px|The constructor for &#039;&#039;NameObj&#039;&#039;.]]&lt;br /&gt;
&lt;br /&gt;
There are a couple of takeaways from this screenshot:&lt;br /&gt;
* The constructor passes an argument, which is a &#039;&#039;&#039;const char *&#039;&#039;&#039; (contained in r4) and is stored in (r3 + 0x4).&lt;br /&gt;
* (r3 + 0x0) is where the vtable is &#039;&#039;usually&#039;&#039; stored when a class has virtual functions. There are rare execptions.&lt;br /&gt;
* (r3 + 0x8) is stored with a &#039;&#039;&#039;sth&#039;&#039;&#039;, which means that it is a &#039;&#039;&#039;short&#039;&#039;&#039; datatype.&lt;br /&gt;
* (r3 + 0xA) is also stored with a &#039;&#039;&#039;sth&#039;&#039;&#039;, but with a &#039;&#039;&#039;-1&#039;&#039;&#039; value, so we know for sure that this type is &#039;&#039;signed&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Keep in mind that a constructor does not have to initialize every single member variable in the class! So there could be other members in a class that aren&#039;t mentioned in the constructor at all. After you look at the constructor, look around at the &#039;&#039;member functions&#039;&#039; to see if they use any members that are not initialized in the constructor. You can always verify if your class setup is correct when you can find where this class is created using the &#039;&#039;&#039;new&#039;&#039;&#039; operator. Check if the size passed to the &#039;&#039;&#039;new&#039;&#039;&#039; call matches the size of the class that you have mapped. If it is smaller, you are missing members. If it is bigger, you have too many! Remember that the vtable is implicitly stored at &#039;&#039;&#039;(this + 0x0)&#039;&#039;&#039;, so you do not have to explicitly define it. With all of these members documented, our class setup looks a little like this so far:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class NameObj {&lt;br /&gt;
public:&lt;br /&gt;
    NameObj(const char *pName);&lt;br /&gt;
&lt;br /&gt;
    /* remember that the vtable will be placed here once we define our virtuals! */&lt;br /&gt;
    /* 0x4 */   const char* mName;&lt;br /&gt;
    /* 0x8 */   volatile u16 mFlags;&lt;br /&gt;
    /* 0xA */   s16 mExecutorIdx;&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
After the members comes the &#039;&#039;&#039;vtable&#039;&#039;&#039;, or &#039;&#039;virtual table&#039;&#039;. It is an array of function pointers that can be overridden by classes that inherit the parent class. The vtable for &#039;&#039;&#039;NameObj&#039;&#039;&#039; looks like this:&lt;br /&gt;
[[Image:NameObj_Vtable.png|frameless|700px|The vtable for &#039;&#039;NameObj&#039;&#039;.]]&lt;br /&gt;
&lt;br /&gt;
To document the vtable, you simply document every single function placed here that contains the class name of the class you are currently decompiling. Since &#039;&#039;NameObj&#039;&#039; is a base class, every single function here is going to be defined. If a class overrides a function, you will only document the functions that are overridden. After documenting the vtable, our class looks something like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class NameObj {&lt;br /&gt;
public:&lt;br /&gt;
    NameObj(const char *pName);&lt;br /&gt;
&lt;br /&gt;
    virtual ~NameObj();&lt;br /&gt;
    virtual void init(const JMapInfoIter &amp;amp;rIter);&lt;br /&gt;
    virtual void initAfterPlacement();&lt;br /&gt;
    virtual void movement();&lt;br /&gt;
    virtual void draw() const;&lt;br /&gt;
    virtual void calcAnim();&lt;br /&gt;
    virtual void calcViewAndEntry();&lt;br /&gt;
&lt;br /&gt;
    /* remember that the vtable will be placed here once we define our virtuals! */&lt;br /&gt;
    /* 0x4 */   const char* mName;&lt;br /&gt;
    /* 0x8 */   volatile u16 mFlags;&lt;br /&gt;
    /* 0xA */   s16 mExecutorIdx;&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Once the vtable is complete, you want to document all of the member functions that are in the class. Since &#039;&#039;Super Mario Galaxy 1&#039;&#039; has a symbol map, we can easily find the member functions that &#039;&#039;NameObj&#039;&#039; contains. Once you have figured out their return types and their arguments, you can finish mapping out a class! After finding all of &#039;&#039;NameObj&#039;&#039;&#039;s member functions, the class looks like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class NameObj {&lt;br /&gt;
public:&lt;br /&gt;
    NameObj(const char *pName);&lt;br /&gt;
&lt;br /&gt;
    virtual ~NameObj();&lt;br /&gt;
    virtual void init(const JMapInfoIter &amp;amp;rIter);&lt;br /&gt;
    virtual void initAfterPlacement();&lt;br /&gt;
    virtual void movement();&lt;br /&gt;
    virtual void draw() const;&lt;br /&gt;
    virtual void calcAnim();&lt;br /&gt;
    virtual void calcViewAndEntry();&lt;br /&gt;
&lt;br /&gt;
    void initWithoutIter();&lt;br /&gt;
    void setName(const char *pName);&lt;br /&gt;
    void executeMovement();&lt;br /&gt;
    void requestSuspend();&lt;br /&gt;
    void requestResume();&lt;br /&gt;
    void syncWithFlags();&lt;br /&gt;
&lt;br /&gt;
    /* remember that the vtable will be placed here once we define our virtuals! */&lt;br /&gt;
    /* 0x4 */   const char* mName;&lt;br /&gt;
    /* 0x8 */   volatile u16 mFlags;&lt;br /&gt;
    /* 0xA */   s16 mExecutorIdx;&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Inheriting Class ===&lt;br /&gt;
The process of mapping a class that inherits another class is mainly the same as mapping a base class, except there are things to watch out for so you don&#039;t accidentally duplicate a member variable. The first step is to look at the &#039;&#039;constructor&#039;&#039; of the class you want to map:&lt;br /&gt;
&lt;br /&gt;
[[Image:TripodBossCoin_Ctor.png|frameless|700px|The constructor for &#039;&#039;TripodBossCoin&#039;&#039;.]]&lt;br /&gt;
&lt;br /&gt;
There are a few takeaways from this by looking at the constructor:&lt;br /&gt;
* The class inherits NameObj. Since &#039;&#039;NameObj&#039;&#039; is 0xC bytes long, we know that any member variables for &#039;&#039;TripodBossCoin&#039;&#039; start at &#039;&#039;&#039;0xC&#039;&#039;&#039;.&lt;br /&gt;
* The vtable pointer &#039;&#039;&#039;(this + 0x0)&#039;&#039;&#039; from &#039;&#039;NameObj&#039;&#039; is overridden with the vtable for &#039;&#039;TripodBossCoin&#039;&#039; implicitly.&lt;br /&gt;
* &#039;&#039;&#039;(this + 0xC)&#039;&#039;&#039; is a 32-bit integer initialized to 0. It is not possible to determine if it is signed or not from this store alone.&lt;br /&gt;
* &#039;&#039;&#039;(this + 0x10)&#039;&#039;&#039; is the same scenario as &#039;&#039;&#039;(this + 0xC)&#039;&#039;&#039;.&lt;br /&gt;
* There is a direct instance of &#039;&#039;JGeometry::TMatrix34&amp;lt;JGeometry::SMatrix34C&amp;lt;f32&amp;gt;&#039;&#039; at 0x14. (in Petari &amp;amp; Syati this is typedef&#039;d as &#039;&#039;TMtx34f&#039;&#039;). Since &#039;&#039;TMtx34f&#039;&#039; is 0x30 in size, the next member variable is at 0x14 + 0x30, which is &#039;&#039;&#039;0x44&#039;&#039;&#039;.&lt;br /&gt;
* &#039;&#039;&#039;(this + 0x44)&#039;&#039;&#039; is a signed 32-bit integer, due to &#039;&#039;&#039;-1&#039;&#039;&#039; being stored to it.&lt;br /&gt;
&lt;br /&gt;
After these observations, our class looks like this:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class TripodBossCoin : public NameObj {&lt;br /&gt;
public:&lt;br /&gt;
	TripodBossCoin(const char *);&lt;br /&gt;
	&lt;br /&gt;
	u32 _C;&lt;br /&gt;
	u32 _10;&lt;br /&gt;
	TMtx34f _14;&lt;br /&gt;
	s32 _44;&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Next are the virtuals. The process is a little different from a base class. Let&#039;s take a look at the vtable for &#039;&#039;TripodBossCoin&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
[[Image:TripodBossCoin_Vtable.png|frameless|700px|The vtable for &#039;&#039;TripodBossCoin&#039;&#039;.]]&lt;br /&gt;
&lt;br /&gt;
The biggest takeaway from this screenshot is that only three virtuals are overriden by &#039;&#039;TripodBossCoin&#039;&#039;. And those three functions are &#039;&#039;&#039;TripodBossCoin::~TripodBossCoin()&#039;&#039;&#039;, &#039;&#039;&#039;TripodBossCoin::init()&#039;&#039;&#039; and &#039;&#039;&#039;TripodBossCoin::movement()&#039;&#039;&#039;. So we define them as such:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class TripodBossCoin : public NameObj {&lt;br /&gt;
public:&lt;br /&gt;
	TripodBossCoin(const char *);&lt;br /&gt;
&lt;br /&gt;
    virtual ~TripodBossCoin();&lt;br /&gt;
    virtual void init(const JMapInfoIter &amp;amp;);&lt;br /&gt;
    virtual void movement();&lt;br /&gt;
	&lt;br /&gt;
	u32 _C;&lt;br /&gt;
	u32 _10;&lt;br /&gt;
	TMtx34f _14;&lt;br /&gt;
	s32 _44;&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
It is worth noting that the &#039;&#039;&#039;override&#039;&#039;&#039; keyword was not a part of the C++ standard at this point in time, so all overrides are implicit. After all of this is done, you simply have to repeat the process for base classes and document the member functions that are a part of the class.&lt;br /&gt;
&lt;br /&gt;
=== Loops ===&lt;br /&gt;
==== Predefined bounds ====&lt;br /&gt;
Let&#039;s take a simple loop that stores &amp;lt;i&amp;gt;nullptr&amp;lt;/i&amp;gt; in each 8 elements of a pointer array.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class TestClass {&lt;br /&gt;
public:&lt;br /&gt;
    TestClass();&lt;br /&gt;
&lt;br /&gt;
     int* mPointers[8];&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
TestClass::TestClass() {&lt;br /&gt;
    for (int i = 0; i &amp;lt; 8; i++) {&lt;br /&gt;
        mPointers[i] = nullptr;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The output assembly would look something like:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
li r0, 8 # there are 8 elements in this loop&lt;br /&gt;
li r5, 0 # the value to store in the element (nullptr)&lt;br /&gt;
li r4, 0 # the current element offset in the loop&lt;br /&gt;
mtctr r0 # move the number of iterations into the counter register (8)&lt;br /&gt;
&lt;br /&gt;
loop:&lt;br /&gt;
    stwx r5, r3, r4 # store 0 (r5) into the array at r3 (this) + r4 (our current offset, which is i * 4)&lt;br /&gt;
    addi r4, r4, 4 # increment our offset by sizeof(int) since integers are 32-bits&lt;br /&gt;
    bdnz+ loop # branch back to our loop again&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Variable Length Bounds ====&lt;br /&gt;
Let&#039;s take a simple loop that stores &amp;lt;i&amp;gt;nullptr&amp;lt;/i&amp;gt; in each element of a variable-length array. We will have a class with two members, one that contains the pointer array itself, and another that stores the number of pointers.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class TestClass {&lt;br /&gt;
public:&lt;br /&gt;
    TestClass();&lt;br /&gt;
&lt;br /&gt;
     int** mPointers;&lt;br /&gt;
     int mNumPointers;&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
TestClass::TestClass() {&lt;br /&gt;
    mNumPointers = 8;&lt;br /&gt;
    for (int i = 0; i &amp;lt; mNumPointers ; i++) {&lt;br /&gt;
        mPointers[i] = nullptr;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Because we do not know how many pointers we have stored, we cannot use the counter register like we did with a fixed-size array. Instead, the compiler will use a cmpw (signed integer) or cmplw (unsigned) instruction to compare the current iteration to how many pointers are stored in the class.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
li r0, 8 # there are 8 elements in this loop&lt;br /&gt;
li r7, 0 # the value to store in the element (nullptr)&lt;br /&gt;
stw r0, 4(r3) # r3 + 4 is the offset to our member variable &amp;quot;mNumPointers&amp;quot;&lt;br /&gt;
mr r6, r7 # simple copy of the 0 value so we can also use it for our counter&lt;br /&gt;
li r4, 0 # load 0 into our offset&lt;br /&gt;
b loop # branch into our loop&lt;br /&gt;
&lt;br /&gt;
loop:&lt;br /&gt;
    lwz r5, 0(r3) # load our pointer array from this + 0&lt;br /&gt;
    addi r7, r7, 1 # increment our index by 1&lt;br /&gt;
    stwx r6, r5, r4 # store our nullptr value (r6) into r5 + r4 (ptrArray + currentOffset)&lt;br /&gt;
    addi r4, r4, 4 # increment our offset by sizeof(int) since integers are 32-bits&lt;br /&gt;
    lwz r0, 4(r3) # load our number of pointers we will increment by (mNumPointers)&lt;br /&gt;
    cmpw r7, r0 # compare our number of pointers to the current index in our loop&lt;br /&gt;
    blt+ loop # branch if the number is less than mNumPointers&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Structure Access In Arrays (Pointer Array) ====&lt;br /&gt;
More complex forms of loops comes into play when you are iterating through structures and storing / loading members from those structures. Let&#039;s take this class for example:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
struct TestStruct {&lt;br /&gt;
    int SomeMember;&lt;br /&gt;
    int AnotherMember;&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
class TestClass {&lt;br /&gt;
public:&lt;br /&gt;
    TestClass();&lt;br /&gt;
&lt;br /&gt;
    void storeVals();&lt;br /&gt;
&lt;br /&gt;
     TestStruct** mStructures;&lt;br /&gt;
     int mNumStructures;&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
For the sake of simplicity, let&#039;s assume that the TestClass constructor initializes the number of structures to 8, and constructs them accordingly. With that in mind, let&#039;s see how a struct store will work.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void TestClass::storeVals() {&lt;br /&gt;
    for (int i = 0; i &amp;lt; mNumStructures; i++) {&lt;br /&gt;
        mStructures[i]-&amp;gt;AnotherMember = 5;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
The output assembly would look something like:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
li r7, 0 # our &amp;quot;i&amp;quot; used in the loop, starts at 0&lt;br /&gt;
li r4, 0 # our current offset into the array&lt;br /&gt;
li r6, 5 # the value we are storing into the array&lt;br /&gt;
b loop&lt;br /&gt;
&lt;br /&gt;
loop:&lt;br /&gt;
    lwz r5, 0(r3) # load the array pointer&lt;br /&gt;
    addi r7, r7, 1 # increment our current index (i) by 1&lt;br /&gt;
    lwzx r5, r5, r4 # load the current structure, mStructures[i] where r4 is the current offset&lt;br /&gt;
    addi r4, r4, 4 # increment our offset by sizeof(TestStruct*), which is 4&lt;br /&gt;
    stw r6, 4(r5) # store our value (5) into (mStructures[i] + 4), which is our AnotherMember&lt;br /&gt;
    lwz r0, 4(r3) # load the number of structures from TestClass&lt;br /&gt;
    cmpw r7, r0 # compare the current index to our value in TestClass&lt;br /&gt;
    blt+ loop # loop back if it is less than the value&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Structure Access In Arrays (Direct Array) ====&lt;br /&gt;
Let&#039;s take the previous example and modify it a little. Instead of making an array of pointers to the struct instances, let&#039;s store the array &amp;lt;i&amp;gt;directly&amp;lt;/i&amp;gt; into our class instance.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
struct TestStruct {&lt;br /&gt;
    int SomeMember;&lt;br /&gt;
    int AnotherMember;&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
class TestClass {&lt;br /&gt;
public:&lt;br /&gt;
    TestClass();&lt;br /&gt;
&lt;br /&gt;
    void storeVals();&lt;br /&gt;
&lt;br /&gt;
     TestStruct mStructures[8];&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Again, let us assume that the array has already been constructed and everything is initialized as it should be.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void TestClass::storeVals() {&lt;br /&gt;
    for (int i = 0; i &amp;lt; 8; i++) {&lt;br /&gt;
        mStructures[i].AnotherMember = 5;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
The output assembly would look something like:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
li r0, 8 # load our number of iterations (8)&lt;br /&gt;
li r4, 0 # current offset into the array. initialized at 0&lt;br /&gt;
li r6, 5 # the value to store into the array&lt;br /&gt;
mtctr r0 # move the number of iterations into the counter register&lt;br /&gt;
&lt;br /&gt;
loop:&lt;br /&gt;
    add r5, r3, r4 # jump to the offset into the array. r5 = (this + 0) + r4&lt;br /&gt;
    addi r4, r4, 8 # increment our current offset by sizeof(TestStruct), which is 8&lt;br /&gt;
    stw r6, 4(r5) # store our constant value (5) into the loaded struct + 4 (AnotherMember)&lt;br /&gt;
    bdnz+ loop # branch back to the loop if the counter is not 8&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Shibboleet</name></author>
	</entry>
	<entry>
		<id>https://www.lumasworkshop.com/w/index.php?title=File:TripodBossCoin_Vtable.png&amp;diff=181</id>
		<title>File:TripodBossCoin Vtable.png</title>
		<link rel="alternate" type="text/html" href="https://www.lumasworkshop.com/w/index.php?title=File:TripodBossCoin_Vtable.png&amp;diff=181"/>
		<updated>2024-04-06T12:32:14Z</updated>

		<summary type="html">&lt;p&gt;Shibboleet: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Shibboleet</name></author>
	</entry>
	<entry>
		<id>https://www.lumasworkshop.com/w/index.php?title=File:TripodBossCoin_Ctor.png&amp;diff=180</id>
		<title>File:TripodBossCoin Ctor.png</title>
		<link rel="alternate" type="text/html" href="https://www.lumasworkshop.com/w/index.php?title=File:TripodBossCoin_Ctor.png&amp;diff=180"/>
		<updated>2024-04-06T12:32:02Z</updated>

		<summary type="html">&lt;p&gt;Shibboleet: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Shibboleet</name></author>
	</entry>
	<entry>
		<id>https://www.lumasworkshop.com/w/index.php?title=Decompiling&amp;diff=179</id>
		<title>Decompiling</title>
		<link rel="alternate" type="text/html" href="https://www.lumasworkshop.com/w/index.php?title=Decompiling&amp;diff=179"/>
		<updated>2024-04-06T12:21:02Z</updated>

		<summary type="html">&lt;p&gt;Shibboleet: /* Base Class */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Guides]]&lt;br /&gt;
[[Category:Decompiling]]&lt;br /&gt;
{{WIP}}&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
&#039;&#039;Decompiling&#039;&#039; is the process of taking assembly code and turning it back into a higher level language such as C or C++. It is essentially the reverse of &#039;&#039;compiling&#039;&#039;. &#039;&#039;Matching decompilation&#039;&#039; is the process of decompiling, but having the compiled code match the original assembly 1:1. While matching decompilation is harder than normal decompiling, it can become easier when you understand the patterns of the compiler used. This page aims to let new people understand how this process works, and hopefully be able to get new people into decompilation! While you do not need to be an expert at C or C++ to decompile, it is recommended that you have some experience before attempting decompilation. It is also very recommended that you have some prior knowledge of PowerPC assembly, as that is the key to understanding how a function works. [https://www.nxp.com/docs/en/reference-manual/MPC82XINSET.pdf This document] is a good way to learn or refresh knowledge of the PowerPC architecture. [https://www.warthman.com/images/IBM_PPC_Compiler_Writer%27s_Guide-cwg.pdf This document] is also good to learn some of the patterns that CodeWarrior does.&lt;br /&gt;
&lt;br /&gt;
== Getting Set Up ==&lt;br /&gt;
To begin decompiling &#039;&#039;Super Mario Galaxy&#039;&#039;, you first need to set up the environment. You will need the following tools:&lt;br /&gt;
* [https://gitforwindows.org/ Git (Windows)]&lt;br /&gt;
* Any IDE ([https://code.visualstudio.com/ Visual Studio Recommended])&lt;br /&gt;
* [https://www.python.org/downloads/release/python-397/ Python 3.9.7]&lt;br /&gt;
* IDA Pro (recommended) or Ghidra (Not recommended)&lt;br /&gt;
* [https://shibbo.net/smg/RMGK01_01.idb SMG1 Korean IDB (For IDA)]&lt;br /&gt;
* A &#039;&#039;Super Mario Galaxy&#039;&#039; Korean region DOL.&lt;br /&gt;
&lt;br /&gt;
After you have acquired all of these, setting up [https://github.com/shibbo/Petari Petari] is very simple.&lt;br /&gt;
&lt;br /&gt;
# With a new command prompt open, type in &#039;&#039;&#039;git clone https://github.com/shibbo/Petari&#039;&#039;&#039;. This will clone the repository into a directory called &amp;quot;Petari&amp;quot;.&lt;br /&gt;
# In this new &amp;quot;Petari&amp;quot; folder, place the SMG1 Korean &#039;&#039;&#039;main.dol&#039;&#039;&#039; into this folder, and rename it to &#039;&#039;&#039;baserom.dol&#039;&#039;&#039;.&lt;br /&gt;
# Open a new command prompt in the &amp;quot;Petari&amp;quot; folder.&lt;br /&gt;
# Run the command &#039;&#039;&#039;python setup.py&#039;&#039;&#039;. This will verify your DOL and install all of the libraries used, and the compilers we use to compile the code.&lt;br /&gt;
# Run the command &#039;&#039;&#039;python build.py&#039;&#039;&#039;. This will build the entire project. If you see any warnings, do not worry about them.&lt;br /&gt;
&lt;br /&gt;
== Environment ==&lt;br /&gt;
To properly utilize and use &#039;&#039;Petari&#039;&#039;, it is necessary to understand the structure of the environment. Petari is structured in a way that makes it easy to access and use.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Folder Name !! Description&lt;br /&gt;
|-&lt;br /&gt;
| archive || The folder that gets created when &#039;&#039;&#039;build.py -link&#039;&#039;&#039; is ran. Contains an archive of the object files in each library.&lt;br /&gt;
|-&lt;br /&gt;
| build || The folder that gets created when &#039;&#039;&#039;build.py&#039;&#039;&#039; is ran. Contains the compiled object files.&lt;br /&gt;
|-&lt;br /&gt;
| csv || Contains CSV files that store the status of functions being matched.&lt;br /&gt;
|-&lt;br /&gt;
| data || Contains map files and the percentage badges for the GitHub repo.&lt;br /&gt;
|-&lt;br /&gt;
| docs || The folder that gets created when &#039;&#039;&#039;progress.py&#039;&#039;&#039; is ran. Contains all of the Markdown documentation for matching status.&lt;br /&gt;
|-&lt;br /&gt;
| include || Contains all of the header files for &#039;&#039;Super Mario Galaxy&#039;&#039; specific code.&lt;br /&gt;
|-&lt;br /&gt;
| libs || Contains this folder structure but for different libraries used by the game.&lt;br /&gt;
|-&lt;br /&gt;
| scripts || Various scripts used in IDA for generating headers.&lt;br /&gt;
|-&lt;br /&gt;
| source || Contains all of the source files for &#039;&#039;Super Mario Galaxy&#039;&#039; specific code.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Libraries ==&lt;br /&gt;
&#039;&#039;Super Mario Galaxy&#039;&#039; uses a lot of libraries for certain functionality such as heaps, layouts, OS specific code, and more. Each library described in the table below are &#039;&#039;&#039;statically linked&#039;&#039;&#039; to the game, so every library&#039;s used code is inside of the &#039;&#039;main.dol&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
=== Non-SMG Libraries ===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Name !! Language !! Description&lt;br /&gt;
|-&lt;br /&gt;
| JSystem || C++ || Contains classes for backend things, such as heaps and linked lists.&lt;br /&gt;
|-&lt;br /&gt;
| MetroTRK || C || Target Resident Kernel, for debugging.&lt;br /&gt;
|-&lt;br /&gt;
| MSL_C || C &amp;amp; C++ || Contains standard library functions and types.&lt;br /&gt;
|-&lt;br /&gt;
| nw4r || C++ || Contains classes for sounds, layouts, and more. (SMG only uses the layouts and some math functions)&lt;br /&gt;
|-&lt;br /&gt;
| Runtime || C &amp;amp; C++ || Contains functions that relate to CodeWarrior&#039;s runtime code generation (ctor / dtor lists, etc)&lt;br /&gt;
|-&lt;br /&gt;
| RVL_SDK || C || Contains functions that relate to the Wii&#039;s &amp;quot;OS&amp;quot;.&lt;br /&gt;
|-&lt;br /&gt;
| RVLFaceLib || C || Contains functions that relate to Miis.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== SMG Libraries ===&lt;br /&gt;
All of &#039;&#039;Super Mario Galaxy&#039;&#039;&#039;s libraries are written in C++.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Header text !! Header text&lt;br /&gt;
|-&lt;br /&gt;
| Animation || Library for animation playing.&lt;br /&gt;
|-&lt;br /&gt;
| AreaObj || Library for invisible areas that can be accessed by players in the game.&lt;br /&gt;
|-&lt;br /&gt;
| AudioLib || N/A&lt;br /&gt;
|-&lt;br /&gt;
| Boss || Library for all of the bosses and mini-bosses in the game.&lt;br /&gt;
|-&lt;br /&gt;
| Camera || Library for all camera types.&lt;br /&gt;
|-&lt;br /&gt;
| Demo || Library for all cutscenes.&lt;br /&gt;
|-&lt;br /&gt;
| Effect || Library for all effect rendering.&lt;br /&gt;
|-&lt;br /&gt;
| Enemy || Library for all enemies.&lt;br /&gt;
|-&lt;br /&gt;
| GameAudio || N/A&lt;br /&gt;
|-&lt;br /&gt;
| Gravity || Library for all of the gravity types in the game.&lt;br /&gt;
|-&lt;br /&gt;
| LiveActor || Library for LiveActor, which is an actor that can switch states.&lt;br /&gt;
|-&lt;br /&gt;
| Map || Library for map classes that do not directly interact with the player. (ie switches)&lt;br /&gt;
|-&lt;br /&gt;
| MapObj || Library for all of the map objects in the game.&lt;br /&gt;
|-&lt;br /&gt;
| NameObj || Library for the most basic form of an object in the game.&lt;br /&gt;
|-&lt;br /&gt;
| NPC || Library for all of the non-playable characters.&lt;br /&gt;
|-&lt;br /&gt;
| NWC24 || Library for the mail system in the game.&lt;br /&gt;
|-&lt;br /&gt;
| Player || Library for all of the player related functions.&lt;br /&gt;
|-&lt;br /&gt;
| RhythmLib || N/A&lt;br /&gt;
|-&lt;br /&gt;
| Ride || Library for all of the actors that can be controlled by the player.&lt;br /&gt;
|-&lt;br /&gt;
| Scene || Library for all of the game scene related code.&lt;br /&gt;
|-&lt;br /&gt;
| Screen || Library for all of the layouts in the game.&lt;br /&gt;
|-&lt;br /&gt;
| Speaker || Library for the sound effect playing done on the Wiimote.&lt;br /&gt;
|-&lt;br /&gt;
| System || Library for a lot of the game&#039;s backend systems.&lt;br /&gt;
|-&lt;br /&gt;
| Util || Library for utility functions and classes.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Basics ==&lt;br /&gt;
To properly decompile, it is vital to know how a lot of the assembly will translate into C / C++ code. Here are a couple of patterns that you will see when decompiling code.&lt;br /&gt;
&lt;br /&gt;
== Class Mapping ==&lt;br /&gt;
=== Base Class ===&lt;br /&gt;
The first step to decompiling a class is to map out the class itself. You need to be sure that you document every member, its type (as close as you can guess), its virtual functions, and more. The easiest way to achieve this is to look at the class&#039;s &#039;&#039;constructor&#039;&#039;. Seen below, is an example of a &#039;&#039;constructor&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
[[Image:NameObj_Ctor.png|frameless|700px|The constructor for &#039;&#039;NameObj&#039;&#039;.]]&lt;br /&gt;
&lt;br /&gt;
There are a couple of takeaways from this screenshot:&lt;br /&gt;
* The constructor passes an argument, which is a &#039;&#039;&#039;const char *&#039;&#039;&#039; (contained in r4) and is stored in (r3 + 0x4).&lt;br /&gt;
* (r3 + 0x0) is where the vtable is &#039;&#039;usually&#039;&#039; stored when a class has virtual functions. There are rare execptions.&lt;br /&gt;
* (r3 + 0x8) is stored with a &#039;&#039;&#039;sth&#039;&#039;&#039;, which means that it is a &#039;&#039;&#039;short&#039;&#039;&#039; datatype.&lt;br /&gt;
* (r3 + 0xA) is also stored with a &#039;&#039;&#039;sth&#039;&#039;&#039;, but with a &#039;&#039;&#039;-1&#039;&#039;&#039; value, so we know for sure that this type is &#039;&#039;signed&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Keep in mind that a constructor does not have to initialize every single member variable in the class! So there could be other members in a class that aren&#039;t mentioned in the constructor at all. After you look at the constructor, look around at the &#039;&#039;member functions&#039;&#039; to see if they use any members that are not initialized in the constructor. You can always verify if your class setup is correct when you can find where this class is created using the &#039;&#039;&#039;new&#039;&#039;&#039; operator. Check if the size passed to the &#039;&#039;&#039;new&#039;&#039;&#039; call matches the size of the class that you have mapped. If it is smaller, you are missing members. If it is bigger, you have too many! Remember that the vtable is implicitly stored at &#039;&#039;&#039;(this + 0x0)&#039;&#039;&#039;, so you do not have to explicitly define it. With all of these members documented, our class setup looks a little like this so far:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class NameObj {&lt;br /&gt;
public:&lt;br /&gt;
    NameObj(const char *pName);&lt;br /&gt;
&lt;br /&gt;
    /* remember that the vtable will be placed here once we define our virtuals! */&lt;br /&gt;
    /* 0x4 */   const char* mName;&lt;br /&gt;
    /* 0x8 */   volatile u16 mFlags;&lt;br /&gt;
    /* 0xA */   s16 mExecutorIdx;&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
After the members comes the &#039;&#039;&#039;vtable&#039;&#039;&#039;, or &#039;&#039;virtual table&#039;&#039;. It is an array of function pointers that can be overridden by classes that inherit the parent class. The vtable for &#039;&#039;&#039;NameObj&#039;&#039;&#039; looks like this:&lt;br /&gt;
[[Image:NameObj_Vtable.png|frameless|700px|The vtable for &#039;&#039;NameObj&#039;&#039;.]]&lt;br /&gt;
&lt;br /&gt;
To document the vtable, you simply document every single function placed here that contains the class name of the class you are currently decompiling. Since &#039;&#039;NameObj&#039;&#039; is a base class, every single function here is going to be defined. If a class overrides a function, you will only document the functions that are overridden. After documenting the vtable, our class looks something like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class NameObj {&lt;br /&gt;
public:&lt;br /&gt;
    NameObj(const char *pName);&lt;br /&gt;
&lt;br /&gt;
    virtual ~NameObj();&lt;br /&gt;
    virtual void init(const JMapInfoIter &amp;amp;rIter);&lt;br /&gt;
    virtual void initAfterPlacement();&lt;br /&gt;
    virtual void movement();&lt;br /&gt;
    virtual void draw() const;&lt;br /&gt;
    virtual void calcAnim();&lt;br /&gt;
    virtual void calcViewAndEntry();&lt;br /&gt;
&lt;br /&gt;
    /* remember that the vtable will be placed here once we define our virtuals! */&lt;br /&gt;
    /* 0x4 */   const char* mName;&lt;br /&gt;
    /* 0x8 */   volatile u16 mFlags;&lt;br /&gt;
    /* 0xA */   s16 mExecutorIdx;&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Once the vtable is complete, you want to document all of the member functions that are in the class. Since &#039;&#039;Super Mario Galaxy 1&#039;&#039; has a symbol map, we can easily find the member functions that &#039;&#039;NameObj&#039;&#039; contains. Once you have figured out their return types and their arguments, you can finish mapping out a class! After finding all of &#039;&#039;NameObj&#039;&#039;&#039;s member functions, the class looks like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class NameObj {&lt;br /&gt;
public:&lt;br /&gt;
    NameObj(const char *pName);&lt;br /&gt;
&lt;br /&gt;
    virtual ~NameObj();&lt;br /&gt;
    virtual void init(const JMapInfoIter &amp;amp;rIter);&lt;br /&gt;
    virtual void initAfterPlacement();&lt;br /&gt;
    virtual void movement();&lt;br /&gt;
    virtual void draw() const;&lt;br /&gt;
    virtual void calcAnim();&lt;br /&gt;
    virtual void calcViewAndEntry();&lt;br /&gt;
&lt;br /&gt;
    void initWithoutIter();&lt;br /&gt;
    void setName(const char *pName);&lt;br /&gt;
    void executeMovement();&lt;br /&gt;
    void requestSuspend();&lt;br /&gt;
    void requestResume();&lt;br /&gt;
    void syncWithFlags();&lt;br /&gt;
&lt;br /&gt;
    /* remember that the vtable will be placed here once we define our virtuals! */&lt;br /&gt;
    /* 0x4 */   const char* mName;&lt;br /&gt;
    /* 0x8 */   volatile u16 mFlags;&lt;br /&gt;
    /* 0xA */   s16 mExecutorIdx;&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Loops ===&lt;br /&gt;
==== Predefined bounds ====&lt;br /&gt;
Let&#039;s take a simple loop that stores &amp;lt;i&amp;gt;nullptr&amp;lt;/i&amp;gt; in each 8 elements of a pointer array.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class TestClass {&lt;br /&gt;
public:&lt;br /&gt;
    TestClass();&lt;br /&gt;
&lt;br /&gt;
     int* mPointers[8];&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
TestClass::TestClass() {&lt;br /&gt;
    for (int i = 0; i &amp;lt; 8; i++) {&lt;br /&gt;
        mPointers[i] = nullptr;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The output assembly would look something like:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
li r0, 8 # there are 8 elements in this loop&lt;br /&gt;
li r5, 0 # the value to store in the element (nullptr)&lt;br /&gt;
li r4, 0 # the current element offset in the loop&lt;br /&gt;
mtctr r0 # move the number of iterations into the counter register (8)&lt;br /&gt;
&lt;br /&gt;
loop:&lt;br /&gt;
    stwx r5, r3, r4 # store 0 (r5) into the array at r3 (this) + r4 (our current offset, which is i * 4)&lt;br /&gt;
    addi r4, r4, 4 # increment our offset by sizeof(int) since integers are 32-bits&lt;br /&gt;
    bdnz+ loop # branch back to our loop again&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Variable Length Bounds ====&lt;br /&gt;
Let&#039;s take a simple loop that stores &amp;lt;i&amp;gt;nullptr&amp;lt;/i&amp;gt; in each element of a variable-length array. We will have a class with two members, one that contains the pointer array itself, and another that stores the number of pointers.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class TestClass {&lt;br /&gt;
public:&lt;br /&gt;
    TestClass();&lt;br /&gt;
&lt;br /&gt;
     int** mPointers;&lt;br /&gt;
     int mNumPointers;&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
TestClass::TestClass() {&lt;br /&gt;
    mNumPointers = 8;&lt;br /&gt;
    for (int i = 0; i &amp;lt; mNumPointers ; i++) {&lt;br /&gt;
        mPointers[i] = nullptr;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Because we do not know how many pointers we have stored, we cannot use the counter register like we did with a fixed-size array. Instead, the compiler will use a cmpw (signed integer) or cmplw (unsigned) instruction to compare the current iteration to how many pointers are stored in the class.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
li r0, 8 # there are 8 elements in this loop&lt;br /&gt;
li r7, 0 # the value to store in the element (nullptr)&lt;br /&gt;
stw r0, 4(r3) # r3 + 4 is the offset to our member variable &amp;quot;mNumPointers&amp;quot;&lt;br /&gt;
mr r6, r7 # simple copy of the 0 value so we can also use it for our counter&lt;br /&gt;
li r4, 0 # load 0 into our offset&lt;br /&gt;
b loop # branch into our loop&lt;br /&gt;
&lt;br /&gt;
loop:&lt;br /&gt;
    lwz r5, 0(r3) # load our pointer array from this + 0&lt;br /&gt;
    addi r7, r7, 1 # increment our index by 1&lt;br /&gt;
    stwx r6, r5, r4 # store our nullptr value (r6) into r5 + r4 (ptrArray + currentOffset)&lt;br /&gt;
    addi r4, r4, 4 # increment our offset by sizeof(int) since integers are 32-bits&lt;br /&gt;
    lwz r0, 4(r3) # load our number of pointers we will increment by (mNumPointers)&lt;br /&gt;
    cmpw r7, r0 # compare our number of pointers to the current index in our loop&lt;br /&gt;
    blt+ loop # branch if the number is less than mNumPointers&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Structure Access In Arrays (Pointer Array) ====&lt;br /&gt;
More complex forms of loops comes into play when you are iterating through structures and storing / loading members from those structures. Let&#039;s take this class for example:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
struct TestStruct {&lt;br /&gt;
    int SomeMember;&lt;br /&gt;
    int AnotherMember;&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
class TestClass {&lt;br /&gt;
public:&lt;br /&gt;
    TestClass();&lt;br /&gt;
&lt;br /&gt;
    void storeVals();&lt;br /&gt;
&lt;br /&gt;
     TestStruct** mStructures;&lt;br /&gt;
     int mNumStructures;&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
For the sake of simplicity, let&#039;s assume that the TestClass constructor initializes the number of structures to 8, and constructs them accordingly. With that in mind, let&#039;s see how a struct store will work.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void TestClass::storeVals() {&lt;br /&gt;
    for (int i = 0; i &amp;lt; mNumStructures; i++) {&lt;br /&gt;
        mStructures[i]-&amp;gt;AnotherMember = 5;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
The output assembly would look something like:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
li r7, 0 # our &amp;quot;i&amp;quot; used in the loop, starts at 0&lt;br /&gt;
li r4, 0 # our current offset into the array&lt;br /&gt;
li r6, 5 # the value we are storing into the array&lt;br /&gt;
b loop&lt;br /&gt;
&lt;br /&gt;
loop:&lt;br /&gt;
    lwz r5, 0(r3) # load the array pointer&lt;br /&gt;
    addi r7, r7, 1 # increment our current index (i) by 1&lt;br /&gt;
    lwzx r5, r5, r4 # load the current structure, mStructures[i] where r4 is the current offset&lt;br /&gt;
    addi r4, r4, 4 # increment our offset by sizeof(TestStruct*), which is 4&lt;br /&gt;
    stw r6, 4(r5) # store our value (5) into (mStructures[i] + 4), which is our AnotherMember&lt;br /&gt;
    lwz r0, 4(r3) # load the number of structures from TestClass&lt;br /&gt;
    cmpw r7, r0 # compare the current index to our value in TestClass&lt;br /&gt;
    blt+ loop # loop back if it is less than the value&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Structure Access In Arrays (Direct Array) ====&lt;br /&gt;
Let&#039;s take the previous example and modify it a little. Instead of making an array of pointers to the struct instances, let&#039;s store the array &amp;lt;i&amp;gt;directly&amp;lt;/i&amp;gt; into our class instance.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
struct TestStruct {&lt;br /&gt;
    int SomeMember;&lt;br /&gt;
    int AnotherMember;&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
class TestClass {&lt;br /&gt;
public:&lt;br /&gt;
    TestClass();&lt;br /&gt;
&lt;br /&gt;
    void storeVals();&lt;br /&gt;
&lt;br /&gt;
     TestStruct mStructures[8];&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Again, let us assume that the array has already been constructed and everything is initialized as it should be.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void TestClass::storeVals() {&lt;br /&gt;
    for (int i = 0; i &amp;lt; 8; i++) {&lt;br /&gt;
        mStructures[i].AnotherMember = 5;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
The output assembly would look something like:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
li r0, 8 # load our number of iterations (8)&lt;br /&gt;
li r4, 0 # current offset into the array. initialized at 0&lt;br /&gt;
li r6, 5 # the value to store into the array&lt;br /&gt;
mtctr r0 # move the number of iterations into the counter register&lt;br /&gt;
&lt;br /&gt;
loop:&lt;br /&gt;
    add r5, r3, r4 # jump to the offset into the array. r5 = (this + 0) + r4&lt;br /&gt;
    addi r4, r4, 8 # increment our current offset by sizeof(TestStruct), which is 8&lt;br /&gt;
    stw r6, 4(r5) # store our constant value (5) into the loaded struct + 4 (AnotherMember)&lt;br /&gt;
    bdnz+ loop # branch back to the loop if the counter is not 8&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Shibboleet</name></author>
	</entry>
	<entry>
		<id>https://www.lumasworkshop.com/w/index.php?title=Decompiling&amp;diff=178</id>
		<title>Decompiling</title>
		<link rel="alternate" type="text/html" href="https://www.lumasworkshop.com/w/index.php?title=Decompiling&amp;diff=178"/>
		<updated>2024-04-06T12:20:34Z</updated>

		<summary type="html">&lt;p&gt;Shibboleet: /* Base Class */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Guides]]&lt;br /&gt;
[[Category:Decompiling]]&lt;br /&gt;
{{WIP}}&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
&#039;&#039;Decompiling&#039;&#039; is the process of taking assembly code and turning it back into a higher level language such as C or C++. It is essentially the reverse of &#039;&#039;compiling&#039;&#039;. &#039;&#039;Matching decompilation&#039;&#039; is the process of decompiling, but having the compiled code match the original assembly 1:1. While matching decompilation is harder than normal decompiling, it can become easier when you understand the patterns of the compiler used. This page aims to let new people understand how this process works, and hopefully be able to get new people into decompilation! While you do not need to be an expert at C or C++ to decompile, it is recommended that you have some experience before attempting decompilation. It is also very recommended that you have some prior knowledge of PowerPC assembly, as that is the key to understanding how a function works. [https://www.nxp.com/docs/en/reference-manual/MPC82XINSET.pdf This document] is a good way to learn or refresh knowledge of the PowerPC architecture. [https://www.warthman.com/images/IBM_PPC_Compiler_Writer%27s_Guide-cwg.pdf This document] is also good to learn some of the patterns that CodeWarrior does.&lt;br /&gt;
&lt;br /&gt;
== Getting Set Up ==&lt;br /&gt;
To begin decompiling &#039;&#039;Super Mario Galaxy&#039;&#039;, you first need to set up the environment. You will need the following tools:&lt;br /&gt;
* [https://gitforwindows.org/ Git (Windows)]&lt;br /&gt;
* Any IDE ([https://code.visualstudio.com/ Visual Studio Recommended])&lt;br /&gt;
* [https://www.python.org/downloads/release/python-397/ Python 3.9.7]&lt;br /&gt;
* IDA Pro (recommended) or Ghidra (Not recommended)&lt;br /&gt;
* [https://shibbo.net/smg/RMGK01_01.idb SMG1 Korean IDB (For IDA)]&lt;br /&gt;
* A &#039;&#039;Super Mario Galaxy&#039;&#039; Korean region DOL.&lt;br /&gt;
&lt;br /&gt;
After you have acquired all of these, setting up [https://github.com/shibbo/Petari Petari] is very simple.&lt;br /&gt;
&lt;br /&gt;
# With a new command prompt open, type in &#039;&#039;&#039;git clone https://github.com/shibbo/Petari&#039;&#039;&#039;. This will clone the repository into a directory called &amp;quot;Petari&amp;quot;.&lt;br /&gt;
# In this new &amp;quot;Petari&amp;quot; folder, place the SMG1 Korean &#039;&#039;&#039;main.dol&#039;&#039;&#039; into this folder, and rename it to &#039;&#039;&#039;baserom.dol&#039;&#039;&#039;.&lt;br /&gt;
# Open a new command prompt in the &amp;quot;Petari&amp;quot; folder.&lt;br /&gt;
# Run the command &#039;&#039;&#039;python setup.py&#039;&#039;&#039;. This will verify your DOL and install all of the libraries used, and the compilers we use to compile the code.&lt;br /&gt;
# Run the command &#039;&#039;&#039;python build.py&#039;&#039;&#039;. This will build the entire project. If you see any warnings, do not worry about them.&lt;br /&gt;
&lt;br /&gt;
== Environment ==&lt;br /&gt;
To properly utilize and use &#039;&#039;Petari&#039;&#039;, it is necessary to understand the structure of the environment. Petari is structured in a way that makes it easy to access and use.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Folder Name !! Description&lt;br /&gt;
|-&lt;br /&gt;
| archive || The folder that gets created when &#039;&#039;&#039;build.py -link&#039;&#039;&#039; is ran. Contains an archive of the object files in each library.&lt;br /&gt;
|-&lt;br /&gt;
| build || The folder that gets created when &#039;&#039;&#039;build.py&#039;&#039;&#039; is ran. Contains the compiled object files.&lt;br /&gt;
|-&lt;br /&gt;
| csv || Contains CSV files that store the status of functions being matched.&lt;br /&gt;
|-&lt;br /&gt;
| data || Contains map files and the percentage badges for the GitHub repo.&lt;br /&gt;
|-&lt;br /&gt;
| docs || The folder that gets created when &#039;&#039;&#039;progress.py&#039;&#039;&#039; is ran. Contains all of the Markdown documentation for matching status.&lt;br /&gt;
|-&lt;br /&gt;
| include || Contains all of the header files for &#039;&#039;Super Mario Galaxy&#039;&#039; specific code.&lt;br /&gt;
|-&lt;br /&gt;
| libs || Contains this folder structure but for different libraries used by the game.&lt;br /&gt;
|-&lt;br /&gt;
| scripts || Various scripts used in IDA for generating headers.&lt;br /&gt;
|-&lt;br /&gt;
| source || Contains all of the source files for &#039;&#039;Super Mario Galaxy&#039;&#039; specific code.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Libraries ==&lt;br /&gt;
&#039;&#039;Super Mario Galaxy&#039;&#039; uses a lot of libraries for certain functionality such as heaps, layouts, OS specific code, and more. Each library described in the table below are &#039;&#039;&#039;statically linked&#039;&#039;&#039; to the game, so every library&#039;s used code is inside of the &#039;&#039;main.dol&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
=== Non-SMG Libraries ===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Name !! Language !! Description&lt;br /&gt;
|-&lt;br /&gt;
| JSystem || C++ || Contains classes for backend things, such as heaps and linked lists.&lt;br /&gt;
|-&lt;br /&gt;
| MetroTRK || C || Target Resident Kernel, for debugging.&lt;br /&gt;
|-&lt;br /&gt;
| MSL_C || C &amp;amp; C++ || Contains standard library functions and types.&lt;br /&gt;
|-&lt;br /&gt;
| nw4r || C++ || Contains classes for sounds, layouts, and more. (SMG only uses the layouts and some math functions)&lt;br /&gt;
|-&lt;br /&gt;
| Runtime || C &amp;amp; C++ || Contains functions that relate to CodeWarrior&#039;s runtime code generation (ctor / dtor lists, etc)&lt;br /&gt;
|-&lt;br /&gt;
| RVL_SDK || C || Contains functions that relate to the Wii&#039;s &amp;quot;OS&amp;quot;.&lt;br /&gt;
|-&lt;br /&gt;
| RVLFaceLib || C || Contains functions that relate to Miis.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== SMG Libraries ===&lt;br /&gt;
All of &#039;&#039;Super Mario Galaxy&#039;&#039;&#039;s libraries are written in C++.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Header text !! Header text&lt;br /&gt;
|-&lt;br /&gt;
| Animation || Library for animation playing.&lt;br /&gt;
|-&lt;br /&gt;
| AreaObj || Library for invisible areas that can be accessed by players in the game.&lt;br /&gt;
|-&lt;br /&gt;
| AudioLib || N/A&lt;br /&gt;
|-&lt;br /&gt;
| Boss || Library for all of the bosses and mini-bosses in the game.&lt;br /&gt;
|-&lt;br /&gt;
| Camera || Library for all camera types.&lt;br /&gt;
|-&lt;br /&gt;
| Demo || Library for all cutscenes.&lt;br /&gt;
|-&lt;br /&gt;
| Effect || Library for all effect rendering.&lt;br /&gt;
|-&lt;br /&gt;
| Enemy || Library for all enemies.&lt;br /&gt;
|-&lt;br /&gt;
| GameAudio || N/A&lt;br /&gt;
|-&lt;br /&gt;
| Gravity || Library for all of the gravity types in the game.&lt;br /&gt;
|-&lt;br /&gt;
| LiveActor || Library for LiveActor, which is an actor that can switch states.&lt;br /&gt;
|-&lt;br /&gt;
| Map || Library for map classes that do not directly interact with the player. (ie switches)&lt;br /&gt;
|-&lt;br /&gt;
| MapObj || Library for all of the map objects in the game.&lt;br /&gt;
|-&lt;br /&gt;
| NameObj || Library for the most basic form of an object in the game.&lt;br /&gt;
|-&lt;br /&gt;
| NPC || Library for all of the non-playable characters.&lt;br /&gt;
|-&lt;br /&gt;
| NWC24 || Library for the mail system in the game.&lt;br /&gt;
|-&lt;br /&gt;
| Player || Library for all of the player related functions.&lt;br /&gt;
|-&lt;br /&gt;
| RhythmLib || N/A&lt;br /&gt;
|-&lt;br /&gt;
| Ride || Library for all of the actors that can be controlled by the player.&lt;br /&gt;
|-&lt;br /&gt;
| Scene || Library for all of the game scene related code.&lt;br /&gt;
|-&lt;br /&gt;
| Screen || Library for all of the layouts in the game.&lt;br /&gt;
|-&lt;br /&gt;
| Speaker || Library for the sound effect playing done on the Wiimote.&lt;br /&gt;
|-&lt;br /&gt;
| System || Library for a lot of the game&#039;s backend systems.&lt;br /&gt;
|-&lt;br /&gt;
| Util || Library for utility functions and classes.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Basics ==&lt;br /&gt;
To properly decompile, it is vital to know how a lot of the assembly will translate into C / C++ code. Here are a couple of patterns that you will see when decompiling code.&lt;br /&gt;
&lt;br /&gt;
== Class Mapping ==&lt;br /&gt;
=== Base Class ===&lt;br /&gt;
The first step to decompiling a class is to map out the class itself. You need to be sure that you document every member, its type (as close as you can guess), its virtual functions, and more. The easiest way to achieve this is to look at the class&#039;s &#039;&#039;constructor&#039;&#039;. Seen below, is an example of a &#039;&#039;constructor&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
[[Image:NameObj_Ctor.png|frameless|700px|The constructor for &#039;&#039;NameObj&#039;&#039;.]]&lt;br /&gt;
&lt;br /&gt;
There are a couple of takeaways from this screenshot:&lt;br /&gt;
* The constructor passes an argument, which is a &#039;&#039;&#039;const char *&#039;&#039;&#039; (contained in r4) and is stored in (r3 + 0x4).&lt;br /&gt;
* (r3 + 0x0) is where the vtable is &#039;&#039;usually&#039;&#039; stored when a class has virtual functions. There are rare execptions.&lt;br /&gt;
* (r3 + 0x8) is stored with a &#039;&#039;&#039;sth&#039;&#039;&#039;, which means that it is a &#039;&#039;&#039;short&#039;&#039;&#039; datatype.&lt;br /&gt;
* (r3 + 0xA) is also stored with a &#039;&#039;&#039;sth&#039;&#039;&#039;, but with a &#039;&#039;&#039;-1&#039;&#039;&#039; value, so we know for sure that this type is &#039;&#039;signed&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Keep in mind that a constructor does not have to initialize every single member variable in the class! So there could be other members in a class that aren&#039;t mentioned in the constructor at all. After you look at the constructor, look around at the &#039;&#039;member functions&#039;&#039; to see if they use any members that are not initialized in the constructor. You can always verify if your class setup is correct when you can find where this class is created using the &#039;&#039;&#039;new&#039;&#039;&#039; operator. Check if the size passed to the &#039;&#039;&#039;new&#039;&#039;&#039; call matches the size of the class that you have mapped. If it is smaller, you are missing arguments. If it is bigger, you have too many! Remember that the vtable is implicitly stored at &#039;&#039;&#039;(this + 0x0)&#039;&#039;&#039;, so you do not have to explicitly define it. With all of these members documented, our class setup looks a little like this so far:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class NameObj {&lt;br /&gt;
public:&lt;br /&gt;
    NameObj(const char *pName);&lt;br /&gt;
&lt;br /&gt;
    /* remember that the vtable will be placed here once we define our virtuals! */&lt;br /&gt;
    /* 0x4 */   const char* mName;&lt;br /&gt;
    /* 0x8 */   volatile u16 mFlags;&lt;br /&gt;
    /* 0xA */   s16 mExecutorIdx;&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
After the members comes the &#039;&#039;&#039;vtable&#039;&#039;&#039;, or &#039;&#039;virtual table&#039;&#039;. It is an array of function pointers that can be overridden by classes that inherit the parent class. The vtable for &#039;&#039;&#039;NameObj&#039;&#039;&#039; looks like this:&lt;br /&gt;
[[Image:NameObj_Vtable.png|frameless|700px|The vtable for &#039;&#039;NameObj&#039;&#039;.]]&lt;br /&gt;
&lt;br /&gt;
To document the vtable, you simply document every single function placed here that contains the class name of the class you are currently decompiling. Since &#039;&#039;NameObj&#039;&#039; is a base class, every single function here is going to be defined. If a class overrides a function, you will only document the functions that are overridden. After documenting the vtable, our class looks something like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class NameObj {&lt;br /&gt;
public:&lt;br /&gt;
    NameObj(const char *pName);&lt;br /&gt;
&lt;br /&gt;
    virtual ~NameObj();&lt;br /&gt;
    virtual void init(const JMapInfoIter &amp;amp;rIter);&lt;br /&gt;
    virtual void initAfterPlacement();&lt;br /&gt;
    virtual void movement();&lt;br /&gt;
    virtual void draw() const;&lt;br /&gt;
    virtual void calcAnim();&lt;br /&gt;
    virtual void calcViewAndEntry();&lt;br /&gt;
&lt;br /&gt;
    /* remember that the vtable will be placed here once we define our virtuals! */&lt;br /&gt;
    /* 0x4 */   const char* mName;&lt;br /&gt;
    /* 0x8 */   volatile u16 mFlags;&lt;br /&gt;
    /* 0xA */   s16 mExecutorIdx;&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Once the vtable is complete, you want to document all of the member functions that are in the class. Since &#039;&#039;Super Mario Galaxy 1&#039;&#039; has a symbol map, we can easily find the member functions that &#039;&#039;NameObj&#039;&#039; contains. Once you have figured out their return types and their arguments, you can finish mapping out a class! After finding all of &#039;&#039;NameObj&#039;&#039;&#039;s member functions, the class looks like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class NameObj {&lt;br /&gt;
public:&lt;br /&gt;
    NameObj(const char *pName);&lt;br /&gt;
&lt;br /&gt;
    virtual ~NameObj();&lt;br /&gt;
    virtual void init(const JMapInfoIter &amp;amp;rIter);&lt;br /&gt;
    virtual void initAfterPlacement();&lt;br /&gt;
    virtual void movement();&lt;br /&gt;
    virtual void draw() const;&lt;br /&gt;
    virtual void calcAnim();&lt;br /&gt;
    virtual void calcViewAndEntry();&lt;br /&gt;
&lt;br /&gt;
    void initWithoutIter();&lt;br /&gt;
    void setName(const char *pName);&lt;br /&gt;
    void executeMovement();&lt;br /&gt;
    void requestSuspend();&lt;br /&gt;
    void requestResume();&lt;br /&gt;
    void syncWithFlags();&lt;br /&gt;
&lt;br /&gt;
    /* remember that the vtable will be placed here once we define our virtuals! */&lt;br /&gt;
    /* 0x4 */   const char* mName;&lt;br /&gt;
    /* 0x8 */   volatile u16 mFlags;&lt;br /&gt;
    /* 0xA */   s16 mExecutorIdx;&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Loops ===&lt;br /&gt;
==== Predefined bounds ====&lt;br /&gt;
Let&#039;s take a simple loop that stores &amp;lt;i&amp;gt;nullptr&amp;lt;/i&amp;gt; in each 8 elements of a pointer array.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class TestClass {&lt;br /&gt;
public:&lt;br /&gt;
    TestClass();&lt;br /&gt;
&lt;br /&gt;
     int* mPointers[8];&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
TestClass::TestClass() {&lt;br /&gt;
    for (int i = 0; i &amp;lt; 8; i++) {&lt;br /&gt;
        mPointers[i] = nullptr;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The output assembly would look something like:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
li r0, 8 # there are 8 elements in this loop&lt;br /&gt;
li r5, 0 # the value to store in the element (nullptr)&lt;br /&gt;
li r4, 0 # the current element offset in the loop&lt;br /&gt;
mtctr r0 # move the number of iterations into the counter register (8)&lt;br /&gt;
&lt;br /&gt;
loop:&lt;br /&gt;
    stwx r5, r3, r4 # store 0 (r5) into the array at r3 (this) + r4 (our current offset, which is i * 4)&lt;br /&gt;
    addi r4, r4, 4 # increment our offset by sizeof(int) since integers are 32-bits&lt;br /&gt;
    bdnz+ loop # branch back to our loop again&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Variable Length Bounds ====&lt;br /&gt;
Let&#039;s take a simple loop that stores &amp;lt;i&amp;gt;nullptr&amp;lt;/i&amp;gt; in each element of a variable-length array. We will have a class with two members, one that contains the pointer array itself, and another that stores the number of pointers.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class TestClass {&lt;br /&gt;
public:&lt;br /&gt;
    TestClass();&lt;br /&gt;
&lt;br /&gt;
     int** mPointers;&lt;br /&gt;
     int mNumPointers;&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
TestClass::TestClass() {&lt;br /&gt;
    mNumPointers = 8;&lt;br /&gt;
    for (int i = 0; i &amp;lt; mNumPointers ; i++) {&lt;br /&gt;
        mPointers[i] = nullptr;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Because we do not know how many pointers we have stored, we cannot use the counter register like we did with a fixed-size array. Instead, the compiler will use a cmpw (signed integer) or cmplw (unsigned) instruction to compare the current iteration to how many pointers are stored in the class.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
li r0, 8 # there are 8 elements in this loop&lt;br /&gt;
li r7, 0 # the value to store in the element (nullptr)&lt;br /&gt;
stw r0, 4(r3) # r3 + 4 is the offset to our member variable &amp;quot;mNumPointers&amp;quot;&lt;br /&gt;
mr r6, r7 # simple copy of the 0 value so we can also use it for our counter&lt;br /&gt;
li r4, 0 # load 0 into our offset&lt;br /&gt;
b loop # branch into our loop&lt;br /&gt;
&lt;br /&gt;
loop:&lt;br /&gt;
    lwz r5, 0(r3) # load our pointer array from this + 0&lt;br /&gt;
    addi r7, r7, 1 # increment our index by 1&lt;br /&gt;
    stwx r6, r5, r4 # store our nullptr value (r6) into r5 + r4 (ptrArray + currentOffset)&lt;br /&gt;
    addi r4, r4, 4 # increment our offset by sizeof(int) since integers are 32-bits&lt;br /&gt;
    lwz r0, 4(r3) # load our number of pointers we will increment by (mNumPointers)&lt;br /&gt;
    cmpw r7, r0 # compare our number of pointers to the current index in our loop&lt;br /&gt;
    blt+ loop # branch if the number is less than mNumPointers&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Structure Access In Arrays (Pointer Array) ====&lt;br /&gt;
More complex forms of loops comes into play when you are iterating through structures and storing / loading members from those structures. Let&#039;s take this class for example:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
struct TestStruct {&lt;br /&gt;
    int SomeMember;&lt;br /&gt;
    int AnotherMember;&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
class TestClass {&lt;br /&gt;
public:&lt;br /&gt;
    TestClass();&lt;br /&gt;
&lt;br /&gt;
    void storeVals();&lt;br /&gt;
&lt;br /&gt;
     TestStruct** mStructures;&lt;br /&gt;
     int mNumStructures;&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
For the sake of simplicity, let&#039;s assume that the TestClass constructor initializes the number of structures to 8, and constructs them accordingly. With that in mind, let&#039;s see how a struct store will work.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void TestClass::storeVals() {&lt;br /&gt;
    for (int i = 0; i &amp;lt; mNumStructures; i++) {&lt;br /&gt;
        mStructures[i]-&amp;gt;AnotherMember = 5;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
The output assembly would look something like:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
li r7, 0 # our &amp;quot;i&amp;quot; used in the loop, starts at 0&lt;br /&gt;
li r4, 0 # our current offset into the array&lt;br /&gt;
li r6, 5 # the value we are storing into the array&lt;br /&gt;
b loop&lt;br /&gt;
&lt;br /&gt;
loop:&lt;br /&gt;
    lwz r5, 0(r3) # load the array pointer&lt;br /&gt;
    addi r7, r7, 1 # increment our current index (i) by 1&lt;br /&gt;
    lwzx r5, r5, r4 # load the current structure, mStructures[i] where r4 is the current offset&lt;br /&gt;
    addi r4, r4, 4 # increment our offset by sizeof(TestStruct*), which is 4&lt;br /&gt;
    stw r6, 4(r5) # store our value (5) into (mStructures[i] + 4), which is our AnotherMember&lt;br /&gt;
    lwz r0, 4(r3) # load the number of structures from TestClass&lt;br /&gt;
    cmpw r7, r0 # compare the current index to our value in TestClass&lt;br /&gt;
    blt+ loop # loop back if it is less than the value&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Structure Access In Arrays (Direct Array) ====&lt;br /&gt;
Let&#039;s take the previous example and modify it a little. Instead of making an array of pointers to the struct instances, let&#039;s store the array &amp;lt;i&amp;gt;directly&amp;lt;/i&amp;gt; into our class instance.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
struct TestStruct {&lt;br /&gt;
    int SomeMember;&lt;br /&gt;
    int AnotherMember;&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
class TestClass {&lt;br /&gt;
public:&lt;br /&gt;
    TestClass();&lt;br /&gt;
&lt;br /&gt;
    void storeVals();&lt;br /&gt;
&lt;br /&gt;
     TestStruct mStructures[8];&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Again, let us assume that the array has already been constructed and everything is initialized as it should be.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void TestClass::storeVals() {&lt;br /&gt;
    for (int i = 0; i &amp;lt; 8; i++) {&lt;br /&gt;
        mStructures[i].AnotherMember = 5;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
The output assembly would look something like:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
li r0, 8 # load our number of iterations (8)&lt;br /&gt;
li r4, 0 # current offset into the array. initialized at 0&lt;br /&gt;
li r6, 5 # the value to store into the array&lt;br /&gt;
mtctr r0 # move the number of iterations into the counter register&lt;br /&gt;
&lt;br /&gt;
loop:&lt;br /&gt;
    add r5, r3, r4 # jump to the offset into the array. r5 = (this + 0) + r4&lt;br /&gt;
    addi r4, r4, 8 # increment our current offset by sizeof(TestStruct), which is 8&lt;br /&gt;
    stw r6, 4(r5) # store our constant value (5) into the loaded struct + 4 (AnotherMember)&lt;br /&gt;
    bdnz+ loop # branch back to the loop if the counter is not 8&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Shibboleet</name></author>
	</entry>
	<entry>
		<id>https://www.lumasworkshop.com/w/index.php?title=Decompiling&amp;diff=177</id>
		<title>Decompiling</title>
		<link rel="alternate" type="text/html" href="https://www.lumasworkshop.com/w/index.php?title=Decompiling&amp;diff=177"/>
		<updated>2024-04-06T12:19:43Z</updated>

		<summary type="html">&lt;p&gt;Shibboleet: /* Base Class */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Guides]]&lt;br /&gt;
[[Category:Decompiling]]&lt;br /&gt;
{{WIP}}&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
&#039;&#039;Decompiling&#039;&#039; is the process of taking assembly code and turning it back into a higher level language such as C or C++. It is essentially the reverse of &#039;&#039;compiling&#039;&#039;. &#039;&#039;Matching decompilation&#039;&#039; is the process of decompiling, but having the compiled code match the original assembly 1:1. While matching decompilation is harder than normal decompiling, it can become easier when you understand the patterns of the compiler used. This page aims to let new people understand how this process works, and hopefully be able to get new people into decompilation! While you do not need to be an expert at C or C++ to decompile, it is recommended that you have some experience before attempting decompilation. It is also very recommended that you have some prior knowledge of PowerPC assembly, as that is the key to understanding how a function works. [https://www.nxp.com/docs/en/reference-manual/MPC82XINSET.pdf This document] is a good way to learn or refresh knowledge of the PowerPC architecture. [https://www.warthman.com/images/IBM_PPC_Compiler_Writer%27s_Guide-cwg.pdf This document] is also good to learn some of the patterns that CodeWarrior does.&lt;br /&gt;
&lt;br /&gt;
== Getting Set Up ==&lt;br /&gt;
To begin decompiling &#039;&#039;Super Mario Galaxy&#039;&#039;, you first need to set up the environment. You will need the following tools:&lt;br /&gt;
* [https://gitforwindows.org/ Git (Windows)]&lt;br /&gt;
* Any IDE ([https://code.visualstudio.com/ Visual Studio Recommended])&lt;br /&gt;
* [https://www.python.org/downloads/release/python-397/ Python 3.9.7]&lt;br /&gt;
* IDA Pro (recommended) or Ghidra (Not recommended)&lt;br /&gt;
* [https://shibbo.net/smg/RMGK01_01.idb SMG1 Korean IDB (For IDA)]&lt;br /&gt;
* A &#039;&#039;Super Mario Galaxy&#039;&#039; Korean region DOL.&lt;br /&gt;
&lt;br /&gt;
After you have acquired all of these, setting up [https://github.com/shibbo/Petari Petari] is very simple.&lt;br /&gt;
&lt;br /&gt;
# With a new command prompt open, type in &#039;&#039;&#039;git clone https://github.com/shibbo/Petari&#039;&#039;&#039;. This will clone the repository into a directory called &amp;quot;Petari&amp;quot;.&lt;br /&gt;
# In this new &amp;quot;Petari&amp;quot; folder, place the SMG1 Korean &#039;&#039;&#039;main.dol&#039;&#039;&#039; into this folder, and rename it to &#039;&#039;&#039;baserom.dol&#039;&#039;&#039;.&lt;br /&gt;
# Open a new command prompt in the &amp;quot;Petari&amp;quot; folder.&lt;br /&gt;
# Run the command &#039;&#039;&#039;python setup.py&#039;&#039;&#039;. This will verify your DOL and install all of the libraries used, and the compilers we use to compile the code.&lt;br /&gt;
# Run the command &#039;&#039;&#039;python build.py&#039;&#039;&#039;. This will build the entire project. If you see any warnings, do not worry about them.&lt;br /&gt;
&lt;br /&gt;
== Environment ==&lt;br /&gt;
To properly utilize and use &#039;&#039;Petari&#039;&#039;, it is necessary to understand the structure of the environment. Petari is structured in a way that makes it easy to access and use.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Folder Name !! Description&lt;br /&gt;
|-&lt;br /&gt;
| archive || The folder that gets created when &#039;&#039;&#039;build.py -link&#039;&#039;&#039; is ran. Contains an archive of the object files in each library.&lt;br /&gt;
|-&lt;br /&gt;
| build || The folder that gets created when &#039;&#039;&#039;build.py&#039;&#039;&#039; is ran. Contains the compiled object files.&lt;br /&gt;
|-&lt;br /&gt;
| csv || Contains CSV files that store the status of functions being matched.&lt;br /&gt;
|-&lt;br /&gt;
| data || Contains map files and the percentage badges for the GitHub repo.&lt;br /&gt;
|-&lt;br /&gt;
| docs || The folder that gets created when &#039;&#039;&#039;progress.py&#039;&#039;&#039; is ran. Contains all of the Markdown documentation for matching status.&lt;br /&gt;
|-&lt;br /&gt;
| include || Contains all of the header files for &#039;&#039;Super Mario Galaxy&#039;&#039; specific code.&lt;br /&gt;
|-&lt;br /&gt;
| libs || Contains this folder structure but for different libraries used by the game.&lt;br /&gt;
|-&lt;br /&gt;
| scripts || Various scripts used in IDA for generating headers.&lt;br /&gt;
|-&lt;br /&gt;
| source || Contains all of the source files for &#039;&#039;Super Mario Galaxy&#039;&#039; specific code.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Libraries ==&lt;br /&gt;
&#039;&#039;Super Mario Galaxy&#039;&#039; uses a lot of libraries for certain functionality such as heaps, layouts, OS specific code, and more. Each library described in the table below are &#039;&#039;&#039;statically linked&#039;&#039;&#039; to the game, so every library&#039;s used code is inside of the &#039;&#039;main.dol&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
=== Non-SMG Libraries ===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Name !! Language !! Description&lt;br /&gt;
|-&lt;br /&gt;
| JSystem || C++ || Contains classes for backend things, such as heaps and linked lists.&lt;br /&gt;
|-&lt;br /&gt;
| MetroTRK || C || Target Resident Kernel, for debugging.&lt;br /&gt;
|-&lt;br /&gt;
| MSL_C || C &amp;amp; C++ || Contains standard library functions and types.&lt;br /&gt;
|-&lt;br /&gt;
| nw4r || C++ || Contains classes for sounds, layouts, and more. (SMG only uses the layouts and some math functions)&lt;br /&gt;
|-&lt;br /&gt;
| Runtime || C &amp;amp; C++ || Contains functions that relate to CodeWarrior&#039;s runtime code generation (ctor / dtor lists, etc)&lt;br /&gt;
|-&lt;br /&gt;
| RVL_SDK || C || Contains functions that relate to the Wii&#039;s &amp;quot;OS&amp;quot;.&lt;br /&gt;
|-&lt;br /&gt;
| RVLFaceLib || C || Contains functions that relate to Miis.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== SMG Libraries ===&lt;br /&gt;
All of &#039;&#039;Super Mario Galaxy&#039;&#039;&#039;s libraries are written in C++.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Header text !! Header text&lt;br /&gt;
|-&lt;br /&gt;
| Animation || Library for animation playing.&lt;br /&gt;
|-&lt;br /&gt;
| AreaObj || Library for invisible areas that can be accessed by players in the game.&lt;br /&gt;
|-&lt;br /&gt;
| AudioLib || N/A&lt;br /&gt;
|-&lt;br /&gt;
| Boss || Library for all of the bosses and mini-bosses in the game.&lt;br /&gt;
|-&lt;br /&gt;
| Camera || Library for all camera types.&lt;br /&gt;
|-&lt;br /&gt;
| Demo || Library for all cutscenes.&lt;br /&gt;
|-&lt;br /&gt;
| Effect || Library for all effect rendering.&lt;br /&gt;
|-&lt;br /&gt;
| Enemy || Library for all enemies.&lt;br /&gt;
|-&lt;br /&gt;
| GameAudio || N/A&lt;br /&gt;
|-&lt;br /&gt;
| Gravity || Library for all of the gravity types in the game.&lt;br /&gt;
|-&lt;br /&gt;
| LiveActor || Library for LiveActor, which is an actor that can switch states.&lt;br /&gt;
|-&lt;br /&gt;
| Map || Library for map classes that do not directly interact with the player. (ie switches)&lt;br /&gt;
|-&lt;br /&gt;
| MapObj || Library for all of the map objects in the game.&lt;br /&gt;
|-&lt;br /&gt;
| NameObj || Library for the most basic form of an object in the game.&lt;br /&gt;
|-&lt;br /&gt;
| NPC || Library for all of the non-playable characters.&lt;br /&gt;
|-&lt;br /&gt;
| NWC24 || Library for the mail system in the game.&lt;br /&gt;
|-&lt;br /&gt;
| Player || Library for all of the player related functions.&lt;br /&gt;
|-&lt;br /&gt;
| RhythmLib || N/A&lt;br /&gt;
|-&lt;br /&gt;
| Ride || Library for all of the actors that can be controlled by the player.&lt;br /&gt;
|-&lt;br /&gt;
| Scene || Library for all of the game scene related code.&lt;br /&gt;
|-&lt;br /&gt;
| Screen || Library for all of the layouts in the game.&lt;br /&gt;
|-&lt;br /&gt;
| Speaker || Library for the sound effect playing done on the Wiimote.&lt;br /&gt;
|-&lt;br /&gt;
| System || Library for a lot of the game&#039;s backend systems.&lt;br /&gt;
|-&lt;br /&gt;
| Util || Library for utility functions and classes.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Basics ==&lt;br /&gt;
To properly decompile, it is vital to know how a lot of the assembly will translate into C / C++ code. Here are a couple of patterns that you will see when decompiling code.&lt;br /&gt;
&lt;br /&gt;
== Class Mapping ==&lt;br /&gt;
=== Base Class ===&lt;br /&gt;
The first step to decompiling a class is to map out the class itself. You need to be sure that you document every member, its type (as close as you can guess), its virtual functions, and more. The easiest way to achieve this is to look at the class&#039;s &#039;&#039;constructor&#039;&#039;. Seen below, is an example of a &#039;&#039;constructor&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
[[Image:NameObj_Ctor.png|frameless|700px|The constructor for &#039;&#039;NameObj&#039;&#039;.]]&lt;br /&gt;
&lt;br /&gt;
There are a couple of takeaways from this screenshot:&lt;br /&gt;
* The constructor passes an argument, which is a &#039;&#039;&#039;const char *&#039;&#039;&#039; (contained in r4) and is stored in (r3 + 0x4).&lt;br /&gt;
* (r3 + 0x0) is where the vtable is &#039;&#039;usually&#039;&#039; stored when a class has virtual functions. There are rare execptions.&lt;br /&gt;
* (r3 + 0x8) is stored with a &#039;&#039;&#039;sth&#039;&#039;&#039;, which means that it is a &#039;&#039;&#039;short&#039;&#039;&#039; datatype.&lt;br /&gt;
* (r3 + 0xA) is also stored with a &#039;&#039;&#039;sth&#039;&#039;&#039;, but with a &#039;&#039;&#039;-1&#039;&#039;&#039; value, so we know for sure that this type is &#039;&#039;signed&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Keep in mind that a constructor does not have to initialized every single member variable in the class! So there could be other members in a class that aren&#039;t mentioned in the constructor at all. After you look at the constructor, look around at the &#039;&#039;member functions&#039;&#039; to see if they use any members that are not initialized in the constructor. You can always verify if your class setup is correct when you can find where this class is created using the &#039;&#039;&#039;new&#039;&#039;&#039; operator. Check if the size passed to the &#039;&#039;&#039;new&#039;&#039;&#039; call matches the size of the class that you have mapped. If it is smaller, you are missing arguments. If it is bigger, you have too many! Remember that the vtable is implicitly stored at &#039;&#039;&#039;(this + 0x0)&#039;&#039;&#039;, so you do not have to explicitly define it. With all of these members documented, our class setup looks a little like this so far:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class NameObj {&lt;br /&gt;
public:&lt;br /&gt;
    NameObj(const char *pName);&lt;br /&gt;
&lt;br /&gt;
    /* remember that the vtable will be placed here once we define our virtuals! */&lt;br /&gt;
    /* 0x4 */   const char* mName;&lt;br /&gt;
    /* 0x8 */   volatile u16 mFlags;&lt;br /&gt;
    /* 0xA */   s16 mExecutorIdx;&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
After the members comes the &#039;&#039;&#039;vtable&#039;&#039;&#039;, or &#039;&#039;virtual table&#039;&#039;. It is an array of function pointers that can be overridden by classes that inherit the parent class. The vtable for &#039;&#039;&#039;NameObj&#039;&#039;&#039; looks like this:&lt;br /&gt;
[[Image:NameObj_Vtable.png|frameless|700px|The vtable for &#039;&#039;NameObj&#039;&#039;.]]&lt;br /&gt;
&lt;br /&gt;
To document the vtable, you simply document every single function placed here that contains the class name of the class you are currently decompiling. Since &#039;&#039;NameObj&#039;&#039; is a base class, every single function here is going to be defined. If a class overrides a function, you will only document the functions that are overridden. After documenting the vtable, our class looks something like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class NameObj {&lt;br /&gt;
public:&lt;br /&gt;
    NameObj(const char *pName);&lt;br /&gt;
&lt;br /&gt;
    virtual ~NameObj();&lt;br /&gt;
    virtual void init(const JMapInfoIter &amp;amp;rIter);&lt;br /&gt;
    virtual void initAfterPlacement();&lt;br /&gt;
    virtual void movement();&lt;br /&gt;
    virtual void draw() const;&lt;br /&gt;
    virtual void calcAnim();&lt;br /&gt;
    virtual void calcViewAndEntry();&lt;br /&gt;
&lt;br /&gt;
    /* remember that the vtable will be placed here once we define our virtuals! */&lt;br /&gt;
    /* 0x4 */   const char* mName;&lt;br /&gt;
    /* 0x8 */   volatile u16 mFlags;&lt;br /&gt;
    /* 0xA */   s16 mExecutorIdx;&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Once the vtable is complete, you want to document all of the member functions that are in the class. Since &#039;&#039;Super Mario Galaxy 1&#039;&#039; has a symbol map, we can easily find the member functions that &#039;&#039;NameObj&#039;&#039; contains. Once you have figured out their return types and their arguments, you can finish mapping out a class! After finding all of &#039;&#039;NameObj&#039;&#039;&#039;s member functions, the class looks like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class NameObj {&lt;br /&gt;
public:&lt;br /&gt;
    NameObj(const char *pName);&lt;br /&gt;
&lt;br /&gt;
    virtual ~NameObj();&lt;br /&gt;
    virtual void init(const JMapInfoIter &amp;amp;rIter);&lt;br /&gt;
    virtual void initAfterPlacement();&lt;br /&gt;
    virtual void movement();&lt;br /&gt;
    virtual void draw() const;&lt;br /&gt;
    virtual void calcAnim();&lt;br /&gt;
    virtual void calcViewAndEntry();&lt;br /&gt;
&lt;br /&gt;
    void initWithoutIter();&lt;br /&gt;
    void setName(const char *pName);&lt;br /&gt;
    void executeMovement();&lt;br /&gt;
    void requestSuspend();&lt;br /&gt;
    void requestResume();&lt;br /&gt;
    void syncWithFlags();&lt;br /&gt;
&lt;br /&gt;
    /* remember that the vtable will be placed here once we define our virtuals! */&lt;br /&gt;
    /* 0x4 */   const char* mName;&lt;br /&gt;
    /* 0x8 */   volatile u16 mFlags;&lt;br /&gt;
    /* 0xA */   s16 mExecutorIdx;&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Loops ===&lt;br /&gt;
==== Predefined bounds ====&lt;br /&gt;
Let&#039;s take a simple loop that stores &amp;lt;i&amp;gt;nullptr&amp;lt;/i&amp;gt; in each 8 elements of a pointer array.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class TestClass {&lt;br /&gt;
public:&lt;br /&gt;
    TestClass();&lt;br /&gt;
&lt;br /&gt;
     int* mPointers[8];&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
TestClass::TestClass() {&lt;br /&gt;
    for (int i = 0; i &amp;lt; 8; i++) {&lt;br /&gt;
        mPointers[i] = nullptr;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The output assembly would look something like:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
li r0, 8 # there are 8 elements in this loop&lt;br /&gt;
li r5, 0 # the value to store in the element (nullptr)&lt;br /&gt;
li r4, 0 # the current element offset in the loop&lt;br /&gt;
mtctr r0 # move the number of iterations into the counter register (8)&lt;br /&gt;
&lt;br /&gt;
loop:&lt;br /&gt;
    stwx r5, r3, r4 # store 0 (r5) into the array at r3 (this) + r4 (our current offset, which is i * 4)&lt;br /&gt;
    addi r4, r4, 4 # increment our offset by sizeof(int) since integers are 32-bits&lt;br /&gt;
    bdnz+ loop # branch back to our loop again&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Variable Length Bounds ====&lt;br /&gt;
Let&#039;s take a simple loop that stores &amp;lt;i&amp;gt;nullptr&amp;lt;/i&amp;gt; in each element of a variable-length array. We will have a class with two members, one that contains the pointer array itself, and another that stores the number of pointers.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class TestClass {&lt;br /&gt;
public:&lt;br /&gt;
    TestClass();&lt;br /&gt;
&lt;br /&gt;
     int** mPointers;&lt;br /&gt;
     int mNumPointers;&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
TestClass::TestClass() {&lt;br /&gt;
    mNumPointers = 8;&lt;br /&gt;
    for (int i = 0; i &amp;lt; mNumPointers ; i++) {&lt;br /&gt;
        mPointers[i] = nullptr;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Because we do not know how many pointers we have stored, we cannot use the counter register like we did with a fixed-size array. Instead, the compiler will use a cmpw (signed integer) or cmplw (unsigned) instruction to compare the current iteration to how many pointers are stored in the class.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
li r0, 8 # there are 8 elements in this loop&lt;br /&gt;
li r7, 0 # the value to store in the element (nullptr)&lt;br /&gt;
stw r0, 4(r3) # r3 + 4 is the offset to our member variable &amp;quot;mNumPointers&amp;quot;&lt;br /&gt;
mr r6, r7 # simple copy of the 0 value so we can also use it for our counter&lt;br /&gt;
li r4, 0 # load 0 into our offset&lt;br /&gt;
b loop # branch into our loop&lt;br /&gt;
&lt;br /&gt;
loop:&lt;br /&gt;
    lwz r5, 0(r3) # load our pointer array from this + 0&lt;br /&gt;
    addi r7, r7, 1 # increment our index by 1&lt;br /&gt;
    stwx r6, r5, r4 # store our nullptr value (r6) into r5 + r4 (ptrArray + currentOffset)&lt;br /&gt;
    addi r4, r4, 4 # increment our offset by sizeof(int) since integers are 32-bits&lt;br /&gt;
    lwz r0, 4(r3) # load our number of pointers we will increment by (mNumPointers)&lt;br /&gt;
    cmpw r7, r0 # compare our number of pointers to the current index in our loop&lt;br /&gt;
    blt+ loop # branch if the number is less than mNumPointers&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Structure Access In Arrays (Pointer Array) ====&lt;br /&gt;
More complex forms of loops comes into play when you are iterating through structures and storing / loading members from those structures. Let&#039;s take this class for example:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
struct TestStruct {&lt;br /&gt;
    int SomeMember;&lt;br /&gt;
    int AnotherMember;&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
class TestClass {&lt;br /&gt;
public:&lt;br /&gt;
    TestClass();&lt;br /&gt;
&lt;br /&gt;
    void storeVals();&lt;br /&gt;
&lt;br /&gt;
     TestStruct** mStructures;&lt;br /&gt;
     int mNumStructures;&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
For the sake of simplicity, let&#039;s assume that the TestClass constructor initializes the number of structures to 8, and constructs them accordingly. With that in mind, let&#039;s see how a struct store will work.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void TestClass::storeVals() {&lt;br /&gt;
    for (int i = 0; i &amp;lt; mNumStructures; i++) {&lt;br /&gt;
        mStructures[i]-&amp;gt;AnotherMember = 5;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
The output assembly would look something like:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
li r7, 0 # our &amp;quot;i&amp;quot; used in the loop, starts at 0&lt;br /&gt;
li r4, 0 # our current offset into the array&lt;br /&gt;
li r6, 5 # the value we are storing into the array&lt;br /&gt;
b loop&lt;br /&gt;
&lt;br /&gt;
loop:&lt;br /&gt;
    lwz r5, 0(r3) # load the array pointer&lt;br /&gt;
    addi r7, r7, 1 # increment our current index (i) by 1&lt;br /&gt;
    lwzx r5, r5, r4 # load the current structure, mStructures[i] where r4 is the current offset&lt;br /&gt;
    addi r4, r4, 4 # increment our offset by sizeof(TestStruct*), which is 4&lt;br /&gt;
    stw r6, 4(r5) # store our value (5) into (mStructures[i] + 4), which is our AnotherMember&lt;br /&gt;
    lwz r0, 4(r3) # load the number of structures from TestClass&lt;br /&gt;
    cmpw r7, r0 # compare the current index to our value in TestClass&lt;br /&gt;
    blt+ loop # loop back if it is less than the value&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Structure Access In Arrays (Direct Array) ====&lt;br /&gt;
Let&#039;s take the previous example and modify it a little. Instead of making an array of pointers to the struct instances, let&#039;s store the array &amp;lt;i&amp;gt;directly&amp;lt;/i&amp;gt; into our class instance.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
struct TestStruct {&lt;br /&gt;
    int SomeMember;&lt;br /&gt;
    int AnotherMember;&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
class TestClass {&lt;br /&gt;
public:&lt;br /&gt;
    TestClass();&lt;br /&gt;
&lt;br /&gt;
    void storeVals();&lt;br /&gt;
&lt;br /&gt;
     TestStruct mStructures[8];&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Again, let us assume that the array has already been constructed and everything is initialized as it should be.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void TestClass::storeVals() {&lt;br /&gt;
    for (int i = 0; i &amp;lt; 8; i++) {&lt;br /&gt;
        mStructures[i].AnotherMember = 5;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
The output assembly would look something like:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
li r0, 8 # load our number of iterations (8)&lt;br /&gt;
li r4, 0 # current offset into the array. initialized at 0&lt;br /&gt;
li r6, 5 # the value to store into the array&lt;br /&gt;
mtctr r0 # move the number of iterations into the counter register&lt;br /&gt;
&lt;br /&gt;
loop:&lt;br /&gt;
    add r5, r3, r4 # jump to the offset into the array. r5 = (this + 0) + r4&lt;br /&gt;
    addi r4, r4, 8 # increment our current offset by sizeof(TestStruct), which is 8&lt;br /&gt;
    stw r6, 4(r5) # store our constant value (5) into the loaded struct + 4 (AnotherMember)&lt;br /&gt;
    bdnz+ loop # branch back to the loop if the counter is not 8&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Shibboleet</name></author>
	</entry>
	<entry>
		<id>https://www.lumasworkshop.com/w/index.php?title=Decompiling&amp;diff=176</id>
		<title>Decompiling</title>
		<link rel="alternate" type="text/html" href="https://www.lumasworkshop.com/w/index.php?title=Decompiling&amp;diff=176"/>
		<updated>2024-04-06T12:19:05Z</updated>

		<summary type="html">&lt;p&gt;Shibboleet: class mapping&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Guides]]&lt;br /&gt;
[[Category:Decompiling]]&lt;br /&gt;
{{WIP}}&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
&#039;&#039;Decompiling&#039;&#039; is the process of taking assembly code and turning it back into a higher level language such as C or C++. It is essentially the reverse of &#039;&#039;compiling&#039;&#039;. &#039;&#039;Matching decompilation&#039;&#039; is the process of decompiling, but having the compiled code match the original assembly 1:1. While matching decompilation is harder than normal decompiling, it can become easier when you understand the patterns of the compiler used. This page aims to let new people understand how this process works, and hopefully be able to get new people into decompilation! While you do not need to be an expert at C or C++ to decompile, it is recommended that you have some experience before attempting decompilation. It is also very recommended that you have some prior knowledge of PowerPC assembly, as that is the key to understanding how a function works. [https://www.nxp.com/docs/en/reference-manual/MPC82XINSET.pdf This document] is a good way to learn or refresh knowledge of the PowerPC architecture. [https://www.warthman.com/images/IBM_PPC_Compiler_Writer%27s_Guide-cwg.pdf This document] is also good to learn some of the patterns that CodeWarrior does.&lt;br /&gt;
&lt;br /&gt;
== Getting Set Up ==&lt;br /&gt;
To begin decompiling &#039;&#039;Super Mario Galaxy&#039;&#039;, you first need to set up the environment. You will need the following tools:&lt;br /&gt;
* [https://gitforwindows.org/ Git (Windows)]&lt;br /&gt;
* Any IDE ([https://code.visualstudio.com/ Visual Studio Recommended])&lt;br /&gt;
* [https://www.python.org/downloads/release/python-397/ Python 3.9.7]&lt;br /&gt;
* IDA Pro (recommended) or Ghidra (Not recommended)&lt;br /&gt;
* [https://shibbo.net/smg/RMGK01_01.idb SMG1 Korean IDB (For IDA)]&lt;br /&gt;
* A &#039;&#039;Super Mario Galaxy&#039;&#039; Korean region DOL.&lt;br /&gt;
&lt;br /&gt;
After you have acquired all of these, setting up [https://github.com/shibbo/Petari Petari] is very simple.&lt;br /&gt;
&lt;br /&gt;
# With a new command prompt open, type in &#039;&#039;&#039;git clone https://github.com/shibbo/Petari&#039;&#039;&#039;. This will clone the repository into a directory called &amp;quot;Petari&amp;quot;.&lt;br /&gt;
# In this new &amp;quot;Petari&amp;quot; folder, place the SMG1 Korean &#039;&#039;&#039;main.dol&#039;&#039;&#039; into this folder, and rename it to &#039;&#039;&#039;baserom.dol&#039;&#039;&#039;.&lt;br /&gt;
# Open a new command prompt in the &amp;quot;Petari&amp;quot; folder.&lt;br /&gt;
# Run the command &#039;&#039;&#039;python setup.py&#039;&#039;&#039;. This will verify your DOL and install all of the libraries used, and the compilers we use to compile the code.&lt;br /&gt;
# Run the command &#039;&#039;&#039;python build.py&#039;&#039;&#039;. This will build the entire project. If you see any warnings, do not worry about them.&lt;br /&gt;
&lt;br /&gt;
== Environment ==&lt;br /&gt;
To properly utilize and use &#039;&#039;Petari&#039;&#039;, it is necessary to understand the structure of the environment. Petari is structured in a way that makes it easy to access and use.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Folder Name !! Description&lt;br /&gt;
|-&lt;br /&gt;
| archive || The folder that gets created when &#039;&#039;&#039;build.py -link&#039;&#039;&#039; is ran. Contains an archive of the object files in each library.&lt;br /&gt;
|-&lt;br /&gt;
| build || The folder that gets created when &#039;&#039;&#039;build.py&#039;&#039;&#039; is ran. Contains the compiled object files.&lt;br /&gt;
|-&lt;br /&gt;
| csv || Contains CSV files that store the status of functions being matched.&lt;br /&gt;
|-&lt;br /&gt;
| data || Contains map files and the percentage badges for the GitHub repo.&lt;br /&gt;
|-&lt;br /&gt;
| docs || The folder that gets created when &#039;&#039;&#039;progress.py&#039;&#039;&#039; is ran. Contains all of the Markdown documentation for matching status.&lt;br /&gt;
|-&lt;br /&gt;
| include || Contains all of the header files for &#039;&#039;Super Mario Galaxy&#039;&#039; specific code.&lt;br /&gt;
|-&lt;br /&gt;
| libs || Contains this folder structure but for different libraries used by the game.&lt;br /&gt;
|-&lt;br /&gt;
| scripts || Various scripts used in IDA for generating headers.&lt;br /&gt;
|-&lt;br /&gt;
| source || Contains all of the source files for &#039;&#039;Super Mario Galaxy&#039;&#039; specific code.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Libraries ==&lt;br /&gt;
&#039;&#039;Super Mario Galaxy&#039;&#039; uses a lot of libraries for certain functionality such as heaps, layouts, OS specific code, and more. Each library described in the table below are &#039;&#039;&#039;statically linked&#039;&#039;&#039; to the game, so every library&#039;s used code is inside of the &#039;&#039;main.dol&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
=== Non-SMG Libraries ===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Name !! Language !! Description&lt;br /&gt;
|-&lt;br /&gt;
| JSystem || C++ || Contains classes for backend things, such as heaps and linked lists.&lt;br /&gt;
|-&lt;br /&gt;
| MetroTRK || C || Target Resident Kernel, for debugging.&lt;br /&gt;
|-&lt;br /&gt;
| MSL_C || C &amp;amp; C++ || Contains standard library functions and types.&lt;br /&gt;
|-&lt;br /&gt;
| nw4r || C++ || Contains classes for sounds, layouts, and more. (SMG only uses the layouts and some math functions)&lt;br /&gt;
|-&lt;br /&gt;
| Runtime || C &amp;amp; C++ || Contains functions that relate to CodeWarrior&#039;s runtime code generation (ctor / dtor lists, etc)&lt;br /&gt;
|-&lt;br /&gt;
| RVL_SDK || C || Contains functions that relate to the Wii&#039;s &amp;quot;OS&amp;quot;.&lt;br /&gt;
|-&lt;br /&gt;
| RVLFaceLib || C || Contains functions that relate to Miis.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== SMG Libraries ===&lt;br /&gt;
All of &#039;&#039;Super Mario Galaxy&#039;&#039;&#039;s libraries are written in C++.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Header text !! Header text&lt;br /&gt;
|-&lt;br /&gt;
| Animation || Library for animation playing.&lt;br /&gt;
|-&lt;br /&gt;
| AreaObj || Library for invisible areas that can be accessed by players in the game.&lt;br /&gt;
|-&lt;br /&gt;
| AudioLib || N/A&lt;br /&gt;
|-&lt;br /&gt;
| Boss || Library for all of the bosses and mini-bosses in the game.&lt;br /&gt;
|-&lt;br /&gt;
| Camera || Library for all camera types.&lt;br /&gt;
|-&lt;br /&gt;
| Demo || Library for all cutscenes.&lt;br /&gt;
|-&lt;br /&gt;
| Effect || Library for all effect rendering.&lt;br /&gt;
|-&lt;br /&gt;
| Enemy || Library for all enemies.&lt;br /&gt;
|-&lt;br /&gt;
| GameAudio || N/A&lt;br /&gt;
|-&lt;br /&gt;
| Gravity || Library for all of the gravity types in the game.&lt;br /&gt;
|-&lt;br /&gt;
| LiveActor || Library for LiveActor, which is an actor that can switch states.&lt;br /&gt;
|-&lt;br /&gt;
| Map || Library for map classes that do not directly interact with the player. (ie switches)&lt;br /&gt;
|-&lt;br /&gt;
| MapObj || Library for all of the map objects in the game.&lt;br /&gt;
|-&lt;br /&gt;
| NameObj || Library for the most basic form of an object in the game.&lt;br /&gt;
|-&lt;br /&gt;
| NPC || Library for all of the non-playable characters.&lt;br /&gt;
|-&lt;br /&gt;
| NWC24 || Library for the mail system in the game.&lt;br /&gt;
|-&lt;br /&gt;
| Player || Library for all of the player related functions.&lt;br /&gt;
|-&lt;br /&gt;
| RhythmLib || N/A&lt;br /&gt;
|-&lt;br /&gt;
| Ride || Library for all of the actors that can be controlled by the player.&lt;br /&gt;
|-&lt;br /&gt;
| Scene || Library for all of the game scene related code.&lt;br /&gt;
|-&lt;br /&gt;
| Screen || Library for all of the layouts in the game.&lt;br /&gt;
|-&lt;br /&gt;
| Speaker || Library for the sound effect playing done on the Wiimote.&lt;br /&gt;
|-&lt;br /&gt;
| System || Library for a lot of the game&#039;s backend systems.&lt;br /&gt;
|-&lt;br /&gt;
| Util || Library for utility functions and classes.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Basics ==&lt;br /&gt;
To properly decompile, it is vital to know how a lot of the assembly will translate into C / C++ code. Here are a couple of patterns that you will see when decompiling code.&lt;br /&gt;
&lt;br /&gt;
== Class Mapping ==&lt;br /&gt;
=== Base Class ===&lt;br /&gt;
The first step to decompiling a class is to map out the class itself. You need to be sure that you document every member, it&#039;s type (as close as you can guess), it&#039;s virtual functions, and more. The easiest way to achieve this is to look at the class&#039;s &#039;&#039;constructor&#039;&#039;. Seen below, is an example of a &#039;&#039;constructor&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
[[Image:NameObj_Ctor.png|frameless|700px|The constructor for &#039;&#039;NameObj&#039;&#039;.]]&lt;br /&gt;
&lt;br /&gt;
There are a couple of takeaways from this screenshot:&lt;br /&gt;
* The constructor passes an argument, which is a &#039;&#039;&#039;const char *&#039;&#039;&#039; (contained in r4) and is stored in (r3 + 0x4).&lt;br /&gt;
* (r3 + 0x0) is where the vtable is &#039;&#039;usually&#039;&#039; stored when a class has virtual functions. There are rare execptions.&lt;br /&gt;
* (r3 + 0x8) is stored with a &#039;&#039;&#039;sth&#039;&#039;&#039;, which means that it is a &#039;&#039;&#039;short&#039;&#039;&#039; datatype.&lt;br /&gt;
* (r3 + 0xA) is also stored with a &#039;&#039;&#039;sth&#039;&#039;&#039;, but with a &#039;&#039;&#039;-1&#039;&#039;&#039; value, so we know for sure that this type is &#039;&#039;signed&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Keep in mind that a constructor does not have to initialized every single member variable in the class! So there could be other members in a class that aren&#039;t mentioned in the constructor at all. After you look at the constructor, look around at the &#039;&#039;member functions&#039;&#039; to see if they use any members that are not initialized in the constructor. You can always verify if your class setup is correct when you can find where this class is created using the &#039;&#039;&#039;new&#039;&#039;&#039; operator. Check if the size passed to the &#039;&#039;&#039;new&#039;&#039;&#039; call matches the size of the class that you have mapped. If it is smaller, you are missing arguments. If it is bigger, you have too many! Remember that the vtable is implicitly stored at &#039;&#039;&#039;(this + 0x0)&#039;&#039;&#039;, so you do not have to explicitly define it. With all of these members documented, our class setup looks a little like this so far:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class NameObj {&lt;br /&gt;
public:&lt;br /&gt;
    NameObj(const char *pName);&lt;br /&gt;
&lt;br /&gt;
    /* remember that the vtable will be placed here once we define our virtuals! */&lt;br /&gt;
    /* 0x4 */   const char* mName;&lt;br /&gt;
    /* 0x8 */   volatile u16 mFlags;&lt;br /&gt;
    /* 0xA */   s16 mExecutorIdx;&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
After the members comes the &#039;&#039;&#039;vtable&#039;&#039;&#039;, or &#039;&#039;virtual table&#039;&#039;. It is an array of function pointers that can be overridden by classes that inherit the parent class. The vtable for &#039;&#039;&#039;NameObj&#039;&#039;&#039; looks like this:&lt;br /&gt;
[[Image:NameObj_Vtable.png|frameless|700px|The vtable for &#039;&#039;NameObj&#039;&#039;.]]&lt;br /&gt;
&lt;br /&gt;
To document the vtable, you simply document every single function placed here that contains the class name of the class you are currently decompiling. Since &#039;&#039;NameObj&#039;&#039; is a base class, every single function here is going to be defined. If a class overrides a function, you will only document the functions that are overridden. After documenting the vtable, our class looks something like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class NameObj {&lt;br /&gt;
public:&lt;br /&gt;
    NameObj(const char *pName);&lt;br /&gt;
&lt;br /&gt;
    virtual ~NameObj();&lt;br /&gt;
    virtual void init(const JMapInfoIter &amp;amp;rIter);&lt;br /&gt;
    virtual void initAfterPlacement();&lt;br /&gt;
    virtual void movement();&lt;br /&gt;
    virtual void draw() const;&lt;br /&gt;
    virtual void calcAnim();&lt;br /&gt;
    virtual void calcViewAndEntry();&lt;br /&gt;
&lt;br /&gt;
    /* remember that the vtable will be placed here once we define our virtuals! */&lt;br /&gt;
    /* 0x4 */   const char* mName;&lt;br /&gt;
    /* 0x8 */   volatile u16 mFlags;&lt;br /&gt;
    /* 0xA */   s16 mExecutorIdx;&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Once the vtable is complete, you want to document all of the member functions that are in the class. Since &#039;&#039;Super Mario Galaxy 1&#039;&#039; has a symbol map, we can easily find the member functions that &#039;&#039;NameObj&#039;&#039; contains. Once you have figured out their return types and their arguments, you can finish mapping out a class! After finding all of &#039;&#039;NameObj&#039;&#039;&#039;s member functions, the class looks like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class NameObj {&lt;br /&gt;
public:&lt;br /&gt;
    NameObj(const char *pName);&lt;br /&gt;
&lt;br /&gt;
    virtual ~NameObj();&lt;br /&gt;
    virtual void init(const JMapInfoIter &amp;amp;rIter);&lt;br /&gt;
    virtual void initAfterPlacement();&lt;br /&gt;
    virtual void movement();&lt;br /&gt;
    virtual void draw() const;&lt;br /&gt;
    virtual void calcAnim();&lt;br /&gt;
    virtual void calcViewAndEntry();&lt;br /&gt;
&lt;br /&gt;
    void initWithoutIter();&lt;br /&gt;
    void setName(const char *pName);&lt;br /&gt;
    void executeMovement();&lt;br /&gt;
    void requestSuspend();&lt;br /&gt;
    void requestResume();&lt;br /&gt;
    void syncWithFlags();&lt;br /&gt;
&lt;br /&gt;
    /* remember that the vtable will be placed here once we define our virtuals! */&lt;br /&gt;
    /* 0x4 */   const char* mName;&lt;br /&gt;
    /* 0x8 */   volatile u16 mFlags;&lt;br /&gt;
    /* 0xA */   s16 mExecutorIdx;&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Loops ===&lt;br /&gt;
==== Predefined bounds ====&lt;br /&gt;
Let&#039;s take a simple loop that stores &amp;lt;i&amp;gt;nullptr&amp;lt;/i&amp;gt; in each 8 elements of a pointer array.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class TestClass {&lt;br /&gt;
public:&lt;br /&gt;
    TestClass();&lt;br /&gt;
&lt;br /&gt;
     int* mPointers[8];&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
TestClass::TestClass() {&lt;br /&gt;
    for (int i = 0; i &amp;lt; 8; i++) {&lt;br /&gt;
        mPointers[i] = nullptr;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The output assembly would look something like:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
li r0, 8 # there are 8 elements in this loop&lt;br /&gt;
li r5, 0 # the value to store in the element (nullptr)&lt;br /&gt;
li r4, 0 # the current element offset in the loop&lt;br /&gt;
mtctr r0 # move the number of iterations into the counter register (8)&lt;br /&gt;
&lt;br /&gt;
loop:&lt;br /&gt;
    stwx r5, r3, r4 # store 0 (r5) into the array at r3 (this) + r4 (our current offset, which is i * 4)&lt;br /&gt;
    addi r4, r4, 4 # increment our offset by sizeof(int) since integers are 32-bits&lt;br /&gt;
    bdnz+ loop # branch back to our loop again&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Variable Length Bounds ====&lt;br /&gt;
Let&#039;s take a simple loop that stores &amp;lt;i&amp;gt;nullptr&amp;lt;/i&amp;gt; in each element of a variable-length array. We will have a class with two members, one that contains the pointer array itself, and another that stores the number of pointers.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class TestClass {&lt;br /&gt;
public:&lt;br /&gt;
    TestClass();&lt;br /&gt;
&lt;br /&gt;
     int** mPointers;&lt;br /&gt;
     int mNumPointers;&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
TestClass::TestClass() {&lt;br /&gt;
    mNumPointers = 8;&lt;br /&gt;
    for (int i = 0; i &amp;lt; mNumPointers ; i++) {&lt;br /&gt;
        mPointers[i] = nullptr;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Because we do not know how many pointers we have stored, we cannot use the counter register like we did with a fixed-size array. Instead, the compiler will use a cmpw (signed integer) or cmplw (unsigned) instruction to compare the current iteration to how many pointers are stored in the class.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
li r0, 8 # there are 8 elements in this loop&lt;br /&gt;
li r7, 0 # the value to store in the element (nullptr)&lt;br /&gt;
stw r0, 4(r3) # r3 + 4 is the offset to our member variable &amp;quot;mNumPointers&amp;quot;&lt;br /&gt;
mr r6, r7 # simple copy of the 0 value so we can also use it for our counter&lt;br /&gt;
li r4, 0 # load 0 into our offset&lt;br /&gt;
b loop # branch into our loop&lt;br /&gt;
&lt;br /&gt;
loop:&lt;br /&gt;
    lwz r5, 0(r3) # load our pointer array from this + 0&lt;br /&gt;
    addi r7, r7, 1 # increment our index by 1&lt;br /&gt;
    stwx r6, r5, r4 # store our nullptr value (r6) into r5 + r4 (ptrArray + currentOffset)&lt;br /&gt;
    addi r4, r4, 4 # increment our offset by sizeof(int) since integers are 32-bits&lt;br /&gt;
    lwz r0, 4(r3) # load our number of pointers we will increment by (mNumPointers)&lt;br /&gt;
    cmpw r7, r0 # compare our number of pointers to the current index in our loop&lt;br /&gt;
    blt+ loop # branch if the number is less than mNumPointers&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Structure Access In Arrays (Pointer Array) ====&lt;br /&gt;
More complex forms of loops comes into play when you are iterating through structures and storing / loading members from those structures. Let&#039;s take this class for example:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
struct TestStruct {&lt;br /&gt;
    int SomeMember;&lt;br /&gt;
    int AnotherMember;&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
class TestClass {&lt;br /&gt;
public:&lt;br /&gt;
    TestClass();&lt;br /&gt;
&lt;br /&gt;
    void storeVals();&lt;br /&gt;
&lt;br /&gt;
     TestStruct** mStructures;&lt;br /&gt;
     int mNumStructures;&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
For the sake of simplicity, let&#039;s assume that the TestClass constructor initializes the number of structures to 8, and constructs them accordingly. With that in mind, let&#039;s see how a struct store will work.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void TestClass::storeVals() {&lt;br /&gt;
    for (int i = 0; i &amp;lt; mNumStructures; i++) {&lt;br /&gt;
        mStructures[i]-&amp;gt;AnotherMember = 5;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
The output assembly would look something like:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
li r7, 0 # our &amp;quot;i&amp;quot; used in the loop, starts at 0&lt;br /&gt;
li r4, 0 # our current offset into the array&lt;br /&gt;
li r6, 5 # the value we are storing into the array&lt;br /&gt;
b loop&lt;br /&gt;
&lt;br /&gt;
loop:&lt;br /&gt;
    lwz r5, 0(r3) # load the array pointer&lt;br /&gt;
    addi r7, r7, 1 # increment our current index (i) by 1&lt;br /&gt;
    lwzx r5, r5, r4 # load the current structure, mStructures[i] where r4 is the current offset&lt;br /&gt;
    addi r4, r4, 4 # increment our offset by sizeof(TestStruct*), which is 4&lt;br /&gt;
    stw r6, 4(r5) # store our value (5) into (mStructures[i] + 4), which is our AnotherMember&lt;br /&gt;
    lwz r0, 4(r3) # load the number of structures from TestClass&lt;br /&gt;
    cmpw r7, r0 # compare the current index to our value in TestClass&lt;br /&gt;
    blt+ loop # loop back if it is less than the value&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Structure Access In Arrays (Direct Array) ====&lt;br /&gt;
Let&#039;s take the previous example and modify it a little. Instead of making an array of pointers to the struct instances, let&#039;s store the array &amp;lt;i&amp;gt;directly&amp;lt;/i&amp;gt; into our class instance.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
struct TestStruct {&lt;br /&gt;
    int SomeMember;&lt;br /&gt;
    int AnotherMember;&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
class TestClass {&lt;br /&gt;
public:&lt;br /&gt;
    TestClass();&lt;br /&gt;
&lt;br /&gt;
    void storeVals();&lt;br /&gt;
&lt;br /&gt;
     TestStruct mStructures[8];&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Again, let us assume that the array has already been constructed and everything is initialized as it should be.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void TestClass::storeVals() {&lt;br /&gt;
    for (int i = 0; i &amp;lt; 8; i++) {&lt;br /&gt;
        mStructures[i].AnotherMember = 5;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
The output assembly would look something like:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
li r0, 8 # load our number of iterations (8)&lt;br /&gt;
li r4, 0 # current offset into the array. initialized at 0&lt;br /&gt;
li r6, 5 # the value to store into the array&lt;br /&gt;
mtctr r0 # move the number of iterations into the counter register&lt;br /&gt;
&lt;br /&gt;
loop:&lt;br /&gt;
    add r5, r3, r4 # jump to the offset into the array. r5 = (this + 0) + r4&lt;br /&gt;
    addi r4, r4, 8 # increment our current offset by sizeof(TestStruct), which is 8&lt;br /&gt;
    stw r6, 4(r5) # store our constant value (5) into the loaded struct + 4 (AnotherMember)&lt;br /&gt;
    bdnz+ loop # branch back to the loop if the counter is not 8&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Shibboleet</name></author>
	</entry>
	<entry>
		<id>https://www.lumasworkshop.com/w/index.php?title=File:NameObj_Vtable.png&amp;diff=175</id>
		<title>File:NameObj Vtable.png</title>
		<link rel="alternate" type="text/html" href="https://www.lumasworkshop.com/w/index.php?title=File:NameObj_Vtable.png&amp;diff=175"/>
		<updated>2024-04-06T12:14:15Z</updated>

		<summary type="html">&lt;p&gt;Shibboleet: vtable for nameobj&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Summary ==&lt;br /&gt;
vtable for nameobj&lt;/div&gt;</summary>
		<author><name>Shibboleet</name></author>
	</entry>
	<entry>
		<id>https://www.lumasworkshop.com/w/index.php?title=File:NameObj_Ctor.png&amp;diff=174</id>
		<title>File:NameObj Ctor.png</title>
		<link rel="alternate" type="text/html" href="https://www.lumasworkshop.com/w/index.php?title=File:NameObj_Ctor.png&amp;diff=174"/>
		<updated>2024-04-06T12:01:12Z</updated>

		<summary type="html">&lt;p&gt;Shibboleet: NameObj constructor image&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Summary ==&lt;br /&gt;
NameObj constructor image&lt;/div&gt;</summary>
		<author><name>Shibboleet</name></author>
	</entry>
	<entry>
		<id>https://www.lumasworkshop.com/w/index.php?title=MSBT_(File_Format)&amp;diff=140</id>
		<title>MSBT (File Format)</title>
		<link rel="alternate" type="text/html" href="https://www.lumasworkshop.com/w/index.php?title=MSBT_(File_Format)&amp;diff=140"/>
		<updated>2024-03-07T16:05:21Z</updated>

		<summary type="html">&lt;p&gt;Shibboleet: /* Label Indices */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:File formats]]&lt;br /&gt;
&#039;&#039;&#039;MSBT&#039;&#039;&#039; stands for &#039;&#039;Message Binary Text&#039;&#039;, it contains all of the text used in &#039;&#039;&#039;Super Mario Galaxy 2&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
== Header ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; &lt;br /&gt;
! Offset !! Type !! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x00 || String || &#039;&#039;MsgStdBn&#039;&#039; in ASCII.&lt;br /&gt;
|-&lt;br /&gt;
| 0x08 || UInt16 || Endianess. 0xFEFF for Big Endian, 0xFFFE for Little Endian.&lt;br /&gt;
|-&lt;br /&gt;
| 0x0A || UInt32 || Version.&lt;br /&gt;
|-&lt;br /&gt;
| 0x0E || UInt16 || Number of sections.&lt;br /&gt;
|-&lt;br /&gt;
| 0x10 || UInt16 || Padding.&lt;br /&gt;
|-&lt;br /&gt;
| 0x12 || UInt32 || File length.&lt;br /&gt;
|-&lt;br /&gt;
| 0x16 || Byte[0xA] || Padding.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
= Sections =&lt;br /&gt;
After the header follows the sections. It is worth noting that these sections are padded to the nearest 0x10th byte with the value 0xAB.&lt;br /&gt;
&lt;br /&gt;
== LBL1 ==&lt;br /&gt;
&#039;&#039;LBL1&#039;&#039; is a section that contains the &amp;quot;labels&amp;quot; that are assigned to text. It is a hash table to determine the index that the label is stored at. The indices of the offsets are determined by the &amp;quot;hash&amp;quot; of the number of entries in the list and the label name.&lt;br /&gt;
&lt;br /&gt;
=== Header ===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; &lt;br /&gt;
! Offset !! Type !! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x00 || String || &#039;&#039;LBL1&#039;&#039; in ASCII.&lt;br /&gt;
|-&lt;br /&gt;
| 0x04 || UInt32 || Section size. Does not account for this header or padding.&lt;br /&gt;
|-&lt;br /&gt;
| 0x08 || Byte[0x8] || Padding.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Label Entries ===&lt;br /&gt;
&lt;br /&gt;
After the header come the label entries.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; &lt;br /&gt;
! Offset !! Type !! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x00 || UInt32 || Label count.&lt;br /&gt;
|-&lt;br /&gt;
| 0x04 || LabelArray[N] || Labels, where &#039;&#039;&#039;N&#039;&#039;&#039; is the label count read above.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
A label is defined by the following structure:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; &lt;br /&gt;
! Offset !! Type !! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x00 || UInt32 || Number of strings associated with this entry.&lt;br /&gt;
|-&lt;br /&gt;
| 0x04 || UInt32 || Offset to the strings associated with that label, offset relative to the field defining the amount of entries. Reads &#039;&#039;&#039;N&#039;&#039;&#039; strings, depending on the count read above.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Label Indices ===&lt;br /&gt;
The following code can determine the index of a specific label:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def hash_label(label, bucket_count):&lt;br /&gt;
    val = 0&lt;br /&gt;
    for c in label:&lt;br /&gt;
        val = ((val * 0x492) + ord(c)) &amp;amp; 0xFFFFFFFF&lt;br /&gt;
    return val % bucket_count&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For example, a file with &#039;&#039;&#039;0x65&#039;&#039;&#039; label entries with a label string of &#039;&#039;&#039;Pichan001_Flow001&#039;&#039;&#039; will be at index 0 of the label list, with &#039;&#039;&#039;PichanRacer000_Flow002&#039;&#039;&#039; being at index 1, and so on. If there is a gap between two indices, then it is filled with the previous entry&#039;s offset until the next index is determined.&lt;br /&gt;
&lt;br /&gt;
== ATR1 ==&lt;br /&gt;
&lt;br /&gt;
=== Header ===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; &lt;br /&gt;
! Offset !! Type !! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x00 || String || &#039;&#039;ATR1&#039;&#039; in ASCII.&lt;br /&gt;
|-&lt;br /&gt;
| 0x04 || UInt32 || Section size. Does not account for this header or padding.&lt;br /&gt;
|-&lt;br /&gt;
| 0x08 || Byte[0x8] || Padding.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Attribute Entries ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; &lt;br /&gt;
! Offset !! Type !! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x00 || UInt32 || Attribute set count.&lt;br /&gt;
|-&lt;br /&gt;
| 0x04 || UInt32 || Attribute size. The size of each attribute in bytes.&lt;br /&gt;
|-&lt;br /&gt;
| 0x08 || AttributeSetArray[N] || Attribute sets, where &#039;&#039;&#039;N&#039;&#039;&#039; is the set count read above.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The attribute structure is dependent on the game, but in Super Mario Galaxy 2 each attribute is of size 0x0C and has the following structure:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; &lt;br /&gt;
! Offset !! Type !! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x00 || Byte || NPC Sound ID.&amp;lt;/br&amp;gt;TODO: Add a list of NPC Sounds here?&lt;br /&gt;
|-&lt;br /&gt;
| 0x01 || Byte || Camera type.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! ID !! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0 || AUTOMATIC - The camera will be handled automatically by the game.&lt;br /&gt;
|-&lt;br /&gt;
| 1 || MANUAL - The camera used will be one from the CameraParam.bcam file inside the zone&#039;s Map archive.&lt;br /&gt;
|-&lt;br /&gt;
| 2 || NONE - The camera will not change.&lt;br /&gt;
|}&lt;br /&gt;
|-&lt;br /&gt;
| 0x02 || Byte || Trigger type.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! ID !! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0 || The player has to be close to the NPC and press A to start the dialog.&lt;br /&gt;
|-&lt;br /&gt;
| 1 || The dialog is activated automatically when the player is close, but the player can still move when the dialog has started. The dialog stops when the player exits the trigger area.&lt;br /&gt;
|-&lt;br /&gt;
| 2 || The dialog is activated automatically when the player is close, but the player has to finish the dialog to continue moving.&lt;br /&gt;
|-&lt;br /&gt;
| 3 || The dialog is activated automatically when the player is anywhere (or in a much larger area?), but works otherwise like 2.&lt;br /&gt;
|}&lt;br /&gt;
|-&lt;br /&gt;
| 0x03 || Byte || Dialog style.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! ID !! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0 &amp;amp;ndash; 2 || White textbox.&lt;br /&gt;
|-&lt;br /&gt;
| 3 || Billboard textbox.&lt;br /&gt;
|}&lt;br /&gt;
|-&lt;br /&gt;
| 0x04 || UInt16 || Camera ID. This is the ID that you find inside the CameraParam.bcam file. Needs to be higher than 0.&lt;br /&gt;
|-&lt;br /&gt;
| 0x06 || Byte || MessageArea ID. This matches with MessageArea&#039;s Obj Arg 0.&lt;br /&gt;
|-&lt;br /&gt;
| 0x07 || Byte ||&lt;br /&gt;
|-&lt;br /&gt;
| 0x08 || UInt32 || Offset to a UTF-16 encoded, null terminated, string. Seems to be unused.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== TXT2 ==&lt;br /&gt;
&lt;br /&gt;
=== Header ===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; &lt;br /&gt;
! Offset !! Type !! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x00 || String || &#039;&#039;TXT2&#039;&#039; in ASCII.&lt;br /&gt;
|-&lt;br /&gt;
| 0x04 || UInt32 || Section size. Does not account for this header or padding.&lt;br /&gt;
|-&lt;br /&gt;
| 0x08 || Byte[0x8] || Padding.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Text Entries ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; &lt;br /&gt;
! Offset !! Type !! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x00 || UInt32 || Text count.&lt;br /&gt;
|-&lt;br /&gt;
| 0x04 || Text[N] || Texts, where &#039;&#039;&#039;N&#039;&#039;&#039; is the text count read above.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
A text entry is a UTF-16 string, with embedded &amp;quot;tags&amp;quot; that affect the way the text displays and functions. A tag begins with a value of 0x000E and then the &amp;quot;tag&amp;quot;. The following &amp;quot;tags&amp;quot; are possible:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; &lt;br /&gt;
! Type !! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x0 || System Group&lt;br /&gt;
|-&lt;br /&gt;
| 0x1 || Display Group&lt;br /&gt;
|-&lt;br /&gt;
| 0x2 || Sound Group&lt;br /&gt;
|-&lt;br /&gt;
| 0x3 || Picture Group&lt;br /&gt;
|-&lt;br /&gt;
| 0x4 || Font Size Group&lt;br /&gt;
|-&lt;br /&gt;
| 0x5 || Localize Group&lt;br /&gt;
|-&lt;br /&gt;
| 0x6 || Number Group&lt;br /&gt;
|-&lt;br /&gt;
| 0x7 || String Group&lt;br /&gt;
|-&lt;br /&gt;
| 0x9 || Race Time Group&lt;br /&gt;
|-&lt;br /&gt;
| 0xA || Font Group&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
A &amp;quot;tag&amp;quot; can have a &amp;quot;command&amp;quot;, which tells it how to function.&lt;br /&gt;
&lt;br /&gt;
=== System Group ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; &lt;br /&gt;
! Offset !! Type !! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x00 || UInt16 || Type. [0 == Japanese, 3 == Color]&lt;br /&gt;
|-&lt;br /&gt;
| 0x02 || UInt16 || Data size.&lt;br /&gt;
|-&lt;br /&gt;
| 0x04 || UInt16 || The color to use.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Display Group ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; &lt;br /&gt;
! Offset !! Type !! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x00 || UInt16 || Display type.&lt;br /&gt;
|-&lt;br /&gt;
| 0x02 || UInt16 || Data size.&lt;br /&gt;
|-&lt;br /&gt;
| 0x04 || UInt16 || Padding.&lt;br /&gt;
|-&lt;br /&gt;
| 0x06 || UInt16 || Number of frames to wait if the type is 0.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Sound Group ===&lt;br /&gt;
Plays a given sound.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; &lt;br /&gt;
! Offset !! Type !! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x00 || UInt16 || Should always be 2.&lt;br /&gt;
|-&lt;br /&gt;
| 0x02 || UInt16 || &lt;br /&gt;
|-&lt;br /&gt;
| 0x04 || UInt16 || String length.&lt;br /&gt;
|-&lt;br /&gt;
| 0x06 || String[Length] || UTF-16 string containing the sound effect to play.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Picture Group ===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; &lt;br /&gt;
! Offset !! Type !! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x00 || UInt16 || Character index.&lt;br /&gt;
|-&lt;br /&gt;
| 0x02 || UInt16 || Font.&lt;br /&gt;
|-&lt;br /&gt;
| 0x04 || UInt16 || Character ID.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Font Size Group ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; &lt;br /&gt;
! Offset !! Type !! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x00 || UInt16 || Font Size.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Localize Group ===&lt;br /&gt;
Inserts the current player&#039;s name.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; &lt;br /&gt;
! Offset !! Type !! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x00 || Byte[0x6] || &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Number Group ===&lt;br /&gt;
&lt;br /&gt;
=== String Group ===&lt;br /&gt;
&lt;br /&gt;
=== Race Time Group ===&lt;br /&gt;
&lt;br /&gt;
=== Font Group ===&lt;/div&gt;</summary>
		<author><name>Shibboleet</name></author>
	</entry>
	<entry>
		<id>https://www.lumasworkshop.com/w/index.php?title=MSBT_(File_Format)&amp;diff=139</id>
		<title>MSBT (File Format)</title>
		<link rel="alternate" type="text/html" href="https://www.lumasworkshop.com/w/index.php?title=MSBT_(File_Format)&amp;diff=139"/>
		<updated>2024-03-07T16:04:14Z</updated>

		<summary type="html">&lt;p&gt;Shibboleet: be more specific about how the hash table on LBL1 works&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:File formats]]&lt;br /&gt;
&#039;&#039;&#039;MSBT&#039;&#039;&#039; stands for &#039;&#039;Message Binary Text&#039;&#039;, it contains all of the text used in &#039;&#039;&#039;Super Mario Galaxy 2&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
== Header ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; &lt;br /&gt;
! Offset !! Type !! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x00 || String || &#039;&#039;MsgStdBn&#039;&#039; in ASCII.&lt;br /&gt;
|-&lt;br /&gt;
| 0x08 || UInt16 || Endianess. 0xFEFF for Big Endian, 0xFFFE for Little Endian.&lt;br /&gt;
|-&lt;br /&gt;
| 0x0A || UInt32 || Version.&lt;br /&gt;
|-&lt;br /&gt;
| 0x0E || UInt16 || Number of sections.&lt;br /&gt;
|-&lt;br /&gt;
| 0x10 || UInt16 || Padding.&lt;br /&gt;
|-&lt;br /&gt;
| 0x12 || UInt32 || File length.&lt;br /&gt;
|-&lt;br /&gt;
| 0x16 || Byte[0xA] || Padding.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
= Sections =&lt;br /&gt;
After the header follows the sections. It is worth noting that these sections are padded to the nearest 0x10th byte with the value 0xAB.&lt;br /&gt;
&lt;br /&gt;
== LBL1 ==&lt;br /&gt;
&#039;&#039;LBL1&#039;&#039; is a section that contains the &amp;quot;labels&amp;quot; that are assigned to text. It is a hash table to determine the index that the label is stored at. The indices of the offsets are determined by the &amp;quot;hash&amp;quot; of the number of entries in the list and the label name.&lt;br /&gt;
&lt;br /&gt;
=== Header ===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; &lt;br /&gt;
! Offset !! Type !! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x00 || String || &#039;&#039;LBL1&#039;&#039; in ASCII.&lt;br /&gt;
|-&lt;br /&gt;
| 0x04 || UInt32 || Section size. Does not account for this header or padding.&lt;br /&gt;
|-&lt;br /&gt;
| 0x08 || Byte[0x8] || Padding.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Label Entries ===&lt;br /&gt;
&lt;br /&gt;
After the header come the label entries.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; &lt;br /&gt;
! Offset !! Type !! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x00 || UInt32 || Label count.&lt;br /&gt;
|-&lt;br /&gt;
| 0x04 || LabelArray[N] || Labels, where &#039;&#039;&#039;N&#039;&#039;&#039; is the label count read above.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
A label is defined by the following structure:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; &lt;br /&gt;
! Offset !! Type !! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x00 || UInt32 || Number of strings associated with this entry.&lt;br /&gt;
|-&lt;br /&gt;
| 0x04 || UInt32 || Offset to the strings associated with that label, offset relative to the field defining the amount of entries. Reads &#039;&#039;&#039;N&#039;&#039;&#039; strings, depending on the count read above.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Label Indices ===&lt;br /&gt;
The following code can determine the index of a specific label:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def hash_label(label, bucket_count):&lt;br /&gt;
    val = 0&lt;br /&gt;
    for c in label:&lt;br /&gt;
        val = ((val * 0x492) + ord(c)) &amp;amp; 0xFFFFFFFF&lt;br /&gt;
    return val % bucket_count&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For example, a file with &#039;&#039;&#039;0x65&#039;&#039;&#039; label entries with a label string of &#039;&#039;&#039;Pichan001_Flow001&#039;&#039;&#039; will be at index 0 of the label list, with &#039;&#039;&#039;PichanRacer000_Flow002&#039;&#039;&#039; being at index 1, and so on.&lt;br /&gt;
&lt;br /&gt;
== ATR1 ==&lt;br /&gt;
&lt;br /&gt;
=== Header ===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; &lt;br /&gt;
! Offset !! Type !! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x00 || String || &#039;&#039;ATR1&#039;&#039; in ASCII.&lt;br /&gt;
|-&lt;br /&gt;
| 0x04 || UInt32 || Section size. Does not account for this header or padding.&lt;br /&gt;
|-&lt;br /&gt;
| 0x08 || Byte[0x8] || Padding.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Attribute Entries ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; &lt;br /&gt;
! Offset !! Type !! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x00 || UInt32 || Attribute set count.&lt;br /&gt;
|-&lt;br /&gt;
| 0x04 || UInt32 || Attribute size. The size of each attribute in bytes.&lt;br /&gt;
|-&lt;br /&gt;
| 0x08 || AttributeSetArray[N] || Attribute sets, where &#039;&#039;&#039;N&#039;&#039;&#039; is the set count read above.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The attribute structure is dependent on the game, but in Super Mario Galaxy 2 each attribute is of size 0x0C and has the following structure:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; &lt;br /&gt;
! Offset !! Type !! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x00 || Byte || NPC Sound ID.&amp;lt;/br&amp;gt;TODO: Add a list of NPC Sounds here?&lt;br /&gt;
|-&lt;br /&gt;
| 0x01 || Byte || Camera type.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! ID !! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0 || AUTOMATIC - The camera will be handled automatically by the game.&lt;br /&gt;
|-&lt;br /&gt;
| 1 || MANUAL - The camera used will be one from the CameraParam.bcam file inside the zone&#039;s Map archive.&lt;br /&gt;
|-&lt;br /&gt;
| 2 || NONE - The camera will not change.&lt;br /&gt;
|}&lt;br /&gt;
|-&lt;br /&gt;
| 0x02 || Byte || Trigger type.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! ID !! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0 || The player has to be close to the NPC and press A to start the dialog.&lt;br /&gt;
|-&lt;br /&gt;
| 1 || The dialog is activated automatically when the player is close, but the player can still move when the dialog has started. The dialog stops when the player exits the trigger area.&lt;br /&gt;
|-&lt;br /&gt;
| 2 || The dialog is activated automatically when the player is close, but the player has to finish the dialog to continue moving.&lt;br /&gt;
|-&lt;br /&gt;
| 3 || The dialog is activated automatically when the player is anywhere (or in a much larger area?), but works otherwise like 2.&lt;br /&gt;
|}&lt;br /&gt;
|-&lt;br /&gt;
| 0x03 || Byte || Dialog style.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! ID !! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0 &amp;amp;ndash; 2 || White textbox.&lt;br /&gt;
|-&lt;br /&gt;
| 3 || Billboard textbox.&lt;br /&gt;
|}&lt;br /&gt;
|-&lt;br /&gt;
| 0x04 || UInt16 || Camera ID. This is the ID that you find inside the CameraParam.bcam file. Needs to be higher than 0.&lt;br /&gt;
|-&lt;br /&gt;
| 0x06 || Byte || MessageArea ID. This matches with MessageArea&#039;s Obj Arg 0.&lt;br /&gt;
|-&lt;br /&gt;
| 0x07 || Byte ||&lt;br /&gt;
|-&lt;br /&gt;
| 0x08 || UInt32 || Offset to a UTF-16 encoded, null terminated, string. Seems to be unused.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== TXT2 ==&lt;br /&gt;
&lt;br /&gt;
=== Header ===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; &lt;br /&gt;
! Offset !! Type !! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x00 || String || &#039;&#039;TXT2&#039;&#039; in ASCII.&lt;br /&gt;
|-&lt;br /&gt;
| 0x04 || UInt32 || Section size. Does not account for this header or padding.&lt;br /&gt;
|-&lt;br /&gt;
| 0x08 || Byte[0x8] || Padding.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Text Entries ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; &lt;br /&gt;
! Offset !! Type !! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x00 || UInt32 || Text count.&lt;br /&gt;
|-&lt;br /&gt;
| 0x04 || Text[N] || Texts, where &#039;&#039;&#039;N&#039;&#039;&#039; is the text count read above.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
A text entry is a UTF-16 string, with embedded &amp;quot;tags&amp;quot; that affect the way the text displays and functions. A tag begins with a value of 0x000E and then the &amp;quot;tag&amp;quot;. The following &amp;quot;tags&amp;quot; are possible:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; &lt;br /&gt;
! Type !! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x0 || System Group&lt;br /&gt;
|-&lt;br /&gt;
| 0x1 || Display Group&lt;br /&gt;
|-&lt;br /&gt;
| 0x2 || Sound Group&lt;br /&gt;
|-&lt;br /&gt;
| 0x3 || Picture Group&lt;br /&gt;
|-&lt;br /&gt;
| 0x4 || Font Size Group&lt;br /&gt;
|-&lt;br /&gt;
| 0x5 || Localize Group&lt;br /&gt;
|-&lt;br /&gt;
| 0x6 || Number Group&lt;br /&gt;
|-&lt;br /&gt;
| 0x7 || String Group&lt;br /&gt;
|-&lt;br /&gt;
| 0x9 || Race Time Group&lt;br /&gt;
|-&lt;br /&gt;
| 0xA || Font Group&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
A &amp;quot;tag&amp;quot; can have a &amp;quot;command&amp;quot;, which tells it how to function.&lt;br /&gt;
&lt;br /&gt;
=== System Group ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; &lt;br /&gt;
! Offset !! Type !! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x00 || UInt16 || Type. [0 == Japanese, 3 == Color]&lt;br /&gt;
|-&lt;br /&gt;
| 0x02 || UInt16 || Data size.&lt;br /&gt;
|-&lt;br /&gt;
| 0x04 || UInt16 || The color to use.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Display Group ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; &lt;br /&gt;
! Offset !! Type !! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x00 || UInt16 || Display type.&lt;br /&gt;
|-&lt;br /&gt;
| 0x02 || UInt16 || Data size.&lt;br /&gt;
|-&lt;br /&gt;
| 0x04 || UInt16 || Padding.&lt;br /&gt;
|-&lt;br /&gt;
| 0x06 || UInt16 || Number of frames to wait if the type is 0.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Sound Group ===&lt;br /&gt;
Plays a given sound.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; &lt;br /&gt;
! Offset !! Type !! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x00 || UInt16 || Should always be 2.&lt;br /&gt;
|-&lt;br /&gt;
| 0x02 || UInt16 || &lt;br /&gt;
|-&lt;br /&gt;
| 0x04 || UInt16 || String length.&lt;br /&gt;
|-&lt;br /&gt;
| 0x06 || String[Length] || UTF-16 string containing the sound effect to play.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Picture Group ===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; &lt;br /&gt;
! Offset !! Type !! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x00 || UInt16 || Character index.&lt;br /&gt;
|-&lt;br /&gt;
| 0x02 || UInt16 || Font.&lt;br /&gt;
|-&lt;br /&gt;
| 0x04 || UInt16 || Character ID.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Font Size Group ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; &lt;br /&gt;
! Offset !! Type !! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x00 || UInt16 || Font Size.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Localize Group ===&lt;br /&gt;
Inserts the current player&#039;s name.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; &lt;br /&gt;
! Offset !! Type !! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x00 || Byte[0x6] || &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Number Group ===&lt;br /&gt;
&lt;br /&gt;
=== String Group ===&lt;br /&gt;
&lt;br /&gt;
=== Race Time Group ===&lt;br /&gt;
&lt;br /&gt;
=== Font Group ===&lt;/div&gt;</summary>
		<author><name>Shibboleet</name></author>
	</entry>
	<entry>
		<id>https://www.lumasworkshop.com/w/index.php?title=Decompiling&amp;diff=138</id>
		<title>Decompiling</title>
		<link rel="alternate" type="text/html" href="https://www.lumasworkshop.com/w/index.php?title=Decompiling&amp;diff=138"/>
		<updated>2024-03-02T18:42:26Z</updated>

		<summary type="html">&lt;p&gt;Shibboleet: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Guides]]&lt;br /&gt;
[[Category:Decompiling]]&lt;br /&gt;
{{WIP}}&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
&#039;&#039;Decompiling&#039;&#039; is the process of taking assembly code and turning it back into a higher level language such as C or C++. It is essentially the reverse of &#039;&#039;compiling&#039;&#039;. &#039;&#039;Matching decompilation&#039;&#039; is the process of decompiling, but having the compiled code match the original assembly 1:1. While matching decompilation is harder than normal decompiling, it can become easier when you understand the patterns of the compiler used. This page aims to let new people understand how this process works, and hopefully be able to get new people into decompilation! While you do not need to be an expert at C or C++ to decompile, it is recommended that you have some experience before attempting decompilation. It is also very recommended that you have some prior knowledge of PowerPC assembly, as that is the key to understanding how a function works. [https://www.nxp.com/docs/en/reference-manual/MPC82XINSET.pdf This document] is a good way to learn or refresh knowledge of the PowerPC architecture. [https://www.warthman.com/images/IBM_PPC_Compiler_Writer%27s_Guide-cwg.pdf This document] is also good to learn some of the patterns that CodeWarrior does.&lt;br /&gt;
&lt;br /&gt;
== Getting Set Up ==&lt;br /&gt;
To begin decompiling &#039;&#039;Super Mario Galaxy&#039;&#039;, you first need to set up the environment. You will need the following tools:&lt;br /&gt;
* [https://gitforwindows.org/ Git (Windows)]&lt;br /&gt;
* Any IDE ([https://code.visualstudio.com/ Visual Studio Recommended])&lt;br /&gt;
* [https://www.python.org/downloads/release/python-397/ Python 3.9.7]&lt;br /&gt;
* IDA Pro (recommended) or Ghidra (Not recommended)&lt;br /&gt;
* [https://shibbo.net/smg/RMGK01_01.idb SMG1 Korean IDB (For IDA)]&lt;br /&gt;
* A &#039;&#039;Super Mario Galaxy&#039;&#039; Korean region DOL.&lt;br /&gt;
&lt;br /&gt;
After you have acquired all of these, setting up [https://github.com/shibbo/Petari Petari] is very simple.&lt;br /&gt;
&lt;br /&gt;
# With a new command prompt open, type in &#039;&#039;&#039;git clone https://github.com/shibbo/Petari&#039;&#039;&#039;. This will clone the repository into a directory called &amp;quot;Petari&amp;quot;.&lt;br /&gt;
# In this new &amp;quot;Petari&amp;quot; folder, place the SMG1 Korean &#039;&#039;&#039;main.dol&#039;&#039;&#039; into this folder, and rename it to &#039;&#039;&#039;baserom.dol&#039;&#039;&#039;.&lt;br /&gt;
# Open a new command prompt in the &amp;quot;Petari&amp;quot; folder.&lt;br /&gt;
# Run the command &#039;&#039;&#039;python setup.py&#039;&#039;&#039;. This will verify your DOL and install all of the libraries used, and the compilers we use to compile the code.&lt;br /&gt;
# Run the command &#039;&#039;&#039;python build.py&#039;&#039;&#039;. This will build the entire project. If you see any warnings, do not worry about them.&lt;br /&gt;
&lt;br /&gt;
== Environment ==&lt;br /&gt;
To properly utilize and use &#039;&#039;Petari&#039;&#039;, it is necessary to understand the structure of the environment. Petari is structured in a way that makes it easy to access and use.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Folder Name !! Description&lt;br /&gt;
|-&lt;br /&gt;
| archive || The folder that gets created when &#039;&#039;&#039;build.py -link&#039;&#039;&#039; is ran. Contains an archive of the object files in each library.&lt;br /&gt;
|-&lt;br /&gt;
| build || The folder that gets created when &#039;&#039;&#039;build.py&#039;&#039;&#039; is ran. Contains the compiled object files.&lt;br /&gt;
|-&lt;br /&gt;
| csv || Contains CSV files that store the status of functions being matched.&lt;br /&gt;
|-&lt;br /&gt;
| data || Contains map files and the percentage badges for the GitHub repo.&lt;br /&gt;
|-&lt;br /&gt;
| docs || The folder that gets created when &#039;&#039;&#039;progress.py&#039;&#039;&#039; is ran. Contains all of the Markdown documentation for matching status.&lt;br /&gt;
|-&lt;br /&gt;
| include || Contains all of the header files for &#039;&#039;Super Mario Galaxy&#039;&#039; specific code.&lt;br /&gt;
|-&lt;br /&gt;
| libs || Contains this folder structure but for different libraries used by the game.&lt;br /&gt;
|-&lt;br /&gt;
| scripts || Various scripts used in IDA for generating headers.&lt;br /&gt;
|-&lt;br /&gt;
| source || Contains all of the source files for &#039;&#039;Super Mario Galaxy&#039;&#039; specific code.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Libraries ==&lt;br /&gt;
&#039;&#039;Super Mario Galaxy&#039;&#039; uses a lot of libraries for certain functionality such as heaps, layouts, OS specific code, and more. Each library described in the table below are &#039;&#039;&#039;statically linked&#039;&#039;&#039; to the game, so every library&#039;s used code is inside of the &#039;&#039;main.dol&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
=== Non-SMG Libraries ===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Name !! Language !! Description&lt;br /&gt;
|-&lt;br /&gt;
| JSystem || C++ || Contains classes for backend things, such as heaps and linked lists.&lt;br /&gt;
|-&lt;br /&gt;
| MetroTRK || C || Target Resident Kernel, for debugging.&lt;br /&gt;
|-&lt;br /&gt;
| MSL_C || C &amp;amp; C++ || Contains standard library functions and types.&lt;br /&gt;
|-&lt;br /&gt;
| nw4r || C++ || Contains classes for sounds, layouts, and more. (SMG only uses the layouts and some math functions)&lt;br /&gt;
|-&lt;br /&gt;
| Runtime || C &amp;amp; C++ || Contains functions that relate to CodeWarrior&#039;s runtime code generation (ctor / dtor lists, etc)&lt;br /&gt;
|-&lt;br /&gt;
| RVL_SDK || C || Contains functions that relate to the Wii&#039;s &amp;quot;OS&amp;quot;.&lt;br /&gt;
|-&lt;br /&gt;
| RVLFaceLib || C || Contains functions that relate to Miis.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== SMG Libraries ===&lt;br /&gt;
All of &#039;&#039;Super Mario Galaxy&#039;&#039;&#039;s libraries are written in C++.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Header text !! Header text&lt;br /&gt;
|-&lt;br /&gt;
| Animation || Library for animation playing.&lt;br /&gt;
|-&lt;br /&gt;
| AreaObj || Library for invisible areas that can be accessed by players in the game.&lt;br /&gt;
|-&lt;br /&gt;
| AudioLib || N/A&lt;br /&gt;
|-&lt;br /&gt;
| Boss || Library for all of the bosses and mini-bosses in the game.&lt;br /&gt;
|-&lt;br /&gt;
| Camera || Library for all camera types.&lt;br /&gt;
|-&lt;br /&gt;
| Demo || Library for all cutscenes.&lt;br /&gt;
|-&lt;br /&gt;
| Effect || Library for all effect rendering.&lt;br /&gt;
|-&lt;br /&gt;
| Enemy || Library for all enemies.&lt;br /&gt;
|-&lt;br /&gt;
| GameAudio || N/A&lt;br /&gt;
|-&lt;br /&gt;
| Gravity || Library for all of the gravity types in the game.&lt;br /&gt;
|-&lt;br /&gt;
| LiveActor || Library for LiveActor, which is an actor that can switch states.&lt;br /&gt;
|-&lt;br /&gt;
| Map || Library for map classes that do not directly interact with the player. (ie switches)&lt;br /&gt;
|-&lt;br /&gt;
| MapObj || Library for all of the map objects in the game.&lt;br /&gt;
|-&lt;br /&gt;
| NameObj || Library for the most basic form of an object in the game.&lt;br /&gt;
|-&lt;br /&gt;
| NPC || Library for all of the non-playable characters.&lt;br /&gt;
|-&lt;br /&gt;
| NWC24 || Library for the mail system in the game.&lt;br /&gt;
|-&lt;br /&gt;
| Player || Library for all of the player related functions.&lt;br /&gt;
|-&lt;br /&gt;
| RhythmLib || N/A&lt;br /&gt;
|-&lt;br /&gt;
| Ride || Library for all of the actors that can be controlled by the player.&lt;br /&gt;
|-&lt;br /&gt;
| Scene || Library for all of the game scene related code.&lt;br /&gt;
|-&lt;br /&gt;
| Screen || Library for all of the layouts in the game.&lt;br /&gt;
|-&lt;br /&gt;
| Speaker || Library for the sound effect playing done on the Wiimote.&lt;br /&gt;
|-&lt;br /&gt;
| System || Library for a lot of the game&#039;s backend systems.&lt;br /&gt;
|-&lt;br /&gt;
| Util || Library for utility functions and classes.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Basics ==&lt;br /&gt;
To properly decompile, it is vital to know how a lot of the assembly will translate into C / C++ code. Here are a couple of patterns that you will see when decompiling code.&lt;br /&gt;
&lt;br /&gt;
=== Loops ===&lt;br /&gt;
==== Predefined bounds ====&lt;br /&gt;
Let&#039;s take a simple loop that stores &amp;lt;i&amp;gt;nullptr&amp;lt;/i&amp;gt; in each 8 elements of a pointer array.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class TestClass {&lt;br /&gt;
public:&lt;br /&gt;
    TestClass();&lt;br /&gt;
&lt;br /&gt;
     int* mPointers[8];&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
TestClass::TestClass() {&lt;br /&gt;
    for (int i = 0; i &amp;lt; 8; i++) {&lt;br /&gt;
        mPointers[i] = nullptr;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The output assembly would look something like:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
li r0, 8 # there are 8 elements in this loop&lt;br /&gt;
li r5, 0 # the value to store in the element (nullptr)&lt;br /&gt;
li r4, 0 # the current element offset in the loop&lt;br /&gt;
mtctr r0 # move the number of iterations into the counter register (8)&lt;br /&gt;
&lt;br /&gt;
loop:&lt;br /&gt;
    stwx r5, r3, r4 # store 0 (r5) into the array at r3 (this) + r4 (our current offset, which is i * 4)&lt;br /&gt;
    addi r4, r4, 4 # increment our offset by sizeof(int) since integers are 32-bits&lt;br /&gt;
    bdnz+ loop # branch back to our loop again&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Variable Length Bounds ====&lt;br /&gt;
Let&#039;s take a simple loop that stores &amp;lt;i&amp;gt;nullptr&amp;lt;/i&amp;gt; in each element of a variable-length array. We will have a class with two members, one that contains the pointer array itself, and another that stores the number of pointers.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class TestClass {&lt;br /&gt;
public:&lt;br /&gt;
    TestClass();&lt;br /&gt;
&lt;br /&gt;
     int** mPointers;&lt;br /&gt;
     int mNumPointers;&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
TestClass::TestClass() {&lt;br /&gt;
    mNumPointers = 8;&lt;br /&gt;
    for (int i = 0; i &amp;lt; mNumPointers ; i++) {&lt;br /&gt;
        mPointers[i] = nullptr;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Because we do not know how many pointers we have stored, we cannot use the counter register like we did with a fixed-size array. Instead, the compiler will use a cmpw (signed integer) or cmplw (unsigned) instruction to compare the current iteration to how many pointers are stored in the class.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
li r0, 8 # there are 8 elements in this loop&lt;br /&gt;
li r7, 0 # the value to store in the element (nullptr)&lt;br /&gt;
stw r0, 4(r3) # r3 + 4 is the offset to our member variable &amp;quot;mNumPointers&amp;quot;&lt;br /&gt;
mr r6, r7 # simple copy of the 0 value so we can also use it for our counter&lt;br /&gt;
li r4, 0 # load 0 into our offset&lt;br /&gt;
b loop # branch into our loop&lt;br /&gt;
&lt;br /&gt;
loop:&lt;br /&gt;
    lwz r5, 0(r3) # load our pointer array from this + 0&lt;br /&gt;
    addi r7, r7, 1 # increment our index by 1&lt;br /&gt;
    stwx r6, r5, r4 # store our nullptr value (r6) into r5 + r4 (ptrArray + currentOffset)&lt;br /&gt;
    addi r4, r4, 4 # increment our offset by sizeof(int) since integers are 32-bits&lt;br /&gt;
    lwz r0, 4(r3) # load our number of pointers we will increment by (mNumPointers)&lt;br /&gt;
    cmpw r7, r0 # compare our number of pointers to the current index in our loop&lt;br /&gt;
    blt+ loop # branch if the number is less than mNumPointers&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Structure Access In Arrays (Pointer Array) ====&lt;br /&gt;
More complex forms of loops comes into play when you are iterating through structures and storing / loading members from those structures. Let&#039;s take this class for example:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
struct TestStruct {&lt;br /&gt;
    int SomeMember;&lt;br /&gt;
    int AnotherMember;&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
class TestClass {&lt;br /&gt;
public:&lt;br /&gt;
    TestClass();&lt;br /&gt;
&lt;br /&gt;
    void storeVals();&lt;br /&gt;
&lt;br /&gt;
     TestStruct** mStructures;&lt;br /&gt;
     int mNumStructures;&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
For the sake of simplicity, let&#039;s assume that the TestClass constructor initializes the number of structures to 8, and constructs them accordingly. With that in mind, let&#039;s see how a struct store will work.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void TestClass::storeVals() {&lt;br /&gt;
    for (int i = 0; i &amp;lt; mNumStructures; i++) {&lt;br /&gt;
        mStructures[i]-&amp;gt;AnotherMember = 5;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
The output assembly would look something like:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
li r7, 0 # our &amp;quot;i&amp;quot; used in the loop, starts at 0&lt;br /&gt;
li r4, 0 # our current offset into the array&lt;br /&gt;
li r6, 5 # the value we are storing into the array&lt;br /&gt;
b loop&lt;br /&gt;
&lt;br /&gt;
loop:&lt;br /&gt;
    lwz r5, 0(r3) # load the array pointer&lt;br /&gt;
    addi r7, r7, 1 # increment our current index (i) by 1&lt;br /&gt;
    lwzx r5, r5, r4 # load the current structure, mStructures[i] where r4 is the current offset&lt;br /&gt;
    addi r4, r4, 4 # increment our offset by sizeof(TestStruct*), which is 4&lt;br /&gt;
    stw r6, 4(r5) # store our value (5) into (mStructures[i] + 4), which is our AnotherMember&lt;br /&gt;
    lwz r0, 4(r3) # load the number of structures from TestClass&lt;br /&gt;
    cmpw r7, r0 # compare the current index to our value in TestClass&lt;br /&gt;
    blt+ loop # loop back if it is less than the value&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Structure Access In Arrays (Direct Array) ====&lt;br /&gt;
Let&#039;s take the previous example and modify it a little. Instead of making an array of pointers to the struct instances, let&#039;s store the array &amp;lt;i&amp;gt;directly&amp;lt;/i&amp;gt; into our class instance.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
struct TestStruct {&lt;br /&gt;
    int SomeMember;&lt;br /&gt;
    int AnotherMember;&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
class TestClass {&lt;br /&gt;
public:&lt;br /&gt;
    TestClass();&lt;br /&gt;
&lt;br /&gt;
    void storeVals();&lt;br /&gt;
&lt;br /&gt;
     TestStruct mStructures[8];&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Again, let us assume that the array has already been constructed and everything is initialized as it should be.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void TestClass::storeVals() {&lt;br /&gt;
    for (int i = 0; i &amp;lt; 8; i++) {&lt;br /&gt;
        mStructures[i].AnotherMember = 5;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
The output assembly would look something like:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
li r0, 8 # load our number of iterations (8)&lt;br /&gt;
li r4, 0 # current offset into the array. initialized at 0&lt;br /&gt;
li r6, 5 # the value to store into the array&lt;br /&gt;
mtctr r0 # move the number of iterations into the counter register&lt;br /&gt;
&lt;br /&gt;
loop:&lt;br /&gt;
    add r5, r3, r4 # jump to the offset into the array. r5 = (this + 0) + r4&lt;br /&gt;
    addi r4, r4, 8 # increment our current offset by sizeof(TestStruct), which is 8&lt;br /&gt;
    stw r6, 4(r5) # store our constant value (5) into the loaded struct + 4 (AnotherMember)&lt;br /&gt;
    bdnz+ loop # branch back to the loop if the counter is not 8&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Shibboleet</name></author>
	</entry>
	<entry>
		<id>https://www.lumasworkshop.com/w/index.php?title=Decompiling&amp;diff=137</id>
		<title>Decompiling</title>
		<link rel="alternate" type="text/html" href="https://www.lumasworkshop.com/w/index.php?title=Decompiling&amp;diff=137"/>
		<updated>2024-03-02T18:26:17Z</updated>

		<summary type="html">&lt;p&gt;Shibboleet: /* Structure Access In Arrays */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Guides]]&lt;br /&gt;
[[Category:Decompiling]]&lt;br /&gt;
{{WIP}}&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
&#039;&#039;Decompiling&#039;&#039; is the process of taking assembly code and turning it back into a higher level language such as C or C++. It is essentially the reverse of &#039;&#039;compiling&#039;&#039;. &#039;&#039;Matching decompilation&#039;&#039; is the process of decompiling, but having the compiled code match the original assembly 1:1. While matching decompilation is harder than normal decompiling, it can become easier when you understand the patterns of the compiler used. This page aims to let new people understand how this process works, and hopefully be able to get new people into decompilation! While you do not need to be an expert at C or C++ to decompile, it is recommended that you have some experience before attempting decompilation. It is also very recommended that you have some prior knowledge of PowerPC assembly, as that is the key to understanding how a function works. [https://www.nxp.com/docs/en/reference-manual/MPC82XINSET.pdf This document] is a good way to learn or refresh knowledge of the PowerPC architecture. [https://www.warthman.com/images/IBM_PPC_Compiler_Writer%27s_Guide-cwg.pdf This document] is also good to learn some of the patterns that CodeWarrior does.&lt;br /&gt;
&lt;br /&gt;
== Getting Set Up ==&lt;br /&gt;
To begin decompiling &#039;&#039;Super Mario Galaxy&#039;&#039;, you first need to set up the environment. You will need the following tools:&lt;br /&gt;
* [https://gitforwindows.org/ Git (Windows)]&lt;br /&gt;
* Any IDE ([https://code.visualstudio.com/ Visual Studio Recommended])&lt;br /&gt;
* [https://www.python.org/downloads/release/python-397/ Python 3.9.7]&lt;br /&gt;
* IDA Pro (recommended) or Ghidra (Not recommended)&lt;br /&gt;
* [https://shibbo.net/smg/RMGK01_01.idb SMG1 Korean IDB (For IDA)]&lt;br /&gt;
* A &#039;&#039;Super Mario Galaxy&#039;&#039; Korean region DOL.&lt;br /&gt;
&lt;br /&gt;
After you have acquired all of these, setting up [https://github.com/shibbo/Petari Petari] is very simple.&lt;br /&gt;
&lt;br /&gt;
# With a new command prompt open, type in &#039;&#039;&#039;git clone https://github.com/shibbo/Petari&#039;&#039;&#039;. This will clone the repository into a directory called &amp;quot;Petari&amp;quot;.&lt;br /&gt;
# In this new &amp;quot;Petari&amp;quot; folder, place the SMG1 Korean &#039;&#039;&#039;main.dol&#039;&#039;&#039; into this folder, and rename it to &#039;&#039;&#039;baserom.dol&#039;&#039;&#039;.&lt;br /&gt;
# Open a new command prompt in the &amp;quot;Petari&amp;quot; folder.&lt;br /&gt;
# Run the command &#039;&#039;&#039;python setup.py&#039;&#039;&#039;. This will verify your DOL and install all of the libraries used, and the compilers we use to compile the code.&lt;br /&gt;
# Run the command &#039;&#039;&#039;python build.py&#039;&#039;&#039;. This will build the entire project. If you see any warnings, do not worry about them.&lt;br /&gt;
&lt;br /&gt;
== Environment ==&lt;br /&gt;
To properly utilize and use &#039;&#039;Petari&#039;&#039;, it is necessary to understand the structure of the environment. Petari is structured in a way that makes it easy to access and use.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Folder Name !! Description&lt;br /&gt;
|-&lt;br /&gt;
| archive || The folder that gets created when &#039;&#039;&#039;build.py -link&#039;&#039;&#039; is ran. Contains an archive of the object files in each library.&lt;br /&gt;
|-&lt;br /&gt;
| build || The folder that gets created when &#039;&#039;&#039;build.py&#039;&#039;&#039; is ran. Contains the compiled object files.&lt;br /&gt;
|-&lt;br /&gt;
| csv || Contains CSV files that store the status of functions being matched.&lt;br /&gt;
|-&lt;br /&gt;
| data || Contains map files and the percentage badges for the GitHub repo.&lt;br /&gt;
|-&lt;br /&gt;
| docs || The folder that gets created when &#039;&#039;&#039;progress.py&#039;&#039;&#039; is ran. Contains all of the Markdown documentation for matching status.&lt;br /&gt;
|-&lt;br /&gt;
| include || Contains all of the header files for &#039;&#039;Super Mario Galaxy&#039;&#039; specific code.&lt;br /&gt;
|-&lt;br /&gt;
| libs || Contains this folder structure but for different libraries used by the game.&lt;br /&gt;
|-&lt;br /&gt;
| scripts || Various scripts used in IDA for generating headers.&lt;br /&gt;
|-&lt;br /&gt;
| source || Contains all of the source files for &#039;&#039;Super Mario Galaxy&#039;&#039; specific code.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Libraries ==&lt;br /&gt;
&#039;&#039;Super Mario Galaxy&#039;&#039; uses a lot of libraries for certain functionality such as heaps, layouts, OS specific code, and more. Each library described in the table below are &#039;&#039;&#039;statically linked&#039;&#039;&#039; to the game, so every library&#039;s used code is inside of the &#039;&#039;main.dol&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
=== Non-SMG Libraries ===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Name !! Language !! Description&lt;br /&gt;
|-&lt;br /&gt;
| JSystem || C++ || Contains classes for backend things, such as heaps and linked lists.&lt;br /&gt;
|-&lt;br /&gt;
| MetroTRK || C || Target Resident Kernel, for debugging.&lt;br /&gt;
|-&lt;br /&gt;
| MSL_C || C &amp;amp; C++ || Contains standard library functions and types.&lt;br /&gt;
|-&lt;br /&gt;
| nw4r || C++ || Contains classes for sounds, layouts, and more. (SMG only uses the layouts and some math functions)&lt;br /&gt;
|-&lt;br /&gt;
| Runtime || C &amp;amp; C++ || Contains functions that relate to CodeWarrior&#039;s runtime code generation (ctor / dtor lists, etc)&lt;br /&gt;
|-&lt;br /&gt;
| RVL_SDK || C || Contains functions that relate to the Wii&#039;s &amp;quot;OS&amp;quot;.&lt;br /&gt;
|-&lt;br /&gt;
| RVLFaceLib || C || Contains functions that relate to Miis.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== SMG Libraries ===&lt;br /&gt;
All of &#039;&#039;Super Mario Galaxy&#039;&#039;&#039;s libraries are written in C++.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Header text !! Header text&lt;br /&gt;
|-&lt;br /&gt;
| Animation || Library for animation playing.&lt;br /&gt;
|-&lt;br /&gt;
| AreaObj || Library for invisible areas that can be accessed by players in the game.&lt;br /&gt;
|-&lt;br /&gt;
| AudioLib || N/A&lt;br /&gt;
|-&lt;br /&gt;
| Boss || Library for all of the bosses and mini-bosses in the game.&lt;br /&gt;
|-&lt;br /&gt;
| Camera || Library for all camera types.&lt;br /&gt;
|-&lt;br /&gt;
| Demo || Library for all cutscenes.&lt;br /&gt;
|-&lt;br /&gt;
| Effect || Library for all effect rendering.&lt;br /&gt;
|-&lt;br /&gt;
| Enemy || Library for all enemies.&lt;br /&gt;
|-&lt;br /&gt;
| GameAudio || N/A&lt;br /&gt;
|-&lt;br /&gt;
| Gravity || Library for all of the gravity types in the game.&lt;br /&gt;
|-&lt;br /&gt;
| LiveActor || Library for LiveActor, which is an actor that can switch states.&lt;br /&gt;
|-&lt;br /&gt;
| Map || Library for map classes that do not directly interact with the player. (ie switches)&lt;br /&gt;
|-&lt;br /&gt;
| MapObj || Library for all of the map objects in the game.&lt;br /&gt;
|-&lt;br /&gt;
| NameObj || Library for the most basic form of an object in the game.&lt;br /&gt;
|-&lt;br /&gt;
| NPC || Library for all of the non-playable characters.&lt;br /&gt;
|-&lt;br /&gt;
| NWC24 || Library for the mail system in the game.&lt;br /&gt;
|-&lt;br /&gt;
| Player || Library for all of the player related functions.&lt;br /&gt;
|-&lt;br /&gt;
| RhythmLib || N/A&lt;br /&gt;
|-&lt;br /&gt;
| Ride || Library for all of the actors that can be controlled by the player.&lt;br /&gt;
|-&lt;br /&gt;
| Scene || Library for all of the game scene related code.&lt;br /&gt;
|-&lt;br /&gt;
| Screen || Library for all of the layouts in the game.&lt;br /&gt;
|-&lt;br /&gt;
| Speaker || Library for the sound effect playing done on the Wiimote.&lt;br /&gt;
|-&lt;br /&gt;
| System || Library for a lot of the game&#039;s backend systems.&lt;br /&gt;
|-&lt;br /&gt;
| Util || Library for utility functions and classes.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Basics ==&lt;br /&gt;
To properly decompile, it is vital to know how a lot of the assembly will translate into C / C++ code. Here are a couple of patterns that you will see when decompiling code.&lt;br /&gt;
&lt;br /&gt;
=== Loops ===&lt;br /&gt;
==== Predefined bounds ====&lt;br /&gt;
Let&#039;s take a simple loop that stores &amp;lt;i&amp;gt;nullptr&amp;lt;/i&amp;gt; in each 8 elements of a pointer array.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class TestClass {&lt;br /&gt;
public:&lt;br /&gt;
    TestClass();&lt;br /&gt;
&lt;br /&gt;
     int* mPointers[8];&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
TestClass::TestClass() {&lt;br /&gt;
    for (int i = 0; i &amp;lt; 8; i++) {&lt;br /&gt;
        mPointers[i] = nullptr;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The output assembly would look something like:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
li r0, 8 # there are 8 elements in this loop&lt;br /&gt;
li r5, 0 # the value to store in the element (nullptr)&lt;br /&gt;
li r4, 0 # the current element offset in the loop&lt;br /&gt;
mtctr r0 # move the number of iterations into the counter register (8)&lt;br /&gt;
&lt;br /&gt;
loop:&lt;br /&gt;
    stwx r5, r3, r4 # store 0 (r5) into the array at r3 (this) + r4 (our current offset, which is i * 4)&lt;br /&gt;
    addi r4, r4, 4 # increment our offset by sizeof(int) since integers are 32-bits&lt;br /&gt;
    bdnz+ loop # branch back to our loop again&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Variable Length Bounds ====&lt;br /&gt;
Let&#039;s take a simple loop that stores &amp;lt;i&amp;gt;nullptr&amp;lt;/i&amp;gt; in each element of a variable-length array. We will have a class with two members, one that contains the pointer array itself, and another that stores the number of pointers.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class TestClass {&lt;br /&gt;
public:&lt;br /&gt;
    TestClass();&lt;br /&gt;
&lt;br /&gt;
     int** mPointers;&lt;br /&gt;
     int mNumPointers;&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
TestClass::TestClass() {&lt;br /&gt;
    mNumPointers = 8;&lt;br /&gt;
    for (int i = 0; i &amp;lt; mNumPointers ; i++) {&lt;br /&gt;
        mPointers[i] = nullptr;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Because we do not know how many pointers we have stored, we cannot use the counter register like we did with a fixed-size array. Instead, the compiler will use a cmpw (signed integer) or cmplw (unsigned) instruction to compare the current iteration to how many pointers are stored in the class.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
li r0, 8 # there are 8 elements in this loop&lt;br /&gt;
li r7, 0 # the value to store in the element (nullptr)&lt;br /&gt;
stw r0, 4(r3) # r3 + 4 is the offset to our member variable &amp;quot;mNumPointers&amp;quot;&lt;br /&gt;
mr r6, r7 # simple copy of the 0 value so we can also use it for our counter&lt;br /&gt;
li r4, 0 # load 0 into our offset&lt;br /&gt;
b loop # branch into our loop&lt;br /&gt;
&lt;br /&gt;
loop:&lt;br /&gt;
    lwz r5, 0(r3) # load our pointer array from this + 0&lt;br /&gt;
    addi r7, r7, 1 # increment our index by 1&lt;br /&gt;
    stwx r6, r5, r4 # store our nullptr value (r6) into r5 + r4 (ptrArray + currentOffset)&lt;br /&gt;
    addi r4, r4, 4 # increment our offset by sizeof(int) since integers are 32-bits&lt;br /&gt;
    lwz r0, 4(r3) # load our number of pointers we will increment by (mNumPointers)&lt;br /&gt;
    cmpw r7, r0 # compare our number of pointers to the current index in our loop&lt;br /&gt;
    blt+ loop # branch if the number is less than mNumPointers&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Structure Access In Arrays (Pointer Array) ====&lt;br /&gt;
More complex forms of loops comes into play when you are iterating through structures and storing / loading members from those structures. Let&#039;s take this class for example:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
struct TestStruct {&lt;br /&gt;
    int SomeMember;&lt;br /&gt;
    int AnotherMember;&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
class TestClass {&lt;br /&gt;
public:&lt;br /&gt;
    TestClass();&lt;br /&gt;
&lt;br /&gt;
    void storeVals();&lt;br /&gt;
&lt;br /&gt;
     TestStruct** mStructures;&lt;br /&gt;
     int mNumStructures;&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
For the sake of simplicity, let&#039;s assume that the TestClass constructor initializes the number of structures to 8, and constructs them accordingly. With that in mind, let&#039;s see how a struct store will work.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void TestClass::storeVals() {&lt;br /&gt;
    for (int i = 0; i &amp;lt; mNumStructures; i++) {&lt;br /&gt;
        mStructures[i]-&amp;gt;AnotherMember = 5;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
The output assembly would look something like:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
li r7, 0 # our &amp;quot;i&amp;quot; used in the loop, starts at 0&lt;br /&gt;
li r4, 0 # our current offset into the array&lt;br /&gt;
li r6, 5 # the value we are storing into the array&lt;br /&gt;
b loop&lt;br /&gt;
&lt;br /&gt;
loop:&lt;br /&gt;
    lwz r5, 0(r3) # load the array pointer&lt;br /&gt;
    addi r7, r7, 1 # increment our current index (i) by 1&lt;br /&gt;
    lwzx r5, r5, r4 # load the current structure, mStructures[i] where r4 is the current offset&lt;br /&gt;
    addi r4, r4, 4 # increment our offset by sizeof(TestStruct*), which is 4&lt;br /&gt;
    stw r6, 4(r5) # store our value (5) into (mStructures[i] + 4), which is our AnotherMember&lt;br /&gt;
    lwz r0, 4(r3) # load the number of structures from TestClass&lt;br /&gt;
    cmpw r7, r0 # compare the current index to our value in TestClass&lt;br /&gt;
    blt+ loop # loop back if it is less than the value&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Shibboleet</name></author>
	</entry>
	<entry>
		<id>https://www.lumasworkshop.com/w/index.php?title=Decompiling&amp;diff=136</id>
		<title>Decompiling</title>
		<link rel="alternate" type="text/html" href="https://www.lumasworkshop.com/w/index.php?title=Decompiling&amp;diff=136"/>
		<updated>2024-03-02T18:24:39Z</updated>

		<summary type="html">&lt;p&gt;Shibboleet: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Guides]]&lt;br /&gt;
[[Category:Decompiling]]&lt;br /&gt;
{{WIP}}&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
&#039;&#039;Decompiling&#039;&#039; is the process of taking assembly code and turning it back into a higher level language such as C or C++. It is essentially the reverse of &#039;&#039;compiling&#039;&#039;. &#039;&#039;Matching decompilation&#039;&#039; is the process of decompiling, but having the compiled code match the original assembly 1:1. While matching decompilation is harder than normal decompiling, it can become easier when you understand the patterns of the compiler used. This page aims to let new people understand how this process works, and hopefully be able to get new people into decompilation! While you do not need to be an expert at C or C++ to decompile, it is recommended that you have some experience before attempting decompilation. It is also very recommended that you have some prior knowledge of PowerPC assembly, as that is the key to understanding how a function works. [https://www.nxp.com/docs/en/reference-manual/MPC82XINSET.pdf This document] is a good way to learn or refresh knowledge of the PowerPC architecture. [https://www.warthman.com/images/IBM_PPC_Compiler_Writer%27s_Guide-cwg.pdf This document] is also good to learn some of the patterns that CodeWarrior does.&lt;br /&gt;
&lt;br /&gt;
== Getting Set Up ==&lt;br /&gt;
To begin decompiling &#039;&#039;Super Mario Galaxy&#039;&#039;, you first need to set up the environment. You will need the following tools:&lt;br /&gt;
* [https://gitforwindows.org/ Git (Windows)]&lt;br /&gt;
* Any IDE ([https://code.visualstudio.com/ Visual Studio Recommended])&lt;br /&gt;
* [https://www.python.org/downloads/release/python-397/ Python 3.9.7]&lt;br /&gt;
* IDA Pro (recommended) or Ghidra (Not recommended)&lt;br /&gt;
* [https://shibbo.net/smg/RMGK01_01.idb SMG1 Korean IDB (For IDA)]&lt;br /&gt;
* A &#039;&#039;Super Mario Galaxy&#039;&#039; Korean region DOL.&lt;br /&gt;
&lt;br /&gt;
After you have acquired all of these, setting up [https://github.com/shibbo/Petari Petari] is very simple.&lt;br /&gt;
&lt;br /&gt;
# With a new command prompt open, type in &#039;&#039;&#039;git clone https://github.com/shibbo/Petari&#039;&#039;&#039;. This will clone the repository into a directory called &amp;quot;Petari&amp;quot;.&lt;br /&gt;
# In this new &amp;quot;Petari&amp;quot; folder, place the SMG1 Korean &#039;&#039;&#039;main.dol&#039;&#039;&#039; into this folder, and rename it to &#039;&#039;&#039;baserom.dol&#039;&#039;&#039;.&lt;br /&gt;
# Open a new command prompt in the &amp;quot;Petari&amp;quot; folder.&lt;br /&gt;
# Run the command &#039;&#039;&#039;python setup.py&#039;&#039;&#039;. This will verify your DOL and install all of the libraries used, and the compilers we use to compile the code.&lt;br /&gt;
# Run the command &#039;&#039;&#039;python build.py&#039;&#039;&#039;. This will build the entire project. If you see any warnings, do not worry about them.&lt;br /&gt;
&lt;br /&gt;
== Environment ==&lt;br /&gt;
To properly utilize and use &#039;&#039;Petari&#039;&#039;, it is necessary to understand the structure of the environment. Petari is structured in a way that makes it easy to access and use.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Folder Name !! Description&lt;br /&gt;
|-&lt;br /&gt;
| archive || The folder that gets created when &#039;&#039;&#039;build.py -link&#039;&#039;&#039; is ran. Contains an archive of the object files in each library.&lt;br /&gt;
|-&lt;br /&gt;
| build || The folder that gets created when &#039;&#039;&#039;build.py&#039;&#039;&#039; is ran. Contains the compiled object files.&lt;br /&gt;
|-&lt;br /&gt;
| csv || Contains CSV files that store the status of functions being matched.&lt;br /&gt;
|-&lt;br /&gt;
| data || Contains map files and the percentage badges for the GitHub repo.&lt;br /&gt;
|-&lt;br /&gt;
| docs || The folder that gets created when &#039;&#039;&#039;progress.py&#039;&#039;&#039; is ran. Contains all of the Markdown documentation for matching status.&lt;br /&gt;
|-&lt;br /&gt;
| include || Contains all of the header files for &#039;&#039;Super Mario Galaxy&#039;&#039; specific code.&lt;br /&gt;
|-&lt;br /&gt;
| libs || Contains this folder structure but for different libraries used by the game.&lt;br /&gt;
|-&lt;br /&gt;
| scripts || Various scripts used in IDA for generating headers.&lt;br /&gt;
|-&lt;br /&gt;
| source || Contains all of the source files for &#039;&#039;Super Mario Galaxy&#039;&#039; specific code.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Libraries ==&lt;br /&gt;
&#039;&#039;Super Mario Galaxy&#039;&#039; uses a lot of libraries for certain functionality such as heaps, layouts, OS specific code, and more. Each library described in the table below are &#039;&#039;&#039;statically linked&#039;&#039;&#039; to the game, so every library&#039;s used code is inside of the &#039;&#039;main.dol&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
=== Non-SMG Libraries ===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Name !! Language !! Description&lt;br /&gt;
|-&lt;br /&gt;
| JSystem || C++ || Contains classes for backend things, such as heaps and linked lists.&lt;br /&gt;
|-&lt;br /&gt;
| MetroTRK || C || Target Resident Kernel, for debugging.&lt;br /&gt;
|-&lt;br /&gt;
| MSL_C || C &amp;amp; C++ || Contains standard library functions and types.&lt;br /&gt;
|-&lt;br /&gt;
| nw4r || C++ || Contains classes for sounds, layouts, and more. (SMG only uses the layouts and some math functions)&lt;br /&gt;
|-&lt;br /&gt;
| Runtime || C &amp;amp; C++ || Contains functions that relate to CodeWarrior&#039;s runtime code generation (ctor / dtor lists, etc)&lt;br /&gt;
|-&lt;br /&gt;
| RVL_SDK || C || Contains functions that relate to the Wii&#039;s &amp;quot;OS&amp;quot;.&lt;br /&gt;
|-&lt;br /&gt;
| RVLFaceLib || C || Contains functions that relate to Miis.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== SMG Libraries ===&lt;br /&gt;
All of &#039;&#039;Super Mario Galaxy&#039;&#039;&#039;s libraries are written in C++.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Header text !! Header text&lt;br /&gt;
|-&lt;br /&gt;
| Animation || Library for animation playing.&lt;br /&gt;
|-&lt;br /&gt;
| AreaObj || Library for invisible areas that can be accessed by players in the game.&lt;br /&gt;
|-&lt;br /&gt;
| AudioLib || N/A&lt;br /&gt;
|-&lt;br /&gt;
| Boss || Library for all of the bosses and mini-bosses in the game.&lt;br /&gt;
|-&lt;br /&gt;
| Camera || Library for all camera types.&lt;br /&gt;
|-&lt;br /&gt;
| Demo || Library for all cutscenes.&lt;br /&gt;
|-&lt;br /&gt;
| Effect || Library for all effect rendering.&lt;br /&gt;
|-&lt;br /&gt;
| Enemy || Library for all enemies.&lt;br /&gt;
|-&lt;br /&gt;
| GameAudio || N/A&lt;br /&gt;
|-&lt;br /&gt;
| Gravity || Library for all of the gravity types in the game.&lt;br /&gt;
|-&lt;br /&gt;
| LiveActor || Library for LiveActor, which is an actor that can switch states.&lt;br /&gt;
|-&lt;br /&gt;
| Map || Library for map classes that do not directly interact with the player. (ie switches)&lt;br /&gt;
|-&lt;br /&gt;
| MapObj || Library for all of the map objects in the game.&lt;br /&gt;
|-&lt;br /&gt;
| NameObj || Library for the most basic form of an object in the game.&lt;br /&gt;
|-&lt;br /&gt;
| NPC || Library for all of the non-playable characters.&lt;br /&gt;
|-&lt;br /&gt;
| NWC24 || Library for the mail system in the game.&lt;br /&gt;
|-&lt;br /&gt;
| Player || Library for all of the player related functions.&lt;br /&gt;
|-&lt;br /&gt;
| RhythmLib || N/A&lt;br /&gt;
|-&lt;br /&gt;
| Ride || Library for all of the actors that can be controlled by the player.&lt;br /&gt;
|-&lt;br /&gt;
| Scene || Library for all of the game scene related code.&lt;br /&gt;
|-&lt;br /&gt;
| Screen || Library for all of the layouts in the game.&lt;br /&gt;
|-&lt;br /&gt;
| Speaker || Library for the sound effect playing done on the Wiimote.&lt;br /&gt;
|-&lt;br /&gt;
| System || Library for a lot of the game&#039;s backend systems.&lt;br /&gt;
|-&lt;br /&gt;
| Util || Library for utility functions and classes.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Basics ==&lt;br /&gt;
To properly decompile, it is vital to know how a lot of the assembly will translate into C / C++ code. Here are a couple of patterns that you will see when decompiling code.&lt;br /&gt;
&lt;br /&gt;
=== Loops ===&lt;br /&gt;
==== Predefined bounds ====&lt;br /&gt;
Let&#039;s take a simple loop that stores &amp;lt;i&amp;gt;nullptr&amp;lt;/i&amp;gt; in each 8 elements of a pointer array.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class TestClass {&lt;br /&gt;
public:&lt;br /&gt;
    TestClass();&lt;br /&gt;
&lt;br /&gt;
     int* mPointers[8];&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
TestClass::TestClass() {&lt;br /&gt;
    for (int i = 0; i &amp;lt; 8; i++) {&lt;br /&gt;
        mPointers[i] = nullptr;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The output assembly would look something like:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
li r0, 8 # there are 8 elements in this loop&lt;br /&gt;
li r5, 0 # the value to store in the element (nullptr)&lt;br /&gt;
li r4, 0 # the current element offset in the loop&lt;br /&gt;
mtctr r0 # move the number of iterations into the counter register (8)&lt;br /&gt;
&lt;br /&gt;
loop:&lt;br /&gt;
    stwx r5, r3, r4 # store 0 (r5) into the array at r3 (this) + r4 (our current offset, which is i * 4)&lt;br /&gt;
    addi r4, r4, 4 # increment our offset by sizeof(int) since integers are 32-bits&lt;br /&gt;
    bdnz+ loop # branch back to our loop again&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Variable Length Bounds ====&lt;br /&gt;
Let&#039;s take a simple loop that stores &amp;lt;i&amp;gt;nullptr&amp;lt;/i&amp;gt; in each element of a variable-length array. We will have a class with two members, one that contains the pointer array itself, and another that stores the number of pointers.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class TestClass {&lt;br /&gt;
public:&lt;br /&gt;
    TestClass();&lt;br /&gt;
&lt;br /&gt;
     int** mPointers;&lt;br /&gt;
     int mNumPointers;&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
TestClass::TestClass() {&lt;br /&gt;
    mNumPointers = 8;&lt;br /&gt;
    for (int i = 0; i &amp;lt; mNumPointers ; i++) {&lt;br /&gt;
        mPointers[i] = nullptr;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Because we do not know how many pointers we have stored, we cannot use the counter register like we did with a fixed-size array. Instead, the compiler will use a cmpw (signed integer) or cmplw (unsigned) instruction to compare the current iteration to how many pointers are stored in the class.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
li r0, 8 # there are 8 elements in this loop&lt;br /&gt;
li r7, 0 # the value to store in the element (nullptr)&lt;br /&gt;
stw r0, 4(r3) # r3 + 4 is the offset to our member variable &amp;quot;mNumPointers&amp;quot;&lt;br /&gt;
mr r6, r7 # simple copy of the 0 value so we can also use it for our counter&lt;br /&gt;
li r4, 0 # load 0 into our offset&lt;br /&gt;
b loop # branch into our loop&lt;br /&gt;
&lt;br /&gt;
loop:&lt;br /&gt;
    lwz r5, 0(r3) # load our pointer array from this + 0&lt;br /&gt;
    addi r7, r7, 1 # increment our index by 1&lt;br /&gt;
    stwx r6, r5, r4 # store our nullptr value (r6) into r5 + r4 (ptrArray + currentOffset)&lt;br /&gt;
    addi r4, r4, 4 # increment our offset by sizeof(int) since integers are 32-bits&lt;br /&gt;
    lwz r0, 4(r3) # load our number of pointers we will increment by (mNumPointers)&lt;br /&gt;
    cmpw r7, r0 # compare our number of pointers to the current index in our loop&lt;br /&gt;
    blt+ loop # branch if the number is less than mNumPointers&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Structure Access In Arrays ====&lt;br /&gt;
More complex forms of loops comes into play when you are iterating through structures and storing / loading members from those structures. Let&#039;s take this class for example:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
struct TestStruct {&lt;br /&gt;
    int SomeMember;&lt;br /&gt;
    int AnotherMember;&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
class TestClass {&lt;br /&gt;
public:&lt;br /&gt;
    TestClass();&lt;br /&gt;
&lt;br /&gt;
    void storeVals();&lt;br /&gt;
&lt;br /&gt;
     TestStruct** mStructures;&lt;br /&gt;
     int mNumStructures;&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
For the sake of simplicity, let&#039;s assume that the TestClass constructor initializes the number of structures to 8, and constructs them accordingly. With that in mind, let&#039;s see how a struct store will work.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void TestClass::storeVals() {&lt;br /&gt;
    for (int i = 0; i &amp;lt; mNumStructures; i++) {&lt;br /&gt;
        mStructures[i]-&amp;gt;AnotherMember = 5;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
The output assembly would look something like:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
li r7, 0 # our &amp;quot;i&amp;quot; used in the loop, starts at 0&lt;br /&gt;
li r4, 0 # our current offset into the array&lt;br /&gt;
li r6, 5 # the value we are storing into the array&lt;br /&gt;
b loop&lt;br /&gt;
&lt;br /&gt;
loop:&lt;br /&gt;
    lwz r5, 0(r3) # load the array pointer&lt;br /&gt;
    addi r7, r7, 1 # increment our current index (i) by 1&lt;br /&gt;
    lwzx r5, r5, r4 # load the current structure, mStructures[i] where r4 is the current offset&lt;br /&gt;
    addi r4, r4, 4 # increment our offset by sizeof(TestStruct*), which is 4&lt;br /&gt;
    stw r6, 4(r5) # store our value (5) into (mStructures[i] + 4), which is our AnotherMember&lt;br /&gt;
    lwz r0, 4(r3) # load the number of structures from TestClass&lt;br /&gt;
    cmpw r7, r0 # compare the current index to our value in TestClass&lt;br /&gt;
    blt+ loop # loop back if it is less than the value&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Shibboleet</name></author>
	</entry>
	<entry>
		<id>https://www.lumasworkshop.com/w/index.php?title=Decompiling&amp;diff=135</id>
		<title>Decompiling</title>
		<link rel="alternate" type="text/html" href="https://www.lumasworkshop.com/w/index.php?title=Decompiling&amp;diff=135"/>
		<updated>2024-03-02T17:57:21Z</updated>

		<summary type="html">&lt;p&gt;Shibboleet: /* Predefined bounds */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Guides]]&lt;br /&gt;
[[Category:Decompiling]]&lt;br /&gt;
{{WIP}}&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
&#039;&#039;Decompiling&#039;&#039; is the process of taking assembly code and turning it back into a higher level language such as C or C++. It is essentially the reverse of &#039;&#039;compiling&#039;&#039;. &#039;&#039;Matching decompilation&#039;&#039; is the process of decompiling, but having the compiled code match the original assembly 1:1. While matching decompilation is harder than normal decompiling, it can become easier when you understand the patterns of the compiler used. This page aims to let new people understand how this process works, and hopefully be able to get new people into decompilation! While you do not need to be an expert at C or C++ to decompile, it is recommended that you have some experience before attempting decompilation. It is also very recommended that you have some prior knowledge of PowerPC assembly, as that is the key to understanding how a function works. [https://www.nxp.com/docs/en/reference-manual/MPC82XINSET.pdf This document] is a good way to learn or refresh knowledge of the PowerPC architecture. [https://www.warthman.com/images/IBM_PPC_Compiler_Writer%27s_Guide-cwg.pdf This document] is also good to learn some of the patterns that CodeWarrior does.&lt;br /&gt;
&lt;br /&gt;
== Getting Set Up ==&lt;br /&gt;
To begin decompiling &#039;&#039;Super Mario Galaxy&#039;&#039;, you first need to set up the environment. You will need the following tools:&lt;br /&gt;
* [https://gitforwindows.org/ Git (Windows)]&lt;br /&gt;
* Any IDE ([https://code.visualstudio.com/ Visual Studio Recommended])&lt;br /&gt;
* [https://www.python.org/downloads/release/python-397/ Python 3.9.7]&lt;br /&gt;
* IDA Pro (recommended) or Ghidra (Not recommended)&lt;br /&gt;
* [https://shibbo.net/smg/RMGK01_01.idb SMG1 Korean IDB (For IDA)]&lt;br /&gt;
* A &#039;&#039;Super Mario Galaxy&#039;&#039; Korean region DOL.&lt;br /&gt;
&lt;br /&gt;
After you have acquired all of these, setting up [https://github.com/shibbo/Petari Petari] is very simple.&lt;br /&gt;
&lt;br /&gt;
# With a new command prompt open, type in &#039;&#039;&#039;git clone https://github.com/shibbo/Petari&#039;&#039;&#039;. This will clone the repository into a directory called &amp;quot;Petari&amp;quot;.&lt;br /&gt;
# In this new &amp;quot;Petari&amp;quot; folder, place the SMG1 Korean &#039;&#039;&#039;main.dol&#039;&#039;&#039; into this folder, and rename it to &#039;&#039;&#039;baserom.dol&#039;&#039;&#039;.&lt;br /&gt;
# Open a new command prompt in the &amp;quot;Petari&amp;quot; folder.&lt;br /&gt;
# Run the command &#039;&#039;&#039;python setup.py&#039;&#039;&#039;. This will verify your DOL and install all of the libraries used, and the compilers we use to compile the code.&lt;br /&gt;
# Run the command &#039;&#039;&#039;python build.py&#039;&#039;&#039;. This will build the entire project. If you see any warnings, do not worry about them.&lt;br /&gt;
&lt;br /&gt;
== Environment ==&lt;br /&gt;
To properly utilize and use &#039;&#039;Petari&#039;&#039;, it is necessary to understand the structure of the environment. Petari is structured in a way that makes it easy to access and use.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Folder Name !! Description&lt;br /&gt;
|-&lt;br /&gt;
| archive || The folder that gets created when &#039;&#039;&#039;build.py -link&#039;&#039;&#039; is ran. Contains an archive of the object files in each library.&lt;br /&gt;
|-&lt;br /&gt;
| build || The folder that gets created when &#039;&#039;&#039;build.py&#039;&#039;&#039; is ran. Contains the compiled object files.&lt;br /&gt;
|-&lt;br /&gt;
| csv || Contains CSV files that store the status of functions being matched.&lt;br /&gt;
|-&lt;br /&gt;
| data || Contains map files and the percentage badges for the GitHub repo.&lt;br /&gt;
|-&lt;br /&gt;
| docs || The folder that gets created when &#039;&#039;&#039;progress.py&#039;&#039;&#039; is ran. Contains all of the Markdown documentation for matching status.&lt;br /&gt;
|-&lt;br /&gt;
| include || Contains all of the header files for &#039;&#039;Super Mario Galaxy&#039;&#039; specific code.&lt;br /&gt;
|-&lt;br /&gt;
| libs || Contains this folder structure but for different libraries used by the game.&lt;br /&gt;
|-&lt;br /&gt;
| scripts || Various scripts used in IDA for generating headers.&lt;br /&gt;
|-&lt;br /&gt;
| source || Contains all of the source files for &#039;&#039;Super Mario Galaxy&#039;&#039; specific code.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Libraries ==&lt;br /&gt;
&#039;&#039;Super Mario Galaxy&#039;&#039; uses a lot of libraries for certain functionality such as heaps, layouts, OS specific code, and more. Each library described in the table below are &#039;&#039;&#039;statically linked&#039;&#039;&#039; to the game, so every library&#039;s used code is inside of the &#039;&#039;main.dol&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
=== Non-SMG Libraries ===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Name !! Language !! Description&lt;br /&gt;
|-&lt;br /&gt;
| JSystem || C++ || Contains classes for backend things, such as heaps and linked lists.&lt;br /&gt;
|-&lt;br /&gt;
| MetroTRK || C || Target Resident Kernel, for debugging.&lt;br /&gt;
|-&lt;br /&gt;
| MSL_C || C &amp;amp; C++ || Contains standard library functions and types.&lt;br /&gt;
|-&lt;br /&gt;
| nw4r || C++ || Contains classes for sounds, layouts, and more. (SMG only uses the layouts and some math functions)&lt;br /&gt;
|-&lt;br /&gt;
| Runtime || C &amp;amp; C++ || Contains functions that relate to CodeWarrior&#039;s runtime code generation (ctor / dtor lists, etc)&lt;br /&gt;
|-&lt;br /&gt;
| RVL_SDK || C || Contains functions that relate to the Wii&#039;s &amp;quot;OS&amp;quot;.&lt;br /&gt;
|-&lt;br /&gt;
| RVLFaceLib || C || Contains functions that relate to Miis.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== SMG Libraries ===&lt;br /&gt;
All of &#039;&#039;Super Mario Galaxy&#039;&#039;&#039;s libraries are written in C++.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Header text !! Header text&lt;br /&gt;
|-&lt;br /&gt;
| Animation || Library for animation playing.&lt;br /&gt;
|-&lt;br /&gt;
| AreaObj || Library for invisible areas that can be accessed by players in the game.&lt;br /&gt;
|-&lt;br /&gt;
| AudioLib || N/A&lt;br /&gt;
|-&lt;br /&gt;
| Boss || Library for all of the bosses and mini-bosses in the game.&lt;br /&gt;
|-&lt;br /&gt;
| Camera || Library for all camera types.&lt;br /&gt;
|-&lt;br /&gt;
| Demo || Library for all cutscenes.&lt;br /&gt;
|-&lt;br /&gt;
| Effect || Library for all effect rendering.&lt;br /&gt;
|-&lt;br /&gt;
| Enemy || Library for all enemies.&lt;br /&gt;
|-&lt;br /&gt;
| GameAudio || N/A&lt;br /&gt;
|-&lt;br /&gt;
| Gravity || Library for all of the gravity types in the game.&lt;br /&gt;
|-&lt;br /&gt;
| LiveActor || Library for LiveActor, which is an actor that can switch states.&lt;br /&gt;
|-&lt;br /&gt;
| Map || Library for map classes that do not directly interact with the player. (ie switches)&lt;br /&gt;
|-&lt;br /&gt;
| MapObj || Library for all of the map objects in the game.&lt;br /&gt;
|-&lt;br /&gt;
| NameObj || Library for the most basic form of an object in the game.&lt;br /&gt;
|-&lt;br /&gt;
| NPC || Library for all of the non-playable characters.&lt;br /&gt;
|-&lt;br /&gt;
| NWC24 || Library for the mail system in the game.&lt;br /&gt;
|-&lt;br /&gt;
| Player || Library for all of the player related functions.&lt;br /&gt;
|-&lt;br /&gt;
| RhythmLib || N/A&lt;br /&gt;
|-&lt;br /&gt;
| Ride || Library for all of the actors that can be controlled by the player.&lt;br /&gt;
|-&lt;br /&gt;
| Scene || Library for all of the game scene related code.&lt;br /&gt;
|-&lt;br /&gt;
| Screen || Library for all of the layouts in the game.&lt;br /&gt;
|-&lt;br /&gt;
| Speaker || Library for the sound effect playing done on the Wiimote.&lt;br /&gt;
|-&lt;br /&gt;
| System || Library for a lot of the game&#039;s backend systems.&lt;br /&gt;
|-&lt;br /&gt;
| Util || Library for utility functions and classes.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Basics ==&lt;br /&gt;
To properly decompile, it is vital to know how a lot of the assembly will translate into C / C++ code. Here are a couple of patterns that you will see when decompiling code.&lt;br /&gt;
&lt;br /&gt;
=== Loops ===&lt;br /&gt;
==== Predefined bounds ====&lt;br /&gt;
Let&#039;s take a simple loop that stores &amp;lt;i&amp;gt;nullptr&amp;lt;/i&amp;gt; in each 8 elements of a pointer array.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class TestClass {&lt;br /&gt;
public:&lt;br /&gt;
    TestClass();&lt;br /&gt;
&lt;br /&gt;
     int* mPointers[8];&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
TestClass::TestClass() {&lt;br /&gt;
    for (int i = 0; i &amp;lt; 8; i++) {&lt;br /&gt;
        mPointers[i] = nullptr;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The output assembly would look something like:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
li r0, 8 # there are 8 elements in this loop&lt;br /&gt;
li r5, 0 # the value to store in the element (nullptr)&lt;br /&gt;
li r4, 0 # the current element offset in the loop&lt;br /&gt;
mtctr r0 # move the number of iterations into the counter register (8)&lt;br /&gt;
&lt;br /&gt;
loop:&lt;br /&gt;
    stwx r5, r3, r4 # store 0 (r5) into the array at r3 (this) + r4 (our current offset, which is i * 4)&lt;br /&gt;
    addi r4, r4, 4 # increment our offset by sizeof(int) since integers are 32-bits&lt;br /&gt;
    bdnz+ loop # branch back to our loop again&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Variable Length Bounds ====&lt;br /&gt;
Let&#039;s take a simple loop that stores &amp;lt;i&amp;gt;nullptr&amp;lt;/i&amp;gt; in each element of a variable-length array. We will have a class with two members, one that contains the pointer array itself, and another that stores the number of pointers.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class TestClass {&lt;br /&gt;
public:&lt;br /&gt;
    TestClass();&lt;br /&gt;
&lt;br /&gt;
     int** mPointers;&lt;br /&gt;
     int mNumPointers;&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
TestClass::TestClass() {&lt;br /&gt;
    mNumPointers = 8;&lt;br /&gt;
    for (int i = 0; i &amp;lt; mNumPointers ; i++) {&lt;br /&gt;
        mPointers[i] = nullptr;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Because we do not know how many pointers we have stored, we cannot use the counter register like we did with a fixed-size array. Instead, the compiler will use a cmpw (signed integer) or cmplw (unsigned) instruction to compare the current iteration to how many pointers are stored in the class.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
li r0, 8 # there are 8 elements in this loop&lt;br /&gt;
li r7, 0 # the value to store in the element (nullptr)&lt;br /&gt;
stw r0, 4(r3) # r3 + 4 is the offset to our member variable &amp;quot;mNumPointers&amp;quot;&lt;br /&gt;
mr r6, r7 # simple copy of the 0 value so we can also use it for our counter&lt;br /&gt;
li r4, 0 # load 0 into our offset&lt;br /&gt;
b loop # branch into our loop&lt;br /&gt;
&lt;br /&gt;
loop:&lt;br /&gt;
    lwz r5, 0(r3) # load our pointer array from this + 0&lt;br /&gt;
    addi r7, r7, 1 # increment our index by 1&lt;br /&gt;
    stwx r6, r5, r4 # store our nullptr value (r6) into r5 + r4 (ptrArray + currentOffset)&lt;br /&gt;
    addi r4, r4, 4 # increment our offset by sizeof(int) since integers are 32-bits&lt;br /&gt;
    lwz r0, 4(r3) # load our number of pointers we will increment by (mNumPointers)&lt;br /&gt;
    cmpw r7, r0 # compare our number of pointers to the current index in our loop&lt;br /&gt;
    blt+ loop # branch if the number is less than mNumPointers&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Shibboleet</name></author>
	</entry>
	<entry>
		<id>https://www.lumasworkshop.com/w/index.php?title=Decompiling&amp;diff=134</id>
		<title>Decompiling</title>
		<link rel="alternate" type="text/html" href="https://www.lumasworkshop.com/w/index.php?title=Decompiling&amp;diff=134"/>
		<updated>2024-03-02T17:55:23Z</updated>

		<summary type="html">&lt;p&gt;Shibboleet: /* Variable Length Bounds */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Guides]]&lt;br /&gt;
[[Category:Decompiling]]&lt;br /&gt;
{{WIP}}&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
&#039;&#039;Decompiling&#039;&#039; is the process of taking assembly code and turning it back into a higher level language such as C or C++. It is essentially the reverse of &#039;&#039;compiling&#039;&#039;. &#039;&#039;Matching decompilation&#039;&#039; is the process of decompiling, but having the compiled code match the original assembly 1:1. While matching decompilation is harder than normal decompiling, it can become easier when you understand the patterns of the compiler used. This page aims to let new people understand how this process works, and hopefully be able to get new people into decompilation! While you do not need to be an expert at C or C++ to decompile, it is recommended that you have some experience before attempting decompilation. It is also very recommended that you have some prior knowledge of PowerPC assembly, as that is the key to understanding how a function works. [https://www.nxp.com/docs/en/reference-manual/MPC82XINSET.pdf This document] is a good way to learn or refresh knowledge of the PowerPC architecture. [https://www.warthman.com/images/IBM_PPC_Compiler_Writer%27s_Guide-cwg.pdf This document] is also good to learn some of the patterns that CodeWarrior does.&lt;br /&gt;
&lt;br /&gt;
== Getting Set Up ==&lt;br /&gt;
To begin decompiling &#039;&#039;Super Mario Galaxy&#039;&#039;, you first need to set up the environment. You will need the following tools:&lt;br /&gt;
* [https://gitforwindows.org/ Git (Windows)]&lt;br /&gt;
* Any IDE ([https://code.visualstudio.com/ Visual Studio Recommended])&lt;br /&gt;
* [https://www.python.org/downloads/release/python-397/ Python 3.9.7]&lt;br /&gt;
* IDA Pro (recommended) or Ghidra (Not recommended)&lt;br /&gt;
* [https://shibbo.net/smg/RMGK01_01.idb SMG1 Korean IDB (For IDA)]&lt;br /&gt;
* A &#039;&#039;Super Mario Galaxy&#039;&#039; Korean region DOL.&lt;br /&gt;
&lt;br /&gt;
After you have acquired all of these, setting up [https://github.com/shibbo/Petari Petari] is very simple.&lt;br /&gt;
&lt;br /&gt;
# With a new command prompt open, type in &#039;&#039;&#039;git clone https://github.com/shibbo/Petari&#039;&#039;&#039;. This will clone the repository into a directory called &amp;quot;Petari&amp;quot;.&lt;br /&gt;
# In this new &amp;quot;Petari&amp;quot; folder, place the SMG1 Korean &#039;&#039;&#039;main.dol&#039;&#039;&#039; into this folder, and rename it to &#039;&#039;&#039;baserom.dol&#039;&#039;&#039;.&lt;br /&gt;
# Open a new command prompt in the &amp;quot;Petari&amp;quot; folder.&lt;br /&gt;
# Run the command &#039;&#039;&#039;python setup.py&#039;&#039;&#039;. This will verify your DOL and install all of the libraries used, and the compilers we use to compile the code.&lt;br /&gt;
# Run the command &#039;&#039;&#039;python build.py&#039;&#039;&#039;. This will build the entire project. If you see any warnings, do not worry about them.&lt;br /&gt;
&lt;br /&gt;
== Environment ==&lt;br /&gt;
To properly utilize and use &#039;&#039;Petari&#039;&#039;, it is necessary to understand the structure of the environment. Petari is structured in a way that makes it easy to access and use.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Folder Name !! Description&lt;br /&gt;
|-&lt;br /&gt;
| archive || The folder that gets created when &#039;&#039;&#039;build.py -link&#039;&#039;&#039; is ran. Contains an archive of the object files in each library.&lt;br /&gt;
|-&lt;br /&gt;
| build || The folder that gets created when &#039;&#039;&#039;build.py&#039;&#039;&#039; is ran. Contains the compiled object files.&lt;br /&gt;
|-&lt;br /&gt;
| csv || Contains CSV files that store the status of functions being matched.&lt;br /&gt;
|-&lt;br /&gt;
| data || Contains map files and the percentage badges for the GitHub repo.&lt;br /&gt;
|-&lt;br /&gt;
| docs || The folder that gets created when &#039;&#039;&#039;progress.py&#039;&#039;&#039; is ran. Contains all of the Markdown documentation for matching status.&lt;br /&gt;
|-&lt;br /&gt;
| include || Contains all of the header files for &#039;&#039;Super Mario Galaxy&#039;&#039; specific code.&lt;br /&gt;
|-&lt;br /&gt;
| libs || Contains this folder structure but for different libraries used by the game.&lt;br /&gt;
|-&lt;br /&gt;
| scripts || Various scripts used in IDA for generating headers.&lt;br /&gt;
|-&lt;br /&gt;
| source || Contains all of the source files for &#039;&#039;Super Mario Galaxy&#039;&#039; specific code.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Libraries ==&lt;br /&gt;
&#039;&#039;Super Mario Galaxy&#039;&#039; uses a lot of libraries for certain functionality such as heaps, layouts, OS specific code, and more. Each library described in the table below are &#039;&#039;&#039;statically linked&#039;&#039;&#039; to the game, so every library&#039;s used code is inside of the &#039;&#039;main.dol&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
=== Non-SMG Libraries ===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Name !! Language !! Description&lt;br /&gt;
|-&lt;br /&gt;
| JSystem || C++ || Contains classes for backend things, such as heaps and linked lists.&lt;br /&gt;
|-&lt;br /&gt;
| MetroTRK || C || Target Resident Kernel, for debugging.&lt;br /&gt;
|-&lt;br /&gt;
| MSL_C || C &amp;amp; C++ || Contains standard library functions and types.&lt;br /&gt;
|-&lt;br /&gt;
| nw4r || C++ || Contains classes for sounds, layouts, and more. (SMG only uses the layouts and some math functions)&lt;br /&gt;
|-&lt;br /&gt;
| Runtime || C &amp;amp; C++ || Contains functions that relate to CodeWarrior&#039;s runtime code generation (ctor / dtor lists, etc)&lt;br /&gt;
|-&lt;br /&gt;
| RVL_SDK || C || Contains functions that relate to the Wii&#039;s &amp;quot;OS&amp;quot;.&lt;br /&gt;
|-&lt;br /&gt;
| RVLFaceLib || C || Contains functions that relate to Miis.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== SMG Libraries ===&lt;br /&gt;
All of &#039;&#039;Super Mario Galaxy&#039;&#039;&#039;s libraries are written in C++.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Header text !! Header text&lt;br /&gt;
|-&lt;br /&gt;
| Animation || Library for animation playing.&lt;br /&gt;
|-&lt;br /&gt;
| AreaObj || Library for invisible areas that can be accessed by players in the game.&lt;br /&gt;
|-&lt;br /&gt;
| AudioLib || N/A&lt;br /&gt;
|-&lt;br /&gt;
| Boss || Library for all of the bosses and mini-bosses in the game.&lt;br /&gt;
|-&lt;br /&gt;
| Camera || Library for all camera types.&lt;br /&gt;
|-&lt;br /&gt;
| Demo || Library for all cutscenes.&lt;br /&gt;
|-&lt;br /&gt;
| Effect || Library for all effect rendering.&lt;br /&gt;
|-&lt;br /&gt;
| Enemy || Library for all enemies.&lt;br /&gt;
|-&lt;br /&gt;
| GameAudio || N/A&lt;br /&gt;
|-&lt;br /&gt;
| Gravity || Library for all of the gravity types in the game.&lt;br /&gt;
|-&lt;br /&gt;
| LiveActor || Library for LiveActor, which is an actor that can switch states.&lt;br /&gt;
|-&lt;br /&gt;
| Map || Library for map classes that do not directly interact with the player. (ie switches)&lt;br /&gt;
|-&lt;br /&gt;
| MapObj || Library for all of the map objects in the game.&lt;br /&gt;
|-&lt;br /&gt;
| NameObj || Library for the most basic form of an object in the game.&lt;br /&gt;
|-&lt;br /&gt;
| NPC || Library for all of the non-playable characters.&lt;br /&gt;
|-&lt;br /&gt;
| NWC24 || Library for the mail system in the game.&lt;br /&gt;
|-&lt;br /&gt;
| Player || Library for all of the player related functions.&lt;br /&gt;
|-&lt;br /&gt;
| RhythmLib || N/A&lt;br /&gt;
|-&lt;br /&gt;
| Ride || Library for all of the actors that can be controlled by the player.&lt;br /&gt;
|-&lt;br /&gt;
| Scene || Library for all of the game scene related code.&lt;br /&gt;
|-&lt;br /&gt;
| Screen || Library for all of the layouts in the game.&lt;br /&gt;
|-&lt;br /&gt;
| Speaker || Library for the sound effect playing done on the Wiimote.&lt;br /&gt;
|-&lt;br /&gt;
| System || Library for a lot of the game&#039;s backend systems.&lt;br /&gt;
|-&lt;br /&gt;
| Util || Library for utility functions and classes.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Basics ==&lt;br /&gt;
To properly decompile, it is vital to know how a lot of the assembly will translate into C / C++ code. Here are a couple of patterns that you will see when decompiling code.&lt;br /&gt;
&lt;br /&gt;
=== Loops ===&lt;br /&gt;
==== Predefined bounds ====&lt;br /&gt;
Let&#039;s take a simple loop that stores &amp;lt;i&amp;gt;nullptr&amp;lt;/i&amp;gt; in each 8 elements of a pointer array.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class TestClass {&lt;br /&gt;
public:&lt;br /&gt;
    TestClass();&lt;br /&gt;
&lt;br /&gt;
     int* mPointers[8];&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
TestClass::TestClass() {&lt;br /&gt;
    for (int i = 0; i &amp;lt; 8; i++) {&lt;br /&gt;
        mPointers[i] = nullptr;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The output assembly would look something like:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
li r0, 8 # there are 8 elements in this loop&lt;br /&gt;
li r5, 0 # the value to store in the element (nullptr)&lt;br /&gt;
li r4, 0 # the current element offset in the loop&lt;br /&gt;
mtctr r0 # move the number of iterations into the counter register (8)&lt;br /&gt;
&lt;br /&gt;
loop:&lt;br /&gt;
    stwx r5, r3, r4 # store 0 (r6) into the array at r5 (this) + r6 (our current offset, which is i * 4)&lt;br /&gt;
    addi r4, r4, 4 # increment our offset by sizeof(int) since integers are 32-bits&lt;br /&gt;
    bdnz+ loop # branch back to our loop again&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Variable Length Bounds ====&lt;br /&gt;
Let&#039;s take a simple loop that stores &amp;lt;i&amp;gt;nullptr&amp;lt;/i&amp;gt; in each element of a variable-length array. We will have a class with two members, one that contains the pointer array itself, and another that stores the number of pointers.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class TestClass {&lt;br /&gt;
public:&lt;br /&gt;
    TestClass();&lt;br /&gt;
&lt;br /&gt;
     int** mPointers;&lt;br /&gt;
     int mNumPointers;&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
TestClass::TestClass() {&lt;br /&gt;
    mNumPointers = 8;&lt;br /&gt;
    for (int i = 0; i &amp;lt; mNumPointers ; i++) {&lt;br /&gt;
        mPointers[i] = nullptr;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Because we do not know how many pointers we have stored, we cannot use the counter register like we did with a fixed-size array. Instead, the compiler will use a cmpw (signed integer) or cmplw (unsigned) instruction to compare the current iteration to how many pointers are stored in the class.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
li r0, 8 # there are 8 elements in this loop&lt;br /&gt;
li r7, 0 # the value to store in the element (nullptr)&lt;br /&gt;
stw r0, 4(r3) # r3 + 4 is the offset to our member variable &amp;quot;mNumPointers&amp;quot;&lt;br /&gt;
mr r6, r7 # simple copy of the 0 value so we can also use it for our counter&lt;br /&gt;
li r4, 0 # load 0 into our offset&lt;br /&gt;
b loop # branch into our loop&lt;br /&gt;
&lt;br /&gt;
loop:&lt;br /&gt;
    lwz r5, 0(r3) # load our pointer array from this + 0&lt;br /&gt;
    addi r7, r7, 1 # increment our index by 1&lt;br /&gt;
    stwx r6, r5, r4 # store our nullptr value (r6) into r5 + r4 (ptrArray + currentOffset)&lt;br /&gt;
    addi r4, r4, 4 # increment our offset by sizeof(int) since integers are 32-bits&lt;br /&gt;
    lwz r0, 4(r3) # load our number of pointers we will increment by (mNumPointers)&lt;br /&gt;
    cmpw r7, r0 # compare our number of pointers to the current index in our loop&lt;br /&gt;
    blt+ loop # branch if the number is less than mNumPointers&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Shibboleet</name></author>
	</entry>
	<entry>
		<id>https://www.lumasworkshop.com/w/index.php?title=Decompiling&amp;diff=133</id>
		<title>Decompiling</title>
		<link rel="alternate" type="text/html" href="https://www.lumasworkshop.com/w/index.php?title=Decompiling&amp;diff=133"/>
		<updated>2024-03-02T17:54:49Z</updated>

		<summary type="html">&lt;p&gt;Shibboleet: add info on loops&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Guides]]&lt;br /&gt;
[[Category:Decompiling]]&lt;br /&gt;
{{WIP}}&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
&#039;&#039;Decompiling&#039;&#039; is the process of taking assembly code and turning it back into a higher level language such as C or C++. It is essentially the reverse of &#039;&#039;compiling&#039;&#039;. &#039;&#039;Matching decompilation&#039;&#039; is the process of decompiling, but having the compiled code match the original assembly 1:1. While matching decompilation is harder than normal decompiling, it can become easier when you understand the patterns of the compiler used. This page aims to let new people understand how this process works, and hopefully be able to get new people into decompilation! While you do not need to be an expert at C or C++ to decompile, it is recommended that you have some experience before attempting decompilation. It is also very recommended that you have some prior knowledge of PowerPC assembly, as that is the key to understanding how a function works. [https://www.nxp.com/docs/en/reference-manual/MPC82XINSET.pdf This document] is a good way to learn or refresh knowledge of the PowerPC architecture. [https://www.warthman.com/images/IBM_PPC_Compiler_Writer%27s_Guide-cwg.pdf This document] is also good to learn some of the patterns that CodeWarrior does.&lt;br /&gt;
&lt;br /&gt;
== Getting Set Up ==&lt;br /&gt;
To begin decompiling &#039;&#039;Super Mario Galaxy&#039;&#039;, you first need to set up the environment. You will need the following tools:&lt;br /&gt;
* [https://gitforwindows.org/ Git (Windows)]&lt;br /&gt;
* Any IDE ([https://code.visualstudio.com/ Visual Studio Recommended])&lt;br /&gt;
* [https://www.python.org/downloads/release/python-397/ Python 3.9.7]&lt;br /&gt;
* IDA Pro (recommended) or Ghidra (Not recommended)&lt;br /&gt;
* [https://shibbo.net/smg/RMGK01_01.idb SMG1 Korean IDB (For IDA)]&lt;br /&gt;
* A &#039;&#039;Super Mario Galaxy&#039;&#039; Korean region DOL.&lt;br /&gt;
&lt;br /&gt;
After you have acquired all of these, setting up [https://github.com/shibbo/Petari Petari] is very simple.&lt;br /&gt;
&lt;br /&gt;
# With a new command prompt open, type in &#039;&#039;&#039;git clone https://github.com/shibbo/Petari&#039;&#039;&#039;. This will clone the repository into a directory called &amp;quot;Petari&amp;quot;.&lt;br /&gt;
# In this new &amp;quot;Petari&amp;quot; folder, place the SMG1 Korean &#039;&#039;&#039;main.dol&#039;&#039;&#039; into this folder, and rename it to &#039;&#039;&#039;baserom.dol&#039;&#039;&#039;.&lt;br /&gt;
# Open a new command prompt in the &amp;quot;Petari&amp;quot; folder.&lt;br /&gt;
# Run the command &#039;&#039;&#039;python setup.py&#039;&#039;&#039;. This will verify your DOL and install all of the libraries used, and the compilers we use to compile the code.&lt;br /&gt;
# Run the command &#039;&#039;&#039;python build.py&#039;&#039;&#039;. This will build the entire project. If you see any warnings, do not worry about them.&lt;br /&gt;
&lt;br /&gt;
== Environment ==&lt;br /&gt;
To properly utilize and use &#039;&#039;Petari&#039;&#039;, it is necessary to understand the structure of the environment. Petari is structured in a way that makes it easy to access and use.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Folder Name !! Description&lt;br /&gt;
|-&lt;br /&gt;
| archive || The folder that gets created when &#039;&#039;&#039;build.py -link&#039;&#039;&#039; is ran. Contains an archive of the object files in each library.&lt;br /&gt;
|-&lt;br /&gt;
| build || The folder that gets created when &#039;&#039;&#039;build.py&#039;&#039;&#039; is ran. Contains the compiled object files.&lt;br /&gt;
|-&lt;br /&gt;
| csv || Contains CSV files that store the status of functions being matched.&lt;br /&gt;
|-&lt;br /&gt;
| data || Contains map files and the percentage badges for the GitHub repo.&lt;br /&gt;
|-&lt;br /&gt;
| docs || The folder that gets created when &#039;&#039;&#039;progress.py&#039;&#039;&#039; is ran. Contains all of the Markdown documentation for matching status.&lt;br /&gt;
|-&lt;br /&gt;
| include || Contains all of the header files for &#039;&#039;Super Mario Galaxy&#039;&#039; specific code.&lt;br /&gt;
|-&lt;br /&gt;
| libs || Contains this folder structure but for different libraries used by the game.&lt;br /&gt;
|-&lt;br /&gt;
| scripts || Various scripts used in IDA for generating headers.&lt;br /&gt;
|-&lt;br /&gt;
| source || Contains all of the source files for &#039;&#039;Super Mario Galaxy&#039;&#039; specific code.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Libraries ==&lt;br /&gt;
&#039;&#039;Super Mario Galaxy&#039;&#039; uses a lot of libraries for certain functionality such as heaps, layouts, OS specific code, and more. Each library described in the table below are &#039;&#039;&#039;statically linked&#039;&#039;&#039; to the game, so every library&#039;s used code is inside of the &#039;&#039;main.dol&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
=== Non-SMG Libraries ===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Name !! Language !! Description&lt;br /&gt;
|-&lt;br /&gt;
| JSystem || C++ || Contains classes for backend things, such as heaps and linked lists.&lt;br /&gt;
|-&lt;br /&gt;
| MetroTRK || C || Target Resident Kernel, for debugging.&lt;br /&gt;
|-&lt;br /&gt;
| MSL_C || C &amp;amp; C++ || Contains standard library functions and types.&lt;br /&gt;
|-&lt;br /&gt;
| nw4r || C++ || Contains classes for sounds, layouts, and more. (SMG only uses the layouts and some math functions)&lt;br /&gt;
|-&lt;br /&gt;
| Runtime || C &amp;amp; C++ || Contains functions that relate to CodeWarrior&#039;s runtime code generation (ctor / dtor lists, etc)&lt;br /&gt;
|-&lt;br /&gt;
| RVL_SDK || C || Contains functions that relate to the Wii&#039;s &amp;quot;OS&amp;quot;.&lt;br /&gt;
|-&lt;br /&gt;
| RVLFaceLib || C || Contains functions that relate to Miis.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== SMG Libraries ===&lt;br /&gt;
All of &#039;&#039;Super Mario Galaxy&#039;&#039;&#039;s libraries are written in C++.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Header text !! Header text&lt;br /&gt;
|-&lt;br /&gt;
| Animation || Library for animation playing.&lt;br /&gt;
|-&lt;br /&gt;
| AreaObj || Library for invisible areas that can be accessed by players in the game.&lt;br /&gt;
|-&lt;br /&gt;
| AudioLib || N/A&lt;br /&gt;
|-&lt;br /&gt;
| Boss || Library for all of the bosses and mini-bosses in the game.&lt;br /&gt;
|-&lt;br /&gt;
| Camera || Library for all camera types.&lt;br /&gt;
|-&lt;br /&gt;
| Demo || Library for all cutscenes.&lt;br /&gt;
|-&lt;br /&gt;
| Effect || Library for all effect rendering.&lt;br /&gt;
|-&lt;br /&gt;
| Enemy || Library for all enemies.&lt;br /&gt;
|-&lt;br /&gt;
| GameAudio || N/A&lt;br /&gt;
|-&lt;br /&gt;
| Gravity || Library for all of the gravity types in the game.&lt;br /&gt;
|-&lt;br /&gt;
| LiveActor || Library for LiveActor, which is an actor that can switch states.&lt;br /&gt;
|-&lt;br /&gt;
| Map || Library for map classes that do not directly interact with the player. (ie switches)&lt;br /&gt;
|-&lt;br /&gt;
| MapObj || Library for all of the map objects in the game.&lt;br /&gt;
|-&lt;br /&gt;
| NameObj || Library for the most basic form of an object in the game.&lt;br /&gt;
|-&lt;br /&gt;
| NPC || Library for all of the non-playable characters.&lt;br /&gt;
|-&lt;br /&gt;
| NWC24 || Library for the mail system in the game.&lt;br /&gt;
|-&lt;br /&gt;
| Player || Library for all of the player related functions.&lt;br /&gt;
|-&lt;br /&gt;
| RhythmLib || N/A&lt;br /&gt;
|-&lt;br /&gt;
| Ride || Library for all of the actors that can be controlled by the player.&lt;br /&gt;
|-&lt;br /&gt;
| Scene || Library for all of the game scene related code.&lt;br /&gt;
|-&lt;br /&gt;
| Screen || Library for all of the layouts in the game.&lt;br /&gt;
|-&lt;br /&gt;
| Speaker || Library for the sound effect playing done on the Wiimote.&lt;br /&gt;
|-&lt;br /&gt;
| System || Library for a lot of the game&#039;s backend systems.&lt;br /&gt;
|-&lt;br /&gt;
| Util || Library for utility functions and classes.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Basics ==&lt;br /&gt;
To properly decompile, it is vital to know how a lot of the assembly will translate into C / C++ code. Here are a couple of patterns that you will see when decompiling code.&lt;br /&gt;
&lt;br /&gt;
=== Loops ===&lt;br /&gt;
==== Predefined bounds ====&lt;br /&gt;
Let&#039;s take a simple loop that stores &amp;lt;i&amp;gt;nullptr&amp;lt;/i&amp;gt; in each 8 elements of a pointer array.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class TestClass {&lt;br /&gt;
public:&lt;br /&gt;
    TestClass();&lt;br /&gt;
&lt;br /&gt;
     int* mPointers[8];&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
TestClass::TestClass() {&lt;br /&gt;
    for (int i = 0; i &amp;lt; 8; i++) {&lt;br /&gt;
        mPointers[i] = nullptr;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The output assembly would look something like:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
li r0, 8 # there are 8 elements in this loop&lt;br /&gt;
li r5, 0 # the value to store in the element (nullptr)&lt;br /&gt;
li r4, 0 # the current element offset in the loop&lt;br /&gt;
mtctr r0 # move the number of iterations into the counter register (8)&lt;br /&gt;
&lt;br /&gt;
loop:&lt;br /&gt;
    stwx r5, r3, r4 # store 0 (r6) into the array at r5 (this) + r6 (our current offset, which is i * 4)&lt;br /&gt;
    addi r4, r4, 4 # increment our offset by sizeof(int) since integers are 32-bits&lt;br /&gt;
    bdnz+ loop # branch back to our loop again&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Variable Length Bounds ====&lt;br /&gt;
Let&#039;s take a simple loop that stores &amp;lt;i&amp;gt;nullptr&amp;lt;/i&amp;gt; in each element of a variable-length array. We will have a class with two members, one that contains the pointer array itself, and another that stores the number of pointers.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class TestClass {&lt;br /&gt;
public:&lt;br /&gt;
    TestClass();&lt;br /&gt;
&lt;br /&gt;
     int** mPointers;&lt;br /&gt;
     int mNumPointers;&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
TestClass::TestClass() {&lt;br /&gt;
    mNumPointers = 8;&lt;br /&gt;
    for (int i = 0; i &amp;lt; mNumPointers ; i++) {&lt;br /&gt;
        mPointers[i] = nullptr;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Because we do not know how many pointers we are stored, we cannot use the counter register like we did with a fixed-size array. Instead, the compiler will use a cmpw (signed integer) or cmplw (unsigned) instruction to compare the current iteration to how many pointers are stored in the class.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
li r0, 8 # there are 8 elements in this loop&lt;br /&gt;
li r7, 0 # the value to store in the element (nullptr)&lt;br /&gt;
stw r0, 4(r3) # r3 + 4 is the offset to our member variable &amp;quot;mNumPointers&amp;quot;&lt;br /&gt;
mr r6, r7 # simple copy of the 0 value so we can also use it for our counter&lt;br /&gt;
li r4, 0 # load 0 into our offset&lt;br /&gt;
b loop # branch into our loop&lt;br /&gt;
&lt;br /&gt;
loop:&lt;br /&gt;
    lwz r5, 0(r3) # load our pointer array from this + 0&lt;br /&gt;
    addi r7, r7, 1 # increment our index by 1&lt;br /&gt;
    stwx r6, r5, r4 # store our nullptr value (r6) into r5 + r4 (ptrArray + currentOffset)&lt;br /&gt;
    addi r4, r4, 4 # increment our offset by sizeof(int) since integers are 32-bits&lt;br /&gt;
    lwz r0, 4(r3) # load our number of pointers we will increment by (mNumPointers)&lt;br /&gt;
    cmpw r7, r0 # compare our number of pointers to the current index in our loop&lt;br /&gt;
    blt+ loop # branch if the number is less than mNumPointers&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Shibboleet</name></author>
	</entry>
	<entry>
		<id>https://www.lumasworkshop.com/w/index.php?title=Decompiling&amp;diff=130</id>
		<title>Decompiling</title>
		<link rel="alternate" type="text/html" href="https://www.lumasworkshop.com/w/index.php?title=Decompiling&amp;diff=130"/>
		<updated>2024-02-23T17:18:22Z</updated>

		<summary type="html">&lt;p&gt;Shibboleet: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Guides]]&lt;br /&gt;
[[Category:Decompiling]]&lt;br /&gt;
{{WIP}}&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
&#039;&#039;Decompiling&#039;&#039; is the process of taking assembly code and turning it back into a higher level language such as C or C++. It is essentially the reverse of &#039;&#039;compiling&#039;&#039;. &#039;&#039;Matching decompilation&#039;&#039; is the process of decompiling, but having the compiled code match the original assembly 1:1. While matching decompilation is harder than normal decompiling, it can become easier when you understand the patterns of the compiler used. This page aims to let new people understand how this process works, and hopefully be able to get new people into decompilation! While you do not need to be an expert at C or C++ to decompile, it is recommended that you have some experience before attempting decompilation. It is also very recommended that you have some prior knowledge of PowerPC assembly, as that is the key to understanding how a function works. [https://www.nxp.com/docs/en/reference-manual/MPC82XINSET.pdf This document] is a good way to learn or refresh knowledge of the PowerPC architecture. [https://www.warthman.com/images/IBM_PPC_Compiler_Writer%27s_Guide-cwg.pdf This document] is also good to learn some of the patterns that CodeWarrior does.&lt;br /&gt;
&lt;br /&gt;
== Getting Set Up ==&lt;br /&gt;
To begin decompiling &#039;&#039;Super Mario Galaxy&#039;&#039;, you first need to set up the environment. You will need the following tools:&lt;br /&gt;
* [https://gitforwindows.org/ Git (Windows)]&lt;br /&gt;
* Any IDE ([https://code.visualstudio.com/ Visual Studio Recommended])&lt;br /&gt;
* [https://www.python.org/downloads/release/python-397/ Python 3.9.7]&lt;br /&gt;
* IDA Pro (recommended) or Ghidra (Not recommended)&lt;br /&gt;
* [https://shibbo.net/smg/RMGK01_01.idb SMG1 Korean IDB (For IDA)]&lt;br /&gt;
* A &#039;&#039;Super Mario Galaxy&#039;&#039; Korean region DOL.&lt;br /&gt;
&lt;br /&gt;
After you have acquired all of these, setting up [https://github.com/shibbo/Petari Petari] is very simple.&lt;br /&gt;
&lt;br /&gt;
# With a new command prompt open, type in &#039;&#039;&#039;git clone https://github.com/shibbo/Petari&#039;&#039;&#039;. This will clone the repository into a directory called &amp;quot;Petari&amp;quot;.&lt;br /&gt;
# In this new &amp;quot;Petari&amp;quot; folder, place the SMG1 Korean &#039;&#039;&#039;main.dol&#039;&#039;&#039; into this folder, and rename it to &#039;&#039;&#039;baserom.dol&#039;&#039;&#039;.&lt;br /&gt;
# Open a new command prompt in the &amp;quot;Petari&amp;quot; folder.&lt;br /&gt;
# Run the command &#039;&#039;&#039;python setup.py&#039;&#039;&#039;. This will verify your DOL and install all of the libraries used, and the compilers we use to compile the code.&lt;br /&gt;
# Run the command &#039;&#039;&#039;python build.py&#039;&#039;&#039;. This will build the entire project. If you see any warnings, do not worry about them.&lt;br /&gt;
&lt;br /&gt;
== Environment ==&lt;br /&gt;
To properly utilize and use &#039;&#039;Petari&#039;&#039;, it is necessary to understand the structure of the environment. Petari is structured in a way that makes it easy to access and use.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Folder Name !! Description&lt;br /&gt;
|-&lt;br /&gt;
| archive || The folder that gets created when &#039;&#039;&#039;build.py -link&#039;&#039;&#039; is ran. Contains an archive of the object files in each library.&lt;br /&gt;
|-&lt;br /&gt;
| build || The folder that gets created when &#039;&#039;&#039;build.py&#039;&#039;&#039; is ran. Contains the compiled object files.&lt;br /&gt;
|-&lt;br /&gt;
| csv || Contains CSV files that store the status of functions being matched.&lt;br /&gt;
|-&lt;br /&gt;
| data || Contains map files and the percentage badges for the GitHub repo.&lt;br /&gt;
|-&lt;br /&gt;
| docs || The folder that gets created when &#039;&#039;&#039;progress.py&#039;&#039;&#039; is ran. Contains all of the Markdown documentation for matching status.&lt;br /&gt;
|-&lt;br /&gt;
| include || Contains all of the header files for &#039;&#039;Super Mario Galaxy&#039;&#039; specific code.&lt;br /&gt;
|-&lt;br /&gt;
| libs || Contains this folder structure but for different libraries used by the game.&lt;br /&gt;
|-&lt;br /&gt;
| scripts || Various scripts used in IDA for generating headers.&lt;br /&gt;
|-&lt;br /&gt;
| source || Contains all of the source files for &#039;&#039;Super Mario Galaxy&#039;&#039; specific code.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Libraries ==&lt;br /&gt;
&#039;&#039;Super Mario Galaxy&#039;&#039; uses a lot of libraries for certain functionality such as heaps, layouts, OS specific code, and more. Each library described in the table below are &#039;&#039;&#039;statically linked&#039;&#039;&#039; to the game, so every library&#039;s used code is inside of the &#039;&#039;main.dol&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
=== Non-SMG Libraries ===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Name !! Language !! Description&lt;br /&gt;
|-&lt;br /&gt;
| JSystem || C++ || Contains classes for backend things, such as heaps and linked lists.&lt;br /&gt;
|-&lt;br /&gt;
| MetroTRK || C || Target Resident Kernel, for debugging.&lt;br /&gt;
|-&lt;br /&gt;
| MSL_C || C &amp;amp; C++ || Contains standard library functions and types.&lt;br /&gt;
|-&lt;br /&gt;
| nw4r || C++ || Contains classes for sounds, layouts, and more. (SMG only uses the layouts and some math functions)&lt;br /&gt;
|-&lt;br /&gt;
| Runtime || C &amp;amp; C++ || Contains functions that relate to CodeWarrior&#039;s runtime code generation (ctor / dtor lists, etc)&lt;br /&gt;
|-&lt;br /&gt;
| RVL_SDK || C || Contains functions that relate to the Wii&#039;s &amp;quot;OS&amp;quot;.&lt;br /&gt;
|-&lt;br /&gt;
| RVLFaceLib || C || Contains functions that relate to Miis.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== SMG Libraries ===&lt;br /&gt;
All of &#039;&#039;Super Mario Galaxy&#039;&#039;&#039;s libraries are written in C++.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Header text !! Header text&lt;br /&gt;
|-&lt;br /&gt;
| Animation || Library for animation playing.&lt;br /&gt;
|-&lt;br /&gt;
| AreaObj || Library for invisible areas that can be accessed by players in the game.&lt;br /&gt;
|-&lt;br /&gt;
| AudioLib || N/A&lt;br /&gt;
|-&lt;br /&gt;
| Boss || Library for all of the bosses and mini-bosses in the game.&lt;br /&gt;
|-&lt;br /&gt;
| Camera || Library for all camera types.&lt;br /&gt;
|-&lt;br /&gt;
| Demo || Library for all cutscenes.&lt;br /&gt;
|-&lt;br /&gt;
| Effect || Library for all effect rendering.&lt;br /&gt;
|-&lt;br /&gt;
| Enemy || Library for all enemies.&lt;br /&gt;
|-&lt;br /&gt;
| GameAudio || N/A&lt;br /&gt;
|-&lt;br /&gt;
| Gravity || Library for all of the gravity types in the game.&lt;br /&gt;
|-&lt;br /&gt;
| LiveActor || Library for LiveActor, which is an actor that can switch states.&lt;br /&gt;
|-&lt;br /&gt;
| Map || Library for map classes that do not directly interact with the player. (ie switches)&lt;br /&gt;
|-&lt;br /&gt;
| MapObj || Library for all of the map objects in the game.&lt;br /&gt;
|-&lt;br /&gt;
| NameObj || Library for the most basic form of an object in the game.&lt;br /&gt;
|-&lt;br /&gt;
| NPC || Library for all of the non-playable characters.&lt;br /&gt;
|-&lt;br /&gt;
| NWC24 || Library for the mail system in the game.&lt;br /&gt;
|-&lt;br /&gt;
| Player || Library for all of the player related functions.&lt;br /&gt;
|-&lt;br /&gt;
| RhythmLib || N/A&lt;br /&gt;
|-&lt;br /&gt;
| Ride || Library for all of the actors that can be controlled by the player.&lt;br /&gt;
|-&lt;br /&gt;
| Scene || Library for all of the game scene related code.&lt;br /&gt;
|-&lt;br /&gt;
| Screen || Library for all of the layouts in the game.&lt;br /&gt;
|-&lt;br /&gt;
| Speaker || Library for the sound effect playing done on the Wiimote.&lt;br /&gt;
|-&lt;br /&gt;
| System || Library for a lot of the game&#039;s backend systems.&lt;br /&gt;
|-&lt;br /&gt;
| Util || Library for utility functions and classes.&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Shibboleet</name></author>
	</entry>
</feed>