Banner
Views: 808,227,294
Time:
24 users online:  1UPdudes, AnasMario130, bacon_67_, bandicoot,  BTD6_maker, CalHal, DTA450, Forcepath,  FPzero, fsvgm777, Insanit, JamesD28,  KevinM, Mediocre Espurr, MORC,  Noivern, Nowieso, Ragey, Redwykelz, Sancles, SquidMan_Raps,  Tahixham, Vhack, wuffalo - Guests: 101 - Bots: 234 Users: 42,442 (2,001 active)
Latest: 00_marvelouschester_00
Tip: Do you want to create custom blocks, but have little to no experience with ASM? Use Kipernal's Blockreator!Not logged in.
Sprite/Block/HDMA/ASM Code Library
Forum Index - SMW Hacking - SMW Hacking Help - ASM & Related Topics - Sprite/Block/HDMA/ASM Code Library
Pages: « 1 2 3 4 5 6 7 8 9 10 » Thread Closed
Here's (sort of) a routine which the line guided sprites use to tell which Map16 block they're touching. (Line guides.)
They can be used with normal sprites too.

Quote
LDA $E4,x ; Get X low position of sprite
STA $02 ; store into $02
LDA $14E0,X ;
STA $03
LDA $D8,x ; Get y low position of sprite
STA $00 ; Store into $00
LDA $14D4,x ; Get y hi
STA $01 ; Store into $01
PHK
PEA Return-1
PHB
LDA #$01
PHA
PLB
PEA $90B7
JML $01D94D
Return:


After Return:, $1693 contains the Map16 number of the tile the sprite is touching.
Note: Does not contain high byte. If you want to be able to check high byte, use this routine instead:

Quote
LDA $E4,x ; Get X low position of sprite
STA $02 ; store into $02
LDA $14E0,X ;
STA $03
LDA $D8,x ; Get y low position of sprite
STA $00 ; Store into $00
LDA $14D4,x ; Get y hi
STA $01 ; Store into $01
LDA $00
AND #$F0
STA $06
LDA $02
LSR
LSR
LSR
LSR
ORA $06
PHA
LDA $5A
AND #$01
BEQ CODE_01D977
PLA
LDX $01
CLC
ADC $00BA80,X
STA $05
LDA $00BABC,X
ADC $03
STA $06
BRA CODE_01D989

CODE_01D977
PLA
LDX $03
CLC
ADC.l $00BA60,X
STA $05
LDA.l $00BA9C,x
ADC $01
STA $06

CODE_01D989
LDA.b #$7E
STA $07
LDX $15E9


[$05] contains the Map16 number now (you can load the value with LDA [$05]). If you want to get the high byte of the Map16 tables, do: INC $07 once, then LDA [$05].
The reason you can't do this with a simple jump to the original routine is because [$05] is used later in the routine for other things.

--------------------
--------> Don't follow "Find Roy's Dignity", my hack. Because it's pretty outdated. <--------
Great! I was wondering if you'd post that routine here. This will come in handy!

Just one question (or maybe two), though...you're saying that:

LDA [$05]

will load just the low byte of the Map16 tile into A, and:

INC $07
LDA [$05]

will load just the high byte, right? If I want to load them both at the same time, would this:

REP #$20
LDA [$05]

be the correct way to do it? In other words, to load both the low and high bytes, should I do exactly the same thing I would do to load the low byte alone, but in 16-bit mode?

Edit: Hmm, wait, that doesn't sound right...in a 24-bit pointer beginning at $05, $07 would contain the bank number, wouldn't it? So would the proper way to do it be this:

INC $07
LDA [$05]
XBA
DEC $07
LDA [$05]
REP #$20

?
No, that won't work. This should, however:
LDA [$05]
INC $07
XBA
LDA [$05]
REP #$20

--------------------
<blm> zsnes users are the flatearthers of emulation
Oh, yeah...because it's little-endian. Okay, I have another question: Does that get the "acts like" setting or the actual tile? If I put, say, CMP #$0130 BEQ ... after the REP #$20, would the tile have to actually be tile 130 for the code to branch, or would it just have to act like tile 130?
It would have to be tile 130.

--------------------
<blm> zsnes users are the flatearthers of emulation
Originally posted by Alcaro
No, that won't work. This should, however:
LDA [$05]
INC $07
XBA
LDA [$05]
REP #$20


Actually I think that would have to be:

LDA [$05]
INC $07
XBA
LDA [$05]
XBA
REP #$20

Or

INC $07
LDA [$05]
XBA
DEC $07
LDA [$05]
REP #$20

Since you're first loading the low byte, putting it to the upper 8 bits of the Accumulator and then you load the high byte, which is, of course, wrong. Then you'd have to do CMP #$3001 and while that might not be a disaster, it's still not really convenient. (With BEQ it would work, but you would get problems with BCC and BCS for example.)

--------------------
--------> Don't follow "Find Roy's Dignity", my hack. Because it's pretty outdated. <--------
Not that I would expect anyone to have it, but does anyone happen to have the code for the regular turn block?

--------------------
Userbar

View my YouTube channel here!
View my website here!
Originally posted by I8Strudel
Not that I would expect anyone to have it, but does anyone happen to have the code for the regular turn block?

This thread is actually for routines you can put in your ASM file for a effect, but I can try to point you in the right direction.
Previously I have done a little work looking for the block codes and I remember finding the door code at $00EC1A. Looking around there may help. You'd also want to perhaps find a pointer, which is how the blocks are probably handled.
Here's an interesting routine that works with sprites:

Quote

LDA $1A ; \ set x position of screen boundary to block (low byte)
STA $9A ; /
LDA $1B ; \ set x position of screen boundary to block (high byte)
STA $9B ; /
LDA $1C ; \ set y position of screen boundary to block (low byte)
STA $98 ; /
LDA $1D ; \ set y position of screen boundary to block (high byte)
STA $99 ; /


With this routine, it's posible to create blocks set to the screen position.

To adjust the position of the blocks, it will have to be like this:

Quote

LDA $1A ; \ set x position of screen boundary to block (low byte)
CLC ; |
ADC #$xx ; |
STA $9A ; /
LDA $1B ; \ set x position of screen boundary to block (high byte)
ADC #$00 ; |
STA $9B ; /
LDA $1C ; \ set y position of screen boundary to block (low byte)
CLC ; |
ADC #$xx ; |
STA $98 ; /
LDA $1D ; \ set y position of screen boundary to block (high byte)
ADC #$00 ; |
STA $99 ; /


In #$xx you can experiment with values like 10, 20, 30, etc.
Originally posted by Some sprite I'm making
LDA $D8,x
STA $08
LDA $14D4,x
STA $09
LDA $E4,x
STA $0A
LDA $14E0,x
STA $0B
LDA $13E8 ; \ Check if cape attack is used.
BEQ NoInteract ; / If not, don't interact.
REP #$20 ; A = 16-bit.
LDA $08 ; \ $08 = Sprite Y Pos.
SEC ; | Subtract cape Y pos from it...
SBC $13EB ; | ...and check if cape is in range of sprite
CLC ; |
ADC.w #$0008 ; |
CMP.w #$0010 ; |
SEP #$20 ; A = 8-bit.
BCS NoInteract ; / If difference too big, don't interact.
REP #$20 ; A = 16-bit.
LDA $0A ; \ Now do the same thing, except for the X positions.
SEC ; |
SBC $13E9 ; |
CMP.w #$0010 ; |
SEP #$20 ; A = 8-bit.
BCS NoInteract ; / If difference too big, don't interact.
; Insert interaction code here
NoInteract
; Insert non-interaction code there.


This is a routine that checks for cape interaction. I know there is already a link to a cape interaction thing, but since the Wiki is broken (ok, there is a backup, but it's not quite as easy...) I decided to post mine here. Not sure how much it differs.

--------------------
--------> Don't follow "Find Roy's Dignity", my hack. Because it's pretty outdated. <--------
There is already a routine that checks for sprite/cape collision here, which is in the sprites section for some reason.

Anyway, since I was bored, I decided to create a couple of patch templates. This should also help people to easily create patches if they're new to ASM but can't do routine hacking.

Run every frame in a level.
Hurt routine hijack.

The first one will be run every frame inside a level, and you must end your code with an RTL since the routine is accessed through a JSL.

The second one hacks the hurt routine so that you can put your custom code there, and must also be returned with an RTL. I was too lazy to make a death routine template, though.

This is a routine that will convert a RAM Address from displaying hexadecimal on the status bar to decimal. It's useful for custom counters on the status bar.

This is a routine that will draw a sprite's position to Mario's exact position. To shift it around, you can add/subtract after loading Mario's X/Y low/high byte, and then storing to the sprites X/Y low/high byte. Dispari gave me this, and I figured it would be helpful to post it here so credit should be given to her for this routine.
2 submissions:
DigDiv:
divides out digits. useful if you want to display a number somewhere onscreen.
Note: Value output in Hex. I'll code one for decimal input later.
click

BitCheck:
Finds the first(lowest) bit in a number. useful for nearly all binary using code.
Note: Only finds 1st bit No plans on modifying it.
click
That is all.

--------------------
*WARNING: due to cosmic radiation, Quantum fluctuations, or earth going into sector x79352C, the world may end at any moment. Have a nice day.

Current Project:



Status:Complete

Previous project status: Failed/Quit

Current Issue

C++ : fsteam help



Originally posted by Iceguy
There is already a routine that checks for sprite/cape collision here, which is in the sprites section for some reason.


I see. I do not think that is the appropiate place to put it in, so I'm going to move it to the file bin.

--------------------
--------> Don't follow "Find Roy's Dignity", my hack. Because it's pretty outdated. <--------
I have two subroutines that I made myself that I would like to share. (I think they both work; I've used both of them in sprites, anyway.)

1) Extra-bit-change-cfg

This subroutine changes the settings of a sprite's .cfg file if the extra bit is set. Currently, it changes only the palette and extra property bytes, but more can be added. This should be JSR'd to in the INIT routine.

XxPp1 = $xx
XxPp2 = $xx
PaletteBits = $xx (replace the xx with actual numbers)

LDA $7FAB10,x ;
AND #$04 ; if the extra bit isn't set...
BEQ DontChangeCfg ; don't change the .cfg settings
LDA #XxPp1 ;
STA $7FAB28,x ; set the extra property 1
LDA #XxPp2 ;
STA $7FAB34,x ; set the extra property 2
LDA $166E,x ; load palette and GFX page info
AND #$F1 ; clear out ccc bits
ORA #PaletteBits ; set new palette
STA $15F6,x ; store new palette
DontChangeCfg: ;
RTS

Version without the extra property bytes:

LDA $7FAB10,x ;
AND #$04 ; if the extra bit isn't set...
BEQ DontChangeCfg ; don't change the .cfg settings
LDA $166E,x ; load palette and GFX page info
AND #$F1 ; clear out ccc bits
ORA #PaletteBits ; set new palette
STA $15F6,x ; store new palette
DontChangeCfg: ;
RTS

2) 16-bit pointer subroutine

Yes, I know there is already a 16-bit pointer subroutine in the original SMW (at $0086DF; JSL to it), but I'm pretty sure you can't put more code after the pointer table, which was a problem for me. This subroutine is designed so that you can JSR to it, it will jump to a label, and when it returns, you can still put more code after the JSR to this subroutine. (A, of course, should have the index for the pointer table.)

PointerTable:
dw Label1,Label2,Label3,Label4,Label5,Label6 ; this table can be any length, and you can change the labels to whatever you want.

PHX ; preserve X, because there is a very likely chance that it is already being used
ASL A ; multiply the base value to get the desired index
TAX ; put the resulting value into X
REP #$20 ; set A to 16-bit
LDA PointerTable,x ; load value from pointer table
STA $0A ; and store that to scratch RAM
SEP #$20 ; set A back to 8-bit
PLX ; pull X register back
JMP ($000A) ; jump to address that was stored

I thought this thread would be a good place to put these two subroutines.

Edit: Here's another one. I don't think it's important enough to warrant a new reply, so I'll just add it to this post.

After this short subroutine, the accumulator will be nonzero if a sprite is touching a wall in the direction it is facing.

3) Direction/wall check

LDA $157C,x
INC
AND $1588,x
RTS
I don't like having a signature.

So I'll just link these here.

Need to check sprite on sprite collision? Here's some examples.
http://bin.smwcentral.net/5166/PseudoArcTangent_AimRoutine.txt
Here's the tracking/aiming used in my YI Blowhard sprite. It can be adapted for firing at Mario, staring at Mario, following Mario, and probably many other things. Unfortunately, I never bothered to comment it.

EDIT: keep in mind that this doesn't handle "gradual movement". That's a separate piece of code in the Blowhard.
Kaijyuu: I've actually heard that there was a problem with those subroutines. Apparently, once the index in the loop matched that of the original sprite's index, it would count as being in contact with a sprite, even though the "other" sprite was merely itself. But putting a CPY $15E9 BEQ NextSprite should fix that, shouldn't it?
Honestly never checked. You might be right if nothing's done in the sprite clipping routines to check for that.
Here is a code to determine which top corner of a custom block you are touching. To be used with BTSD's new Corner Offsets feature.

Code
LDA $9A
AND #$08
BNE Rightcorner
*code for left corner here*


The code branches when Mario touches the right corner. If it doesn't branch, it touches the left corner. Since BTSD doesn't have a 'left corner' or 'right corner' feature, I felt like 'emulating' one myself.

--------------------
My blog. I could post stuff now and then
Originally posted by Ersanio
To be used with BTSD's new Corner Offsets feature.


That example I showed you is just a generic example you can apply to anything, be it sides offsets, spriteV/spriteH (but don't use $9A that's Mario's contact point) or any of that. The contact position is valid for any offset. Ofcourse $9A applies to X contact only, not Y contact (that's $98).

edit: added a simple time conversion routine if anyone ever has to read time and treat it like any other value rather than dealing with decimal digits aross 3 bytes.
Pages: « 1 2 3 4 5 6 7 8 9 10 » Thread Closed
Forum Index - SMW Hacking - SMW Hacking Help - ASM & Related Topics - Sprite/Block/HDMA/ASM Code Library

The purpose of this site is not to distribute copyrighted material, but to honor one of our favourite games.

Copyright © 2005 - 2020 - SMW Central
Legal Information - Privacy Policy - Link To Us


Total queries: 7

Menu

Follow Us On

  • YouTube
  • Twitch
  • Twitter

Affiliates

  • Super Mario Bros. X Community
  • ROMhacking.net
  • Mario Fan Games Galaxy