• Welcome to Smashboards, the world's largest Super Smash Brothers community! Over 250,000 Smash Bros. fans from around the world have come to discuss these great games in over 19 million posts!

    You are currently viewing our boards as a visitor. Click here to sign up right now and start on your path in the Smash community!

Yoshi Story = Analysis of codes (Shy Guy function done)

flieskiller

Smash Journeyman
Joined
Jan 3, 2013
Messages
426
I've finished from what I knew the function. I'm not sure what some line does (almost everything with floating points), but I've done my best to show what a function looks like in Melee.

zz_01e3418_ SHY GUY SPAWNING FUNCTION:
"0x00C4(r30)" = number of Shy Guys in the RAM
"0x00C5(r30)" = height category of spawning (0 to 5?)
"0x00C8(r30)" = Timer (-1 every frame)


zz_01e3418_
801e3418: mflr r0
801e341c: stw r0, 0x0004 (sp)
801e3420: stwu sp, -0x0080 (sp)
801e3424: stfd f31, 0x0078 (sp)
801e3428: stfd f30, 0x0070 (sp)
801e342c: stfd f29, 0x0068 (sp)
801e3430: stfd f28, 0x0060 (sp)
801e3434: stfd f27, 0x0058 (sp)
801e3438: stmw r27, 0x0044 (sp)
801e343c: lwz r30, 0x002C (r3)

Object-type of Shy Guy?
801e3440: li r3, 210

Go count the number of Shy Guys in the map
801e3444: bl ->0x8026B3C0

If the number is different from 0, go to the end of the function
801e3448: cmpwi r3, 0
801e344c: bne- ->0x801E3644

If the number of Shy Guys is 0, load the timer stored at "0x00C8(r30)"
801e3450: lwz r3, 0x00C8 (r30)

Check if the timer is at 0. If yes, branch to the beginning of the spawning
801e3454: cmpwi r3, 0
801e3458: beq- ->0x801E3468

Timer is bigger than 0, so reduce the timer by 1 (-1 per frame) then branch to the end of the function.
801e345c: subi r0, r3, 1

Store the new timer value
801e3460: stw r0, 0x00C8 (r30)

Branch to the end
801e3464: b ->0x801E3644

801e3468: lwz r3, -0x4CE8 (r13)
801e346c: lfs f0, 0x0004 (r3)
801e3470: fctiwz f0,f0
801e3474: stfd f0, 0x0030 (sp)
801e3478: lwz r0, 0x0034 (sp)
801e347c: stfd f0, 0x0038 (sp)
801e3480: cmpwi r0, 0
801e3484: lwz r3, 0x003C (sp)
801e3488: beq- ->0x801E3494
801e348c: bl ->0x80380580
801e3490: b ->0x801E3498
801e3494: li r3, 0
801e3498: xoris r0, r3, 0x8000
801e349c: lwz r4, -0x4CE8 (r13)
801e34a0: stw r0, 0x0034 (sp)
801e34a4: lis r3, 0x4330
801e34a8: lfd f1, -0x4768 (rtoc)

Set the new timer
801e34ac: li r0, 120

801e34b0: stw r3, 0x0030 (sp)
801e34b4: lfs f2, 0 (r4)
801e34b8: lfd f0, 0x0030 (sp)
801e34bc: fsubs f0,f0,f1
801e34c0: fadds f0,f2,f0
801e34c4: fctiwz f0,f0
801e34c8: stfd f0, 0x0038 (sp)
801e34cc: lwz r3, 0x003C (sp)
801e34d0: stw r3, 0x00C8 (r30)

Store the new timer into the RAM
801e34d4: stw r0, 0x00C8 (r30)

Start to choose the height , below 6? (between 0 and 5?)
801e34d8: li r3, 6
801e34dc: bl ->0x80380580

Load the previous height? So 2 times can't be the same
801e34e0: lbz r0, 0x00C5 (r30)
801e34e4: extsb r0, r0

Compare the previous height vs the current, if they're equal do the math again
801e34e8: cmpw r0, r3
801e34ec: beq+ ->0x801E34D8

Check the height to choose wether the Shy Guys will spawn left or right
801e34f0: extsb r0, r3
801e34f4: cmpwi r3, 3

Store the new height into the RAM
801e34f8: stb r0, 0x00C5 (r30)

If the number is 3, 4 or 5, go to the branch and set the spawn to the right, else spawn to the left
801e34fc: bge- ->0x801E350C
801e3500: lfs f0, -0x4760 (rtoc)
801e3504: stfs f0, 0x0020 (sp)
801e3508: b ->0x801E3514
801e350c: lfs f0, -0x475C (rtoc)
801e3510: stfs f0, 0x0020 (sp)

801e3514: lwz r0, -0x4CE8 (r13)
801e3518: rlwinm r31, r3, 2, 0, 29 (3fffffff)
801e351c: add r3, r0, r31
801e3520: lfs f0, 0x000C (r3)
801e3524: li r3, 3
801e3528: stfs f0, 0x0024 (sp)
801e352c: lfs f0, -0x4758 (rtoc)
801e3530: stfs f0, 0x0028 (sp)
801e3534: bl ->0x80380580
801e3538: lwz r4, -0x4CE8 (r13)
801e353c: mr r29, r3
801e3540: lfs f0, 0x0008 (r4)
801e3544: fctiwz f0,f0
801e3548: stfd f0, 0x0038 (sp)
801e354c: lwz r0, 0x003C (sp)
801e3550: stfd f0, 0x0030 (sp)

Beginning for number of Shy Guys. With the RNG function bl at 801e3534, if that number is 0, it will go farther into the code and start somewhere else.
801e3554: cmpwi r0, 0
801e3558: lwz r3, 0x0034 (sp)
801e355c: beq- ->0x801E3568

Start of choosing the number of Shy Guys spawning, if the number given was different from 0 (still not sure why). Get a new number then skip a few lines.
801e3560: bl ->0x80380580
801e3564: b ->0x801E356C

If the number from 801e3534 was 0, put it again to 0
801e3568: li r3, 0

from the bl 801e3564, check if the number was 0. If it was 0 before that, it will go to the line above, so it will never go to the branch from the condition below.
801e356c: cmpwi r3, 0
801e3570: bne- ->0x801E3588

This is the line where it really starts. with r3 set to 3, the number received can be from 0 to 2.
801e3574: li r3, 3
801e3578: bl ->0x80380580

Add 3 to the number and store it into r0, then store it into the Shy Guys RAM spot.
801e357c: addi r0, r3, 3
801e3580: stb r0, 0x00C4 (r30)

Branch to the function a little below to make more calculations.
801e3584: b ->0x801E3590

Arrived from 801e3570, set 1 into the RAM spot for the Shy Guys
801e3588: li r0, 1
801e358c: stb r0, 0x00C4 (r30)

All the calculations above go through those lines, with 2 loaded in r3, the RNG function can only load 0 or 1, so there is a 50% to go branch into the place where it will spawn only 1 Shy Guy.
801e3590: li r3, 2
801e3594: bl ->0x80380580

If the given number is 1, go load a single Shy Guy. Else, continue to create another number.
801e3598: cmpwi r3, 0
801e359c: bne- ->0x801E35B4

Get a number between 0 and 2
801e35a0: li r3, 3
801e35a4: bl ->0x80380580

Then add 3 to that number and use it definitively. After that, branch to the next part of the function.
801e35a8: addi r0, r3, 3
801e35ac: stb r0, 0x00C4 (r30)
801e35b0: b ->0x801E35BC

If the number at 801e3598 was 1, go here and load 1 to spawn a single Shy Guy.
801e35b4: li r0, 1
801e35b8: stb r0, 0x00C4 (r30)


WITH THE CODE ABOVE: I'm not sure how all that can land to 2 Shy Guys...

801e35bc: lfs f27, -0x4754 (rtoc)
801e35c0: li r27, 0
801e35c4: lfd f28, -0x4768 (rtoc)
801e35c8: lis r28, 0x4330
801e35cc: lfs f29, -0x4750 (rtoc)
801e35d0: lfs f30, -0x4758 (rtoc)
801e35d4: lfs f31, -0x474C (rtoc)

Branch at the end of the loop, because it will count the amount of Shy Guys and will go out of the loop when all will be spawned.
801e35d8: b ->0x801E3634

Put r0 at 8000000x, where x is the number in r27.
801e35dc: xoris r0, r27, 0x8000
801e35e0: stw r0, 0x0034 (sp)

801e35e4: addi r3, r27, 0
801e35e8: addi r5, r29, 0
801e35ec: stw r28, 0x0030 (sp)
801e35f0: addi r4, sp, 32
801e35f4: lfd f0, 0x0030 (sp)
801e35f8: fsubs f0,f0,f28
801e35fc: fmuls f0,f27,f0
801e3600: fctiwz f0,f0
801e3604: stfd f0, 0x0038 (sp)
801e3608: lwz r6, 0x003C (sp)

Branches to the 2 functions that spawn the Shy Guy. First is spawning the item and second is choosing the coordinates?
801e360c: bl ->0x802D8618
801e3610: bl ->0x80380528

801e3614: fsubs f0,f1,f29
801e3618: lwz r3, -0x4CE8 (r13)

Add 1 to the amount of Shy Guys spawned for now.
801e361c: addi r27, r27, 1

801e3620: addi r0, r3, 12
801e3624: fmuls f1,f30,f0
801e3628: lfsx f0,r31,r0
801e362c: fmadds f0,f31,f1,f0
801e3630: stfs f0, 0x0024 (sp)

Start of the loop, load the amount of Shy Guys
801e3634: lbz r0, 0x00C4 (r30)
801e3638: extsb r0, r0

After each loops, r27 is incremented by 1, so when all are spawned and both numbers are equal, it will no longer branches and finish the rest of the function
801e363c: cmpw r27, r0
801e3640: blt+ ->0x801E35DC

Final part of function, do a bunch of stuff in the float registers and finish.
801e3644: lmw r27, 0x0044 (sp)
801e3648: lwz r0, 0x0084 (sp)
801e364c: lfd f31, 0x0078 (sp)
801e3650: lfd f30, 0x0070 (sp)
801e3654: lfd f29, 0x0068 (sp)
801e3658: lfd f28, 0x0060 (sp)
801e365c: lfd f27, 0x0058 (sp)
801e3660: addi sp, sp, 128
801e3664: mtlr r0
801e3668: blr

Now, all the lines that have something interesting/exploitable to change:
801e3448 Choose a maximum number of Shy Guys before spawning more (like 10 max in the stage at the same time)
801e344c branch directly instead of number for unlimited Shy Guys

801e345c amount of time substracted each frame. Should stay at 1.

801e34ac Is the new timer. Default is 120 (which is 2 seconds)

801e34d8 Is the amount of heights. Should not exceed the default 6, but lowering the number might make the Shy Guys spawn more on a certain side of the stage
801e34ec put "nop" on this will make the Shy Guys available to spawn on the same height multiple times in a row

801e34fc Can choose if the Shy Guys will spawn always from the same side

801e355c If you want to spawn always the same number, branch this directly to 801e35b4 (48000058)
801e35a8 Small chance to spawn a higher number of Shy Guys, increase the amount added to have a higher amount (default +3)
801e35b4 1/2 chance to spawn that number of Shy Guys (default 1)

Example picture:
shyguyarmy.jpg


Lines changed to have the same result on the picture:
Shy Guys will spawn even if there are some existing already.
041e344c 60000000

Reduce the timer of spawning the next wave, from 120 to 10 frames
041e34ac 38000010

Also, here are some codes about the stage that aren't in that function.
Shy Guys drop food even if items are at off (1.02)[flieskiller]
0428fb1c 4800000c
It removes the verification that the item is set at ON and branches directly to give the Shy Guy the food item.

Shy Guys drop any items [flieskiller]
(xx = item) (default is 12 for food)
0428fb28 380000xx
THIS CODE CRASHES THE GAME. I expect is that anything else than food has some random/bizarre things about coordinates (like a super scope held above the head of the Shy Guy), this is why it might crash, it's just luck. I'll check onto it later to make it not crash the game.
 
Last edited:

flieskiller

Smash Journeyman
Joined
Jan 3, 2013
Messages
426
Function done! Can be found in the post above.

Too much cryptic stuff for me with the floating point (register f0, f1 etc.), but I could understand a lot of it. I might explore the 2 bl in a later time.
 

Achilles1515

Smash Master
Joined
Jun 18, 2007
Messages
3,211
Location
Cincinnati / Columbus OH
Flieskiller, see if this works for making hits on a Shy Guy after it has been killed not count towards the Shy Guy KO count.

Code:
Shy Guy KO Fix (1.02) [Achilles]
C203887C 00000004
2C180000 41820014
8078002C 80630024
2C030002 41820008
90040904 00000000
 

SinsOfApathy

Smash Journeyman
Joined
Feb 24, 2015
Messages
474
NNID
Psion312
Just an FYI, the bl 0x8026B3C0 is a call to getCountOfItemType(r3 id), so 210 is definitely the entity ID for Shy Guys.

If I had to guess, since Nintendo's compiler groups common functions together, 801E3030 is the Yoshi Story init function, since it calls a function I've named "Stages_SpawnInteractObj", which means it's a physically interactable object, likely the cloud.

The weird thing about that Shy Guy function is that it doesn't actually call any of the Spawn functions I have mapped. Though I haven't stepped through the blr or anything.
 
Last edited:
Top Bottom