Jump to content

SoD's OoT 1.0 (U) Notes


SoulofDeity
 Share

Recommended Posts

here's a better version of the above code, a fully controllable sequence player :D

 

source:

 

 

.org 0x80170000_start:   li t0, 0x801C84B4   lb t1, 0x0000 (t0)   li t0, var   lb t2, 0x0000 (t0)   bne t1, t2, checkKeys   sb t1, 0x0000 (t0)ret:   jr ra   nopcheckKeys:   lh a1, 0x0002 (t0)   li t2, 0x8011A604   sh a1, 0x0000 (t2)   li t2, 0x00000001checkRight:   bne t1, t2, checkLeft   addiu t2, t2, 0x0001   li t2, 0x0000006C   bne a1, t2, incSeq   addiu a1, a1, 0x0001incSeq:   jr ra   sh a1, 0x0002 (t0)checkLeft:   bne t1, t2, checkDown   addiu t2, t2, 0x0002   bne a1, r0, decSeq   addiu a1, a1, 0xFFFFdecSeq:   jr ra   sh a1, 0x0002 (t0)checkDown:   bne t1, t2, checkUp   addiu t2, t2, 0x0004   j 0x800C6B54   lui a1, 0x0000checkUp:   bne t1, t2, ret   nop   j 0x800C6B54   nopvar:.org 0x80003BD4hook:   j _start   nop

 

 

 

 

assembled code:

 

 

81170000 3C0881170002 801C81170004 350881170006 84B481170008 81098117000A 00008117000C 3C088117000E 801781170010 350881170012 009081170014 810A81170016 000081170018 15498117001A 00038117001C A1098117001E 000081170020 03E081170022 000881170024 000081170026 000081170028 85058117002A 00028117002C 3C0A8117002E 801181170030 354A81170032 A60481170034 A54581170036 000081170038 340A8117003A 00018117003C 15498117003E 000681170040 254A81170042 000181170044 340A81170046 006C81170048 15458117004A 00018117004C 24A58117004E 000181170050 03E081170052 000881170054 A50581170056 000281170058 15498117005A 00058117005C 254A8117005E 000281170060 140581170062 000181170064 24A581170066 FFFF81170068 03E08117006A 00088117006C A5058117006E 000281170070 154981170072 000381170074 254A81170076 000481170078 08038117007A 1AD58117007C 3C058117007E 000081170080 154981170082 FFE781170084 000081170086 000081170088 08038117008A 1AD58117008C 00008117008E 000081003BD4 080581003BD6 C00081003BD8 000081003BDA 0000 

 

 

nemu64 cheat file:

 

 

[THE LEGEND OF ZELDA.Cheats]NumCheats=1CheatName0=Play SequenceCheatName0Count=76CheatName0Code0=81170000 3C08CheatName0Code1=81170002 801CCheatName0Code2=81170004 3508CheatName0Code3=81170006 84B4CheatName0Code4=81170008 8109CheatName0Code5=8117000A 0000CheatName0Code6=8117000C 3C08CheatName0Code7=8117000E 8017CheatName0Code8=81170010 3508CheatName0Code9=81170012 0090CheatName0Code10=81170014 810ACheatName0Code11=81170016 0000CheatName0Code12=81170018 1549CheatName0Code13=8117001A 0003CheatName0Code14=8117001C A109CheatName0Code15=8117001E 0000CheatName0Code16=81170020 03E0CheatName0Code17=81170022 0008CheatName0Code18=81170024 0000CheatName0Code19=81170026 0000CheatName0Code20=81170028 8505CheatName0Code21=8117002A 0002CheatName0Code22=8117002C 3C0ACheatName0Code23=8117002E 8011CheatName0Code24=81170030 354ACheatName0Code25=81170032 A604CheatName0Code26=81170034 A545CheatName0Code27=81170036 0000CheatName0Code28=81170038 340ACheatName0Code29=8117003A 0001CheatName0Code30=8117003C 1549CheatName0Code31=8117003E 0006CheatName0Code32=81170040 254ACheatName0Code33=81170042 0001CheatName0Code34=81170044 340ACheatName0Code35=81170046 006CCheatName0Code36=81170048 1545CheatName0Code37=8117004A 0001CheatName0Code38=8117004C 24A5CheatName0Code39=8117004E 0001CheatName0Code40=81170050 03E0CheatName0Code41=81170052 0008CheatName0Code42=81170054 A505CheatName0Code43=81170056 0002CheatName0Code44=81170058 1549CheatName0Code45=8117005A 0005CheatName0Code46=8117005C 254ACheatName0Code47=8117005E 0002CheatName0Code48=81170060 1405CheatName0Code49=81170062 0001CheatName0Code50=81170064 24A5CheatName0Code51=81170066 FFFFCheatName0Code52=81170068 03E0CheatName0Code53=8117006A 0008CheatName0Code54=8117006C A505CheatName0Code55=8117006E 0002CheatName0Code56=81170070 1549CheatName0Code57=81170072 0003CheatName0Code58=81170074 254ACheatName0Code59=81170076 0004CheatName0Code60=81170078 0803CheatName0Code61=8117007A 1AD5CheatName0Code62=8117007C 3C05CheatName0Code63=8117007E 0000CheatName0Code64=81170080 1549CheatName0Code65=81170082 FFE7CheatName0Code66=81170084 0000CheatName0Code67=81170086 0000CheatName0Code68=81170088 0803CheatName0Code69=8117008A 1AD5CheatName0Code70=8117008C 0000CheatName0Code71=8117008E 0000CheatName0Code72=81003BD4 0805CheatName0Code73=81003BD6 C000CheatName0Code74=81003BD8 0000CheatName0Code75=81003BDA 0000 

 

 

Usage:

  • The current sequence number is displayed where link's rupees are

  • Press D-Left to decrement the sequence number

  • Press D-Right to increment the sequence number

  • Press D-Up to play the sequence

  • Press D-Down to stop the current sequence

  • Like 1
Link to comment
Share on other sites

Tried this with V1.0 on PJ64

Can't get the first code to play any song other than the intro.

Can't get the second code to play anything. Also the rupee counter increments are odd.

 

Edit: Got the first code to work by resetting the emulator.

Link to comment
Share on other sites

Tried this with V1.0 on PJ64Can't get the first code to play any song other than the intro.Can't get the second code to play anything. Also the rupee counter increments are odd.Edit: Got the first code to work by resetting the emulator.

yeah, I figured it probably wouldn't work on the PJ64 since it's assembly mod and the dynarec needs to be reset. it works in the nemu64 tho. if you want, I can make a rom patch for it

Link to comment
Share on other sites

Did some maths and some smart hex viewing and I think I managed to find the pointer table used by the 0x3E8 cutscene command that points to asm that (among other things) sets up which cutscene to play next after a cutscene is done.It's located at B7D2C8 in rom. This was found using Zelda's Courtyard CS #1 (Zelda's Lullaby) which refers to offset 33h, which is B7D394. B7D394 contains the pointer value 80053BE8 which in turn should point to some asm that sets an entrance index of 00CD and a cutscene of FFF8 

Exits:000003E8 00000001 xxxx yyyy zzzz zzzz?x = index for a list of pointers that points to the machine code. The code at these addresses sets the exit number/cutscene to usey = start framez = end frame (seems to be repeated)

Edit: 8005 3350h is the ram offset to the asm code that determines where to place you when pulling the master sword (regardless of whether it was the first or n'th time). That converts to AC91B0 Rom.Change what entrance/cutscene plays when pulling the Master Sword the first time:AC91DA: Entrance Index. Default is 00A0AC91F2: Cutscene number. Default is FFF3Change what entrance to use when pulling the Master Sword after the first timeAC9212: Entrance index. Default is 02CA
Link to comment
Share on other sites

In ovl_player_actor: Change what entrance index/cutscene plays after opening a chest with the Silver Gauntlets inside:

 

Edit: Thanks to Three_Pendants for the chest? check

 

BE9BDE: Check against what item was within the chest to see if the cutscene should play (set to 0035)

 

BE9BE2: Entrance Index (set to 0123)

BE9BEE: Cutscene (set to FFF1 for cutscene 1)

Link to comment
Share on other sites

I figured out everything about the on entrance cutscene table.

$000DEC64 cutscene table Entry Format: ${ee ee aa ff oo oo oo oo}

e = entrance index

a = age to play cutscene (0 for adult only, 1 for child only, 2 for both)

f = event flags (pattern is 00-07 sets 0ED5, 08-0F sets 0ED4, 10-17 sets 0ED7, 18-1F sets 0ED6, etc.

o = pointer to cutscene

Link to comment
Share on other sites

  • 2 months later...

Someone requested a clipping code from me and I didn't have it written down so I had to kinda re-find it.

$801DB0B2		// player state%10000000		// lock player state%00001000		// disable jump attack%00000100		// disable player animation / movement updating%00000010		// disable jumping%00000001		// disable map collisionWARNING:  You must manually change these back to 0 to undo them, so like if          you disable map collision, you cannot touch the ground again until          you reset it to 0.Hold Z To Lock Player State-----------------------------------------D01C84B4 0000801DB0B2 0000D01C84B4 0020801DB0B2 0080Hold Z to Lock Player Animation, Speed, and Direction-----------------------------------------D01C84B4 0000801DB0B2 0000D01C84B4 0020801DB0B2 0004Press Z To Disable Collision (walk through walls and floors)-----------------------------------------D01C84B4 0000801DB0B2 0000D01C84B4 0020801DB0B2 0001Disable Jumping-----------------------------------------801DB0B2 0002Disable Jump Attack (Link will still hop and shout)-----------------------------------------801DB0B2 0008
  • Like 2
Link to comment
Share on other sites

So I realized I never documented this when I was helping someone on skype, so I came back to post it.

 

 

RECAP

==================================================

As said in a couple of my older posts, the 0xFC GBI instruction sets the combiner mode. where the equation is:

(a -  * c + d;
The substituted arguments encoded into 0xFC:

 a0,  b0,  c0,  d0 = color mode 1Aa0, Ab0, Ac0, Ad0 = alpha mode 1 a1,  b1,  c1,  d1 = color mode 2Aa1, Ab1, Ac1, Ad1 = alpha mode 2
color mode 2 should always be set to the same as color mode 1 otherwise 2-cycle rendering happens.

the most common blending mode in 3d rendering is 1-srcAlpha; (because the alpha channel actually represents opacity and this converts opacity to alpha;  eg. opacity of 0.25,  1.0 - 0.25 =  alpha of 0.75).

 

the alpha mode for this would be:

(1 - TEXEL0) * 1 + 0
which is

Aa0  = 6Ab0  = 1Ac0  = 6Ad0  = 7
An additional note, K5 should be used in place of 0 when specifying the a0 or b0 fields of the color mode because the fields are 4-bit.

 

 

 

THE COOL STUFF

==================================================

The F3DZEX microde makes use of 3 tiles:  0, 1, and 7.  Tile 0 is the main texture, tile 1 is the subtexture, and tile 7 is used to copy data into TMEM with F0 (for palettes) or F3 (for textures). Knowing this and the information in the recap above, multi-texturing is actually not hard at all. First, load TEXEL0 (tile 0):

FD 90 00 00 02 00 22 60  ; set TIMG offset to 0x02002260F5 90 00 00 07 01 44 62  ; assign TIMG to tile 07 and assign it's propertiesE6 00 00 00 00 00 00 00  ; load syncF3 00 00 00 07 3F F1 00  ; copy tile 07 into TMEME7 00 00 00 00 00 00 00  ; pipe syncF5 88 10 00 00 01 44 62  ; assign TIMG to tile 00 and assign it's propertiesF2 00 00 00 00 0F C0 7C  ; set tile 00 size
next load TEXEL1 (tile 1):

FD 90 00 00 02 00 22 60   ; set TIMG offset to 0x02002260F5 90 00 00 07 01 40 61   ; assign TIMG to tile 07 and assign it's propertiesE6 00 00 00 00 00 00 00   ; load syncF3 00 00 00 07 3F F1 00   ; copy tile 07 into TMEME7 00 00 00 00 00 00 00   ; pipe syncF5 88 10 00 01 01 40 61   ; assign TIMG to tile 01 and assign it's propertiesF2 00 00 00 01 0F C0 7C   ; set tile 01 size
Then, assign a blending mode. For example, to multiply them together evenly:

(TEXEL0 - K5) * TEXEL1 + 0
...or to blend additively such as done for the grain of grass in the game:

(TEXEL1 - TEXEL0) * 1 + TEXEL0
However, if you wanted to use the second texture as an alpha mask, you could do:

color mode  =  (TEXEL0 - K5) * SHADE + PRIMITIVEalpha mode  =  (1 - TEXEL1) * 1 + 0
And don't go apeshit and start hyperventilating if your multi-texture combiner mode can't support shading or primitive colors. That's what the COMBINED argument and color/alpha mode 2 are for. (the COMBINED and COMBINED_ALPHA can only be used color mode 2 and are color and alpha output after mode 1 is processed)

 

 

To generate combiner instructions, you can use the source to a C program I wrote a while back called fcint.

 

 

Also, just for the sake of reference, loading a palette...

FD 10 00 00 02 00 78 60   ; set TIMG offset to 0x02002260E8 00 00 00 00 00 00 00   ; tile syncF5 00 01 F0 07 00 00 00   ; assign TIMG to tile 07 and assign it's propertiesE6 00 00 00 00 00 00 00   ; load syncF0 00 00 00 07 03 C0 00   ; copy tile 07 into TMEM  ((3C0 >> 6) + 1) == 16 colorsE7 00 00 00 00 00 00 00   ; pipe sync
EDIT

================================================

Just something interesting I found out, 0xDB MOVEWORD can be used to set the physical addresses for segments.

DB 06 00 18 80 17 00 00
Explanation:

[*]DB = MOVEWORD (or rather, write word) to an address specified in a table in dmem

[*]06 = index of the segment table offset in the address table

[*]0018 = offset to add to address (in this case, 4 * segment number because each address in the segment table is 4 bytes)

[*]80170000 = the 32-bit word to write at address[index]+offset

A heads up though, the game usually just uses assembly code to set segment offsets. There are only 6 MOVEMEM instructions in the entire game all located within 1 display list in the code file used to set segments 08, 09, 0A, 0B, 0C, and 0D to 0x80127098

  • Like 1
Link to comment
Share on other sites

  • 3 months later...

Since this thread has been ruined, imma fix r up

 

These are the notes I've been taking for OoT 1.0 (U), be it assembly hacking, rom poking, reverse engineering gameshark code, porting debug rom stuff, etc.

It still a work in progress, but I hope it helps some of you people out there who don't like working with the debug rom :P

Terms and Definitions
##########################################################################

* All hexadecimal values are big endian
* binary values are prefixed with %
     eg. %00000101 is binary for 5
* hexadecimal values are prefixed with $
     eg. $10 is 16
* decimal values either have no prefix or are prefixed with #
     eg. 5 or #5 is 5
* groups of bytes that are the same value types are surrounded
  by brackets with a type prefix.
     eg. %{00000000 00000010 00000101}	would be 3 binary values
         #{0, 1, 5}			would be 3 decimal values
         ${00 01 05}			would be 3 hexadecimal values

BYTE      = 1 byte   = 8 bits   =       $00 -       $FF
HALFWORD  = 2 bytes  = 16 bits  =     $0000 -     $FFFF
WORD      = 4 bytes  = 32 bits  = $00000000 - $FFFFFFFF

Segments
----------------------------------------------------------------
   $00 code			$01 code (same as $00)
   $02 current scene		$03 current map
   $04 gameplay keep		$05 field keep / dungeon keep
   $06 current object		$07 link animation
   $08 texture bank 1		$09 texture bank 2
   $0A ???			$0B ???
   $0C actor bank		$0D limb matrices
   $0E ???			$0F ???

ROM STUFF
##########################################################################

$00F03000 - $00F5ECE0	gameplay_keep.zdata
$00F5F000 - $00F6C330	gameplay_field_keep.zdata
$00F6D000 - $00F84AF0	gameplay_dangeon_keep.zdata
$00F86000 - $00FBD800	object_link_boy.zobj
$00FBE000 - $00FEAF80	object_link_child.zobj
$00A87000 - $00B8AD30	code.zasm

  Offset   Size  Description
----------------------------------------------------------------
   $00045E20   write the following data here to force game to check for
               all 6 medallions [UNTESTED:  PORTED FROM DBG ROM]
                      ${ 8E0200A4 3049003F 392A003F 1540001A }
                      ${ 00000000 00000000 00000000 00000000 }
   $00045F9E  2  $0000 = create normal files, $0001 = create 64dd files
                 [DO NOT USE. IT'S A BROKEN FUNCTION, WILL CRASH GAME]
   $0007F01A  2  default water temple water level
   $0007FBAE  2  intro custscene exit number
   $0007FBB3  2  start as $01=child link,  $00=adult link
   $0007FBBA  2  intro cutscene number  $FFF? or $0000 (no cutscene)
   $000D7184  4  navi normal color
   $000D7194  4  navi npc color
   $000D719C  4  navi enemy color
   $000D71A4  4  navi sign color
   $000D71AC  4  navi checkable color
   $000D71BC  4  navi boss color
   $000D7530     actor table
   $000DEC64     cutscene table
                 Entry Format:  ${ee ee ff ff oo oo oo oo}
                    e = entrance index
                    f = flags
                    o = pointer to cutscene

   $000E64DC  2  green rupee value
   $000E64DE  2  blue rupee value
   $000E64E0  2  red rupee value
   $000E64E2  2  purple rupee value
   $000E64E4  2  orange rupee value
   $000E6A38  3  kokiri tunic color
   $000E6A3B  3  goron tunic color
   $000E6A3E  3  zora tunic color
   $000E7C2E  2  small quiver capacity
   $000E7C30  2  medium quiver capacity
   $000E7C32  2  large quiver capacity
   $000E7C36  2  small bomb bag capacity
   $000E7C38  2  medium bomb bag capacity
   $000E7C3A  2  large bomb bag capacity
   $000E7C4C  2  child wallet capacity
   $000E7C4E  2  adult wallet capacity
   $000E7C50  2  giant wallet capacity
   $000E7C56  2  small deku seed bag capacity
   $000E7C58  2  medium deku seed bag capacity
   $000E7C5A  2  large deku seed bag capacity
   $000E7C5E  2  small deku stick capacity
   $000E7C60  2  medium deku stick capacity
   $000E7C62  2  large deku stick capacity
   $000E7C66  2  small deku nut capacity
   $000E7C68  2  medium deku nut capacity
   $000E7C6A  2  large deku nut capacity
   $000E7F58     object table
   $000EA440     scene table

$00BB11E0 - $00BCDB70	ovl_kaleido_scope.zactor
  Offset   Size  Description
----------------------------------------------------------------
   $000165B4     item selectable table
   $000165DC     item icon mode table

$00BCDB70 - $00BF40D0	ovl_player_actor.zactor
----------------------------------------------------------------
   $000004E0  4  link's voice changer. value is ${34 18 ?? ??}
         $0000 - $001F  adult link
         $0020 - $003F  young link with some adult link sounds
         $0043 - $004F  navi
         $0050 - $0053  talon
         $0054 - $0057  ingo
         $0058 - $0059  great fairy
         $005A - $0066  ruto with some navi sounds
         $0067 - $0068  cursed skulltalla person
         $0069 - $006E  young zelda
         $006F - $0074  shiek with some navi sounds
         $0075 - $0079  adult zelda
         $007A - $007A  king zora

   $00015C12  2  player state %{00000000 0000t0c0}
                    t - is z-targetting
                    c - is falling
                 if you enable t at the same time as c, link
                 swaps between falling and standing every frame,
                 which has the neat effect of letting you walk
                 through walls, and pressing 'z' will make you
                 fall through the floor.

   $00018A54  8  force link to be ${3C 0E 00 00 25 CE ?? ??}
         $0000 - adult    $0001 - child

$00DD1A00 - $00DD34B0	ovl_Obj_Oshihiki.zactor
  Offset   Size  Description
----------------------------------------------------------------

   $00001186  2  block pushing speed
   $000011CE  2  block pushing distance
   $00001326  2  block pushing delay

RAM STUFF
##########################################################################

Important Addresses
----------------------------------------------------------------
   $800110A0	code
   $8011A5D0	savedata
   $8011DC44	??? [possible memory pool for alloc]
   $80120C38	segment table

Functions
----------------------------------------------------------------
   $80003BCC	Used as a delay, called continously throughout
                the entire game. <HOOKABLE>
   $80002E80	DMA Transfer
		   Arguments:	a0=ramAddr, a1=romAddr, a2=size

Variables
----------------------------------------------------------------
; miscellaneous
$8005703C	create file type $0000 = normal		HALFWORD
                                 $0001 = 64DD
$800900BC	default waterlevel for water temple	HALFWORD

; savestate stuff
$8011A600	health (20*16)				HALFWORD
$8011A5FE	max health (20*16)			HALFWORD
$8011A605	number of rupees			HALFWORD
$8011A6A1	skulltulas killed			BYTE
$8011A699	number of small keys			BYTE

; item slots
$8011A644	item slot 0  (default:deku sticks)	BYTE
$8011A645	item slot 1  (default:deku nuts)	BYTE
$8011A646	item slot 2  (default:bombs)		BYTE
$8011A647	item slot 3  (default:fairy bow)	BYTE
$8011A648	item slot 4  (default:fire arrow)	BYTE
$8011A649	item slot 5  (default:din's fire)	BYTE
$8011A64A	item slot 6  (default:fairy slingshot)	BYTE
$8011A64B	item slot 7  (default:ocarina)		BYTE
$8011A64C	item slot 8  (default:bombchus)		BYTE
$8011A64D	item slot 9  (default:hookshot)		BYTE
$8011A64E	item slot 10 (default:ice arrow)	BYTE
$8011A64F	item slot 11 (default:farore's wind)	BYTE
$8011A650	item slot 12 (default:boomerang)	BYTE
$8011A651	item slot 13 (default:lens of truth)	BYTE
$8011A652	item slot 14 (default:magic beans)	BYTE
$8011A653	item slot 15 (default:megaton hammer)	BYTE
$8011A654	item slot 16 (default:light arrow)	BYTE
$8011A655	item slot 17 (default:nayru's love)	BYTE
$8011A656	item slot 18 (default:bottle 1)		BYTE
$8011A657	item slot 19 (default:bottle 2)		BYTE
$8011A658	item slot 20 (default:bottle 3)		BYTE
$8011A659	item slot 21 (default:bottle 4)		BYTE
$8011A65A	item slot 22 (default:adult trade item)	BYTE
$8011A65B	item slot 23 (default:child trade item)	BYTE

; ammmunition
$8011A65C	deku stick ammo				BYTE
$8011A65D	deku nut ammo				BYTE
$8011A65E	bomb ammo				BYTE
$8011A65F	arrow ammo				BYTE
$8011A662	slingshot ammo				BYTE
$8011A664	bombchu ammo				BYTE
$8011A66A	number of magic beans			BYTE

; controller
$801C84B4	control pad %{abzstgfh 00qwikjl}	HALFWORD
		   a = a button		b = b button
		   z = z trigger	s = start button
		   q = l trigger	w = r trigger
		   t = d-up button	g = d-down button
		   f = d-left button	h = d-right button
		   i = c-up button	k = c-down button
		   j = c-left button	l = c-right button

$801C84B6	analog stick x-axis			BYTE
$801C84B7	analog stick y-axis			BYTE

Item Slot Values
----------------------------------------------------------------

$00 deku sticks		$01 deku nuts		$02 bombs
$03 fairy bow		$04 fire arrow		$05 din's fire
$06 fairy slingshot	$07 fairy ocarina	$08 ocarina of time
$09 bombchus		$0A hookshot		$0B longshot
$0C ice arrow		$0D farore's wind	$0E boomerang
$0F lens of truth	$10 magic beans		$11 megaton hammer
$12 light arrow		$13 nayru's love	$14 empty bottle
$15 red potion		$16 green potion	$17 blue potion
$18 fairy		$19 fish		$1A full lon lon milk
$1B ruto's letter	$1C blue flame		$1D bugs
$1E big poe		$1F half lon lon milk	$20 poe
$21 weird egg		$22 chicken		$23 zelda's letter
$24 keaton mask		$25 skull mask		$26 spooky mask
$27 bunny hood		$28 goron mask		$29 zora mask
$2A gerudo mask		$2B mask of truth	$2C sold out
$2D pocket egg		$2E pocket cucco	$2F cojiro
$30 odd mushroom	$31 odd potion		$32 poacher saw
$33 broken goron sword	$34 prescription	$35 eyeball frog
$36 eye drops		$37 claim check		$38 powered fire arrow
$39 powered ice arrow	$3A powered light arrow	$3B kokiri sword
$3C master sword	$3D giant's knife	$3E deku shield
$3F hylian shield	$40 mirror shield	$41 kokiri tunic
$42 goron tunic		$43 zora tunic		$44 kokiri boots
$45 iron boots		$46 hover boots		$47 small bullet bag
$48 medium bullet bag	$49 large bullet bag	$4A small quiver
$4B medium quiver	$4C large quiver	$4D small bomb bag
$4E medium bomb bag	$4F large bomb bag	$50 goron bracelet
$51 silver gauntlets	$52 golden gauntlets	$53 silver scale
$54 golden scale	$55 broken giants knife	$56 adult wallet
$57 giant wallet	$58 deku seeds		$59 fishing rod

 

  • Like 2
Link to comment
Share on other sites

  • 2 months later...

a few more miscellaneous things

$01795300	160x160 rgba32		main logo
$017AEB00	192x192 i4		logo mask; a 3x3 grid of 64x64 tiles
   $017AEB00	64x64 i4		top-left of logo mask
   $017AF300	64x64 i4		top of logo mask
   $017AFB00	64x64 i4		top-right of logo mask
   $017B0300	64x64 i4		left of logo mask
   $017B0B00	64x64 i4		center of logo mask
   $017B1300	64x64 i4		right of logo mask
   $017B1B00	64x64 i4		bottom-left of logo mask
   $017B2300	64x64 i4		bottom of logo mask
   $017B2B00	64x64 i4		bottom-right of logo mask
$017B3700	72x8 i8			"the legend of"
$017B3940	96x8 i8			"ocarina of time"

Usage Tables:  00 = adult, 01 = child, 09 = both
::: NOTE :::
   slots != items and with the exception of the last 3 values values in
   the item usage table, they're all listed in the same order as their
   item value.

   $00BC7794	select item slot usage table
   $00BC77AC	equipment slot usage table
   $00BC77BC	item usage table
      $00BC77D0 bottled items
      $00BC77F7	swords
      $00BC77FA	shields
      $00BC77FD tunics
      $00BC7800	boots
      $00BC7803	deku seed bags
      $00BC7806	quivers
      $00BC7809	bomb bags
      $00BC780C	bracelets / gauntlets
      $00BC780F	scales


$00B67390	change to below to enable map select
	${00 00 00 00 00 B9 E4 00 00 BA 11 60 80 80 09 C0}
         {80 80 37 20 00 00 00 00 80 80 1C 14 80 80 1C 08}
here's some rips of the logo stuff I did in case people need it. (you probably will since Rice's plugin screws up the texture formatting a bit)

logowwu.png

 

NOTE: the below is actually 9 textures arranged in a 3x3 grid of 64x64 i4 textures!!!

logomasku.png

 

(and because some people prefer to use the debug rom)

logonjr.png

 

 

some extra notes the debug rom:

$017F7000	160x160 rgba32		main logo
$01817000	192x192 i4		logo mask; a 3x3 grid of 64x64 tiles
   $01817000	64x64 i4		top-left of logo mask
   $01817800	64x64 i4		top of logo mask
   $01818000	64x64 i4		top-right of logo mask
   $01818800	64x64 i4		left of logo mask
   $01819000	64x64 i4		center of logo mask
   $01819800	64x64 i4		right of logo mask
   $0181A000	64x64 i4		bottom-left of logo mask
   $0181A800	64x64 i4		bottom of logo mask
   $0181B000	64x64 i4		bottom-right of logo mask
$0181BC00	72x8 i8			"the legend of"
$0181BE40	96x8 i8			"ocarina of time"
--------------------------------

 

EDIT:

almost forgot, here's a patch for the 1.0 rom that enables file select. i did it because I was tired of having to retype it in every time I made a new nemu cheat file

 

  • Like 2
Link to comment
Share on other sites

  • 2 years later...

I've been doing a little research on how the game's physics work. I've been using the debug rom, but this information should translate over nonetheless...

 

In the debug rom RAM map, there are 2 functions called CheckCollision_setAT (@0x8005d79c) and CheckCollision_setOT (@0x8005dc4c). The second one (setOT) is called the most often. It seems to be used for all the collision in the game that should only require simple bounds checks; eg. whether or not you're walking into a bush, tree, sign, npc, or any other object.

 

The first one (setAT) seems to be used for all collision that would require complex collision checks that traverse an actor's joint hierarchy. It's used for sword swings, rolling, epona's feet, projectiles, explosions, and enemy attacks from what I can see so far.

 

They aren't called that often; maybe one per frame for setOT, so I think they might be called merely to set the location of the actor and object instance tables for the physics engine or something.

 

As far as motion is concerned, it's been documented that each actor instance has 3 position/rotation pairs. In a header for some custom actor examples in the old vg64tools svn trunk, I noticed that someone named one of the fields as 'acceleration'. From this, I have a reasonable hunch that the 3 position/rotation pairs are basically past/present/future transforms for an actor. The past transform should remain unchanged from the last iteration of the game loop. the future transform is where the actor should be in the next iteration. the current transform would be some kind of linear interpolation between the two that is calculated with respect to the game's physics. That is to say that actors basically can ignore the physics engine as long as the physics engine is aware of the simple and complex (hierarchical) collision data for the object.

 

As for the collision format itself, I've found quotes online that the Zelda64 engine is based on the Mario64 engine, which uses a fast sweeping ellipsoids algorithm; and there's a function in the game called 'ClObjJntSph_set3' (Collision Object - Joint Sphere?). While the game appears to never call this function, I think it gives a subtle clue that the complex hierarchical collision checking works on a joint-by-joint basis.

  • Like 2
Link to comment
Share on other sites

  • 4 weeks later...

I wasn't going to post this because I figured it'd be a waste of time, but I figured, why not.

 

 

 

The Zelda64 Overlay Format

 

The overlays in Zelda64 games are fairly simple object files. It's just a dump of the ".text" section, followed by a dump of the ".data" section, and then a dump of the ".rodata" section. Immediately after this, there's a small structure with the format:

struct
{
    uint32_t size_of_text_section_in_bytes;
    uint32_t size_of_data_section_in_bytes;
    uint32_t size_of_rodata_section_in_bytes;
    uint32_t size_of_bss_section_in_bytes;
    uint32_t number_of_relocations;
};

This is just common knowledge to people who are familiar with object files, but the ".text" section contains the code, the ".data" section contains data that's both readable and writable, the ".rodata" section contains data that's read-only, and the ".bss" section contains data that's initialized to 0 (hence the reason that there is no dump of the ".bss" section in the overlay file.

 

Immediately after this structure is the relocations themselves. Each relocation is a 32-bit value. The uppermost 4-bits is the section type:

enum
{
    TEXT_SECTION   = 0,
    DATA_SECTION   = 1,
    RODATA_SECTION = 2,
    BSS_SECTION    = 3
};

The next 4-bits is the relocation type. Each relocation type corresponds exactly to the MIPS relocation types of the ELF file format. As you can see, relocations are actually pretty simple to do. You just extract the operands, apply the calculation, and write the result back. That said, there are a lot of different relocation types, so if you want to fully support the linking and/or loading of object files, it's going to be a bit of a pain in the ass.

 

Immediately after all of the relocations, padding is added to the file such that it's 16-byte aligned minus 4-bytes; and there must be more than 0 bytes of padding. So if the file ends with:

00001000:  xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx
00001010:  xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx
00001020:  xx xx xx xx xx xx xx xx xx xx xx xx

Then you'll need to add 16 bytes of padding. Immediately after this padding is a 32-bit pointer to the structure that contains the section sizes and the number of relocations.

 

 

The Combiner Modes

 

The combiner is executed after the texturizing unit samples and filters texels from the tiles (which is also after the rasterizer generates fragments from the vertices). There are 2 types of combining: color combining, and alpha combining. Both use the equation "(A - B ) * C + D", but the operands that they accept differ. For the color combiner:

enum
{
    CC_A_COMBINED_COLOR    = 0,  // the combined color from cycle 1
    CC_A_TEXEL0_COLOR      = 1,  // the color of the texel for tile 0
    CC_A_TEXEL1_COLOR      = 2,  // the color of the texel for tile 1
    CC_A_PRIMITIVE_COLOR   = 3,  // the primitive color, set via the 0xFA SetPrimColor command
    CC_A_SHADE_COLOR       = 4,  // the shade (vertex) color
    CC_A_ENVIRONMENT_COLOR = 5,  // the environment color, set via the 0xFB SetEnvColor command
    CC_A_1                 = 6,  // vec3 { 1.0, 1.0, 1.0 } rgb
    CC_A_NOISE             = 7,  // a random color
    CC_A_0                 = 8   // vec3 { 0.0, 0.0, 0.0 } rgb
    ...
    // values 9..15 are all the same as value 8
};

enum
{
    CC_B_COMBINED_COLOR    = 0,  // the combined color from cycle 1
    CC_B_TEXEL0_COLOR      = 1,  // the color of the texel for tile 0
    CC_B_TEXEL1_COLOR      = 2,  // the color of the texel for tile 1
    CC_B_PRIMITIVE_COLOR   = 3,  // the primitive color, set via the 0xFA SetPrimColor command
    CC_B_SHADE_COLOR       = 4,  // the shade (vertex) color
    CC_B_ENVIRONMENT_COLOR = 5,  // the environment color, set via the 0xFB SetEnvColor command
    CC_B_CENTER            = 6,  // the chroma key center, set via the SetKeyR and SetKeyGB commands
    CC_B_K4                = 7,  // the chroma key K4 constant, set via the SetConvert command
    CC_B_0                 = 8   // vec3 { 0.0, 0.0, 0.0 } rgb
    ...
    // values 9..15 are all the same as value 8
};

enum
{
    CC_C_COMBINED_COLOR    = 0,  // the combined color from cycle 1
    CC_C_TEXEL0_COLOR      = 1,  // the color of the texel for tile 0
    CC_C_TEXEL1_COLOR      = 2,  // the color of the texel for tile 1
    CC_C_PRIMITIVE_COLOR   = 3,  // the primitive color, set via the 0xFA SetPrimColor command
    CC_C_SHADE_COLOR       = 4,  // the shade (vertex) color
    CC_C_ENVIRONMENT_COLOR = 5,  // the environment color, set via the 0xFB SetEnvColor command
    CC_C_SCALE             = 6,  // the chroma key scale, set via the SetKeyR and SetKeyGB commands
    CC_C_COMBINED_ALPHA    = 7,  // the combined alpha from cycle 1
    CC_C_TEXEL0_ALPHA      = 8,  // the alpha of the texel for tile 0
    CC_C_TEXEL1_ALPHA      = 9,  // the alpha of the texel for tile 1
    CC_C_PRIMITIVE_ALPHA   = 10, // the primitive alpha, set via the 0xFA SetPrimColor command
    CC_C_SHADE_ALPHA       = 11, // the shade (vertex) alpha
    CC_C_ENVIRONMENT_ALPHA = 12, // the environment alpha, set via the 0xFB SetEnvColor command
    CC_C_LOD               = 13, // the actual lod fraction
    CC_C_PRIMITIVE_LOD     = 14, // the primitive lod fraction, set via the 0xFA SetPrimColor command
    CC_C_K5                = 15, // the chroma key K5 constant, set via the SetConvert command
    CC_C_0                 = 16, // vec3 { 0.0, 0.0, 0.0 } rgb
    ...
    // values 17..31 are all the same as value 16
};

enum
{
    CC_D_COMBINED_COLOR    = 0,  // the combined color from cycle 1
    CC_D_TEXEL0_COLOR      = 1,  // the color of the texel for tile 0
    CC_D_TEXEL1_COLOR      = 2,  // the color of the texel for tile 1
    CC_D_PRIMITIVE_COLOR   = 3,  // the primitive color, set via the 0xFA SetPrimColor command
    CC_D_SHADE_COLOR       = 4,  // the shade (vertex) color
    CC_D_ENVIRONMENT_COLOR = 5,  // the environment color, set via the 0xFB SetEnvColor command
    CC_D_1                 = 6,  // vec3 { 1.0, 1.0, 1.0 } rgb
    CC_D_0                 = 7   // vec3 { 0.0, 0.0, 0.0 } rgb
};

Well, that seems messy as fuck, but there's no helping that; just a side effect of them trying to cram as much crap into a single command as possible. Anyhow, here's the alpha combiner modes:

enum
{
    AC_ABD_COMBINED_ALPHA    = 0,  // the combined alpha from cycle 1
    AC_ABD_TEXEL0_ALPHA      = 1,  // the alpha of the texel for tile 0
    AC_ABD_TEXEL1_ALPHA      = 2,  // the alpha of the texel for tile 1
    AC_ABD_PRIMITIVE_ALPHA   = 3,  // the primitive alpha, set via the 0xFA SetPrimColor command
    AC_ABD_SHADE_ALPHA       = 4,  // the shade (vertex) alpha
    AC_ABD_ENVIRONMENT_ALPHA = 5,  // the environment alpha, set via the 0xFB SetEnvColor command
    AC_ABD_1                 = 6,  // 1.0
    AC_ABD_0                 = 7,  // 0.0
}

enum
{
    AC_C_LOD                 = 0,  // the lod fraction
    AC_C_TEXEL0_ALPHA        = 1,  // the alpha of the texel for tile 0
    AC_C_TEXEL1_ALPHA        = 2,  // the alpha of the texel for tile 1
    AC_C_PRIMITIVE_ALPHA     = 3,  // the primitive alpha, set via the 0xFA SetPrimColor command
    AC_C_SHADE_ALPHA         = 4,  // the shade (vertex) alpha
    AC_C_ENVIRONMENT_ALPHA   = 5,  // the environment alpha, set via the 0xFB SetEnvColor command
    AC_C_PRIMITIVE_LOD       = 6,  // the primitive lod fraction, set via the 0xFA SetPrimColor command
    AC_C_0                   = 7,  // 0.0
};

One thing that should also be mentioned (if you haven't inferred it already from the comments above, is that the 0xFC SetCombine command actually sets 2 color combine modes and 2 alpha combine modes at the same time. In single-cycle mode, the 2 modes are exactly the same, and the 'COMBINED_COLOR / COMBINED_ALPHA'  values are unused. In double-cycle mode, the two modes are different. Double-cycle mode is typically used for multitexturing.

 

Algebraically speaking, because the combining equation is (A - B ) * C + D; the following statements hold true:

Rule 1: if B = 0, then (A * C + D) = ((A -  * C + D)

Rule 2: if C = 0, then (D) = ((A -  * C + D)

Rule 3: if D = 0, then ((A -  * C) = ((A -  * C + D)

Rule 4: if B = 0 and D = 0, then (A * C) = ((A -  * C + D)

Given these statements, here are some common color combiner modes:

Modulate  = TEXEL0_COLOR * SHADE_COLOR      // See Rule 4
Decal     = TEXEL0_COLOR                    // See Rule 2
Blend     = (PRIMITIVE_COLOR - ENVIRONMENT_COLOR) * TEXEL0_COLOR + ENVIRONMENT_COLOR

and here are some common alpha combiner modes:

Select = TEXEL0_ALPHA
Multiply = TEXEL0_ALPHA * TEXEL1_ALPHA      // See Rule 4
  • Like 1
Link to comment
Share on other sites

The Matrix Format

 

This is confusing as hell to explain, so I think it's best to start by explaining how 32-bit fixed-point calculations work. A 32-bit fixed-point value has the format 's15.16', where the 's' represents the sign-bit, the 15 represents the 15 integer bits, and the 16 represents the 16 fractional bits.

 

For the fractional part, a value of 0 is equal to 0, and a value of 65,536 is equal to 1. Note that you can never actually have a fractional value of 1, because the carried bit exceeds the 16-bit range and the value wraps back around to 0. You can convert to this format simply by multiplying by 65,536. eg. 0.5 * 65,536 = 32,768 = 0x8000. You can also convert back by dividing by 65,536. It's important to note that the carried bit that was mentioned before will actually overflow into the integer part of the number; just like how 0.9 + 0.2 = 1.1.

 

In addition to the encoding of the fractional number information, the s15.16 format also uses two's complement encoding. This means that when the sign-bit is set, the actual integer value is 0 - (32,768 - the_value). eg. a value of 32,765 with the sign-bit set (0xFFFD) would equal 0 - (32,768 - 32,765) = -3. The same rule also applies to the fractional value, where the actual fractional value is 0 - (1.0 - the_value) when the sign-bit is set. That said, this is just a side effect of the two's complement encoding, and has nothing to do particularly with the fractional number format.

 

The last thing we need to cover before we can get on to the actual matrix format is how overflow from addition and multiplication is handled for fixed-point values. Well, first things first, because of the way that the fractional component is encoded, fixed-point addition, subtraction, multiplication, and division are all equivalent to integer addition, subtraction, multiplication, and division. This makes things much easier. The second thing you need to know is that the overflow from 32-bit addition and multiplication can easily be captured just by using 64-bit arithmetic; the confusing part is converting back to a 32-bit value. So how does the N64 do it? It extracts the "middle" 32-bits of the 64-bit value. This seems like some sort of sorcery, but just try it:

1.5 = (1 << 16) + (0.5 * 65536) = 0x00018000

0x00018000 * 0x00018000 = 0x0000000240000000

0x0000000240000000 -> 0x0000 00024000 0000 -> 0x00024000

0x00024000 >> 16 = 0x0002 = 2
0x00024000 & 0xFFFF = 0x4000 = 16384
16384 / 65536 = 0.25

2 + 0.25 = 2.25

1.5 * 1.5 = 2.25

Crazy, huh? That said, some of the values in rotation and projection matrices have really small fractional values prone to generate errors when multiplied against factors with much higher values. As a result, the N64 manual states that developers should perform their actual calculations using floating-point and only convert the matrices to fixed-point when they're uploading to the RSP. Speaking of which, now that we understand how the math for each individual value works, it's time to look at the matrix format itself.

struct Matrix
{
    int16_t integer_parts[4][4];
    uint16_t fractional_parts[4][4];
};

Well, that makes no fucking sense, but that's what it is. If you're unfamiliar with C syntax, a [4][4] array is equivalent to a [16] element array. Technically speaking, the gbi.h defines the matrix as a 'long [4][4]', which requires bit shifting integers together and fractionals together (which I personally find hideous and confusing).

  • Like 1
Link to comment
Share on other sites

Some good notes, though I think most if not all is documented on the cloudmodding wiki.

 

One thing that interests me is whether or not there's an easy way to generate a compatible overlay file with gcc. I've come really close to it through linker scripts, but my hang-up is that I either can't generate relocation data, or I end up generating an ELF object file. As relocation types, I believe the run-time relocation function only supports a handful of relocation types (the wiki lists four, but I haven't checked the code/data recently to confirm).

 

On the topic of matrices, one thing to point out is that if you're doing some matrix manipulation in floats, care must be taken when downcasting from float -> int (and later a short), since such a cast will fail on real hardware if the value ends up being bigger than int_max/smaller than int min.

Link to comment
Share on other sites

 

One thing that interests me is whether or not there's an easy way to generate a compatible overlay file with gcc.

 

Aside from nOVL, you could use a linker script to create a flat binary and then write a script that uses the 'readelf' tool with the '-r' option to list the relocations and their types; and then use a tool like 'awk' to convert the output into a list of entries that you can pipe onto the end of the file. If you're talking about having some way of making a vanilla gcc output an overlay, then the answer is no. At the very least, you'd need to make a new target for libBFD and recompile gcc against it.

 

 

On the topic of matrices, one thing to point out is that if you're doing some matrix manipulation in floats, care must be taken when downcasting from float -> int (and later a short), since such a cast will fail on real hardware if the value ends up being bigger than int_max/smaller than int min.

 

I'm just stating what the N64 developer's manual itself tells game developers to do. It emphasizes that developers shouldn't use very large numbers in their matrices (which is uncommon anyhow), and has mildly informational charts showing where the values lose precision during conversions or calculations. The whole point of doing the calculations in floating point is that the number of artifacts are significantly reduced.

Link to comment
Share on other sites

  • 2 months later...

I'm just stating what the N64 developer's manual itself tells game developers to do. It emphasizes that developers shouldn't use very large numbers in their matrices (which is uncommon anyhow), and has mildly informational charts showing where the values lose precision during conversions or calculations. The whole point of doing the calculations in floating point is that the number of artifacts are significantly reduced.

 

I was watching one of the Mario 64 videos that explained that and it even showed what happens when the number gets too big. Causes it to round and make Mario skip huge segments of mesh while walking and incrementing his x or z axis. It can get pretty crazy. 

  • Like 1
Link to comment
Share on other sites

 Share

×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.