Language…
21 users online: crocodileman94, DanMario24YT, Domokun007, GamesInTweed, Green, GRIMMKIN, Heitor Porfirio, iRhyiku, Knetog, LightAligns, Maw, Nayfal, ocked, PMH, RZRider, Silver_Revolver, SMW Magic, test212, TheXander, VSmario90, yoshiatom - Guests: 299 - Bots: 321
Users: 64,795 (2,374 active)
Latest user: mathew

Official Hex/ASM/Etc. Help Thread

  • Pages:
  • 1
  • 2
  • 3
  • 4
  • 5
  • 407
  • 408
  • 409
  • 410
  • 411
  • 412
  • 413
  • 414
  • 415
  • 416
  • 417
  • 418
  • 419
  • 420
I recommend you to move PHX</ocde> and PHY</ocde> in front of %sprite_block_position() because the routine at $07FC3B, which is called afterwards, is using Y and Y is also used to determine the high byte i.e. page of the Map16 acts like, causing the block to act like tile 125 (I assume the normal acts like is tile 25).
Unexpected end tag (</ocde>) at 40, expected </code>
Unexpected end tag (</ocde>) at 61, expected </code>
Tag (code) was not closed.
Tag (code) was not closed.
Fixed, thanks a lot for your help #smw{:TUP:}
My 1st romhack in progress (testing avaiable)...
(beta)
I am trying to make a sprite that does something a few seconds after touching it but I've ran into a problem that I can't seem to fix. For some reason, the timer only works if you stay inside the sprite.

Code
	JSL $01A7DC|!BankB
	BCC Return

	INC !1602,x			; set timer
	LDA !1602,x			; load timer
	CMP #$20			; \ branch when it reaches a set value
	BNE ++				; /


Can someone explain what I'm doing wrong?
Don't eat the sandwich
Originally posted by RollingRigatonis
Code
	JSL $01A7DC|!BankB
	BCC Return

This branch means that everything between it and the "Return" label only runs when you touch the sprite. (Apparently including all your timer and effect code.)

Try something like this instead:
- use a timer that counts down until it reaches zero, then stays at zero. (There are a handful of unused sprite addresses that have this behavior already built in.)
- when you touch the sprite, and the timer is zero, set it to some value (e.g. #$20). This is the only thing you need in your "when you touch the sprite" section.
- when the timer is at 1, do the thing you want. This check should run all the time, not only when you touch the sprite. The reason you check for 1 instead of 0 is to make sure the thing is only done for one frame.


 
I don't know if anyone can help me, but I wanted to put the "Kirby Bomb Blocks" interaction (the Bomb Block exactly) to explode when Mario touches it from above, but I don't know how to do that as much as knowing ASM. In my hack I wanted to do like a cutscene where Mario falls off a fake bridge into a hole, and teleports him to a cave. Thank you very much!
I know making a Custom Boss isn't ideal for someone who's getting into ASM but a last here I am, I'm assuming it has something to do with "BEQ" as there's nothing to match it with. Edit: Nvm I fixed it.


Code
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Koopa/Bowser final boss for K3SH2, done by Idyllic/Picayune.
; Start date 8/17/2022.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

!Deafeat = $1C ; music to play after koopa dies and the score rolls.

print "INIT ",pc
print "MAIN ",pc
JSR Bossmaincode
RTL

Bossmaincode:
JSR BootlegGraphics

LDA #$00
%SubOffScreen()


JSL $01A7DC
BEQ TehGoat

TehGoat:
JSL $03A6C8
LDA #$FF
STA $1493
LDA #!Deafeat
STA $1DFB
STA $13C6
LDA #$FF
RTS

BootlegGraphics:
%GetDrawInfo()



My Favorite Nu-Metal Albums For You!! (Spotify Links).

W3Schools W3Schools W3Schools W3Schools W3Schools W3Schools


As Of 1/28/2024.
Complete noob question, but I've been trying to find/make a block that can only be destroyed by throw blocks.

All similar blocks I've found on the site aren't really what I'm looking for. Some have throw blocks pierce them, which I don't want, and all of them act strangely whenever you toss a throw block up into them (destroys the blocks, pierces, and doesn't get rid of the throw block).

I'm just looking for a block that will break whenever a throw block is kicked into it, having the throw block break as well. I also wouldn't want the throw block to break anymore than a singular block. And if you kick a throw block upwards, it will break both the block and the throw block.

If this is already a thing someone's uploaded I'm sorry, but it would be amazing if someone could either link me an already existing block, or help me with the coding. I've tried blockreator but for some reason I just can't get what I want down : /
Progress Update!!
Not sure if people check this thread anymore but I've ran into a problem and I have no idea how to fix it or if it is even possible to fix it, using the layer 3 tides seems to break the player's collision with layer 1. If the player is big and ducks into a one block high opening, they will glitch through the ground instead of being pushed out like normal. I've also noticed that it does this when interactive layer 2 is enabled too, which I am also using quite a bit.
I hardly know anything about ASM and I can't find any info about this anywhere so I was hoping someone would help me in fixing this if its possible, I don't want to have to cancel something I've spent two whole years working on nor do I want to release a severely broken hack.
Don't eat the sandwich


Originally posted by RollingRigatonis
Not sure if people check this thread anymore but I've ran into a problem and I have no idea how to fix it or if it is even possible to fix it, using the layer 3 tides seems to break the player's collision with layer 1. If the player is big and ducks into a one block high opening, they will glitch through the ground instead of being pushed out like normal. I've also noticed that it does this when interactive layer 2 is enabled too, which I am also using quite a bit.

As far as I know there is no existing patch fix to this, it's just the way interaction works, likely due to RAM addresses used when processing one layer not accounting for already having a value from processing the other layer. When using an interactable Layer 2 though, you can at least somewhat fix the issue by just overlapping solid Layer 1 and Layer 2 tiles on top of each other; it's not perfect (will cause Mario to just straight up die if he spinjumps in a one-tile space), but it'll fix the movement issues from having only Layer 1 or Layer 2 tiles.

Other than that, I'd recommend redesigning your levels to avoid one-tile-high ceilings if you can avoid it, or if you want to create small-Mario-only passageways then use a damaging ceiling like spikes.

Professional frame-by-frame time wizard. YouTube - Twitter - SMW Glitch List - SMW Randomizer
I tried looking through the collision code $00ED28 and was able to make a patch for Layer 2:
Code
org $00ED16
db $B0,$12

org $00ED1A
db $EA,$EA

org $00ED28
db $EA,$EA


This seems to fix the issues I was having, but it created a new problem where the the player clips through the ground if Layer 2 is moving.

EDIT: Nevermind, after fiddling with it some more I was able to make a patch that fixes this problem too:
Code
org $00ED1A
db $EA,$EA

org $00ED28
db $A4,$79

Don't eat the sandwich
I'm trying to use Darolac's Ultimate Boom-Boom Boss Sprite but it's not working properly.

I put the extra bits 2 and 3, I put whatever extension that have in the ReadMe file, but it doesn't work as it should.
He just walks around hitting the walls.

I forgot something maybe in the ASM file?

EDIT: Solved!
I'm trying to make a version of dry bones that will jump across ledges, I've found the area I think is responsible for turning the sprite around when it is at a gap (NotOnGround), but I'm not sure how exactly to make it jump. I had asked this a few years ago and someone suggested to just set the y speed to a negative value but I don't know how to do this.

Code
NotOnGround:

STZ $1570,x		;
LDA $1510,x		;
BEQ NoUpdate		; skip the next part if the sprite acts like 30

LDA $C2,x		;
BNE NoUpdate		;
INC $C2,x		;

JSR FlipSpriteDir		; flip the sprite's direction
JSL $818022		; update sprite X position without gravity...
JSL $818022		; twice


I'm assuming it'll involve replacing "FlipSpriteDir" with the bit to throw the sprite upwards but still I don't know what exactly to do.
Originally posted by Rammy
I'm assuming it'll involve replacing "FlipSpriteDir" with the bit to throw the sprite upwards but still I don't know what exactly to do.

Yeah, it should just be a matter of replacing "JSR FlipSpriteDir" with "LDA.b #-$30 : STA $AA,x" (you can change -$30 to the value you like).
Originally posted by Kevin
Originally posted by Rammy
I'm assuming it'll involve replacing "FlipSpriteDir" with the bit to throw the sprite upwards but still I don't know what exactly to do.

Yeah, it should just be a matter of replacing "JSR FlipSpriteDir" with "LDA.b #-$30 : STA $AA,x" (you can change -$30 to the value you like).


Yep works flawlessly, really don't get how it wouldn't work before.
Though now I'm seeing a new issue. The sprite seems to be grabbing tiles from the wrong page, how can I fix this?


This would depend on how the sprite's graphics routine is written, specifically with any writes to "$0303,x", which refers to a sprite tile's YXPPCCCT data. Specifically, the graphics page comes from the T bit.

Assuming you're using this disassembly of the Dry Bones, you'll find the reference to that address looks like this:

Code
LDA TileProp,x	; palette, GFX page, and X flip
ORA $64		; add in sprite priority settings
STA $0303,y	; set the tile properties

$64 is just a general RAM address used to help with controlling the PP bits of the YXPPCCCT settings for various sprites, so the T bit comes from the TileProp table referenced here. That table, at least in the version of the sprite on the site, looks like this:

Code
TileProp:
db $43,$43,$43,$03,$03,$03


Since each of these values are odd, that means the T bit is already set for them. So if you are using the disassembly, the fact that you're seeing the other graphics page means either you changed the values in this table at some point (or edited the graphics routine), or something else strange is going on.

Professional frame-by-frame time wizard. YouTube - Twitter - SMW Glitch List - SMW Randomizer
Originally posted by Thomas
Since each of these values are odd, that means the T bit is already set for them. So if you are using the disassembly, the fact that you're seeing the other graphics page means either you changed the values in this table at some point (or edited the graphics routine), or something else strange is going on.


Something else is going on then as the only thing I've directly changed in this sprite was the NotOnGround routine. I tested in a clean rom and the same thing still happens. Normal dry bones and some dry bones edits that were posted here, such as the ones that throw the bones in an arch, aren't affected either in case you were wondering. Should I try to change the table?

Here's the full sprite in case you want to try and dig around in it:
drybone.asm
drybone.cfg


Hm, I don't see anything noticeably wrong in the code, so you'd probably need to check in an actual debugger.

If you're not familiar with ASM debuggers, I recommend either Mesen-S or bsnes-plus, which are two emulators with debugging suites built in. Here's Mesen-S's, for instance:



One of the useful features with the debuggers for these emulators is that both support using the WDM opcode (which functionally does nothing) as a breakpoint. So you can insert that opcode into the code where you want to debug (i.e. the graphics routine), and the debugger will automatically trigger when the code reaches that line. From there you can check the values and indexing that the code actually ends up doing, to try and figure out where the weird values are coming from.
(In Mesen-S, the option to enable the WDM breakpoint is in the menu under Options -> Break Options -> Break on WDM)

Professional frame-by-frame time wizard. YouTube - Twitter - SMW Glitch List - SMW Randomizer
I'm not familiar with debuggers at all, what exactly should I be looking for?


When a breakpoint is hit, the game will pause and you can manually step through the code currently executing in the debugger with the control buttons at the upper left.

You can see the current state of the registers, such as the accumulator and X/Y indices, in the top right. You can also see the state of specific RAM addresses in the debugger itself; for instance, this line shown in the screenshot:
Code
INC $19 [$000019] = $01

is indicating that the RAM address $19 is currently $01 as of the line the debugger is currently at.


With that information, you can check that the values being obtained and written in the code actually line up with what you are expecting. In particular, a few things you'll want to confirm:

1) That the X index being used to get a value from the TileProp table is actually within the range of that table (i.e. it is between 00 and 05). This may indicate an issue with the way the index is being obtained. If you are getting bad values, check that the value of $157C (the sprite's direction) is only either 00 or 01; any other values will cause incorrect indices.

2) That the values being obtained from the TileProp table actually match up with the values you have in the code. If not, check whether the data bank is set correctly (the "D" register in the CPU view). It should match the bank the code is currently running in; if it doesn't, that bank isn't being properly set, so the code ends up using a different ROM address than the one you're actually expecting it to be.

3) That the Y index used to index the OAM data hasn't been changed. It should be the same value for each of the $0300/$0301/$0302/$0303 addresses, and the value itself should be a multiple of 04 in hex (i.e. [x0], [x4], [x8], or [xC]). If it's not a multiple of 4, then the OAM data is misaligned for some reason.

4) That the OAM data isn't being overwritten by something else. You can do this by setting a breakpoint on the specific address the YXPPCCCT settings are being written to (the 24-bit address shown in light blue by the debugger). When you press the "continue" button in the top left (the play button), the code will skip until the next breakpoint is hit, i.e. when the RAM address gets written to again.

This isn't an all-encompassing list of potential causes, but it'll give you a starting point on what to look for. Basically, just look for anything that doesn't match up with how the code seems like it should be executing.

Professional frame-by-frame time wizard. YouTube - Twitter - SMW Glitch List - SMW Randomizer


When a breakpoint is hit, the game will pause and you can manually step through the code currently executing in the debugger with the control buttons at the upper left.

You can see the current state of the registers, such as the accumulator and X/Y indices, in the top right. You can also see the state of specific RAM addresses in the debugger itself; for instance, this line shown in the screenshot:
Code
INC $19 [$000019] = $01

is indicating that the RAM address $19 is currently $01 as of the line the debugger is currently at.


With that information, you can check that the values being obtained and written in the code actually line up with what you are expecting. In particular, a few things you'll want to confirm:

1) That the X index being used to get a value from the TileProp table is actually within the range of that table (i.e. it is between 00 and 05). This may indicate an issue with the way the index is being obtained. If you are getting bad values, check that the value of $157C (the sprite's direction) is only either 00 or 01; any other values will cause incorrect indices.

2) That the values being obtained from the TileProp table actually match up with the values you have in the code. If not, check whether the data bank is set correctly (the "D" register in the CPU view). It should match the bank the code is currently running in; if it doesn't, that bank isn't being properly set, so the code ends up using a different ROM address than the one you're actually expecting it to be.

3) That the Y index used to index the OAM data hasn't been changed. It should be the same value for each of the $0300/$0301/$0302/$0303 addresses, and the value itself should be a multiple of 04 in hex (i.e. [x0], [x4], [x8], or [xC]). If it's not a multiple of 4, then the OAM data is misaligned for some reason.

4) That the OAM data isn't being overwritten by something else. You can do this by setting a breakpoint on the specific address the YXPPCCCT settings are being written to (the 24-bit address shown in light blue by the debugger). When you press the "continue" button in the top left (the play button), the code will skip until the next breakpoint is hit, i.e. when the RAM address gets written to again.

This isn't an all-encompassing list of potential causes, but it'll give you a starting point on what to look for. Basically, just look for anything that doesn't match up with how the code seems like it should be executing.

Professional frame-by-frame time wizard. YouTube - Twitter - SMW Glitch List - SMW Randomizer
  • Pages:
  • 1
  • 2
  • 3
  • 4
  • 5
  • 407
  • 408
  • 409
  • 410
  • 411
  • 412
  • 413
  • 414
  • 415
  • 416
  • 417
  • 418
  • 419
  • 420