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.

This commit is contained in:
waltje
2017-10-19 04:27:04 -04:00
parent bcffcb4d22
commit 1d60a99ea3
36 changed files with 1244 additions and 1001 deletions

View File

@@ -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, <mgrca8@gmail.com>
# Fred N. van Kempen, <decwiz@yahoo.com>
@@ -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)

View File

@@ -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, <http://pcem-emulator.co.uk/>
* Miran Grca, <mgrca8@gmail.com>
@@ -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;
}

View File

@@ -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, <http://pcem-emulator.co.uk/>
* Miran Grca, <mgrca8@gmail.com>
@@ -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*/

View File

@@ -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, <http://pcem-emulator.co.uk/>
* Miran Grca, <mgrca8@gmail.com>
@@ -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;

300
src/win/win_video.c Normal file
View File

@@ -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, <decwiz@yahoo.com>
*
* Copyright 2017 Fred N. van Kempen.
*/
#define UNICODE
#define BITMAP WINDOWS_BITMAP
#include <windows.h>
#include <windowsx.h>
#undef BITMAP
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <stdlib.h>
#include <time.h>
#include <wchar.h>
#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();
}
}

View File

@@ -1,327 +0,0 @@
/*
* 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.
*
* Implement the VNC renderer with LibVNCServer.
*
* Version: @(#)win_vnc.c 1.0.3 2017/10/16
*
* Authors: Fred N. van Kempen, <decwiz@yahoo.com>
* Based on raw code by RichardG, <richardg867@gmail.com>
*
* Copyright 2017 Fred N. van Kempen.
*/
#include <stdio.h>
#include <stdint.h>
#include "../86box.h"
#include "../device.h"
#include "../video/video.h"
#include "../plat.h"
#include "../plat_keyboard.h"
#include "../ui.h"
#define BITMAP MY_BITMAP
#include <rfb/rfb.h>
#undef BITMAP
#include "win.h"
#include "win_vnc.h"
static rfbScreenInfoPtr rfb = NULL;
static int clients;
static int updatingSize;
static int allowedX,
allowedY;
static int keysyms_00[] = {
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 00-07
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 08-0f
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 10-17
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 18-1f
0x0039, 0x2a02, 0x2a28, 0x2a04, 0x2a05, 0x2a06, 0x2a08, 0x0028, // 20-27
0x2a0a, 0x2a0b, 0x2a09, 0x2a0d, 0x0033, 0x000c, 0x0034, 0x0035, // 28-2f
0x000b, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, // 30-37
0x0009, 0x000a, 0x2a27, 0x0027, 0x2a33, 0x000d, 0x2a34, 0x2a35, // 38-3f
0x2a03, 0x2a1e, 0x2a30, 0x2a2e, 0x2a20, 0x2a12, 0x2a21, 0x2a22, // 40-47
0x2a23, 0x2a17, 0x2a24, 0x2a25, 0x2a26, 0x2a32, 0x2a31, 0x2a18, // 48-4f
0x2a19, 0x2a10, 0x2a13, 0x2a1f, 0x2a14, 0x2a16, 0x2a2f, 0x2a11, // 50-57
0x2a2d, 0x2a15, 0x2a2c, 0x001a, 0x0000, 0x001b, 0x2a07, 0x2a0c, // 58-5f
0x0029, 0x001e, 0x0030, 0x002e, 0x0020, 0x0012, 0x0021, 0x0022, // 60-67
0x0023, 0x0017, 0x0024, 0x0025, 0x0026, 0x0032, 0x0031, 0x0018, // 68-6f
0x0019, 0x0010, 0x0013, 0x001f, 0x0014, 0x0016, 0x002f, 0x0011, // 70-77
0x002d, 0x0015, 0x002c, 0x2a1a, 0x0000, 0x2a1b, 0x2a29, 0x0000, // 78-7f
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 80-87
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 88-8f
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 90-97
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 98-9f
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // a0-a7
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // a8-af
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // b0-b7
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // b8-bf
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // c0-c7
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // c8-cf
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // d0-d7
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // d8-df
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // e0-e7
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // e8-ef
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // f0-f7
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 // f8-ff
};
static int keysyms_ff[] = {
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 00-07
0x000e, 0x000f, 0x0000, 0x004c, 0x0000, 0x001c, 0x0000, 0x0000, // 08-0f
0x0000, 0x0000, 0x0000, 0xff45, 0x0000, 0x0000, 0x0000, 0x0000, // 10-17
0x0000, 0x0000, 0x0000, 0x0001, 0x0000, 0x0000, 0x0000, 0x0000, // 18-1f
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 20-27
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 28-2f
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 30-37
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 38-3f
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 40-47
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 48-4f
0x0047, 0x00cb, 0xaac8, 0x00cd, 0x00d0, 0x0049, 0x0051, 0x004f, // 50-57
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 58-5f
0x0000, 0x0000, 0x0000, 0x0052, 0x0000, 0x0000, 0x0000, 0x00dd, // 60-67
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 68-6f
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 70-77
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 78-7f
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 80-87
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x009c, 0x0000, 0x0000, // 88-8f
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 90-97
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 98-9f
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // a0-a7
0x0000, 0x0000, 0x0037, 0x004e, 0x0000, 0x004a, 0x0000, 0x00b5, // a8-af
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // b0-b7
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x003b, 0x003c, // b8-bf
0x003d, 0x003e, 0x003f, 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, // c0-c7
0x0057, 0x0058, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // c8-cf
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // d0-d7
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // d8-df
0x0000, 0x0036, 0x0000, 0x001d, 0x009d, 0x0000, 0x0000, 0x0000, // e0-e7
0x0000, 0x0038, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // e8-ef
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // f0-f7
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0053 // f8-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)
{
int will_press = 0;
int key;
#if 0
pclog("VNC: kbdevent %d %x\n", down, k);
#endif
if ((k >> 8) == 0x00) {
will_press = keysyms_00[k & 0xff];
} else if ((k >> 8) == 0xff) {
will_press = keysyms_ff[k & 0xff];
}
if (will_press <= 0) return;
#if 0
pclog("VNC: translated to %x %x\n",
(will_press >> 8) & 0xff, will_press & 0xff);
#endif
// first key
key = (will_press >> 8) & 0xff;
if (key > 0)
recv_key[key] = down;
// second key
key = will_press & 0xff;
if (key > 0)
recv_key[key] = down;
}
static void
vnc_blit(int x, int y, int y1, int y2, int w, int h)
{
uint32_t *p;
int yy;
for (yy=y1; yy<y2; yy++) {
p = (uint32_t *)&(((uint32_t *)rfb->frameBuffer)[yy*2048]);
if ((y+yy) >= 0 && (y+yy) < 2048)
memcpy(p, &(((uint32_t *)buffer32->line[y+yy])[x]), w*4);
}
video_blit_complete();
if (! updatingSize)
rfbMarkRectAsModified(rfb, 0,0, allowedX,allowedY);
}
static void
vnc_blit8(int x, int y, int w, int h)
{
uint32_t *p;
int xx, yy;
for (yy = 0; yy < h; yy++) {
p = (uint32_t *)&(((uint32_t *)rfb->frameBuffer)[yy*2048]);
if ((y+yy) >= 0 && (y+yy) < buffer->h) {
for (xx=0; xx<w; xx++)
p[xx] = pal_lookup[buffer->line[y+yy][x+xx]];
}
}
video_blit_complete();
if (! updatingSize)
rfbMarkRectAsModified(rfb, 0,0, x+w,y+h);
}
int
vnc_init(HWND h)
{
static char title[128];
rfbPixelFormat rpf = {
/*
* Screen format:
* 32bpp; 32 depth;
* little endian;
* true color;
* max 255 R/G/B;
* red shift 16; green shift 8; blue shift 0;
* padding
*/
32, 32, 0, 1, 255,255,255, 16, 8, 0, 0, 0
};
if (rfb == NULL) {
wcstombs(title, ui_window_title(NULL), sizeof(title));
updatingSize = 0;
allowedX = allowedY = 2048;
rfb = rfbGetScreen(0, NULL, 2048, 2048, 8, 3, 4);
rfb->desktopName = title;
rfb->frameBuffer = (char *)malloc(2048 * 2048 * 4);
rfb->serverFormat = rpf;
rfb->alwaysShared = TRUE;
rfb->displayHook = vnc_display;
rfb->kbdAddEvent = vnc_kbdevent;
rfb->newClientHook = vnc_newclient;
rfbInitServer(rfb);
rfbRunEventLoop(rfb, -1, TRUE);
}
/* Set up our BLIT handlers. */
video_setblit(vnc_blit8, vnc_blit);
pclog("VNC: init complete.\n");
clients = 0;
return(1);
}
void
vnc_close(void)
{
pclog("VNC: closed.\n");
}
void
vnc_resize(int x, int y)
{
rfbClientIteratorPtr iterator;
rfbClientPtr cl;
if (rfb == NULL) return;
if ((x != rfb->width || y != rfb->height) && x > 160 && y > 0) {
pclog("VNC: updating resolution: %dx%d\n", x, y);
allowedX = (rfb->width < x) ? rfb->width : x;
allowedY = (rfb->width < y) ? rfb->width : y;
rfb->width = x;
rfb->height = y;
iterator = rfbGetClientIterator(rfb);
while ((cl = rfbClientIteratorNext(iterator)) != NULL) {
LOCK(cl->updateMutex);
cl->newFBSizePending = 1;
UNLOCK(cl->updateMutex);
}
}
}
int
vnc_pause(void)
{
return((clients > 0) ? 0 : 1);
}
void
vnc_take_screenshot(wchar_t *fn)
{
pclog("VNC: take_screenshot\n");
}

View File

@@ -1,30 +0,0 @@
/*
* 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.
*
* Definitions for the VNC renderer.
*
* Version: @(#)win_vnc.h 1.0.1 2017/10/13
*
* Authors: RichardG, <richardg867@gmail.com>
* Fred N. van Kempen, <decwiz@yahoo.com>
*
* Copyright 2017 Fred N. van Kempen.
*/
#ifndef WIN_VNC_H
# define WIN_VNC_H
extern int vnc_init(HWND h);
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);
#endif /*WIN_VNC_H*/