Points of Required Attention™
Please chime in on a proposed restructuring of the ROM hacking sections.
Views: 88,480,353
Main | FAQ | Uploader | IRC chat | Radio | Memberlist | Active users | Latest posts | Calendar | Stats | Online users | Search 04-25-24 05:46 AM
Guest: Register | Login

0 users currently in ROM Hacking | 2 guests

Main - ROM Hacking - Super Mario 64 notes New thread | New reply


Cellar Dweller
Posted on 05-29-08 09:25 AM Link | Quote | ID: 84361


Snifit
Level: 39

Posts: 114/287
EXP: 385149
Next: 19622

Since: 02-19-07
From: Arkansas

Last post: 4050 days
Last view: 3218 days
I'm posting a bunch of my SM64 notes in the hopes that somebody will find them useful. Most of the files are disassembled code annotated with equivalent pseudo C. There are some files that contain lists of commands or descriptions of structure formats.

Feel free to ask for explanations of terse or obscure notes, or share what you have found. Do not expect me to help with a specific problem you are having with a hack, and do not ask for help with TT64.

URL to download the notes: http://desktop64.homeip.net:8086/sm64notes_20080529.tar.gz

messiaen
Posted on 05-29-08 07:16 PM (rev. 3 of 05-29-08 07:43 PM) Link | Quote | ID: 84376


Cheep-cheep
Level: 32

Posts: 3/193
EXP: 204430
Next: 2012

Since: 05-26-08
From: Porto Alegre, Brazil

Last post: 4442 days
Last view: 4770 days
Wow, that is very nice! Here is my little contribuition regarding behaviour commands:

0x32 - Scales polygon and collision data (at least when a 0x2A pointer is present)

[0] = Command byte
[1] = Always zero
[2,3] = Scaling factor

0x23 - Sets a collision sphere

[0] = Command byte.
[1,2,3] = Always zero, unused?
[4] = 00 or 01 (?)
[5,6,7]= Some kind of coordinates?

For the collision sphere to work, you need to set these two indexes with the 0x10 command:

0x05 - Necessary to "turn on" the collision sphere (10 05 00 00)

0x2A - Type of interaction (ex: 10 2A 00 02)
Values: 02 = grab,
04 = door
40 = climb object

There are others 0x2A values but I haven't looked at those.

If you with to test/experiment with behaviors, use this as a guide.

blackhole89
Posted on 05-29-08 09:08 PM Link | Quote | ID: 84389


The Guardian
Moloch whose eyes are a thousand blind windows!
Level: 124

Posts: 1691/4196
EXP: 21530859
Next: 305742

Since: 02-19-07
From: Ithaca, NY, US

Last post: 470 days
Last view: 83 days



Posted by messiaen
If you with to test/experiment with behaviors, use this as a guide.

"This page is temporarily unavailable.
The data transfer limit has been exceeded due to high traffic. If you own this page, go to Account Settings and click Details to learn more."

Can you put it on the uploader?

____________________



messiaen
Posted on 05-29-08 09:42 PM Link | Quote | ID: 84394


Cheep-cheep
Level: 32

Posts: 4/193
EXP: 204430
Next: 2012

Since: 05-26-08
From: Porto Alegre, Brazil

Last post: 4442 days
Last view: 4770 days
CellarDweller already did. Here is the link.

You can hove lots of fun by swapping and adding 0x0C calls. Here is one example of a simple behavior edit. The same behavior with a experimental fixed camera. I'm trying to get a simple Isometric Mario level .

And to save you some time, you can edit the behaviors directly from the RAM. The behavior bank begins at 0xEB180, and after you change something you have to exit the level before the changes have effect.

Cellar Dweller
Posted on 05-29-08 09:51 PM (rev. 2 of 05-29-08 11:46 PM) Link | Quote | ID: 84397


Snifit
Level: 39

Posts: 115/287
EXP: 385149
Next: 19622

Since: 02-19-07
From: Arkansas

Last post: 4050 days
Last view: 3218 days
I already have that doc. In fact, I ran Perl scripts that took that file as input to generate little repots. For example, there is a list of command numbers that are sorted by frequency at the bottom of behavior_commands.txt that was generated by a Perl script. I used it to prioritize the behavior commands for disassembly.

Here are two download links. One hosted on my DSL line and one on the Board2 uploader. The line endings have been changed from the original because Perl didn't like them.
http://desktop64.homeip.net:8086/SM64Behaviors.txt
http://acmlm.no-ip.org/uploader/get.php?id=143

(I see that messiaen posted after I had this post mostly done)

EDIT: The proper grouping of the bytes of the 0x23 command are:
23 xx xx xx [xx xx] [xx xx]
[4,5] 16 bit integer
[6,7] 16 bit integer
Both are converted to floating point values and stored at offsets 0x1f8 and 0x1fc in the object structure(see proc0x8038528c_behavior_command_0x23_set_twofloats_w_16b.txt). If these values are not set, the default values are 50.0 and 100.0 decimal(see proc0x802c9c00_init_object_struct.txt). This command is equivalent to two 0x0e commands:
0e 5c [xx xx] 0e 5d [xx xx]

Cellar Dweller
Posted on 05-31-08 08:42 AM Link | Quote | ID: 84484


Snifit
Level: 39

Posts: 116/287
EXP: 385149
Next: 19622

Since: 02-19-07
From: Arkansas

Last post: 4050 days
Last view: 3218 days
I have just documented two behavior commands that are used to loop a number of times:

05 xx [xx xx]
Saves the current interpreter pointer to the stack followed a constant. This command is used with the 0x06 command to form a loop.
[2,3] converted to a 32 bit value and saved on the stack (number of times to loop)

06 xx xx xx
Decrements the value on the top of the stack. If the result is zero, pop the two top values off the top of the stack, else jump to the value one element from the top of the stack. This command also yields. This command is used to form loops with the 0x05 command.




The animation pointers set with the 0x27 command (index 0x26) point to an array of segmented pointers. The 0x28 command picks out a segmented pointer from the current object's array, converts it to a RAM pointer, and sets it in the object structure. In other words, it appears that the 0x28 command is used to set the current pose.

28 [xx] xx xx
(Set current pose?)
[1 ] (pose number?)

messiaen
Posted on 05-31-08 12:02 PM (rev. 2 of 05-31-08 12:29 PM) Link | Quote | ID: 84485


Cheep-cheep
Level: 32

Posts: 5/193
EXP: 204430
Next: 2012

Since: 05-26-08
From: Porto Alegre, Brazil

Last post: 4442 days
Last view: 4770 days
Again, these are nice discoveries! Upon changing/removing some 0x28 commands a few days ago, I noticed that the Bob-omb animations became glitched. Not only that, but when they exploded they would "respawn" at their initial point.

By the way, do you know know much data can be stored in each RAM segment using the 0x17 and 0x18 commands ? Also, is there a fixed point in memory to start loading each RAM segment? What is the relevant file here, segment_functions.txt ?

Cellar Dweller
Posted on 05-31-08 12:55 PM Link | Quote | ID: 84487


Snifit
Level: 39

Posts: 117/287
EXP: 385149
Next: 19622

Since: 02-19-07
From: Arkansas

Last post: 4050 days
Last view: 3218 days
The blocks of data loaded by the level scripts are allocated from a shared pool of about 1.4MiB. Therefore the RAM addresses that the segments start at can vary. If you are looking for the start of the segments in an emulator memory viewer, the location of the segment table is 0x8033b400 (as described by generalnotes.txt and segment_functions.txt). Note that the table contains physical addresses, so you will need to add 0x80000000 to get the address that the N64 CPU uses.

messiaen
Posted on 07-19-08 01:42 AM Link | Quote | ID: 87666


Cheep-cheep
Level: 32

Posts: 13/193
EXP: 204430
Next: 2012

Since: 05-26-08
From: Porto Alegre, Brazil

Last post: 4442 days
Last view: 4770 days
from struct_object.txt :

/* 4 @ 0x194 - another floating point value if unset, default is 1000.0 (solidity related?)*/

This is probably the disappear(drawing?) distance of the solidity triangles pointed by the 0x2A command. In my experimental levels, I set in some objects a maximum value with the 0x0E command (ie, 0E 43 4B FF) to get the collision loaded all the time, so that enemies can walk on it. However, it slow downs the game if overused (unless the collision data loaded is VERY simple).

Behavior command 0x34 is related to a very simple type of animation used by some objects (ie, the flames which use the Burning behavior 0x0C84).

Cellar Dweller
Posted on 07-28-08 06:08 AM Link | Quote | ID: 88132


Snifit
Level: 39

Posts: 134/287
EXP: 385149
Next: 19622

Since: 02-19-07
From: Arkansas

Last post: 4050 days
Last view: 3218 days
Due to my computer being out for several weeks the download link has not been working and because the file is on the hard disk of the same computer, I have not been able to rehost it. Here is a download link to use until I get the network set back up the way I want it:

sm64notes_20080529.tar.gz

messiaen
Posted on 08-08-08 03:32 PM Link | Quote | ID: 88700


Cheep-cheep
Level: 32

Posts: 25/193
EXP: 204430
Next: 2012

Since: 05-26-08
From: Porto Alegre, Brazil

Last post: 4442 days
Last view: 4770 days
Some of my notes on the on the sequenced music format. I've been working on it just for a few days, but there's some interesing data here, enough to make some minor music changes.

Basic pitch table:


Octave || Note Numbers
# || C | C# | D | D# | E | F | F# | G | G# | A | A# | B
------------------------------------------------------------------------------
x-1 || 1B | 1C | 1D | 1E | 1F | 20 | 21 | 22 | 23 | 24 | 25 | 26
x || 27 | 28 | 29 | 2A | 2B | 2C | 2D | 2E | 2F | 30 | 31 | 32
x+1 || 33 | 34 | 35 | 36 | 37 | 38 | 39 | 3A | 3B | 3C | 3D | 3E


When this table is used, here is the format:

{58} 85 [22] (18) # eight-note G

{} = Velocity
Second byte = Not really sure, but something like ticks before NoteOff.
[] = Pitch (normal table)
() = Duration (18 = eight-note, 30 = quarter-note, 60 = half-note, 20 = triplets, all simple proportions) [delta-tick?]

This alternate note table is also used. It's basically the same plus 80 (hex), so it sets some kind of flag:


Octave || Note Numbers
# || C | C# | D | D# | E | F | F# | G | G# | A | A# | B
------------------------------------------------------------------------------
x-1 || 9B | 9C | 9D | 9E | 9F | A0 | A1 | A2 | A3 | A4 | A5 | A6
x || A7 | A8 | A9 | AA | AB | AC | AD | AE | AF | B0 | B1 | B2
x+1 || B3 | B4 | B5 | B6 | B7 | B8 | B9 | BA | BB | BC | BD | BE


When this alternate table is used, we have 3 bytes instead of 4. "Duration" is omitted (it uses the last parameter supplied). Excerpt:

{64} 40 [24] (60) # half-note A (normal pitch table)
{5C} C8 [26] (20) # triplet B

{64} *40* ~AC~ triplet F # Begins alternate, 3 byte format. Duration = triplet 20 (last one supplied)
{5E} *88* ~AC~ # triplet F
{62} *90* ~AC~ # triplet F
{5C} *50* ~AB~ # triplet E
{5E} *60* ~A9~ # triplet D
{64} *58* [27] (80) C

~xx~ = alternate pitch table

And here is one VERY important thing, the *JUMP* command, which is also used for Loops!

[FC] [1B EE]

[00] = Jump
[01, 02] = Jumps to offset 0x1BEE, counting from the begginning of the sequence.

The "FF" character to indicate when to jump back. Here is one loop example using this command:

FC 1B EE # Jump to 0x1BEE (0x00 = 7B4080,start of track). Return when ch = FF.
FC 1B F9 # Jump to 0x1BF9
FC 1B EE # Again (Manual Loop)
FC 1B F9
FC 1B EE # Again (Manual Loop)
FC 1B F9

----

PS: I'm clueless how to make that pitch table look better here. "code" and "pre" didn't worked very well.

messiaen
Posted on 08-29-08 01:44 PM Link | Quote | ID: 89617


Cheep-cheep
Level: 32

Posts: 37/193
EXP: 204430
Next: 2012

Since: 05-26-08
From: Porto Alegre, Brazil

Last post: 4442 days
Last view: 4770 days
Hi Cellar Dweller, I was going through some of your notes and had this idea of using some unused bytes in the "RAM objects" struct to get rid of some hardcoded pointers.

Fir instance, here is the original code that loads Koopa's trajectory for Bob-omb Battlefield:

802FCDF0: LUI A0, 0x8033 # A0 = 0x80330000
[...]
802FCDFC: ADDU A0, A0, T6 # This doesn't seems to do anything because T6 = 0
802FCE00: JAL 0x80277F50 # Probably some segmented memory function
802FCE04: LW A0, 0x2864 (A0) # Delay slot: Load word from 0x80332864 (in ROM, 0xED864) [Koopa trajectory pointer]

And here is a possible replacement:

802FCDF0: LUI A0, 0x8036 # A0 = 0x80360000
[...]
802FCDFC: LW A0, 0x1160 (A0) # Get pointer for RAM object to A0.
802FCE00: JAL 0x80277F50
802FCE04: LW A0, 0x0180 (A0) # Load Koopa's path pointer from offset 0x180 of RAM object.

According to your object_struct.txt, 0x180 usually doesn't have a specific purpose (but of course of must be used by some objects) so I used it to hold a flexible pointer which is set by the behavior:

[27] [3E] 00 00 [07 01 16 A0]

3E = index for offset 0x180

This seems to be an interesting way to get rid of some hardcoded pointers by using unused space in the object struct.

Levesque
Posted on 08-30-08 01:13 AM Link | Quote | ID: 89638


Red Cheep-cheep
Account taken over, please contact admins to reclaim
Level: 34

Posts: 46/217
EXP: 242678
Next: 10973

Since: 07-14-08

Last post: 3029 days
Last view: 3029 days
Thanks for these guys, I'm gunna use these to tinker with SM64 when I get my new PC.

messiaen
Posted on 09-05-08 05:52 PM (rev. 2 of 09-05-08 05:53 PM) Link | Quote | ID: 89908


Cheep-cheep
Level: 32

Posts: 39/193
EXP: 204430
Next: 2012

Since: 05-26-08
From: Porto Alegre, Brazil

Last post: 4442 days
Last view: 4770 days
Here is something I tried yesterday and seems to be potentially very useful.

Looking through Cellar Dweller's Notes, I saw that some behavior commands are unused. So, I replaced the code of the 0x12 command with a modified version of the 0x0C (simple JAL) command. However, this new command can jump to data inside one of the level banks using the segmented_to_virtual (0x80277f50) function, which returns the virtual memory address of a segmented pointer.

Sample usage:

12 00 00 00 07 01 16 A0 # Address must be word aligned (multiple of 4)

Here is the important part of the 0x0C Behavior script command:

80384688: LW T7, 0x0004 (T6) # Load argument from 0x0C command
8038468C: SW T7, 0x001C (SP) # Store in Stack
80384690: LW T9, 0x001C (SP) # Copy to T9
80384694: JALR RA, T9 # JAL to Register T9
80384698: NOP # Delay Slot

And the modified version I used in the 0x12 command:

80384E20: JAL 0x80277F50 # Segmented to Virtual function
80384E24: LW A0, 0x001C (SP) # Pass segmented pointer to function
80384E28: SW V0, 0x001C (SP) # Save in stack
80384E2C: JALR RA, V0 # JAL to Register V0 [V0 = return value from segmented_to_virtual]
80384E30: NOP # Delay Slot

I tried inserting a JR RA / NOP somewhere in a level 'bank' and calling it through this command and it seemed to work ok, so I think this could be an interesting solution.

messiaen
Posted on 10-12-08 08:13 PM Link | Quote | ID: 92149


Cheep-cheep
Level: 32

Posts: 59/193
EXP: 204430
Next: 2012

Since: 05-26-08
From: Porto Alegre, Brazil

Last post: 4442 days
Last view: 4770 days
I have set a site with my notes on Mario 64 hacking. I'm a begginer in both C and MIPS so except some errors but there's lot of useful stuff there.

One thing I'm working is extending script functionality, here are two very useful new commands:

0x10 Level Command: Loads a block of ROM data into extended memory and updates segment table - this one is an hybrid 0x16/0x17 command, and the main purpose is to load segmented data into extended memory, to overcome memory limitations.

Flexible Collision Behavior command (0x12) - this behavior script command detects the model ID used by an object and assigns the right collision pointer from a pointer list in the ROM.

Main - ROM Hacking - Super Mario 64 notes New thread | New reply

Acmlmboard 2.1+4δ (2023-01-15)
© 2005-2023 Acmlm, blackhole89, Xkeeper et al.

Page rendered in 0.024 seconds. (339KB of memory used)
MySQL - queries: 102, rows: 136/137, time: 0.015 seconds.