From b1c07e0c413d87546bc64602508d20c2755c7574 Mon Sep 17 00:00:00 2001 From: David Rose Date: Thu, 9 Jan 2003 22:50:30 +0000 Subject: [PATCH] new window code --- panda/src/wdxdisplay8/config_wdxdisplay8.cxx | 98 - panda/src/wdxdisplay8/config_wdxdisplay8.h | 42 - panda/src/wdxdisplay8/dxInput8.cxx | 276 -- panda/src/wdxdisplay8/dxInput8.h | 45 - panda/src/wdxdisplay8/wdxGraphicsPipe8.cxx | 110 - panda/src/wdxdisplay8/wdxGraphicsPipe8.h | 72 - panda/src/wdxdisplay8/wdxGraphicsWindow8.cxx | 3458 ----------------- panda/src/wdxdisplay8/wdxGraphicsWindow8.h | 195 - .../wdxdisplay8/wdxdisplay8_composite1.cxx | 5 - 9 files changed, 4301 deletions(-) delete mode 100644 panda/src/wdxdisplay8/config_wdxdisplay8.cxx delete mode 100644 panda/src/wdxdisplay8/config_wdxdisplay8.h delete mode 100644 panda/src/wdxdisplay8/dxInput8.cxx delete mode 100644 panda/src/wdxdisplay8/dxInput8.h delete mode 100644 panda/src/wdxdisplay8/wdxGraphicsPipe8.cxx delete mode 100644 panda/src/wdxdisplay8/wdxGraphicsPipe8.h delete mode 100644 panda/src/wdxdisplay8/wdxGraphicsWindow8.cxx delete mode 100644 panda/src/wdxdisplay8/wdxGraphicsWindow8.h delete mode 100644 panda/src/wdxdisplay8/wdxdisplay8_composite1.cxx diff --git a/panda/src/wdxdisplay8/config_wdxdisplay8.cxx b/panda/src/wdxdisplay8/config_wdxdisplay8.cxx deleted file mode 100644 index ee4068194e..0000000000 --- a/panda/src/wdxdisplay8/config_wdxdisplay8.cxx +++ /dev/null @@ -1,98 +0,0 @@ -// Filename: config_wdxdisplay.cxx -// Created by: mike (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 "wdxGraphicsPipe8.h" -#include "wdxGraphicsWindow8.h" - -#include - -Configure(config_wdxdisplay); -NotifyCategoryDef(wdxdisplay, "display"); - -ConfigureFn(config_wdxdisplay) { - init_libwdxdisplay8(); -} - -bool dx_force_16bpp_zbuffer = config_wdxdisplay.GetBool("dx-force-16bpp-zbuffer", false); -bool bResponsive_minimized_fullscreen_window = config_wdxdisplay.GetBool("responsive-minimized-fullscreen-window",false); -bool dx_preserve_fpu_state = config_wdxdisplay.GetBool("dx-preserve-fpu-state", false); -int dx_preferred_deviceID = config_wdxdisplay.GetInt("dx-preferred-device-id", -1); - -// if true, use ddraw's GetAvailVidMem to fail if driver says it has too little video mem -bool dx_do_vidmemsize_check = config_wdxdisplay.GetBool("do-vidmemsize-check", true); - -// if true, override win-width/height and use driver vidmem info to pick what will -// be a fullscreen window size close to the best perf capability of card, based on -// a heuristic -bool dx_pick_best_screenres = config_wdxdisplay.GetBool("pick-best-screenres", false); - -// For now, set this true to use the IME correctly on Win2000, or -// false on Win98. This is temporary; once we have been able to -// verify that this distinction is actually necessary, we can replace -// 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); - -//////////////////////////////////////////////////////////////////// -// Function: init_libwdxdisplay -// Description: Initializes the library. This must be called at -// least once before any of the functions or classes in -// this library can be used. Normally it will be -// called by the static initializers and need not be -// called explicitly, but special cases exist. -//////////////////////////////////////////////////////////////////// -void init_libwdxdisplay8() { - static bool initialized = false; - if (initialized) { - return; - } - initialized = true; - - atexit(AtExitFn); - - wdxGraphicsPipe::init_type(); - GraphicsPipe::get_factory().register_factory( - wdxGraphicsPipe::get_class_type(), - wdxGraphicsPipe::make_wdxGraphicsPipe); - wdxGraphicsWindow::init_type(); - GraphicsWindow::get_factory().register_factory( - wdxGraphicsWindow::get_class_type(), - wdxGraphicsWindow::make_wdxGraphicsWindow); - - set_global_parameters(); -} - -// cant use global var cleanly because global var static init executed after init_libwdxdisplay(), incorrectly reiniting var -Filename get_icon_filename() { - string iconname = config_wdxdisplay.GetString("win32-window-icon",""); - return ExecutionEnvironment::expand_string(iconname); -} - -Filename get_color_cursor_filename() { - string cursorname = config_wdxdisplay.GetString("win32-color-cursor",""); - return ExecutionEnvironment::expand_string(cursorname); -} - -Filename get_mono_cursor_filename() { - string cursorname = config_wdxdisplay.GetString("win32-mono-cursor",""); - return ExecutionEnvironment::expand_string(cursorname); -} diff --git a/panda/src/wdxdisplay8/config_wdxdisplay8.h b/panda/src/wdxdisplay8/config_wdxdisplay8.h deleted file mode 100644 index 89b0cb95c7..0000000000 --- a/panda/src/wdxdisplay8/config_wdxdisplay8.h +++ /dev/null @@ -1,42 +0,0 @@ -// Filename: config_wdxdisplay.h -// Created by: mike (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 __CONFIG_WDXDISPLAY8_H__ -#define __CONFIG_WDXDISPLAY8_H__ - -#include -#include -#include - -NotifyCategoryDecl(wdxdisplay, EXPCL_PANDADX, EXPTP_PANDADX); - -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 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(); - -#endif /* __CONFIG_WDXDISPLAY_H__ */ diff --git a/panda/src/wdxdisplay8/dxInput8.cxx b/panda/src/wdxdisplay8/dxInput8.cxx deleted file mode 100644 index a6d4ac5b0d..0000000000 --- a/panda/src/wdxdisplay8/dxInput8.cxx +++ /dev/null @@ -1,276 +0,0 @@ -// 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 deleted file mode 100644 index 85b72eb15e..0000000000 --- a/panda/src/wdxdisplay8/dxInput8.h +++ /dev/null @@ -1,45 +0,0 @@ -// 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.cxx b/panda/src/wdxdisplay8/wdxGraphicsPipe8.cxx deleted file mode 100644 index a51f030604..0000000000 --- a/panda/src/wdxdisplay8/wdxGraphicsPipe8.cxx +++ /dev/null @@ -1,110 +0,0 @@ -// Filename: wdxGraphicsPipe.cxx -// Created by: mike (09Jan97) -// -//////////////////////////////////////////////////////////////////// -// -// 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 "wdxGraphicsPipe8.h" -#include "config_wdxdisplay8.h" -#include -#include -#include - -//////////////////////////////////////////////////////////////////// -// Static variables -//////////////////////////////////////////////////////////////////// -TypeHandle wdxGraphicsPipe::_type_handle; - -//wdxGraphicsPipe *global_pipe; - -wdxGraphicsPipe::wdxGraphicsPipe(const PipeSpecifier& spec) -: InteractiveGraphicsPipe(spec) { -// _width = GetSystemMetrics(SM_CXSCREEN); -// _height = GetSystemMetrics(SM_CYSCREEN); - _shift = false; -// global_pipe = this; -} - -//////////////////////////////////////////////////////////////////// -// Function: wdxGraphicsPipe::get_window_type -// Access: Public, Virtual -// Description: Returns the TypeHandle of the kind of window -// preferred by this kind of pipe. -//////////////////////////////////////////////////////////////////// -TypeHandle wdxGraphicsPipe:: -get_window_type() const { - return wdxGraphicsWindow::get_class_type(); -} - -GraphicsPipe *wdxGraphicsPipe:: -make_wdxGraphicsPipe(const FactoryParams ¶ms) { - GraphicsPipe::PipeSpec *pipe_param; - if(!get_param_into(pipe_param, params)) { - return new wdxGraphicsPipe(PipeSpecifier()); - } else { - return new wdxGraphicsPipe(pipe_param->get_specifier()); - } -} - -TypeHandle wdxGraphicsPipe::get_class_type(void) { - return _type_handle; -} - -const char *pipe_type_name="wdxGraphicsPipe8"; - -void wdxGraphicsPipe::init_type(void) { - InteractiveGraphicsPipe::init_type(); - register_type(_type_handle, pipe_type_name, - InteractiveGraphicsPipe::get_class_type()); -} - -TypeHandle wdxGraphicsPipe::get_type(void) const { - return get_class_type(); -} - -wdxGraphicsPipe::wdxGraphicsPipe(void) { - wdxdisplay_cat.error() - << pipe_type_name <<"s should not be created with the default constructor" << endl; -} - -wdxGraphicsPipe::wdxGraphicsPipe(const wdxGraphicsPipe&) { - wdxdisplay_cat.error() - << pipe_type_name << "s should not be copied" << endl; -} - -wdxGraphicsPipe& wdxGraphicsPipe::operator=(const wdxGraphicsPipe&) { - wdxdisplay_cat.error() - << pipe_type_name << "s should not be assigned" << endl; - return *this; -} - -//////////////////////////////////////////////////////////////////// -// Function: find_window -// Access: -// Description: Find the window that has the xwindow "win" in the -// window list for the pipe (if it exists) -//////////////////////////////////////////////////////////////////// -wdxGraphicsWindow *wdxGraphicsPipe:: -find_window(HWND win) { - int num_windows = get_num_windows(); - for(int w = 0; w < num_windows; w++) { - wdxGraphicsWindow *window = DCAST(wdxGraphicsWindow, get_window(w)); - if((window->_dxgsg!=NULL) && (window->_dxgsg->scrn.hWnd == win)) - return window; - } - return NULL; -} - - diff --git a/panda/src/wdxdisplay8/wdxGraphicsPipe8.h b/panda/src/wdxdisplay8/wdxGraphicsPipe8.h deleted file mode 100644 index 872fc160b8..0000000000 --- a/panda/src/wdxdisplay8/wdxGraphicsPipe8.h +++ /dev/null @@ -1,72 +0,0 @@ -// Filename: wdxGraphicsPipe.h -// Created by: mike (09Jan97) -// -//////////////////////////////////////////////////////////////////// -// -// 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 WDXGRAPHICSPIPE8_H -#define WDXGRAPHICSPIPE8_H -// -//////////////////////////////////////////////////////////////////// -// Includes -//////////////////////////////////////////////////////////////////// -#include - -#include -#include -#include "wdxGraphicsWindow8.h" - -//////////////////////////////////////////////////////////////////// -// Defines -//////////////////////////////////////////////////////////////////// - -//////////////////////////////////////////////////////////////////// -// Class : wdxGraphicsPipe -// Description : -//////////////////////////////////////////////////////////////////// -class EXPCL_PANDADX wdxGraphicsPipe : public InteractiveGraphicsPipe { -public: - wdxGraphicsPipe(const PipeSpecifier&); - - wdxGraphicsWindow* find_window(HWND win); -// ButtonHandle lookup_key(WPARAM wparam) const; - - virtual TypeHandle get_window_type() const; - -public: - - static GraphicsPipe* make_wdxGraphicsPipe(const FactoryParams ¶ms); - - static TypeHandle get_class_type(void); - static void init_type(void); - virtual TypeHandle get_type(void) const; - virtual TypeHandle force_init_type() {init_type(); return get_class_type();} - -private: - - static TypeHandle _type_handle; - -// int _width; -// int _height; - bool _shift; - -protected: - - wdxGraphicsPipe(void); - wdxGraphicsPipe(const wdxGraphicsPipe&); - wdxGraphicsPipe& operator=(const wdxGraphicsPipe&); - -}; - -#endif diff --git a/panda/src/wdxdisplay8/wdxGraphicsWindow8.cxx b/panda/src/wdxdisplay8/wdxGraphicsWindow8.cxx deleted file mode 100644 index f0ca2bb1e8..0000000000 --- a/panda/src/wdxdisplay8/wdxGraphicsWindow8.cxx +++ /dev/null @@ -1,3458 +0,0 @@ -// Filename: wdxGraphicsWindow.cxx -// Created by: mike (09Jan00) -// -//////////////////////////////////////////////////////////////////// -// -// 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 -#include -#include -#include -#include "wdxGraphicsWindow8.h" -#include "wdxGraphicsPipe8.h" -#include "config_wdxdisplay8.h" - -#include -#include -#include - -#ifdef DO_PSTATS -#include -#endif - -#include -#include - -//////////////////////////////////////////////////////////////////// -// Static variables -//////////////////////////////////////////////////////////////////// -TypeHandle wdxGraphicsWindow::_type_handle; - -#define LAST_ERROR 0 -#define ERRORBOX_TITLE "Panda3D Error" -#define WDX_WINDOWCLASSNAME "wdxDisplay" -#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 -// establish correspondence b/w DX7 mem info & DX8 device -typedef struct { - HMONITOR hMon; - DWORD MaxAvailVidMem; - bool bIsLowVidMemCard; - GUID DX7_DeviceGUID; - DWORD VendorID,DeviceID; -// char szDriver[MAX_DEVICE_IDENTIFIER_STRING]; -} CardID; - -typedef vector CardIDVec; -static CardIDVec *g_pCardIDVec=NULL; - -HWND_PANDAWIN_MAP hwnd_pandawin_map; -wdxGraphicsWindow* global_wdxwinptr = NULL; // need this for temporary windproc - -#define MAX_DISPLAYS 20 - -#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); - -// imperfect method to ID NVid? could also scan desc str, but that isnt fullproof either -#define IS_NVIDIA(DDDEVICEID) ((DDDEVICEID.VendorId==0x10DE) || (DDDEVICEID.VendorId==0x12D2)) -#define IS_ATI(DDDEVICEID) (DDDEVICEID.VendorId==0x1002) -#define IS_MATROX(DDDEVICEID) (DDDEVICEID.VendorId==0x102B) - -// because we dont have access to ModifierButtons, as a hack just synchronize state of these -// keys on get/lose keybd focus -#define NUM_MODIFIER_KEYS 16 -unsigned int hardcoded_modifier_buttons[NUM_MODIFIER_KEYS]={VK_SHIFT,VK_MENU,VK_CONTROL,VK_SPACE,VK_TAB, - VK_UP,VK_DOWN,VK_LEFT,VK_RIGHT,VK_PRIOR,VK_NEXT,VK_HOME,VK_END, - VK_INSERT,VK_DELETE,VK_ESCAPE}; - -#define UNKNOWN_VIDMEM_SIZE 0xFFFFFFFF -/* -static DWORD BitDepth_2_DDBDMask(DWORD iBitDepth) { - switch(iBitDepth) { - case 16: return DDBD_16; - case 32: return DDBD_32; - case 24: return DDBD_24; - case 8: return DDBD_8; - case 1: return DDBD_1; - case 2: return DDBD_2; - case 4: return DDBD_4; - } - return 0x0; -} - -typedef enum {DBGLEV_FATAL,DBGLEV_ERROR,DBGLEV_WARNING,DBGLEV_INFO,DBGLEV_DEBUG,DBGLEV_SPAM - } DebugLevels; - -void PrintDBGStr(DebugLevels level,HRESULT hr,const char *msgstr) { - ostream *pstrm; - static ostream dbg_strms[DBGLEV_SPAM+1]={wdxdisplay_cat.fatal,wdxdisplay_cat.error, - wdxdisplay_cat.warning,wdxdisplay_cat.info,wdxdisplay_cat.debug,wdxdisplay_cat.spam}; - assert(level<=DBGLEV_SPAM); - - pstrm=dbg_strms[level]; - (*pstrm)->fatal() << "GetDisplayMode failed, hr = " << ConvD3DErrorToString(hr) << endl; -} -*/ - -// pops up MsgBox w/system error msg -#define LAST_ERROR 0 -void PrintErrorMessage(DWORD msgID) { - LPTSTR pMessageBuffer; - - if(msgID==LAST_ERROR) - msgID=GetLastError(); - - FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, - NULL,msgID, - MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), //The user default language - (LPTSTR) &pMessageBuffer, // the weird ptrptr->ptr cast is intentional, see FORMAT_MESSAGE_ALLOCATE_BUFFER - 1024, NULL); - MessageBox(GetDesktopWindow(),pMessageBuffer,_T(ERRORBOX_TITLE),MB_OK); - wdxdisplay_cat.fatal() << "System error msg: " << pMessageBuffer << endl; - LocalFree( pMessageBuffer ); -} - -//#if defined(NOTIFY_DEBUG) || defined(DO_PSTATS) -//#ifdef _DEBUG -#if 0 -extern void dbgPrintVidMem(LPDIRECTDRAW7 pDD, LPDDSCAPS2 lpddsCaps,const char *pMsg) { - DWORD dwTotal,dwFree; - HRESULT hr; - - // These Caps bits arent allowed to be specified when calling GetAvailVidMem. - // They don't affect surface allocation in a vram heap. - -#define AVAILVIDMEM_BADCAPS (DDSCAPS_BACKBUFFER | \ - DDSCAPS_FRONTBUFFER | \ - DDSCAPS_COMPLEX | \ - DDSCAPS_FLIP | \ - DDSCAPS_OWNDC | \ - DDSCAPS_PALETTE | \ - DDSCAPS_SYSTEMMEMORY | \ - DDSCAPS_VISIBLE | \ - DDSCAPS_WRITEONLY) - - DDSCAPS2 ddsCaps = *lpddsCaps; - ddsCaps.dwCaps &= ~(AVAILVIDMEM_BADCAPS); // turn off the bad caps -// ddsCaps.dwCaps |= DDSCAPS_VIDEOMEMORY; done internally by DX anyway - - if(FAILED( hr = pDD->GetAvailableVidMem(&ddsCaps,&dwTotal,&dwFree))) { - wdxdisplay_cat.debug() << "GetAvailableVidMem failed : hr = " << ConvD3DErrorToString(hr) << endl; - exit(1); - } - - // Write a debug message to the console reporting the texture memory. - char tmpstr[100],tmpstr2[100]; - sprintf(tmpstr,"%.4g",dwTotal/1000000.0); - sprintf(tmpstr2,"%.4g",dwFree/1000000.0); - if(wdxdisplay_cat.is_debug()) - wdxdisplay_cat.debug() << "AvailableVidMem before creating "<< pMsg << ",(megs) total: " << tmpstr << " free:" << tmpstr2 <scrn.hWnd = hwnd; - - // Determine the initial open status of the IME. - _ime_open = false; - _ime_active = false; - HIMC hIMC = ImmGetContext(hwnd); - if (hIMC != 0) { - _ime_open = (ImmGetOpenStatus(hIMC) != 0); - ImmReleaseContext(hwnd, hIMC); - } -} - -//////////////////////////////////////////////////////////////////// -// Function: static_window_proc -// Access: -// Description: -//////////////////////////////////////////////////////////////////// -LONG WINAPI static_window_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) { - HWND_PANDAWIN_MAP::iterator pwin; - pwin=hwnd_pandawin_map.find(hwnd); - - if(pwin!=hwnd_pandawin_map.end()) { - wdxGraphicsWindow *wdxwinptr=(*pwin).second; - return wdxwinptr->window_proc(hwnd, msg, wparam, lparam); - } else if(global_wdxwinptr!=NULL){ - // this stuff should only be used during CreateWindow() - return global_wdxwinptr->window_proc(hwnd, msg, wparam, lparam); - } else { - // should never need this?? (maybe at shutdwn?) - return DefWindowProc(hwnd, msg, wparam, lparam); - } -} - -// Note: could use _TrackMouseEvent in comctrl32.dll (part of IE 3.0+) which emulates -// TrackMouseEvent on w95, but that requires another 500K of memory to hold that DLL, -// which is lame just to support w95, which probably has other issues anyway -INLINE void wdxGraphicsWindow:: -track_mouse_leaving(HWND hwnd) { - TRACKMOUSEEVENT tme = {sizeof(TRACKMOUSEEVENT),TME_LEAVE,hwnd,0}; - BOOL bSucceeded = TrackMouseEvent(&tme); // tell win32 to post WM_MOUSELEAVE msgs - - if((!bSucceeded) && wdxdisplay_cat.is_debug()) - wdxdisplay_cat.debug() << "TrackMouseEvent failed!, LastError=" << GetLastError() << endl; - - _tracking_mouse_leaving=true; -} - -//////////////////////////////////////////////////////////////////// -// Function: window_proc -// Access: -// Description: -//////////////////////////////////////////////////////////////////// -LONG wdxGraphicsWindow:: -window_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) { - int button = -1; - int x, y, width, height; - - switch(msg) { - case WM_PAINT: { - if((_WindowAdjustingType != NotAdjusting) || (!DX_IS_READY)) { - // let DefWndProc do WM_ERASEBKGND & just draw black, - // rather than forcing Present to stretchblt the old window contents - // into the new size - break; - } - - PAINTSTRUCT ps; - BeginPaint(hwnd, &ps); - if(DX_IS_READY) { - _dxgsg->show_frame(true); // 'true' since just want to show the last rendered backbuf, if any - } - EndPaint(hwnd, &ps); - return 0; - } - - case WM_MOUSEMOVE: { - if(!DX_IS_READY) - break; - - // Win32 doesn't return the same numbers as X does when the mouse - // goes beyond the upper or left side of the window - #define SET_MOUSE_COORD(iVal,VAL) { \ - iVal = VAL; \ - if(iVal & 0x8000) \ - iVal -= 0x10000; \ - } - - if(!_tracking_mouse_leaving) { - // need to re-call TrackMouseEvent every time mouse re-enters window - track_mouse_leaving(hwnd); - } - - WORD newX=LOWORD(lparam); - WORD newY=HIWORD(lparam); - - SET_MOUSE_COORD(x,newX); - SET_MOUSE_COORD(y,newY); - - handle_mouse_motion(x, y); - if(_props._fullscreen && (_dxgsg!=NULL) && (_dxgsg->scrn.pD3DDevice!=NULL)) - _dxgsg->scrn.pD3DDevice->SetCursorPosition(newX,newY,D3DCURSOR_IMMEDIATE_UPDATE); - return 0; - } - - // if cursor is invisible, make it visible when moving in the window bars,etc - case WM_NCMOUSEMOVE: { - if(!_props._bCursorIsVisible) { - if(!_cursor_in_windowclientarea) { -// SetCursor(_pParentWindowGroup->_hMouseCursor); - ShowCursor(true); - _cursor_in_windowclientarea=true; - } - } - break; - } - - case WM_NCMOUSELEAVE: { - if(!_props._bCursorIsVisible) { - ShowCursor(false); -// SetCursor(NULL); - _cursor_in_windowclientarea=false; - } - break; - } - - case WM_MOUSELEAVE: { - // wdxdisplay_cat.fatal() << "XXXXX WM_MOUSELEAVE received\n"; - - _tracking_mouse_leaving=false; - handle_mouse_exit(); - break; - } - - case WM_CREATE: { - track_mouse_leaving(hwnd); - _cursor_in_windowclientarea=false; - ClearToBlack(hwnd,_props); - set_cursor_visibility(true); - break; - } - - case WM_IME_NOTIFY: - if (wparam == IMN_SETOPENSTATUS) { - HIMC hIMC = ImmGetContext(hwnd); - nassertr(hIMC != 0, 0); - _ime_open = (ImmGetOpenStatus(hIMC) != 0); - if (!_ime_open) { - _ime_active = false; // Sanity enforcement. - } - ImmReleaseContext(hwnd, hIMC); - } - break; - - case WM_IME_STARTCOMPOSITION: - // In case we're running fullscreen mode, we have to turn on - // explicit DX support for overlay windows now, so we'll be able - // to see the IME window. - _dxgsg->support_overlay_window(true); - _ime_active = true; - break; - - case WM_IME_ENDCOMPOSITION: - // Turn off the support for overlay windows, since we're done - // with the IME window for now and it just slows things down. - _dxgsg->support_overlay_window(false); - _ime_active = false; - break; - - case WM_IME_COMPOSITION: - if (lparam & GCS_RESULTSTR) { - if (!_input_devices.empty()) { - HIMC hIMC = ImmGetContext(hwnd); - nassertr(hIMC != 0, 0); - - static const int max_ime_result = 128; - static char ime_result[max_ime_result]; - - if (_ime_composition_w) { - // Since ImmGetCompositionStringA() doesn't seem to work - // for Win2000 (it always returns question mark - // characters), we have to use ImmGetCompositionStringW() - // on this OS. This is actually the easier of the two - // functions to use. - - DWORD result_size = - ImmGetCompositionStringW(hIMC, GCS_RESULTSTR, - ime_result, max_ime_result); - - // Add this string into the text buffer of the application. - - // ImmGetCompositionStringW() returns a string, but it's - // filled in with wstring data: every two characters defines a - // 16-bit unicode char. The docs aren't clear on the - // endianness of this. I guess it's safe to assume all Win32 - // machines are little-endian. - for (DWORD i = 0; i < result_size; i += 2) { - int result = - ((int)(unsigned char)ime_result[i + 1] << 8) | - (unsigned char)ime_result[i]; - _input_devices[0].keystroke(result); - } - } else { - // On the other hand, ImmGetCompositionStringW() doesn't - // work on Win95 or Win98; for these OS's we must use - // ImmGetCompositionStringA(). - DWORD result_size = - ImmGetCompositionStringA(hIMC, GCS_RESULTSTR, - ime_result, max_ime_result); - - // ImmGetCompositionStringA() returns an encoded ANSI - // string, which we now have to map to wide-character - // Unicode. - static const int max_wide_result = 128; - static wchar_t wide_result[max_wide_result]; - - int wide_size = - MultiByteToWideChar(CP_ACP, 0, - ime_result, result_size, - wide_result, max_wide_result); - if (wide_size == 0) { - PrintErrorMessage(LAST_ERROR); - } - for (int i = 0; i < wide_size; i++) { - _input_devices[0].keystroke(wide_result[i]); - } - } - - ImmReleaseContext(hwnd, hIMC); - } - return 0; - } - break; - - case WM_CHAR: - // Ignore WM_CHAR messages if we have the IME open, since - // everything will come in through WM_IME_COMPOSITION. (It's - // supposed to come in through WM_CHAR, too, but there seems to - // be a bug in Win2000 in that it only sends question mark - // characters through here.) - if (!_ime_open && !_input_devices.empty()) { - _input_devices[0].keystroke(wparam); - } - break; - - case WM_SYSKEYDOWN: { - // Alt and F10 are sent as WM_SYSKEYDOWN instead of WM_KEYDOWN - // want to use defwindproc on Alt syskey so std windows cmd Alt-F4 works, etc - POINT point; - GetCursorPos(&point); - ScreenToClient(hwnd, &point); - handle_keypress(lookup_key(wparam), point.x, point.y); - if (wparam == VK_F10) { - //bypass default windproc F10 behavior (it activates the main menu, but we have none) - return 0; - } - } - break; - - case WM_SYSCOMMAND: - if(wparam==SC_KEYMENU) { - // if Alt is released (alone w/o other keys), defwindproc will send - // this command, which will 'activate' the title bar menu (we have none) - // and give focus to it. we dont want this to happen, so kill this msg - return 0; - } - break; - - case WM_KEYDOWN: { - POINT point; - - GetCursorPos(&point); - ScreenToClient(hwnd, &point); - handle_keypress(lookup_key(wparam), point.x, point.y); - - // Handle Cntrl-V paste from clipboard. Is there a better way - // to detect this hotkey? - if ((wparam=='V') && (GetKeyState(VK_CONTROL) < 0) && - !_input_devices.empty()) { - HGLOBAL hglb; - char *lptstr; - - if (!IsClipboardFormatAvailable(CF_TEXT)) - return 0; - - if (!OpenClipboard(NULL)) - return 0; - - // Maybe we should support CF_UNICODETEXT if it is available - // too? - hglb = GetClipboardData(CF_TEXT); - if (hglb!=NULL) { - lptstr = (char *) GlobalLock(hglb); - if (lptstr != NULL) { - char *pChar; - for(pChar=lptstr;*pChar!=NULL;pChar++) { - _input_devices[0].keystroke((uchar)*pChar); - } - GlobalUnlock(hglb); - } - } - CloseClipboard(); - } - break; - } - - case WM_SYSKEYUP: - case WM_KEYUP: - handle_keyrelease(lookup_key(wparam)); - break; - - case WM_LBUTTONDOWN: - button = 0; - case WM_MBUTTONDOWN: - if(button < 0) - button = 1; - case WM_RBUTTONDOWN: - if(!DX_IS_READY) - break; - - if(button < 0) - button = 2; - SetCapture(hwnd); - SET_MOUSE_COORD(x,LOWORD(lparam)); - SET_MOUSE_COORD(y,HIWORD(lparam)); - handle_keypress(MouseButton::button(button), x, y); - return 0; - - case WM_LBUTTONUP: - button = 0; - case WM_MBUTTONUP: - if(button < 0) - button = 1; - case WM_RBUTTONUP: - if(!DX_IS_READY) - break; - - if(button < 0) - button = 2; - ReleaseCapture(); - #if 0 - SET_MOUSE_COORD(x,LOWORD(lparam)); - SET_MOUSE_COORD(y,HIWORD(lparam)); - #endif - handle_keyrelease(MouseButton::button(button)); - return 0; - - case WM_SETCURSOR: - // Turn off any GDI window cursor - // dx8 cursor not working yet - - if(_use_dx8_cursor && _props._fullscreen) { - // SetCursor( NULL ); - // _dxgsg->scrn.pD3DDevice->ShowCursor(true); - - set_cursor_visibility(true); - return TRUE; // prevent Windows from setting cursor to window class cursor (see docs on WM_SETCURSOR) - } - break; - - case WM_MOVE: - if(!DX_IS_READY) - break; - handle_window_move(LOWORD(lparam), HIWORD(lparam) ); - return 0; - -#if 0 - doesnt work yet - - case WM_GETMINMAXINFO: { - - // make sure window size doesnt go to zero - LPMINMAXINFO pInfo=(LPMINMAXINFO) lparam; - wdxdisplay_cat.spam() << "initial WM_GETMINMAXINFO: MinX:" << pInfo->ptMinTrackSize.x << " MinY:" << pInfo->ptMinTrackSize.y << endl; - - RECT client_rect; - GetClientRect( hwnd, &client_rect ); - - wdxdisplay_cat.spam() << "WM_GETMINMAXINFO: ClientRect: left: " << client_rect.left << " right: " << client_rect.right - << " top: " << client_rect.top << " bottom: " << client_rect.bottom << endl; - - - UINT client_ysize=RECT_YSIZE(client_rect); - UINT client_xsize=RECT_XSIZE(client_rect); - - if(client_ysize==0) { - RECT wnd_rect; - GetWindowRect( hwnd, &wnd_rect ); - wdxdisplay_cat.spam() << "WM_GETMINMAXINFO: WndRect: left: " << wnd_rect.left << " right: " << wnd_rect.right - << " top: " << wnd_rect.top << " bottom: " << wnd_rect.bottom << endl; - - pInfo->ptMinTrackSize.y=RECT_YSIZE(wnd_rect)-client_ysize+2; - } - - if(client_xsize==0) { - RECT wnd_rect; - GetWindowRect( hwnd, &wnd_rect ); - pInfo->ptMinTrackSize.x=RECT_XSIZE(wnd_rect)-client_xsize+2; - } - - if((client_ysize==0) || (client_xsize==0)) { - wdxdisplay_cat.spam() << "final WM_GETMINMAXINFO: MinX:" << pInfo->ptMinTrackSize.x << " MinY:" << pInfo->ptMinTrackSize.y << endl; - return 0; - } - break; - } -#endif - - case WM_EXITSIZEMOVE: - #ifdef _DEBUG - wdxdisplay_cat.spam() << "WM_EXITSIZEMOVE received" << endl; - #endif - - if(_WindowAdjustingType==Resizing) { - bool bSucceeded=handle_windowed_resize(hwnd,true); - - if(!bSucceeded) { -#if 0 - bugbug need to fix this stuff - SetWindowPos(hwnd,NULL,0,0,lastxsize,lastysize, - SWP_NOMOVE | -#endif - } - } - - _WindowAdjustingType = NotAdjusting; - _dxgsg->SetDXReady(true); - return 0; - - case WM_ENTERSIZEMOVE: { - if(_dxgsg!=NULL) - _dxgsg->SetDXReady(false); // dont see pic during resize - _WindowAdjustingType = MovingOrResizing; - } - break; - - case WM_SIZE: { - - #ifdef _DEBUG - { - width = LOWORD(lparam); height = HIWORD(lparam); - wdxdisplay_cat.spam() << "WM_SIZE received with width:" << width << " height: " << height << " flags: " << - ((wparam == SIZE_MAXHIDE)? "SIZE_MAXHIDE " : "") << ((wparam == SIZE_MAXSHOW)? "SIZE_MAXSHOW " : "") << - ((wparam == SIZE_MINIMIZED)? "SIZE_MINIMIZED " : "") << ((wparam == SIZE_RESTORED)? "SIZE_RESTORED " : "") << - ((wparam == SIZE_MAXIMIZED)? "SIZE_MAXIMIZED " : "") << endl; - } - #endif - // old comment -- added SIZE_RESTORED to handle 3dfx case - if(_props._fullscreen || ((_dxgsg==NULL) || (_dxgsg->scrn.hWnd==NULL)) || ((wparam != SIZE_RESTORED) && (wparam != SIZE_MAXIMIZED))) - break; - - width = LOWORD(lparam); height = HIWORD(lparam); - - if((_props._xsize != width) || (_props._ysize != height)) { - _WindowAdjustingType = Resizing; - - // for maximized,unmaximize, need to call resize code artificially - // since no WM_EXITSIZEMOVE is generated. - if(wparam==SIZE_MAXIMIZED) { - _bSizeIsMaximized=TRUE; - window_proc(hwnd, WM_EXITSIZEMOVE, 0x0,0x0); - } else if((wparam==SIZE_RESTORED) && _bSizeIsMaximized) { - _bSizeIsMaximized=FALSE; // only want to reinit dx if restoring from maximized state - window_proc(hwnd, WM_EXITSIZEMOVE, 0x0,0x0); - } - } - - break; - } - - case WM_DISPLAYCHANGE: { - #ifdef _DEBUG - width = LOWORD(lparam); height = HIWORD(lparam); - DWORD newbitdepth=wparam; - wdxdisplay_cat.spam() <<"WM_DISPLAYCHANGE received with width:" << width << " height: " << height << " bpp: " << wparam<< endl; - #endif - - // unfortunately this doesnt seem to work because RestoreAllSurfaces doesn't - // seem to think we're back in the original displaymode even after I've received - // the WM_DISPLAYCHANGE msg, and returns WRONGMODE error. So the only way I can - // think of to make this work is to have the timer periodically check for restored - // coop level - - // if(_props._fullscreen && !_window_active) { - // if(_dxgsg!=NULL) - // _dxgsg->CheckCooperativeLevel(DO_REACTIVATE_WINDOW); - // else reactivate_window(); - // } - - // does the windowed case handle displaychange properly? no. need to recreate all devices - } - break; - - case WM_SETFOCUS: { - // wdxdisplay_cat.info() << "got WM_SETFOCUS\n"; - if(!DX_IS_READY) { - break; - } - - POINT point; - GetCursorPos(&point); - ScreenToClient(hwnd, &point); - - // this is a hack to make sure common modifier keys have proper state - // since at focus loss, app may never receive key-up event corresponding to - // a key-down. it would be better to know the exact set of ModifierButtons the - // user is using, since we may miss some here - - for(int i=0;iflags << endl; - break; - } - - case WM_GETMINMAXINFO: - wdxdisplay_cat.spam() << "WM_GETMINMAXINFO received\n" << endl; - break; -#endif - - case WM_ERASEBKGND: - // WM_ERASEBKGND will be ignored during resizing, because - // we dont want to redraw as user is manually resizing window - if(_WindowAdjustingType) - break; - return 0; // dont let GDI waste time redrawing the deflt background - - case WM_TIMER: - // 2 cases of app deactivation: - // - // 1) user has switched out of fullscreen mode - // this is first signalled when ACTIVATEAPP returns false - // for this case, we dont wake up until WM_SIZE returns restore or maximize - // and WM_TIMER just periodically reawakens app for idle processing - - // unfortunately this doesnt seem to work because RestoreAllSurfaces doesn't - // seem to think we're back in the original displaymode even after I've received - // the WM_DISPLAYCHANGE msg, and returns WRONGMODE error. So the only way I can - // think of to make this work is to have the timer periodically check for restored - // coop level, as it does in case 2) - - // - // 2) windowed app has lost access to dx because another app has taken dx exclusive mode - // here we rely on WM_TIMER to periodically check if it is ok to reawaken app. - // windowed apps currently run regardless of if its window is in the foreground - // so we cannot rely on window messages to reawaken app - - if((wparam==_PandaPausedTimer) && ((!_window_active)||_active_minimized_fullscreen)) { - assert(_dxgsg!=NULL); - _dxgsg->CheckCooperativeLevel(DO_REACTIVATE_WINDOW); - - // wdxdisplay_cat.spam() << "periodic return of control to app\n"; - _return_control_to_app = true; - // throw_event("PandaPaused"); - // 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: - #ifdef _DEBUG - wdxdisplay_cat.spam() << "WM_CLOSE received\n"; - #endif - // close_window(); - delete _pParentWindowGroup; - - // BUGBUG: right now there is no way to tell the panda app the graphics window is invalid or - // has been closed by the user, to prevent further methods from being called on the window. - // this needs to be added to panda for multiple windows to work. in the meantime, just - // trigger an exit here if # windows==0, since that is the expected behavior when all - // windows are closed (should be done by the app though, and it assumes you only make this - // type of panda gfx window) - - if(hwnd_pandawin_map.size()==0) { - exit(0); - } - return 0; - - case WM_ACTIVATEAPP: { - #ifdef _DEBUG - wdxdisplay_cat.spam() << "WM_ACTIVATEAPP(" << (bool)(wparam!=0) <<") received\n"; - #endif - - if((!wparam) && _props._fullscreen) { - deactivate_window(); - return 0; - } // dont want to reactivate until window is actually un-minimized (see WM_SIZE) - break; - } - } - - return DefWindowProc(hwnd, msg, wparam, lparam); -} - -// should be used by both fullscrn and windowed resize -bool wdxGraphicsWindow::reset_device_resize_window(UINT new_xsize, UINT new_ysize) { - DXScreenData *pScrn=&_dxgsg->scrn; - assert((new_xsize>0)&&(new_ysize>0)); - bool bRetval=true; - - D3DPRESENT_PARAMETERS d3dpp; - memcpy(&d3dpp,&pScrn->PresParams,sizeof(D3DPRESENT_PARAMETERS)); - d3dpp.BackBufferWidth = new_xsize; - d3dpp.BackBufferHeight = new_ysize; - HRESULT hr=_dxgsg->reset_d3d_device(&d3dpp); - - if(FAILED(hr)) { - bRetval=false; - wdxdisplay_cat.error() << "reset_device_resize_window Reset() failed" << D3DERRORSTRING(hr); - if(hr==D3DERR_OUTOFVIDEOMEMORY) { - hr=_dxgsg->reset_d3d_device(&pScrn->PresParams); - if(FAILED(hr)) { - wdxdisplay_cat.error() << "reset_device_resize_window Reset() failed OutOfVidmem, then failed again doing Reset w/original params:" << D3DERRORSTRING(hr); - exit(1); - } else { - if(wdxdisplay_cat.is_info()) - wdxdisplay_cat.info() << "reset of original size (" <PresParams.BackBufferWidth << "," - << pScrn->PresParams.BackBufferHeight << ") succeeded\n"; - } - } else { - exit(1); - } - } - - init_resized_window(); - return bRetval; -} - -//////////////////////////////////////////////////////////////////// -// Function: handle_reshape -// Access: -// Description: -//////////////////////////////////////////////////////////////////// -bool wdxGraphicsWindow::handle_windowed_resize(HWND hWnd,bool bDoDxReset) { - // handles windowed, non-fullscreen resizing - GdiFlush(); - - assert(!_props._fullscreen); - - if(bDoDxReset && (_dxgsg!=NULL)) { - if(_dxgsg->scrn.pD3DDevice==NULL) { - //assume this is initial creation reshape, so ignore this call - return true; - } - } - - if(_dxgsg!=NULL) - _dxgsg->SetDXReady(false); - - RECT view_rect; - - GetClientRect( hWnd, &view_rect ); - ClientToScreen( hWnd, (POINT*)&view_rect.left ); // translates top,left pnt - ClientToScreen( hWnd, (POINT*)&view_rect.right ); // translates right,bottom pnt - - _props._xorg = view_rect.left; // _props origin should reflect upper left of view rectangle - _props._yorg = view_rect.top; - - DWORD xsize= RECT_XSIZE(view_rect); - DWORD ysize= RECT_YSIZE(view_rect); - - if((xsize==0)||(ysize==0)) { - return false; - } - - bool bResizeSucceeded=true; - -/* - fail if resize fails, dont adjust size - do { - // change _props xsize,ysize (need to do this here in case _dxgsg==NULL) - resized(xsize,ysize); - - if((_dxgsg!=NULL)&& bDoDxReset) { - bResizeSucceeded=reset_device_resize_window(xsize,ysize); // create the new resized rendertargets - if(!bResizeSucceeded) { - // size was too large. try a smaller size - if(wdxdisplay_cat.is_debug()) { - wdxdisplay_cat.debug() << "windowed_resize to size: (" << xsize << "," << ysize << ") failed due to out-of-memory, retrying w/reduced size\n"; - } - - xsize *= 0.8f; - ysize *= 0.8f; - - view_rect.right=view_rect.left+xsize; - view_rect.bottom=view_rect.top+ysize; - } - } - } while(!bResizeSucceeded); -*/ - - // change _props xsize,ysize (need to do this here in case _dxgsg==NULL) - // reset_device_resize will call it again, this is OK - resized(xsize,ysize); - - if((_dxgsg!=NULL)&& bDoDxReset) { - bResizeSucceeded=reset_device_resize_window(xsize,ysize); // create the new resized rendertargets - if(!bResizeSucceeded) { - if(wdxdisplay_cat.is_debug()) - wdxdisplay_cat.debug() << "windowed_resize to size: (" << xsize << "," << ysize << ") failed due to out-of-memory\n"; - } else { - if(wdxdisplay_cat.is_debug()) - wdxdisplay_cat.debug() << "windowed_resize to origin: (" << _props._xorg << "," << _props._yorg << "), size: (" << _props._xsize << "," << _props._ysize << ")\n"; - } - } - - if(_dxgsg!=NULL) - _dxgsg->SetDXReady(true); - - return bResizeSucceeded; -} - -void wdxGraphicsWindow::deactivate_window(void) { - // current policy is to suspend minimized or deactivated fullscreen windows, but leave - // regular windows running normally - - if((!_window_active) || _exiting_window || _active_minimized_fullscreen) { - #ifdef _DEBUG - if(wdxdisplay_cat.is_spam()) - wdxdisplay_cat.spam() << "deactivate_window called, but ignored in current mode\n"; - #endif - return; - } - - if(bResponsive_minimized_fullscreen_window) { - if(wdxdisplay_cat.is_spam()) - wdxdisplay_cat.spam() << "WDX fullscreen window switching to active minimized mode...\n"; - _active_minimized_fullscreen = true; - } else { - - if(wdxdisplay_cat.is_spam()) - wdxdisplay_cat.spam() << "WDX window deactivated, waiting...\n"; - - _window_active = false; - } - - if(_props._fullscreen) { - // make sure window is minimized - - WINDOWPLACEMENT wndpl; - wndpl.length=sizeof(WINDOWPLACEMENT); - if(!GetWindowPlacement(_dxgsg->scrn.hWnd,&wndpl)) { - wdxdisplay_cat.error() << "GetWindowPlacement failed!\n"; - return; - } - - if((wndpl.showCmd!=SW_MINIMIZE)&&(wndpl.showCmd!=SW_SHOWMINIMIZED)) { - ShowWindow(_dxgsg->scrn.hWnd, SW_MINIMIZE); - } - - throw_event("PandaPaused"); // right now this is used to signal python event handler to disable audio - } - -// if(!bResponsive_minimized_fullscreen_window) { - // need this even in responsive-mode to trigger the dxgsg check of cooplvl, i think? - - _PandaPausedTimer = SetTimer(_dxgsg->scrn.hWnd,PAUSED_TIMER_ID,500,NULL); - if(_PandaPausedTimer!=PAUSED_TIMER_ID) { - 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 -void wdxGraphicsWindow::reactivate_window(void) { - if((!_window_active)||(_active_minimized_fullscreen)) { - - // first see if dx cooperative level is OK for reactivation - // if(!_dxgsg->CheckCooperativeLevel()) - // return; - - if(_PandaPausedTimer!=NULL) { - KillTimer(_dxgsg->scrn.hWnd,_PandaPausedTimer); - _PandaPausedTimer = NULL; - } - - if(!_window_active) { - _window_active = true; - if(wdxdisplay_cat.is_spam()) - wdxdisplay_cat.spam() << "WDX window re-activated...\n"; - } else { - _active_minimized_fullscreen = false; - if(wdxdisplay_cat.is_spam()) - wdxdisplay_cat.spam() << "WDX window unminimized from active-minimized state...\n"; - } - - // need to call dx_init and ResourceManagerDiscardBytes since D3D Reset() was called - init_resized_window(); - - // move window to top of zorder - // if(_props._fullscreen) - // SetWindowPos(_DisplayDataArray[0].hWnd, HWND_TOP, 0,0,0,0, SWP_NOMOVE | SWP_NOSENDCHANGING | SWP_NOSIZE | SWP_NOOWNERZORDER); - GdiFlush(); - } - - if(_props._fullscreen) { - throw_event("PandaRestarted"); // right now this is used to signal python event handler to re-enable audio - } -} - -//////////////////////////////////////////////////////////////////// -// Function: Constructor -// Access: -// Description: -//////////////////////////////////////////////////////////////////// -wdxGraphicsWindow::wdxGraphicsWindow(GraphicsPipe* pipe) : GraphicsWindow(pipe) { - _ime_active = false; - _pParentWindowGroup=NULL; - _pParentWindowGroup=new wdxGraphicsWindowGroup(this); -} - -//////////////////////////////////////////////////////////////////// -// Function: Constructor -// Access: -// Description: -//////////////////////////////////////////////////////////////////// -wdxGraphicsWindow::wdxGraphicsWindow(GraphicsPipe* pipe, const GraphicsWindow::Properties& props) - : GraphicsWindow(pipe, props) { - _ime_open = false; - _pParentWindowGroup=NULL; - _pParentWindowGroup=new wdxGraphicsWindowGroup(this); -} - -bool supports_color_cursors(D3DADAPTER_IDENTIFIER8 &DevID) { - // TODO: add more cards as more testing is done - if(IS_NVIDIA(DevID)) { - // all nvidia seem to support 256 color - return true; - } else if(IS_ATI(DevID)) { - // radeons seem to be in the 5100 range and support color, assume anything in 6000 or above - // is newer than radeon and supports 256 color - if(((DevID.DeviceId>=0x5100) && (DevID.DeviceId<=0x5200)) || - (DevID.DeviceId>=0x6000)) - return true; - } else if IS_MATROX(DevID) { - if(DevID.DeviceId==0x0525) // G400 seems to support color cursors, havent tested other matrox - return true; - } - - return false; -} - -HCURSOR CreateNullCursor(HINSTANCE hInst) { - #define CURSORBYTESIZE (32*4) - - // 1-bit 32x32 - BYTE ANDPlane[CURSORBYTESIZE],XORPlane[CURSORBYTESIZE]; - - ZeroMemory(XORPlane,CURSORBYTESIZE); - memset(ANDPlane,0xFF,CURSORBYTESIZE); - - return CreateCursor(hInst,0,0,32,32,ANDPlane,XORPlane); -} - -void wdxGraphicsWindowGroup::CreateWindows(void) { - HINSTANCE hProgramInstance = GetModuleHandle(NULL); - WNDCLASS wc; - static bool wc_registered = false; - _hParentWindow = NULL; - _bLoadedCustomCursor=false; - - // Clear before filling in window structure! - ZeroMemory(&wc, sizeof(WNDCLASS)); - wc.style = CS_HREDRAW | CS_VREDRAW; //CS_OWNDC; - wc.lpfnWndProc = (WNDPROC) static_window_proc; - wc.hInstance = hProgramInstance; - - // all this must be moved to dx_init, since we need to create DX surface - string windows_icon_filename = get_icon_filename().to_os_specific(); - - - if(!windows_icon_filename.empty()) { - // Note: LoadImage seems to cause win2k internal heap corruption (outputdbgstr warnings) - // if icon is more than 8bpp - - // loads a .ico fmt file - wc.hIcon = (HICON) LoadImage(NULL, windows_icon_filename.c_str(), IMAGE_ICON, 0, 0, LR_LOADFROMFILE ); - - if(wc.hIcon==NULL) { - wdxdisplay_cat.warning() << "windows icon filename '" << windows_icon_filename << "' not found!!\n"; - } - } else { - wc.hIcon = NULL; // use default app icon - } - -#if 0 - // Note: dx_init() uses the cursor handle to create the dx cursor surface - string windows_color_cursor_filename = get_color_cursor_filename().to_os_specific(); - - if(!windows_color_cursor_filename.empty()) { - // card support for full color non-black/white GDI cursors varies greatly. if the cursor is not supported, - // it is rendered in software by GDI, which causes a flickering effect (because it's not synced - // with flip?). GDI transparently masks the lack of HW support so there is no easy way for app to detect - // if HW cursor support exists. alternatives are to tie cursor motion to frame rate using DDraw blts - // or overlays (this is done automatically by DX8 runtime mouse cursor support), or to have separate thread draw cursor - // (sync issues?). instead we do mono cursor unless card is known to support 256 color cursors - bool bSupportsColorCursor=true; - - #if 0 - // remove this check for now, since dx8 should emulate color cursors - /* if any card doesnt support color, dont load it*/ - for(int w=0;w<_windows.size();w++) - bSupportsColorCursor &= supports_color_cursors(_windows[w]->_dxgsg->scrn.DXDeviceID); - #endif - - if(bSupportsColorCursor) { - DWORD load_flags = LR_LOADFROMFILE; - - if(dx_full_screen) { - // I think cursors should use LR_CREATEDIBSECTION since they should not be mapped to the device palette (in the case of 256-color cursors) - // since they are not going to be used on the desktop - load_flags |= LR_CREATEDIBSECTION; - } - - // Note: LoadImage seems to cause win2k internal heap corruption (outputdbgstr warnings) - // if icon is more than 8bpp - - // loads a .cur fmt file. - _hMouseCursor = (HCURSOR) LoadImage(NULL, windows_color_cursor_filename.c_str(), IMAGE_CURSOR, 0, 0, load_flags ); - - if(_hMouseCursor==NULL) { - wdxdisplay_cat.warning() << "windows color cursor filename '" << windows_color_cursor_filename << "' not found!!\n"; - goto try_mono_cursor; - - } - - _bLoadedCustomCursor=true; - } - } - - try_mono_cursor: -#endif - - if(!_bLoadedCustomCursor) { - string windows_mono_cursor_filename = get_mono_cursor_filename().to_os_specific(); - - if(!windows_mono_cursor_filename.empty()) { - // Note: LoadImage seems to cause win2k internal heap corruption (outputdbgstr warnings) - // if icon is more than 8bpp - - DWORD load_flags = LR_LOADFROMFILE; - - if(dx_full_screen) { - // I think cursors should use LR_CREATEDIBSECTION since they should not be mapped to the device palette (in the case of 256-color cursors) - // since they are not going to be used on the desktop - load_flags |= LR_CREATEDIBSECTION; - } - // loads a .cur fmt file. - _hMouseCursor = (HCURSOR) LoadImage(NULL, windows_mono_cursor_filename.c_str(), IMAGE_CURSOR, 0, 0, load_flags); - - if(_hMouseCursor==NULL) { - wdxdisplay_cat.warning() << "windows mono cursor filename '" << windows_mono_cursor_filename << "' not found!!\n"; - } else _bLoadedCustomCursor=true; - } - } - - if(!_bLoadedCustomCursor) - _hMouseCursor = LoadCursor(NULL, DEFAULT_CURSOR); - - // need both a mouse and no-mouse class in case we have mixed fullscrn/windowed - // windowed must use GDI mouse, fullscrn usually wont - if (!wc_registered) { - // We only need to register the window class once per session. - - wc.hCursor = _hMouseCursor; // for windowed mode use the GDI cursor. - // bugbug: for fullscreen do we need to do a SetWindowLongNULL - wc.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH); - wc.lpszMenuName = NULL; - wc.lpszClassName = WDX_WINDOWCLASSNAME; - - if(!RegisterClass(&wc)) { - wdxdisplay_cat.error() << "could not register window class " << WDX_WINDOWCLASSNAME << endl; - } - - if(dx_use_dx_cursor) { - wc.hCursor = CreateNullCursor(hProgramInstance); - if(wc.hCursor==NULL) - wdxdisplay_cat.error() << "failed to create NULL cursor, error=" << GetLastError() << endl; - - wc.lpszClassName = WDX_WINDOWCLASSNAME_NOCURSOR; - - if(!RegisterClass(&wc)) { - wdxdisplay_cat.error() << "could not register window class " << WDX_WINDOWCLASSNAME_NOCURSOR << endl; - } - } - - wc_registered = true; - } - - DWORD base_window_style = WS_POPUP | WS_SYSMENU; // for CreateWindow - - global_wdxwinptr = _windows[0]; // for use during createwin() bugbug look at this again - - // rect now contains the coords for the entire window, not the client - // extra windows must be parented to the first so app doesnt minimize when user selects them - for(DWORD devnum=0;devnum<_windows.size();devnum++) { - DWORD xleft,ytop,xsize,ysize; - GraphicsWindow::Properties *props = &_windows[devnum]->_props; - DWORD final_window_style; - - final_window_style=base_window_style; - char *pWindowClassName; - - if(_windows[devnum]->_props._fullscreen) { - MONITORINFO minfo; - ZeroMemory(&minfo, sizeof(MONITORINFO)); - minfo.cbSize = sizeof(MONITORINFO); - // since DX8 cant be installed on w95, ok to statically link to GetMonInfo - // get upper-left corner coords using GetMonitorInfo - GetMonitorInfo(_windows[devnum]->_dxgsg->scrn.hMon, &minfo); - xleft=minfo.rcMonitor.left; - ytop=minfo.rcMonitor.top; - xsize=props->_xsize; - ysize=props->_ysize; - - pWindowClassName= (dx_use_dx_cursor ? WDX_WINDOWCLASSNAME_NOCURSOR : WDX_WINDOWCLASSNAME); - } else { - // specify client area, use adjustwindowrect to figure out size of final window to - // pass to CreateWin - - RECT win_rect; - SetRect(&win_rect, props->_xorg, props->_yorg, props->_xorg + props->_xsize, - props->_yorg + props->_ysize); - - if(props->_border) - final_window_style |= WS_OVERLAPPEDWINDOW; // should we just use WS_THICKFRAME instead? - - AdjustWindowRect(&win_rect, final_window_style, false); //compute window size based on desired client area size - - // make sure origin is on screen - if(win_rect.left < 0) { - win_rect.right -= win_rect.left; win_rect.left = 0; - } - if(win_rect.top < 0) { - win_rect.bottom -= win_rect.top; win_rect.top = 0; - } - - xleft=win_rect.left; - ytop= win_rect.top; - xsize=RECT_XSIZE(win_rect); - ysize=RECT_YSIZE(win_rect); - - pWindowClassName=WDX_WINDOWCLASSNAME; - } - - wdxdisplay_cat.info() << "opening " << props->_xsize << "x" << props->_ysize - << ((_windows[devnum]->_props._fullscreen) ? " fullscreen" : " regular") << " window\n"; - - if((xsize==0) || (ysize==0)) { - wdxdisplay_cat.fatal() << "can't create window with zero area for device " << devnum << "!\n"; - exit(1); - } - - // BUGBUG: this sets window posns based on desktop arrangement of monitors (that is what GetMonInfo is for). - // need to move to chancfg stuff instead (i.e. use the properties x/yorg's) when that is ready - HWND hWin = CreateWindow(pWindowClassName, props->_title.c_str(), - final_window_style, xleft,ytop,xsize,ysize, - _hParentWindow, NULL, hProgramInstance, 0); - - if(!hWin) { - wdxdisplay_cat.fatal() << "CreateWindow failed for device " << devnum << "!, LastError=" << GetLastError() << endl; - #ifdef _DEBUG - PrintErrorMessage(LAST_ERROR); - #endif - exit(1); - } - - _windows[devnum]->set_window_handle(hWin); - _windows[devnum]->_dxgsg->scrn.pProps = &_windows[devnum]->_props; - - if(devnum==0) - _hParentWindow=hWin; - } - -/* - } else { -// assert(_windows.size()==1); - - GraphicsWindow::Properties *props = &_windows[0]->_props; - - RECT win_rect; - SetRect(&win_rect, props->_xorg, props->_yorg, props->_xorg + props->_xsize, - props->_yorg + props->_ysize); - - if(props->_border) - window_style |= WS_OVERLAPPEDWINDOW; // should we just use WS_THICKFRAME instead? - - AdjustWindowRect(&win_rect, window_style, FALSE); //compute window size based on desired client area size - - // make sure origin is on screen - if(win_rect.left < 0) { - win_rect.right -= win_rect.left; win_rect.left = 0; - } - if(win_rect.top < 0) { - win_rect.bottom -= win_rect.top; win_rect.top = 0; - } - - _hParentWindow = - CreateWindow(WDX_WINDOWCLASSNAME, props->_title.c_str(), - window_style, - win_rect.left, win_rect.top, win_rect.right-win_rect.left,win_rect.bottom-win_rect.top, - NULL, NULL, hProgramInstance, 0); - _windows[0]->set_window_handle(_hParentWindow); - } - - if(_hParentWindow==NULL) { - wdxdisplay_cat.fatal() << "CreateWindow failed!\n"; - exit(1); - } -*/ - for(DWORD devnum=0;devnum<_windows.size();devnum++) { - wdxGraphicsWindow *pWDXWin = _windows[devnum]; - // for use by the window_proc - hwnd_pandawin_map[pWDXWin->_dxgsg->scrn.hWnd] = pWDXWin; - -/* - // DC is mostly used for writing fps meter (but also old palette code, which needs updating) - // probably only need to do this for devnum 0 - HDC hdc = GetDC(pWDXWin->_dxgsg_>scrn.hWnd); - pWDXWin->_dxgsg->Set_HDC(hdc); -*/ - } - - // now we can stop using the global_wdxwinptr crutch since windows are created - global_wdxwinptr = NULL; // get rid of any reference to this obj -} - -//////////////////////////////////////////////////////////////////// -// Function: config -// Access: -// Description: Set up win32 window. -//////////////////////////////////////////////////////////////////// -void wdxGraphicsWindow::config_window(wdxGraphicsWindowGroup *pParentGroup) { -// assert(_pParentWindowGroup==NULL); - _pParentWindowGroup=pParentGroup; - - GraphicsWindow::config(); - - _hdc = NULL; - _gsg = _dxgsg = NULL; - _exiting_window = false; - _window_active = true; - _return_control_to_app = false; - _active_minimized_fullscreen = false; - - if(_props._fullscreen || dx_full_screen) { - _props._fullscreen = dx_full_screen= true; - } - - _use_dx8_cursor = dx_use_dx_cursor; - if(!_props._fullscreen) - _use_dx8_cursor = false; - - _WindowAdjustingType = NotAdjusting; - _bSizeIsMaximized=FALSE; - - _gsg = _dxgsg = NULL; - // Create a GSG to manage the graphics - if(_gsg==NULL) { - make_gsg(); - if(_gsg==NULL) { - wdxdisplay_cat.error() << "make_gsg() failed!\n"; - exit(1); - } - } - _dxgsg = DCAST(DXGraphicsStateGuardian, _gsg); - _dxgsg->scrn.bIsDX81 = pParentGroup->_bIsDX81; - - // Check the version of the OS we are running. If we are running - // win2000, we must use ImmGetCompositionStringW() to report the - // characters returned by the IME, since WM_CHAR and - // ImmGetCompositionStringA() both just return question marks. - // However, this function doesn't work for Win98; on this OS, we - // have to use ImmGetCompositionStringA() instead, which returns an - // encoded string in shift-jis (which we then have to decode). - - // For now, this is user-configurable, to allow testing of this code - // on both OS's. After we verify that truth of the above claim, we - // should base this decision on GetVersionEx() or maybe - // VerifyVersionInfo(). - - _ime_composition_w = ime_composition_w; - - // need to re-evaluate above in light of this, it seems that - // ImmGetCompositionStringW should work on both: - // The Input Method Editor and Unicode Windows 98/Me, Windows - // NT/2000/XP: Windows supports a Unicode interface for the - // IME, in addition to the ANSI interface originally supported. - // Windows 98/Me supports all the Unicode functions except - // ImmIsUIMessage. Also, all the messages in Windows 98/Me are - // ANSI based. Since Windows 98/Me does not support Unicode - // messages, applications can use ImmGetCompositionString to - // receive Unicode characters from a Unicode based IME on - // Windows 98/Me. There are two issues involved with Unicode - // handling and the IME. One is that the Unicode versions of - // IME routines return the size of a buffer in bytes rather - // than 16-bit Unicode characters,and the other is the IME - // normally returns Unicode characters (rather than DBCS) in - // the WM_CHAR and WM_IME_CHAR messages. Use RegisterClassW - // to cause the WM_CHAR and WM_IME_CHAR messages to return - // Unicode characters in the wParam parameter rather than DBCS - // characters. This is only available under Windows NT; it is - // stubbed out in Windows 95/98/Me. -} - -void wdxGraphicsWindow::finish_window_setup(void) { - // Now indicate that we have our keyboard/mouse device ready. - GraphicsWindowInputDevice device = GraphicsWindowInputDevice::pointer_and_keyboard("keyboard/mouse"); - _input_devices.push_back(device); - - // move windows to top of zorder - HWND hWin = _dxgsg->scrn.hWnd; - - // call twice to override STARTUPINFO value, which may be set to hidden initially (by emacs for instance) - ShowWindow(hWin, SW_SHOWNORMAL); - ShowWindow(hWin, SW_SHOWNORMAL); - // UpdateWindow( _mwindow ); - SetWindowPos(hWin, HWND_TOP, 0,0,0,0, SWP_NOMOVE | SWP_NOSENDCHANGING | SWP_NOSIZE); -} - -// this handles external programmatic requests for resizing (usually fullscrn resize) -bool wdxGraphicsWindow::resize(unsigned int xsize,unsigned int ysize) { - bool bResizeSucceeded=false; - - if((xsize==_props._xsize)&&(ysize==_props._ysize)) { - if(wdxdisplay_cat.is_debug()) - wdxdisplay_cat.debug() << "redundant resize() called, returning\n"; - return true; - } - - if(!_props._fullscreen) { - if(wdxdisplay_cat.is_debug()) - wdxdisplay_cat.debug() << "resize("<scrn.hWnd,&wi); - AdjustWindowRectEx(&win_rect, wi.dwStyle, false, wi.dwExStyle); //compute window size based on desired client area size - - // make sure origin is on screen - if(win_rect.left < 0) { - win_rect.right -= win_rect.left; win_rect.left = 0; - _props._xorg=0; - } - if(win_rect.top < 0) { - win_rect.bottom -= win_rect.top; win_rect.top = 0; - _props._yorg=0; - } - - SetWindowPos(_dxgsg->scrn.hWnd, NULL, win_rect.left,win_rect.top, RECT_XSIZE(win_rect), RECT_YSIZE(win_rect), SWP_NOZORDER | SWP_NOSENDCHANGING); - // WM_ERASEBKGND will be ignored, because _WindowAdjustingType!=NotAdjusting because - // we dont want to redraw as user is manually resizing window, so need to force explicit - // background clear for the programmatic resize fn call - _WindowAdjustingType=NotAdjusting; - - //window_proc(_mwindow, WM_ERASEBKGND,(WPARAM)_hdc,0x0); // this doesnt seem to be working in toontown resize, so I put ddraw blackblt in handle_windowed_resize instead - - return handle_windowed_resize(_dxgsg->scrn.hWnd,true); - } - - assert(IS_VALID_PTR(_dxgsg)); - - if(wdxdisplay_cat.is_info()) - wdxdisplay_cat.info() << "fullscrn resize("<SetDXReady(false); - - bool bCouldntFindValidZBuf; - D3DFORMAT pixFmt; - bool bNeedZBuffer = (_dxgsg->scrn.PresParams.EnableAutoDepthStencil!=false); - bool bNeedStencilBuffer = IS_STENCIL_FORMAT(_dxgsg->scrn.PresParams.AutoDepthStencilFormat); - - bool bIsGoodMode=false; - - if(!special_check_fullscreen_resolution(xsize,ysize)) { - // bypass the lowvidmem test below for certain "lowmem" cards we know have valid modes - - // wdxdisplay_cat.info() << "1111111 lowvidmemcard="<< _dxgsg->scrn.bIsLowVidMemCard << endl; - if(_dxgsg->scrn.bIsLowVidMemCard && (!((xsize==640) && (ysize==480)))) { - wdxdisplay_cat.error() << "resize() failed: will not try to resize low vidmem device #" << _dxgsg->scrn.CardIDNum << " to non-640x480!\n"; - goto Error_Return; - } - } - - // must ALWAYS use search_for_valid_displaymode even if we know a-priori that res is valid so we can - // get a valid pixfmt - search_for_valid_displaymode(xsize,ysize,bNeedZBuffer,bNeedStencilBuffer, - &_dxgsg->scrn.SupportedScreenDepthsMask,&bCouldntFindValidZBuf, - &pixFmt); - bIsGoodMode=(pixFmt!=D3DFMT_UNKNOWN); - - if(!bIsGoodMode) { - wdxdisplay_cat.error() << "resize() failed: " - << (bCouldntFindValidZBuf ? "Couldnt find valid zbuffer format to go with FullScreen mode" : "No supported FullScreen modes") - << " at " << xsize << "x" << ysize << " for device #" << _dxgsg->scrn.CardIDNum <scrn.DisplayMode.Width=xsize; - _dxgsg->scrn.DisplayMode.Height=ysize; - _dxgsg->scrn.DisplayMode.Format = pixFmt; - _dxgsg->scrn.DisplayMode.RefreshRate = D3DPRESENT_RATE_DEFAULT; - - _dxgsg->scrn.PresParams.BackBufferFormat = pixFmt; // make reset_device_resize use presparams or displaymode?? - - // resized(xsize,ysize); not needed? - - bResizeSucceeded=reset_device_resize_window(xsize,ysize); - - if(!bResizeSucceeded) { - wdxdisplay_cat.error() << "resize() failed with OUT-OF-MEMORY error!\n"; - - if((!IS_16BPP_DISPLAY_FORMAT(_dxgsg->scrn.PresParams.BackBufferFormat)) && - (_dxgsg->scrn.SupportedScreenDepthsMask & (R5G6B5_FLAG|X1R5G5B5_FLAG))) { - // fallback strategy, if we trying >16bpp, fallback to 16bpp buffers - _dxgsg->scrn.DisplayMode.Format = ((_dxgsg->scrn.SupportedScreenDepthsMask & R5G6B5_FLAG) ? D3DFMT_R5G6B5 : D3DFMT_X1R5G5B5); - dx_force_16bpp_zbuffer=true; - if(wdxdisplay_cat.info()) - wdxdisplay_cat.info() << "CreateDevice failed with out-of-vidmem, retrying w/16bpp buffers on device #"<< _dxgsg->scrn.CardIDNum << endl; - - bResizeSucceeded= reset_device_resize_window(xsize,ysize); // create the new resized rendertargets - } - } - - Error_Return: - - _dxgsg->SetDXReady(true); - - if(wdxdisplay_cat.is_debug()) - wdxdisplay_cat.debug() << "fullscrn resize("<scrn.DXDeviceID.VendorId; - DWORD DeviceId=_dxgsg->scrn.DXDeviceID.DeviceId; - switch(VendorId) { - case 0x8086: // Intel - /*for now, just validate all the intel cards at these resolutions. - I dont have a complete list of intel deviceIDs (missing 82830, 845, etc) - // Intel i810,i815,82810 - if((DeviceId==0x7121)||(DeviceId==0x7123)||(DeviceId==0x7125)|| - (DeviceId==0x1132)) - */ - { - if((xsize==640)&&(ysize==480)) - return true; - if((xsize==800)&&(ysize==600)) - return true; - if((xsize==1024)&&(ysize==768)) - return true; - } - break; - } - - return false; -} - -UINT wdxGraphicsWindow:: -verify_window_sizes(UINT numsizes,UINT *dimen) { - // unfortunately this only works AFTER you make the window initially, - // so its really mostly useful for resizes only - assert(IS_VALID_PTR(_dxgsg)); - - UINT num_valid_modes=0; - - // not requesting same refresh rate since changing res might not support same refresh rate at new size - - UINT *pCurDim=(UINT *)dimen; - - for(UINT i=0;iscrn.bIsLowVidMemCard) { - bIsGoodMode=((xsize==640) && (ysize==480)); - } else { - search_for_valid_displaymode(xsize,ysize,_dxgsg->scrn.PresParams.EnableAutoDepthStencil!=false, - IS_STENCIL_FORMAT(_dxgsg->scrn.PresParams.AutoDepthStencilFormat), - &_dxgsg->scrn.SupportedScreenDepthsMask,&CouldntFindAnyValidZBuf, - &newPixFmt); - bIsGoodMode=(newPixFmt!=D3DFMT_UNKNOWN); - } - } - - if(bIsGoodMode) { - num_valid_modes++; - } else { - // tell caller the mode is invalid - pCurDim[0] = 0; - pCurDim[1] = 0; - } - - if(wdxdisplay_cat.is_spam()) - wdxdisplay_cat.spam() << "Fullscrn Mode (" << xsize << "," << ysize << ")\t" << (bIsGoodMode ? "V" : "Inv") <<"alid\n"; - } - - return num_valid_modes; -} - -BOOL WINAPI DX7_DriverEnumCallback( GUID* pGUID, TCHAR* strDesc,TCHAR* strName,VOID *argptr, HMONITOR hm) { -// #define PRNT(XX) ((XX!=NULL) ? XX : "NULL") -// cout << "strDesc: "<< PRNT(strDesc) << " strName: "<< PRNT(strName)<push_back(CurCardID); - return DDENUMRET_OK; -} - -void wdxGraphicsWindowGroup:: -find_all_card_memavails(void) { - if(g_pCardIDVec!=NULL) // we've already got the info - return; - - #define DDRAW_NAME "ddraw.dll" - - HINSTANCE hDDrawDLL = LoadLibrary(DDRAW_NAME); - if(hDDrawDLL == 0) { - wdxdisplay_cat.fatal() << "LoadLibrary(" << DDRAW_NAME <<") failed!, error=" << GetLastError() << endl; - exit(1); - } - - LPDIRECTDRAWCREATEEX pDDCreateEx; - - pDDCreateEx = (LPDIRECTDRAWCREATEEX) GetProcAddress(hDDrawDLL,"DirectDrawCreateEx"); - if(pDDCreateEx == NULL) { - wdxdisplay_cat.fatal() << "GetProcAddr failed for DDCreateEx" << endl; - exit(1); - } - - LPDIRECTDRAWENUMERATEEX pDDEnumEx = (LPDIRECTDRAWENUMERATEEX) GetProcAddress(hDDrawDLL,"DirectDrawEnumerateExA"); - if(pDDEnumEx == NULL) { - wdxdisplay_cat.fatal() << "GetProcAddr failed for DirectDrawEnumerateEx! (win95 system?)\n"; - exit(1); - } - - HRESULT hr = (*pDDEnumEx)(DX7_DriverEnumCallback, NULL, DDENUM_ATTACHEDSECONDARYDEVICES | DDENUM_NONDISPLAYDEVICES); - if(FAILED(hr)) { - wdxdisplay_cat.fatal() << "DirectDrawEnumerateEx failed" << D3DERRORSTRING(hr); - exit(1); - } - - if(g_pCardIDVec==NULL) { - wdxdisplay_cat.error() << "DirectDrawEnumerateEx enum'ed no devices!\n"; - return; - } - - GUID ZeroGUID; - ZeroMemory(&ZeroGUID,sizeof(GUID)); - - if(g_pCardIDVec->size()>1) { - assert(IsEqualGUID(ZeroGUID,(*g_pCardIDVec)[0].DX7_DeviceGUID)); - // delete enum of primary display (always the first), since it is duplicated by explicit entry - g_pCardIDVec->erase(g_pCardIDVec->begin()); - } - - for(UINT i=0;isize();i++) { - LPDIRECTDRAW7 pDD; - BYTE ddd_space[sizeof(DDDEVICEIDENTIFIER2)+4]; //bug in DX7 requires 4 extra bytes for GetDeviceID - DDDEVICEIDENTIFIER2 *pDX7DeviceID=(DDDEVICEIDENTIFIER2 *)&ddd_space[0]; - GUID *pGUID= &((*g_pCardIDVec)[i].DX7_DeviceGUID); - - if(IsEqualGUID(*pGUID,ZeroGUID)) - pGUID=NULL; - - // Create the Direct Draw Object - hr = (*pDDCreateEx)(pGUID,(void **)&pDD, IID_IDirectDraw7, NULL); - if(FAILED(hr)) { - wdxdisplay_cat.fatal() << "DirectDrawCreateEx failed for device ("<< i << ")" << D3DERRORSTRING(hr); - continue; - } - - ZeroMemory(ddd_space,sizeof(DDDEVICEIDENTIFIER2)); - - hr = pDD->GetDeviceIdentifier(pDX7DeviceID,0x0); - if(FAILED(hr)) { - wdxdisplay_cat.fatal() << "GetDeviceID failed for device ("<< i << ")" << D3DERRORSTRING(hr); - continue; - } - - (*g_pCardIDVec)[i].DeviceID = pDX7DeviceID->dwDeviceId; - (*g_pCardIDVec)[i].VendorID = pDX7DeviceID->dwVendorId; - - // Get Current VidMem avail. Note this is only an estimate, when we switch to fullscreen - // mode from desktop, more vidmem will be available (typically 1.2 meg). I dont want - // to switch to fullscreen more than once due to the annoying monitor flicker, so try - // to figure out optimal mode using this estimate - DDSCAPS2 ddsGAVMCaps; - DWORD dwVidMemTotal,dwVidMemFree; - dwVidMemTotal=dwVidMemFree=0; - { - // print out total INCLUDING AGP just for information purposes and future use - // The real value I'm interested in for purposes of measuring possible valid screen sizes - // shouldnt include AGP - ZeroMemory(&ddsGAVMCaps,sizeof(DDSCAPS2)); - ddsGAVMCaps.dwCaps = DDSCAPS_VIDEOMEMORY; - - if(FAILED(hr = pDD->GetAvailableVidMem(&ddsGAVMCaps,&dwVidMemTotal,&dwVidMemFree))) { - wdxdisplay_cat.error() << "GetAvailableVidMem failed for device #"<< i << D3DERRORSTRING(hr); - // goto skip_device; - exit(1); // probably want to exit, since it may be my fault - } - } - wdxdisplay_cat.info() << "GetAvailableVidMem (including AGP) returns Total: "<GetAvailableVidMem(&ddsGAVMCaps,&dwVidMemTotal,&dwVidMemFree))) { - wdxdisplay_cat.error() << "GetAvailableVidMem failed for device #"<< i<< D3DERRORSTRING(hr); - // goto skip_device; - exit(1); // probably want to exit, since it may be my fault - } - - wdxdisplay_cat.info() << "GetAvailableVidMem (no AGP) returns Total: "<Release(); // release DD obj, since this is all we needed it for - - if(!dx_do_vidmemsize_check) { - // still calling the DD stuff to get deviceID, etc. is this necessary? - (*g_pCardIDVec)[i].MaxAvailVidMem = UNKNOWN_VIDMEM_SIZE; - (*g_pCardIDVec)[i].bIsLowVidMemCard = false; - continue; - } - - if(dwVidMemTotal==0) { // unreliable driver - dwVidMemTotal=UNKNOWN_VIDMEM_SIZE; - } else { - if(!ISPOW2(dwVidMemTotal)) { - // assume they wont return a proper max value, so - // round up to next pow of 2 - UINT count=0; - while((dwVidMemTotal >> count)!=0x0) - count++; - dwVidMemTotal = (1 << count); - } - } - - // after SetDisplayMode, GetAvailVidMem totalmem seems to go down by 1.2 meg (contradicting above - // comment and what I think would be correct behavior (shouldnt FS mode release the desktop vidmem?), - // so this is the true value - (*g_pCardIDVec)[i].MaxAvailVidMem = dwVidMemTotal; - - // I can never get this stuff to work reliably, so I'm just rounding up to nearest pow2. - // Could try to get HardwareInformation.MemorySize MB number from registry like video control panel, - // but its not clear how to find the proper registry location for a given card - - // #define LOWVIDMEMTHRESHOLD 3500000 - // #define CRAPPY_DRIVER_IS_LYING_VIDMEMTHRESHOLD 1000000 - - #define LOWVIDMEMTHRESHOLD 5700000 // 4MB cards should fall below this - #define CRAPPY_DRIVER_IS_LYING_VIDMEMTHRESHOLD 1000000 // if # is > 1MB, card is lying and I cant tell what it is - - // assume buggy drivers (this means you, FireGL2) may return zero (or small amts) for dwVidMemTotal, so ignore value if its < CRAPPY_DRIVER_IS_LYING_VIDMEMTHRESHOLD - bool bLowVidMemFlag = ((dwVidMemTotal>CRAPPY_DRIVER_IS_LYING_VIDMEMTHRESHOLD) && (dwVidMemTotal< LOWVIDMEMTHRESHOLD)); - - (*g_pCardIDVec)[i].bIsLowVidMemCard = bLowVidMemFlag; - wdxdisplay_cat.info() << "SetLowVidMem flag to "<< bLowVidMemFlag<< " based on adjusted VidMemTotal: " <=0x5100) && (_DXDeviceID.dwDeviceId<=0x5200)) || - (_DXDeviceID.dwDeviceId>=0x6000)) - bSupportsColorCursor=true; - } else if IS_MATROX(_DXDeviceID) { - if(_DXDeviceID.dwDeviceId==0x0525) // G400 seems to support color cursors, havent tested other matrox - bSupportsColorCursor=true; - } - - // TODO: add more cards as more testing is done - - if(bSupportsColorCursor) { - // Note: LoadImage seems to cause win2k internal heap corruption (outputdbgstr warnings) - // if icon is more than 8bpp - - DWORD load_flags = LR_LOADFROMFILE; - - if(_props._fullscreen) { - // I think cursors should use LR_CREATEDIBSECTION since they should not be mapped to the device palette (in the case of 256-color cursors) - // since they are not going to be used on the desktop - load_flags |= LR_CREATEDIBSECTION; - } - - // loads a .cur fmt file. - HCURSOR hNewMouseCursor = (HCURSOR) LoadImage(NULL, windows_color_cursor_filename.c_str(), IMAGE_CURSOR, 0, 0, load_flags ); - - if(hNewMouseCursor==NULL) { - wdxdisplay_cat.warning() << "windows color cursor filename '" << windows_color_cursor_filename << "' not found!!\n"; - return; - } - - SetClassLongPtr(_mwindow, GCLP_HCURSOR, (LONG_PTR) hNewMouseCursor); - SetCursor(hNewMouseCursor); - - if(_bLoadedCustomCursor) - DestroyCursor(_hMouseCursor); - _hMouseCursor = hNewMouseCursor; - } -} -*/ - -int D3DFMT_to_DepthBits(D3DFORMAT fmt) { - switch(fmt) { - case D3DFMT_D16: return 16; - case D3DFMT_D24X8: - case D3DFMT_D24X4S4: - case D3DFMT_D24S8: return 24; - case D3DFMT_D32: return 32; - case D3DFMT_D15S1: return 15; - default: - wdxdisplay_cat.debug() << "D3DFMT_DepthBits: unhandled D3DFMT!\n"; - return 0; - } -} - -bool wdxGraphicsWindow::FindBestDepthFormat(DXScreenData &Display,D3DDISPLAYMODE &TestDisplayMode,D3DFORMAT *pBestFmt,bool bWantStencil,bool bForce16bpp,bool bVerboseMode) const { - // list fmts in order of preference - #define NUM_TEST_ZFMTS 3 - static D3DFORMAT NoStencilPrefList[NUM_TEST_ZFMTS]={D3DFMT_D32,D3DFMT_D24X8,D3DFMT_D16}; - static D3DFORMAT StencilPrefList[NUM_TEST_ZFMTS]={D3DFMT_D24S8,D3DFMT_D24X4S4,D3DFMT_D15S1}; - - // do not use Display.DisplayMode since that is probably not set yet, use TestDisplayMode instead - - // int want_color_bits = _props._want_color_bits; - // int want_depth_bits = _props._want_depth_bits; should we pay attn to these so panda user can select bitdepth? - - *pBestFmt = D3DFMT_UNKNOWN; - HRESULT hr; - - // nvidia likes zbuf depth to match rendertarget depth - bool bOnlySelect16bpp= (dx_force_16bpp_zbuffer || bForce16bpp || - (IS_NVIDIA(Display.DXDeviceID) && IS_16BPP_DISPLAY_FORMAT(TestDisplayMode.Format))); - - if(bVerboseMode) - wdxdisplay_cat.info() << "FindBestDepthFmt: bSelectOnly16bpp: " << bOnlySelect16bpp << endl; - - for(int i=0;iCheckDeviceFormat(Display.CardIDNum,D3DDEVTYPE_HAL,TestDisplayMode.Format, - D3DUSAGE_DEPTHSTENCIL,D3DRTYPE_SURFACE,TestDepthFmt); - - if(FAILED(hr)) { - if(hr==D3DERR_NOTAVAILABLE) { - if(bVerboseMode) - wdxdisplay_cat.info() << "FindBestDepthFmt: ChkDevFmt returns NotAvail for " << D3DFormatStr(TestDepthFmt) << endl; - continue; - } - - wdxdisplay_cat.error() << "unexpected CheckDeviceFormat failure" << D3DERRORSTRING(hr); - exit(1); - } - - hr = Display.pD3D8->CheckDepthStencilMatch(Display.CardIDNum,D3DDEVTYPE_HAL, - TestDisplayMode.Format, // adapter format - TestDisplayMode.Format, // backbuffer fmt (should be the same in my apps) - TestDepthFmt); - if(SUCCEEDED(hr)) { - *pBestFmt = TestDepthFmt; - break; - } else { - if(hr==D3DERR_NOTAVAILABLE) { - if(bVerboseMode) - wdxdisplay_cat.info() << "FindBestDepthFmt: ChkDepMatch returns NotAvail for " << D3DFormatStr(TestDisplayMode.Format) << ", " << D3DFormatStr(TestDepthFmt) << endl; - } else { - wdxdisplay_cat.error() << "unexpected CheckDepthStencilMatch failure for " << D3DFormatStr(TestDisplayMode.Format) << ", " << D3DFormatStr(TestDepthFmt) << endl; - exit(1); - } - } - } - - if(bVerboseMode) - wdxdisplay_cat.info() << "FindBestDepthFmt returns fmt " << D3DFormatStr(*pBestFmt) << endl; - - return (*pBestFmt != D3DFMT_UNKNOWN); -} - -// all ptr args are output parameters -// if no valid mode found, returns *pSuggestedPixFmt = D3DFMT_UNKNOWN; -void wdxGraphicsWindow::search_for_valid_displaymode(UINT RequestedXsize,UINT RequestedYsize,bool bWantZBuffer,bool bWantStencil, - UINT *pSupportedScreenDepthsMask,bool *pCouldntFindAnyValidZBuf, - D3DFORMAT *pSuggestedPixFmt, bool bVerboseMode) { - assert(IS_VALID_PTR(_dxgsg)); - assert(IS_VALID_PTR(_dxgsg->scrn.pD3D8)); - HRESULT hr; - - #ifndef NDEBUG -// no longer true, due to special_check_fullscreen_res, where lowvidmem cards are allowed higher resolutions -// if(_dxgsg->scrn.bIsLowVidMemCard) -// nassertv((RequestedXsize==640)&&(RequestedYsize==480)); - #endif - - *pSuggestedPixFmt = D3DFMT_UNKNOWN; - *pSupportedScreenDepthsMask = 0x0; - *pCouldntFindAnyValidZBuf=false; - - int cNumModes=_dxgsg->scrn.pD3D8->GetAdapterModeCount(_dxgsg->scrn.CardIDNum); - D3DDISPLAYMODE BestDispMode; - ZeroMemory(&BestDispMode,sizeof(BestDispMode)); - - if(bVerboseMode) - wdxdisplay_cat.info() << "searching for valid display modes at res: (" << RequestedXsize << "," << RequestedYsize << "), TotalModes: " << cNumModes<< endl; - - // ignore memory based checks for min res 640x480. some cards just dont give accurate memavails. - // (should I do the check anyway for 640x480 32bpp?) - bool bDoMemBasedChecks=((!((RequestedXsize==640)&&(RequestedYsize==480))) && - (_dxgsg->scrn.MaxAvailVidMem!=UNKNOWN_VIDMEM_SIZE) && - (!special_check_fullscreen_resolution(RequestedXsize,RequestedYsize))); - - if(bVerboseMode || wdxdisplay_cat.is_spam()) { - wdxdisplay_cat.info() << "DoMemBasedChecks = " << bDoMemBasedChecks << endl; - } - - for(int i=0;iscrn.pD3D8->EnumAdapterModes(_dxgsg->scrn.CardIDNum,i,&dispmode); - if(FAILED(hr)) { - wdxdisplay_cat.error() << "EnumAdapterDisplayMode failed for device #"<<_dxgsg->scrn.CardIDNum<< D3DERRORSTRING(hr); - exit(1); - } - - if((dispmode.Width!=RequestedXsize) || (dispmode.Height!=RequestedYsize)) - continue; - - if((dispmode.RefreshRate<60) && (dispmode.RefreshRate>1)) { - // dont want refresh rates under 60Hz, but 0 or 1 might indicate a default refresh rate, which is usually >=60 - if(bVerboseMode) - wdxdisplay_cat.info() << "skipping mode["<scrn.pD3D8->CheckDeviceFormat(_dxgsg->scrn.CardIDNum,D3DDEVTYPE_HAL,dispmode.Format, - D3DUSAGE_RENDERTARGET,D3DRTYPE_SURFACE,dispmode.Format); - if(FAILED(hr)) { - if(hr==D3DERR_NOTAVAILABLE) { - if(bVerboseMode) - wdxdisplay_cat.info() << "skipping mode["<scrn.CardIDNum << D3DERRORSTRING(hr); - exit(1); - } - } - - bool bIs16bppRenderTgt = IS_16BPP_DISPLAY_FORMAT(dispmode.Format); - float RendTgtMinMemReqmt; - - // if we have a valid memavail value, try to determine if we have enough space - if( bDoMemBasedChecks) { - - // assume user is testing fullscreen, not windowed, so use the dwTotal value - // see if 3 scrnbufs (front/back/z)at 16bpp at xsize*ysize will fit with a few - // extra megs for texmem - - // 8MB Rage Pro says it has 6.8 megs Total free and will run at 1024x768, so - // formula makes it so that is OK - - #define REQD_TEXMEM 1800000 - - float bytes_per_pixel = (bIs16bppRenderTgt ? 2 : 4); - assert(_props._mask & W_DOUBLE); - - // *2 for double buffer - - RendTgtMinMemReqmt = ((float)RequestedXsize)*((float)RequestedYsize)*bytes_per_pixel*2+REQD_TEXMEM; - - if(bVerboseMode || wdxdisplay_cat.is_spam()) - wdxdisplay_cat.info() << "Testing Mode (" <scrn.MaxAvailVidMem << endl; - - if(RendTgtMinMemReqmt>_dxgsg->scrn.MaxAvailVidMem) { - if(bVerboseMode || wdxdisplay_cat.is_debug()) - wdxdisplay_cat.info() << "not enough VidMem for render tgt, skipping display fmt " << D3DFormatStr(dispmode.Format) - << " (" << (int)RendTgtMinMemReqmt << " > " << _dxgsg->scrn.MaxAvailVidMem << ")\n"; - continue; - } - } - - if(bWantZBuffer) { - D3DFORMAT zformat; - if(!FindBestDepthFormat(_dxgsg->scrn,dispmode,&zformat,bWantStencil,false)) { - *pCouldntFindAnyValidZBuf=true; - continue; - } - - float MinMemReqmt = 0.0f; - - if(bDoMemBasedChecks) { - // test memory again, this time including zbuf size - float zbytes_per_pixel = (IS_16BPP_ZBUFFER(zformat) ? 2 : 4); - float MinMemReqmt = RendTgtMinMemReqmt + ((float)RequestedXsize)*((float)RequestedYsize)*zbytes_per_pixel; - - if(bVerboseMode || wdxdisplay_cat.is_spam()) - wdxdisplay_cat.info() << "Testing Mode w/Z (" << RequestedXsize << "x" << RequestedYsize << "," - << D3DFormatStr(dispmode.Format) << ")\nReqdVidMem: "<< (int)MinMemReqmt << " AvailVidMem: " << _dxgsg->scrn.MaxAvailVidMem << endl; - - if(MinMemReqmt>_dxgsg->scrn.MaxAvailVidMem) { - if(bVerboseMode || wdxdisplay_cat.is_debug()) - wdxdisplay_cat.info() << "not enough VidMem for RendTgt+zbuf, skipping display fmt " << D3DFormatStr(dispmode.Format) - << " (" << (int)MinMemReqmt << " > " << _dxgsg->scrn.MaxAvailVidMem << ")\n"; - continue; - } - } - - if((!bDoMemBasedChecks) || (MinMemReqmt<_dxgsg->scrn.MaxAvailVidMem)) { - if(!IS_16BPP_ZBUFFER(zformat)) { - // see if things fit with a 16bpp zbuffer - - if(!FindBestDepthFormat(_dxgsg->scrn,dispmode,&zformat,bWantStencil,true,bVerboseMode)) { - if(bVerboseMode) - wdxdisplay_cat.info() << "FindBestDepthFmt rejected Mode["<VendorId==0x00008086) - return true; - - return false; -} - -// returns true if successful -bool wdxGraphicsWindow::search_for_device(LPDIRECT3D8 pD3D8,DXDeviceInfo *pDevInfo) { - DWORD dwRenderWidth = _props._xsize; - DWORD dwRenderHeight = _props._ysize; - HRESULT hr; - - assert(_dxgsg!=NULL); - _dxgsg->scrn.pD3D8 = pD3D8; - _dxgsg->scrn.CardIDNum=pDevInfo->cardID; // could this change by end? - - bool bWantStencil = ((_props._mask & W_STENCIL)!=0); - - hr = pD3D8->GetAdapterIdentifier(pDevInfo->cardID,D3DENUM_NO_WHQL_LEVEL,&_dxgsg->scrn.DXDeviceID); - if(FAILED(hr)) { - wdxdisplay_cat.fatal() << "D3D GetAdapterID failed" << D3DERRORSTRING(hr); - } - - D3DCAPS8 d3dcaps; - hr = pD3D8->GetDeviceCaps(pDevInfo->cardID,D3DDEVTYPE_HAL,&d3dcaps); - if(FAILED(hr)) { - if((hr==D3DERR_INVALIDDEVICE)||(hr==D3DERR_NOTAVAILABLE)) { - wdxdisplay_cat.fatal() << "No DirectX 8 D3D-capable 3D hardware detected for device # "<cardID<<" ("<szDescription << ")! Exiting...\n"; - } else { - wdxdisplay_cat.fatal() << "GetDeviceCaps failed" << D3DERRORSTRING(hr); - } - exit(1); - } - - //search_for_valid_displaymode needs these to be set - memcpy(&_dxgsg->scrn.d3dcaps,&d3dcaps,sizeof(D3DCAPS8)); - _dxgsg->scrn.CardIDNum=pDevInfo->cardID; - - _dxgsg->scrn.MaxAvailVidMem = UNKNOWN_VIDMEM_SIZE; - _dxgsg->scrn.bIsLowVidMemCard = false; - - // bugbug: wouldnt we like to do GetAVailVidMem so we can do upper-limit memory computation for dx8 cards too? - // otherwise verify_window_sizes cant do much - if((d3dcaps.MaxStreams==0)|| dx_pick_best_screenres) { - if(wdxdisplay_cat.is_debug()) - wdxdisplay_cat.debug() << "checking vidmem size\n"; - assert(IS_VALID_PTR(_pParentWindowGroup)); - - // look for low memory video cards - _pParentWindowGroup->find_all_card_memavails(); - - UINT IDnum; - - // simple linear search to match DX7 card info w/DX8 card ID - for(IDnum=0;IDnumsize();IDnum++) { -// wdxdisplay_cat.info() << "comparing '" << (*g_pCardIDVec)[IDnum].Driver << "' to '" << _dxgsg->scrn.DXDeviceID.Driver << "'\n"; - if(//(stricmp((*g_pCardIDVec)[IDnum].szDriver,pDevInfo->szDriver)==0) && - (pDevInfo->VendorID==(*g_pCardIDVec)[IDnum].VendorID) && - (pDevInfo->DeviceID==(*g_pCardIDVec)[IDnum].DeviceID) && - (pDevInfo->hMon==(*g_pCardIDVec)[IDnum].hMon)) - break; - } - - if(IDnumsize()) { - _dxgsg->scrn.MaxAvailVidMem = (*g_pCardIDVec)[IDnum].MaxAvailVidMem; - _dxgsg->scrn.bIsLowVidMemCard = (*g_pCardIDVec)[IDnum].bIsLowVidMemCard; - } else wdxdisplay_cat.error() << "Error: couldnt find a CardID match in DX7 info, assuming card is not a lowmem card\n"; - } - - if((bWantStencil) && (d3dcaps.StencilCaps==0x0)) { - wdxdisplay_cat.fatal() << "Stencil ability requested, but device #" << pDevInfo->cardID << " (" << _dxgsg->scrn.DXDeviceID.Description<<"), has no stencil capability!\n"; - exit(1); - } - - // just because TNL is true, it doesnt mean vtx shaders are supported in HW (see GF2) - // for this case, you probably want MIXED processing to use HW for fixed-fn vertex processing - // and SW for vtx shaders - _dxgsg->scrn.bIsTNLDevice=((d3dcaps.DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT)!=0); - _dxgsg->scrn.bCanUseHWVertexShaders = (d3dcaps.VertexShaderVersion >= D3DVS_VERSION(1,0)); - _dxgsg->scrn.bCanUsePixelShaders = (d3dcaps.PixelShaderVersion >= D3DPS_VERSION(1,0)); - - bool bNeedZBuffer = ((!(d3dcaps.RasterCaps & D3DPRASTERCAPS_ZBUFFERLESSHSR )) - && (_props._mask & W_DEPTH)); - - _dxgsg->scrn.PresParams.EnableAutoDepthStencil=bNeedZBuffer; - - D3DFORMAT pixFmt=D3DFMT_UNKNOWN; - - if(_props._fullscreen) { - _props._xorg = _props._yorg = 0; - - bool bCouldntFindValidZBuf; - if(!_dxgsg->scrn.bIsLowVidMemCard) { - bool bUseDefaultSize=dx_pick_best_screenres&& - ((_dxgsg->scrn.MaxAvailVidMem == UNKNOWN_VIDMEM_SIZE) || - is_badvidmem_card(&_dxgsg->scrn.DXDeviceID)); - - if(dx_pick_best_screenres && !bUseDefaultSize) { - typedef struct { - UINT memlimit; - DWORD scrnX,scrnY; - } Memlimres; - - const Memlimres MemRes[] = { - { 0, 640, 480}, - { 8000000, 800, 600}, - #if 0 - {16000000, 1024, 768}, - {32000000, 1280,1024}, // 32MB+ cards will choose this - #else - // unfortunately the 32MB card perf varies greatly (TNT2-GF2), - // so we need to be conservative since frame rate difference - // can change from 15->30fps when going from 1280x1024->800x600 - // on low-end 32mb cards - {16000000, 800, 600}, - {32000000, 800, 600}, // 32MB+ cards will choose this - #endif - // some monitors have trouble w/1600x1200, so dont pick this by deflt, - // even though 64MB cards should handle it - {64000000, 1280,1024} // 64MB+ cards will choose this - }; - const NumResLims = (sizeof(MemRes)/sizeof(Memlimres)); - - for(int i=NumResLims-1;i>=0;i--) { - // find biggest slot card can handle - if(_dxgsg->scrn.MaxAvailVidMem > MemRes[i].memlimit) { - dwRenderWidth=MemRes[i].scrnX; - dwRenderHeight=MemRes[i].scrnY; - - wdxdisplay_cat.info() << "pick_best_screenres: trying " << dwRenderWidth << "x" << dwRenderHeight << " based on " << _dxgsg->scrn.MaxAvailVidMem << " bytes avail\n"; - - search_for_valid_displaymode(dwRenderWidth,dwRenderHeight,bNeedZBuffer,bWantStencil, - &_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) - break; - - wdxdisplay_cat.info() << "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; - } - } - // otherwise just go with whatever was specified (we probably shouldve marked this card as lowmem if it gets to end of loop w/o breaking - } - - if(pixFmt==D3DFMT_UNKNOWN) { - - if(bUseDefaultSize) { - wdxdisplay_cat.info() << "pick_best_screenres: defaulted 800x600 based on no reliable vidmem size\n"; - dwRenderWidth=800; dwRenderHeight=600; - } - - search_for_valid_displaymode(dwRenderWidth,dwRenderHeight,bNeedZBuffer,bWantStencil, - &_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") - << " at " << dwRenderWidth << "x" << dwRenderHeight << " for device #" << _dxgsg->scrn.CardIDNum <scrn.SupportedScreenDepthsMask, - &bCouldntFindValidZBuf, - &pixFmt,true); - return false; - } - } - } else { - // Low Memory card - dwRenderWidth=640; - dwRenderHeight=480; - dx_force_16bpptextures = true; - - // force 16bpp zbuf? or let user get extra bits if they have the mem? - - search_for_valid_displaymode(dwRenderWidth,dwRenderHeight,bNeedZBuffer,bWantStencil, - &_dxgsg->scrn.SupportedScreenDepthsMask, - &bCouldntFindValidZBuf, - &pixFmt); - - // hack: figuring out exactly what res to use is tricky, instead I will - // just use 640x480 if we have < 3 meg avail - - if(_dxgsg->scrn.SupportedScreenDepthsMask & R5G6B5_FLAG) - pixFmt = D3DFMT_R5G6B5; - else if(_dxgsg->scrn.SupportedScreenDepthsMask & X1R5G5B5_FLAG) - pixFmt = D3DFMT_X1R5G5B5; - else { - wdxdisplay_cat.fatal() << "Low Memory VidCard has no supported FullScreen 16bpp resolutions at "<< dwRenderWidth << "x" << dwRenderHeight - << " for device #" << pDevInfo->cardID << " (" << _dxgsg->scrn.DXDeviceID.Description <<"), skipping device...\n"; - - // run it again in verbose mode to get more dbg info to log - search_for_valid_displaymode(dwRenderWidth,dwRenderHeight,bNeedZBuffer,bWantStencil, - &_dxgsg->scrn.SupportedScreenDepthsMask, - &bCouldntFindValidZBuf, - &pixFmt,true); - return false; - } - - if(wdxdisplay_cat.is_info()) - wdxdisplay_cat.info() << "Available VidMem (" << _dxgsg->scrn.MaxAvailVidMem << ") is under " << LOWVIDMEMTHRESHOLD <<", using 640x480 16bpp rendertargets to save tex vidmem.\n"; - } - } else { - // Windowed Mode - - D3DDISPLAYMODE dispmode; - hr=pD3D8->GetAdapterDisplayMode(pDevInfo->cardID,&dispmode); - if(FAILED(hr)) { - wdxdisplay_cat.fatal() << "GetAdapterDisplayMode(" << pDevInfo->cardID << ") failed" << D3DERRORSTRING(hr); - exit(1); - } - pixFmt = dispmode.Format; - } - - _dxgsg->scrn.DisplayMode.Width=dwRenderWidth; - _dxgsg->scrn.DisplayMode.Height=dwRenderHeight; - _dxgsg->scrn.DisplayMode.Format = pixFmt; - _dxgsg->scrn.DisplayMode.RefreshRate = D3DPRESENT_RATE_DEFAULT; - _dxgsg->scrn.hMon=pDevInfo->hMon; - return true; -} - -//return true if successful -void wdxGraphicsWindow:: -CreateScreenBuffersAndDevice(DXScreenData &Display) { - - // only want this to apply to initial startup - dx_pick_best_screenres=false; - - DWORD dwRenderWidth=Display.DisplayMode.Width; - DWORD dwRenderHeight=Display.DisplayMode.Height; - LPDIRECT3D8 pD3D8=Display.pD3D8; - D3DCAPS8 *pD3DCaps = &Display.d3dcaps; - D3DPRESENT_PARAMETERS* pPresParams = &Display.PresParams; - RECT view_rect; - HRESULT hr; - bool bWantStencil = ((_props._mask & W_STENCIL)!=0); - - assert(pD3D8!=NULL); - assert(pD3DCaps->DevCaps & D3DDEVCAPS_HWRASTERIZATION); - - #ifndef NDEBUG - if(!(_props._mask & W_DEPTH)) { - wdxdisplay_cat.info() << "no zbuffer requested, skipping zbuffer creation\n"; - } - #endif - - pPresParams->BackBufferFormat = Display.DisplayMode.Format; // dont need dest alpha, so just use adapter format - - if(dx_sync_video && !(pD3DCaps->Caps & D3DCAPS_READ_SCANLINE)) { - wdxdisplay_cat.info() << "HW doesnt support syncing to vertical refresh, ignoring dx_sync_video\n"; - dx_sync_video=false; - } - - // verify the rendertarget fmt one last time - if(FAILED(pD3D8->CheckDeviceFormat(Display.CardIDNum, D3DDEVTYPE_HAL, Display.DisplayMode.Format,D3DUSAGE_RENDERTARGET, - D3DRTYPE_SURFACE, pPresParams->BackBufferFormat))) { - wdxdisplay_cat.error() << "device #"<BackBufferFormat) << endl; - goto Fallback_to_16bpp_buffers; - } - - if(FAILED(pD3D8->CheckDeviceType(Display.CardIDNum,D3DDEVTYPE_HAL, Display.DisplayMode.Format,pPresParams->BackBufferFormat, - _props._fullscreen))) { - wdxdisplay_cat.error() << "device #"<BackBufferFormat) << endl; - goto Fallback_to_16bpp_buffers; - } - - if(Display.PresParams.EnableAutoDepthStencil) { - if(!FindBestDepthFormat(Display,Display.DisplayMode,&Display.PresParams.AutoDepthStencilFormat,bWantStencil,false)) { - wdxdisplay_cat.error() << "FindBestDepthFormat failed in CreateScreenBuffers for device #"<Windowed = !_props._fullscreen; - - if(dx_multisample_antialiasing_level>1) { - // need to check both rendertarget and zbuffer fmts - hr = pD3D8->CheckDeviceMultiSampleType(Display.CardIDNum, D3DDEVTYPE_HAL, Display.DisplayMode.Format, - _props._fullscreen, D3DMULTISAMPLE_TYPE(dx_multisample_antialiasing_level)); - if(FAILED(hr)) { - wdxdisplay_cat.fatal() << "device #"<CheckDeviceMultiSampleType(Display.CardIDNum, D3DDEVTYPE_HAL, Display.PresParams.AutoDepthStencilFormat, - _props._fullscreen, D3DMULTISAMPLE_TYPE(dx_multisample_antialiasing_level)); - if(FAILED(hr)) { - wdxdisplay_cat.fatal() << "device #"<MultiSampleType = D3DMULTISAMPLE_TYPE(dx_multisample_antialiasing_level); - - if(wdxdisplay_cat.is_info()) - wdxdisplay_cat.info() << "device #"<BackBufferCount = 1; - pPresParams->Flags = 0x0; - pPresParams->hDeviceWindow = Display.hWnd; - pPresParams->BackBufferWidth = Display.DisplayMode.Width; - pPresParams->BackBufferHeight = Display.DisplayMode.Height; - DWORD dwBehaviorFlags=0x0; - - if(_dxgsg->scrn.bIsTNLDevice) { - dwBehaviorFlags|=D3DCREATE_HARDWARE_VERTEXPROCESSING; - // note: we could create a pure device in this case if I eliminated the GetRenderState calls in dxgsg - - // also, no software vertex processing available since I specify D3DCREATE_HARDWARE_VERTEXPROCESSING - // and not D3DCREATE_MIXED_VERTEXPROCESSING - } else { - dwBehaviorFlags|=D3DCREATE_SOFTWARE_VERTEXPROCESSING; - } - - if(dx_preserve_fpu_state) - dwBehaviorFlags|=D3DCREATE_FPU_PRESERVE; - - // if window is not foreground in exclusive mode, ddraw thinks you are 'not active', so - // it changes your WM_ACTIVATEAPP from true to false, causing us - // to go into a 'wait-for WM_ACTIVATEAPP true' loop, and the event never comes so we hang - // in fullscreen wait. also doing this for windowed mode since it was requested. - if(!SetForegroundWindow(Display.hWnd)) { - wdxdisplay_cat.warning() << "SetForegroundWindow() failed!\n"; - } - - if(_props._fullscreen) { - pPresParams->SwapEffect = D3DSWAPEFFECT_DISCARD; // we dont care about preserving contents of old frame - pPresParams->FullScreen_PresentationInterval = (dx_sync_video ? D3DPRESENT_INTERVAL_ONE : D3DPRESENT_INTERVAL_IMMEDIATE); - pPresParams->FullScreen_RefreshRateInHz = Display.DisplayMode.RefreshRate; - -#if 0 -/* this is incorrect, we dont need rendertarget to hold alpha to do normal alpha blending, since blending is usually just - based on source alpha. so for now its OK to pick rendertargets with same format as display - - // assume app requires alpha-blending - // will fullscrn alphablend work with DISCARD anyway even if this cap is not set? I dont see it being set by latest drivers - // for any card. need to test both dx8.0 and dx8.1, it may be that dx8.1 works even if cap is not set, but 8.0 doesnt - if((!Display.bIsDX81) || (!(d3dcaps.Caps3 & D3DCAPS3_ALPHA_FULLSCREEN_FLIP_OR_DISCARD))) { - pPresParams->SwapEffect = (dx_sync_video ? D3DSWAPEFFECT_COPY_VSYNC : D3DSWAPEFFECT_COPY); - - if(pPresParams->MultiSampleType != D3DMULTISAMPLE_NONE) { - wdxdisplay_cat.fatal() << "device #"<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, - dwBehaviorFlags, pPresParams, &Display.pD3DDevice); - - if(FAILED(hr)) { - wdxdisplay_cat.fatal() << "D3D CreateDevice failed for device #" << Display.CardIDNum << ", " << D3DERRORSTRING(hr); - - if(hr == D3DERR_OUTOFVIDEOMEMORY) - goto Fallback_to_16bpp_buffers; - } - - SetRect(&view_rect, 0, 0, dwRenderWidth, dwRenderHeight); - } // end create full screen buffers - - else { // CREATE WINDOWED BUFFERS - - if(!(pD3DCaps->Caps2 & D3DCAPS2_CANRENDERWINDOWED)) { - wdxdisplay_cat.fatal() << "the 3D HW cannot render windowed, exiting..." << endl; - exit(1); - } - - D3DDISPLAYMODE dispmode; - hr = Display.pD3D8->GetAdapterDisplayMode(Display.CardIDNum, &dispmode); - - if(FAILED(hr)) { - wdxdisplay_cat.fatal() << "GetAdapterDisplayMode failed" << D3DERRORSTRING(hr); - exit(1); - } - - if(dispmode.Format == D3DFMT_P8) { - wdxdisplay_cat.fatal() << "Can't run windowed in an 8-bit or less display mode" << endl; - exit(1); - } - - pPresParams->FullScreen_PresentationInterval = 0; - - if(dx_multisample_antialiasing_level<2) { - if(dx_sync_video) { - pPresParams->SwapEffect = D3DSWAPEFFECT_COPY_VSYNC; - } else { - pPresParams->SwapEffect = D3DSWAPEFFECT_DISCARD; //D3DSWAPEFFECT_COPY; does this make any difference? - } - } else { - pPresParams->SwapEffect = D3DSWAPEFFECT_DISCARD; - } - - assert((dwRenderWidth==pPresParams->BackBufferWidth)&&(dwRenderHeight==pPresParams->BackBufferHeight)); - - hr = pD3D8->CreateDevice(Display.CardIDNum, D3DDEVTYPE_HAL, _pParentWindowGroup->_hParentWindow, - dwBehaviorFlags, pPresParams, &Display.pD3DDevice); - - if(FAILED(hr)) { - wdxdisplay_cat.fatal() << "D3D CreateDevice failed for device #" << Display.CardIDNum << D3DERRORSTRING(hr); - exit(1); - } - } // end create windowed buffers - -// ======================================================== - - PRINT_REFCNT(wdxdisplay,_dxgsg->scrn.pD3DDevice); - - if(pPresParams->EnableAutoDepthStencil) { - _dxgsg->_buffer_mask |= RenderBuffer::T_depth; - if(IS_STENCIL_FORMAT(pPresParams->AutoDepthStencilFormat)) - _dxgsg->_buffer_mask |= RenderBuffer::T_stencil; - } - - init_resized_window(); - - return; - -Fallback_to_16bpp_buffers: - - if((!IS_16BPP_DISPLAY_FORMAT(pPresParams->BackBufferFormat)) && - (Display.SupportedScreenDepthsMask & (R5G6B5_FLAG|X1R5G5B5_FLAG))) { - // fallback strategy, if we trying >16bpp, fallback to 16bpp buffers - - Display.DisplayMode.Format = ((Display.SupportedScreenDepthsMask & R5G6B5_FLAG) ? D3DFMT_R5G6B5 : D3DFMT_X1R5G5B5); - - dx_force_16bpp_zbuffer=true; - if(wdxdisplay_cat.info()) - wdxdisplay_cat.info() << "CreateDevice failed with out-of-vidmem, retrying w/16bpp buffers on device #"<< Display.CardIDNum << endl; - CreateScreenBuffersAndDevice(Display); - return; - } else if(!((dwRenderWidth==640)&&(dwRenderHeight==480))) { - if(wdxdisplay_cat.info()) - wdxdisplay_cat.info() << "CreateDevice failed w/out-of-vidmem, retrying at 640x480 w/16bpp buffers on device #"<< Display.CardIDNum << endl; - // try final fallback to 640x480x16 - dx_force_16bpp_zbuffer=true; - Display.DisplayMode.Width=640; - Display.DisplayMode.Height=480; - CreateScreenBuffersAndDevice(Display); - return; - } else { - exit(1); - } -} - -// assumes CreateDevice or Device->Reset() has just been called, -// and the new size is specified in _dxgsg->scrn.PresParams -void wdxGraphicsWindow::init_resized_window(void) { - DXScreenData *pDisplay=&_dxgsg->scrn; - HRESULT hr; - - DWORD newWidth = pDisplay->PresParams.BackBufferWidth; - DWORD newHeight = pDisplay->PresParams.BackBufferHeight; - - if(pDisplay->PresParams.Windowed) { - POINT ul,lr; - RECT client_rect; - - // need to figure out x,y origin offset of window client area on screen - // (we already know the client area size) - - GetClientRect(pDisplay->hWnd, &client_rect); - ul.x=client_rect.left; ul.y=client_rect.top; - lr.x=client_rect.right; lr.y=client_rect.bottom; - ClientToScreen(pDisplay->hWnd, &ul); - ClientToScreen(pDisplay->hWnd, &lr); - client_rect.left=ul.x; client_rect.top=ul.y; - client_rect.right=lr.x; client_rect.bottom=lr.y; - _props._xorg = client_rect.left; // _props should reflect view rectangle - _props._yorg = client_rect.top; - - #ifdef _DEBUG - // try to make sure GDI and DX agree on window client area size - // but client rect will not include any offscreen areas, so dont - // do check if window was bigger than screen (there are other bad - // cases too, like when window is positioned partly offscreen, - // or if window trim border make size bigger than screen) - - RECT desktop_rect; - GetClientRect(GetDesktopWindow(), &desktop_rect); - if((_props._xsizehWnd,_props); - - // clear textures and VB's out of video&AGP mem, so cache is reset - hr = pDisplay->pD3DDevice->ResourceManagerDiscardBytes(0); - if(FAILED(hr)) { - wdxdisplay_cat.error() << "ResourceManagerDiscardBytes failed for device #" << pDisplay->CardIDNum << D3DERRORSTRING(hr); - } - - // Create the viewport - D3DVIEWPORT8 vp = {0,0,_props._xsize,_props._ysize,0.0f,1.0f}; - hr = pDisplay->pD3DDevice->SetViewport( &vp ); - if(FAILED(hr)) { - wdxdisplay_cat.fatal() << "SetViewport failed for device #" << pDisplay->CardIDNum << D3DERRORSTRING(hr); - exit(1); - } - - _dxgsg->dx_init(_pParentWindowGroup->_hMouseCursor); - // do not SetDXReady() yet since caller may want to do more work before letting rendering proceed - - SetCursor(_pParentWindowGroup->_hMouseCursor); - set_cursor_visibility(true); -} - -// does NOT override _props._bCursorIsVisible -INLINE void wdxGraphicsWindow::set_cursor_visibility(bool bVisible) { - bool bValidDXPtrs; - - if(_use_dx8_cursor) - bValidDXPtrs = (IS_VALID_PTR(_dxgsg) && IS_VALID_PTR(_dxgsg->scrn.pD3DDevice)); - - if(_props._bCursorIsVisible) { - if(_use_dx8_cursor) { - ShowCursor(false); - if(bValidDXPtrs) - _dxgsg->scrn.pD3DDevice->ShowCursor(bVisible); - } else { - ShowCursor(bVisible); - } - } else { - ShowCursor(false); - if(_use_dx8_cursor && bValidDXPtrs) - _dxgsg->scrn.pD3DDevice->ShowCursor(false); - } -} - -//////////////////////////////////////////////////////////////////// -// Function: setup_colormap -// Access: -// Description: -//////////////////////////////////////////////////////////////////// -void wdxGraphicsWindow::setup_colormap(void) { - PIXELFORMATDESCRIPTOR pfd; - LOGPALETTE *logical; - int n; - - // should probably do this some other way than through opengl PixelFormat calls - - /* grab the pixel format */ - memset(&pfd, 0, sizeof(PIXELFORMATDESCRIPTOR)); - DescribePixelFormat(_hdc, GetPixelFormat(_hdc), - sizeof(PIXELFORMATDESCRIPTOR), &pfd); - - if(!(pfd.dwFlags & PFD_NEED_PALETTE || - pfd.iPixelType == PFD_TYPE_COLORINDEX)) - return; - - n = 1 << pfd.cColorBits; - - /* allocate a bunch of memory for the logical palette (assume 256 - colors in a Win32 palette */ - logical = (LOGPALETTE*)malloc(sizeof(LOGPALETTE) + - sizeof(PALETTEENTRY) * n); - memset(logical, 0, sizeof(LOGPALETTE) + sizeof(PALETTEENTRY) * n); - - /* set the entries in the logical palette */ - logical->palVersion = 0x300; - logical->palNumEntries = n; - - /* start with a copy of the current system palette */ - GetSystemPaletteEntries(_hdc, 0, 256, &logical->palPalEntry[0]); - - if(pfd.iPixelType == PFD_TYPE_RGBA) { - int redMask = (1 << pfd.cRedBits) - 1; - int greenMask = (1 << pfd.cGreenBits) - 1; - int blueMask = (1 << pfd.cBlueBits) - 1; - int i; - - /* fill in an RGBA color palette */ - for(i = 0; i < n; ++i) { - logical->palPalEntry[i].peRed = - (((i >> pfd.cRedShift) & redMask) * 255) / redMask; - logical->palPalEntry[i].peGreen = - (((i >> pfd.cGreenShift) & greenMask) * 255) / greenMask; - logical->palPalEntry[i].peBlue = - (((i >> pfd.cBlueShift) & blueMask) * 255) / blueMask; - logical->palPalEntry[i].peFlags = 0; - } - } - - _colormap = CreatePalette(logical); - free(logical); - - SelectPalette(_hdc, _colormap, FALSE); - RealizePalette(_hdc); -} - -/* dont need to override the defaults (which just go to gsg->begin_frame()) -//////////////////////////////////////////////////////////////////// -// Function: begin_frame -// Access: -//////////////////////////////////////////////////////////////////// -void wdxGraphicsWindow::begin_frame(void) { - GraphicsWindow::begin_frame(); -} - -//////////////////////////////////////////////////////////////////// -// Function: end_frame -// Access: -// Description: timer info, incs frame # -//////////////////////////////////////////////////////////////////// -void wdxGraphicsWindow::end_frame(void) { - GraphicsWindow::end_frame(); -} -*/ - -//////////////////////////////////////////////////////////////////// -// Function: handle_window_move -// Access: -// Description: we receive the new x and y position of the client -//////////////////////////////////////////////////////////////////// -void wdxGraphicsWindow::handle_window_move(int x, int y) { - _props._xorg = x; - _props._yorg = y; -} - -//////////////////////////////////////////////////////////////////// -// Function: handle_mouse_motion -// Access: -// Description: -//////////////////////////////////////////////////////////////////// -void wdxGraphicsWindow::handle_mouse_motion(int x, int y) { - _input_devices[0].set_pointer_in_window(x, y); -} - -//////////////////////////////////////////////////////////////////// -// Function: handle_mouse_exit -// Access: -// Description: -//////////////////////////////////////////////////////////////////// -void wdxGraphicsWindow::handle_mouse_exit(void) { - _input_devices[0].set_pointer_out_of_window(); -} - -//////////////////////////////////////////////////////////////////// -// Function: handle_keypress -// Access: -// Description: -//////////////////////////////////////////////////////////////////// -void wdxGraphicsWindow:: -handle_keypress(ButtonHandle key, int x, int y) { -/* - if(key.has_ascii_equivalent()) { - wdxdisplay_cat.spam() << key.get_ascii_equivalent() << endl; - - short d1 = GetKeyState(VK_CONTROL); - short d2 = GetKeyState(VK_SHIFT); - wdxdisplay_cat.spam().flags(ios::hex | ios::uppercase ); - wdxdisplay_cat.spam() << " Control: " << ((d1 < 0)? "down" : "up") << " Shift: " << ((d2 < 0)? "down" : "up") << endl; - } -*/ - _input_devices[0].set_pointer_in_window(x, y); - if(key != ButtonHandle::none()) { - _input_devices[0].button_down(key); - } -} - -//////////////////////////////////////////////////////////////////// -// Function: handle_keyrelease -// Access: -// Description: -//////////////////////////////////////////////////////////////////// -void wdxGraphicsWindow:: -handle_keyrelease(ButtonHandle key) { - if(key != ButtonHandle::none()) { - _input_devices[0].button_up(key); - } -} - -void INLINE process_1_event(void) { - MSG msg; - - if(!GetMessage(&msg, NULL, 0, 0)) { - // WM_QUIT received - DestroyAllWindows(false); - exit(msg.wParam); // this will invoke AtExitFn - } - - // Translate virtual key messages - TranslateMessage(&msg); - // Call window_proc - DispatchMessage(&msg); -} - -void INLINE wdxGraphicsWindow::process_events(void) { - if(!_window_active) { - // Get 1 msg at a time until no more are left and we block and sleep, - // or message changes _return_control_to_app or _window_active status - - while((!_window_active) && (!_return_control_to_app)) { - process_1_event(); - } - _return_control_to_app = false; - - } else { - MSG msg; - - // handle all msgs on queue in a row - while(PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE)) { - process_1_event(); - } - } -} - -//////////////////////////////////////////////////////////////////// -// Function: wdxGraphicsWindow::get_gsg_type -// Access: Public, Virtual -// Description: Returns the TypeHandle of the kind of GSG preferred -// by this kind of window. -//////////////////////////////////////////////////////////////////// -TypeHandle wdxGraphicsWindow:: -get_gsg_type() const { - return DXGraphicsStateGuardian::get_class_type(); -} - -GraphicsWindow *wdxGraphicsWindow:: -make_wdxGraphicsWindow(const FactoryParams ¶ms) { - GraphicsWindow::WindowPipe *pipe_param; - if(!get_param_into(pipe_param, params)) { - wdxdisplay_cat.error() - << "No pipe specified for window creation!" << endl; - return NULL; - } - - GraphicsPipe *pipe = pipe_param->get_pipe(); - - GraphicsWindow::WindowProps *props_param; - if(!get_param_into(props_param, params)) { - return new wdxGraphicsWindow(pipe); - } else { - return new wdxGraphicsWindow(pipe, props_param->get_properties()); - } -} - -TypeHandle wdxGraphicsWindow::get_class_type(void) { - return _type_handle; -} - -void wdxGraphicsWindow::init_type(void) { - GraphicsWindow::init_type(); - register_type(_type_handle, "wdxGraphicsWindow8", - GraphicsWindow::get_class_type()); -} - -TypeHandle wdxGraphicsWindow::get_type(void) const { - return get_class_type(); -} - -//////////////////////////////////////////////////////////////////// -// Function: lookup_key -// Access: -// Description: -//////////////////////////////////////////////////////////////////// -ButtonHandle wdxGraphicsWindow:: -lookup_key(WPARAM wparam) const { - // First, check for a few buttons that we filter out when the IME - // window is open. - if (!_ime_active) { - switch(wparam) { - case VK_BACK: return KeyboardButton::backspace(); - case VK_DELETE: return KeyboardButton::del(); - case VK_ESCAPE: return KeyboardButton::escape(); - case VK_SPACE: return KeyboardButton::space(); - case VK_UP: return KeyboardButton::up(); - case VK_DOWN: return KeyboardButton::down(); - case VK_LEFT: return KeyboardButton::left(); - case VK_RIGHT: return KeyboardButton::right(); - } - } - - // Now check for the rest of the buttons, including the ones that - // we allow through even when the IME window is open. - switch(wparam) { - case VK_TAB: return KeyboardButton::tab(); - case VK_PRIOR: return KeyboardButton::page_up(); - case VK_NEXT: return KeyboardButton::page_down(); - case VK_HOME: return KeyboardButton::home(); - case VK_END: return KeyboardButton::end(); - case VK_F1: return KeyboardButton::f1(); - case VK_F2: return KeyboardButton::f2(); - case VK_F3: return KeyboardButton::f3(); - case VK_F4: return KeyboardButton::f4(); - case VK_F5: return KeyboardButton::f5(); - case VK_F6: return KeyboardButton::f6(); - case VK_F7: return KeyboardButton::f7(); - case VK_F8: return KeyboardButton::f8(); - case VK_F9: return KeyboardButton::f9(); - case VK_F10: return KeyboardButton::f10(); - case VK_F11: return KeyboardButton::f11(); - case VK_F12: return KeyboardButton::f12(); - case VK_INSERT: return KeyboardButton::insert(); - case VK_CAPITAL: return KeyboardButton::caps_lock(); - case VK_NUMLOCK: return KeyboardButton::num_lock(); - case VK_SCROLL: return KeyboardButton::scroll_lock(); - case VK_SNAPSHOT: return KeyboardButton::print_screen(); - - case VK_SHIFT: - case VK_LSHIFT: - case VK_RSHIFT: - return KeyboardButton::shift(); - - case VK_CONTROL: - case VK_LCONTROL: - case VK_RCONTROL: - return KeyboardButton::control(); - - case VK_MENU: - case VK_LMENU: - case VK_RMENU: - return KeyboardButton::alt(); - - default: - int key = MapVirtualKey(wparam, 2); - if (isascii(key) && key != 0) { - // We used to try to remap lowercase to uppercase keys - // here based on the state of the shift and/or caps lock - // keys. But that's a mistake, and doesn't allow for - // international or user-defined keyboards; let Windows - // do that mapping. - - // Nowadays, we make a distinction between a "button" - // and a "keystroke". A button corresponds to a - // physical button on the keyboard and has a down and up - // event associated. A keystroke may or may not - // correspond to a physical button, but will be some - // Unicode character and will not have a corresponding - // up event. - return KeyboardButton::ascii_key(tolower(key)); - } - break; - } - return ButtonHandle::none(); -} - -int wdxGraphicsWindow:: -get_depth_bitwidth(void) { - assert(_dxgsg!=NULL); - if(_dxgsg->scrn.PresParams.EnableAutoDepthStencil) - return _dxgsg->scrn.depth_buffer_bitdepth; - else return 0; - -// GetSurfaceDesc is not reliable, on GF2, GetSurfDesc returns 32bpp when you created a 24bpp zbuf -// instead store the depth used at creation time - -// DX_DECLARE_CLEAN(DDSURFACEDESC2, ddsd); -// _dxgsg->_zbuf->GetSurfaceDesc(&ddsd); -// return ddsd.ddpfPixelFormat.dwRGBBitCount; -} - -void wdxGraphicsWindow:: -get_framebuffer_format(PixelBuffer::Type &fb_type, PixelBuffer::Format &fb_format) { - assert(_dxgsg!=NULL); - - fb_type = PixelBuffer::T_unsigned_byte; - // this is sortof incorrect, since for F_rgb5 it's really 5 bits per channel - //would have to change a lot of texture stuff to make this correct though - - if(IS_16BPP_DISPLAY_FORMAT(_dxgsg->scrn.PresParams.BackBufferFormat)) - fb_format = PixelBuffer::F_rgb5; - else fb_format = PixelBuffer::F_rgb; -} - -// Global system parameters we want to modify during our run -static int iMouseTrails; -static bool bCursorShadowOn,bMouseVanish; - -#ifndef SPI_GETMOUSEVANISH -// get rid of this when we upgrade to winxp winuser.h in newest platform sdk -#define SPI_GETMOUSEVANISH 0x1020 -#define SPI_SETMOUSEVANISH 0x1021 -#endif - -#ifndef SPI_GETCURSORSHADOW -#error You have old windows headers, need to get latest MS Platform SDK -#endif - -void set_global_parameters(void) { - // turn off mousetrails and cursor shadow and mouse cursor vanish - // cursor shadow causes cursor blink and reduced frame rate due to lack of driver support for - // cursor alpha blending - - // this is a win2k/xp only param, could use GetVersionEx to do it just for win2k, - // but since it is just a param it will just cause a silent error on other OS's - // that should be ok - SystemParametersInfo(SPI_GETCURSORSHADOW,NULL,&bCursorShadowOn,NULL); - SystemParametersInfo(SPI_SETCURSORSHADOW,NULL,(PVOID)false,NULL); - - SystemParametersInfo(SPI_GETMOUSETRAILS,NULL,&iMouseTrails,NULL); - SystemParametersInfo(SPI_SETMOUSETRAILS,NULL,(PVOID)0,NULL); - - // this is ME/XP only feature - SystemParametersInfo(SPI_GETMOUSEVANISH,NULL,&bMouseVanish,NULL); - SystemParametersInfo(SPI_SETMOUSEVANISH,NULL,(PVOID)false,NULL); -} - -void restore_global_parameters(void) { - SystemParametersInfo(SPI_SETCURSORSHADOW,NULL,(PVOID)bCursorShadowOn,NULL); - SystemParametersInfo(SPI_SETMOUSETRAILS,NULL,(PVOID)iMouseTrails,NULL); - SystemParametersInfo(SPI_SETMOUSEVANISH,NULL,(PVOID)bMouseVanish,NULL); -} - - -// fns for exporting to python, which cant pass variable length arrays -wdxGraphicsWindowGroup::wdxGraphicsWindowGroup(GraphicsPipe *pipe,const GraphicsWindow::Properties &Win1Prop) { - GraphicsWindow::Properties WinPropArr[1]; - WinPropArr[0]=Win1Prop; - make_windows(pipe,1,WinPropArr); -} - -wdxGraphicsWindowGroup::wdxGraphicsWindowGroup(GraphicsPipe *pipe, - const GraphicsWindow::Properties &Win1Prop, - const GraphicsWindow::Properties &Win2Prop) { - GraphicsWindow::Properties WinPropArr[2]; - - WinPropArr[0]=Win1Prop; - WinPropArr[1]=Win2Prop; - make_windows(pipe,2,WinPropArr); -} - -wdxGraphicsWindowGroup::wdxGraphicsWindowGroup(GraphicsPipe *pipe, - const GraphicsWindow::Properties &Win1Prop, - const GraphicsWindow::Properties &Win2Prop, - const GraphicsWindow::Properties &Win3Prop) { - GraphicsWindow::Properties WinPropArr[3]; - - WinPropArr[0]=Win1Prop; - WinPropArr[1]=Win2Prop; - WinPropArr[2]=Win3Prop; - make_windows(pipe,3,WinPropArr); -} - -wdxGraphicsWindowGroup::wdxGraphicsWindowGroup(wdxGraphicsWindow *OneWindow) { - // init a 1 window group - // called from config_window - - _windows.reserve(1); - _windows.push_back(OneWindow); - initWindowGroup(); -} - -void wdxGraphicsWindowGroup::initWindowGroup(void) { - HRESULT hr; - - assert(_windows.size()>0); - _hOldForegroundWindow=GetForegroundWindow(); - _bClosingAllWindows= false; - - UINT num_windows=_windows.size(); - - #define D3D8_NAME "d3d8.dll" - #define D3DCREATE8 "Direct3DCreate8" - - _hD3D8_DLL = LoadLibrary(D3D8_NAME); - if(_hD3D8_DLL == 0) { - wdxdisplay_cat.fatal() << "PandaDX8 requires DX8, can't locate " << D3D8_NAME <<"!\n"; - exit(1); - } - - _hMouseCursor = NULL; - _bLoadedCustomCursor = false; - - _pDInputInfo = NULL; - - // can only get multimon HW acceleration in fullscrn on DX7 - - UINT numMonitors = GetSystemMetrics(SM_CMONITORS); - - if(numMonitors < num_windows) { - if(numMonitors==0) { - numMonitors=1; //win95 system will fail this call - } else { - wdxdisplay_cat.fatal() << "system has only "<< numMonitors << " monitors attached, couldn't find enough devices to meet multi window reqmt of " << num_windows << endl; - exit(1); - } - } - - // Do all DX7 stuff first - // find_all_card_memavails(); - - LPDIRECT3D8 pD3D8; - - typedef LPDIRECT3D8 (WINAPI *Direct3DCreate8_ProcPtr)(UINT SDKVersion); - - // dont want to statically link to possibly non-existent d3d8 dll, so must call D3DCr8 indirectly - Direct3DCreate8_ProcPtr D3DCreate8_Ptr = - (Direct3DCreate8_ProcPtr) GetProcAddress(_hD3D8_DLL, D3DCREATE8); - - if(D3DCreate8_Ptr == NULL) { - wdxdisplay_cat.fatal() << "GetProcAddress for "<< D3DCREATE8 << "failed!" << endl; - exit(1); - } - -// these were taken from the 8.0 and 8.1 d3d8.h SDK headers -#define D3D_SDK_VERSION_8_0 120 -#define D3D_SDK_VERSION_8_1 220 - - // are we using 8.0 or 8.1? - WIN32_FIND_DATA TempFindData; - HANDLE hFind; - char tmppath[MAX_PATH]; - GetSystemDirectory(tmppath,MAX_PATH); - strcat(tmppath,"\\dpnhpast.dll"); - hFind = FindFirstFile ( tmppath,&TempFindData ); - if(hFind != INVALID_HANDLE_VALUE) { - FindClose(hFind); - _bIsDX81=true; - pD3D8 = (*D3DCreate8_Ptr)(D3D_SDK_VERSION_8_1); - } else { - _bIsDX81=false; - pD3D8 = (*D3DCreate8_Ptr)(D3D_SDK_VERSION_8_0); - } - - if(pD3D8==NULL) { - wdxdisplay_cat.fatal() << D3DCREATE8 << " failed!\n"; - exit(1); - } - - _numAdapters = pD3D8->GetAdapterCount(); - if(_numAdapters < num_windows) { - wdxdisplay_cat.fatal() << "couldn't find enough devices attached to meet multi window reqmt of " << num_windows << endl; - exit(1); - } - - for(UINT i=0;i<_numAdapters;i++) { - D3DADAPTER_IDENTIFIER8 adapter_info; - ZeroMemory(&adapter_info,sizeof(D3DADAPTER_IDENTIFIER8)); - hr = pD3D8->GetAdapterIdentifier(i,D3DENUM_NO_WHQL_LEVEL,&adapter_info); - if(FAILED(hr)) { - wdxdisplay_cat.fatal() << "D3D GetAdapterID failed" << D3DERRORSTRING(hr); - } - - LARGE_INTEGER *DrvVer=&adapter_info.DriverVersion; - - wdxdisplay_cat.info() << "D3D8 Adapter[" << i << "]: " << adapter_info.Description << - ", Driver: " << adapter_info.Driver << ", DriverVersion: (" - << HIWORD(DrvVer->HighPart) << "." << LOWORD(DrvVer->HighPart) << "." - << HIWORD(DrvVer->LowPart) << "." << LOWORD(DrvVer->LowPart) << ")\nVendorID: 0x" - << (void*) adapter_info.VendorId << " DeviceID: 0x" << (void*) adapter_info.DeviceId - << " SubsysID: 0x" << (void*) adapter_info.SubSysId << " Revision: 0x" - << (void*) adapter_info.Revision << endl; - - HMONITOR hMon=pD3D8->GetAdapterMonitor(i); - if(hMon==NULL) { - wdxdisplay_cat.info() << "D3D8 Adapter[" << i << "]: seems to be disabled, skipping it\n"; - continue; - } - - DXDeviceInfo devinfo; - ZeroMemory(&devinfo,sizeof(devinfo)); - memcpy(&devinfo.guidDeviceIdentifier,&adapter_info.DeviceIdentifier,sizeof(GUID)); - strncpy(devinfo.szDescription,adapter_info.Description,MAX_DEVICE_IDENTIFIER_STRING); - strncpy(devinfo.szDriver,adapter_info.Driver,MAX_DEVICE_IDENTIFIER_STRING); - devinfo.VendorID=adapter_info.VendorId; - devinfo.DeviceID=adapter_info.DeviceId; - devinfo.hMon=hMon; - devinfo.cardID=i; - - _DeviceInfoVec.push_back(devinfo); - } - - for(UINT i=0;iconfig_window(this); - } - - UINT good_device_count=0; - - if(num_windows==1) { - UINT D3DAdapterNum = D3DADAPTER_DEFAULT; - - if(dx_preferred_deviceID!=-1) { - if(dx_preferred_deviceID>=(int)_numAdapters) { - wdxdisplay_cat.fatal() << "invalid 'dx-preferred-device-id', valid values are 0-" << _numAdapters-1 << ", using default adapter 0 instead\n"; - } else D3DAdapterNum=dx_preferred_deviceID; - } - if(_windows[0]->search_for_device(pD3D8,&(_DeviceInfoVec[D3DAdapterNum]))) - good_device_count=1; - } else { - for(UINT devnum=0;devnum<_DeviceInfoVec.size() && (good_device_count < num_windows);devnum++) { - if(_windows[devnum]->search_for_device(pD3D8,&(_DeviceInfoVec[devnum]))) - good_device_count++; - } - } - - if(good_device_count < num_windows) { - if(good_device_count==0) - wdxdisplay_cat.fatal() << "no usable display devices, exiting...\n"; - else wdxdisplay_cat.fatal() << "multi-device request for " << num_windows << "devices, found only "<< good_device_count << " usable ones, exiting!"; - exit(1); - } - - _DeviceInfoVec.clear(); // dont need this anymore - - if(wdxdisplay_cat.is_debug() && (g_pCardIDVec!=NULL)) { - // print out the MaxAvailVidMems - for(UINT i=0;i<_windows.size();i++) { - D3DADAPTER_IDENTIFIER8 adapter_info; - pD3D8->GetAdapterIdentifier(_windows[i]->_dxgsg->scrn.CardIDNum,D3DENUM_NO_WHQL_LEVEL,&adapter_info); - wdxdisplay_cat.info() << "D3D8 Adapter[" << i << "]: " << adapter_info.Description - << ", MaxAvailVideoMem: " << _windows[i]->_dxgsg->scrn.MaxAvailVidMem - << ", IsLowVidMemCard: " << (_windows[i]->_dxgsg->scrn.bIsLowVidMemCard ? "true" : "false") << endl; - } - } - - CreateWindows(); // creates win32 windows (need to do this before Setting coopLvls and display modes, - // but after we have all the monitor handles needed by CreateWindow() - -// SetCoopLevelsAndDisplayModes(); - - if(dx_show_fps_meter) - _windows[0]->_dxgsg->_bShowFPSMeter = true; // just show fps on 1st mon - - for(UINT i=0;iCreateScreenBuffersAndDevice(_windows[i]->_dxgsg->scrn); - } - - for(UINT i=0;ifinish_window_setup(); - } - - SAFE_DELETE(g_pCardIDVec); // dont need this anymore - - for(UINT i=0;i_dxgsg->SetDXReady(true); - } - - dx_pick_best_screenres = false; // only want to do this on startup, not resize - - #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) { - make_windows(pipe,num_windows,WinPropArray); -} - -void wdxGraphicsWindowGroup:: -make_windows(GraphicsPipe *pipe,int num_windows,GraphicsWindow::Properties *WinPropArray) { - _hParentWindow=NULL; - _windows.reserve(num_windows); - int i; - - // first make all the objs without running the dx config() stuff - for(i=0;iclose_window(); - } - - if((_hOldForegroundWindow!=NULL) /*&& (scrn.hWnd==GetForegroundWindow())*/) { - SetForegroundWindow(_hOldForegroundWindow); - } - - if(_bLoadedCustomCursor && (_hMouseCursor!=NULL)) - DestroyCursor(_hMouseCursor); - - if(_hD3D8_DLL != NULL) { - FreeLibrary(_hD3D8_DLL); - _hD3D8_DLL = NULL; - } -} - diff --git a/panda/src/wdxdisplay8/wdxGraphicsWindow8.h b/panda/src/wdxdisplay8/wdxGraphicsWindow8.h deleted file mode 100644 index a164286249..0000000000 --- a/panda/src/wdxdisplay8/wdxGraphicsWindow8.h +++ /dev/null @@ -1,195 +0,0 @@ -// Filename: wdxGraphicsWindow.h -// Created by: mike (09Jan97) -// -//////////////////////////////////////////////////////////////////// -// -// 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 WDXGRAPHICSWINDOW_H -#define WDXGRAPHICSWINDOW_H - -//////////////////////////////////////////////////////////////////// -// Includes -//////////////////////////////////////////////////////////////////// -#include -#include -#include "dxGraphicsStateGuardian8.h" -#include - -//////////////////////////////////////////////////////////////////// -// Defines -//////////////////////////////////////////////////////////////////// -class wdxGraphicsPipe; -class wdxGraphicsWindowGroup; - -const int WDXWIN_CONFIGURE = 4; -const int WDXWIN_EVENT = 8; - -//#define FIND_CARD_MEMAVAILS - -typedef HRESULT (WINAPI * LPDIRECTDRAWCREATEEX)(GUID FAR * lpGuid, LPVOID *lplpDD, REFIID iid,IUnknown FAR *pUnkOuter); - -typedef struct { - UINT cardID; - char szDriver[MAX_DEVICE_IDENTIFIER_STRING]; - char szDescription[MAX_DEVICE_IDENTIFIER_STRING]; - GUID guidDeviceIdentifier; - DWORD VendorID,DeviceID; - HMONITOR hMon; -} DXDeviceInfo; -typedef vector DXDeviceInfoVec; - -//////////////////////////////////////////////////////////////////// -// Class : wdxGraphicsWindow -// Description : -//////////////////////////////////////////////////////////////////// -class EXPCL_PANDADX wdxGraphicsWindow : public GraphicsWindow { - friend class DXGraphicsStateGuardian; - friend class DXTextureContext; - friend class wdxGraphicsWindowGroup; - friend class DInput8Info; - -public: - wdxGraphicsWindow(GraphicsPipe* pipe); - wdxGraphicsWindow(GraphicsPipe* pipe,const GraphicsWindow::Properties& props); - - // this constructor will not initialize the wdx stuff, only the panda graphicswindow stuff - wdxGraphicsWindow(GraphicsPipe* pipe,const GraphicsWindow::Properties& props,wdxGraphicsWindowGroup *pParentGroup); - - virtual ~wdxGraphicsWindow(void); - - virtual TypeHandle get_gsg_type() const; - static GraphicsWindow* make_wdxGraphicsWindow(const FactoryParams ¶ms); - - void set_window_handle(HWND hwnd); - - LONG window_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam); - void process_events(void); - - void handle_window_move( int x, int y ); - void handle_mouse_motion( int x, int y ); - void handle_mouse_exit(void); - void handle_keypress(ButtonHandle key, int x, int y ); - void handle_keyrelease(ButtonHandle key); - void dx_setup(); - -// dont need to override these now? -// virtual void begin_frame( void ); -// virtual void end_frame( void ); - - virtual bool resize(unsigned int xsize,unsigned int ysize); - virtual unsigned int verify_window_sizes(unsigned int numsizes,unsigned int *dimen); - bool special_check_fullscreen_resolution(UINT xsize,UINT ysize); - virtual int get_depth_bitwidth(void); - virtual void get_framebuffer_format(PixelBuffer::Type &fb_type, PixelBuffer::Format &fb_format); - -protected: - ButtonHandle lookup_key(WPARAM wparam) const; - void config_single_window(void); - void config_window(wdxGraphicsWindowGroup *pParentGroup); - void finish_window_setup(void); - bool search_for_device(LPDIRECT3D8 pD3D8,DXDeviceInfo *pDevinfo); - void search_for_valid_displaymode(UINT RequestedXsize,UINT RequestedYsize,bool bWantZBuffer,bool bWantStencil, - UINT *pSupportedScreenDepthsMask,bool *pCouldntFindAnyValidZBuf, - D3DFORMAT *pSuggestedPixFmt,bool bVerboseMode = false); - bool FindBestDepthFormat(DXScreenData &Display,D3DDISPLAYMODE &TestDisplayMode,D3DFORMAT *pBestFmt,bool bWantStencil,bool bForce16bpp,bool bVerboseMode = false) const; - void init_resized_window(void); - bool reset_device_resize_window(UINT new_xsize, UINT new_ysize); - void setup_colormap(void); - INLINE void track_mouse_leaving(HWND hwnd); - -public: - UINT_PTR _PandaPausedTimer; - DXGraphicsStateGuardian *_dxgsg; - void CreateScreenBuffersAndDevice(DXScreenData &Display); - -private: - wdxGraphicsWindowGroup *_pParentWindowGroup; - HDC _hdc; - HPALETTE _colormap; - typedef enum { NotAdjusting,MovingOrResizing,Resizing } WindowAdjustType; - WindowAdjustType _WindowAdjustingType; - bool _bSizeIsMaximized; - bool _ime_open; - bool _ime_active; - bool _ime_composition_w; - bool _exiting_window; - bool _window_inactive; - bool _active_minimized_fullscreen; - bool _return_control_to_app; - bool _cursor_in_windowclientarea; - bool _use_dx8_cursor; - bool _tracking_mouse_leaving; - int _depth_buffer_bpp; - -public: - static TypeHandle get_class_type(void); - static void init_type(void); - virtual TypeHandle get_type(void) const; - virtual TypeHandle force_init_type() {init_type(); return get_class_type();} - - void DestroyMe(bool bAtExitFnCalled); - virtual void do_close_window(); - void deactivate_window(void); - void reactivate_window(void); - INLINE void set_cursor_visibility(bool bVisible); - bool handle_windowed_resize(HWND hWnd,bool bDoDXReset); - -private: - static TypeHandle _type_handle; -}; - -// this class really belongs in panda, not here -class EXPCL_PANDADX wdxGraphicsWindowGroup { -// group of windows are all created at the same time - friend class wdxGraphicsWindow; - -PUBLISHED: - wdxGraphicsWindowGroup(GraphicsPipe *,const GraphicsWindow::Properties&); - wdxGraphicsWindowGroup(GraphicsPipe *,const GraphicsWindow::Properties&,const GraphicsWindow::Properties&); - wdxGraphicsWindowGroup(GraphicsPipe *,const GraphicsWindow::Properties&,const GraphicsWindow::Properties&, - const GraphicsWindow::Properties&); -public: - wdxGraphicsWindowGroup(wdxGraphicsWindow *OneWindow); - // dont publish variable length one, since FFI wont support it - wdxGraphicsWindowGroup(GraphicsPipe *pipe,int num_windows,GraphicsWindow::Properties *WinPropArray); - ~wdxGraphicsWindowGroup(); -// void SetCoopLevelsAndDisplayModes(void); -protected: - void find_all_card_memavails(void); -public: - void CreateWindows(void); - void make_windows(GraphicsPipe *,int num_windows,GraphicsWindow::Properties *pWinPropArray); - void initWindowGroup(void); - - pvector _windows; - DXDeviceInfoVec *_pDeviceInfoVec; // only used during init to store valid devices - HWND _hParentWindow; - HWND _hOldForegroundWindow; - HCURSOR _hMouseCursor; - bool _bLoadedCustomCursor; - bool _bClosingAllWindows; - bool _bIsDX81; - DWORD _numMonitors,_numAdapters; - LPDIRECT3D8 _pD3D8; - HINSTANCE _hD3D8_DLL; - DInput8Info *_pDInputInfo; - DXDeviceInfoVec _DeviceInfoVec; -}; - -extern void set_global_parameters(void); -extern void restore_global_parameters(void); -extern bool is_badvidmem_card(D3DADAPTER_IDENTIFIER8 *pDevID); - - -#endif diff --git a/panda/src/wdxdisplay8/wdxdisplay8_composite1.cxx b/panda/src/wdxdisplay8/wdxdisplay8_composite1.cxx deleted file mode 100644 index 30c7bca344..0000000000 --- a/panda/src/wdxdisplay8/wdxdisplay8_composite1.cxx +++ /dev/null @@ -1,5 +0,0 @@ - -#include "config_wdxdisplay8.cxx" -#include "wdxGraphicsPipe8.cxx" -#include "dxInput8.cxx" -