mirror of
https://github.com/TomHarte/CLK.git
synced 2024-11-29 12:50:28 +00:00
Sought further to reduce the processing footprint of palette changes by updating only those table entries that are affected by a change.
This commit is contained in:
parent
911ee5a0d3
commit
85253a5876
@ -159,6 +159,7 @@ class CRTCBusHandler {
|
|||||||
mode_(2),
|
mode_(2),
|
||||||
next_mode_(2),
|
next_mode_(2),
|
||||||
cycles_into_hsync_(0) {
|
cycles_into_hsync_(0) {
|
||||||
|
establish_palette_hits();
|
||||||
build_mode_table();
|
build_mode_table();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -351,32 +352,41 @@ class CRTCBusHandler {
|
|||||||
crt_->output_level(length * 16);
|
crt_->output_level(length * 16);
|
||||||
}
|
}
|
||||||
|
|
||||||
void patch_mode_table(int pen) {
|
#define Mode0Colour0(c) ((c & 0x80) >> 7) | ((c & 0x20) >> 3) | ((c & 0x08) >> 2) | ((c & 0x02) << 2)
|
||||||
// TODO: patch, don't rebuild.
|
#define Mode0Colour1(c) ((c & 0x40) >> 6) | ((c & 0x10) >> 2) | ((c & 0x04) >> 1) | ((c & 0x01) << 3)
|
||||||
switch(mode_) {
|
|
||||||
case 0:
|
#define Mode1Colour0(c) ((c & 0x80) >> 7) | ((c & 0x08) >> 2)
|
||||||
break;
|
#define Mode1Colour1(c) ((c & 0x40) >> 6) | ((c & 0x04) >> 1)
|
||||||
case 1:
|
#define Mode1Colour2(c) ((c & 0x20) >> 5) | ((c & 0x02) >> 0)
|
||||||
if(pen > 3) return;
|
#define Mode1Colour3(c) ((c & 0x10) >> 4) | ((c & 0x01) << 1)
|
||||||
break;
|
|
||||||
case 2:
|
#define Mode3Colour0(c) ((c & 0x80) >> 7) | ((c & 0x08) >> 2)
|
||||||
if(pen > 1) return;
|
#define Mode3Colour1(c) ((c & 0x40) >> 6) | ((c & 0x04) >> 1)
|
||||||
break;
|
|
||||||
case 3:
|
void establish_palette_hits() {
|
||||||
if(pen > 3) return;
|
for(int c = 0; c < 256; c++) {
|
||||||
break;
|
mode0_palette_hits_[Mode0Colour0(c)].push_back((uint8_t)c);
|
||||||
|
mode0_palette_hits_[Mode0Colour1(c)].push_back((uint8_t)c);
|
||||||
|
|
||||||
|
mode1_palette_hits_[Mode1Colour0(c)].push_back((uint8_t)c);
|
||||||
|
mode1_palette_hits_[Mode1Colour1(c)].push_back((uint8_t)c);
|
||||||
|
mode1_palette_hits_[Mode1Colour2(c)].push_back((uint8_t)c);
|
||||||
|
mode1_palette_hits_[Mode1Colour3(c)].push_back((uint8_t)c);
|
||||||
|
|
||||||
|
mode3_palette_hits_[Mode3Colour0(c)].push_back((uint8_t)c);
|
||||||
|
mode3_palette_hits_[Mode3Colour1(c)].push_back((uint8_t)c);
|
||||||
}
|
}
|
||||||
build_mode_table();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void build_mode_table() {
|
void build_mode_table() {
|
||||||
switch(mode_) {
|
switch(mode_) {
|
||||||
case 0:
|
case 0:
|
||||||
|
// Mode 0: abcdefgh -> [gcea] [hdfb]
|
||||||
for(int c = 0; c < 256; c++) {
|
for(int c = 0; c < 256; c++) {
|
||||||
// prepare mode 0
|
// prepare mode 0
|
||||||
uint8_t *mode0_pixels = (uint8_t *)&mode0_output_[c];
|
uint8_t *mode0_pixels = (uint8_t *)&mode0_output_[c];
|
||||||
mode0_pixels[0] = palette_[((c & 0x80) >> 7) | ((c & 0x20) >> 3) | ((c & 0x08) >> 2) | ((c & 0x02) << 2)];
|
mode0_pixels[0] = palette_[Mode0Colour0(c)];
|
||||||
mode0_pixels[1] = palette_[((c & 0x40) >> 6) | ((c & 0x10) >> 2) | ((c & 0x04) >> 1) | ((c & 0x01) << 3)];
|
mode0_pixels[1] = palette_[Mode0Colour1(c)];
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -384,10 +394,10 @@ class CRTCBusHandler {
|
|||||||
for(int c = 0; c < 256; c++) {
|
for(int c = 0; c < 256; c++) {
|
||||||
// prepare mode 1
|
// prepare mode 1
|
||||||
uint8_t *mode1_pixels = (uint8_t *)&mode1_output_[c];
|
uint8_t *mode1_pixels = (uint8_t *)&mode1_output_[c];
|
||||||
mode1_pixels[0] = palette_[((c & 0x80) >> 7) | ((c & 0x08) >> 2)];
|
mode1_pixels[0] = palette_[Mode1Colour0(c)];
|
||||||
mode1_pixels[1] = palette_[((c & 0x40) >> 6) | ((c & 0x04) >> 1)];
|
mode1_pixels[1] = palette_[Mode1Colour1(c)];
|
||||||
mode1_pixels[2] = palette_[((c & 0x20) >> 5) | ((c & 0x02) >> 0)];
|
mode1_pixels[2] = palette_[Mode1Colour2(c)];
|
||||||
mode1_pixels[3] = palette_[((c & 0x10) >> 4) | ((c & 0x01) << 1)];
|
mode1_pixels[3] = palette_[Mode1Colour3(c)];
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -410,13 +420,61 @@ class CRTCBusHandler {
|
|||||||
for(int c = 0; c < 256; c++) {
|
for(int c = 0; c < 256; c++) {
|
||||||
// prepare mode 3
|
// prepare mode 3
|
||||||
uint8_t *mode3_pixels = (uint8_t *)&mode3_output_[c];
|
uint8_t *mode3_pixels = (uint8_t *)&mode3_output_[c];
|
||||||
mode3_pixels[0] = palette_[((c & 0x80) >> 7) | ((c & 0x08) >> 2)];
|
mode3_pixels[0] = palette_[Mode3Colour0(c)];
|
||||||
mode3_pixels[1] = palette_[((c & 0x40) >> 6) | ((c & 0x04) >> 1)];
|
mode3_pixels[1] = palette_[Mode3Colour1(c)];
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void patch_mode_table(int pen) {
|
||||||
|
switch(mode_) {
|
||||||
|
case 0: {
|
||||||
|
for(uint8_t c : mode0_palette_hits_[pen]) {
|
||||||
|
uint8_t *mode0_pixels = (uint8_t *)&mode0_output_[c];
|
||||||
|
mode0_pixels[0] = palette_[Mode0Colour0(c)];
|
||||||
|
mode0_pixels[1] = palette_[Mode0Colour1(c)];
|
||||||
|
}
|
||||||
|
} break;
|
||||||
|
case 1:
|
||||||
|
if(pen > 3) return;
|
||||||
|
for(uint8_t c : mode1_palette_hits_[pen]) {
|
||||||
|
uint8_t *mode1_pixels = (uint8_t *)&mode1_output_[c];
|
||||||
|
mode1_pixels[0] = palette_[Mode1Colour0(c)];
|
||||||
|
mode1_pixels[1] = palette_[Mode1Colour1(c)];
|
||||||
|
mode1_pixels[2] = palette_[Mode1Colour2(c)];
|
||||||
|
mode1_pixels[3] = palette_[Mode1Colour3(c)];
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
if(pen > 1) return;
|
||||||
|
// Whichever pen this is, there's only one table entry it doesn't touch, so just
|
||||||
|
// rebuild the whole thing.
|
||||||
|
build_mode_table();
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
if(pen > 3) return;
|
||||||
|
// Same argument applies here as to case 1, as the unused bits aren't masked out.
|
||||||
|
for(uint8_t c : mode3_palette_hits_[pen]) {
|
||||||
|
uint8_t *mode3_pixels = (uint8_t *)&mode3_output_[c];
|
||||||
|
mode3_pixels[0] = palette_[Mode3Colour0(c)];
|
||||||
|
mode3_pixels[1] = palette_[Mode3Colour1(c)];
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#undef Mode0Colour0
|
||||||
|
#undef Mode0Colour1
|
||||||
|
|
||||||
|
#undef Mode1Colour0
|
||||||
|
#undef Mode1Colour1
|
||||||
|
#undef Mode1Colour2
|
||||||
|
#undef Mode1Colour3
|
||||||
|
|
||||||
|
#undef Mode3Colour0
|
||||||
|
#undef Mode3Colour1
|
||||||
|
|
||||||
uint8_t mapped_palette_value(uint8_t colour) {
|
uint8_t mapped_palette_value(uint8_t colour) {
|
||||||
#define COL(r, g, b) (r << 4) | (g << 2) | b
|
#define COL(r, g, b) (r << 4) | (g << 2) | b
|
||||||
static const uint8_t mapping[32] = {
|
static const uint8_t mapping[32] = {
|
||||||
@ -451,6 +509,10 @@ class CRTCBusHandler {
|
|||||||
uint64_t mode2_output_[256];
|
uint64_t mode2_output_[256];
|
||||||
uint16_t mode3_output_[256];
|
uint16_t mode3_output_[256];
|
||||||
|
|
||||||
|
std::vector<uint8_t> mode0_palette_hits_[16];
|
||||||
|
std::vector<uint8_t> mode1_palette_hits_[4];
|
||||||
|
std::vector<uint8_t> mode3_palette_hits_[4];
|
||||||
|
|
||||||
int pen_;
|
int pen_;
|
||||||
uint8_t palette_[16];
|
uint8_t palette_[16];
|
||||||
uint8_t border_;
|
uint8_t border_;
|
||||||
|
Loading…
Reference in New Issue
Block a user