Pages: 1
Posted on 05-31-12, 08:00 pm (rev. 5 by  Arisotura on 06-03-12, 08:20 pm)
☭ coffee and cream


Karma: 10398
Posts: 338/2766
Since: 06-26-11
I figured I'd post my findings somewhere, as well as what is already known, so that it doesn't get lost, and if other people are interested in SMG hacking, they can do stuff too.

Disclaimer: I haven't looked into SMG2 yet, so parts of this information may be wrong or irrelevant for SMG2. However the base structure is mostly the same.

Exsiting documentation
* Yaz0 compression (author unknown)
* RARC (.arc) format (groepaz/hitmen)
* BCSV info (Treeki)
* More on BCSV (Treeki)
* BMD (3D model) file format (thakis) (note: bmdview2's source code will give you more info)
* Some info about the Gamecube/Wii GPU (texgen and TEV) (thakis)

How to calculate BCSV field name hashes
        public static uint FieldNameToHash(string field)
        {
            uint ret = 0;
            foreach (char ch in field)
            {
                ret *= 0x1F;
                ret += ch;
            }
            return ret;
        }

Extracted from Anarchy in the Galaxy. Very simple hash function that is also very prone to collisions.

How to find strings matching the field name hashes in BCSV files
* Guess what the field could be, calculate the hash of a potential name and see if it matches. Sometimes it works but sometimes not.
* Open SMG's binary (main.dol) in a hex editor and look for already known names. There may be some of the names you're looking for near them.
* Disassemble SMG's binary, find the function used for calculating name hashes and find all the references to it. May take a while, SMG's code must be huge and very complex. That, and IDA doesn't like that code at all (keeps glitching and crashing). And most importantly, I know nothing about PPC assembly.
* Try all the possible strings until you find one that matches. But like any bruteforce attack, this can take long. Also, since the hash function is very prone to collisions, you may find a nonsense name.

Documentation that would be interesting
* Wii discs' filesystem format. Wiibrew describes the partition tables but doesn't go much further. And since the filesystems are in encrypted regions, reverse-engineering isn't easy.

ISO archive structure
All the interesting files are stored on partition 1 of the disc (on Wii discs, partition 0 is typically used for system updates).

Interesting subdirectories:
* AudioRes: contains musics and sound effects
* Eu[language]: contains message data
* LayoutData: contains graphics for the HUD displays (power gauge, coin counts, etc...)
* MovieData: contains the movies
* ObjectData: contains graphics for all the game's visible objects, including the planets
* ParticleData: contains one file (Effect.arc). Presumably used for particles
* StageData: contains data for all the stages and their zones. Namely, which stars are possible, which zones and objects will be loaded for each star, etc...

StageData structure
(note: in SMG1, all the directory/file names inside archives are lowercase)

There is one .arc file for each zone, and one subdirectory for each stage. Each stage's subdir contains a .arc layed out as such:

/StageData/[stagename]/[stagename]Scenario.arc
* Scenario
    * ScenarioData.bcsv
    * ZoneList.bcsv

ZoneList.bcsv has one field (ZoneName). It just tells which zones the stage will use.

ScenarioData.bcsv contains info about the possible stars for the stage. It contains the following fields:
* ScenarioNo: scenario ID (basically, a scenario corresponds to a possible star)
* ScenarioName: name of the scenario in Japanese (not used by the game)
* PowerStarId: bitmask corresponding to power stars' IDs. Apparently tells which ones may terminate the scenario, or something... (bit0=star 1, bit1=star 2...)
* AppearPowerStarObj: another Japanese string
* Comet: tells if the star is attached to a comet: empty string or Dark/Purple/Quick/Red/Black (Dark=Daredevil, Black=Shadow, Quick=Fast Foe, Red=Speedy, Purple=Purple)
* LuigiModeTimer: idk what this is about, iirc Luigi is mostly the same as Mario, there's no such timer
* [zone layermask fields]*
* IsHidden: tells if the star for this scenario is hidden or not
* [D6C80400]: dunno what this is. It is always 1 except in FileSelect's scenario data. Oh by the way the name is a hex number because I haven't found the string for that hash.

*[zone layermask fields]: for each zone in the stage, there is one field whose name is the zone's name. The values for those fields are bitmasks that tell which layers of the zone will be loaded along with the Common layer (bit0=LayerA, bit1=LayerB...).

Scenario IDs
Regular galaxy:
* 1: normal star #1
* 2: normal star #2
* 3: normal star #3
* 4: comet star #1
* 5: comet star #2
* 6: hidden star
* 7: hidden green star

AstroDome:
* 1: Terrace dome
* 2: Fountain dome
* 3: Kitchen dome
* 4: Bedroom dome
* 5: Engine Room dome
* 6: Garden dome

AstroGalaxy:
* 1: Observatory at beginning (0 grand star)
* 2: Observatory with 2 grand stars
* 3: Observatory with 4 grand stars
* 4: Observatory with 6 grand stars
* 5: Observatory after final fight (7 grand stars)

* not finished *
_________________________
Kuribo64 - RH-fucking-cafe - Kafuka

zrghij
Pages: 1