diff --git a/Makefile.win b/Makefile.win index 71036ccf47..27cdb3cc11 100644 --- a/Makefile.win +++ b/Makefile.win @@ -44,7 +44,8 @@ JOBJ := conf/config_file.o \ compat/compat.o \ file_path.o \ tools/input_common_joyconfig.o \ - input/dinput.o + input/dinput.o \ + input/winxinput_joypad.o CC = gcc CXX = g++ @@ -63,6 +64,8 @@ HAVE_THREADS = 1 HAVE_RGUI = 1 DYNAMIC = 1 +HAVE_WINXINPUT = 1 + ifeq ($(SLIM),) HAVE_SDL = 1 HAVE_SDL_IMAGE = 1 @@ -212,6 +215,11 @@ ifeq ($(HAVE_PYTHON), 1) OBJ += gfx/py_state/py_state.o endif +ifeq ($(HAVE_WINXINPUT), 1) + DEFINES += -DHAVE_WINXINPUT + OBJ += input/winxinput_joypad.o +endif + ifeq ($(HAVE_DINPUT), 1) LIBS += -ldinput8 -ldxguid -lole32 DEFINES += -DHAVE_DINPUT diff --git a/frontend/frontend_context.c b/frontend/frontend_context.c index 24fa1dd161..3072732b4c 100644 --- a/frontend/frontend_context.c +++ b/frontend/frontend_context.c @@ -36,11 +36,12 @@ static const frontend_ctx_driver_t *frontend_ctx_drivers[] = { #if defined(IOS) || defined(OSX) &frontend_ctx_apple, #endif + NULL // zero length array is not valid }; const frontend_ctx_driver_t *frontend_ctx_find_driver(const char *ident) { - for (unsigned i = 0; i < sizeof(frontend_ctx_drivers) / sizeof(frontend_ctx_drivers[0]); i++) + for (unsigned i = 0; frontend_ctx_drivers[i]; i++) { if (strcmp(frontend_ctx_drivers[i]->ident, ident) == 0) return frontend_ctx_drivers[i]; @@ -51,7 +52,7 @@ const frontend_ctx_driver_t *frontend_ctx_find_driver(const char *ident) const frontend_ctx_driver_t *frontend_ctx_init_first(void) { - for (unsigned i = 0; i < sizeof(frontend_ctx_drivers) / sizeof(frontend_ctx_drivers[0]); i++) + for (unsigned i = 0; frontend_ctx_drivers[i]; i++) return frontend_ctx_drivers[i]; return NULL; diff --git a/input/dinput.c b/input/dinput.c index 024f323ba9..972772da75 100644 --- a/input/dinput.c +++ b/input/dinput.c @@ -68,12 +68,6 @@ static bool dinput_init_context(void) if (g_ctx) return true; - if (driver.display_type != RARCH_DISPLAY_WIN32) - { - RARCH_ERR("Cannot open DInput as no Win32 window is present.\n"); - return false; - } - CoInitialize(NULL); // Who said we shouldn't have same call signature in a COM API? <_< @@ -386,6 +380,36 @@ static BOOL CALLBACK enum_axes_cb(const DIDEVICEOBJECTINSTANCE *inst, void *p) return DIENUM_CONTINUE; } +static const char* const XBOX_PAD_NAMES[] = +{ + "Controller (Gamepad for Xbox 360)", + "Controller (XBOX 360 For Windows)", + "Controller (Xbox 360 Wireless Receiver for Windows)", + "Controller (Xbox wireless receiver for windows)", + "XBOX 360 For Windows (Controller)", + "Xbox 360 Wireless Receiver", + "Xbox Receiver for Windows (Wireless Controller)", + "Xbox wireless receiver for windows (Controller)", + NULL +}; + +static bool name_is_360_pad(const char* name) +{ + for (unsigned i = 0; ; ++i) + { + const char* t = XBOX_PAD_NAMES[i]; + if (t == NULL) + return false; + else if (lstrcmpi(name, t) == 0) + return true; + } +} + +// Keep track of which pad indexes are 360 controllers +// not static, will be read in winxinput_joypad.c +// -1 = not xbox pad, otherwise 0..3 +int g_xbox_pad_indexes[MAX_PLAYERS]; + static BOOL CALLBACK enum_joypad_cb(const DIDEVICEINSTANCE *inst, void *p) { (void)p; @@ -399,7 +423,18 @@ static BOOL CALLBACK enum_joypad_cb(const DIDEVICEINSTANCE *inst, void *p) #else if (FAILED(IDirectInput8_CreateDevice(g_ctx, &inst->guidInstance, pad, NULL))) #endif - return DIENUM_CONTINUE; + return DIENUM_CONTINUE; + +#ifdef HAVE_WINXINPUT + int last_xbox_pad_index = 0; + + if (name_is_360_pad(inst->tszProductName)) + { + if (last_xbox_pad_index < 4) + g_xbox_pad_indexes[g_joypad_cnt] = last_xbox_pad_index; + ++last_xbox_pad_index; + } +#endif IDirectInputDevice8_SetDataFormat(*pad, &c_dfDIJoystick2); IDirectInputDevice8_SetCooperativeLevel(*pad, (HWND)driver.video_window, @@ -417,6 +452,9 @@ static bool dinput_joypad_init(void) { if (!dinput_init_context()) return false; + + for (unsigned i = 0; i < MAX_PLAYERS; ++i) + g_xbox_pad_indexes[i] = -1; RARCH_LOG("Enumerating DInput joypads ...\n"); IDirectInput8_EnumDevices(g_ctx, DI8DEVCLASS_GAMECTRL, diff --git a/input/input_common.c b/input/input_common.c index 12be6eaf76..fb799e3884 100644 --- a/input/input_common.c +++ b/input/input_common.c @@ -41,6 +41,9 @@ static const rarch_joypad_driver_t *joypad_drivers[] = { #ifndef IS_RETROLAUNCH +#ifdef HAVE_WINXINPUT + &winxinput_joypad, +#endif #ifdef HAVE_DINPUT &dinput_joypad, #endif diff --git a/input/input_common.h b/input/input_common.h index 2ce912e98a..dc118ff4e1 100644 --- a/input/input_common.h +++ b/input/input_common.h @@ -93,6 +93,7 @@ const char *input_joypad_name(const rarch_joypad_driver_t *driver, unsigned joyp extern const rarch_joypad_driver_t dinput_joypad; extern const rarch_joypad_driver_t linuxraw_joypad; +extern const rarch_joypad_driver_t winxinput_joypad; // Named as such to avoid confusion with xb1/360 port code extern const rarch_joypad_driver_t sdl_joypad; diff --git a/input/winxinput_joypad.c b/input/winxinput_joypad.c new file mode 100644 index 0000000000..00ab50c60b --- /dev/null +++ b/input/winxinput_joypad.c @@ -0,0 +1,351 @@ +/* RetroArch - A frontend for libretro. + * Copyright (C) 2013 - pinumbernumber + * + * RetroArch is free software: you can redistribute it and/or modify it under the terms + * of the GNU General Public License as published by the Free Software Found- + * ation, either version 3 of the License, or (at your option) any later version. + * + * RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + * PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with RetroArch. + * If not, see . + */ + +// Support 360 controllers on Windows. +// Said controllers do show under DInput but they have limitations in this mode; +// The triggers are combined rather than seperate and it is not possible to use +// the guide button. + +// Some wrappers for other controllers also simulate xinput (as it is easier to implement) +// so this may be useful for those also. +#include "input_common.h" + +#include "../general.h" +#include "../boolean.h" + +#include +#include +#include + +// Check the definitions do not already exist. +// Official and mingw xinput headers have different include guards +#if ((!_XINPUT_H_) && (!__WINE_XINPUT_H)) + +#define XINPUT_GAMEPAD_DPAD_UP 0x0001 +#define XINPUT_GAMEPAD_DPAD_DOWN 0x0002 +#define XINPUT_GAMEPAD_DPAD_LEFT 0x0004 +#define XINPUT_GAMEPAD_DPAD_RIGHT 0x0008 +#define XINPUT_GAMEPAD_START 0x0010 +#define XINPUT_GAMEPAD_BACK 0x0020 +#define XINPUT_GAMEPAD_LEFT_THUMB 0x0040 +#define XINPUT_GAMEPAD_RIGHT_THUMB 0x0080 +#define XINPUT_GAMEPAD_LEFT_SHOULDER 0x0100 +#define XINPUT_GAMEPAD_RIGHT_SHOULDER 0x0200 +#define XINPUT_GAMEPAD_A 0x1000 +#define XINPUT_GAMEPAD_B 0x2000 +#define XINPUT_GAMEPAD_X 0x4000 +#define XINPUT_GAMEPAD_Y 0x8000 + +typedef struct +{ + uint16_t wButtons; + uint8_t bLeftTrigger; + uint8_t bRightTrigger; + int16_t sThumbLX; + int16_t sThumbLY; + int16_t sThumbRX; + int16_t sThumbRY; +} XINPUT_GAMEPAD; + +typedef struct +{ + uint32_t dwPacketNumber; + XINPUT_GAMEPAD Gamepad; +} XINPUT_STATE; + +#endif + +// Guide constant is not officially documented +#define XINPUT_GAMEPAD_GUIDE 0x0400 + +#ifndef ERROR_DEVICE_NOT_CONNECTED +#define ERROR_DEVICE_NOT_CONNECTED 1167 +#endif + +#ifndef HAVE_DINPUT +#error Cannot compile xinput without dinput. +#endif + +// Due to 360 pads showing up under both XI and DI, and since we are going +// to have to pass through unhandled joypad numbers to DI, a slightly ugly +// hack is required here. dinput_joypad_init will fill this. +// For each pad index, the appropriate entry will be set to -1 if it is not +// a 360 pad, or the correct XInput player number (0..3 inclusive) if it is. +extern int g_xbox_pad_indexes[MAX_PLAYERS]; + +// For xinput1_3.dll +static HINSTANCE g_winxinput_dll; + +// Function pointer, to be assigned with GetProcAddress +typedef uint32_t (__stdcall *XInputGetStateEx_t)(uint32_t, XINPUT_STATE*); +static XInputGetStateEx_t g_XInputGetStateEx; + +// Guide button may or may not be available +static bool g_winxinput_guide_button_supported; + +typedef struct +{ + XINPUT_STATE xstate; + bool connected; +} winxinput_joypad_state; + +static winxinput_joypad_state g_winxinput_states[4]; + +static int pad_index_to_xplayer_index(unsigned pad) +{ + return g_xbox_pad_indexes[pad]; +} + +static bool winxinput_joypad_init(void) +{ + g_winxinput_dll = NULL; + + // Find the correct path to load the DLL from. + // Usually this will be from the system directory, + // but occasionally a user may wish to use a third-party + // wrapper DLL (such as x360ce); support these by checking + // the working directory first. + + // No need to check for existance as we will be checking LoadLibrary's + // success anyway. + const char* DLL_NAME = "xinput1_3.dll"; + g_winxinput_dll = LoadLibrary(DLL_NAME); // Using dylib_* complicates building joyconfig. + if (!g_winxinput_dll) + { + // Loading from working dir failed, try to load from system. + char dll_path[MAX_PATH]; + GetSystemDirectory(dll_path, sizeof(dll_path)); + strlcat(dll_path, "\\", 1); + strlcat(dll_path, DLL_NAME, sizeof(DLL_NAME)); + g_winxinput_dll = LoadLibrary(dll_path); + + if (!g_winxinput_dll) + { + RARCH_ERR("Failed to load xinput1_3.dll, ensure DirectX and controller drivers are up to date.\n"); + return false; // DLL does not exist or is invalid + } + + } + + // If we get here then an xinput DLL is correctly loaded. + // First try to load ordinal 100 (XInputGetStateEx). + g_XInputGetStateEx = (XInputGetStateEx_t) GetProcAddress(g_winxinput_dll, (const char*)100); + g_winxinput_guide_button_supported = true; + + if (!g_XInputGetStateEx) + { + // no ordinal 100. (old version of x360ce perhaps?) Load the ordinary XInputGetState, + // at the cost of losing guide button support. + g_winxinput_guide_button_supported = false; + g_XInputGetStateEx = (XInputGetStateEx_t) GetProcAddress(g_winxinput_dll, "XInputGetState"); + if (!g_XInputGetStateEx) + { + RARCH_ERR("Failed to init XInput: xinput1_3.dll is invalid or corrupt.\n"); + return false; // DLL was loaded but did not contain the correct function. + } + RARCH_WARN("XInput: No guide button support.\n"); + } + + // zero out the states + for (unsigned i = 0; i < 4; ++i) + memset(&g_winxinput_states[i], 0, sizeof(winxinput_joypad_state)); + + // Do a dummy poll to check which controllers are connected. + XINPUT_STATE dummy_state; + for (unsigned i = 0; i < 4; ++i) + { + g_winxinput_states[i].connected = !(g_XInputGetStateEx(i, &dummy_state) == ERROR_DEVICE_NOT_CONNECTED); + if (g_winxinput_states[i].connected) + RARCH_LOG("Found XInput controller, player #%u\n", i); + } + + if ((!g_winxinput_states[0].connected) && + (!g_winxinput_states[1].connected) && + (!g_winxinput_states[2].connected) && + (!g_winxinput_states[3].connected)) + return false; + + // We're going to have to be buddies with dinput if we want to be able + // to use XI and non-XI controllers together. + return dinput_joypad.init(); +} + +static bool winxinput_joypad_query_pad(unsigned pad) +{ + int xplayer = pad_index_to_xplayer_index(pad); + if (xplayer > -1) + return g_winxinput_states[0].connected; + else + return dinput_joypad.query_pad(pad); +} + +static void winxinput_joypad_destroy(void) +{ + for (unsigned i = 0; i < 4; ++i) + memset(&g_winxinput_states[i], 0, sizeof(winxinput_joypad_state)); + + FreeLibrary(g_winxinput_dll); + g_winxinput_dll = NULL; + g_XInputGetStateEx = NULL; + + dinput_joypad.destroy(); +} + +// Buttons are provided by XInput as bits of a uint16. +// Map from rarch button index (0..10) to a mask to bitwise-& the buttons against. +// dpad is handled seperately. +static const uint16_t button_index_to_bitmap_code[] = { + XINPUT_GAMEPAD_A, + XINPUT_GAMEPAD_B, + XINPUT_GAMEPAD_X, + XINPUT_GAMEPAD_Y, + XINPUT_GAMEPAD_LEFT_SHOULDER, + XINPUT_GAMEPAD_RIGHT_SHOULDER, + XINPUT_GAMEPAD_START, + XINPUT_GAMEPAD_BACK, + XINPUT_GAMEPAD_LEFT_THUMB, + XINPUT_GAMEPAD_RIGHT_THUMB, + XINPUT_GAMEPAD_GUIDE +}; + +static bool winxinput_joypad_button (unsigned port_num, uint16_t joykey) +{ + if (joykey == NO_BTN) + return false; + + int xplayer = pad_index_to_xplayer_index(port_num); + if (xplayer == -1) + return dinput_joypad.button(port_num, joykey); + + if (!(g_winxinput_states[xplayer].connected)) + return false; + + uint16_t btn_word = g_winxinput_states[xplayer].xstate.Gamepad.wButtons; + + if (GET_HAT_DIR(joykey)) + { + switch (GET_HAT_DIR(joykey)) + { + case HAT_UP_MASK: return btn_word & XINPUT_GAMEPAD_DPAD_UP; + case HAT_DOWN_MASK: return btn_word & XINPUT_GAMEPAD_DPAD_DOWN; + case HAT_LEFT_MASK: return btn_word & XINPUT_GAMEPAD_DPAD_LEFT; + case HAT_RIGHT_MASK: return btn_word & XINPUT_GAMEPAD_DPAD_RIGHT; + } + return false; // hat requested and no hat button down + } + else + { + // non-hat button + unsigned num_buttons = g_winxinput_guide_button_supported ? 11 : 10; + + if (joykey < num_buttons) + return btn_word & button_index_to_bitmap_code[joykey]; + } + return false; +} + +static int16_t winxinput_joypad_axis (unsigned port_num, uint32_t joyaxis) +{ + if (joyaxis == AXIS_NONE) + return 0; + + int xplayer = pad_index_to_xplayer_index(port_num); + + if (xplayer == -1) + return dinput_joypad.axis(port_num, joyaxis); + + if (!(g_winxinput_states[xplayer].connected)) + return false; + + int16_t val = 0; + int axis = -1; + + bool is_neg = false; + bool is_pos = false; + + if (AXIS_NEG_GET(joyaxis) <= 3) // triggers (axes 4,5) cannot be negative + { + axis = AXIS_NEG_GET(joyaxis); + is_neg = true; + } + else if (AXIS_POS_GET(joyaxis) <= 5) + { + axis = AXIS_POS_GET(joyaxis); + is_pos = true; + } + + XINPUT_GAMEPAD* pad = &(g_winxinput_states[xplayer].xstate.Gamepad); + + switch (axis) + { + case 0: val = pad->sThumbLX; break; + case 1: val = pad->sThumbLY; break; + case 2: val = pad->sThumbRX; break; + case 3: val = pad->sThumbRY; break; + + case 4: val = pad->bLeftTrigger * 32767 / 255; break; // map 0..255 to 0..32767 + case 5: val = pad->bRightTrigger * 32767 / 255; break; + } + + if (is_neg && val > 0) + val = 0; + else if (is_pos && val < 0) + val = 0; + + // Clamp to avoid overflow error + if (val == -32768) + val = -32767; + + return val; +} + +static void winxinput_joypad_poll(void) +{ + for (unsigned i = 0; i < 4; ++i) + if (g_XInputGetStateEx(i, &(g_winxinput_states[i].xstate)) == ERROR_DEVICE_NOT_CONNECTED) + g_winxinput_states[i].connected = false; + + dinput_joypad.poll(); +} + +static const char* const XBOX_CONTROLLER_NAMES[4] = +{ + "Xbox 360 Controller (Player 1)", + "Xbox 360 Controller (Player 2)", + "Xbox 360 Controller (Player 3)", + "Xbox 360 Controller (Player 4)" +}; + +const char* winxinput_joypad_name (unsigned pad) +{ + int xplayer = pad_index_to_xplayer_index(pad); + + if (xplayer < 0) + return dinput_joypad.name(pad); + else + // TODO: Different name if disconnected? + return XBOX_CONTROLLER_NAMES[xplayer]; +} + +const rarch_joypad_driver_t winxinput_joypad = { + winxinput_joypad_init, + winxinput_joypad_query_pad, + winxinput_joypad_destroy, + winxinput_joypad_button, + winxinput_joypad_axis, + winxinput_joypad_poll, + winxinput_joypad_name, + "winxinput", +}; diff --git a/msvc/msvc-2010/RetroArch-msvc2010.sln b/msvc/msvc-2010/RetroArch-msvc2010.sln new file mode 100644 index 0000000000..6bb4b9c199 --- /dev/null +++ b/msvc/msvc-2010/RetroArch-msvc2010.sln @@ -0,0 +1,20 @@ + +Microsoft Visual Studio Solution File, Format Version 11.00 +# Visual C++ Express 2010 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "RetroArch-msvc2010", "RetroArch-msvc2010.vcxproj", "{27FF7CE1-4059-4AA1-8062-FD529560FA54}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Release|Win32 = Release|Win32 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {27FF7CE1-4059-4AA1-8062-FD529560FA54}.Debug|Win32.ActiveCfg = Debug|Win32 + {27FF7CE1-4059-4AA1-8062-FD529560FA54}.Debug|Win32.Build.0 = Debug|Win32 + {27FF7CE1-4059-4AA1-8062-FD529560FA54}.Release|Win32.ActiveCfg = Release|Win32 + {27FF7CE1-4059-4AA1-8062-FD529560FA54}.Release|Win32.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/msvc/msvc-2010/RetroArch-msvc2010.vcxproj b/msvc/msvc-2010/RetroArch-msvc2010.vcxproj index 17c46dec6d..45bbb6b6cd 100644 --- a/msvc/msvc-2010/RetroArch-msvc2010.vcxproj +++ b/msvc/msvc-2010/RetroArch-msvc2010.vcxproj @@ -88,7 +88,7 @@ Level3 Disabled - WIN32;HAVE_WIN32_D3D9;HAVE_CG;HAVE_GLSL;HAVE_FBO;HAVE_ZLIB;WANT_MINIZ;_DEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_SCREENSHOTS;HAVE_BSV_MOVIE;HAVE_DINPUT;HAVE_XAUDIO;HAVE_DSOUND;HAVE_OPENGL;HAVE_DYLIB;HAVE_NETPLAY;HAVE_NETWORK_CMD;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;_CRT_SECURE_NO_WARNINGS;__SSE__;__i686__;HAVE_OVERLAY;HAVE_RGUI;HAVE_GL_SYNC + WIN32;HAVE_WIN32_D3D9;HAVE_CG;HAVE_GLSL;HAVE_FBO;HAVE_ZLIB;WANT_MINIZ;_DEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_SCREENSHOTS;HAVE_BSV_MOVIE;HAVE_DINPUT;HAVE_WINXINPUT;HAVE_XAUDIO;HAVE_DSOUND;HAVE_OPENGL;HAVE_DYLIB;HAVE_NETPLAY;HAVE_NETWORK_CMD;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;_CRT_SECURE_NO_WARNINGS;__SSE__;__i686__;HAVE_OVERLAY;HAVE_RGUI;HAVE_GL_SYNC $(MSBuildProjectDirectory);$(MSBuildProjectDirectory)\..\..\;$(CG_INC_PATH);%(AdditionalIncludeDirectories) MultiThreadedDebug CompileAsCpp @@ -108,7 +108,7 @@ Level3 Disabled - WIN32;HAVE_WIN32_D3D9;HAVE_CG;HAVE_GLSL;HAVE_FBO;HAVE_ZLIB;WANT_MINIZ;_DEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_SCREENSHOTS;HAVE_BSV_MOVIE;HAVE_DINPUT;HAVE_XAUDIO;HAVE_DSOUND;HAVE_OPENGL;HAVE_DYLIB;HAVE_NETPLAY;HAVE_NETWORK_CMD;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;_CRT_SECURE_NO_WARNINGS;__SSE__;__SSE2__;__x86_64__;HAVE_OVERLAY;HAVE_RGUI;HAVE_GL_SYNC + WIN32;HAVE_WIN32_D3D9;HAVE_CG;HAVE_GLSL;HAVE_FBO;HAVE_ZLIB;WANT_MINIZ;_DEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_SCREENSHOTS;HAVE_BSV_MOVIE;HAVE_DINPUT;HAVE_WINXINPUT;HAVE_XAUDIO;HAVE_DSOUND;HAVE_OPENGL;HAVE_DYLIB;HAVE_NETPLAY;HAVE_NETWORK_CMD;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;_CRT_SECURE_NO_WARNINGS;__SSE__;__SSE2__;__x86_64__;HAVE_OVERLAY;HAVE_RGUI;HAVE_GL_SYNC $(MSBuildProjectDirectory);$(MSBuildProjectDirectory)\..\..\;$(CG_INC_PATH);%(AdditionalIncludeDirectories) MultiThreadedDebug CompileAsCpp @@ -130,7 +130,7 @@ MaxSpeed true true - WIN32;HAVE_WIN32_D3D9;HAVE_CG;HAVE_GLSL;HAVE_FBO;HAVE_ZLIB;WANT_MINIZ;NDEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_SCREENSHOTS;HAVE_BSV_MOVIE;HAVE_DINPUT;HAVE_XAUDIO;HAVE_DSOUND;HAVE_OPENGL;HAVE_DYLIB;HAVE_NETPLAY;HAVE_NETWORK_CMD;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;_CRT_SECURE_NO_WARNINGS;__SSE__;__i686__;HAVE_OVERLAY;HAVE_RGUI;HAVE_GL_SYNC + WIN32;HAVE_WIN32_D3D9;HAVE_CG;HAVE_GLSL;HAVE_FBO;HAVE_ZLIB;WANT_MINIZ;NDEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_SCREENSHOTS;HAVE_BSV_MOVIE;HAVE_DINPUT;HAVE_WINXINPUT;HAVE_XAUDIO;HAVE_DSOUND;HAVE_OPENGL;HAVE_DYLIB;HAVE_NETPLAY;HAVE_NETWORK_CMD;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;_CRT_SECURE_NO_WARNINGS;__SSE__;__i686__;HAVE_OVERLAY;HAVE_RGUI;HAVE_GL_SYNC $(MSBuildProjectDirectory);$(MSBuildProjectDirectory)\..\..\;$(CG_INC_PATH);%(AdditionalIncludeDirectories) MultiThreaded CompileAsCpp @@ -154,7 +154,7 @@ MaxSpeed true true - WIN32;HAVE_WIN32_D3D9;HAVE_CG;HAVE_GLSL;HAVE_FBO;NDEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_SCREENSHOTS;HAVE_BSV_MOVIE;HAVE_DINPUT;HAVE_XAUDIO;HAVE_DSOUND;HAVE_OPENGL;HAVE_DYLIB;HAVE_NETPLAY;HAVE_NETWORK_CMD;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;HAVE_ZLIB;WANT_MINIZ;_CRT_SECURE_NO_WARNINGS;__SSE__;__SSE2__;__x86_64__;HAVE_OVERLAY;HAVE_RGUI;HAVE_GL_SYNC + WIN32;HAVE_WIN32_D3D9;HAVE_CG;HAVE_GLSL;HAVE_FBO;NDEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_SCREENSHOTS;HAVE_BSV_MOVIE;HAVE_DINPUT;HAVE_WINXINPUT;HAVE_XAUDIO;HAVE_DSOUND;HAVE_OPENGL;HAVE_DYLIB;HAVE_NETPLAY;HAVE_NETWORK_CMD;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;HAVE_ZLIB;WANT_MINIZ;_CRT_SECURE_NO_WARNINGS;__SSE__;__SSE2__;__x86_64__;HAVE_OVERLAY;HAVE_RGUI;HAVE_GL_SYNC $(MSBuildProjectDirectory);$(MSBuildProjectDirectory)\..\..\;$(CG_INC_PATH);%(AdditionalIncludeDirectories) MultiThreaded CompileAsCpp @@ -250,6 +250,8 @@ + +