Commit 36beed9f authored by Scott Duensing's avatar Scott Duensing

IIgs stencil blitter fixed. Thanks dwsJason!

parent d2094b8d
......@@ -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),14
using GlobalData
jsubroutine (4:surface,4:tiles,4:stencil,2:sx,2:sy,2:tx,2:ty),16
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
lda sx ; add in stencil X position
lsr a
lsr a
lsr a ; div by 8 to get to byte index
clc
adc stoffset
tay
blitTop lda stenB ; Load stencil bit pattern
tax ; Copy to x
asl a ; Shift up a nibble for next time
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
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
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
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
lda [tiles],y ; Load 4 tile pixels
sta tile_pix
ldy target ; Load Y register with target pixel offset
sta [surface],y ; Store 4 pixels into screen
lda [surface],y
and mask0123
ora tile_pix
clc ; Increment to next pixel target quad
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;
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment