diff --git a/src/config.c b/src/config.c index b4dae66e2..5653ebcb8 100644 --- a/src/config.c +++ b/src/config.c @@ -1911,7 +1911,7 @@ config_dump(void) while (sec != NULL) { entry_t *ent; - if (sec->name && sec->name[0]) + if (sec->name[0]) config_log("[%s]\n", sec->name); ent = (entry_t *)sec->entry_head.next; diff --git a/src/cpu/codegen.h b/src/cpu/codegen.h index e613ecbed..38847f78b 100644 --- a/src/cpu/codegen.h +++ b/src/cpu/codegen.h @@ -42,7 +42,7 @@ #ifdef __amd64__ #include "codegen_x86-64.h" -#elif defined i386 || defined __i386 || defined __i386__ || defined _X86_ || defined _WIN32 +#elif defined i386 || defined __i386 || defined __i386__ || defined _X86_ || defined _M_IX86 || defined _M_X64 #include "codegen_x86.h" #else #error Dynamic recompiler not implemented on your platform diff --git a/src/cpu/codegen_ops.c b/src/cpu/codegen_ops.c index 2c0ce4929..a577d3b6e 100644 --- a/src/cpu/codegen_ops.c +++ b/src/cpu/codegen_ops.c @@ -16,7 +16,7 @@ #ifdef __amd64__ #include "codegen_ops_x86-64.h" -#elif defined i386 || defined __i386 || defined __i386__ || defined _X86_ || defined _WIN32 +#elif defined i386 || defined __i386 || defined __i386__ || defined _X86_ || defined _M_IX86 || defined _M_X64 #include "codegen_ops_x86.h" #endif diff --git a/src/cpu/codegen_x86.c b/src/cpu/codegen_x86.c index e7d53ea9f..4e1a8845d 100644 --- a/src/cpu/codegen_x86.c +++ b/src/cpu/codegen_x86.c @@ -36,7 +36,7 @@ * Boston, MA 02111-1307 * USA. */ -#if defined i386 || defined __i386 || defined __i386__ || defined _X86_ || defined _WIN32 +#if defined i386 || defined __i386 || defined __i386__ || defined _X86_ || defined _M_IX86 || defined _M_X64 #include #include diff --git a/src/cpu/x87_ops.h b/src/cpu/x87_ops.h index 4cc514cb7..65ead134e 100644 --- a/src/cpu/x87_ops.h +++ b/src/cpu/x87_ops.h @@ -288,7 +288,7 @@ static __inline void x87_stmmx(MMX_REG r) static __inline uint16_t x87_compare(double a, double b) { -#if defined i386 || defined __i386 || defined __i386__ || defined _X86_ || defined _WIN32 +#if defined i386 || defined __i386 || defined __i386__ || defined _X86_ || defined _M_IX86 || defined _M_X64 uint32_t result; if (!is386) @@ -354,7 +354,7 @@ static __inline uint16_t x87_compare(double a, double b) #else /* Generic C version is known to give incorrect results in some * situations, eg comparison of infinity (Unreal) */ - uint32_t out = 0; + uint32_t result = 0; if (is386) { @@ -383,9 +383,9 @@ static __inline uint16_t x87_compare(double a, double b) static __inline uint16_t x87_ucompare(double a, double b) { -#if defined i386 || defined __i386 || defined __i386__ || defined _X86_ || defined _WIN32 +#if defined i386 || defined __i386 || defined __i386__ || defined _X86_ || defined _M_IX86 || defined _M_X64 uint32_t result; - + #ifndef _MSC_VER /* Memory barrier, to force GCC to write to the input parameters * before the compare rather than after */ diff --git a/src/floppy/fdd_86f.c b/src/floppy/fdd_86f.c index 16de640b6..55ba012cc 100644 --- a/src/floppy/fdd_86f.c +++ b/src/floppy/fdd_86f.c @@ -1112,7 +1112,7 @@ d86f_get_bit(int drive, int side) /* In some cases, misindentification occurs so we need to make sure the surface data array is not not NULL. */ - if (d86f_has_surface_desc(drive) && dev->track_surface_data && dev->track_surface_data[side]) { + if (d86f_has_surface_desc(drive) && dev->track_surface_data[side]) { if (d86f_reverse_bytes(drive)) { surface_data = dev->track_surface_data[side][track_word] & 0xFF; } else { @@ -1124,7 +1124,7 @@ d86f_get_bit(int drive, int side) current_bit = (encoded_data >> track_bit) & 1; dev->last_word[side] <<= 1; - if (d86f_has_surface_desc(drive) && dev->track_surface_data && dev->track_surface_data[side]) { + if (d86f_has_surface_desc(drive) && dev->track_surface_data[side]) { surface_bit = (surface_data >> track_bit) & 1; if (! surface_bit) dev->last_word[side] |= current_bit; diff --git a/src/network/slirp/ip.h b/src/network/slirp/ip.h index 5fa673963..4ced4ef17 100644 --- a/src/network/slirp/ip.h +++ b/src/network/slirp/ip.h @@ -209,7 +209,7 @@ typedef u_int32_t caddr32_t; #endif #endif -#ifdef __amd64__ +#if defined(__amd64__) || defined(__aarch64__) typedef uintptr_t ipqp_32; typedef uintptr_t ipasfragp_32; #else @@ -230,7 +230,7 @@ typedef caddr32_t ipasfragp_32; #endif struct ipovly { -#ifdef __amd64__ +#if defined(__amd64__) || defined(__aarch64__) uintptr_t ih_next, ih_prev; /* for protocol sequence q's */ #else caddr32_t ih_next, ih_prev; /* for protocol sequence q's */ @@ -258,7 +258,7 @@ struct ipovly { * size 28 bytes */ struct ipq { -#ifdef __amd64__ +#if defined(__amd64__) || defined(__aarch64__) uintptr_t next,prev; /* to other reass headers */ #else ipqp_32 next,prev; /* to other reass headers */ diff --git a/src/network/slirp/tcp.h b/src/network/slirp/tcp.h index d9a8ccf72..5df25a8f0 100644 --- a/src/network/slirp/tcp.h +++ b/src/network/slirp/tcp.h @@ -33,7 +33,7 @@ #ifndef _TCP_H_ #define _TCP_H_ -#ifdef __amd64__ +#if defined(__amd64__) || defined(__aarch64__) typedef uintptr_t tcp_seq; #else typedef u_int32_t tcp_seq; diff --git a/src/network/slirp/tcp_var.h b/src/network/slirp/tcp_var.h index e6fbd3abb..a9606c276 100644 --- a/src/network/slirp/tcp_var.h +++ b/src/network/slirp/tcp_var.h @@ -36,7 +36,7 @@ #include "tcpip.h" #include "tcp_timer.h" -#ifdef __amd64__ +#if defined(__amd64__) || defined(__aarch64__) typedef uintptr_t tcpiphdrp_32; #else #if SIZEOF_CHAR_P == 4 @@ -178,7 +178,7 @@ struct tcpcb { * port numbers (which are no longer needed once we've located the * tcpcb) are overlayed with an mbuf pointer. */ -#ifdef __amd64__ +#if defined(__amd64__) || defined(__aarch64__) typedef uintptr_t mbufp_32; #else #if SIZEOF_CHAR_P == 4 diff --git a/src/printer/printer.h b/src/printer/printer.h index 88e52f8f5..33f7d58c9 100644 --- a/src/printer/printer.h +++ b/src/printer/printer.h @@ -58,7 +58,7 @@ #define FONT_FILE_OCRB L"ocra.ttf" -extern const void +extern void select_codepage(uint16_t code, uint16_t *curmap); diff --git a/src/printer/prt_cpmap.c b/src/printer/prt_cpmap.c index d29ace8a4..f7c7330f6 100644 --- a/src/printer/prt_cpmap.c +++ b/src/printer/prt_cpmap.c @@ -10,12 +10,12 @@ * * Version: @(#)prt_cpmap.c 1.0.2 2018/10/05 * - * Authors: Michael Drüing, + * Authors: Michael Dr�ing, * Fred N. van Kempen, * * Based on code by Frederic Weymann (originally for DosBox.) * - * Copyright 2018 Michael Drüing. + * Copyright 2018 Michael Dr�ing. * Copyright 2018 Fred N. van Kempen. * * Redistribution and use in source and binary forms, with @@ -572,7 +572,7 @@ static const struct { /* Select a ASCII->Unicode mapping by CP number */ -const void +void select_codepage(uint16_t code, uint16_t *curmap) { int i = 0; diff --git a/src/random.c b/src/random.c index 3d1d229a2..c4f28548f 100644 --- a/src/random.c +++ b/src/random.c @@ -18,6 +18,9 @@ #include #include "random.h" +#if !(defined(__i386__) || defined (__x86_64__)) +#include +#endif uint32_t preconst = 0x6ED9EBA1; @@ -44,6 +47,7 @@ static __inline__ uint32_t rotr32c (uint32_t x, uint32_t n) static __inline__ unsigned long long rdtsc(void) { +#if defined(__i386__) || defined (__x86_64__) unsigned hi, lo; #ifdef __MSC__ __asm { @@ -55,6 +59,9 @@ static __inline__ unsigned long long rdtsc(void) __asm__ __volatile__ ("rdtsc" : "=a"(lo), "=d"(hi)); #endif return ( (unsigned long long)lo)|( ((unsigned long long)hi)<<32 ); +#else + return time(NULL); +#endif } static uint32_t RDTSC(void) diff --git a/src/scsi/scsi_ncr5380.c b/src/scsi/scsi_ncr5380.c index e35c0cdf2..262725726 100644 --- a/src/scsi/scsi_ncr5380.c +++ b/src/scsi/scsi_ncr5380.c @@ -910,7 +910,7 @@ ncr_callback(void *priv) ncr_log("Select - target ID = %i\n", ncr->target_id); /*Once the device has been found and selected, mark it as busy*/ - if ((ncr->target_id != -1) && scsi_device_present(&scsi_devices[ncr->target_id])) { + if ((ncr->target_id != (uint8_t)-1) && scsi_device_present(&scsi_devices[ncr->target_id])) { ncr->cur_bus |= BUS_BSY; ncr_log("Device found at ID %i\n", ncr->target_id); ncr_log("Current Bus BSY=%02x\n", ncr->cur_bus); diff --git a/src/scsi/scsi_ncr53c8xx.h b/src/scsi/scsi_ncr53c8xx.h index bf2136e0d..e50e6d954 100644 --- a/src/scsi/scsi_ncr53c8xx.h +++ b/src/scsi/scsi_ncr53c8xx.h @@ -21,7 +21,7 @@ * Copyright 2009-2018 Artyom Tarasenko. * Copyright 2017,2018 Miran Grca. */ -#ifndef SCSI_NCR5C38XX_H +#ifndef SCSI_NCR53C8XX_H # define SCSI_NCR53C8XX_H diff --git a/src/sound/resid-fp/sid.cc b/src/sound/resid-fp/sid.cc index eda01ab2f..431d5712d 100644 --- a/src/sound/resid-fp/sid.cc +++ b/src/sound/resid-fp/sid.cc @@ -96,7 +96,7 @@ static int host_cpu_features(void) static int features = 0; static int features_detected = 0; /* 32-bit only */ -#if defined(__i386__) || (defined(_MSC_VER) && defined(_WIN32)) +#if defined(__i386__) || (defined(_MSC_VER) && defined(_M_IX86)) unsigned long temp1, temp2; #endif @@ -104,7 +104,7 @@ static int host_cpu_features(void) return features; features_detected = 1; -#if defined(_MSC_VER) && defined(_WIN32) /* MSVC compatible assembly appropriate for 32-bit Windows */ +#if defined(_MSC_VER) && defined(_M_IX86) /* MSVC compatible assembly appropriate for 32-bit Windows */ /* see if we are dealing with a cpu that has the cpuid instruction */ __asm { pushf @@ -127,7 +127,7 @@ static int host_cpu_features(void) : : "eax"); #endif -#if defined(__i386__) || (defined(_MSC_VER) && defined(_WIN32)) +#if defined(__i386__) || (defined(_MSC_VER) && defined(_M_IX86)) temp1 &= 0x200000; temp2 &= 0x200000; if (temp1 == temp2) { diff --git a/src/video/vid_voodoo.c b/src/video/vid_voodoo.c index 20c573d02..1b3fa5870 100644 --- a/src/video/vid_voodoo.c +++ b/src/video/vid_voodoo.c @@ -2656,9 +2656,9 @@ static inline void voodoo_tmu_fetch_and_blend(voodoo_t *voodoo, voodoo_params_t state->tex_a[0] ^= 0xff; } -#if ((defined i386 || defined __i386 || defined __i386__ || defined _X86_ || defined _WIN32) && !(defined __amd64__) && (defined USE_DYNAREC)) +#if ((defined i386 || defined __i386 || defined __i386__ || defined _X86_ || defined _M_IX86) && !(defined __amd64__ || defined _M_X64) && (defined USE_DYNAREC)) #include "vid_voodoo_codegen_x86.h" -#elif ((defined __amd64__) && (defined USE_DYNAREC)) +#elif ((defined __amd64__ || defined _M_X64) && (defined USE_DYNAREC)) #include "vid_voodoo_codegen_x86-64.h" #else #define NO_CODEGEN diff --git a/src/win/86Box.rc b/src/win/86Box.rc index 400e40520..5dfe8edc5 100644 --- a/src/win/86Box.rc +++ b/src/win/86Box.rc @@ -210,7 +210,7 @@ BEGIN VK_PRIOR,IDM_VID_FULLSCREEN, VIRTKEY, CONTROL , ALT VK_F11, IDM_ACTION_SCREENSHOT, VIRTKEY, CONTROL VK_F12, IDM_ACTION_RESET_CAD, VIRTKEY, CONTROL - VK_PAUSE,IDM_ACTION_PAUSE + VK_PAUSE,IDM_ACTION_PAUSE, VIRTKEY END diff --git a/src/win/Makefile.mingw b/src/win/Makefile.mingw index 6e0ed2781..dcaba9b7d 100644 --- a/src/win/Makefile.mingw +++ b/src/win/Makefile.mingw @@ -28,7 +28,7 @@ ifndef DEV_BUILD DEV_BUILD := n endif ifndef FLTO -FLTO := 1 +FLTO := full endif ifeq ($(DEV_BUILD), y) @@ -129,6 +129,12 @@ endif ifndef X64 X64 := n endif +ifndef ARM +ARM := n +endif +ifndef ARM64 +ARM64 := n +endif ifndef WX WX := n endif @@ -138,6 +144,21 @@ endif ifndef RDP RDP := n endif +ifndef DINPUT + DINPUT := y + ifeq ($(ARM), y) + DINPUT := n + endif +endif +ifndef D3DX + D3DX := y + ifeq ($(ARM), y) + D3DX := n + endif + ifeq ($(ARM64), y) + D3DX := n + endif +endif ifndef OPENAL OPENAL := y endif @@ -148,7 +169,13 @@ ifndef MUNT MUNT := y endif ifndef DYNAREC -DYNAREC := y + DYNAREC := y + ifeq ($(ARM), y) + DYNAREC := n + endif + ifeq ($(ARM64), y) + DYNAREC := n + endif endif @@ -213,6 +240,19 @@ CPP := g++ -m32 CC := gcc -m32 endif WINDRES := windres +STRIP := strip +ifeq ($(ARM64), y) +CPP := aarch64-w64-mingw32-g++ +CC := aarch64-w64-mingw32-gcc +WINDRES := aarch64-w64-mingw32-windres +STRIP := aarch64-w64-mingw32-strip +endif +ifeq ($(ARM), y) +CPP := armv7-w64-mingw32-g++ +CC := armv7-w64-mingw32-gcc +WINDRES := armv7-w64-mingw32-windres +STRIP := armv7-w64-mingw32-strip +endif DEPS = -MMD -MF $*.d -c $< DEPFILE := win/.depends @@ -257,6 +297,16 @@ else endif endif AFLAGS := -msse2 -mfpmath=sse +ifeq ($(ARM), y) + DFLAGS := -march=armv7-a + AOPTIM := + AFLAGS := -mfloat-abi=hard +endif +ifeq ($(ARM64), y) + DFLAGS := -march=armv8-a + AOPTIM := + AFLAGS := -mfloat-abi=hard +endif RFLAGS := --input-format=rc -O coff ifeq ($(RELEASE), y) OPTS += -DRELEASE_BUILD @@ -348,6 +398,14 @@ RDPLIB += -lrdp RDPOBJ := rdp.o endif +ifeq ($(DINPUT), y) +OPTS += -DUSE_DINPUT +endif + +ifeq ($(D3DX), y) +OPTS += -DUSE_D3DX +endif + # Options for the DEV branch. ifeq ($(DEV_BRANCH), y) OPTS += -DDEV_BRANCH @@ -559,7 +617,12 @@ VIDOBJ := video.o \ PLATOBJ := win.o \ win_dynld.o win_thread.o \ win_cdrom.o win_keyboard.o \ - win_mouse.o win_joystick.o win_midi.o + win_midi.o +ifeq ($(DINPUT), y) + PLATOBJ += win_mouse.o win_joystick.o +else + PLATOBJ += win_mouse_rawinput.o win_joystick_xinput.o +endif OBJ := $(MAINOBJ) $(INTELOBJ) $(CPUOBJ) $(MCHOBJ) $(DEVOBJ) \ $(FDDOBJ) $(CDROMOBJ) $(ZIPOBJ) $(HDDOBJ) \ @@ -572,7 +635,7 @@ endif LIBS := -mwindows \ -lopenal.dll \ - -lddraw -ldinput8 -ldxguid -ld3d9 -ld3dx9 \ + -lddraw -ldxguid -ld3d9 \ -lcomctl32 -lwinmm ifeq ($(D2D), y) LIBS += $(D2DLIB) @@ -587,11 +650,18 @@ ifneq ($(WX), n) LIBS += $(WX_LIBS) -lm endif LIBS += -lpng -lz -lwsock32 -liphlpapi -LIBS += -static -lstdc++ -lgcc +LIBS += -static -lstdc++ ifneq ($(X64), y) LIBS += -Wl,--large-address-aware endif - +ifeq ($(DINPUT), y) + LIBS += -ldinput8 +else + LIBS += -lxinput +endif +ifeq ($(D3DX), y) +LIBS += -ld3dx9 +endif # Build module rules. ifeq ($(AUTODEP), y) @@ -644,7 +714,7 @@ $(PROG).exe: $(OBJ) 86Box.res @echo Linking $(PROG).exe .. @$(CC) -o $(PROG).exe $(OBJ) 86Box.res $(LIBS) ifneq ($(DEBUG), y) - @strip $(PROG).exe + @$(STRIP) $(PROG).exe endif pcap_if.res: pcap_if.rc @@ -655,13 +725,13 @@ pcap_if.exe: pcap_if.o win_dynld.o pcap_if.res @echo Linking pcap_if.exe .. @$(CC) -o pcap_if.exe pcap_if.o win_dynld.o pcap_if.res ifneq ($(DEBUG), y) - @strip pcap_if.exe + @$(STRIP) pcap_if.exe endif hello.exe: hello.o $(CXX) $(LDFLAGS) -o hello.exe hello.o $(WXLIBS) $(LIBS) ifneq ($(DEBUG), y) - @strip hello.exe + @$(STRIP) hello.exe endif diff --git a/src/win/win.h b/src/win/win.h index f3045663f..959056ba9 100644 --- a/src/win/win.h +++ b/src/win/win.h @@ -112,6 +112,9 @@ extern void keyboard_handle(LPARAM lParam, int infocus); extern void win_mouse_init(void); extern void win_mouse_close(void); +#ifndef USE_DINPUT +extern void win_mouse_handle(LPARAM lParam, int infocus); +#endif extern LPARAM win_get_string(int id); diff --git a/src/win/win_about.c b/src/win/win_about.c index 355dd313d..ae0eea162 100644 --- a/src/win/win_about.c +++ b/src/win/win_about.c @@ -31,7 +31,7 @@ #include "win.h" -#ifdef __amd64__ +#if defined(__amd64__) || defined(__aarch64__) static LRESULT CALLBACK #else static BOOL CALLBACK diff --git a/src/win/win_d3d.cpp b/src/win/win_d3d.cpp index 4f8a6fd4f..0815470a4 100644 --- a/src/win/win_d3d.cpp +++ b/src/win/win_d3d.cpp @@ -637,6 +637,7 @@ d3d_pause(void) void d3d_take_screenshot(wchar_t *fn) { +#ifdef USE_D3DX LPDIRECT3DSURFACE9 d3dSurface = NULL; if (! d3dTexture) return; @@ -646,4 +647,9 @@ d3d_take_screenshot(wchar_t *fn) d3dSurface->Release(); d3dSurface = NULL; +#else + /* TODO: how to take screenshot without d3dx? + just a stub for now */ + pclog("Direct3D: d3d_take_screenshot(%s)\n", fn); +#endif } diff --git a/src/win/win_devconf.c b/src/win/win_devconf.c index b83c35e90..a0a1e5018 100644 --- a/src/win/win_devconf.c +++ b/src/win/win_devconf.c @@ -36,7 +36,7 @@ static device_context_t config_device; static uint8_t deviceconfig_changed = 0; -#ifdef __amd64__ +#if defined(__amd64__) || defined(__aarch64__) static LRESULT CALLBACK #else static BOOL CALLBACK diff --git a/src/win/win_joystick_xinput.cpp b/src/win/win_joystick_xinput.cpp new file mode 100644 index 000000000..8a7f11b7f --- /dev/null +++ b/src/win/win_joystick_xinput.cpp @@ -0,0 +1,255 @@ +/* + * 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. + * + * Xinput joystick interface. + * + * Version: @(#)win_joystick_xinput.cpp 1.0.0 2019/3/19 + * + * Authors: Sarah Walker, + * Miran Grca, + * GH Cao, + * + * Copyright 2008-2018 Sarah Walker. + * Copyright 2016-2018 Miran Grca. + * Copyright 2019 GH Cao. + */ +#include +#include +#include +#include +#include +#define HAVE_STDARG_H +#include "../86box.h" +#include "../device.h" +#include "../plat.h" +#include "../game/gameport.h" +#include "win.h" + +#define XINPUT_MAX_JOYSTICKS 4 +#define XINPUT_NAME "Xinput compatiable controller" +#define XINPUT_NAME_LX "Left Stick X" +#define XINPUT_NAME_LY "Left Stick Y" +#define XINPUT_NAME_RX "Right Stick X" +#define XINPUT_NAME_RY "Right Stick Y" +#define XINPUT_NAME_DPAD_X "D-pad X" +#define XINPUT_NAME_DPAD_Y "D-pad Y" +#define XINPUT_NAME_LB "LB" +#define XINPUT_NAME_RB "RB" +#define XINPUT_NAME_LT "LT" +#define XINPUT_NAME_RT "RT" +#define XINPUT_NAME_A "A" +#define XINPUT_NAME_B "B" +#define XINPUT_NAME_X "X" +#define XINPUT_NAME_Y "Y" +#define XINPUT_NAME_BACK "Back/View" +#define XINPUT_NAME_START "Start/Menu" +#define XINPUT_NAME_LS "Left Stick" +#define XINPUT_NAME_RS "Right Stick" + +#ifdef ENABLE_JOYSTICK_LOG +int joystick_do_log = ENABLE_JOYSTICK_LOG; + + +static void +joystick_log(const char *fmt, ...) +{ + va_list ap; + + if (joystick_do_log) { + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); + } +} +#else +#define joystick_log(fmt, ...) +#endif + +plat_joystick_t plat_joystick_state[MAX_PLAT_JOYSTICKS]; +joystick_t joystick_state[MAX_JOYSTICKS]; +int joysticks_present = 0; + +XINPUT_STATE controllers[XINPUT_MAX_JOYSTICKS]; + +void joystick_init() +{ + int c; + + atexit(joystick_close); + + joysticks_present = 0; + + memset(controllers, 0, sizeof(XINPUT_STATE) * XINPUT_MAX_JOYSTICKS); + + for (c=0; c 127) ? 128 : 0; + plat_joystick_state[c].b[7] = (controllers[c].Gamepad.bRightTrigger > 127) ? 128 : 0; + plat_joystick_state[c].b[8] = (controllers[c].Gamepad.wButtons & XINPUT_GAMEPAD_BACK) ? 128 : 0; + plat_joystick_state[c].b[9] = (controllers[c].Gamepad.wButtons & XINPUT_GAMEPAD_START) ? 128 : 0; + plat_joystick_state[c].b[10] = (controllers[c].Gamepad.wButtons & XINPUT_GAMEPAD_LEFT_THUMB) ? 128 : 0; + plat_joystick_state[c].b[11] = (controllers[c].Gamepad.wButtons & XINPUT_GAMEPAD_RIGHT_THUMB) ? 128 : 0; + + int dpad_x = 0, dpad_y = 0; + if (controllers[c].Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_UP) + dpad_y+=32767; + if (controllers[c].Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_DOWN) + dpad_y-=32767; + if (controllers[c].Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_RIGHT) + dpad_x+=32767; + if (controllers[c].Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_LEFT) + dpad_x-=32767; + + plat_joystick_state[c].a[2] = dpad_x; + plat_joystick_state[c].a[5] = dpad_y; + } +} + +static int joystick_get_axis(int joystick_nr, int mapping) +{ + if (mapping & POV_X) + { + int pov = plat_joystick_state[joystick_nr].p[mapping & 3]; + + if (LOWORD(pov) == 0xFFFF) + return 0; + else + return sin((2*M_PI * (double)pov) / 36000.0) * 32767; + } + else if (mapping & POV_Y) + { + int pov = plat_joystick_state[joystick_nr].p[mapping & 3]; + + if (LOWORD(pov) == 0xFFFF) + return 0; + else + return -cos((2*M_PI * (double)pov) / 36000.0) * 32767; + } + else + return plat_joystick_state[joystick_nr].a[plat_joystick_state[joystick_nr].axis[mapping].id]; +} + +void joystick_process(void) +{ + int c, d; + + if (joystick_type == 7) return; + + joystick_poll(); + + for (c = 0; c < joystick_get_max_joysticks(joystick_type); c++) + { + if (joystick_state[c].plat_joystick_nr) + { + int joystick_nr = joystick_state[c].plat_joystick_nr - 1; + + for (d = 0; d < joystick_get_axis_count(joystick_type); d++) + joystick_state[c].axis[d] = joystick_get_axis(joystick_nr, joystick_state[c].axis_mapping[d]); + for (d = 0; d < joystick_get_button_count(joystick_type); d++) + joystick_state[c].button[d] = plat_joystick_state[joystick_nr].b[joystick_state[c].button_mapping[d]]; + + for (d = 0; d < joystick_get_pov_count(joystick_type); d++) + { + int x, y; + double angle, magnitude; + + x = joystick_get_axis(joystick_nr, joystick_state[c].pov_mapping[d][0]); + y = joystick_get_axis(joystick_nr, joystick_state[c].pov_mapping[d][1]); + + angle = (atan2((double)y, (double)x) * 360.0) / (2*M_PI); + magnitude = sqrt((double)x*(double)x + (double)y*(double)y); + + if (magnitude < 16384) + joystick_state[c].pov[d] = -1; + else + joystick_state[c].pov[d] = ((int)angle + 90 + 360) % 360; + } + } + else + { + for (d = 0; d < joystick_get_axis_count(joystick_type); d++) + joystick_state[c].axis[d] = 0; + for (d = 0; d < joystick_get_button_count(joystick_type); d++) + joystick_state[c].button[d] = 0; + for (d = 0; d < joystick_get_pov_count(joystick_type); d++) + joystick_state[c].pov[d] = -1; + } + } +} + diff --git a/src/win/win_jsconf.c b/src/win/win_jsconf.c index 7fa1e52ce..1ca6f5ef8 100644 --- a/src/win/win_jsconf.c +++ b/src/win/win_jsconf.c @@ -150,7 +150,7 @@ static int get_pov(HWND hdlg, int id) return axis_sel - nr_povs; } -#ifdef __amd64__ +#if defined(__amd64__) || defined(__aarch64__) static LRESULT CALLBACK #else static BOOL CALLBACK diff --git a/src/win/win_mouse.cpp b/src/win/win_mouse.cpp index 5fab0ad9f..a57969196 100644 --- a/src/win/win_mouse.cpp +++ b/src/win/win_mouse.cpp @@ -20,7 +20,7 @@ #include #include #include -#include "../86Box.h" +#include "../86box.h" #include "../mouse.h" #include "../plat.h" #include "win.h" @@ -60,10 +60,10 @@ win_mouse_init(void) void win_mouse_close(void) { - if (lpdi_mouse != NULL) { + if (lpdi_mouse != NULL) { lpdi_mouse->Release(); lpdi_mouse = NULL; - } + } } @@ -71,8 +71,8 @@ void mouse_poll(void) { static int buttons = 0; - static int x = 0, y = 0, z = 0; - int b; + static int x = 0, y = 0, z = 0; + int b; if (FAILED(lpdi_mouse->GetDeviceState(sizeof(DIMOUSESTATE), (LPVOID)&mousestate))) { @@ -81,23 +81,23 @@ mouse_poll(void) } if (mouse_capture || video_fullscreen) { - if (x != mousestate.lX || y != mousestate.lY || z != mousestate.lZ) { - mouse_x += mousestate.lX; - mouse_y += mousestate.lY; - mouse_z += mousestate.lZ/120; + if (x != mousestate.lX || y != mousestate.lY || z != mousestate.lZ) { + mouse_x += mousestate.lX; + mouse_y += mousestate.lY; + mouse_z += mousestate.lZ/120; - x = mousestate.lX; - y = mousestate.lY; - z = mousestate.lZ/120; - } + x = mousestate.lX; + y = mousestate.lY; + z = mousestate.lZ/120; + } - b = 0; - if (mousestate.rgbButtons[0] & 0x80) b |= 1; - if (mousestate.rgbButtons[1] & 0x80) b |= 2; - if (mousestate.rgbButtons[2] & 0x80) b |= 4; - if (buttons != b) { - mouse_buttons = b; - buttons = b; - } + b = 0; + if (mousestate.rgbButtons[0] & 0x80) b |= 1; + if (mousestate.rgbButtons[1] & 0x80) b |= 2; + if (mousestate.rgbButtons[2] & 0x80) b |= 4; + if (buttons != b) { + mouse_buttons = b; + buttons = b; + } } } diff --git a/src/win/win_mouse_rawinput.cpp b/src/win/win_mouse_rawinput.cpp new file mode 100644 index 000000000..fc983d24d --- /dev/null +++ b/src/win/win_mouse_rawinput.cpp @@ -0,0 +1,160 @@ +/* + * 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. + * + * RawInput mouse interface. + * + * Version: @(#)win_mouse_rawinput.cpp 1.0.0 2019/3/19 + * + * Authors: Sarah Walker, + * Miran Grca, + * GH Cao, + * + * Copyright 2008-2017 Sarah Walker. + * Copyright 2016,2017 Miran Grca. + * Copyright 2019 GH Cao. + */ +#include +#include +#include +#include +#include "../86box.h" +#include "../mouse.h" +#include "../plat.h" +#include "win.h" + +int mouse_capture; + +typedef struct { + int buttons; + int dx; + int dy; + int dwheel; +} MOUSESTATE; + +MOUSESTATE mousestate; + +void +win_mouse_init(void) +{ + atexit(win_mouse_close); + + mouse_capture = 0; + + /* Initialize the RawInput (mouse) module. */ + RAWINPUTDEVICE ridev; + ridev.dwFlags = 0; + ridev.hwndTarget = NULL; + ridev.usUsagePage = 0x01; + ridev.usUsage = 0x02; + if (! RegisterRawInputDevices(&ridev, 1, sizeof(ridev))) + fatal("plat_mouse_init: RegisterRawInputDevices failed\n"); + + memset(&mousestate, 0, sizeof(MOUSESTATE)); +} + +void +win_mouse_handle(LPARAM lParam, int infocus) +{ + uint32_t ri_size = 0; + UINT size; + RAWINPUT *raw; + RAWMOUSE state; + + if (! infocus) return; + + GetRawInputData((HRAWINPUT)lParam, RID_INPUT, NULL, + &size, sizeof(RAWINPUTHEADER)); + + raw = (RAWINPUT*)malloc(size); + if (raw == NULL) return; + + /* Here we read the raw input data for the mouse */ + ri_size = GetRawInputData((HRAWINPUT)(lParam), RID_INPUT, + raw, &size, sizeof(RAWINPUTHEADER)); + if (ri_size != size) goto err; + + /* If the input is not a mouse, we ignore it */ + if (raw->header.dwType != RIM_TYPEMOUSE) goto err; + + state = raw->data.mouse; + + /* read mouse buttons and wheel */ + if (state.usButtonFlags & RI_MOUSE_LEFT_BUTTON_DOWN) + mousestate.buttons |= 1; + else if (state.usButtonFlags & RI_MOUSE_LEFT_BUTTON_UP) + mousestate.buttons &= ~1; + + if (state.usButtonFlags & RI_MOUSE_MIDDLE_BUTTON_DOWN) + mousestate.buttons |= 4; + else if (state.usButtonFlags & RI_MOUSE_MIDDLE_BUTTON_UP) + mousestate.buttons &= ~4; + + if (state.usButtonFlags & RI_MOUSE_RIGHT_BUTTON_DOWN) + mousestate.buttons |= 2; + else if (state.usButtonFlags & RI_MOUSE_RIGHT_BUTTON_UP) + mousestate.buttons &= ~2; + + if (state.usButtonFlags & RI_MOUSE_WHEEL) { + mousestate.dwheel += (SHORT)state.usButtonData / 120; + } + + + if (state.usFlags & MOUSE_MOVE_ABSOLUTE) { + /* absolute mouse, i.e. RDP or VNC + * seems to work fine for RDP on Windows 10 + * Not sure about other environments. + */ + static int x=state.lLastX, y=state.lLastY; + mousestate.dx += (state.lLastX - x)/100; + mousestate.dy += (state.lLastY - y)/100; + x=state.lLastX; + y=state.lLastY; + } else { + /* relative mouse, i.e. regular mouse */ + mousestate.dx += state.lLastX; + mousestate.dy += state.lLastY; + } + + err: + free(raw); +} + +void +win_mouse_close(void) +{ + RAWINPUTDEVICE ridev; + ridev.dwFlags = RIDEV_REMOVE; + ridev.hwndTarget = NULL; + ridev.usUsagePage = 0x01; + ridev.usUsage = 0x02; + RegisterRawInputDevices(&ridev, 1, sizeof(ridev)); +} + +void +mouse_poll(void) +{ + static int b = 0; + if (mouse_capture || video_fullscreen) { + if (mousestate.dx != 0 || mousestate.dy != 0 || mousestate.dwheel != 0) { + mouse_x += mousestate.dx; + mouse_y += mousestate.dy; + mouse_z = mousestate.dwheel; + + mousestate.dx=0; + mousestate.dy=0; + mousestate.dwheel=0; + + //pclog("dx=%d, dy=%d, dwheel=%d\n", mouse_x, mouse_y, mouse_z); + } + + if (b != mousestate.buttons) { + mouse_buttons = mousestate.buttons; + b = mousestate.buttons; + } + } +} diff --git a/src/win/win_new_floppy.c b/src/win/win_new_floppy.c index 5a4dd7a1f..3b48b7f86 100644 --- a/src/win/win_new_floppy.c +++ b/src/win/win_new_floppy.c @@ -542,7 +542,7 @@ new_floppy_msgbox(HWND hwnd, int type, void *arg) } -#ifdef __amd64__ +#if defined(__amd64__) || defined(__aarch64__) static LRESULT CALLBACK #else static BOOL CALLBACK diff --git a/src/win/win_settings.c b/src/win/win_settings.c index 0bfd70fed..7a642fc69 100644 --- a/src/win/win_settings.c +++ b/src/win/win_settings.c @@ -154,7 +154,7 @@ image_list_init(HWND hwndList, const uint8_t *icon_ids) if (icon_ids[i] == 0) break; -#ifdef __amd64__ +#if defined(__amd64__) || defined(__aarch64__) hiconItem = LoadIcon(hinstance, (LPCWSTR) ((uint64_t) icon_ids[i])); #else hiconItem = LoadIcon(hinstance, (LPCWSTR) ((uint32_t) icon_ids[i])); @@ -644,7 +644,7 @@ win_settings_machine_recalc_machine(HWND hdlg) } -#ifdef __amd64__ +#if defined(__amd64__) || defined(__aarch64__) static LRESULT CALLBACK #else static BOOL CALLBACK @@ -858,7 +858,7 @@ recalc_vid_list(HWND hdlg) } -#ifdef __amd64__ +#if defined(__amd64__) || defined(__aarch64__) static LRESULT CALLBACK #else static BOOL CALLBACK @@ -977,7 +977,7 @@ mouse_valid(int num, int m) } -#ifdef __amd64__ +#if defined(__amd64__) || defined(__aarch64__) static LRESULT CALLBACK #else static BOOL CALLBACK @@ -1128,7 +1128,7 @@ mpu401_standalone_allow(void) } -#ifdef __amd64__ +#if defined(__amd64__) || defined(__aarch64__) static LRESULT CALLBACK #else static BOOL CALLBACK @@ -1335,7 +1335,7 @@ win_settings_sound_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) } -#ifdef __amd64__ +#if defined(__amd64__) || defined(__aarch64__) static LRESULT CALLBACK #else static BOOL CALLBACK @@ -1453,7 +1453,7 @@ recalc_hdc_list(HWND hdlg) } -#ifdef __amd64__ +#if defined(__amd64__) || defined(__aarch64__) static LRESULT CALLBACK #else static BOOL CALLBACK @@ -1785,7 +1785,7 @@ static void network_recalc_combos(HWND hdlg) } -#ifdef __amd64__ +#if defined(__amd64__) || defined(__aarch64__) static LRESULT CALLBACK #else static BOOL CALLBACK @@ -2513,7 +2513,7 @@ recalc_selection(HWND hdlg) } -#ifdef __amd64__ +#if defined(__amd64__) || defined(__aarch64__) static LRESULT CALLBACK #else static BOOL CALLBACK @@ -3211,14 +3211,14 @@ hard_disk_track_all(void) } -#ifdef __amd64__ +#if defined(__amd64__) || defined(__aarch64__) static LRESULT CALLBACK #else static BOOL CALLBACK #endif win_settings_hard_disks_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) { - HWND h; + HWND h = NULL; int old_sel = 0, b = 0, assign = 0; const uint8_t hd_icons[2] = { 64, 0 }; @@ -4044,14 +4044,14 @@ zip_untrack(uint8_t id) } -#ifdef __amd64__ +#if defined(__amd64__) || defined(__aarch64__) static LRESULT CALLBACK #else static BOOL CALLBACK #endif win_settings_floppy_drives_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) { - HWND h; + HWND h = NULL; int i = 0, old_sel = 0; WCHAR szText[256]; const uint8_t fd_icons[15] = { 248, 16, 16, 16, 16, 16, 16, 24, 24, 24, 24, 24, 24, 24, 0 }; @@ -4150,14 +4150,14 @@ win_settings_floppy_drives_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM l } -#ifdef __amd64__ +#if defined(__amd64__) || defined(__aarch64__) static LRESULT CALLBACK #else static BOOL CALLBACK #endif win_settings_other_removable_devices_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) { - HWND h; + HWND h = NULL; int old_sel = 0, b = 0, assign = 0; uint32_t b2 = 0; const uint8_t cd_icons[3] = { 249, 32, 0 }; @@ -4498,7 +4498,7 @@ win_settings_communicate_closure(void) } -#ifdef __amd64__ +#if defined(__amd64__) || defined(__aarch64__) static LRESULT CALLBACK #else static BOOL CALLBACK @@ -4524,14 +4524,14 @@ win_settings_confirm(HWND hdlg, int button) } -#ifdef __amd64__ +#if defined(__amd64__) || defined(__aarch64__) static LRESULT CALLBACK #else static BOOL CALLBACK #endif win_settings_main_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) { - HWND h; + HWND h = NULL; int category, i = 0, j = 0; const uint8_t cat_icons[11] = { 240, 241, 242, 243, 80, 244, 245, 64, 246, 247, 0 }; diff --git a/src/win/win_snd_gain.c b/src/win/win_snd_gain.c index 6580fec7e..0dc4e5dcc 100644 --- a/src/win/win_snd_gain.c +++ b/src/win/win_snd_gain.c @@ -35,7 +35,7 @@ static uint8_t old_gain; -#ifdef __amd64__ +#if defined(__amd64__) || defined(__aarch64__) static LRESULT CALLBACK #else static BOOL CALLBACK diff --git a/src/win/win_stbar.c b/src/win/win_stbar.c index 13c6c9b20..d2fbb2d00 100644 --- a/src/win/win_stbar.c +++ b/src/win/win_stbar.c @@ -796,7 +796,7 @@ ui_sb_mount_zip_img(uint8_t id, int part, uint8_t wp, wchar_t *file_name) /* Handle messages for the Status Bar window. */ -#ifdef __amd64__ +#if defined(__amd64__) || defined(__aarch64__) static LRESULT CALLBACK #else static BOOL CALLBACK diff --git a/src/win/win_ui.c b/src/win/win_ui.c index 02d45d532..fc7e2709e 100644 --- a/src/win/win_ui.c +++ b/src/win/win_ui.c @@ -8,7 +8,7 @@ * * user Interface module for WinAPI on Windows. * - * Version: @(#)win_ui.c 1.0.38 2018/11/18 + * Version: @(#)win_ui.c 1.0.39 2019/3/20 * * Authors: Sarah Walker, * Miran Grca, @@ -17,6 +17,7 @@ * Copyright 2008-2018 Sarah Walker. * Copyright 2016-2018 Miran Grca. * Copyright 2017,2018 Fred N. van Kempen. + * Copyright 2019 GH Cao. */ #define UNICODE #include @@ -50,6 +51,7 @@ HWND hwndMain, /* application main window */ HMENU menuMain; /* application main menu */ HICON hIcon[256]; /* icon data loaded from resources */ RECT oldclip; /* mouse rect */ +int sbar_height = 23; /* statusbar height */ int infocus = 1; int rctrl_is_lalt = 0; int user_resize = 0; @@ -273,9 +275,10 @@ MainWindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) HMENU hmenu; int sb_borders[3]; - RECT rect; + RECT rect, rc; int temp_x, temp_y; + int non_client_width, non_client_height; switch (message) { case WM_CREATE: @@ -337,7 +340,6 @@ MainWindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) case IDM_VID_RESIZE: vid_resize = !vid_resize; CheckMenuItem(hmenu, IDM_VID_RESIZE, (vid_resize)? MF_CHECKED : MF_UNCHECKED); - GetWindowRect(hwnd, &rect); if (vid_resize) SetWindowLongPtr(hwnd, GWL_STYLE, (WS_OVERLAPPEDWINDOW) | WS_VISIBLE); @@ -346,10 +348,15 @@ MainWindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) SendMessage(hwndSBAR, SB_GETBORDERS, 0, (LPARAM) sb_borders); + GetWindowRect(hwnd, &rect); + GetClientRect(hwnd, &rc); + non_client_width = (rect.right-rect.left) - (rc.right-rc.left); + non_client_height = (rect.bottom-rect.top) - (rc.bottom-rc.top); + /* Main Window. */ - MoveWindow(hwnd, rect.left, rect.top, - unscaled_size_x + (GetSystemMetrics(vid_resize ? SM_CXSIZEFRAME : SM_CXFIXEDFRAME) * 2), - unscaled_size_y + (GetSystemMetrics(SM_CYEDGE) * 2) + (GetSystemMetrics(vid_resize ? SM_CYSIZEFRAME : SM_CYFIXEDFRAME) * 2) + GetSystemMetrics(SM_CYMENUSIZE) + GetSystemMetrics(SM_CYCAPTION) + 17 + sb_borders[1] + 1, + MoveWindow(hwnd, rect.left, rect.top, + unscaled_size_x + non_client_width, + unscaled_size_y + non_client_height + sbar_height, TRUE); /* Render window. */ @@ -556,7 +563,7 @@ MainWindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) SendMessage(hwndSBAR, SB_GETBORDERS, 0, (LPARAM) sb_borders); temp_x = (lParam & 0xFFFF); - temp_y = (lParam >> 16) - (21 + sb_borders[1]); + temp_y = (lParam >> 16) - sbar_height; if (temp_x < 1) temp_x = 1; if (temp_y < 1) @@ -726,8 +733,9 @@ ui_init(int nCmdShow) WNDCLASSEX wincl; /* buffer for main window's class */ RAWINPUTDEVICE ridev; /* RawInput device */ MSG messages; /* received-messages buffer */ - HWND hwnd; /* handle for our window */ + HWND hwnd = NULL; /* handle for our window */ HACCEL haccel; /* handle to accelerator table */ + RECT sbar_rect; /* RECT of the status bar */ int bRet; if (settings_only) { @@ -838,6 +846,12 @@ ui_init(int nCmdShow) /* Create the status bar window. */ StatusBarCreate(hwndMain, IDC_STATUS, hinstance); + /* Get the actual height of the statusbar, + * since that is not something we can change. + */ + GetWindowRect(hwndSBAR, &sbar_rect); + sbar_height = sbar_rect.bottom - sbar_rect.top; + /* * Before we can create the Render window, we first have * to prepare some other things that it depends on. @@ -1002,7 +1016,9 @@ void plat_resize(int x, int y) { int sb_borders[3]; - RECT r; + RECT r, rc; + int non_client_width; + int non_client_height; /* First, see if we should resize the UI window. */ if (!vid_resize) { @@ -1011,11 +1027,14 @@ plat_resize(int x, int y) SendMessage(hwndSBAR, SB_GETBORDERS, 0, (LPARAM) sb_borders); GetWindowRect(hwndMain, &r); + GetClientRect(hwndMain, &rc); + non_client_width = (r.right-r.left) - (rc.right-rc.left); + non_client_height = (r.bottom-r.top) - (rc.bottom-rc.top); + MoveWindow(hwndMain, r.left, r.top, - x + (GetSystemMetrics(vid_resize ? SM_CXSIZEFRAME : SM_CXFIXEDFRAME) * 2), - y + (GetSystemMetrics(SM_CYEDGE) * 2) + (GetSystemMetrics(vid_resize ? SM_CYSIZEFRAME : SM_CYFIXEDFRAME) * 2) + GetSystemMetrics(SM_CYMENUSIZE) + GetSystemMetrics(SM_CYCAPTION) + 17 + sb_borders[1] + 1, + x + non_client_width, + y + non_client_height + sbar_height, TRUE); - GetWindowRect(hwndMain, &r); MoveWindow(hwndRender, 0, 0, x, y, TRUE); GetWindowRect(hwndRender, &r); @@ -1060,7 +1079,7 @@ plat_mouse_capture(int on) /* Catch WM_INPUT messages for 'current focus' window. */ static LONG_PTR input_orig_proc; static HWND input_orig_hwnd = NULL; -#ifdef __amd64__ +#if defined(__amd64__) || defined(__aarch64__) static LRESULT CALLBACK #else static BOOL CALLBACK @@ -1070,6 +1089,9 @@ input_proc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) switch (message) { case WM_INPUT: keyboard_handle(lParam, infocus); +#ifndef USE_DINPUT + win_mouse_handle(lParam, infocus); +#endif break; case WM_SETFOCUS: