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.
|
; 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
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -157,19 +157,25 @@ bool jlGameGetButton(byte which) {
|
||||||
|
|
||||||
|
|
||||||
bool _jlImgCreate(jlImgT **img) {
|
bool _jlImgCreate(jlImgT **img) {
|
||||||
jlImgT *t = (jlImgT *)jlMalloc(sizeof(jlImgT));
|
jlImgT *t = NULL;
|
||||||
if (t != NULL) {
|
|
||||||
memset(t, 0, sizeof(jlImgT));
|
// Are we loading into a new image?
|
||||||
t->id[0] = 'I';
|
if (*img == NULL) {
|
||||||
t->id[1] = 'M';
|
t = (jlImgT *)jlMalloc(sizeof(jlImgT));
|
||||||
t->id[2] = 'G';
|
if (t == NULL) {
|
||||||
t->version = 0;
|
return false;
|
||||||
memcpy(t->palette, SHRCOLORS, sizeof(t->palette));
|
}
|
||||||
memcpy(t->pixels, SHRPIXELS, sizeof(t->pixels));
|
|
||||||
*img = t;
|
*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 -->
|
// 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,22 +412,28 @@ bool jlGameGetButton(byte which) {
|
||||||
|
|
||||||
|
|
||||||
bool _jlImgCreate(jlImgT **img) {
|
bool _jlImgCreate(jlImgT **img) {
|
||||||
jlImgT *t = (jlImgT *)jlMalloc(sizeof(jlImgT));
|
jlImgT *t = NULL;
|
||||||
if (t != NULL) {
|
|
||||||
memset(t, 0, sizeof(jlImgT));
|
// Are we loading into a new image?
|
||||||
t->id[0] = 'I';
|
if (*img == NULL) {
|
||||||
t->id[1] = 'M';
|
t = (jlImgT *)jlMalloc(sizeof(jlImgT));
|
||||||
t->id[2] = 'G';
|
if (t == NULL) {
|
||||||
t->version = 0;
|
return false;
|
||||||
// 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;
|
*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