From bc6a8f451ad9e089c989bc04aed8a68945c212c4 Mon Sep 17 00:00:00 2001 From: Flyinghead Date: Mon, 17 Sep 2018 12:59:52 +0200 Subject: [PATCH] Fix picotcp on Windows Automatically configure tap IP address, route and proxy arp using iphlpapi. Partial port to MINGW. --- core/build.h | 2 +- core/core.mk | 10 +- core/deps/picotcp/modules/pico_arp.c | 3 +- .../picotcp/modules/pico_dev_tap_windows.c | 61 +++++---- .../picotcp/modules/pico_dev_tap_windows.h | 1 + core/deps/picotcp/rules/tap.mk | 7 +- core/deps/picotcp/rules/tun.mk | 5 +- core/deps/picotcp/stack/pico_stack.c | 6 + core/hw/modem/picoppp.cpp | 125 +++++++++++++++++- core/hw/modem/pppd.cpp | 2 +- core/hw/pvr/Renderer_if.cpp | 2 +- core/hw/pvr/ta_ctx.cpp | 8 +- core/types.h | 4 + core/windows/winmain.cpp | 15 ++- shell/linux/Makefile | 42 ++++-- 15 files changed, 240 insertions(+), 53 deletions(-) diff --git a/core/build.h b/core/build.h index 1cd3c0880..c0fbacba5 100755 --- a/core/build.h +++ b/core/build.h @@ -152,7 +152,7 @@ //automatic #if defined(_WIN32) && !defined(TARGET_WIN86) && !defined(TARGET_WIN64) - #if !defined(_M_AMD64) + #if !defined(_M_AMD64) && !defined(__x86_64__) #define TARGET_WIN86 #else #define TARGET_WIN64 diff --git a/core/core.mk b/core/core.mk index 3b3b83bd8..c0db0774b 100755 --- a/core/core.mk +++ b/core/core.mk @@ -8,7 +8,7 @@ RZDCY_SRC_DIR ?= $(call my-dir) RZDCY_MODULES := cfg/ hw/arm7/ hw/aica/ hw/holly/ hw/ hw/gdrom/ hw/maple/ hw/modem/ \ hw/mem/ hw/pvr/ hw/sh4/ hw/sh4/interpr/ hw/sh4/modules/ plugins/ profiler/ oslib/ \ - hw/extdev/ hw/arm/ hw/naomi/ imgread/ linux/ ./ deps/coreio/ deps/zlib/ deps/chdr/ deps/crypto/ \ + hw/extdev/ hw/arm/ hw/naomi/ imgread/ ./ deps/coreio/ deps/zlib/ deps/chdr/ deps/crypto/ \ deps/libelf/ deps/chdpsr/ arm_emitter/ rend/ reios/ deps/libpng/ deps/xbrz/ @@ -56,7 +56,7 @@ ifndef NO_NIXPROF endif ifdef FOR_ANDROID - RZDCY_MODULES += android/ deps/libandroid/ deps/libzip/ + RZDCY_MODULES += android/ deps/libandroid/ linux/ deps/libzip/ endif ifdef USE_SDL @@ -64,7 +64,11 @@ ifdef USE_SDL endif ifdef FOR_LINUX - RZDCY_MODULES += linux-dist/ + RZDCY_MODULES += linux-dist/ linux/ +endif + +ifdef FOR_WINDOWS + RZDCY_MODULES += windows/ endif RZDCY_FILES := $(foreach dir,$(addprefix $(RZDCY_SRC_DIR)/,$(RZDCY_MODULES)),$(wildcard $(dir)*.cpp)) diff --git a/core/deps/picotcp/modules/pico_arp.c b/core/deps/picotcp/modules/pico_arp.c index 4a026506e..8ff25e25f 100644 --- a/core/deps/picotcp/modules/pico_arp.c +++ b/core/deps/picotcp/modules/pico_arp.c @@ -443,7 +443,8 @@ static int pico_arp_process_in(struct pico_frame *f, struct pico_arp_hdr *hdr, s // } /* If no existing entry was found, create a new entry, or fail trying. */ - if ((!found) && (pico_arp_create_entry(hdr->s_mac, hdr->src, f->dev) < 0)) { + /* Do not create an entry for Slaac V4 probe packets (0.0.0.0) */ + if ((!found) && (hdr->src.addr == 0 || pico_arp_create_entry(hdr->s_mac, hdr->src, f->dev) < 0)) { pico_frame_discard(f); return -1; } diff --git a/core/deps/picotcp/modules/pico_dev_tap_windows.c b/core/deps/picotcp/modules/pico_dev_tap_windows.c index 252f32a3e..22e06e0b0 100644 --- a/core/deps/picotcp/modules/pico_dev_tap_windows.c +++ b/core/deps/picotcp/modules/pico_dev_tap_windows.c @@ -25,6 +25,9 @@ #include #include "pico_dev_tap_windows_private.h" +#define DEBUG_TAP_INFO +#define DEBUG_TAP_GENERAL + /* * Debugging info */ @@ -96,7 +99,8 @@ struct tuntap uint8_t mac[6]; /* Windows stuff */ - DWORD adapter_index; /*adapter index for TAP-Windows adapter, ~0 if undefined */ + //DWORD adapter_index; /*adapter index for TAP-Windows adapter, ~0 if undefined */ + const char *guid; HANDLE hand; struct overlapped_io reads; /* for overlapped IO */ struct overlapped_io writes; @@ -217,13 +221,13 @@ const struct tap_reg *get_tap_reg (void) if (!strcmp (component_id, TAP_WIN_COMPONENT_ID)) { struct tap_reg *reg; - reg = PICO_ZALLOC(sizeof(struct tap_reg), 1); + reg = PICO_ZALLOC(sizeof(struct tap_reg)); /* ALLOC_OBJ_CLEAR_GC (reg, struct tap_reg, gc); */ if (!reg) return NULL; /* reg->guid = string_alloc (net_cfg_instance_id, gc); */ - reg->guid = PICO_ZALLOC (strlen(net_cfg_instance_id) + 1, 1); + reg->guid = PICO_ZALLOC (strlen(net_cfg_instance_id) + 1); if (!(reg->guid)) { PICO_FREE(reg); @@ -329,13 +333,13 @@ const struct panel_reg *get_panel_reg (void) struct panel_reg *reg; /* ALLOC_OBJ_CLEAR_GC (reg, struct panel_reg, gc); */ - reg = PICO_ZALLOC(sizeof(struct panel_reg), 1); + reg = PICO_ZALLOC(sizeof(struct panel_reg)); if (!reg) return NULL; n = WideCharToMultiByte (CP_UTF8, 0, name_data, -1, NULL, 0, NULL, NULL); /* name = gc_malloc (n, false, gc); */ - name = PICO_ZALLOC(n, 1); + name = PICO_ZALLOC(n); if (!name) { PICO_FREE(reg); @@ -345,7 +349,7 @@ const struct panel_reg *get_panel_reg (void) WideCharToMultiByte (CP_UTF8, 0, name_data, -1, name, n, NULL, NULL); reg->name = name; /* reg->guid = string_alloc (enum_name, gc); */ - reg->guid = PICO_ZALLOC(strlen(enum_name) + 1, 1); + reg->guid = PICO_ZALLOC(strlen(enum_name) + 1); if (!reg->guid) { PICO_FREE((void *)reg->name); @@ -520,13 +524,14 @@ int open_tun (const char *dev, const char *dev_type, const char *dev_node, struc ); if (tt->hand == INVALID_HANDLE_VALUE) - dbg_tap_info("CreateFile failed on TAP device: %s\n", device_path); + dbg_tap_info("CreateFile failed on TAP device: %s error %d\n", device_path, GetLastError()); /* translate high-level device name into a device instance GUID using the registry */ tt->actual_name = PICO_ZALLOC(strlen(name) + 1); if (tt->actual_name) strcpy(tt->actual_name, name); + tt->guid = device_guid; } dbg_tap_info("TAP-WIN32 device [%s] opened: %s\n", tt->actual_name, device_path); @@ -605,11 +610,11 @@ int open_tun (const char *dev, const char *dev_type, const char *dev_node, struc if (tt->type == DEV_TYPE_TUN) { dbg_tap_info("TUN type not supported for now...\n"); + // TODO: Set Point-to-point through DeviceIoControl TAP_WIN_IOCTL_CONFIG_TUN return -1; } else if (tt->type == DEV_TYPE_TAP) { /* TAP DEVICE */ - dbg_tap_info("TODO: Set Point-to-point through DeviceIoControl\n"); } /* set driver media status to 'connected' */ @@ -688,7 +693,7 @@ int tun_read_queue (struct tuntap *tt, uint8_t *buffer, int maxsize) /* the overlapped read will signal this event on I/O completion */ if (!ResetEvent (tt->reads.overlapped.hEvent)) - dbg_tap("ResetEvent failed\n"); + dbg_tap_info("ResetEvent failed\n"); status = ReadFile( tt->hand, @@ -703,7 +708,7 @@ int tun_read_queue (struct tuntap *tt, uint8_t *buffer, int maxsize) /* since we got an immediate return, we must signal the event object ourselves */ /* ASSERT (SetEvent (tt->reads.overlapped.hEvent)); */ if (!SetEvent (tt->reads.overlapped.hEvent)) - dbg_tap("SetEvent failed\n"); + dbg_tap_info("SetEvent failed\n"); tt->reads.iostate = IOSTATE_IMMEDIATE_RETURN; tt->reads.status = 0; @@ -724,11 +729,11 @@ int tun_read_queue (struct tuntap *tt, uint8_t *buffer, int maxsize) else /* error occurred */ { if (!SetEvent (tt->reads.overlapped.hEvent)) - dbg_tap("SetEvent failed\n"); + dbg_tap_info("SetEvent failed\n"); tt->reads.iostate = IOSTATE_IMMEDIATE_RETURN; tt->reads.status = err; - dbg_tap ("WIN32 I/O: TAP Read error [%d] : %d\n", (int) len, (int) err); + dbg_tap_info("WIN32 I/O: TAP Read error [%d] : %d\n", (int) len, (int) err); } } } @@ -764,7 +769,7 @@ int tun_finalize(HANDLE h, struct overlapped_io *io, uint8_t **buf, uint32_t *bu io->iostate = IOSTATE_INITIAL; if (!ResetEvent (io->overlapped.hEvent)) - dbg_tap("ResetEvent in finalize failed!\n"); + dbg_tap_info("ResetEvent in finalize failed!\n"); dbg_tap_win32 ("WIN32 I/O: TAP Completion success: QUEUED! [%d]\n", ret); } @@ -773,15 +778,16 @@ int tun_finalize(HANDLE h, struct overlapped_io *io, uint8_t **buf, uint32_t *bu /* error during a queued operation */ /* error, or just not completed? */ ret = 0; - if (GetLastError() != ERROR_IO_INCOMPLETE) + int last_error = GetLastError(); + if (last_error != ERROR_IO_INCOMPLETE) { /* if no error (i.e. just not finished yet), then DON'T execute this code */ io->iostate = IOSTATE_INITIAL; if (!ResetEvent (io->overlapped.hEvent)) - dbg_tap("ResetEvent in finalize failed!\n"); + dbg_tap_info("ResetEvent in finalize failed!\n"); - dbg_tap("WIN32 I/O: TAP Completion error\n"); + dbg_tap_info("WIN32 I/O: TAP Completion error %d\n", last_error); ret = -1; /* There actually was an error */ } } @@ -791,14 +797,14 @@ int tun_finalize(HANDLE h, struct overlapped_io *io, uint8_t **buf, uint32_t *bu case IOSTATE_IMMEDIATE_RETURN: io->iostate = IOSTATE_INITIAL; if (!ResetEvent (io->overlapped.hEvent)) - dbg_tap("ResetEvent in finalize failed!\n"); + dbg_tap_info("ResetEvent in finalize failed!\n"); if (io->status) { /* error return for a non-queued operation */ SetLastError (io->status); ret = -1; - dbg_tap("WIN32 I/O: TAP Completion non-queued error\n"); + dbg_tap_info("WIN32 I/O: TAP Completion non-queued error\n"); } else { @@ -815,11 +821,11 @@ int tun_finalize(HANDLE h, struct overlapped_io *io, uint8_t **buf, uint32_t *bu case IOSTATE_INITIAL: /* were we called without proper queueing? */ SetLastError (ERROR_INVALID_FUNCTION); ret = -1; - dbg_tap ("WIN32 I/O: TAP Completion BAD STATE\n"); + dbg_tap_info("WIN32 I/O: TAP Completion BAD STATE\n"); break; default: - dbg_tap ("Some weird case happened..\n"); + dbg_tap_info("Some weird case happened..\n"); } if (buf) @@ -845,7 +851,7 @@ int tun_write_queue (struct tuntap *tt, uint8_t *buf, uint32_t buf_len) /* the overlapped write will signal this event on I/O completion */ if (!ResetEvent (tt->writes.overlapped.hEvent)) - dbg_tap("ResetEvent in write_queue failed!\n"); + dbg_tap_info("ResetEvent in write_queue failed!\n"); status = WriteFile( tt->hand, @@ -861,7 +867,7 @@ int tun_write_queue (struct tuntap *tt, uint8_t *buf, uint32_t buf_len) /* since we got an immediate return, we must signal the event object ourselves */ if (!SetEvent (tt->writes.overlapped.hEvent)) - dbg_tap("SetEvent in write_queue failed!\n"); + dbg_tap_info("SetEvent in write_queue failed!\n"); tt->writes.status = 0; @@ -882,7 +888,7 @@ int tun_write_queue (struct tuntap *tt, uint8_t *buf, uint32_t buf_len) else /* error occurred */ { if (!SetEvent (tt->writes.overlapped.hEvent)) - dbg_tap("SetEvent in write_queue failed!\n"); + dbg_tap_info("SetEvent in write_queue failed!\n"); tt->writes.iostate = IOSTATE_IMMEDIATE_RETURN; tt->writes.status = err; @@ -1026,8 +1032,6 @@ static int pico_tap_poll(struct pico_device *dev, int loop_score) return loop_score; } - - #define CLEAR(x) memset(&(x), 0, sizeof(x)) void overlapped_io_init (struct overlapped_io *o, int event_state) @@ -1066,7 +1070,7 @@ void init_tun_post (struct tuntap *tt) struct pico_device *pico_tap_create(char *name, uint8_t *mac) { struct pico_device_tap *tap = PICO_ZALLOC(sizeof(struct pico_device_tap)); - struct tuntap *tt = PICO_ZALLOC(sizeof(struct tuntap), 1); + struct tuntap *tt = PICO_ZALLOC(sizeof(struct tuntap)); if (!(tap) || !(tt)) return NULL; @@ -1099,3 +1103,8 @@ struct pico_device *pico_tap_create(char *name, uint8_t *mac) return (struct pico_device *)tap; } + +const char *pico_tap_get_guid(struct pico_device *dev) +{ + return ((struct pico_device_tap *)dev)->tt->guid; +} diff --git a/core/deps/picotcp/modules/pico_dev_tap_windows.h b/core/deps/picotcp/modules/pico_dev_tap_windows.h index bdc6977ae..ded5cd072 100644 --- a/core/deps/picotcp/modules/pico_dev_tap_windows.h +++ b/core/deps/picotcp/modules/pico_dev_tap_windows.h @@ -12,6 +12,7 @@ struct pico_device *pico_tap_create(char *name, uint8_t *mac); /* TODO: not implemented yet */ /* void pico_tap_destroy(struct pico_device *null); */ +const char *pico_tap_get_guid(struct pico_device *dev); #endif diff --git a/core/deps/picotcp/rules/tap.mk b/core/deps/picotcp/rules/tap.mk index 2f3e14978..bb7a02a52 100644 --- a/core/deps/picotcp/rules/tap.mk +++ b/core/deps/picotcp/rules/tap.mk @@ -1 +1,6 @@ -MOD_OBJ+=$(LIBBASE)modules/pico_dev_tap.o +UNAME=$(shell uname) +ifeq ($(findstring MINGW,$(UNAME)),) + MOD_OBJ+=$(LIBBASE)modules/pico_dev_tap.o +else + MOD_OBJ+=$(LIBBASE)modules/pico_dev_tap_windows.o +endif diff --git a/core/deps/picotcp/rules/tun.mk b/core/deps/picotcp/rules/tun.mk index a5b93fec9..ab1c541a4 100644 --- a/core/deps/picotcp/rules/tun.mk +++ b/core/deps/picotcp/rules/tun.mk @@ -1 +1,4 @@ -MOD_OBJ+=$(LIBBASE)modules/pico_dev_tun.o +UNAME=$(shell uname) +ifeq ($(findstring MINGW,$(UNAME)),) + MOD_OBJ+=$(LIBBASE)modules/pico_dev_tun.o +endif diff --git a/core/deps/picotcp/stack/pico_stack.c b/core/deps/picotcp/stack/pico_stack.c index 007cd40bf..7b5ac3497 100644 --- a/core/deps/picotcp/stack/pico_stack.c +++ b/core/deps/picotcp/stack/pico_stack.c @@ -40,6 +40,12 @@ # define MOCKABLE #endif +#ifdef _WIN32 +#ifdef WEAK +#undef WEAK +#endif +#define WEAK +#endif volatile pico_time pico_tick; volatile pico_err_t pico_err; diff --git a/core/hw/modem/picoppp.cpp b/core/hw/modem/picoppp.cpp index 444e28ac1..586e05167 100644 --- a/core/hw/modem/picoppp.cpp +++ b/core/hw/modem/picoppp.cpp @@ -3,7 +3,11 @@ extern "C" { #include #include +#ifdef _WIN32 +#include +#else #include +#endif #include #include #ifdef DHCP @@ -11,7 +15,12 @@ extern "C" { #endif } +#ifdef _WIN32 +#include +#define NETWORK_TAP +#else #define NETWORK_TUN +#endif #include "types.h" #include "cfg/cfg.h" @@ -20,6 +29,7 @@ extern "C" { static struct pico_device *ppp; struct pico_device* tap; struct pico_device* tun; +u8 virtual_mac[] = { 0x76, 0x6D, 0x61, 0x63, 0x30, 0x31 }; static std::queue in_buffer; static std::queue out_buffer; @@ -100,7 +110,7 @@ static bool pico_stack_inited; bool start_pico() { - struct pico_ip4 ipaddr, netmask, zero = { + struct pico_ip4 ipaddr, dcaddr, dnsaddr, netmask, zero = { 0 }; @@ -120,14 +130,14 @@ bool start_pico() printf("No IP address set for Netplay. Set IP= in the [network] section\n"); return false; } - pico_string_to_ipv4(dc_ip.c_str(), &ipaddr.addr); - pico_ppp_set_peer_ip(ppp, ipaddr); + pico_string_to_ipv4(dc_ip.c_str(), &dcaddr.addr); + pico_ppp_set_peer_ip(ppp, dcaddr); pico_string_to_ipv4("192.168.167.1", &ipaddr.addr); pico_ppp_set_ip(ppp, ipaddr); string dns_ip = cfgLoadStr("network", "DNS", "46.101.91.123"); - pico_string_to_ipv4(dns_ip.c_str(), &ipaddr.addr); - pico_ppp_set_dns1(ppp, ipaddr); + pico_string_to_ipv4(dns_ip.c_str(), &dnsaddr.addr); + pico_ppp_set_dns1(ppp, dnsaddr); #ifdef NETWORK_TAP // TAP @@ -138,7 +148,11 @@ bool start_pico() // # ip route add /32 dev tap0 # where is the value of network:IP in emu.cfg./. This also allows proxy arp // # echo '1' >/proc/sys/net/ipv4/conf/all/proxy_arp // (or ...conf/tap0/proxy_arp and ...conf/eth0/proxy_arp only) +#ifdef _WIN32 + tap = pico_tap_create("tap0", virtual_mac); +#else tap = pico_tap_create("tap0"); +#endif if (!tap) { stop_pico(); @@ -150,6 +164,107 @@ bool start_pico() pico_ipv4_link_add(tap, ipaddr, netmask); // Proxy ARP pico_arp_create_entry(tap->eth->mac.addr, ipaddr, ppp); + +#ifdef _WIN32 + int err; + + // Enable routing + OVERLAPPED overlapped; + memset(&overlapped, 0, sizeof(overlapped)); + overlapped.hEvent = overlapped.hEvent = CreateEvent (NULL, FALSE, FALSE, NULL); + if (overlapped.hEvent == NULL) + printf("CreateEvent failed with error %d\n", GetLastError()); + else + { + HANDLE handle; + err = EnableRouter(&handle, &overlapped); + if (err != ERROR_IO_PENDING) + printf("EnableRouter failed with error %d\n", err); + else + printf("Windows router enabled\n"); + CloseHandle(overlapped.hEvent); + } + + // Get the LAN interface index + DWORD idx = -1; + err = GetBestInterface(dnsaddr.addr, &idx); + if (err != NO_ERROR) + printf("GetBestInterface failed error %d\n", err); + + // Create a Proxy ARP entry for the DC on the local LAN + if (idx != -1) + { + err = CreateProxyArpEntry(dcaddr.addr, 0xffffffff, idx); + if (err == ERROR_OBJECT_ALREADY_EXISTS) + printf("Proxy ARP entry already exists\n"); + else if (err != NO_ERROR) + printf("CreateProxyArpEntry failed error %d\n", err); + } + + // Get the TAP interface index + unsigned long size = sizeof(IP_INTERFACE_INFO); + IP_INTERFACE_INFO *infos = (IP_INTERFACE_INFO *)malloc(size); + err = GetInterfaceInfo(infos, &size); + if (err == ERROR_INSUFFICIENT_BUFFER) + { + free(infos); + infos = (IP_INTERFACE_INFO *)malloc(size); + err = GetInterfaceInfo(infos, &size); + if (err != NO_ERROR) + { + printf("GetInterfaceInfo failed error %d\n", err); + infos->NumAdapters = 0; + } + } + + const char *tap_guid = pico_tap_get_guid(tap); + wchar_t wtap_guid[40]; + MultiByteToWideChar(CP_UTF8, 0, tap_guid, strlen(tap_guid), &wtap_guid[0], 40); + DWORD tap_idx = -1; // 11; + for (int i = 0; i < infos->NumAdapters; i++) + { + printf("Found interface %ls index %d\n", infos->Adapter[i].Name, infos->Adapter[i].Index); + if (wcsstr(infos->Adapter[i].Name, wtap_guid) != NULL) + { + tap_idx = infos->Adapter[i].Index; + break; + } + } + free(infos); + + // Set the TAP interface IP address + pico_string_to_ipv4("192.168.166.1", &ipaddr.addr); + pico_string_to_ipv4("255.255.255.0", &netmask.addr); + unsigned long nte_context, nte_instance; + err = AddIPAddress(ipaddr.addr, netmask.addr, tap_idx, &nte_context, &nte_instance); + if (err == ERROR_OBJECT_ALREADY_EXISTS) + printf("TAP IP address already set\n"); + else if (err != NO_ERROR) + printf("AddIpAddress failed with error %d\n", err); + else + printf("TAP IP address set\n"); + + // Create a route to the DC through the TAP interface + if (tap_idx != -1) + { + MIB_IPFORWARDROW fwd; + memset(&fwd, 0, sizeof(fwd)); + fwd.dwForwardDest = dcaddr.addr; + fwd.dwForwardMask = 0xffffffff; + fwd.dwForwardIfIndex = tap_idx; + fwd.dwForwardProto = MIB_IPPROTO_NETMGMT; + fwd.dwForwardAge = INFINITE; + fwd.dwForwardMetric1 = 500; + err = CreateIpForwardEntry(&fwd); + if (err == ERROR_OBJECT_ALREADY_EXISTS) + printf("IP forward entry already exists\n"); + else if (err != NO_ERROR) + printf("CreateIpForwardEntry failed with error %d\n", err); + else + printf("IP forward entry created\n"); + } + +#endif #endif #ifdef NETWORK_TUN diff --git a/core/hw/modem/pppd.cpp b/core/hw/modem/pppd.cpp index cd6e09a24..31afb279f 100644 --- a/core/hw/modem/pppd.cpp +++ b/core/hw/modem/pppd.cpp @@ -22,7 +22,7 @@ */ #include "types.h" -#if 1//HOST_OS == OS_LINUX +#if HOST_OS == OS_LINUX #include #include diff --git a/core/hw/pvr/Renderer_if.cpp b/core/hw/pvr/Renderer_if.cpp index a15713528..002f79c25 100644 --- a/core/hw/pvr/Renderer_if.cpp +++ b/core/hw/pvr/Renderer_if.cpp @@ -490,7 +490,7 @@ bool rend_init() case 0: renderer = rend_GLES2(); break; -#if HOST_OS == OS_WINDOWS +#if 0 //HOST_OS == OS_WINDOWS case 1: renderer = rend_D3D11(); break; diff --git a/core/hw/pvr/ta_ctx.cpp b/core/hw/pvr/ta_ctx.cpp index 608dc7c3d..f5dcb95d1 100644 --- a/core/hw/pvr/ta_ctx.cpp +++ b/core/hw/pvr/ta_ctx.cpp @@ -41,7 +41,9 @@ int posix_memalign(void** memptr, size_t alignment, size_t size) { void* OS_aligned_malloc(size_t align, size_t size) { void *result; - #if HOST_OS == OS_WINDOWS + #ifdef __MINGW32__ + return __mingw_aligned_malloc(size, align); + #elif HOST_OS == OS_WINDOWS result = _aligned_malloc(size, align); #else if(posix_memalign(&result, align, size)) result = 0; @@ -52,7 +54,9 @@ void* OS_aligned_malloc(size_t align, size_t size) // helper for 32 byte aligned memory de-allocation void OS_aligned_free(void *ptr) { - #if HOST_OS == OS_WINDOWS + #ifdef __MINGW32__ + __mingw_aligned_free(ptr); + #elif HOST_OS == OS_WINDOWS _aligned_free(ptr); #else free(ptr); diff --git a/core/types.h b/core/types.h index 4f6004868..fa9d2a0f9 100644 --- a/core/types.h +++ b/core/types.h @@ -5,10 +5,14 @@ #if BUILD_COMPILER==COMPILER_VC #define DECL_ALIGN(x) __declspec(align(x)) #else +#ifndef __forceinline #define __forceinline inline +#endif #define DECL_ALIGN(x) __attribute__((aligned(x))) +#ifndef _WIN32 #define __debugbreak #endif +#endif #if HOST_CPU == CPU_X86 diff --git a/core/windows/winmain.cpp b/core/windows/winmain.cpp index 3c01f4617..22d0a6566 100644 --- a/core/windows/winmain.cpp +++ b/core/windows/winmain.cpp @@ -683,8 +683,15 @@ int CALLBACK WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine SetupPath(); - //SetUnhandledExceptionFilter(&ExeptionHandler); +#ifndef __GNUC__ __try +#else +#ifdef _WIN64 + AddVectoredExceptionHandler(1, ExeptionHandler); +#else + SetUnhandledExceptionFilter(&ExeptionHandler); +#endif +#endif { int dc_init(int argc,wchar* argv[]); void dc_run(); @@ -692,16 +699,18 @@ int CALLBACK WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine dc_init(argc,argv); #ifdef _WIN64 - setup_seh(); + setup_seh(); #endif dc_run(); dc_term(); } +#ifndef __GNUC__ __except( ExeptionHandler(GetExceptionInformation()) ) { printf("Unhandled exception - Emulation thread halted...\n"); } +#endif SetUnhandledExceptionFilter(0); return 0; @@ -831,4 +840,4 @@ void VArray2::UnLockRegion(u32 offset,u32 size) } int get_mic_data(u8* buffer) { return 0; } -int push_vmu_screen(u8* buffer) { return 0; } \ No newline at end of file +int push_vmu_screen(u8* buffer) { return 0; } diff --git a/shell/linux/Makefile b/shell/linux/Makefile index d769c8bfc..50ebdc578 100644 --- a/shell/linux/Makefile +++ b/shell/linux/Makefile @@ -6,6 +6,7 @@ WEBUI :=1 USE_OSS := 1 #USE_PULSEAUDIO := 1 USE_EVDEV := 1 +PLATFORM_EXT := elf CXX=${CC_PREFIX}g++ CC=${CC_PREFIX}gcc @@ -229,6 +230,30 @@ else ifneq (,$(findstring vero4k,$(platform))) USE_GLES := 1 USE_SDL := 1 +# Windows +else ifneq (,$(findstring win32,$(platform))) + X64_REC := 1 + NOT_ARM := 1 + CFLAGS += -DTARGET_NO_WEBUI -fno-builtin-sqrtf -funroll-loops + LDFLAGS += -static-libgcc -static-libstdc++ + LIBS := -lopengl32 -lwinmm -lgdi32 -lwsock32 -ldsound -lcomctl32 -lcomdlg32 -lxinput -liphlpapi + PLATFORM_EXT := exe + CC = gcc + CXX = g++ +ifeq ($(WITH_DYNAREC), x86) + LDFLAGS += -m32 + CFLAGS += -m32 +else + CFLAGS += -D TARGET_NO_AREC +endif + undefine USE_X11 + undefine USE_ALSA + undefine USE_OSS + undefine USE_EVDEV + undefine FOR_LINUX + undefine WEBUI + NO_NIXPROF := 1 + FOR_WINDOWS := 1 else $(error Unknown platform) endif @@ -246,8 +271,10 @@ CXXFLAGS += -fno-rtti -fpermissive -fno-operator-names -D_GLIBCXX_USE_CXX11_ABI= INCS += -I$(RZDCY_SRC_DIR) -I$(RZDCY_SRC_DIR)/deps -I$(RZDCY_SRC_DIR)/khronos -LIBS += -lm -lrt -ldl -LIBS += -lpthread +LIBS += -lm -lpthread +ifdef FOR_LINUX +LIBS += -lrt -ldl +endif PREFIX ?= /usr/local MAN_DIR ?= ${PREFIX}/share/man/man1 @@ -328,7 +355,7 @@ endif ifdef USE_GLES CXXFLAGS += -DGLES LIBS += -lEGL -lGLESv2 -else +else ifdef FOR_LINUX LIBS += -ldl -lGL #for desktop gl endif @@ -337,20 +364,20 @@ ifdef HAS_SOFTREND CXXFLAGS += -DTARGET_SOFTREND endif -EXECUTABLE_STRIPPED=nosym-reicast.elf +EXECUTABLE_STRIPPED=nosym-reicast.$(PLATFORM_EXT) ifdef NAOMI CFLAGS += -D TARGET_NAOMI -D SAVE_EPPROM DC_PLATFORM=naomi - EXECUTABLE=reicast_naomi.elf + EXECUTABLE=reicast_naomi.$(PLATFORM_EXT) EXECUTABLE_NAME=reicast-naomi else ifdef DISPFRAME CFLAGS += -D TARGET_DISPFRAME DC_PLATFORM=dispframe - EXECUTABLE=dispframe.elf + EXECUTABLE=dispframe.$(PLATFORM_EXT) EXECUTABLE_NAME=dispframe else DC_PLATFORM=dreamcast - EXECUTABLE=reicast.elf + EXECUTABLE=reicast.$(PLATFORM_EXT) EXECUTABLE_NAME=reicast endif @@ -444,7 +471,6 @@ $(BUILDDIR)/hw/modem/picoppp.build_obj: $(BUILDDIR)/deps/picotcp/lib/libpicotcp. $(BUILDDIR)/deps/picotcp/lib/libpicotcp.a: mkdir -p $(BUILDDIR)/deps/picotcp - echo cd $(RZDCY_SRC_DIR)/deps/picotcp , make PREFIX=$(PWD)/$(BUILDDIR)/deps/picotcp cd $(RZDCY_SRC_DIR)/deps/picotcp ; make PREFIX=$(PWD)/$(BUILDDIR)/deps/picotcp .PRECIOUS = $(DEPDIR)/%.d