Commit bfc7dc09 authored by Scott Duensing's avatar Scott Duensing

Working on new stencil blitter for IIgs.

parent 0be3ee69
......@@ -11,3 +11,5 @@ notes.txt
assets/JoeyLib Logo - 320x200.png
assets/JoeyLib Logo.jpg
assets/JoeyLib Logo.png
*.stn
*.img
......@@ -97,7 +97,7 @@ void convertStencil(char *filename, char *basename) {
for (int y=0; y<image->h; y++) {
for (int x=0; x<image->w; x++) {
data <<= 1;
data |= (getPixel(image, x, y) == 0);
data |= (getPixel(image, x, y) != 0);
bits++;
if (bits > 7) {
bytes++;
......
......@@ -99,8 +99,9 @@ function doIIgsBuild() {
rm "${IMPORT}" 2> /dev/null || true
cp "${OUT}/test" "${OUT}/Test#B30000"
cp "${JOEY}/joeylib/joeylib/src/kanga.sta" "${OUT}/kanga.sta#060000"
cp "${JOEY}/joeylib/joeylib/src/font.sta" "${OUT}/font.sta#060000"
cp "${JOEY}/joeylib/joeylib/src/kanga.img" "${OUT}/kanga.img#060000"
cp "${JOEY}/joeylib/joeylib/src/font.img" "${OUT}/font.img#060000"
cp "${JOEY}/joeylib/joeylib/src/font.stn" "${OUT}/font.stn#060000"
cp "${JOEY}/joeylib/joeylib/src/music" "${OUT}/music#D50000"
cp "${JOEY}/joeylib/joeylib/src/music.w" "${OUT}/music.w#060000"
......@@ -108,8 +109,9 @@ function doIIgsBuild() {
"${CADIUS}" createfolder "${IMPORT}" ${VOL}/data > /dev/null
"${CADIUS}" addfile "${IMPORT}" ${VOL} "${JOEY}/dist/IIgs/Tool221#ba0000" > /dev/null
"${CADIUS}" addfile "${IMPORT}" ${VOL} "${OUT}/Test#b30000" > /dev/null
"${CADIUS}" addfile "${IMPORT}" ${VOL}/data "${OUT}/kanga.sta#060000" > /dev/null
"${CADIUS}" addfile "${IMPORT}" ${VOL}/data "${OUT}/font.sta#060000" > /dev/null
"${CADIUS}" addfile "${IMPORT}" ${VOL}/data "${OUT}/kanga.img#060000" > /dev/null
"${CADIUS}" addfile "${IMPORT}" ${VOL}/data "${OUT}/font.img#060000" > /dev/null
"${CADIUS}" addfile "${IMPORT}" ${VOL}/data "${OUT}/font.stn#060000" > /dev/null
"${CADIUS}" addfile "${IMPORT}" ${VOL}/data "${OUT}/music#D50000" > /dev/null
"${CADIUS}" addfile "${IMPORT}" ${VOL}/data "${OUT}/music.w#060000" > /dev/null
......
......@@ -27,8 +27,8 @@
GlobalData data
ScanTable entry
ds 400 ; 400 bytes for scanline offsets
ScTable ds 400 ; 400 bytes for 200 scanline offsets
StTable ds 50 ; 50 bytes for 25 stencil table offsets
VblRate ds 2 ; Either 5 or 6 depending on PAL or NTSC.
VblTime ds 2 ; Integer Counter
end
......@@ -61,7 +61,7 @@ yc equ 9 ; Y Counter
asl a ; y screen location is now in the accumulator
tay
clc
lda ScanTable,y ; Load byte offset of y position from table
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
......@@ -75,7 +75,7 @@ yc equ 9 ; Y Counter
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 ScanTable,y ; Load byte offset of y position from table
lda ScTable,y ; Load byte offset of y position from table
adc tx ; Add x position to scanline offset
sta target ; Offset to start of target pixels
......@@ -128,7 +128,7 @@ blitTop ldy source ; Load Y register with source pixel offset
;----------------------------------------
; Blit an 8x8 block with alpha to (almost) anywhere on a surface.
;----------------------------------------
asmB88a start
asmB88ax start
source equ 1 ; Source Pixels Offset
target equ 3 ; Target Pixels Offset
......@@ -153,7 +153,7 @@ yc equ 11 ; Y Counter
asl a ; y screen location is now in the accumulator
tay
clc
lda ScanTable,y ; Load byte offset of y position from table
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
......@@ -175,7 +175,7 @@ yc equ 11 ; Y Counter
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 ScanTable,y ; Load byte offset of y position from table
lda ScTable,y ; Load byte offset of y position from table
adc tx ; Add x position to scanline offset
sta target ; Offset to start of target pixels
......@@ -237,6 +237,150 @@ blitTop ldy target ; Load Y register with target pixel offset
end
;----------------------------------------
; Blit an 8x8 block with stencil to (almost) anywhere on a surface.
;----------------------------------------
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 12 ; Stencil Buffer Data - bits - two bytes, but we only use one
maskW equ 14 ; Actual mask bytes for pixels
jsubroutine (4:surface,4:tiles,4:stencil,2:sx,2:sy,2:tx,2:ty),16
using GlobalData
; Find offset into tile memory
lda sx ; Multiply sx by 4 to get offset (two pixels per byte)
asl a
asl a
sta t
clc
lda sy ; Multiply sy by 16 to get index into scanline table
asl a
asl a
asl a
asl a ; y screen location is now in the accumulator
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
; 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
; 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
adc tx ; Add x position to scanline offset
sta target ; Offset to start of target pixels
; Find starting stencil byte
clc
ldy ty ; Vertical cell position
lda StTable,y ; Load offset location of start of this row in the stencil buffer
adc tx ; Add x position to address offset
sta stenO ; Offset to start of mask data
lda #0 ; Load 0 into X and Y counters
sta xc
sta yc
blitTop lda [stenO] ; Load byte at stencil offset
xba ; Shift it into the high byte
sta stenB ; Put it in to the stencil byte
; Convert stencil byte to mask word (4 pixels)
ldx #4 ; How many pixels to process?
lda #0 ; Initially, the mask word is all zero bits
sta maskW
nextNib lda stenB ; Load stencil byte into accumulator
asl a ; Shift first bit out of stencil byte into C
bcs pixOn ; If C is set, we draw the pixel
lda maskW ; Load mask word into accumulator
asl a ; Shift mask word over a pixel (4 bits)
asl a
asl a
asl a
and #$fff0 ; Do not draw pixel - mask it off
sta maskW ; Store updated mask word
jmp nextPix ; Start next pixel
pixOn lda maskW ; Load mask word into accumulator
asl a ; Shift mask word over a pixel (4 bits)
asl a
asl a
asl a
and #$ffff ; Draw pixel
sta maskW ; Store updated mask word
nextPix dex ; Decrement pixel counter in X
bne nextNib ; Not zero? Do next nibble/pixel
; Draw four pixels
ldy target ; Load Y register with target pixel offset
lda [surface],y ; Load target pixels
and maskW ; AND with mask word
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
clc ; Increment to next pixel target quad
lda #2
adc target
sta target
clc ; Increment to next pixel source quad
lda #2
adc source
sta source
clc ; Increment to next stencil byte
lda #1
adc stenO
sta stenO
clc
lda xc ; Increment X counter
adc #1
sta xc
cmp #2 ; End of X pixels?
bcc blitTop ; Nope!
lda #0 ; Reset X counter
sta xc
clc ; Increment target offset
lda #156
adc target
sta target
clc ; Increment source offset
lda #156
adc source
sta source
clc ; Increment stencil mask offset
lda #39
adc stenO
sta stenO
clc
lda yc ; Increment Y counter
adc #1
sta yc
cmp #8 ; End of Y pixels?
bcs blitDone ; Yep!
brl blitTop ; Back for more
blitDone jreturn
end
;----------------------------------------
; Set Border Color
;----------------------------------------
......@@ -879,7 +1023,7 @@ temp1 equ 1
lda Yp ; Load accumulator with Y location
asl a ; Shift accumulator left (multiply by 2) for word offset into table
tay ; Transfer accumulator to y register
lda ScanTable,y ; Look up scan line address offset
lda ScTable,y ; Look up scan line address offset
sta temp1 ; Store accumulator (row offset into SHR memory) into temp1
clc ; Clear carry flag
lda Xp ; Place X position in accumulator
......@@ -1100,7 +1244,7 @@ PBoth sta temp3 ; Store accumulator in temp3
lda Yp ; Load accumulator with Y location
asl a ; Shift accumulator left (multiply by 2)
tay ; Transfer accumulator to y register
lda ScanTable,y ; Look up scan line address offset
lda ScTable,y ; Look up scan line address offset
adc temp1 ; Add X position to address with carry
tay ; Transfer accumulator to y
......@@ -1348,13 +1492,24 @@ asmStart start
ldy #0 ; Load 0 into y register
lda #0 ; Load 0 into accumulator
clc ; Clear carry flag
buildTable anop
sta ScanTable,y ; Store accumulator in ScanTable+x
adc #160 ; Add 160 to accumulator
tScan anop
sta ScTable,y ; Store accumulator in ScTable+x
adc #160 ; Add 160 to accumulator (320 pixels / 2 pixels per byte)
iny ; Increment y
iny ; Increment y
cpy #400 ; Compare y to 400 (200 scanlines)
bcc buildTable ; Repeat Scan Table Loop until we do all 200 lines
bcc tScan ; Repeat Scan Table Loop until we do all 200 lines
ldy #0 ; Load 0 into y register
lda #0 ; Load 0 into accumulator
clc ; Clear carry flag
tSten anop
sta StTable,y ; Store accumulator in StencilTable+x
adc #320 ; Add 320 to accumulator (8 lines * 40 bytes)
iny ; Increment y
iny ; Increment y
cpy #50 ; Compare y to 50 (25 stencil cell offsets)
bcc tSten ; Repeat Stencil Table Loop until we do all 25 cells
lda hertz ; Store refresh rate / 10 in VblCount and VblRate
sta >VblRate
......
......@@ -156,6 +156,29 @@ 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));
*img = t;
return true;
}
return false;
}
void jlImgDisplay(jlImgT *img) {
memcpy(SHRCOLORS, img->palette, sizeof(img->palette));
memcpy(SHRPIXELS, img->pixels, sizeof(img->pixels));
}
char _jlKeyCheck(char key) {
if ((key < 8) || (key > 127)) {
key = 0;
......@@ -206,8 +229,8 @@ void jlPaletteSet(byte index, byte r, byte g, byte b) {
}
void jlPaletteSetFromSta(jlStaT *sta) {
memcpy(SHRCOLORS, sta->palette, sizeof(sta->palette));
void jlPaletteSetFromImg(jlImgT *img) {
memcpy(SHRCOLORS, img->palette, sizeof(img->palette));
}
......@@ -266,29 +289,6 @@ void jlSoundPlay(jlSoundT *sound) {
}
bool _jlStaCreate(jlStaT **sta) {
jlStaT *t = (jlStaT *)jlMalloc(sizeof(jlStaT));
if (t != NULL) {
memset(t, 0, sizeof(jlStaT));
t->id[0] = 'S';
t->id[1] = 'T';
t->id[2] = 'A';
t->version = 0;
memcpy(t->palette, SHRCOLORS, sizeof(t->palette));
memcpy(t->pixels, SHRPIXELS, sizeof(t->pixels));
*sta = t;
return true;
}
return false;
}
void jlStaDisplay(jlStaT *sta) {
memcpy(SHRCOLORS, sta->palette, sizeof(sta->palette));
memcpy(SHRPIXELS, sta->pixels, sizeof(sta->pixels));
}
void jlUtilIdle(void) {
// No need to pump the message loop on the IIgs
}
......
......@@ -177,42 +177,6 @@ void jlDrawBlit8x8(jlSurfaceT source, jint16 sx, jint16 sy, jint16 tx, jint16 ty
}
/*
void jlDrawBlit8x8a(jlSurfaceT source, jint16 sx, jint16 sy, jint16 tx, jint16 ty, byte offset) {
int mo; // Mask offset
int so; // Source Pixel Offset
int to; // Target Pixel Offset
int x;
int y;
jlPixelPairT m; // Mask
jlPixelPairT s; // Source Pixel
jlPixelPairT t; // Target Pixel
jlPixelPairT *pixels = (jlPixelPairT *)source;
jlPixelPairT *target = (jlPixelPairT *)_jlDrawTargetActual;
// We mask off unused bits in the source tile location so they can be used to hold other data.
mo = ((sy & 0x1f) * 8 * 160) + (((sx & 0x3f) + offset) * 4); // This is in tiles
so = ((sy & 0x1f) * 8 * 160) + ((sx & 0x3f) * 4); // This is in tiles
if (jlUtilIsOdd(tx)) tx--; // tx must be even because there are two pixels per byte
to = ty * 160 + (int)(tx * 0.5); // This is in pixels...
for (y=0; y<8; y++) {
for (x=0; x<4; x++) {
m = pixels[mo++];
s = pixels[so++];
t = target[to];
t.r = (t.r & m.r) | s.r;
t.l = (t.l & m.l) | s.l;
target[to++] = t;
}
mo += 156;
so += 156;
to += 156;
}
}
*/
void jlDrawBlit8x8a(jlSurfaceT source, jlStnT *stencil, jint16 sx, jint16 sy, jint16 tx, jint16 ty) {
int mo; // Mask offset
int so; // Source Pixel Offset
......@@ -238,11 +202,11 @@ void jlDrawBlit8x8a(jlSurfaceT source, jlStnT *stencil, jint16 sx, jint16 sy, ji
s = pixels[so++];
//***FIX*** Another endian order issue. Left & Right are swapped.
if ((stencil->pixels[mo] & (1 << b--)) == 0) {
if ((stencil->pixels[mo] & (1 << b--)) != 0) {
t.r = s.r;
}
if ((stencil->pixels[mo] & (1 << b--)) == 0) {
if ((stencil->pixels[mo] & (1 << b--)) != 0) {
t.l = s.l;
}
......
......@@ -324,7 +324,7 @@ bool _jlVecLoad(jlVecT **vec, char *filename);
#ifdef JOEY_IIGS
// Inlined functions - asm code
extern void asmB88(jlSurfaceT target, jlSurfaceT source, jint16 cx1, jint16 cy1, jint16 cx2, jint16 cy2);
extern void asmB88a(jlSurfaceT target, jlSurfaceT source, jint16 cx1, jint16 cy1, jint16 cx2, jint16 cy2, byte alphaOffset);
extern void asmB88a(jlSurfaceT target, jlSurfaceT source, byte *stencil, jint16 cx1, jint16 cy1, jint16 cx2, jint16 cy2);
extern void asmDrawBM(jlSurfaceT target, jint16 startX, jint16 startY, jint16 width, jint16 height, byte *mapData, juint16 stride, jlSurfaceT source);
//extern void asmDrawLine(jlSurfaceT target, jint16 color, jint16 x1, jint16 y1, jint16 x2, jint16 y2);
extern jint16 asmGetPoint(jlSurfaceT target, jint16 x, jint16 y);
......@@ -334,7 +334,7 @@ extern void asmPoint(jlSurfaceT target, jint16 color, jint16 x, jint16 y);
// Inlined functions
#define jlDrawBlit8x8(source, cx1, cy1, cx2, cy2) asmB88(_jlDrawTargetActual, source, cx1, cy1, cx2, cy2)
#define jlDrawBlit8x8a(source, cx1, cy1, cx2, cy2, offset) asmB88a(_jlDrawTargetActual, source, cx1, cy1, cx2, cy2, offset)
#define jlDrawBlit8x8a(source, stencil, cx1, cy1, cx2, cy2) asmB88a(_jlDrawTargetActual, source, (byte *)stencil, cx1, cy1, cx2, cy2)
#define jlDrawBlitMap(startX, startY, width, height, mapData, stride, source) asmDrawBM(_jlDrawTargetActual, startX, startY, width, height, (byte *)mapData, stride, source)
#define jlDrawPixelGet(x, y) asmGetPoint(_jlDrawTargetActual, x, y)
#define jlDrawPixelSet(x, y) asmPoint(_jlDrawTargetActual, _jlDrawColorNibbles, x, y)
......
......@@ -41,8 +41,8 @@ extern void asmDrawLine(jlSurfaceT target, jint16 color, jint16 x1, jint16 y1
// Font hacking!
__attribute__((__format__ (__printf__, 4, 0)))
void printAt(jlImgT *font, jint16 cx, jint16 cy, const char *what, ...) {
__attribute__((__format__ (__printf__, 5, 0)))
void printAt(jlImgT *font, jlStnT *stencil, jint16 cx, jint16 cy, const char *what, ...) {
jint16 x;
jint16 y;
jint16 tx;
......@@ -63,7 +63,11 @@ void printAt(jlImgT *font, jint16 cx, jint16 cy, const char *what, ...) {
//y = (msg[counter] - ' ') / 40;
x = msg[counter] % 40;
y = msg[counter] / 40;
jlDrawBlit8x8(jlImgSurfaceGet(font), x, y, tx, ty);
if (stencil) {
jlDrawBlit8x8a(jlImgSurfaceGet(font), stencil, x, y, tx, ty);
} else {
jlDrawBlit8x8(jlImgSurfaceGet(font), x, y, tx, ty);
}
tx += 8;
}
}
......@@ -99,7 +103,7 @@ void lineTest(void) {
while (!jlKeyPressed()) {
y = 17;
//printAt(font, 1, y++, "R = %d ", asmTest((jlSurfaceT)0x012000));
printAt(font, 1, y++, "Drawing %s ", what);
printAt(font, NULL, 1, y++, "Drawing %s ", what);
jlDrawColorSet((byte)color);
if (phase < 2) {
......@@ -191,6 +195,12 @@ void blitTest(void) {
jlDrawClear();
jlPaletteSet(15, 15, 15, 15);
printAt(font, NULL, 1, 2, "%s", "Blitting without stencil buffer.");
printAt(font, stencil, 1, 4, "%s", "Blitting with stencil buffer.");
jlDisplayPresent();
jlKeyWaitForAny();
/*
y = 91;
while (!jlKeyPressed()) {
for (x=0; x<319-8; x++) {
......@@ -202,7 +212,7 @@ void blitTest(void) {
}
jlDrawBlit8x8(jlImgSurfaceGet(font), 1, 0, x, y);
printAt(font, 1, 1, "Drawing at %d x %d ", x, y);
printAt(font, NULL, 1, 1, "Drawing at %d x %d ", x, y);
jlDisplayPresent();
jlDrawBlit8x8(jlImgSurfaceGet(font), 0, 0, x, y);
jlUtilSleep(1);
......@@ -212,6 +222,7 @@ void blitTest(void) {
}
}
jlKeyRead();
*/
jlStnFree(stencil);
jlImgFree(font);
......
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