From 8a3367ff6f121c4a118e56274c67829cfe408502 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Sun, 3 Jul 2022 01:07:13 +0600 Subject: [PATCH] Multi-monitor support (backend preparation part) --- src/86box.c | 10 +- src/include/86box/86box.h | 3 - src/include/86box/plat.h | 3 - src/include/86box/vid_cga.h | 2 + src/include/86box/vid_ega.h | 4 +- src/include/86box/vid_hercules.h | 1 + src/include/86box/vid_svga.h | 2 +- src/include/86box/vid_xga.h | 2 +- src/include/86box/video.h | 109 +++++-- src/machine/m_amstrad.c | 7 +- src/machine/m_at_compaq.c | 4 +- src/machine/m_pcjr.c | 3 +- src/machine/m_tandy.c | 3 +- src/qt/qt_mainwindow.cpp | 2 +- src/qt/qt_ui.cpp | 2 +- src/unix/unix_sdl.c | 2 +- src/video/vid_ati_mach64.c | 22 +- src/video/vid_bt48x_ramdac.c | 26 +- src/video/vid_cga.c | 2 +- src/video/vid_cl54xx.c | 14 +- src/video/vid_ega.c | 20 +- src/video/vid_ega_render.c | 4 +- src/video/vid_et4000w32.c | 10 +- src/video/vid_hercules.c | 2 +- src/video/vid_ht216.c | 2 +- src/video/vid_ibm_rgb528_ramdac.c | 10 +- src/video/vid_s3.c | 4 +- src/video/vid_s3_virge.c | 4 +- src/video/vid_sigma.c | 3 +- src/video/vid_svga.c | 16 +- src/video/vid_tgui9440.c | 4 +- src/video/vid_tvp3026_ramdac.c | 26 +- src/video/vid_voodoo_banshee.c | 64 ++-- src/video/vid_xga.c | 10 +- src/video/video.c | 474 +++++++++++++++++++----------- src/win/win_opengl.c | 2 +- src/win/win_sdl.c | 4 +- 37 files changed, 537 insertions(+), 345 deletions(-) diff --git a/src/86box.c b/src/86box.c index 148eb63f8..9f62836ad 100644 --- a/src/86box.c +++ b/src/86box.c @@ -201,17 +201,17 @@ char exe_path[2048]; /* path (dir) of executable */ char usr_path[1024]; /* path (dir) of user data */ char cfg_path[1024]; /* full path of config file */ FILE *stdlog = NULL; /* file to log output to */ -int scrnsz_x = SCREEN_RES_X; /* current screen size, X */ -int scrnsz_y = SCREEN_RES_Y; /* current screen size, Y */ +//int scrnsz_x = SCREEN_RES_X; /* current screen size, X */ +//int scrnsz_y = SCREEN_RES_Y; /* current screen size, Y */ int config_changed; /* config has changed */ int title_update; int framecountx = 0; int hard_reset_pending = 0; -int unscaled_size_x = SCREEN_RES_X; /* current unscaled size X */ -int unscaled_size_y = SCREEN_RES_Y; /* current unscaled size Y */ -int efscrnsz_y = SCREEN_RES_Y; +//int unscaled_size_x = SCREEN_RES_X; /* current unscaled size X */ +//int unscaled_size_y = SCREEN_RES_Y; /* current unscaled size Y */ +//int efscrnsz_y = SCREEN_RES_Y; static wchar_t mouse_msg[3][200]; diff --git a/src/include/86box/86box.h b/src/include/86box/86box.h index c4ddaed4b..93876f611 100644 --- a/src/include/86box/86box.h +++ b/src/include/86box/86box.h @@ -141,9 +141,6 @@ extern char cfg_path[1024]; /* full path of config file */ #ifndef USE_NEW_DYNAREC extern FILE *stdlog; /* file to log output to */ #endif -extern int scrnsz_x, /* current screen size, X */ - scrnsz_y; /* current screen size, Y */ -extern int efscrnsz_y; extern int config_changed; /* config has changed */ diff --git a/src/include/86box/plat.h b/src/include/86box/plat.h index 1f787da9e..2c0ad054a 100644 --- a/src/include/86box/plat.h +++ b/src/include/86box/plat.h @@ -90,9 +90,6 @@ extern char emu_version[200]; /* version ID string */ extern int rctrl_is_lalt; extern int update_icons; -extern int unscaled_size_x, /* current unscaled size X */ - unscaled_size_y; /* current unscaled size Y */ - extern int kbd_req_capture, hide_status_bar, hide_tool_bar; /* System-related functions. */ diff --git a/src/include/86box/vid_cga.h b/src/include/86box/vid_cga.h index 26fe2ea1a..d36872e18 100644 --- a/src/include/86box/vid_cga.h +++ b/src/include/86box/vid_cga.h @@ -46,6 +46,8 @@ typedef struct cga_t int drawcursor; + int fullchange; + uint8_t *vram; uint8_t charbuffer[256]; diff --git a/src/include/86box/vid_ega.h b/src/include/86box/vid_ega.h index b007ac46d..f1ba7e417 100644 --- a/src/include/86box/vid_ega.h +++ b/src/include/86box/vid_ega.h @@ -46,14 +46,14 @@ typedef struct ega_t { readmode, writemode, readplane, vrammask, chain4, chain2_read, chain2_write, con, oddeven_page, oddeven_chain, vc, sc, - dispon, hdisp_on, cursoron, blink, + dispon, hdisp_on, cursoron, blink, fullchange, linepos, vslines, linecountff, oddeven, lowres, interlace, linedbl, lindebl, rowcount, vtotal, dispend, vsyncstart, split, hdisp, hdisp_old, htotal, hdisp_time, rowoffset, vblankstart, scrollcache, firstline, lastline, firstline_draw, lastline_draw, x_add, y_add, - displine, video_res_x, video_res_y, video_bpp, index; + displine, res_x, res_y, bpp, index; uint32_t charseta, charsetb, ma_latch, ma, maback, ca, vram_limit, overscan_color; diff --git a/src/include/86box/vid_hercules.h b/src/include/86box/vid_hercules.h index f97a8fa18..53f45dd27 100644 --- a/src/include/86box/vid_hercules.h +++ b/src/include/86box/vid_hercules.h @@ -51,6 +51,7 @@ typedef struct { int vadj; int lp_ff; + int fullchange; int cols[256][2][2]; diff --git a/src/include/86box/vid_svga.h b/src/include/86box/vid_svga.h index 40613fe99..530ea648d 100644 --- a/src/include/86box/vid_svga.h +++ b/src/include/86box/vid_svga.h @@ -35,7 +35,7 @@ typedef struct { int ena, - x, y, xoff, yoff, xsize, ysize, + x, y, xoff, yoff, cur_xsize, cur_ysize, v_acc, h_acc; uint32_t addr, pitch; } hwcursor_t; diff --git a/src/include/86box/vid_xga.h b/src/include/86box/vid_xga.h index aef837fba..6cc59e0db 100644 --- a/src/include/86box/vid_xga.h +++ b/src/include/86box/vid_xga.h @@ -22,7 +22,7 @@ typedef struct { int ena; - int x, y, xoff, yoff, xsize, ysize; + int x, y, xoff, yoff, cur_xsize, cur_ysize; uint32_t addr; } xga_hwcursor_t; diff --git a/src/include/86box/video.h b/src/include/86box/video.h index 513cb99ad..e6b1645a4 100644 --- a/src/include/86box/video.h +++ b/src/include/86box/video.h @@ -22,6 +22,12 @@ #ifndef EMU_VIDEO_H # define EMU_VIDEO_H +#ifdef __cplusplus +#include +using atomic_bool = std::atomic_bool; +#else +#include +#endif #define makecol(r, g, b) ((b) | ((g) << 8) | ((r) << 16)) #define makecol32(r, g, b) ((b) | ((g) << 8) | ((r) << 16)) @@ -79,20 +85,83 @@ typedef struct { uint8_t chr[32]; } dbcs_font_t; +struct blit_data_struct; + +typedef struct monitor_t +{ + char name[512]; + int mon_xsize; + int mon_ysize; + int mon_scrnsz_x; + int mon_scrnsz_y; + int mon_efscrnsz_y; + int mon_unscaled_size_x; + int mon_unscaled_size_y; + int mon_res_x; + int mon_res_y; + int mon_bpp; + bitmap_t* target_buffer; + int mon_video_timing_read_b, + mon_video_timing_read_w, + mon_video_timing_read_l; + int mon_video_timing_write_b, + mon_video_timing_write_w, + mon_video_timing_write_l; + int mon_overscan_x; + int mon_overscan_y; + int mon_force_resize; + int mon_fullchange; + int mon_changeframecount; + atomic_bool mon_doresize; + int mon_screenshots; + uint32_t* mon_pal_lookup; + int* mon_cga_palette; + int mon_pal_lookup_static; /* Whether it should not be freed by the API. */ + int mon_cga_palette_static; /* Whether it should not be freed by the API. */ + const video_timings_t* mon_vid_timings; + int mon_vid_type; + struct blit_data_struct* mon_blit_data_ptr; +} monitor_t; + +#define MONITORS_NUM 8 +extern monitor_t monitors[MONITORS_NUM]; +extern int monitor_index_global; + typedef rgb_t PALETTE[256]; -extern int changeframecount; +//extern int changeframecount; extern volatile int screenshots; -extern bitmap_t *buffer32; +//extern bitmap_t *buffer32; +#define buffer32 (monitors[monitor_index_global].target_buffer) +#define pal_lookup (monitors[monitor_index_global].mon_pal_lookup) +#define overscan_x (monitors[monitor_index_global].mon_overscan_x) +#define overscan_y (monitors[monitor_index_global].mon_overscan_y) +#define video_timing_read_b (monitors[monitor_index_global].mon_video_timing_read_b) +#define video_timing_read_l (monitors[monitor_index_global].mon_video_timing_read_l) +#define video_timing_read_w (monitors[monitor_index_global].mon_video_timing_read_w) +#define video_timing_write_b (monitors[monitor_index_global].mon_video_timing_write_b) +#define video_timing_write_l (monitors[monitor_index_global].mon_video_timing_write_l) +#define video_timing_write_w (monitors[monitor_index_global].mon_video_timing_write_w) +#define video_res_x (monitors[monitor_index_global].mon_res_x) +#define video_res_y (monitors[monitor_index_global].mon_res_y) +#define video_bpp (monitors[monitor_index_global].mon_bpp) +#define xsize (monitors[monitor_index_global].mon_xsize) +#define ysize (monitors[monitor_index_global].mon_ysize) +#define cga_palette (*monitors[monitor_index_global].mon_cga_palette) +#define changeframecount (monitors[monitor_index_global].mon_changeframecount) +#define scrnsz_x (monitors[monitor_index_global].mon_scrnsz_x) +#define scrnsz_y (monitors[monitor_index_global].mon_scrnsz_y) +#define efscrnsz_y (monitors[monitor_index_global].mon_efscrnsz_y) +#define unscaled_size_x (monitors[monitor_index_global].mon_unscaled_size_x) +#define unscaled_size_y (monitors[monitor_index_global].mon_unscaled_size_y) extern PALETTE cgapal, cgapal_mono[6]; -extern uint32_t pal_lookup[256]; +//extern uint32_t pal_lookup[256]; extern int video_fullscreen, video_fullscreen_scale, - video_fullscreen_first; -extern int fullchange; + video_fullscreen_first; extern uint8_t fontdat[2048][8]; extern uint8_t fontdatm[2048][16]; extern uint8_t fontdatw[512][32]; @@ -104,24 +173,11 @@ extern uint32_t *video_6to8, *video_8togs, *video_8to32, *video_15to32, - *video_16to32; -extern int xsize,ysize; + *video_16to32; extern int enable_overscan; -extern int overscan_x, - overscan_y; extern int force_43; -extern int video_timing_read_b, - video_timing_read_w, - video_timing_read_l; -extern int video_timing_write_b, - video_timing_write_w, - video_timing_write_l; -extern int video_res_x, - video_res_y, - video_bpp; extern int vid_resize; -extern int cga_palette, - herc_blend; +extern int herc_blend; extern int vid_cga_contrast; extern int video_grayscale; extern int video_graytype; @@ -134,6 +190,7 @@ extern int readflash; /* Function handler pointers. */ extern void (*video_recalctimings)(void); +extern void video_screenshot_monitor(uint32_t *buf, int start_x, int start_y, int row_len, int monitor_index); extern void video_screenshot(uint32_t *buf, int start_x, int start_y, int row_len); #ifdef _WIN32 @@ -158,18 +215,26 @@ extern int video_is_cga(void); extern int video_is_ega_vga(void); extern void video_inform(int type, const video_timings_t *ptr); extern int video_get_type(void); +extern int video_get_type_monitor(int monitor_index); -extern void video_setblit(void(*blit)(int,int,int,int)); +extern void video_setblit(void(*blit)(int,int,int,int,int)); extern void video_blend(int x, int y); +extern void video_blend_monitor(int x, int y, int monitor_index); extern void video_blit_memtoscreen_8(int x, int y, int w, int h); +extern void video_blit_memtoscreen_8_monitor(int x, int y, int w, int h, int monitor_index); extern void video_blit_memtoscreen(int x, int y, int w, int h); +extern void video_blit_memtoscreen_monitor(int x, int y, int w, int h, int monitor_index); extern void video_blit_complete(void); extern void video_wait_for_blit(void); extern void video_wait_for_buffer(void); +extern void video_blit_complete_monitor(int monitor_index); +extern void video_wait_for_blit_monitor(int monitor_index); +extern void video_wait_for_buffer_monitor(int monitor_index); extern bitmap_t *create_bitmap(int w, int h); extern void destroy_bitmap(bitmap_t *b); +extern void cgapal_rebuild_monitor(int monitor_index); extern void cgapal_rebuild(void); extern void hline(bitmap_t *b, int x1, int y, int x2, uint32_t col); extern void updatewindowsize(int x, int y); @@ -180,7 +245,9 @@ extern void video_reset_close(void); extern void video_pre_reset(int card); extern void video_reset(int card); extern uint8_t video_force_resize_get(void); +extern uint8_t video_force_resize_get_monitor(int monitor_index); extern void video_force_resize_set(uint8_t res); +extern void video_force_resize_set_monitor(uint8_t res, int monitor_index); extern void video_update_timing(void); extern void loadfont_ex(char *s, int format, int offset); diff --git a/src/machine/m_amstrad.c b/src/machine/m_amstrad.c index e05d0d23e..27244189d 100644 --- a/src/machine/m_amstrad.c +++ b/src/machine/m_amstrad.c @@ -119,6 +119,7 @@ typedef struct { cursoron, cgablink; int vsynctime; + int fullchange; int vadj; uint16_t ma, maback; int dispon; @@ -242,7 +243,7 @@ vid_out_1512(uint16_t addr, uint8_t val, void *priv) vid->crtc[vid->crtcreg] = val & crtc_mask[vid->crtcreg]; if (old != val) { if (vid->crtcreg < 0xe || vid->crtcreg > 0x10) { - fullchange = changeframecount; + vid->fullchange = changeframecount; recalc_timings_1512(vid); } } @@ -1113,7 +1114,7 @@ vid_out_200(uint16_t addr, uint8_t val, void *priv) mda->crtc[mda->crtcreg] = val & crtc_mask[mda->crtcreg]; if (old != val) { if (mda->crtcreg < 0xe || mda->crtcreg > 0x10) { - fullchange = changeframecount; + vid->fullchange = changeframecount; mda_recalctimings(mda); } } @@ -1145,7 +1146,7 @@ vid_out_200(uint16_t addr, uint8_t val, void *priv) cga->crtc[cga->crtcreg] = val & crtc_mask[cga->crtcreg]; if (old != val) { if (cga->crtcreg < 0xe || cga->crtcreg > 0x10) { - fullchange = changeframecount; + vid->fullchange = changeframecount; cga_recalctimings(cga); } } diff --git a/src/machine/m_at_compaq.c b/src/machine/m_at_compaq.c index 4f7181616..c67ccbb39 100644 --- a/src/machine/m_at_compaq.c +++ b/src/machine/m_at_compaq.c @@ -97,7 +97,7 @@ typedef struct compaq_plasma_t int linepos, displine; uint8_t *vram; uint64_t dispontime, dispofftime; - int dispon; + int dispon, fullchange; } compaq_plasma_t; static uint8_t cga_crtcmask[32] = @@ -375,7 +375,7 @@ compaq_plasma_out(uint16_t addr, uint8_t val, void *priv) if (old != val) { if (self->cga.crtcreg < 0xe || self->cga.crtcreg > 0x10) { - fullchange = changeframecount; + self->fullchange = changeframecount; compaq_plasma_recalctimings(self); } } diff --git a/src/machine/m_pcjr.c b/src/machine/m_pcjr.c index 4836da1bc..0a8b9cf46 100644 --- a/src/machine/m_pcjr.c +++ b/src/machine/m_pcjr.c @@ -81,6 +81,7 @@ typedef struct { int dispon; int con, coff, cursoron, blink; int vsynctime; + int fullchange; int vadj; uint16_t ma, maback; uint64_t dispontime, dispofftime; @@ -162,7 +163,7 @@ vid_out(uint16_t addr, uint8_t val, void *p) pcjr->crtc[pcjr->crtcreg] = val & crtcmask[pcjr->crtcreg]; if (old != val) { if (pcjr->crtcreg < 0xe || pcjr->crtcreg > 0x10) { - fullchange = changeframecount; + pcjr->fullchange = changeframecount; recalc_timings(pcjr); } } diff --git a/src/machine/m_tandy.c b/src/machine/m_tandy.c index 39e5fe844..924466e8d 100644 --- a/src/machine/m_tandy.c +++ b/src/machine/m_tandy.c @@ -91,6 +91,7 @@ typedef struct { int con, coff, cursoron, blink; + int fullchange; int vsynctime; int vadj; uint16_t ma, maback; @@ -536,7 +537,7 @@ vid_out(uint16_t addr, uint8_t val, void *priv) vid->crtc[vid->crtcreg] = val & crtcmask[vid->crtcreg]; if (old != val) { if (vid->crtcreg < 0xe || vid->crtcreg > 0x10) { - fullchange = changeframecount; + vid->fullchange = changeframecount; recalc_timings(dev); } } diff --git a/src/qt/qt_mainwindow.cpp b/src/qt/qt_mainwindow.cpp index f0db0f019..c81540d7e 100644 --- a/src/qt/qt_mainwindow.cpp +++ b/src/qt/qt_mainwindow.cpp @@ -119,7 +119,7 @@ static BMessageFilter* filter; #endif extern void qt_mouse_capture(int); -extern "C" void qt_blit(int x, int y, int w, int h); +extern "C" void qt_blit(int x, int y, int w, int h, int monitor_index); MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), diff --git a/src/qt/qt_ui.cpp b/src/qt/qt_ui.cpp index 413057334..207e57655 100644 --- a/src/qt/qt_ui.cpp +++ b/src/qt/qt_ui.cpp @@ -55,7 +55,7 @@ wchar_t* ui_window_title(wchar_t* str) return str; } -extern "C" void qt_blit(int x, int y, int w, int h) +extern "C" void qt_blit(int x, int y, int w, int h, int monitor_index) { main_window->blitToWidget(x, y, w, h); } diff --git a/src/unix/unix_sdl.c b/src/unix/unix_sdl.c index aeeb9d60c..9cd164305 100644 --- a/src/unix/unix_sdl.c +++ b/src/unix/unix_sdl.c @@ -128,7 +128,7 @@ sdl_stretch(int *w, int *h, int *x, int *y) void -sdl_blit_shim(int x, int y, int w, int h) +sdl_blit_shim(int x, int y, int w, int h, int monitor_index) { params.x = x; params.y = y; diff --git a/src/video/vid_ati_mach64.c b/src/video/vid_ati_mach64.c index 2fe70c322..a5325e8f7 100644 --- a/src/video/vid_ati_mach64.c +++ b/src/video/vid_ati_mach64.c @@ -1926,8 +1926,8 @@ static void mach64_vblank_start(svga_t *svga) svga->overlay.x = (mach64->overlay_y_x_start >> 16) & 0x7ff; svga->overlay.y = mach64->overlay_y_x_start & 0x7ff; - svga->overlay.xsize = ((mach64->overlay_y_x_end >> 16) & 0x7ff) - svga->overlay.x; - svga->overlay.ysize = (mach64->overlay_y_x_end & 0x7ff) - svga->overlay.y; + svga->overlay.cur_xsize = ((mach64->overlay_y_x_end >> 16) & 0x7ff) - svga->overlay.x; + svga->overlay.cur_ysize = (mach64->overlay_y_x_end & 0x7ff) - svga->overlay.y; svga->overlay.addr = mach64->buf_offset[0] & 0x3ffff8; svga->overlay.pitch = mach64->buf_pitch[0] & 0xfff; @@ -3050,7 +3050,7 @@ uint32_t mach64_readl(uint32_t addr, void *p) #define DECODE_ARGB1555() \ do \ { \ - for (x = 0; x < mach64->svga.overlay_latch.xsize; x++) \ + for (x = 0; x < mach64->svga.overlay_latch.cur_xsize; x++) \ { \ uint16_t dat = ((uint16_t *)src)[x]; \ \ @@ -3069,7 +3069,7 @@ uint32_t mach64_readl(uint32_t addr, void *p) #define DECODE_RGB565() \ do \ { \ - for (x = 0; x < mach64->svga.overlay_latch.xsize; x++) \ + for (x = 0; x < mach64->svga.overlay_latch.cur_xsize; x++) \ { \ uint16_t dat = ((uint16_t *)src)[x]; \ \ @@ -3088,7 +3088,7 @@ uint32_t mach64_readl(uint32_t addr, void *p) #define DECODE_ARGB8888() \ do \ { \ - for (x = 0; x < mach64->svga.overlay_latch.xsize; x++) \ + for (x = 0; x < mach64->svga.overlay_latch.cur_xsize; x++) \ { \ int b = src[0]; \ int g = src[1]; \ @@ -3102,7 +3102,7 @@ uint32_t mach64_readl(uint32_t addr, void *p) #define DECODE_VYUY422() \ do \ { \ - for (x = 0; x < mach64->svga.overlay_latch.xsize; x += 2) \ + for (x = 0; x < mach64->svga.overlay_latch.cur_xsize; x += 2) \ { \ uint8_t y1, y2; \ int8_t u, v; \ @@ -3140,7 +3140,7 @@ uint32_t mach64_readl(uint32_t addr, void *p) #define DECODE_YVYU422() \ do \ { \ - for (x = 0; x < mach64->svga.overlay_latch.xsize; x += 2) \ + for (x = 0; x < mach64->svga.overlay_latch.cur_xsize; x += 2) \ { \ uint8_t y1, y2; \ int8_t u, v; \ @@ -3217,7 +3217,7 @@ void mach64_overlay_draw(svga_t *svga, int displine) default: mach64_log("Unknown Mach64 scaler format %x\n", mach64->scaler_format); /*Fill buffer with something recognisably wrong*/ - for (x = 0; x < mach64->svga.overlay_latch.xsize; x++) + for (x = 0; x < mach64->svga.overlay_latch.cur_xsize; x++) mach64->overlay_dat[x] = 0xff00ff; break; } @@ -3225,7 +3225,7 @@ void mach64_overlay_draw(svga_t *svga, int displine) if (overlay_cmp_mix == 2) { - for (x = 0; x < mach64->svga.overlay_latch.xsize; x++) + for (x = 0; x < mach64->svga.overlay_latch.cur_xsize; x++) { int h = h_acc >> 12; @@ -3238,7 +3238,7 @@ void mach64_overlay_draw(svga_t *svga, int displine) } else { - for (x = 0; x < mach64->svga.overlay_latch.xsize; x++) + for (x = 0; x < mach64->svga.overlay_latch.cur_xsize; x++) { int h = h_acc >> 12; int gr_cmp = 0, vid_cmp = 0; @@ -3530,7 +3530,7 @@ static void *mach64_common_init(const device_t *info) mach64_in, mach64_out, NULL, mach64_overlay_draw); - mach64->svga.dac_hwcursor.ysize = 64; + mach64->svga.dac_hwcursor.cur_ysize = 64; if (info->flags & DEVICE_PCI) mem_mapping_disable(&mach64->bios_rom.mapping); diff --git a/src/video/vid_bt48x_ramdac.c b/src/video/vid_bt48x_ramdac.c index 4be070467..43b02fa6e 100644 --- a/src/video/vid_bt48x_ramdac.c +++ b/src/video/vid_bt48x_ramdac.c @@ -169,9 +169,9 @@ bt48x_ramdac_out(uint16_t addr, int rs2, int rs3, uint8_t val, void *p, svga_t * ramdac->cmd_r3 = val; if (ramdac->type >= BT485A) bt48x_set_bpp(ramdac, svga); - svga->dac_hwcursor.xsize = svga->dac_hwcursor.ysize = (val & 4) ? 64 : 32; - svga->dac_hwcursor.x = ramdac->hwc_x - svga->dac_hwcursor.xsize; - svga->dac_hwcursor.y = ramdac->hwc_y - svga->dac_hwcursor.ysize; + svga->dac_hwcursor.cur_xsize = svga->dac_hwcursor.cur_ysize = (val & 4) ? 64 : 32; + svga->dac_hwcursor.x = ramdac->hwc_x - svga->dac_hwcursor.cur_xsize; + svga->dac_hwcursor.y = ramdac->hwc_y - svga->dac_hwcursor.cur_ysize; svga->dac_addr = (svga->dac_addr & 0x00ff) | ((val & 0x03) << 8); svga_recalctimings(svga); break; @@ -191,7 +191,7 @@ bt48x_ramdac_out(uint16_t addr, int rs2, int rs3, uint8_t val, void *p, svga_t * break; case 0x0b: /* Cursor RAM Data Register (RS value = 1011) */ index = svga->dac_addr & da_mask; - if ((ramdac->type >= BT485) && (svga->dac_hwcursor.xsize == 64)) + if ((ramdac->type >= BT485) && (svga->dac_hwcursor.cur_xsize == 64)) cd = (uint8_t *) ramdac->cursor64_data; else { index &= 0xff; @@ -204,19 +204,19 @@ bt48x_ramdac_out(uint16_t addr, int rs2, int rs3, uint8_t val, void *p, svga_t * break; case 0x0c: /* Cursor X Low Register (RS value = 1100) */ ramdac->hwc_x = (ramdac->hwc_x & 0x0f00) | val; - svga->dac_hwcursor.x = ramdac->hwc_x - svga->dac_hwcursor.xsize; + svga->dac_hwcursor.x = ramdac->hwc_x - svga->dac_hwcursor.cur_xsize; break; case 0x0d: /* Cursor X High Register (RS value = 1101) */ ramdac->hwc_x = (ramdac->hwc_x & 0x00ff) | ((val & 0x0f) << 8); - svga->dac_hwcursor.x = ramdac->hwc_x - svga->dac_hwcursor.xsize; + svga->dac_hwcursor.x = ramdac->hwc_x - svga->dac_hwcursor.cur_xsize; break; case 0x0e: /* Cursor Y Low Register (RS value = 1110) */ ramdac->hwc_y = (ramdac->hwc_y & 0x0f00) | val; - svga->dac_hwcursor.y = ramdac->hwc_y - svga->dac_hwcursor.ysize; + svga->dac_hwcursor.y = ramdac->hwc_y - svga->dac_hwcursor.cur_ysize; break; case 0x0f: /* Cursor Y High Register (RS value = 1111) */ ramdac->hwc_y = (ramdac->hwc_y & 0x00ff) | ((val & 0x0f) << 8); - svga->dac_hwcursor.y = ramdac->hwc_y - svga->dac_hwcursor.ysize; + svga->dac_hwcursor.y = ramdac->hwc_y - svga->dac_hwcursor.cur_ysize; break; } @@ -318,7 +318,7 @@ bt48x_ramdac_in(uint16_t addr, int rs2, int rs3, void *p, svga_t *svga) break; case 0x0b: /* Cursor RAM Data Register (RS value = 1011) */ index = (svga->dac_addr - 1) & da_mask; - if ((ramdac->type >= BT485) && (svga->dac_hwcursor.xsize == 64)) + if ((ramdac->type >= BT485) && (svga->dac_hwcursor.cur_xsize == 64)) cd = (uint8_t *) ramdac->cursor64_data; else { index &= 0xff; @@ -376,21 +376,21 @@ bt48x_hwcursor_draw(svga_t *svga, int displine) /* The planes come in two parts, and each plane is 1bpp, so a 32x32 cursor has 4 bytes per line, and a 64x64 cursor has 8 bytes per line. */ - pitch = (svga->dac_hwcursor_latch.xsize >> 3); /* Bytes per line. */ + pitch = (svga->dac_hwcursor_latch.cur_xsize >> 3); /* Bytes per line. */ /* A 32x32 cursor has 128 bytes per line, and a 64x64 cursor has 512 bytes per line. */ - bppl = (pitch * svga->dac_hwcursor_latch.ysize); /* Bytes per plane. */ + bppl = (pitch * svga->dac_hwcursor_latch.cur_ysize); /* Bytes per plane. */ mode = ramdac->cmd_r2 & 0x03; if (svga->interlace && svga->dac_hwcursor_oddeven) svga->dac_hwcursor_latch.addr += pitch; - if (svga->dac_hwcursor_latch.xsize == 64) + if (svga->dac_hwcursor_latch.cur_xsize == 64) cd = (uint8_t *) ramdac->cursor64_data; else cd = (uint8_t *) ramdac->cursor32_data; - for (x = 0; x < svga->dac_hwcursor_latch.xsize; x += 16) { + for (x = 0; x < svga->dac_hwcursor_latch.cur_xsize; x += 16) { dat[0] = (cd[svga->dac_hwcursor_latch.addr] << 8) | cd[svga->dac_hwcursor_latch.addr + 1]; dat[1] = (cd[svga->dac_hwcursor_latch.addr + bppl] << 8) | diff --git a/src/video/vid_cga.c b/src/video/vid_cga.c index 9369f1451..d7827732d 100644 --- a/src/video/vid_cga.c +++ b/src/video/vid_cga.c @@ -70,7 +70,7 @@ cga_out(uint16_t addr, uint8_t val, void *p) cga->crtc[cga->crtcreg] = val & crtcmask[cga->crtcreg]; if (old != val) { if ((cga->crtcreg < 0xe) || (cga->crtcreg > 0x10)) { - fullchange = changeframecount; + cga->fullchange = changeframecount; cga_recalctimings(cga); } } diff --git a/src/video/vid_cl54xx.c b/src/video/vid_cl54xx.c index 8c8474f97..b4a7057f0 100644 --- a/src/video/vid_cl54xx.c +++ b/src/video/vid_cl54xx.c @@ -596,7 +596,7 @@ gd54xx_update_overlay(gd54xx_t *gd54xx) svga_t *svga = &gd54xx->svga; int bpp = svga->bpp; - svga->overlay.ysize = gd54xx->overlay.wve - gd54xx->overlay.wvs + 1; + svga->overlay.cur_ysize = gd54xx->overlay.wve - gd54xx->overlay.wvs + 1; gd54xx->overlay.region1size = 32 * gd54xx->overlay.r1sz / bpp + (gd54xx->overlay.r1adjust * 8 / bpp); gd54xx->overlay.region2size = 32 * gd54xx->overlay.r2sz / bpp + (gd54xx->overlay.r2adjust * 8 / bpp); @@ -741,10 +741,10 @@ gd54xx_out(uint16_t addr, uint8_t val, void *p) svga_recalctimings(svga); svga->hwcursor.ena = val & CIRRUS_CURSOR_SHOW; if (svga->crtc[0x27] >= CIRRUS_ID_CLGD5422) - svga->hwcursor.xsize = svga->hwcursor.ysize = + svga->hwcursor.cur_xsize = svga->hwcursor.cur_ysize = ((val & CIRRUS_CURSOR_LARGE) && (svga->crtc[0x27] >= CIRRUS_ID_CLGD5422)) ? 64 : 32; else - svga->hwcursor.xsize = 32; + svga->hwcursor.cur_xsize = 32; if ((svga->seqregs[0x12] & CIRRUS_CURSOR_LARGE) && (svga->crtc[0x27] >= CIRRUS_ID_CLGD5422)) svga->hwcursor.addr = ((gd54xx->vram_size - 0x4000) + ((svga->seqregs[0x13] & 0x3c) * 256)); @@ -1837,7 +1837,7 @@ void gd54xx_hwcursor_draw(svga_t *svga, int displine) int x, xx, comb, b0, b1; uint8_t dat[2]; int offset = svga->hwcursor_latch.x - svga->hwcursor_latch.xoff; - int pitch = (svga->hwcursor.xsize == 64) ? 16 : 4; + int pitch = (svga->hwcursor.cur_xsize == 64) ? 16 : 4; uint32_t bgcol = gd54xx->extpallook[0x00]; uint32_t fgcol = gd54xx->extpallook[0x0f]; uint8_t linedbl = svga->dispend * 9 / 10 >= svga->hdisp; @@ -1847,9 +1847,9 @@ void gd54xx_hwcursor_draw(svga_t *svga, int displine) if (svga->interlace && svga->hwcursor_oddeven) svga->hwcursor_latch.addr += pitch; - for (x = 0; x < svga->hwcursor.xsize; x += 8) { + for (x = 0; x < svga->hwcursor.cur_xsize; x += 8) { dat[0] = svga->vram[svga->hwcursor_latch.addr & svga->vram_display_mask]; - if (svga->hwcursor.xsize == 64) + if (svga->hwcursor.cur_xsize == 64) dat[1] = svga->vram[(svga->hwcursor_latch.addr + 0x08) & svga->vram_display_mask]; else dat[1] = svga->vram[(svga->hwcursor_latch.addr + 0x80) & svga->vram_display_mask]; @@ -1883,7 +1883,7 @@ void gd54xx_hwcursor_draw(svga_t *svga, int displine) svga->hwcursor_latch.addr++; } - if (svga->hwcursor.xsize == 64) + if (svga->hwcursor.cur_xsize == 64) svga->hwcursor_latch.addr += 8; if (svga->interlace && !svga->hwcursor_oddeven) diff --git a/src/video/vid_ega.c b/src/video/vid_ega.c index 81cc34c30..a8f23b7b8 100644 --- a/src/video/vid_ega.c +++ b/src/video/vid_ega.c @@ -111,7 +111,7 @@ ega_out(uint16_t addr, uint8_t val, void *p) if (!ega->attrff) { ega->attraddr = val & 31; if ((val & 0x20) != ega->attr_palette_enable) { - fullchange = 3; + ega->fullchange = 3; ega->attr_palette_enable = val & 0x20; ega_recalctimings(ega); } @@ -119,13 +119,13 @@ ega_out(uint16_t addr, uint8_t val, void *p) o = ega->attrregs[ega->attraddr & 31]; ega->attrregs[ega->attraddr & 31] = val; if (ega->attraddr < 16) - fullchange = changeframecount; + ega->fullchange = changeframecount; if (ega->attraddr == 0x10 || ega->attraddr == 0x14 || ega->attraddr < 0x10) { for (c = 0; c < 16; c++) { if (ega->attrregs[0x10] & 0x80) ega->egapal[c] = (ega->attrregs[c] & 0xf) | ((ega->attrregs[0x14] & 0xf) << 4); else ega->egapal[c] = (ega->attrregs[c] & 0x3f) | ((ega->attrregs[0x14] & 0xc) << 4); } - fullchange = changeframecount; + ega->fullchange = changeframecount; } /* Recalculate timings on change of attribute register 0x11 (overscan border color) too. */ @@ -166,7 +166,7 @@ ega_out(uint16_t addr, uint8_t val, void *p) switch (ega->seqaddr & 0xf) { case 1: if (ega->scrblank && !(val & 0x20)) - fullchange = 3; + ega->fullchange = 3; ega->scrblank = (ega->scrblank & ~0x20) | (val & 0x20); break; case 2: @@ -232,10 +232,10 @@ ega_out(uint16_t addr, uint8_t val, void *p) if (old != val) { if (ega->crtcreg < 0xe || ega->crtcreg > 0x10) { if ((ega->crtcreg == 0xc) || (ega->crtcreg == 0xd)) { - fullchange = 3; + ega->fullchange = 3; ega->ma_latch = ((ega->crtc[0xc] << 8) | ega->crtc[0xd]) + ((ega->crtc[8] & 0x60) >> 5); } else { - fullchange = changeframecount; + ega->fullchange = changeframecount; ega_recalctimings(ega); } } @@ -588,11 +588,11 @@ ega_poll(void *p) ega->cursoron = ega->blink & (16 + (16 * blink_delay)); if (!(ega->gdcreg[6] & 1) && !(ega->blink & 15)) - fullchange = 2; + ega->fullchange = 2; ega->blink = (ega->blink + 1) & 0x7f; - if (fullchange) - fullchange--; + if (ega->fullchange) + ega->fullchange--; } if (ega->vc == ega->vsyncstart) { ega->dispon = 0; @@ -773,7 +773,7 @@ ega_write(uint32_t addr, uint8_t val, void *p) return; if (!(ega->gdcreg[6] & 1)) - fullchange = 2; + ega->fullchange = 2; switch (ega->writemode) { case 1: diff --git a/src/video/vid_ega_render.c b/src/video/vid_ega_render.c index c3ceafc6f..b925ab944 100644 --- a/src/video/vid_ega_render.c +++ b/src/video/vid_ega_render.c @@ -123,7 +123,7 @@ ega_render_text_40(ega_t *ega) ega->firstline_draw = ega->displine; ega->lastline_draw = ega->displine; - if (fullchange) { + if (ega->fullchange) { p = &buffer32->line[ega->displine + ega->y_add][ega->x_add]; xinc = (ega->seqregs[1] & 1) ? 16 : 18; @@ -195,7 +195,7 @@ ega_render_text_80(ega_t *ega) ega->firstline_draw = ega->displine; ega->lastline_draw = ega->displine; - if (fullchange) { + if (ega->fullchange) { p = &buffer32->line[ega->displine + ega->y_add][ega->x_add]; xinc = (ega->seqregs[1] & 1) ? 8 : 9; diff --git a/src/video/vid_et4000w32.c b/src/video/vid_et4000w32.c index 80c48b15f..5a897fcc1 100644 --- a/src/video/vid_et4000w32.c +++ b/src/video/vid_et4000w32.c @@ -269,7 +269,7 @@ et4000w32p_out(uint16_t addr, uint8_t val, void *p) case 0x210b: case 0x211b: case 0x212b: case 0x213b: case 0x214b: case 0x215b: case 0x216b: case 0x217b: et4000->regs[et4000->index] = val; - svga->hwcursor.xsize = svga->hwcursor.ysize = ((et4000->regs[0xEF] & 4) || (et4000->type == ET4000W32)) ? 128 : 64; + svga->hwcursor.cur_xsize = svga->hwcursor.cur_ysize = ((et4000->regs[0xEF] & 4) || (et4000->type == ET4000W32)) ? 128 : 64; svga->hwcursor.x = et4000->regs[0xE0] | ((et4000->regs[0xE1] & 7) << 8); svga->hwcursor.y = et4000->regs[0xE4] | ((et4000->regs[0xE5] & 7) << 8); svga->hwcursor.ena = !!(et4000->regs[0xF7] & 0x80); @@ -284,7 +284,7 @@ et4000w32p_out(uint16_t addr, uint8_t val, void *p) } } - if (svga->hwcursor.xsize == 128) { + if (svga->hwcursor.cur_xsize == 128) { svga->hwcursor.xoff &= 0x7f; svga->hwcursor.yoff &= 0x7f; if (et4000->type > ET4000W32P_REVC) { @@ -303,7 +303,7 @@ et4000w32p_out(uint16_t addr, uint8_t val, void *p) } svga->hwcursor.addr = (et4000->regs[0xe8] | (et4000->regs[0xe9] << 8) | ((et4000->regs[0xea] & 7) << 16)) << 2; - add2addr = svga->hwcursor.yoff * ((svga->hwcursor.xsize == 128) ? 32 : 16); + add2addr = svga->hwcursor.yoff * ((svga->hwcursor.cur_xsize == 128) ? 32 : 16); svga->hwcursor.addr += add2addr; return; } @@ -1764,8 +1764,8 @@ et4000w32p_hwcursor_draw(svga_t *svga, int displine) et4000w32p_t *et4000 = (et4000w32p_t *)svga->p; int x, offset, xx, xx2; int shift = (et4000->adjust_cursor + 1); - int width = (svga->hwcursor_latch.xsize - svga->hwcursor_latch.xoff); - int pitch = (svga->hwcursor_latch.xsize == 128) ? 32 : 16; + int width = (svga->hwcursor_latch.cur_xsize - svga->hwcursor_latch.xoff); + int pitch = (svga->hwcursor_latch.cur_xsize == 128) ? 32 : 16; int x_acc = 4; int minus_width = 0; uint8_t dat; diff --git a/src/video/vid_hercules.c b/src/video/vid_hercules.c index d310fa419..df21c47f3 100644 --- a/src/video/vid_hercules.c +++ b/src/video/vid_hercules.c @@ -92,7 +92,7 @@ hercules_out(uint16_t addr, uint8_t val, void *priv) if (old != val) { if ((dev->crtcreg < 0xe) || (dev->crtcreg > 0x10)) { - fullchange = changeframecount; + dev->fullchange = changeframecount; recalc_timings(dev); } } diff --git a/src/video/vid_ht216.c b/src/video/vid_ht216.c index a9b54c1f0..8ef6fc9e0 100644 --- a/src/video/vid_ht216.c +++ b/src/video/vid_ht216.c @@ -1479,7 +1479,7 @@ void break; } - svga->hwcursor.ysize = 32; + svga->hwcursor.cur_ysize = 32; ht216->vram_mask = mem_size - 1; svga->decode_mask = mem_size - 1; diff --git a/src/video/vid_ibm_rgb528_ramdac.c b/src/video/vid_ibm_rgb528_ramdac.c index 98a42b16e..d70732553 100644 --- a/src/video/vid_ibm_rgb528_ramdac.c +++ b/src/video/vid_ibm_rgb528_ramdac.c @@ -636,7 +636,7 @@ ibm_rgb528_ramdac_out(uint16_t addr, int rs2, uint8_t val, void *p, svga_t *svga break; } svga->dac_hwcursor.addr = ramdac->smlc_part; - svga->dac_hwcursor.xsize = svga->dac_hwcursor.ysize = (val & 0x04) ? 64 : 32; + svga->dac_hwcursor.cur_xsize = svga->dac_hwcursor.cur_ysize = (val & 0x04) ? 64 : 32; svga->dac_hwcursor.ena = ((val & 0x03) != 0x00); break; case 0x031: @@ -681,14 +681,14 @@ ibm_rgb528_ramdac_out(uint16_t addr, int rs2, uint8_t val, void *p, svga_t *svga } break; case 0x035: - if (svga->dac_hwcursor.xsize == 64) + if (svga->dac_hwcursor.cur_xsize == 64) ramdac->cursor_hotspot_x = (val & 0x3f); else ramdac->cursor_hotspot_x = (val & 0x1f); svga->dac_hwcursor.x = ((int) ramdac->hwc_x) - ramdac->cursor_hotspot_x; break; case 0x036: - if (svga->dac_hwcursor.xsize == 64) + if (svga->dac_hwcursor.cur_xsize == 64) ramdac->cursor_hotspot_y = (val & 0x3f); else ramdac->cursor_hotspot_y = (val & 0x1f); @@ -852,7 +852,7 @@ ibm_rgb528_hwcursor_draw(svga_t *svga, int displine) /* The planes come in one part, and each plane is 2bpp, so a 32x32 cursor has 8 bytes per line, and a 64x64 cursor has 16 bytes per line. */ - pitch = (svga->dac_hwcursor_latch.xsize >> 2); /* Bytes per line. */ + pitch = (svga->dac_hwcursor_latch.cur_xsize >> 2); /* Bytes per line. */ if ((ramdac->indexed_data[0x071] & 0x20) && svga->dac_hwcursor_oddeven) svga->dac_hwcursor_latch.addr += pitch; @@ -861,7 +861,7 @@ ibm_rgb528_hwcursor_draw(svga_t *svga, int displine) x_pos = offset + svga->x_add; p = buffer32->line[y_pos]; - for (x = 0; x < svga->dac_hwcursor_latch.xsize; x++) { + for (x = 0; x < svga->dac_hwcursor_latch.cur_xsize; x++) { if (!(x & 3)) four_pixels = ramdac->indexed_data[svga->dac_hwcursor_latch.addr]; diff --git a/src/video/vid_s3.c b/src/video/vid_s3.c index cb968f005..5f849bfbe 100644 --- a/src/video/vid_s3.c +++ b/src/video/vid_s3.c @@ -3250,7 +3250,7 @@ static void s3_trio64v_recalctimings(svga_t *svga) svga->overlay.x = s3->streams.sec_x - s3->streams.pri_x; svga->overlay.y = s3->streams.sec_y - s3->streams.pri_y; - svga->overlay.ysize = s3->streams.sec_h; + svga->overlay.cur_ysize = s3->streams.sec_h; if (s3->streams.buffer_ctrl & 2) svga->overlay.addr = s3->streams.sec_fb1; @@ -7069,7 +7069,7 @@ static void *s3_init(const device_t *info) } } - svga->hwcursor.ysize = 64; + svga->hwcursor.cur_ysize = 64; if (chip == S3_VISION964 && info->local != S3_ELSAWIN2KPROX_964) svga->dac_hwcursor_draw = bt48x_hwcursor_draw; diff --git a/src/video/vid_s3_virge.c b/src/video/vid_s3_virge.c index 662e55379..475269f93 100644 --- a/src/video/vid_s3_virge.c +++ b/src/video/vid_s3_virge.c @@ -830,7 +830,7 @@ static void s3_virge_recalctimings(svga_t *svga) svga->overlay.x = virge->streams.sec_x - virge->streams.pri_x; svga->overlay.y = virge->streams.sec_y - virge->streams.pri_y; - svga->overlay.ysize = virge->streams.sec_h; + svga->overlay.cur_ysize = virge->streams.sec_h; if (virge->streams.buffer_ctrl & 2) svga->overlay.addr = virge->streams.sec_fb1; @@ -3958,7 +3958,7 @@ static void *s3_virge_init(const device_t *info) s3_virge_in, s3_virge_out, s3_virge_hwcursor_draw, s3_virge_overlay_draw); - virge->svga.hwcursor.ysize = 64; + virge->svga.hwcursor.cur_ysize = 64; if (info->local == S3_VIRGE_GX2) rom_init(&virge->bios_rom, (char *) bios_fn, 0xc0000, 0x10000, 0xffff, 0, MEM_MAPPING_EXTERNAL); diff --git a/src/video/vid_sigma.c b/src/video/vid_sigma.c index a6372ad00..9c5474de9 100644 --- a/src/video/vid_sigma.c +++ b/src/video/vid_sigma.c @@ -179,6 +179,7 @@ typedef struct sigma_t int plane; int revision; + int fullchange; } sigma_t; #define COMPOSITE_OLD 0 @@ -228,7 +229,7 @@ sigma_out(uint16_t addr, uint8_t val, void *p) sigma->crtc[sigma->crtcreg] = val & crtcmask[sigma->crtcreg]; if (old != val) { if (sigma->crtcreg < 0xe || sigma->crtcreg > 0x10) { - fullchange = changeframecount; + sigma->fullchange = changeframecount; sigma_recalctimings(sigma); } } diff --git a/src/video/vid_svga.c b/src/video/vid_svga.c index a102d71f0..44cd14320 100644 --- a/src/video/vid_svga.c +++ b/src/video/vid_svga.c @@ -669,34 +669,34 @@ svga_poll(void *p) if (!svga->linepos) { if (svga->displine == svga->hwcursor_latch.y && svga->hwcursor_latch.ena) { - svga->hwcursor_on = svga->hwcursor.ysize - svga->hwcursor_latch.yoff; + svga->hwcursor_on = svga->hwcursor.cur_ysize - svga->hwcursor_latch.yoff; svga->hwcursor_oddeven = 0; } if (svga->displine == (svga->hwcursor_latch.y + 1) && svga->hwcursor_latch.ena && svga->interlace) { - svga->hwcursor_on = svga->hwcursor.ysize - (svga->hwcursor_latch.yoff + 1); + svga->hwcursor_on = svga->hwcursor.cur_ysize - (svga->hwcursor_latch.yoff + 1); svga->hwcursor_oddeven = 1; } if (svga->displine == svga->dac_hwcursor_latch.y && svga->dac_hwcursor_latch.ena) { - svga->dac_hwcursor_on = svga->dac_hwcursor.ysize - svga->dac_hwcursor_latch.yoff; + svga->dac_hwcursor_on = svga->dac_hwcursor.cur_ysize - svga->dac_hwcursor_latch.yoff; svga->dac_hwcursor_oddeven = 0; } if (svga->displine == (svga->dac_hwcursor_latch.y + 1) && svga->dac_hwcursor_latch.ena && svga->interlace) { - svga->dac_hwcursor_on = svga->dac_hwcursor.ysize - (svga->dac_hwcursor_latch.yoff + 1); + svga->dac_hwcursor_on = svga->dac_hwcursor.cur_ysize - (svga->dac_hwcursor_latch.yoff + 1); svga->dac_hwcursor_oddeven = 1; } if (svga->displine == svga->overlay_latch.y && svga->overlay_latch.ena) { - svga->overlay_on = svga->overlay_latch.ysize - svga->overlay_latch.yoff; + svga->overlay_on = svga->overlay_latch.cur_ysize - svga->overlay_latch.yoff; svga->overlay_oddeven = 0; } if (svga->displine == svga->overlay_latch.y+1 && svga->overlay_latch.ena && svga->interlace) { - svga->overlay_on = svga->overlay_latch.ysize - svga->overlay_latch.yoff; + svga->overlay_on = svga->overlay_latch.cur_ysize - svga->overlay_latch.yoff; svga->overlay_oddeven = 1; } @@ -966,9 +966,9 @@ svga_init(const device_t *info, svga_t *svga, void *p, int memsize, svga->hwcursor_draw = hwcursor_draw; svga->overlay_draw = overlay_draw; - svga->hwcursor.xsize = svga->hwcursor.ysize = 32; + svga->hwcursor.cur_xsize = svga->hwcursor.cur_ysize = 32; - svga->dac_hwcursor.xsize = svga->dac_hwcursor.ysize = 32; + svga->dac_hwcursor.cur_xsize = svga->dac_hwcursor.cur_ysize = 32; svga->translate_address = NULL; svga->ksc5601_english_font_type = 0; diff --git a/src/video/vid_tgui9440.c b/src/video/vid_tgui9440.c index 9cf7e1ff7..603acccb9 100644 --- a/src/video/vid_tgui9440.c +++ b/src/video/vid_tgui9440.c @@ -503,7 +503,7 @@ tgui_out(uint16_t addr, uint8_t val, void *p) case 0x50: if (tgui->type >= TGUI_9440) { svga->hwcursor.ena = !!(val & 0x80); - svga->hwcursor.xsize = svga->hwcursor.ysize = ((val & 1) ? 64 : 32); + svga->hwcursor.cur_xsize = svga->hwcursor.cur_ysize = ((val & 1) ? 64 : 32); } break; } @@ -887,7 +887,7 @@ tgui_hwcursor_draw(svga_t *svga, int displine) uint32_t dat[2]; int xx; int offset = svga->hwcursor_latch.x + svga->hwcursor_latch.xoff; - int pitch = (svga->hwcursor_latch.xsize == 64) ? 16 : 8; + int pitch = (svga->hwcursor_latch.cur_xsize == 64) ? 16 : 8; if (svga->interlace && svga->hwcursor_oddeven) svga->hwcursor_latch.addr += pitch; diff --git a/src/video/vid_tvp3026_ramdac.c b/src/video/vid_tvp3026_ramdac.c index 6218998e5..580e96990 100644 --- a/src/video/vid_tvp3026_ramdac.c +++ b/src/video/vid_tvp3026_ramdac.c @@ -154,9 +154,9 @@ tvp3026_ramdac_out(uint16_t addr, int rs2, int rs3, uint8_t val, void *p, svga_t case 0x09: /* Direct Cursor Control (RS value = 1001) */ ramdac->dcc = val; if (ramdac->ccr & 0x80) { - svga->dac_hwcursor.xsize = svga->dac_hwcursor.ysize = 64; - svga->dac_hwcursor.x = ramdac->hwc_x - svga->dac_hwcursor.xsize; - svga->dac_hwcursor.y = ramdac->hwc_y - svga->dac_hwcursor.ysize; + svga->dac_hwcursor.cur_xsize = svga->dac_hwcursor.cur_ysize = 64; + svga->dac_hwcursor.x = ramdac->hwc_x - svga->dac_hwcursor.cur_xsize; + svga->dac_hwcursor.y = ramdac->hwc_y - svga->dac_hwcursor.cur_ysize; svga->dac_hwcursor.ena = !!(val & 0x03); ramdac->mode = val & 0x03; } @@ -165,9 +165,9 @@ tvp3026_ramdac_out(uint16_t addr, int rs2, int rs3, uint8_t val, void *p, svga_t switch (ramdac->ind_idx) { case 0x06: /* Indirect Cursor Control */ ramdac->ccr = val; - svga->dac_hwcursor.xsize = svga->dac_hwcursor.ysize = 64; - svga->dac_hwcursor.x = ramdac->hwc_x - svga->dac_hwcursor.xsize; - svga->dac_hwcursor.y = ramdac->hwc_y - svga->dac_hwcursor.ysize; + svga->dac_hwcursor.cur_xsize = svga->dac_hwcursor.cur_ysize = 64; + svga->dac_hwcursor.x = ramdac->hwc_x - svga->dac_hwcursor.cur_xsize; + svga->dac_hwcursor.y = ramdac->hwc_y - svga->dac_hwcursor.cur_ysize; svga->dac_hwcursor.ena = !!(val & 0x03); ramdac->mode = val & 0x03; break; @@ -254,19 +254,19 @@ tvp3026_ramdac_out(uint16_t addr, int rs2, int rs3, uint8_t val, void *p, svga_t break; case 0x0c: /* Cursor X Low Register (RS value = 1100) */ ramdac->hwc_x = (ramdac->hwc_x & 0x0f00) | val; - svga->dac_hwcursor.x = ramdac->hwc_x - svga->dac_hwcursor.xsize; + svga->dac_hwcursor.x = ramdac->hwc_x - svga->dac_hwcursor.cur_xsize; break; case 0x0d: /* Cursor X High Register (RS value = 1101) */ ramdac->hwc_x = (ramdac->hwc_x & 0x00ff) | ((val & 0x0f) << 8); - svga->dac_hwcursor.x = ramdac->hwc_x - svga->dac_hwcursor.xsize; + svga->dac_hwcursor.x = ramdac->hwc_x - svga->dac_hwcursor.cur_xsize; break; case 0x0e: /* Cursor Y Low Register (RS value = 1110) */ ramdac->hwc_y = (ramdac->hwc_y & 0x0f00) | val; - svga->dac_hwcursor.y = ramdac->hwc_y - svga->dac_hwcursor.ysize; + svga->dac_hwcursor.y = ramdac->hwc_y - svga->dac_hwcursor.cur_ysize; break; case 0x0f: /* Cursor Y High Register (RS value = 1111) */ ramdac->hwc_y = (ramdac->hwc_y & 0x00ff) | ((val & 0x0f) << 8); - svga->dac_hwcursor.y = ramdac->hwc_y - svga->dac_hwcursor.ysize; + svga->dac_hwcursor.y = ramdac->hwc_y - svga->dac_hwcursor.cur_ysize; break; } @@ -464,10 +464,10 @@ tvp3026_hwcursor_draw(svga_t *svga, int displine) /* The planes come in two parts, and each plane is 1bpp, so a 32x32 cursor has 4 bytes per line, and a 64x64 cursor has 8 bytes per line. */ - pitch = (svga->dac_hwcursor_latch.xsize >> 3); /* Bytes per line. */ + pitch = (svga->dac_hwcursor_latch.cur_xsize >> 3); /* Bytes per line. */ /* A 32x32 cursor has 128 bytes per line, and a 64x64 cursor has 512 bytes per line. */ - bppl = (pitch * svga->dac_hwcursor_latch.ysize); /* Bytes per plane. */ + bppl = (pitch * svga->dac_hwcursor_latch.cur_ysize); /* Bytes per plane. */ mode = ramdac->mode; if (svga->interlace && svga->dac_hwcursor_oddeven) @@ -475,7 +475,7 @@ tvp3026_hwcursor_draw(svga_t *svga, int displine) cd = (uint8_t *) ramdac->cursor64_data; - for (x = 0; x < svga->dac_hwcursor_latch.xsize; x += 16) { + for (x = 0; x < svga->dac_hwcursor_latch.cur_xsize; x += 16) { dat[0] = (cd[svga->dac_hwcursor_latch.addr] << 8) | cd[svga->dac_hwcursor_latch.addr + 1]; dat[1] = (cd[svga->dac_hwcursor_latch.addr + bppl] << 8) | diff --git a/src/video/vid_voodoo_banshee.c b/src/video/vid_voodoo_banshee.c index 020cb65a4..42b06eb4b 100644 --- a/src/video/vid_voodoo_banshee.c +++ b/src/video/vid_voodoo_banshee.c @@ -547,12 +547,12 @@ static void banshee_recalctimings(svga_t *svga) svga->overlay.x = voodoo->overlay.start_x; svga->overlay.y = voodoo->overlay.start_y; - svga->overlay.xsize = voodoo->overlay.size_x; - svga->overlay.ysize = voodoo->overlay.size_y; + svga->overlay.cur_xsize = voodoo->overlay.size_x; + svga->overlay.cur_ysize = voodoo->overlay.size_y; svga->overlay.pitch = (banshee->vidDesktopOverlayStride & VID_STRIDE_OVERLAY_MASK) >> VID_STRIDE_OVERLAY_SHIFT; if (banshee->vidProcCfg & VIDPROCCFG_OVERLAY_TILE) svga->overlay.pitch *= 128*32; - if (svga->overlay.xsize <= 0 || svga->overlay.ysize <= 0) + if (svga->overlay.cur_xsize <= 0 || svga->overlay.cur_ysize <= 0) svga->overlay.ena = 0; if (svga->overlay.ena) { @@ -739,8 +739,8 @@ static void banshee_ext_outl(uint16_t addr, uint32_t val, void *p) else svga->hwcursor.yoff = 0; svga->hwcursor.addr = (banshee->hwCurPatAddr & 0xfffff0) + (svga->hwcursor.yoff * 16); - svga->hwcursor.xsize = 64; - svga->hwcursor.ysize = 64; + svga->hwcursor.cur_xsize = 64; + svga->hwcursor.cur_ysize = 64; // banshee_log("hwCurLoc %08x %i\n", val, svga->hwcursor.y); break; case Video_hwCurC0: @@ -2103,7 +2103,7 @@ static void banshee_overlay_draw(svga_t *svga, int displine) OVERLAY_SAMPLE(banshee->overlay_buffer[1]); if (banshee->vidProcCfg & VIDPROCCFG_H_SCALE_ENABLE) { - for (x = 0; x < svga->overlay_latch.xsize; x++) + for (x = 0; x < svga->overlay_latch.cur_xsize; x++) { unsigned int x_coeff = (src_x & 0xfffff) >> 4; unsigned int coeffs[4] = { @@ -2135,7 +2135,7 @@ static void banshee_overlay_draw(svga_t *svga, int displine) } else { - for (x = 0; x < svga->overlay_latch.xsize; x++) + for (x = 0; x < svga->overlay_latch.cur_xsize; x++) { uint32_t samp0 = banshee->overlay_buffer[0][src_x >> 20]; uint32_t samp1 = banshee->overlay_buffer[1][src_x >> 20]; @@ -2153,12 +2153,12 @@ static void banshee_overlay_draw(svga_t *svga, int displine) case VIDPROCCFG_FILTER_MODE_DITHER_4X4: if (banshee->voodoo->scrfilter && banshee->voodoo->scrfilterEnabled) { - uint8_t *fil = malloc((svga->overlay_latch.xsize) * 3); - uint8_t *fil3 = malloc((svga->overlay_latch.xsize) * 3); + uint8_t *fil = malloc((svga->overlay_latch.cur_xsize) * 3); + uint8_t *fil3 = malloc((svga->overlay_latch.cur_xsize) * 3); if (banshee->vidProcCfg & VIDPROCCFG_H_SCALE_ENABLE) /* leilei HACK - don't know of real 4x1 hscaled behavior yet, double for now */ { - for (x=0; xoverlay_latch.xsize;x++) + for (x=0; xoverlay_latch.cur_xsize;x++) { fil[x*3] = ((banshee->overlay_buffer[0][src_x >> 20])); fil[x*3+1] = ((banshee->overlay_buffer[0][src_x >> 20] >> 8)); @@ -2171,7 +2171,7 @@ static void banshee_overlay_draw(svga_t *svga, int displine) } else { - for (x=0; xoverlay_latch.xsize;x++) + for (x=0; xoverlay_latch.cur_xsize;x++) { fil[x*3] = ((banshee->overlay_buffer[0][x])); fil[x*3+1] = ((banshee->overlay_buffer[0][x] >> 8)); @@ -2183,7 +2183,7 @@ static void banshee_overlay_draw(svga_t *svga, int displine) } if (y % 2 == 0) { - for (x=0; xoverlay_latch.xsize;x++) + for (x=0; xoverlay_latch.cur_xsize;x++) { fil[x*3] = banshee->voodoo->purpleline[fil[x*3+0]][0]; fil[x*3+1] = banshee->voodoo->purpleline[fil[x*3+1]][1]; @@ -2191,25 +2191,25 @@ static void banshee_overlay_draw(svga_t *svga, int displine) } } - for (x=1; xoverlay_latch.xsize;x++) + for (x=1; xoverlay_latch.cur_xsize;x++) { fil3[(x)*3] = vb_filter_v1_rb [fil[x*3]] [fil[(x-1) *3]]; fil3[(x)*3+1] = vb_filter_v1_g [fil[x*3+1]][fil[(x-1) *3+1]]; fil3[(x)*3+2] = vb_filter_v1_rb [fil[x*3+2]] [fil[(x-1) *3+2]]; } - for (x=1; xoverlay_latch.xsize;x++) + for (x=1; xoverlay_latch.cur_xsize;x++) { fil[(x)*3] = vb_filter_v1_rb [fil[x*3]] [fil3[(x-1) *3]]; fil[(x)*3+1] = vb_filter_v1_g [fil[x*3+1]][fil3[(x-1) *3+1]]; fil[(x)*3+2] = vb_filter_v1_rb [fil[x*3+2]] [fil3[(x-1) *3+2]]; } - for (x=1; xoverlay_latch.xsize;x++) + for (x=1; xoverlay_latch.cur_xsize;x++) { fil3[(x)*3] = vb_filter_v1_rb [fil[x*3]] [fil[(x-1) *3]]; fil3[(x)*3+1] = vb_filter_v1_g [fil[x*3+1]][fil[(x-1) *3+1]]; fil3[(x)*3+2] = vb_filter_v1_rb [fil[x*3+2]] [fil[(x-1) *3+2]]; } - for (x=0; xoverlay_latch.xsize;x++) + for (x=0; xoverlay_latch.cur_xsize;x++) { fil[(x)*3] = vb_filter_v1_rb [fil[x*3]] [fil3[(x+1) *3]]; fil[(x)*3+1] = vb_filter_v1_g [fil[x*3+1]][fil3[(x+1) *3+1]]; @@ -2224,7 +2224,7 @@ static void banshee_overlay_draw(svga_t *svga, int displine) { if (banshee->vidProcCfg & VIDPROCCFG_H_SCALE_ENABLE) { - for (x = 0; x < svga->overlay_latch.xsize; x++) + for (x = 0; x < svga->overlay_latch.cur_xsize; x++) { p[x] = banshee->overlay_buffer[0][src_x >> 20]; src_x += voodoo->overlay.vidOverlayDudx; @@ -2232,7 +2232,7 @@ static void banshee_overlay_draw(svga_t *svga, int displine) } else { - for (x = 0; x < svga->overlay_latch.xsize; x++) + for (x = 0; x < svga->overlay_latch.cur_xsize; x++) p[x] = banshee->overlay_buffer[0][x]; } } @@ -2241,18 +2241,18 @@ static void banshee_overlay_draw(svga_t *svga, int displine) case VIDPROCCFG_FILTER_MODE_DITHER_2X2: if (banshee->voodoo->scrfilter && banshee->voodoo->scrfilterEnabled) { - uint8_t *fil = malloc((svga->overlay_latch.xsize) * 3); - uint8_t *soak = malloc((svga->overlay_latch.xsize) * 3); - uint8_t *soak2 = malloc((svga->overlay_latch.xsize) * 3); + uint8_t *fil = malloc((svga->overlay_latch.cur_xsize) * 3); + uint8_t *soak = malloc((svga->overlay_latch.cur_xsize) * 3); + uint8_t *soak2 = malloc((svga->overlay_latch.cur_xsize) * 3); - uint8_t *samp1 = malloc((svga->overlay_latch.xsize) * 3); - uint8_t *samp2 = malloc((svga->overlay_latch.xsize) * 3); - uint8_t *samp3 = malloc((svga->overlay_latch.xsize) * 3); - uint8_t *samp4 = malloc((svga->overlay_latch.xsize) * 3); + uint8_t *samp1 = malloc((svga->overlay_latch.cur_xsize) * 3); + uint8_t *samp2 = malloc((svga->overlay_latch.cur_xsize) * 3); + uint8_t *samp3 = malloc((svga->overlay_latch.cur_xsize) * 3); + uint8_t *samp4 = malloc((svga->overlay_latch.cur_xsize) * 3); src = &svga->vram[src_addr2 & svga->vram_mask]; OVERLAY_SAMPLE(banshee->overlay_buffer[1]); - for (x=0; xoverlay_latch.xsize;x++) + for (x=0; xoverlay_latch.cur_xsize;x++) { samp1[x*3] = ((banshee->overlay_buffer[0][x])); samp1[x*3+1] = ((banshee->overlay_buffer[0][x] >> 8)); @@ -2289,7 +2289,7 @@ static void banshee_overlay_draw(svga_t *svga, int displine) if (banshee->vidProcCfg & VIDPROCCFG_H_SCALE_ENABLE) /* 2x2 on a scaled low res */ { - for (x=0; xoverlay_latch.xsize;x++) + for (x=0; xoverlay_latch.cur_xsize;x++) { p[x] = (fil[(src_x >> 20)*3+2] << 16) | (fil[(src_x >> 20)*3+1] << 8) | fil[(src_x >> 20)*3]; src_x += voodoo->overlay.vidOverlayDudx; @@ -2297,7 +2297,7 @@ static void banshee_overlay_draw(svga_t *svga, int displine) } else { - for (x=0; xoverlay_latch.xsize;x++) + for (x=0; xoverlay_latch.cur_xsize;x++) { p[x] = (fil[x*3+2] << 16) | (fil[x*3+1] << 8) | fil[x*3]; } @@ -2315,7 +2315,7 @@ static void banshee_overlay_draw(svga_t *svga, int displine) { if (banshee->vidProcCfg & VIDPROCCFG_H_SCALE_ENABLE) { - for (x = 0; x < svga->overlay_latch.xsize; x++) + for (x = 0; x < svga->overlay_latch.cur_xsize; x++) { p[x] = banshee->overlay_buffer[0][src_x >> 20]; @@ -2324,7 +2324,7 @@ static void banshee_overlay_draw(svga_t *svga, int displine) } else { - for (x = 0; x < svga->overlay_latch.xsize; x++) + for (x = 0; x < svga->overlay_latch.cur_xsize; x++) p[x] = banshee->overlay_buffer[0][x]; } } @@ -2334,7 +2334,7 @@ static void banshee_overlay_draw(svga_t *svga, int displine) default: if (banshee->vidProcCfg & VIDPROCCFG_H_SCALE_ENABLE) { - for (x = 0; x < svga->overlay_latch.xsize; x++) + for (x = 0; x < svga->overlay_latch.cur_xsize; x++) { p[x] = banshee->overlay_buffer[0][src_x >> 20]; @@ -2343,7 +2343,7 @@ static void banshee_overlay_draw(svga_t *svga, int displine) } else { - for (x = 0; x < svga->overlay_latch.xsize; x++) + for (x = 0; x < svga->overlay_latch.cur_xsize; x++) p[x] = banshee->overlay_buffer[0][x]; } break; diff --git a/src/video/vid_xga.c b/src/video/vid_xga.c index 1dfa2e6ec..cb56b622d 100644 --- a/src/video/vid_xga.c +++ b/src/video/vid_xga.c @@ -2034,7 +2034,7 @@ xga_hwcursor_draw(svga_t *svga, int displine) x_pos = offset + svga->x_add; p = buffer32->line[y_pos]; - for (x = 0; x < xga->hwcursor_latch.xsize; x++) { + for (x = 0; x < xga->hwcursor_latch.cur_xsize; x++) { if (x >= idx) { if (!(x & 0x03)) dat = xga->sprite_data[xga->hwcursor_latch.addr & 0x3ff]; @@ -2491,13 +2491,13 @@ xga_poll(xga_t *xga, svga_t *svga) if (!xga->linepos) { if (xga->displine == xga->hwcursor_latch.y && xga->hwcursor_latch.ena) { - xga->hwcursor_on = xga->hwcursor_latch.ysize - (xga->cursor_data_on ? 32 : 0); + xga->hwcursor_on = xga->hwcursor_latch.cur_ysize - (xga->cursor_data_on ? 32 : 0); xga->hwcursor_oddeven = 0; } if (xga->displine == (xga->hwcursor_latch.y + 1) && xga->hwcursor_latch.ena && xga->interlace) { - xga->hwcursor_on = xga->hwcursor_latch.ysize - (xga->cursor_data_on ? 33 : 1); + xga->hwcursor_on = xga->hwcursor_latch.cur_ysize - (xga->cursor_data_on ? 33 : 1); xga->hwcursor_oddeven = 1; } @@ -2708,8 +2708,8 @@ static void xga->vram = calloc(xga->vram_size, 1); xga->changedvram = calloc(xga->vram_size >> 12, 1); xga->on = 0; - xga->hwcursor.xsize = 64; - xga->hwcursor.ysize = 64; + xga->hwcursor.cur_xsize = 64; + xga->hwcursor.cur_ysize = 64; xga->bios_rom.sz = 0x2000; f = rom_fopen(XGA_BIOS_PATH, "rb"); diff --git a/src/video/video.c b/src/video/video.c index f58b29c84..efedfbb09 100644 --- a/src/video/video.c +++ b/src/video/video.c @@ -75,7 +75,7 @@ #include volatile int screenshots = 0; -bitmap_t *buffer32 = NULL; +//bitmap_t *buffer32 = NULL; uint8_t fontdat[2048][8]; /* IBM CGA font */ uint8_t fontdatm[2048][16]; /* IBM MDA font */ uint8_t fontdatw[512][32]; /* Wyse700 font */ @@ -83,31 +83,15 @@ uint8_t fontdat8x12[256][16]; /* MDSI Genius font */ uint8_t fontdat12x18[256][36]; /* IM1024 font */ dbcs_font_t *fontdatksc5601 = NULL; /* Korean KSC-5601 font */ dbcs_font_t *fontdatksc5601_user = NULL; /* Korean KSC-5601 user defined font */ -uint32_t pal_lookup[256]; -int xsize = 1, - ysize = 1; -int cga_palette = 0, - herc_blend = 0; +int herc_blend = 0; uint32_t *video_6to8 = NULL, *video_8togs = NULL, *video_8to32 = NULL, *video_15to32 = NULL, - *video_16to32 = NULL; -int changeframecount = 2; + *video_16to32 = NULL; int frames = 0; int fullchange = 0; uint8_t edatlookup[4][4]; -int overscan_x = 0, - overscan_y = 0; -int video_timing_read_b = 0, - video_timing_read_w = 0, - video_timing_read_l = 0; -int video_timing_write_b = 0, - video_timing_write_w = 0, - video_timing_write_l = 0; -int video_res_x = 0, - video_res_y = 0, - video_bpp = 0; static int video_force_resize; int video_grayscale = 0; int video_graytype = 0; @@ -115,6 +99,8 @@ static int vid_type; static const video_timings_t *vid_timings; static uint32_t cga_2_table[16]; static uint8_t thread_run = 0; +monitor_t monitors[MONITORS_NUM]; +int monitor_index_global = 0; #ifdef _WIN32 void * __cdecl (*video_copy)(void *_Dst, const void *_Src, size_t _Size) = memcpy; @@ -251,10 +237,12 @@ const uint32_t shade[5][256] = }; -static struct { +static struct blit_data_struct { int x, y, w, h; int busy; int buffer_in_use; + int thread_run; + int monitor_index; thread_t *blit_thread; event_t *wake_blit_thread; @@ -263,7 +251,7 @@ static struct { } blit_data; -static void (*blit_func)(int x, int y, int w, int h); +static void (*blit_func)(int x, int y, int w, int h, int monitor_index); #ifdef ENABLE_VIDEO_LOG @@ -287,7 +275,7 @@ video_log(const char *fmt, ...) void -video_setblit(void(*blit)(int,int,int,int)) +video_setblit(void(*blit)(int,int,int,int,int)) { blit_func = blit; } @@ -296,41 +284,68 @@ video_setblit(void(*blit)(int,int,int,int)) void video_blit_complete(void) { - blit_data.buffer_in_use = 0; - - thread_set_event(blit_data.buffer_not_in_use); + video_blit_complete_monitor(monitor_index_global); } void video_wait_for_blit(void) { - while (blit_data.busy) - thread_wait_event(blit_data.blit_complete, -1); - thread_reset_event(blit_data.blit_complete); + video_wait_for_blit_monitor(monitor_index_global); } void video_wait_for_buffer(void) { - while (blit_data.buffer_in_use) - thread_wait_event(blit_data.buffer_not_in_use, -1); - thread_reset_event(blit_data.buffer_not_in_use); + video_wait_for_buffer_monitor(monitor_index_global); } -static png_structp png_ptr; -static png_infop info_ptr; +void +video_blit_complete_monitor(int monitor_index) +{ + struct blit_data_struct* blit_data_ptr = monitors[monitor_index].mon_blit_data_ptr; + blit_data_ptr->buffer_in_use = 0; + + thread_set_event(blit_data_ptr->buffer_not_in_use); +} + + +void +video_wait_for_blit_monitor(int monitor_index) +{ + struct blit_data_struct* blit_data_ptr = monitors[monitor_index].mon_blit_data_ptr; + + while (blit_data_ptr->busy) + thread_wait_event(blit_data_ptr->blit_complete, -1); + thread_reset_event(blit_data_ptr->blit_complete); +} + + +void +video_wait_for_buffer_monitor(int monitor_index) +{ + struct blit_data_struct* blit_data_ptr = monitors[monitor_index].mon_blit_data_ptr; + + while (blit_data_ptr->buffer_in_use) + thread_wait_event(blit_data_ptr->buffer_not_in_use, -1); + thread_reset_event(blit_data_ptr->buffer_not_in_use); +} + + +static png_structp png_ptr[MONITORS_NUM]; +static png_infop info_ptr[MONITORS_NUM]; static void -video_take_screenshot(const char *fn, uint32_t *buf, int start_x, int start_y, int row_len) +video_take_screenshot_monitor(const char *fn, uint32_t *buf, int start_x, int start_y, int row_len, int monitor_index) { int i, x, y; png_bytep *b_rgb = NULL; FILE *fp = NULL; uint32_t temp = 0x00000000; + struct blit_data_struct* blit_data_ptr = monitors[monitor_index].mon_blit_data_ptr; /* create file */ fp = plat_fopen((char *) fn, (char *) "wb"); @@ -340,37 +355,37 @@ video_take_screenshot(const char *fn, uint32_t *buf, int start_x, int start_y, i } /* initialize stuff */ - png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); + png_ptr[monitor_index] = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); - if (!png_ptr) { + if (!png_ptr[monitor_index]) { video_log("[video_take_screenshot] png_create_write_struct failed"); fclose(fp); return; } - info_ptr = png_create_info_struct(png_ptr); - if (!info_ptr) { + info_ptr[monitor_index] = png_create_info_struct(png_ptr[monitor_index]); + if (!info_ptr[monitor_index]) { video_log("[video_take_screenshot] png_create_info_struct failed"); fclose(fp); return; } - png_init_io(png_ptr, fp); + png_init_io(png_ptr[monitor_index], fp); - png_set_IHDR(png_ptr, info_ptr, blit_data.w, blit_data.h, + png_set_IHDR(png_ptr[monitor_index], info_ptr[monitor_index], blit_data_ptr->w, blit_data_ptr->h, 8, PNG_COLOR_TYPE_RGB, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE); - b_rgb = (png_bytep *) malloc(sizeof(png_bytep) * blit_data.h); + b_rgb = (png_bytep *) malloc(sizeof(png_bytep) * blit_data_ptr->h); if (b_rgb == NULL) { video_log("[video_take_screenshot] Unable to Allocate RGB Bitmap Memory"); fclose(fp); return; } - 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) { + for (y = 0; y < blit_data_ptr->h; ++y) { + b_rgb[y] = (png_byte *) malloc(png_get_rowbytes(png_ptr[monitor_index], info_ptr[monitor_index])); + for (x = 0; x < blit_data_ptr->w; ++x) { if (buf == NULL) memset(&(b_rgb[y][x * 3]), 0x00, 3); else { @@ -382,14 +397,14 @@ video_take_screenshot(const char *fn, uint32_t *buf, int start_x, int start_y, i } } - png_write_info(png_ptr, info_ptr); + png_write_info(png_ptr[monitor_index], info_ptr[monitor_index]); - png_write_image(png_ptr, b_rgb); + png_write_image(png_ptr[monitor_index], b_rgb); - png_write_end(png_ptr, NULL); + png_write_end(png_ptr[monitor_index], NULL); /* cleanup heap allocation */ - for (i = 0; i < blit_data.h; i++) + for (i = 0; i < blit_data_ptr->h; i++) if (b_rgb[i]) free(b_rgb[i]); if (b_rgb) free(b_rgb); @@ -399,7 +414,7 @@ video_take_screenshot(const char *fn, uint32_t *buf, int start_x, int start_y, i void -video_screenshot(uint32_t *buf, int start_x, int start_y, int row_len) +video_screenshot_monitor(uint32_t *buf, int start_x, int start_y, int row_len, int monitor_index) { char path[1024], fn[128]; @@ -409,7 +424,7 @@ video_screenshot(uint32_t *buf, int start_x, int start_y, int row_len) path_append_filename(path, usr_path, SCREENSHOT_PATH); if (! plat_dir_check(path)) - plat_dir_create(path); + plat_dir_create(path); path_slash(path); @@ -418,10 +433,16 @@ video_screenshot(uint32_t *buf, int start_x, int start_y, int row_len) video_log("taking screenshot to: %s\n", path); - video_take_screenshot((const char *) path, buf, start_x, start_y, row_len); - png_destroy_write_struct(&png_ptr, &info_ptr); + video_take_screenshot_monitor((const char *) path, buf, start_x, start_y, row_len, monitor_index); + png_destroy_write_struct(&png_ptr[monitor_index], &info_ptr[monitor_index]); - screenshots--; + monitors[monitor_index].mon_screenshots--; +} + +void +video_screenshot(uint32_t *buf, int start_x, int start_y, int row_len) +{ + video_screenshot_monitor(buf, start_x, start_y, row_len, monitor_index_global); } @@ -454,40 +475,48 @@ video_transform_copy(void *__restrict _Dst, const void *__restrict _Src, size_t static void blit_thread(void *param) { - while (thread_run) { - thread_wait_event(blit_data.wake_blit_thread, -1); - thread_reset_event(blit_data.wake_blit_thread); + struct blit_data_struct* data = param; + while (data->thread_run) { + thread_wait_event(data->wake_blit_thread, -1); + thread_reset_event(data->wake_blit_thread); MTR_BEGIN("video", "blit_thread"); if (blit_func) - blit_func(blit_data.x, blit_data.y, blit_data.w, blit_data.h); + blit_func(data->x, data->y, data->w, data->h, data->monitor_index); - blit_data.busy = 0; + data->busy = 0; MTR_END("video", "blit_thread"); - thread_set_event(blit_data.blit_complete); + thread_set_event(data->blit_complete); } } void video_blit_memtoscreen(int x, int y, int w, int h) +{ + video_blit_memtoscreen_monitor(x, y, w, h, monitor_index_global); +} + + +void +video_blit_memtoscreen_monitor(int x, int y, int w, int h, int monitor_index) { MTR_BEGIN("video", "video_blit_memtoscreen"); if ((w <= 0) || (h <= 0)) - return; + return; - video_wait_for_blit(); + video_wait_for_blit_monitor(monitor_index); - blit_data.busy = 1; - blit_data.buffer_in_use = 1; - blit_data.x = x; - blit_data.y = y; - blit_data.w = w; - blit_data.h = h; + monitors[monitor_index].mon_blit_data_ptr->busy = 1; + monitors[monitor_index].mon_blit_data_ptr->buffer_in_use = 1; + monitors[monitor_index].mon_blit_data_ptr->x = x; + monitors[monitor_index].mon_blit_data_ptr->y = y; + monitors[monitor_index].mon_blit_data_ptr->w = w; + monitors[monitor_index].mon_blit_data_ptr->h = h; - thread_set_event(blit_data.wake_blit_thread); + thread_set_event(monitors[monitor_index].mon_blit_data_ptr->wake_blit_thread); MTR_END("video", "video_blit_memtoscreen"); } @@ -521,7 +550,7 @@ uint32_t pixel_to_color(uint8_t *pixels32, uint8_t pos) void -video_blend(int x, int y) +video_blend_monitor(int x, int y, int monitor_index) { int xx; uint32_t pixels32_1, pixels32_2; @@ -529,152 +558,207 @@ video_blend(int x, int y) static unsigned int carry = 0; if (!herc_blend) - return; + return; if (!x) - carry = 0; + carry = 0; - val1 = pixels8(&(buffer32->line[y][x])); + val1 = pixels8(&(monitors[monitor_index].target_buffer->line[y][x])); val2 = (val1 >> 1) + carry; carry = (val1 & 1) << 7; pixels32_1 = cga_2_table[val1 >> 4] + cga_2_table[val2 >> 4]; pixels32_2 = cga_2_table[val1 & 0xf] + cga_2_table[val2 & 0xf]; for (xx = 0; xx < 4; xx++) { - buffer32->line[y][x + xx] = pixel_to_color((uint8_t *) &pixels32_1, xx); - buffer32->line[y][x + (xx | 4)] = pixel_to_color((uint8_t *) &pixels32_2, xx); + monitors[monitor_index].target_buffer->line[y][x + xx] = pixel_to_color((uint8_t *) &pixels32_1, xx); + monitors[monitor_index].target_buffer->line[y][x + (xx | 4)] = pixel_to_color((uint8_t *) &pixels32_2, xx); } } +void +video_blend(int x, int y) +{ + video_blend_monitor(x, y, monitor_index_global); +} + + +void +video_blit_memtoscreen_8_monitor(int x, int y, int w, int h, int monitor_index) +{ + int yy, xx; + + if ((w > 0) && (h > 0)) { + for (yy = 0; yy < h; yy++) { + if ((y + yy) >= 0 && (y + yy) < monitors[monitor_index].target_buffer->h) { + for (xx = 0; xx < w; xx++) { + if (monitors[monitor_index].target_buffer->line[y + yy][x + xx] <= 0xff) + monitors[monitor_index].target_buffer->line[y + yy][x + xx] = monitors[monitor_index].mon_pal_lookup[monitors[monitor_index].target_buffer->line[y + yy][x + xx]]; + else + monitors[monitor_index].target_buffer->line[y + yy][x + xx] = 0x00000000; + } + } + } + } + + video_blit_memtoscreen_monitor(x, y, w, h, monitor_index); +} + + void video_blit_memtoscreen_8(int x, int y, int w, int h) { - int yy, xx; - - if ((w > 0) && (h > 0)) { - for (yy = 0; yy < h; yy++) { - if ((y + yy) >= 0 && (y + yy) < buffer32->h) { - for (xx = 0; xx < w; xx++) { - if (buffer32->line[y + yy][x + xx] <= 0xff) - buffer32->line[y + yy][x + xx] = pal_lookup[buffer32->line[y + yy][x + xx]]; - else - buffer32->line[y + yy][x + xx] = 0x00000000; - } - } - } - } - - video_blit_memtoscreen(x, y, w, h); + video_blit_memtoscreen_8_monitor(x, y, w, h, monitor_index_global); } void -cgapal_rebuild(void) +cgapal_rebuild_monitor(int monitor_index) { int c; + uint32_t* palette_lookup = monitors[monitor_index].mon_pal_lookup; + int cga_palette_monitor = *monitors[monitor_index].mon_cga_palette; /* We cannot do this (yet) if we have not been enabled yet. */ if (video_6to8 == NULL) return; for (c=0; c<256; c++) { - pal_lookup[c] = makecol(video_6to8[cgapal[c].r], + palette_lookup[c] = makecol(video_6to8[cgapal[c].r], video_6to8[cgapal[c].g], video_6to8[cgapal[c].b]); } - if ((cga_palette > 1) && (cga_palette < 7)) { + if ((cga_palette_monitor > 1) && (cga_palette_monitor < 7)) { if (vid_cga_contrast != 0) { for (c = 0; c < 16; c++) { - pal_lookup[c] = makecol(video_6to8[cgapal_mono[cga_palette - 2][c].r], - video_6to8[cgapal_mono[cga_palette - 2][c].g], - video_6to8[cgapal_mono[cga_palette - 2][c].b]); - pal_lookup[c+16] = makecol(video_6to8[cgapal_mono[cga_palette - 2][c].r], - video_6to8[cgapal_mono[cga_palette - 2][c].g], - video_6to8[cgapal_mono[cga_palette - 2][c].b]); - pal_lookup[c+32] = makecol(video_6to8[cgapal_mono[cga_palette - 2][c].r], - video_6to8[cgapal_mono[cga_palette - 2][c].g], - video_6to8[cgapal_mono[cga_palette - 2][c].b]); - pal_lookup[c+48] = makecol(video_6to8[cgapal_mono[cga_palette - 2][c].r], - video_6to8[cgapal_mono[cga_palette - 2][c].g], - video_6to8[cgapal_mono[cga_palette - 2][c].b]); + palette_lookup[c] = makecol(video_6to8[cgapal_mono[cga_palette_monitor - 2][c].r], + video_6to8[cgapal_mono[cga_palette_monitor - 2][c].g], + video_6to8[cgapal_mono[cga_palette_monitor - 2][c].b]); + palette_lookup[c+16] = makecol(video_6to8[cgapal_mono[cga_palette_monitor - 2][c].r], + video_6to8[cgapal_mono[cga_palette_monitor - 2][c].g], + video_6to8[cgapal_mono[cga_palette_monitor - 2][c].b]); + palette_lookup[c+32] = makecol(video_6to8[cgapal_mono[cga_palette_monitor - 2][c].r], + video_6to8[cgapal_mono[cga_palette_monitor - 2][c].g], + video_6to8[cgapal_mono[cga_palette_monitor - 2][c].b]); + palette_lookup[c+48] = makecol(video_6to8[cgapal_mono[cga_palette_monitor - 2][c].r], + video_6to8[cgapal_mono[cga_palette_monitor - 2][c].g], + video_6to8[cgapal_mono[cga_palette_monitor - 2][c].b]); } } else { for (c = 0; c < 16; c++) { - pal_lookup[c] = makecol(video_6to8[cgapal_mono[cga_palette - 1][c].r], - video_6to8[cgapal_mono[cga_palette - 1][c].g], - video_6to8[cgapal_mono[cga_palette - 1][c].b]); - pal_lookup[c+16] = makecol(video_6to8[cgapal_mono[cga_palette - 1][c].r], - video_6to8[cgapal_mono[cga_palette - 1][c].g], - video_6to8[cgapal_mono[cga_palette - 1][c].b]); - pal_lookup[c+32] = makecol(video_6to8[cgapal_mono[cga_palette - 1][c].r], - video_6to8[cgapal_mono[cga_palette - 1][c].g], - video_6to8[cgapal_mono[cga_palette - 1][c].b]); - pal_lookup[c+48] = makecol(video_6to8[cgapal_mono[cga_palette - 1][c].r], - video_6to8[cgapal_mono[cga_palette - 1][c].g], - video_6to8[cgapal_mono[cga_palette - 1][c].b]); + palette_lookup[c] = makecol(video_6to8[cgapal_mono[cga_palette_monitor - 1][c].r], + video_6to8[cgapal_mono[cga_palette_monitor - 1][c].g], + video_6to8[cgapal_mono[cga_palette_monitor - 1][c].b]); + palette_lookup[c+16] = makecol(video_6to8[cgapal_mono[cga_palette_monitor - 1][c].r], + video_6to8[cgapal_mono[cga_palette_monitor - 1][c].g], + video_6to8[cgapal_mono[cga_palette_monitor - 1][c].b]); + palette_lookup[c+32] = makecol(video_6to8[cgapal_mono[cga_palette_monitor - 1][c].r], + video_6to8[cgapal_mono[cga_palette_monitor - 1][c].g], + video_6to8[cgapal_mono[cga_palette_monitor - 1][c].b]); + palette_lookup[c+48] = makecol(video_6to8[cgapal_mono[cga_palette_monitor - 1][c].r], + video_6to8[cgapal_mono[cga_palette_monitor - 1][c].g], + video_6to8[cgapal_mono[cga_palette_monitor - 1][c].b]); } } } - if (cga_palette == 7) - pal_lookup[0x16] = makecol(video_6to8[42],video_6to8[42],video_6to8[0]); + if (cga_palette_monitor == 7) + palette_lookup[0x16] = makecol(video_6to8[42],video_6to8[42],video_6to8[0]); +} + +void +cgapal_rebuild(void) +{ + cgapal_rebuild_monitor(monitor_index_global); +} + + +void +video_inform_monitor(int type, const video_timings_t *ptr, int monitor_index) +{ + monitor_t* monitor = &monitors[monitor_index]; + monitor->mon_vid_type = type; + monitor->mon_vid_timings = ptr; } void video_inform(int type, const video_timings_t *ptr) { - vid_type = type; - vid_timings = ptr; + video_inform_monitor(type, ptr, monitor_index_global); +} + + +int +video_get_type_monitor(int monitor_index) +{ + return monitors[monitor_index].mon_vid_type; } int video_get_type(void) { - return vid_type; + return video_get_type_monitor(0); } void video_update_timing(void) { - if (!vid_timings) - return; + const video_timings_t* monitor_vid_timings = NULL; + int *vid_timing_read_b = NULL; + int *vid_timing_read_l = NULL; + int *vid_timing_read_w = NULL; + int *vid_timing_write_b = NULL; + int *vid_timing_write_l = NULL; + int *vid_timing_write_w = NULL; + int i = 0; - if (vid_timings->type == VIDEO_ISA) { - video_timing_read_b = ISA_CYCLES(vid_timings->read_b); - video_timing_read_w = ISA_CYCLES(vid_timings->read_w); - video_timing_read_l = ISA_CYCLES(vid_timings->read_l); - video_timing_write_b = ISA_CYCLES(vid_timings->write_b); - video_timing_write_w = ISA_CYCLES(vid_timings->write_w); - video_timing_write_l = ISA_CYCLES(vid_timings->write_l); - } else if (vid_timings->type == VIDEO_PCI) { - video_timing_read_b = (int)(pci_timing * vid_timings->read_b); - video_timing_read_w = (int)(pci_timing * vid_timings->read_w); - video_timing_read_l = (int)(pci_timing * vid_timings->read_l); - video_timing_write_b = (int)(pci_timing * vid_timings->write_b); - video_timing_write_w = (int)(pci_timing * vid_timings->write_w); - video_timing_write_l = (int)(pci_timing * vid_timings->write_l); - } else if (vid_timings->type == VIDEO_AGP) { - video_timing_read_b = (int)(agp_timing * vid_timings->read_b); - video_timing_read_w = (int)(agp_timing * vid_timings->read_w); - video_timing_read_l = (int)(agp_timing * vid_timings->read_l); - video_timing_write_b = (int)(agp_timing * vid_timings->write_b); - video_timing_write_w = (int)(agp_timing * vid_timings->write_w); - video_timing_write_l = (int)(agp_timing * vid_timings->write_l); - } else { - video_timing_read_b = (int)(bus_timing * vid_timings->read_b); - video_timing_read_w = (int)(bus_timing * vid_timings->read_w); - video_timing_read_l = (int)(bus_timing * vid_timings->read_l); - video_timing_write_b = (int)(bus_timing * vid_timings->write_b); - video_timing_write_w = (int)(bus_timing * vid_timings->write_w); - video_timing_write_l = (int)(bus_timing * vid_timings->write_l); - } + for (i = 0; i < MONITORS_NUM; i++) { + monitor_vid_timings = monitors[i].mon_vid_timings; + if (!monitor_vid_timings) + continue; + vid_timing_read_b = &monitors[i].mon_video_timing_read_b; + vid_timing_read_l = &monitors[i].mon_video_timing_read_l; + vid_timing_read_w = &monitors[i].mon_video_timing_read_w; + vid_timing_write_b = &monitors[i].mon_video_timing_write_b; + vid_timing_write_l = &monitors[i].mon_video_timing_write_l; + vid_timing_write_w = &monitors[i].mon_video_timing_write_w; - if (cpu_16bitbus) { - video_timing_read_l = video_timing_read_w * 2; - video_timing_write_l = video_timing_write_w * 2; + if (monitor_vid_timings->type == VIDEO_ISA) { + *vid_timing_read_b = ISA_CYCLES(monitor_vid_timings->read_b); + *vid_timing_read_w = ISA_CYCLES(monitor_vid_timings->read_w); + *vid_timing_read_l = ISA_CYCLES(monitor_vid_timings->read_l); + *vid_timing_write_b = ISA_CYCLES(monitor_vid_timings->write_b); + *vid_timing_write_w = ISA_CYCLES(monitor_vid_timings->write_w); + *vid_timing_write_l = ISA_CYCLES(monitor_vid_timings->write_l); + } else if (vid_timings->type == VIDEO_PCI) { + *vid_timing_read_b = (int)(pci_timing * monitor_vid_timings->read_b); + *vid_timing_read_w = (int)(pci_timing * monitor_vid_timings->read_w); + *vid_timing_read_l = (int)(pci_timing * monitor_vid_timings->read_l); + *vid_timing_write_b = (int)(pci_timing * monitor_vid_timings->write_b); + *vid_timing_write_w = (int)(pci_timing * monitor_vid_timings->write_w); + *vid_timing_write_l = (int)(pci_timing * monitor_vid_timings->write_l); + } else if (vid_timings->type == VIDEO_AGP) { + *vid_timing_read_b = (int)(agp_timing * monitor_vid_timings->read_b); + *vid_timing_read_w = (int)(agp_timing * monitor_vid_timings->read_w); + *vid_timing_read_l = (int)(agp_timing * monitor_vid_timings->read_l); + *vid_timing_write_b = (int)(agp_timing * monitor_vid_timings->write_b); + *vid_timing_write_w = (int)(agp_timing * monitor_vid_timings->write_w); + *vid_timing_write_l = (int)(agp_timing * monitor_vid_timings->write_l); + } else { + *vid_timing_read_b = (int)(bus_timing * monitor_vid_timings->read_b); + *vid_timing_read_w = (int)(bus_timing * monitor_vid_timings->read_w); + *vid_timing_read_l = (int)(bus_timing * monitor_vid_timings->read_l); + *vid_timing_write_b = (int)(bus_timing * monitor_vid_timings->write_b); + *vid_timing_write_w = (int)(bus_timing * monitor_vid_timings->write_w); + *vid_timing_write_l = (int)(bus_timing * monitor_vid_timings->write_l); + } + + if (cpu_16bitbus) { + *vid_timing_read_l = *vid_timing_read_w * 2; + *vid_timing_write_l = *vid_timing_write_w * 2; + } } } @@ -762,7 +846,7 @@ hline(bitmap_t *b, int x1, int y, int x2, uint32_t col) { int x; - if (y < 0 || y >= buffer32->h) + if (y < 0 || y >= b->h) return; for (x = x1; x < x2; x++) @@ -820,6 +904,48 @@ create_bitmap(int x, int y) return(b); } +void +video_monitor_init(int index) +{ + memset(&monitors[index], 0, sizeof(monitor_t)); + monitors[index].mon_xsize = 640; + monitors[index].mon_ysize = 480; + monitors[index].mon_res_x = 640; + monitors[index].mon_res_y = 480; + monitors[index].mon_scrnsz_x = 640; + monitors[index].mon_scrnsz_y = 480; + monitors[index].mon_efscrnsz_y = 480; + monitors[index].mon_unscaled_size_x = 480; + monitors[index].mon_unscaled_size_y = 480; + monitors[index].mon_bpp = 8; + monitors[index].mon_changeframecount = 2; + monitors[index].target_buffer = create_bitmap(2048, 2048); + atomic_init(&monitors[index].mon_doresize, 0); + monitors[index].mon_blit_data_ptr = calloc(1, sizeof(struct blit_data_struct)); + monitors[index].mon_blit_data_ptr->wake_blit_thread = thread_create_event(); + monitors[index].mon_blit_data_ptr->blit_complete = thread_create_event(); + monitors[index].mon_blit_data_ptr->buffer_not_in_use = thread_create_event(); + monitors[index].mon_blit_data_ptr->thread_run = 1; + monitors[index].mon_pal_lookup = calloc(sizeof(uint32_t), 256); + monitors[index].mon_cga_palette = calloc(1, sizeof(int)); + thread_create(blit_thread, monitors[index].mon_blit_data_ptr); +} + +void +video_monitor_close(int monitor_index) +{ + if (monitors[monitor_index].target_buffer == NULL) { return; } + monitors[monitor_index].mon_blit_data_ptr->thread_run = 0; + thread_set_event(monitors[monitor_index].mon_blit_data_ptr->wake_blit_thread); + thread_wait(monitors[monitor_index].mon_blit_data_ptr->blit_thread); + thread_destroy_event(monitors[monitor_index].mon_blit_data_ptr->buffer_not_in_use); + thread_destroy_event(monitors[monitor_index].mon_blit_data_ptr->blit_complete); + thread_destroy_event(monitors[monitor_index].mon_blit_data_ptr->wake_blit_thread); + free(monitors[monitor_index].mon_blit_data_ptr); + if (!monitors[monitor_index].mon_pal_lookup_static) free(monitors[monitor_index].mon_pal_lookup); + if (!monitors[monitor_index].mon_cga_palette_static) free(monitors[monitor_index].mon_cga_palette); + memset(&monitors[monitor_index], 0, sizeof(monitor_t)); +} void video_init(void) @@ -832,9 +958,6 @@ video_init(void) (total[(c >> 1) & 1] << 16) | (total[(c >> 0) & 1] << 24); } - /* Account for overscan. */ - buffer32 = create_bitmap(2048, 2048); - for (c = 0; c < 64; c++) { cgapal[c + 64].r = (((c & 4) ? 2 : 0) | ((c & 0x10) ? 1 : 0)) * 21; cgapal[c + 64].g = (((c & 2) ? 2 : 0) | ((c & 0x10) ? 1 : 0)) * 21; @@ -878,23 +1001,15 @@ video_init(void) for (c = 0; c < 65536; c++) video_16to32[c] = calc_16to32(c); - blit_data.wake_blit_thread = thread_create_event(); - blit_data.blit_complete = thread_create_event(); - blit_data.buffer_not_in_use = thread_create_event(); - thread_run = 1; - blit_data.blit_thread = thread_create(blit_thread, NULL); + memset(monitors, 0, sizeof(monitors)); + video_monitor_init(0); } void video_close(void) { - thread_run = 0; - thread_set_event(blit_data.wake_blit_thread); - thread_wait(blit_data.blit_thread); - thread_destroy_event(blit_data.buffer_not_in_use); - thread_destroy_event(blit_data.blit_complete); - thread_destroy_event(blit_data.wake_blit_thread); + video_monitor_close(0); free(video_16to32); free(video_15to32); @@ -902,8 +1017,6 @@ video_close(void) free(video_8togs); free(video_6to8); - destroy_bitmap(buffer32); - if (fontdatksc5601) { free(fontdatksc5601); fontdatksc5601 = NULL; @@ -915,18 +1028,29 @@ video_close(void) } } +uint8_t +video_force_resize_get_monitor(int monitor_index) +{ + return monitors[monitor_index].mon_force_resize; +} uint8_t video_force_resize_get(void) { - return video_force_resize; + return monitors[monitor_index_global].mon_force_resize; +} + +void +video_force_resize_set_monitor(uint8_t res, int monitor_index) +{ + monitors[monitor_index].mon_force_resize = res; } void video_force_resize_set(uint8_t res) { - video_force_resize = res; + monitors[monitor_index_global].mon_force_resize = res; } void diff --git a/src/win/win_opengl.c b/src/win/win_opengl.c index b1dab78ca..02d163293 100644 --- a/src/win/win_opengl.c +++ b/src/win/win_opengl.c @@ -871,7 +871,7 @@ static void opengl_main(void* param) CoUninitialize(); } -static void opengl_blit(int x, int y, int w, int h) +static void opengl_blit(int x, int y, int w, int h, int monitor_index) { int row; diff --git a/src/win/win_sdl.c b/src/win/win_sdl.c index cd4b26169..a2a8d5159 100644 --- a/src/win/win_sdl.c +++ b/src/win/win_sdl.c @@ -229,7 +229,7 @@ sdl_stretch(int *w, int *h, int *x, int *y) static void -sdl_blit(int x, int y, int w, int h) +sdl_blit(int x, int y, int w, int h, int monitor_index) { SDL_Rect r_src; int ret; @@ -269,7 +269,7 @@ sdl_blit(int x, int y, int w, int h) static void -sdl_blit_ex(int x, int y, int w, int h) +sdl_blit_ex(int x, int y, int w, int h, int monitor_index) { SDL_Rect r_src; void *pixeldata;