IIgs stencil blitter fixed. Thanks dwsJason!

This commit is contained in:
Scott Duensing 2020-07-30 19:55:28 -05:00
parent d2094b8d00
commit 36beed9f6c
5 changed files with 156 additions and 102 deletions

BIN
assets/IMGTemplate.xcf (Stored with Git LFS) Normal file

Binary file not shown.

Binary file not shown.

View file

@ -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. ; Blit an 8x8 block with stencil to (almost) anywhere on a surface.
; (Thanks dwsJason!)
;---------------------------------------- ;----------------------------------------
asmB88a start asmB88a start
source equ 1 ; Source Pixels Offset source equ 1 ; Source Pixels Offset
target equ 3 ; Target Pixels Offset target equ 3 ; Target Pixels Offset
t equ 5 ; Temp xc equ 5 ; X Counter
xc equ 7 ; X Counter yc equ 7 ; Y Counter
yc equ 9 ; Y Counter mask0123 equ 9
stenO equ 11 ; Stencil Buffer Offset stoffset equ 11
stenB equ 13 ; Stencil bit pattern 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 using GlobalData
; Find offset into tile memory ; Find offset into tile memory
; Divide source horizontal position by two since there are two pixels per byte ; Divide source horizontal position by two since there are two pixels per byte
lda sx ; Load X source position into accumulator lda sx ; Load X source position into accumulator
lsr a ; Shift Right - divide by 2 lsr a ; Shift Right - divide by 2
sta t tax ; save in temp
clc
; c=? but does not matter
lda sy ; Load sy to get index into scanline table 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) asl a ; Multiply by two to get offset into scanline table (two bytes per entry in table)
tay tay
clc txa
lda ScTable,y ; Load byte offset of y position from table adc ScTable,y ; Load byte offset of y position from table
adc t ; Add t to scanline offset ; c=0 from the asl above here
sta source ; Offset to start of source pixels 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 ; Divide target horizontal position by two since there are two pixels per byte
lda tx ; Load X target position into accumulator lsr tx
lsr a ; Shift Right - divide by 2
clc
sta tx ; Store it back into tx
; Find offset into target surface memory
lda ty ; Load ty to get index into scanline table 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) asl a ; Multiply by two to get offset into scanline table (two bytes per entry in table)
tay tay
lda ScTable,y ; Load byte offset of y position from table 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 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 lda sy
;***FIX*** Does not handle non-byte boundaries! asl a
clc tay
lda sy ; Vertical cell position lda ScTable,y ; look up in the pixel scanline table
asl a ; Multiply by two to get offset into stencil table (two bytes per entry in table) lsr a
tay ; Move to Y lsr a ; we're 4 times smaller, so just divide it
lda StTable,y ; Load offset location of start of this row in the stencil buffer sta stoffset
adc sx ; Add x position to address offset
sta stenO ; Offset to start of mask data
lda #0 ; Load 0 into X and Y counters lda #0 ; Load 0 into X and Y counters
sta xc sta xc
sta yc sta yc
stenTop ldy stenO ; Load byte at stencil offset blitTop anop
lda [stencil],y ; build the mask
xba ; Shift it into the high byte lda #$FFFF
sta stenB ; Put it in to the stencil byte sta mask0123 ; default all 4 pixels visible
blitTop lda stenB ; Load stencil bit pattern lda sx ; add in stencil X position
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
lsr a lsr a
lsr a lsr a
; lsr a lsr a ; div by 8 to get to byte index
tay ; Put it in y clc
lda MaTable,y ; Load mask word adc stoffset
; Draw four pixels tay
ldy target ; Load Y register with target pixel offset
and [surface],y ; AND target pixels with mask word 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 ldy source ; Load Y register with source pixel offset
ora [tiles],y ; OR with source pixels lda [tiles],y ; Load 4 tile pixels
ldy target ; Load Y register with target pixel offset sta tile_pix
sta [surface],y ; Store 4 pixels into screen
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 lda #2
adc target adc target
sta 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 lda #2
adc source adc source
sta source sta source ;clc ; c=0 here as long as source didn't go above $FFFF
clc
lda xc ; Increment X counter lda xc ; Increment X counter
adc #1 adc #1
sta xc sta xc
cmp #2 ; End of X pixels? cmp #2 ; End of X pixels?
bcc blitTop ; Nope! bcc blitTop ; Nope! lda #0 ; Reset X counter
lda #0 ; Reset X counter stz xc ; reset xcounter to 0
sta xc ; c = 1
clc ; Increment target offset ; reset stencil X
lda #156 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 adc target
sta target sta target
clc ; Increment source offset ;clc ; Increment source offset
; c=0 unless target goes above $FFFF
lda #156 lda #156
adc source adc source
sta source sta source
clc ; Increment stencil mask offset ; clc c=0 unless source goes above $FFFF
lda #40
adc stenO
sta stenO
clc
lda yc ; Increment Y counter lda yc ; Increment Y counter
adc #1 adc #1
sta yc sta yc
cmp #8 ; End of Y pixels? cmp #8 ; End of Y pixels?
bcs blitDone ; Yep! bcs maskend ; Yep!
brl stenTop ; Back for more jmp blitTop
maskend anop
blitDone jreturn jreturn
end end

View file

@ -157,8 +157,16 @@ bool jlGameGetButton(byte which) {
bool _jlImgCreate(jlImgT **img) { bool _jlImgCreate(jlImgT **img) {
jlImgT *t = (jlImgT *)jlMalloc(sizeof(jlImgT)); jlImgT *t = NULL;
if (t != NULL) {
// Are we loading into a new image?
if (*img == NULL) {
t = (jlImgT *)jlMalloc(sizeof(jlImgT));
if (t == NULL) {
return false;
}
*img = t;
}
memset(t, 0, sizeof(jlImgT)); memset(t, 0, sizeof(jlImgT));
t->id[0] = 'I'; t->id[0] = 'I';
t->id[1] = 'M'; t->id[1] = 'M';
@ -169,8 +177,6 @@ bool _jlImgCreate(jlImgT **img) {
*img = t; *img = t;
return true; return true;
} }
return false;
}
void jlImgDisplay(jlImgT *img) { void jlImgDisplay(jlImgT *img) {

View file

@ -199,9 +199,6 @@ void jlDrawBlit8x8a(jlSurfaceT source, jlStnT *stencil, jint16 sx, jint16 sy, ji
// Color = <-- 40 tiles, 80 bytes, 160 pixels --> // Color = <-- 40 tiles, 80 bytes, 160 pixels -->
// Stencil = <-- 20 bytes, 160 bits --> // Stencil = <-- 20 bytes, 160 bits -->
i = so / 8;
pos = 7 - (so % 8);
for (y=0; y<8; y++) { for (y=0; y<8; y++) {
for (x=0; x<4; x++) { for (x=0; x<4; x++) {
@ -415,8 +412,16 @@ bool jlGameGetButton(byte which) {
bool _jlImgCreate(jlImgT **img) { bool _jlImgCreate(jlImgT **img) {
jlImgT *t = (jlImgT *)jlMalloc(sizeof(jlImgT)); jlImgT *t = NULL;
if (t != NULL) {
// Are we loading into a new image?
if (*img == NULL) {
t = (jlImgT *)jlMalloc(sizeof(jlImgT));
if (t == NULL) {
return false;
}
*img = t;
}
memset(t, 0, sizeof(jlImgT)); memset(t, 0, sizeof(jlImgT));
t->id[0] = 'I'; t->id[0] = 'I';
t->id[1] = 'M'; t->id[1] = 'M';
@ -430,8 +435,6 @@ bool _jlImgCreate(jlImgT **img) {
*img = t; *img = t;
return true; return true;
} }
return false;
}
void jlImgDisplay(jlImgT *img) { void jlImgDisplay(jlImgT *img) {