IIgs stencil blitter fixed. Thanks dwsJason!
This commit is contained in:
parent
d2094b8d00
commit
36beed9f6c
5 changed files with 156 additions and 102 deletions
BIN
assets/IMGTemplate.xcf
(Stored with Git LFS)
Normal file
BIN
assets/IMGTemplate.xcf
(Stored with Git LFS)
Normal file
Binary file not shown.
Binary file not shown.
|
@ -123,130 +123,172 @@ blitTop ldy source ; Load Y register with source pixel offset
|
|||
|
||||
;----------------------------------------
|
||||
; Blit an 8x8 block with stencil to (almost) anywhere on a surface.
|
||||
; (Thanks dwsJason!)
|
||||
;----------------------------------------
|
||||
asmB88a start
|
||||
asmB88a start
|
||||
|
||||
source equ 1 ; Source Pixels Offset
|
||||
target equ 3 ; Target Pixels Offset
|
||||
t equ 5 ; Temp
|
||||
xc equ 7 ; X Counter
|
||||
yc equ 9 ; Y Counter
|
||||
stenO equ 11 ; Stencil Buffer Offset
|
||||
stenB equ 13 ; Stencil bit pattern
|
||||
source equ 1 ; Source Pixels Offset
|
||||
target equ 3 ; Target Pixels Offset
|
||||
xc equ 5 ; X Counter
|
||||
yc equ 7 ; Y Counter
|
||||
mask0123 equ 9
|
||||
stoffset equ 11
|
||||
tile_pix equ 13
|
||||
|
||||
jsubroutine (4:surface,4:tiles,4:stencil,2:sx,2:sy,2:tx,2:ty),16
|
||||
|
||||
jsubroutine (4:surface,4:tiles,4:stencil,2:sx,2:sy,2:tx,2:ty),14
|
||||
using GlobalData
|
||||
|
||||
; Find offset into tile memory
|
||||
; Divide source horizontal position by two since there are two pixels per byte
|
||||
lda sx ; Load X source position into accumulator
|
||||
lsr a ; Shift Right - divide by 2
|
||||
sta t
|
||||
clc
|
||||
tax ; save in temp
|
||||
|
||||
; c=? but does not matter
|
||||
lda sy ; Load sy to get index into scanline table
|
||||
asl a ; Multiply by two to get offset into scanline table (two bytes per entry in table)
|
||||
tay
|
||||
clc
|
||||
lda ScTable,y ; Load byte offset of y position from table
|
||||
adc t ; Add t to scanline offset
|
||||
sta source ; Offset to start of source pixels
|
||||
txa
|
||||
adc ScTable,y ; Load byte offset of y position from table
|
||||
; c=0 from the asl above here
|
||||
sta source ; Offset to start of source pixels; Find offset into target surface memory
|
||||
|
||||
; Divide target horizontal position by two since there are two pixels per byte
|
||||
lda tx ; Load X target position into accumulator
|
||||
lsr a ; Shift Right - divide by 2
|
||||
clc
|
||||
sta tx ; Store it back into tx
|
||||
lsr tx
|
||||
|
||||
; Find offset into target surface memory
|
||||
lda ty ; Load ty to get index into scanline table
|
||||
asl a ; Multiply by two to get offset into scanline table (two bytes per entry in table)
|
||||
tay
|
||||
lda ScTable,y ; Load byte offset of y position from table
|
||||
; c=0 from the asl above
|
||||
adc tx ; Add x position to scanline offset
|
||||
sta target ; Offset to start of target pixels
|
||||
sta target ; Offset to start of target pixels; Find the upper left corner of the stencil
|
||||
|
||||
; Find starting stencil byte
|
||||
;***FIX*** Does not handle non-byte boundaries!
|
||||
clc
|
||||
lda sy ; Vertical cell position
|
||||
asl a ; Multiply by two to get offset into stencil table (two bytes per entry in table)
|
||||
tay ; Move to Y
|
||||
lda StTable,y ; Load offset location of start of this row in the stencil buffer
|
||||
adc sx ; Add x position to address offset
|
||||
sta stenO ; Offset to start of mask data
|
||||
lda sy
|
||||
asl a
|
||||
tay
|
||||
lda ScTable,y ; look up in the pixel scanline table
|
||||
lsr a
|
||||
lsr a ; we're 4 times smaller, so just divide it
|
||||
sta stoffset
|
||||
|
||||
lda #0 ; Load 0 into X and Y counters
|
||||
sta xc
|
||||
sta yc
|
||||
|
||||
stenTop ldy stenO ; Load byte at stencil offset
|
||||
lda [stencil],y
|
||||
xba ; Shift it into the high byte
|
||||
sta stenB ; Put it in to the stencil byte
|
||||
blitTop anop
|
||||
; build the mask
|
||||
lda #$FFFF
|
||||
sta mask0123 ; default all 4 pixels visible
|
||||
|
||||
blitTop lda stenB ; Load stencil bit pattern
|
||||
tax ; Copy to x
|
||||
asl a ; Shift up a nibble for next time
|
||||
asl a
|
||||
asl a
|
||||
asl a
|
||||
sta stenB ; Save for next pass
|
||||
txa ; Load original stencil byte back back
|
||||
xba ; Flip what we want into LSB
|
||||
and #$00f0 ; Mask off top nibble
|
||||
lsr a ; Shift it down to low nibble but multiplied by 2
|
||||
lda sx ; add in stencil X position
|
||||
lsr a
|
||||
lsr a
|
||||
; lsr a
|
||||
tay ; Put it in y
|
||||
lda MaTable,y ; Load mask word
|
||||
; Draw four pixels
|
||||
ldy target ; Load Y register with target pixel offset
|
||||
and [surface],y ; AND target pixels with mask word
|
||||
lsr a ; div by 8 to get to byte index
|
||||
clc
|
||||
adc stoffset
|
||||
tay
|
||||
|
||||
lda sx
|
||||
and #7
|
||||
; A = number of initial bits to shift out
|
||||
; to get to the mask
|
||||
tax ; save in X
|
||||
|
||||
lda [stencil],y ; load the stencil
|
||||
|
||||
xba ; since we divided by 8, need to get our bits up high
|
||||
skipbit anop ; burn bits we don't care about
|
||||
asl a
|
||||
dex
|
||||
bpl skipbit
|
||||
|
||||
tax
|
||||
bcc mask0 ; bit clear, leave mask alone
|
||||
lda #$00F0 ; bit set, set the mask bits
|
||||
trb mask0123
|
||||
mask0 anop
|
||||
txa
|
||||
asl a
|
||||
tax
|
||||
bcc mask1 ; bit clear, leave mask alone
|
||||
lda #$000F ; bit set, set the mask bits
|
||||
trb mask0123
|
||||
mask1 anop
|
||||
txa
|
||||
asl a
|
||||
tax
|
||||
bcc mask2 ; bit clear, leave mask alone
|
||||
lda #$F000 ; bit set, set the mask bits
|
||||
trb mask0123
|
||||
mask2 anop
|
||||
txa
|
||||
asl a
|
||||
bcc mask3 ; bit clear, leave mask alone
|
||||
lda #$0F00 ; bit set, set the mask bits
|
||||
trb mask0123
|
||||
mask3 anop
|
||||
; c=?
|
||||
clc ; c=0
|
||||
lda sx
|
||||
adc #4 ; Add 4 here because we're moving left to right
|
||||
sta sx
|
||||
|
||||
ldy source ; Load Y register with source pixel offset
|
||||
ora [tiles],y ; OR with source pixels
|
||||
ldy target ; Load Y register with target pixel offset
|
||||
sta [surface],y ; Store 4 pixels into screen
|
||||
lda [tiles],y ; Load 4 tile pixels
|
||||
sta tile_pix
|
||||
|
||||
clc ; Increment to next pixel target quad
|
||||
ldy target ; Load Y register with target pixel offset
|
||||
lda [surface],y
|
||||
and mask0123
|
||||
ora tile_pix
|
||||
|
||||
sta [surface],y ; Store 4 pixels into screen
|
||||
;clc ; Increment to next pixel target quad
|
||||
lda #2
|
||||
adc target
|
||||
sta target
|
||||
clc ; Increment to next pixel source quad
|
||||
; c=0 here as long as target didn't go over $FFFF
|
||||
;clc ; Increment to next pixel source quad
|
||||
lda #2
|
||||
adc source
|
||||
sta source
|
||||
|
||||
clc
|
||||
sta source ;clc ; c=0 here as long as source didn't go above $FFFF
|
||||
lda xc ; Increment X counter
|
||||
adc #1
|
||||
sta xc
|
||||
cmp #2 ; End of X pixels?
|
||||
bcc blitTop ; Nope!
|
||||
bcc blitTop ; Nope! lda #0 ; Reset X counter
|
||||
|
||||
lda #0 ; Reset X counter
|
||||
sta xc
|
||||
clc ; Increment target offset
|
||||
lda #156
|
||||
stz xc ; reset xcounter to 0
|
||||
; c = 1
|
||||
; reset stencil X
|
||||
lda sx
|
||||
sbc #8
|
||||
sta sx
|
||||
|
||||
; c=0
|
||||
clc
|
||||
lda stoffset ;Increment Stencil offset
|
||||
adc #40 ; 160 / 4
|
||||
sta stoffset ; c=0 ; Increment target offset
|
||||
|
||||
lda #156 ; c=1, so instead of doing clc, adc 156, just do adc 155
|
||||
adc target
|
||||
sta target
|
||||
clc ; Increment source offset
|
||||
;clc ; Increment source offset
|
||||
; c=0 unless target goes above $FFFF
|
||||
lda #156
|
||||
adc source
|
||||
sta source
|
||||
clc ; Increment stencil mask offset
|
||||
lda #40
|
||||
adc stenO
|
||||
sta stenO
|
||||
clc
|
||||
; clc c=0 unless source goes above $FFFF
|
||||
lda yc ; Increment Y counter
|
||||
adc #1
|
||||
sta yc
|
||||
cmp #8 ; End of Y pixels?
|
||||
bcs blitDone ; Yep!
|
||||
brl stenTop ; Back for more
|
||||
|
||||
blitDone jreturn
|
||||
bcs maskend ; Yep!
|
||||
jmp blitTop
|
||||
maskend anop
|
||||
jreturn
|
||||
end
|
||||
|
||||
|
||||
|
|
|
@ -157,19 +157,25 @@ bool jlGameGetButton(byte which) {
|
|||
|
||||
|
||||
bool _jlImgCreate(jlImgT **img) {
|
||||
jlImgT *t = (jlImgT *)jlMalloc(sizeof(jlImgT));
|
||||
if (t != NULL) {
|
||||
memset(t, 0, sizeof(jlImgT));
|
||||
t->id[0] = 'I';
|
||||
t->id[1] = 'M';
|
||||
t->id[2] = 'G';
|
||||
t->version = 0;
|
||||
memcpy(t->palette, SHRCOLORS, sizeof(t->palette));
|
||||
memcpy(t->pixels, SHRPIXELS, sizeof(t->pixels));
|
||||
jlImgT *t = NULL;
|
||||
|
||||
// Are we loading into a new image?
|
||||
if (*img == NULL) {
|
||||
t = (jlImgT *)jlMalloc(sizeof(jlImgT));
|
||||
if (t == NULL) {
|
||||
return false;
|
||||
}
|
||||
*img = t;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
memset(t, 0, sizeof(jlImgT));
|
||||
t->id[0] = 'I';
|
||||
t->id[1] = 'M';
|
||||
t->id[2] = 'G';
|
||||
t->version = 0;
|
||||
memcpy(t->palette, SHRCOLORS, sizeof(t->palette));
|
||||
memcpy(t->pixels, SHRPIXELS, sizeof(t->pixels));
|
||||
*img = t;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -199,9 +199,6 @@ void jlDrawBlit8x8a(jlSurfaceT source, jlStnT *stencil, jint16 sx, jint16 sy, ji
|
|||
// Color = <-- 40 tiles, 80 bytes, 160 pixels -->
|
||||
// Stencil = <-- 20 bytes, 160 bits -->
|
||||
|
||||
i = so / 8;
|
||||
pos = 7 - (so % 8);
|
||||
|
||||
for (y=0; y<8; y++) {
|
||||
for (x=0; x<4; x++) {
|
||||
|
||||
|
@ -415,22 +412,28 @@ bool jlGameGetButton(byte which) {
|
|||
|
||||
|
||||
bool _jlImgCreate(jlImgT **img) {
|
||||
jlImgT *t = (jlImgT *)jlMalloc(sizeof(jlImgT));
|
||||
if (t != NULL) {
|
||||
memset(t, 0, sizeof(jlImgT));
|
||||
t->id[0] = 'I';
|
||||
t->id[1] = 'M';
|
||||
t->id[2] = 'G';
|
||||
t->version = 0;
|
||||
// Backing store does not exist at startup
|
||||
if (_jlBackingStore != NULL) {
|
||||
memcpy(t->palette, _jlBackingStore->palette, sizeof(t->palette));
|
||||
memcpy(t->pixels, _jlBackingStore->pixels, sizeof(t->pixels));
|
||||
jlImgT *t = NULL;
|
||||
|
||||
// Are we loading into a new image?
|
||||
if (*img == NULL) {
|
||||
t = (jlImgT *)jlMalloc(sizeof(jlImgT));
|
||||
if (t == NULL) {
|
||||
return false;
|
||||
}
|
||||
*img = t;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
memset(t, 0, sizeof(jlImgT));
|
||||
t->id[0] = 'I';
|
||||
t->id[1] = 'M';
|
||||
t->id[2] = 'G';
|
||||
t->version = 0;
|
||||
// Backing store does not exist at startup
|
||||
if (_jlBackingStore != NULL) {
|
||||
memcpy(t->palette, _jlBackingStore->palette, sizeof(t->palette));
|
||||
memcpy(t->pixels, _jlBackingStore->pixels, sizeof(t->pixels));
|
||||
}
|
||||
*img = t;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue