From 1d60a99ea3ad464dda036ff69ed03f1d670c7e08 Mon Sep 17 00:00:00 2001 From: waltje Date: Thu, 19 Oct 2017 04:27:04 -0400 Subject: [PATCH] Another major change round. VNC moved to top level. More cleanups of global data, all VM processing now handled in pc.c (out of the platforms, yay!), and some video cleanups. This build MAY have issues with window sizes, resizing, and fullscreen will not work until the next build- sorry. --- src/86box.h | 104 +++--- src/config.c | 44 ++- src/config.h | 2 +- src/ibm.h | 7 - src/machine/machine_at_scat.c | 29 +- src/mouse.c | 21 +- src/pc.c | 481 +++++++++++++++++------- src/plat.h | 18 +- src/plat_joystick.h | 110 +++--- src/plat_mouse.h | 18 +- src/rom.c | 4 +- src/ui.h | 3 +- src/video/vid_cga.c | 4 +- src/video/vid_colorplus.c | 4 +- src/video/vid_ega.c | 6 +- src/video/vid_genius.c | 4 +- src/video/vid_hercules.c | 4 +- src/video/vid_herculesplus.c | 4 +- src/video/vid_incolor.c | 4 +- src/video/vid_mda.c | 4 +- src/video/vid_olivetti_m24.c | 4 +- src/video/vid_pc1512.c | 4 +- src/video/vid_pcjr.c | 4 +- src/video/vid_svga.c | 31 +- src/video/vid_tandy.c | 4 +- src/video/vid_tandysl.c | 4 +- src/video/vid_wy700.c | 4 +- src/video/video.c | 77 ++-- src/video/video.h | 2 - src/{win/win_vnc.c => vnc.c} | 183 ++++++---- src/{win/win_vnc.h => vnc.h} | 18 +- src/win/Makefile.mingw | 19 +- src/win/win.c | 671 +++++++++------------------------- src/win/win.h | 39 +- src/win/win_joystick.cc | 6 +- src/win/win_video.c | 300 +++++++++++++++ 36 files changed, 1244 insertions(+), 1001 deletions(-) rename src/{win/win_vnc.c => vnc.c} (84%) rename src/{win/win_vnc.h => vnc.h} (76%) create mode 100644 src/win/win_video.c diff --git a/src/86box.h b/src/86box.h index 1b926a40b..69435018f 100644 --- a/src/86box.h +++ b/src/86box.h @@ -6,9 +6,9 @@ * * This file is part of the 86Box distribution. * - * Main emulator include file. + * Main include file for the application. * - * Version: @(#)86box.h 1.0.4 2017/10/16 + * Version: @(#)86box.h 1.0.6 2017/10/18 * * Authors: Miran Grca, * Fred N. van Kempen, @@ -23,6 +23,19 @@ /* Configuration values. */ #define SERIAL_MAX 2 #define PARALLEL_MAX 1 +#define SCREEN_RES_X 640 +#define SCREEN_RES_Y 480 + +/* Version info. */ +#define EMU_NAME "86Box" +#define EMU_NAME_W L"86Box" +#define EMU_VERSION "2.00" +#define EMU_VERSION_W L"2.00" + +/* Filename and pathname info. */ +#define CONFIG_FILE_W L"86box.cfg" +#define NVR_PATH L"nvr" +#define SCREENSHOT_PATH L"screenshots" #if defined(ENABLE_BUSLOGIC_LOG) || \ @@ -38,57 +51,56 @@ # define ENABLE_LOG_COMMANDS 1 #endif -#define EMU_VERSION "2.00" -#define EMU_VERSION_W L"2.00" -#define EMU_NAME "86Box" -#define EMU_NAME_W L"86Box" - -#define CONFIG_FILE_W L"86box.cfg" - -#define NVR_PATH L"nvr" -#define SCREENSHOT_PATH L"screenshots" - - -/* Global variables. */ -#ifdef ENABLE_LOG_TOGGLES -extern int buslogic_do_log; -extern int cdrom_do_log; -extern int d86f_do_log; -extern int fdc_do_log; -extern int ide_do_log; -extern int serial_do_log; -extern int nic_do_log; -#endif - -extern int suppress_overscan; -extern int invert_display; -extern int scale; -extern int vid_api; -extern int vid_resize; -extern int winsizex,winsizey; - -extern wchar_t exe_path[1024]; -extern wchar_t cfg_path[1024]; - -extern uint64_t timer_freq; /* plat.h */ -extern int infocus; /* plat.h */ - -extern int dump_on_exit; -extern int start_in_fullscreen; -extern int window_w, window_h, window_x, window_y, window_remember; - - -/* Function prototypes. */ #ifdef __cplusplus extern "C" { #endif +/* Global variables. */ +extern int dump_on_exit; /* (O) dump regs on exit*/ +extern int start_in_fullscreen; /* (O) start in fullscreen */ + +extern int window_w, window_h, /* (C) window size and */ + window_x, window_y, /* position info */ + window_remember, + vid_resize, /* (C) allow resizing */ + invert_display, /* (C) invert the display */ + suppress_overscan; /* (C) suppress overscans */ +extern int scale; /* (C) screen scale factor */ +extern int vid_api; /* (C) video renderer */ +extern int vid_cga_contrast, /* (C) video */ + video_fullscreen, /* (C) video */ + video_fullscreen_first, /* (C) video */ + video_fullscreen_scale, /* (C) video */ + enable_overscan, /* (C) video */ + force_43, /* (C) video */ + video_speed; /* (C) video */ + + +#ifdef ENABLE_LOG_TOGGLES +extern int buslogic_do_log; +extern int cdrom_do_log; +extern int d86f_do_log; +extern int fdc_do_log; +extern int ide_do_log; +extern int serial_do_log; +extern int nic_do_log; +#endif + +extern wchar_t exe_path[1024]; /* path (dir) of executable */ +extern wchar_t cfg_path[1024]; /* path (dir) of user data */ +extern int scrnsz_x, /* current screen size, X */ + scrnsz_y; /* current screen size, Y */ + + +/* Function prototypes. */ extern void pclog(const char *format, ...); extern void fatal(const char *format, ...); +extern void set_screen_size(int x, int y); +extern void set_screen_size_natural(void); extern int pc_init_modules(void); extern int pc_init(int argc, wchar_t *argv[]); -extern void pc_close(void); +extern void pc_close(void *threadid); extern void pc_reset_hard_close(void); extern void pc_reset_hard_init(void); extern void pc_reset_hard(void); @@ -97,7 +109,9 @@ extern void pc_full_speed(void); extern void pc_speed_changed(void); extern void pc_send_cad(void); extern void pc_send_cae(void); -extern void pc_run(void); +extern void pc_thread(void *param); +extern void pc_start(void); +extern void pc_onesec(void); #ifdef __cplusplus } diff --git a/src/config.c b/src/config.c index 6476c7efd..8ba1cf5fa 100644 --- a/src/config.c +++ b/src/config.c @@ -8,7 +8,7 @@ * * Configuration file handler. * - * Version: @(#)config.c 1.0.22 2017/10/16 + * Version: @(#)config.c 1.0.24 2017/10/18 * * Authors: Sarah Walker, * Miran Grca, @@ -101,8 +101,31 @@ typedef struct { } +/* Commandline options. */ +int dump_on_exit = 0; /* (O) dump regs on exit */ +int start_in_fullscreen = 0; /* (O) start in fullscreen */ + +/* Configuration values. */ +int window_w, window_h, /* (C) window size and */ + window_x, window_y, /* position info */ + window_remember, + vid_resize, /* (C) allow resizing */ + invert_display, /* (C) invert the display */ + suppress_overscan = 0; /* (C) suppress overscans */ +int scale = 0; /* (C) screen scale factor */ +int vid_api = 0; /* (C) video renderer */ +int vid_cga_contrast = 0, /* (C) video */ + video_fullscreen = 0, /* (C) video */ + video_fullscreen_scale = 0, /* (C) video */ + video_fullscreen_first = 0, /* (C) video */ + enable_overscan = 0, /* (C) video */ + force_43 = 0, /* (C) video */ + video_speed = 0; /* (C) video */ + + wchar_t config_file_default[256]; + static list_t config_head; @@ -416,23 +439,8 @@ load_general(void) vid_resize = !!config_get_int(cat, "vid_resize", 0); memset(temp, '\0', sizeof(temp)); - p = config_get_string(cat, "vid_renderer", "d3d9"); - if (p != NULL) - strcpy(temp, p); - if (! strcmp(temp, "ddraw")) - vid_api = 0; - else if (! strcmp(temp, "d3d9")) - vid_api = 1; -#ifdef USE_VNC - else if (! strcmp(temp, "vnc")) - vid_api = 2; -#endif -#ifdef USE_RDP - else if (! strcmp(temp, "rdp")) - vid_api = 3; -#endif - else - vid_api = 1; /* default to d3d9 on invalid values */ + p = config_get_string(cat, "vid_renderer", "default"); + vid_api = plat_vidapi(p); config_delete_var(cat, "vid_api"); video_fullscreen_scale = config_get_int(cat, "video_fullscreen_scale", 0); diff --git a/src/config.h b/src/config.h index 257bdd1b7..2a6960b87 100644 --- a/src/config.h +++ b/src/config.h @@ -8,7 +8,7 @@ * * Configuration file handler header. * - * Version: @(#)config.h 1.0.4 2017/10/16 + * Version: @(#)config.h 1.0.5 2017/10/18 * * Authors: Sarah Walker, * Miran Grca, diff --git a/src/ibm.h b/src/ibm.h index 185b20b05..2c7a2a9f7 100644 --- a/src/ibm.h +++ b/src/ibm.h @@ -567,8 +567,6 @@ uint32_t svga_color_transform(uint32_t color); extern "C" { #endif -extern void onesec(void); - extern int checkio(int port); extern void codegen_block_end(void); extern void codegen_reset(void); @@ -608,9 +606,4 @@ extern void x87_reset(void); #endif -/* Configuration values. */ -#define SERIAL_MAX 2 -#define PARALLEL_MAX 1 - - #endif /*EMU_IBM_H*/ diff --git a/src/machine/machine_at_scat.c b/src/machine/machine_at_scat.c index b06fad779..17f4797c6 100644 --- a/src/machine/machine_at_scat.c +++ b/src/machine/machine_at_scat.c @@ -10,7 +10,7 @@ * * Re-worked version based on the 82C235 datasheet and errata. * - * Version: @(#)at_scat.c 1.0.3 2017/10/16 + * Version: @(#)at_scat.c 1.0.4 2017/10/18 * * Authors: Original by GreatPsycho for PCem. * Fred N. van Kempen, @@ -30,7 +30,7 @@ #include "machine.h" -#define SCAT_DEBUG 2 +#define SCAT_DEBUG 1 #define SCAT_DMA_WS_CTL 0x01 #define SCAT_VERSION 0x40 @@ -177,12 +177,10 @@ set_xms_bound(uint8_t val) 0x160000 - scat_xms_bound, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL); } else { -#if 0 for (i=0; i<6; i++) mem_mapping_disable(&scat_shadowram_mapping[i]); if (mem_size > 1024) mem_mapping_enable(&ram_high_mapping); -#endif if (scat_xms_bound > max_xms) scat_xms_bound = max_xms; @@ -280,10 +278,8 @@ ems_state(int state) } else { mem_mapping_set_exec(&scat_mapping[i], ram+base_addr); mem_mapping_disable(&scat_mapping[i]); -#if 0 if (i < 24) mem_mapping_enable(&scat_top_mapping[i]); -#endif } } } @@ -491,7 +487,6 @@ ics_write(uint8_t idx, uint8_t val) break; case SCAT_EMS_CTL: -pclog("SCAT: EMSctrl(%02x)\n", val); if (val & 0x40) { if (val & 1) { io_sethandler(0x0218, 3, @@ -527,24 +522,18 @@ pclog("SCAT: EMSctrl(%02x)\n", val); case SCAT_DRAM_CONFIG: if ((scat_regs[SCAT_EXT_BOUNDARY] & 0x40) == 0) { -pclog("SCAT: 0\n"); if ((val & 0x0f) == 3) { -pclog("SCAT: 3\n"); if (mem_size > 1024) mem_mapping_disable(&ram_high_mapping); for (idx=0; idx<6; idx++) mem_mapping_enable(&scat_shadowram_mapping[idx]); } else { -pclog("SCAT: 0\n"); for (idx=0; idx<6; idx++) mem_mapping_disable(&scat_shadowram_mapping[idx]); -#if 0 if (mem_size > 1024) mem_mapping_enable(&ram_high_mapping); -#endif } } else { -pclog("SCAT: 1\n"); for (idx=0; idx<6; idx++) mem_mapping_disable(&scat_shadowram_mapping[idx]); if (mem_size > 1024) @@ -688,8 +677,6 @@ scat_init(void) */ pclog("SCAT: mem_size=%d\n", mem_size); - -#if 0 /* Create the 32 EMS page frame mappings for 256-640K. */ for (i=0; i<24; i++) { mem_mapping_add(&scat_top_mapping[i], @@ -698,12 +685,9 @@ scat_init(void) ems_pgwr, NULL, NULL, mem_size > 256+(i<<4) ? ram+0x40000+(i<<14) : NULL, MEM_MAPPING_INTERNAL, NULL); -// mem_mapping_enable(&scat_top_mapping[i]); - mem_mapping_disable(&scat_top_mapping[i]); + mem_mapping_enable(&scat_top_mapping[i]); } -#endif -#if 0 /* Re-map the 128K at A0000 (video BIOS) to above 16MB+top. */ mem_mapping_add(&scat_A000_mapping, 0xA0000, 0x20000, @@ -712,9 +696,7 @@ scat_init(void) ram+0xA0000, MEM_MAPPING_INTERNAL, NULL); mem_mapping_disable(&scat_A000_mapping); -#endif -#if 0 /* Create 32 page frames for EMS, each 16K. */ for (i=0; i<32; i++) { scat_ems[i].regs_2x8 = 0xff; @@ -727,9 +709,8 @@ scat_init(void) 0, &scat_ems[i]); mem_mapping_disable(&scat_mapping[i]); } -#endif -// for (i=4; i<10; i++) isram[i] = 0; + for (i=4; i<10; i++) isram[i] = 0; /* Re-map the BIOS ROM (C0000-FFFFF) area. */ for (i=12; i<16; i++) { @@ -741,7 +722,6 @@ scat_init(void) 0, NULL); } -#if 0 for (i=0; i<6; i++) { mem_mapping_add(&scat_shadowram_mapping[i], 0x100000 + (i<<16), 0x10000, @@ -750,7 +730,6 @@ scat_init(void) mem_size >= 1024 ? ram+get_addr(0x100000+(i<<16), NULL) : NULL, MEM_MAPPING_INTERNAL, NULL); } -#endif set_xms_bound(0); shadow_state_update(); diff --git a/src/mouse.c b/src/mouse.c index 567fba71a..aee1dca46 100644 --- a/src/mouse.c +++ b/src/mouse.c @@ -8,7 +8,7 @@ * * Common driver module for MOUSE devices. * - * Version: @(#)mouse.c 1.0.9 2017/10/09 + * Version: @(#)mouse.c 1.0.10 2017/10/17 * * Authors: Sarah Walker, * Miran Grca, @@ -26,6 +26,7 @@ #include "device.h" #include "mouse.h" #include "machine/machine.h" +#include "plat_mouse.h" static mouse_t mouse_none = { @@ -81,6 +82,24 @@ mouse_emu_close(void) } +void +mouse_process(void) +{ + static int poll_delay = 2; + int x, y, z; + + if (--poll_delay) return; + + mouse_poll_host(); + + mouse_get_mickeys(&x, &y, &z); + + mouse_poll(x, y, z, mouse_buttons); + + poll_delay = 2; +} + + void mouse_poll(int x, int y, int z, int b) { diff --git a/src/pc.c b/src/pc.c index 5a88e5b49..f7e3fd3a5 100644 --- a/src/pc.c +++ b/src/pc.c @@ -8,7 +8,7 @@ * * Emulation core dispatcher. * - * Version: @(#)pc.c 1.0.28 2017/10/16 + * Version: @(#)pc.c 1.0.29 2017/10/18 * * Authors: Sarah Walker, * Miran Grca, @@ -77,30 +77,44 @@ #include "plat_mouse.h" -int window_w, window_h, window_x, window_y, window_remember; -int dump_on_exit = 0; -int start_in_fullscreen = 0; +/* Statistics. */ +extern int mmuflush, + readlnum, + writelnum; + + +/* Statistics. */ +int sndcount = 0; +int sreadlnum, + swritelnum, + segareads, + segawrites, + scycles_lost; +float mips, flops; +int cycles_lost = 0; // video +int insc = 0; // cpu +int emu_fps = 0, fps; // video +int framecount; + int CPUID; -int vid_resize, vid_api; int output; int atfullspeed; -int cycles_lost = 0; -int clockrate; -int insc = 0; -float mips, flops; -int framecount, fps; -int win_title_update = 0; -int status_update_needed = 0; -int pollmouse_delay = 2; -int mousecapture; -int suppress_overscan = 0; int cpuspeed2; -wchar_t exe_path[1024]; -wchar_t cfg_path[1024]; +int clockrate; + +int gfx_present[GFX_MAX]; // should not be here + +wchar_t exe_path[1024]; /* path (dir) of executable */ +wchar_t cfg_path[1024]; /* path (dir) of user data */ +int scrnsz_x = SCREEN_RES_X, /* current screen size, X */ + scrnsz_y = SCREEN_RES_Y; /* current screen size, Y */ +int title_update; +int mousecapture; +int64_t main_time; -extern int mmuflush; -extern int readlnum,writelnum; +static int unscaled_size_x = SCREEN_RES_X, /* current unscaled size X */ + unscaled_size_y = SCREEN_RES_Y; /* current unscaled size Y */ /* Log something to the logfile or stdout. */ @@ -149,6 +163,95 @@ fatal(const char *format, ...) } +void +set_screen_size(int x, int y) +{ + int owsx = scrnsz_x; + int owsy = scrnsz_y; + int temp_overscan_x = overscan_x; + int temp_overscan_y = overscan_y; + double dx, dy, dtx, dty; + int efscrnsz_y; + + /* Make sure we keep usable values. */ + pclog("SetScreenSize(%d, %d) resize=%d\n", x, y, vid_resize); + if (x < 320) x = 320; + if (y < 200) y = 200; + if (x > 2048) x = 2048; + if (y > 2048) y = 2048; + + /* Save the new values as "real" (unscaled) resolution. */ + unscaled_size_x = x; + efscrnsz_y = y; + + if (suppress_overscan) + temp_overscan_x = temp_overscan_y = 0; + + if (force_43) { + dx = (double)x; + dtx = (double)temp_overscan_x; + + dy = (double)y; + dty = (double)temp_overscan_y; + + /* Account for possible overscan. */ + if (temp_overscan_y == 16) { + /* CGA */ + dy = (((dx - dtx) / 4.0) * 3.0) + dty; + } else if (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; + } else { + unscaled_size_y = efscrnsz_y; + } + + switch(scale) { + case 0: /* 50% */ + scrnsz_x = (unscaled_size_x>>1); + scrnsz_y = (unscaled_size_y>>1); + break; + + case 1: /* 100% */ + scrnsz_x = unscaled_size_x; + scrnsz_y = unscaled_size_y; + break; + + case 2: /* 150% */ + scrnsz_x = ((unscaled_size_x*3)>>1); + scrnsz_y = ((unscaled_size_y*3)>>1); + break; + + case 3: /* 200% */ + scrnsz_x = (unscaled_size_x<<1); + scrnsz_y = (unscaled_size_y<<1); + break; + } + + /* If the resolution has changed, let the main thread handle it. */ + if ((owsx != scrnsz_x) || (owsy != scrnsz_y)) + doresize = 1; + else + doresize = 0; +} + + +void +set_screen_size_natural(void) +{ + set_screen_size(unscaled_size_x, unscaled_size_y); +} + + /* * Perform initial startup of the PC. * @@ -312,8 +415,7 @@ pc_init_modules(void) int c, i; pclog("Scanning for ROM images:\n"); - c = 0; - for (i=0; iexit(i); @@ -640,134 +767,216 @@ pc_close(void) /* - * Run the actual configured PC. + * The main thread runs the actual emulator code. + * + * We basically run until the upper layers terminate us, by + * setting the variable 'quited' there to 1. We get a pointer + * to that variable as our function argument. */ -int framecountx=0; -int sndcount=0; -int sreadlnum,swritelnum,segareads,segawrites, scycles_lost; -int serial_fifo_read, serial_fifo_write; -int emu_fps = 0; - -static wchar_t wmachine[2048]; -static wchar_t wcpu[2048]; - - -static void -pollmouse(void) -{ - int x, y, z; - - if (--pollmouse_delay) return; - - pollmouse_delay = 2; - - mouse_poll_host(); - - mouse_get_mickeys(&x, &y, &z); - - mouse_poll(x, y, z, mouse_buttons); -} - - void -pc_run(void) +pc_thread(void *param) { - wchar_t temp[200]; - int done = 0; + wchar_t temp[200], wcpu[2048]; + wchar_t wmachine[2048]; + uint64_t start_time, end_time; + uint32_t old_time, new_time; + int status_update_needed; + int done, drawits, frames; + int *quitp = (int *)param; + int framecountx; - startblit(); - clockrate = machines[machine].cpu[cpu_manufacturer].cpus[cpu].rspeed; - - if (is386) { -#ifdef USE_DYNAREC - if (cpu_use_dynarec) - exec386_dynarec(machines[machine].cpu[cpu_manufacturer].cpus[cpu].rspeed / 100); - else + pclog("PC: starting main thread...\n"); + + main_time = 0; + framecountx = 0; + status_update_needed = title_update = 1; + old_time = plat_get_ticks(); + done = drawits = frames = 0; + while (! *quitp) { + /* Update the Stat(u)s window with the current info. */ + if (status_update_needed) { +#if 1 + pclog("Updating STATS window..\n"); +// ui_status_update(); #endif - exec386(machines[machine].cpu[cpu_manufacturer].cpus[cpu].rspeed / 100); - } else if (AT) { - exec386(machines[machine].cpu[cpu_manufacturer].cpus[cpu].rspeed / 100); - } else { - execx86(machines[machine].cpu[cpu_manufacturer].cpus[cpu].rspeed / 100); - } + status_update_needed = 0; + } - keyboard_process(); + /* See if it is time to run a frame of code. */ + new_time = plat_get_ticks(); + drawits += (new_time - old_time); + old_time = new_time; + if (drawits > 0 && !dopause) { + /* Yes, so do one frame now. */ + start_time = plat_timer_read(); + drawits -= 10; + if (drawits > 50) + drawits = 0; - pollmouse(); + /* Run a block of code. */ + startblit(); + clockrate = machines[machine].cpu[cpu_manufacturer].cpus[cpu].rspeed; - if (joystick_type != 7) - joystick_poll(); + if (is386) { +#ifdef USE_DYNAREC + if (cpu_use_dynarec) + exec386_dynarec(clockrate/100); + else +#endif + exec386(clockrate/100); + } else if (AT) { + exec386(clockrate/100); + } else { + execx86(clockrate/100); + } - endblit(); + keyboard_process(); - framecountx++; - framecount++; - if (framecountx >= 100) { - framecountx = 0; - mips = (float)insc/1000000.0f; - insc = 0; - flops = (float)fpucount/1000000.0f; - fpucount = 0; - sreadlnum = readlnum; - swritelnum = writelnum; - segareads = egareads; - segawrites = egawrites; - scycles_lost = cycles_lost; + mouse_process(); + + joystick_process(); + + endblit(); + + /* Done with this frame, update statistics. */ + framecount++; + if (++framecountx >= 100) { + framecountx = 0; + + /* FIXME: all this should go into a "stats" struct! */ + mips = (float)insc/1000000.0f; + insc = 0; + flops = (float)fpucount/1000000.0f; + fpucount = 0; + sreadlnum = readlnum; + swritelnum = writelnum; + segareads = egareads; + segawrites = egawrites; + scycles_lost = cycles_lost; #ifdef USE_DYNAREC - cpu_recomp_blocks_latched = cpu_recomp_blocks; - cpu_recomp_ins_latched = cpu_state.cpu_recomp_ins; - cpu_recomp_full_ins_latched = cpu_recomp_full_ins; - cpu_new_blocks_latched = cpu_new_blocks; - cpu_recomp_flushes_latched = cpu_recomp_flushes; - cpu_recomp_evicted_latched = cpu_recomp_evicted; - cpu_recomp_reuse_latched = cpu_recomp_reuse; - cpu_recomp_removed_latched = cpu_recomp_removed; - cpu_reps_latched = cpu_reps; - cpu_notreps_latched = cpu_notreps; + cpu_recomp_blocks_latched = cpu_recomp_blocks; + cpu_recomp_ins_latched = cpu_state.cpu_recomp_ins; + cpu_recomp_full_ins_latched = cpu_recomp_full_ins; + cpu_new_blocks_latched = cpu_new_blocks; + cpu_recomp_flushes_latched = cpu_recomp_flushes; + cpu_recomp_evicted_latched = cpu_recomp_evicted; + cpu_recomp_reuse_latched = cpu_recomp_reuse; + cpu_recomp_removed_latched = cpu_recomp_removed; + cpu_reps_latched = cpu_reps; + cpu_notreps_latched = cpu_notreps; - cpu_recomp_blocks = 0; - cpu_state.cpu_recomp_ins = 0; - cpu_recomp_full_ins = 0; - cpu_new_blocks = 0; - cpu_recomp_flushes = 0; - cpu_recomp_evicted = 0; - cpu_recomp_reuse = 0; - cpu_recomp_removed = 0; - cpu_reps = 0; - cpu_notreps = 0; + cpu_recomp_blocks = 0; + cpu_state.cpu_recomp_ins = 0; + cpu_recomp_full_ins = 0; + cpu_new_blocks = 0; + cpu_recomp_flushes = 0; + cpu_recomp_evicted = 0; + cpu_recomp_reuse = 0; + cpu_recomp_removed = 0; + cpu_reps = 0; + cpu_notreps = 0; #endif - status_update_needed = 1; - readlnum = writelnum = 0; - egareads = egawrites = 0; - cycles_lost = 0; - mmuflush = 0; - emu_fps = frames; - frames = 0; - } + readlnum = writelnum = 0; + egareads = egawrites = 0; + cycles_lost = 0; + mmuflush = 0; + emu_fps = frames; + frames = 0; - if (win_title_update) { - mbstowcs(wmachine, machine_getname(), strlen(machine_getname())+1); - mbstowcs(wcpu, machines[machine].cpu[cpu_manufacturer].cpus[cpu].name, - strlen(machines[machine].cpu[cpu_manufacturer].cpus[cpu].name)+1); - swprintf(temp, sizeof_w(temp), L"%ls v%ls - %i%% - %ls - %ls - %ls", - EMU_NAME_W, EMU_VERSION_W, fps, wmachine, wcpu, - (!mousecapture) ? plat_get_string(IDS_2077) + /* We need a Status window update now. */ + status_update_needed = 1; + } + + if (title_update) { + mbstowcs(wmachine, machine_getname(), strlen(machine_getname())+1); + mbstowcs(wcpu, machines[machine].cpu[cpu_manufacturer].cpus[cpu].name, + strlen(machines[machine].cpu[cpu_manufacturer].cpus[cpu].name)+1); + swprintf(temp, sizeof_w(temp), + L"%ls v%ls - %i%% - %ls - %ls - %ls", + EMU_NAME_W,EMU_VERSION_W,fps,wmachine,wcpu, + (!mousecapture) ? plat_get_string(IDS_2077) : ((mouse_get_type(mouse_type) & MOUSE_TYPE_3BUTTON) ? plat_get_string(IDS_2078) : plat_get_string(IDS_2079))); - ui_window_title(temp); - win_title_update = 0; + ui_window_title(temp); + + title_update = 0; + } + + /* One more frame done! */ + done++; + + /* Every 200 frames we save the machine status. */ + if (++frames >= 200 && nvr_dosave) { + nvr_save(); + nvr_dosave = 0; + frames = 0; + } + + end_time = plat_timer_read(); + main_time += (end_time - start_time); + } else { + /* Just so we dont overload the host OS. */ + plat_delay_ms(1); + } + + /* If needed, hand a screen resize. */ + if (!video_fullscreen && doresize && (scrnsz_x>0) && (scrnsz_y>0)) { +#if 1 + plat_resize(scrnsz_x, scrnsz_y); +#else + SendMessage(hwndSBAR, SB_GETBORDERS, 0, (LPARAM)sb_borders); + GetWindowRect(hwndMain, &r); + MoveWindow(hwndRender, 0, 0, scrnsz_x, scrnsz_y, TRUE); + GetWindowRect(hwndRender, &r); + MoveWindow(hwndSBAR, + 0, r.bottom+GetSystemMetrics(SM_CYEDGE), + scrnsz_x, 17, TRUE); + GetWindowRect(hwndMain, &r); + + MoveWindow(hwndMain, r.left, r.top, + scrnsz_x+(GetSystemMetrics(vid_resize ? SM_CXSIZEFRAME : SM_CXFIXEDFRAME) * 2), + scrnsz_y+(GetSystemMetrics(SM_CYEDGE)*2)+(GetSystemMetrics(vid_resize?SM_CYSIZEFRAME:SM_CYFIXEDFRAME)*2)+GetSystemMetrics(SM_CYMENUSIZE)+GetSystemMetrics(SM_CYCAPTION)+17+sb_borders[1]+1, + TRUE); + + if (mousecapture) { + GetWindowRect(hwndRender, &r); + ClipCursor(&r); + } +#endif + + doresize = 0; + } + + /* If requested, leave full-screen mode. */ + if (leave_fullscreen_flag) { +#if 1 + pclog("Leaving full-screen mode..\n"); +// plat_fullscreen(0); +#else + SendMessage(hwndMain, WM_LEAVEFULLSCREEN, 0, 0); +#endif + leave_fullscreen_flag = 0; + } + +#if 0 + /* Do we really need this all the time? */ + if (video_fullscreen && infocus) + SetCursorPos(9999, 9999); +#endif } - done++; + pclog("PC: main thread done.\n"); } +/* Handler for the 1-second timer to refresh the window title. */ void -onesec(void) +pc_onesec(void) { fps = framecount; framecount = 0; - win_title_update = 1; + + title_update = 1; } diff --git a/src/plat.h b/src/plat.h index 9b9f27eb3..c62a9899c 100644 --- a/src/plat.h +++ b/src/plat.h @@ -8,7 +8,7 @@ * * Define the various platform support functions. * - * Version: @(#)plat.h 1.0.9 2017/10/16 + * Version: @(#)plat.h 1.0.11 2017/10/18 * * Authors: Miran Grca, * Fred N. van Kempen, @@ -33,7 +33,14 @@ extern "C" { #endif /* Global variables residing in the platform module. */ -GLOBAL int dopause; +GLOBAL int dopause, /* system is paused */ + doresize, /* screen resize requested */ + quited, /* system exit requested */ + leave_fullscreen_flag; /* windowed-mode requested */ +GLOBAL uint64_t timer_freq; +//GLOBAL int efwinsizey; +GLOBAL int infocus; +GLOBAL int mousecapture; /* System-related functions. */ @@ -52,6 +59,10 @@ extern uint64_t plat_timer_read(void); extern uint32_t plat_get_ticks(void); extern void plat_delay_ms(uint32_t count); extern void plat_pause(int p); +extern int plat_vidapi(char *name); +extern int plat_setvid(int api); +extern void plat_setfullscreen(int on); +extern void plat_resize(int max_x, int max_y); /* Return the size (in wchar's) of a wchar_t array. */ @@ -71,7 +82,6 @@ extern wchar_t *plat_get_string_from_string(char *str); /* Platform-specific device support. */ extern uint8_t host_cdrom_drive_available[26]; extern uint8_t host_cdrom_drive_available_num; -extern uint32_t cdrom_capacity; extern void cdrom_init_host_drives(void); extern void cdrom_eject(uint8_t id); @@ -109,8 +119,6 @@ extern int thread_release_mutex(mutex_t *mutex); /* Other stuff. */ extern void startblit(void); extern void endblit(void); -extern void updatewindowsize(int x, int y); -extern void uws_natural(void); extern void leave_fullscreen(void); extern void take_screenshot(void); diff --git a/src/plat_joystick.h b/src/plat_joystick.h index aecb3537c..ecb80168e 100644 --- a/src/plat_joystick.h +++ b/src/plat_joystick.h @@ -4,66 +4,66 @@ #ifdef __cplusplus extern "C" { #endif - void joystick_init(); - void joystick_close(); - void joystick_poll(); - - typedef struct plat_joystick_t - { - char name[64]; - - int a[8]; - int b[32]; - int p[4]; - - struct - { - char name[32]; - int id; - } axis[8]; - - struct - { - char name[32]; - int id; - } button[32]; - - struct - { - char name[32]; - int id; - } pov[4]; - - int nr_axes; - int nr_buttons; - int nr_povs; - } plat_joystick_t; +extern void joystick_init(void); +extern void joystick_close(void); +extern void joystick_process(void); - #define MAX_PLAT_JOYSTICKS 8 +typedef struct plat_joystick_t +{ + char name[64]; - extern plat_joystick_t plat_joystick_state[MAX_PLAT_JOYSTICKS]; - extern int joysticks_present; + int a[8]; + int b[32]; + int p[4]; - #define POV_X 0x80000000 - #define POV_Y 0x40000000 - - typedef struct joystick_t - { - int axis[8]; - int button[32]; - int pov[4]; - - int plat_joystick_nr; - int axis_mapping[8]; - int button_mapping[32]; - int pov_mapping[4][2]; - } joystick_t; + struct + { + char name[32]; + int id; + } axis[8]; - #define MAX_JOYSTICKS 4 - extern joystick_t joystick_state[MAX_JOYSTICKS]; + struct + { + char name[32]; + int id; + } button[32]; - #define JOYSTICK_PRESENT(n) (joystick_state[n].plat_joystick_nr != 0) + struct + { + char name[32]; + int id; + } pov[4]; + + int nr_axes; + int nr_buttons; + int nr_povs; +} plat_joystick_t; + +#define MAX_PLAT_JOYSTICKS 8 + +extern plat_joystick_t plat_joystick_state[MAX_PLAT_JOYSTICKS]; +extern int joysticks_present; + +#define POV_X 0x80000000 +#define POV_Y 0x40000000 + +typedef struct joystick_t +{ + int axis[8]; + int button[32]; + int pov[4]; + + int plat_joystick_nr; + int axis_mapping[8]; + int button_mapping[32]; + int pov_mapping[4][2]; +} joystick_t; + +#define MAX_JOYSTICKS 4 +extern joystick_t joystick_state[MAX_JOYSTICKS]; + +#define JOYSTICK_PRESENT(n) (joystick_state[n].plat_joystick_nr != 0) #ifdef __cplusplus } -#endif \ No newline at end of file +#endif diff --git a/src/plat_mouse.h b/src/plat_mouse.h index ff248f301..f5be1597c 100644 --- a/src/plat_mouse.h +++ b/src/plat_mouse.h @@ -1,16 +1,22 @@ /* Copyright holders: Sarah Walker see COPYING for more details */ + + +extern int mousecapture; +extern int mouse_buttons; + + #ifdef __cplusplus extern "C" { #endif - void mouse_init(); - void mouse_close(); - extern int mouse_buttons; - void mouse_poll_host(); - void mouse_get_mickeys(int *x, int *y, int *z); - extern int mousecapture; +extern void mouse_init(void); +extern void mouse_close(void); +extern void mouse_process(void); +extern void mouse_poll_host(void); +extern void mouse_get_mickeys(int *x, int *y, int *z); + #ifdef __cplusplus } #endif diff --git a/src/rom.c b/src/rom.c index 4ab1ee82c..ad27f969f 100644 --- a/src/rom.c +++ b/src/rom.c @@ -13,7 +13,7 @@ * - c386sx16 BIOS fails checksum * - the loadfont() calls should be done elsewhere * - * Version: @(#)rom.c 1.0.13 2017/10/16 + * Version: @(#)rom.c 1.0.14 2017/10/17 * * Authors: Sarah Walker, * Miran Grca, @@ -565,7 +565,7 @@ rom_load_bios(int rom_id) return(1); case ROM_DESKPRO_386: - if (rom_load_interleaved( + if (! rom_load_interleaved( L"roms/machines/deskpro386/109592-005.U11.bin", L"roms/machines/deskpro386/109591-005.U13.bin", 0x000000, 32768, 0, rom)) break; diff --git a/src/ui.h b/src/ui.h index 52f675e7d..54823da29 100644 --- a/src/ui.h +++ b/src/ui.h @@ -8,7 +8,7 @@ * * Define the various UI functions. * - * Version: @(#)ui.h 1.0.4 2017/10/16 + * Version: @(#)ui.h 1.0.5 2017/10/16 * * Authors: Miran Grca, * Fred N. van Kempen, @@ -41,6 +41,7 @@ extern "C" { extern int ui_msgbox(int type, void *arg); +extern void ui_check_menu_item(int id, int checked); /* Status Bar functions. */ #define SB_ICON_WIDTH 24 diff --git a/src/video/vid_cga.c b/src/video/vid_cga.c index e5cef155b..7f6ad068f 100644 --- a/src/video/vid_cga.c +++ b/src/video/vid_cga.c @@ -8,7 +8,7 @@ * * Emulation of the old and new IBM CGA graphics cards. * - * Version: @(#)vid_cga.c 1.0.5 2017/10/16 + * Version: @(#)vid_cga.c 1.0.7 2017/10/18 * * Authors: Sarah Walker, * Miran Grca, @@ -402,7 +402,7 @@ void cga_poll(void *p) ysize = cga->lastline - cga->firstline; if (xsize < 64) xsize = 656; if (ysize < 32) ysize = 200; - updatewindowsize(xsize, (ysize << 1) + 16); + set_screen_size(xsize, (ysize << 1) + 16); } if (cga->composite) diff --git a/src/video/vid_colorplus.c b/src/video/vid_colorplus.c index cd220e702..fb3cdceba 100644 --- a/src/video/vid_colorplus.c +++ b/src/video/vid_colorplus.c @@ -8,7 +8,7 @@ * * Plantronics ColorPlus emulation. * - * Version: @(#)vid_colorplus.c 1.0.1 2017/10/16 + * Version: @(#)vid_colorplus.c 1.0.3 2017/10/18 * * Authors: Sarah Walker, * Miran Grca, @@ -321,7 +321,7 @@ void colorplus_poll(void *p) ysize = colorplus->cga.lastline - colorplus->cga.firstline; if (xsize < 64) xsize = 656; if (ysize < 32) ysize = 200; - updatewindowsize(xsize, (ysize << 1) + 16); + set_screen_size(xsize, (ysize << 1) + 16); } if (colorplus->cga.composite) diff --git a/src/video/vid_ega.c b/src/video/vid_ega.c index b5c2d1bdd..e3f494950 100644 --- a/src/video/vid_ega.c +++ b/src/video/vid_ega.c @@ -9,7 +9,7 @@ * Emulation of the EGA, Chips & Technologies SuperEGA, and * AX JEGA graphics cards. * - * Version: @(#)vid_ega.c 1.0.6 2017/10/16 + * Version: @(#)vid_ega.c 1.0.8 2017/10/18 * * Authors: Sarah Walker, * Miran Grca, @@ -687,9 +687,9 @@ void ega_poll(void *p) } if (ega->vres) - updatewindowsize(xsize + x_add_ex, (ysize << 1) + y_add_ex); + set_screen_size(xsize + x_add_ex, (ysize << 1) + y_add_ex); else - updatewindowsize(xsize + x_add_ex, ysize + y_add_ex); + set_screen_size(xsize + x_add_ex, ysize + y_add_ex); } if (enable_overscan) diff --git a/src/video/vid_genius.c b/src/video/vid_genius.c index d06472887..20ab61790 100644 --- a/src/video/vid_genius.c +++ b/src/video/vid_genius.c @@ -8,7 +8,7 @@ * * MDSI Genius VHR emulation. * - * Version: @(#)vid_genius.c 1.0.1 2017/10/16 + * Version: @(#)vid_genius.c 1.0.3 2017/10/18 * * Authors: Sarah Walker, * Miran Grca, @@ -557,7 +557,7 @@ void genius_poll(void *p) ysize = GENIUS_YSIZE; if (xsize < 64) xsize = 656; if (ysize < 32) ysize = 200; - updatewindowsize(xsize, ysize); + set_screen_size(xsize, ysize); } video_blit_memtoscreen_8(0, 0, xsize, ysize); diff --git a/src/video/vid_hercules.c b/src/video/vid_hercules.c index f072ff324..738a1c63f 100644 --- a/src/video/vid_hercules.c +++ b/src/video/vid_hercules.c @@ -8,7 +8,7 @@ * * Hercules emulation. * - * Version: @(#)vid_hercules.c 1.0.2 2017/10/16 + * Version: @(#)vid_hercules.c 1.0.4 2017/10/18 * * Authors: Sarah Walker, * Miran Grca, @@ -290,7 +290,7 @@ void hercules_poll(void *p) // printf("Resize to %i,%i - R1 %i\n",xsize,ysize,crtcm[1]); if (xsize < 64) xsize = 656; if (ysize < 32) ysize = 200; - updatewindowsize(xsize, ysize); + set_screen_size(xsize, ysize); } video_blit_memtoscreen_8(0, hercules->firstline, xsize, ysize); frames++; diff --git a/src/video/vid_herculesplus.c b/src/video/vid_herculesplus.c index eff620f8e..a9bf93229 100644 --- a/src/video/vid_herculesplus.c +++ b/src/video/vid_herculesplus.c @@ -8,7 +8,7 @@ * * Hercules InColor emulation. * - * Version: @(#)vid_herculesplus.c 1.0.1 2017/10/16 + * Version: @(#)vid_herculesplus.c 1.0.3 2017/10/18 * * Authors: Sarah Walker, * Miran Grca, @@ -639,7 +639,7 @@ void herculesplus_poll(void *p) ysize = herculesplus->lastline - herculesplus->firstline; if (xsize < 64) xsize = 656; if (ysize < 32) ysize = 200; - updatewindowsize(xsize, ysize); + set_screen_size(xsize, ysize); } video_blit_memtoscreen(0, herculesplus->firstline, 0, herculesplus->lastline - herculesplus->firstline, xsize, herculesplus->lastline - herculesplus->firstline); frames++; diff --git a/src/video/vid_incolor.c b/src/video/vid_incolor.c index 5ea18478b..18e8b7879 100644 --- a/src/video/vid_incolor.c +++ b/src/video/vid_incolor.c @@ -8,7 +8,7 @@ * * Hercules InColor emulation. * - * Version: @(#)vid_incolor.c 1.0.1 2017/10/16 + * Version: @(#)vid_incolor.c 1.0.3 2017/10/18 * * Authors: Sarah Walker, * Miran Grca, @@ -986,7 +986,7 @@ void incolor_poll(void *p) ysize = incolor->lastline - incolor->firstline; if (xsize < 64) xsize = 656; if (ysize < 32) ysize = 200; - updatewindowsize(xsize, ysize); + set_screen_size(xsize, ysize); } video_blit_memtoscreen(0, incolor->firstline, 0, incolor->lastline - incolor->firstline, xsize, incolor->lastline - incolor->firstline); frames++; diff --git a/src/video/vid_mda.c b/src/video/vid_mda.c index cd0be946a..dc350ff3b 100644 --- a/src/video/vid_mda.c +++ b/src/video/vid_mda.c @@ -8,7 +8,7 @@ * * MDA emulation. * - * Version: @(#)vid_mda.c 1.0.2 2017/10/16 + * Version: @(#)vid_mda.c 1.0.4 2017/10/18 * * Authors: Sarah Walker, * Miran Grca, @@ -249,7 +249,7 @@ void mda_poll(void *p) ysize = mda->lastline - mda->firstline; if (xsize < 64) xsize = 656; if (ysize < 32) ysize = 200; - updatewindowsize(xsize, ysize); + set_screen_size(xsize, ysize); } video_blit_memtoscreen_8(0, mda->firstline, xsize, mda->lastline - mda->firstline); frames++; diff --git a/src/video/vid_olivetti_m24.c b/src/video/vid_olivetti_m24.c index 91d6e52b8..90398d7fc 100644 --- a/src/video/vid_olivetti_m24.c +++ b/src/video/vid_olivetti_m24.c @@ -8,7 +8,7 @@ * * Olivetti M24 video emulation- essentially double-res CGA. * - * Version: @(#)vid_olivetti_m24.c 1.0.1 2017/10/16 + * Version: @(#)vid_olivetti_m24.c 1.0.3 2017/10/18 * * Authors: Sarah Walker, * Miran Grca, @@ -410,7 +410,7 @@ void m24_poll(void *p) ysize = m24->lastline - m24->firstline; if (xsize < 64) xsize = 656; if (ysize < 32) ysize = 200; - updatewindowsize(xsize, ysize + 16); + set_screen_size(xsize, ysize + 16); } video_blit_memtoscreen_8(0, m24->firstline - 8, xsize, (m24->lastline - m24->firstline) + 16); diff --git a/src/video/vid_pc1512.c b/src/video/vid_pc1512.c index 1e5a616da..ffb5c6fb4 100644 --- a/src/video/vid_pc1512.c +++ b/src/video/vid_pc1512.c @@ -15,7 +15,7 @@ * time as between 12 and 46 cycles. We currently always use * the lower number. * - * Version: @(#)vid_pc1512.c 1.0.1 2017/10/16 + * Version: @(#)vid_pc1512.c 1.0.3 2017/10/18 * * Authors: Sarah Walker, * Miran Grca, @@ -419,7 +419,7 @@ static void pc1512_poll(void *p) ysize = pc1512->lastline - pc1512->firstline; if (xsize < 64) xsize = 656; if (ysize < 32) ysize = 200; - updatewindowsize(xsize, (ysize << 1) + 16); + set_screen_size(xsize, (ysize << 1) + 16); } video_blit_memtoscreen_8(0, pc1512->firstline - 4, xsize, (pc1512->lastline - pc1512->firstline) + 8); diff --git a/src/video/vid_pcjr.c b/src/video/vid_pcjr.c index 43bcc580d..76be08f20 100644 --- a/src/video/vid_pcjr.c +++ b/src/video/vid_pcjr.c @@ -8,7 +8,7 @@ * * Video emulation for IBM PCjr. * - * Version: @(#)vid_pcjr.c 1.0.1 2017/10/16 + * Version: @(#)vid_pcjr.c 1.0.3 2017/10/18 * * Authors: Sarah Walker, * Miran Grca, @@ -509,7 +509,7 @@ void pcjr_poll(void *p) ysize = pcjr->lastline - pcjr->firstline; if (xsize < 64) xsize = 656; if (ysize < 32) ysize = 200; - updatewindowsize(xsize, (ysize << 1) + 16); + set_screen_size(xsize, (ysize << 1) + 16); } if (pcjr->composite) diff --git a/src/video/vid_svga.c b/src/video/vid_svga.c index 6d8da3ca8..f7b68a226 100644 --- a/src/video/vid_svga.c +++ b/src/video/vid_svga.c @@ -11,7 +11,7 @@ * This is intended to be used by another SVGA driver, * and not as a card in it's own right. * - * Version: @(#)vid_svga.c 1.0.5 2017/10/16 + * Version: @(#)vid_svga.c 1.0.7 2017/10/18 * * Authors: Sarah Walker, * Miran Grca, @@ -1617,30 +1617,13 @@ void svga_doblit(int y1, int y2, int wx, int wy, svga_t *svga) return; } - if (((wx!=xsize) || ((wy + 1)!=ysize)) && !vid_resize) - { - xsize=wx; - ysize=wy+1; - if (xsize<64) xsize=640; - if (ysize<32) ysize=200; - - if ((xsize > 2032) || (ysize > 2032)) - { - x_add = 0; - y_add = 0; - suppress_overscan = 1; - } - else - { - suppress_overscan = 0; - } - - updatewindowsize(xsize + x_add,ysize + y_add); - } - if (vid_resize) + if (((wx!=xsize) || ((wy+1)!=ysize))) { + /* Screen res has changed.. fix up, and let them know. */ xsize = wx; - ysize = wy + 1; + ysize = wy+1; + if (xsize<64) xsize = 640; + if (ysize<32) ysize = 200; if ((xsize > 2032) || (ysize > 2032)) { @@ -1652,6 +1635,8 @@ void svga_doblit(int y1, int y2, int wx, int wy, svga_t *svga) { suppress_overscan = 0; } + + set_screen_size(xsize+x_add,ysize+y_add); } if (enable_overscan && !suppress_overscan) diff --git a/src/video/vid_tandy.c b/src/video/vid_tandy.c index f703efb43..1029665f3 100644 --- a/src/video/vid_tandy.c +++ b/src/video/vid_tandy.c @@ -8,7 +8,7 @@ * * Emulation of the Tandy Model 1000 video. * - * Version: @(#)vid_tandy.c 1.0.1 2017/10/16 + * Version: @(#)vid_tandy.c 1.0.2 2017/10/18 * * Authors: Sarah Walker, * Miran Grca, @@ -546,7 +546,7 @@ void tandy_poll(void *p) ysize = tandy->lastline - tandy->firstline; if (xsize < 64) xsize = 656; if (ysize < 32) ysize = 200; - updatewindowsize(xsize, (ysize << 1) + 16); + set_screen_size(xsize, (ysize << 1) + 16); } if (tandy->composite) diff --git a/src/video/vid_tandysl.c b/src/video/vid_tandysl.c index f09590ad1..354963472 100644 --- a/src/video/vid_tandysl.c +++ b/src/video/vid_tandysl.c @@ -8,7 +8,7 @@ * * Emulation of the Tandy Model 1000/SL video. * - * Version: @(#)vid_tandysl.c 1.0.1 2017/10/16 + * Version: @(#)vid_tandysl.c 1.0.3 2017/10/18 * * Authors: Sarah Walker, * Miran Grca, @@ -615,7 +615,7 @@ static void tandysl_poll(void *p) ysize = tandy->lastline - tandy->firstline; if (xsize < 64) xsize = 656; if (ysize < 32) ysize = 200; - updatewindowsize(xsize, (ysize << 1) + 16); + set_screen_size(xsize, (ysize << 1) + 16); } video_blit_memtoscreen_8(0, tandy->firstline-4, xsize, (tandy->lastline - tandy->firstline) + 8); diff --git a/src/video/vid_wy700.c b/src/video/vid_wy700.c index cbcf404b7..76724b3fd 100644 --- a/src/video/vid_wy700.c +++ b/src/video/vid_wy700.c @@ -8,7 +8,7 @@ * * Wyse-700 emulation. * - * Version: @(#)vid_wy700.c 1.0.1 2017/10/16 + * Version: @(#)vid_wy700.c 1.0.3 2017/10/18 * * Authors: Sarah Walker, * Miran Grca, @@ -866,7 +866,7 @@ void wy700_poll(void *p) ysize = WY700_YSIZE; if (xsize < 64) xsize = 656; if (ysize < 32) ysize = 200; - updatewindowsize(xsize, ysize); + set_screen_size(xsize, ysize); } video_blit_memtoscreen_8(0, 0, xsize, ysize); diff --git a/src/video/video.c b/src/video/video.c index bf745f7b7..6081b660b 100644 --- a/src/video/video.c +++ b/src/video/video.c @@ -40,7 +40,7 @@ * W = 3 bus clocks * L = 4 bus clocks * - * Version: @(#)video.c 1.0.2 2017/10/13 + * Version: @(#)video.c 1.0.4 2017/10/18 * * Authors: Sarah Walker, * Miran Grca, @@ -73,33 +73,35 @@ enum { }; -int vid_cga_contrast = 0; +BITMAP *screen = NULL; +BITMAP *buffer= NULL, + *buffer32= NULL; +uint8_t fontdat[256][8]; /* IBM CGA font */ +uint8_t fontdatm[256][16]; /* IBM MDA font */ +uint8_t fontdatw[512][32]; /* Wyse700 font */ +uint8_t fontdat8x12[256][16]; /* MDSI Genius font */ +uint32_t pal_lookup[256]; +int xsize = 1, + ysize = 1; int cga_palette = 0; -int video_fullscreen = 0, - video_fullscreen_scale, - video_fullscreen_first; -uint32_t *video_6to8, - *video_15to32, - *video_16to32; -BITMAP *screen; +uint32_t *video_6to8 = NULL, + *video_15to32 = NULL, + *video_16to32 = NULL; int egareads = 0, egawrites = 0, changeframecount = 2; uint8_t rotatevga[8][256]; int frames = 0; -int fullchange; +int fullchange = 0; uint8_t edatlookup[4][4]; -int enable_overscan; -int overscan_x, - overscan_y; -int force_43; -int video_timing_b, - video_timing_w, - video_timing_l; -int video_res_x, - video_res_y, - video_bpp; -int video_speed = 0; +int overscan_x = 0, + overscan_y = 0; +int video_timing_b = 0, + video_timing_w = 0, + video_timing_l = 0; +int video_res_x = 0, + video_res_y = 0, + video_bpp = 0; int video_timing[6][4] = { { VIDEO_ISA, 8, 16, 32 }, { VIDEO_ISA, 6, 8, 16 }, @@ -108,14 +110,6 @@ int video_timing[6][4] = { { VIDEO_BUS, 4, 5, 10 }, { VIDEO_BUS, 3, 3, 4 } }; -BITMAP *buffer, - *buffer32; -uint8_t fontdat[256][8]; -uint8_t fontdatm[256][16]; -uint8_t fontdatw[512][32]; /* Wyse700 font */ -uint8_t fontdat8x12[256][16]; /* MDSI Genius font */ -int xsize=1, - ysize=1; PALETTE cgapal = { {0,0,0}, {0,42,0}, {42,0,0}, {42,21,0}, {0,0,0}, {0,42,42}, {42,0,42}, {42,42,42}, @@ -181,7 +175,6 @@ PALETTE cgapal_mono[6] = { {0x34,0x35,0x33},{0x37,0x37,0x34},{0x3e,0x3e,0x3a},{0x3f,0x3f,0x3b}, } }; -uint32_t pal_lookup[256]; static struct { @@ -193,11 +186,11 @@ static struct { event_t *wake_blit_thread; event_t *blit_complete; event_t *buffer_not_in_use; -} blit_data; +} blit_data; -static void (*memtoscreen_func)(int x, int y, int y1, int y2, int w, int h); -static void (*memtoscreen_8_func)(int x, int y, int w, int h); +static void (*blit_func)(int x, int y, int y1, int y2, int w, int h); +static void (*blit8_func)(int x, int y, int w, int h); static @@ -208,9 +201,9 @@ void blit_thread(void *param) thread_reset_event(blit_data.wake_blit_thread); if (blit_data.blit8) - memtoscreen_8_func(blit_data.x, blit_data.y, blit_data.w, blit_data.h); + blit8_func(blit_data.x, blit_data.y, blit_data.w, blit_data.h); else - memtoscreen_func(blit_data.x, blit_data.y, blit_data.y1, blit_data.y2, blit_data.w, blit_data.h); + blit_func(blit_data.x, blit_data.y, blit_data.y1, blit_data.y2, blit_data.w, blit_data.h); blit_data.busy = 0; thread_set_event(blit_data.blit_complete); @@ -221,8 +214,8 @@ void blit_thread(void *param) void video_setblit(void(*blit8)(int,int,int,int),void(*blit)(int,int,int,int,int,int)) { - memtoscreen_func = blit; - memtoscreen_8_func = blit8; + blit_func = blit; + blit8_func = blit8; } @@ -297,6 +290,9 @@ cgapal_rebuild(void) { int c; + /* We cannot do this (yet) if we have not been enabled yet. */ + if (video_6to8 == NULL) return; + for (c=0; c<256; c++) { pal_lookup[c] = makecol(video_6to8[cgapal[c].r], video_6to8[cgapal[c].g], @@ -482,6 +478,8 @@ video_init(void) { int c, d, e; + pclog("VIDEO: initializing..\n"); + /* Account for overscan. */ buffer32 = create_bitmap(2048, 2048); @@ -583,7 +581,10 @@ loadfont(wchar_t *s, int format) int c,d; f = rom_fopen(s, L"rb"); - if (f == NULL) return; + if (f == NULL) { + pclog("VIDEO: cannot load font '%ls', fmt=%d\n", s, format); + return; + } switch (format) { case 0: /* MDA */ diff --git a/src/video/video.h b/src/video/video.h index 1aaf09e84..bbdb9f0eb 100644 --- a/src/video/video.h +++ b/src/video/video.h @@ -57,8 +57,6 @@ extern int video_res_x, video_res_y, video_bpp; extern int vid_resize; -extern int winsizex, - winsizey; extern int cga_palette; extern int vid_cga_contrast; extern int video_grayscale; diff --git a/src/win/win_vnc.c b/src/vnc.c similarity index 84% rename from src/win/win_vnc.c rename to src/vnc.c index a5e8f4413..a76544a80 100644 --- a/src/win/win_vnc.c +++ b/src/vnc.c @@ -6,9 +6,9 @@ * * This file is part of the 86Box distribution. * - * Implement the VNC renderer with LibVNCServer. + * Implement the VNC remote renderer with LibVNCServer. * - * Version: @(#)win_vnc.c 1.0.3 2017/10/16 + * Version: @(#)lnx_vnc.c 1.0.4 2017/10/18 * * Authors: Fred N. van Kempen, * Based on raw code by RichardG, @@ -17,17 +17,26 @@ */ #include #include -#include "../86box.h" -#include "../device.h" -#include "../video/video.h" -#include "../plat.h" -#include "../plat_keyboard.h" -#include "../ui.h" +#include +#include +#include +#include "86box.h" +#include "device.h" +#include "video/video.h" +#include "plat.h" +#include "plat_keyboard.h" +#include "plat_mouse.h" +#include "ui.h" #define BITMAP MY_BITMAP #include #undef BITMAP -#include "win.h" -#include "win_vnc.h" +#include "vnc.h" + + +#define VNC_MIN_X 320 +#define VNC_MAX_X 2048 +#define VNC_MIN_Y 200 +#define VNC_MAX_Y 2048 static rfbScreenInfoPtr rfb = NULL; @@ -107,53 +116,6 @@ static int keysyms_ff[] = { }; -static void -vnc_clientgone(rfbClientPtr cl) -{ - pclog("VNC: client disconnected: %s\n", cl->host); - - if (clients > 0) - clients--; - if (clients == 0) { - /* No more clients, pause the emulator. */ - pclog("VNC: no clients, pausing..\n"); - plat_pause(1); - } -} - - -static enum rfbNewClientAction -vnc_newclient(rfbClientPtr cl) -{ - /* Hook the ClientGone function so we know when they're gone. */ - cl->clientGoneHook = vnc_clientgone; - - pclog("VNC: new client: %s\n", cl->host); - if (++clients == 1) { - /* We now have clients, un-pause the emulator. */ - pclog("VNC: unpausing..\n"); - plat_pause(0); - } - - return(RFB_CLIENT_ACCEPT); -} - - -static void -vnc_display(rfbClientPtr cl) -{ - /* Avoid race condition between resize and update. */ - if (!updatingSize && cl->newFBSizePending) { - updatingSize = 1; - } else if (updatingSize && !cl->newFBSizePending) { - updatingSize = 0; - - allowedX = rfb->width; - allowedY = rfb->height; - } -} - - static void vnc_kbdevent(rfbBool down, rfbKeySym k, rfbClientPtr cl) { @@ -177,18 +139,79 @@ vnc_kbdevent(rfbBool down, rfbKeySym k, rfbClientPtr cl) (will_press >> 8) & 0xff, will_press & 0xff); #endif - // first key + /* First key. */ key = (will_press >> 8) & 0xff; if (key > 0) recv_key[key] = down; - // second key + /* Second key. */ key = will_press & 0xff; if (key > 0) recv_key[key] = down; } +static void +vnc_ptrevent(int but, int x, int y, rfbClientPtr cl) +{ + if (x>=0 && x=0 && yhost); + + if (clients > 0) + clients--; + if (clients == 0) { + /* No more clients, pause the emulator. */ + pclog("VNC: no clients, pausing..\n"); + plat_pause(1); + } +} + + +static enum rfbNewClientAction +vnc_newclient(rfbClientPtr cl) +{ + /* Hook the ClientGone function so we know when they're gone. */ + cl->clientGoneHook = vnc_clientgone; + + pclog("VNC: new client: %s\n", cl->host); + if (++clients == 1) { + /* We now have clients, un-pause the emulator if needed. */ + pclog("VNC: unpausing..\n"); + plat_pause(0); + } + + /* For now, we always accept clients. */ + return(RFB_CLIENT_ACCEPT); +} + + +static void +vnc_display(rfbClientPtr cl) +{ + /* Avoid race condition between resize and update. */ + if (!updatingSize && cl->newFBSizePending) { + updatingSize = 1; + } else if (updatingSize && !cl->newFBSizePending) { + updatingSize = 0; + + allowedX = rfb->width; + allowedY = rfb->height; + } +} + + static void vnc_blit(int x, int y, int y1, int y2, int w, int h) { @@ -196,9 +219,9 @@ vnc_blit(int x, int y, int y1, int y2, int w, int h) int yy; for (yy=y1; yyframeBuffer)[yy*2048]); + p = (uint32_t *)&(((uint32_t *)rfb->frameBuffer)[yy*VNC_MAX_X]); - if ((y+yy) >= 0 && (y+yy) < 2048) + if ((y+yy) >= 0 && (y+yy) < VNC_MAX_Y) memcpy(p, &(((uint32_t *)buffer32->line[y+yy])[x]), w*4); } @@ -216,7 +239,7 @@ vnc_blit8(int x, int y, int w, int h) int xx, yy; for (yy = 0; yy < h; yy++) { - p = (uint32_t *)&(((uint32_t *)rfb->frameBuffer)[yy*2048]); + p = (uint32_t *)&(((uint32_t *)rfb->frameBuffer)[yy*VNC_MAX_X]); if ((y+yy) >= 0 && (y+yy) < buffer->h) { for (xx=0; xxdesktopName = title; - rfb->frameBuffer = (char *)malloc(2048 * 2048 * 4); + rfb->frameBuffer = (char *)malloc(VNC_MAX_X*VNC_MAX_Y*4); rfb->serverFormat = rpf; rfb->alwaysShared = TRUE; rfb->displayHook = vnc_display; + rfb->ptrAddEvent = vnc_ptrevent; rfb->kbdAddEvent = vnc_kbdevent; rfb->newClientHook = vnc_newclient; + /* Set up our current resolution. */ + rfb->width = allowedX; + rfb->height = allowedY; + rfbInitServer(rfb); rfbRunEventLoop(rfb, -1, TRUE); @@ -271,10 +301,10 @@ vnc_init(HWND h) /* Set up our BLIT handlers. */ video_setblit(vnc_blit8, vnc_blit); - pclog("VNC: init complete.\n"); - clients = 0; + pclog("VNC: init complete.\n"); + return(1); } @@ -282,7 +312,13 @@ vnc_init(HWND h) void vnc_close(void) { - pclog("VNC: closed.\n"); + if (rfb != NULL) { + free(rfb->frameBuffer); + + rfbScreenCleanup(rfb); + + rfb = NULL; + } } @@ -294,6 +330,12 @@ vnc_resize(int x, int y) if (rfb == NULL) return; + /* TightVNC doesn't like certain sizes.. */ + if (x < VNC_MIN_X || x > VNC_MAX_X || y < VNC_MIN_Y || y > VNC_MAX_Y) { + pclog("VNC: invalid resoltion %dx%d requested!\n", x, y); + return; + } + if ((x != rfb->width || y != rfb->height) && x > 160 && y > 0) { pclog("VNC: updating resolution: %dx%d\n", x, y); @@ -313,6 +355,7 @@ vnc_resize(int x, int y) } +/* Tell them to pause if we have no clients. */ int vnc_pause(void) { diff --git a/src/win/win_vnc.h b/src/vnc.h similarity index 76% rename from src/win/win_vnc.h rename to src/vnc.h index ba3d793e9..96330284d 100644 --- a/src/win/win_vnc.h +++ b/src/vnc.h @@ -8,23 +8,31 @@ * * Definitions for the VNC renderer. * - * Version: @(#)win_vnc.h 1.0.1 2017/10/13 + * Version: @(#)vnc.h 1.0.3 2017/10/18 * * Authors: RichardG, * Fred N. van Kempen, * * Copyright 2017 Fred N. van Kempen. */ -#ifndef WIN_VNC_H -# define WIN_VNC_H +#ifndef EMU_VNC_H +# define EMU_VNC_H -extern int vnc_init(HWND h); +#ifdef __cplusplus +extern "C" { +#endif + +extern int vnc_init(void *); extern void vnc_close(void); extern void vnc_resize(int x, int y); extern int vnc_pause(void); extern void vnc_take_screenshot(wchar_t *fn); +#ifdef __cplusplus +} +#endif -#endif /*WIN_VNC_H*/ + +#endif /*EMU_VNC_H*/ diff --git a/src/win/Makefile.mingw b/src/win/Makefile.mingw index 95a3c5beb..64ba39c6a 100644 --- a/src/win/Makefile.mingw +++ b/src/win/Makefile.mingw @@ -8,7 +8,7 @@ # # Makefile for Win32 (MinGW32) environment. # -# Version: @(#)Makefile.mingw 1.0.63 2017/10/14 +# Version: @(#)Makefile.mingw 1.0.64 2017/10/18 # # Authors: Miran Grca, # Fred N. van Kempen, @@ -224,7 +224,7 @@ RFLAGS += -DUSE_VNC VNCLIB := -L$(VNC_PATH)\LIB endif VNCLIB += -lvncserver -VNCOBJ := win_vnc.o +VNCOBJ := vnc.o endif ifeq ($(RDP), y) @@ -235,7 +235,7 @@ RFLAGS += -DUSE_RDP RDPLIB := -L$(RDP_PATH)\LIB endif RDPLIB += -lrdp -RDPOBJ := win_rdp.o +RDPOBJ := rdp.o endif # Options for the DEV branch. @@ -276,7 +276,7 @@ endif MAINOBJ := pc.o config.o random.o timer.o io.o dma.o nmi.o pic.o \ pit.o ppi.o pci.o mca.o mcr.o mem.o memregs.o rom.o \ - device.o nvr.o nvr_at.o nvr_ps2.o \ + device.o nvr.o nvr_at.o nvr_ps2.o $(VNCOBJ) $(RDPOBJ) \ intel.o intel_flash.o intel_sio.o CPUOBJ := cpu.o 386.o 386_dynarec.o 808x.o \ @@ -400,12 +400,11 @@ VIDOBJ := video.o \ PLATOBJ := win.o \ win_ddraw.o win_ddraw_fs.o win_d3d.o win_d3d_fs.o \ - $(VNCOBJ) $(RDPOBJ) \ - win_dynld.o win_thread.o $(WSERIAL) win_cdrom.o win_cdrom_ioctl.o \ - win_keyboard.o win_mouse.o win_joystick.o win_midi.o \ + win_dynld.o win_thread.o $(WSERIAL) win_video.o \ + win_cdrom.o win_cdrom_ioctl.o win_keyboard.o win_mouse.o \ + win_joystick.o win_midi.o \ win_dialog.o win_about.o win_status.o win_stbar.o \ - win_settings.o win_deviceconfig.o win_joystickconfig.o \ - $(OPENDIR) + win_settings.o win_deviceconfig.o win_joystickconfig.o OBJ := $(MAINOBJ) $(CPUOBJ) $(MCHOBJ) $(DEVOBJ) \ $(FDDOBJ) $(CDROMOBJ) $(HDDOBJ) \ @@ -513,7 +512,7 @@ ifneq ($(AUTODEP), y) depclean: @-rm -f $(DEPFILE) 2>NUL @echo Creating dependencies.. - @echo # Run "make depends" to re-create this file. $(DEPFILE) + @echo # Run "make depends" to re-create this file. >$(DEPFILE) depends: DEPOBJ=$(OBJ:%.o=%.d) depends: depclean $(OBJ:%.o=%.d) diff --git a/src/win/win.c b/src/win/win.c index c034c0e3f..15fafa5b7 100644 --- a/src/win/win.c +++ b/src/win/win.c @@ -8,7 +8,7 @@ * * The Emulator's Windows core. * - * Version: @(#)win.c 1.0.25 2017/10/16 + * Version: @(#)win.c 1.0.27 2017/10/18 * * Authors: Sarah Walker, * Miran Grca, @@ -59,11 +59,7 @@ #include "../plat_midi.h" #include "../ui.h" #include "win.h" -#include "win_ddraw.h" #include "win_d3d.h" -#ifdef USE_VNC -# include "win_vnc.h" -#endif #define TIMER_1SEC 1 @@ -74,32 +70,18 @@ typedef struct { } rc_str_t; -extern int status_update_needed; - - -/* Public data, more or less non-specific to platform. */ -int scale = 0; -uint64_t timer_freq; -int winsizex = 640, - winsizey = 480; -int efwinsizey = 480; -int gfx_present[GFX_MAX]; -int drawits = 0; -int mousecapture = 0; -uint64_t main_time; - -/* Public data, specific to platform. */ -HWND hwndMain; -HMENU menuMain; +/* Platform Public data, specific (defined in lnx.h.) */ +HINSTANCE hinstance; /* application instance */ +HWND hwndMain, /* application main window */ + hwndRender; /* machine render window */ +HMENU menuMain; /* application main menu */ HANDLE ghMutex; -HINSTANCE hinstance; -HICON hIcon[512]; -RECT oldclip; -LCID dwLanguage; +HICON hIcon[512]; /* icon data loaded from resources */ +LCID lang_id; /* current language ID used */ +DWORD dwSubLangID; +RECT oldclip; /* mouse rect */ int infocus = 1; -int recv_key[272]; -uint32_t dwLangID, - dwSubLangID; +int recv_key[272]; /* keyboard input buffer */ char openfilestring[260]; WCHAR wopenfilestring[260]; @@ -107,19 +89,11 @@ WCHAR wopenfilestring[260]; /* Local data. */ static HANDLE thMain; -static HWND hwndRender; /* machine render window */ static wchar_t wTitle[512]; static RAWINPUTDEVICE device; static HHOOK hKeyboardHook; static int hook_enabled = 0; static int save_window_pos = 0; -static int doresize = 0; -static int quited; -static int leave_fullscreen_flag = 0; -static int unscaled_size_x = 0; -static int unscaled_size_y = 0; -static uint64_t start_time; -static uint64_t end_time; static wchar_t **argv; static int argc; static wchar_t *argbuf; @@ -132,42 +106,6 @@ static rc_str_t *lpRCstr2048, *lpRCstr5376, *lpRCstr5632, *lpRCstr6144; -static struct { - int local; - int (*init)(HWND h); - void (*close)(void); - void (*resize)(int x, int y); - int (*pause)(void); -} vid_apis[2][4] = { - { - { 1, ddraw_init, ddraw_close, NULL, ddraw_pause }, - { 1, d3d_init, d3d_close, d3d_resize, d3d_pause }, -#ifdef USE_VNC - { 0, vnc_init, vnc_close, vnc_resize, vnc_pause }, -#else - { 0, NULL, NULL, NULL, NULL }, -#endif -#ifdef USE_RDP - { 0, rdp_init, rdp_close, rdp_resize, rdp_pause } -#else - { 0, NULL, NULL, NULL, NULL } -#endif - }, - { - { 1, ddraw_fs_init, ddraw_fs_close, NULL, ddraw_fs_pause }, - { 1, d3d_fs_init, d3d_fs_close, NULL, d3d_fs_pause }, -#ifdef USE_VNC - { 0, vnc_init, vnc_close, vnc_resize, vnc_pause }, -#else - { 0, NULL, NULL, NULL, NULL }, -#endif -#ifdef USE_RDP - { 0, rdp_init, rdp_close, rdp_resize, rdp_pause } -#else - { 0, NULL, NULL, NULL, NULL } -#endif - } -}; HICON @@ -219,80 +157,6 @@ video_toggle_option(HMENU h, int *val, int id) } -/* The main thread runs the actual emulator code. */ -static void -MainThread(LPVOID param) -{ - int sb_borders[3]; - DWORD old_time, new_time; - int frames = 0; - RECT r; - - drawits = 0; - old_time = plat_get_ticks(); - while (! quited) { - if (status_update_needed) { - if (hwndStatus != NULL) - SendMessage(hwndStatus, WM_USER, 0, 0); - status_update_needed = 0; - } - - new_time = plat_get_ticks(); - drawits += new_time - old_time; - old_time = new_time; - if (drawits > 0 && !dopause) { - start_time = plat_timer_read(); - drawits -= 10; - if (drawits > 50) drawits = 0; - pc_run(); - - if (++frames >= 200 && nvr_dosave) { - frames = 0; - nvr_save(); - nvr_dosave = 0; - } - - end_time = plat_timer_read(); - main_time += end_time - start_time; - } else - plat_delay_ms(1); - - if (!video_fullscreen && vid_apis[0][vid_api].local && - doresize && (winsizex>0) && (winsizey>0)) { - SendMessage(hwndSBAR, SB_GETBORDERS, 0, (LPARAM) sb_borders); - GetWindowRect(hwndMain, &r); - MoveWindow(hwndRender, 0, 0, winsizex, winsizey, TRUE); - GetWindowRect(hwndRender, &r); - MoveWindow(hwndSBAR, - 0, r.bottom + GetSystemMetrics(SM_CYEDGE), - winsizex, 17, TRUE); - GetWindowRect(hwndMain, &r); - - MoveWindow(hwndMain, r.left, r.top, - winsizex + (GetSystemMetrics(vid_resize ? SM_CXSIZEFRAME : SM_CXFIXEDFRAME) * 2), - winsizey + (GetSystemMetrics(SM_CYEDGE) * 2) + (GetSystemMetrics(vid_resize ? SM_CYSIZEFRAME : SM_CYFIXEDFRAME) * 2) + GetSystemMetrics(SM_CYMENUSIZE) + GetSystemMetrics(SM_CYCAPTION) + 17 + sb_borders[1] + 1, - TRUE); - - if (mousecapture) { - GetWindowRect(hwndRender, &r); - ClipCursor(&r); - } - - doresize = 0; - } - - if (leave_fullscreen_flag) { - leave_fullscreen_flag = 0; - - SendMessage(hwndMain, WM_LEAVEFULLSCREEN, 0, 0); - } - - if (video_fullscreen && infocus) - SetCursorPos(9999, 9999); - } -} - - static void ResetAllMenus(void) { @@ -399,7 +263,7 @@ static LRESULT CALLBACK LowLevelKeyboardProc(int nCode, WPARAM wParam, LPARAM lParam) { BOOL bControlKeyDown; - KBDLLHOOKSTRUCT* p; + KBDLLHOOKSTRUCT *p; if (nCode < 0 || nCode != HC_ACTION) return(CallNextHookEx(hKeyboardHook, nCode, wParam, lParam)); @@ -528,42 +392,12 @@ MainWindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) #ifdef USE_RDP case IDM_VID_RDP: #endif - startblit(); - video_wait_for_blit(); - CheckMenuItem(hmenu, IDM_VID_DDRAW+vid_api, MF_UNCHECKED); - vid_apis[0][vid_api].close(); - vid_api = LOWORD(wParam) - IDM_VID_DDRAW; - if (vid_apis[0][vid_api].local) - ShowWindow(hwndRender, SW_SHOW); - else - ShowWindow(hwndRender, SW_HIDE); - CheckMenuItem(hmenu, IDM_VID_DDRAW+vid_api, MF_CHECKED); - vid_apis[0][vid_api].init(hwndRender); - endblit(); - device_force_redraw(); - cgapal_rebuild(); + plat_setvid(LOWORD(wParam) - IDM_VID_DDRAW); config_save(); break; case IDM_VID_FULLSCREEN: - if (video_fullscreen == 1) break; - - if (video_fullscreen_first) { - video_fullscreen_first = 0; - ui_msgbox(MBX_INFO, (wchar_t *)IDS_2074); - } - - startblit(); - video_wait_for_blit(); - mouse_close(); - vid_apis[0][vid_api].close(); - video_fullscreen = 1; - vid_apis[1][vid_api].init(hwndMain); - mouse_init(); - leave_fullscreen_flag = 0; - endblit(); - device_force_redraw(); - cgapal_rebuild(); + plat_setfullscreen(1); config_save(); break; @@ -802,28 +636,17 @@ MainWindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) break; case WM_SIZE: - winsizex = (lParam & 0xFFFF); - winsizey = (lParam >> 16) - (17 + 6); - if (winsizey < 0) - winsizey = 0; + scrnsz_x = (lParam & 0xFFFF); + scrnsz_y = (lParam >> 16) - (17 + 6); + if (scrnsz_y < 0) + scrnsz_y = 0; - MoveWindow(hwndSBAR, 0, winsizey + 6, winsizex, 17, TRUE); + plat_resize(scrnsz_x, scrnsz_y); - if (vid_apis[0][vid_api].local && (hwndRender != NULL)) { - MoveWindow(hwndRender, 0, 0, winsizex, winsizey, TRUE); + if (mousecapture) { + GetWindowRect(hwndRender, &rect); - if (vid_apis[video_fullscreen][vid_api].resize) { - startblit(); - video_wait_for_blit(); - vid_apis[video_fullscreen][vid_api].resize(winsizex, winsizey); - endblit(); - } - - if (mousecapture) { - GetWindowRect(hwndRender, &rect); - - ClipCursor(&rect); - } + ClipCursor(&rect); } if (window_remember) { @@ -851,7 +674,7 @@ MainWindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) case WM_TIMER: if (wParam == TIMER_1SEC) { - onesec(); + pc_onesec(); } break; @@ -865,15 +688,8 @@ MainWindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) break; case WM_LEAVEFULLSCREEN: - startblit(); - mouse_close(); - vid_apis[1][vid_api].close(); - video_fullscreen = 0; + plat_setfullscreen(0); config_save(); - vid_apis[0][vid_api].init(hwndRender); - mouse_init(); - endblit(); - device_force_redraw(); cgapal_rebuild(); break; @@ -1080,7 +896,15 @@ WinMain(HINSTANCE hInst, HINSTANCE hPrev, LPSTR lpszArg, int nFunsterStil) HWND hwnd; /* handle for our window */ HACCEL haccel; /* handle to accelerator table */ int bRet; - LARGE_INTEGER qpc_freq; + + /* We need this later. */ + hinstance = hInst; + + /* First, set our (default) language. */ + set_language(0x0409); + + /* Load common strings from the resource file. */ + LoadCommonStrings(); #ifdef USE_CONSOLE /* Create console window. */ @@ -1099,20 +923,14 @@ WinMain(HINSTANCE hInst, HINSTANCE hPrev, LPSTR lpszArg, int nFunsterStil) return(1); } - /* We need this later. */ - hinstance = hInst; - - /* Load common strings from the resource file. */ - LoadCommonStrings(); - /* Create our main window's class and register it. */ - wincl.hInstance = hInst; + wincl.hInstance = hinstance; wincl.lpszClassName = CLASS_NAME; wincl.lpfnWndProc = MainWindowProcedure; wincl.style = CS_DBLCLKS; /* Catch double-clicks */ wincl.cbSize = sizeof(WNDCLASSEX); - wincl.hIcon = LoadIcon(hInst, (LPCTSTR)100); - wincl.hIconSm = LoadIcon(hInst, (LPCTSTR)100); + wincl.hIcon = LoadIcon(hinstance, (LPCTSTR)100); + wincl.hIconSm = LoadIcon(hinstance, (LPCTSTR)100); wincl.hCursor = NULL; wincl.lpszMenuName = NULL; wincl.cbClsExtra = 0; @@ -1126,7 +944,7 @@ WinMain(HINSTANCE hInst, HINSTANCE hPrev, LPSTR lpszArg, int nFunsterStil) return(2); /* Load the Window Menu(s) from the resources. */ - menuMain = LoadMenu(hInst, MENU_NAME); + menuMain = LoadMenu(hinstance, MENU_NAME); /* Set the initial title for the program's main window. */ _swprintf(title, L"%s v%s", EMU_NAME_W, EMU_VERSION_W); @@ -1139,17 +957,17 @@ WinMain(HINSTANCE hInst, HINSTANCE hPrev, LPSTR lpszArg, int nFunsterStil) (WS_OVERLAPPEDWINDOW & ~WS_SIZEBOX) | DS_3DLOOK, CW_USEDEFAULT, /* Windows decides the position */ CW_USEDEFAULT, /* where window ends up on the screen */ - 640+(GetSystemMetrics(SM_CXFIXEDFRAME)*2), /* width */ - 480+(GetSystemMetrics(SM_CYFIXEDFRAME)*2)+GetSystemMetrics(SM_CYMENUSIZE)+GetSystemMetrics(SM_CYCAPTION)+1, /* and height in pixels */ + scrnsz_x+(GetSystemMetrics(SM_CXFIXEDFRAME)*2), /* width */ + scrnsz_y+(GetSystemMetrics(SM_CYFIXEDFRAME)*2)+GetSystemMetrics(SM_CYMENUSIZE)+GetSystemMetrics(SM_CYCAPTION)+1, /* and height in pixels */ HWND_DESKTOP, /* window is a child to desktop */ menuMain, /* menu */ - hInst, /* Program Instance handler */ + hinstance, /* Program Instance handler */ NULL); /* no Window Creation data */ hwndMain = hwnd; ui_window_title(title); - /* Resize the window if needed. */ + /* Set up main window for resizing if configured. */ if (vid_resize) SetWindowLongPtr(hwnd, GWL_STYLE, (WS_OVERLAPPEDWINDOW&~WS_MINIMIZEBOX)); @@ -1157,6 +975,7 @@ WinMain(HINSTANCE hInst, HINSTANCE hPrev, LPSTR lpszArg, int nFunsterStil) SetWindowLongPtr(hwnd, GWL_STYLE, (WS_OVERLAPPEDWINDOW&~WS_SIZEBOX&~WS_THICKFRAME&~WS_MAXIMIZEBOX&~WS_MINIMIZEBOX)); + /* Move to the last-saved position if needed. */ if (window_remember) MoveWindow(hwnd, window_x, window_y, window_w, window_h, TRUE); @@ -1167,7 +986,7 @@ WinMain(HINSTANCE hInst, HINSTANCE hPrev, LPSTR lpszArg, int nFunsterStil) ShowWindow(hwnd, nFunsterStil); /* Load the accelerator table */ - haccel = LoadAccelerators(hInst, ACCEL_NAME); + haccel = LoadAccelerators(hinstance, ACCEL_NAME); if (haccel == NULL) { MessageBox(hwndMain, plat_get_string(IDS_2053), @@ -1192,7 +1011,7 @@ WinMain(HINSTANCE hInst, HINSTANCE hPrev, LPSTR lpszArg, int nFunsterStil) get_registry_key_map(); /* Create the status bar window. */ - StatusBarCreate(hwndMain, IDC_STATUS, hInst); + StatusBarCreate(hwndMain, IDC_STATUS, hinstance); /* * Before we can create the Render window, we first have @@ -1203,24 +1022,18 @@ WinMain(HINSTANCE hInst, HINSTANCE hPrev, LPSTR lpszArg, int nFunsterStil) /* Create the Machine Rendering window. */ hwndRender = CreateWindow(L"STATIC", NULL, WS_CHILD|SS_BITMAP, 0, 0, 1, 1, hwnd, NULL, hInst, NULL); - MoveWindow(hwndRender, 0, 0, winsizex, winsizey, TRUE); + MoveWindow(hwndRender, 0, 0, scrnsz_x, scrnsz_y, TRUE); - /* If this is a local renderer, enable it. */ - if (vid_apis[0][vid_api].local) - ShowWindow(hwndRender, SW_SHOW); - - /* Select the best system renderer available. */ - if (! vid_apis[0][vid_api].init(hwndRender)) { - vid_api ^= 1; - if (! vid_apis[0][vid_api].init(hwndRender)) { - MessageBox(hwnd, - plat_get_string(IDS_2095), - plat_get_string(IDS_2050), - MB_OK | MB_ICONERROR); - return(5); - } + /* Initialize the configured Video API. */ + if (! plat_setvid(vid_api)) { + MessageBox(hwnd, + plat_get_string(IDS_2095), + plat_get_string(IDS_2050), + MB_OK | MB_ICONERROR); + return(5); } +#if 0 /* Initialize the rendering window, or fullscreen. */ if (start_in_fullscreen) { startblit(); @@ -1231,11 +1044,10 @@ WinMain(HINSTANCE hInst, HINSTANCE hPrev, LPSTR lpszArg, int nFunsterStil) endblit(); device_force_redraw(); } - if (vid_apis[video_fullscreen][vid_api].resize) { - startblit(); - vid_apis[video_fullscreen][vid_api].resize(winsizex, winsizey); - endblit(); - } +#endif + + /* Set up the current window size. */ + plat_resize(scrnsz_x, scrnsz_y); /* All done, fire up the actual emulated machine. */ if (! pc_init_modules()) { @@ -1253,23 +1065,18 @@ WinMain(HINSTANCE hInst, HINSTANCE hPrev, LPSTR lpszArg, int nFunsterStil) /* Set the PAUSE mode depending on the renderer. */ plat_pause(0); + /* Initialize raw keyboard input buffer. */ + memset(recv_key, 0x00, sizeof(recv_key)); + /* * Everything has been configured, and all seems to work, * so now it is time to start the main thread to do some * real work, and we will hang in here, dealing with the * UI until we're done. */ - timeBeginPeriod(1); - QueryPerformanceFrequency(&qpc_freq); - timer_freq = qpc_freq.QuadPart; - - atexit(releasemouse); - - thMain = (HANDLE)_beginthread(MainThread, 0, NULL); - SetThreadPriority(thMain, THREAD_PRIORITY_HIGHEST); + do_start(); /* Run the message loop. It will run until GetMessage() returns 0 */ - quited = 0; while (! quited) { bRet = GetMessage(&messages, NULL, 0, 0); if ((bRet == 0) || quited) break; @@ -1288,33 +1095,21 @@ WinMain(HINSTANCE hInst, HINSTANCE hPrev, LPSTR lpszArg, int nFunsterStil) DispatchMessage(&messages); } - if (recv_key[0x58] && recv_key[0x42] && mousecapture) { + if (mousecapture && recv_key[0x58] && recv_key[0x42]) { ClipCursor(&oldclip); ShowCursor(TRUE); mousecapture = 0; } - if ((recv_key[0x1D] || recv_key[0x9D]) && + if (video_fullscreen && + (recv_key[0x1D] || recv_key[0x9D]) && (recv_key[0x38] || recv_key[0xB8]) && - (recv_key[0x51] || recv_key[0xD1]) && video_fullscreen) { - leave_fullscreen(); + (recv_key[0x51] || recv_key[0xD1])) { + /* Signal "exit fullscreen mode". */ + plat_setfullscreen(0); } } - /* Why start??? --FvK */ - startblit(); - - Sleep(200); - TerminateThread(thMain, 0); - - nvr_save(); - - config_save(); - - pc_close(); - - vid_apis[video_fullscreen][vid_api].close(); - timeEndPeriod(1); if (mousecapture) { @@ -1322,24 +1117,100 @@ WinMain(HINSTANCE hInst, HINSTANCE hPrev, LPSTR lpszArg, int nFunsterStil) ShowCursor(TRUE); } - UnregisterClass(SUB_CLASS_NAME, hInst); - UnregisterClass(CLASS_NAME, hInst); + UnregisterClass(SUB_CLASS_NAME, hinstance); + UnregisterClass(CLASS_NAME, hinstance); + + /* Close down the emulator. */ + do_stop(); return(messages.wParam); } -FILE * -plat_fopen(wchar_t *path, wchar_t *mode) +wchar_t * +ui_window_title(wchar_t *s) { - return(_wfopen(path, mode)); + if (! video_fullscreen) { + if (s != NULL) + wcscpy(wTitle, s); + else + s = wTitle; + + SetWindowText(hwndMain, s); + } + + return(s); +} + + +/* Set (or re-set) the language for the application. */ +void +set_language(int id) +{ + LCID lcidNew = MAKELCID(id, dwSubLangID); + + if (lang_id != lcidNew) { + /* Set our new language ID. */ + lang_id = lcidNew; + + SetThreadLocale(lang_id); + + /* Load the strings table for this ID. */ + LoadCommonStrings(); + +#if 0 + /* Update the menus for this ID. */ + MenuUpdate(); +#endif + } +} + + +/* + * We do this here since there is platform-specific stuff + * going on here, and we do it in a function separate from + * main() so we can call it from the UI module as well. + */ +void +do_start(void) +{ + LARGE_INTEGER qpc; + + /* We have not stopped yet. */ + quited = 0; + + /* Initialize the high-precision timer. */ + timeBeginPeriod(1); + QueryPerformanceFrequency(&qpc); + timer_freq = qpc.QuadPart; + pclog("Main timer precision: %llu\n", timer_freq); + + atexit(releasemouse); + + /* Start the emulator, really. */ + thMain = thread_create(pc_thread, &quited); + SetThreadPriority(thMain, THREAD_PRIORITY_HIGHEST); +} + + +/* Cleanly stop the emulator. */ +void +do_stop(void) +{ + quited = 1; + + plat_delay_ms(100); + + pc_close(thMain); + + thMain = NULL; } void -plat_remove(wchar_t *path) +plat_get_exe_name(wchar_t *s, int size) { - _wremove(path); + GetModuleFileName(hinstance, s, size); } @@ -1359,10 +1230,17 @@ plat_chdir(wchar_t *path) } -void -plat_get_exe_name(wchar_t *s, int size) +FILE * +plat_fopen(wchar_t *path, wchar_t *mode) { - GetModuleFileName(hinstance, s, size); + return(_wfopen(path, mode)); +} + + +void +plat_remove(wchar_t *path) +{ + _wremove(path); } @@ -1417,22 +1295,6 @@ plat_put_backslash(wchar_t *s) } -wchar_t * -ui_window_title(wchar_t *s) -{ - if (! video_fullscreen) { - if (s != NULL) - wcscpy(wTitle, s); - else - s = wTitle; - - SetWindowText(hwndMain, s); - } - - return(s); -} - - int plat_dir_check(wchar_t *path) { @@ -1476,54 +1338,24 @@ plat_delay_ms(uint32_t count) /* We should have the language ID as a parameter. */ -void -win_set_language(void) -{ - SetThreadLocale(dwLanguage); -} - - -/* Update the global language used. This needs a parameter.. */ -void -win_language_update(void) -{ - win_set_language(); -#if 0 - MenuUpdate(); -#endif - LoadCommonStrings(); -} - - -void -win_language_check(void) -{ - LCID dwLanguageNew = MAKELCID(dwLangID, dwSubLangID); - - if (dwLanguageNew != dwLanguage) { - dwLanguage = dwLanguageNew; - - win_language_update(); - } -} - - void plat_pause(int p) { - static wchar_t oldtitle[512]; + static wchar_t oldtitle[128]; + wchar_t title[128]; /* If un-pausing, as the renderer if that's OK. */ if (p == 0) - p = vid_apis[video_fullscreen][vid_api].pause(); + p = get_vidpause(); /* If already so, done. */ if (dopause == p) return; if (p) { - wcscpy(oldtitle, wTitle); - wcscat(wTitle, L" - PAUSED -"); - ui_window_title(NULL); + wcscpy(oldtitle, ui_window_title(NULL)); + wcscpy(title, oldtitle); + wcscat(title, L" - PAUSED -"); + ui_window_title(title); } else { ui_window_title(oldtitle); } @@ -1531,7 +1363,8 @@ plat_pause(int p) dopause = p; /* Update the actual menu. */ - CheckMenuItem(menuMain, IDM_ACTION_PAUSE, (dopause)?MF_CHECKED:MF_UNCHECKED); + CheckMenuItem(menuMain, IDM_ACTION_PAUSE, + (dopause) ? MF_CHECKED : MF_UNCHECKED); } @@ -1569,169 +1402,3 @@ plat_get_string_from_string(char *str) { return(plat_get_string(atoi(str))); } - - -void -take_screenshot(void) -{ - wchar_t path[1024], fn[128]; - struct tm *info; - time_t now; - - pclog("Screenshot: video API is: %i\n", vid_api); - if ((vid_api < 0) || (vid_api > 1)) return; - - memset(fn, 0, sizeof(fn)); - memset(path, 0, sizeof(path)); - - (void)time(&now); - info = localtime(&now); - - plat_append_filename(path, cfg_path, SCREENSHOT_PATH, sizeof(path)-2); - - if (! plat_dir_check(path)) - plat_dir_create(path); - -#ifdef WIN32 - wcscat(path, L"\\"); -#else - wcscat(path, L"/"); -#endif - - switch(vid_api) { - case 0: /* ddraw */ - wcsftime(path, 128, L"%Y%m%d_%H%M%S.bmp", info); - plat_append_filename(path, cfg_path, fn, 1024); - if (video_fullscreen) - ddraw_fs_take_screenshot(path); - else - ddraw_take_screenshot(path); - pclog("Screenshot: fn='%ls'\n", path); - break; - - case 1: /* d3d9 */ - wcsftime(fn, 128, L"%Y%m%d_%H%M%S.png", info); - plat_append_filename(path, cfg_path, fn, 1024); - if (video_fullscreen) - d3d_fs_take_screenshot(path); - else - d3d_take_screenshot(path); - pclog("Screenshot: fn='%ls'\n", path); - break; - -#ifdef USE_VNC - case 2: /* vnc */ - wcsftime(fn, 128, L"%Y%m%d_%H%M%S.png", info); - plat_append_filename(path, cfg_path, fn, 1024); - vnc_take_screenshot(path); - pclog("Screenshot: fn='%ls'\n", path); - break; -#endif - } -} - - -void -startblit(void) -{ - WaitForSingleObject(ghMutex, INFINITE); -} - - -void -endblit(void) -{ - ReleaseMutex(ghMutex); -} - - -void -updatewindowsize(int x, int y) -{ - int owsx = winsizex; - int owsy = winsizey; - int temp_overscan_x = overscan_x; - int temp_overscan_y = overscan_y; - double dx, dy, dtx, dty; - - if (vid_resize) return; - - if (x < 160) x = 160; - if (y < 100) y = 100; - if (x > 2048) x = 2048; - if (y > 2048) y = 2048; - - if (suppress_overscan) - temp_overscan_x = temp_overscan_y = 0; - - unscaled_size_x=x; efwinsizey=y; - - if (force_43) { - dx = (double) x; - dtx = (double) temp_overscan_x; - - dy = (double) y; - dty = (double) temp_overscan_y; - - /* Account for possible overscan. */ - if (temp_overscan_y == 16) { - /* CGA */ - dy = (((dx - dtx) / 4.0) * 3.0) + dty; - } else if (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; - } else { - unscaled_size_y = efwinsizey; - } - - switch(scale) { - case 0: - winsizex = unscaled_size_x >> 1; - winsizey = unscaled_size_y >> 1; - break; - - case 1: - winsizex = unscaled_size_x; - winsizey = unscaled_size_y; - break; - - case 2: - winsizex = (unscaled_size_x * 3) >> 1; - winsizey = (unscaled_size_y * 3) >> 1; - break; - - case 3: - winsizex = unscaled_size_x << 1; - winsizey = unscaled_size_y << 1; - break; - } - - if ((owsx != winsizex) || (owsy != winsizey)) - doresize = 1; - else - doresize = 0; -} - - -void -uws_natural(void) -{ - updatewindowsize(unscaled_size_x, efwinsizey); -} - - -void -leave_fullscreen(void) -{ - leave_fullscreen_flag = 1; -} diff --git a/src/win/win.h b/src/win/win.h index 916087de9..424646f15 100644 --- a/src/win/win.h +++ b/src/win/win.h @@ -6,11 +6,9 @@ * * This file is part of the 86Box distribution. * - * This file should contain things only used by the platform - * support modules for Windows. Generic definitions for UI and - * platform go into ../plat*.h. + * Platform support defintions for Win32. * - * Version: @(#)win.h 1.0.5 2017/10/13 + * Version: @(#)win.h 1.0.6 2017/10/18 * * Authors: Sarah Walker, * Miran Grca, @@ -20,12 +18,10 @@ * Copyright 2016,2017 Miran Grca. * Copyright 2017 Fred N. van Kempen. */ -#ifndef BOX_WIN_H -# define BOX_WIN_H +#ifndef PLAT_WIN_H +# define PLAT_WIN_H -# ifndef NO_UNICODE -# define UNICODE -# endif +# define UNICODE # define BITMAP WINDOWS_BITMAP # if 0 # ifdef _WIN32_WINNT @@ -52,13 +48,16 @@ #define WM_SAVESETTINGS 0x8888 +extern HINSTANCE hinstance; +extern HWND hwndMain, + hwndRender; +extern HANDLE ghMutex; +extern LCID lang_id; +extern HICON hIcon[512]; + extern int status_is_open; extern int mousecapture; -extern LCID dwLanguage; - -extern HINSTANCE hinstance; -extern HWND hwndMain; -extern HICON hIcon[512]; +extern int recv_key[272]; extern char openfilestring[260]; extern WCHAR wopenfilestring[260]; @@ -70,9 +69,13 @@ extern "C" { extern HICON LoadIconEx(PCTSTR pszIconName); -extern void win_language_set(void); -extern void win_language_update(void); -extern void win_language_check(void); +/* Emulator start/stop support functions. */ +extern void do_start(void); +extern void do_stop(void); + +/* Internal platform support functions. */ +extern void set_language(int id); +extern int get_vidpause(void); #ifdef EMU_DEVICE_H extern void deviceconfig_open(HWND hwnd, device_t *device); @@ -122,4 +125,4 @@ extern wchar_t *BrowseFolder(wchar_t *saved_path, wchar_t *title); #endif -#endif /*BOX_WIN_H*/ +#endif /*PLAT_WIN_H*/ diff --git a/src/win/win_joystick.cc b/src/win/win_joystick.cc index 695638ee8..56d2627e8 100644 --- a/src/win/win_joystick.cc +++ b/src/win/win_joystick.cc @@ -8,7 +8,7 @@ * * Joystick interface to host device. * - * Version: @(#)win_joystick.cc 1.0.4 2017/10/12 + * Version: @(#)win_joystick.cc 1.0.5 2017/10/17 * * Authors: Sarah Walker, * Miran Grca, @@ -220,10 +220,12 @@ static int joystick_get_axis(int joystick_nr, int mapping) return plat_joystick_state[joystick_nr].a[plat_joystick_state[joystick_nr].axis[mapping].id]; } -void joystick_poll() +void joystick_process(void) { int c, d; + if (joystick_type != 7) return; + for (c = 0; c < joysticks_present; c++) { DIJOYSTATE joystate; diff --git a/src/win/win_video.c b/src/win/win_video.c new file mode 100644 index 000000000..7696f37cc --- /dev/null +++ b/src/win/win_video.c @@ -0,0 +1,300 @@ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Platform video API support for Win32. + * + * Version: @(#)win_video.c 1.0.1 2017/10/18 + * + * Author: Fred N. van Kempen, + * + * Copyright 2017 Fred N. van Kempen. + */ +#define UNICODE +#define BITMAP WINDOWS_BITMAP +#include +#include +#undef BITMAP +#include +#include +#include +#include +#include +#include +#include "../86box.h" +#include "../config.h" +#include "../device.h" +#include "../video/video.h" +#include "../plat.h" +#include "../plat_mouse.h" +#include "../ui.h" +#ifdef USE_VNC +# include "../vnc.h" +#endif +#ifdef USE_RDP +# include "../rdp.h" +#endif +#include "win.h" +#include "win_ddraw.h" +#include "win_d3d.h" + + +static struct { + char *name; + int local; + int (*init)(void *); + void (*close)(void); + void (*resize)(int x, int y); + int (*pause)(void); +} vid_apis[2][4] = { + { + { "DDraw", 1, (int(*)(void*))ddraw_init, ddraw_close, NULL, ddraw_pause }, + { "D3D", 1, (int(*)(void*))d3d_init, d3d_close, d3d_resize, d3d_pause }, +#ifdef USE_VNC + { "VNC", 0, vnc_init, vnc_close, vnc_resize, vnc_pause }, +#else + { NULL, 0, NULL, NULL, NULL, NULL }, +#endif +#ifdef USE_RDP + { "RDP", 0, rdp_init, rdp_close, rdp_resize, rdp_pause } +#else + { NULL, 0, NULL, NULL, NULL, NULL } +#endif + }, + { + { "DDraw", 1, (int(*)(void*))ddraw_fs_init, ddraw_fs_close, NULL, ddraw_fs_pause }, + { "D3D", 1, (int(*)(void*))d3d_fs_init, d3d_fs_close, NULL, d3d_fs_pause }, +#ifdef USE_VNC + { "VNC", 0, vnc_init, vnc_close, vnc_resize, vnc_pause }, +#else + { NULL, 0, NULL, NULL, NULL, NULL }, +#endif +#ifdef USE_RDP + { "RDP", 0, rdp_init, rdp_close, rdp_resize, rdp_pause } +#else + { NULL, 0, NULL, NULL, NULL, NULL } +#endif + }, +}; + + +#if 0 + /* Initialize the rendering window, or fullscreen. */ + if (start_in_fullscreen) { + startblit(); + vid_apis[0][vid_api].close(); + video_fullscreen = 1; + vid_apis[1][vid_api].init(hwndRender); + leave_fullscreen_flag = 0; + endblit(); + device_force_redraw(); + } +#endif + + +/* Return the VIDAPI number for the given name. */ +int +plat_vidapi(char *name) +{ + int i; + + if (!strcasecmp(name, "default") || !strcasecmp(name, "system")) return(0); + + for (i=0; i<4; i++) { + if (vid_apis[0][i].name && + !strcasecmp(vid_apis[0][i].name, name)) return(i); + } + + /* Default value. */ + return(0); +} + + +int +plat_setvid(int api) +{ + int i; + + pclog("Initializing VIDAPI: api=%d\n", api); + startblit(); + video_wait_for_blit(); + + /* Close the (old) API. */ + vid_apis[0][vid_api].close(); +#ifdef USE_WX + ui_check_menu_item(IDM_View_WX+vid_api, 0); +#endif + vid_api = api; + + if (vid_apis[0][vid_api].local) + ShowWindow(hwndRender, SW_SHOW); + else + ShowWindow(hwndRender, SW_HIDE); + + /* Initialize the (new) API. */ +#ifdef USE_WX + ui_check_menu_item(IDM_View_WX+vid_api, 1); +#endif + i = vid_apis[0][vid_api].init((void *)hwndRender); + endblit(); + if (! i) return(0); + + device_force_redraw(); + + return(1); +} + + +int +get_vidpause(void) +{ + return(vid_apis[video_fullscreen][vid_api].pause()); +} + + +void +plat_setfullscreen(int on) +{ + static int flag = 0; + + /* Want off and already off? */ + if (!on && !video_fullscreen) return; + + /* Want on and already on? */ + if (on && video_fullscreen) return; + + if (!on && !flag) { + /* We want to leave FS mode. */ + flag = 1; + + return; + } + + if (video_fullscreen_first) { + video_fullscreen_first = 0; + ui_msgbox(MBX_INFO, (wchar_t *)IDS_2074); + } + + /* OK, claim the video. */ + startblit(); + video_wait_for_blit(); + + mouse_close(); + + /* Close the current mode, and open the new one. */ + vid_apis[video_fullscreen][vid_api].close(); + video_fullscreen = on; + vid_apis[video_fullscreen][vid_api].init(NULL); + flag = 0; + + mouse_init(); + + /* Release video and make it redraw the screen. */ + endblit(); + device_force_redraw(); +} + + +void +take_screenshot(void) +{ + wchar_t path[1024], fn[128]; + struct tm *info; + time_t now; + + pclog("Screenshot: video API is: %i\n", vid_api); + if ((vid_api < 0) || (vid_api > 1)) return; + + memset(fn, 0, sizeof(fn)); + memset(path, 0, sizeof(path)); + + (void)time(&now); + info = localtime(&now); + + plat_append_filename(path, cfg_path, SCREENSHOT_PATH, sizeof(path)-2); + + if (! plat_dir_check(path)) + plat_dir_create(path); + +#ifdef WIN32 + wcscat(path, L"\\"); +#else + wcscat(path, L"/"); +#endif + + switch(vid_api) { + case 0: /* ddraw */ + wcsftime(path, 128, L"%Y%m%d_%H%M%S.bmp", info); + plat_append_filename(path, cfg_path, fn, 1024); + if (video_fullscreen) + ddraw_fs_take_screenshot(path); + else + ddraw_take_screenshot(path); + pclog("Screenshot: fn='%ls'\n", path); + break; + + case 1: /* d3d9 */ + wcsftime(fn, 128, L"%Y%m%d_%H%M%S.png", info); + plat_append_filename(path, cfg_path, fn, 1024); + if (video_fullscreen) + d3d_fs_take_screenshot(path); + else + d3d_take_screenshot(path); + pclog("Screenshot: fn='%ls'\n", path); + break; + +#ifdef USE_VNC + case 2: /* vnc */ + wcsftime(fn, 128, L"%Y%m%d_%H%M%S.png", info); + plat_append_filename(path, cfg_path, fn, 1024); + vnc_take_screenshot(path); + pclog("Screenshot: fn='%ls'\n", path); + break; +#endif + } +} + + +void /* plat_ */ +startblit(void) +{ + WaitForSingleObject(ghMutex, INFINITE); +} + + +void /* plat_ */ +endblit(void) +{ + ReleaseMutex(ghMutex); +} + + +/* Tell the UI and/or renderers about a new screen resolution. */ +void +plat_resize(int x, int y) +{ +pclog("PLAT: VID[%d,%d] resizing to %dx%d\n", video_fullscreen, vid_api, x, y); + /* First, see if we should resize the UI window. */ + if (vid_resize) { + /* Move the main window. */ + + /* Move the status bar with it. */ + MoveWindow(hwndSBAR, 0, y+6, x, 17, TRUE); + + /* Move the render window if we have one. */ + if (vid_apis[0][vid_api].local && (hwndRender != NULL)) { + MoveWindow(hwndRender, 0, 0, x, y, TRUE); + } + } + + /* Now, tell the renderer about the new screen size we want. */ + if (vid_apis[video_fullscreen][vid_api].resize) { + startblit(); + vid_apis[video_fullscreen][vid_api].resize(x, y); + endblit(); + } +}