; 'NES-sprite example'
;---------------------------------------------------------------------
; Implemented in ATALAN Programming language
; by Marcel Cevani
; 14.01.2011
; 
;---------------------------------------------------------------------
; This is example some sprites are displayed by sending the OAM data to the PPU chip.
; Please run the buildSprite.bat file, it append the gfx data to the rom
; Tnx to Patater for his nice Nes dev tutorials (http://www.patater.com/nes-asm-tutorials) ;)
; gfx test data is from playpower.org game hanuman quiz
; NROM:
; Max codesize   : 16Kib
; Max gfxsize    : 4Kib
; Emulator tested: fceux (2.1.4a) , needs new PPU enabled!
;---------------------------------------------------------------------
; NROM rom layout:
; Max codesize : 16Kib
; Max gfxsize  : 4Kib
;---------------------------------------------------------------------
; changed by Marcel Cevani 01.02.2011
;  - clean up souce code
;  - created some simple lib's for controlling sprites (no dma)
;  - changed gfx to Hanuman quiz
;  Tnx to Atalan the snake & rudla :)
;---------------------------------------------------------------------


use nes
use nes_sprite
use nes_mmc1
use nes_bg


; Hanuman sprite pal (taken from Hanuman Quiz game)
const hanuspritePal:sprPal = ($21,$16,$0f,$38,$21,$16,$38,$18,$21,$30,$2e,$06,$21,$17,$27,$28)
const hanusBGPal:bgPal = ($21,$16,$0f,$38,$21,$16,$38,$18,$21,$30,$2e,$06,$21,$17,$27,$28)


					

;const hanuSpriteMulti1:array = ($04,$04,
;								$00,$03,$00,$04,$00,$00,
;				                $05,$00,$06,$00,$09,$00,
;								$0a,$00,$0b,$00,$0c,$00,
;								$0f,$00,$10,$00,$00,$13 $00,$14,$00,$00)

const hanuSpriteMulti1:array = ($04,$04,$00,$00,
				$00,$03,$04,$00,
				$05,$06,$09,$0a,
				$0b,$0c,$0f,$10,
				$00,$13,$14,$00)


const hanuSpriteMulti2:array = ($04,$04,$00,$00,
				$00,$01,$02,$00, 
				$05,$06,$07,$08,  
				$0b,$0c,$0d,$0e,
				$00,$011,$12,$00)


const hanuSpriteMulti3:array = ($04,$04,$00,$00,
				$00,$00,$00,$00, 
				$05,$15,$16,$17,  
				$18,$19,$1a,$1b,
				$00,$00,$00,$00)

const  sprite1:array = (hanuSpriteMulti1,hanuSpriteMulti2,hanuSpriteMulti3)
const  sprite2:array = (hanuSpriteMulti1,hanuSpriteMulti2,hanuSpriteMulti3)

const  spriteArray:array = (sprite1 , sprite2 , sprite2 , sprite1)


out sprXPos:array(5) of byte
out sprYPos:array(5) of byte
out sprAnim:array(5) of byte


; start of example
start_example@


waitvbl
waitvbl
waitvbl


; Init MMC1 Mapper

setMMC1Ctrl 24

setMMC1Prog 0

setMMC1Chr0 0

setMMC1Chr1 1
; set Display Mode
setDisplayMode %00001000 %00010000

; loading pal
waitvbl
sprLoadPal hanuspritePal
waitvbl
bgLoadPal hanusBGPal
; Scrool pos of sprite
frame:0..255
anim:0..255
xPos:0..255

anim  = 0
frame = 0

test1:adr
test2:adr
test3:adr

test1 = sprite1
test1 = sprite2
test1 = hanuSpriteMulti1
test1 = hanuSpriteMulti2
test1 = hanuSpriteMulti3



sprXPos(0) = 32
sprYPos(0) = 128

sprXPos(1) = 64
sprYPos(1) = 128

sprXPos(2) = 128
sprYPos(2) = 64

sprXPos(3) = 200
sprYPos(3) = 128

sprXPos(4) = 200
sprYPos(4) = 128

sprAnim(0) = 0
sprAnim(1) = 0
sprAnim(2) = 0
sprAnim(3) = 0
sprAnim(4) = 0

_LAST_FRAME_OAM_INDEX = 0
frame = 0
_OAM_INDEX = 0
main@
; wait until we are in vblank
waitvbl
PPU_DMA_ADR= 3
_LAST_FRAME_OAM_INDEX =_OAM_INDEX
_OAM_INDEX = 0

CPU_PROF_START = 1


windowStartIndex = frame 

i:0..3
for i
    sprIndex = (windowStartIndex + i) bitand 3 
    setMultiSprite spriteArray sprXPos(sprIndex) sprYPos(sprIndex) sprIndex sprAnim(sprIndex)


if _LAST_FRAME_OAM_INDEX >_OAM_INDEX
	resetUnusedSprites

frame = frame + 1

if frame == 3
   frame = 0

sprAnim(0) = 2

CPU_PROF_END = 1

goto main
