New blitting routines working!

This commit is contained in:
Scott Duensing 2019-10-08 19:58:26 -05:00
parent 0ecf3e1c8b
commit 910a735c08
4 changed files with 179 additions and 127 deletions

View file

@ -35,71 +35,67 @@ VblTime ds 2 ; Integer Counter
;---------------------------------------- ;----------------------------------------
; Blit an 8x8 block. ***TODO*** Unroll loops ; Blit an 8x8 block to (almost) anywhere on a surface.
;---------------------------------------- ;----------------------------------------
asmB88 start asmB88 start
so equ 1 ; Source Pixels Offset source equ 1 ; Source Pixels Offset
to equ 3 ; Target Pixels Offset target equ 3 ; Target Pixels Offset
t equ 5 ; Temp t equ 5 ; Temp
xc equ 7 ; X Counter xc equ 7 ; X Counter
yc equ 9 ; Y Counter yc equ 9 ; Y Counter
jsubroutine (4:surface,4:tiles,2:cx1,2:cy1,2:cx2,2:cy2),10 jsubroutine (4:surface,4:tiles,2:sx,2:sy,2:tx,2:ty),10
using GlobalData using GlobalData
; Find offset into tile memory ; Find offset into tile memory
lda cx1 ; Multiply cx1 by 4 to get offset (two pixels per byte) lda sx ; Multiply sx by 4 to get offset (two pixels per byte)
asl a asl a
asl a asl a
sta t sta t
clc clc
lda cy1 ; Multiply cy1 by 16 to get index into scanline table lda sy ; Multiply sy by 16 to get index into scanline table
asl a asl a
asl a asl a
asl a asl a
asl a ; y screen location is now in the accumulator asl a ; y screen location is now in the accumulator
tax tay
clc clc
lda >ScanTable,x ; Load byte offset of y position from table lda ScanTable,y ; Load byte offset of y position from table
adc t ; Add t to scanline offset adc t ; Add t to scanline offset
sta so ; Offset to start of source pixels 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 cx2
; Find offset into target surface memory ; Find offset into target surface memory
clc lda ty ; Load ty to get index into scanline table
lda cx2 ; Multiply cx2 by 4 to get offset (two pixels per byte) asl a ; Multiply by two to get offset into scanline table (two bytes per entry in table)
asl a tay
asl a lda ScanTable,y ; Load byte offset of y position from table
sta t adc tx ; Add x position to scanline offset
clc sta target ; Offset to start of target pixels
lda cy2 ; Multiply cy2 by 16 to get index into scanline table
asl a
asl a
asl a
asl a ; y screen location is now in the accumulator
clc
tax
lda >ScanTable,x ; Load byte offset of y position from table
adc t ; Add t to scanline offset
sta to ; Offset to start of target pixels
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
blitTop ldy so ; Load Y register with source pixel offset blitTop ldy source ; Load Y register with source pixel offset
lda [tiles],y ; Load 4 tile pixels lda [tiles],y ; Load 4 tile pixels
ldy to ; Load Y register with target pixel offset ldy target ; Load Y register with target pixel offset
sta [surface],y ; Store 4 pixels into screen sta [surface],y ; Store 4 pixels into screen
clc ; Increment to next pixel target quad clc ; Increment to next pixel target quad
lda #2 lda #2
adc to adc target
sta to sta target
clc ; Increment to next pixel source quad clc ; Increment to next pixel source quad
lda #2 lda #2
adc so adc source
sta so sta source
clc clc
lda xc ; Increment X counter lda xc ; Increment X counter
@ -112,12 +108,12 @@ blitTop ldy so ; Load Y register with source pixel offset
sta xc sta xc
clc ; Increment target offset clc ; Increment target offset
lda #156 lda #156
adc to adc target
sta to sta target
clc ; Increment source offset clc ; Increment source offset
lda #156 lda #156
adc so adc source
sta so sta source
clc clc
lda yc ; Increment Y counter lda yc ; Increment Y counter
adc #1 adc #1
@ -130,88 +126,84 @@ blitTop ldy so ; Load Y register with source pixel offset
;---------------------------------------- ;----------------------------------------
; Blit an 8x8 block with alpha. ; Blit an 8x8 block with alpha to (almost) anywhere on a surface.
;---------------------------------------- ;----------------------------------------
asmB88a start asmB88a start
so equ 1 ; Source Pixels Offset source equ 1 ; Source Pixels Offset
to equ 3 ; Target Pixels Offset target equ 3 ; Target Pixels Offset
mo equ 5 ; Mask Offset mask equ 5 ; Mask Offset
t equ 7 ; Temp t equ 7 ; Temp
xc equ 9 ; X Counter xc equ 9 ; X Counter
yc equ 11 ; Y Counter yc equ 11 ; Y Counter
jsubroutine (4:surface,4:tiles,2:cx1,2:cy1,2:cx2,2:cy2,2:offset),12 jsubroutine (4:surface,4:tiles,2:sx,2:sy,2:tx,2:ty,2:offset),12
using GlobalData using GlobalData
; Find offset into tile memory ; Find offset into tile memory
lda cx1 ; Multiply cx1 by 4 to get offset (two pixels per byte) lda sx ; Multiply sx by 4 to get offset (two pixels per byte)
asl a asl a
asl a asl a
sta t sta t
clc clc
lda cy1 ; Multiply cy1 by 16 to get index into scanline table lda sy ; Multiply sy by 16 to get index into scanline table
asl a asl a
asl a asl a
asl a asl a
asl a ; y screen location is now in the accumulator asl a ; y screen location is now in the accumulator
tax tay
clc clc
lda >ScanTable,x ; Load byte offset of y position from table lda ScanTable,y ; Load byte offset of y position from table
adc t ; Add t to scanline offset adc t ; Add t to scanline offset
sta so ; Offset to start of source pixels sta source ; Offset to start of source pixels
; Find offset into tile memory for mask data ; Find offset into tile memory for mask data
lda offset ; Load offset lda offset ; Load offset
asl a ; Multiply by 4 asl a ; Multiply by 4
asl a asl a
clc clc
adc so ; Add to source pixel offset adc source ; Add to source pixel offset
sta mo ; Offset to start of mask pixels sta mask ; Offset to start of mask 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 ; Find offset into target surface memory
clc lda ty ; Load ty to get index into scanline table
lda cx2 ; Multiply cx2 by 4 to get offset (two pixels per byte) asl a ; Multiply by two to get offset into scanline table (two bytes per entry in table)
asl a tay
asl a lda ScanTable,y ; Load byte offset of y position from table
sta t adc tx ; Add x position to scanline offset
clc sta target ; Offset to start of target pixels
lda cy2 ; Multiply cy2 by 16 to get index into scanline table
asl a
asl a
asl a
asl a ; y screen location is now in the accumulator
clc
tax
lda >ScanTable,x ; Load byte offset of y position from table
adc t ; Add t to scanline offset
sta to ; Offset to start of target pixels
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
blitTop ldy to ; Load Y register with target pixel offset blitTop ldy target ; Load Y register with target pixel offset
lda [surface],y ; Load target pixels lda [surface],y ; Load target pixels
ldy mo ; Load Y register with mask pixel offset ldy mask ; Load Y register with mask pixel offset
and [tiles],y ; AND with mask and [tiles],y ; AND with mask
ldy so ; Load Y register with source pixel offset ldy source ; Load Y register with source pixel offset
ora [tiles],y ; OR with source pixels ora [tiles],y ; OR with source pixels
ldy to ; Load Y register with target pixel offset ldy target ; Load Y register with target pixel offset
sta [surface],y ; Store 4 pixels into screen sta [surface],y ; Store 4 pixels into screen
clc ; Increment to next pixel target quad clc ; Increment to next pixel target quad
lda #2 lda #2
adc to adc target
sta to sta target
clc ; Increment to next pixel source quad clc ; Increment to next pixel source quad
lda #2 lda #2
adc so adc source
sta so sta source
clc ; Increment to next pixel mask quad clc ; Increment to next pixel mask quad
lda #2 lda #2
adc mo adc mask
sta mo sta mask
clc clc
lda xc ; Increment X counter lda xc ; Increment X counter
@ -224,16 +216,16 @@ blitTop ldy to ; Load Y register with target pixel offset
sta xc sta xc
clc ; Increment target offset clc ; Increment target offset
lda #156 lda #156
adc to adc target
sta to sta target
clc ; Increment source offset clc ; Increment source offset
lda #156 lda #156
adc so adc source
sta so sta source
clc ; Increment mask offset clc ; Increment mask offset
lda #156 lda #156
adc mo adc mask
sta mo sta mask
clc clc
lda yc ; Increment Y counter lda yc ; Increment Y counter
adc #1 adc #1
@ -245,7 +237,6 @@ blitTop ldy to ; Load Y register with target pixel offset
end end
;---------------------------------------- ;----------------------------------------
; Set Border Color ; Set Border Color
;---------------------------------------- ;----------------------------------------
@ -278,15 +269,21 @@ loopY equ 9
sta offset sta offset
clc ; Find loop ending values clc ; Find loop ending values
lda startX lda width ; Load width of map to draw, in tiles
adc width asl a ; Multiply by 8 to get pixels
sta loopX asl a
asl a
adc startX ; Add starting position in pixels
sta loopX ; Store it
clc clc
lda startY lda height ; Load height of map to draw, in tiles
adc height asl a ; Multiply by 8 to get pixels
sta loopY asl a
asl a
adc startY ; Add starting position in pixels
sta loopY ; Store it
ldx startX ; Loop counters ldx startX ; Initialize loop counters
ldy startY ldy startY
drawTop phy ; Keep Y for later drawTop phy ; Keep Y for later
@ -316,7 +313,9 @@ drawTop phy ; Keep Y for later
ply ; Unclobber ply ; Unclobber
plx plx
inx ; Increment x loop txa ; Increment x loop
adc #8 ; Increment in pixels
tax
cpx loopX ; Loop until 'width' cpx loopX ; Loop until 'width'
bcc drawTop bcc drawTop
@ -325,7 +324,9 @@ drawTop phy ; Keep Y for later
lda offset ; Add stride to offset lda offset ; Add stride to offset
adc stride adc stride
sta offset sta offset
iny ; Increment y loop tya ; Increment y loop
adc #8 ; Increment in pixels
tay
cpy loopY ; Loop until 'height' cpy loopY ; Loop until 'height'
bcc drawTop bcc drawTop

View file

@ -154,7 +154,7 @@ void jlDisplayPresent(void) {
} }
void jlDrawBlit8x8(jlSurfaceT source, jint16 cx1, jint16 cy1, jint16 cx2, jint16 cy2) { void jlDrawBlit8x8(jlSurfaceT source, jint16 sx, jint16 sy, jint16 tx, jint16 ty) {
int o1; int o1;
int o2; int o2;
int x; int x;
@ -163,8 +163,9 @@ void jlDrawBlit8x8(jlSurfaceT source, jint16 cx1, jint16 cy1, jint16 cx2, jint16
jlPixelPairT *target = (jlPixelPairT *)_jlDrawTargetActual; jlPixelPairT *target = (jlPixelPairT *)_jlDrawTargetActual;
// We mask off unused bits in the source tile location so they can be used to hold other data. // We mask off unused bits in the source tile location so they can be used to hold other data.
o1 = ((cy1 & 0x1f) * 8 * 160) + ((cx1 & 0x3f) * 4); o1 = ((sy & 0x1f) * 8 * 160) + ((sx & 0x3f) * 4); // This is in tiles
o2 = (cy2 * 8 * 160) + (cx2 * 4); o2 = ty * 160 + (int)(tx * 0.5); // This is in pixels...
if (jlUtilIsOdd(o2)) o2--; //...and must be even
for (y=0; y<8; y++) { for (y=0; y<8; y++) {
for (x=0; x<4; x++) { for (x=0; x<4; x++) {
@ -176,7 +177,7 @@ void jlDrawBlit8x8(jlSurfaceT source, jint16 cx1, jint16 cy1, jint16 cx2, jint16
} }
void jlDrawBlit8x8a(jlSurfaceT source, jint16 cx1, jint16 cy1, jint16 cx2, jint16 cy2, byte offset) { void jlDrawBlit8x8a(jlSurfaceT source, jint16 sx, jint16 sy, jint16 tx, jint16 ty, byte offset) {
int mo; // Mask offset int mo; // Mask offset
int so; // Source Pixel Offset int so; // Source Pixel Offset
int to; // Target Pixel Offset int to; // Target Pixel Offset
@ -189,9 +190,10 @@ void jlDrawBlit8x8a(jlSurfaceT source, jint16 cx1, jint16 cy1, jint16 cx2, jint1
jlPixelPairT *target = (jlPixelPairT *)_jlDrawTargetActual; jlPixelPairT *target = (jlPixelPairT *)_jlDrawTargetActual;
// We mask off unused bits in the source tile location so they can be used to hold other data. // We mask off unused bits in the source tile location so they can be used to hold other data.
mo = ((cy1 & 0x1f) * 8 * 160) + (((cx1 & 0x3f) + offset) * 4); mo = ((sy & 0x1f) * 8 * 160) + (((sx & 0x3f) + offset) * 4); // This is in tiles
so = ((cy1 & 0x1f) * 8 * 160) + ((cx1 & 0x3f) * 4); so = ((sy & 0x1f) * 8 * 160) + ((sx & 0x3f) * 4); // This is in tiles
to = (cy2 * 8 * 160) + (cx2 * 4); to = ty * 160 + (int)(tx * 0.5); // This is in pixels...
if (jlUtilIsOdd(to)) to--; //...and must be even
for (y=0; y<8; y++) { for (y=0; y<8; y++) {
for (x=0; x<4; x++) { for (x=0; x<4; x++) {
@ -210,21 +212,23 @@ void jlDrawBlit8x8a(jlSurfaceT source, jint16 cx1, jint16 cy1, jint16 cx2, jint1
void jlDrawBlitMap(jint16 startX, jint16 startY, jint16 width, jint16 height, byte *mapData, juint16 stride, jlSurfaceT source) { void jlDrawBlitMap(jint16 startX, jint16 startY, jint16 width, jint16 height, byte *mapData, juint16 stride, jlSurfaceT source) {
// startX = start tile for drawing // startX = start tile for drawing - in pixels
// startY = start tile for drawing // startY = start tile for drawing - in pixels
// width = tiles to draw horizontally // width = tiles to draw horizontally - in tiles
// height = tiles to draw vertically // height = tiles to draw vertically - in tiles
// mapData = pointer to tile x/y pairs to draw // mapData = pointer to tile x/y pairs to draw
// stride = number of tile bytes to skip in the mapData for every horizontal line // stride = number of tile bytes to skip in the mapData for every horizontal line
// tiles = sta to fetch tile data from // tiles = surface to fetch tile data from
jint16 x; jint16 x;
jint16 y; jint16 y;
byte tileX; byte tileX;
byte tileY; byte tileY;
juint16 offset = 0; juint16 offset = 0;
jint16 endX = width * 8 + startX;
jint16 endY = height * 8 + startY;
for (y=startY; y<height; y++) { for (y=startY; y<endY; y+=8) {
for (x=startX; x<width; x++) { for (x=startX; x<endX; x+=8) {
tileX = mapData[offset++]; tileX = mapData[offset++];
tileY = mapData[offset++]; tileY = mapData[offset++];
jlDrawBlit8x8(source, tileX, tileY, x, y); jlDrawBlit8x8(source, tileX, tileY, x, y);

View file

@ -224,15 +224,11 @@ void *_jlRealloc(void *pointer, size_t size);
#endif #endif
#define jlByteSwap(twoBytes) ((juint16)((twoBytes) & 0xff) >> 8) | (juint16)((twoBytes) << 8)
#define jlStaSurfaceGet(sta) ((jlSurfaceT)sta->pixels)
void jlDisplayBorder(jlBorderColorsE color); void jlDisplayBorder(jlBorderColorsE color);
void jlDisplayPresent(void); void jlDisplayPresent(void);
void jlDrawBlit8x8(jlSurfaceT source, jint16 cx1, jint16 cy1, jint16 cx2, jint16 cy2); void jlDrawBlit8x8(jlSurfaceT source, jint16 sx, jint16 sy, jint16 tx, jint16 ty);
void jlDrawBlit8x8a(jlSurfaceT source, jint16 cx1, jint16 cy1, jint16 cx2, jint16 cy2, byte offset); void jlDrawBlit8x8a(jlSurfaceT source, jint16 sx, jint16 sy, jint16 tx, jint16 ty, byte offset);
void jlDrawBlitMap(jint16 startX, jint16 startY, jint16 width, jint16 height, byte *mapData, juint16 stride, jlSurfaceT source); void jlDrawBlitMap(jint16 startX, jint16 startY, jint16 width, jint16 height, byte *mapData, juint16 stride, jlSurfaceT source);
void jlDrawBox(jint16 x1, jint16 y1, jint16 x2, jint16 y2); void jlDrawBox(jint16 x1, jint16 y1, jint16 x2, jint16 y2);
void jlDrawBoxFilled(jint16 x1, jint16 y1, jint16 x2, jint16 y2); void jlDrawBoxFilled(jint16 x1, jint16 y1, jint16 x2, jint16 y2);
@ -281,7 +277,9 @@ void jlStaFree(jlStaT *sta);
#define jlStaLoad(sta, filename) _jlStaLoad((jlStaT **)&(sta), filename) // Syntatic Sugar #define jlStaLoad(sta, filename) _jlStaLoad((jlStaT **)&(sta), filename) // Syntatic Sugar
bool _jlStaLoad(jlStaT **sta, char *filename); bool _jlStaLoad(jlStaT **sta, char *filename);
bool jlStaSave(jlStaT *sta, char *filename); bool jlStaSave(jlStaT *sta, char *filename);
#define jlStaSurfaceGet(sta) ((jlSurfaceT)sta->pixels)
#define jlUtilByteSwap(twoBytes) ((juint16)((twoBytes) & 0xff) >> 8) | (juint16)((twoBytes) << 8)
void jlUtilDie(const char *why, ...) __attribute__((noreturn)); void jlUtilDie(const char *why, ...) __attribute__((noreturn));
void jlUtilIdle(void); void jlUtilIdle(void);
#define jlUtilIsOdd(x) (((x & 1) == 1) ? true : false) #define jlUtilIsOdd(x) (((x & 1) == 1) ? true : false)

View file

@ -32,8 +32,8 @@ segment "testapp";
#endif #endif
extern jint16 asmTest(jlSurfaceT source); //extern jint16 asmTest(jlSurfaceT source);
extern void asmDrawLine(jlSurfaceT target, jint16 color, jint16 x1, jint16 y1, jint16 x2, jint16 y2); //extern void asmDrawLine(jlSurfaceT target, jint16 color, jint16 x1, jint16 y1, jint16 x2, jint16 y2);
// Font hacking! // Font hacking!
@ -41,6 +41,8 @@ __attribute__((__format__ (__printf__, 4, 0)))
void printAt(jlStaT *font, jint16 cx, jint16 cy, const char *what, ...) { void printAt(jlStaT *font, jint16 cx, jint16 cy, const char *what, ...) {
jint16 x; jint16 x;
jint16 y; jint16 y;
jint16 tx;
jint16 ty;
jint16 counter; jint16 counter;
char msg[40]; // Very short messages (screen width). Be careful! char msg[40]; // Very short messages (screen width). Be careful!
va_list va; va_list va;
@ -49,15 +51,19 @@ void printAt(jlStaT *font, jint16 cx, jint16 cy, const char *what, ...) {
vsprintf(msg, what, va); vsprintf(msg, what, va);
va_end(va); va_end(va);
tx = cx * 8;
ty = cy * 8;
for (counter=0; counter<(int)strlen(msg); counter++) { for (counter=0; counter<(int)strlen(msg); counter++) {
x = (msg[counter] - ' ') % 40; x = (msg[counter] - ' ') % 40;
y = (msg[counter] - ' ') / 40; y = (msg[counter] - ' ') / 40;
jlDrawBlit8x8(jlStaSurfaceGet(font), x, y, counter + cx, cy); jlDrawBlit8x8(jlStaSurfaceGet(font), x, y, tx, ty);
tx += 8;
} }
} }
int main(void) { void lineTest(void) {
jlStaT *kanga = NULL; jlStaT *kanga = NULL;
jlStaT *font = NULL; jlStaT *font = NULL;
@ -72,8 +78,6 @@ int main(void) {
jint16 nextColor = 1; jint16 nextColor = 1;
char what[32]; char what[32];
jlUtilStartup("JoeyLib Test");
if (!jlStaLoad(kanga, "kanga")) jlUtilDie("Unable to load kanga.sta!"); if (!jlStaLoad(kanga, "kanga")) jlUtilDie("Unable to load kanga.sta!");
if (!jlStaLoad(font, "font")) jlUtilDie("Unable to load font.sta!"); if (!jlStaLoad(font, "font")) jlUtilDie("Unable to load font.sta!");
@ -92,11 +96,13 @@ int main(void) {
printAt(font, 1, y++, "Drawing %s ", what); printAt(font, 1, y++, "Drawing %s ", what);
jlDrawColorSet((byte)color); jlDrawColorSet((byte)color);
/*
if (phase < 2) { if (phase < 2) {
asmDrawLine(_jlDrawTargetActual, _jlDrawColor, x2, y2, 319-x2, 199-y2); asmDrawLine(_jlDrawTargetActual, _jlDrawColor, x2, y2, 319-x2, 199-y2);
} else { } else {
asmDrawLine(_jlDrawTargetActual, _jlDrawColor, 319-x2, 199-y2, x2, y2); asmDrawLine(_jlDrawTargetActual, _jlDrawColor, 319-x2, 199-y2, x2, y2);
} }
*/
ox = x2; ox = x2;
oy = y2; oy = y2;
op = phase; op = phase;
@ -142,11 +148,13 @@ int main(void) {
jlDisplayPresent(); jlDisplayPresent();
jlDrawColorSet((byte)0); jlDrawColorSet((byte)0);
/*
if (op < 2) { if (op < 2) {
asmDrawLine(_jlDrawTargetActual, _jlDrawColor, ox, oy, 319-ox, 199-oy); asmDrawLine(_jlDrawTargetActual, _jlDrawColor, ox, oy, 319-ox, 199-oy);
} else { } else {
asmDrawLine(_jlDrawTargetActual, _jlDrawColor, 319-ox, 199-oy, ox, oy); asmDrawLine(_jlDrawTargetActual, _jlDrawColor, 319-ox, 199-oy, ox, oy);
} }
*/
color = nextColor; color = nextColor;
nextColor++; nextColor++;
@ -160,6 +168,47 @@ int main(void) {
jlStaFree(font); jlStaFree(font);
jlStaFree(kanga); jlStaFree(kanga);
}
void blitTest(void) {
jlStaT *font = NULL;
jint16 y;
jint16 x;
if (!jlStaLoad(font, "font")) jlUtilDie("Unable to load font.sta!");
jlStaDisplay(font);
jlDisplayPresent();
jlKeyWaitForAny();
jlDrawColorSet(1);
jlDrawClear();
jlPaletteSet(15, 15, 15, 15);
y = 91;
while (!jlKeyPressed()) {
for (x=0; x<319-8; x++) {
jlDrawBlit8x8(jlStaSurfaceGet(font), 6, 3, x, y);
printAt(font, 1, 1, "Drawing at %d x %d ", x, y);
jlDisplayPresent();
jlDrawBlit8x8(jlStaSurfaceGet(font), 0, 0, x, y);
if (jlKeyPressed()) {
break;
}
}
}
jlKeyRead();
jlStaFree(font);
}
int main(void) {
jlUtilStartup("JoeyLib Test");
//lineTest();
blitTest();
jlUtilShutdown(); jlUtilShutdown();
} }