Commit 910a735c authored by Scott Duensing's avatar Scott Duensing

New blitting routines working!

parent 0ecf3e1c
......@@ -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
so equ 1 ; Source Pixels Offset
to equ 3 ; Target Pixels Offset
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
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
; 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
sta t
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 ; y screen location is now in the accumulator
tax
tay
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
sta so ; Offset to start of source pixels
sta source ; Offset to start of source pixels
; Find offset into target surface memory
clc
lda cx2 ; Multiply cx2 by 4 to get offset (two pixels per byte)
asl a
asl a
sta t
clc
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
; 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
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
sta tx ; Store it back into cx2
; 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 ScanTable,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
lda #0 ; Load 0 into X and Y counters
sta xc
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
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
clc ; Increment to next pixel target quad
lda #2
adc to
sta to
adc target
sta target
clc ; Increment to next pixel source quad
lda #2
adc so
sta so
adc source
sta source
clc
lda xc ; Increment X counter
......@@ -112,12 +108,12 @@ blitTop ldy so ; Load Y register with source pixel offset
sta xc
clc ; Increment target offset
lda #156
adc to
sta to
adc target
sta target
clc ; Increment source offset
lda #156
adc so
sta so
adc source
sta source
clc
lda yc ; Increment Y counter
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
so equ 1 ; Source Pixels Offset
to equ 3 ; Target Pixels Offset
mo equ 5 ; Mask Offset
source equ 1 ; Source Pixels Offset
target equ 3 ; Target Pixels Offset
mask equ 5 ; Mask Offset
t equ 7 ; Temp
xc equ 9 ; X 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
; 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
sta t
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 ; y screen location is now in the accumulator
tax
tay
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
sta so ; Offset to start of source pixels
sta source ; Offset to start of source pixels
; Find offset into tile memory for mask data
lda offset ; Load offset
asl a ; Multiply by 4
asl a
clc
adc so ; Add to source pixel offset
sta mo ; Offset to start of mask pixels
adc source ; Add to source pixel offset
sta mask ; Offset to start of mask pixels
; Find offset into target surface memory
clc
lda cx2 ; Multiply cx2 by 4 to get offset (two pixels per byte)
asl a
asl a
sta t
; 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
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
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 ScanTable,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
lda #0 ; Load 0 into X and Y counters
sta xc
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
ldy mo ; Load Y register with mask pixel offset
ldy mask ; Load Y register with mask pixel offset
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
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
clc ; Increment to next pixel target quad
lda #2
adc to
sta to
adc target
sta target
clc ; Increment to next pixel source quad
lda #2
adc so
sta so
adc source
sta source
clc ; Increment to next pixel mask quad
lda #2
adc mo
sta mo
adc mask
sta mask
clc
lda xc ; Increment X counter
......@@ -224,16 +216,16 @@ blitTop ldy to ; Load Y register with target pixel offset
sta xc
clc ; Increment target offset
lda #156
adc to
sta to
adc target
sta target
clc ; Increment source offset
lda #156
adc so
sta so
adc source
sta source
clc ; Increment mask offset
lda #156
adc mo
sta mo
adc mask
sta mask
clc
lda yc ; Increment Y counter
adc #1
......@@ -245,7 +237,6 @@ blitTop ldy to ; Load Y register with target pixel offset
end
;----------------------------------------
; Set Border Color
;----------------------------------------
......@@ -278,15 +269,21 @@ loopY equ 9
sta offset
clc ; Find loop ending values
lda startX
adc width
sta loopX
lda width ; Load width of map to draw, in tiles
asl a ; Multiply by 8 to get pixels
asl a
asl a
adc startX ; Add starting position in pixels
sta loopX ; Store it
clc
lda startY
adc height
sta loopY
lda height ; Load height of map to draw, in tiles
asl a ; Multiply by 8 to get pixels
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
drawTop phy ; Keep Y for later
......@@ -316,7 +313,9 @@ drawTop phy ; Keep Y for later
ply ; Unclobber
plx
inx ; Increment x loop
txa ; Increment x loop
adc #8 ; Increment in pixels
tax
cpx loopX ; Loop until 'width'
bcc drawTop
......@@ -325,7 +324,9 @@ drawTop phy ; Keep Y for later
lda offset ; Add stride to offset
adc stride
sta offset
iny ; Increment y loop
tya ; Increment y loop
adc #8 ; Increment in pixels
tay
cpy loopY ; Loop until 'height'
bcc drawTop
......
......@@ -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 o2;
int x;
......@@ -163,8 +163,9 @@ void jlDrawBlit8x8(jlSurfaceT source, jint16 cx1, jint16 cy1, jint16 cx2, jint16
jlPixelPairT *target = (jlPixelPairT *)_jlDrawTargetActual;
// 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);
o2 = (cy2 * 8 * 160) + (cx2 * 4);
o1 = ((sy & 0x1f) * 8 * 160) + ((sx & 0x3f) * 4); // This is in tiles
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 (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 so; // Source 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;
// 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);
so = ((cy1 & 0x1f) * 8 * 160) + ((cx1 & 0x3f) * 4);
to = (cy2 * 8 * 160) + (cx2 * 4);
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
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 (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) {
// startX = start tile for drawing
// startY = start tile for drawing
// width = tiles to draw horizontally
// height = tiles to draw vertically
// startX = start tile for drawing - in pixels
// startY = start tile for drawing - in pixels
// width = tiles to draw horizontally - in tiles
// height = tiles to draw vertically - in tiles
// mapData = pointer to tile x/y pairs to draw
// 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 y;
byte tileX;
byte tileY;
juint16 offset = 0;
jint16 endX = width * 8 + startX;
jint16 endY = height * 8 + startY;
for (y=startY; y<height; y++) {
for (x=startX; x<width; x++) {
for (y=startY; y<endY; y+=8) {
for (x=startX; x<endX; x+=8) {
tileX = mapData[offset++];
tileY = mapData[offset++];
jlDrawBlit8x8(source, tileX, tileY, x, y);
......
......@@ -224,15 +224,11 @@ void *_jlRealloc(void *pointer, size_t size);
#endif
#define jlByteSwap(twoBytes) ((juint16)((twoBytes) & 0xff) >> 8) | (juint16)((twoBytes) << 8)
#define jlStaSurfaceGet(sta) ((jlSurfaceT)sta->pixels)
void jlDisplayBorder(jlBorderColorsE color);
void jlDisplayPresent(void);
void jlDrawBlit8x8(jlSurfaceT source, jint16 cx1, jint16 cy1, jint16 cx2, jint16 cy2);
void jlDrawBlit8x8a(jlSurfaceT source, jint16 cx1, jint16 cy1, jint16 cx2, jint16 cy2, byte offset);
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);
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 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
bool _jlStaLoad(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 jlUtilIdle(void);
#define jlUtilIsOdd(x) (((x & 1) == 1) ? true : false)
......
......@@ -32,8 +32,8 @@ segment "testapp";
#endif
extern jint16 asmTest(jlSurfaceT source);
extern void asmDrawLine(jlSurfaceT target, jint16 color, jint16 x1, jint16 y1, jint16 x2, jint16 y2);
//extern jint16 asmTest(jlSurfaceT source);
//extern void asmDrawLine(jlSurfaceT target, jint16 color, jint16 x1, jint16 y1, jint16 x2, jint16 y2);
// Font hacking!
......@@ -41,6 +41,8 @@ __attribute__((__format__ (__printf__, 4, 0)))
void printAt(jlStaT *font, jint16 cx, jint16 cy, const char *what, ...) {
jint16 x;
jint16 y;
jint16 tx;
jint16 ty;
jint16 counter;
char msg[40]; // Very short messages (screen width). Be careful!
va_list va;
......@@ -49,30 +51,32 @@ void printAt(jlStaT *font, jint16 cx, jint16 cy, const char *what, ...) {
vsprintf(msg, what, va);
va_end(va);
tx = cx * 8;
ty = cy * 8;
for (counter=0; counter<(int)strlen(msg); counter++) {
x = (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) {
jlStaT *kanga = NULL;
jlStaT *font = NULL;
jint16 y;
jint16 phase = 0;
jint16 x2 = 0;
jint16 y2 = 0;
jint16 ox = 0;
jint16 oy = 0;
jint16 op = 0;
jint16 color = 15;
jint16 nextColor = 1;
char what[32];
void lineTest(void) {
jlUtilStartup("JoeyLib Test");
jlStaT *kanga = NULL;
jlStaT *font = NULL;
jint16 y;
jint16 phase = 0;
jint16 x2 = 0;
jint16 y2 = 0;
jint16 ox = 0;
jint16 oy = 0;
jint16 op = 0;
jint16 color = 15;
jint16 nextColor = 1;
char what[32];
if (!jlStaLoad(kanga, "kanga")) jlUtilDie("Unable to load kanga.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);
jlDrawColorSet((byte)color);
/*
if (phase < 2) {
asmDrawLine(_jlDrawTargetActual, _jlDrawColor, x2, y2, 319-x2, 199-y2);
} else {
asmDrawLine(_jlDrawTargetActual, _jlDrawColor, 319-x2, 199-y2, x2, y2);
}
*/
ox = x2;
oy = y2;
op = phase;
......@@ -142,11 +148,13 @@ int main(void) {
jlDisplayPresent();
jlDrawColorSet((byte)0);
/*
if (op < 2) {
asmDrawLine(_jlDrawTargetActual, _jlDrawColor, ox, oy, 319-ox, 199-oy);
} else {
asmDrawLine(_jlDrawTargetActual, _jlDrawColor, 319-ox, 199-oy, ox, oy);
}
*/
color = nextColor;
nextColor++;
......@@ -160,6 +168,47 @@ int main(void) {
jlStaFree(font);
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();
}
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