Language…
18 users online: aaa,  Alex, caioskii, DavitheHuman, E-man38, FrozenQuills, Fullcannon, itsmefigs, LuigiTime, Mastered UI - KooLexx, Nextalis,  sincx, sniktak, SteamyPanini, Teaser, VinylHeart, yogui, Zavok - Guests: 72 - Bots: 572
Users: 54,993 (2,186 active)
Latest user: Doomkid

Activate ASM after clearing a specific level

Hi all! Hope you're all having a great day. I've recently begun working on a hack again after dropping it for about 5 years, and I've got a question.

Would it be possible, either through UberASM or otherwise, to have a patch only activate after clearing a specific level? The example I had in mind would be to disable spinjumping in the game, but after beating the final level of the first world, it gets enabled again.

Is this possible in any way? I've been envisioning my hack to be more RPG-like than the original game, and would absolutely love to be able to have abilities unlocked as you progress through the game. I know next to nothing about writing ASM myself, and certainly don't want to ask someone to do it for me, but I'm not sure if what I'm asking is even possible by any means! I appreciate any answers someone might be able to provide, and thank you in advance. Cheers!
Try this UberASM code in all of the world one levels:
Code
 LDA $18
	AND #$80
	TSB $16
	TRB $18
	RTS
Originally posted by Neeberz
Try this UberASM code in all of the world one levels:
Code
 LDA $18
	AND #$80
	TSB $16
	TRB $18
	RTS

Thank you for your reply! Correct me if I'm wrong, but that would simply disable spinjumping in world 1, right? I should've worded my example a little better; the general idea is the player can earn abilities at different points in the game and then be able to go back to previous levels and utilize them to find secret exits and easter eggs. So lets say in the first level there's an area you can't reach except by walljumping, but you wouldn't actually "learn" that technique until beating the boss of world 2, or something.
Originally posted by KDJewl
So lets say in the first level there's an area you can't reach except by walljumping, but you wouldn't actually "learn" that technique until beating the boss of world 2, or something.


The easiest way to get what you want is to simply run the ability code if a flag has been set. It's dead simple with Uberasm.
Set aside a byte or two of freeram then simply define each bit to be a flag for a specific ability you want Mario to have.
i.e. if you have code to allow mario to double jump and to wall jump, the double jump bit could be bit 0 and the wall jump code could be bit 1
Then you just set the correct bit when the specified level is beaten. In your uberasm code, you could have each ability be a piece of 'libray' code, and in the gamemode code, you only jump to the ability code if the correct bit is set.
Potentially something like this:
Code
; gamemode_14.asm
main:
LDA $70 	; say this is your freeram
BIT #$01	; you've defined this bit as your 'walljump' bit
BNE .wallkick
JSL MarioWallJump_Main
.wallkick
BIT #$02	; you've defined this bit as your 'double jump' bit
BNE .out
JSL MarioDoubleJump_Main
.out
RTL


You do have to ensure the RAM you chose is loaded/saved into SRAM though, but this is much easier to manage with a patch like SRAM plus (or BW-RAM plus if you're using SA-1)
Originally posted by meatloaf
Originally posted by KDJewl
So lets say in the first level there's an area you can't reach except by walljumping, but you wouldn't actually "learn" that technique until beating the boss of world 2, or something.


The easiest way to get what you want is to simply run the ability code if a flag has been set. It's dead simple with Uberasm.
Set aside a byte or two of freeram then simply define each bit to be a flag for a specific ability you want Mario to have.
i.e. if you have code to allow mario to double jump and to wall jump, the double jump bit could be bit 0 and the wall jump code could be bit 1
Then you just set the correct bit when the specified level is beaten. In your uberasm code, you could have each ability be a piece of 'libray' code, and in the gamemode code, you only jump to the ability code if the correct bit is set.
Potentially something like this:
Code
; gamemode_14.asm
main:
LDA $70 	; say this is your freeram
BIT #$01	; you've defined this bit as your 'walljump' bit
BNE .wallkick
JSL MarioWallJump_Main
.wallkick
BIT #$02	; you've defined this bit as your 'double jump' bit
BNE .out
JSL MarioDoubleJump_Main
.out
RTL


You do have to ensure the RAM you chose is loaded/saved into SRAM though, but this is much easier to manage with a patch like SRAM plus (or BW-RAM plus if you're using SA-1)

Whoa, thank you! This is really interesting! Now I'm quite new at all of this, so I hope you don't mind if I pick your brain more about it. I understand that if I wanted the code to trigger after level 105 was beaten, I'd have to check address $1ECB. Unfortunately I don't really know where to go from there. Other than very basic loading and storing values to addresses, its all quite foreign to me. I do understand if its inappropriate of me to ask for a step-by-step to all of this, though! I hate being that guy.
Originally posted by KDJewl

Whoa, thank you! This is really interesting! Now I'm quite new at all of this, so I hope you don't mind if I pick your brain more about it. I understand that if I wanted the code to trigger after level 105 was beaten, I'd have to check address $1ECB. Unfortunately I don't really know where to go from there. Other than very basic loading and storing values to addresses, its all quite foreign to me. I do understand if its inappropriate of me to ask for a step-by-step to all of this, though! I hate being that guy.


>$1ECB
Sure, you could use this, and run some overworld 'init' code that sets the bytes depending on what level was beaten. You'd need an easy way to determine what level Mario is on top of/just came out of. There may be a RAM address for that, but it might be troublesome to find (I don't know where it would be, myself).

What I think would be much easier is to just modify the sprite that ends your level to conditionally write the byte(s) you define as freeram as it's ending the level.
For example, if you grab the goal sphere disassembly hosted on the site, you can edit the cfg (or json) file with PIXI's cfg editor to give it an extra extended byte, which PIXI indexes for you with the `!extra_byte_1' define...You can then simply edit the sprite to then logical OR the value into your defined freeram if its non zero when Mario collects the goal sphere. Furthermore, this way you're not tied to specific level numbers (which makes your life a lot easier if you decide to shuffle things around for whatever reason).
If it's a boss you want to yield the ability, you can do the exact same thing except simply put the requisite code in its death routine.

Even further, you can use something like Objectool to easily create custom objects that grant Mario these abilities permanently.
Originally posted by meatloaf
Originally posted by KDJewl

Whoa, thank you! This is really interesting! Now I'm quite new at all of this, so I hope you don't mind if I pick your brain more about it. I understand that if I wanted the code to trigger after level 105 was beaten, I'd have to check address $1ECB. Unfortunately I don't really know where to go from there. Other than very basic loading and storing values to addresses, its all quite foreign to me. I do understand if its inappropriate of me to ask for a step-by-step to all of this, though! I hate being that guy.


>$1ECB
Sure, you could use this, and run some overworld 'init' code that sets the bytes depending on what level was beaten. You'd need an easy way to determine what level Mario is on top of/just came out of. There may be a RAM address for that, but it might be troublesome to find (I don't know where it would be, myself).

What I think would be much easier is to just modify the sprite that ends your level to conditionally write the byte(s) you define as freeram as it's ending the level.
For example, if you grab the goal sphere disassembly hosted on the site, you can edit the cfg (or json) file with PIXI's cfg editor to give it an extra extended byte, which PIXI indexes for you with the `!extra_byte_1' define...You can then simply edit the sprite to then logical OR the value into your defined freeram if its non zero when Mario collects the goal sphere. Furthermore, this way you're not tied to specific level numbers (which makes your life a lot easier if you decide to shuffle things around for whatever reason).
If it's a boss you want to yield the ability, you can do the exact same thing except simply put the requisite code in its death routine.

Even further, you can use something like Objectool to easily create custom objects that grant Mario these abilities permanently.

I've been tinkering around all afternoon with a few of the methods you've outlined and have come to the conclusion that I simply lack the overall ASM knowledge to get this to happen haha. I really appreciate everything you've said, though! I'm going to keep all this and come back to it if I can teach myself a little more about all of this stuff. Hopefully I haven't wasted too much of your time with all of this! You've given me insight into a few different options and that by itself is a heck of a lot more than I started with haha!