Language…
14 users online: anonimzwx, Dennsen86, deported, derv82,  Donut, drkrdnk, ForthRightMC, Fozymandias, hhuxy, kms415,  LouisDoucet, masl, oliver1, RichardDS90 - Guests: 290 - Bots: 260
Users: 64,795 (2,375 active)
Latest user: mathew

Sprite Programming [Legacy]

Oh don't refer to that tutorial ever again, it was written when I sucked at ASM :D
In the MAIN routine, we'll need a routine that will draw the graphics. For simplicity, we can just JSR to another routine that will draw the graphics.

Here is an example of what I mean.


The link there takes me to some white screen with a single advertisement.
I own a community of TF2 servers!

ASMT - A new revolutionary ASM system, aka 65c816 ASseMbly Thing
SMWCP - SMW Central Presents a Product- tion long name

frog

http://esolangs.org/wiki/MarioLANG
The files and images should be back up now.
Hey, just wanted to say that this tutorial is amazing. It really helped me understand spriting. Thanks! :D
Well, I've read through this and it's a really amazing tutorial. It even helped me make a sprite while I had only even knew a small bit of ASM (although it took constantly bugging you to get it to work (sorry D=)).

Amazing job Iceyoshi. You've really done a spectacular job with this tutorial.
I copied your code to spawn a custom sprite, and it spawned the normal sprite...
A little problem. I'm programming a 16x16 very simple sprite, but when I test it, the level don't appear!

Here's the code:

MaxxEdit: Geez, that was a large code. Link to it instead.
Fierce Deity is cool.
Workin' in OW request...
Currently attendind Scape Santa, but I don't know what to do...
Ok so I was trying to make a sprite that looks like Mario and floats above his head one 16x16 block away. I based it alot off of the code for a 16x32 sprite.

The problem is though, if I jump too high, it disappears. If I go off the screen the sprite is placed at and go back to it after disappearing it, it's back but the y disposition flips so his body is on top and his hat floats under him.

Also he won't face the right for some reason?

Code
dcb "INIT"
JSR SUB_HORZ_POS
TYA
STA $157C,x
RTL

dcb "MAIN"

PHB		;\
PHK		; | Change the data bank to the one our code is running from.
PLB		; | This is a good practice.
JSR SpriteCode	; | Jump to the sprite's function.
PLB		; | Restore old data bank.
RTL		;/ And return.

;===================================
;Sprite Function
;===================================

RETURN: RTS

SpriteCode:
	JSR Graphics

	LDA $14C8,x			;\
	CMP #$08			; | If sprite dead,
	BNE RETURN			;/ Return.
	LDA $9D				;\
	BNE RETURN			;/ If locked, return.
;sprites coding below
LDA $94
STA $E4,x
LDA $95
STA $14E0,x
LDA $96
SEC
SBC #$10
STA $D8,x
LDA $97
STA $14D4,x
;sprites coding above
	JSR SUB_OFF_SCREEN_X0		; Handle offscreen.

	RTS
;===================================
;Graphics Code
;===================================

PROPERTIES: dcb $80,$00
TILEMAP: dcb $00,$02
YDISP: dcb $10,$00

Graphics:
	JSR GET_DRAW_INFO 	; Before actually coding the graphics, we need a routine that will get the current sprite's value 
		 	 	; into the OAM.
		  		; The OAM being a place where the tile data for the current sprite will be stored.
	LDA $157C,x
	STA $02			; Store direction to $02 for use with property routine later.

	PHX			;\ Push the sprite index, since we're using it for a loop.	
	LDX #$01		;/ X = number of times to loop through. Since we only draw one MORE tile, loop one more time.
Loop:
	LDA $00			;\
	STA $0300,y		;/ Draw the X position of the sprite

	LDA $01			;\
	SEC			; | Y displacement is added for the Y position, so one tile is higher than the other.
	SBC YDISP,x		; | Otherwise, both tiles would have been drawn to the same position!
	STA $0301,y		; | If X is 00, i.e. first tile, then load the first value from the table and apply that
				;/ as the displacement. For the second tile, F0 is added to make it higher than the first.

	LDA TILEMAP,x		; X still contains index for the tile to draw. If it's the first tile, draw first tile in
	STA $0302,y		; the table. If X = 01, i.e. second tile, draw second tile in the table.

	PHX			; Push number of times to go through loop (01), because we're using it for a table here.
	LDX $02			;\
	LDA PROPERTIES,x	; | Set properties based on direction.
	ORA $64
	STA $0303,y		;/
	PLX			; Pull number of times to go through loop.

	INY			;\
	INY			; | The OAM is 8x8, but our sprite is 16x16 ..
	INY			; | So increment it 4 times.
	INY			;/
	
	DEX			; After drawing this tile, decrease number of tiles to go through loop. If the second tile
				; is drawn, then loop again to draw the first tile.

	BPL Loop		; Loop until X becomes negative (FF).
	
	PLX			; Pull back the sprite index! We pushed it at the beginning of the routine.

	LDY #$02		; Y ends with the tile size .. 02 means it's 16x16
	LDA #$01		; A -> number of tiles drawn - 1.
				; I drew 2 tiles, so 2-1 = 1. A = 01.

	JSL $01B7B3		; Call the routine that draws the sprite.
	RTS			; Never forget this!

I own a community of TF2 servers!

ASMT - A new revolutionary ASM system, aka 65c816 ASseMbly Thing
SMWCP - SMW Central Presents a Product- tion long name

frog

http://esolangs.org/wiki/MarioLANG
Sorry for the late response, guys.

@Fakescraper: The problem is here:

LDA $96
SEC
SBC #$10
STA $D8,x
LDA $97
STA $14D4,x

If you're modifying the low byte, you also have to modify the high byte. Add this between LDA $97 and STA $14D4,x:

SBC #$00

@SomeGuy: I'm surprised I never noticed that... that code is for spawning a normal sprite. Thanks for mentioning it, I'll go fix it.

K, with regards to drawing tiles, three questions.

1: When you say X and Y position does this mean in regards to the level or in regards to something else, like the clipping "field" of the sprite? I'm very confused about this and it would probably help with my second and third questions.

2: my hack's version of the fishin' boo isn't supposed to have a cloud.

When I was fooling around with trying to figure out what tiles make up the cloud it seemed like it was made of 8x8 tiles, as opposed to 16x16. It might've been one tile duplicating itself a few times (i think this is the case) though.

I'm pretty sure that in order to get rid of the cloud so my fishin boo (well, flying jellyfish with a wrecking ball) won't look ridiculous all i have to do is go into the fishin boo disassembly and take out

Code
LDA #(number of cloud tile, which i am too lazy to look up at the moment)		;\
	STA $0302,y		;/ Tile to draw. This is currently tile 24.
				; NOTE: The tile is the upper-left tile of the 16x16 tile you want to draw

	LDA #$06
	ORA $64
	STA $0303,y		; Write the YXPPCCCT property byte of the sprite
				; See this part of the tutorial again for more info

	INY			;\
	INY			; | The OAM is 8x8, but our sprite is 16x16 ..
	INY			; | So increment it 4 times.
	INY			;/

	LDY #$02		; Y ends with the tile size .. 02 means it's 16x16
	LDA #$00		; A -> number of tiles drawn - 1.
				; I drew only 1 tile so I put in 1-1 = 00.

	JSL $01B7B3		; Call the routine that draws the sprite.
	RTS			; Never forget this!


for every instance of that code appearing, as well as its x and y position, properties, and X/Y displacement. (i'm assuming bad things will happen if it tries to draw "nothing").

Then what? would I keep the same clipping value?
Also i'm probably missing it but i'm having some trouble understanding the clipping table, and what the dots, the 16x16 dark blue square, and the light blue rectangle mean, respectively.

3: as an aside i'm (In the far future) making a boss where you have to kill him by scrolling him off the screen and therefore activating the "Goal if no sprites on screen" generator.

i figure this might help me understand questions 1 and 2 better and then maybe i could become the greatest hacker in the world :P

Code
SBC $1A                 ;  | mark sprite invalid if far enough off screen


What does $1A mean? Is it the number of pixels off-screen the sprite needs to be for it to be invalid? I probably don't need to change it anyways, but i'm curious.

Stay frosty!


I'm with a problem. I made a custom sprite, but, when I test it, it falls behind the ground!

Here 1s:

The cfg file
The asm file

Any help???





Dream team (feed them, please):






In your cfg file, "don't interact with objects" is checked. I think that could be why.

@hebesphenomegacorona: It sets the X and Y position relative to the screen boarder. $00 will have the sprite's X position relative to screen boarder, and $01 will have the sprite's Y position relative to screen boarder.

If you want to get rid of the cloud tiles, then the simplest way would be to open the .ASM file, and go to this line:

Code
TILEMAP		    dcb $60,$60,$64,$8A,$60,$60,$AC,$AC,$AC,$CE


See the $60? That's the cloud tile in page 1. Just replace it with any other blank tile in the first GFX page and I'm pretty sure it'll be gone. You don't need to modify anything else in the code/cfg file.

Quote
what the dots, the 16x16 dark blue square, and the light blue rectangle mean

I don't quite get what you mean here.

$1A = Layer 1's X position (see the RAM Map). You shouldn't really care about that since it won't matter anyway.


Another question with my sprite: I've added hitpoints and I wanted to act like a spiny when Mario spinjumps it. But when I test it, it simple dies at first hit, and when I spinjump it, it dies too!!! Any help???





Dream team (feed them, please):






If you're modifying the low byte, you also have to modify the high byte. Add this between LDA $97 and STA $14D4,x:

Shouldn't I add a SEC?


LDA $97
SEC
SBC #$00
STA $14D4,x

edit:
Nevermind testing it seemed to work. I can see why now.

Now to see if I can't figure out why it only faces the right.

edit:
It doesn't seem to work. I tried this but it doesn't work.
If I face the right the gfx become glitchy.

LDA $76
BNE Faceright
LDA #$01
STA $157C,x
BRA Movey
Faceright:
STZ $157C,x
I own a community of TF2 servers!

ASMT - A new revolutionary ASM system, aka 65c816 ASseMbly Thing
SMWCP - SMW Central Presents a Product- tion long name

frog

http://esolangs.org/wiki/MarioLANG
And the 64x64 sprite??Anybody know??

how can i let it x-flip the whole time instead of animate the whole time? i make a fake fire flower, and the fire flower flips x the whole time...

EDIT: EDIT: moved pervious edit to help forum in advanced SMW hacking



I might put some sort of signature here once. I guess.
Originally posted by Iceguy


@hebesphenomegacorona: It sets the X and Y position relative to the screen boarder. $00 will have the sprite's X position relative to screen boarder, and $01 will have the sprite's Y position relative to screen boarder.

If you want to get rid of the cloud tiles, then the simplest way would be to open the .ASM file, and go to this line:

Code
TILEMAP		    dcb $60,$60,$64,$8A,$60,$60,$AC,$AC,$AC,$CE


See the $60? That's the cloud tile in page 1. Just replace it with any other blank tile in the first GFX page and I'm pretty sure it'll be gone. You don't need to modify anything else in the code/cfg file.


thanks!

so wait would that mean that the graphisc ALWAYS stay at that position relative to the screen border? I'm kind of confused about that.

also part of the reason i'm kind of wanting to just get rid of the tiles entirely instead of blanking them is because the fishin' boo eats up a ton of tile space and you can have like 1 other sprite on screen with him a lot of the time, it's really annoying! (this might just be with certain sprites)

I figured getting rid of his cloud entirely would make it easier to have more sprites on screen.
Wow, nice tut, Iceguy, I will use this to create sprites in the near future. Thanks a ton.
i am brand new to this and asm stuff so thanks so much for this tutorial it helps out alot :)...

im guessin all i need is xkas or addsprite and notepad?
REMOVED
Well, I spent the better part of an evening going over this tutorial and managed to make a (mostly) functional 16x16 sprite. I read lessons 1-8 in full and skimmed over the rest

A few issues I've noticed with the sprite I made by following the instructions...

1) The sprite continues to animate as it falls off the screen.
2) The sprite does not flip upside down when it is falling off the screen (I realize not all sprites do this, but its probably an important thing to cover)
3) Mario does not get points for stomping the sprite
4) When you spinjump/yoshi jump the sprite, the smoke puff does not appear (it does on normal SMW sprites in addition to the impact spark and stars)
5) Nothing happens if it is walking across a group of turnblocks and you hit it from below... In most cases, you'd want it to die.

Also, it would be nice if you could cover what to do to set the palette and whether or not the sprite uses the second graphics page or not using the cfg file in a bit more detail...

Its possible some of these things are covered in the later lessons and I just missed it, but looking at the subject of those lessons, it didn't seem like it would've been. These are all useful things that should probably be explained in the next version.

And if anyone can help me before then, that'd be appreciated too ^_^.
I have a hack thread - Link (Now with a demo!)
Also a music thread - Link

C3 Projects
2013: Modern Spiny Pack
2012: MGSS v0.1
Spring 2010: SMB2 Autobomb Sprite