videoctrl: refactor palette access.

This commit is contained in:
Maxim Poliakovski 2023-04-01 12:08:25 +02:00
parent e01fea87a9
commit 888d919ae7
7 changed files with 53 additions and 49 deletions

View File

@ -300,11 +300,8 @@ void AtiMach64Gx::rgb514_write_reg(uint8_t reg_addr, uint8_t value)
case Rgb514::CLUT_DATA:
this->clut_color[this->comp_index++] = value;
if (this->comp_index >= 3) {
// TODO: combine separate components into a single ARGB value
this->palette[this->clut_index][0] = this->clut_color[0];
this->palette[this->clut_index][1] = this->clut_color[1];
this->palette[this->clut_index][2] = this->clut_color[2];
this->palette[this->clut_index][3] = 255;
this->set_palette_color(this->clut_index, clut_color[0],
clut_color[1], clut_color[2], 0xFF);
this->clut_index++;
this->comp_index = 0;
}

View File

@ -221,11 +221,14 @@ uint32_t ATIRage::read_reg(uint32_t offset, uint32_t size) {
break;
case ATI_DAC_REGS:
if (offset == ATI_DAC_DATA) {
this->mm_regs[ATI_DAC_DATA] =
this->palette[this->mm_regs[ATI_DAC_R_INDEX]][this->comp_index];
this->comp_index++; /* move to next color component */
if (this->comp_index >= 3) {
/* autoincrement reading index - move to next palette entry */
if (!this->comp_index) {
uint8_t alpha; // temporal variable for unused alpha
get_palette_colors(this->mm_regs[ATI_DAC_R_INDEX], color_buf[0],
color_buf[1], color_buf[2], alpha);
}
this->mm_regs[ATI_DAC_DATA] = color_buf[this->comp_index];
if (++this->comp_index >= 3) {
// autoincrement reading index - move to next palette entry
(this->mm_regs[ATI_DAC_R_INDEX])++;
this->comp_index = 0;
}
@ -308,19 +311,12 @@ void ATIRage::write_reg(uint32_t offset, uint32_t value, uint32_t size)
this->comp_index = 0;
break;
case ATI_DAC_DATA:
this->palette[this->mm_regs[ATI_DAC_W_INDEX]][this->comp_index] = value & 0xFF;
this->comp_index++; /* move to next color component */
if (this->comp_index >= 3) {
LOG_F(
INFO,
"ATI DAC palette entry #%d set to R=%X, G=%X, B=%X",
this->mm_regs[ATI_DAC_W_INDEX],
this->palette[this->mm_regs[ATI_DAC_W_INDEX]][0],
this->palette[this->mm_regs[ATI_DAC_W_INDEX]][1],
this->palette[this->mm_regs[ATI_DAC_W_INDEX]][2]);
/* autoincrement writing index - move to next palette entry */
(this->mm_regs[ATI_DAC_W_INDEX])++;
this->comp_index = 0;
this->color_buf[this->comp_index] = (value >> 8) & this->dac_mask;
if (++this->comp_index >= 3) {
this->set_palette_color(this->dac_wr_index, color_buf[0],
color_buf[1], color_buf[2], 0xFF);
this->dac_wr_index++; // auto-increment color index
this->comp_index = 0; // reset color component index
}
}
break;

View File

@ -93,7 +93,12 @@ private:
std::unique_ptr<DisplayID> disp_id;
int comp_index; /* color component index for DAC palette access */
// DAC interface state
uint8_t dac_wr_index = 0; // current DAC color index for writing
uint8_t dac_rd_index = 0; // current DAC color index for reading
uint8_t dac_mask = 0; // current DAC mask
int comp_index = 0; // current color component index
uint8_t color_buf[3] = {}; // buffer for storing DAC color components
};
#endif /* ATI_RAGE_H */
#endif // ATI_RAGE_H

View File

@ -352,11 +352,8 @@ void ControlVideo::iodev_write(uint32_t address, uint16_t value)
case RadacalRegs::CLUT_DATA:
this->clut_color[this->comp_index++] = value;
if (this->comp_index >= 3) {
// TODO: combine separate components into a single ARGB value
this->palette[this->rad_addr][0] = this->clut_color[0];
this->palette[this->rad_addr][1] = this->clut_color[1];
this->palette[this->rad_addr][2] = this->clut_color[2];
this->palette[this->rad_addr][3] = 255;
this->set_palette_color(this->rad_addr, clut_color[0],
clut_color[1], clut_color[2], 0xFF);
this->rad_addr++; // auto-increment CLUT address
this->comp_index = 0;
}

View File

@ -1,6 +1,6 @@
/*
DingusPPC - The Experimental PowerPC Macintosh emulator
Copyright (C) 2018-21 divingkatae and maximum
Copyright (C) 2018-23 divingkatae and maximum
(theweirdo) spatium
(Contact divingkatae#1017 or powermax#2286 on Discord for more info)
@ -107,13 +107,10 @@ void PdmOnboardVideo::set_clut_color(uint8_t color)
{
this->clut_color[this->comp_index++] = color;
if (this->comp_index >= 3) {
// TODO: combine separate components into a single ARGB value
this->palette[this->clut_index][0] = this->clut_color[0];
this->palette[this->clut_index][1] = this->clut_color[1];
this->palette[this->clut_index][2] = this->clut_color[2];
this->palette[this->clut_index][3] = 255;
this->clut_index++; // assume the HW works like that
this->comp_index = 0; // assume the HW works like that
this->set_palette_color(this->clut_index, clut_color[0],
clut_color[1], clut_color[2], 0xFF);
this->clut_index++;
this->comp_index = 0;
}
}
@ -245,10 +242,8 @@ void PdmOnboardVideo::convert_frame_1bpp(uint8_t *dst_buf, int dst_pitch)
uint32_t pixels[2];
// prepare cached ARGB values for white & black pixels
pixels[0] = (0xFF << 24) | (this->palette[127][0] << 16) |
(this->palette[127][1] << 8) | this->palette[127][2];
pixels[1] = (0xFF << 24) | (this->palette[255][0] << 16) |
(this->palette[255][1] << 8) | this->palette[255][2];
pixels[0] = this->palette[127];
pixels[1] = this->palette[255];
src_buf = this->fb_ptr;
src_pitch = this->fb_pitch;

View File

@ -121,6 +121,20 @@ void VideoCtrlBase::update_screen()
//LOG_F(INFO, "Display uodate took: %lld ns", time_elapsed.count());
}
void VideoCtrlBase::get_palette_colors(uint8_t index, uint8_t& r, uint8_t& g,
uint8_t& b, uint8_t& a)
{
b = this->palette[index] & 0xFFU;
g = (this->palette[index] >> 8) & 0xFFU;
r = (this->palette[index] >> 16) & 0xFFU;
a = (this->palette[index] >> 24) & 0xFFU;
}
void VideoCtrlBase::set_palette_color(uint8_t index, uint8_t r, uint8_t g, uint8_t b, uint8_t a)
{
this->palette[index] = (a << 24) | (r << 16) | (g << 8) | b;
}
void VideoCtrlBase::convert_frame_1bpp(uint8_t *dst_buf, int dst_pitch)
{
// TODO: implement me!
@ -128,7 +142,7 @@ void VideoCtrlBase::convert_frame_1bpp(uint8_t *dst_buf, int dst_pitch)
void VideoCtrlBase::convert_frame_8bpp(uint8_t *dst_buf, int dst_pitch)
{
uint8_t *src_buf, *src_row, *dst_row, pix;
uint8_t *src_buf, *src_row, *dst_row;
int src_pitch;
src_buf = this->fb_ptr;
@ -139,11 +153,7 @@ void VideoCtrlBase::convert_frame_8bpp(uint8_t *dst_buf, int dst_pitch)
dst_row = &dst_buf[h * dst_pitch];
for (int x = 0; x < this->active_width; x++) {
pix = src_row[x];
dst_row[0] = this->palette[pix][2]; // B
dst_row[1] = this->palette[pix][1]; // G
dst_row[2] = this->palette[pix][0]; // R
dst_row[3] = 255; // Alpha
WRITE_DWORD_LE_A(dst_row, this->palette[src_row[x]]);
dst_row += 4;
}
}

View File

@ -36,6 +36,10 @@ public:
void update_screen(void);
void get_palette_colors(uint8_t index, uint8_t& r, uint8_t& g, uint8_t& b,
uint8_t& a);
void set_palette_color(uint8_t index, uint8_t r, uint8_t g, uint8_t b, uint8_t a);
// converters for various framebuffer pixel depths
virtual void convert_frame_1bpp(uint8_t *dst_buf, int dst_pitch);
virtual void convert_frame_8bpp(uint8_t *dst_buf, int dst_pitch);
@ -49,7 +53,7 @@ protected:
float pixel_clock;
float refresh_rate;
uint8_t palette[256][4]; /* internal DAC palette in RGBA format */
uint32_t palette[256]; // internal DAC palette in RGBA format
// Framebuffer parameters
uint8_t* fb_ptr;