![]() | ||
Views: 24,264,018 |
Home
| Forums
| Uploader
| Wiki
| Object databases
| IRC
Rules/FAQ | Memberlist | Calendar | Stats | Online users | Last posts | Search |
03-21-25 03:31 AM |
Guest: |
0 users reading [ASM Resource] Customising behaviour of player/objects/levels | 1 bot |
Main - General SM64DS hacking - [ASM Resource] Customising behaviour of player/objects/levels | Hide post layouts | New reply |
dy |
| ||
Member Normal user Level: 13 Posts: 8/30 EXP: 8289 Next: 1978 Since: 04-02-18 Last post: 2506 days ago Last view: 2498 days ago |
Introduction
Firstly, huge thanks to the team behind SM64DSe and the ASM Patch Templates, as well as everyone who's contributed to documenting the object parameters, memory addresses and subroutines. What I have found and documented here wouldn't be possible if it wasn't for the amazing quality of research, documentation and tools available to the community. Special thanks also to Fiachra who helped me get started and inspired me to learn ASM hacking. This thread is intended to collate discoveries on how to customise certain player, object and level properties/behaviours (in ways that can't be changed using SM64DSe alone). It is not a substitute for the existing ASM resources, which are invaluable if you want to create ASM hacks or do your own research. If you've made any discoveries of your own which fit with this thread, please feel welcome and encouraged to share! Getting Started with ASM In order to understand and use the information provided, you will need some basic ARM ASM knowledge. This is not intended to be a general ASM help thread, but don't worry, there are plenty of tutorials available online. I personally have very little programming experience and knew zero ASM just 2 weeks ago, but learnt a lot from this tutorial (30 minute read) and playing around with the no$gba debugger (see below). Useful programs:
Additional tips:
Documented Discoveries OK, now onto the good stuff! This post will be updated as new discoveries are made.
Yoshi: can punch and grab Hold "Y" (sprint) while attacking to punch/grab/dive: this post Player: speed and jump height See this post Wing Cap: who can get Feather powerup There are several parts to this: Despawn loop check: here Whether to give wings when collected: here Whether relevant "? Blocks" spawn Feathers or Power Flowers: here Power Flowers: who can see Power Flowers in mirror room Unfortunately crashes when collected by Mario/Wario in Castle 2F, and there is no reflection for Yoshi's fire breath. But it seems to work properly in painting levels. Including this in case anyone wants to use static Power Flowers in custom/painting levels only. Visibility of static Power Flowers: here Brick Blocks / Black Brick Blocks: who can break When ground pounded: here When kicked or sweep kicked: here When punched: here On explosion: here Ice Blocks: can be shattered See this post Boos: who can defeat On any attack that can normally defeat Boos: here Bob-ombs: whether to reappear and what to spawn when defeated Whether to reappear: here What to spawn: here Piranha Plants: whether to reappear and what to spawn When defeated: here Wooden Crates: whether to reappear and what to spawn When broken: here When swallowed by Yoshi: here Yellow Coins / Blue Coins: whether they disappear Countdown timer: here Object Draw Distances Easy way to change for all or specific objects: here Something easy: you could set a fixed draw distance for everything (r2 = 0x600000 seems to give good results without killing the frame rate) Something fancy: offset 0xC (2 bytes) of the object's address (r4) is the ActorID of the object - so you could check this to set different draw distances for different objects Bowser Star Doors / Endless Stairs: star and character requirements Bowser Star Doors: here Endless Stairs - music/lighting effects: here Endless Stairs - whether can get to top: here Change when you get "recovered X stars" messages: here Power Stars: whether to continue or exit level after collecting 100-Coin Stars: here Level type: here Level and level transition behaviours See this post Allows you to do things like: Conducting Your Own Research For those who are interested in doing their own research and wondering how I discovered these, the process essentially involves:
The ASM Hacking Templates (especially symbols.x and SM64DS_2.h from v2) are fantastic resources of currently known data locations, subroutines and their memory addresses. Action Replay codes can also be very helpful, if there is one that does something similar to what you want. Lastly, you can find addresses of object-specific callbacks (eg, OnGroundPounded(), OnKicked(), etc) by following steps 1-8 of Fiachra's tutorial for finding an object's constructor - after the constructor address, you'll see a long list of more addresses (which are the addresses of the various callback functions). You'll need some ASM knowledge and a bit of creativity/patience. Tracing backwards involves looking at r14 (LR) to find earlier code that called your breakpointed code (and repeat if necessary). Unfortunately sometimes code uses "b" jumps rather than "bl" jumps (which don't store the return address to r14), so you might end up further back then you wanted and then have to step forwards. For tracing forwards, you can use "F7" in no$gba to step through code line by line (the debugger helpfully tells you the value of registers and whether conditional instructions evaluate to 'true' or 'false' as you step through). You can also use no$gba to change code on the fly to see if it changes what you want to change. Chaining breakpoints and conditional breakpoints can be very helpful (see this post for an example). See here for how to set different types of conditional breakpoints (thanks to Fiachra for the link). You can also create breakpoints which are triggered whenever a memory address is read or written to (this can be really handy) - the previous documentationis a bit off for these though, so see here instead. Lastly, once you've found what you are looking for, follow steps 3-5 in this post to find which overlay it appears in. ____________________ - ASM resource for customising behaviour of player/objects/levels - NSMBe with direct overwrite feature |
pants64 |
| ||
![]() Red Koopa Normal user Level: 25 ![]() Posts: 66/125 EXP: 79851 Next: 9769 Since: 04-12-16 Last post: 72 days ago Last view: 4 days ago |
This is extremely awesome. Keep up the great work! |
dy |
| ||
Member Normal user Level: 13 Posts: 15/30 EXP: 8289 Next: 1978 Since: 04-02-18 Last post: 2506 days ago Last view: 2498 days ago |
Holy crap!!!
Did you know Yoshi has fully functional punch/kick/dive/grab attacks and animations!?
How the game decides whether to perform a 'punch' or 'eat' attack: here Here's a quick patch for ASMPatchTemplate which allows Yoshi to use both his new and old attacks (hold "Y" while attacking to punch/dive/grab, etc):
nsub_020DDEAC_ov_02:
@ check if character is Yoshi ldr r0, [r4, #0x8] cmp r0, #0x3 bne 0x020DDEDC @ approach used by the game to get "INPUT_PERSISTENT" ldr r1, =0x020A0E40 mov r0, #0x18 ldrb r2, [r1] ldr r1, =0x0209F49C mul r0, r2, r0 ldrh r0, [r1, r0] @ choose attack depending on whether "Y" is pressed ands r0, r0, #0x800 beq 0x020DDEB8 b 0x020DDEDC To switch to hold "Y" for eat attack, just change the "beq" to "bne" (but the current setup feels more natural for dive attacks while sprinting). PS: I've also discovered how to change the following:
I'll post these here once I've documented them properly (soon)! ____________________ - ASM resource for customising behaviour of player/objects/levels - NSMBe with direct overwrite feature |
pants64 |
| ||
![]() Red Koopa Normal user Level: 25 ![]() Posts: 75/125 EXP: 79851 Next: 9769 Since: 04-12-16 Last post: 72 days ago Last view: 4 days ago |
Nice! How did you discover Yoshi's secret abilities in the first place? |
dy |
| ||
Member Normal user Level: 13 Posts: 16/30 EXP: 8289 Next: 1978 Since: 04-02-18 Last post: 2506 days ago Last view: 2498 days ago |
Posted by StarPants Similar process to all the others - this one was actually surprisingly straightforward:
EDIT: Fixed code for YoshiCanPunchAndEat - I accidentally stuffed up the Yoshi check, so it was affecting every character! ____________________ - ASM resource for customising behaviour of player/objects/levels - NSMBe with direct overwrite feature |
pants64 |
| ||
![]() Red Koopa Normal user Level: 25 ![]() Posts: 76/125 EXP: 79851 Next: 9769 Since: 04-12-16 Last post: 72 days ago Last view: 4 days ago |
It is very surprising that it doesn't crash. Maybe Yoshi was intended to be able to punch but this ability was removed in the last minute. |
dy |
| ||
Member Normal user Level: 13 Posts: 17/30 EXP: 8289 Next: 1978 Since: 04-02-18 Last post: 2506 days ago Last view: 2498 days ago |
EDIT: I think you might be right. His punch seems to be set to be much weaker than any other character's (Goombas don't go very far at all), but he can run quite fast while carrying things.
It's a bit of a mixed bag in terms of consistency though. He can throw Big Bob-omb pretty far, but can't seem to throw crates as far as Luigi. Also if you bring lost little penguin to Mama Penguin with Yoshi she won't recognise it and just give the "have you seen" speech... Will have to figure out how to fix all that. ____________________ - ASM resource for customising behaviour of player/objects/levels - NSMBe with direct overwrite feature |
dy |
| ||
Member Normal user Level: 13 Posts: 19/30 EXP: 8289 Next: 1978 Since: 04-02-18 Last post: 2506 days ago Last view: 2498 days ago |
As promised, here are some discoveries which allow you to customise the behaviour of level transitions and Power Stars.
Might not sound very exciting at first, but it allows you to do things such as:
100-Coin Stars: here Level type: here Level: whether to display star select screen Level type, moving between levels: here See below on how to set the star number without the star select screen Level: set star number for level See here Allows you to create multiple setups for the secret/boss/castle levels, or force the star number if you don't want courses to have star select screens Level: persistence across levels Coin count and object respawns: here Note: some objects are not added to the death table, so will respawn when moving between sublevels (eg, Brick Blocks in Cool Cool Mountain after you return from the slide) Level: attainability of 100-Coin Stars Level type and coin requirements: here (Thanks to whoever created the Action Replay code for the offset) Whether and when to display "recovered X stars" text See here Pause Menu: whether can "Exit Course" See here Pause Menu: make Main Castle use course/level pause screen Change the instruction at each of the following addresses from cmp r0, 0x1D" (castle ActID) to "cmp r0, 0xFE" (or another unused ActID):
0x02029550 - shows text for course/level pause screen 0x020252B4 - don't show star map on top screen 0x020280C8 - fix glitch when entering Options screen 0x02028B74 - fix glitch when leaving Options screen 0x02027FD4 - fix glitch when leaving Controller Modes screen Pause Menu / Star Text: make main courses like secret/boss levels To make pause menu only show the course name (like with secret/boss levels), and make the text when you leave with a Power Star like that for secret or boss levels:
- set r6 to either 0x12 or 0x15 instead (same effect for pause menu, for exit text 0x12 = "[course name] COMPLETE" and 0x15 = "another castle secret star CLEAR") - store r0 (the level's real ActID) to a global variable 0x0201DA6C: - get the stored (real) ActID and add to r0 instead (this makes it display the correct course name) - leave the value of r6 untouched (ie, still 0x12 or 0x15) 0x02025680: - make the jump unconditional (removes "score" from pause screen) 0x02023E54: - conditional branch - if true, displays "Congratulations" bubble text on exit (like after boss fight) 0x02024568: - jump to 0x0202457C (saves highscore but doesn't display "Highscore" bubble text) ____________________ - ASM resource for customising behaviour of player/objects/levels - NSMBe with direct overwrite feature |
dy |
| ||
Member Normal user Level: 13 Posts: 25/30 EXP: 8289 Next: 1978 Since: 04-02-18 Last post: 2506 days ago Last view: 2498 days ago |
Added above some ways to change the type of pause screen and text you get when exiting a level with a star in the above post. I've also realised that Black Brick Blocks share the same vtable and callbacks as orange Brick Blocks - the onAttacked callbacks checks the ActorID to determine what type of brick block it is and therefore whether it should break. The first post has been updated to reflect this.
Also, I've discovered that you can make Ice Blocks breakable by making the various onAttacked callbacks point to the corresponding callbacks for Brick Blocks instead (they normally point to dummy functions, so aren't breakable). Correct particle effects and everything!
To make them breakable: here To change which characters can break them, see "Brick Blocks / Black Brick Blocks: who can break" in the first post For replacing the vtable pointers, you can use my modified version of NSMBe (which allows you to directly overwrite code using the same syntax as when creating standard hooks). ____________________ - ASM resource for customising behaviour of player/objects/levels - NSMBe with direct overwrite feature |
Hiccup |
| ||
Normal user Level: 58 Posts: 805/815 EXP: 1574363 Next: 3183 Since: 09-06-12 Last post: 2020 days ago Last view: 98 days ago |
The reason the ice block breaking works with the shards may be because you technically can break them if you hack Giant Mario into the level and walk into one. |
dy |
| ||
Member Normal user Level: 13 Posts: 27/30 EXP: 8289 Next: 1978 Since: 04-02-18 Last post: 2506 days ago Last view: 2498 days ago |
Posted by Hiccup Yep, you're probably right. If you look at all the onKicked(), onPunched(), onGroundPounded(), etc functions for the Brick Block, you'll see that basically all they're doing is returning a pointer in r1 if the object should be broken. It gets that pointer by getting the address of the vtable for that object (the first four bytes at the object's address), adding 0x7C to that address, then getting the value from there. Looking at the commented out vtable structure in SM64DS_2.h, offset 0x7C would be the 31st function (InitResources being the 0th), which is the Kill() function. So looks like all it does is check whether the object should break, and if so, return the address of the object's Kill() function in r1. So yeah, they must have programmed IceBlock::Kill() to break with shards for if hit by Mega Mario. ____________________ - ASM resource for customising behaviour of player/objects/levels - NSMBe with direct overwrite feature |
FZone96 |
| ||
Newcomer Normal user Level: 5 ![]() Posts: 4/4 EXP: 408 Next: 121 Since: 02-01-18 From: Germany Last post: 2511 days ago Last view: 2444 days ago |
Is it possible to make a character run faster than Mario using this? |
pants64 |
| ||
![]() Red Koopa Normal user Level: 25 ![]() Posts: 81/125 EXP: 79851 Next: 9769 Since: 04-12-16 Last post: 72 days ago Last view: 4 days ago |
The check for max speed is somewhere around 020BF330. The instruction in that address is mov r0,r0,lsr 0Ch. If you want to double the max speed, change that instruction to mov r0,r0,lsr 0Bh and if you want to multiply it by four, change the instruction to mov r0,r0,lsr 0Ah and so on. This will affect all characters afaik. Please note that the acceleration will be the same, so it takes more time to reach the max speed.
Edit: This isn't the ideal way of doing this and it may have side effects. Maybe you should find the actual comparison of the max speed and current horzSpeed. |
dy |
| ||
Member Normal user Level: 13 Posts: 28/30 EXP: 8289 Next: 1978 Since: 04-02-18 Last post: 2506 days ago Last view: 2498 days ago |
Thanks StarPants - good to see others doing ASM research as well!
There is a 4 halfword data table which sets out the speed multiplier for each character, which affects both walk and run speeds (I found it earlier today but had been planning to look into how it interacts with carry speed and swim speed as well before I posted). Unfortunately not in front of my PC now, but will try post tomorrow (just a heads up so other people don't spend time unnecessarily trying to find it as well - this one was tricky). UPDATE Heh, StarPants - you actually got really close to finding the data table for movement speed. If you look at 0x020BF30C (just a few lines above the address you found), you'll see it gets the player charID, then loads r2 with a value from 0x020FF170 (plus an offset depending on the charID). The function at 0x020BF30C gets called a lot, with a different multiplier in r1 depending on whether it's determining the speed for running, walking, crawling, etc. This isn't character dependent, so if a character has a faster walking speed, it will have a faster running speed. Anyway, without further ado...
See here (including ceiling hang and slippery slide) Despite what many game guides say, all characters have the exact same acceleration and deceleration (and no, Luigi does not have a faster top speed than Mario). Also, thanks to Skelux's "Increase Acceleration" additional patch for the memory address re ground acceleration. Player: carry speed Regular and heavy objects: here Player: swim speed See here Player: jump power See here (including back flip, side flip and long jump) I've also figured out how to change the player's attack knockback power and throwing power, but these are all hardcoded differently for different objects - will upload these once I've finished looking into the different objects. ____________________ - ASM resource for customising behaviour of player/objects/levels - NSMBe with direct overwrite feature |
pants64 |
| ||
![]() Red Koopa Normal user Level: 25 ![]() Posts: 82/125 EXP: 79851 Next: 9769 Since: 04-12-16 Last post: 72 days ago Last view: 4 days ago |
I saw there was something going on in the registers but couldn't analyse it any further. I'm glad you got it.
unrelatedly: If anyone's doing a kaizo they can try to nop at 0x020BF330. I tried in first person and it felt pretty much like a motorbike without breaks. Never rode one irl though. |
dy |
| ||
Member Normal user Level: 13 Posts: 29/30 EXP: 8289 Next: 1978 Since: 04-02-18 Last post: 2506 days ago Last view: 2498 days ago |
Posted by StarPants Oops, I meant a few lines above at 0x20BF30C (I'll fix my above post). Took me a while to work out too - I find that using F7 in no$gba debugger to step through line by line and look at what's happening to the registers after each line, can help make sense of things when I'm struggling. Essentially this is what it's doing: ldr r2, [r0, 0x8] // r2 = 4 bytes at address (r0 + 0x8) = charID (0:M, 1:L, 2:W, 3:Y)
ldr r0, =0x020FF170 // r0 = 0x020FF170 and r2, r2, 0xFF // r2 = r2 bitwise AND 0xFF (seems unnecessary?) mov r2, r2, lsl 0x1 // r2 *= r2 (left shift 1 bit is effectively x2) = charID x2 ldrh r2, [r0, r2] // r2 = 2 bytes at address (0x020FF170 + charID x2) After that it gets to some mathsy stuff which I didn't really follow either. But yeah, nop'ing at 0x020BF330 stops it dividing the top speed (by what, something like 2^12?) but without changing acceleration/deceleration. So yeah... (It looks even funnier in 3rd person btw, because it speeds up some of the animations as well.) Also FYI - you can change data values in no$gba debugger by changing the instruction to "dcd 0xXXXXXXXX" (took me a while to work out), so you can test things like changing the speed table values on the fly. Don't use "dcd" with ASMPatchTemplate / devkitARM though - use ".word", ".hword", or ".byte" instead. ____________________ - ASM resource for customising behaviour of player/objects/levels - NSMBe with direct overwrite feature |
pants64 |
| ||
![]() Red Koopa Normal user Level: 25 ![]() Posts: 99/125 EXP: 79851 Next: 9769 Since: 04-12-16 Last post: 72 days ago Last view: 4 days ago |
Collecting a cap changes the real character:
Not very cleanly though |
Main - General SM64DS hacking - [ASM Resource] Customising behaviour of player/objects/levels | Hide post layouts | New reply |
Page rendered in 0.780 seconds. (2048KB of memory used) MySQL - queries: 29, rows: 231/231, time: 0.103 seconds. ![]() © 2005-2008 Acmlm, Xkeeper, blackhole89 et al. |