From 4f6954ae11aa77f7b5025f3e4a7411dda27ceef1 Mon Sep 17 00:00:00 2001 From: cxgeorge <> Date: Sat, 10 Aug 2002 02:36:54 +0000 Subject: [PATCH] add rudimentary dinput support --- panda/src/wdxdisplay8/Sources.pp | 25 +- panda/src/wdxdisplay8/config_wdxdisplay8.cxx | 2 + panda/src/wdxdisplay8/config_wdxdisplay8.h | 3 +- panda/src/wdxdisplay8/dxInput8.cxx | 276 ++++++++++++++++++ panda/src/wdxdisplay8/dxInput8.h | 45 +++ panda/src/wdxdisplay8/wdxGraphicsPipe8.h | 2 +- panda/src/wdxdisplay8/wdxGraphicsWindow8.cxx | 76 ++++- panda/src/wdxdisplay8/wdxGraphicsWindow8.h | 1 + .../wdxdisplay8/wdxdisplay8_composite1.cxx | 1 + 9 files changed, 407 insertions(+), 24 deletions(-) create mode 100644 panda/src/wdxdisplay8/dxInput8.cxx create mode 100644 panda/src/wdxdisplay8/dxInput8.h diff --git a/panda/src/wdxdisplay8/Sources.pp b/panda/src/wdxdisplay8/Sources.pp index e83fcd04e1..98d4d11901 100644 --- a/panda/src/wdxdisplay8/Sources.pp +++ b/panda/src/wdxdisplay8/Sources.pp @@ -2,26 +2,27 @@ #define OTHER_LIBS interrogatedb:c dconfig:c dtoolconfig:m \ dtoolutil:c dtoolbase:c dtool:m -#define WIN_SYS_LIBS Imm32.lib +#define WIN_SYS_LIBS Imm32.lib dinput8.lib #define USE_PACKAGES dx #begin lib_target #define TARGET wdxdisplay8 #define LOCAL_LIBS dxgsg8 - - #define COMBINED_SOURCES $[TARGET]_composite1.cxx - - // need to install these due to external projects that link directly with libpandadx (bartop) + + #define COMBINED_SOURCES $[TARGET]_composite1.cxx + + // need to install these due to external projects that link directly with libpandadx (bartop) #define INSTALL_HEADERS \ - config_wdxdisplay8.h wdxGraphicsPipe8.h wdxGraphicsWindow8.h - + config_wdxdisplay8.h wdxGraphicsPipe8.h wdxGraphicsWindow8.h dxInput8.h + + #define INCLUDED_SOURCES \ - config_wdxdisplay8.cxx wdxGraphicsPipe8.cxx - - // note SOURCES shoult NOT include INCLUDED_SOURCES, that would cause a double build + config_wdxdisplay8.cxx wdxGraphicsPipe8.cxx dxInput8.cxx + + // note SOURCES should NOT include INCLUDED_SOURCES, that would cause a double build // SOURCES should be headers and separately-built cxx files // build wdxGraphicsWindow.cxx separately since its big - + #define SOURCES wdxGraphicsWindow8.cxx $[INSTALL_HEADERS] - + #end lib_target diff --git a/panda/src/wdxdisplay8/config_wdxdisplay8.cxx b/panda/src/wdxdisplay8/config_wdxdisplay8.cxx index 4aa0d55160..ee4068194e 100644 --- a/panda/src/wdxdisplay8/config_wdxdisplay8.cxx +++ b/panda/src/wdxdisplay8/config_wdxdisplay8.cxx @@ -48,6 +48,8 @@ bool dx_pick_best_screenres = config_wdxdisplay.GetBool("pick-best-screenres", f // this config variable with an actual OS detection. bool ime_composition_w = config_wdxdisplay.GetBool("ime-composition-w", true); +bool dx_use_joystick = config_wdxdisplay.GetBool("use-joystick", false); + extern void AtExitFn(void); //////////////////////////////////////////////////////////////////// diff --git a/panda/src/wdxdisplay8/config_wdxdisplay8.h b/panda/src/wdxdisplay8/config_wdxdisplay8.h index 3292e74897..89b0cb95c7 100644 --- a/panda/src/wdxdisplay8/config_wdxdisplay8.h +++ b/panda/src/wdxdisplay8/config_wdxdisplay8.h @@ -29,12 +29,13 @@ extern bool bResponsive_minimized_fullscreen_window; extern bool dx_force_16bpp_zbuffer; extern bool dx_preserve_fpu_state; extern bool dx_do_vidmemsize_check; -extern bool dx_pick_best_screenres; extern int dx_preferred_deviceID; +extern bool dx_pick_best_screenres; extern Filename get_icon_filename(); extern Filename get_mono_cursor_filename(); extern Filename get_color_cursor_filename(); extern bool ime_composition_w; +extern bool dx_use_joystick; extern EXPCL_PANDADX void init_libwdxdisplay8(); diff --git a/panda/src/wdxdisplay8/dxInput8.cxx b/panda/src/wdxdisplay8/dxInput8.cxx new file mode 100644 index 0000000000..a6d4ac5b0d --- /dev/null +++ b/panda/src/wdxdisplay8/dxInput8.cxx @@ -0,0 +1,276 @@ +// Filename: dxInput8.cxx +// Created by: angelina jolie (07Oct99) +// +//////////////////////////////////////////////////////////////////// +// +// PANDA 3D SOFTWARE +// Copyright (c) 2001, Disney Enterprises, Inc. All rights reserved +// +// All use of this software is subject to the terms of the Panda 3d +// Software license. You should have received a copy of this license +// along with this source code; you will also find a current copy of +// the license at http://www.panda3d.org/license.txt . +// +// To contact the maintainers of this program write to +// panda3d@yahoogroups.com . +// +//////////////////////////////////////////////////////////////////// + +#include "config_wdxdisplay8.h" +#include + +#define AXIS_RESOLUTION 2000 // use this many levels of resolution by default (could be more if needed and device supported it) +#define AXIS_RANGE_CENTERED // if defined, axis range is centered on 0, instead of starting on 0 + +BOOL CALLBACK EnumGameCtrlsCallback( const DIDEVICEINSTANCE* pdidInstance, + VOID* pContext ) { + DI_DeviceInfos *pDevInfos = (DI_DeviceInfos *)pContext; + + (*pDevInfos).push_back(*pdidInstance); + + if(wdxdisplay_cat.is_debug()) + wdxdisplay_cat.debug() << "Found DevType 0x" << (void*)pdidInstance->dwDevType << ": " << pdidInstance->tszInstanceName << ": " << pdidInstance->tszProductName <Unacquire(); + SAFE_RELEASE(_DeviceList[i]); + } + + // bugbug: need to handle this + // if(_JoystickPollTimer!=NULL) + // KillTimer(...) + + SAFE_RELEASE(_pDInput8); + if(_hDInputDLL) { + FreeLibrary(_hDInputDLL); + _hDInputDLL=NULL; + } +} + +bool DInput8Info::InitDirectInput(void) { + HRESULT hr; + + // assumes dx8 exists + // use dynamic load so non-dinput programs dont have to load dinput + #define DLLNAME "dinput8.dll" + #define DINPUTCREATE "DirectInput8Create" + + HINSTANCE _hDInputDLL = LoadLibrary(DLLNAME); + if(_hDInputDLL == 0) { + wdxdisplay_cat.fatal() << "LoadLibrary(" << DLLNAME <<") failed!, error=" << GetLastError() << endl; + exit(1); + } + + typedef HRESULT (WINAPI * LPDIRECTINPUT8CREATE)(HINSTANCE hinst, DWORD dwVersion, REFIID riidltf, LPVOID *ppvOut, LPUNKNOWN punkOuter); + LPDIRECTINPUT8CREATE pDInputCreate8; + + pDInputCreate8 = (LPDIRECTINPUT8CREATE) GetProcAddress(_hDInputDLL,DINPUTCREATE); + if(pDInputCreate8 == NULL) { + wdxdisplay_cat.fatal() << "GetProcAddr failed for " << DINPUTCREATE << endl; + exit(1); + } + + // Register with the DirectInput subsystem and get a pointer + // to a IDirectInput interface we can use. + // Create a DInput object + if( FAILED( hr = (*pDInputCreate8)(GetModuleHandle(NULL), DIRECTINPUT_VERSION, + IID_IDirectInput8, (VOID**)&_pDInput8, NULL ) ) ) { + wdxdisplay_cat.error() << DINPUTCREATE << "failed" << D3DERRORSTRING(hr); + return false; + } + + // enum all the joysticks,etc (but not keybd/mouse) + if( FAILED( hr = _pDInput8->EnumDevices(DI8DEVCLASS_GAMECTRL, + EnumGameCtrlsCallback, + (LPVOID)&_DevInfos, DIEDFL_ATTACHEDONLY ) ) ) { + wdxdisplay_cat.error() << "EnumDevices failed" << D3DERRORSTRING(hr); + return false; + } + + return true; +} + +bool DInput8Info::CreateJoystickOrPad(HWND hWnd) { + bool bFoundDev = false; + UINT devnum=0; + char *errstr=NULL; + + // look through the list for the first joystick or gamepad + for(;devnum<_DevInfos.size();devnum++) { + DWORD devType = GET_DIDEVICE_TYPE(_DevInfos[devnum].dwDevType); + if((devType==DI8DEVTYPE_GAMEPAD) ||(devType==DI8DEVTYPE_JOYSTICK)) { + bFoundDev=true; + break; + } + } + + if(!bFoundDev) { + wdxdisplay_cat.error() << "Cant find an attached Joystick or GamePad!\n"; + return false; + } + + LPDIRECTINPUTDEVICE8 pJoyDevice; + + // Obtain an interface to the enumerated joystick. + HRESULT hr = _pDInput8->CreateDevice(_DevInfos[devnum].guidInstance, &pJoyDevice, NULL ); + if(FAILED(hr)) { + errstr="CreateDevice"; + goto handle_error; + } + + assert(pJoyDevice!=NULL); + _DeviceList.push_back(pJoyDevice); + + // Set the data format to "simple joystick" - a predefined data format + // + // A data format specifies which controls on a device we are interested in, + // and how they should be reported. This tells DInput that we will be + // passing a DIJOYSTATE2 structure to IDirectInputDevice::GetDeviceState(). + hr = pJoyDevice->SetDataFormat(&c_dfDIJoystick2); + if(FAILED(hr)) { + errstr="SetDataFormat"; + goto handle_error; + } + + // must be called AFTER SetDataFormat to get all the proper flags + DX_DECLARE_CLEAN(DIDEVCAPS, DIDevCaps); + hr = pJoyDevice->GetCapabilities(&DIDevCaps); + assert(SUCCEEDED(hr)); + + _DevCaps.push_back(DIDevCaps); + + if(wdxdisplay_cat.is_debug()) + wdxdisplay_cat.debug() << "Joy/Pad has " << DIDevCaps.dwAxes << " Axes, " << DIDevCaps.dwButtons << " Buttons, " << DIDevCaps.dwPOVs << " POVs" << endl; + + // Set the cooperative level to let DInput know how this device should + // interact with the system and with other DInput applications. + hr = pJoyDevice->SetCooperativeLevel( hWnd, DISCL_EXCLUSIVE | DISCL_FOREGROUND); + if(FAILED(hr)) { + errstr="SetCooperativeLevel"; + goto handle_error; + } + + // set the min/max values property for discovered axes. + hr = pJoyDevice->EnumObjects(EnumObjectsCallbackJoystick, (LPVOID)pJoyDevice, DIDFT_AXIS); + if(FAILED(hr)) { + errstr="EnumObjects"; + goto handle_error; + } + + return true; + + handle_error: + wdxdisplay_cat.error() << errstr << " failed for (" << _DevInfos[devnum].tszInstanceName << ":" << _DevInfos[devnum].tszProductName << ")" << D3DERRORSTRING(hr); + return false; +} + +//----------------------------------------------------------------------------- +// Name: EnumObjectsCallback() +// Desc: Callback function for enumerating objects (axes, buttons, POVs) on a +// joystick. This function enables user interface elements for objects +// that are found to exist, and scales axes min/max values. +//----------------------------------------------------------------------------- +BOOL CALLBACK EnumObjectsCallbackJoystick( const DIDEVICEOBJECTINSTANCE* pdidoi, + VOID* pContext ) { + + LPDIRECTINPUTDEVICE8 pJoyDevice = (LPDIRECTINPUTDEVICE8) pContext; + HRESULT hr; + + // For axes that are returned, set the DIPROP_RANGE property for the + // enumerated axis in order to scale min/max values. + if( pdidoi->dwType & DIDFT_AXIS ) { + DIPROPRANGE diprg; + diprg.diph.dwSize = sizeof(DIPROPRANGE); + diprg.diph.dwHeaderSize = sizeof(DIPROPHEADER); + diprg.diph.dwHow = DIPH_BYID; + diprg.diph.dwObj = pdidoi->dwType; // Specify the enumerated axis + + #ifdef AXIS_RANGE_CENTERED + diprg.lMin = -AXIS_RESOLUTION/2; + diprg.lMax = +AXIS_RESOLUTION/2; + #else + diprg.lMin = 0; + diprg.lMax = +AXIS_RESOLUTION; + #endif + + // Set the range for the axis + hr = pJoyDevice->SetProperty( DIPROP_RANGE, &diprg.diph); + if(FAILED(hr)) { + wdxdisplay_cat.error() << "SetProperty on axis failed" << D3DERRORSTRING(hr); + return DIENUM_STOP; + } + } + + return DIENUM_CONTINUE; +} + +bool DInput8Info::ReadJoystick(int devnum, DIJOYSTATE2 &js) { + LPDIRECTINPUTDEVICE8 pJoystick = _DeviceList[devnum]; + assert(pJoystick!=NULL); + HRESULT hr; + char *errstr; + + // Poll the device to read the current state + + hr = pJoystick->Poll(); + + if( FAILED(hr) ) { + // DInput is telling us that the input stream has been + // interrupted. We aren't tracking any state between polls, so + // we don't have any special reset that needs to be done. We + // just re-acquire and try again. + + if((hr==DIERR_NOTACQUIRED)||(hr == DIERR_INPUTLOST)) { + hr = pJoystick->Acquire(); + + if(FAILED(hr)) { + if(wdxdisplay_cat.is_spam()) + wdxdisplay_cat.spam() << "Acquire failed" << D3DERRORSTRING(hr); + + // hr may be DIERR_OTHERAPPHASPRIO or other errors. This + // may occur when the app is minimized or in the process of + // switching, so just try again later + return false; + } + + hr = pJoystick->Poll(); + if(FAILED(hr)) { + // should never happen! + errstr = "Poll after successful Acquire failed"; + goto handle_error; + } + } else { + errstr = "Unknown Poll failure"; + goto handle_error; + } + } + + // should we make a vector of devstate dataformats to generalize this fn for all device types? + + // Get the input's device state + hr = pJoystick->GetDeviceState( sizeof(DIJOYSTATE2), &js); + if(FAILED(hr)) { + errstr = "GetDeviceState failed"; + goto handle_error; + } + + return true; + + handle_error: + wdxdisplay_cat.fatal() << errstr << D3DERRORSTRING(hr); + return false; +} + + diff --git a/panda/src/wdxdisplay8/dxInput8.h b/panda/src/wdxdisplay8/dxInput8.h new file mode 100644 index 0000000000..85b72eb15e --- /dev/null +++ b/panda/src/wdxdisplay8/dxInput8.h @@ -0,0 +1,45 @@ +// Filename: dxInput8.h +// Created by: blllyjo (07Oct99) +// +//////////////////////////////////////////////////////////////////// +// +// PANDA 3D SOFTWARE +// Copyright (c) 2001, Disney Enterprises, Inc. All rights reserved +// +// All use of this software is subject to the terms of the Panda 3d +// Software license. You should have received a copy of this license +// along with this source code; you will also find a current copy of +// the license at http://www.panda3d.org/license.txt . +// +// To contact the maintainers of this program write to +// panda3d@yahoogroups.com . +// +//////////////////////////////////////////////////////////////////// + +#ifndef DXINPUT8_H +#define DXINPUT8_H + +#define DIRECTINPUT_VERSION 0x800 +#include +typedef vector DI_DeviceInfos; +typedef vector DI_DeviceObjInfos; + +class DInput8Info { +public: + DInput8Info(void); + ~DInput8Info(void); + bool InitDirectInput(void); + bool CreateJoystickOrPad(HWND hWnd); + bool ReadJoystick(int devnum, DIJOYSTATE2 &js); + + HINSTANCE _hDInputDLL; + UINT_PTR _JoystickPollTimer; + LPDIRECTINPUT8 _pDInput8; + DI_DeviceInfos _DevInfos; + // arrays for all created devices. Should probably put these together in a struct, + // along with the data fmt info + vector _DeviceList; + vector _DevCaps; +}; + +#endif diff --git a/panda/src/wdxdisplay8/wdxGraphicsPipe8.h b/panda/src/wdxdisplay8/wdxGraphicsPipe8.h index 98473af164..376b13b71f 100644 --- a/panda/src/wdxdisplay8/wdxGraphicsPipe8.h +++ b/panda/src/wdxdisplay8/wdxGraphicsPipe8.h @@ -31,7 +31,7 @@ // Defines //////////////////////////////////////////////////////////////////// -extern char * ConvD3DErrorToString(const HRESULT &error); +// extern char * ConvD3DErrorToString(const HRESULT &error); //////////////////////////////////////////////////////////////////// // Class : wdxGraphicsPipe diff --git a/panda/src/wdxdisplay8/wdxGraphicsWindow8.cxx b/panda/src/wdxdisplay8/wdxGraphicsWindow8.cxx index 6622c06da2..5993a0eb56 100644 --- a/panda/src/wdxdisplay8/wdxGraphicsWindow8.cxx +++ b/panda/src/wdxdisplay8/wdxGraphicsWindow8.cxx @@ -46,6 +46,9 @@ TypeHandle wdxGraphicsWindow::_type_handle; #define WDX_WINDOWCLASSNAME_NOCURSOR WDX_WINDOWCLASSNAME "_NoCursor" #define DEFAULT_CURSOR IDC_ARROW +// define this to enable debug testing of dinput joystick +//#define DINPUT_DEBUG_POLL + typedef map HWND_PANDAWIN_MAP; // CardIDVec is used in DX7 lowmem card-classification pass so DX8 can @@ -67,7 +70,8 @@ wdxGraphicsWindow* global_wdxwinptr = NULL; // need this for temporary windproc #define MAX_DISPLAYS 20 -#define PAUSED_TIMER_ID 7 // completely arbitrary choice +#define PAUSED_TIMER_ID 7 // completely arbitrary choice +#define JOYSTICK_POLL_TIMER_ID 8 #define DX_IS_READY ((_dxgsg!=NULL)&&(_dxgsg->GetDXReady())) LONG WINAPI static_window_proc(HWND hwnd, UINT msg, WPARAM wparam,LPARAM lparam); @@ -828,6 +832,25 @@ window_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) { // do we still need to do this since I return control to app periodically using timer msgs? // does app need to know to avoid major computation? } + + #ifdef DINPUT_DEBUG_POLL + // probably want to get rid of this in favor of event-based input + if(dx_use_joystick && (wparam==_pParentWindowGroup->_pDInputInfo->_JoystickPollTimer)) { + DIJOYSTATE2 js; + ZeroMemory(&js,sizeof(js)); + if(_pParentWindowGroup->_pDInputInfo->ReadJoystick(0,js)) { + // for now just print stuff out to make sure it works + wdxdisplay_cat.debug() << "joyPos (X: " << js.lX << ",Y: " << js.lY << ",Z: " << js.lZ << ")\n"; + for(int i=0;i<128;i++) { + if(js.rgbButtons[i]!=0) + wdxdisplay_cat.debug() << "joyButton "<< i << " pressed\n"; + } + } else { + wdxdisplay_cat.error() << "read of Joystick failed!\n"; + exit(1); + } + } + #endif return 0; case WM_CLOSE: @@ -1032,6 +1055,9 @@ void wdxGraphicsWindow::deactivate_window(void) { wdxdisplay_cat.error() << "Error in SetTimer!\n"; } // } + + + // bugbug: need to handle dinput devices } // currently this should only be called from CheckCoopLvl to return from Alt-tab @@ -2178,7 +2204,7 @@ bool wdxGraphicsWindow::search_for_device(LPDIRECT3D8 pD3D8,DXDeviceInfo *pDevIn } Memlimres; const Memlimres MemRes[] = { - { 0, 640, 480}, + { 0, 640, 480}, { 8000000, 800, 600}, {16000000, 1024, 768}, {32000000, 1280,1024}, // 32MB cards will choose this @@ -2198,15 +2224,15 @@ bool wdxGraphicsWindow::search_for_device(LPDIRECT3D8 pD3D8,DXDeviceInfo *pDevIn &_dxgsg->scrn.SupportedScreenDepthsMask, &bCouldntFindValidZBuf, &pixFmt); - - + + // note I'm not saving refresh rate, will just use adapter default at given res for now - + if(pixFmt==D3DFMT_UNKNOWN) { wdxdisplay_cat.debug() << "skipping scrnres; " << (bCouldntFindValidZBuf ? "Couldnt find valid zbuffer format to go with FullScreen mode" : "No supported FullScreen modes") << " at " << dwRenderWidth << "x" << dwRenderHeight << " for device #" << _dxgsg->scrn.CardIDNum << endl; - } else + } else break; } } @@ -2218,10 +2244,10 @@ bool wdxGraphicsWindow::search_for_device(LPDIRECT3D8 pD3D8,DXDeviceInfo *pDevIn &_dxgsg->scrn.SupportedScreenDepthsMask, &bCouldntFindValidZBuf, &pixFmt); - - + + // note I'm not saving refresh rate, will just use adapter default at given res for now - + if(pixFmt==D3DFMT_UNKNOWN) { wdxdisplay_cat.fatal() << (bCouldntFindValidZBuf ? "Couldnt find valid zbuffer format to go with FullScreen mode" : "No supported FullScreen modes") @@ -2408,7 +2434,7 @@ CreateScreenBuffersAndDevice(DXScreenData &Display) { if(pPresParams->MultiSampleType != D3DMULTISAMPLE_NONE) assert(pPresParams->SwapEffect == D3DSWAPEFFECT_DISCARD); // only valid effect for multisample #endif - + ClearToBlack(Display.hWnd,_props); hr = pD3D8->CreateDevice(Display.CardIDNum, D3DDEVTYPE_HAL, _pParentWindowGroup->_hParentWindow, @@ -3018,6 +3044,8 @@ void wdxGraphicsWindowGroup::initWindowGroup(void) { _hMouseCursor = NULL; _bLoadedCustomCursor = false; + _pDInputInfo = NULL; + // can only get multimon HW acceleration in fullscrn on DX7 UINT numMonitors = GetSystemMetrics(SM_CMONITORS); @@ -3179,6 +3207,32 @@ void wdxGraphicsWindowGroup::initWindowGroup(void) { for(UINT i=0;i_dxgsg->SetDXReady(true); } + + #ifdef DINPUT_DEBUG_POLL + if(dx_use_joystick) { + _pDInputInfo = new DInput8Info; + assert(_pDInputInfo !=NULL); + if(!_pDInputInfo->InitDirectInput()) { + wdxdisplay_cat.error() << "InitDirectInput failed!\n"; + exit(1); + } + + if(!_pDInputInfo->CreateJoystickOrPad(_hParentWindow)) { // associate w/parent window of group for now + wdxdisplay_cat.error() << "CreateJoystickOrPad failed!\n"; + exit(1); + } + + // for now, just set up a WM_TIMER to poll the joystick. + // could configure it to do event-based input, and that is default w/action mapping + // which would be better, less processor intensive + + #define POLL_FREQUENCY_HZ 3 + _pDInputInfo->_JoystickPollTimer = SetTimer(_hParentWindow, JOYSTICK_POLL_TIMER_ID, 1000/POLL_FREQUENCY_HZ, NULL); + if(_pDInputInfo->_JoystickPollTimer!=JOYSTICK_POLL_TIMER_ID) { + wdxdisplay_cat.error() << "Error in joystick SetTimer!\n"; + } + } + #endif } wdxGraphicsWindowGroup::wdxGraphicsWindowGroup(GraphicsPipe *pipe,int num_windows,GraphicsWindow::Properties *WinPropArray) { @@ -3212,6 +3266,8 @@ wdxGraphicsWindowGroup::~wdxGraphicsWindowGroup() { // this fn must be called before windows are actually closed _bClosingAllWindows= true; + SAFE_DELETE(_pDInputInfo); + for(UINT i=0;i<_windows.size();i++) { _windows[i]->close_window(); } diff --git a/panda/src/wdxdisplay8/wdxGraphicsWindow8.h b/panda/src/wdxdisplay8/wdxGraphicsWindow8.h index 087cf05171..e943cd6ceb 100644 --- a/panda/src/wdxdisplay8/wdxGraphicsWindow8.h +++ b/panda/src/wdxdisplay8/wdxGraphicsWindow8.h @@ -24,6 +24,7 @@ #include #include #include "dxGraphicsStateGuardian8.h" +#include //////////////////////////////////////////////////////////////////// // Defines diff --git a/panda/src/wdxdisplay8/wdxdisplay8_composite1.cxx b/panda/src/wdxdisplay8/wdxdisplay8_composite1.cxx index 9e0485351a..30c7bca344 100644 --- a/panda/src/wdxdisplay8/wdxdisplay8_composite1.cxx +++ b/panda/src/wdxdisplay8/wdxdisplay8_composite1.cxx @@ -1,4 +1,5 @@ #include "config_wdxdisplay8.cxx" #include "wdxGraphicsPipe8.cxx" +#include "dxInput8.cxx"