Fix picotcp on Windows

Automatically configure tap IP address, route and proxy arp using iphlpapi.
Partial port to MINGW.
This commit is contained in:
Flyinghead 2018-09-17 12:59:52 +02:00
parent 6699a8a294
commit bc6a8f451a
15 changed files with 240 additions and 53 deletions

View File

@ -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

View File

@ -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))

View File

@ -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;
}

View File

@ -25,6 +25,9 @@
#include <winioctl.h>
#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;
}

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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;

View File

@ -3,7 +3,11 @@
extern "C" {
#include <pico_stack.h>
#include <pico_dev_ppp.h>
#ifdef _WIN32
#include <pico_dev_tap_windows.h>
#else
#include <pico_dev_tap.h>
#endif
#include <pico_arp.h>
#include <pico_dev_tun.h>
#ifdef DHCP
@ -11,7 +15,12 @@ extern "C" {
#endif
}
#ifdef _WIN32
#include <iphlpapi.h>
#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<u8> in_buffer;
static std::queue<u8> 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 <IP>/32 dev tap0 # where <IP> 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

View File

@ -22,7 +22,7 @@
*/
#include "types.h"
#if 1//HOST_OS == OS_LINUX
#if HOST_OS == OS_LINUX
#include <unistd.h>
#include <stdio.h>

View File

@ -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;

View File

@ -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);

View File

@ -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

View File

@ -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; }
int push_vmu_screen(u8* buffer) { return 0; }

View File

@ -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