mirror of
https://github.com/86Box/86Box.git
synced 2026-02-21 17:15:32 -07:00
Merge pull request #2432 from Cacodemon345/multimonitor-take2-ui
Multi-monitor support
This commit is contained in:
139
src/86box.c
139
src/86box.c
@@ -139,10 +139,6 @@ char log_path[1024] = { '\0'}; /* (O) full path of logfile */
|
||||
char vm_name[1024] = { '\0'}; /* (O) display name of the VM */
|
||||
|
||||
/* Configuration values. */
|
||||
int window_w; /* (C) window size and */
|
||||
int window_h; /* position info */
|
||||
int window_x;
|
||||
int window_y;
|
||||
int window_remember;
|
||||
int vid_resize; /* (C) allow resizing */
|
||||
int invert_display = 0; /* (C) invert the display */
|
||||
@@ -166,6 +162,8 @@ int postcard_enabled = 0; /* (C) enable POST card */
|
||||
int isamem_type[ISAMEM_MAX] = { 0,0,0,0 }; /* (C) enable ISA mem cards */
|
||||
int isartc_type = 0; /* (C) enable ISA RTC card */
|
||||
int gfxcard = 0; /* (C) graphics/video card */
|
||||
int gfxcard_2 = 0; /* (C) graphics/video card */
|
||||
int show_second_monitors = 1; /* (C) show non-primary monitors */
|
||||
int sound_is_float = 1; /* (C) sound uses FP values */
|
||||
int GAMEBLASTER = 0; /* (C) sound option */
|
||||
int GUS = 0; /* (C) sound option */
|
||||
@@ -201,17 +199,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];
|
||||
@@ -855,6 +853,15 @@ pc_init_modules(void)
|
||||
}
|
||||
}
|
||||
|
||||
if (! video_card_available(gfxcard_2)) {
|
||||
char temp[1024] = { 0 };
|
||||
char tempc[1024] = { 0 };
|
||||
device_get_name(video_card_getdevice(gfxcard_2), 0, tempc);
|
||||
snprintf(temp, sizeof(temp), "Video card #2 \"%s\" is not available due to missing ROMs in the roms/video directory. Disabling the second video card.", tempc);
|
||||
ui_msgbox_header(MBX_INFO, (wchar_t *) IDS_2128, temp);
|
||||
gfxcard_2 = 0;
|
||||
}
|
||||
|
||||
atfullspeed = 0;
|
||||
|
||||
random_init();
|
||||
@@ -1250,14 +1257,13 @@ pc_onesec(void)
|
||||
title_update = 1;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
set_screen_size(int x, int y)
|
||||
set_screen_size_monitor(int x, int y, int monitor_index)
|
||||
{
|
||||
int owsx = scrnsz_x;
|
||||
int owsy = scrnsz_y;
|
||||
int temp_overscan_x = overscan_x;
|
||||
int temp_overscan_y = overscan_y;
|
||||
int owsx = monitors[monitor_index].mon_scrnsz_x;
|
||||
int owsy = monitors[monitor_index].mon_scrnsz_y;
|
||||
int temp_overscan_x = monitors[monitor_index].mon_overscan_x;
|
||||
int temp_overscan_y = monitors[monitor_index].mon_overscan_y;
|
||||
double dx, dy, dtx, dty;
|
||||
|
||||
/* Make sure we keep usable values. */
|
||||
@@ -1270,78 +1276,89 @@ set_screen_size(int x, int y)
|
||||
if (y > 2048) y = 2048;
|
||||
|
||||
/* Save the new values as "real" (unscaled) resolution. */
|
||||
unscaled_size_x = x;
|
||||
efscrnsz_y = y;
|
||||
monitors[monitor_index].mon_unscaled_size_x = x;
|
||||
monitors[monitor_index].mon_efscrnsz_y = y;
|
||||
|
||||
if (suppress_overscan)
|
||||
temp_overscan_x = temp_overscan_y = 0;
|
||||
temp_overscan_x = temp_overscan_y = 0;
|
||||
|
||||
if (force_43) {
|
||||
dx = (double)x;
|
||||
dtx = (double)temp_overscan_x;
|
||||
dx = (double)x;
|
||||
dtx = (double)temp_overscan_x;
|
||||
|
||||
dy = (double)y;
|
||||
dty = (double)temp_overscan_y;
|
||||
dy = (double)y;
|
||||
dty = (double)temp_overscan_y;
|
||||
|
||||
/* Account for possible overscan. */
|
||||
if (!(video_is_ega_vga()) && (temp_overscan_y == 16)) {
|
||||
/* CGA */
|
||||
dy = (((dx - dtx) / 4.0) * 3.0) + dty;
|
||||
} else if (!(video_is_ega_vga()) && (temp_overscan_y < 16)) {
|
||||
/* MDA/Hercules */
|
||||
dy = (x / 4.0) * 3.0;
|
||||
} else {
|
||||
if (enable_overscan) {
|
||||
/* EGA/(S)VGA with overscan */
|
||||
dy = (((dx - dtx) / 4.0) * 3.0) + dty;
|
||||
} else {
|
||||
/* EGA/(S)VGA without overscan */
|
||||
dy = (x / 4.0) * 3.0;
|
||||
}
|
||||
}
|
||||
unscaled_size_y = (int)dy;
|
||||
/* Account for possible overscan. */
|
||||
if (video_get_type_monitor(monitor_index) != VIDEO_FLAG_TYPE_SPECIAL && (temp_overscan_y == 16)) {
|
||||
/* CGA */
|
||||
dy = (((dx - dtx) / 4.0) * 3.0) + dty;
|
||||
} else if (video_get_type_monitor(monitor_index) != VIDEO_FLAG_TYPE_SPECIAL && (temp_overscan_y < 16)) {
|
||||
/* MDA/Hercules */
|
||||
dy = (x / 4.0) * 3.0;
|
||||
} else {
|
||||
if (enable_overscan) {
|
||||
/* EGA/(S)VGA with overscan */
|
||||
dy = (((dx - dtx) / 4.0) * 3.0) + dty;
|
||||
} else {
|
||||
/* EGA/(S)VGA without overscan */
|
||||
dy = (x / 4.0) * 3.0;
|
||||
}
|
||||
}
|
||||
monitors[monitor_index].mon_unscaled_size_y = (int)dy;
|
||||
} else
|
||||
unscaled_size_y = efscrnsz_y;
|
||||
monitors[monitor_index].mon_unscaled_size_y = monitors[monitor_index].mon_efscrnsz_y;
|
||||
|
||||
switch(scale) {
|
||||
case 0: /* 50% */
|
||||
scrnsz_x = (unscaled_size_x>>1);
|
||||
scrnsz_y = (unscaled_size_y>>1);
|
||||
break;
|
||||
case 0: /* 50% */
|
||||
monitors[monitor_index].mon_scrnsz_x = (monitors[monitor_index].mon_unscaled_size_x>>1);
|
||||
monitors[monitor_index].mon_scrnsz_y = (monitors[monitor_index].mon_unscaled_size_y>>1);
|
||||
break;
|
||||
|
||||
case 1: /* 100% */
|
||||
scrnsz_x = unscaled_size_x;
|
||||
scrnsz_y = unscaled_size_y;
|
||||
break;
|
||||
case 1: /* 100% */
|
||||
monitors[monitor_index].mon_scrnsz_x = monitors[monitor_index].mon_unscaled_size_x;
|
||||
monitors[monitor_index].mon_scrnsz_y = monitors[monitor_index].mon_unscaled_size_y;
|
||||
break;
|
||||
|
||||
case 2: /* 150% */
|
||||
scrnsz_x = ((unscaled_size_x*3)>>1);
|
||||
scrnsz_y = ((unscaled_size_y*3)>>1);
|
||||
break;
|
||||
case 2: /* 150% */
|
||||
monitors[monitor_index].mon_scrnsz_x = ((monitors[monitor_index].mon_unscaled_size_x*3)>>1);
|
||||
monitors[monitor_index].mon_scrnsz_y = ((monitors[monitor_index].mon_unscaled_size_y*3)>>1);
|
||||
break;
|
||||
|
||||
case 3: /* 200% */
|
||||
scrnsz_x = (unscaled_size_x<<1);
|
||||
scrnsz_y = (unscaled_size_y<<1);
|
||||
break;
|
||||
case 3: /* 200% */
|
||||
monitors[monitor_index].mon_scrnsz_x = (monitors[monitor_index].mon_unscaled_size_x<<1);
|
||||
monitors[monitor_index].mon_scrnsz_y = (monitors[monitor_index].mon_unscaled_size_y<<1);
|
||||
break;
|
||||
}
|
||||
|
||||
/* If the resolution has changed, let the main thread handle it. */
|
||||
if ((owsx != scrnsz_x) || (owsy != scrnsz_y))
|
||||
atomic_flag_clear(&doresize);
|
||||
atomic_store(&doresize_monitors[monitor_index], 1);
|
||||
}
|
||||
|
||||
void
|
||||
set_screen_size(int x, int y)
|
||||
{
|
||||
set_screen_size_monitor(x, y, monitor_index_global);
|
||||
}
|
||||
|
||||
void
|
||||
reset_screen_size_monitor(int monitor_index)
|
||||
{
|
||||
set_screen_size(monitors[monitor_index].mon_unscaled_size_x, monitors[monitor_index].mon_efscrnsz_y);
|
||||
}
|
||||
|
||||
void
|
||||
reset_screen_size(void)
|
||||
{
|
||||
set_screen_size(unscaled_size_x, efscrnsz_y);
|
||||
for (int i = 0; i < MONITORS_NUM; i++)
|
||||
set_screen_size(monitors[i].mon_unscaled_size_x, monitors[i].mon_efscrnsz_y);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
set_screen_size_natural(void)
|
||||
{
|
||||
set_screen_size(unscaled_size_x, unscaled_size_y);
|
||||
for (int i = 0; i < MONITORS_NUM; i++)
|
||||
set_screen_size(monitors[i].mon_unscaled_size_x, monitors[i].mon_unscaled_size_y);
|
||||
}
|
||||
|
||||
|
||||
|
||||
69
src/config.c
69
src/config.c
@@ -552,14 +552,8 @@ load_general(void)
|
||||
if (window_remember || (vid_resize & 2)) {
|
||||
if (!window_remember)
|
||||
config_delete_var(cat, "window_remember");
|
||||
|
||||
p = config_get_string(cat, "window_coordinates", NULL);
|
||||
if (p == NULL)
|
||||
p = "0, 0, 0, 0";
|
||||
sscanf(p, "%i, %i, %i, %i", &window_w, &window_h, &window_x, &window_y);
|
||||
} else {
|
||||
config_delete_var(cat, "window_remember");
|
||||
config_delete_var(cat, "window_coordinates");
|
||||
|
||||
window_w = window_h = window_x = window_y = 0;
|
||||
}
|
||||
@@ -932,6 +926,49 @@ load_video(void)
|
||||
voodoo_enabled = !!config_get_int(cat, "voodoo", 0);
|
||||
ibm8514_enabled = !!config_get_int(cat, "8514a", 0);
|
||||
xga_enabled = !!config_get_int(cat, "xga", 0);
|
||||
show_second_monitors = !!config_get_int(cat, "show_second_monitors", 1);
|
||||
p = config_get_string(cat, "gfxcard_2", NULL);
|
||||
if (!p) p = "none";
|
||||
gfxcard_2 = video_get_video_from_internal_name(p);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
load_monitor(int monitor_index)
|
||||
{
|
||||
char monitor_config_name[sizeof("Monitor #") + 12] = { [0] = 0 };
|
||||
char* ptr = NULL;
|
||||
|
||||
if (monitor_index == 0) {
|
||||
/* Migrate configs */
|
||||
ptr = config_get_string("General", "window_coordinates", NULL);
|
||||
|
||||
config_delete_var("General", "window_coordinates");
|
||||
}
|
||||
snprintf(monitor_config_name, sizeof(monitor_config_name), "Monitor #%i", monitor_index + 1);
|
||||
if (!ptr) ptr = config_get_string(monitor_config_name, "window_coordinates", "0, 0, 0, 0");
|
||||
if (window_remember || (vid_resize & 2)) sscanf(ptr, "%i, %i, %i, %i",
|
||||
&monitor_settings[monitor_index].mon_window_x, &monitor_settings[monitor_index].mon_window_y,
|
||||
&monitor_settings[monitor_index].mon_window_w, &monitor_settings[monitor_index].mon_window_h);
|
||||
}
|
||||
|
||||
static void
|
||||
save_monitor(int monitor_index)
|
||||
{
|
||||
char monitor_config_name[sizeof("Monitor #") + 12] = { [0] = 0 };
|
||||
char saved_coordinates[12 * 4 + 8 + 1] = { [0] = 0 };
|
||||
|
||||
snprintf(monitor_config_name, sizeof(monitor_config_name), "Monitor #%i", monitor_index + 1);
|
||||
if (!(monitor_settings[monitor_index].mon_window_x == 0
|
||||
&& monitor_settings[monitor_index].mon_window_y == 0
|
||||
&& monitor_settings[monitor_index].mon_window_w == 0
|
||||
&& monitor_settings[monitor_index].mon_window_h == 0) && (window_remember || (vid_resize & 2))) {
|
||||
snprintf(saved_coordinates, sizeof(saved_coordinates), "%i, %i, %i, %i", monitor_settings[monitor_index].mon_window_x, monitor_settings[monitor_index].mon_window_y,
|
||||
monitor_settings[monitor_index].mon_window_w, monitor_settings[monitor_index].mon_window_h);
|
||||
|
||||
config_set_string(monitor_config_name, "window_coordinates", saved_coordinates);
|
||||
}
|
||||
else config_delete_var(monitor_config_name, "window_coordinates");
|
||||
}
|
||||
|
||||
|
||||
@@ -2156,6 +2193,8 @@ config_load(void)
|
||||
config_log("Config file not present or invalid!\n");
|
||||
} else {
|
||||
load_general(); /* General */
|
||||
for (i = 0; i < MONITORS_NUM; i++)
|
||||
load_monitor(i);
|
||||
load_machine(); /* Machine */
|
||||
load_video(); /* Video */
|
||||
load_input_devices(); /* Input devices */
|
||||
@@ -2265,12 +2304,8 @@ save_general(void)
|
||||
config_set_int(cat, "window_remember", window_remember);
|
||||
else
|
||||
config_delete_var(cat, "window_remember");
|
||||
|
||||
sprintf(temp, "%i, %i, %i, %i", window_w, window_h, window_x, window_y);
|
||||
config_set_string(cat, "window_coordinates", temp);
|
||||
} else {
|
||||
config_delete_var(cat, "window_remember");
|
||||
config_delete_var(cat, "window_coordinates");
|
||||
}
|
||||
|
||||
if (vid_resize & 2) {
|
||||
@@ -2480,6 +2515,16 @@ save_video(void)
|
||||
else
|
||||
config_set_int(cat, "xga", xga_enabled);
|
||||
|
||||
if (gfxcard_2 == 0)
|
||||
config_delete_var(cat, "gfxcard_2");
|
||||
else
|
||||
config_set_string(cat, "gfxcard_2", video_get_internal_name(gfxcard_2));
|
||||
|
||||
if (show_second_monitors == 1)
|
||||
config_delete_var(cat, "show_second_monitors");
|
||||
else
|
||||
config_set_int(cat, "show_second_monitors", show_second_monitors);
|
||||
|
||||
delete_section_if_empty(cat);
|
||||
}
|
||||
|
||||
@@ -3079,7 +3124,11 @@ save_other_removable_devices(void)
|
||||
void
|
||||
config_save(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
save_general(); /* General */
|
||||
for (i = 0; i < MONITORS_NUM; i++)
|
||||
save_monitor(i);
|
||||
save_machine(); /* Machine */
|
||||
save_video(); /* Video */
|
||||
save_input_devices(); /* Input devices */
|
||||
|
||||
@@ -80,9 +80,11 @@ extern char log_path[1024]; /* (O) full path of logfile */
|
||||
extern char vm_name[1024]; /* (O) display name of the VM */
|
||||
|
||||
|
||||
extern int window_w, window_h, /* (C) window size and */
|
||||
window_x, window_y, /* position info */
|
||||
window_remember,
|
||||
#define window_x monitor_settings[0].mon_window_x
|
||||
#define window_y monitor_settings[0].mon_window_y
|
||||
#define window_w monitor_settings[0].mon_window_w
|
||||
#define window_h monitor_settings[0].mon_window_h
|
||||
extern int window_remember,
|
||||
vid_resize, /* (C) allow resizing */
|
||||
invert_display, /* (C) invert the display */
|
||||
suppress_overscan; /* (C) suppress overscans */
|
||||
@@ -141,9 +143,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 */
|
||||
|
||||
|
||||
@@ -156,7 +155,9 @@ extern void pclog_toggle_suppr(void);
|
||||
extern void pclog(const char *fmt, ...);
|
||||
extern void fatal(const char *fmt, ...);
|
||||
extern void set_screen_size(int x, int y);
|
||||
extern void set_screen_size_monitor(int x, int y, int monitor_index);
|
||||
extern void reset_screen_size(void);
|
||||
extern void reset_screen_size_monitor(int monitor_index);
|
||||
extern void set_screen_size_natural(void);
|
||||
extern void update_mouse_msg();
|
||||
#if 0
|
||||
|
||||
@@ -77,7 +77,6 @@ extern "C" {
|
||||
/* Global variables residing in the platform module. */
|
||||
extern int dopause, /* system is paused */
|
||||
mouse_capture; /* mouse is captured in app */
|
||||
extern atomic_flag_t doresize; /* screen resize requested */
|
||||
extern volatile int is_quit; /* system exit requested */
|
||||
|
||||
#ifdef MTR_ENABLED
|
||||
@@ -90,9 +89,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. */
|
||||
@@ -120,7 +116,8 @@ extern char *plat_vidapi_name(int api);
|
||||
extern int plat_setvid(int api);
|
||||
extern void plat_vidsize(int x, int y);
|
||||
extern void plat_setfullscreen(int on);
|
||||
extern void plat_resize(int x, int y);
|
||||
extern void plat_resize_monitor(int x, int y, int monitor_index);
|
||||
extern void plat_resize(int x, int y);
|
||||
extern void plat_vidapi_enable(int enabled);
|
||||
extern void plat_vidapi_reload(void);
|
||||
extern void plat_vid_reload_options(void);
|
||||
|
||||
@@ -62,6 +62,8 @@ extern void ui_check_menu_item(int id, int checked);
|
||||
|
||||
extern wchar_t *ui_window_title(wchar_t *s);
|
||||
extern void ui_status_update(void);
|
||||
extern void ui_init_monitor(int monitor_index);
|
||||
extern void ui_deinit_monitor(int monitor_index);
|
||||
extern int ui_sb_find_part(int tag);
|
||||
extern void ui_sb_set_ready(int ready);
|
||||
extern void ui_sb_update_panes(void);
|
||||
|
||||
@@ -46,6 +46,8 @@ typedef struct cga_t
|
||||
|
||||
int drawcursor;
|
||||
|
||||
int fullchange;
|
||||
|
||||
uint8_t *vram;
|
||||
|
||||
uint8_t charbuffer[256];
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -51,12 +51,18 @@ typedef struct {
|
||||
int vadj;
|
||||
|
||||
int lp_ff;
|
||||
int fullchange;
|
||||
|
||||
int cols[256][2][2];
|
||||
|
||||
uint8_t *vram;
|
||||
int monitor_index;
|
||||
int prev_monitor_index;
|
||||
} hercules_t;
|
||||
|
||||
#define VIDEO_MONITOR_PROLOGUE() { dev->prev_monitor_index = monitor_index_global; monitor_index_global = dev->monitor_index; }
|
||||
#define VIDEO_MONITOR_EPILOGUE() { monitor_index_global = dev->prev_monitor_index; }
|
||||
|
||||
static void *hercules_init(const device_t *info);
|
||||
|
||||
#endif /*VIDEO_HERCULES_H*/
|
||||
|
||||
@@ -25,11 +25,16 @@ typedef struct mda_t
|
||||
int con, coff, cursoron;
|
||||
int dispon, blink;
|
||||
int vsynctime;
|
||||
int vadj;
|
||||
int vadj;
|
||||
int monitor_index;
|
||||
int prev_monitor_index;
|
||||
|
||||
uint8_t *vram;
|
||||
} mda_t;
|
||||
|
||||
#define VIDEO_MONITOR_PROLOGUE() { mda->prev_monitor_index = monitor_index_global; monitor_index_global = mda->monitor_index; }
|
||||
#define VIDEO_MONITOR_EPILOGUE() { monitor_index_global = mda->prev_monitor_index; }
|
||||
|
||||
void mda_init(mda_t *mda);
|
||||
void mda_setcol(int chr, int blink, int fg, uint8_t cga_ink);
|
||||
void mda_out(uint16_t addr, uint8_t val, void *p);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -22,6 +22,12 @@
|
||||
#ifndef EMU_VIDEO_H
|
||||
# define EMU_VIDEO_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
#include <atomic>
|
||||
using atomic_bool = std::atomic_bool;
|
||||
#else
|
||||
#include <stdatomic.h>
|
||||
#endif
|
||||
|
||||
#define makecol(r, g, b) ((b) | ((g) << 8) | ((r) << 16))
|
||||
#define makecol32(r, g, b) ((b) | ((g) << 8) | ((r) << 16))
|
||||
@@ -79,20 +85,93 @@ 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;
|
||||
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;
|
||||
|
||||
typedef struct monitor_settings_t {
|
||||
int mon_window_x; /* (C) window size and position info. */
|
||||
int mon_window_y;
|
||||
int mon_window_w;
|
||||
int mon_window_h;
|
||||
} monitor_settings_t;
|
||||
|
||||
#define MONITORS_NUM 8
|
||||
extern monitor_t monitors[MONITORS_NUM];
|
||||
extern monitor_settings_t monitor_settings[MONITORS_NUM];
|
||||
extern atomic_bool doresize_monitors[MONITORS_NUM];
|
||||
extern int monitor_index_global;
|
||||
extern int gfxcard_2;
|
||||
extern int show_second_monitors;
|
||||
|
||||
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 +183,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 +200,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
|
||||
@@ -153,34 +220,48 @@ extern const device_t *video_card_getdevice(int card);
|
||||
extern int video_card_has_config(int card);
|
||||
extern char *video_get_internal_name(int card);
|
||||
extern int video_get_video_from_internal_name(char *s);
|
||||
extern int video_card_get_flags(int card);
|
||||
extern int video_is_mda(void);
|
||||
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 void video_inform_monitor(int type, const video_timings_t *ptr, int monitor_index);
|
||||
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);
|
||||
|
||||
extern void video_monitor_init(int);
|
||||
extern void video_monitor_close(int);
|
||||
extern void video_init(void);
|
||||
extern void video_close(void);
|
||||
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);
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@ extern "C"
|
||||
#include <86box/video.h>
|
||||
}
|
||||
|
||||
D3D9Renderer::D3D9Renderer(QWidget *parent)
|
||||
D3D9Renderer::D3D9Renderer(QWidget *parent, int monitor_index)
|
||||
: QWidget{parent}, RendererCommon()
|
||||
{
|
||||
QPalette pal = palette();
|
||||
@@ -27,6 +27,7 @@ D3D9Renderer::D3D9Renderer(QWidget *parent)
|
||||
RendererCommon::parentWidget = parent;
|
||||
|
||||
this->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
|
||||
this->m_monitor_index = monitor_index;
|
||||
}
|
||||
|
||||
D3D9Renderer::~D3D9Renderer()
|
||||
@@ -138,8 +139,8 @@ void D3D9Renderer::resizeEvent(QResizeEvent *event)
|
||||
|
||||
void D3D9Renderer::blit(int x, int y, int w, int h)
|
||||
{
|
||||
if ((x < 0) || (y < 0) || (w <= 0) || (h <= 0) || (w > 2048) || (h > 2048) || (buffer32 == NULL) || surfaceInUse) {
|
||||
video_blit_complete();
|
||||
if ((x < 0) || (y < 0) || (w <= 0) || (h <= 0) || (w > 2048) || (h > 2048) || (monitors[m_monitor_index].target_buffer == NULL) || surfaceInUse) {
|
||||
video_blit_complete_monitor(m_monitor_index);
|
||||
return;
|
||||
}
|
||||
surfaceInUse = true;
|
||||
@@ -152,16 +153,16 @@ void D3D9Renderer::blit(int x, int y, int w, int h)
|
||||
srcRect.right = source.right();
|
||||
|
||||
if (screenshots) {
|
||||
video_screenshot((uint32_t *) &(buffer32->line[y][x]), 0, 0, 2048);
|
||||
video_screenshot_monitor((uint32_t *) &(monitors[m_monitor_index].target_buffer->line[y][x]), 0, 0, 2048, m_monitor_index);
|
||||
}
|
||||
if (SUCCEEDED(d3d9surface->LockRect(&lockRect, &srcRect, 0))) {
|
||||
for (int y1 = 0; y1 < h; y1++) {
|
||||
video_copy(((uint8_t*)lockRect.pBits) + (y1 * lockRect.Pitch), &(buffer32->line[y + y1][x]), w * 4);
|
||||
video_copy(((uint8_t*)lockRect.pBits) + (y1 * lockRect.Pitch), &(monitors[m_monitor_index].target_buffer->line[y + y1][x]), w * 4);
|
||||
}
|
||||
video_blit_complete();
|
||||
video_blit_complete_monitor(m_monitor_index);
|
||||
d3d9surface->UnlockRect();
|
||||
}
|
||||
else video_blit_complete();
|
||||
else video_blit_complete_monitor(m_monitor_index);
|
||||
surfaceInUse = false;
|
||||
QTimer::singleShot(0, this, [this] { this->update(); });
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@ class D3D9Renderer : public QWidget, public RendererCommon
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit D3D9Renderer(QWidget *parent = nullptr);
|
||||
explicit D3D9Renderer(QWidget *parent = nullptr, int monitor_index = 0);
|
||||
~D3D9Renderer();
|
||||
bool hasBlitFunc() override { return true; }
|
||||
void blit(int x, int y, int w, int h) override;
|
||||
@@ -39,6 +39,7 @@ private:
|
||||
|
||||
std::atomic<bool> surfaceInUse{false}, finalized{false};
|
||||
bool alreadyInitialized = false;
|
||||
int m_monitor_index = 0;
|
||||
};
|
||||
|
||||
#endif // D3D9RENDERER_HPP
|
||||
|
||||
@@ -32,6 +32,7 @@ extern "C" {
|
||||
|
||||
void HardwareRenderer::resizeGL(int w, int h)
|
||||
{
|
||||
m_context->makeCurrent(this);
|
||||
glViewport(0, 0, qRound(w * devicePixelRatio()), qRound(h * devicePixelRatio()));
|
||||
}
|
||||
|
||||
|
||||
@@ -122,19 +122,13 @@ main_thread_fn()
|
||||
/* Just so we dont overload the host OS. */
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(1));
|
||||
}
|
||||
|
||||
/* If needed, handle a screen resize. */
|
||||
if (!atomic_flag_test_and_set(&doresize) && !video_fullscreen && !is_quit) {
|
||||
if (vid_resize & 2)
|
||||
plat_resize(fixed_size_x, fixed_size_y);
|
||||
else
|
||||
plat_resize(scrnsz_x, scrnsz_y);
|
||||
}
|
||||
}
|
||||
|
||||
is_quit = 1;
|
||||
}
|
||||
|
||||
static std::thread* main_thread;
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
|
||||
QApplication::setAttribute(Qt::AA_DisableHighDpiScaling, false);
|
||||
@@ -258,7 +252,7 @@ int main(int argc, char* argv[]) {
|
||||
main_window->installEventFilter(&socket);
|
||||
socket.connectToServer(qgetenv("86BOX_MANAGER_SOCKET"));
|
||||
}
|
||||
pc_reset_hard_init();
|
||||
//pc_reset_hard_init();
|
||||
|
||||
/* Set the PAUSE mode depending on the renderer. */
|
||||
// plat_pause(0);
|
||||
@@ -284,13 +278,38 @@ int main(int argc, char* argv[]) {
|
||||
}
|
||||
|
||||
/* Initialize the rendering window, or fullscreen. */
|
||||
auto main_thread = std::thread([] {
|
||||
main_thread_fn();
|
||||
QTimer::singleShot(0, &app, []
|
||||
{
|
||||
pc_reset_hard_init();
|
||||
main_thread = new std::thread(main_thread_fn);
|
||||
});
|
||||
|
||||
QTimer resizeTimer;
|
||||
resizeTimer.setInterval(0);
|
||||
resizeTimer.callOnTimeout([]()
|
||||
{
|
||||
/* If needed, handle a screen resize. */
|
||||
for (int i = 0; i < MONITORS_NUM; i++) {
|
||||
if (!monitors[i].target_buffer) continue;
|
||||
if (atomic_load(&doresize_monitors[i]) == 1 && !video_fullscreen && !is_quit) {
|
||||
if (vid_resize & 2)
|
||||
plat_resize_monitor(fixed_size_x, fixed_size_y, i);
|
||||
else
|
||||
plat_resize_monitor(monitors[i].mon_scrnsz_x, monitors[i].mon_scrnsz_y, i);
|
||||
atomic_store(&doresize_monitors[i], 0);
|
||||
}
|
||||
}
|
||||
|
||||
if (is_quit) {
|
||||
QApplication::quit();
|
||||
}
|
||||
});
|
||||
resizeTimer.start();
|
||||
|
||||
auto ret = app.exec();
|
||||
cpu_thread_run = 0;
|
||||
main_thread.join();
|
||||
main_thread->join();
|
||||
pc_close(nullptr);
|
||||
|
||||
socket.close();
|
||||
return ret;
|
||||
|
||||
@@ -20,6 +20,8 @@
|
||||
* Copyright 2021-2022 Teemu Korhonen
|
||||
* Copyright 2022 dob205
|
||||
*/
|
||||
#include <QDebug>
|
||||
|
||||
#include "qt_mainwindow.hpp"
|
||||
#include "ui_qt_mainwindow.h"
|
||||
|
||||
@@ -61,6 +63,7 @@ extern "C" {
|
||||
#include <QPushButton>
|
||||
#include <QDesktopServices>
|
||||
#include <QUrl>
|
||||
#include <QMenuBar>
|
||||
#include <QCheckBox>
|
||||
#include <QActionGroup>
|
||||
#include <QOpenGLContext>
|
||||
@@ -120,7 +123,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),
|
||||
@@ -140,7 +143,7 @@ MainWindow::MainWindow(QWidget *parent) :
|
||||
statusBar()->setVisible(!hide_status_bar);
|
||||
statusBar()->setStyleSheet("QStatusBar::item {border: None; } QStatusBar QLabel { margin-right: 2px; margin-bottom: 1px; }");
|
||||
ui->toolBar->setVisible(!hide_tool_bar);
|
||||
|
||||
renderers[0].reset(nullptr);
|
||||
auto toolbar_spacer = new QWidget();
|
||||
toolbar_spacer->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
|
||||
ui->toolBar->addWidget(toolbar_spacer);
|
||||
@@ -225,7 +228,7 @@ MainWindow::MainWindow(QWidget *parent) :
|
||||
});
|
||||
|
||||
connect(this, &MainWindow::resizeContents, this, [this](int w, int h) {
|
||||
if (!QApplication::platformName().contains("eglfs") && vid_resize == 0) {
|
||||
if (!QApplication::platformName().contains("eglfs") && vid_resize != 1) {
|
||||
w = (w / (!dpi_scale ? util::screenOfWidget(this)->devicePixelRatio() : 1.));
|
||||
|
||||
int modifiedHeight = (h / (!dpi_scale ? util::screenOfWidget(this)->devicePixelRatio() : 1.))
|
||||
@@ -238,6 +241,18 @@ MainWindow::MainWindow(QWidget *parent) :
|
||||
}
|
||||
});
|
||||
|
||||
connect(this, &MainWindow::resizeContentsMonitor, this, [this](int w, int h, int monitor_index)
|
||||
{
|
||||
if (!QApplication::platformName().contains("eglfs") && vid_resize != 1) {
|
||||
qDebug() << "Resize";
|
||||
w = (w / (!dpi_scale ? util::screenOfWidget(renderers[monitor_index].get())->devicePixelRatio() : 1.));
|
||||
|
||||
int modifiedHeight = (h / (!dpi_scale ? util::screenOfWidget(renderers[monitor_index].get())->devicePixelRatio() : 1.));
|
||||
|
||||
renderers[monitor_index]->setFixedSize(w, modifiedHeight);
|
||||
}
|
||||
});
|
||||
|
||||
connect(ui->menubar, &QMenuBar::triggered, this, [this] {
|
||||
config_save();
|
||||
if (QApplication::activeWindow() == this)
|
||||
@@ -263,6 +278,7 @@ MainWindow::MainWindow(QWidget *parent) :
|
||||
ui->actionHiDPI_scaling->setChecked(dpi_scale);
|
||||
ui->actionHide_status_bar->setChecked(hide_status_bar);
|
||||
ui->actionHide_tool_bar->setChecked(hide_tool_bar);
|
||||
ui->actionShow_non_primary_monitors->setChecked(show_second_monitors);
|
||||
ui->actionUpdate_status_bar_icons->setChecked(update_icons);
|
||||
ui->actionEnable_Discord_integration->setChecked(enable_discord);
|
||||
|
||||
@@ -305,27 +321,33 @@ MainWindow::MainWindow(QWidget *parent) :
|
||||
|
||||
connect(actGroup, &QActionGroup::triggered, [this](QAction* action) {
|
||||
vid_api = action->property("vid_api").toInt();
|
||||
RendererStack::Renderer newVidApi = RendererStack::Renderer::Software;
|
||||
switch (vid_api)
|
||||
{
|
||||
case 0:
|
||||
ui->stackedWidget->switchRenderer(RendererStack::Renderer::Software);
|
||||
newVidApi = RendererStack::Renderer::Software;
|
||||
break;
|
||||
case 1:
|
||||
ui->stackedWidget->switchRenderer(RendererStack::Renderer::OpenGL);
|
||||
newVidApi = (RendererStack::Renderer::OpenGL);
|
||||
break;
|
||||
case 2:
|
||||
ui->stackedWidget->switchRenderer(RendererStack::Renderer::OpenGLES);
|
||||
newVidApi = (RendererStack::Renderer::OpenGLES);
|
||||
break;
|
||||
case 3:
|
||||
ui->stackedWidget->switchRenderer(RendererStack::Renderer::OpenGL3);
|
||||
newVidApi = (RendererStack::Renderer::OpenGL3);
|
||||
break;
|
||||
case 4:
|
||||
ui->stackedWidget->switchRenderer(RendererStack::Renderer::Vulkan);
|
||||
newVidApi = (RendererStack::Renderer::Vulkan);
|
||||
break;
|
||||
case 5:
|
||||
ui->stackedWidget->switchRenderer(RendererStack::Renderer::Direct3D9);
|
||||
newVidApi = (RendererStack::Renderer::Direct3D9);
|
||||
break;
|
||||
}
|
||||
ui->stackedWidget->switchRenderer(newVidApi);
|
||||
if (!show_second_monitors) return;
|
||||
for (int i = 1; i < MONITORS_NUM; i++) {
|
||||
if (renderers[i]) renderers[i]->switchRenderer(newVidApi);
|
||||
}
|
||||
});
|
||||
|
||||
connect(ui->stackedWidget, &RendererStack::rendererChanged, [this]() {
|
||||
@@ -495,6 +517,11 @@ MainWindow::MainWindow(QWidget *parent) :
|
||||
#endif
|
||||
|
||||
setContextMenuPolicy(Qt::PreventContextMenu);
|
||||
|
||||
connect(this, &MainWindow::initRendererMonitor, this, &MainWindow::initRendererMonitorSlot);
|
||||
connect(this, &MainWindow::initRendererMonitorForNonQtThread, this, &MainWindow::initRendererMonitorSlot, Qt::BlockingQueuedConnection);
|
||||
connect(this, &MainWindow::destroyRendererMonitor, this, &MainWindow::destroyRendererMonitorSlot);
|
||||
connect(this, &MainWindow::destroyRendererMonitorForNonQtThread, this, &MainWindow::destroyRendererMonitorSlot, Qt::BlockingQueuedConnection);
|
||||
}
|
||||
|
||||
void MainWindow::closeEvent(QCloseEvent *event) {
|
||||
@@ -527,18 +554,74 @@ void MainWindow::closeEvent(QCloseEvent *event) {
|
||||
window_x = this->geometry().x();
|
||||
window_y = this->geometry().y();
|
||||
}
|
||||
for (int i = 1; i < MONITORS_NUM; i++) {
|
||||
if (renderers[i]) {
|
||||
monitor_settings[i].mon_window_w = renderers[i]->geometry().width();
|
||||
monitor_settings[i].mon_window_h = renderers[i]->geometry().height();
|
||||
if (!QApplication::platformName().contains("wayland")) continue;
|
||||
monitor_settings[i].mon_window_x = renderers[i]->geometry().x();
|
||||
monitor_settings[i].mon_window_y = renderers[i]->geometry().y();
|
||||
}
|
||||
}
|
||||
}
|
||||
qt_nvr_save();
|
||||
config_save();
|
||||
|
||||
if (ui->stackedWidget->mouse_exit_func)
|
||||
ui->stackedWidget->mouse_exit_func();
|
||||
|
||||
ui->stackedWidget->switchRenderer(RendererStack::Renderer::Software);
|
||||
|
||||
qt_nvr_save();
|
||||
config_save();
|
||||
QApplication::processEvents();
|
||||
cpu_thread_run = 0;
|
||||
event->accept();
|
||||
}
|
||||
|
||||
void MainWindow::initRendererMonitorSlot(int monitor_index)
|
||||
{
|
||||
auto& secondaryRenderer = this->renderers[monitor_index];
|
||||
secondaryRenderer.reset(new RendererStack(nullptr, monitor_index));
|
||||
if (secondaryRenderer) {
|
||||
connect(this, &MainWindow::pollMouse, secondaryRenderer.get(), &RendererStack::mousePoll, Qt::DirectConnection);
|
||||
connect(secondaryRenderer.get(), &RendererStack::rendererChanged, this, [this, monitor_index]
|
||||
{
|
||||
this->renderers[monitor_index]->show();
|
||||
});
|
||||
secondaryRenderer->setWindowFlags(Qt::CustomizeWindowHint | Qt::WindowTitleHint | Qt::WindowCloseButtonHint);
|
||||
secondaryRenderer->setWindowTitle(QObject::tr("86Box Monitor #") + QString::number(monitor_index + 1));
|
||||
|
||||
if (vid_resize == 2) {
|
||||
secondaryRenderer->setFixedSize(fixed_size_x, fixed_size_y);
|
||||
}
|
||||
secondaryRenderer->setWindowIcon(this->windowIcon());
|
||||
if (show_second_monitors) {
|
||||
secondaryRenderer->show();
|
||||
if (window_remember) {
|
||||
secondaryRenderer->setGeometry(monitor_settings[monitor_index].mon_window_x < 120 ? 120 : monitor_settings[monitor_index].mon_window_x,
|
||||
monitor_settings[monitor_index].mon_window_y < 120 ? 120 : monitor_settings[monitor_index].mon_window_y,
|
||||
monitor_settings[monitor_index].mon_window_w > 2048 ? 2048 : monitor_settings[monitor_index].mon_window_w,
|
||||
monitor_settings[monitor_index].mon_window_h > 2048 ? 2048 : monitor_settings[monitor_index].mon_window_h);
|
||||
}
|
||||
secondaryRenderer->switchRenderer((RendererStack::Renderer)vid_api);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void MainWindow::destroyRendererMonitorSlot(int monitor_index)
|
||||
{
|
||||
if (this->renderers[monitor_index]) {
|
||||
if (window_remember) {
|
||||
monitor_settings[monitor_index].mon_window_w = renderers[monitor_index]->geometry().width();
|
||||
monitor_settings[monitor_index].mon_window_h = renderers[monitor_index]->geometry().height();
|
||||
monitor_settings[monitor_index].mon_window_x = renderers[monitor_index]->geometry().x();
|
||||
monitor_settings[monitor_index].mon_window_y = renderers[monitor_index]->geometry().y();
|
||||
}
|
||||
config_save();
|
||||
this->renderers[monitor_index].release()->deleteLater();
|
||||
}
|
||||
}
|
||||
|
||||
MainWindow::~MainWindow() {
|
||||
delete ui;
|
||||
}
|
||||
@@ -546,6 +629,7 @@ MainWindow::~MainWindow() {
|
||||
void MainWindow::showEvent(QShowEvent *event) {
|
||||
if (shownonce) return;
|
||||
shownonce = true;
|
||||
if (window_remember) resize(window_w, window_h + menuBar()->height() + (hide_status_bar ? 0 : statusBar()->height()) + (hide_tool_bar ? 0 : ui->toolBar->height()));
|
||||
if (window_remember && !QApplication::platformName().contains("wayland")) {
|
||||
setGeometry(window_x, window_y, window_w, window_h + menuBar()->height() + (hide_status_bar ? 0 : statusBar()->height()) + (hide_tool_bar ? 0 : ui->toolBar->height()));
|
||||
}
|
||||
@@ -555,15 +639,8 @@ void MainWindow::showEvent(QShowEvent *event) {
|
||||
+ (hide_status_bar ? 0 : statusBar()->height())
|
||||
+ (hide_tool_bar ? 0 : ui->toolBar->height()));
|
||||
|
||||
scrnsz_x = fixed_size_x;
|
||||
scrnsz_y = fixed_size_y;
|
||||
}
|
||||
else if (window_remember && vid_resize == 1) {
|
||||
ui->stackedWidget->setFixedSize(window_w, window_h);
|
||||
adjustSize();
|
||||
ui->stackedWidget->setFixedSize(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX);
|
||||
scrnsz_x = window_w;
|
||||
scrnsz_y = window_h;
|
||||
monitors[0].mon_scrnsz_x = fixed_size_x;
|
||||
monitors[0].mon_scrnsz_y = fixed_size_y;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1361,7 +1438,7 @@ void MainWindow::on_actionFullscreen_triggered() {
|
||||
+ (!hide_status_bar ? statusBar()->height() : 0)
|
||||
+ (!hide_tool_bar ? ui->toolBar->height() : 0));
|
||||
|
||||
emit resizeContents(scrnsz_x, scrnsz_y);
|
||||
emit resizeContents(monitors[0].mon_scrnsz_x, monitors[0].mon_scrnsz_y);
|
||||
}
|
||||
} else {
|
||||
if (video_fullscreen_first)
|
||||
@@ -1495,9 +1572,13 @@ void MainWindow::keyPressEvent(QKeyEvent* event)
|
||||
event->accept();
|
||||
}
|
||||
|
||||
void MainWindow::blitToWidget(int x, int y, int w, int h)
|
||||
void MainWindow::blitToWidget(int x, int y, int w, int h, int monitor_index)
|
||||
{
|
||||
ui->stackedWidget->blit(x, y, w, h);
|
||||
if (monitor_index >= 1) {
|
||||
if (renderers[monitor_index]) renderers[monitor_index]->blit(x, y, w, h);
|
||||
else video_blit_complete_monitor(monitor_index);
|
||||
}
|
||||
else ui->stackedWidget->blit(x, y, w, h);
|
||||
}
|
||||
|
||||
void MainWindow::keyReleaseEvent(QKeyEvent* event)
|
||||
@@ -1536,16 +1617,34 @@ void MainWindow::on_actionResizable_window_triggered(bool checked) {
|
||||
setWindowFlag(Qt::WindowMaximizeButtonHint);
|
||||
setWindowFlag(Qt::MSWindowsFixedSizeDialogHint, false);
|
||||
setFixedSize(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX);
|
||||
for (int i = 1; i < MONITORS_NUM; i++) {
|
||||
if (monitors[i].target_buffer) {
|
||||
renderers[i]->setWindowFlag(Qt::WindowMaximizeButtonHint);
|
||||
renderers[i]->setFixedSize(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
vid_resize = 0;
|
||||
setWindowFlag(Qt::WindowMaximizeButtonHint, false);
|
||||
setWindowFlag(Qt::MSWindowsFixedSizeDialogHint);
|
||||
for (int i = 1; i < MONITORS_NUM; i++) {
|
||||
if (monitors[i].target_buffer) {
|
||||
renderers[i]->setWindowFlag(Qt::WindowMaximizeButtonHint, false);
|
||||
emit resizeContentsMonitor(monitors[i].mon_scrnsz_x, monitors[i].mon_scrnsz_y, i);
|
||||
}
|
||||
}
|
||||
}
|
||||
show();
|
||||
ui->stackedWidget->switchRenderer((RendererStack::Renderer)vid_api);
|
||||
|
||||
ui->menuWindow_scale_factor->setEnabled(! checked);
|
||||
emit resizeContents(scrnsz_x, scrnsz_y);
|
||||
emit resizeContents(monitors[0].mon_scrnsz_x, monitors[0].mon_scrnsz_y);
|
||||
ui->stackedWidget->switchRenderer((RendererStack::Renderer)vid_api);
|
||||
for (int i = 1; i < MONITORS_NUM; i++) {
|
||||
if (monitors[i].target_buffer && show_second_monitors) {
|
||||
renderers[i]->show();
|
||||
renderers[i]->switchRenderer((RendererStack::Renderer)vid_api);
|
||||
QApplication::processEvents();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -1558,6 +1657,9 @@ video_toggle_option(QAction* action, int *val)
|
||||
endblit();
|
||||
config_save();
|
||||
device_force_redraw();
|
||||
for (int i = 0; i < MONITORS_NUM; i++) {
|
||||
if (monitors[i].target_buffer) video_force_resize_set_monitor(1, i);
|
||||
}
|
||||
}
|
||||
|
||||
void MainWindow::on_actionInverted_VGA_monitor_triggered() {
|
||||
@@ -1572,8 +1674,9 @@ static void update_scaled_checkboxes(Ui::MainWindow* ui, QAction* selected) {
|
||||
|
||||
reset_screen_size();
|
||||
device_force_redraw();
|
||||
video_force_resize_set(1);
|
||||
atomic_flag_clear(&doresize);
|
||||
for (int i = 0; i < MONITORS_NUM; i++) {
|
||||
if (monitors[i].target_buffer) video_force_resize_set_monitor(1, i);
|
||||
}
|
||||
config_save();
|
||||
}
|
||||
|
||||
@@ -1752,7 +1855,6 @@ void MainWindow::on_actionChange_contrast_for_monochrome_display_triggered() {
|
||||
|
||||
void MainWindow::on_actionForce_4_3_display_ratio_triggered() {
|
||||
video_toggle_option(ui->actionForce_4_3_display_ratio, &force_43);
|
||||
video_force_resize_set(1);
|
||||
}
|
||||
|
||||
void MainWindow::on_actionRemember_size_and_position_triggered()
|
||||
@@ -1764,6 +1866,14 @@ void MainWindow::on_actionRemember_size_and_position_triggered()
|
||||
window_x = geometry().x();
|
||||
window_y = geometry().y();
|
||||
}
|
||||
for (int i = 1; i < MONITORS_NUM; i++) {
|
||||
if (window_remember && renderers[i]) {
|
||||
monitor_settings[i].mon_window_w = renderers[i]->geometry().width();
|
||||
monitor_settings[i].mon_window_h = renderers[i]->geometry().height();
|
||||
monitor_settings[i].mon_window_x = renderers[i]->geometry().x();
|
||||
monitor_settings[i].mon_window_y = renderers[i]->geometry().y();
|
||||
}
|
||||
}
|
||||
ui->actionRemember_size_and_position->setChecked(window_remember);
|
||||
}
|
||||
|
||||
@@ -1778,7 +1888,10 @@ void MainWindow::on_actionHiDPI_scaling_triggered()
|
||||
{
|
||||
dpi_scale ^= 1;
|
||||
ui->actionHiDPI_scaling->setChecked(dpi_scale);
|
||||
emit resizeContents(scrnsz_x, scrnsz_y);
|
||||
emit resizeContents(monitors[0].mon_scrnsz_x, monitors[0].mon_scrnsz_y);
|
||||
for (int i = 1; i < MONITORS_NUM; i++) {
|
||||
if (renderers[i]) emit resizeContentsMonitor(monitors[i].mon_scrnsz_x, monitors[i].mon_scrnsz_y, i);
|
||||
}
|
||||
}
|
||||
|
||||
void MainWindow::on_actionHide_status_bar_triggered()
|
||||
@@ -1794,7 +1907,7 @@ void MainWindow::on_actionHide_status_bar_triggered()
|
||||
} else {
|
||||
int vid_resize_orig = vid_resize;
|
||||
vid_resize = 0;
|
||||
emit resizeContents(scrnsz_x, scrnsz_y);
|
||||
emit resizeContents(monitors[0].mon_scrnsz_x, monitors[0].mon_scrnsz_y);
|
||||
vid_resize = vid_resize_orig;
|
||||
}
|
||||
}
|
||||
@@ -1812,7 +1925,7 @@ void MainWindow::on_actionHide_tool_bar_triggered()
|
||||
} else {
|
||||
int vid_resize_orig = vid_resize;
|
||||
vid_resize = 0;
|
||||
emit resizeContents(scrnsz_x, scrnsz_y);
|
||||
emit resizeContents(monitors[0].mon_scrnsz_x, monitors[0].mon_scrnsz_y);
|
||||
vid_resize = vid_resize_orig;
|
||||
}
|
||||
}
|
||||
@@ -1826,7 +1939,8 @@ void MainWindow::on_actionUpdate_status_bar_icons_triggered()
|
||||
void MainWindow::on_actionTake_screenshot_triggered()
|
||||
{
|
||||
startblit();
|
||||
screenshots++;
|
||||
for (int i = 0; i < MONITORS_NUM; i++)
|
||||
monitors[i].mon_screenshots++;
|
||||
endblit();
|
||||
device_force_redraw();
|
||||
}
|
||||
@@ -1892,8 +2006,13 @@ void MainWindow::on_actionRenderer_options_triggered()
|
||||
{
|
||||
auto dlg = ui->stackedWidget->getOptions(this);
|
||||
|
||||
if (dlg)
|
||||
dlg->exec();
|
||||
if (dlg) {
|
||||
if (dlg->exec() == QDialog::Accepted) {
|
||||
for (int i = 1; i < MONITORS_NUM; i++) {
|
||||
if (renderers[i] && renderers[i]->hasOptions()) renderers[i]->reloadOptions();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void MainWindow::on_actionMCA_devices_triggered()
|
||||
@@ -1904,3 +2023,36 @@ void MainWindow::on_actionMCA_devices_triggered()
|
||||
dlg->exec();
|
||||
}
|
||||
|
||||
|
||||
void MainWindow::on_actionShow_non_primary_monitors_triggered()
|
||||
{
|
||||
show_second_monitors ^= 1;
|
||||
|
||||
if (show_second_monitors) {
|
||||
for (int monitor_index = 1; monitor_index < MONITORS_NUM; monitor_index++) {
|
||||
auto& secondaryRenderer = renderers[monitor_index];
|
||||
if (!renderers[monitor_index]) continue;
|
||||
secondaryRenderer->show();
|
||||
if (window_remember) {
|
||||
secondaryRenderer->setGeometry(monitor_settings[monitor_index].mon_window_x < 120 ? 120 : monitor_settings[monitor_index].mon_window_x,
|
||||
monitor_settings[monitor_index].mon_window_y < 120 ? 120 : monitor_settings[monitor_index].mon_window_y,
|
||||
monitor_settings[monitor_index].mon_window_w > 2048 ? 2048 : monitor_settings[monitor_index].mon_window_w,
|
||||
monitor_settings[monitor_index].mon_window_h > 2048 ? 2048 : monitor_settings[monitor_index].mon_window_h);
|
||||
}
|
||||
secondaryRenderer->switchRenderer((RendererStack::Renderer)vid_api);
|
||||
}
|
||||
} else {
|
||||
for (int monitor_index = 1; monitor_index < MONITORS_NUM; monitor_index++) {
|
||||
auto& secondaryRenderer = renderers[monitor_index];
|
||||
if (!renderers[monitor_index]) continue;
|
||||
secondaryRenderer->hide();
|
||||
if (window_remember && renderers[monitor_index]) {
|
||||
monitor_settings[monitor_index].mon_window_w = renderers[monitor_index]->geometry().width();
|
||||
monitor_settings[monitor_index].mon_window_h = renderers[monitor_index]->geometry().height();
|
||||
monitor_settings[monitor_index].mon_window_x = renderers[monitor_index]->geometry().x();
|
||||
monitor_settings[monitor_index].mon_window_y = renderers[monitor_index]->geometry().y();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#include <memory>
|
||||
|
||||
class MediaMenu;
|
||||
class RendererStack;
|
||||
|
||||
namespace Ui {
|
||||
class MainWindow;
|
||||
@@ -26,12 +27,13 @@ public:
|
||||
|
||||
void showMessage(int flags, const QString& header, const QString& message);
|
||||
void getTitle(wchar_t* title);
|
||||
void blitToWidget(int x, int y, int w, int h);
|
||||
void blitToWidget(int x, int y, int w, int h, int monitor_index);
|
||||
QSize getRenderWidgetSize();
|
||||
void setSendKeyboardInput(bool enabled);
|
||||
signals:
|
||||
void paint(const QImage& image);
|
||||
void resizeContents(int w, int h);
|
||||
void resizeContentsMonitor(int w, int h, int monitor_index);
|
||||
void pollMouse();
|
||||
void statusBarMessage(const QString& msg);
|
||||
void updateStatusBarPanes();
|
||||
@@ -40,6 +42,10 @@ signals:
|
||||
void updateStatusBarTip(int tag);
|
||||
void updateMenuResizeOptions();
|
||||
void updateWindowRememberOption();
|
||||
void initRendererMonitor(int monitor_index);
|
||||
void destroyRendererMonitor(int monitor_index);
|
||||
void initRendererMonitorForNonQtThread(int monitor_index);
|
||||
void destroyRendererMonitorForNonQtThread(int monitor_index);
|
||||
|
||||
void setTitle(const QString& title);
|
||||
void setFullscreen(bool state);
|
||||
@@ -51,6 +57,8 @@ public slots:
|
||||
void showSettings();
|
||||
void hardReset();
|
||||
void togglePause();
|
||||
void initRendererMonitorSlot(int monitor_index);
|
||||
void destroyRendererMonitorSlot(int monitor_index);
|
||||
private slots:
|
||||
void on_actionFullscreen_triggered();
|
||||
void on_actionSettings_triggered();
|
||||
@@ -115,9 +123,13 @@ protected:
|
||||
void closeEvent(QCloseEvent* event) override;
|
||||
void changeEvent(QEvent* event) override;
|
||||
|
||||
private slots:
|
||||
void on_actionShow_non_primary_monitors_triggered();
|
||||
|
||||
private:
|
||||
Ui::MainWindow *ui;
|
||||
std::unique_ptr<MachineStatus> status;
|
||||
std::array<std::unique_ptr<RendererStack>, 8> renderers;
|
||||
std::shared_ptr<MediaMenu> mm;
|
||||
|
||||
#ifdef Q_OS_MACOS
|
||||
|
||||
@@ -54,7 +54,7 @@
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>724</width>
|
||||
<height>21</height>
|
||||
<height>23</height>
|
||||
</rect>
|
||||
</property>
|
||||
<widget class="QMenu" name="menuAction">
|
||||
@@ -161,6 +161,7 @@
|
||||
<addaction name="actionHide_tool_bar"/>
|
||||
<addaction name="actionHide_status_bar"/>
|
||||
<addaction name="separator"/>
|
||||
<addaction name="actionShow_non_primary_monitors"/>
|
||||
<addaction name="actionResizable_window"/>
|
||||
<addaction name="actionRemember_size_and_position"/>
|
||||
<addaction name="separator"/>
|
||||
@@ -757,6 +758,14 @@
|
||||
<number>5</number>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionShow_non_primary_monitors">
|
||||
<property name="checkable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Show non-primary monitors</string>
|
||||
</property>
|
||||
</action>
|
||||
</widget>
|
||||
<customwidgets>
|
||||
<customwidget>
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
OpenGLRenderer::OpenGLRenderer(QWidget *parent)
|
||||
: QWindow(parent->windowHandle())
|
||||
, renderTimer(new QTimer(this))
|
||||
, options(nullptr)
|
||||
{
|
||||
renderTimer->setTimerType(Qt::PreciseTimer);
|
||||
/* TODO: need's more accuracy, maybe target 1ms earlier and spin yield */
|
||||
@@ -165,9 +166,7 @@ OpenGLRenderer::initialize()
|
||||
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, QOpenGLTexture::RGBA8_UNorm, INIT_WIDTH, INIT_HEIGHT, 0, QOpenGLTexture::BGRA, QOpenGLTexture::UInt32_RGBA8_Rev, NULL);
|
||||
|
||||
options = new OpenGLOptions(this, true, glslVersion);
|
||||
|
||||
applyOptions();
|
||||
reloadOptions();
|
||||
|
||||
glClearColor(0.f, 0.f, 0.f, 1.f);
|
||||
|
||||
@@ -304,6 +303,15 @@ OpenGLRenderer::applyOptions()
|
||||
currentFilter = options->filter();
|
||||
}
|
||||
|
||||
void
|
||||
OpenGLRenderer::reloadOptions()
|
||||
{
|
||||
if (options) { delete options; options = nullptr; }
|
||||
options = new OpenGLOptions(this, true, glslVersion);
|
||||
|
||||
applyOptions();
|
||||
}
|
||||
|
||||
void
|
||||
OpenGLRenderer::applyShader(const OpenGLShaderPass &shader)
|
||||
{
|
||||
|
||||
@@ -53,6 +53,7 @@ public:
|
||||
void finalize() override final;
|
||||
bool hasOptions() const override { return true; }
|
||||
QDialog *getOptions(QWidget *parent) override;
|
||||
void reloadOptions() override;
|
||||
|
||||
signals:
|
||||
void initialized();
|
||||
|
||||
@@ -52,7 +52,7 @@ extern MainWindow* main_window;
|
||||
QElapsedTimer elapsed_timer;
|
||||
|
||||
static std::atomic_int blitmx_contention = 0;
|
||||
static std::mutex blitmx;
|
||||
static std::recursive_mutex blitmx;
|
||||
|
||||
class CharPointer {
|
||||
public:
|
||||
|
||||
@@ -28,6 +28,8 @@ public:
|
||||
virtual bool hasOptions() const { return false; }
|
||||
/* Returns options dialog for renderer */
|
||||
virtual QDialog *getOptions(QWidget *parent) { return nullptr; }
|
||||
/* Reloads options of renderer */
|
||||
virtual void reloadOptions() {}
|
||||
|
||||
virtual bool hasBlitFunc() { return false; }
|
||||
virtual void blit(int x, int y, int w, int h) {}
|
||||
|
||||
@@ -44,6 +44,7 @@
|
||||
#endif
|
||||
|
||||
extern "C" {
|
||||
#include <86box/86box.h>
|
||||
#include <86box/mouse.h>
|
||||
#include <86box/plat.h>
|
||||
#include <86box/video.h>
|
||||
@@ -51,14 +52,21 @@ extern "C" {
|
||||
double mouse_sensitivity = 1.0;
|
||||
}
|
||||
|
||||
struct mouseinputdata {
|
||||
int deltax, deltay, deltaz;
|
||||
int mousebuttons;
|
||||
};
|
||||
static mouseinputdata mousedata;
|
||||
|
||||
extern "C" void macos_poll_mouse();
|
||||
extern MainWindow *main_window;
|
||||
RendererStack::RendererStack(QWidget *parent)
|
||||
RendererStack::RendererStack(QWidget *parent, int monitor_index)
|
||||
: QStackedWidget(parent)
|
||||
, ui(new Ui::RendererStack)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
|
||||
m_monitor_index = monitor_index;
|
||||
#if defined __unix__ && !defined __HAIKU__
|
||||
char *mouse_type = getenv("EMU86BOX_MOUSE"), auto_mouse_type[16];
|
||||
if (!mouse_type || (mouse_type[0] == '\0') || !stricmp(mouse_type, "auto")) {
|
||||
@@ -313,7 +321,7 @@ RendererStack::createRenderer(Renderer renderer)
|
||||
case Renderer::Direct3D9:
|
||||
{
|
||||
this->createWinId();
|
||||
auto hw = new D3D9Renderer(this);
|
||||
auto hw = new D3D9Renderer(this, m_monitor_index);
|
||||
rendererWindow = hw;
|
||||
connect(hw, &D3D9Renderer::error, this, [this](QString str)
|
||||
{
|
||||
@@ -398,14 +406,14 @@ RendererStack::createRenderer(Renderer renderer)
|
||||
void
|
||||
RendererStack::blitDummy(int x, int y, int w, int h)
|
||||
{
|
||||
video_blit_complete();
|
||||
video_blit_complete_monitor(m_monitor_index);
|
||||
blitDummied = true;
|
||||
}
|
||||
|
||||
void
|
||||
RendererStack::blitRenderer(int x, int y, int w, int h)
|
||||
{
|
||||
if (blitDummied) { blitDummied = false; video_blit_complete(); return; }
|
||||
if (blitDummied) { blitDummied = false; video_blit_complete_monitor(m_monitor_index); return; }
|
||||
directBlitting = true;
|
||||
rendererWindow->blit(x, y, w, h);
|
||||
directBlitting = false;
|
||||
@@ -415,8 +423,8 @@ RendererStack::blitRenderer(int x, int y, int w, int h)
|
||||
void
|
||||
RendererStack::blitCommon(int x, int y, int w, int h)
|
||||
{
|
||||
if ((x < 0) || (y < 0) || (w <= 0) || (h <= 0) || (w > 2048) || (h > 2048) || (buffer32 == NULL) || imagebufs.empty() || std::get<std::atomic_flag *>(imagebufs[currentBuf])->test_and_set() || blitDummied) {
|
||||
video_blit_complete();
|
||||
if ((x < 0) || (y < 0) || (w <= 0) || (h <= 0) || (w > 2048) || (h > 2048) || (monitors[m_monitor_index].target_buffer == NULL) || imagebufs.empty() || std::get<std::atomic_flag *>(imagebufs[currentBuf])->test_and_set() || blitDummied) {
|
||||
video_blit_complete_monitor(m_monitor_index);
|
||||
return;
|
||||
}
|
||||
sx = x;
|
||||
@@ -426,13 +434,21 @@ RendererStack::blitCommon(int x, int y, int w, int h)
|
||||
uint8_t *imagebits = std::get<uint8_t *>(imagebufs[currentBuf]);
|
||||
for (int y1 = y; y1 < (y + h); y1++) {
|
||||
auto scanline = imagebits + (y1 * rendererWindow->getBytesPerRow()) + (x * 4);
|
||||
video_copy(scanline, &(buffer32->line[y1][x]), w * 4);
|
||||
video_copy(scanline, &(monitors[m_monitor_index].target_buffer->line[y1][x]), w * 4);
|
||||
}
|
||||
|
||||
if (screenshots) {
|
||||
video_screenshot((uint32_t *) imagebits, x, y, 2048);
|
||||
if (monitors[m_monitor_index].mon_screenshots) {
|
||||
video_screenshot_monitor((uint32_t *) imagebits, x, y, 2048, m_monitor_index);
|
||||
}
|
||||
video_blit_complete();
|
||||
video_blit_complete_monitor(m_monitor_index);
|
||||
emit blitToRenderer(currentBuf, sx, sy, sw, sh);
|
||||
currentBuf = (currentBuf + 1) % imagebufs.size();
|
||||
}
|
||||
|
||||
void RendererStack::closeEvent(QCloseEvent* event)
|
||||
{
|
||||
if (cpu_thread_run == 0 || is_quit == 1) { event->accept(); return; }
|
||||
event->ignore();
|
||||
main_window->close();
|
||||
}
|
||||
|
||||
|
||||
@@ -23,7 +23,7 @@ class RendererStack : public QStackedWidget {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit RendererStack(QWidget *parent = nullptr);
|
||||
explicit RendererStack(QWidget *parent = nullptr, int monitor_index = 0);
|
||||
~RendererStack();
|
||||
|
||||
void mousePressEvent(QMouseEvent *event) override;
|
||||
@@ -31,6 +31,7 @@ public:
|
||||
void mouseMoveEvent(QMouseEvent *event) override;
|
||||
void wheelEvent(QWheelEvent *event) override;
|
||||
void leaveEvent(QEvent *event) override;
|
||||
void closeEvent(QCloseEvent *event) override;
|
||||
void keyPressEvent(QKeyEvent *event) override
|
||||
{
|
||||
event->ignore();
|
||||
@@ -52,6 +53,8 @@ public:
|
||||
|
||||
/* Does current renderer implement options dialog */
|
||||
bool hasOptions() const { return rendererWindow ? rendererWindow->hasOptions() : false; }
|
||||
/* Reloads options of current renderer */
|
||||
void reloadOptions() const { return rendererWindow->reloadOptions(); }
|
||||
/* Returns options dialog for current renderer */
|
||||
QDialog *getOptions(QWidget *parent) { return rendererWindow ? rendererWindow->getOptions(parent) : nullptr; }
|
||||
|
||||
@@ -87,16 +90,11 @@ private:
|
||||
|
||||
Ui::RendererStack *ui;
|
||||
|
||||
struct mouseinputdata {
|
||||
int deltax, deltay, deltaz;
|
||||
int mousebuttons;
|
||||
};
|
||||
mouseinputdata mousedata;
|
||||
|
||||
int x, y, w, h, sx, sy, sw, sh;
|
||||
|
||||
int currentBuf = 0;
|
||||
int isMouseDown = 0;
|
||||
int m_monitor_index = 0;
|
||||
|
||||
std::vector<std::tuple<uint8_t *, std::atomic_flag *>> imagebufs;
|
||||
|
||||
|
||||
@@ -46,6 +46,7 @@ SettingsDisplay::~SettingsDisplay()
|
||||
|
||||
void SettingsDisplay::save() {
|
||||
gfxcard = ui->comboBoxVideo->currentData().toInt();
|
||||
gfxcard_2 = ui->comboBoxVideoSecondary->currentData().toInt();
|
||||
voodoo_enabled = ui->checkBoxVoodoo->isChecked() ? 1 : 0;
|
||||
ibm8514_enabled = ui->checkBox8514->isChecked() ? 1 : 0;
|
||||
xga_enabled = ui->checkBoxXga->isChecked() ? 1 : 0;
|
||||
@@ -87,11 +88,16 @@ void SettingsDisplay::onCurrentMachineChanged(int machineId) {
|
||||
|
||||
if (machine_has_flags(machineId, MACHINE_VIDEO_ONLY) > 0) {
|
||||
ui->comboBoxVideo->setEnabled(false);
|
||||
ui->comboBoxVideoSecondary->setEnabled(false);
|
||||
ui->pushButtonConfigureSecondary->setEnabled(false);
|
||||
selectedRow = 1;
|
||||
} else {
|
||||
ui->comboBoxVideo->setEnabled(true);
|
||||
ui->comboBoxVideoSecondary->setEnabled(true);
|
||||
ui->pushButtonConfigureSecondary->setEnabled(true);
|
||||
}
|
||||
ui->comboBoxVideo->setCurrentIndex(selectedRow);
|
||||
if (gfxcard_2 == 0) ui->pushButtonConfigureSecondary->setEnabled(false);
|
||||
}
|
||||
|
||||
void SettingsDisplay::on_pushButtonConfigure_clicked() {
|
||||
@@ -137,6 +143,41 @@ void SettingsDisplay::on_comboBoxVideo_currentIndexChanged(int index) {
|
||||
ui->checkBoxXga->setChecked(xga_enabled);
|
||||
|
||||
ui->pushButtonConfigureXga->setEnabled((hasIsa16 || has_MCA) && ui->checkBoxXga->isChecked());
|
||||
|
||||
int c = 2;
|
||||
|
||||
ui->comboBoxVideoSecondary->clear();
|
||||
ui->comboBoxVideoSecondary->addItem(QObject::tr("None"), 0);
|
||||
|
||||
ui->comboBoxVideoSecondary->setCurrentIndex(0);
|
||||
// TODO: Implement support for selecting non-MDA secondary cards properly when MDA cards are the primary ones.
|
||||
if (video_card_get_flags(videoCard) == VIDEO_FLAG_TYPE_MDA) {
|
||||
ui->comboBoxVideoSecondary->setCurrentIndex(0);
|
||||
return;
|
||||
}
|
||||
while (true) {
|
||||
const device_t* video_dev = video_card_getdevice(c);
|
||||
QString name = DeviceConfig::DeviceName(video_dev, video_get_internal_name(c), 1);
|
||||
if (name.isEmpty()) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (video_card_available(c) &&
|
||||
device_is_valid(video_dev, machineId) &&
|
||||
!(video_card_get_flags(c) == video_card_get_flags(videoCard))) {
|
||||
ui->comboBoxVideoSecondary->addItem(name, c);
|
||||
if (c == gfxcard_2)
|
||||
ui->comboBoxVideoSecondary->setCurrentIndex(ui->comboBoxVideoSecondary->count() - 1);
|
||||
}
|
||||
|
||||
c++;
|
||||
}
|
||||
|
||||
if (gfxcard_2 == 0 || (machine_has_flags(machineId, MACHINE_VIDEO_ONLY) > 0))
|
||||
{
|
||||
ui->comboBoxVideoSecondary->setCurrentIndex(0);
|
||||
ui->pushButtonConfigureSecondary->setEnabled(false);
|
||||
}
|
||||
}
|
||||
|
||||
void SettingsDisplay::on_checkBoxVoodoo_stateChanged(int state) {
|
||||
@@ -146,3 +187,21 @@ void SettingsDisplay::on_checkBoxVoodoo_stateChanged(int state) {
|
||||
void SettingsDisplay::on_checkBoxXga_stateChanged(int state) {
|
||||
ui->pushButtonConfigureXga->setEnabled(state == Qt::Checked);
|
||||
}
|
||||
|
||||
void SettingsDisplay::on_comboBoxVideoSecondary_currentIndexChanged(int index)
|
||||
{
|
||||
if (index < 0) {
|
||||
ui->pushButtonConfigureSecondary->setEnabled(false);
|
||||
return;
|
||||
}
|
||||
int videoCard = ui->comboBoxVideoSecondary->currentData().toInt();
|
||||
ui->pushButtonConfigureSecondary->setEnabled(index != 0 && video_card_has_config(videoCard) > 0);
|
||||
}
|
||||
|
||||
|
||||
void SettingsDisplay::on_pushButtonConfigureSecondary_clicked()
|
||||
{
|
||||
auto* device = video_card_getdevice(ui->comboBoxVideoSecondary->currentData().toInt());
|
||||
DeviceConfig::ConfigureDevice(device, 0, qobject_cast<Settings*>(Settings::settings));
|
||||
}
|
||||
|
||||
|
||||
@@ -20,6 +20,12 @@ public:
|
||||
public slots:
|
||||
void onCurrentMachineChanged(int machineId);
|
||||
|
||||
private slots:
|
||||
void on_pushButtonConfigureSecondary_clicked();
|
||||
|
||||
private slots:
|
||||
void on_comboBoxVideoSecondary_currentIndexChanged(int index);
|
||||
|
||||
private slots:
|
||||
void on_checkBoxVoodoo_stateChanged(int state);
|
||||
void on_checkBoxXga_stateChanged(int state);
|
||||
|
||||
@@ -26,16 +26,29 @@
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item row="0" column="1">
|
||||
<widget class="QComboBox" name="comboBoxVideo"/>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label">
|
||||
<item row="3" column="0" colspan="2">
|
||||
<widget class="QCheckBox" name="checkBox8514">
|
||||
<property name="text">
|
||||
<string>Video:</string>
|
||||
<string>8514/A</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="0">
|
||||
<spacer name="verticalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QComboBox" name="comboBoxVideo"/>
|
||||
</item>
|
||||
<item row="0" column="2">
|
||||
<widget class="QPushButton" name="pushButtonConfigure">
|
||||
<property name="sizePolicy">
|
||||
@@ -49,53 +62,57 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="2">
|
||||
<widget class="QPushButton" name="pushButtonConfigureVoodoo">
|
||||
<property name="text">
|
||||
<string>Configure</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0" colspan="2">
|
||||
<item row="2" column="0" colspan="2">
|
||||
<widget class="QCheckBox" name="checkBoxVoodoo">
|
||||
<property name="text">
|
||||
<string>Voodoo Graphics</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0" colspan="2">
|
||||
<widget class="QCheckBox" name="checkBox8514">
|
||||
<property name="text">
|
||||
<string>8514/A</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="2">
|
||||
<widget class="QPushButton" name="pushButtonConfigureXga">
|
||||
<item row="2" column="2">
|
||||
<widget class="QPushButton" name="pushButtonConfigureVoodoo">
|
||||
<property name="text">
|
||||
<string>Configure</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0" colspan="2">
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string>Video:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="0" colspan="2">
|
||||
<widget class="QCheckBox" name="checkBoxXga">
|
||||
<property name="text">
|
||||
<string>XGA</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="0">
|
||||
<spacer name="verticalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
<item row="4" column="2">
|
||||
<widget class="QPushButton" name="pushButtonConfigureXga">
|
||||
<property name="text">
|
||||
<string>Configure</string>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="label_2">
|
||||
<property name="text">
|
||||
<string>Video #2:</string>
|
||||
</property>
|
||||
</spacer>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QComboBox" name="comboBoxVideoSecondary"/>
|
||||
</item>
|
||||
<item row="1" column="2">
|
||||
<widget class="QPushButton" name="pushButtonConfigureSecondary">
|
||||
<property name="text">
|
||||
<string>Configure</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
|
||||
@@ -20,9 +20,12 @@
|
||||
#include "qt_mainwindow.hpp"
|
||||
#include "ui_qt_mainwindow.h"
|
||||
|
||||
#include "qt_util.hpp"
|
||||
|
||||
#include <QStatusBar>
|
||||
#include <QMenuBar>
|
||||
#include <QTimer>
|
||||
#include <QScreen>
|
||||
|
||||
extern "C"
|
||||
{
|
||||
@@ -44,6 +47,11 @@ SpecifyDimensions::SpecifyDimensions(QWidget *parent) :
|
||||
ui->spinBoxWidth->setValue(main_window->getRenderWidgetSize().width());
|
||||
ui->spinBoxHeight->setRange(16, 2048);
|
||||
ui->spinBoxHeight->setValue(main_window->getRenderWidgetSize().height());
|
||||
|
||||
if (dpi_scale == 0) {
|
||||
ui->spinBoxWidth->setValue(main_window->getRenderWidgetSize().width() * util::screenOfWidget(main_window)->devicePixelRatio());
|
||||
ui->spinBoxHeight->setValue(main_window->getRenderWidgetSize().height() * util::screenOfWidget(main_window)->devicePixelRatio());
|
||||
}
|
||||
}
|
||||
|
||||
SpecifyDimensions::~SpecifyDimensions()
|
||||
@@ -62,14 +70,21 @@ void SpecifyDimensions::on_SpecifyDimensions_accepted()
|
||||
fixed_size_x = ui->spinBoxWidth->value();
|
||||
fixed_size_y = ui->spinBoxHeight->value();
|
||||
|
||||
main_window->setFixedSize(ui->spinBoxWidth->value(),
|
||||
ui->spinBoxHeight->value()
|
||||
+ (!hide_status_bar ? main_window->statusBar()->height() : 0)
|
||||
+ (!hide_tool_bar ? main_window->ui->toolBar->height() : 0)
|
||||
+ main_window->menuBar()->height());
|
||||
main_window->resizeContents(fixed_size_x, fixed_size_y);
|
||||
|
||||
emit main_window->updateMenuResizeOptions();
|
||||
main_window->show();
|
||||
for (int i = 1; i < MONITORS_NUM; i++) {
|
||||
if (main_window->renderers[i]) {
|
||||
main_window->renderers[i]->setWindowFlag(Qt::WindowMaximizeButtonHint, false);
|
||||
main_window->renderers[i]->setWindowFlag(Qt::MSWindowsFixedSizeDialogHint);
|
||||
emit main_window->resizeContentsMonitor(fixed_size_x, fixed_size_y, i);
|
||||
if (show_second_monitors) {
|
||||
main_window->renderers[i]->show();
|
||||
main_window->renderers[i]->switchRenderer((RendererStack::Renderer)vid_api);
|
||||
}
|
||||
}
|
||||
}
|
||||
main_window->ui->stackedWidget->switchRenderer((RendererStack::Renderer)vid_api);
|
||||
}
|
||||
else
|
||||
@@ -83,6 +98,16 @@ void SpecifyDimensions::on_SpecifyDimensions_accepted()
|
||||
window_h = ui->spinBoxHeight->value();
|
||||
main_window->setFixedSize(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX);
|
||||
emit main_window->resizeContents(ui->spinBoxWidth->value(), ui->spinBoxHeight->value());
|
||||
for (int i = 1; i < MONITORS_NUM; i++) {
|
||||
if (main_window->renderers[i]) {
|
||||
main_window->renderers[i]->setWindowFlag(Qt::WindowMaximizeButtonHint);
|
||||
main_window->renderers[i]->setWindowFlag(Qt::MSWindowsFixedSizeDialogHint, false);
|
||||
emit main_window->resizeContentsMonitor(ui->spinBoxWidth->value(), ui->spinBoxHeight->value(), i);
|
||||
main_window->renderers[i]->setFixedSize(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX);
|
||||
if (show_second_monitors) { main_window->renderers[i]->show();
|
||||
main_window->renderers[i]->switchRenderer((RendererStack::Renderer)vid_api); }
|
||||
}
|
||||
}
|
||||
vid_resize = 1;
|
||||
emit main_window->updateMenuResizeOptions();
|
||||
}
|
||||
|
||||
@@ -55,17 +55,18 @@ 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);
|
||||
main_window->blitToWidget(x, y, w, h, monitor_index);
|
||||
}
|
||||
|
||||
void mouse_poll() {
|
||||
main_window->pollMouse();
|
||||
}
|
||||
|
||||
void plat_resize(int w, int h) {
|
||||
main_window->resizeContents(w, h);
|
||||
void plat_resize_monitor(int w, int h, int monitor_index) {
|
||||
if (monitor_index >= 1) main_window->resizeContentsMonitor(w, h, monitor_index);
|
||||
else main_window->resizeContents(w, h);
|
||||
}
|
||||
|
||||
void plat_setfullscreen(int on) {
|
||||
@@ -98,6 +99,20 @@ int ui_msgbox_header(int flags, void *header, void* message) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
void ui_init_monitor(int monitor_index) {
|
||||
if (QThread::currentThread() == main_window->thread()) {
|
||||
emit main_window->initRendererMonitor(monitor_index);
|
||||
}
|
||||
else emit main_window->initRendererMonitorForNonQtThread(monitor_index);
|
||||
}
|
||||
|
||||
void ui_deinit_monitor(int monitor_index) {
|
||||
if (QThread::currentThread() == main_window->thread()) {
|
||||
emit main_window->destroyRendererMonitor(monitor_index);
|
||||
}
|
||||
else emit main_window->destroyRendererMonitorForNonQtThread(monitor_index);
|
||||
}
|
||||
|
||||
int ui_msgbox(int flags, void *message) {
|
||||
return ui_msgbox_header(flags, nullptr, message);
|
||||
}
|
||||
|
||||
@@ -36,6 +36,7 @@ static zwp_pointer_constraints_v1* conf_pointer_interface = nullptr;
|
||||
static zwp_locked_pointer_v1* conf_pointer = nullptr;
|
||||
|
||||
static int rel_mouse_x = 0, rel_mouse_y = 0;
|
||||
static bool wl_init_ok = false;
|
||||
|
||||
void rel_mouse_event(void* data, zwp_relative_pointer_v1* zwp_relative_pointer_v1, uint32_t tstmp, uint32_t tstmpl, wl_fixed_t dx, wl_fixed_t dy, wl_fixed_t dx_real, wl_fixed_t dy_real)
|
||||
{
|
||||
@@ -92,15 +93,18 @@ static const struct wl_registry_listener registry_listener = {
|
||||
|
||||
void wl_init()
|
||||
{
|
||||
wl_display* display = (wl_display*)QGuiApplication::platformNativeInterface()->nativeResourceForIntegration("wl_display");
|
||||
if (display)
|
||||
{
|
||||
auto registry = wl_display_get_registry(display);
|
||||
if (registry)
|
||||
if (!wl_init_ok) {
|
||||
wl_display* display = (wl_display*)QGuiApplication::platformNativeInterface()->nativeResourceForIntegration("wl_display");
|
||||
if (display)
|
||||
{
|
||||
wl_registry_add_listener(registry, ®istry_listener, nullptr);
|
||||
wl_display_roundtrip(display);
|
||||
auto registry = wl_display_get_registry(display);
|
||||
if (registry)
|
||||
{
|
||||
wl_registry_add_listener(registry, ®istry_listener, nullptr);
|
||||
wl_display_roundtrip(display);
|
||||
}
|
||||
}
|
||||
wl_init_ok = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -26,6 +26,7 @@ thread_create(void (*thread_rout)(void *param), void *param)
|
||||
int
|
||||
thread_wait(thread_t *arg)
|
||||
{
|
||||
if (!arg) return 0;
|
||||
auto thread = reinterpret_cast<std::thread*>(arg);
|
||||
thread->join();
|
||||
return 0;
|
||||
|
||||
@@ -563,11 +563,12 @@ main_thread(void *param)
|
||||
SDL_Delay(1);
|
||||
|
||||
/* If needed, handle a screen resize. */
|
||||
if (!atomic_flag_test_and_set(&doresize) && !video_fullscreen && !is_quit) {
|
||||
if (atomic_load(&doresize_monitors[0]) && !video_fullscreen && !is_quit) {
|
||||
if (vid_resize & 2)
|
||||
plat_resize(fixed_size_x, fixed_size_y);
|
||||
else
|
||||
plat_resize(scrnsz_x, scrnsz_y);
|
||||
atomic_store(&doresize_monitors[0], 1);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1114,6 +1115,7 @@ void monitor_thread(void* param)
|
||||
#endif
|
||||
}
|
||||
|
||||
extern int gfxcard_2;
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
SDL_Event event;
|
||||
@@ -1127,6 +1129,7 @@ int main(int argc, char** argv)
|
||||
return 6;
|
||||
}
|
||||
|
||||
gfxcard_2 = 0;
|
||||
eventthread = SDL_ThreadID();
|
||||
blitmtx = SDL_CreateMutex();
|
||||
if (!blitmtx)
|
||||
|
||||
@@ -128,18 +128,18 @@ 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;
|
||||
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)))
|
||||
if (!(!sdl_enabled || (x < 0) || (y < 0) || (w <= 0) || (h <= 0) || (w > 2048) || (h > 2048) || (buffer32 == NULL) || (sdl_render == NULL) || (sdl_tex == NULL)) || (monitor_index >= 1))
|
||||
video_copy(interpixels, &(buffer32->line[y][x]), h * 2048 * sizeof(uint32_t));
|
||||
if (screenshots)
|
||||
video_screenshot(interpixels, 0, 0, 2048);
|
||||
blitreq = 1;
|
||||
video_blit_complete();
|
||||
video_blit_complete_monitor(monitor_index);
|
||||
}
|
||||
|
||||
void ui_window_title_real();
|
||||
@@ -516,3 +516,6 @@ wchar_t* ui_window_title(wchar_t* str)
|
||||
#endif
|
||||
return str;
|
||||
}
|
||||
|
||||
void ui_init_monitor(int monitor_index) {}
|
||||
void ui_deinit_monitor(int monitor_index) {}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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) |
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -66,6 +66,7 @@ hercules_out(uint16_t addr, uint8_t val, void *priv)
|
||||
hercules_t *dev = (hercules_t *)priv;
|
||||
uint8_t old;
|
||||
|
||||
VIDEO_MONITOR_PROLOGUE()
|
||||
switch (addr) {
|
||||
case 0x03b0:
|
||||
case 0x03b2:
|
||||
@@ -92,7 +93,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);
|
||||
}
|
||||
}
|
||||
@@ -146,6 +147,8 @@ hercules_out(uint16_t addr, uint8_t val, void *priv)
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
VIDEO_MONITOR_EPILOGUE()
|
||||
}
|
||||
|
||||
|
||||
@@ -295,6 +298,7 @@ hercules_poll(void *priv)
|
||||
int drawcursor;
|
||||
uint32_t *p;
|
||||
|
||||
VIDEO_MONITOR_PROLOGUE()
|
||||
ca = (dev->crtc[15] | (dev->crtc[14] << 8)) & 0x3fff;
|
||||
|
||||
if (! dev->linepos) {
|
||||
@@ -516,6 +520,7 @@ hercules_poll(void *priv)
|
||||
}
|
||||
}
|
||||
}
|
||||
VIDEO_MONITOR_EPILOGUE()
|
||||
}
|
||||
|
||||
|
||||
@@ -527,6 +532,7 @@ hercules_init(const device_t *info)
|
||||
|
||||
dev = (hercules_t *)malloc(sizeof(hercules_t));
|
||||
memset(dev, 0x00, sizeof(hercules_t));
|
||||
dev->monitor_index = monitor_index_global;
|
||||
|
||||
overscan_x = 16;
|
||||
overscan_y = 28;
|
||||
|
||||
@@ -80,14 +80,18 @@ typedef struct {
|
||||
uint16_t ma, maback;
|
||||
int con, coff, cursoron;
|
||||
int dispon, blink;
|
||||
int vsynctime;
|
||||
int vsynctime;
|
||||
int vadj;
|
||||
int monitor_index, prev_monitor_index;
|
||||
|
||||
int cols[256][2][2];
|
||||
|
||||
uint8_t *vram;
|
||||
} herculesplus_t;
|
||||
|
||||
#define VIDEO_MONITOR_PROLOGUE() { dev->prev_monitor_index = monitor_index_global; monitor_index_global = dev->monitor_index; }
|
||||
#define VIDEO_MONITOR_EPILOGUE() { monitor_index_global = dev->prev_monitor_index; }
|
||||
|
||||
static video_timings_t timing_herculesplus = {VIDEO_ISA, 8, 16, 32, 8, 16, 32};
|
||||
|
||||
|
||||
@@ -180,7 +184,7 @@ herculesplus_in(uint16_t port, void *priv)
|
||||
break;
|
||||
|
||||
case 0x3ba:
|
||||
/* 0x50: InColor card identity */
|
||||
/* 0x10: Hercules Plus card identity */
|
||||
ret = (dev->stat & 0xf) | ((dev->stat & 8) << 4) | 0x10;
|
||||
break;
|
||||
}
|
||||
@@ -489,6 +493,7 @@ herculesplus_poll(void *priv)
|
||||
uint16_t ca = (dev->crtc[15] | (dev->crtc[14] << 8)) & 0x3fff;
|
||||
int x, oldvc, oldsc;
|
||||
|
||||
VIDEO_MONITOR_PROLOGUE();
|
||||
if (! dev->linepos) {
|
||||
timer_advance_u64(&dev->timer, dev->dispofftime);
|
||||
dev->stat |= 1;
|
||||
@@ -602,6 +607,8 @@ herculesplus_poll(void *priv)
|
||||
if ((dev->sc == (dev->crtc[10] & 31) || ((dev->crtc[8] & 3) == 3 && dev->sc == ((dev->crtc[10] & 31) >> 1))))
|
||||
dev->con = 1;
|
||||
}
|
||||
|
||||
VIDEO_MONITOR_EPILOGUE();
|
||||
}
|
||||
|
||||
|
||||
@@ -615,10 +622,11 @@ herculesplus_init(const device_t *info)
|
||||
memset(dev, 0, sizeof(herculesplus_t));
|
||||
|
||||
dev->vram = (uint8_t *)malloc(0x10000); /* 64k VRAM */
|
||||
dev->monitor_index = monitor_index_global;
|
||||
|
||||
timer_add(&dev->timer, herculesplus_poll, dev, 1);
|
||||
|
||||
mem_mapping_add(&dev->mapping, 0xb0000, 0x10000,
|
||||
mem_mapping_add(&dev->mapping, 0xb0000, 0x08000,
|
||||
herculesplus_read,NULL,NULL,
|
||||
herculesplus_write,NULL,NULL,
|
||||
dev->vram, MEM_MAPPING_EXTERNAL, dev);
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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];
|
||||
|
||||
|
||||
@@ -110,6 +110,8 @@ void mda_poll(void *p)
|
||||
uint8_t chr, attr;
|
||||
int oldsc;
|
||||
int blink;
|
||||
|
||||
VIDEO_MONITOR_PROLOGUE()
|
||||
if (!mda->linepos)
|
||||
{
|
||||
timer_advance_u64(&mda->timer, mda->dispofftime);
|
||||
@@ -252,6 +254,7 @@ void mda_poll(void *p)
|
||||
mda->con = 1;
|
||||
}
|
||||
}
|
||||
VIDEO_MONITOR_EPILOGUE();
|
||||
}
|
||||
|
||||
void mda_init(mda_t *mda)
|
||||
@@ -278,6 +281,7 @@ void mda_init(mda_t *mda)
|
||||
mdacols[0x88][0][1] = mdacols[0x88][1][1] = 16;
|
||||
|
||||
overscan_x = overscan_y = 0;
|
||||
mda->monitor_index = monitor_index_global;
|
||||
|
||||
cga_palette = device_get_config_int("rgb_type") << 1;
|
||||
if (cga_palette > 6)
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -40,6 +40,7 @@
|
||||
|
||||
typedef struct {
|
||||
const device_t *device;
|
||||
int flags;
|
||||
} VIDEO_CARD;
|
||||
|
||||
|
||||
@@ -109,13 +110,13 @@ video_cards[] = {
|
||||
{ &cpqega_device },
|
||||
{ &ega_device },
|
||||
{ &g2_gc205_device },
|
||||
{ &hercules_device },
|
||||
{ &herculesplus_device },
|
||||
{ &hercules_device, VIDEO_FLAG_TYPE_MDA },
|
||||
{ &herculesplus_device, VIDEO_FLAG_TYPE_MDA },
|
||||
{ &incolor_device },
|
||||
{ &im1024_device },
|
||||
{ &iskra_ega_device },
|
||||
{ &et4000_kasan_isa_device },
|
||||
{ &mda_device },
|
||||
{ &mda_device, VIDEO_FLAG_TYPE_MDA },
|
||||
{ &genius_device },
|
||||
{ &nga_device },
|
||||
{ &ogc_device },
|
||||
@@ -275,6 +276,10 @@ vid_table_log(const char *fmt, ...)
|
||||
void
|
||||
video_reset_close(void)
|
||||
{
|
||||
for (int i = 1; i < MONITORS_NUM; i++)
|
||||
video_monitor_close(i);
|
||||
|
||||
monitor_index_global = 0;
|
||||
video_inform(VIDEO_FLAG_TYPE_NONE, &timing_default);
|
||||
was_reset = 0;
|
||||
}
|
||||
@@ -289,16 +294,18 @@ video_prepare(void)
|
||||
fontdatksc5601 = NULL;
|
||||
}
|
||||
|
||||
/* Reset the CGA palette. */
|
||||
cga_palette = 0;
|
||||
cgapal_rebuild();
|
||||
|
||||
/* Reset the blend. */
|
||||
herc_blend = 0;
|
||||
|
||||
/* Do an inform on the default values, so that that there's some sane values initialized
|
||||
even if the device init function does not do an inform of its own. */
|
||||
video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_default);
|
||||
for (int i = 0; i < MONITORS_NUM; i++) {
|
||||
/* Reset the CGA palette. */
|
||||
if (monitors[i].mon_cga_palette) *monitors[i].mon_cga_palette = 0;
|
||||
cgapal_rebuild_monitor(i);
|
||||
|
||||
/* Do an inform on the default values, so that that there's some sane values initialized
|
||||
even if the device init function does not do an inform of its own. */
|
||||
video_inform_monitor(VIDEO_FLAG_TYPE_SPECIAL, &timing_default, i);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -321,6 +328,7 @@ video_reset(int card)
|
||||
vid_table_log("VIDEO: reset (gfxcard=%d, internal=%d)\n",
|
||||
card, machine_has_flags(machine, MACHINE_VIDEO) ? 1 : 0);
|
||||
|
||||
monitor_index_global = 0;
|
||||
loadfont("roms/video/mda/mda.rom", 0);
|
||||
|
||||
/* Do not initialize internal cards here. */
|
||||
@@ -334,6 +342,17 @@ video_reset(int card)
|
||||
device_add(video_cards[card].device);
|
||||
}
|
||||
|
||||
if (!(card == VID_NONE)
|
||||
&& !machine_has_flags(machine, MACHINE_VIDEO_ONLY)
|
||||
&& gfxcard_2 != 0
|
||||
&& (video_cards[gfxcard_2].flags != video_cards[gfxcard].flags)
|
||||
&& device_is_valid(video_card_getdevice(gfxcard_2), machine)) {
|
||||
video_monitor_init(1);
|
||||
monitor_index_global = 1;
|
||||
device_add(video_cards[gfxcard_2].device);
|
||||
monitor_index_global = 0;
|
||||
}
|
||||
|
||||
/* Enable the Voodoo if configured. */
|
||||
if (voodoo_enabled)
|
||||
device_add(&voodoo_device);
|
||||
@@ -351,6 +370,11 @@ video_card_available(int card)
|
||||
return(1);
|
||||
}
|
||||
|
||||
int
|
||||
video_card_get_flags(int card)
|
||||
{
|
||||
return video_cards[card].flags;
|
||||
}
|
||||
|
||||
const device_t *
|
||||
video_card_getdevice(int card)
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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) |
|
||||
|
||||
@@ -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; x<svga->overlay_latch.xsize;x++)
|
||||
for (x=0; x<svga->overlay_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; x<svga->overlay_latch.xsize;x++)
|
||||
for (x=0; x<svga->overlay_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; x<svga->overlay_latch.xsize;x++)
|
||||
for (x=0; x<svga->overlay_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; x<svga->overlay_latch.xsize;x++)
|
||||
for (x=1; x<svga->overlay_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; x<svga->overlay_latch.xsize;x++)
|
||||
for (x=1; x<svga->overlay_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; x<svga->overlay_latch.xsize;x++)
|
||||
for (x=1; x<svga->overlay_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; x<svga->overlay_latch.xsize;x++)
|
||||
for (x=0; x<svga->overlay_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; x<svga->overlay_latch.xsize;x++)
|
||||
for (x=0; x<svga->overlay_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; x<svga->overlay_latch.xsize;x++)
|
||||
for (x=0; x<svga->overlay_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; x<svga->overlay_latch.xsize;x++)
|
||||
for (x=0; x<svga->overlay_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;
|
||||
|
||||
@@ -2048,7 +2048,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];
|
||||
@@ -2476,13 +2476,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;
|
||||
}
|
||||
|
||||
@@ -2702,8 +2702,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 = 0x8000;
|
||||
|
||||
f = rom_fopen(xga->type ? XGA2_BIOS_PATH : XGA_BIOS_PATH, "rb");
|
||||
|
||||
@@ -48,6 +48,7 @@
|
||||
* Copyright 2008-2019 Sarah Walker.
|
||||
* Copyright 2016-2019 Miran Grca.
|
||||
*/
|
||||
#include <stdatomic.h>
|
||||
#define PNG_DEBUG 0
|
||||
#include <png.h>
|
||||
#include <stdarg.h>
|
||||
@@ -68,6 +69,7 @@
|
||||
#include <86box/timer.h>
|
||||
#include <86box/path.h>
|
||||
#include <86box/plat.h>
|
||||
#include <86box/ui.h>
|
||||
#include <86box/thread.h>
|
||||
#include <86box/video.h>
|
||||
#include <86box/vid_svga.h>
|
||||
@@ -75,7 +77,7 @@
|
||||
#include <minitrace/minitrace.h>
|
||||
|
||||
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 +85,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 +101,10 @@ 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];
|
||||
monitor_settings_t monitor_settings[MONITORS_NUM];
|
||||
atomic_bool doresize_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 +241,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 +255,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 +279,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 +288,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 +359,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 +401,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,9 +418,9 @@ 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];
|
||||
char path[1024], fn[256];
|
||||
|
||||
memset(fn, 0, sizeof(fn));
|
||||
memset(path, 0, sizeof(path));
|
||||
@@ -409,19 +428,27 @@ 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);
|
||||
strcat(path, "Monitor_");
|
||||
snprintf(&path[strlen(path)], 42, "%d_", monitor_index + 1);
|
||||
|
||||
plat_tempfile(fn, NULL, ".png");
|
||||
strcat(path, fn);
|
||||
|
||||
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, 0);
|
||||
}
|
||||
|
||||
|
||||
@@ -454,40 +481,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 +556,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 +564,212 @@ 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 = 0;
|
||||
|
||||
/* We cannot do this (yet) if we have not been enabled yet. */
|
||||
if (video_6to8 == NULL) return;
|
||||
|
||||
if (monitors[monitor_index].target_buffer == NULL ||
|
||||
monitors[monitor_index].mon_cga_palette == NULL) return;
|
||||
|
||||
cga_palette_monitor = *monitors[monitor_index].mon_cga_palette;
|
||||
|
||||
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 (monitor_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 (monitor_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 +857,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 +915,55 @@ 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);
|
||||
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_blit_data_ptr->monitor_index = index;
|
||||
monitors[index].mon_pal_lookup = calloc(sizeof(uint32_t), 256);
|
||||
monitors[index].mon_cga_palette = calloc(1, sizeof(int));
|
||||
monitors[index].mon_force_resize = 1;
|
||||
monitors[index].mon_vid_type = VIDEO_FLAG_TYPE_NONE;
|
||||
atomic_init(&doresize_monitors[index], 0);
|
||||
if (index >= 1) ui_init_monitor(index);
|
||||
monitors[index].mon_blit_data_ptr->blit_thread = 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);
|
||||
if (monitor_index >= 1) ui_deinit_monitor(monitor_index);
|
||||
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);
|
||||
destroy_bitmap(monitors[monitor_index].target_buffer);
|
||||
monitors[monitor_index].target_buffer = NULL;
|
||||
memset(&monitors[monitor_index], 0, sizeof(monitor_t));
|
||||
}
|
||||
|
||||
void
|
||||
video_init(void)
|
||||
@@ -832,9 +976,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 +1019,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 +1035,6 @@ video_close(void)
|
||||
free(video_8togs);
|
||||
free(video_6to8);
|
||||
|
||||
destroy_bitmap(buffer32);
|
||||
|
||||
if (fontdatksc5601) {
|
||||
free(fontdatksc5601);
|
||||
fontdatksc5601 = NULL;
|
||||
@@ -915,18 +1046,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
|
||||
|
||||
@@ -495,6 +495,9 @@ WinMain(HINSTANCE hInst, HINSTANCE hPrev, LPSTR lpszArg, int nCmdShow)
|
||||
return(1);
|
||||
}
|
||||
|
||||
extern int gfxcard_2;
|
||||
gfxcard_2 = 0;
|
||||
|
||||
/* Create console window. */
|
||||
if (force_debug) {
|
||||
CreateConsole(1);
|
||||
@@ -552,11 +555,12 @@ main_thread(void *param)
|
||||
Sleep(1);
|
||||
|
||||
/* If needed, handle a screen resize. */
|
||||
if (!atomic_flag_test_and_set(&doresize) && !video_fullscreen && !is_quit) {
|
||||
if (atomic_load(&doresize_monitors[0]) && !video_fullscreen && !is_quit) {
|
||||
if (vid_resize & 2)
|
||||
plat_resize(fixed_size_x, fixed_size_y);
|
||||
else
|
||||
plat_resize(scrnsz_x, scrnsz_y);
|
||||
atomic_store(&doresize_monitors[0], 0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1189,7 +1193,7 @@ plat_setfullscreen(int on)
|
||||
video_fullscreen &= 1;
|
||||
video_force_resize_set(1);
|
||||
if (!(on & 1))
|
||||
atomic_flag_clear(&doresize);
|
||||
atomic_store(&doresize_monitors[0], 1);
|
||||
|
||||
win_mouse_init();
|
||||
|
||||
|
||||
@@ -871,14 +871,14 @@ 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;
|
||||
|
||||
if ((x < 0) || (y < 0) || (w <= 0) || (h <= 0) || (w > 2048) || (h > 2048) || (buffer32 == NULL) || (thread == NULL) ||
|
||||
atomic_flag_test_and_set(&blit_info[write_pos].in_use))
|
||||
atomic_flag_test_and_set(&blit_info[write_pos].in_use) || monitor_index >= 1)
|
||||
{
|
||||
video_blit_complete();
|
||||
video_blit_complete_monitor(monitor_index);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -229,13 +229,13 @@ 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;
|
||||
|
||||
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();
|
||||
if (!sdl_enabled || (x < 0) || (y < 0) || (w <= 0) || (h <= 0) || (w > 2048) || (h > 2048) || (buffer32 == NULL) || (sdl_render == NULL) || (sdl_tex == NULL) || monitor_index >= 1) {
|
||||
video_blit_complete_monitor(monitor_index);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
#include <86box/86box.h>
|
||||
#include <86box/config.h>
|
||||
#include <86box/plat.h>
|
||||
#include <86box/video.h>
|
||||
#include <86box/sound.h>
|
||||
#include <86box/win.h>
|
||||
|
||||
@@ -133,7 +134,7 @@ SpecifyDimensionsDialogProcedure(HWND hdlg, UINT message, WPARAM wParam, LPARAM
|
||||
|
||||
scrnsz_x = fixed_size_x;
|
||||
scrnsz_y = fixed_size_y;
|
||||
atomic_flag_clear(&doresize);
|
||||
atomic_store(&doresize_monitors[0], 1);
|
||||
|
||||
GetWindowRect(hwndMain, &r);
|
||||
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
#include <86box/plat.h>
|
||||
#include <86box/resource.h>
|
||||
#include <86box/ui.h>
|
||||
#include <86box/video.h>
|
||||
#include <86box/win.h>
|
||||
|
||||
HWND hwndRebar = NULL;
|
||||
|
||||
@@ -646,7 +646,7 @@ MainWindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
|
||||
|
||||
scrnsz_x = unscaled_size_x;
|
||||
scrnsz_y = unscaled_size_y;
|
||||
atomic_flag_clear(&doresize);
|
||||
atomic_store(&doresize_monitors[0], 1);
|
||||
config_save();
|
||||
break;
|
||||
|
||||
@@ -745,7 +745,7 @@ MainWindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
|
||||
reset_screen_size();
|
||||
device_force_redraw();
|
||||
video_force_resize_set(1);
|
||||
atomic_flag_clear(&doresize);
|
||||
atomic_store(&doresize_monitors[0], 1);
|
||||
config_save();
|
||||
break;
|
||||
|
||||
@@ -760,7 +760,7 @@ MainWindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
|
||||
case IDM_VID_HIDPI:
|
||||
dpi_scale = !dpi_scale;
|
||||
CheckMenuItem(hmenu, IDM_VID_HIDPI, dpi_scale ? MF_CHECKED : MF_UNCHECKED);
|
||||
atomic_flag_clear(&doresize);
|
||||
atomic_store(&doresize_monitors[0], 1);
|
||||
config_save();
|
||||
break;
|
||||
|
||||
@@ -860,7 +860,7 @@ MainWindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
|
||||
/* Main Window. */
|
||||
ResizeWindowByClientArea(hwndMain, temp_x, temp_y + (hide_status_bar ? 0 : sbar_height) + (hide_tool_bar ? 0 : tbar_height));
|
||||
} else if (!user_resize)
|
||||
atomic_flag_clear(&doresize);
|
||||
atomic_store(&doresize_monitors[0], 1);
|
||||
break;
|
||||
|
||||
case WM_WINDOWPOSCHANGED:
|
||||
@@ -909,13 +909,13 @@ MainWindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
|
||||
if (temp_x != scrnsz_x || temp_y != scrnsz_y) {
|
||||
scrnsz_x = temp_x;
|
||||
scrnsz_y = temp_y;
|
||||
atomic_flag_clear(&doresize);
|
||||
atomic_store(&doresize_monitors[0], 1);
|
||||
}
|
||||
} else {
|
||||
if (rect.right != scrnsz_x || rect.bottom != scrnsz_y) {
|
||||
scrnsz_x = rect.right;
|
||||
scrnsz_y = rect.bottom;
|
||||
atomic_flag_clear(&doresize);
|
||||
atomic_store(&doresize_monitors[0], 1);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1092,7 +1092,7 @@ MainWindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
|
||||
/* If window is not resizable, then tell the main thread to
|
||||
resize it, as sometimes, moves can mess up the window size. */
|
||||
if (!vid_resize)
|
||||
atomic_flag_clear(&doresize);
|
||||
atomic_store(&doresize_monitors[0], 1);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -1580,3 +1580,6 @@ plat_mouse_capture(int on)
|
||||
mouse_capture = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void ui_init_monitor(int monitor_index) {}
|
||||
void ui_deinit_monitor(int monitor_index) {}
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
"network",
|
||||
"vulkan",
|
||||
"widgets",
|
||||
"png",
|
||||
"zstd"
|
||||
]
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user