Rewritten renderer blitting, fixes flickering when inversion or grayscale is used.
This commit is contained in:
41
src/config.c
41
src/config.c
@@ -2056,28 +2056,29 @@ config_load(void)
|
||||
cassette_ui_writeprot = 0;
|
||||
|
||||
config_log("Config file not present or invalid!\n");
|
||||
return;
|
||||
} else {
|
||||
load_general(); /* General */
|
||||
load_machine(); /* Machine */
|
||||
load_video(); /* Video */
|
||||
load_input_devices(); /* Input devices */
|
||||
load_sound(); /* Sound */
|
||||
load_network(); /* Network */
|
||||
load_ports(); /* Ports (COM & LPT) */
|
||||
load_storage_controllers(); /* Storage controllers */
|
||||
load_hard_disks(); /* Hard disks */
|
||||
load_floppy_and_cdrom_drives(); /* Floppy and CD-ROM drives */
|
||||
/* TODO: Backwards compatibility, get rid of this when enough time has passed. */
|
||||
load_floppy_drives(); /* Floppy drives */
|
||||
load_other_removable_devices(); /* Other removable devices */
|
||||
load_other_peripherals(); /* Other peripherals */
|
||||
|
||||
/* Mark the configuration as changed. */
|
||||
config_changed = 1;
|
||||
|
||||
config_log("Config loaded.\n\n");
|
||||
}
|
||||
|
||||
load_general(); /* General */
|
||||
load_machine(); /* Machine */
|
||||
load_video(); /* Video */
|
||||
load_input_devices(); /* Input devices */
|
||||
load_sound(); /* Sound */
|
||||
load_network(); /* Network */
|
||||
load_ports(); /* Ports (COM & LPT) */
|
||||
load_storage_controllers(); /* Storage controllers */
|
||||
load_hard_disks(); /* Hard disks */
|
||||
load_floppy_and_cdrom_drives(); /* Floppy and CD-ROM drives */
|
||||
/* TODO: Backwards compatibility, get rid of this when enough time has passed. */
|
||||
load_floppy_drives(); /* Floppy drives */
|
||||
load_other_removable_devices(); /* Other removable devices */
|
||||
load_other_peripherals(); /* Other peripherals */
|
||||
|
||||
/* Mark the configuration as changed. */
|
||||
config_changed = 1;
|
||||
|
||||
config_log("Config loaded.\n\n");
|
||||
video_copy = (video_grayscale || invert_display) ? video_transform_copy : memcpy;
|
||||
}
|
||||
|
||||
|
||||
|
@@ -133,6 +133,10 @@ extern int readflash;
|
||||
|
||||
/* Function handler pointers. */
|
||||
extern void (*video_recalctimings)(void);
|
||||
extern void * __cdecl (*video_copy)(void *_Dst, const void *_Src, size_t _Size);
|
||||
|
||||
extern void video_screenshot(uint32_t *buf, int start_x, int start_y, int row_len);
|
||||
extern void * __cdecl video_transform_copy(void *_Dst, const void *_Src, size_t _Size);
|
||||
|
||||
|
||||
/* Table functions. */
|
||||
|
@@ -133,7 +133,10 @@ sdl_blit_shim(int x, int y, int w, int h)
|
||||
params.y = y;
|
||||
params.w = w;
|
||||
params.h = h;
|
||||
if (!(!sdl_enabled || (x < 0) || (y < 0) || (w <= 0) || (h <= 0) || (w > 2048) || (h > 2048) || (buffer32 == NULL) || (sdl_render == NULL) || (sdl_tex == NULL))) memcpy(interpixels, &(buffer32->line[y][x]), h * (2048 + 64) * sizeof(uint32_t));
|
||||
if (!(!sdl_enabled || (x < 0) || (y < 0) || (w <= 0) || (h <= 0) || (w > 2048) || (h > 2048) || (buffer32 == NULL) || (sdl_render == NULL) || (sdl_tex == NULL)))
|
||||
video_copy(interpixels, &(buffer32->line[y][x]), h * (2048 + 64) * sizeof(uint32_t));
|
||||
if (screenshots)
|
||||
video_screenshot(interpixels, 0, 0, (2048 + 64));
|
||||
blitreq = 1;
|
||||
video_blit_complete();
|
||||
}
|
||||
|
@@ -114,6 +114,8 @@ static const video_timings_t *vid_timings;
|
||||
static uint32_t cga_2_table[16];
|
||||
static uint8_t thread_run = 0;
|
||||
|
||||
void * __cdecl (*video_copy)(void *_Dst, const void *_Src, size_t _Size) = memcpy;
|
||||
|
||||
|
||||
PALETTE cgapal = {
|
||||
{0,0,0}, {0,42,0}, {42,0,0}, {42,21,0},
|
||||
@@ -317,7 +319,7 @@ static png_infop info_ptr;
|
||||
|
||||
|
||||
static void
|
||||
video_take_screenshot(const char *fn)
|
||||
video_take_screenshot(const char *fn, uint32_t *buf, int start_x, int start_y, int row_len)
|
||||
{
|
||||
int i, x, y;
|
||||
png_bytep *b_rgb = NULL;
|
||||
@@ -363,10 +365,10 @@ video_take_screenshot(const char *fn)
|
||||
for (y = 0; y < blit_data.h; ++y) {
|
||||
b_rgb[y] = (png_byte *) malloc(png_get_rowbytes(png_ptr, info_ptr));
|
||||
for (x = 0; x < blit_data.w; ++x) {
|
||||
if (buffer32 == NULL)
|
||||
if (buf == NULL)
|
||||
memset(&(b_rgb[y][x * 3]), 0x00, 3);
|
||||
else {
|
||||
temp = buffer32->line[blit_data.y + y][blit_data.x + x];
|
||||
temp = buf[((start_y + y) * row_len) + start_x + x];
|
||||
b_rgb[y][x * 3] = (temp >> 16) & 0xff;
|
||||
b_rgb[y][(x * 3) + 1] = (temp >> 8) & 0xff;
|
||||
b_rgb[y][(x * 3) + 2] = temp & 0xff;
|
||||
@@ -390,8 +392,8 @@ video_take_screenshot(const char *fn)
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
video_screenshot(void)
|
||||
void
|
||||
video_screenshot(uint32_t *buf, int start_x, int start_y, int row_len)
|
||||
{
|
||||
char path[1024], fn[128];
|
||||
|
||||
@@ -410,50 +412,42 @@ video_screenshot(void)
|
||||
|
||||
video_log("taking screenshot to: %s\n", path);
|
||||
|
||||
video_take_screenshot((const char *) path);
|
||||
video_take_screenshot((const char *) path, buf, start_x, start_y, row_len);
|
||||
png_destroy_write_struct(&png_ptr, &info_ptr);
|
||||
|
||||
screenshots--;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
video_transform_copy(uint32_t *dst, uint32_t *src, int len)
|
||||
void * __cdecl
|
||||
video_transform_copy(void *_Dst, const void *_Src, size_t _Size)
|
||||
{
|
||||
int i;
|
||||
uint32_t *dest_ex = (uint32_t *) _Dst;
|
||||
uint32_t *src_ex = (uint32_t *) _Src;
|
||||
|
||||
if ((dst != NULL) && (src != NULL)) {
|
||||
for (i = 0; i < len; i++) {
|
||||
*dst = video_color_transform(*src);
|
||||
dst++;
|
||||
src++;
|
||||
_Size /= sizeof(uint32_t);
|
||||
|
||||
if ((dest_ex != NULL) && (src_ex != NULL)) {
|
||||
for (i = 0; i < _Size; i++) {
|
||||
*dest_ex = video_color_transform(*src_ex);
|
||||
dest_ex++;
|
||||
src_ex++;
|
||||
}
|
||||
}
|
||||
|
||||
return _Dst;
|
||||
}
|
||||
|
||||
|
||||
static
|
||||
void blit_thread(void *param)
|
||||
{
|
||||
int yy;
|
||||
|
||||
while (thread_run) {
|
||||
thread_wait_event(blit_data.wake_blit_thread, -1);
|
||||
thread_reset_event(blit_data.wake_blit_thread);
|
||||
MTR_BEGIN("video", "blit_thread");
|
||||
|
||||
if ((video_grayscale || invert_display) && (blit_data.h > 0)) {
|
||||
for (yy = 0; yy < blit_data.h; yy++) {
|
||||
if (((blit_data.y + yy) >= 0) && ((blit_data.y + yy) < buffer32->h)) {
|
||||
video_transform_copy(&(buffer32->line[blit_data.y + yy][blit_data.x]), &(buffer32->line[blit_data.y + yy][blit_data.x]), blit_data.w);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (screenshots) {
|
||||
video_screenshot();
|
||||
screenshots--;
|
||||
video_log("screenshot taken, %i left\n", screenshots);
|
||||
}
|
||||
|
||||
if (blit_func)
|
||||
blit_func(blit_data.x, blit_data.y, blit_data.w, blit_data.h);
|
||||
|
||||
|
@@ -179,8 +179,11 @@ vnc_blit(int x, int y, int w, int h)
|
||||
p = (uint32_t *)&(((uint32_t *)rfb->frameBuffer)[yy*VNC_MAX_X]);
|
||||
|
||||
if ((y+yy) >= 0 && (y+yy) < VNC_MAX_Y)
|
||||
memcpy(p, &(buffer32->line[yy]), w*sizeof(uint32_t));
|
||||
video_copy(p, &(buffer32->line[yy]), w*sizeof(uint32_t));
|
||||
}
|
||||
|
||||
if (screenshots)
|
||||
video_screenshot((uint32_t *) rfb->frameBuffer, 0, 0, ROW_LENGTH);
|
||||
|
||||
video_blit_complete();
|
||||
|
||||
|
@@ -816,7 +816,10 @@ static void opengl_blit(int x, int y, int w, int h)
|
||||
return;
|
||||
}
|
||||
|
||||
memcpy(blit_info[write_pos].buffer, &(buffer32->line[y][x]), h * ROW_LENGTH * sizeof(uint32_t));
|
||||
video_copy(blit_info[write_pos].buffer, &(buffer32->line[y][x]), h * ROW_LENGTH * sizeof(uint32_t));
|
||||
|
||||
if (screenshots)
|
||||
video_screenshot(blit_info[write_pos].buffer, 0, 0, ROW_LENGTH);
|
||||
|
||||
video_blit_complete();
|
||||
|
||||
|
@@ -232,7 +232,8 @@ static void
|
||||
sdl_blit(int x, int y, int w, int h)
|
||||
{
|
||||
SDL_Rect r_src;
|
||||
int ret;
|
||||
void *pixeldata;
|
||||
int pitch, ret;
|
||||
|
||||
if (!sdl_enabled || (x < 0) || (y < 0) || (w <= 0) || (h <= 0) || (w > 2048) || (h > 2048) || (buffer32 == NULL) || (sdl_render == NULL) || (sdl_tex == NULL)) {
|
||||
video_blit_complete();
|
||||
@@ -241,17 +242,21 @@ sdl_blit(int x, int y, int w, int h)
|
||||
|
||||
SDL_LockMutex(sdl_mutex);
|
||||
|
||||
r_src.x = x;
|
||||
r_src.y = y;
|
||||
r_src.w = w;
|
||||
r_src.h = h;
|
||||
SDL_UpdateTexture(sdl_tex, &r_src, &(buffer32->line[y][x]), (2048 + 64) * sizeof(uint32_t));
|
||||
SDL_LockTexture(sdl_tex, 0, &pixeldata, &pitch);
|
||||
|
||||
video_copy(pixeldata, &(buffer32->line[y][x]), h * (2048 + 64) * sizeof(uint32_t));
|
||||
|
||||
if (screenshots)
|
||||
video_screenshot((uint32_t *) pixeldata, 0, 0, (2048 + 64));
|
||||
|
||||
SDL_UnlockTexture(sdl_tex);
|
||||
|
||||
video_blit_complete();
|
||||
|
||||
SDL_RenderClear(sdl_render);
|
||||
|
||||
r_src.x = x;
|
||||
r_src.y = y;
|
||||
r_src.x = 0;
|
||||
r_src.y = 0;
|
||||
r_src.w = w;
|
||||
r_src.h = h;
|
||||
|
||||
@@ -353,7 +358,7 @@ sdl_init_texture(void)
|
||||
sdl_render = SDL_CreateRenderer(sdl_win, -1, SDL_RENDERER_SOFTWARE);
|
||||
|
||||
sdl_tex = SDL_CreateTexture(sdl_render, SDL_PIXELFORMAT_ARGB8888,
|
||||
SDL_TEXTUREACCESS_STREAMING, 2048, 2048);
|
||||
SDL_TEXTUREACCESS_STREAMING, (2048 + 64), (2048 + 64));
|
||||
}
|
||||
|
||||
|
||||
|
@@ -822,6 +822,7 @@ MainWindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
|
||||
|
||||
case IDM_VID_INVERT:
|
||||
video_toggle_option(hmenu, &invert_display, IDM_VID_INVERT);
|
||||
video_copy = (video_grayscale || invert_display) ? video_transform_copy : memcpy;
|
||||
break;
|
||||
|
||||
case IDM_VID_OVERSCAN:
|
||||
@@ -854,6 +855,7 @@ MainWindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
|
||||
case IDM_VID_GRAY_WHITE:
|
||||
CheckMenuItem(hmenu, IDM_VID_GRAY_RGB+video_grayscale, MF_UNCHECKED);
|
||||
video_grayscale = LOWORD(wParam) - IDM_VID_GRAY_RGB;
|
||||
video_copy = (video_grayscale || invert_display) ? video_transform_copy : memcpy;
|
||||
CheckMenuItem(hmenu, IDM_VID_GRAY_RGB+video_grayscale, MF_CHECKED);
|
||||
device_force_redraw();
|
||||
config_save();
|
||||
|
Reference in New Issue
Block a user