1
0
mirror of https://gitlab.com/camelot/kickc.git synced 2025-04-08 14:37:40 +00:00

Bitmap mode working!

This commit is contained in:
FlightControl 2021-01-21 09:02:29 +01:00
parent 962c5f0e17
commit 4db64f30cf
12 changed files with 2390 additions and 1991 deletions

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1 @@
dex

View File

@ -0,0 +1,2 @@
dex
dex

View File

@ -0,0 +1,4 @@
dex
dex
dex
dex

View File

@ -7,7 +7,7 @@ void bitmap_init(byte layer, dword address);
// Clear all graphics on the bitmap
void bitmap_clear();
void bitmap_plot(word x, word y);
void bitmap_plot(word x, word y, byte c);
// Draw a line on the bitmap
void bitmap_line(word x0, word x1, word y0, word y1);
void bitmap_line(word x0, word x1, word y0, word y1, byte c);

View File

@ -8,14 +8,22 @@
// 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_bit[640];
const byte bitmap_plot_bitmask[640];
const byte bitmap_plot_bitshift[640];
__ma dword bitmap_address = 0;
__ma byte bitmap_layer = 0;
const word hdeltas[4] = {0, 80, 40, 20};
const word vdeltas[4] = {0, 60, 30, 15};
const byte bitmasks[5] = {0, $80, $C0, $F0, $FF};
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) {
@ -24,43 +32,55 @@ void bitmap_init(byte layer, dword address) {
byte color_depth = vera_layer_get_color_depth(bitmap_layer);
byte hscale = vera_display_get_hscale(); // Returns 1 when 640 and 2 when 320.
byte vscale = vera_display_get_vscale(); // Returns 1 when 480 and 2 when 240.
byte bitmask = bitmasks[color_depth];
signed byte bitshift = bitshifts[color_depth];
for(word x : 0..639) {
if(color_depth==1) {
// 1 BPP
if(color_depth==0) {
bitmap_plot_x[x] = (x >> 3);
bitmap_plot_bit[x] = bitmask;
bitmap_plot_bitmask[x] = bitmask;
bitmap_plot_bitshift[x] = (byte)bitshift;
bitshift -= 1;
bitmask >>= 1;
}
if(color_depth==2) {
// 2 BPP
if(color_depth==1) {
bitmap_plot_x[x] = (x >> 2);
bitmap_plot_bit[x] = bitmask;
bitmap_plot_bitmask[x] = bitmask;
bitmap_plot_bitshift[x] = (byte)bitshift;
bitshift -= 2;
bitmask >>= 2;
}
if(color_depth==4) {
// 4 BPP
if(color_depth==2) {
bitmap_plot_x[x] = (x >> 1);
bitmap_plot_bit[x] = bitmask;
bitmap_plot_bitmask[x] = bitmask;
bitmap_plot_bitshift[x] = (byte)bitshift;
bitshift -= 4;
bitmask >>= 4;
}
if(color_depth==8) {
// 8 BPP
if(color_depth==3) {
bitmap_plot_x[x] = x;
bitmap_plot_bit[x] = bitmask;
bitmap_plot_bitmask[x] = bitmask;
bitmap_plot_bitshift[x] = (byte)bitshift;
}
if(bitshift<0) {
bitshift = bitshifts[color_depth];
}
if(bitmask==0) {
bitmask = bitmasks[color_depth];
bitmask = bitmasks[color_depth];
}
}
// This sets the right delta to skip a whole line based on the scale, depending on the color depth.
word hdelta = hdeltas[hscale];
if(color_depth==8) hdelta = hdelta << 3;
if(color_depth==4) hdelta = hdelta << 2;
if(color_depth==2) hdelta = hdelta << 1;
word hdelta = hdeltas[(color_depth<<2)+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;
bitmap_plot_y[y] = yoffs;
yoffs = yoffs + hdelta;
}
}
@ -71,35 +91,26 @@ void bitmap_clear() {
byte bitmask = bitmasks[color_depth];
byte hscale = vera_display_get_hscale(); // Returns 1 when 640 and 2 when 320.
byte vscale = vera_display_get_vscale(); // Returns 1 when 480 and 2 when 240.
word count = hdeltas[hscale];
if(color_depth==8) count = count << 6;
if(color_depth==4) count = count << 5;
if(color_depth==2) count = count << 4;
if(color_depth==1) count = count << 3;
word lines = vera_display_get_height();
dword address = bitmap_address;
word hdelta = hdeltas[hscale];
if(color_depth==8) hdelta = hdelta << 3;
if(color_depth==4) hdelta = hdelta << 2;
if(color_depth==2) hdelta = hdelta << 1;
for(word line=0; line<lines; line++) {
memset_vram_address(address,0,count);
address+=hdelta;
}
word vdelta = vdeltas[vscale];
word hdelta = hdeltas[(color_depth<<2)+hscale];
dword count = mul16u(hdelta,vdelta);
memset_vram_address(bitmap_address,0,count);
}
void bitmap_plot(word x, word y) {
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_bit[x];
*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) {
void bitmap_line(word x0, word x1, word y0, word y1, byte c) {
word xd;
word yd;
if(x0<x1) {
@ -107,16 +118,16 @@ void bitmap_line(word x0, word x1, word y0, word y1) {
if(y0<y1) {
yd = y1-y0;
if(yd<xd) {
bitmap_line_xdyi(x0, y0, x1, xd, yd);
bitmap_line_xdyi(x0, y0, x1, xd, yd, c);
} else {
bitmap_line_ydxi(y0, x0, y1, yd, xd);
bitmap_line_ydxi(y0, x0, y1, yd, xd, c);
}
} else {
yd = y0-y1;
if(yd<xd) {
bitmap_line_xdyd(x0, y0, x1, xd, yd);
bitmap_line_xdyd(x0, y0, x1, xd, yd, c);
} else {
bitmap_line_ydxd(y1, x1, y0, yd, xd);
bitmap_line_ydxd(y1, x1, y0, yd, xd, c);
}
}
} else {
@ -124,25 +135,25 @@ void bitmap_line(word x0, word x1, word y0, word y1) {
if(y0<y1) {
yd = y1-y0;
if(yd<xd) {
bitmap_line_xdyd(x1, y1, x0, xd, yd);
bitmap_line_xdyd(x1, y1, x0, xd, yd, c);
} else {
bitmap_line_ydxd(y0, x0, y1, yd, xd);
bitmap_line_ydxd(y0, x0, y1, yd, xd, c);
}
} else {
yd = y0-y1;
if(yd<xd) {
bitmap_line_xdyi(x1, y1, x0, xd, yd);
bitmap_line_xdyi(x1, y1, x0, xd, yd, c);
} else {
bitmap_line_ydxi(y1, x1, y0, yd, xd);
bitmap_line_ydxi(y1, x1, y0, yd, xd, c);
}
}
}
}
void bitmap_line_xdyi(word x, word y, word x1, word xd, word yd) {
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);
bitmap_plot(x,y,c);
x++;
e = e+yd;
if(xd<e) {
@ -152,10 +163,10 @@ void bitmap_line_xdyi(word x, word y, word x1, word xd, word yd) {
} while (x!=(x1+1));
}
void bitmap_line_xdyd(word x, word y, word x1, word xd, word yd) {
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);
bitmap_plot(x,y,c);
x++;
e = e+yd;
if(xd<e) {
@ -165,10 +176,10 @@ void bitmap_line_xdyd(word x, word y, word x1, word xd, word yd) {
} while (x!=(x1+1));
}
void bitmap_line_ydxi(word y, word x, word y1, word yd, word xd) {
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);
bitmap_plot(x,y,c);
y++;
e = e+xd;
if(yd<e) {
@ -178,10 +189,10 @@ void bitmap_line_ydxi(word y, word x, word y1, word yd, word xd) {
} while (y!=(y1+1));
}
void bitmap_line_ydxd(word y, word x, word y1, word yd, word xd) {
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);
bitmap_plot(x,y,c);
y = y++;
e = e+xd;
if(yd<e) {

View File

@ -71,6 +71,28 @@ unsigned int divr16u(unsigned int dividend, unsigned int divisor, unsigned int r
return quotient;
}
// Performs modulo on two 16 bit unsigned ints and an initial remainder
// Returns the remainder.
// The final remainder will be set into the global variable rem16u
// Implemented using simple binary division
unsigned int modr16u(unsigned int dividend, unsigned int divisor, unsigned int rem) {
unsigned int quotient = 0;
for( char i : 0..15) {
rem = rem << 1;
if( (>dividend & $80) != 0 ) {
rem = rem | 1;
}
dividend = dividend << 1;
quotient = quotient << 1;
if(rem>=divisor) {
quotient++;
rem = rem - divisor;
}
}
rem16u = rem;
return rem;
}
// Performs division on two 16 bit unsigned ints
// Returns the quotient dividend/divisor.
// The remainder will be set into the global variable rem16u

View File

@ -87,6 +87,7 @@ byte vera_display_get_vscale() {
word vera_display_get_height() {
byte scale = vera_display_get_vscale();
*VERA_CTRL = *VERA_CTRL | VERA_DCSEL;
word height = (word)(*VERA_DC_VSTOP - *VERA_DC_VSTART);
switch( scale ) {
case 2:
@ -96,9 +97,25 @@ word vera_display_get_height() {
height = height >> 2;
break;
}
*VERA_CTRL = *VERA_CTRL & ~VERA_DCSEL;
return height<<1;
}
word vera_display_get_width() {
byte scale = vera_display_get_hscale();
*VERA_CTRL = *VERA_CTRL | VERA_DCSEL;
word width = (word)(*VERA_DC_HSTOP - *VERA_DC_HSTART);
switch( scale ) {
case 2:
width = width >> 1;
break;
case 3:
width = width >> 2;
break;
}
*VERA_CTRL = *VERA_CTRL & ~VERA_DCSEL;
return width<<1;
}
// --- VERA layer management ---
@ -224,13 +241,13 @@ inline void vera_layer_set_color_depth_8BPP(byte layer) {
*addr |= VERA_LAYER_COLOR_DEPTH_8BPP;
}
// Get the map width or height of the layer.
// Get the color depth of the layer.
// - layer: Value of 0 or 1.
// - return: 1, 2, 4 or 8.
// - return: 0 = 1 color, 1 = 2 colors, 2 = 4 colors or 3 = 8 colors.
byte vera_layer_get_color_depth(byte layer) {
byte* config = vera_layer_config[layer];
byte mask = (byte)VERA_LAYER_COLOR_DEPTH_MASK;
return VERA_LAYER_COLOR_DEPTH[(*config & mask)];
return *config & mask;
}
// Enable the layer to be displayed on the screen.
@ -664,8 +681,8 @@ void vera_layer_mode_bitmap(byte layer, dword bitmap_address, word mapwidth, wor
break;
}
vera_layer_set_tilebase(layer,tilebase);
vera_layer_set_config(layer, config);
vera_layer_set_tilebase(layer,tilebase);
}
// --- TILE FUNCTIONS ---

View File

@ -0,0 +1,77 @@
// Example program for the Commander X16.
// Demonstrates the usage of the VERA graphic modes and layering.
// Author: Sven Van de Velde
#include <conio.h>
#include <printf.h>
#include <bitmap-draw.h>
#include <stdlib.h>
#include <division.h>
void main() {
// Before we configure the bitmap pane into vera memory we need to re-arrange a few things!
// It is better to load all in bank 0, but then there is an issue.
// So the default CX16 character set is located in bank 0, at address 0xF800.
// So we need to move this character set to bank 1, suggested is at address 0xF000.
// The CX16 by default writes textual output to layer 1 in text mode, so we need to
// realign the moved character set to 0xf000 as the new tile base for layer 1.
// We also will need to realign for layer 1 the map base from 0x00000 to 0x14000.
// This is now all easily done with a few statements in the new kickc vera lib ...
memcpy_in_vram(1, 0xF000, VERA_INC_1, 0, 0xF800, VERA_INC_1, 256*8); // We copy the 128 character set of 8 bytes each.
vera_layer_mode_tile(1, 0x14000, 0x1F000, 128, 64, 8, 8, 1);
vera_layer_mode_bitmap(0, (dword)0x00000, 320, 1);
screenlayer(1);
textcolor(WHITE);
bgcolor(BLACK);
clrscr();
gotoxy(0,25);
printf("vera in bitmap mode,\n");
printf("color depth 1 bits per pixel.\n");
printf("in this mode, it is possible to display\n");
printf("graphics in 2 colors (black or color).\n");
vera_layer_show(0);
bitmap_init(0, 0x00000);
bitmap_clear();
gotoxy(0,29);
textcolor(YELLOW);
printf("press a key ...");
while(!kbhit()) {
bitmap_line(modr16u(rand(),320,0), modr16u(rand(),320,0), modr16u(rand(),200,0), modr16u(rand(),200,0), rand()&1);
};
textcolor(WHITE);
bgcolor(BLACK);
clrscr();
gotoxy(0,26);
printf("here you see all the colors possible.\n");
gotoxy(0,29);
textcolor(YELLOW);
printf("press a key ...");
word x = 0;
byte color = 0;
while(!kbhit()) {
bitmap_line(x, x, 0, 199, color);
color++;
if(color>1) color=0;
x++;
if(x>319) x=0;
};
screenlayer(1);
textcolor(WHITE);
bgcolor(BLUE);
clrscr();
}

View File

@ -0,0 +1,77 @@
// Example program for the Commander X16.
// Demonstrates the usage of the VERA graphic modes and layering.
// Author: Sven Van de Velde
#include <conio.h>
#include <printf.h>
#include <bitmap-draw.h>
#include <stdlib.h>
#include <division.h>
void main() {
// Before we configure the bitmap pane into vera memory we need to re-arrange a few things!
// It is better to load all in bank 0, but then there is an issue.
// So the default CX16 character set is located in bank 0, at address 0xF800.
// So we need to move this character set to bank 1, suggested is at address 0xF000.
// The CX16 by default writes textual output to layer 1 in text mode, so we need to
// realign the moved character set to 0xf000 as the new tile base for layer 1.
// We also will need to realign for layer 1 the map base from 0x00000 to 0x14000.
// This is now all easily done with a few statements in the new kickc vera lib ...
memcpy_in_vram(1, 0xF000, VERA_INC_1, 0, 0xF800, VERA_INC_1, 256*8); // We copy the 128 character set of 8 bytes each.
vera_layer_mode_tile(1, 0x14000, 0x1F000, 128, 64, 8, 8, 1);
vera_layer_mode_bitmap(0, (dword)0x00000, 320, 2);
screenlayer(1);
textcolor(WHITE);
bgcolor(BLACK);
clrscr();
gotoxy(0,25);
printf("vera in bitmap mode,\n");
printf("color depth 2 bits per pixel.\n");
printf("in this mode, it is possible to display\n");
printf("graphics in 4 colors.\n");
vera_layer_show(0);
bitmap_init(0, 0x00000);
bitmap_clear();
gotoxy(0,29);
textcolor(YELLOW);
printf("press a key ...");
while(!kbhit()) {
bitmap_line(modr16u(rand(),320,0), modr16u(rand(),320,0), modr16u(rand(),200,0), modr16u(rand(),200,0), rand()&3);
};
textcolor(WHITE);
bgcolor(BLACK);
clrscr();
gotoxy(0,26);
printf("here you see all the colors possible.\n");
gotoxy(0,29);
textcolor(YELLOW);
printf("press a key ...");
word x = 0;
byte color = 0;
while(!kbhit()) {
bitmap_line(x, x, 0, 199, color);
color++;
if(color>3) color=0;
x++;
if(x>319) x=0;
};
screenlayer(1);
textcolor(WHITE);
bgcolor(BLUE);
clrscr();
}

View File

@ -0,0 +1,78 @@
// Example program for the Commander X16.
// Demonstrates the usage of the VERA graphic modes and layering.
// Author: Sven Van de Velde
#include <conio.h>
#include <printf.h>
#include <bitmap-draw.h>
#include <stdlib.h>
#include <division.h>
void main() {
// Before we configure the bitmap pane into vera memory we need to re-arrange a few things!
// It is better to load all in bank 0, but then there is an issue.
// So the default CX16 character set is located in bank 0, at address 0xF800.
// So we need to move this character set to bank 1, suggested is at address 0xF000.
// The CX16 by default writes textual output to layer 1 in text mode, so we need to
// realign the moved character set to 0xf000 as the new tile base for layer 1.
// We also will need to realign for layer 1 the map base from 0x00000 to 0x14000.
// This is now all easily done with a few statements in the new kickc vera lib ...
memcpy_in_vram(1, 0xF000, VERA_INC_1, 0, 0xF800, VERA_INC_1, 256*8); // We copy the 128 character set of 8 bytes each.
vera_layer_mode_tile(1, 0x14000, 0x1F000, 128, 64, 8, 8, 1);
vera_layer_mode_bitmap(0, (dword)0x00000, 320, 4);
screenlayer(1);
textcolor(WHITE);
bgcolor(BLACK);
clrscr();
gotoxy(0,25);
printf("vera in bitmap mode,\n");
printf("color depth 8 bits per pixel.\n");
printf("in this mode, it is possible to display\n");
printf("graphics in 256 colors.\n");
vera_layer_show(0);
bitmap_init(0, 0x00000);
bitmap_clear();
gotoxy(0,29);
textcolor(YELLOW);
printf("press a key ...");
while(!kbhit()) {
bitmap_line(modr16u(rand(),320,0), modr16u(rand(),320,0), modr16u(rand(),200,0), modr16u(rand(),200,0), rand()&15);
};
textcolor(WHITE);
bgcolor(BLACK);
clrscr();
gotoxy(0,26);
printf("here you see all the colors possible.\n");
gotoxy(0,29);
textcolor(YELLOW);
printf("press a key ...");
word x = 0;
byte color = 0;
while(!kbhit()) {
bitmap_line(x, x, 0, 199, color);
color++;
if(color>15) color=0;
x++;
if(x>319) x=0;
};
screenlayer(1);
textcolor(WHITE);
bgcolor(BLUE);
clrscr();
}

View File

@ -12,39 +12,65 @@
#include <printf.h>
#include <bitmap-draw.h>
#include <stdlib.h>
#include <division.h>
char lines_x[] = { 60, 80, 110, 80, 60, 40, 10, 40, 60 };
char lines_y[] = { 10, 40, 60, 80, 110, 80, 60, 40, 10 };
char lines_cnt = 8;
void lines() {
for(char l=0; l<lines_cnt;l++) {
bitmap_line(lines_x[l], lines_x[l+1], lines_y[l], lines_y[l+1]);
}
}
void main() {
vera_layer_mode_bitmap(0, (dword)0x04000, 640, 1);
// Before we configure the bitmap pane into vera memory we need to re-arrange a few things!
// It is better to load all in bank 0, but then there is an issue.
// So the default CX16 character set is located in bank 0, at address 0xF800.
// So we need to move this character set to bank 1, suggested is at address 0xF000.
// The CX16 by default writes textual output to layer 1 in text mode, so we need to
// realign the moved character set to 0xf000 as the new tile base for layer 1.
// We also will need to realign for layer 1 the map base from 0x00000 to 0x14000.
// This is now all easily done with a few statements in the new kickc vera lib ...
memcpy_in_vram(1, 0xF000, VERA_INC_1, 0, 0xF800, VERA_INC_1, 256*8); // We copy the 128 character set of 8 bytes each.
vera_layer_mode_tile(1, 0x14000, 0x1F000, 128, 64, 8, 8, 1);
vera_layer_mode_bitmap(0, (dword)0x00000, 320, 8);
screenlayer(1);
textcolor(RED);
textcolor(WHITE);
bgcolor(BLACK);
clrscr();
gotoxy(0,20);
gotoxy(0,25);
printf("vera in bitmap mode,\n");
printf("color depth 8 bits per pixel.\n");
printf("in this mode, it is possible to display\n\n");
printf("graphics in 256 colors.\n\n");
printf("in this mode, it is possible to display\n");
printf("graphics in 256 colors.\n");
vera_layer_show(0);
bitmap_init(0, 0x4000);
bitmap_init(0, 0x00000);
bitmap_clear();
gotoxy(0,29);
textcolor(YELLOW);
printf("press a key ...");
while(!kbhit()) {
bitmap_line(rand()&$00FF, rand()&$00FF, rand()&$007F, rand()&$007F);
bitmap_line(modr16u(rand(),320,0), modr16u(rand(),320,0), modr16u(rand(),200,0), modr16u(rand(),200,0), rand()&255);
};
textcolor(WHITE);
bgcolor(BLACK);
clrscr();
gotoxy(0,26);
printf("here you see all the colors possible.\n");
gotoxy(0,29);
textcolor(YELLOW);
printf("press a key ...");
word x = 0;
byte color = 0;
while(!kbhit()) {
bitmap_line(x, x, 0, 199, color);
color++;
x++;
if(x>319) x=0;
};
screenlayer(1);