It is currently Thu Jul 20, 2017 9:27 am

All times are UTC - 7 hours





Post new topic Reply to topic  [ 1 post ] 
Author Message
PostPosted: Sat Mar 11, 2017 11:24 am 
Offline
User avatar

Joined: Wed Apr 07, 2010 1:14 am
Posts: 463
Location: Iran
Code:
;NES Programming Tutorial
;Level 8 : Multiple Sprites
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;Constants
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;Variables
L_byte         = $0000
H_byte         = $0001
bg_X_pos       = $0002
bg_Y_pos       = $0003
NMI_index      = $0004

spt1_Y         = $0200
spt1_tile      = $0201
spt1_att       = $0202
spt1_X         = $0203

spt2_Y         = $0204
spt2_tile      = $0205
spt2_att       = $0206
spt2_X         = $0207

spt3_Y         = $0208
spt3_tile      = $0209
spt3_att       = $020A
spt3_X         = $020B

spt4_Y         = $020C
spt4_tile      = $020D
spt4_att       = $020E
spt4_X         = $020F

spt5_Y         = $0210
spt5_tile      = $0211
spt5_att       = $0212
spt5_X         = $0213

spt6_Y         = $0214
spt6_tile      = $0215
spt6_att       = $0216
spt6_X         = $0217

spt7_Y         = $0218
spt7_tile      = $0219
spt7_att       = $021A
spt7_X         = $021B

spt8_Y         = $021C
spt8_tile      = $021D
spt8_att       = $021E
spt8_X         = $021F

spt9_Y         = $0220
spt9_tile      = $0221
spt9_att       = $0222
spt9_X         = $0223

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;iNES header data (16bytes)
;32KB PRG + 8KB CHR + NROM-256 + Vertical Mirroring
  .db $4E,$45,$53,$1A,$02,$01,$01,$00
  .db $00,$00,$00,$00,$00,$00,$00,$00
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;PRG codes $8000 ~ $FFFF (32KB)
  .base $8000

RESET:
   SEI
   CLD

;Turn off NMI and rendering
   LDA #%00000000
   STA $2000
   LDA #%00000000
   STA $2001

;PPU warm up
   LDA $2002
vBlank_wait1:
   BIT $2002
   BPL vBlank_wait1
vBlank_wait2:
   BIT $2002
   BPL vBlank_wait2

;Clear RAM
   LDA #$00
   LDX #$00
clear_loop:
   STA $0000, X
   STA $0100, X
   STA $0200, X
   STA $0300, X
   STA $0400, X
   STA $0500, X
   STA $0600, X
   STA $0700, X
   INX
   CPX #$00
   BNE clear_loop

;Name table + Attribute
   LDA $2002
   LDA #$20
   STA $2006
   LDA #$00
   STA $2006
   LDA #<nam_att
   STA L_byte
   LDA #>nam_att
   STA H_byte
   LDX #$00
   LDY #$00
nam_loop:
   LDA ($00), Y
   STA $2007
   INY
   CPY #$00
   BNE nam_loop
   INC H_byte
   INX
   CPX #$04
   BNE nam_loop

;Name table + Attribute 2
   LDA $2002
   LDA #$24
   STA $2006
   LDA #$00
   STA $2006
   LDA #<nam_att_2
   STA L_byte
   LDA #>nam_att_2
   STA H_byte
   LDX #$00
   LDY #$00
nam_loop_2:
   LDA ($00), Y
   STA $2007
   INY
   CPY #$00
   BNE nam_loop_2
   INC H_byte
   INX
   CPX #$04
   BNE nam_loop_2

;Background color setup
   LDA $2002
   LDA #$3F
   STA $2006
   LDA #$00
   STA $2006
   LDX #$00
bg_pal_loop:
   LDA bg_pal, X
   STA $2007
   INX
   CPX #$10
   BNE bg_pal_loop

;Sprites color setup
   LDA $2002
   LDA #$3F
   STA $2006
   LDA #$10
   STA $2006
   LDX #$00
spt_pal_loop:
   LDA spt_pal, X
   STA $2007
   INX
   CPX #$10
   BNE spt_pal_loop
 
;Sprites data to ram
LoadSprites:
   LDX #$00
LoadSpritesLoop:
   LDA sprites, X
   STA $0200, X
   INX
   CPX #$00
   BNE LoadSpritesLoop
 
;Reset Scroll
   LDA #$00
   STA $2005
   LDA #$00
   STA $2005
   
;Turn on NMI and rendering
   LDA #%10001000
   STA $2000
   LDA #%00011010
   STA $2001

;Infinite loop
Forever:

;Move background
   JSR vblank_wait
   INC bg_X_pos
   LDA bg_X_pos
   STA $2005
   LDA #$00
   STA $2005

;Give effect to sprites
   INC spt6_Y
   INC spt7_Y
   INC spt8_Y
   INC spt9_Y
   
;Sprites data to OAM
   JSR vblank_wait
   LDA #$00
   STA $2003
   LDA #$02
   STA $4014

   JMP Forever
;---------------------------;
vblank_wait:
   LDA NMI_index
not_yet:
   CMP NMI_index
   BEQ not_yet
   RTS   
;---------------------------;
NMI:
   INC NMI_index
   RTI
;---------------------------;
IRQ:
   RTI
;---------------------------;
nam_att:
  .incbin "mario_bg.nam"

nam_att_2:
  .incbin "mario_bg_2.nam"

bg_pal:
  .incbin "mario_bg.pal"
 
spt_pal:
  .incbin "mario_spt.pal"

sprites:
  .incbin "mario_spt.oam"
;---------------------------; 
  .pad $FFFA,$FF 
;Vectors
  .org $FFFA
  .dw NMI
  .dw RESET
  .dw IRQ
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;CHR data $0000 ~ $1FFF (8KB)
  .base $0000
  .incbin "mario_bg.chr"
  .incbin "mario_spt.chr"
  .pad $2000,$FF


Output :

Image


Explanation :

* Transferring 4-byte info of one sprite with $2003 and $2004 is ok, but it is slow for multiple sprites

* There is a faster way to transfer multiple sprites data to OAM : Using $2003 and $4014

* The data of sprites are stored in the RAM from $0200 to $02FF (256 Bytes)

* Extract those data from "Super Mario Bros. (W) [!].nes" and save them as : mario_spt.oam

* Attach it to the source code

Code:
sprites:
  .incbin "mario_spt.oam"


* We load the data of sprites into $0200 to $02FF

Code:
;Sprites data to ram
LoadSprites:
   LDX #$00
LoadSpritesLoop:
   LDA sprites, X
   STA $0200, X
   INX
   CPX #$00
   BNE LoadSpritesLoop


* We set OAM memory address to $00 with $2003

Code:
   LDA #$00
   STA $2003


* We write $02 to $2014

Code:
   LDA #$02
   STA $4014


* We only write the High byte of the RAM address to $2014, the Low byte of the RAM is automatically adjusted to $00 and there is no need to declare it.

* With this method a total of 256 bytes (info of 64 sprites) are transferred from RAM ($0200 ~ $02FF) to OAM memory

* This method is called DMA. Need more info about it? Then read this : PPU OAM

* Inside the game engine loop we can change the info of sprites which are saved on the ram

Code:
;Give effect to sprites
   INC spt6_Y
   INC spt7_Y
   INC spt8_Y
   INC spt9_Y


* In this code we increase the Y coordinate of mario sprite, so it seems mario is going down constantly

/////////////////////////////////////////////////////////////////////////////////////////////////

Exercise :

Open mario_spt.oam with HxD and edit mario's data to become upside down.

/////////////////////////////////////////////////////////////////////////////////////////////////

Files :
asm6.exe
Assembler.bat
Game.asm
name.exe
Bg_Editor.bat
alleg42.dll
mario_bg.nam
mario_bg_2.nam
mario_bg.pal
mario_spt.pal
mario_spt.oam
mario_bg.chr
mario_spt.chr

/////////////////////////////////////////////////////////////////////////////////////////////////

Former Level : NES Programming Tutorial : Sprite
Next Level : NES Programming Tutorial : Using Joypad


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 1 post ] 

All times are UTC - 7 hours


Who is online

Users browsing this forum: No registered users and 3 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB® Forum Software © phpBB Group