They have a point Dinoguy. You're really getting annoying, with the lame posts you make and the PMs you've sent me and my friends asking for custom sprite requests. Learn some tact, and better grammar while you're at it, before I burst a blood vessel. Not too much to ask.
Anyway, status update:
Sprite's about 1/3 coded. I was on a spree tonight, still am. I was gonna just test parts of him at a time as I code them, but decided no it's better I just finish it up all at once. The fact that it'll be more complex to debug doesn't phase me a bit; the Debugger can solve
ANY problem that comes up, if TRASM.exe doesn't alert me of them first.
Roy taught me a new technique for this sprite: I finally got to use Indirect Indexing, via "JMP (abs, x)"! If you don't know what that means in ASM terms, let me explain it: imagine a JMP command that uses a Table and X Reference to decide where to JMP to, and every value on the Table is a Label name that appears somewhere in the .ASM file. It's pretty freaking sweet.
It's actually pretty fun to code this sprite! I coded a routine at the beginning that branches to 1 of like 20 different MAIN routines depending on what a particular Ram address is (that's what needed the "JMP (abs, x)"), and I'm currently just coding each individual routine jumped to by that. Each routine is rather small too.
Also, I coded a subroutine that a couple of those "action routines" will use, which locks the sprite's Y position on Mario. But this doesn't mean the sprite's Y position permenantly = Mario's Y position. Instead it sets the sprite's Y speed higher or lower depending on how far away it vertically is from Mario, so rather than snapping to his Y position it smoothly slides up or down to match his level.
And here's the routine:
Code
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Vertical Lock-On Subroutine ;
; When called every frame, sprite will vertically stay locked onto ;
; Mario's Y position. ;
; Copy+Paste SUB_VERT_POS from the Subroutine Library somewhere in ;
; your code. ;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
t_EOR:
db $FF,$00
SUB_LOCKONY:
JSR SUB_VERT_POS ; "Y" now has 00 if sprite above Mario or 01 if below Mario
LDA $14D4,x ; \
XBA ; | get sprite relative position to Mario
LDA $D8,x ; | (uses 16-bit "A" momentarily)
REP #$20 ; |
SEC ; |
SBC $D3 ; |
SEP #$20 ; /
EOR t_EOR,y ; reverse if needed-- makes value a positive value
LSR A ; divide by 2
EOR t_EOR,y ; \ value's +/- is now opposite of whatever it started as
EOR #$FF ; /
STA $AA,x ; store to sprite Y speed. Now it vertically stays locked on to Mario.
RTS ; return
This routine hasn't been tested and might not work though, so if using it, caution is advised.
If it works though, it should be pretty awesome. The Master Hand sprite uses this during it's Flick Counterattack, and also when it aims before firing his Energy Gun attack.
Edit: Okay, check this out. I wrote a modified version of the Custom Sprite Generation Subroutine by smkdan... It's an alternative method I'm gonna try using for all my future custom sprites. This Routine is adapted so that you can have one sprite generate whatever sprite you want based on a Ram address instead of a Defined variable.
Code
; Generate Custom Sprite Subroutine
;
; When called, $04 should have custom sprite number to generate.
; $05-$06 should have X offsetting (to the right),
; and $07-$08 should have Y offset. (Both offsettings are Long.)
; X and Y speed etc. should be called from the generated sprite code.
; Generated sprites do NOT call their INIT routine.
SUB_SPRITE_GEN:
JSL $02A9E4 ; \ grab free sprite slot
BMI RETURNB ; / return if none left before anything else...
LDA #$08 ; \
STA $14C8,y ; | set custom sprite type
LDA $04 ; |
PHX ; |
TYX ; |
STA $7FAB9E,x ; |
PLX ; /
LDA $14E0,x ; \
XBA ; | set x position
LDA $E4,x ; | (lo+hi)
PHA ; |
LDA $157C,x ; |
BEQ SPR_RIGHT ; |
REP #$20 ; |
LDA $05 ; |
EOR #$FFFF ; |
STA $05 ; |
SEP #$20 ; |
SPR_RIGHT:
PLA ; |
REP #$20 ; |
CLC ; |
ADC $05 ; |
SEP #$20 ; |
STA $E4,y ; |
XBA ; |
STA $14E0,y ; /
LDA $14D4,x ; \
XBA ; | set y position
LDA $D8,x ; | (lo+hi)
REP #$20 ; |
CLC ; |
ADC $07 ; |
SEP #$20 ; |
STA $D8,y ; |
XBA ; |
STA $14D4,y ; /
LDA $09 ; \ set sprite X speed
STA $B6,y ; /
LDA $0A ; \ set sprite Y speed
STA $AA,y ; /
TYX ; \
JSL $07F7D2 ; | create the sprite and set flags
JSL $0187A7 ; |
LDA #$88 ; |
STA $7FAB10,X ; /
RETURNB:
RTS ; finish
As you can see, it requires some setting up.
Right before you JSR to this routine, you need to set the Ram addresses $04, $05, $06, $07 and $08 to certain values.
$04: the Custom Sprite number from sprites.TXT to generate.
$05: X Offsetting of generated sprite (lo byte), when its Facing Direction = right.
$06: X Offsetting of generated sprite (hi byte), when its Facing Direction = right.
$07: Y Offsetting of generated sprite (lo byte).
$08: Y Offsetting of generated sprite (hi byte).
$09: X Speed of generated sprite.
$0A: Y Speed of generated sprite.
Custom sprite customization improves DRASTICALLY with this routine. Not only can you have a custom sprite generate many different kinds of custom sprites with ONE routine, but you can do some real cool tricks with it too.
- Use in conjunction with $01ACF9 and a Table to make it generate a random sprite from a list!
- Use in conjunction with SUB_HORZ_POS, and you could have a sprite like the SSBB boss Duon, who does one attack when facing you and another attack when you're behind him!
- Use in conjunction with smkdan's Count Custom Sprites subroutine, and you could have a Lakitu which throws flippable Green Spinies if there are none on the screen, but non-flippable Red Spinies if there are! This way you can have puzzles where you have to get him to throw the Green Spiny at a certain place so you can flip it there and break a block wall, by killing the existing Green Spiny with proper timing.
- Got a sprite with 3 cannons sticking from it in multiple directions? Each cannon can shoot a different projectile at a different speed and angle from a different cannon!
Many more tricks of course-- the possibilities are ENDLESS-- but that's all I can think of. And again this sprite routine is not tested, but I don't see why it shouldn't work.
Edit2: I altered my code so that $09 and $0A set sprite X and Y speed. I'll edit this again later if I find a bug with it.
It's me!!
High on life is the best high.