mirror of
https://github.com/dingusdev/dingusppc.git
synced 2024-06-09 22:29:30 +00:00
videoctrl: support guest rendered HW cursors.
This commit is contained in:
parent
74a49d1568
commit
616d0728fd
|
@ -351,7 +351,10 @@ void ATIRage::write_reg(uint32_t reg_offset, uint32_t value, uint32_t size) {
|
|||
return;
|
||||
case ATI_GEN_TEST_CNTL:
|
||||
if (bit_changed(this->regs[reg_offset >> 2], value, 7)) {
|
||||
LOG_F(INFO, "%s: HW cursor status changed", this->name.c_str());
|
||||
if (bit_set(value, 7))
|
||||
this->setup_hw_cursor();
|
||||
else
|
||||
this->cursor_on = false;
|
||||
}
|
||||
if (bit_changed(this->regs[reg_offset >> 2], value, 8)) {
|
||||
if (!bit_set(value, 8))
|
||||
|
@ -606,6 +609,7 @@ void ATIRage::draw_hw_cursor(uint8_t *dst_buf, int dst_pitch) {
|
|||
WRITE_DWORD_BE_A(dst_row, color1);
|
||||
break;
|
||||
case 2: // transparent
|
||||
WRITE_DWORD_BE_A(dst_row, 0);
|
||||
break;
|
||||
case 3: // 1's complement of display pixel
|
||||
break;
|
||||
|
@ -615,6 +619,11 @@ void ATIRage::draw_hw_cursor(uint8_t *dst_buf, int dst_pitch) {
|
|||
}
|
||||
}
|
||||
|
||||
void ATIRage::get_cursor_position(int& x, int& y) {
|
||||
x = this->regs[ATI_CUR_HORZ_VERT_POSN >> 2] & 0xFFFFU;
|
||||
y = (this->regs[ATI_CUR_HORZ_VERT_POSN >> 2] >> 16) & 0xFFFFU;
|
||||
}
|
||||
|
||||
static const PropMap AtiRage_Properties = {
|
||||
{"gfxmem_size",
|
||||
new IntProperty( 2, vector<uint32_t>({2, 4, 6}))},
|
||||
|
|
|
@ -78,6 +78,7 @@ protected:
|
|||
void crtc_update();
|
||||
void crtc_enable();
|
||||
void draw_hw_cursor(uint8_t *dst_buf, int dst_pitch);
|
||||
void get_cursor_position(int& x, int& y);
|
||||
|
||||
private:
|
||||
uint32_t regs[512] = {}; // internal registers
|
||||
|
|
|
@ -45,6 +45,10 @@ VideoCtrlBase::VideoCtrlBase(int width, int height)
|
|||
|
||||
VideoCtrlBase::~VideoCtrlBase()
|
||||
{
|
||||
if (this->cursor_texture) {
|
||||
SDL_DestroyTexture(this->cursor_texture);
|
||||
}
|
||||
|
||||
if (this->disp_texture) {
|
||||
SDL_DestroyTexture(this->disp_texture);
|
||||
}
|
||||
|
@ -136,18 +140,14 @@ void VideoCtrlBase::update_screen()
|
|||
SDL_UnlockTexture(this->disp_texture);
|
||||
SDL_RenderClear(this->renderer);
|
||||
SDL_RenderCopy(this->renderer, this->disp_texture, NULL, NULL);
|
||||
|
||||
// draw HW cursor if enabled
|
||||
if (this->cursor_on) {
|
||||
this->get_cursor_position(cursor_rect.x, cursor_rect.y);
|
||||
SDL_RenderCopy(this->renderer, this->cursor_texture, NULL, &cursor_rect);
|
||||
}
|
||||
|
||||
SDL_RenderPresent(this->renderer);
|
||||
|
||||
// HW cursor data is stored at the beginning of the video memory
|
||||
// HACK: use src_offset to recognize cursor data being ready
|
||||
// Normally, we should check GEN_CUR_ENABLE bit in the GEN_TEST_CNTL register
|
||||
//if (src_offset > 0x400 && READ_DWORD_LE_A(&this->block_io_regs[ATI_CUR_OFFSET])) {
|
||||
// this->draw_hw_cursor(dst_buf + dst_pitch * 20 + 120, dst_pitch);
|
||||
//}
|
||||
|
||||
//auto end_time = std::chrono::steady_clock::now();
|
||||
//auto time_elapsed = std::chrono::duration_cast<std::chrono::nanoseconds>(end_time - start_time);
|
||||
//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,
|
||||
|
@ -164,6 +164,39 @@ void VideoCtrlBase::set_palette_color(uint8_t index, uint8_t r, uint8_t g, uint8
|
|||
this->palette[index] = (a << 24) | (r << 16) | (g << 8) | b;
|
||||
}
|
||||
|
||||
void VideoCtrlBase::setup_hw_cursor(int cursor_width, int cursor_height)
|
||||
{
|
||||
uint8_t* dst_buf;
|
||||
int dst_pitch;
|
||||
|
||||
if (this->cursor_texture) {
|
||||
SDL_DestroyTexture(this->cursor_texture);
|
||||
}
|
||||
|
||||
this->cursor_texture = SDL_CreateTexture(
|
||||
this->renderer,
|
||||
SDL_PIXELFORMAT_ARGB8888,
|
||||
SDL_TEXTUREACCESS_STREAMING,
|
||||
cursor_width, cursor_height
|
||||
);
|
||||
|
||||
if (this->cursor_texture == NULL) {
|
||||
ABORT_F("SDL_CreateTexture for HW cursor failed with %s", SDL_GetError());
|
||||
}
|
||||
|
||||
SDL_LockTexture(this->cursor_texture, NULL, (void **)&dst_buf, &dst_pitch);
|
||||
SDL_SetTextureBlendMode(this->cursor_texture, SDL_BLENDMODE_BLEND);
|
||||
this->draw_hw_cursor(dst_buf, dst_pitch);
|
||||
SDL_UnlockTexture(this->cursor_texture);
|
||||
|
||||
this->cursor_rect.x = 0;
|
||||
this->cursor_rect.y = 0;
|
||||
this->cursor_rect.w = cursor_width;
|
||||
this->cursor_rect.h = cursor_height;
|
||||
|
||||
this->cursor_on = true;
|
||||
}
|
||||
|
||||
void VideoCtrlBase::convert_frame_1bpp(uint8_t *dst_buf, int dst_pitch)
|
||||
{
|
||||
// TODO: implement me!
|
||||
|
|
|
@ -42,6 +42,11 @@ public:
|
|||
uint8_t& a);
|
||||
void set_palette_color(uint8_t index, uint8_t r, uint8_t g, uint8_t b, uint8_t a);
|
||||
|
||||
// HW cursor support
|
||||
void setup_hw_cursor(int cursor_width=64, int cur_height=64);
|
||||
virtual void draw_hw_cursor(uint8_t *dst_buf, int dst_pitch) {};
|
||||
virtual void get_cursor_position(int& x, int& y) { x = 0; y = 0; };
|
||||
|
||||
// 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);
|
||||
|
@ -51,6 +56,7 @@ protected:
|
|||
bool crtc_on = false;
|
||||
bool blank_on = true;
|
||||
bool resizing = false;
|
||||
bool cursor_on = false;
|
||||
int active_width; // width of the visible display area
|
||||
int active_height; // height of the visible display area
|
||||
int hori_total = 0;
|
||||
|
@ -73,6 +79,8 @@ private:
|
|||
SDL_Window* display_wnd = 0;
|
||||
SDL_Renderer* renderer = 0;
|
||||
SDL_Texture* disp_texture = 0;
|
||||
SDL_Texture* cursor_texture = 0;
|
||||
SDL_Rect cursor_rect; // destination rectangle for cursor drawing
|
||||
};
|
||||
|
||||
#endif // VIDEO_CTRL_H
|
||||
|
|
Loading…
Reference in New Issue
Block a user