SoulofDeity Posted May 12, 2013 Author Share Posted May 12, 2013 here's a better version of the above code, a fully controllable sequence player 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 1 Link to comment Share on other sites More sharing options...
mzxrules Posted May 13, 2013 Share Posted May 13, 2013 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 More sharing options...
SoulofDeity Posted May 13, 2013 Author Share Posted May 13, 2013 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 More sharing options...
mzxrules Posted May 14, 2013 Share Posted May 14, 2013 Nah. Don't need to accidentally dirty my rom. Link to comment Share on other sites More sharing options...
mzxrules Posted May 16, 2013 Share Posted May 16, 2013 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 More sharing options...
mzxrules Posted May 17, 2013 Share Posted May 17, 2013 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 More sharing options...
mzxrules Posted May 18, 2013 Share Posted May 18, 2013 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 More sharing options...
SoulofDeity Posted May 20, 2013 Author Share Posted May 20, 2013 some more little stuff... World Map$00852000 216x126 CI8 texture$00858C00 palette Here's a rip as well just in case anyone want it it's paletted, but since it's a png your image editor might not import it as indexed. *shrugs* Link to comment Share on other sites More sharing options...
SoulofDeity Posted August 11, 2013 Author Share Posted August 11, 2013 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 2 Link to comment Share on other sites More sharing options...
SoulofDeity Posted August 12, 2013 Author Share Posted August 12, 2013 Toying around with the "Press Z to Disable Collision" cheat shown above. Has many wonderful uses... Totally spahming dat shit. 3 Link to comment Share on other sites More sharing options...
mzxrules Posted August 12, 2013 Share Posted August 12, 2013 If you lock Y velocity, would you be able to clip through vertical walls? Link to comment Share on other sites More sharing options...
SoulofDeity Posted August 13, 2013 Author Share Posted August 13, 2013 If you lock Y velocity, would you be able to clip through vertical walls?I'm not sure, but I think it only affects vertical collision, which is why I drop under stuff and cancel jump up to the other side. Link to comment Share on other sites More sharing options...
SoulofDeity Posted August 20, 2013 Author Share Posted August 20, 2013 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 2color 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 + 0which is Aa0 = 6Ab0 = 1Ac0 = 6Ad0 = 7An 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 sizenext 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 sizeThen, 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 + TEXEL0However, 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 + 0And 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 syncEDIT================================================ 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 00Explanation:[*]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 1 Link to comment Share on other sites More sharing options...
mzxrules Posted December 8, 2013 Share Posted December 8, 2013 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 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 2 Link to comment Share on other sites More sharing options...
mzxrules Posted February 13, 2014 Share Posted February 13, 2014 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) NOTE: the below is actually 9 textures arranged in a 3x3 grid of 64x64 i4 textures!!! (and because some people prefer to use the debug rom) 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 2 Link to comment Share on other sites More sharing options...
SoulofDeity Posted January 8, 2017 Author Share Posted January 8, 2017 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. 2 Link to comment Share on other sites More sharing options...
SoulofDeity Posted February 2, 2017 Author Share Posted February 2, 2017 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 1 Link to comment Share on other sites More sharing options...
SoulofDeity Posted February 2, 2017 Author Share Posted February 2, 2017 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). 1 Link to comment Share on other sites More sharing options...
mzxrules Posted February 4, 2017 Share Posted February 4, 2017 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 More sharing options...
SoulofDeity Posted February 4, 2017 Author Share Posted February 4, 2017 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 More sharing options...
Acelib Posted April 12, 2017 Share Posted April 12, 2017 Thanks SoD, these are really useful. Link to comment Share on other sites More sharing options...
Mallos31 Posted April 13, 2017 Share Posted April 13, 2017 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. 1 Link to comment Share on other sites More sharing options...
Recommended Posts