Uno degli ultimi post di Pippo79 mi ha fatto studiare il problema dello specchiamento degli sprites. Ice00 in AnnGonng e Elav gia' aveva scritto una routine per gli sprites multicolor, quindi sono passato al problema (relativamente) piu' semplice degli sprites hires.
Uno sprite e' composto da 63 bytes che formano una griglia di 24x21 punti, ogni riga e' formata da 3 byte (8x3=24)
Per specchiare sull'asse X uno sprite hires occorre far si' che ogni bit che si trova a destra finisca a sinistra. Per fare questo gli operatori di bitshift sono li' apposta.
Si shifta a destra un bit con LSR, il bit 0 finisce nel Carry, e con ROL possiamo portarlo nel byte di destinazione. Ovviamente si puo' fare anche passandoli al contrario, il bit piu' a sinistra con asl va nel carry e lo riportiamo nella destinazione con un ROR.
01010101 >>>C
|
00000000 <<<C
ripetendo questo per 8 volte abbiamo ribaltato un byte.
00000001
00000010
00000101
...
10101010
Dopo di che' bisogna ripetere il tutto per il 2o e 3o byte, facendo attenzione a far si' che la il 1o byte sorgente finisca nel 3o della destinazione, il 2o nel 2o e il 3o nel 1o. Il tutto ripetuto per ognuna delle 21 righe dello sprite.
;------------------------------------------------------------
; mirror one hires sprite
; iAN CooG/HokutoForce
;------------------------------------------------------------
*=$801
debug = 0
src = $fb
dst = $fd
zps = $02
app = $03
zpd = $04
cnt = $05
;------------------------------------------------------------
word eop
word 7102
byte $9e,[start]d,0
eop
word 0
;------------------------------------------------------------
start
lda #$01
sta $D027 ;both sprites white
sta $D028
jsr $e544
ldy #[sprite1/$40]
sty $07f8 ;sprite1 pointer
iny
sty $07f9 ;sprite2 pointer
lda #$03
sta $d015 ;spr1+2 active
lda #100
sta $d000 ;position sprites @ 100,100
sta $d001
sta $d003
lda #124 ;spr2 adjacent to spr1
sta $d002
lda #<sprite1 ;set pointers in zeropage
sta src
lda #>sprite1
sta src+1
lda #<sprite2
sta dst
lda #>sprite2
sta dst+1
jsr MirrorHiresSprite
rts
;------------------------------------------------------------
.if debug == 1
w8sp
jsr w8sp2
bne w8sp
w8sp1
jsr w8sp2
beq w8sp1
lda #0
sta $c6
w8sp2
lda $dc00
and $dc01
and #$10
rts
.endif
;------------------------------------------------------------
MirrorHiresSprite
lda #$02 ;destination must be copied backward every 3 bytes
sta zpd ; 012 -> 210, 345 -> 543 etc
ldy #$00
sty zps
sty app
sty cnt
lp1 ldy zps
cpy #$3f ; 1sprite is made of 63 bytes
beq exit
.if debug == 1
jsr w8sp ;4 debug, every byte
.endif
lda (src),y
ldx #7 ;mirror one byte, hires sprite
lp2
lsr ;put the rightmost bit of spr1 to carry
rol app ;put carry to the rightmost bit of sp2 then shift to left
dex
bpl lp2
lda app
ldy zpd ; now set current byte in spr2 with app
sta (dst),y
inc zps ;next source index
dec zpd ;previous dest index
inc cnt
lda cnt
cmp #03 ; processed 3 bytes? goto next row
bne lp1
;jsr w8sp ;4 debug, every row
lda #0
sta cnt
lda zpd
clc
adc #6 ; 3rd byte of next row at dest
sta zpd
bne lp1 ; jmp is also ok but 3 bytes
exit
rts
;------------------------------------------------------------
*= $08c0
sprite1
byte %11110011,%11101111,%10100000
byte %00001000,%00000000,%00100000
byte %11110011,%10001110,%00100000
byte %10001010,%00001000,%00100000
byte %10001011,%11101000,%00111110
byte %00000000,%00000000,%00000000
byte %00011111,%00111001,%11100000
byte %00000000,%00000100,%00010000
byte %00011100,%01000000,%00010000
byte %00010000,%01000100,%00010000
byte %00011111,%00111000,%00010000
byte %00000000,%00000000,%00000000
byte %01010101,%01010101,%01010101
byte %00000000,%00000000,%00000000
byte %11111001,%00010100,%01111010
byte %00000100,%00010000,%10000010
byte %00000101,%11110100,%01110010
byte %00000101,%00010100,%00001010
byte %00000101,%00010100,%00001000
byte %00000101,%00010100,%00001010
byte %00000101,%00010101,%11110010
byte 0
sprite2
;------------------------------------------------------------
Il problema degli sprites multicolor invece e' rappresentato dal fatto che i bit devono essere shiftati a coppie, pena l'inversione dei colori.
Studiando il sorgente di Elav ne ho tratto uno schema esemplificativo, per vedere come le coppie di bit viaggiavano da un byte all'altro.
; mirror di 1 byte in un multicolor sprite
;esempio, 00-10-01-11
; A C temp2 temp3
; 00100111 0 00000000 00000000
;1a coppia
lsr ; 00010011>1 00000000 00000000
rol temp3 ; 00010011 0 00000000 00000001<C
lsr ; 00001001>1 00000000 00000001
rol temp2 ; 00001001 0 00000001<C 00000001
lsr temp3 ; 00001001 1 00000001 00000000>C
rol temp2 ; 00001001 0 00000011<C 00000000
;2a coppia
lsr ; 00000100>1 00000011 00000000
rol temp3 ; 00000100 0 00000011 00000001<C
lsr ; 00000010 0 00000011 00000001
rol temp2 ; 00000010 0 00000110<C 00000001
lsr temp3 ; 00000010 1 00000110 00000000>C
rol temp2 ; 00000010 0 00001101<C 00000000
;3a coppia
lsr ; 00000001 0 00001101 00000000
rol temp3 ; 00000001 0 00001101 00000000<C
lsr ; 00000000>1 00001101 00000000
rol temp2 ; 00000000 0 00011011<C 00000000
lsr temp3 ; 00000000 0 00011011 00000000>C
rol temp2 ; 00000000 0 00110110 00000000
;4a coppia
lsr ; 00000000 0 00110110 00000000
rol temp3 ; 00000000 0 00110110 00000000<C
lsr ; 00000000 0 00110110 00000000
rol temp2 ; 00000000 0 01101100 00000000
lsr temp3 ; 00000000 0 01101100 00000000>C
rol temp2 ; 00000000 0 11011000 00000000
;mirrored