502 lines
13 KiB
C++
502 lines
13 KiB
C++
// Ryzom - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
|
|
// Copyright (C) 2010 Winch Gate Property Limited
|
|
//
|
|
// This program is free software: you can redistribute it and/or modify
|
|
// it under the terms of the GNU Affero General Public License as
|
|
// published by the Free Software Foundation, either version 3 of the
|
|
// License, or (at your option) any later version.
|
|
//
|
|
// This program is distributed in the hope that it will be useful,
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
// GNU Affero General Public License for more details.
|
|
//
|
|
// You should have received a copy of the GNU Affero General Public License
|
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
// ***************************************************************************
|
|
// display_dlg.cpp : implementation file
|
|
// ***************************************************************************
|
|
|
|
#include "stdafx.h"
|
|
#include "client_config.h"
|
|
#include "display_dlg.h"
|
|
#include "cfg_file.h"
|
|
|
|
using namespace std;
|
|
using namespace NLMISC;
|
|
using namespace NL3D;
|
|
|
|
// ***************************************************************************
|
|
|
|
std::vector<string> GLExtensions;
|
|
std::string GLRenderer;
|
|
std::string GLVendor;
|
|
std::string GLVersion;
|
|
std::string D3DDescription;
|
|
std::string D3DDeviceName;
|
|
std::string D3DDriver;
|
|
std::string D3DDriverVersion;
|
|
std::string D3DVendor;
|
|
|
|
uint VideoMemory;
|
|
uint HardwareSoundBuffer;
|
|
uint64 SystemMemory;
|
|
uint CPUFrequency;
|
|
|
|
bool GetGLInformation ()
|
|
{
|
|
// *** INIT VARIABLES
|
|
|
|
GLExtensions.clear ();
|
|
GLRenderer = "";
|
|
GLVendor = "";
|
|
GLVersion = "";
|
|
|
|
// *** INIT OPENGL
|
|
|
|
// Register a window class
|
|
WNDCLASS wc;
|
|
memset(&wc,0,sizeof(wc));
|
|
wc.style = CS_HREDRAW | CS_VREDRAW ;//| CS_DBLCLKS;
|
|
wc.lpfnWndProc = DefWindowProc;
|
|
wc.cbClsExtra = 0;
|
|
wc.cbWndExtra = 0;
|
|
wc.hInstance = GetModuleHandle(NULL);
|
|
wc.hIcon = (HICON)NULL;
|
|
wc.hCursor = LoadCursor(NULL,IDC_ARROW);
|
|
wc.hbrBackground = WHITE_BRUSH;
|
|
wc.lpszClassName = "RyzomGetGlInformation";
|
|
wc.lpszMenuName = NULL;
|
|
if ( !RegisterClass(&wc) )
|
|
return false;
|
|
|
|
// Create a window
|
|
ULONG WndFlags = WS_OVERLAPPEDWINDOW+WS_CLIPCHILDREN+WS_CLIPSIBLINGS;
|
|
RECT WndRect;
|
|
WndRect.left=0;
|
|
WndRect.top=0;
|
|
WndRect.right=100;
|
|
WndRect.bottom=100;
|
|
HWND hWnd = CreateWindow ( "RyzomGetGlInformation",
|
|
"",
|
|
WndFlags,
|
|
CW_USEDEFAULT,CW_USEDEFAULT,
|
|
WndRect.right,WndRect.bottom,
|
|
NULL,
|
|
NULL,
|
|
GetModuleHandle(NULL),
|
|
NULL);
|
|
if (!hWnd)
|
|
return false;
|
|
|
|
HDC hDC = GetDC(hWnd);
|
|
|
|
// Remove current gl context
|
|
wglMakeCurrent (hDC, NULL);
|
|
|
|
// Select pixel format
|
|
int depth = GetDeviceCaps (hDC, BITSPIXEL);
|
|
PIXELFORMATDESCRIPTOR pfd;
|
|
memset(&pfd,0,sizeof(pfd));
|
|
pfd.nSize = sizeof(pfd);
|
|
pfd.nVersion = 1;
|
|
pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
|
|
pfd.iPixelType = PFD_TYPE_RGBA;
|
|
pfd.cColorBits = (char)depth;
|
|
if(depth<=16)
|
|
pfd.cDepthBits = 16;
|
|
else
|
|
{
|
|
pfd.cDepthBits = 24;
|
|
pfd.cAlphaBits = 8;
|
|
}
|
|
pfd.iLayerType = PFD_MAIN_PLANE;
|
|
int pf=ChoosePixelFormat(hDC, &pfd);
|
|
if (!pf)
|
|
return false;
|
|
if ( !SetPixelFormat(hDC, pf, &pfd) )
|
|
return false;
|
|
|
|
// Create final context
|
|
HGLRC hRC = wglCreateContext (hDC);
|
|
wglMakeCurrent(hDC, hRC);
|
|
|
|
// *** GET INFORMATION
|
|
|
|
GLVendor = (const char *) glGetString (GL_VENDOR);
|
|
GLRenderer = (const char *) glGetString (GL_RENDERER);
|
|
GLVersion = (const char *) glGetString (GL_VERSION);
|
|
|
|
// Get extension string
|
|
string glext = (char*)glGetString(GL_EXTENSIONS);
|
|
const char *token = strtok ( (char*)glext.c_str (), " ");
|
|
while( token != NULL )
|
|
{
|
|
GLExtensions.push_back (token);
|
|
token = strtok( NULL, " ");
|
|
}
|
|
|
|
// Get proc adress
|
|
typedef const char* (APIENTRY * PFNWGFGETEXTENSIONSSTRINGARB) (HDC);
|
|
PFNWGFGETEXTENSIONSSTRINGARB wglGetExtensionsStringARB;
|
|
if ((wglGetExtensionsStringARB=(PFNWGFGETEXTENSIONSSTRINGARB)wglGetProcAddress("wglGetExtensionsStringARB")))
|
|
{
|
|
// Get extension string
|
|
glext = wglGetExtensionsStringARB (hDC);
|
|
token = strtok ( (char*)glext.c_str (), " ");
|
|
while( token != NULL )
|
|
{
|
|
GLExtensions.push_back (token);
|
|
token = strtok( NULL, " ");
|
|
}
|
|
}
|
|
|
|
// *** RELEASE OPENGL
|
|
|
|
if (hRC)
|
|
wglDeleteContext(hRC);
|
|
if (hWnd&&hDC)
|
|
{
|
|
ReleaseDC (hWnd,hDC);
|
|
DestroyWindow (hWnd);
|
|
}
|
|
|
|
// Done
|
|
return true;
|
|
}
|
|
|
|
// ***************************************************************************
|
|
|
|
bool GetD3DInformation (NL3D::IDriver *d3dDriver)
|
|
{
|
|
IDriver::CAdapter desc;
|
|
if (d3dDriver->getAdapter (0xffffffff, desc))
|
|
{
|
|
D3DDescription = desc.Description;
|
|
D3DDeviceName = desc.DeviceName;
|
|
D3DDriver = desc.Driver;
|
|
D3DDriverVersion = toString ((uint16)(desc.DriverVersion>>48))+"."+
|
|
toString ((uint16)(desc.DriverVersion>>32))+"."+
|
|
toString ((uint16)(desc.DriverVersion>>16))+"."+
|
|
toString ((uint16)(desc.DriverVersion&0xffff));
|
|
D3DVendor = desc.Vendor;
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
// ***************************************************************************
|
|
|
|
bool GetVideoMemory ()
|
|
{
|
|
VideoMemory = 0;
|
|
bool ret = false;
|
|
|
|
// Initialise Direct Draw
|
|
IDirectDraw *dd;
|
|
HRESULT result = DirectDrawCreate(NULL, &dd, NULL);
|
|
if (result == DD_OK)
|
|
{
|
|
DDCAPS caps;
|
|
memset (&caps, 0, sizeof(DDCAPS));
|
|
caps.dwSize = sizeof(DDCAPS);
|
|
dd->GetCaps (&caps, NULL);
|
|
VideoMemory = caps.dwVidMemTotal;
|
|
ret = true;
|
|
dd->Release ();
|
|
}
|
|
|
|
// Can't get it
|
|
return ret;
|
|
}
|
|
|
|
// ***************************************************************************
|
|
|
|
bool GetHardwareSoundBuffer ()
|
|
{
|
|
bool ret = false;
|
|
HardwareSoundBuffer = 0;
|
|
|
|
// The DirectSound object
|
|
#if (DIRECTSOUND_VERSION >= 0x0800)
|
|
LPDIRECTSOUND8 _DirectSound;
|
|
#else
|
|
LPDIRECTSOUND _DirectSound;
|
|
#endif
|
|
|
|
#if (DIRECTSOUND_VERSION >= 0x0800)
|
|
if (DirectSoundCreate8(NULL, &_DirectSound, NULL) == DS_OK)
|
|
#else
|
|
if (DirectSoundCreate(NULL, &_DirectSound, NULL) == DS_OK)
|
|
#endif
|
|
{
|
|
DSCAPS caps;
|
|
memset (&caps, 0, sizeof (DSCAPS));
|
|
caps.dwSize = sizeof (DSCAPS);
|
|
|
|
HRESULT result = _DirectSound->GetCaps (&caps);
|
|
if (result == DS_OK)
|
|
{
|
|
HardwareSoundBuffer = caps.dwFreeHw3DStaticBuffers;
|
|
ret = true;
|
|
}
|
|
_DirectSound->Release ();
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
// ***************************************************************************
|
|
|
|
bool GetSystemInformation (IDriver *d3dDriver)
|
|
{
|
|
bool result = GetGLInformation ();
|
|
result |= GetD3DInformation (d3dDriver);
|
|
result |= GetVideoMemory ();
|
|
result |= GetHardwareSoundBuffer ();
|
|
SystemMemory = CSystemInfo::totalPhysicalMemory ();
|
|
CPUFrequency = (uint)(CSystemInfo::getProcessorFrequency () / (uint64)1000000);
|
|
return result;
|
|
}
|
|
// ***************************************************************************
|
|
|
|
std::vector<CVideoMode> VideoModes[2];
|
|
|
|
// ***************************************************************************
|
|
|
|
void RegisterVideoModes (uint driverId, IDriver *driver)
|
|
{
|
|
vector<GfxMode> modes;
|
|
driver->getModes (modes);
|
|
|
|
uint i;
|
|
VideoModes[driverId].clear();
|
|
for (i=0; i<modes.size(); i++)
|
|
{
|
|
// Keep only 32 bits
|
|
if ((modes[i].Depth == 32) && (modes[i].Width >= 800) && (modes[i].Width >= 600))
|
|
{
|
|
// Add this mode
|
|
CVideoMode mode;
|
|
mode.Width = modes[i].Width;
|
|
mode.Height = modes[i].Height;
|
|
mode.ColorDepth = modes[i].Depth;
|
|
mode.Frequency = modes[i].Frequency;
|
|
VideoModes[driverId].push_back (mode);
|
|
}
|
|
}
|
|
}
|
|
|
|
// ***************************************************************************
|
|
// CDisplayDlg dialog
|
|
// ***************************************************************************
|
|
|
|
CDisplayDlg::CDisplayDlg(CWnd* pParent /*=NULL*/)
|
|
: CBaseDialog(CDisplayDlg::IDD, pParent)
|
|
{
|
|
//{{AFX_DATA_INIT(CDisplayDlg)
|
|
DriverChoiceMode = DrvChooseUnknwown;
|
|
Windowed = -1;
|
|
Width = 0;
|
|
Height = 0;
|
|
Mode = -1;
|
|
PositionX = 0;
|
|
PositionY = 0;
|
|
//}}AFX_DATA_INIT
|
|
}
|
|
|
|
// ***************************************************************************
|
|
|
|
void CDisplayDlg::DoDataExchange(CDataExchange* pDX)
|
|
{
|
|
CDialog::DoDataExchange(pDX);
|
|
//{{AFX_DATA_MAP(CDisplayDlg)
|
|
DDX_Control(pDX, IDC_DISPLAY_FS_TEXT0, TextFS0);
|
|
DDX_Control(pDX, IDC_DISPLAY_WND_TEXT0, TextWnd0);
|
|
DDX_Control(pDX, IDC_DISPLAY_WND_TEXT1, TextWnd1);
|
|
DDX_Control(pDX, IDC_DISPLAY_WND_TEXT2, TextWnd2);
|
|
DDX_Control(pDX, IDC_DISPLAY_WND_TEXT3, TextWnd3);
|
|
DDX_Control(pDX, IDC_POSITION_Y, PositionYCtrl);
|
|
DDX_Control(pDX, IDC_POSITION_X, PositionXCtrl);
|
|
DDX_Control(pDX, IDC_HEIGHT, HeightCtrl);
|
|
DDX_Control(pDX, IDC_WIDTH, WidthCtrl);
|
|
DDX_Control(pDX, IDC_MODE, ModeCtrl);
|
|
DDX_Radio(pDX, IDC_DRV3D_AUTO, DriverChoiceMode);
|
|
DDX_Radio(pDX, IDC_FULLSCREEN, Windowed);
|
|
DDX_Text(pDX, IDC_WIDTH, Width);
|
|
DDX_Text(pDX, IDC_HEIGHT, Height);
|
|
DDX_CBIndex(pDX, IDC_MODE, Mode);
|
|
DDX_Text(pDX, IDC_POSITION_X, PositionX);
|
|
DDX_Text(pDX, IDC_POSITION_Y, PositionY);
|
|
//}}AFX_DATA_MAP
|
|
}
|
|
|
|
// ***************************************************************************
|
|
|
|
BEGIN_MESSAGE_MAP(CDisplayDlg, CDialog)
|
|
//{{AFX_MSG_MAP(CDisplayDlg)
|
|
ON_BN_CLICKED(IDC_FULLSCREEN, OnFullscreen)
|
|
ON_BN_CLICKED(IDC_WINDOW, OnWindow)
|
|
ON_BN_CLICKED(IDC_DIRECT3D, OnDirect3d)
|
|
ON_BN_CLICKED(IDC_DRV3D_AUTO, OnDrv3DAuto)
|
|
ON_EN_CHANGE(IDC_HEIGHT, OnChangeHeight)
|
|
ON_BN_CLICKED(IDC_OPENGL, OnOpengl)
|
|
ON_EN_CHANGE(IDC_POSITION_X, OnChangePositionX)
|
|
ON_EN_CHANGE(IDC_WIDTH, OnChangeWidth)
|
|
ON_EN_CHANGE(IDC_POSITION_Y, OnChangePositionY)
|
|
ON_CBN_SELCHANGE(IDC_MODE, OnSelchangeMode)
|
|
//}}AFX_MSG_MAP
|
|
END_MESSAGE_MAP()
|
|
|
|
// ***************************************************************************
|
|
// CDisplayDlg message handlers
|
|
// ***************************************************************************
|
|
|
|
void CDisplayDlg::OnFullscreen()
|
|
{
|
|
UpdateData (TRUE);
|
|
updateState ();
|
|
UpdateData (FALSE);
|
|
InvalidateConfig ();
|
|
}
|
|
|
|
// ***************************************************************************
|
|
|
|
void CDisplayDlg::OnWindow()
|
|
{
|
|
UpdateData (TRUE);
|
|
updateState ();
|
|
UpdateData (FALSE);
|
|
InvalidateConfig ();
|
|
}
|
|
|
|
// ***************************************************************************
|
|
|
|
void CDisplayDlg::updateState ()
|
|
{
|
|
ModeCtrl.EnableWindow (Windowed == 0);
|
|
TextFS0.EnableWindow (Windowed == 0);
|
|
WidthCtrl.EnableWindow (Windowed == 1);
|
|
HeightCtrl.EnableWindow (Windowed == 1);
|
|
PositionXCtrl.EnableWindow (Windowed == 1);
|
|
PositionYCtrl.EnableWindow (Windowed == 1);
|
|
TextWnd0.EnableWindow (Windowed == 1);
|
|
TextWnd1.EnableWindow (Windowed == 1);
|
|
TextWnd2.EnableWindow (Windowed == 1);
|
|
TextWnd3.EnableWindow (Windowed == 1);
|
|
|
|
// Fill the combobox values
|
|
ModeCtrl.ResetContent ();
|
|
uint i;
|
|
if (DriverChoiceMode != DrvChooseUnknwown)
|
|
{
|
|
TDriver actualDriver = getActualDriver();
|
|
for (i=0; i<VideoModes[actualDriver].size (); i++)
|
|
{
|
|
ucstring videoMode = toString (VideoModes[actualDriver][i].Width) + "x" + toString (VideoModes[actualDriver][i].Height) +
|
|
" " + toString (VideoModes[actualDriver][i].ColorDepth) + " " + CI18N::get ("uiConfigBits") + " " +
|
|
toString (VideoModes[actualDriver][i].Frequency) + " " + CI18N::get ("uiConfigHz");
|
|
|
|
// hulud : Don't know how to set a wide string in a combo box...
|
|
ModeCtrl.SendMessage (CB_INSERTSTRING, -1, (LPARAM)(videoMode.toString().c_str()));
|
|
}
|
|
}
|
|
|
|
// Select the string
|
|
ModeCtrl.SetCurSel (Mode);
|
|
}
|
|
|
|
// ***************************************************************************
|
|
|
|
BOOL CDisplayDlg::OnInitDialog()
|
|
{
|
|
CDialog::OnInitDialog();
|
|
|
|
updateState ();
|
|
|
|
return TRUE; // return TRUE unless you set the focus to a control
|
|
// EXCEPTION: OCX Property Pages should return FALSE
|
|
}
|
|
|
|
// ***************************************************************************
|
|
|
|
void CDisplayDlg::OnDirect3d()
|
|
{
|
|
UpdateData (TRUE);
|
|
updateState ();
|
|
UpdateData (FALSE);
|
|
InvalidateConfig ();
|
|
}
|
|
|
|
// ***************************************************************************
|
|
void CDisplayDlg::OnDrv3DAuto()
|
|
{
|
|
UpdateData (TRUE);
|
|
updateState ();
|
|
UpdateData (FALSE);
|
|
InvalidateConfig ();
|
|
}
|
|
|
|
// ***************************************************************************
|
|
|
|
void CDisplayDlg::OnChangeHeight()
|
|
{
|
|
InvalidateConfig ();
|
|
}
|
|
|
|
// ***************************************************************************
|
|
|
|
void CDisplayDlg::OnOpengl()
|
|
{
|
|
UpdateData (TRUE);
|
|
updateState ();
|
|
UpdateData (FALSE);
|
|
InvalidateConfig ();
|
|
}
|
|
|
|
// ***************************************************************************
|
|
|
|
void CDisplayDlg::OnChangePositionX()
|
|
{
|
|
InvalidateConfig ();
|
|
}
|
|
|
|
// ***************************************************************************
|
|
|
|
void CDisplayDlg::OnChangeWidth()
|
|
{
|
|
InvalidateConfig ();
|
|
}
|
|
|
|
// ***************************************************************************
|
|
|
|
void CDisplayDlg::OnChangePositionY()
|
|
{
|
|
InvalidateConfig ();
|
|
}
|
|
|
|
// ***************************************************************************
|
|
|
|
void CDisplayDlg::OnSelchangeMode()
|
|
{
|
|
InvalidateConfig ();
|
|
}
|
|
|
|
// ***************************************************************************
|
|
CDisplayDlg::TDriver CDisplayDlg::getActualDriver() const
|
|
{
|
|
switch(DriverChoiceMode)
|
|
{
|
|
case DrvChooseOpenGL: return OpenGL;
|
|
case DrvChooseDirect3D: return Direct3D;
|
|
default:
|
|
{
|
|
// D3D better on ATI Radeon cards
|
|
std::string deviceName;
|
|
uint64 drvVersion;
|
|
CSystemInfo::getVideoInfo(deviceName, drvVersion);
|
|
return strstr(toLower(deviceName).c_str(), "radeon") != NULL ? Direct3D : OpenGL;
|
|
}
|
|
}
|
|
return OpenGL;
|
|
}
|