Yes... Boy, I wish it were just 4!tepples wrote:This is NESdev, where four thousand cycles equal 35.2 scanlines.
Oh, I see... I kinda remembered Castlevania games to be side-scrolles, with stairs taking you to the other floors, but with no vertical scrolling. Well, then you know that scrolling in both directions is not exactly trivial! =)Celius wrote:My game will scroll all 4 directions just as yours does
It'd probably be easier for me to just paste it here then explaining everything, so here it is:So it took you 4000 cycles just to draw those three metasprites? I guess I'll have to see how long it'll take for my routine. But I have to ask. What exactly is happening in your drawing routine?
Code: Select all
DrawMetaSprite:
;-- SUBROUTINE --------------------------------------------------
;DESCRIPTION:
; Processes the sprites in a sprite definition.
;INPUT:
; A: Mask used to modify the attributes;
; X: bytes to skip when moving to the next slot (4 or -4);
; SpriteDefinition: Address of the sprite definition;
; SpriteStep: value to add to the slot index after each sprite;
; SpriteX, SpriteY: coordinates of the object;
;DESTROYS: A, X, Y, SpriteX, SpriteY;
;----------------------------------------------------------------
;Verify if there are slots left
ldy SlotsLeft
bne +
rts
+
;Save the attributes
sta SpriteAttrib
;Point to the first byte in the definition
ldy #$00
;Copy the sprite count
lda (SpriteDefinition), y
sta SpritesLeft
;Calculate the central X coordinate of the sprite
sec
lda SpriteX+0
sbc CameraX+0
sta SpriteX+0
lda SpriteX+1
sbc CameraX+1
sta SpriteX+1
;Fix the coordinate if the sprite is flipped horizontally
bit SpriteAttrib
bvc NoHorFlip
sec
lda SpriteX+0
sbc #$07
sta SpriteX+0
lda SpriteX+1
sbc #$00
sta SpriteX+1
NoHorFlip:
;Calculate the central Y coordinate of the sprite
sec
lda SpriteY+0
sbc CameraY+0
sta SpriteY+0
lda SpriteY+1
sbc CameraY+1
sta SpriteY+1
;Compensate for the sprite delay and blank scanlines
clc
lda SpriteY+0
adc #$0f
sta SpriteY+0
lda SpriteY+1
adc #$00
sta SpriteY+1
;Fix the coordinate if the sprite is flipped vertically
bit SpriteAttrib
bpl NoVertFlip
sec
lda SpriteY+0
sbc #$0f
sta SpriteY+0
lda SpriteY+1
sbc #$00
sta SpriteY+1
NoVertFlip:
;Load the correct index of the slot
stx SpriteStep
txa
bmi +
ldx SpriteSlotA
jmp DrawSprite
+ ldx SpriteSlotB
jmp DrawSprite
OutOfScreen:
dec SpritesLeft
beq SpritesFinished
;Advance to the next definition block
clc
tya
and #%11111100
adc #%00000100
tay
DrawSprite:
;Advance to the next definition byte
iny
;Load the relative X coordinate
lda (SpriteDefinition), y
;Check if the sprite is flipped horizontally
bit SpriteAttrib
bvc +
;Invert the value if it is
eor #$ff
+ sta SpriteTemp
;Add the displacement
clc
adc SpriteX+0
;Store the result
sta SpritePage+3, x
;Check if the result was valid
php
lda #$7f
cmp SpriteTemp
adc #$80
plp
adc SpriteX+1
and ScreenXMask
bne OutOfScreen
;Advance to the next definition byte
iny
;Load the relative Y coordinate
lda (SpriteDefinition), y
;Check if the sprite is flipped vertically
bit SpriteAttrib
bpl +
;Invert the value if it is
eor #$ff
+ sta SpriteTemp
;Add the displacement
clc
adc SpriteY+0
;Store the result
sta SpritePage+0, x
;Check if the result was valid
php
lda #$7f
cmp SpriteTemp
adc #$80
plp
adc SpriteY+1
and ScreenYMask
bne OutOfScreen
;Advance to the next definition byte
iny
;Load the index of the sprite
lda (SpriteDefinition), y
;Store it in the slot
sta SpritePage+1, x
;Advance to the next definition byte
iny
;Load the byte with the attributes of the sprite
lda (SpriteDefinition), y
;Modify it as necessary
eor SpriteAttrib
;Store it in the slot
sta SpritePage+2, x
;Move on to the next slot
clc
txa
adc SpriteStep
tax
dec SlotsLeft
beq SpritesFinished
;Move on to the next definition
dec SpritesLeft
bne DrawSprite
SpritesFinished:
lda SpriteStep
bmi +
stx SpriteSlotA
rts
+ stx SpriteSlotB
rtsEDIT: Oh, you must remember to clear the unused sprites after you're done drawing all the objects. I do this with the following code:
Code: Select all
;Clear the unused sprite slots
lda SlotsLeft
beq SlotsCleared
ldx SpriteSlotA
lda #$ef
ClearSlot:
sta SpritePage+0, x
inx
inx
inx
inx
dec SlotsLeft
bne ClearSlot
SlotsCleared: