Language…
26 users online: Alucard648,  AmperSam,  Anorakun, cozyduck, DasFueller, E-man38, El Makuarro Gaming,  Fernap, formulachicken, Gulaschko, HeitorPorfirio2006, LiamBLOL, lincolnic, Mapping_bl, Murphmario,  NopeContest, OEO6, PencilLaddy, requiredyump, RichardDS90, Romano338, ShUriK KiD, Squiggs, twicepipes, Valentine, xfix - Guests: 122 - Bots: 219
Users: 55,680 (2,387 active)
Latest user: shinkintoad

Sprite Programming [Legacy]

Originally posted by Ramp202
@link - you don't return from the graphics routine. (need a RTS)


one day i'm going to suicide... (-_-")

thanks

ok , now it doesn't brick the rom , but i can see nothing, it has no GFX...

Thanks Ladida for this EPIC and Awesome layout!

Then your problem is here:

Quote
Graphics: JSR GET_DRAW_INFO


GET_DRAW_INFO:


Why is GET_DRAW_INFO here? It's supposed to be a separate routine in the file. Get it from here and paste it at the end of the file, and removed the GET_DRAW_INFO label just below the graphics routine.
it has to be something like this?
Code
dcb "INIT"
RTL

dcb "MAIN"
JSR Graphics 	; I've added this label. We'll jump here to draw the graphics.
RTL 		; After drawing the graphics, end our code.


;===================================
; GRAPHICS ROUTINE HERE
;===================================

Graphics:	JSR GET_DRAW_INFO 


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; GET_DRAW_INFO
; This is a helper for the graphics routine.  It sets off screen flags, and sets up
; variables.  It will return with the following:
;
;       Y = index to sprite OAM ($300)
;       $00 = sprite x position relative to screen boarder
;       $01 = sprite y position relative to screen boarder  
;
; It is adapted from the subroutine at $03B760
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

SPR_T1              dcb $0C,$1C
SPR_T2              dcb $01,$02

GET_DRAW_INFO       STZ $186C,x             ; reset sprite offscreen flag, vertical
	STZ $15A0,x             ; reset sprite offscreen flag, horizontal
	LDA $E4,x               ; \
	CMP $1A                 ;  | set horizontal offscreen if necessary
	LDA $14E0,x             ;  |
	SBC $1B                 ;  |
	BEQ ON_SCREEN_X         ;  |
	INC $15A0,x             ; /

ON_SCREEN_X         LDA $14E0,x             ; \
	XBA	 ;  |
	LDA $E4,x               ;  |
	REP #$20                ;  |
	SEC	 ;  |
	SBC $1A                 ;  | mark sprite invalid if far enough off screen
	CLC	 ;  |
	ADC.W #$0040            ;  |
	CMP.W #$0180            ;  |
	SEP #$20                ;  |
	ROL A                   ;  |
	AND #$01                ;  |
	STA $15C4,x             ; / 
	BNE INVALID             ; 
	
	LDY #$00                ; \ set up loop:
	LDA $1662,x             ;  | 
	AND #$20                ;  | if not smushed (1662 & 0x20), go through loop twice
	BEQ ON_SCREEN_LOOP      ;  | else, go through loop once
	INY	 ; / 
ON_SCREEN_LOOP      LDA $D8,x               ; \ 
	CLC	 ;  | set vertical offscreen if necessary
	ADC SPR_T1,y            ;  |
	PHP	 ;  |
	CMP $1C                 ;  | (vert screen boundry)
	ROL $00                 ;  |
	PLP	 ;  |
	LDA $14D4,x             ;  | 
	ADC #$00                ;  |
	LSR $00                 ;  |
	SBC $1D                 ;  |
	BEQ ON_SCREEN_Y         ;  |
	LDA $186C,x             ;  | (vert offscreen)
	ORA SPR_T2,y            ;  |
	STA $186C,x             ;  |
ON_SCREEN_Y         DEY	 ;  |
	BPL ON_SCREEN_LOOP      ; /

	LDY $15EA,x             ; get offset to sprite OAM
	LDA $E4,x               ; \ 
	SEC	 ;  | 
	SBC $1A                 ;  | $00 = sprite x position relative to screen boarder
	STA $00                 ; / 
	LDA $D8,x               ; \ 
	SEC	 ;  | 
	SBC $1C                 ;  | $01 = sprite y position relative to screen boarder
	STA $01                 ; / 
	RTS	 ; return

INVALID             PLA	 ; \ return from *main gfx routine* subroutine...
	PLA	 ;  |    ...(not just this subroutine)
	RTS	 ; /


Thanks Ladida for this EPIC and Awesome layout!

Yes, but...

Graphics:
JSR GET_DRAW_INFO

LDA $00
STA $0300,y

LDA $01
STA $0301,y

.....
maybe like this?

Code
dcb "INIT"
RTL

dcb "MAIN"
JSR Graphics 	; I've added this label. We'll jump here to draw the graphics.
RTL 		; After drawing the graphics, end our code.


;===================================
; GRAPHICS ROUTINE HERE
;===================================

Graphics:	
JSR GET_DRAW_INFO 
LDA $00 
STA $0300,y

LDA $01
STA $0301,y

LDA #$E6
STA $0302,y

LDA #%00000110
ORA $64
STA $0303,y

INY
INY
INY
INY

LDY #$02 
LDA #$00 
JSL $01B7B3
RTS

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; GET_DRAW_INFO
; This is a helper for the graphics routine.  It sets off screen flags, and sets up
; variables.  It will return with the following:
;
;       Y = index to sprite OAM ($300)
;       $00 = sprite x position relative to screen boarder
;       $01 = sprite y position relative to screen boarder  
;
; It is adapted from the subroutine at $03B760
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

SPR_T1              dcb $0C,$1C
SPR_T2              dcb $01,$02

GET_DRAW_INFO       STZ $186C,x             ; reset sprite offscreen flag, vertical
	STZ $15A0,x             ; reset sprite offscreen flag, horizontal
	LDA $E4,x               ; \
	CMP $1A                 ;  | set horizontal offscreen if necessary
	LDA $14E0,x             ;  |
	SBC $1B                 ;  |
	BEQ ON_SCREEN_X         ;  |
	INC $15A0,x             ; /

ON_SCREEN_X         LDA $14E0,x             ; \
	XBA	 ;  |
	LDA $E4,x               ;  |
	REP #$20                ;  |
	SEC	 ;  |
	SBC $1A                 ;  | mark sprite invalid if far enough off screen
	CLC	 ;  |
	ADC.W #$0040            ;  |
	CMP.W #$0180            ;  |
	SEP #$20                ;  |
	ROL A                   ;  |
	AND #$01                ;  |
	STA $15C4,x             ; / 
	BNE INVALID             ; 
	
	LDY #$00                ; \ set up loop:
	LDA $1662,x             ;  | 
	AND #$20                ;  | if not smushed (1662 & 0x20), go through loop twice
	BEQ ON_SCREEN_LOOP      ;  | else, go through loop once
	INY	 ; / 
ON_SCREEN_LOOP      LDA $D8,x               ; \ 
	CLC	 ;  | set vertical offscreen if necessary
	ADC SPR_T1,y            ;  |
	PHP	 ;  |
	CMP $1C                 ;  | (vert screen boundry)
	ROL $00                 ;  |
	PLP	 ;  |
	LDA $14D4,x             ;  | 
	ADC #$00                ;  |
	LSR $00                 ;  |
	SBC $1D                 ;  |
	BEQ ON_SCREEN_Y         ;  |
	LDA $186C,x             ;  | (vert offscreen)
	ORA SPR_T2,y            ;  |
	STA $186C,x             ;  |
ON_SCREEN_Y         DEY	 ;  |
	BPL ON_SCREEN_LOOP      ; /

	LDY $15EA,x             ; get offset to sprite OAM
	LDA $E4,x               ; \ 
	SEC	 ;  | 
	SBC $1A                 ;  | $00 = sprite x position relative to screen boarder
	STA $00                 ; / 
	LDA $D8,x               ; \ 
	SEC	 ;  | 
	SBC $1C                 ;  | $01 = sprite y position relative to screen boarder
	STA $01                 ; / 
	RTS	 ; return

INVALID             PLA	 ; \ return from *main gfx routine* subroutine...
	PLA	 ;  |    ...(not just this subroutine)
	RTS	 ; /
Yep, this is correct. But you might want to do this:

dcb "INIT"
RTL

dcb "MAIN"
PHB
PHK
PLB
JSR SpriteCode
PLB
RTL

SpriteCode:
JSR Graphics
*Moar code here*
RTS

Graphics
*Code Here*
thanks!

E: i've done the 16x16 animated sprite, but it has a glich, look:



here , the code. i know that i put this part of code:

Code
PHX
LDA $13
LSR ;\
LSR ; | Slowers the animation rate.
LSR ;/
AND #$01
TAX
LDA TILEMAP,x
STA $0302,y
PLX


in the wrong place:

Code
dcb "INIT"
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
	BNE RETURN
	LDA $9D
	BNE RETURN

	JSR SUB_OFF_SCREEN_X0
	
	
;===================================
;Graphics Code
;===================================

TILEMAP: dcb $CA,$CC

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 $00			;\
	STA $0300,y		;/ Draw the X position of the sprite

	LDA $01			;\
	STA $0301,y		;/ Draw the Y position of the sprite

;Those 2 above are always needed to figure out the X/Y position of the sprite
	
	PHX
LDA $13
LSR ;\
LSR ; | Slowers the animation rate.
LSR ;/
AND #$01
TAX
LDA TILEMAP,x
STA $0302,y
PLX

	LDA #$07
	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!


(i don't put the get draw info , and the sub_off_screen, they are obiously at the end of the code)
Yea it's a bumpty but i need help.

Weird sprite error. It's fall straight down.
Thanks man!

and there's a grammar error in the seventh paragraph namely learnt instead of learned. but that's just minor.
THANKS!
"Learned" and "learnt" are both proper spellings.
I'm trying to make an animated sprite, but it crashes the game when I enter the level.

My Code:
http://pastebin.com/aNSNe33h

EDIT: Never mind I finally got it working and now I'm super happy.#w{:>}
Hacks:
-That Other Plumber
Iceguy, do you think it would be a good idea to add a note in the "Make use of the extra bit" section that you check different addresses for shooters and generators? When $7FAB10 didn't help me shoot a sprite twice as fast, I checked a generic shooter file and saw it checked $1783 with AND #$40. Looking at a generic generator, that seems to check $18B9 with AND #$40. Granted, I usually have no idea what I'm talking about when it comes to sprite coding, so if I'm missing something obvious, just ignore me :b

I'm sure I've said it before, but for me this is one of the useful tutorials on the site, and I find myself referencing it all the time, even though I usually just make minor edits to existing sprites. Thanks for making it (:
Youtube (Main) | Youtube (Alt) | Bandcamp | DeviantART
Originally posted by wiiqwertyuiop
TRAMS

"Trams" is a valid Swedish word, and it means "nonsense".
Therefore, this is the best typo I have ever seen.
<blm> zsnes users are the flatearthers of emulation
I made a boss from this tutorial, it inserted it, you cannot jump on it or touch it it just walks through you... immamelia told me to remove the JSR after The suboff screen command, i did and the sprite moved and walked right off screen any help?



EDIT: here is a video...


http://www.youtube.com/watch?v=hv5LEHlIMAg
blunted
Uh.. I should really check this forum more often.

Quote
Iceguy, do you think it would be a good idea to add a note in the "Make use of the extra bit" section that you check different addresses for shooters and generators? When $7FAB10 didn't help me shoot a sprite twice as fast, I checked a generic shooter file and saw it checked $1783 with AND #$40. Looking at a generic generator, that seems to check $18B9 with AND #$40. Granted, I usually have no idea what I'm talking about when it comes to sprite coding, so if I'm missing something obvious, just ignore me :b

Don't worry, you are making sense. :P Also, good idea, I completely forgot about noting that when writing this tutorial. Thanks for reminding me.

Quote
Dont you think its about time to convert this tutorial to xkas? Everything is in TRASM as of now, and a few things could be changed, and add, as well.

Here's the problem: I don't want to 'convert this tutorial to xkas', I want to completely rewrite it but I have no idea when that'll happen. I am sort of dissatisfied with most of the lessons (mainly because my spriting skills weren't that good back then and the explanations could have been slightly better) and the tutorial could greatly be shortened despite many people finding them to be very useful.

Quote
I made a boss from this tutorial, it inserted it, you cannot jump on it or touch it it just walks through you... immamelia told me to remove the JSR after The suboff screen command, i did and the sprite moved and walked right off screen any help?



EDIT: here is a video...


http://www.youtube.com/watch?v=hv5LEHlIMAg

You mean you want the sprite to have interaction with Mario? If so, read lesson 4. If not, please explain what you mean.
Would you mind if I rewrote this for xkas? Obviously I'd put my own spin on it, but I have time to dedicate to something like this so you wouldn't have to worry about it.
What about my ASM tutorial? It will include several sections about making sprites.

----------------

I'm working on a hack! Check it out here.