mirror of
https://gitlab.com/camelot/kickc.git
synced 2025-08-07 22:25:13 +00:00
206 lines
5.8 KiB
C
206 lines
5.8 KiB
C
// Plot and line drawing routines for HIRES bitmaps
|
|
// Currently it can only plot on the first 256 x-positions.
|
|
|
|
#include <bitmap-draw.h>
|
|
#include <veralib.h>
|
|
#include <multiply.h>
|
|
|
|
// Tables for the plotter - initialized by calling bitmap_draw_init();
|
|
const word __bitmap_plot_x[640];
|
|
const dword __bitmap_plot_y[480];
|
|
const byte __bitmap_plot_bitmask[640];
|
|
const byte __bitmap_plot_bitshift[640];
|
|
|
|
__ma dword __bitmap_address = 0;
|
|
__ma byte __bitmap_layer = 0;
|
|
__ma byte __bitmap_hscale = 0;
|
|
__ma byte __bitmap_vscale = 0;
|
|
__ma byte __bitmap_color_depth = 0;
|
|
|
|
word hdeltas[16] = {
|
|
0, 80, 40, 20, // 1 BPP
|
|
0, 160, 80, 40, // 2 BPP
|
|
0, 320, 160, 80, // 4 BPP
|
|
0, 640, 320, 160 // 8 BPP
|
|
};
|
|
const word vdeltas[4] = {0, 480, 240, 160};
|
|
const byte bitmasks[5] = {$80, $C0, $F0, $FF};
|
|
const signed byte bitshifts[5] = {7, 6, 4, 0};
|
|
|
|
|
|
// Initialize the bitmap plotter tables for a specific bitmap
|
|
void bitmap_init(byte layer, dword address) {
|
|
__bitmap_address = address;
|
|
__bitmap_layer = layer;
|
|
__bitmap_color_depth = vera_layer_get_color_depth(__bitmap_layer);
|
|
__bitmap_hscale = vera_display_get_hscale(); // Returns 1 when 640 and 2 when 320.
|
|
__bitmap_vscale = vera_display_get_vscale(); // Returns 1 when 480 and 2 when 240.
|
|
|
|
byte bitmask = bitmasks[__bitmap_color_depth];
|
|
signed byte bitshift = bitshifts[__bitmap_color_depth];
|
|
|
|
for(word x : 0..639) {
|
|
// 1 BPP
|
|
if(__bitmap_color_depth==0) {
|
|
__bitmap_plot_x[x] = (x >> 3);
|
|
__bitmap_plot_bitmask[x] = bitmask;
|
|
__bitmap_plot_bitshift[x] = (byte)bitshift;
|
|
bitshift -= 1;
|
|
bitmask >>= 1;
|
|
}
|
|
// 2 BPP
|
|
if(__bitmap_color_depth==1) {
|
|
__bitmap_plot_x[x] = (x >> 2);
|
|
__bitmap_plot_bitmask[x] = bitmask;
|
|
__bitmap_plot_bitshift[x] = (byte)bitshift;
|
|
bitshift -= 2;
|
|
bitmask >>= 2;
|
|
}
|
|
// 4 BPP
|
|
if(__bitmap_color_depth==2) {
|
|
__bitmap_plot_x[x] = (x >> 1);
|
|
__bitmap_plot_bitmask[x] = bitmask;
|
|
__bitmap_plot_bitshift[x] = (byte)bitshift;
|
|
bitshift -= 4;
|
|
bitmask >>= 4;
|
|
}
|
|
// 8 BPP
|
|
if(__bitmap_color_depth==3) {
|
|
__bitmap_plot_x[x] = x;
|
|
__bitmap_plot_bitmask[x] = bitmask;
|
|
__bitmap_plot_bitshift[x] = (byte)bitshift;
|
|
}
|
|
if(bitshift<0) {
|
|
bitshift = bitshifts[__bitmap_color_depth];
|
|
}
|
|
if(bitmask==0) {
|
|
bitmask = bitmasks[__bitmap_color_depth];
|
|
}
|
|
}
|
|
|
|
// This sets the right delta to skip a whole line based on the scale, depending on the color depth.
|
|
word hdelta = hdeltas[(__bitmap_color_depth<<2)+__bitmap_hscale];
|
|
// We start at the bitmap address; The plot_y contains the bitmap address embedded so we know where a line starts.
|
|
dword yoffs = __bitmap_address;
|
|
for(word y : 0..479) {
|
|
__bitmap_plot_y[y] = yoffs;
|
|
yoffs = yoffs + hdelta;
|
|
}
|
|
}
|
|
|
|
// Clear all graphics on the bitmap
|
|
void bitmap_clear() {
|
|
byte bitmask = bitmasks[__bitmap_color_depth];
|
|
word vdelta = vdeltas[__bitmap_vscale];
|
|
word hdelta = hdeltas[(__bitmap_color_depth<<2)+__bitmap_hscale];
|
|
dword count = mul16u(hdelta,vdelta);
|
|
memset_vram_address(__bitmap_address,0,count);
|
|
}
|
|
|
|
void bitmap_plot(word x, word y, byte c) {
|
|
// Needs unsigned int arrays arranged as two underlying char arrays to allow char* plotter_x = plot_x[x]; - and eventually - char* plotter = plot_x[x] + plot_y[y];
|
|
dword plot_x = __bitmap_plot_x[x];
|
|
dword plot_y = __bitmap_plot_y[y];
|
|
dword plotter = plot_x+plot_y;
|
|
byte bitshift = __bitmap_plot_bitshift[x];
|
|
c = bitshift?c<<(bitshift):c;
|
|
vera_vram_address0(plotter,VERA_INC_0);
|
|
*VERA_DATA0 = (*VERA_DATA0 & ~__bitmap_plot_bitmask[x]) | c;
|
|
}
|
|
|
|
|
|
// Draw a line on the bitmap
|
|
void bitmap_line(word x0, word x1, word y0, word y1, byte c) {
|
|
word xd;
|
|
word yd;
|
|
if(x0<x1) {
|
|
xd = x1-x0;
|
|
if(y0<y1) {
|
|
yd = y1-y0;
|
|
if(yd<xd) {
|
|
bitmap_line_xdyi(x0, y0, x1, xd, yd, c);
|
|
} else {
|
|
bitmap_line_ydxi(y0, x0, y1, yd, xd, c);
|
|
}
|
|
} else {
|
|
yd = y0-y1;
|
|
if(yd<xd) {
|
|
bitmap_line_xdyd(x0, y0, x1, xd, yd, c);
|
|
} else {
|
|
bitmap_line_ydxd(y1, x1, y0, yd, xd, c);
|
|
}
|
|
}
|
|
} else {
|
|
xd = x0-x1;
|
|
if(y0<y1) {
|
|
yd = y1-y0;
|
|
if(yd<xd) {
|
|
bitmap_line_xdyd(x1, y1, x0, xd, yd, c);
|
|
} else {
|
|
bitmap_line_ydxd(y0, x0, y1, yd, xd, c);
|
|
}
|
|
} else {
|
|
yd = y0-y1;
|
|
if(yd<xd) {
|
|
bitmap_line_xdyi(x1, y1, x0, xd, yd, c);
|
|
} else {
|
|
bitmap_line_ydxi(y1, x1, y0, yd, xd, c);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void bitmap_line_xdyi(word x, word y, word x1, word xd, word yd,byte c) {
|
|
word e = yd>>1;
|
|
do {
|
|
bitmap_plot(x,y,c);
|
|
x++;
|
|
e = e+yd;
|
|
if(xd<e) {
|
|
y++;
|
|
e = e - xd;
|
|
}
|
|
} while (x!=(x1+1));
|
|
}
|
|
|
|
void bitmap_line_xdyd(word x, word y, word x1, word xd, word yd, byte c) {
|
|
word e = yd>>1;
|
|
do {
|
|
bitmap_plot(x,y,c);
|
|
x++;
|
|
e = e+yd;
|
|
if(xd<e) {
|
|
y--;
|
|
e = e - xd;
|
|
}
|
|
} while (x!=(x1+1));
|
|
}
|
|
|
|
void bitmap_line_ydxi(word y, word x, word y1, word yd, word xd, byte c) {
|
|
word e = xd>>1;
|
|
do {
|
|
bitmap_plot(x,y,c);
|
|
y++;
|
|
e = e+xd;
|
|
if(yd<e) {
|
|
x++;
|
|
e = e - yd;
|
|
}
|
|
} while (y!=(y1+1));
|
|
}
|
|
|
|
void bitmap_line_ydxd(word y, word x, word y1, word yd, word xd, byte c) {
|
|
word e = xd>>1;
|
|
do {
|
|
bitmap_plot(x,y,c);
|
|
y = y++;
|
|
e = e+xd;
|
|
if(yd<e) {
|
|
x--;
|
|
e = e - yd;
|
|
}
|
|
} while (y!=(y1+1));
|
|
}
|
|
|
|
|