You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

469 lines
14 KiB

/*==LICENSE==*
CyanWorlds.com Engine - MMOG client, server and tools
Copyright (C) 2011 Cyan Worlds, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
You can contact Cyan Worlds, Inc. by email legal@cyan.com
or by snail mail at:
Cyan Worlds, Inc.
14617 N Newport Hwy
Mead, WA 99021
*==LICENSE==*/
///////////////////////////////////////////////////////////////////////////////
// //
// hsG3DDeviceSelector Class Header //
// Generic device enumeration (D3D, OpenGL, etc) //
// Cyan, Inc. //
// //
//// Version History //////////////////////////////////////////////////////////
// //
// 5.21.2001 mcn - Cleaned out all the old Glide stuff, since Plasma2 will //
// not support Glide :( //
// //
///////////////////////////////////////////////////////////////////////////////
#ifndef hsG3DDeviceSelector_inc
#define hsG3DDeviceSelector_inc
#include "hsWinRef.h"
#include "hsTemplates.h"
#include "hsBitVector.h"
#ifdef HS_BUILD_FOR_WIN32
#define HS_SELECT_DIRECT3D // not supported on the Mac.
#endif // HS_BUILD_FOR_WIN32
#ifdef HS_BUILD_FOR_WIN32
#define __MSC__
#define DYNAHEADER 1
#endif // HS_BUILD_FOR_WIN32
/// #define the following to allow selection of the D3D reference driver
#define HS_ALLOW_D3D_REF_DRIVER 1
class hsStream;
struct D3DEnum_DeviceInfo;
struct D3DEnum_DriverInfo;
struct D3DEnum_DeviceInfo;
struct D3DEnum_DriverInfo;
class hsG3DDeviceMode
{
enum {
kNone = 0x0,
kDiscarded = 0x1
};
protected:
UInt32 fFlags;
UInt32 fWidth;
UInt32 fHeight;
UInt32 fDepth;
hsTArray<UInt16> fZStencilDepths; // Array of supported depth/stencil buffer formats.
// Each entry is of the form: ( stencil bit count << 8 ) | ( depth bit count )
hsTArray<UInt8> fFSAATypes; // Array of multisample types supported (each one 2-16)
hsBool fCanRenderToCubics;
public:
hsG3DDeviceMode();
~hsG3DDeviceMode();
hsBool operator< (const hsG3DDeviceMode &mode) const;
void Clear();
hsBool GetDiscarded() const { return 0 != (fFlags & kDiscarded); }
UInt32 GetWidth() const { return fWidth; }
UInt32 GetHeight() const { return fHeight; }
UInt32 GetColorDepth() const { return fDepth; }
UInt8 GetNumZStencilDepths( void ) const { return fZStencilDepths.GetCount(); }
UInt16 GetZStencilDepth( UInt8 i ) const { return fZStencilDepths[ i ]; }
UInt8 GetNumFSAATypes( void ) const { return fFSAATypes.GetCount(); }
UInt8 GetFSAAType( UInt8 i ) const { return fFSAATypes[ i ]; }
hsBool GetCanRenderToCubics( void ) const { return fCanRenderToCubics; }
void SetDiscarded(hsBool on=true) { if(on) fFlags |= kDiscarded; else fFlags &= ~kDiscarded; }
void SetWidth(UInt32 w) { fWidth = w; }
void SetHeight(UInt32 h) { fHeight = h; }
void SetColorDepth(UInt32 d) { fDepth = d; }
void ClearZStencilDepths( void ) { fZStencilDepths.Reset(); }
void AddZStencilDepth( UInt16 depth ) { fZStencilDepths.Append( depth ); }
void ClearFSAATypes( void ) { fFSAATypes.Reset(); }
void AddFSAAType( UInt8 type ) { fFSAATypes.Append( type ); }
void SetCanRenderToCubics( hsBool can ) { fCanRenderToCubics = can; }
void Read(hsStream* s);
void Write(hsStream* s) const;
};
class hsG3DDeviceRecord
{
public:
enum {
kNone = 0x0,
kDiscarded = 0x1,
kInvalid = 0x2
};
enum FogTypes {
kFogExp = 0,
kFogExp2,
kNumFogTypes
};
protected:
UInt32 fRecordVersion; /// Version starts at 2 (see .cpp for explanation)
enum {
kCurrRecordVersion = 0x0b
/// Version history:
/// 1 - Initial version (had no version #)
/// 2 - Added Z and LOD bias
/// 3 - Changed Z and LOD bias to floats, added fog tweaks
/// 4 - Changed values for fog tweaks; force reload through version #
/// 5 - Same as #4, updated fog end bias to be based solely on fog quantization/bit depth
/// 6 - Updated values for the ATI boards, Matrox, and i810
/// 7 - Added fog knee tweaks
/// 8 - Added support for multiple depth/stencil formats per mode
/// 9 - Added multisample types to the mode record
/// A - Added anisotropic sample field
/// B - Added flag for cubic textures support
};
/// Version < 2 Data
UInt32 fFlags;
UInt32 fG3DDeviceType;
UInt32 fG3DHALorHEL;
char* fG3DDriverDesc;
char* fG3DDriverName;
char* fG3DDriverVersion;
char* fG3DDeviceDesc;
hsBitVector fCaps;
UInt32 fLayersAtOnce;
UInt32 fMemoryBytes;
hsTArray<hsG3DDeviceMode> fModes;
/// New to Version 3
float fZBiasRating;
float fLODBiasRating;
float fFogExpApproxStart;
float fFogExp2ApproxStart;
float fFogEndBias; // As a percentage of the max value for fog
// (i.e. for Z fog, it's a percentage of 1 to add on,
// for W fog, it's a percentage of the yon)
/// Version 7 - Fog Knee values
float fFogKnees[ kNumFogTypes ];
float fFogKneeVals[ kNumFogTypes ];
/// Version 9 - The actual AA setting we use
UInt8 fAASetting;
/// Version A - the anisotropic level we use
UInt8 fMaxAnisotropicSamples; // 1 to disable, up to max allowed in hardware
int fPixelShaderMajorVer;
int fPixelShaderMinorVer;
public:
hsG3DDeviceRecord();
virtual ~hsG3DDeviceRecord();
hsG3DDeviceRecord(const hsG3DDeviceRecord& src);
hsG3DDeviceRecord& operator=(const hsG3DDeviceRecord& src);
UInt32 GetG3DDeviceType() const { return fG3DDeviceType; }
const char* GetG3DDeviceTypeName() const;
UInt32 GetG3DHALorHEL() const { return fG3DHALorHEL; }
UInt32 GetMemoryBytes() const { return fMemoryBytes; }
const char* GetDriverDesc() const { return fG3DDriverDesc; }
const char* GetDriverName() const { return fG3DDriverName; }
const char* GetDriverVersion() const { return fG3DDriverVersion; }
const char* GetDeviceDesc() const { return fG3DDeviceDesc; }
void SetG3DDeviceType(UInt32 t) { fG3DDeviceType = t; }
void SetG3DHALorHEL(UInt32 h) { fG3DHALorHEL = h; }
void SetMemoryBytes(UInt32 b) { fMemoryBytes = b; }
void SetDriverDesc(const char* s);
void SetDriverName(const char* s);
void SetDriverVersion(const char* s);
void SetDeviceDesc(const char* s);
hsBool GetCap(UInt32 cap) const { return fCaps.IsBitSet(cap); }
void SetCap(UInt32 cap, hsBool on=true) { fCaps.SetBit(cap, on); }
float GetZBiasRating( void ) const { return fZBiasRating; }
void SetZBiasRating( float rating ) { fZBiasRating = rating; }
float GetLODBiasRating( void ) const { return fLODBiasRating; }
void SetLODBiasRating( float rating ) { fLODBiasRating = rating; }
void GetFogApproxStarts( float &expApprox, float &exp2Approx ) const { expApprox = fFogExpApproxStart;
exp2Approx = fFogExp2ApproxStart; }
void SetFogApproxStarts( float exp, float exp2 ) { fFogExpApproxStart = exp;
fFogExp2ApproxStart = exp2; }
float GetFogEndBias( void ) const { return fFogEndBias; }
void SetFogEndBias( float rating ) { fFogEndBias = rating; }
void GetFogKneeParams( UInt8 type, float &knee, float &kneeVal ) const { knee = fFogKnees[ type ]; kneeVal = fFogKneeVals[ type ]; }
void SetFogKneeParams( UInt8 type, float knee, float kneeVal ) { fFogKnees[ type ] = knee; fFogKneeVals[ type ] = kneeVal; }
UInt32 GetLayersAtOnce() const { return fLayersAtOnce; }
void SetLayersAtOnce(UInt32 n) { fLayersAtOnce = n; }
UInt8 GetAASetting() const { return fAASetting; }
void SetAASetting( UInt8 s ) { fAASetting = s; }
UInt8 GetMaxAnisotropicSamples( void ) const { return fMaxAnisotropicSamples; }
void SetMaxAnisotropicSamples( UInt8 num ) { fMaxAnisotropicSamples = num; }
void SetDiscarded(hsBool on=true) { if(on)fFlags |= kDiscarded; else fFlags &= ~kDiscarded; }
hsBool GetDiscarded() const { return 0 != (fFlags & kDiscarded); }
void SetInvalid( hsBool on = true ) { if( on ) fFlags |= kInvalid; else fFlags &= ~kInvalid; }
hsBool IsInvalid() const { return 0 != ( fFlags & kInvalid ); }
hsTArray<hsG3DDeviceMode>& GetModes() { return fModes; }
hsG3DDeviceMode* GetMode(int i) const { return &fModes[i]; }
void ClearModes();
void Clear();
void RemoveDiscarded();
// PlaceHolder - Whether a mode can window is restricted by the current setup
// of the PC. E.g. if the user changes from 16 bit to TrueColor, the Modes that
// can window are pretty much flipped. So we'll have to pass in enough info (like
// the hWnd?) to find out what the current setup is to make sure it's compatible.
hsBool ModeCanWindow(void* ctx, hsG3DDeviceMode* mode) { return false; }
void SetPixelShaderVersion(int major, int minor) { fPixelShaderMajorVer = major; fPixelShaderMinorVer = minor; }
void GetPixelShaderVersion(int &major, int &minor) { major = fPixelShaderMajorVer; minor = fPixelShaderMinorVer; }
void Read(hsStream* s);
void Write(hsStream* s) const;
};
class hsG3DDeviceModeRecord
{
protected:
hsG3DDeviceRecord fDevice;
hsG3DDeviceMode fMode;
public:
hsG3DDeviceModeRecord();
hsG3DDeviceModeRecord(const hsG3DDeviceRecord& devRec, const hsG3DDeviceMode& devMode);
~hsG3DDeviceModeRecord();
hsG3DDeviceModeRecord(const hsG3DDeviceModeRecord& src);
hsG3DDeviceModeRecord& operator=(const hsG3DDeviceModeRecord& src);
const hsG3DDeviceRecord* GetDevice() const { return &fDevice; }
const hsG3DDeviceMode* GetMode() const { return &fMode; }
};
class hsG3DDeviceSelector : public hsRefCnt
{
public:
enum {
kDevTypeUnknown = 0,
kDevTypeGlide,
kDevTypeDirect3D,
kDevTypeOpenGL,
kDevTypeDirect3DTnL,
kNumDevTypes
};
enum {
kHHTypeUnknown = 0,
kHHD3DNullDev,
kHHD3DRampDev,
kHHD3DRGBDev,
kHHD3DHALDev,
kHHD3DMMXDev,
kHHD3DTnLHalDev,
kHHD3DRefDev,
kHHD3D3dfxDev,
kHHD3D3dfxVoodoo5Dev,
kNumHHTypes
};
enum {
kCapsNone = 0,
kCapsNoWindow,
kCapsMipmap,
kCapsPerspective,
kCapsHardware,
kCapsWBuffer,
kCapsCompressTextures,
kCapsHWTransform,
kCapsDither,
kCapsFogLinear,
kCapsFogExp,
kCapsFogExp2,
kCapsFogRange,
kCapsLODWatch,
kCapsUNUSED,
kCapsDoesSmallTextures,
kCapsPixelFog,
kCapsBadYonStuff,
kCapsNoKindaSmallTexs,
kCapsCubicTextures,
kCapsCubicMipmap,
kCapsZBias,
kCapsPixelShader,
kCapsNoAA,
kCapsDoubleFlush,
kCapsSingleFlush,
kCapsCantShadow,
kCapsMaxUVWSrc2,
kCapsCantProj,
kCapsLimitedProj,
kCapsShareDepth,
kCapsBadManaged,
kCapsNoAniso,
// etc.
kNumCaps
};
enum
{
kDefaultWidth = 800,
kDefaultHeight = 600,
kDefaultDepth = 32
};
protected:
hsTArray<hsG3DDeviceRecord> fRecords;
char fTempWinClass[ 128 ];
char fErrorString[ 128 ];
void ITryDirect3DTnLDevice(D3DEnum_DeviceInfo* devInfo, hsG3DDeviceRecord& srcDevRec);
void ITryDirect3DTnLDriver(D3DEnum_DriverInfo* drivInfo);
void ITryDirect3DTnL(hsWinRef winRef);
hsBool IInitDirect3D( void );
#ifdef HS_SELECT_DX7
void ITryDirect3DDevice(D3DEnum_DeviceInfo* devInfo, hsG3DDeviceRecord& srcDevRec);
void ITryDirect3DDriver(D3DEnum_DriverInfo* drivInfo);
void ITryDirect3D(hsWinRef winRef);
#endif // HS_SELECT_DX7
void IFudgeDirectXDevice( hsG3DDeviceRecord &record,
D3DEnum_DriverInfo *driverInfo, D3DEnum_DeviceInfo *deviceInfo );
UInt32 IAdjustDirectXMemory( UInt32 cardMem );
hsBool IGetD3DCardInfo( hsG3DDeviceRecord &record, void *driverInfo, void *deviceInfo,
DWORD *vendorID, DWORD *deviceID, char **driverString, char **descString );
#ifdef HS_SELECT_DX7
hsBool IGetD3D7CardInfo( hsG3DDeviceRecord &record, void *driverInfo, void *deviceInfo,
DWORD *vendorID, DWORD *deviceID, char **driverString, char **descString );
#endif // HS_SELECT_DX7
void ITryOpenGL( hsWinRef winRef );
void IGetExtOpenGLInfo( hsG3DDeviceRecord &devRec );
void IGetOpenGLModes( hsG3DDeviceRecord &devRec, char *driverName );
hsBool ITestOpenGLRes( int width, int height, int bitDepth,
hsG3DDeviceRecord &devRec, char *driverName );
#ifdef HS_OPEN_GL
#if HS_BUILD_FOR_WIN32
UInt32 ICreateTempOpenGLContext( HDC hDC, hsBool makeItFull );
#endif
#endif
void ISetFudgeFactors( UInt8 chipsetID, hsG3DDeviceRecord &record );
public:
hsG3DDeviceSelector();
virtual ~hsG3DDeviceSelector();
void Clear();
void RemoveDiscarded();
void RemoveUnusableDevModes(hsBool bTough); // Removes modes and devices not allowed supported in release
hsBool Init( void ); // Returns false if couldn't init
const char *GetErrorString( void ) { return fErrorString; }
void Enumerate(hsWinRef winRef);
hsTArray<hsG3DDeviceRecord>& GetDeviceRecords() { return fRecords; }
hsBool GetDefault(hsG3DDeviceModeRecord *dmr);
hsG3DDeviceRecord* GetRecord(int i) { return &fRecords[i]; }
void Read(hsStream* s);
void Write(hsStream* s);
};
#define M3DDEMOINFO 1 /// Always compiled now, but only enabled if
/// WIN_INIT has DemoInfoOutput in it
///////////////////////////////////////////////////////////////////////////////
//
// Demo Debug File header file stuff
// Created 10.10.2000 by Mathew Burrack @ Cyan, Inc.
//
///////////////////////////////////////////////////////////////////////////////
#include <stdio.h>
#include "headspin.h"
class plDemoDebugFile
{
public:
plDemoDebugFile() { fDemoDebugFP = nil; fIsOpen = false; fEnabled = false; }
~plDemoDebugFile() { IDDFClose(); }
// Static function to write a string to the DDF
static void Write( char *string );
// Static function to write two strings to the DDF
static void Write( char *string1, char *string2 );
// Static function to write a string and a signed integer value to the DDF
static void Write( char *string1, Int32 value );
// Enables or disables the DDF class
static void Enable( hsBool yes ) { fEnabled = yes; }
protected:
static hsBool fIsOpen;
static FILE *fDemoDebugFP;
static hsBool fEnabled;
// Opens the DDF for writing
static hsBool IDDFOpen( void );
// Closes the DDF
static void IDDFClose( void );
};
#endif // hsG3DDeviceSelector_inc