Initial commit
This commit is contained in:
41
engine/platformWin32/GLWinExtFunc.h
Executable file
41
engine/platformWin32/GLWinExtFunc.h
Executable file
@ -0,0 +1,41 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// Torque Game Engine
|
||||
// Copyright (C) GarageGames.com, Inc.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
#ifndef WGL_GROUP_BEGIN
|
||||
#define WGL_GROUP_BEGIN( flag )
|
||||
#define UNDEF_BEGIN
|
||||
#endif
|
||||
|
||||
#ifndef WGL_GROUP_END
|
||||
#define WGL_GROUP_END()
|
||||
#define UNDEF_END
|
||||
#endif
|
||||
|
||||
//WGL_ARB_extensions_string
|
||||
WGL_GROUP_BEGIN(WGL_ARB_extensions_string)
|
||||
WGLEXT_FUNCTION( const char*, wglGetExtensionsStringARB, (HDC), return NULL; )
|
||||
WGL_GROUP_END()
|
||||
|
||||
//WGL_EXT_swap_control
|
||||
WGL_GROUP_BEGIN(WGL_EXT_swap_control)
|
||||
WGLEXT_FUNCTION( BOOL, wglSwapIntervalEXT,(int), return 0; )
|
||||
WGLEXT_FUNCTION( int, wglGetSwapIntervalEXT,(void), return 0; )
|
||||
WGL_GROUP_END()
|
||||
|
||||
WGL_GROUP_BEGIN(WGL_3DFX_gamma_control)
|
||||
WGLEXT_FUNCTION( BOOL, wglGetDeviceGammaRamp3DFX, (HDC, LPVOID), return false; )
|
||||
WGLEXT_FUNCTION( BOOL, wglSetDeviceGammaRamp3DFX, (HDC, LPVOID), return false; )
|
||||
WGL_GROUP_END()
|
||||
|
||||
#ifdef UNDEF_BEGIN
|
||||
#undef WGL_GROUP_BEGIN
|
||||
#undef UNDEF_BEGIN
|
||||
#endif
|
||||
|
||||
#ifdef UNDEF_END
|
||||
#undef WGL_GROUP_END
|
||||
#undef UNDEF_END
|
||||
#endif
|
28
engine/platformWin32/GLWinFunc.h
Executable file
28
engine/platformWin32/GLWinFunc.h
Executable file
@ -0,0 +1,28 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// Torque Game Engine
|
||||
// Copyright (C) GarageGames.com, Inc.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
WGLD3D_FUNCTION( BOOL, CopyContext, (HGLRC, HGLRC, UINT), return false; )
|
||||
WGLD3D_FUNCTION( HGLRC, CreateContext, (HDC), return NULL; )
|
||||
//WGL_FUNCTION( HGLRC, wglCreateLayerContext, (HDC, S32), return NULL; )
|
||||
WGLD3D_FUNCTION( BOOL, DeleteContext, (HGLRC), return false; )
|
||||
WGLD3D_FUNCTION( HGLRC, GetCurrentContext, (VOID), return NULL; )
|
||||
WGLD3D_FUNCTION( HDC, GetCurrentDC, (VOID), return NULL; )
|
||||
WGLD3D_FUNCTION( PROC, GetProcAddress, (LPCSTR), return NULL; )
|
||||
WGLD3D_FUNCTION( BOOL, MakeCurrent, (HDC, HGLRC), return false; )
|
||||
WGLD3D_FUNCTION( BOOL, ShareLists, (HGLRC, HGLRC), return false; )
|
||||
//WGL_FUNCTION( BOOL, wglUseFontBitmaps, (HDC, DWORD, DWORD, DWORD), return false; )
|
||||
//WGL_FUNCTION( BOOL, wglUseFontOutlines, (HDC, DWORD, DWORD, DWORD, FLOAT, FLOAT, S32, LPGLYPHMETRICSFLOAT), return false; )
|
||||
WGLD3D_FUNCTION( BOOL, DescribeLayerPlane, (HDC, S32, S32, UINT, LPLAYERPLANEDESCRIPTOR), return false; )
|
||||
//WGL_FUNCTION( S32, wglSetLayerPaletteEntries, (HDC, S32, S32, S32, CONST COLORREF *), return 0; )
|
||||
//WGL_FUNCTION( S32, wglGetLayerPaletteEntries, (HDC, S32, S32, S32, COLORREF *), return 0; )
|
||||
//WGL_FUNCTION( BOOL, wglRealizeLayerPalette, (HDC, S32, BOOL), return false; )
|
||||
//WGL_FUNCTION( BOOL, wglSwapLayerBuffers, (HDC, UINT), return false; )
|
||||
|
||||
WGL_FUNCTION( S32, wglChoosePixelFormat,(HDC, CONST PIXELFORMATDESCRIPTOR *), return 0; )
|
||||
WGL_FUNCTION( S32, wglDescribePixelFormat, (HDC, S32, UINT, LPPIXELFORMATDESCRIPTOR), return 0; )
|
||||
WGL_FUNCTION( S32, wglGetPixelFormat, (HDC), return 0; )
|
||||
WGL_FUNCTION( BOOL, wglSetPixelFormat, (HDC, S32, CONST PIXELFORMATDESCRIPTOR *), return false; )
|
||||
WGL_FUNCTION( BOOL, wglSwapBuffers, (HDC), return false; )
|
10374
engine/platformWin32/d3dgl.cc
Executable file
10374
engine/platformWin32/d3dgl.cc
Executable file
File diff suppressed because it is too large
Load Diff
215
engine/platformWin32/d3dgl.h
Executable file
215
engine/platformWin32/d3dgl.h
Executable file
@ -0,0 +1,215 @@
|
||||
#ifndef _D3DGL_H_
|
||||
#define _D3DGL_H_
|
||||
|
||||
#define D3D_OVERLOADS
|
||||
|
||||
#ifndef __D3DX_H__
|
||||
#include "d3dx.h"
|
||||
#endif
|
||||
#ifndef _GLLIST_H_
|
||||
#include "platformWin32/gllist.h"
|
||||
#endif
|
||||
#ifndef _PLATFORMGL_H_
|
||||
#include "platformWin32/platformGL.h"
|
||||
#endif
|
||||
|
||||
#define M_2PI (3.1415926535897932384626433 * 2.0)
|
||||
#define mDegToRad(d) ((d*M_PI) / 180.0)
|
||||
|
||||
/* Multitexture extensions */
|
||||
#define GL_TEXTURE0_SGIS 0x835E
|
||||
#define GL_TEXTURE1_SGIS 0x835F
|
||||
#define GL_TEXTURE2_SGIS 0x8360
|
||||
#define GL_TEXTURE3_SGIS 0x8361
|
||||
|
||||
#define MAXGLTEXHANDLES 4096
|
||||
|
||||
struct QuakeVertex {
|
||||
D3DVALUE x, y, z;
|
||||
D3DVALUE nx, ny, nz;
|
||||
D3DCOLOR color;
|
||||
};
|
||||
|
||||
struct QuakeTVertex {
|
||||
D3DVALUE x, y, z;
|
||||
D3DVALUE nx, ny, nz;
|
||||
D3DCOLOR color;
|
||||
D3DVALUE tu, tv;
|
||||
};
|
||||
|
||||
struct QuakeMTVertex {
|
||||
D3DVALUE x, y, z;
|
||||
D3DVALUE nx, ny, nz;
|
||||
D3DCOLOR color;
|
||||
D3DVALUE tu, tv, tu2, tv2;
|
||||
};
|
||||
|
||||
struct QuakeFMTVertex {
|
||||
D3DVALUE x, y, z;
|
||||
D3DVALUE nx, ny, nz;
|
||||
D3DCOLOR diffuse;
|
||||
D3DCOLOR specular;
|
||||
D3DVALUE tu, tv, tu2, tv2;
|
||||
};
|
||||
|
||||
struct TransformedQuakeVertex {
|
||||
D3DVALUE x, y, z, rhw;
|
||||
D3DCOLOR color;
|
||||
D3DVALUE tu, tv, tu2, tv2;
|
||||
};
|
||||
|
||||
#define QUAKEVFMT (D3DFVF_XYZ | D3DFVF_NORMAL | D3DFVF_DIFFUSE)
|
||||
#define QUAKETVFMT (D3DFVF_XYZ | D3DFVF_NORMAL | D3DFVF_DIFFUSE | D3DFVF_TEX1)
|
||||
#define QUAKEMTVFMT (D3DFVF_XYZ | D3DFVF_NORMAL | D3DFVF_DIFFUSE | D3DFVF_TEX2)
|
||||
#define QUAKEFMTVFMT (D3DFVF_XYZ | D3DFVF_NORMAL | D3DFVF_DIFFUSE | D3DFVF_TEX2 | D3DFVF_SPECULAR)
|
||||
#define QUAKETRVFMT (D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_TEX2)
|
||||
|
||||
#define VBUFSIZE 2048
|
||||
#define MAXVERTSPERPRIM 128
|
||||
|
||||
#define RESPATH_QUAKE "Software\\Microsoft\\Quake"
|
||||
|
||||
struct TexInfo {
|
||||
DWORD m_block;
|
||||
DWORD m_dwStage;
|
||||
BOOL m_capture;
|
||||
GLint m_internalformat;
|
||||
D3DX_SURFACEFORMAT m_fmt;
|
||||
GLsizei m_width;
|
||||
GLsizei m_height;
|
||||
GLsizei m_oldwidth;
|
||||
GLsizei m_oldheight;
|
||||
LPDIRECTDRAWSURFACE7 m_ddsurf;
|
||||
D3DTEXTUREMINFILTER m_minmode;
|
||||
D3DTEXTUREMAGFILTER m_magmode;
|
||||
D3DTEXTUREMIPFILTER m_mipmode;
|
||||
D3DTEXTUREADDRESS m_addu, m_addv;
|
||||
};
|
||||
|
||||
struct Globals {
|
||||
// Cache Line 1
|
||||
GLenum m_prim;
|
||||
unsigned m_comp;
|
||||
unsigned m_nfv[4];
|
||||
unsigned m_vcnt[4];
|
||||
|
||||
// Cache Line 2
|
||||
void *m_verts;
|
||||
// Following always needs to be together
|
||||
/********************************/
|
||||
D3DVALUE m_nx, m_ny, m_nz;
|
||||
D3DCOLOR m_color;
|
||||
D3DVALUE m_tu, m_tv, m_tu2, m_tv2;
|
||||
/********************************/
|
||||
BOOL m_texturing;
|
||||
BOOL m_mtex;
|
||||
|
||||
// Cache Line 3
|
||||
LPDIRECT3DVERTEXBUFFER7 m_vbuf, m_tvbuf, m_mtvbuf, m_fmtvbuf;
|
||||
LPDIRECT3DDEVICE7 m_d3ddev;
|
||||
|
||||
DWORD m_shaders[2][9];
|
||||
int m_winWidth;
|
||||
int m_winHeight;
|
||||
GLint m_scix, m_sciy;
|
||||
GLsizei m_sciw, m_scih;
|
||||
GLint m_vwx, m_vwy;
|
||||
GLsizei m_vww, m_vwh;
|
||||
GLint m_lckfirst;
|
||||
GLsizei m_lckcount;
|
||||
HWND m_hwnd;
|
||||
HDC m_hdc;
|
||||
ID3DXContext *m_pD3DX;
|
||||
D3DX_SURFACEFORMAT m_ddFourBitAlphaSurfFormat;
|
||||
D3DX_SURFACEFORMAT m_ddEightBitAlphaSurfFormat;
|
||||
D3DX_SURFACEFORMAT m_ddFiveBitSurfFormat;
|
||||
D3DX_SURFACEFORMAT m_ddEightBitSurfFormat;
|
||||
D3DX_SURFACEFORMAT m_ddLuminanceSurfFormat;
|
||||
D3DX_SURFACEFORMAT m_ddAlphaSurfFormat;
|
||||
D3DDEVICEDESC7 m_dd;
|
||||
GLenum m_cullMode;
|
||||
D3DTRANSFORMSTATETYPE m_matrixMode;
|
||||
BOOL m_cullEnabled;
|
||||
BOOL m_texHandleValid;
|
||||
BOOL m_subsample;
|
||||
BOOL m_usemtex;
|
||||
BOOL m_usemipmap;
|
||||
BOOL m_doFlip;
|
||||
BOOL m_makeSquare;
|
||||
BOOL m_scissoring;
|
||||
BOOL m_updvwp;
|
||||
BOOL m_usecolorary, m_usetexcoordary[2], m_usevertexary;
|
||||
GLuint m_curstagebinding[2];
|
||||
GLenum m_curtgt, m_client_active_texture_arb;
|
||||
int m_blendmode[2];
|
||||
D3DCOLOR m_clearColor;
|
||||
GLclampd m_clearDepth;
|
||||
const GLfloat *m_vertexary;
|
||||
const void *m_colorary;
|
||||
GLsizei m_numIndices;
|
||||
WORD *m_wIndices;
|
||||
const GLfloat *m_texcoordary[2];
|
||||
LPDIRECTDRAWSURFACE7 m_curtex[2];
|
||||
GLList<D3DMATRIX> m_matrixStack[3];
|
||||
WNDPROC m_wndproc;
|
||||
DWORD m_lod;
|
||||
TexInfo m_tex[MAXGLTEXHANDLES]; // support upto MAXGLTEXHANDLES for the time being;
|
||||
GLList<GLuint> m_freeTextures;
|
||||
GLenum m_frontFace;
|
||||
BOOL m_usenormalary;
|
||||
const GLfloat *m_normalary;
|
||||
DWORD m_normalstride;
|
||||
DWORD m_texcoordstride[2];
|
||||
DWORD m_vertexstride;
|
||||
BOOL m_texgen[2];
|
||||
GLint m_texgenmode[2];
|
||||
GLfloat m_texgenplane[2][2][4];
|
||||
D3DMATRIX m_inverseworld;
|
||||
BOOL m_inversedirty;
|
||||
BOOL m_objectdirty[2];
|
||||
D3DCOLOR m_envcolor;
|
||||
DWORD m_colorstride;
|
||||
GLenum m_colortype;
|
||||
D3DLIGHT7 m_lights[8];
|
||||
GLfloat *m_spherecoords;
|
||||
DWORD m_zbias;
|
||||
BOOL m_usedirectional;
|
||||
D3DMATRIX m_curtexmatrix;
|
||||
BOOL m_usefogary;
|
||||
D3DCOLOR m_fogcolor;
|
||||
const GLfloat *m_fogary;
|
||||
DWORD m_fogstride;
|
||||
};
|
||||
|
||||
#ifndef M_PI
|
||||
#define M_PI 3.1415926536
|
||||
#endif
|
||||
|
||||
#define CEILING( A, B ) ( (A) % (B) == 0 ? (A)/(B) : (A)/(B)+1 )
|
||||
|
||||
/* To work around optimizer bug in MSVC4.1 */
|
||||
#if defined(__WIN32__) && !defined(OPENSTEP)
|
||||
void
|
||||
dummy(GLuint j, GLuint k)
|
||||
{
|
||||
}
|
||||
#else
|
||||
#define dummy(J, K)
|
||||
#endif
|
||||
|
||||
/* EXT_bgra */
|
||||
#define GL_BGR 0x80E0
|
||||
#define GL_BGRA 0x80E1
|
||||
|
||||
/* Errors */
|
||||
#define GLU_NO_ERROR 0
|
||||
#define GLU_ERROR 100103
|
||||
#define GLU_INVALID_ENUM 100900
|
||||
#define GLU_INVALID_VALUE 100901
|
||||
#define GLU_OUT_OF_MEMORY 100902
|
||||
|
||||
/* GLU 1.1 and later */
|
||||
#define GLU_VERSION 100800
|
||||
#define GLU_EXTENSIONS 100801
|
||||
|
||||
#endif
|
1038
engine/platformWin32/gl_types.h
Executable file
1038
engine/platformWin32/gl_types.h
Executable file
File diff suppressed because it is too large
Load Diff
178
engine/platformWin32/platformGL.h
Executable file
178
engine/platformWin32/platformGL.h
Executable file
@ -0,0 +1,178 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// Torque Game Engine
|
||||
// Copyright (c) 2003 GarageGames.Com
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#ifndef _PLATFORMGL_H_
|
||||
#define _PLATFORMGL_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "platformWin32/gl_types.h"
|
||||
|
||||
#define GLAPI extern
|
||||
#define GLAPIENTRY __stdcall
|
||||
|
||||
#include "platformWin32/gl_types.h"
|
||||
|
||||
#define GL_FUNCTION(fn_type,fn_name,fn_args, fn_value) extern fn_type (__stdcall *fn_name)fn_args;
|
||||
#include "platform/GLCoreFunc.h"
|
||||
#include "platform/GLExtFunc.h"
|
||||
#include "platform/GLUFunc.h"
|
||||
#undef GL_FUNCTION
|
||||
|
||||
/* EXT_vertex_buffer */
|
||||
#define GL_V12MTVFMT_EXT 0x8702
|
||||
#define GL_V12MTNVFMT_EXT 0x8703
|
||||
#define GL_V12FTVFMT_EXT 0x8704
|
||||
#define GL_V12FMTVFMT_EXT 0x8705
|
||||
|
||||
struct GLState
|
||||
{
|
||||
bool suppARBMultitexture;
|
||||
bool suppEXTblendcolor;
|
||||
bool suppEXTblendminmax;
|
||||
bool suppPackedPixels;
|
||||
bool suppTexEnvAdd;
|
||||
bool suppLockedArrays;
|
||||
bool suppTextureEnvCombine;
|
||||
bool suppVertexArrayRange;
|
||||
bool suppFogCoord;
|
||||
bool suppEdgeClamp;
|
||||
bool suppTextureCompression;
|
||||
bool suppS3TC;
|
||||
bool suppFXT1;
|
||||
bool suppTexAnisotropic;
|
||||
bool suppPalettedTexture;
|
||||
bool suppVertexBuffer;
|
||||
bool suppSwapInterval;
|
||||
|
||||
unsigned int triCount[4];
|
||||
unsigned int primCount[4];
|
||||
unsigned int primMode; // 0-3
|
||||
|
||||
GLfloat maxAnisotropy;
|
||||
GLint maxTextureUnits;
|
||||
};
|
||||
|
||||
extern GLState gGLState;
|
||||
#define UNSIGNED_SHORT_5_6_5 0x8363
|
||||
#define UNSIGNED_SHORT_5_6_5_REV 0x8364
|
||||
|
||||
extern bool gOpenGLDisablePT;
|
||||
extern bool gOpenGLDisableCVA;
|
||||
extern bool gOpenGLDisableTEC;
|
||||
extern bool gOpenGLDisableARBMT;
|
||||
extern bool gOpenGLDisableFC;
|
||||
extern bool gOpenGLDisableTCompress;
|
||||
extern bool gOpenGLNoEnvColor;
|
||||
extern float gOpenGLGammaCorrection;
|
||||
extern bool gOpenGLNoDrawArraysAlpha;
|
||||
|
||||
inline void dglSetRenderPrimType(unsigned int type)
|
||||
{
|
||||
gGLState.primMode = type;
|
||||
}
|
||||
|
||||
inline void dglClearPrimMetrics()
|
||||
{
|
||||
for(int i = 0; i < 4; i++)
|
||||
gGLState.triCount[i] = gGLState.primCount[i] = 0;
|
||||
}
|
||||
|
||||
inline bool dglDoesSupportPalettedTexture()
|
||||
{
|
||||
return gGLState.suppPalettedTexture && (gOpenGLDisablePT == false);
|
||||
}
|
||||
|
||||
inline bool dglDoesSupportCompiledVertexArray()
|
||||
{
|
||||
return gGLState.suppLockedArrays && (gOpenGLDisableCVA == false);
|
||||
}
|
||||
|
||||
inline bool dglDoesSupportTextureEnvCombine()
|
||||
{
|
||||
return gGLState.suppTextureEnvCombine && (gOpenGLDisableTEC == false);
|
||||
}
|
||||
|
||||
inline bool dglDoesSupportARBMultitexture()
|
||||
{
|
||||
return gGLState.suppARBMultitexture && (gOpenGLDisableARBMT == false);
|
||||
}
|
||||
|
||||
inline bool dglDoesSupportEXTBlendColor()
|
||||
{
|
||||
return gGLState.suppEXTblendcolor;
|
||||
}
|
||||
|
||||
inline bool dglDoesSupportEXTBlendMinMax()
|
||||
{
|
||||
return gGLState.suppEXTblendminmax;
|
||||
}
|
||||
|
||||
inline bool dglDoesSupportVertexArrayRange()
|
||||
{
|
||||
return gGLState.suppVertexArrayRange;
|
||||
}
|
||||
|
||||
inline bool dglDoesSupportFogCoord()
|
||||
{
|
||||
return gGLState.suppFogCoord && (gOpenGLDisableFC == false);
|
||||
}
|
||||
|
||||
inline bool dglDoesSupportEdgeClamp()
|
||||
{
|
||||
return gGLState.suppEdgeClamp;
|
||||
}
|
||||
|
||||
inline bool dglDoesSupportTextureCompression()
|
||||
{
|
||||
return gGLState.suppTextureCompression && (gOpenGLDisableTCompress == false);
|
||||
}
|
||||
|
||||
inline bool dglDoesSupportS3TC()
|
||||
{
|
||||
return gGLState.suppS3TC;
|
||||
}
|
||||
|
||||
inline bool dglDoesSupportFXT1()
|
||||
{
|
||||
return gGLState.suppFXT1;
|
||||
}
|
||||
|
||||
inline bool dglDoesSupportTexEnvAdd()
|
||||
{
|
||||
return gGLState.suppTexEnvAdd;
|
||||
}
|
||||
|
||||
inline bool dglDoesSupportTexAnisotropy()
|
||||
{
|
||||
return gGLState.suppTexAnisotropic;
|
||||
}
|
||||
|
||||
inline bool dglDoesSupportVertexBuffer()
|
||||
{
|
||||
return gGLState.suppVertexBuffer;
|
||||
}
|
||||
|
||||
inline GLfloat dglGetMaxAnisotropy()
|
||||
{
|
||||
return gGLState.maxAnisotropy;
|
||||
}
|
||||
|
||||
inline GLint dglGetMaxTextureUnits()
|
||||
{
|
||||
if (dglDoesSupportARBMultitexture())
|
||||
return gGLState.maxTextureUnits;
|
||||
else
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
91
engine/platformWin32/platformWin32.h
Executable file
91
engine/platformWin32/platformWin32.h
Executable file
@ -0,0 +1,91 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// Torque Game Engine
|
||||
// Copyright (C) GarageGames.com, Inc.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#ifndef _PLATFORMWIN32_H_
|
||||
#define _PLATFORMWIN32_H_
|
||||
|
||||
// Sanity check for UNICODE
|
||||
#ifdef TORQUE_UNICODE
|
||||
# ifndef UNICODE
|
||||
# error "ERROR: You must have UNICODE defined in your preprocessor settings (ie, /DUNICODE) if you have TORQUE_UNICODE enabled in torqueConfig.h!"
|
||||
# endif
|
||||
#endif
|
||||
|
||||
// define this so that we can use WM_MOUSEWHEEL messages...
|
||||
#ifndef _WIN32_WINNT
|
||||
#define _WIN32_WINNT 0x0400
|
||||
#endif
|
||||
|
||||
#include <windows.h>
|
||||
#ifndef _PLATFORM_H_
|
||||
#include "platform/platform.h"
|
||||
#endif
|
||||
|
||||
#if defined(TORQUE_COMPILER_CODEWARRIOR)
|
||||
# include <ansi_prefix.win32.h>
|
||||
# include <stdio.h>
|
||||
# include <string.h>
|
||||
#else
|
||||
# include <stdio.h>
|
||||
# include <string.h>
|
||||
#endif
|
||||
|
||||
#if defined(TORQUE_COMPILER_VISUALC) || defined(TORQUE_COMPILER_GCC2)
|
||||
#define vsnprintf _vsnprintf
|
||||
#define stricmp _stricmp
|
||||
#define strnicmp _strnicmp
|
||||
#define strupr _strupr
|
||||
#define strlwr _strlwr
|
||||
#endif
|
||||
|
||||
#define NOMINMAX
|
||||
|
||||
struct Win32PlatState
|
||||
{
|
||||
FILE *log_fp;
|
||||
HINSTANCE hinstOpenGL;
|
||||
HINSTANCE hinstGLU;
|
||||
HINSTANCE hinstOpenAL;
|
||||
HWND appWindow;
|
||||
HDC appDC;
|
||||
HINSTANCE appInstance;
|
||||
HGLRC hGLRC;
|
||||
DWORD processId;
|
||||
|
||||
#ifdef UNICODE
|
||||
HIMC imeHandle;
|
||||
#endif
|
||||
|
||||
S32 desktopBitsPixel;
|
||||
S32 desktopWidth;
|
||||
S32 desktopHeight;
|
||||
U32 currentTime;
|
||||
|
||||
Win32PlatState();
|
||||
};
|
||||
|
||||
extern Win32PlatState winState;
|
||||
|
||||
extern bool GL_Init( const char *dllname_gl, const char *dllname_glu );
|
||||
extern bool GL_EXT_Init();
|
||||
extern void GL_Shutdown();
|
||||
|
||||
extern HWND CreateOpenGLWindow( U32 width, U32 height, bool fullScreen );
|
||||
extern HWND CreateCurtain( U32 width, U32 height );
|
||||
extern void CreatePixelFormat( PIXELFORMATDESCRIPTOR *pPFD, S32 colorBits, S32 depthBits, S32 stencilBits, bool stereo );
|
||||
extern S32 ChooseBestPixelFormat( HDC hDC, PIXELFORMATDESCRIPTOR *pPFD );
|
||||
extern void setModifierKeys( S32 modKeys );
|
||||
|
||||
#define WGLD3D_FUNCTION(fn_type, fn_name, fn_args, fn_value) extern fn_type (__stdcall *dwgl##fn_name)fn_args;
|
||||
#define WGL_FUNCTION(fn_type, fn_name, fn_args, fn_value) extern fn_type (__stdcall *d##fn_name)fn_args;
|
||||
#include "platformWin32/GLWinFunc.h"
|
||||
#undef WGL_FUNCTION
|
||||
#undef WGLD3D_FUNCTION
|
||||
|
||||
#define WGLEXT_FUNCTION(fn_type, fn_name, fn_args, fn_value) extern fn_type (__stdcall *d##fn_name)fn_args;
|
||||
#include "platformWin32/GLWinExtFunc.h"
|
||||
#undef WGLEXT_FUNCTION
|
||||
|
||||
#endif //_PLATFORMWIN32_H_
|
37
engine/platformWin32/win32NPatch.h
Executable file
37
engine/platformWin32/win32NPatch.h
Executable file
@ -0,0 +1,37 @@
|
||||
// for the moment, this seems to be the best roundup of
|
||||
// the npatch extensions on the PC.
|
||||
|
||||
#ifndef GL_ATI_pn_triangles
|
||||
#define GL_ATI_pn_triangles 1
|
||||
|
||||
#define GL_PN_TRIANGLES_ATI 0x87F0
|
||||
#define GL_MAX_PN_TRIANGLES_TESSELATION_LEVEL_ATI 0x87F1
|
||||
#define GL_PN_TRIANGLES_POINT_MODE_ATI 0x87F2
|
||||
#define GL_PN_TRIANGLES_NORMAL_MODE_ATI 0x87F3
|
||||
#define GL_PN_TRIANGLES_TESSELATION_LEVEL_ATI 0x87F4
|
||||
#define GL_PN_TRIANGLES_POINT_MODE_LINEAR_ATI 0x87F5
|
||||
#define GL_PN_TRIANGLES_POINT_MODE_CUBIC_ATI 0x87F6
|
||||
#define GL_PN_TRIANGLES_NORMAL_MODE_LINEAR_ATI 0x87F7
|
||||
#define GL_PN_TRIANGLES_NORMAL_MODE_QUADRATIC_ATI 0x87F8
|
||||
|
||||
typedef void (APIENTRY *PFNGLPNTRIANGLESIATIPROC)(GLenum pname, GLint param);
|
||||
typedef void (APIENTRY *PFNGLPNTRIANGLESFATIPROC)(GLenum pname, GLfloat param);
|
||||
|
||||
#endif
|
||||
|
||||
#define GL_NPATCH_EXT_STRING "GL_ATI_pn_triangles"
|
||||
#define GL_NPATCH_SETINT_STRING "glPNTrianglesiATI"
|
||||
typedef PFNGLPNTRIANGLESIATIPROC PFNNPatchSetInt;
|
||||
|
||||
#define GETINT_NPATCH_MAX_LEVEL GL_MAX_PN_TRIANGLES_TESSELATION_LEVEL_ATI
|
||||
#define GL_NPATCH_FLAG GL_PN_TRIANGLES_ATI
|
||||
#define GL_NPATCH_LOD GL_PN_TRIANGLES_TESSELATION_LEVEL_ATI
|
||||
|
||||
#define SETINT_NPATCH_POINTINTERP GL_PN_TRIANGLES_POINT_MODE_ATI
|
||||
#define SETINT_NPATCH_NORMALINTERP GL_PN_TRIANGLES_NORMAL_MODE_ATI
|
||||
|
||||
#define NPATCH_POINTINTERP_MIN GL_PN_TRIANGLES_POINT_MODE_LINEAR_ATI
|
||||
#define NPATCH_POINTINTERP_MAX GL_PN_TRIANGLES_POINT_MODE_CUBIC_ATI
|
||||
|
||||
#define NPATCH_NORMALINTERP_MIN GL_PN_TRIANGLES_NORMAL_MODE_LINEAR_ATI
|
||||
#define NPATCH_NORMALINTERP_MAX GL_PN_TRIANGLES_NORMAL_MODE_QUADRATIC_ATI
|
336
engine/platformWin32/winAsmBlit.cc
Executable file
336
engine/platformWin32/winAsmBlit.cc
Executable file
@ -0,0 +1,336 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// Torque Game Engine
|
||||
// Copyright (C) GarageGames.com, Inc.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "terrain/terrData.h"
|
||||
#include "math/mMath.h"
|
||||
#include "dgl/dgl.h"
|
||||
#include "dgl/gBitmap.h"
|
||||
#include "terrain/terrRender.h"
|
||||
|
||||
#if !defined(__MWERKS__) && defined(_MSC_VER)
|
||||
#define asm _asm
|
||||
#endif
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
//void terrMipBlit_asm(U16 *dest, U32 destStride, U32 squareSize, const U8 *sourcePtr, U32 sourceStep, U32 sourceRowAdd)
|
||||
//{
|
||||
// //for(U32 k = 0; k < squareSize; k++)
|
||||
// //{
|
||||
// // for(U32 l = 0; l < squareSize; l++)
|
||||
// // {
|
||||
// // dest[l] = *((U16 *) sourcePtr);
|
||||
// // sourcePtr += sourceStep;
|
||||
// // }
|
||||
// // dest -= destStride;
|
||||
// // sourcePtr += sourceRowAdd;
|
||||
// //}
|
||||
// if(sourceStep == 2)
|
||||
// {
|
||||
// destStride <<= 1;
|
||||
// sourceRowAdd += squareSize << 1;
|
||||
// asm
|
||||
// {
|
||||
// push eax
|
||||
// push ebx
|
||||
// push ecx
|
||||
// push edx
|
||||
// push edi
|
||||
// push esi
|
||||
//
|
||||
// mov edx, squareSize
|
||||
// mov edi, dest
|
||||
// mov esi, sourcePtr
|
||||
// shr edx, 1
|
||||
// mov ecx, 0
|
||||
// mov ebx, 0
|
||||
// pixelLoop2:
|
||||
// mov eax, [esi+ebx*4]
|
||||
// mov [edi+ebx*4], eax
|
||||
// inc ebx
|
||||
// cmp ebx, edx
|
||||
// jnz pixelLoop2
|
||||
//
|
||||
// mov ebx, 0
|
||||
// inc ecx
|
||||
// sub edi, destStride
|
||||
// add esi, sourceRowAdd
|
||||
// cmp ecx, squareSize
|
||||
// jl pixelLoop2
|
||||
//
|
||||
// pop esi
|
||||
// pop edi
|
||||
// pop edx
|
||||
// pop ecx
|
||||
// pop ebx
|
||||
// pop eax
|
||||
// }
|
||||
// }
|
||||
// else if(sourceStep == -2)
|
||||
// {
|
||||
// destStride <<= 1;
|
||||
// asm
|
||||
// {
|
||||
// push eax
|
||||
// push ebx
|
||||
// push ecx
|
||||
// push edx
|
||||
// push edi
|
||||
// push esi
|
||||
//
|
||||
// mov edx, squareSize
|
||||
// mov edi, dest
|
||||
// mov esi, sourcePtr
|
||||
// shr edx, 1
|
||||
// mov ecx, 0
|
||||
// mov ebx, 0
|
||||
// pixelLoopNeg2:
|
||||
// mov eax, [esi-2]
|
||||
// sub esi, 4
|
||||
// ror eax, 16
|
||||
// mov [edi+ebx*4], eax
|
||||
// inc ebx
|
||||
// cmp ebx, edx
|
||||
// jnz pixelLoopNeg2
|
||||
//
|
||||
// mov ebx, 0
|
||||
// inc ecx
|
||||
// sub edi, destStride
|
||||
// add esi, sourceRowAdd
|
||||
// cmp ecx, squareSize
|
||||
// jl pixelLoopNeg2
|
||||
//
|
||||
// pop esi
|
||||
// pop edi
|
||||
// pop edx
|
||||
// pop ecx
|
||||
// pop ebx
|
||||
// pop eax
|
||||
// }
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// destStride = (destStride + squareSize) << 1;
|
||||
// asm
|
||||
// {
|
||||
// push eax
|
||||
// push ebx
|
||||
// push ecx
|
||||
// push edx
|
||||
// push edi
|
||||
// push esi
|
||||
//
|
||||
// mov eax, squareSize
|
||||
// mov edi, dest
|
||||
// mov esi, sourcePtr
|
||||
// lea edx, [edi + eax * 2]
|
||||
// mov ecx, 0 // row index
|
||||
// mov ebx, sourceStep
|
||||
// pixelLoop:
|
||||
// mov ax, [esi+ebx]
|
||||
// shl eax, 16
|
||||
// add edi, 4
|
||||
// mov ax, [esi]
|
||||
// lea esi, [esi+ebx*2]
|
||||
// mov [edi-4], eax
|
||||
// cmp edi, edx
|
||||
// jnz pixelLoop
|
||||
//
|
||||
// inc ecx
|
||||
// sub edi, destStride
|
||||
// mov eax, squareSize
|
||||
// add esi, sourceRowAdd
|
||||
// lea edx, [edi + eax * 2]
|
||||
// cmp ecx, squareSize
|
||||
// jl pixelLoop
|
||||
//
|
||||
// pop esi
|
||||
// pop edi
|
||||
// pop edx
|
||||
// pop ecx
|
||||
// pop ebx
|
||||
// pop eax
|
||||
// }
|
||||
// }
|
||||
//}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
void bitmapExtrude5551_asm(const void *srcMip, void *mip, U32 height, U32 width)
|
||||
{
|
||||
const U16 *src = (const U16 *) srcMip;
|
||||
U16 *dst = (U16 *) mip;
|
||||
U32 stride = width << 1;
|
||||
|
||||
for(U32 y = 0; y < height; y++)
|
||||
{
|
||||
for(U32 x = 0; x < width; x++)
|
||||
{
|
||||
U32 a = src[0];
|
||||
U32 b = src[1];
|
||||
U32 c = src[stride];
|
||||
U32 d = src[stride+1];
|
||||
dst[x] = ((((a >> 11) + (b >> 11) + (c >> 11) + (d >> 11)) >> 2) << 11) |
|
||||
((( ((a >> 6) & 0x1f) + ((b >> 6) & 0x1f) + ((c >> 6) & 0x1f) + ((d >> 6) & 0x1F) ) >> 2) << 6) |
|
||||
((( ((a >> 1) & 0x1F) + ((b >> 1) & 0x1F) + ((c >> 1) & 0x1f) + ((d >> 1) & 0x1f)) >> 2) << 1);
|
||||
src += 2;
|
||||
}
|
||||
src += stride;
|
||||
dst += width;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#if defined(TORQUE_SUPPORTS_VC_INLINE_X86_ASM)
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
void bitmapExtrudeRGB_mmx(const void *srcMip, void *mip, U32 srcHeight, U32 srcWidth)
|
||||
{
|
||||
if (srcHeight == 1 || srcWidth == 1) {
|
||||
bitmapExtrudeRGB_c(srcMip, mip, srcHeight, srcWidth);
|
||||
return;
|
||||
}
|
||||
|
||||
U32 width = srcWidth >> 1;
|
||||
U32 height = srcHeight >> 1;
|
||||
|
||||
if (width <= 1)
|
||||
{
|
||||
bitmapExtrudeRGB_c(srcMip, mip, srcHeight, srcWidth);
|
||||
return;
|
||||
}
|
||||
|
||||
U64 ZERO = 0x0000000000000000;
|
||||
const U8 *src = (const U8 *) srcMip;
|
||||
U8 *dst = (U8 *) mip;
|
||||
U32 srcStride = (width << 1) * 3;
|
||||
U32 dstStride = width * 3;
|
||||
|
||||
for(U32 y = 0; y < height; y++)
|
||||
{
|
||||
asm
|
||||
{
|
||||
mov eax, src
|
||||
mov ebx, eax
|
||||
add ebx, srcStride
|
||||
mov ecx, dst
|
||||
mov edx, width
|
||||
|
||||
//--------------------------------------
|
||||
row_loop:
|
||||
|
||||
punpcklbw mm0, [eax]
|
||||
psrlw mm0, 8
|
||||
|
||||
punpcklbw mm1, [eax+3]
|
||||
psrlw mm1, 8
|
||||
paddw mm0, mm1
|
||||
|
||||
punpcklbw mm1, [ebx]
|
||||
psrlw mm1, 8
|
||||
paddw mm0, mm1
|
||||
|
||||
punpcklbw mm1, [ebx+3]
|
||||
psrlw mm1, 8
|
||||
paddw mm0, mm1
|
||||
|
||||
psrlw mm0, 2
|
||||
//pxor mm1, mm1
|
||||
packuswb mm0, ZERO // mm1
|
||||
|
||||
movd [ecx], mm0
|
||||
add eax, 6
|
||||
add ebx, 6
|
||||
add ecx, 3
|
||||
dec edx
|
||||
jnz row_loop
|
||||
}
|
||||
src += srcStride + srcStride; // advance to next line
|
||||
dst += dstStride;
|
||||
}
|
||||
asm
|
||||
{
|
||||
emms
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
void bitmapConvertRGB_to_5551_mmx(U8 *src, U32 pixels)
|
||||
{
|
||||
U64 MULFACT = 0x0008200000082000; // RGB quad word multiplier
|
||||
U64 REDBLUE = 0x00f800f800f800f8; // Red-Blue mask
|
||||
U64 GREEN = 0x0000f8000000f800; // Green mask
|
||||
U64 ALPHA = 0x0000000000010001; // 100% Alpha mask
|
||||
U64 ZERO = 0x0000000000000000;
|
||||
|
||||
U32 evenPixels = pixels >> 1; // the MMX loop can only do an even number
|
||||
U32 oddPixels = pixels & 1; // of pixels since it processes 2 at a time
|
||||
|
||||
U16 *dst = (U16*)src;
|
||||
|
||||
if (evenPixels)
|
||||
{
|
||||
asm
|
||||
{
|
||||
mov eax, src // YES, src = dst at start
|
||||
mov ebx, dst // convert image in place
|
||||
mov edx, evenPixels
|
||||
|
||||
pixel_loop2:
|
||||
movd mm0, [eax] // get first 24-bit pixel
|
||||
movd mm1, [eax+3] // get second 24-bit pixel
|
||||
punpckldq mm0, mm1 // put second in high dword
|
||||
movq mm1, mm0 // save the original data
|
||||
pand mm0, REDBLUE // mask out all but the 5MSBits of red and blue
|
||||
pmaddwd mm0, MULFACT // multiply each word by
|
||||
// 2**13, 2**3, 2**13, 2**3 and add results
|
||||
pand mm1, GREEN // mask out all but the 5MSBits of green
|
||||
por mm0, mm1 // combine the red, green, and blue bits
|
||||
psrld mm0, 6 // shift into position
|
||||
packssdw mm0, ZERO // pack into single dword
|
||||
pslld mm0, 1 // shift into final position
|
||||
por mm0, ALPHA // add the alpha bit
|
||||
movd [ebx], mm0
|
||||
|
||||
add eax, 6
|
||||
add ebx, 4
|
||||
dec edx
|
||||
jnz pixel_loop2
|
||||
|
||||
mov src, eax
|
||||
mov dst, ebx
|
||||
emms
|
||||
}
|
||||
}
|
||||
|
||||
if (oddPixels)
|
||||
{
|
||||
U32 r = src[0] >> 3;
|
||||
U32 g = src[1] >> 3;
|
||||
U32 b = src[2] >> 3;
|
||||
|
||||
*dst = (b << 1) | (g << 6) | (r << 11) | 1;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
void PlatformBlitInit()
|
||||
{
|
||||
bitmapExtrude5551 = bitmapExtrude5551_asm;
|
||||
bitmapExtrudeRGB = bitmapExtrudeRGB_c;
|
||||
|
||||
if (Platform::SystemInfo.processor.properties & CPU_PROP_MMX)
|
||||
{
|
||||
#if defined(TORQUE_SUPPORTS_VC_INLINE_X86_ASM)
|
||||
bitmapExtrudeRGB = bitmapExtrudeRGB_mmx;
|
||||
bitmapConvertRGB_to_5551 = bitmapConvertRGB_to_5551_mmx;
|
||||
#endif
|
||||
}
|
||||
// terrMipBlit = terrMipBlit_asm;
|
||||
}
|
241
engine/platformWin32/winCPUInfo.cc
Executable file
241
engine/platformWin32/winCPUInfo.cc
Executable file
@ -0,0 +1,241 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// Torque Game Engine
|
||||
// Copyright (C) GarageGames.com, Inc.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "platform/platform.h"
|
||||
#include "platformWin32/platformWin32.h"
|
||||
#include "console/console.h"
|
||||
#include "core/stringTable.h"
|
||||
#include <math.h>
|
||||
|
||||
Platform::SystemInfo_struct Platform::SystemInfo;
|
||||
extern void PlatformBlitInit();
|
||||
extern void SetProcessorInfo(Platform::SystemInfo_struct::Processor& pInfo,
|
||||
char* vendor, U32 processor, U32 properties); // platform/platformCPU.cc
|
||||
|
||||
|
||||
#if defined(TORQUE_SUPPORTS_NASM)
|
||||
// asm cpu detection routine from platform code
|
||||
extern "C"
|
||||
{
|
||||
void detectX86CPUInfo(char *vendor, U32 *processor, U32 *properties);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
void Processor::init()
|
||||
{
|
||||
// Reference:
|
||||
// www.cyrix.com
|
||||
// www.amd.com
|
||||
// www.intel.com
|
||||
// http://developer.intel.com/design/PentiumII/manuals/24512701.pdf
|
||||
|
||||
Con::printf("Processor Init:");
|
||||
|
||||
Platform::SystemInfo.processor.type = CPU_X86Compatible;
|
||||
Platform::SystemInfo.processor.name = StringTable->insert("Unknown x86 Compatible");
|
||||
Platform::SystemInfo.processor.mhz = 0;
|
||||
Platform::SystemInfo.processor.properties = CPU_PROP_C;
|
||||
|
||||
char vendor[13] = {0,};
|
||||
U32 properties = 0;
|
||||
U32 processor = 0;
|
||||
|
||||
#if defined(TORQUE_SUPPORTS_NASM)
|
||||
|
||||
detectX86CPUInfo(vendor, &processor, &properties);
|
||||
|
||||
#elif defined(TORQUE_SUPPORTS_VC_INLINE_X86_ASM)
|
||||
__asm
|
||||
{
|
||||
//--------------------------------------
|
||||
// is CPUID supported
|
||||
push ebx
|
||||
push edx
|
||||
push ecx
|
||||
pushfd
|
||||
pushfd // save EFLAGS to stack
|
||||
pop eax // move EFLAGS into EAX
|
||||
mov ebx, eax
|
||||
xor eax, 0x200000 // flip bit 21
|
||||
push eax
|
||||
popfd // restore EFLAGS
|
||||
pushfd
|
||||
pop eax
|
||||
cmp eax, ebx
|
||||
jz EXIT // doesn't support CPUID instruction
|
||||
|
||||
//--------------------------------------
|
||||
// Get Vendor Informaion using CPUID eax==0
|
||||
xor eax, eax
|
||||
cpuid
|
||||
|
||||
mov DWORD PTR vendor, ebx
|
||||
mov DWORD PTR vendor+4, edx
|
||||
mov DWORD PTR vendor+8, ecx
|
||||
|
||||
// get Generic Extended CPUID info
|
||||
mov eax, 1
|
||||
cpuid // eax=1, so cpuid queries feature information
|
||||
|
||||
and eax, 0x0ff0
|
||||
mov processor, eax // just store the model bits
|
||||
mov properties, edx
|
||||
|
||||
// Want to check for 3DNow(tm). Need to see if extended cpuid functions present.
|
||||
mov eax, 0x80000000
|
||||
cpuid
|
||||
cmp eax, 0x80000000
|
||||
jbe MAYBE_3DLATER
|
||||
mov eax, 0x80000001
|
||||
cpuid
|
||||
and edx, 0x80000000 // 3DNow if bit 31 set -> put bit in our properties
|
||||
or properties, edx
|
||||
MAYBE_3DLATER:
|
||||
|
||||
|
||||
EXIT:
|
||||
popfd
|
||||
pop ecx
|
||||
pop edx
|
||||
pop ebx
|
||||
}
|
||||
#endif
|
||||
|
||||
SetProcessorInfo(Platform::SystemInfo.processor, vendor, processor, properties);
|
||||
|
||||
// now calculate speed of processor...
|
||||
U16 nearmhz = 0; // nearest rounded mhz
|
||||
U16 mhz = 0; // calculated value.
|
||||
#if defined(TORQUE_SUPPORTS_VC_INLINE_X86_ASM) || defined(TORQUE_COMPILER_MINGW)
|
||||
//--------------------------------------
|
||||
// if RDTSC support calculate the aproximate Mhz of the CPU
|
||||
if (Platform::SystemInfo.processor.properties & CPU_PROP_RDTSC &&
|
||||
Platform::SystemInfo.processor.properties & CPU_PROP_FPU)
|
||||
{
|
||||
const U32 msToWait = 1000; // bigger this is, more accurate we are.
|
||||
U32 tsLo1 = 0, tsHi1 = 0; // time stamp storage.
|
||||
U32 tsLo2 = 0, tsHi2 = 0; // time stamp storage.
|
||||
U16 Nearest66Mhz = 0, Delta66Mhz = 0;
|
||||
U16 Nearest50Mhz = 0, Delta50Mhz = 0;
|
||||
F64 tsFirst, tsSecond, tsDelta;
|
||||
U32 ms;
|
||||
|
||||
// starting time marker.
|
||||
ms = GetTickCount(); // !!!!TBD - this function may have too high an error... dunno.
|
||||
|
||||
#if defined(TORQUE_COMPILER_MINGW)
|
||||
asm ("rdtsc" : "=a" (tsLo1), "=d" (tsHi1));
|
||||
#elif defined(TORQUE_SUPPORTS_VC_INLINE_X86_ASM) // VC|CW
|
||||
__asm
|
||||
{
|
||||
push eax
|
||||
push edx
|
||||
rdtsc
|
||||
mov tsLo1, eax
|
||||
mov tsHi1, edx
|
||||
pop edx
|
||||
pop eax
|
||||
}
|
||||
#endif
|
||||
|
||||
// the faster this check and exit is, the more accurate the time-stamp-delta will be.
|
||||
while(GetTickCount() < ms + msToWait) {};
|
||||
|
||||
#if defined(TORQUE_COMPILER_MINGW)
|
||||
asm ("rdtsc" : "=a" (tsLo2), "=d" (tsHi2));
|
||||
#elif defined(TORQUE_SUPPORTS_VC_INLINE_X86_ASM) // VC|CW
|
||||
__asm
|
||||
{
|
||||
push eax
|
||||
push edx
|
||||
rdtsc
|
||||
mov tsLo2, eax
|
||||
mov tsHi2, edx
|
||||
pop edx
|
||||
pop eax
|
||||
}
|
||||
#endif
|
||||
|
||||
// do calculations in doubles for accuracy, since we're working with 64-bit math here...
|
||||
// grabbed this from the MINGW sample.
|
||||
tsFirst = ((F64)tsHi1 * (F64)0x10000 * (F64)0x10000) + (F64)tsLo1;
|
||||
tsSecond = ((F64)tsHi2 * (F64)0x10000 * (F64)0x10000) + (F64)tsLo2;
|
||||
// get the timestamp delta. potentially large number here, as it's in Hz.
|
||||
tsDelta = tsSecond - tsFirst;
|
||||
|
||||
// adjust for slightly-off-delay -- better to assume +1ms than try to really calc.
|
||||
tsDelta *= (F64)(msToWait + 1);
|
||||
tsDelta /= (F64)msToWait;
|
||||
// factor back into 1s of time.
|
||||
tsDelta *= ((F64)1000/(F64)msToWait);
|
||||
// then convert into Mhz
|
||||
tsDelta /= (F64)1000000;
|
||||
tsDelta += 0.5f; // trying to get closer to the right values, effectively rounding up.
|
||||
mhz = (U32)tsDelta;
|
||||
|
||||
// Find nearest full/half multiple of 66/133 MHz
|
||||
Nearest66Mhz = ((((mhz * 3) + 100) / 200) * 200) / 3;
|
||||
// 660 = 1980 = 2080 = 100 = 2000 = 666
|
||||
// 440 = 1320 = 1420 = 70 = 1400 = 466
|
||||
|
||||
// find delta to nearest 66 multiple.
|
||||
Delta66Mhz = abs(Nearest66Mhz - mhz);
|
||||
|
||||
// Find nearest full/half multiple of 100 MHz
|
||||
Nearest50Mhz = (((mhz + 25) / 50) * 50);
|
||||
// 440 = 465 = 9 = 450
|
||||
|
||||
// find delta to nearest 50 multiple.
|
||||
Delta50Mhz = abs(Nearest50Mhz - mhz);
|
||||
|
||||
if (Delta50Mhz < Delta66Mhz) // closer to a 50 boundary
|
||||
nearmhz = Nearest50Mhz;
|
||||
else
|
||||
{
|
||||
nearmhz = Nearest66Mhz;
|
||||
if (nearmhz==666) // hack around -- !!!!TBD - other cases?!?!
|
||||
nearmhz = 667;
|
||||
}
|
||||
|
||||
// !!!TBD
|
||||
// would be nice if we stored both the calculated and the adjusted/guessed values.
|
||||
Platform::SystemInfo.processor.mhz = nearmhz; // hold onto adjusted value only.
|
||||
}
|
||||
#endif
|
||||
|
||||
if (mhz==0)
|
||||
{
|
||||
Con::printf(" %s, (Unknown) Mhz", Platform::SystemInfo.processor.name);
|
||||
// stick SOMETHING in so it isn't ZERO.
|
||||
Platform::SystemInfo.processor.mhz = 200; // seems a decent value.
|
||||
}
|
||||
else
|
||||
{
|
||||
if (nearmhz >= 1000)
|
||||
Con::printf(" %s, ~%.2f Ghz", Platform::SystemInfo.processor.name, ((float)nearmhz)/1000.0f);
|
||||
else
|
||||
Con::printf(" %s, ~%d Mhz", Platform::SystemInfo.processor.name, nearmhz);
|
||||
if (nearmhz != mhz)
|
||||
{
|
||||
if (mhz >= 1000)
|
||||
Con::printf(" (timed at roughly %.2f Ghz)", ((float)mhz)/1000.0f);
|
||||
else
|
||||
Con::printf(" (timed at roughly %d Mhz)", mhz);
|
||||
}
|
||||
}
|
||||
|
||||
if (Platform::SystemInfo.processor.properties & CPU_PROP_FPU)
|
||||
Con::printf(" FPU detected");
|
||||
if (Platform::SystemInfo.processor.properties & CPU_PROP_MMX)
|
||||
Con::printf(" MMX detected");
|
||||
if (Platform::SystemInfo.processor.properties & CPU_PROP_3DNOW)
|
||||
Con::printf(" 3DNow detected");
|
||||
if (Platform::SystemInfo.processor.properties & CPU_PROP_SSE)
|
||||
Con::printf(" SSE detected");
|
||||
Con::printf(" ");
|
||||
|
||||
PlatformBlitInit();
|
||||
}
|
296
engine/platformWin32/winConsole.cc
Executable file
296
engine/platformWin32/winConsole.cc
Executable file
@ -0,0 +1,296 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// Torque Game Engine
|
||||
// Copyright (C) GarageGames.com, Inc.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "platformWin32/platformWin32.h"
|
||||
#include "platformWin32/winConsole.h"
|
||||
#include "platform/event.h"
|
||||
#include "platform/gameInterface.h"
|
||||
#include "core/unicode.h"
|
||||
|
||||
WinConsole *WindowsConsole = NULL;
|
||||
|
||||
ConsoleFunction(enableWinConsole, void, 2, 2, "enableWinConsole(bool);")
|
||||
{
|
||||
argc;
|
||||
WindowsConsole->enable(dAtob(argv[1]));
|
||||
}
|
||||
|
||||
void WinConsole::create()
|
||||
{
|
||||
WindowsConsole = new WinConsole();
|
||||
}
|
||||
|
||||
void WinConsole::destroy()
|
||||
{
|
||||
delete WindowsConsole;
|
||||
WindowsConsole = NULL;
|
||||
}
|
||||
|
||||
void WinConsole::enable(bool enabled)
|
||||
{
|
||||
winConsoleEnabled = enabled;
|
||||
if(winConsoleEnabled)
|
||||
{
|
||||
AllocConsole();
|
||||
const char *title = Con::getVariable("Con::WindowTitle");
|
||||
if (title && *title)
|
||||
{
|
||||
#ifdef UNICODE
|
||||
UTF16 buf[512];
|
||||
convertUTF8toUTF16((UTF8 *)title, buf, sizeof(buf));
|
||||
SetConsoleTitle(buf);
|
||||
#else
|
||||
SetConsoleTitle(title);
|
||||
#endif
|
||||
}
|
||||
stdOut = GetStdHandle(STD_OUTPUT_HANDLE);
|
||||
stdIn = GetStdHandle(STD_INPUT_HANDLE);
|
||||
stdErr = GetStdHandle(STD_ERROR_HANDLE);
|
||||
|
||||
printf("%s", Con::getVariable("Con::Prompt"));
|
||||
}
|
||||
}
|
||||
|
||||
bool WinConsole::isEnabled()
|
||||
{
|
||||
if ( WindowsConsole )
|
||||
return WindowsConsole->winConsoleEnabled;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static void winConsoleConsumer(ConsoleLogEntry::Level, const char *line)
|
||||
{
|
||||
if (WindowsConsole)
|
||||
WindowsConsole->processConsoleLine(line);
|
||||
}
|
||||
|
||||
WinConsole::WinConsole()
|
||||
{
|
||||
for (S32 iIndex = 0; iIndex < MAX_CMDS; iIndex ++)
|
||||
rgCmds[iIndex][0] = '\0';
|
||||
|
||||
iCmdIndex = 0;
|
||||
winConsoleEnabled = false;
|
||||
Con::addConsumer(winConsoleConsumer);
|
||||
inpos = 0;
|
||||
lineOutput = false;
|
||||
}
|
||||
|
||||
WinConsole::~WinConsole()
|
||||
{
|
||||
Con::removeConsumer(winConsoleConsumer);
|
||||
}
|
||||
|
||||
void WinConsole::printf(const char *s, ...)
|
||||
{
|
||||
// Get the line into a buffer.
|
||||
static const int BufSize = 4096;
|
||||
static char buffer[4096];
|
||||
DWORD bytes;
|
||||
va_list args;
|
||||
va_start(args, s);
|
||||
vsnprintf(buffer, BufSize, s, args);
|
||||
// Replace tabs with carats, like the "real" console does.
|
||||
char *pos = buffer;
|
||||
while (*pos) {
|
||||
if (*pos == '\t') {
|
||||
*pos = '^';
|
||||
}
|
||||
pos++;
|
||||
}
|
||||
// Axe the color characters.
|
||||
Con::stripColorChars(buffer);
|
||||
// Print it.
|
||||
WriteFile(stdOut, buffer, strlen(buffer), &bytes, NULL);
|
||||
FlushFileBuffers( stdOut );
|
||||
}
|
||||
|
||||
void WinConsole::processConsoleLine(const char *consoleLine)
|
||||
{
|
||||
if(winConsoleEnabled)
|
||||
{
|
||||
inbuf[inpos] = 0;
|
||||
if(lineOutput)
|
||||
printf("%s\n", consoleLine);
|
||||
else
|
||||
printf("%c%s\n%s%s", '\r', consoleLine, Con::getVariable("Con::Prompt"), inbuf);
|
||||
}
|
||||
}
|
||||
|
||||
void WinConsole::process()
|
||||
{
|
||||
if(winConsoleEnabled)
|
||||
{
|
||||
DWORD numEvents;
|
||||
GetNumberOfConsoleInputEvents(stdIn, &numEvents);
|
||||
if(numEvents)
|
||||
{
|
||||
INPUT_RECORD rec[20];
|
||||
char outbuf[512];
|
||||
S32 outpos = 0;
|
||||
|
||||
ReadConsoleInput(stdIn, rec, 20, &numEvents);
|
||||
DWORD i;
|
||||
for(i = 0; i < numEvents; i++)
|
||||
{
|
||||
if(rec[i].EventType == KEY_EVENT)
|
||||
{
|
||||
KEY_EVENT_RECORD *ke = &(rec[i].Event.KeyEvent);
|
||||
if(ke->bKeyDown)
|
||||
{
|
||||
switch (ke->uChar.AsciiChar)
|
||||
{
|
||||
// If no ASCII char, check if it's a handled virtual key
|
||||
case 0:
|
||||
switch (ke->wVirtualKeyCode)
|
||||
{
|
||||
// UP ARROW
|
||||
case 0x26 :
|
||||
// Go to the previous command in the cyclic array
|
||||
if ((-- iCmdIndex) < 0)
|
||||
iCmdIndex = MAX_CMDS - 1;
|
||||
|
||||
// If this command isn't empty ...
|
||||
if (rgCmds[iCmdIndex][0] != '\0')
|
||||
{
|
||||
// Obliterate current displayed text
|
||||
for (S32 i = outpos = 0; i < inpos; i ++)
|
||||
{
|
||||
outbuf[outpos ++] = '\b';
|
||||
outbuf[outpos ++] = ' ';
|
||||
outbuf[outpos ++] = '\b';
|
||||
}
|
||||
|
||||
// Copy command into command and display buffers
|
||||
for (inpos = 0; inpos < (S32)strlen(rgCmds[iCmdIndex]); inpos ++, outpos ++)
|
||||
{
|
||||
outbuf[outpos] = rgCmds[iCmdIndex][inpos];
|
||||
inbuf [inpos ] = rgCmds[iCmdIndex][inpos];
|
||||
}
|
||||
}
|
||||
// If previous is empty, stay on current command
|
||||
else if ((++ iCmdIndex) >= MAX_CMDS)
|
||||
{
|
||||
iCmdIndex = 0;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
// DOWN ARROW
|
||||
case 0x28 : {
|
||||
// Go to the next command in the command array, if
|
||||
// it isn't empty
|
||||
if (rgCmds[iCmdIndex][0] != '\0' && (++ iCmdIndex) >= MAX_CMDS)
|
||||
iCmdIndex = 0;
|
||||
|
||||
// Obliterate current displayed text
|
||||
for (S32 i = outpos = 0; i < inpos; i ++)
|
||||
{
|
||||
outbuf[outpos ++] = '\b';
|
||||
outbuf[outpos ++] = ' ';
|
||||
outbuf[outpos ++] = '\b';
|
||||
}
|
||||
|
||||
// Copy command into command and display buffers
|
||||
for (inpos = 0; inpos < (S32)strlen(rgCmds[iCmdIndex]); inpos ++, outpos ++)
|
||||
{
|
||||
outbuf[outpos] = rgCmds[iCmdIndex][inpos];
|
||||
inbuf [inpos ] = rgCmds[iCmdIndex][inpos];
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
// LEFT ARROW
|
||||
case 0x25 :
|
||||
break;
|
||||
|
||||
// RIGHT ARROW
|
||||
case 0x27 :
|
||||
break;
|
||||
|
||||
default :
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case '\b':
|
||||
if(inpos > 0)
|
||||
{
|
||||
outbuf[outpos++] = '\b';
|
||||
outbuf[outpos++] = ' ';
|
||||
outbuf[outpos++] = '\b';
|
||||
inpos--;
|
||||
}
|
||||
break;
|
||||
case '\t':
|
||||
// In the output buffer, we're going to have to erase the current line (in case
|
||||
// we're cycling through various completions) and write out the whole input
|
||||
// buffer, so (inpos * 3) + complen <= 512. Should be OK. The input buffer is
|
||||
// also 512 chars long so that constraint will also be fine for the input buffer.
|
||||
{
|
||||
// Erase the current line.
|
||||
U32 i;
|
||||
for (i = 0; i < inpos; i++) {
|
||||
outbuf[outpos++] = '\b';
|
||||
outbuf[outpos++] = ' ';
|
||||
outbuf[outpos++] = '\b';
|
||||
}
|
||||
// Modify the input buffer with the completion.
|
||||
U32 maxlen = 512 - (inpos * 3);
|
||||
if (ke->dwControlKeyState & SHIFT_PRESSED) {
|
||||
inpos = Con::tabComplete(inbuf, inpos, maxlen, false);
|
||||
}
|
||||
else {
|
||||
inpos = Con::tabComplete(inbuf, inpos, maxlen, true);
|
||||
}
|
||||
// Copy the input buffer to the output.
|
||||
for (i = 0; i < inpos; i++) {
|
||||
outbuf[outpos++] = inbuf[i];
|
||||
}
|
||||
}
|
||||
break;
|
||||
case '\n':
|
||||
case '\r':
|
||||
outbuf[outpos++] = '\r';
|
||||
outbuf[outpos++] = '\n';
|
||||
|
||||
inbuf[inpos] = 0;
|
||||
outbuf[outpos] = 0;
|
||||
printf("%s", outbuf);
|
||||
|
||||
S32 eventSize;
|
||||
eventSize = ConsoleEventHeaderSize;
|
||||
|
||||
dStrcpy(postEvent.data, inbuf);
|
||||
postEvent.size = eventSize + dStrlen(inbuf) + 1;
|
||||
Game->postEvent(postEvent);
|
||||
|
||||
// If we've gone off the end of our array, wrap
|
||||
// back to the beginning
|
||||
if (iCmdIndex >= MAX_CMDS)
|
||||
iCmdIndex %= MAX_CMDS;
|
||||
|
||||
// Put the new command into the array
|
||||
strcpy(rgCmds[iCmdIndex ++], inbuf);
|
||||
|
||||
printf("%s", Con::getVariable("Con::Prompt"));
|
||||
inpos = outpos = 0;
|
||||
break;
|
||||
default:
|
||||
inbuf[inpos++] = ke->uChar.AsciiChar;
|
||||
outbuf[outpos++] = ke->uChar.AsciiChar;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if(outpos)
|
||||
{
|
||||
outbuf[outpos] = 0;
|
||||
printf("%s", outbuf);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
49
engine/platformWin32/winConsole.h
Executable file
49
engine/platformWin32/winConsole.h
Executable file
@ -0,0 +1,49 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// Torque Game Engine
|
||||
// Copyright (C) GarageGames.com, Inc.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#ifndef _WINCONSOLE_H_
|
||||
#define _WINCONSOLE_H_
|
||||
|
||||
#define MAX_CMDS 10
|
||||
#ifndef _CONSOLE_H_
|
||||
#include "console/console.h"
|
||||
#endif
|
||||
#ifndef _EVENT_H_
|
||||
#include "platform/event.h"
|
||||
#endif
|
||||
|
||||
class WinConsole
|
||||
{
|
||||
bool winConsoleEnabled;
|
||||
|
||||
HANDLE stdOut;
|
||||
HANDLE stdIn;
|
||||
HANDLE stdErr;
|
||||
ConsoleEvent postEvent;
|
||||
char inbuf[512];
|
||||
S32 inpos;
|
||||
bool lineOutput;
|
||||
char curTabComplete[512];
|
||||
S32 tabCompleteStart;
|
||||
char rgCmds[MAX_CMDS][512];
|
||||
S32 iCmdIndex;
|
||||
|
||||
void printf(const char *s, ...);
|
||||
|
||||
public:
|
||||
WinConsole();
|
||||
~WinConsole();
|
||||
|
||||
void process();
|
||||
void enable(bool);
|
||||
void processConsoleLine(const char *consoleLine);
|
||||
static void create();
|
||||
static void destroy();
|
||||
static bool isEnabled();
|
||||
};
|
||||
|
||||
extern WinConsole *WindowsConsole;
|
||||
|
||||
#endif
|
723
engine/platformWin32/winD3DVideo.cc
Executable file
723
engine/platformWin32/winD3DVideo.cc
Executable file
@ -0,0 +1,723 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// Torque Game Engine
|
||||
// Copyright (C) GarageGames.com, Inc.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "platformWin32/platformGL.h"
|
||||
#include "platformWin32/platformWin32.h"
|
||||
#include "platform/platformAudio.h"
|
||||
#include "platformWin32/winD3DVideo.h"
|
||||
#include "console/console.h"
|
||||
#include "math/mPoint.h"
|
||||
#include "platform/event.h"
|
||||
#include "platform/gameInterface.h"
|
||||
#include "console/consoleInternal.h"
|
||||
#include "console/ast.h"
|
||||
|
||||
#if defined(TORQUE_DEBUG)
|
||||
# define OPENGL2D3D_DLL "opengl2d3d_DEBUG.dll"
|
||||
# define GLU2D3D_DLL "glu2d3d_DEBUG.dll"
|
||||
#else
|
||||
# define OPENGL2D3D_DLL "opengl2d3d.dll"
|
||||
# define GLU2D3D_DLL "glu2d3d.dll"
|
||||
#endif
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
bool D3DDevice::smCanSwitchBitDepth = true;
|
||||
bool D3DDevice::smStay16 = false;
|
||||
|
||||
static void profileSystem(const char *vendor, const char *renderer)
|
||||
{
|
||||
Con::setBoolVariable("$pref::Video::safeModeOn", true);
|
||||
Con::setBoolVariable("$pref::OpenGL::disableEXTCompiledVertexArray", false);
|
||||
Con::setBoolVariable("$pref::OpenGL::disableSubImage", false);
|
||||
Con::setBoolVariable("$pref::OpenGL::noEnvColor", true);
|
||||
Con::setBoolVariable("$pref::OpenGL::disableARBTextureCompression", false);
|
||||
Con::setBoolVariable("$pref::Interior::lockArrays", true);
|
||||
Con::setBoolVariable("$pref::TS::skipFirstFog", false);
|
||||
Con::setBoolVariable("$pref::OpenGL::disableEXTFogCoord", false);
|
||||
|
||||
Con::setVariable("$pref::Video::profiledVendor", vendor);
|
||||
Con::setVariable("$pref::Video::profiledRenderer", renderer);
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
D3DDevice::D3DDevice()
|
||||
{
|
||||
initDevice();
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void D3DDevice::initDevice()
|
||||
{
|
||||
// Set the device name:
|
||||
mDeviceName = "D3D";
|
||||
|
||||
// Set some initial conditions:
|
||||
mResolutionList.clear();
|
||||
|
||||
// Enumerate all available resolutions:
|
||||
DEVMODE devMode;
|
||||
U32 modeNum = 0;
|
||||
U32 stillGoing = true;
|
||||
while ( stillGoing )
|
||||
{
|
||||
dMemset( &devMode, 0, sizeof( devMode ) );
|
||||
devMode.dmSize = sizeof( devMode );
|
||||
|
||||
stillGoing = EnumDisplaySettings( NULL, modeNum++, &devMode );
|
||||
|
||||
if ( devMode.dmPelsWidth >= 640 && devMode.dmPelsHeight >= 480
|
||||
&& ( devMode.dmBitsPerPel == 16 || (devMode.dmBitsPerPel == 32 && !smStay16) ) &&
|
||||
( smCanSwitchBitDepth || devMode.dmBitsPerPel == winState.desktopBitsPixel ) )
|
||||
{
|
||||
// Only add this resolution if it is not already in the list:
|
||||
bool alreadyInList = false;
|
||||
for ( U32 i = 0; i < mResolutionList.size(); i++ )
|
||||
{
|
||||
if ( devMode.dmPelsWidth == mResolutionList[i].w
|
||||
&& devMode.dmPelsHeight == mResolutionList[i].h
|
||||
&& devMode.dmBitsPerPel == mResolutionList[i].bpp )
|
||||
{
|
||||
alreadyInList = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ( !alreadyInList )
|
||||
{
|
||||
Resolution newRes( devMode.dmPelsWidth, devMode.dmPelsHeight, devMode.dmBitsPerPel );
|
||||
mResolutionList.push_back( newRes );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
bool D3DDevice::activate( U32 width, U32 height, U32 bpp, bool fullScreen )
|
||||
{
|
||||
bool needResurrect = false;
|
||||
|
||||
// If the rendering context exists, delete it:
|
||||
if ( winState.hGLRC )
|
||||
{
|
||||
Con::printf( "Killing the texture manager..." );
|
||||
Game->textureKill();
|
||||
needResurrect = true;
|
||||
|
||||
Con::printf( "Making the rendering context not current..." );
|
||||
if ( !dwglMakeCurrent( NULL, NULL ) )
|
||||
{
|
||||
AssertFatal( false, "D3DDevice::activate\ndwglMakeCurrent( NULL, NULL ) failed!" );
|
||||
return false;
|
||||
}
|
||||
|
||||
Con::printf( "Deleting the rendering context ..." );
|
||||
if ( !dwglDeleteContext( winState.hGLRC ) )
|
||||
{
|
||||
AssertFatal( false, "D3DDevice::activate\ndwglDeleteContext failed!" );
|
||||
return false;
|
||||
}
|
||||
winState.hGLRC = NULL;
|
||||
}
|
||||
|
||||
// If the window already exists, kill it so we can start fresh:
|
||||
if ( winState.appWindow )
|
||||
{
|
||||
Con::printf( "Releasing the device context..." );
|
||||
ReleaseDC( winState.appWindow, winState.appDC );
|
||||
winState.appDC = NULL;
|
||||
|
||||
Con::printf( "Destroying the window..." );
|
||||
DestroyWindow( winState.appWindow );
|
||||
winState.appWindow = NULL;
|
||||
}
|
||||
|
||||
// If OpenGL library already loaded, shut it down and reload it:
|
||||
if ( winState.hinstOpenGL )
|
||||
GL_Shutdown();
|
||||
|
||||
GL_Init(OPENGL2D3D_DLL,GLU2D3D_DLL);
|
||||
|
||||
// Set the resolution:
|
||||
if ( !setScreenMode( width, height, bpp, ( fullScreen || mFullScreenOnly ), true, false ) )
|
||||
return false;
|
||||
|
||||
// Get original gamma ramp
|
||||
mRestoreGamma = GetDeviceGammaRamp(winState.appDC, mOriginalRamp);
|
||||
|
||||
// Output some driver info to the console:
|
||||
const char* vendorString = (const char*) glGetString( GL_VENDOR );
|
||||
const char* rendererString = (const char*) glGetString( GL_RENDERER );
|
||||
const char* versionString = (const char*) glGetString( GL_VERSION );
|
||||
Con::printf( "OpenGL driver information:" );
|
||||
if ( vendorString )
|
||||
Con::printf( " Vendor: %s", vendorString );
|
||||
if ( rendererString )
|
||||
Con::printf( " Renderer: %s", rendererString );
|
||||
if ( versionString )
|
||||
Con::printf( " Version: %s", versionString );
|
||||
|
||||
if ( needResurrect )
|
||||
{
|
||||
// Reload the textures:
|
||||
Con::printf( "Resurrecting the texture manager..." );
|
||||
Game->textureResurrect();
|
||||
}
|
||||
|
||||
GL_EXT_Init();
|
||||
|
||||
Con::setVariable( "$pref::Video::displayDevice", mDeviceName );
|
||||
Con::setBoolVariable( "$SwapIntervalSupported", false );
|
||||
Con::setBoolVariable( "$pref::OpenGL::allowTexGen", false );
|
||||
Con::setBoolVariable( "$pref::environmentMaps", false );
|
||||
|
||||
// only do this for the first session
|
||||
if (!Con::getBoolVariable("$DisableSystemProfiling") && (dStrcmp(vendorString, Con::getVariable("$pref::Video::profiledVendor")) ||
|
||||
dStrcmp(rendererString, Con::getVariable("$pref::Video::profiledRenderer"))))
|
||||
profileSystem(vendorString, rendererString);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void D3DDevice::shutdown()
|
||||
{
|
||||
if ( winState.hGLRC )
|
||||
{
|
||||
if (mRestoreGamma)
|
||||
SetDeviceGammaRamp(winState.appDC, mOriginalRamp);
|
||||
|
||||
dwglMakeCurrent( NULL, NULL );
|
||||
dwglDeleteContext( winState.hGLRC );
|
||||
winState.hGLRC = NULL;
|
||||
}
|
||||
|
||||
if ( winState.appDC )
|
||||
{
|
||||
ReleaseDC( winState.appWindow, winState.appDC );
|
||||
winState.appDC = NULL;
|
||||
}
|
||||
|
||||
if ( smIsFullScreen || (smStay16 && winState.desktopBitsPixel != 16))
|
||||
ChangeDisplaySettings( NULL, 0 );
|
||||
|
||||
GL_Shutdown();
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// This is the real workhorse function of the DisplayDevice...
|
||||
//
|
||||
bool D3DDevice::setScreenMode( U32 width, U32 height, U32 bpp, bool fullScreen, bool forceIt, bool repaint )
|
||||
{
|
||||
HWND curtain = NULL;
|
||||
char errorMessage[256];
|
||||
Resolution newRes( width, height, bpp );
|
||||
bool newFullScreen = fullScreen;
|
||||
bool safeModeOn = Con::getBoolVariable( "$pref::Video::safeModeOn" );
|
||||
|
||||
if ( !newFullScreen && mFullScreenOnly )
|
||||
{
|
||||
Con::warnf( ConsoleLogEntry::General, "D3DDevice::setScreenMode - device or desktop color depth does not allow windowed mode!" );
|
||||
newFullScreen = true;
|
||||
}
|
||||
|
||||
if ( !newFullScreen && ( newRes.w >= winState.desktopWidth || newRes.h >= winState.desktopHeight ) )
|
||||
{
|
||||
Con::warnf( ConsoleLogEntry::General, "D3DDevice::setScreenMode -- can't switch to resolution larger than desktop in windowed mode!" );
|
||||
// Find the largest standard resolution that will fit on the desktop:
|
||||
U32 resIndex;
|
||||
for ( resIndex = mResolutionList.size() - 1; resIndex > 0; resIndex-- )
|
||||
{
|
||||
if ( mResolutionList[resIndex].w < winState.desktopWidth
|
||||
&& mResolutionList[resIndex].h < winState.desktopHeight )
|
||||
break;
|
||||
}
|
||||
newRes = mResolutionList[resIndex];
|
||||
}
|
||||
|
||||
if ( newRes.w < 640 || newRes.h < 480 )
|
||||
{
|
||||
Con::warnf( ConsoleLogEntry::General, "D3DDevice::setScreenMode -- can't go smaller than 640x480!" );
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( newFullScreen )
|
||||
{
|
||||
if (newRes.bpp != 16 && mFullScreenOnly)
|
||||
newRes.bpp = 16;
|
||||
|
||||
// Match the new resolution to one in the list:
|
||||
U32 resIndex = 0;
|
||||
U32 bestScore = 0, thisScore = 0;
|
||||
for ( int i = 0; i < mResolutionList.size(); i++ )
|
||||
{
|
||||
if ( newRes == mResolutionList[i] )
|
||||
{
|
||||
resIndex = i;
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
thisScore = abs( S32( newRes.w ) - S32( mResolutionList[i].w ) )
|
||||
+ abs( S32( newRes.h ) - S32( mResolutionList[i].h ) )
|
||||
+ ( newRes.bpp == mResolutionList[i].bpp ? 0 : 1 );
|
||||
|
||||
if ( !bestScore || ( thisScore < bestScore ) )
|
||||
{
|
||||
bestScore = thisScore;
|
||||
resIndex = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
newRes = mResolutionList[resIndex];
|
||||
}
|
||||
else
|
||||
// Basically ignore the bit depth parameter:
|
||||
if (!smStay16)
|
||||
newRes.bpp = winState.desktopBitsPixel;
|
||||
else
|
||||
newRes.bpp = 16;
|
||||
|
||||
// Return if already at this resolution:
|
||||
if ( !forceIt && newRes == smCurrentRes && newFullScreen == smIsFullScreen )
|
||||
return true;
|
||||
|
||||
Con::printf( "Setting screen mode to %dx%dx%d (%s)...", newRes.w, newRes.h, newRes.bpp, ( newFullScreen ? "fs" : "w" ) );
|
||||
|
||||
bool needResurrect = false;
|
||||
|
||||
// oh just always do it
|
||||
//if ( ( newRes.bpp != smCurrentRes.bpp ) || ( safeModeOn && ( ( smIsFullScreen != newFullScreen ) || newFullScreen ) ) )
|
||||
if (true)
|
||||
{
|
||||
// Delete the rendering context:
|
||||
if ( winState.hGLRC )
|
||||
{
|
||||
if (!Video::smNeedResurrect)
|
||||
{
|
||||
Con::printf( "Killing the texture manager..." );
|
||||
Game->textureKill();
|
||||
needResurrect = true;
|
||||
}
|
||||
|
||||
Con::printf( "Making the rendering context not current..." );
|
||||
if ( !dwglMakeCurrent( NULL, NULL ) )
|
||||
{
|
||||
AssertFatal( false, "D3DDevice::setScreenMode\ndwglMakeCurrent( NULL, NULL ) failed!" );
|
||||
return false;
|
||||
}
|
||||
|
||||
Con::printf( "Deleting the rendering context..." );
|
||||
if ( !dwglDeleteContext( winState.hGLRC ) )
|
||||
{
|
||||
AssertFatal( false, "D3DDevice::setScreenMode\ndwglDeleteContext failed!" );
|
||||
return false;
|
||||
}
|
||||
winState.hGLRC = NULL;
|
||||
}
|
||||
|
||||
// Release the device context:
|
||||
if ( winState.appDC )
|
||||
{
|
||||
Con::printf( "Releasing the device context..." );
|
||||
ReleaseDC( winState.appWindow, winState.appDC );
|
||||
winState.appDC = NULL;
|
||||
}
|
||||
|
||||
// Destroy the window:
|
||||
if ( winState.appWindow )
|
||||
{
|
||||
Con::printf( "Destroying the window..." );
|
||||
DestroyWindow( winState.appWindow );
|
||||
winState.appWindow = NULL;
|
||||
}
|
||||
}
|
||||
else if ( smIsFullScreen != newFullScreen )
|
||||
{
|
||||
// Change the window style:
|
||||
Con::printf( "Changing the window style..." );
|
||||
S32 windowStyle = WS_CLIPCHILDREN | WS_CLIPSIBLINGS;
|
||||
if ( newFullScreen )
|
||||
windowStyle |= ( WS_POPUP | WS_MAXIMIZE | WS_VISIBLE );
|
||||
else
|
||||
windowStyle |= ( WS_OVERLAPPED | WS_CAPTION );
|
||||
|
||||
if ( !SetWindowLong( winState.appWindow, GWL_STYLE, windowStyle ) )
|
||||
Platform::AlertOK( "Error", "Failed to change the window style!" );
|
||||
}
|
||||
|
||||
U32 test;
|
||||
if ( newFullScreen )
|
||||
{
|
||||
// Change the display settings:
|
||||
DEVMODE devMode;
|
||||
dMemset( &devMode, 0, sizeof( devMode ) );
|
||||
devMode.dmSize = sizeof( devMode );
|
||||
devMode.dmPelsWidth = newRes.w;
|
||||
devMode.dmPelsHeight = newRes.h;
|
||||
devMode.dmBitsPerPel = newRes.bpp;
|
||||
devMode.dmFields = DM_PELSWIDTH | DM_PELSHEIGHT | DM_BITSPERPEL;
|
||||
|
||||
Con::printf( "Changing the display settings to %dx%dx%d...", newRes.w, newRes.h, newRes.bpp );
|
||||
curtain = CreateCurtain( newRes.w, newRes.h );
|
||||
test = ChangeDisplaySettings( &devMode, CDS_FULLSCREEN );
|
||||
if ( test != DISP_CHANGE_SUCCESSFUL )
|
||||
{
|
||||
smIsFullScreen = false;
|
||||
Con::setBoolVariable( "$pref::Video::fullScreen", false );
|
||||
ChangeDisplaySettings( NULL, 0 );
|
||||
Con::errorf( ConsoleLogEntry::General, "D3DDevice::setScreenMode - ChangeDisplaySettings failed." );
|
||||
switch( test )
|
||||
{
|
||||
case DISP_CHANGE_RESTART:
|
||||
Platform::AlertOK( "Display Change Failed", "You must restart your machine to get the specified mode." );
|
||||
break;
|
||||
|
||||
case DISP_CHANGE_BADMODE:
|
||||
Platform::AlertOK( "Display Change Failed", "The specified mode is not supported by this device." );
|
||||
break;
|
||||
|
||||
default:
|
||||
Platform::AlertOK( "Display Change Failed", "Hardware failed to switch to the specified mode." );
|
||||
break;
|
||||
};
|
||||
DestroyWindow( curtain );
|
||||
return false;
|
||||
}
|
||||
else
|
||||
smIsFullScreen = true;
|
||||
}
|
||||
else if ( smIsFullScreen || (smStay16 && winState.desktopBitsPixel != 16))
|
||||
{
|
||||
if (!smStay16 || winState.desktopBitsPixel == 16)
|
||||
{
|
||||
Con::printf( "Changing to the desktop display settings (%dx%dx%d)...", winState.desktopWidth, winState.desktopHeight, winState.desktopBitsPixel );
|
||||
ChangeDisplaySettings( NULL, 0 );
|
||||
}
|
||||
else
|
||||
{
|
||||
// Change the display settings:
|
||||
DEVMODE devMode;
|
||||
|
||||
dMemset( &devMode, 0, sizeof( devMode ) );
|
||||
devMode.dmSize = sizeof( devMode );
|
||||
devMode.dmBitsPerPel = newRes.bpp;
|
||||
devMode.dmFields = DM_BITSPERPEL;
|
||||
|
||||
Con::printf( "Changing the display settings to %dx%dx%d...", winState.desktopWidth, winState.desktopHeight, newRes.bpp );
|
||||
test = ChangeDisplaySettings( &devMode, 0 );
|
||||
if ( test != DISP_CHANGE_SUCCESSFUL )
|
||||
{
|
||||
smIsFullScreen = true;
|
||||
Con::setBoolVariable( "$pref::Video::fullScreen", true );
|
||||
ChangeDisplaySettings( NULL, 0 );
|
||||
Con::errorf( ConsoleLogEntry::General, "D3DDevice::setScreenMode - ChangeDisplaySettings failed." );
|
||||
switch ( test )
|
||||
{
|
||||
case DISP_CHANGE_RESTART:
|
||||
Platform::AlertOK( "Display Change Failed", "You must restart your machine to get the specified mode." );
|
||||
break;
|
||||
|
||||
case DISP_CHANGE_BADMODE:
|
||||
Platform::AlertOK( "Display Change Failed", "The specified mode is not supported by this device." );
|
||||
break;
|
||||
|
||||
default:
|
||||
Platform::AlertOK( "Display Change Failed", "Hardware failed to switch to the specified mode." );
|
||||
break;
|
||||
};
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
smIsFullScreen = false;
|
||||
}
|
||||
Con::setBoolVariable( "$pref::Video::fullScreen", smIsFullScreen );
|
||||
|
||||
bool newWindow = false;
|
||||
if ( !winState.appWindow )
|
||||
{
|
||||
Con::printf( "Creating a new %swindow...", ( fullScreen ? "full-screen " : "" ) );
|
||||
winState.appWindow = CreateOpenGLWindow( newRes.w, newRes.h, newFullScreen );
|
||||
if ( !winState.appWindow )
|
||||
{
|
||||
AssertFatal( false, "D3DDevice::setScreenMode\nFailed to create a new window!" );
|
||||
return false;
|
||||
}
|
||||
newWindow = true;
|
||||
}
|
||||
|
||||
// Move the window:
|
||||
if ( !newFullScreen )
|
||||
{
|
||||
// Adjust the window rect to compensate for the window style:
|
||||
RECT windowRect;
|
||||
windowRect.left = windowRect.top = 0;
|
||||
windowRect.right = newRes.w;
|
||||
windowRect.bottom = newRes.h;
|
||||
|
||||
AdjustWindowRect( &windowRect, GetWindowLong( winState.appWindow, GWL_STYLE ), false );
|
||||
U32 adjWidth = windowRect.right - windowRect.left;
|
||||
U32 adjHeight = windowRect.bottom - windowRect.top;
|
||||
|
||||
// Center the window on the desktop:
|
||||
U32 xPos = ( winState.desktopWidth - adjWidth ) / 2;
|
||||
U32 yPos = ( winState.desktopHeight - adjHeight ) / 2;
|
||||
test = SetWindowPos( winState.appWindow, 0, xPos, yPos, adjWidth, adjHeight, SWP_NOZORDER );
|
||||
if ( !test )
|
||||
{
|
||||
dSprintf( errorMessage, 255, "D3DDevice::setScreenMode\nSetWindowPos failed trying to move the window to (%d,%d) and size it to %dx%d.", xPos, yPos, newRes.w, newRes.h );
|
||||
AssertFatal( false, errorMessage );
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else if ( !newWindow )
|
||||
{
|
||||
// Move and size the window to take up the whole screen:
|
||||
if ( !SetWindowPos( winState.appWindow, 0, 0, 0, newRes.w, newRes.h, SWP_NOZORDER ) )
|
||||
{
|
||||
dSprintf( errorMessage, 255, "D3DDevice::setScreenMode\nSetWindowPos failed to move the window to (0,0) and size it to %dx%d.", newRes.w, newRes.h );
|
||||
AssertFatal( false, errorMessage );
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if ( !winState.appDC )
|
||||
{
|
||||
// Get a new device context:
|
||||
Con::printf( "Acquiring a new device context..." );
|
||||
winState.appDC = GetDC( winState.appWindow );
|
||||
if ( !winState.appDC )
|
||||
{
|
||||
AssertFatal( false, "D3DDevice::setScreenMode\nGetDC failed to get a valid device context!" );
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if ( newWindow )
|
||||
{
|
||||
// Set the pixel format of the new window:
|
||||
PIXELFORMATDESCRIPTOR pfd;
|
||||
dwglDescribePixelFormat( winState.appDC, 1, sizeof( pfd ), &pfd );
|
||||
if ( !SetPixelFormat( winState.appDC, 1, &pfd ) )
|
||||
{
|
||||
//AssertFatal( false, "D3DDevice::setScreenMode\nFailed to set the pixel format!" );
|
||||
//return false;
|
||||
}
|
||||
Con::printf( "Pixel format set:" );
|
||||
Con::printf( " %d color bits, %d depth bits, %d stencil bits", pfd.cColorBits, pfd.cDepthBits, pfd.cStencilBits );
|
||||
}
|
||||
|
||||
if ( !winState.hGLRC )
|
||||
{
|
||||
// Create a new rendering context:
|
||||
Con::printf( "Creating a new rendering context..." );
|
||||
winState.hGLRC = dwglCreateContext( winState.appDC );
|
||||
if ( !winState.hGLRC )
|
||||
{
|
||||
AssertFatal( false, "D3DDevice::setScreenMode\ndwglCreateContext failed to create an OpenGL rendering context!" );
|
||||
return false;
|
||||
}
|
||||
|
||||
// Make the new rendering context current:
|
||||
Con::printf( "Making the new rendering context current..." );
|
||||
if ( !dwglMakeCurrent( winState.appDC, winState.hGLRC ) )
|
||||
{
|
||||
AssertFatal( false, "D3DDevice::setScreenMode\ndwglMakeCurrent failed to make the rendering context current!" );
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( needResurrect )
|
||||
{
|
||||
// Reload the textures:
|
||||
Con::printf( "Resurrecting the texture manager..." );
|
||||
Game->textureResurrect();
|
||||
}
|
||||
}
|
||||
|
||||
smCurrentRes = newRes;
|
||||
Platform::setWindowSize( newRes.w, newRes.h );
|
||||
char tempBuf[15];
|
||||
dSprintf( tempBuf, sizeof( tempBuf ), "%d %d %d", smCurrentRes.w, smCurrentRes.h, smCurrentRes.bpp );
|
||||
Con::setVariable( "$pref::Video::resolution", tempBuf );
|
||||
|
||||
if ( curtain )
|
||||
DestroyWindow( curtain );
|
||||
|
||||
// Doesn't hurt to do this even it isn't necessary:
|
||||
ShowWindow( winState.appWindow, SW_SHOW );
|
||||
SetForegroundWindow( winState.appWindow );
|
||||
SetFocus( winState.appWindow );
|
||||
|
||||
if ( repaint )
|
||||
Con::evaluate( "resetCanvas();" );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void D3DDevice::swapBuffers()
|
||||
{
|
||||
dwglSwapBuffers( winState.appDC );
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
const char* D3DDevice::getDriverInfo()
|
||||
{
|
||||
// Output some driver info to the console:
|
||||
const char* vendorString = (const char*) glGetString( GL_VENDOR );
|
||||
const char* rendererString = (const char*) glGetString( GL_RENDERER );
|
||||
const char* versionString = (const char*) glGetString( GL_VERSION );
|
||||
const char* extensionsString = (const char*) glGetString( GL_EXTENSIONS );
|
||||
|
||||
U32 bufferLen = ( vendorString ? dStrlen( vendorString ) : 0 )
|
||||
+ ( rendererString ? dStrlen( rendererString ) : 0 )
|
||||
+ ( versionString ? dStrlen( versionString ) : 0 )
|
||||
+ ( extensionsString ? dStrlen( extensionsString ) : 0 )
|
||||
+ 4;
|
||||
|
||||
char* returnString = Con::getReturnBuffer( bufferLen );
|
||||
dSprintf( returnString, bufferLen, "%s\t%s\t%s\t%s",
|
||||
( vendorString ? vendorString : "" ),
|
||||
( rendererString ? rendererString : "" ),
|
||||
( versionString ? versionString : "" ),
|
||||
( extensionsString ? extensionsString : "" ) );
|
||||
|
||||
return( returnString );
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
bool D3DDevice::getGammaCorrection(F32 &g)
|
||||
{
|
||||
U16 ramp[256*3];
|
||||
|
||||
if (!GetDeviceGammaRamp(winState.appDC, ramp))
|
||||
return false;
|
||||
|
||||
F32 csum = 0.0;
|
||||
U32 ccount = 0;
|
||||
|
||||
for (U16 i = 0; i < 256; ++i)
|
||||
{
|
||||
if (i != 0 && ramp[i] != 0 && ramp[i] != 65535)
|
||||
{
|
||||
F64 b = (F64) i/256.0;
|
||||
F64 a = (F64) ramp[i]/65535.0;
|
||||
F32 c = (F32) (mLog(a)/mLog(b));
|
||||
|
||||
csum += c;
|
||||
++ccount;
|
||||
}
|
||||
}
|
||||
g = csum/ccount;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
bool D3DDevice::setGammaCorrection(F32 g)
|
||||
{
|
||||
U16 ramp[256*3];
|
||||
|
||||
for (U16 i = 0; i < 256; ++i)
|
||||
ramp[i] = mPow((F32) i/256.0f, g) * 65535.0f;
|
||||
dMemcpy(&ramp[256],ramp,256*sizeof(U16));
|
||||
dMemcpy(&ramp[512],ramp,256*sizeof(U16));
|
||||
|
||||
return SetDeviceGammaRamp(winState.appDC, ramp);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
bool D3DDevice::setVerticalSync( bool on )
|
||||
{
|
||||
on;
|
||||
return( false );
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
DisplayDevice* D3DDevice::create()
|
||||
{
|
||||
bool result = false;
|
||||
|
||||
OSVERSIONINFO OSVersionInfo;
|
||||
|
||||
dMemset( &OSVersionInfo, 0, sizeof( OSVERSIONINFO ) );
|
||||
OSVersionInfo.dwOSVersionInfoSize = sizeof( OSVERSIONINFO );
|
||||
if ( GetVersionEx( &OSVersionInfo ) &&
|
||||
(OSVersionInfo.dwPlatformId == VER_PLATFORM_WIN32_NT &&
|
||||
OSVersionInfo.dwMajorVersion <= 4) )
|
||||
return NULL;
|
||||
|
||||
// If we can't do OpenGL, don't attempt D3D either (probably Voodoo2 only)
|
||||
if (Video::getDevice("OpenGL") == NULL)
|
||||
return NULL;
|
||||
|
||||
// This shouldn't happen, but just to be safe...
|
||||
if ( winState.hinstOpenGL )
|
||||
GL_Shutdown();
|
||||
|
||||
if (!GL_Init(OPENGL2D3D_DLL,GLU2D3D_DLL))
|
||||
return NULL;
|
||||
|
||||
// Create a test window to see if OpenGL hardware acceleration is available:
|
||||
WNDCLASS wc;
|
||||
dMemset(&wc, 0, sizeof(wc));
|
||||
wc.style = CS_OWNDC;
|
||||
wc.lpfnWndProc = DefWindowProc;
|
||||
wc.hInstance = winState.appInstance;
|
||||
wc.lpszClassName = dT("D3DTest");
|
||||
RegisterClass( &wc );
|
||||
|
||||
HWND testWindow = CreateWindow(
|
||||
dT("D3DTest"),
|
||||
dT(""),
|
||||
WS_POPUP,
|
||||
0, 0, 640, 480,
|
||||
NULL,
|
||||
NULL,
|
||||
winState.appInstance,
|
||||
NULL );
|
||||
|
||||
if ( testWindow )
|
||||
{
|
||||
HDC testDC = GetDC( testWindow );
|
||||
|
||||
if ( testDC )
|
||||
{
|
||||
PIXELFORMATDESCRIPTOR pfd;
|
||||
|
||||
result = dwglDescribePixelFormat( testDC, 1, sizeof( pfd ), &pfd );
|
||||
ReleaseDC( testWindow, testDC );
|
||||
}
|
||||
DestroyWindow( testWindow );
|
||||
}
|
||||
|
||||
UnregisterClass( dT("D3DTest"), winState.appInstance );
|
||||
|
||||
GL_Shutdown();
|
||||
|
||||
if ( result )
|
||||
{
|
||||
D3DDevice* newOGLDevice = new D3DDevice();
|
||||
if ( newOGLDevice )
|
||||
{
|
||||
newOGLDevice->mFullScreenOnly = Video::getDevice("OpenGL")->isFullScreenOnly();
|
||||
return (DisplayDevice*) newOGLDevice;
|
||||
}
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
else
|
||||
return NULL;
|
||||
}
|
39
engine/platformWin32/winD3DVideo.h
Executable file
39
engine/platformWin32/winD3DVideo.h
Executable file
@ -0,0 +1,39 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// Torque Game Engine
|
||||
// Copyright (C) GarageGames.com, Inc.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#ifndef _WIND3DVIDEO_H_
|
||||
#define _WIND3DVIDEO_H_
|
||||
|
||||
#ifndef _PLATFORMVIDEO_H_
|
||||
#include "platform/platformVideo.h"
|
||||
#endif
|
||||
|
||||
class D3DDevice : public DisplayDevice
|
||||
{
|
||||
static bool smCanSwitchBitDepth;
|
||||
|
||||
bool mRestoreGamma;
|
||||
U16 mOriginalRamp[256*3];
|
||||
|
||||
public:
|
||||
D3DDevice();
|
||||
|
||||
void initDevice();
|
||||
bool activate( U32 width, U32 height, U32 bpp, bool fullScreen );
|
||||
void shutdown();
|
||||
void destroy();
|
||||
bool setScreenMode( U32 width, U32 height, U32 bpp, bool fullScreen, bool forceIt = false, bool repaint = true );
|
||||
void swapBuffers();
|
||||
const char* getDriverInfo();
|
||||
bool getGammaCorrection(F32 &g);
|
||||
bool setGammaCorrection(F32 g);
|
||||
bool setVerticalSync( bool on );
|
||||
|
||||
static DisplayDevice* create();
|
||||
|
||||
static bool smStay16;
|
||||
};
|
||||
|
||||
#endif // _H_WIND3DVIDEO
|
1652
engine/platformWin32/winDInputDevice.cc
Executable file
1652
engine/platformWin32/winDInputDevice.cc
Executable file
File diff suppressed because it is too large
Load Diff
144
engine/platformWin32/winDInputDevice.h
Executable file
144
engine/platformWin32/winDInputDevice.h
Executable file
@ -0,0 +1,144 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// Torque Game Engine
|
||||
// Copyright (C) GarageGames.com, Inc.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#ifndef _WINDINPUTDEVICE_H_
|
||||
#define _WINDINPUTDEVICE_H_
|
||||
|
||||
#ifndef _PLATFORMWIN32_H_
|
||||
#include "platformWin32/platformWin32.h"
|
||||
#endif
|
||||
#ifndef _PLATFORMINPUT_H_
|
||||
#include "platform/platformInput.h"
|
||||
#endif
|
||||
#ifndef _EVENT_H_
|
||||
#include "platform/event.h"
|
||||
#endif
|
||||
|
||||
#include <dinput.h>
|
||||
|
||||
|
||||
class DInputDevice : public InputDevice
|
||||
{
|
||||
public:
|
||||
static LPDIRECTINPUT8 smDInputInterface;
|
||||
|
||||
protected:
|
||||
enum Constants
|
||||
{
|
||||
QUEUED_BUFFER_SIZE = 128,
|
||||
|
||||
SIZEOF_BUTTON = 1, // size of an object's data in bytes
|
||||
SIZEOF_KEY = 1,
|
||||
SIZEOF_AXIS = 4,
|
||||
SIZEOF_POV = 4,
|
||||
};
|
||||
|
||||
static U8 smKeyboardCount;
|
||||
static U8 smMouseCount;
|
||||
static U8 smJoystickCount;
|
||||
static U8 smUnknownCount;
|
||||
|
||||
static U8 smModifierKeys;
|
||||
static bool smKeyStates[256];
|
||||
static bool smInitialized;
|
||||
|
||||
//--------------------------------------
|
||||
LPDIRECTINPUTDEVICE8 mDevice;
|
||||
DIDEVICEINSTANCE mDeviceInstance;
|
||||
DIDEVCAPS mDeviceCaps;
|
||||
U8 mDeviceType;
|
||||
U8 mDeviceID;
|
||||
|
||||
bool mAcquired;
|
||||
bool mNeedSync;
|
||||
|
||||
//--------------------------------------
|
||||
DIDEVICEOBJECTINSTANCE* mObjInstance;
|
||||
DIOBJECTDATAFORMAT* mObjFormat;
|
||||
ObjInfo* mObjInfo;
|
||||
U8* mObjBuffer1; // polled device input buffers
|
||||
U8* mObjBuffer2;
|
||||
U8* mPrevObjBuffer; // points to buffer 1 or 2
|
||||
|
||||
// Hack for POV
|
||||
S32 mPrevPOVPos;
|
||||
|
||||
U32 mObjBufferSize; // size of objBuffer*
|
||||
U32 mObjCount; // number of objects on this device
|
||||
U32 mObjEnumCount; // used during enumeration ONLY
|
||||
U32 mObjBufferOfs; // used during enumeration ONLY
|
||||
|
||||
static BOOL CALLBACK EnumObjectsProc( const DIDEVICEOBJECTINSTANCE *doi, LPVOID pvRef );
|
||||
|
||||
bool enumerateObjects();
|
||||
bool processAsync();
|
||||
bool processImmediate();
|
||||
bool processKeyEvent( InputEvent &event );
|
||||
|
||||
void syncKeyboardState();
|
||||
|
||||
DWORD findObjInstance( DWORD offset );
|
||||
bool buildEvent( DWORD offset, S32 newData, S32 oldData );
|
||||
|
||||
public:
|
||||
DInputDevice( const DIDEVICEINSTANCE* deviceInst );
|
||||
~DInputDevice();
|
||||
|
||||
static void init();
|
||||
static void resetModifierKeys();
|
||||
|
||||
bool create();
|
||||
void destroy();
|
||||
|
||||
bool acquire();
|
||||
bool unacquire();
|
||||
|
||||
bool isAcquired();
|
||||
bool isPolled();
|
||||
|
||||
U8 getDeviceType();
|
||||
U8 getDeviceID();
|
||||
|
||||
const char* getName();
|
||||
const char* getProductName();
|
||||
|
||||
// Console interface functions:
|
||||
const char* getJoystickAxesString();
|
||||
static bool joystickDetected();
|
||||
//
|
||||
|
||||
bool process();
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
inline bool DInputDevice::isAcquired()
|
||||
{
|
||||
return mAcquired;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
inline bool DInputDevice::isPolled()
|
||||
{
|
||||
//return true;
|
||||
return ( mDeviceCaps.dwFlags & DIDC_POLLEDDEVICE );
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
inline U8 DInputDevice::getDeviceType()
|
||||
{
|
||||
return mDeviceType;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
inline U8 DInputDevice::getDeviceID()
|
||||
{
|
||||
return mDeviceID;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//------------------------------------------------------------------------------
|
||||
U16 DIK_to_Key( U8 dikCode );
|
||||
U8 Key_to_DIK( U16 keyCode );
|
||||
#endif // _H_WINDINPUTDEVICE_
|
541
engine/platformWin32/winDirectInput.cc
Executable file
541
engine/platformWin32/winDirectInput.cc
Executable file
@ -0,0 +1,541 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// Torque Game Engine
|
||||
// Copyright (C) GarageGames.com, Inc.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "platformWin32/platformWin32.h"
|
||||
#include "platform/platformVideo.h"
|
||||
#include "platformWin32/winDirectInput.h"
|
||||
#include "platformWin32/winDInputDevice.h"
|
||||
#include "platform/event.h"
|
||||
#include "console/console.h"
|
||||
#include "console/consoleTypes.h"
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Static class variables:
|
||||
bool DInputManager::smKeyboardEnabled = true;
|
||||
bool DInputManager::smMouseEnabled = false;
|
||||
bool DInputManager::smJoystickEnabled = false;
|
||||
|
||||
// Type definitions:
|
||||
typedef HRESULT (WINAPI* FN_DirectInputCreate)(HINSTANCE hinst, DWORD dwVersion, REFIID riidltf, LPVOID *ppvOut, LPUNKNOWN punkOuter);
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
DInputManager::DInputManager()
|
||||
{
|
||||
mEnabled = false;
|
||||
mDInputLib = NULL;
|
||||
mDInputInterface = NULL;
|
||||
mKeyboardActive = mMouseActive = mJoystickActive = false;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void DInputManager::init()
|
||||
{
|
||||
Con::addVariable( "pref::Input::KeyboardEnabled", TypeBool, &smKeyboardEnabled );
|
||||
Con::addVariable( "pref::Input::MouseEnabled", TypeBool, &smMouseEnabled );
|
||||
Con::addVariable( "pref::Input::JoystickEnabled", TypeBool, &smJoystickEnabled );
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
bool DInputManager::enable()
|
||||
{
|
||||
FN_DirectInputCreate fnDInputCreate;
|
||||
|
||||
disable();
|
||||
#ifdef LOG_INPUT
|
||||
Input::log( "Enabling DirectInput...\n" );
|
||||
#endif
|
||||
mDInputLib = LoadLibrary( dT("DInput8.dll") );
|
||||
if ( mDInputLib )
|
||||
{
|
||||
fnDInputCreate = (FN_DirectInputCreate) GetProcAddress( mDInputLib, "DirectInput8Create" );
|
||||
if ( fnDInputCreate )
|
||||
{
|
||||
bool result = SUCCEEDED( fnDInputCreate( winState.appInstance, DIRECTINPUT_VERSION,
|
||||
IID_IDirectInput8, reinterpret_cast<void**>(&mDInputInterface), NULL ));
|
||||
if ( result )
|
||||
{
|
||||
#ifdef LOG_INPUT
|
||||
Input::log( "DirectX 8 or greater detected.\n" );
|
||||
#endif
|
||||
}
|
||||
|
||||
if ( result )
|
||||
{
|
||||
enumerateDevices();
|
||||
mEnabled = true;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
disable();
|
||||
|
||||
#ifdef LOG_INPUT
|
||||
Input::log( "Failed to enable DirectInput.\n" );
|
||||
#endif
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void DInputManager::disable()
|
||||
{
|
||||
unacquire( SI_ANY, SI_ANY );
|
||||
|
||||
DInputDevice* dptr;
|
||||
iterator ptr = begin();
|
||||
while ( ptr != end() )
|
||||
{
|
||||
dptr = dynamic_cast<DInputDevice*>( *ptr );
|
||||
if ( dptr )
|
||||
{
|
||||
removeObject( dptr );
|
||||
//if ( dptr->getManager() )
|
||||
//dptr->getManager()->unregisterObject( dptr );
|
||||
delete dptr;
|
||||
ptr = begin();
|
||||
}
|
||||
else
|
||||
ptr++;
|
||||
}
|
||||
|
||||
if ( mDInputInterface )
|
||||
{
|
||||
mDInputInterface->Release();
|
||||
mDInputInterface = NULL;
|
||||
}
|
||||
|
||||
if ( mDInputLib )
|
||||
{
|
||||
FreeLibrary( mDInputLib );
|
||||
mDInputLib = NULL;
|
||||
}
|
||||
|
||||
mEnabled = false;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void DInputManager::onDeleteNotify( SimObject* object )
|
||||
{
|
||||
Parent::onDeleteNotify( object );
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
bool DInputManager::onAdd()
|
||||
{
|
||||
if ( !Parent::onAdd() )
|
||||
return false;
|
||||
|
||||
acquire( SI_ANY, SI_ANY );
|
||||
return true;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void DInputManager::onRemove()
|
||||
{
|
||||
unacquire( SI_ANY, SI_ANY );
|
||||
Parent::onRemove();
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
bool DInputManager::acquire( U8 deviceType, U8 deviceID )
|
||||
{
|
||||
bool anyActive = false;
|
||||
DInputDevice* dptr;
|
||||
for ( iterator ptr = begin(); ptr != end(); ptr++ )
|
||||
{
|
||||
dptr = dynamic_cast<DInputDevice*>( *ptr );
|
||||
if ( dptr
|
||||
&& ( ( deviceType == SI_ANY ) || ( dptr->getDeviceType() == deviceType ) )
|
||||
&& ( ( deviceID == SI_ANY ) || ( dptr->getDeviceID() == deviceID ) ) )
|
||||
{
|
||||
if ( dptr->acquire() )
|
||||
anyActive = true;
|
||||
}
|
||||
}
|
||||
|
||||
return anyActive;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void DInputManager::unacquire( U8 deviceType, U8 deviceID )
|
||||
{
|
||||
DInputDevice* dptr;
|
||||
for ( iterator ptr = begin(); ptr != end(); ptr++ )
|
||||
{
|
||||
dptr = dynamic_cast<DInputDevice*>( *ptr );
|
||||
if ( dptr
|
||||
&& ( ( deviceType == SI_ANY ) || ( dptr->getDeviceType() == deviceType ) )
|
||||
&& ( ( deviceID == SI_ANY ) || ( dptr->getDeviceID() == deviceID ) ) )
|
||||
dptr->unacquire();
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void DInputManager::process()
|
||||
{
|
||||
DInputDevice* dptr;
|
||||
for ( iterator ptr = begin(); ptr != end(); ptr++ )
|
||||
{
|
||||
dptr = dynamic_cast<DInputDevice*>( *ptr );
|
||||
if ( dptr )
|
||||
dptr->process();
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void DInputManager::enumerateDevices()
|
||||
{
|
||||
if ( mDInputInterface )
|
||||
{
|
||||
#ifdef LOG_INPUT
|
||||
Input::log( "Enumerating input devices...\n" );
|
||||
#endif
|
||||
|
||||
DInputDevice::init();
|
||||
DInputDevice::smDInputInterface = mDInputInterface;
|
||||
mDInputInterface->EnumDevices( DI8DEVTYPE_KEYBOARD, EnumDevicesProc, this, DIEDFL_ATTACHEDONLY );
|
||||
mDInputInterface->EnumDevices( DI8DEVTYPE_MOUSE, EnumDevicesProc, this, DIEDFL_ATTACHEDONLY );
|
||||
mDInputInterface->EnumDevices( DI8DEVTYPE_JOYSTICK, EnumDevicesProc, this, DIEDFL_ATTACHEDONLY );
|
||||
mDInputInterface->EnumDevices( DI8DEVTYPE_GAMEPAD, EnumDevicesProc, this, DIEDFL_ATTACHEDONLY );
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
BOOL CALLBACK DInputManager::EnumDevicesProc( const DIDEVICEINSTANCE* pddi, LPVOID pvRef )
|
||||
{
|
||||
DInputManager* manager = (DInputManager*) pvRef;
|
||||
DInputDevice* newDevice = new DInputDevice( pddi );
|
||||
manager->addObject( newDevice );
|
||||
if ( !newDevice->create() )
|
||||
{
|
||||
manager->removeObject( newDevice );
|
||||
delete newDevice;
|
||||
}
|
||||
|
||||
return (DIENUM_CONTINUE);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
bool DInputManager::enableKeyboard()
|
||||
{
|
||||
DInputManager* mgr = dynamic_cast<DInputManager*>( Input::getManager() );
|
||||
if ( !mgr || !mgr->isEnabled() )
|
||||
return( false );
|
||||
|
||||
if ( smKeyboardEnabled && mgr->isKeyboardActive() )
|
||||
return( true );
|
||||
|
||||
smKeyboardEnabled = true;
|
||||
if ( Input::isActive() )
|
||||
smKeyboardEnabled = mgr->activateKeyboard();
|
||||
|
||||
if ( smKeyboardEnabled )
|
||||
{
|
||||
Con::printf( "DirectInput keyboard enabled." );
|
||||
#ifdef LOG_INPUT
|
||||
Input::log( "Keyboard enabled.\n" );
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
Con::warnf( "DirectInput keyboard failed to enable!" );
|
||||
#ifdef LOG_INPUT
|
||||
Input::log( "Keyboard failed to enable!\n" );
|
||||
#endif
|
||||
}
|
||||
|
||||
return( smKeyboardEnabled );
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void DInputManager::disableKeyboard()
|
||||
{
|
||||
DInputManager* mgr = dynamic_cast<DInputManager*>( Input::getManager() );
|
||||
if ( !mgr || !mgr->isEnabled() || !smKeyboardEnabled )
|
||||
return;
|
||||
|
||||
mgr->deactivateKeyboard();
|
||||
smKeyboardEnabled = false;
|
||||
Con::printf( "DirectInput keyboard disabled." );
|
||||
#ifdef LOG_INPUT
|
||||
Input::log( "Keyboard disabled.\n" );
|
||||
#endif
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
bool DInputManager::isKeyboardEnabled()
|
||||
{
|
||||
return( smKeyboardEnabled );
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
bool DInputManager::activateKeyboard()
|
||||
{
|
||||
if ( !mEnabled || !Input::isActive() || !smKeyboardEnabled )
|
||||
return( false );
|
||||
|
||||
// Acquire only one keyboard:
|
||||
mKeyboardActive = acquire( KeyboardDeviceType, 0 );
|
||||
#ifdef LOG_INPUT
|
||||
Input::log( mKeyboardActive ? "Keyboard activated.\n" : "Keyboard failed to activate!\n" );
|
||||
#endif
|
||||
return( mKeyboardActive );
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void DInputManager::deactivateKeyboard()
|
||||
{
|
||||
if ( mEnabled && mKeyboardActive )
|
||||
{
|
||||
unacquire( KeyboardDeviceType, SI_ANY );
|
||||
mKeyboardActive = false;
|
||||
#ifdef LOG_INPUT
|
||||
Input::log( "Keyboard deactivated.\n" );
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
bool DInputManager::enableMouse()
|
||||
{
|
||||
DInputManager* mgr = dynamic_cast<DInputManager*>( Input::getManager() );
|
||||
if ( !mgr || !mgr->isEnabled() )
|
||||
return( false );
|
||||
|
||||
if ( smMouseEnabled && mgr->isMouseActive() )
|
||||
return( true );
|
||||
|
||||
smMouseEnabled = true;
|
||||
if ( Input::isActive() )
|
||||
smMouseEnabled = mgr->activateMouse();
|
||||
|
||||
if ( smMouseEnabled )
|
||||
{
|
||||
Con::printf( "DirectInput mouse enabled." );
|
||||
#ifdef LOG_INPUT
|
||||
Input::log( "Mouse enabled.\n" );
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
Con::warnf( "DirectInput mouse failed to enable!" );
|
||||
#ifdef LOG_INPUT
|
||||
Input::log( "Mouse failed to enable!\n" );
|
||||
#endif
|
||||
}
|
||||
|
||||
return( smMouseEnabled );
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void DInputManager::disableMouse()
|
||||
{
|
||||
DInputManager* mgr = dynamic_cast<DInputManager*>( Input::getManager() );
|
||||
if ( !mgr || !mgr->isEnabled() || !smMouseEnabled )
|
||||
return;
|
||||
|
||||
mgr->deactivateMouse();
|
||||
smMouseEnabled = false;
|
||||
Con::printf( "DirectInput mouse disabled." );
|
||||
#ifdef LOG_INPUT
|
||||
Input::log( "Mouse disabled.\n" );
|
||||
#endif
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
bool DInputManager::isMouseEnabled()
|
||||
{
|
||||
return( smMouseEnabled );
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
bool DInputManager::activateMouse()
|
||||
{
|
||||
if ( !mEnabled || !Input::isActive() || !smMouseEnabled )
|
||||
return( false );
|
||||
|
||||
mMouseActive = acquire( MouseDeviceType, SI_ANY );
|
||||
#ifdef LOG_INPUT
|
||||
Input::log( mMouseActive ? "Mouse activated.\n" : "Mouse failed to activate!\n" );
|
||||
#endif
|
||||
return( mMouseActive );
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void DInputManager::deactivateMouse()
|
||||
{
|
||||
if ( mEnabled && mMouseActive )
|
||||
{
|
||||
unacquire( MouseDeviceType, SI_ANY );
|
||||
mMouseActive = false;
|
||||
#ifdef LOG_INPUT
|
||||
Input::log( "Mouse deactivated.\n" );
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
bool DInputManager::enableJoystick()
|
||||
{
|
||||
DInputManager* mgr = dynamic_cast<DInputManager*>( Input::getManager() );
|
||||
if ( !mgr || !mgr->isEnabled() )
|
||||
return( false );
|
||||
|
||||
if ( smJoystickEnabled && mgr->isJoystickActive() )
|
||||
return( true );
|
||||
|
||||
smJoystickEnabled = true;
|
||||
if ( Input::isActive() )
|
||||
smJoystickEnabled = mgr->activateJoystick();
|
||||
|
||||
if ( smJoystickEnabled )
|
||||
{
|
||||
Con::printf( "DirectInput joystick enabled." );
|
||||
#ifdef LOG_INPUT
|
||||
Input::log( "Joystick enabled.\n" );
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
Con::warnf( "DirectInput joystick failed to enable!" );
|
||||
#ifdef LOG_INPUT
|
||||
Input::log( "Joystick failed to enable!\n" );
|
||||
#endif
|
||||
}
|
||||
|
||||
return( smJoystickEnabled );
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void DInputManager::disableJoystick()
|
||||
{
|
||||
DInputManager* mgr = dynamic_cast<DInputManager*>( Input::getManager() );
|
||||
if ( !mgr || !mgr->isEnabled() || !smJoystickEnabled )
|
||||
return;
|
||||
|
||||
mgr->deactivateJoystick();
|
||||
smJoystickEnabled = false;
|
||||
Con::printf( "DirectInput joystick disabled." );
|
||||
#ifdef LOG_INPUT
|
||||
Input::log( "Joystick disabled.\n" );
|
||||
#endif
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
bool DInputManager::isJoystickEnabled()
|
||||
{
|
||||
return( smJoystickEnabled );
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
bool DInputManager::activateJoystick()
|
||||
{
|
||||
if ( !mEnabled || !Input::isActive() || !smJoystickEnabled )
|
||||
return( false );
|
||||
|
||||
mJoystickActive = acquire( JoystickDeviceType, SI_ANY );
|
||||
#ifdef LOG_INPUT
|
||||
Input::log( mJoystickActive ? "Joystick activated.\n" : "Joystick failed to activate!\n" );
|
||||
#endif
|
||||
return( mJoystickActive );
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void DInputManager::deactivateJoystick()
|
||||
{
|
||||
if ( mEnabled && mJoystickActive )
|
||||
{
|
||||
unacquire( JoystickDeviceType, SI_ANY );
|
||||
mJoystickActive = false;
|
||||
#ifdef LOG_INPUT
|
||||
Input::log( "Joystick deactivated.\n" );
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
const char* DInputManager::getJoystickAxesString( U32 deviceID )
|
||||
{
|
||||
DInputDevice* dptr;
|
||||
for ( iterator ptr = begin(); ptr != end(); ptr++ )
|
||||
{
|
||||
dptr = dynamic_cast<DInputDevice*>( *ptr );
|
||||
if ( dptr && ( dptr->getDeviceType() == JoystickDeviceType ) && ( dptr->getDeviceID() == deviceID ) )
|
||||
return( dptr->getJoystickAxesString() );
|
||||
}
|
||||
|
||||
return( "" );
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
ConsoleFunction( activateKeyboard, bool, 1, 1, "activateKeyboard()" )
|
||||
{
|
||||
argc; argv;
|
||||
DInputManager* mgr = dynamic_cast<DInputManager*>( Input::getManager() );
|
||||
if ( mgr )
|
||||
return( mgr->activateKeyboard() );
|
||||
|
||||
return( false );
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
ConsoleFunction( deactivateKeyboard, void, 1, 1, "deactivateKeyboard()" )
|
||||
{
|
||||
argc; argv;
|
||||
DInputManager* mgr = dynamic_cast<DInputManager*>( Input::getManager() );
|
||||
if ( mgr )
|
||||
mgr->deactivateKeyboard();
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
ConsoleFunction( enableMouse, bool, 1, 1, "enableMouse()" )
|
||||
{
|
||||
argc; argv;
|
||||
return( DInputManager::enableMouse() );
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
ConsoleFunction( disableMouse, void, 1, 1, "disableMouse()" )
|
||||
{
|
||||
argc; argv;
|
||||
DInputManager::disableMouse();
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
ConsoleFunction( enableJoystick, bool, 1, 1, "enableJoystick()" )
|
||||
{
|
||||
argc; argv;
|
||||
return( DInputManager::enableJoystick() );
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
ConsoleFunction( disableJoystick, void, 1, 1, "disableJoystick()" )
|
||||
{
|
||||
argc; argv;
|
||||
DInputManager::disableJoystick();
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
ConsoleFunction( echoInputState, void, 1, 1, "echoInputState()" )
|
||||
{
|
||||
argc; argv;
|
||||
DInputManager* mgr = dynamic_cast<DInputManager*>( Input::getManager() );
|
||||
if ( mgr && mgr->isEnabled() )
|
||||
{
|
||||
Con::printf( "DirectInput is enabled %s.", Input::isActive() ? "and active" : "but inactive" );
|
||||
Con::printf( "- Keyboard is %sabled and %sactive.",
|
||||
mgr->isKeyboardEnabled() ? "en" : "dis",
|
||||
mgr->isKeyboardActive() ? "" : "in" );
|
||||
Con::printf( "- Mouse is %sabled and %sactive.",
|
||||
mgr->isMouseEnabled() ? "en" : "dis",
|
||||
mgr->isMouseActive() ? "" : "in" );
|
||||
Con::printf( "- Joystick is %sabled and %sactive.",
|
||||
mgr->isJoystickEnabled() ? "en" : "dis",
|
||||
mgr->isJoystickActive() ? "" : "in" );
|
||||
}
|
||||
else
|
||||
Con::printf( "DirectInput is not enabled." );
|
||||
}
|
87
engine/platformWin32/winDirectInput.h
Executable file
87
engine/platformWin32/winDirectInput.h
Executable file
@ -0,0 +1,87 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// Torque Game Engine
|
||||
// Copyright (C) GarageGames.com, Inc.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#ifndef _WINDIRECTINPUT_H_
|
||||
#define _WINDIRECTINPUT_H_
|
||||
|
||||
#ifndef _PLATFORMWIN32_H_
|
||||
#include "platformWin32/platformWin32.h"
|
||||
#endif
|
||||
#ifndef _PLATFORMINPUT_H_
|
||||
#include "platform/platformInput.h"
|
||||
#endif
|
||||
#ifndef _WINDINPUTDEVICE_H_
|
||||
#include "platformWin32/winDInputDevice.h"
|
||||
#endif
|
||||
|
||||
#include <dinput.h>
|
||||
|
||||
struct InputEvent;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
class DInputManager : public InputManager
|
||||
{
|
||||
private:
|
||||
typedef SimGroup Parent;
|
||||
|
||||
HMODULE mDInputLib;
|
||||
LPDIRECTINPUT8 mDInputInterface;
|
||||
|
||||
static bool smKeyboardEnabled;
|
||||
static bool smMouseEnabled;
|
||||
static bool smJoystickEnabled;
|
||||
|
||||
bool mKeyboardActive;
|
||||
bool mMouseActive;
|
||||
bool mJoystickActive;
|
||||
|
||||
void enumerateDevices();
|
||||
|
||||
static BOOL CALLBACK EnumDevicesProc( const DIDEVICEINSTANCE *pddi, LPVOID pvRef );
|
||||
|
||||
bool acquire( U8 deviceType, U8 deviceID );
|
||||
void unacquire( U8 deviceType, U8 deviceID );
|
||||
|
||||
public:
|
||||
DInputManager();
|
||||
|
||||
bool enable();
|
||||
void disable();
|
||||
|
||||
void onDeleteNotify( SimObject* object );
|
||||
bool onAdd();
|
||||
void onRemove();
|
||||
|
||||
void process();
|
||||
|
||||
// DirectInput functions:
|
||||
static void init();
|
||||
|
||||
static bool enableKeyboard();
|
||||
static void disableKeyboard();
|
||||
static bool isKeyboardEnabled();
|
||||
bool activateKeyboard();
|
||||
void deactivateKeyboard();
|
||||
bool isKeyboardActive() { return( mKeyboardActive ); }
|
||||
|
||||
static bool enableMouse();
|
||||
static void disableMouse();
|
||||
static bool isMouseEnabled();
|
||||
bool activateMouse();
|
||||
void deactivateMouse();
|
||||
bool isMouseActive() { return( mMouseActive ); }
|
||||
|
||||
static bool enableJoystick();
|
||||
static void disableJoystick();
|
||||
static bool isJoystickEnabled();
|
||||
bool activateJoystick();
|
||||
void deactivateJoystick();
|
||||
bool isJoystickActive() { return( mJoystickActive ); }
|
||||
|
||||
// Console interface:
|
||||
const char* getJoystickAxesString( U32 deviceID );
|
||||
};
|
||||
|
||||
#endif // _H_WINDIRECTINPUT_
|
1062
engine/platformWin32/winFileio.cc
Executable file
1062
engine/platformWin32/winFileio.cc
Executable file
File diff suppressed because it is too large
Load Diff
335
engine/platformWin32/winFont.cc
Executable file
335
engine/platformWin32/winFont.cc
Executable file
@ -0,0 +1,335 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// Torque Game Engine
|
||||
// Copyright (C) GarageGames.com, Inc.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "platformWin32/platformWin32.h"
|
||||
#include "platformWin32/winFont.h"
|
||||
#include "dgl/gNewFont.h"
|
||||
#include "dgl/gFont.h"
|
||||
#include "dgl/gBitmap.h"
|
||||
#include "math/mRect.h"
|
||||
#include "console/console.h"
|
||||
#include "core/unicode.h"
|
||||
|
||||
static HDC fontHDC = NULL;
|
||||
static HBITMAP fontBMP = NULL;
|
||||
|
||||
static U32 charsetMap[]=
|
||||
{
|
||||
ANSI_CHARSET,
|
||||
SYMBOL_CHARSET,
|
||||
SHIFTJIS_CHARSET,
|
||||
HANGEUL_CHARSET,
|
||||
HANGUL_CHARSET,
|
||||
GB2312_CHARSET,
|
||||
CHINESEBIG5_CHARSET,
|
||||
OEM_CHARSET,
|
||||
JOHAB_CHARSET,
|
||||
HEBREW_CHARSET,
|
||||
ARABIC_CHARSET,
|
||||
GREEK_CHARSET,
|
||||
TURKISH_CHARSET,
|
||||
VIETNAMESE_CHARSET,
|
||||
THAI_CHARSET,
|
||||
EASTEUROPE_CHARSET,
|
||||
RUSSIAN_CHARSET,
|
||||
MAC_CHARSET,
|
||||
BALTIC_CHARSET,
|
||||
};
|
||||
#define NUMCHARSETMAP (sizeof(charsetMap) / sizeof(U32))
|
||||
|
||||
void createFontInit(void);
|
||||
void createFontShutdown(void);
|
||||
void CopyCharToBitmap(GBitmap *pDstBMP, HDC hSrcHDC, const RectI &r);
|
||||
|
||||
void createFontInit()
|
||||
{
|
||||
fontHDC = CreateCompatibleDC(NULL);
|
||||
fontBMP = CreateCompatibleBitmap(fontHDC, 256, 256);
|
||||
}
|
||||
|
||||
void createFontShutdown()
|
||||
{
|
||||
DeleteObject(fontBMP);
|
||||
DeleteObject(fontHDC);
|
||||
}
|
||||
|
||||
void CopyCharToBitmap(GBitmap *pDstBMP, HDC hSrcHDC, const RectI &r)
|
||||
{
|
||||
for (S32 i = r.point.y; i < r.point.y + r.extent.y; i++)
|
||||
{
|
||||
for (S32 j = r.point.x; j < r.point.x + r.extent.x; j++)
|
||||
{
|
||||
COLORREF color = GetPixel(hSrcHDC, j, i);
|
||||
if (color)
|
||||
*pDstBMP->getAddress(j, i) = 255;
|
||||
else
|
||||
*pDstBMP->getAddress(j, i) = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
GOldFont *createFont(const char *name, dsize_t size, U32 charset /* = TGE_ANSI_CHARSET */)
|
||||
{
|
||||
if(!name)
|
||||
return NULL;
|
||||
if(size < 1)
|
||||
return NULL;
|
||||
|
||||
if(charset > NUMCHARSETMAP)
|
||||
charset = TGE_ANSI_CHARSET;
|
||||
|
||||
#ifdef UNICODE
|
||||
UTF16 n[512];
|
||||
convertUTF8toUTF16((UTF8 *)name, n, sizeof(n));
|
||||
HFONT hNewFont = CreateFont(size,0,0,0,0,0,0,0,0,0,0,0,0,n);
|
||||
#else
|
||||
HFONT hNewFont = CreateFont(size,0,0,0,0,0,0,0,charsetMap[charset],0,0,0,0,name);
|
||||
#endif
|
||||
if(!hNewFont)
|
||||
return NULL;
|
||||
|
||||
GOldFont *retFont = new GOldFont;
|
||||
static U8 scratchPad[65536];
|
||||
|
||||
TEXTMETRIC textMetric;
|
||||
COLORREF backgroundColorRef = RGB( 0, 0, 0);
|
||||
COLORREF foregroundColorRef = RGB(255, 255, 255);
|
||||
|
||||
SelectObject(fontHDC, fontBMP);
|
||||
SelectObject(fontHDC, hNewFont);
|
||||
SetBkColor(fontHDC, backgroundColorRef);
|
||||
SetTextColor(fontHDC, foregroundColorRef);
|
||||
GetTextMetrics(fontHDC, &textMetric);
|
||||
MAT2 matrix;
|
||||
GLYPHMETRICS metrics;
|
||||
RectI clip;
|
||||
|
||||
FIXED zero;
|
||||
zero.fract = 0;
|
||||
zero.value = 0;
|
||||
FIXED one;
|
||||
one.fract = 0;
|
||||
one.value = 1;
|
||||
|
||||
matrix.eM11 = one;
|
||||
matrix.eM12 = zero;
|
||||
matrix.eM21 = zero;
|
||||
matrix.eM22 = one;
|
||||
S32 glyphCount = 0;
|
||||
|
||||
for(S32 i = 32; i < 256; i++)
|
||||
{
|
||||
#ifdef UNICODE
|
||||
UTF16 c[2];
|
||||
const UTF8 t[] = { (const UTF8)i, 0 };
|
||||
|
||||
convertUTF8toUTF16(t, c, sizeof(c));
|
||||
#endif
|
||||
|
||||
if(GetGlyphOutline(
|
||||
fontHDC, // handle of device context
|
||||
#ifdef UNICODE
|
||||
c[0], // character to query
|
||||
#else
|
||||
i, // character to query
|
||||
#endif
|
||||
GGO_GRAY8_BITMAP, // format of data to return
|
||||
&metrics, // address of structure for metrics
|
||||
sizeof(scratchPad), // size of buffer for data
|
||||
scratchPad, // address of buffer for data
|
||||
&matrix // address of transformation matrix structure
|
||||
) != GDI_ERROR)
|
||||
{
|
||||
glyphCount++;
|
||||
U32 rowStride = (metrics.gmBlackBoxX + 3) & ~3; // DWORD aligned
|
||||
U32 size = rowStride * metrics.gmBlackBoxY;
|
||||
for(U32 j = 0; j < size; j++)
|
||||
{
|
||||
U32 pad = U32(scratchPad[j]) << 2;
|
||||
if(pad > 255)
|
||||
pad = 255;
|
||||
scratchPad[j] = pad;
|
||||
}
|
||||
S32 inc = metrics.gmCellIncX;
|
||||
if(inc < 0)
|
||||
inc = -inc;
|
||||
retFont->insertBitmap(i, scratchPad, rowStride, metrics.gmBlackBoxX, metrics.gmBlackBoxY, metrics.gmptGlyphOrigin.x, metrics.gmptGlyphOrigin.y, metrics.gmCellIncX);
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef UNICODE
|
||||
UTF16 b = i;
|
||||
#else
|
||||
char b = i;
|
||||
#endif
|
||||
SIZE size;
|
||||
GetTextExtentPoint32(fontHDC, &b, 1, &size);
|
||||
if(size.cx)
|
||||
retFont->insertBitmap(i, scratchPad, 0, 0, 0, 0, 0, size.cx);
|
||||
}
|
||||
}
|
||||
retFont->pack(textMetric.tmHeight, textMetric.tmAscent);
|
||||
//clean up local vars
|
||||
DeleteObject(hNewFont);
|
||||
|
||||
if (!glyphCount)
|
||||
Con::errorf(ConsoleLogEntry::General,"Error creating font: %s %d",name, size);
|
||||
|
||||
return retFont;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// WinFont class
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
PlatformFont *createPlatformFont(const char *name, U32 size, U32 charset /* = TGE_ANSI_CHARSET */)
|
||||
{
|
||||
PlatformFont *retFont = new WinFont;
|
||||
|
||||
if(retFont->create(name, size, charset))
|
||||
return retFont;
|
||||
|
||||
delete retFont;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
WinFont::WinFont() : mFont(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
WinFont::~WinFont()
|
||||
{
|
||||
if(mFont)
|
||||
{
|
||||
DeleteObject(mFont);
|
||||
}
|
||||
}
|
||||
|
||||
bool WinFont::create(const char *name, U32 size, U32 charset /* = TGE_ANSI_CHARSET */)
|
||||
{
|
||||
if(name == NULL || size < 1)
|
||||
return false;
|
||||
|
||||
if(charset > NUMCHARSETMAP)
|
||||
charset = TGE_ANSI_CHARSET;
|
||||
|
||||
#ifdef UNICODE
|
||||
UTF16 n[512];
|
||||
convertUTF8toUTF16((UTF8 *)name, n, sizeof(n));
|
||||
mFont = CreateFont(size,0,0,0,0,0,0,0,DEFAULT_CHARSET,OUT_TT_PRECIS,0,PROOF_QUALITY,0,n);
|
||||
#else
|
||||
mFont = CreateFont(size,0,0,0,0,0,0,0,charsetMap[charset],OUT_TT_PRECIS,0,PROOF_QUALITY,0,name);
|
||||
#endif
|
||||
if(mFont == NULL)
|
||||
return false;
|
||||
|
||||
SelectObject(fontHDC, fontBMP);
|
||||
SelectObject(fontHDC, mFont);
|
||||
GetTextMetrics(fontHDC, &mTextMetric);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool WinFont::isValidChar(const UTF16 ch) const
|
||||
{
|
||||
return ch != 0 /* && (ch >= mTextMetric.tmFirstChar && ch <= mTextMetric.tmLastChar)*/;
|
||||
}
|
||||
|
||||
bool WinFont::isValidChar(const UTF8 *str) const
|
||||
{
|
||||
return isValidChar(oneUTF8toUTF32(str));
|
||||
}
|
||||
|
||||
|
||||
PlatformFont::CharInfo &WinFont::getCharInfo(const UTF16 ch) const
|
||||
{
|
||||
static PlatformFont::CharInfo c;
|
||||
|
||||
dMemset(&c, 0, sizeof(c));
|
||||
c.bitmapIndex = -1;
|
||||
|
||||
static U8 scratchPad[65536];
|
||||
|
||||
COLORREF backgroundColorRef = RGB( 0, 0, 0);
|
||||
COLORREF foregroundColorRef = RGB(255, 255, 255);
|
||||
SelectObject(fontHDC, fontBMP);
|
||||
SelectObject(fontHDC, mFont);
|
||||
SetBkColor(fontHDC, backgroundColorRef);
|
||||
SetTextColor(fontHDC, foregroundColorRef);
|
||||
|
||||
MAT2 matrix;
|
||||
GLYPHMETRICS metrics;
|
||||
RectI clip;
|
||||
|
||||
FIXED zero;
|
||||
zero.fract = 0;
|
||||
zero.value = 0;
|
||||
FIXED one;
|
||||
one.fract = 0;
|
||||
one.value = 1;
|
||||
|
||||
matrix.eM11 = one;
|
||||
matrix.eM12 = zero;
|
||||
matrix.eM21 = zero;
|
||||
matrix.eM22 = one;
|
||||
|
||||
|
||||
if(GetGlyphOutline(
|
||||
fontHDC, // handle of device context
|
||||
ch, // character to query
|
||||
GGO_GRAY8_BITMAP, // format of data to return
|
||||
&metrics, // address of structure for metrics
|
||||
sizeof(scratchPad), // size of buffer for data
|
||||
scratchPad, // address of buffer for data
|
||||
&matrix // address of transformation matrix structure
|
||||
) != GDI_ERROR)
|
||||
{
|
||||
U32 rowStride = (metrics.gmBlackBoxX + 3) & ~3; // DWORD aligned
|
||||
U32 size = rowStride * metrics.gmBlackBoxY;
|
||||
for(U32 j = 0; j < size; j++)
|
||||
{
|
||||
U32 pad = U32(scratchPad[j]) << 2;
|
||||
if(pad > 255)
|
||||
pad = 255;
|
||||
scratchPad[j] = pad;
|
||||
}
|
||||
S32 inc = metrics.gmCellIncX;
|
||||
if(inc < 0)
|
||||
inc = -inc;
|
||||
|
||||
c.xOffset = 0;
|
||||
c.yOffset = 0;
|
||||
c.width = metrics.gmBlackBoxX;
|
||||
c.height = metrics.gmBlackBoxY;
|
||||
c.xOrigin = metrics.gmptGlyphOrigin.x;
|
||||
c.yOrigin = metrics.gmptGlyphOrigin.y;
|
||||
c.xIncrement = metrics.gmCellIncX;
|
||||
|
||||
c.bitmapData = new U8[c.width * c.height];
|
||||
for(U32 y = 0; S32(y) < c.height; y++)
|
||||
{
|
||||
U32 x;
|
||||
for(x = 0; x < c.width; x++)
|
||||
c.bitmapData[y * c.width + x] = scratchPad[y * rowStride + x];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
SIZE size;
|
||||
GetTextExtentPoint32W(fontHDC, &ch, 1, &size);
|
||||
if(size.cx)
|
||||
{
|
||||
c.xIncrement = size.cx;
|
||||
c.bitmapIndex = 0;
|
||||
}
|
||||
}
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
PlatformFont::CharInfo &WinFont::getCharInfo(const UTF8 *str) const
|
||||
{
|
||||
return getCharInfo(oneUTF8toUTF32(str));
|
||||
}
|
43
engine/platformWin32/winFont.h
Executable file
43
engine/platformWin32/winFont.h
Executable file
@ -0,0 +1,43 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// Torque Game Engine
|
||||
// Copyright (C) GarageGames.com, Inc.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#ifndef _PLATFORMFONT_H_
|
||||
#include "platform/platformFont.h"
|
||||
#endif
|
||||
|
||||
#ifndef _WINFONT_H_
|
||||
#define _WINFONT_H_
|
||||
|
||||
class WinFont : public PlatformFont
|
||||
{
|
||||
private:
|
||||
HFONT mFont;
|
||||
TEXTMETRIC mTextMetric;
|
||||
|
||||
public:
|
||||
WinFont();
|
||||
virtual ~WinFont();
|
||||
|
||||
// PlatformFont virtual methods
|
||||
virtual bool isValidChar(const UTF16 ch) const;
|
||||
virtual bool isValidChar(const UTF8 *str) const;
|
||||
|
||||
inline virtual U32 getFontHeight() const
|
||||
{
|
||||
return mTextMetric.tmHeight;
|
||||
}
|
||||
|
||||
inline virtual U32 getFontBaseLine() const
|
||||
{
|
||||
return mTextMetric.tmAscent;
|
||||
}
|
||||
|
||||
virtual PlatformFont::CharInfo &getCharInfo(const UTF16 ch) const;
|
||||
virtual PlatformFont::CharInfo &getCharInfo(const UTF8 *str) const;
|
||||
|
||||
virtual bool create(const char *name, dsize_t size, U32 charset = TGE_ANSI_CHARSET);
|
||||
};
|
||||
|
||||
#endif // _WINFONT_H_
|
581
engine/platformWin32/winGL.cc
Executable file
581
engine/platformWin32/winGL.cc
Executable file
@ -0,0 +1,581 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// Torque Game Engine
|
||||
// Copyright (C) GarageGames.com, Inc.
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "platformWin32/platformWin32.h"
|
||||
#include "platformWin32/platformGL.h"
|
||||
#include "dgl/dgl.h"
|
||||
#include "platform/platformVideo.h"
|
||||
#include "core/unicode.h"
|
||||
|
||||
#include "console/console.h"
|
||||
#include "console/consoleTypes.h"
|
||||
|
||||
GLState gGLState;
|
||||
|
||||
bool gOpenGLDisablePT = false;
|
||||
bool gOpenGLDisableCVA = false;
|
||||
bool gOpenGLDisableTEC = false;
|
||||
bool gOpenGLDisableARBMT = false;
|
||||
bool gOpenGLDisableFC = false;
|
||||
bool gOpenGLDisableTCompress = false;
|
||||
bool gOpenGLNoEnvColor = false;
|
||||
float gOpenGLGammaCorrection = 0.5;
|
||||
bool gOpenGLNoDrawArraysAlpha = false;
|
||||
|
||||
//------------------------------------------------------------------
|
||||
//bind functions for each function prototype
|
||||
//------------------------------------------------------------------
|
||||
|
||||
//GL_EXT/ARB
|
||||
enum {
|
||||
ARB_multitexture = BIT(0),
|
||||
ARB_texture_compression = BIT(1),
|
||||
EXT_compiled_vertex_array = BIT(2),
|
||||
EXT_fog_coord = BIT(3),
|
||||
EXT_paletted_texture = BIT(4),
|
||||
NV_vertex_array_range = BIT(5),
|
||||
EXT_blend_color = BIT(6),
|
||||
EXT_blend_minmax = BIT(7)
|
||||
};
|
||||
|
||||
//WGL_ARB
|
||||
enum {
|
||||
WGL_ARB_extensions_string = BIT(0),
|
||||
WGL_EXT_swap_control = BIT(1),
|
||||
WGL_3DFX_gamma_control = BIT(2)
|
||||
};
|
||||
|
||||
|
||||
//------------------------------------------------------------------
|
||||
//create dummy functions and set real functions to dummies for:
|
||||
// -core GL
|
||||
// -core WGL
|
||||
// -WGL extensions
|
||||
//------------------------------------------------------------------
|
||||
|
||||
//defines...
|
||||
//-------------
|
||||
// we want to declare/define all GL functions here and set them all to a "stub"
|
||||
// function so that if they're called before they're initialized, they'll spew
|
||||
// some console spam to make it easier to debug. We also need to declare/define
|
||||
// a "dll" version, which will ALWAYS point to the function defined in the dll.
|
||||
// This for special functionality like wireframe, logging, and performance metrics
|
||||
// that will override the normal function and do some additional work. We'll make
|
||||
// the dll versions extern so that we can seperate out all the performance/logging
|
||||
// functionality to a seperate file to keep this one a little bit cleaner. So,
|
||||
// our macros look like this for the most part (although a lot uglier in practice):
|
||||
|
||||
// type name##_t(params) { console_warning; return ret; }
|
||||
// type name(params) = name##_t;
|
||||
// extern type dll##name(params = name##_t
|
||||
|
||||
#ifndef TORQUE_LIB
|
||||
|
||||
#define GL_FUNCTION(fn_type, fn_name, fn_args, fn_body) fn_type (APIENTRY fn_name##_t)fn_args \
|
||||
{ Con::printf("Could not load this GL function: %s", #fn_name); fn_body } \
|
||||
fn_type (APIENTRY * fn_name)fn_args = fn_name##_t; \
|
||||
extern fn_type (APIENTRY * dll##fn_name)fn_args = fn_name##_t;
|
||||
#define WGL_FUNCTION(fn_type, fn_name, fn_args, fn_body) fn_type (APIENTRY d##fn_name##_t)fn_args \
|
||||
{ Con::printf("Could not load this WGL function: %s", #fn_name); fn_body } \
|
||||
fn_type (APIENTRY * d##fn_name)fn_args = d##fn_name##_t; \
|
||||
extern fn_type (APIENTRY * dlld##fn_name)fn_args = d##fn_name##_t;
|
||||
#define WGLD3D_FUNCTION(fn_type, fn_name, fn_args, fn_body) fn_type (APIENTRY dwgl##fn_name##_t)fn_args \
|
||||
{ Con::printf("Could not load this WGLD3D function: wgl%s", #fn_name); fn_body } \
|
||||
fn_type (APIENTRY * dwgl##fn_name)fn_args = dwgl##fn_name##_t; \
|
||||
extern fn_type (APIENTRY * dlldwgl##fn_name)fn_args = dwgl##fn_name##_t;
|
||||
#define WGLEXT_FUNCTION(fn_type, fn_name, fn_args, fn_body) fn_type (APIENTRY d##fn_name##_t)fn_args \
|
||||
{ Con::printf("Could not load this WGLEXT function: %s", #fn_name); fn_body } \
|
||||
fn_type (APIENTRY * d##fn_name)fn_args = d##fn_name##_t;
|
||||
|
||||
#else
|
||||
|
||||
#define GL_FUNCTION(fn_type, fn_name, fn_args, fn_body) fn_type (APIENTRY fn_name##_t)fn_args \
|
||||
{ fn_body } \
|
||||
fn_type (APIENTRY * fn_name)fn_args = fn_name##_t; \
|
||||
extern fn_type (APIENTRY * dll##fn_name)fn_args = fn_name##_t;
|
||||
#define WGL_FUNCTION(fn_type, fn_name, fn_args, fn_body) fn_type (APIENTRY d##fn_name##_t)fn_args \
|
||||
{ fn_body } \
|
||||
fn_type (APIENTRY * d##fn_name)fn_args = d##fn_name##_t; \
|
||||
extern fn_type (APIENTRY * dlld##fn_name)fn_args = d##fn_name##_t;
|
||||
#define WGLD3D_FUNCTION(fn_type, fn_name, fn_args, fn_body) fn_type (APIENTRY dwgl##fn_name##_t)fn_args \
|
||||
{ fn_body } \
|
||||
fn_type (APIENTRY * dwgl##fn_name)fn_args = dwgl##fn_name##_t; \
|
||||
extern fn_type (APIENTRY * dlldwgl##fn_name)fn_args = dwgl##fn_name##_t;
|
||||
#define WGLEXT_FUNCTION(fn_type, fn_name, fn_args, fn_body) fn_type (APIENTRY d##fn_name##_t)fn_args \
|
||||
{ fn_body } \
|
||||
fn_type (APIENTRY * d##fn_name)fn_args = d##fn_name##_t;
|
||||
|
||||
#endif
|
||||
|
||||
//includes...
|
||||
#include "platform/GLCoreFunc.h"
|
||||
#include "platform/GLExtFunc.h"
|
||||
#include "platform/GLUFunc.h"
|
||||
#include "platformWin32/GLWinFunc.h"
|
||||
#include "platformWin32/GLWinExtFunc.h"
|
||||
|
||||
//undefs...
|
||||
#undef GL_FUNCTION
|
||||
#undef WGL_FUNCTION
|
||||
#undef WGLD3D_FUNCTION
|
||||
#undef WGLEXT_FUNCTION
|
||||
|
||||
// These functions won't be in the normal OGL dll, so don't give
|
||||
// errors about them because we know we'll be ok without them
|
||||
static bool isFnOk(const char* name)
|
||||
{
|
||||
if (dStrcmp(name, "glAvailableVertexBufferEXT") == 0 ||
|
||||
dStrcmp(name, "glAllocateVertexBufferEXT") == 0 ||
|
||||
dStrcmp(name, "glLockVertexBufferEXT") == 0 ||
|
||||
dStrcmp(name, "glUnlockVertexBufferEXT") == 0 ||
|
||||
dStrcmp(name, "glSetVertexBufferEXT") == 0 ||
|
||||
dStrcmp(name, "glOffsetVertexBufferEXT") == 0 ||
|
||||
dStrcmp(name, "glFillVertexBufferEXT") == 0 ||
|
||||
dStrcmp(name, "glFreeVertexBufferEXT") == 0)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------
|
||||
//bind functions for each function prototype
|
||||
//------------------------------------------------------------------
|
||||
static bool bindGLFunction( void *&fnAddress, const char *name )
|
||||
{
|
||||
void* addr = (void*)(GetProcAddress( winState.hinstOpenGL, name ));
|
||||
bool ok = (bool)addr;
|
||||
if( !ok )
|
||||
{
|
||||
if (!isFnOk(name))
|
||||
Con::errorf(ConsoleLogEntry::General, " Missing OpenGL function '%s'", name);
|
||||
else
|
||||
ok = true;
|
||||
}
|
||||
else
|
||||
fnAddress = addr;
|
||||
return ok;
|
||||
}
|
||||
|
||||
static bool bindGLUFunction( void *&fnAddress, const char *name )
|
||||
{
|
||||
void* addr = (void*)(GetProcAddress( winState.hinstGLU, name ));
|
||||
if( !addr )
|
||||
Con::errorf(ConsoleLogEntry::General, " Missing GLU function '%s'", name);
|
||||
else
|
||||
fnAddress = addr;
|
||||
return (addr != NULL);
|
||||
}
|
||||
|
||||
static bool bindEXTFunction( void *&fnAddress, const char *name )
|
||||
{
|
||||
void* addr = (void*)(dwglGetProcAddress( name ));
|
||||
if( !addr )
|
||||
Con::errorf(ConsoleLogEntry::General, " Missing OpenGL extension '%s'", name);
|
||||
else
|
||||
fnAddress = addr;
|
||||
return (addr != NULL);
|
||||
}
|
||||
|
||||
static bool bindWGLFunction( void *&fnAddress, const char *name )
|
||||
{
|
||||
void* addr = (void*)(GetProcAddress( winState.hinstOpenGL, name ));
|
||||
if( !addr )
|
||||
Con::errorf(ConsoleLogEntry::General, " Missing WGL function '%s'", name);
|
||||
else
|
||||
fnAddress = addr;
|
||||
return (addr != NULL);
|
||||
}
|
||||
|
||||
static bool bindWGLEXTFunction( void *&fnAddress, const char *name )
|
||||
{
|
||||
void* addr = (void*)(dwglGetProcAddress( name ));
|
||||
if( !addr )
|
||||
Con::errorf(ConsoleLogEntry::General, " Missing WGLEXT function '%s'", name);
|
||||
else
|
||||
fnAddress = addr;
|
||||
|
||||
return (addr != NULL);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------
|
||||
//binds for each function group
|
||||
//------------------------------------------------------------------
|
||||
static bool bindGLFunctions()
|
||||
{
|
||||
bool result = true;
|
||||
#define GL_FUNCTION(fn_return, fn_name, fn_args, fn_value) \
|
||||
result &= bindGLFunction( *(void**)&dll##fn_name, #fn_name); \
|
||||
fn_name = dll##fn_name;
|
||||
#include "platform/GLCoreFunc.h"
|
||||
#undef GL_FUNCTION
|
||||
return result;
|
||||
}
|
||||
|
||||
static bool bindGLUFunctions()
|
||||
{
|
||||
bool result = true;
|
||||
#define GL_FUNCTION(fn_return, fn_name, fn_args, fn_value) \
|
||||
result &= bindGLUFunction( *(void**)&dll##fn_name, #fn_name); \
|
||||
fn_name = dll##fn_name;
|
||||
#include "platform/GLUFunc.h"
|
||||
#undef GL_FUNCTION
|
||||
return result;
|
||||
}
|
||||
|
||||
static bool bindEXTFunctions(U32 extMask)
|
||||
{
|
||||
bool result = true;
|
||||
|
||||
#define GL_GROUP_BEGIN( flag ) \
|
||||
if( extMask & flag ) {
|
||||
#define GL_GROUP_END() }
|
||||
|
||||
#define GL_FUNCTION(fn_return, fn_name, fn_args, fn_value) \
|
||||
result &= bindEXTFunction( *(void**)&dll##fn_name, #fn_name); \
|
||||
fn_name = dll##fn_name;
|
||||
#include "platform/GLExtFunc.h"
|
||||
#undef GL_FUNCTION
|
||||
|
||||
#undef GL_GROUP_BEGIN
|
||||
#undef GL_GROUP_END
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static bool bindWGLFunctions(const char* prefix)
|
||||
{
|
||||
//ugh... the stupid D3D wrapper prefixes some functions
|
||||
//with either wd3d or wgl, so we have to account for that
|
||||
static char buff[200];
|
||||
bool result = true;
|
||||
#define WGLD3D_FUNCTION(fn_return, fn_name, fn_args, fn_value) \
|
||||
dSprintf(buff, 200, "%s%s", prefix, #fn_name); \
|
||||
result &= bindWGLFunction( *(void**)&dlldwgl##fn_name, buff); \
|
||||
dwgl##fn_name = dlldwgl##fn_name;
|
||||
#define WGL_FUNCTION(fn_return, fn_name, fn_args, fn_valud) \
|
||||
result &= bindWGLFunction( *(void**)&dlld##fn_name, #fn_name); \
|
||||
d##fn_name = dlld##fn_name;
|
||||
#include "platformWin32/GLWinFunc.h"
|
||||
#undef WGLD3D_FUNCTION
|
||||
#undef WGL_FUNCTION
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static bool bindWGLEXTFunctions(U32 extMask)
|
||||
{
|
||||
bool result = true;
|
||||
|
||||
#define WGL_GROUP_BEGIN( flag ) \
|
||||
if( extMask & flag ) {
|
||||
#define WGL_GROUP_END() }
|
||||
|
||||
#define WGLEXT_FUNCTION(fn_return, fn_name, fn_args, fn_value) result &= bindWGLEXTFunction( *(void**)&d##fn_name, #fn_name);
|
||||
#include "platformWin32/GLWinExtFunc.h"
|
||||
#undef WGLEXT_FUNCTION
|
||||
|
||||
#undef WGL_GROUP_BEGIN
|
||||
#undef WGL_GROUP_END
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------
|
||||
//unbind functions
|
||||
//------------------------------------------------------------------
|
||||
|
||||
//GL core, GL_EXT/ARB, and GLU can all be done in one shot
|
||||
static void unbindGLFunctions()
|
||||
{
|
||||
#define GL_FUNCTION(fn_type, fn_name, fn_args, fn_body) fn_name = dll##fn_name = fn_name##_t;
|
||||
#include "platform/GLCoreFunc.h"
|
||||
#include "platform/GLExtFunc.h"
|
||||
#include "platform/GLUFunc.h"
|
||||
#undef GL_FUNCTION
|
||||
}
|
||||
|
||||
static void unbindWGLFunctions()
|
||||
{
|
||||
#define WGL_FUNCTION(fn_type, fn_name, fn_args, fn_body) d##fn_name = dlld##fn_name = d##fn_name##_t;
|
||||
#define WGLD3D_FUNCTION(fn_type, fn_name, fn_args, fn_body) dwgl##fn_name = dlldwgl##fn_name = dwgl##fn_name##_t;
|
||||
#include "platformWin32/GLWinFunc.h"
|
||||
#undef WGLD3D_FUNCTION
|
||||
#undef WGL_FUNCTION
|
||||
}
|
||||
|
||||
static void unbindWGLEXTFunctions()
|
||||
{
|
||||
#define WGLEXT_FUNCTION(fn_type, fn_name, fn_args, fn_body) d##fn_name = d##fn_name##_t;
|
||||
#include "platformWin32/GLWinExtFunc.h"
|
||||
#undef WGLEXT_FUNCTION
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------
|
||||
// GL_Shutdown - unbind all functions and unload libraries
|
||||
//------------------------------------------------------------------
|
||||
void GL_Shutdown( void )
|
||||
{
|
||||
if ( winState.hinstOpenGL )
|
||||
FreeLibrary( winState.hinstOpenGL );
|
||||
winState.hinstOpenGL = NULL;
|
||||
|
||||
if ( winState.hinstGLU )
|
||||
FreeLibrary( winState.hinstGLU );
|
||||
winState.hinstGLU = NULL;
|
||||
|
||||
unbindGLFunctions(); //we can do GL, GLU, and EXTs in the same function
|
||||
unbindWGLFunctions();//these have to be seperate
|
||||
unbindWGLEXTFunctions();
|
||||
|
||||
gGLState.suppSwapInterval = false;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
// GL_Init - load OpenGL library and bind core GL/GLU/WGL functions
|
||||
//---------------------------------------------------------
|
||||
bool GL_Init( const char *dllname_gl, const char *dllname_glu )
|
||||
{
|
||||
if ( winState.hinstOpenGL && winState.hinstGLU)
|
||||
return true;
|
||||
|
||||
#ifdef UNICODE
|
||||
UTF16 dn_gl[1024], dn_glu[1024];
|
||||
convertUTF8toUTF16((UTF8 *)dllname_gl, dn_gl, sizeof(dn_gl));
|
||||
convertUTF8toUTF16((UTF8 *)dllname_glu, dn_glu, sizeof(dn_glu));
|
||||
#endif
|
||||
// Load OpenGL DLL
|
||||
if (!winState.hinstOpenGL)
|
||||
{
|
||||
#ifdef UNICODE
|
||||
if ( ( winState.hinstOpenGL = LoadLibrary( dn_gl ) ) == 0 )
|
||||
#else
|
||||
if ( ( winState.hinstOpenGL = LoadLibrary( dllname_gl ) ) == 0 )
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
// Load OpenGL GLU DLL
|
||||
if ( !winState.hinstGLU )
|
||||
{
|
||||
#ifdef UNICODE
|
||||
if ( ( winState.hinstGLU = LoadLibrary( dn_glu ) ) == 0 )
|
||||
#else
|
||||
if ( ( winState.hinstGLU = LoadLibrary( dllname_glu ) ) == 0 )
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!bindGLFunctions())
|
||||
Con::errorf("You are missing some OpenGL functions. That's bad.");
|
||||
if (!bindGLUFunctions())
|
||||
Con::errorf("You are missing some GLU functions. That's bad.");
|
||||
// these will have already been bound thru the OGL version
|
||||
if (dStrstr(dllname_gl, "d3d") == NULL)
|
||||
{
|
||||
if (!bindWGLFunctions("wgl"))
|
||||
Con::errorf("You are missing some WGL Functions. That's REALLY bad.");
|
||||
}
|
||||
else
|
||||
if (!bindWGLFunctions("wd3d"))
|
||||
Con::errorf("You are missing some WGL Functions. That's REALLY bad.");
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
//---------------------------------------------------------
|
||||
// GL_EXT_Init - Initialize all GL/WGL extensions
|
||||
//---------------------------------------------------------
|
||||
bool GL_EXT_Init( )
|
||||
{
|
||||
// Load extensions...
|
||||
//
|
||||
const char* pExtString = reinterpret_cast<const char*>(glGetString(GL_EXTENSIONS));
|
||||
gGLState.primMode = 0;
|
||||
U32 extBitMask = 0;
|
||||
|
||||
// GL_EXT_paletted_texture
|
||||
if (pExtString && dStrstr(pExtString, (const char*)"GL_EXT_paletted_texture") != NULL)
|
||||
{
|
||||
extBitMask |= EXT_paletted_texture;
|
||||
gGLState.suppPalettedTexture = true;
|
||||
}
|
||||
else
|
||||
gGLState.suppPalettedTexture = false;
|
||||
|
||||
// EXT_compiled_vertex_array
|
||||
if (pExtString && dStrstr(pExtString, (const char*)"GL_EXT_compiled_vertex_array") != NULL)
|
||||
{
|
||||
extBitMask |= EXT_compiled_vertex_array;
|
||||
gGLState.suppLockedArrays = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
gGLState.suppLockedArrays = false;
|
||||
}
|
||||
|
||||
// ARB_multitexture
|
||||
if (pExtString && dStrstr(pExtString, (const char*)"GL_ARB_multitexture") != NULL)
|
||||
{
|
||||
extBitMask |= ARB_multitexture;
|
||||
gGLState.suppARBMultitexture = true;
|
||||
} else {
|
||||
gGLState.suppARBMultitexture = false;
|
||||
}
|
||||
|
||||
// EXT_blend_color
|
||||
if(pExtString && dStrstr(pExtString, (const char*)"GL_EXT_blend_color") != NULL)
|
||||
{
|
||||
extBitMask |= EXT_blend_color;
|
||||
gGLState.suppEXTblendcolor = true;
|
||||
} else {
|
||||
gGLState.suppEXTblendcolor = false;
|
||||
}
|
||||
|
||||
// EXT_blend_minmax
|
||||
if(pExtString && dStrstr(pExtString, (const char*)"GL_EXT_blend_minmax") != NULL)
|
||||
{
|
||||
extBitMask |= EXT_blend_color;
|
||||
gGLState.suppEXTblendminmax = true;
|
||||
} else {
|
||||
gGLState.suppEXTblendminmax = false;
|
||||
}
|
||||
|
||||
// EXT_fog_coord
|
||||
if (pExtString && dStrstr(pExtString, (const char*)"GL_EXT_fog_coord") != NULL)
|
||||
{
|
||||
extBitMask |= EXT_fog_coord;
|
||||
gGLState.suppFogCoord = true;
|
||||
} else {
|
||||
gGLState.suppFogCoord = false;
|
||||
}
|
||||
|
||||
// EXT_texture_compression_s3tc
|
||||
if (pExtString && dStrstr(pExtString, (const char*)"GL_EXT_texture_compression_s3tc") != NULL)
|
||||
gGLState.suppS3TC = true;
|
||||
else
|
||||
gGLState.suppS3TC = false;
|
||||
|
||||
// ARB_texture_compression
|
||||
if (pExtString && dStrstr(pExtString, (const char*)"GL_ARB_texture_compression") != NULL)
|
||||
{
|
||||
extBitMask |= ARB_texture_compression;
|
||||
gGLState.suppTextureCompression = true;
|
||||
} else {
|
||||
gGLState.suppTextureCompression = false;
|
||||
}
|
||||
|
||||
// NV_vertex_array_range
|
||||
if (pExtString && dStrstr(pExtString, (const char*)"NV_vertex_array_range") != NULL)
|
||||
{
|
||||
extBitMask |= NV_vertex_array_range;
|
||||
gGLState.suppVertexArrayRange = true;
|
||||
}
|
||||
else
|
||||
gGLState.suppVertexArrayRange = false;
|
||||
|
||||
// 3DFX_texture_compression_FXT1
|
||||
if (pExtString && dStrstr(pExtString, (const char*)"3DFX_texture_compression_FXT1") != NULL)
|
||||
gGLState.suppFXT1 = true;
|
||||
else
|
||||
gGLState.suppFXT1 = false;
|
||||
|
||||
if (!bindEXTFunctions(extBitMask))
|
||||
Con::warnf("You are missing some OpenGL Extensions. This is bad.");
|
||||
|
||||
// Binary states, i.e., no supporting functions
|
||||
// EXT_packed_pixels
|
||||
// EXT_texture_env_combine
|
||||
//
|
||||
// dhc note: a number of these can have multiple matching 'versions', private, ext, and arb.
|
||||
gGLState.suppPackedPixels = pExtString? (dStrstr(pExtString, (const char*)"GL_EXT_packed_pixels") != NULL) : false;
|
||||
gGLState.suppTextureEnvCombine = pExtString? (dStrstr(pExtString, (const char*)"GL_EXT_texture_env_combine") != NULL) : false;
|
||||
gGLState.suppEdgeClamp = pExtString? (dStrstr(pExtString, (const char*)"GL_EXT_texture_edge_clamp") != NULL) : false;
|
||||
gGLState.suppEdgeClamp |= pExtString? (dStrstr(pExtString, (const char*)"GL_SGIS_texture_edge_clamp") != NULL) : false;
|
||||
gGLState.suppTexEnvAdd = pExtString? (dStrstr(pExtString, (const char*)"GL_ARB_texture_env_add") != NULL) : false;
|
||||
gGLState.suppTexEnvAdd |= pExtString? (dStrstr(pExtString, (const char*)"GL_EXT_texture_env_add") != NULL) : false;
|
||||
|
||||
// Anisotropic filtering
|
||||
gGLState.suppTexAnisotropic = pExtString? (dStrstr(pExtString, (const char*)"GL_EXT_texture_filter_anisotropic") != NULL) : false;
|
||||
if (gGLState.suppTexAnisotropic)
|
||||
glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &gGLState.maxAnisotropy);
|
||||
if (gGLState.suppARBMultitexture)
|
||||
glGetIntegerv(GL_MAX_TEXTURE_UNITS_ARB, &gGLState.maxTextureUnits);
|
||||
else
|
||||
gGLState.maxTextureUnits = 1;
|
||||
|
||||
//----------------------
|
||||
|
||||
//WGL extensions....
|
||||
U32 wglExtMask = 0;
|
||||
|
||||
// Swap interval
|
||||
if (pExtString && dStrstr(pExtString, (const char*)"WGL_EXT_swap_control") != NULL)
|
||||
{
|
||||
wglExtMask |= WGL_EXT_swap_control;
|
||||
gGLState.suppSwapInterval = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
gGLState.suppSwapInterval = false;
|
||||
}
|
||||
|
||||
if (!bindWGLEXTFunctions(wglExtMask))
|
||||
{
|
||||
Con::warnf("You are missing some WGLEXT Functions. That's possibly VERY bad.");
|
||||
}
|
||||
|
||||
Con::printf("OpenGL Init: Enabled Extensions");
|
||||
if (gGLState.suppARBMultitexture) Con::printf(" ARB_multitexture (Max Texture Units: %d)", gGLState.maxTextureUnits);
|
||||
if (gGLState.suppEXTblendcolor) Con::printf(" EXT_blend_color");
|
||||
if (gGLState.suppEXTblendminmax) Con::printf(" EXT_blend_minmax");
|
||||
if (gGLState.suppPalettedTexture) Con::printf(" EXT_paletted_texture");
|
||||
if (gGLState.suppLockedArrays) Con::printf(" EXT_compiled_vertex_array");
|
||||
if (gGLState.suppVertexArrayRange) Con::printf(" NV_vertex_array_range");
|
||||
if (gGLState.suppTextureEnvCombine) Con::printf(" EXT_texture_env_combine");
|
||||
if (gGLState.suppPackedPixels) Con::printf(" EXT_packed_pixels");
|
||||
if (gGLState.suppFogCoord) Con::printf(" EXT_fog_coord");
|
||||
if (gGLState.suppTextureCompression) Con::printf(" ARB_texture_compression");
|
||||
if (gGLState.suppS3TC) Con::printf(" EXT_texture_compression_s3tc");
|
||||
if (gGLState.suppFXT1) Con::printf(" 3DFX_texture_compression_FXT1");
|
||||
if (gGLState.suppTexEnvAdd) Con::printf(" (ARB|EXT)_texture_env_add");
|
||||
if (gGLState.suppTexAnisotropic) Con::printf(" EXT_texture_filter_anisotropic (Max anisotropy: %g)", gGLState.maxAnisotropy);
|
||||
if (gGLState.suppSwapInterval) Con::printf(" WGL_EXT_swap_control");
|
||||
|
||||
Con::warnf("OpenGL Init: Disabled Extensions");
|
||||
if (!gGLState.suppARBMultitexture) Con::warnf(" ARB_multitexture");
|
||||
if (!gGLState.suppEXTblendcolor) Con::warnf(" EXT_blend_color");
|
||||
if (!gGLState.suppEXTblendminmax) Con::warnf(" EXT_blend_minmax");
|
||||
if (!gGLState.suppPalettedTexture) Con::warnf(" EXT_paletted_texture");
|
||||
if (!gGLState.suppLockedArrays) Con::warnf(" EXT_compiled_vertex_array");
|
||||
if (!gGLState.suppVertexArrayRange) Con::warnf(" NV_vertex_array_range");
|
||||
if (!gGLState.suppTextureEnvCombine) Con::warnf(" EXT_texture_env_combine");
|
||||
if (!gGLState.suppPackedPixels) Con::warnf(" EXT_packed_pixels");
|
||||
if (!gGLState.suppFogCoord) Con::warnf(" EXT_fog_coord");
|
||||
if (!gGLState.suppTextureCompression) Con::warnf(" ARB_texture_compression");
|
||||
if (!gGLState.suppS3TC) Con::warnf(" EXT_texture_compression_s3tc");
|
||||
if (!gGLState.suppFXT1) Con::warnf(" 3DFX_texture_compression_FXT1");
|
||||
if (!gGLState.suppTexEnvAdd) Con::warnf(" (ARB|EXT)_texture_env_add");
|
||||
if (!gGLState.suppTexAnisotropic) Con::warnf(" EXT_texture_filter_anisotropic");
|
||||
if (!gGLState.suppSwapInterval) Con::warnf(" WGL_EXT_swap_control");
|
||||
Con::printf("");
|
||||
|
||||
// Set some console variables:
|
||||
Con::setBoolVariable( "$FogCoordSupported", gGLState.suppFogCoord );
|
||||
Con::setBoolVariable( "$TextureCompressionSupported", gGLState.suppTextureCompression );
|
||||
Con::setBoolVariable( "$AnisotropySupported", gGLState.suppTexAnisotropic );
|
||||
Con::setBoolVariable( "$PalettedTextureSupported", gGLState.suppPalettedTexture );
|
||||
Con::setBoolVariable( "$SwapIntervalSupported", gGLState.suppSwapInterval );
|
||||
|
||||
if (!gGLState.suppPalettedTexture && Con::getBoolVariable("$pref::OpenGL::forcePalettedTexture",false))
|
||||
{
|
||||
Con::setBoolVariable("$pref::OpenGL::forcePalettedTexture", false);
|
||||
Con::setBoolVariable("$pref::OpenGL::force16BitTexture", true);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
2824
engine/platformWin32/winGLSpecial.cc
Executable file
2824
engine/platformWin32/winGLSpecial.cc
Executable file
File diff suppressed because it is too large
Load Diff
825
engine/platformWin32/winInput.cc
Executable file
825
engine/platformWin32/winInput.cc
Executable file
@ -0,0 +1,825 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// Torque Game Engine
|
||||
// Copyright (C) GarageGames.com, Inc.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "platformWin32/platformWin32.h"
|
||||
#include "platform/platformInput.h"
|
||||
#include "platform/platformVideo.h"
|
||||
#include "platformWin32/winDirectInput.h"
|
||||
#include "platform/event.h"
|
||||
#include "console/console.h"
|
||||
|
||||
#ifdef LOG_INPUT
|
||||
#include <time.h>
|
||||
#include <stdarg.h>
|
||||
#endif
|
||||
|
||||
// Static class variables:
|
||||
InputManager* Input::smManager;
|
||||
bool Input::smActive;
|
||||
bool Input::smLastKeyboardActivated;
|
||||
bool Input::smLastMouseActivated;
|
||||
bool Input::smLastJoystickActivated;
|
||||
|
||||
#ifdef LOG_INPUT
|
||||
static HANDLE gInputLog;
|
||||
#endif
|
||||
|
||||
static void fillAsciiTable();
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//
|
||||
// This function gets the standard ASCII code corresponding to our key code
|
||||
// and the existing modifier key state.
|
||||
//
|
||||
//------------------------------------------------------------------------------
|
||||
struct AsciiData
|
||||
{
|
||||
struct KeyData
|
||||
{
|
||||
U16 ascii;
|
||||
bool isDeadChar;
|
||||
};
|
||||
|
||||
KeyData upper;
|
||||
KeyData lower;
|
||||
KeyData goofy;
|
||||
};
|
||||
|
||||
|
||||
#define NUM_KEYS ( KEY_OEM_102 + 1 )
|
||||
#define KEY_FIRST KEY_ESCAPE
|
||||
static AsciiData AsciiTable[NUM_KEYS];
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void Input::init()
|
||||
{
|
||||
Con::printf( "Input Init:" );
|
||||
|
||||
destroy();
|
||||
|
||||
#ifdef LOG_INPUT
|
||||
struct tm* newTime;
|
||||
time_t aclock;
|
||||
time( &aclock );
|
||||
newTime = localtime( &aclock );
|
||||
asctime( newTime );
|
||||
|
||||
gInputLog = CreateFile( "input.log", GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL );
|
||||
log( "Input log opened at %s\n", asctime( newTime ) );
|
||||
#endif
|
||||
|
||||
smActive = false;
|
||||
smLastKeyboardActivated = true;
|
||||
smLastMouseActivated = true;
|
||||
smLastJoystickActivated = true;
|
||||
|
||||
OSVERSIONINFO OSVersionInfo;
|
||||
dMemset( &OSVersionInfo, 0, sizeof( OSVERSIONINFO ) );
|
||||
OSVersionInfo.dwOSVersionInfoSize = sizeof( OSVERSIONINFO );
|
||||
if ( GetVersionEx( &OSVersionInfo ) )
|
||||
{
|
||||
#ifdef LOG_INPUT
|
||||
log( "Operating System:\n" );
|
||||
switch ( OSVersionInfo.dwPlatformId )
|
||||
{
|
||||
case VER_PLATFORM_WIN32s:
|
||||
log( " Win32s on Windows 3.1 version %d.%d\n", OSVersionInfo.dwMajorVersion, OSVersionInfo.dwMinorVersion );
|
||||
break;
|
||||
|
||||
case VER_PLATFORM_WIN32_WINDOWS:
|
||||
log( " Windows 95 version %d.%d\n", OSVersionInfo.dwMajorVersion, OSVersionInfo.dwMinorVersion );
|
||||
log( " Build number %d\n", LOWORD( OSVersionInfo.dwBuildNumber ) );
|
||||
break;
|
||||
|
||||
case VER_PLATFORM_WIN32_NT:
|
||||
log( " WinNT version %d.%d\n", OSVersionInfo.dwMajorVersion, OSVersionInfo.dwMinorVersion );
|
||||
log( " Build number %d\n", OSVersionInfo.dwBuildNumber );
|
||||
break;
|
||||
}
|
||||
|
||||
if ( OSVersionInfo.szCSDVersion != NULL )
|
||||
log( " %s\n", OSVersionInfo.szCSDVersion );
|
||||
|
||||
log( "\n" );
|
||||
#endif
|
||||
|
||||
if ( !( OSVersionInfo.dwPlatformId == VER_PLATFORM_WIN32_NT && OSVersionInfo.dwMajorVersion < 5 ) )
|
||||
{
|
||||
smManager = new DInputManager;
|
||||
if ( !smManager->enable() )
|
||||
{
|
||||
Con::printf( " DirectInput not enabled." );
|
||||
delete smManager;
|
||||
smManager = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
DInputManager::init();
|
||||
Con::printf( " DirectInput enabled." );
|
||||
}
|
||||
}
|
||||
else
|
||||
Con::printf( " WinNT detected -- DirectInput not enabled." );
|
||||
}
|
||||
|
||||
fillAsciiTable();
|
||||
Con::printf( "" );
|
||||
|
||||
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
ConsoleFunction( isJoystickDetected, bool, 1, 1, "isJoystickDetected()" )
|
||||
{
|
||||
argc; argv;
|
||||
return( DInputDevice::joystickDetected() );
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
ConsoleFunction( getJoystickAxes, const char*, 2, 2, "getJoystickAxes( instance )" )
|
||||
{
|
||||
argc;
|
||||
DInputManager* mgr = dynamic_cast<DInputManager*>( Input::getManager() );
|
||||
if ( mgr )
|
||||
return( mgr->getJoystickAxesString( dAtoi( argv[1] ) ) );
|
||||
|
||||
return( "" );
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
static void fillAsciiTable()
|
||||
{
|
||||
#ifdef LOG_INPUT
|
||||
char buf[256];
|
||||
Input::log( "--- Filling the ASCII table! ---\n" );
|
||||
#endif
|
||||
|
||||
//HKL layout = GetKeyboardLayout( 0 );
|
||||
U8 state[256];
|
||||
U16 ascii[2];
|
||||
U32 dikCode, vKeyCode, keyCode;
|
||||
S32 result;
|
||||
|
||||
dMemset( &AsciiTable, 0, sizeof( AsciiTable ) );
|
||||
dMemset( &state, 0, sizeof( state ) );
|
||||
|
||||
for ( keyCode = KEY_FIRST; keyCode < NUM_KEYS; keyCode++ )
|
||||
{
|
||||
ascii[0] = ascii[1] = 0;
|
||||
dikCode = Key_to_DIK( keyCode );
|
||||
if ( dikCode )
|
||||
{
|
||||
//vKeyCode = MapVirtualKeyEx( dikCode, 1, layout );
|
||||
vKeyCode = MapVirtualKey( dikCode, 1 );
|
||||
#ifdef LOG_INPUT
|
||||
dSprintf( buf, sizeof( buf ), "KC: %#04X DK: %#04X VK: %#04X\n",
|
||||
keyCode, dikCode, vKeyCode );
|
||||
Input::log( buf );
|
||||
#endif
|
||||
|
||||
// Lower case:
|
||||
ascii[0] = ascii[1] = 0;
|
||||
//result = ToAsciiEx( vKeyCode, dikCode, state, ascii, 0, layout );
|
||||
result = ToAscii( vKeyCode, dikCode, state, ascii, 0 );
|
||||
#ifdef LOG_INPUT
|
||||
dSprintf( buf, sizeof( buf ), " LOWER- R: %d A[0]: %#06X A[1]: %#06X\n",
|
||||
result, ascii[0], ascii[1] );
|
||||
Input::log( buf );
|
||||
#endif
|
||||
if ( result == 2 )
|
||||
AsciiTable[keyCode].lower.ascii = ascii[1] ? ascii[1] : ( ascii[0] >> 8 );
|
||||
else if ( result == 1 )
|
||||
AsciiTable[keyCode].lower.ascii = ascii[0];
|
||||
else if ( result < 0 )
|
||||
{
|
||||
AsciiTable[keyCode].lower.ascii = ascii[0];
|
||||
AsciiTable[keyCode].lower.isDeadChar = true;
|
||||
// Need to clear the dead character from the keyboard layout:
|
||||
//ToAsciiEx( vKeyCode, dikCode, state, ascii, 0, layout );
|
||||
ToAscii( vKeyCode, dikCode, state, ascii, 0 );
|
||||
}
|
||||
|
||||
// Upper case:
|
||||
ascii[0] = ascii[1] = 0;
|
||||
state[VK_SHIFT] = 0x80;
|
||||
//result = ToAsciiEx( vKeyCode, dikCode, state, ascii, 0, layout );
|
||||
result = ToAscii( vKeyCode, dikCode, state, ascii, 0 );
|
||||
#ifdef LOG_INPUT
|
||||
dSprintf( buf, sizeof( buf ), " UPPER- R: %d A[0]: %#06X A[1]: %#06X\n",
|
||||
result, ascii[0], ascii[1] );
|
||||
Input::log( buf );
|
||||
#endif
|
||||
if ( result == 2 )
|
||||
AsciiTable[keyCode].upper.ascii = ascii[1] ? ascii[1] : ( ascii[0] >> 8 );
|
||||
else if ( result == 1 )
|
||||
AsciiTable[keyCode].upper.ascii = ascii[0];
|
||||
else if ( result < 0 )
|
||||
{
|
||||
AsciiTable[keyCode].upper.ascii = ascii[0];
|
||||
AsciiTable[keyCode].upper.isDeadChar = true;
|
||||
// Need to clear the dead character from the keyboard layout:
|
||||
//ToAsciiEx( vKeyCode, dikCode, state, ascii, 0, layout );
|
||||
ToAscii( vKeyCode, dikCode, state, ascii, 0 );
|
||||
}
|
||||
state[VK_SHIFT] = 0;
|
||||
|
||||
// Foreign mod case:
|
||||
ascii[0] = ascii[1] = 0;
|
||||
state[VK_CONTROL] = 0x80;
|
||||
state[VK_MENU] = 0x80;
|
||||
//result = ToAsciiEx( vKeyCode, dikCode, state, ascii, 0, layout );
|
||||
result = ToAscii( vKeyCode, dikCode, state, ascii, 0 );
|
||||
#ifdef LOG_INPUT
|
||||
dSprintf( buf, sizeof( buf ), " GOOFY- R: %d A[0]: %#06X A[1]: %#06X\n",
|
||||
result, ascii[0], ascii[1] );
|
||||
Input::log( buf );
|
||||
#endif
|
||||
if ( result == 2 )
|
||||
AsciiTable[keyCode].goofy.ascii = ascii[1] ? ascii[1] : ( ascii[0] >> 8 );
|
||||
else if ( result == 1 )
|
||||
AsciiTable[keyCode].goofy.ascii = ascii[0];
|
||||
else if ( result < 0 )
|
||||
{
|
||||
AsciiTable[keyCode].goofy.ascii = ascii[0];
|
||||
AsciiTable[keyCode].goofy.isDeadChar = true;
|
||||
// Need to clear the dead character from the keyboard layout:
|
||||
//ToAsciiEx( vKeyCode, dikCode, state, ascii, 0, layout );
|
||||
ToAscii( vKeyCode, dikCode, state, ascii, 0 );
|
||||
}
|
||||
state[VK_CONTROL] = 0;
|
||||
state[VK_MENU] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef LOG_INPUT
|
||||
Input::log( "--- Finished filling the ASCII table! ---\n\n" );
|
||||
#endif
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
U16 Input::getKeyCode( U16 asciiCode )
|
||||
{
|
||||
U16 keyCode = 0;
|
||||
U16 i;
|
||||
|
||||
// This is done three times so the lowerkey will always
|
||||
// be found first. Some foreign keyboards have duplicate
|
||||
// chars on some keys.
|
||||
for ( i = KEY_FIRST; i < NUM_KEYS && !keyCode; i++ )
|
||||
{
|
||||
if ( AsciiTable[i].lower.ascii == asciiCode )
|
||||
{
|
||||
keyCode = i;
|
||||
break;
|
||||
};
|
||||
}
|
||||
|
||||
for ( i = KEY_FIRST; i < NUM_KEYS && !keyCode; i++ )
|
||||
{
|
||||
if ( AsciiTable[i].upper.ascii == asciiCode )
|
||||
{
|
||||
keyCode = i;
|
||||
break;
|
||||
};
|
||||
}
|
||||
|
||||
for ( i = KEY_FIRST; i < NUM_KEYS && !keyCode; i++ )
|
||||
{
|
||||
if ( AsciiTable[i].goofy.ascii == asciiCode )
|
||||
{
|
||||
keyCode = i;
|
||||
break;
|
||||
};
|
||||
}
|
||||
|
||||
return( keyCode );
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
U16 Input::getAscii( U16 keyCode, KEY_STATE keyState )
|
||||
{
|
||||
if ( keyCode >= NUM_KEYS )
|
||||
return 0;
|
||||
|
||||
switch ( keyState )
|
||||
{
|
||||
case STATE_LOWER:
|
||||
return AsciiTable[keyCode].lower.ascii;
|
||||
case STATE_UPPER:
|
||||
return AsciiTable[keyCode].upper.ascii;
|
||||
case STATE_GOOFY:
|
||||
return AsciiTable[keyCode].goofy.ascii;
|
||||
default:
|
||||
return(0);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void Input::destroy()
|
||||
{
|
||||
#ifdef LOG_INPUT
|
||||
if ( gInputLog )
|
||||
{
|
||||
log( "*** CLOSING LOG ***\n" );
|
||||
CloseHandle( gInputLog );
|
||||
gInputLog = NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
if ( smManager && smManager->isEnabled() )
|
||||
{
|
||||
smManager->disable();
|
||||
delete smManager;
|
||||
smManager = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
bool Input::enable()
|
||||
{
|
||||
if ( smManager && !smManager->isEnabled() )
|
||||
return( smManager->enable() );
|
||||
|
||||
return( false );
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void Input::disable()
|
||||
{
|
||||
if ( smManager && smManager->isEnabled() )
|
||||
smManager->disable();
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
void Input::activate()
|
||||
{
|
||||
#ifdef UNICODE
|
||||
winState.imeHandle = ImmGetContext( winState.appWindow );
|
||||
ImmReleaseContext( winState.appWindow, winState.imeHandle );
|
||||
#endif
|
||||
|
||||
DInputDevice::resetModifierKeys();
|
||||
if ( !Con::getBoolVariable( "$enableDirectInput" ) )
|
||||
return;
|
||||
|
||||
if ( smManager && smManager->isEnabled() && !smActive )
|
||||
{
|
||||
Con::printf( "Activating DirectInput..." );
|
||||
#ifdef LOG_INPUT
|
||||
Input::log( "Activating DirectInput...\n" );
|
||||
#endif
|
||||
smActive = true;
|
||||
DInputManager* dInputManager = dynamic_cast<DInputManager*>( smManager );
|
||||
if ( dInputManager )
|
||||
{
|
||||
if ( dInputManager->isKeyboardEnabled() && smLastKeyboardActivated )
|
||||
dInputManager->activateKeyboard();
|
||||
|
||||
if ( Video::isFullScreen() )
|
||||
{
|
||||
// DirectInput Mouse Hook-Up:
|
||||
if ( dInputManager->isMouseEnabled() && smLastMouseActivated )
|
||||
dInputManager->activateMouse();
|
||||
}
|
||||
else
|
||||
dInputManager->deactivateMouse();
|
||||
|
||||
if ( dInputManager->isJoystickEnabled() && smLastJoystickActivated )
|
||||
dInputManager->activateJoystick();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void Input::deactivate()
|
||||
{
|
||||
if ( smManager && smManager->isEnabled() && smActive )
|
||||
{
|
||||
#ifdef LOG_INPUT
|
||||
Input::log( "Deactivating DirectInput...\n" );
|
||||
#endif
|
||||
DInputManager* dInputManager = dynamic_cast<DInputManager*>( smManager );
|
||||
|
||||
if ( dInputManager )
|
||||
{
|
||||
smLastKeyboardActivated = dInputManager->isKeyboardActive();
|
||||
smLastMouseActivated = dInputManager->isMouseActive();
|
||||
smLastJoystickActivated = dInputManager->isJoystickActive();
|
||||
|
||||
dInputManager->deactivateKeyboard();
|
||||
dInputManager->deactivateMouse();
|
||||
dInputManager->deactivateJoystick();
|
||||
}
|
||||
|
||||
smActive = false;
|
||||
Con::printf( "DirectInput deactivated." );
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void Input::reactivate()
|
||||
{
|
||||
// This is soo hacky...
|
||||
SetForegroundWindow( winState.appWindow );
|
||||
PostMessage( winState.appWindow, WM_ACTIVATE, WA_ACTIVE, NULL );
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
bool Input::isEnabled()
|
||||
{
|
||||
if ( smManager )
|
||||
return smManager->isEnabled();
|
||||
return false;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
bool Input::isActive()
|
||||
{
|
||||
return smActive;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void Input::process()
|
||||
{
|
||||
if ( smManager && smManager->isEnabled() && smActive )
|
||||
smManager->process();
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
InputManager* Input::getManager()
|
||||
{
|
||||
return( smManager );
|
||||
}
|
||||
|
||||
#ifdef LOG_INPUT
|
||||
//------------------------------------------------------------------------------
|
||||
void Input::log( const char* format, ... )
|
||||
{
|
||||
if ( !gInputLog )
|
||||
return;
|
||||
|
||||
va_list argptr;
|
||||
va_start( argptr, format );
|
||||
|
||||
char buffer[512];
|
||||
dVsprintf( buffer, 511, format, argptr );
|
||||
DWORD bytes;
|
||||
WriteFile( gInputLog, buffer, dStrlen( buffer ), &bytes, NULL );
|
||||
|
||||
va_end( argptr );
|
||||
}
|
||||
|
||||
ConsoleFunction( inputLog, void, 2, 2, "inputLog( string )" )
|
||||
{
|
||||
argc;
|
||||
Input::log( "%s\n", argv[1] );
|
||||
}
|
||||
#endif // LOG_INPUT
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//------------------------------------------------------------------------------
|
||||
static U8 VcodeRemap[256] =
|
||||
{
|
||||
0, // 0x00
|
||||
0, // 0x01 VK_LBUTTON
|
||||
0, // 0x02 VK_RBUTTON
|
||||
0, // 0x03 VK_CANCEL
|
||||
0, // 0x04 VK_MBUTTON
|
||||
0, // 0x05
|
||||
0, // 0x06
|
||||
0, // 0x07
|
||||
KEY_BACKSPACE, // 0x08 VK_BACK
|
||||
KEY_TAB, // 0x09 VK_TAB
|
||||
0, // 0x0A
|
||||
0, // 0x0B
|
||||
0, // 0x0C VK_CLEAR
|
||||
KEY_RETURN, // 0x0D VK_RETURN
|
||||
0, // 0x0E
|
||||
0, // 0x0F
|
||||
KEY_SHIFT, // 0x10 VK_SHIFT
|
||||
KEY_CONTROL, // 0x11 VK_CONTROL
|
||||
KEY_ALT, // 0x12 VK_MENU
|
||||
KEY_PAUSE, // 0x13 VK_PAUSE
|
||||
KEY_CAPSLOCK, // 0x14 VK_CAPITAL
|
||||
0, // 0x15 VK_KANA, VK_HANGEUL, VK_HANGUL
|
||||
0, // 0x16
|
||||
0, // 0x17 VK_JUNJA
|
||||
0, // 0x18 VK_FINAL
|
||||
0, // 0x19 VK_HANJA, VK_KANJI
|
||||
0, // 0x1A
|
||||
KEY_ESCAPE, // 0x1B VK_ESCAPE
|
||||
|
||||
0, // 0x1C VK_CONVERT
|
||||
0, // 0x1D VK_NONCONVERT
|
||||
0, // 0x1E VK_ACCEPT
|
||||
0, // 0x1F VK_MODECHANGE
|
||||
|
||||
KEY_SPACE, // 0x20 VK_SPACE
|
||||
KEY_PAGE_UP, // 0x21 VK_PRIOR
|
||||
KEY_PAGE_DOWN, // 0x22 VK_NEXT
|
||||
KEY_END, // 0x23 VK_END
|
||||
KEY_HOME, // 0x24 VK_HOME
|
||||
KEY_LEFT, // 0x25 VK_LEFT
|
||||
KEY_UP, // 0x26 VK_UP
|
||||
KEY_RIGHT, // 0x27 VK_RIGHT
|
||||
KEY_DOWN, // 0x28 VK_DOWN
|
||||
0, // 0x29 VK_SELECT
|
||||
KEY_PRINT, // 0x2A VK_PRINT
|
||||
0, // 0x2B VK_EXECUTE
|
||||
0, // 0x2C VK_SNAPSHOT
|
||||
KEY_INSERT, // 0x2D VK_INSERT
|
||||
KEY_DELETE, // 0x2E VK_DELETE
|
||||
KEY_HELP, // 0x2F VK_HELP
|
||||
|
||||
KEY_0, // 0x30 VK_0 VK_0 thru VK_9 are the same as ASCII '0' thru '9' (// 0x30 - // 0x39)
|
||||
KEY_1, // 0x31 VK_1
|
||||
KEY_2, // 0x32 VK_2
|
||||
KEY_3, // 0x33 VK_3
|
||||
KEY_4, // 0x34 VK_4
|
||||
KEY_5, // 0x35 VK_5
|
||||
KEY_6, // 0x36 VK_6
|
||||
KEY_7, // 0x37 VK_7
|
||||
KEY_8, // 0x38 VK_8
|
||||
KEY_9, // 0x39 VK_9
|
||||
0, // 0x3A
|
||||
0, // 0x3B
|
||||
0, // 0x3C
|
||||
0, // 0x3D
|
||||
0, // 0x3E
|
||||
0, // 0x3F
|
||||
0, // 0x40
|
||||
|
||||
KEY_A, // 0x41 VK_A VK_A thru VK_Z are the same as ASCII 'A' thru 'Z' (// 0x41 - // 0x5A)
|
||||
KEY_B, // 0x42 VK_B
|
||||
KEY_C, // 0x43 VK_C
|
||||
KEY_D, // 0x44 VK_D
|
||||
KEY_E, // 0x45 VK_E
|
||||
KEY_F, // 0x46 VK_F
|
||||
KEY_G, // 0x47 VK_G
|
||||
KEY_H, // 0x48 VK_H
|
||||
KEY_I, // 0x49 VK_I
|
||||
KEY_J, // 0x4A VK_J
|
||||
KEY_K, // 0x4B VK_K
|
||||
KEY_L, // 0x4C VK_L
|
||||
KEY_M, // 0x4D VK_M
|
||||
KEY_N, // 0x4E VK_N
|
||||
KEY_O, // 0x4F VK_O
|
||||
KEY_P, // 0x50 VK_P
|
||||
KEY_Q, // 0x51 VK_Q
|
||||
KEY_R, // 0x52 VK_R
|
||||
KEY_S, // 0x53 VK_S
|
||||
KEY_T, // 0x54 VK_T
|
||||
KEY_U, // 0x55 VK_U
|
||||
KEY_V, // 0x56 VK_V
|
||||
KEY_W, // 0x57 VK_W
|
||||
KEY_X, // 0x58 VK_X
|
||||
KEY_Y, // 0x59 VK_Y
|
||||
KEY_Z, // 0x5A VK_Z
|
||||
|
||||
|
||||
KEY_WIN_LWINDOW, // 0x5B VK_LWIN
|
||||
KEY_WIN_RWINDOW, // 0x5C VK_RWIN
|
||||
KEY_WIN_APPS, // 0x5D VK_APPS
|
||||
0, // 0x5E
|
||||
0, // 0x5F
|
||||
|
||||
KEY_NUMPAD0, // 0x60 VK_NUMPAD0
|
||||
KEY_NUMPAD1, // 0x61 VK_NUMPAD1
|
||||
KEY_NUMPAD2, // 0x62 VK_NUMPAD2
|
||||
KEY_NUMPAD3, // 0x63 VK_NUMPAD3
|
||||
KEY_NUMPAD4, // 0x64 VK_NUMPAD4
|
||||
KEY_NUMPAD5, // 0x65 VK_NUMPAD5
|
||||
KEY_NUMPAD6, // 0x66 VK_NUMPAD6
|
||||
KEY_NUMPAD7, // 0x67 VK_NUMPAD7
|
||||
KEY_NUMPAD8, // 0x68 VK_NUMPAD8
|
||||
KEY_NUMPAD9, // 0x69 VK_NUMPAD9
|
||||
KEY_MULTIPLY, // 0x6A VK_MULTIPLY
|
||||
KEY_ADD, // 0x6B VK_ADD
|
||||
KEY_SEPARATOR, // 0x6C VK_SEPARATOR
|
||||
KEY_SUBTRACT, // 0x6D VK_SUBTRACT
|
||||
KEY_DECIMAL, // 0x6E VK_DECIMAL
|
||||
KEY_DIVIDE, // 0x6F VK_DIVIDE
|
||||
KEY_F1, // 0x70 VK_F1
|
||||
KEY_F2, // 0x71 VK_F2
|
||||
KEY_F3, // 0x72 VK_F3
|
||||
KEY_F4, // 0x73 VK_F4
|
||||
KEY_F5, // 0x74 VK_F5
|
||||
KEY_F6, // 0x75 VK_F6
|
||||
KEY_F7, // 0x76 VK_F7
|
||||
KEY_F8, // 0x77 VK_F8
|
||||
KEY_F9, // 0x78 VK_F9
|
||||
KEY_F10, // 0x79 VK_F10
|
||||
KEY_F11, // 0x7A VK_F11
|
||||
KEY_F12, // 0x7B VK_F12
|
||||
KEY_F13, // 0x7C VK_F13
|
||||
KEY_F14, // 0x7D VK_F14
|
||||
KEY_F15, // 0x7E VK_F15
|
||||
KEY_F16, // 0x7F VK_F16
|
||||
KEY_F17, // 0x80 VK_F17
|
||||
KEY_F18, // 0x81 VK_F18
|
||||
KEY_F19, // 0x82 VK_F19
|
||||
KEY_F20, // 0x83 VK_F20
|
||||
KEY_F21, // 0x84 VK_F21
|
||||
KEY_F22, // 0x85 VK_F22
|
||||
KEY_F23, // 0x86 VK_F23
|
||||
KEY_F24, // 0x87 VK_F24
|
||||
0, // 0x88
|
||||
0, // 0x89
|
||||
0, // 0x8A
|
||||
0, // 0x8B
|
||||
0, // 0x8C
|
||||
0, // 0x8D
|
||||
0, // 0x8E
|
||||
0, // 0x8F
|
||||
|
||||
KEY_NUMLOCK, // 0x90 VK_NUMLOCK
|
||||
KEY_SCROLLLOCK, // 0x91 VK_OEM_SCROLL
|
||||
0, // 0x92
|
||||
0, // 0x93
|
||||
0, // 0x94
|
||||
0, // 0x95
|
||||
0, // 0x96
|
||||
0, // 0x97
|
||||
0, // 0x98
|
||||
0, // 0x99
|
||||
0, // 0x9A
|
||||
0, // 0x9B
|
||||
0, // 0x9C
|
||||
0, // 0x9D
|
||||
0, // 0x9E
|
||||
0, // 0x9F
|
||||
|
||||
KEY_LSHIFT, // 0xA0 VK_LSHIFT
|
||||
KEY_RSHIFT, // 0xA1 VK_RSHIFT
|
||||
KEY_LCONTROL, // 0xA2 VK_LCONTROL
|
||||
KEY_RCONTROL, // 0xA3 VK_RCONTROL
|
||||
KEY_LALT, // 0xA4 VK_LMENU
|
||||
KEY_RALT, // 0xA5 VK_RMENU
|
||||
0, // 0xA6
|
||||
0, // 0xA7
|
||||
0, // 0xA8
|
||||
0, // 0xA9
|
||||
0, // 0xAA
|
||||
0, // 0xAB
|
||||
0, // 0xAC
|
||||
0, // 0xAD
|
||||
0, // 0xAE
|
||||
0, // 0xAF
|
||||
0, // 0xB0
|
||||
0, // 0xB1
|
||||
0, // 0xB2
|
||||
0, // 0xB3
|
||||
0, // 0xB4
|
||||
0, // 0xB5
|
||||
0, // 0xB6
|
||||
0, // 0xB7
|
||||
0, // 0xB8
|
||||
0, // 0xB9
|
||||
KEY_SEMICOLON, // 0xBA VK_OEM_1
|
||||
KEY_EQUALS, // 0xBB VK_OEM_PLUS
|
||||
KEY_COMMA, // 0xBC VK_OEM_COMMA
|
||||
KEY_MINUS, // 0xBD VK_OEM_MINUS
|
||||
KEY_PERIOD, // 0xBE VK_OEM_PERIOD
|
||||
KEY_SLASH, // 0xBF VK_OEM_2
|
||||
KEY_TILDE, // 0xC0 VK_OEM_3
|
||||
0, // 0xC1
|
||||
0, // 0xC2
|
||||
0, // 0xC3
|
||||
0, // 0xC4
|
||||
0, // 0xC5
|
||||
0, // 0xC6
|
||||
0, // 0xC7
|
||||
0, // 0xC8
|
||||
0, // 0xC9
|
||||
0, // 0xCA
|
||||
0, // 0xCB
|
||||
0, // 0xCC
|
||||
0, // 0xCD
|
||||
0, // 0xCE
|
||||
0, // 0xCF
|
||||
0, // 0xD0
|
||||
0, // 0xD1
|
||||
0, // 0xD2
|
||||
0, // 0xD3
|
||||
0, // 0xD4
|
||||
0, // 0xD5
|
||||
0, // 0xD6
|
||||
0, // 0xD7
|
||||
0, // 0xD8
|
||||
0, // 0xD9
|
||||
0, // 0xDA
|
||||
KEY_LBRACKET, // 0xDB VK_OEM_4
|
||||
KEY_BACKSLASH, // 0xDC VK_OEM_5
|
||||
KEY_RBRACKET, // 0xDD VK_OEM_6
|
||||
KEY_APOSTROPHE, // 0xDE VK_OEM_7
|
||||
0, // 0xDF VK_OEM_8
|
||||
0, // 0xE0
|
||||
0, // 0xE1 VK_OEM_AX AX key on Japanese AX keyboard
|
||||
KEY_OEM_102, // 0xE2 VK_OEM_102
|
||||
0, // 0xE3
|
||||
0, // 0xE4
|
||||
|
||||
0, // 0xE5 VK_PROCESSKEY
|
||||
|
||||
0, // 0xE6
|
||||
0, // 0xE7
|
||||
0, // 0xE8
|
||||
0, // 0xE9
|
||||
0, // 0xEA
|
||||
0, // 0xEB
|
||||
0, // 0xEC
|
||||
0, // 0xED
|
||||
0, // 0xEE
|
||||
0, // 0xEF
|
||||
|
||||
0, // 0xF0
|
||||
0, // 0xF1
|
||||
0, // 0xF2
|
||||
0, // 0xF3
|
||||
0, // 0xF4
|
||||
0, // 0xF5
|
||||
|
||||
0, // 0xF6 VK_ATTN
|
||||
0, // 0xF7 VK_CRSEL
|
||||
0, // 0xF8 VK_EXSEL
|
||||
0, // 0xF9 VK_EREOF
|
||||
0, // 0xFA VK_PLAY
|
||||
0, // 0xFB VK_ZOOM
|
||||
0, // 0xFC VK_NONAME
|
||||
0, // 0xFD VK_PA1
|
||||
0, // 0xFE VK_OEM_CLEAR
|
||||
0 // 0xFF
|
||||
};
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//
|
||||
// This function translates a virtual key code to our corresponding internal
|
||||
// key code using the preceding table.
|
||||
//
|
||||
//------------------------------------------------------------------------------
|
||||
U8 TranslateOSKeyCode(U8 vcode)
|
||||
{
|
||||
return VcodeRemap[vcode];
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Clipboard functions
|
||||
const char* Platform::getClipboard()
|
||||
{
|
||||
HGLOBAL hGlobal;
|
||||
LPVOID pGlobal;
|
||||
|
||||
//make sure we can access the clipboard
|
||||
if (!IsClipboardFormatAvailable(CF_TEXT))
|
||||
return "";
|
||||
if (!OpenClipboard(NULL))
|
||||
return "";
|
||||
|
||||
hGlobal = GetClipboardData(CF_TEXT);
|
||||
pGlobal = GlobalLock(hGlobal);
|
||||
S32 cbLength = strlen((char *)pGlobal);
|
||||
char *returnBuf = Con::getReturnBuffer(cbLength + 1);
|
||||
strcpy(returnBuf, (char *)pGlobal);
|
||||
returnBuf[cbLength] = '\0';
|
||||
GlobalUnlock(hGlobal);
|
||||
CloseClipboard();
|
||||
|
||||
//note - this function never returns NULL
|
||||
return returnBuf;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
bool Platform::setClipboard(const char *text)
|
||||
{
|
||||
if (!text)
|
||||
return false;
|
||||
|
||||
//make sure we can access the clipboard
|
||||
if (!OpenClipboard(NULL))
|
||||
return false;
|
||||
|
||||
S32 cbLength = strlen(text);
|
||||
|
||||
HGLOBAL hGlobal;
|
||||
LPVOID pGlobal;
|
||||
|
||||
hGlobal = GlobalAlloc(GHND, cbLength + 1);
|
||||
pGlobal = GlobalLock (hGlobal);
|
||||
|
||||
strcpy((char *)pGlobal, text);
|
||||
|
||||
GlobalUnlock(hGlobal);
|
||||
|
||||
EmptyClipboard();
|
||||
SetClipboardData(CF_TEXT, hGlobal);
|
||||
CloseClipboard();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
113
engine/platformWin32/winMath.cc
Executable file
113
engine/platformWin32/winMath.cc
Executable file
@ -0,0 +1,113 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// Torque Game Engine
|
||||
// Copyright (C) GarageGames.com, Inc.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "platform/platform.h"
|
||||
#include "console/console.h"
|
||||
#include "math/mMath.h"
|
||||
|
||||
|
||||
extern void mInstallLibrary_C();
|
||||
extern void mInstallLibrary_ASM();
|
||||
|
||||
|
||||
extern void mInstall_AMD_Math();
|
||||
extern void mInstall_Library_SSE();
|
||||
|
||||
|
||||
//--------------------------------------
|
||||
ConsoleFunction( mathInit, void, 1, 10, "( ... )"
|
||||
"Install the math library with specified extensions.\n\n"
|
||||
"Possible parameters are:\n"
|
||||
" - 'DETECT' Autodetect math lib settings.\n"
|
||||
" - 'C' Enable the C math routines. C routines are always enabled.\n"
|
||||
" - 'FPU' Enable floating point unit routines.\n"
|
||||
" - 'MMX' Enable MMX math routines.\n"
|
||||
" - '3DNOW' Enable 3dNow! math routines.\n"
|
||||
" - 'SSE' Enable SSE math routines.\n")
|
||||
|
||||
|
||||
{
|
||||
U32 properties = CPU_PROP_C; // C entensions are always used
|
||||
|
||||
if (argc == 1)
|
||||
{
|
||||
Math::init(0);
|
||||
return;
|
||||
}
|
||||
for (argc--, argv++; argc; argc--, argv++)
|
||||
{
|
||||
if (dStricmp(*argv, "DETECT") == 0) {
|
||||
Math::init(0);
|
||||
return;
|
||||
}
|
||||
if (dStricmp(*argv, "C") == 0) {
|
||||
properties |= CPU_PROP_C;
|
||||
continue;
|
||||
}
|
||||
if (dStricmp(*argv, "FPU") == 0) {
|
||||
properties |= CPU_PROP_FPU;
|
||||
continue;
|
||||
}
|
||||
if (dStricmp(*argv, "MMX") == 0) {
|
||||
properties |= CPU_PROP_MMX;
|
||||
continue;
|
||||
}
|
||||
if (dStricmp(*argv, "3DNOW") == 0) {
|
||||
properties |= CPU_PROP_3DNOW;
|
||||
continue;
|
||||
}
|
||||
if (dStricmp(*argv, "SSE") == 0) {
|
||||
properties |= CPU_PROP_SSE;
|
||||
continue;
|
||||
}
|
||||
Con::printf("Error: MathInit(): ignoring unknown math extension '%s'", *argv);
|
||||
}
|
||||
Math::init(properties);
|
||||
}
|
||||
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void Math::init(U32 properties)
|
||||
{
|
||||
if (!properties)
|
||||
// detect what's available
|
||||
properties = Platform::SystemInfo.processor.properties;
|
||||
else
|
||||
// Make sure we're not asking for anything that's not supported
|
||||
properties &= Platform::SystemInfo.processor.properties;
|
||||
|
||||
Con::printf("Math Init:");
|
||||
Con::printf(" Installing Standard C extensions");
|
||||
mInstallLibrary_C();
|
||||
|
||||
Con::printf(" Installing Assembly extensions");
|
||||
mInstallLibrary_ASM();
|
||||
|
||||
if (properties & CPU_PROP_FPU)
|
||||
{
|
||||
Con::printf(" Installing FPU extensions");
|
||||
}
|
||||
|
||||
if (properties & CPU_PROP_MMX)
|
||||
{
|
||||
Con::printf(" Installing MMX extensions");
|
||||
if (properties & CPU_PROP_3DNOW)
|
||||
{
|
||||
Con::printf(" Installing 3DNow extensions");
|
||||
mInstall_AMD_Math();
|
||||
}
|
||||
}
|
||||
|
||||
if (properties & CPU_PROP_SSE)
|
||||
{
|
||||
Con::printf(" Installing SSE extensions");
|
||||
mInstall_Library_SSE();
|
||||
}
|
||||
|
||||
Con::printf(" ");
|
||||
}
|
||||
|
||||
|
47
engine/platformWin32/winMath_ASM.cc
Executable file
47
engine/platformWin32/winMath_ASM.cc
Executable file
@ -0,0 +1,47 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// Torque Game Engine
|
||||
// Copyright (C) GarageGames.com, Inc.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "math/mMath.h"
|
||||
|
||||
#if defined(TORQUE_SUPPORTS_VC_INLINE_X86_ASM)
|
||||
static S32 m_mulDivS32_ASM(S32 a, S32 b, S32 c)
|
||||
{ // a * b / c
|
||||
S32 r;
|
||||
_asm
|
||||
{
|
||||
mov eax, a
|
||||
imul b
|
||||
idiv c
|
||||
mov r, eax
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
static U32 m_mulDivU32_ASM(S32 a, S32 b, U32 c)
|
||||
{ // a * b / c
|
||||
S32 r;
|
||||
_asm
|
||||
{
|
||||
mov eax, a
|
||||
mov edx, 0
|
||||
mul b
|
||||
div c
|
||||
mov r, eax
|
||||
}
|
||||
return r;
|
||||
}
|
||||
#endif
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void mInstallLibrary_ASM()
|
||||
{
|
||||
#if defined(TORQUE_SUPPORTS_VC_INLINE_X86_ASM)
|
||||
m_mulDivS32 = m_mulDivS32_ASM;
|
||||
m_mulDivU32 = m_mulDivU32_ASM;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
55
engine/platformWin32/winMemory.cc
Executable file
55
engine/platformWin32/winMemory.cc
Executable file
@ -0,0 +1,55 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// Torque Game Engine
|
||||
// Copyright (C) GarageGames.com, Inc.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "platformWin32/platformWin32.h"
|
||||
|
||||
void* dMemcpy(void *dst, const void *src, unsigned size)
|
||||
{
|
||||
return memcpy(dst,src,size);
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------
|
||||
void* dMemmove(void *dst, const void *src, unsigned size)
|
||||
{
|
||||
return memmove(dst,src,size);
|
||||
}
|
||||
|
||||
//--------------------------------------
|
||||
void* dMemset(void *dst, S32 c, unsigned size)
|
||||
{
|
||||
return memset(dst,c,size);
|
||||
}
|
||||
|
||||
//--------------------------------------
|
||||
S32 dMemcmp(const void *ptr1, const void *ptr2, unsigned len)
|
||||
{
|
||||
return memcmp(ptr1, ptr2, len);
|
||||
}
|
||||
|
||||
#ifdef new
|
||||
#undef new
|
||||
#endif
|
||||
|
||||
#if defined(TORQUE_COMPILER_MINGW)
|
||||
#include <stdlib.h>
|
||||
#endif
|
||||
|
||||
//--------------------------------------
|
||||
void* FN_CDECL operator new(dsize_t, void* ptr)
|
||||
{
|
||||
return (ptr);
|
||||
}
|
||||
|
||||
void* dRealMalloc(dsize_t s)
|
||||
{
|
||||
return malloc(s);
|
||||
}
|
||||
|
||||
void dRealFree(void* p)
|
||||
{
|
||||
free(p);
|
||||
}
|
||||
|
41
engine/platformWin32/winMutex.cc
Executable file
41
engine/platformWin32/winMutex.cc
Executable file
@ -0,0 +1,41 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// Torque Game Engine
|
||||
// Copyright (C) GarageGames.com, Inc.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "platformWin32/platformWin32.h"
|
||||
#include "platform/platformMutex.h"
|
||||
|
||||
void * Mutex::createMutex()
|
||||
{
|
||||
CRITICAL_SECTION * mutex = new CRITICAL_SECTION;
|
||||
InitializeCriticalSection(mutex);
|
||||
return((void*)mutex);
|
||||
}
|
||||
|
||||
void Mutex::destroyMutex(void * mutex)
|
||||
{
|
||||
AssertFatal(mutex, "Mutex::destroyMutex: invalid mutex");
|
||||
DeleteCriticalSection((CRITICAL_SECTION*)mutex);
|
||||
delete mutex;
|
||||
}
|
||||
|
||||
bool Mutex::lockMutex(void * mutex, bool block)
|
||||
{
|
||||
AssertFatal(mutex, "Mutex::lockMutex: invalid mutex");
|
||||
if(block)
|
||||
{
|
||||
EnterCriticalSection((CRITICAL_SECTION*)mutex);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return TryEnterCriticalSection((CRITICAL_SECTION*)mutex);
|
||||
}
|
||||
}
|
||||
|
||||
void Mutex::unlockMutex(void * mutex)
|
||||
{
|
||||
AssertFatal(mutex, "Mutex::unlockMutex: invalid mutex");
|
||||
LeaveCriticalSection((CRITICAL_SECTION*)mutex);
|
||||
}
|
826
engine/platformWin32/winNet.cc
Executable file
826
engine/platformWin32/winNet.cc
Executable file
@ -0,0 +1,826 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// Torque Game Engine
|
||||
// Copyright (C) GarageGames.com, Inc.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
#include "platformWin32/platformWin32.h"
|
||||
#include "platform/platform.h"
|
||||
#include "platform/event.h"
|
||||
#include <winsock.h>
|
||||
|
||||
#if !defined(USE_IPX) || defined(TORQUE_COMPILER_MINGW)
|
||||
# define NO_IPX_SUPPORT
|
||||
#endif
|
||||
|
||||
#if !defined(NO_IPX_SUPPORT)
|
||||
# include <wsipx.h>
|
||||
#else
|
||||
typedef void* SOCKADDR_IPX;
|
||||
#endif
|
||||
|
||||
#include "console/console.h"
|
||||
#include "platform/gameInterface.h"
|
||||
#include "core/fileStream.h"
|
||||
|
||||
struct NameLookup
|
||||
{
|
||||
U8 hostEntStruct[MAXGETHOSTSTRUCT];
|
||||
HANDLE lookupHandle;
|
||||
SOCKET socket;
|
||||
U16 port;
|
||||
NameLookup *nextLookup;
|
||||
};
|
||||
|
||||
static NameLookup *lookupList = NULL;
|
||||
|
||||
static Net::Error getLastError();
|
||||
static S32 defaultPort = 28000;
|
||||
static S32 netPort = 0;
|
||||
static SOCKET ipxSocket = INVALID_SOCKET;
|
||||
static SOCKET udpSocket = INVALID_SOCKET;
|
||||
|
||||
enum WinNetConstants {
|
||||
MaxConnections = 1024, ///< Maximum allowed number of connections.
|
||||
};
|
||||
|
||||
HWND winsockWindow = NULL;
|
||||
|
||||
static LRESULT PASCAL WinsockProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
U32 error;
|
||||
U32 bufLen;
|
||||
U32 event;
|
||||
SOCKET socket;
|
||||
Net::Error err;
|
||||
S32 bytesRead;
|
||||
|
||||
static ConnectedNotifyEvent notifyEvent;
|
||||
static ConnectedReceiveEvent receiveEvent;
|
||||
static ConnectedAcceptEvent acceptEvent;
|
||||
|
||||
switch(message)
|
||||
{
|
||||
case WM_USER:
|
||||
error = WSAGETSELECTERROR(lParam);
|
||||
event = WSAGETSELECTEVENT(lParam);
|
||||
socket = wParam;
|
||||
switch(event)
|
||||
{
|
||||
case FD_READ:
|
||||
err = Net::recv(socket, receiveEvent.data, MaxPacketDataSize, &bytesRead);
|
||||
if(err == Net::NoError && bytesRead != 0)
|
||||
{
|
||||
receiveEvent.tag = socket;
|
||||
receiveEvent.size = ConnectedReceiveEventHeaderSize + bytesRead;
|
||||
Game->postEvent(receiveEvent);
|
||||
}
|
||||
break;
|
||||
case FD_CONNECT:
|
||||
notifyEvent.tag = socket;
|
||||
if(error)
|
||||
notifyEvent.state = ConnectedNotifyEvent::ConnectFailed;
|
||||
else
|
||||
notifyEvent.state = ConnectedNotifyEvent::Connected;
|
||||
Game->postEvent(notifyEvent);
|
||||
break;
|
||||
case FD_CLOSE:
|
||||
// see first if there is anything to read:
|
||||
for(;;)
|
||||
{
|
||||
err = Net::recv(socket, receiveEvent.data, MaxPacketDataSize, &bytesRead);
|
||||
if(err != Net::NoError || bytesRead == 0)
|
||||
break;
|
||||
|
||||
receiveEvent.tag = socket;
|
||||
receiveEvent.size = ConnectedReceiveEventHeaderSize + bytesRead;
|
||||
Game->postEvent(receiveEvent);
|
||||
}
|
||||
notifyEvent.tag = socket;
|
||||
notifyEvent.state = ConnectedNotifyEvent::Disconnected;
|
||||
Game->postEvent(notifyEvent);
|
||||
break;
|
||||
case FD_ACCEPT:
|
||||
acceptEvent.portTag = socket;
|
||||
acceptEvent.connectionTag = Net::accept(socket, &acceptEvent.address);
|
||||
if(acceptEvent.connectionTag != InvalidSocket)
|
||||
{
|
||||
Net::setBlocking(acceptEvent.connectionTag, false);
|
||||
WSAAsyncSelect(acceptEvent.connectionTag, winsockWindow, WM_USER, FD_READ | FD_CONNECT | FD_CLOSE);
|
||||
Game->postEvent(acceptEvent);
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case WM_USER + 1:
|
||||
error = WSAGETASYNCERROR(lParam);
|
||||
bufLen = WSAGETASYNCBUFLEN(lParam);
|
||||
HANDLE handle;
|
||||
handle = HANDLE(wParam);
|
||||
NameLookup **walk;
|
||||
for(walk = &lookupList; *walk; walk = &((*walk)->nextLookup))
|
||||
{
|
||||
if((*walk)->lookupHandle == handle)
|
||||
{
|
||||
NameLookup *temp = *walk;
|
||||
struct hostent *hp = (struct hostent *) temp->hostEntStruct;
|
||||
|
||||
if(error)
|
||||
{
|
||||
notifyEvent.state = ConnectedNotifyEvent::DNSFailed;
|
||||
notifyEvent.tag = temp->socket;
|
||||
::closesocket(temp->socket);
|
||||
}
|
||||
else
|
||||
{
|
||||
SOCKADDR_IN ipAddr;
|
||||
memcpy(&ipAddr.sin_addr.s_addr, hp->h_addr, sizeof(IN_ADDR));
|
||||
ipAddr.sin_port = temp->port;
|
||||
ipAddr.sin_family = AF_INET;
|
||||
|
||||
notifyEvent.tag = temp->socket;
|
||||
|
||||
WSAAsyncSelect(temp->socket, winsockWindow, WM_USER, FD_READ | FD_CONNECT | FD_CLOSE);
|
||||
bool wserr = ::connect(temp->socket, (PSOCKADDR) &ipAddr, sizeof(ipAddr)); // always errors out
|
||||
if (wserr && WSAGetLastError() == WSAEWOULDBLOCK)
|
||||
notifyEvent.state = ConnectedNotifyEvent::DNSResolved;
|
||||
else {
|
||||
Con::printf("Connect error: %d", WSAGetLastError());
|
||||
::closesocket(temp->socket);
|
||||
notifyEvent.state = ConnectedNotifyEvent::ConnectFailed;
|
||||
}
|
||||
}
|
||||
Game->postEvent(notifyEvent);
|
||||
|
||||
*walk = temp->nextLookup;
|
||||
delete temp;
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return DefWindowProc( hWnd, message, wParam, lParam );
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static void InitNetWindow()
|
||||
{
|
||||
WNDCLASS wc;
|
||||
dMemset(&wc, 0, sizeof(wc));
|
||||
|
||||
wc.style = 0;
|
||||
wc.lpfnWndProc = WinsockProc;
|
||||
wc.cbClsExtra = 0;
|
||||
wc.cbWndExtra = 0;
|
||||
wc.hInstance = winState.appInstance;
|
||||
wc.hIcon = 0;
|
||||
wc.hCursor = 0;
|
||||
wc.hbrBackground = 0;
|
||||
wc.lpszMenuName = 0;
|
||||
wc.lpszClassName = dT("WinSockClass");
|
||||
RegisterClass( &wc );
|
||||
winsockWindow = CreateWindowEx(
|
||||
0,
|
||||
dT("WinSockClass"),
|
||||
dT(""),
|
||||
0,
|
||||
0, 0, 0, 0,
|
||||
NULL, NULL,
|
||||
winState.appInstance,
|
||||
NULL);
|
||||
}
|
||||
|
||||
bool Net::init()
|
||||
{
|
||||
WSADATA stWSAData;
|
||||
InitNetWindow();
|
||||
return !WSAStartup(0x0101, &stWSAData);
|
||||
}
|
||||
|
||||
void Net::shutdown()
|
||||
{
|
||||
while(lookupList)
|
||||
{
|
||||
NameLookup *temp = lookupList;
|
||||
lookupList = temp->nextLookup;
|
||||
WSACancelAsyncRequest ( temp->lookupHandle );
|
||||
delete temp;
|
||||
}
|
||||
DestroyWindow(winsockWindow);
|
||||
closePort();
|
||||
WSACleanup();
|
||||
}
|
||||
|
||||
static void netToIPSocketAddress(const NetAddress *address, SOCKADDR_IN *sockAddr)
|
||||
{
|
||||
dMemset(sockAddr, 0, sizeof(SOCKADDR_IN));
|
||||
sockAddr->sin_family = AF_INET;
|
||||
sockAddr->sin_port = htons(address->port);
|
||||
sockAddr->sin_addr.s_net = address->netNum[0];
|
||||
sockAddr->sin_addr.s_host = address->netNum[1];
|
||||
sockAddr->sin_addr.s_lh = address->netNum[2];
|
||||
sockAddr->sin_addr.s_impno = address->netNum[3];
|
||||
}
|
||||
|
||||
static void IPSocketToNetAddress(const SOCKADDR_IN *sockAddr, NetAddress *address)
|
||||
{
|
||||
address->type = NetAddress::IPAddress;
|
||||
address->port = htons(sockAddr->sin_port);
|
||||
address->netNum[0] = sockAddr->sin_addr.s_net;
|
||||
address->netNum[1] = sockAddr->sin_addr.s_host;
|
||||
address->netNum[2] = sockAddr->sin_addr.s_lh;
|
||||
address->netNum[3] = sockAddr->sin_addr.s_impno;
|
||||
}
|
||||
|
||||
static void netToIPXSocketAddress(const NetAddress *address, SOCKADDR_IPX *sockAddr)
|
||||
{
|
||||
#if !defined(NO_IPX_SUPPORT)
|
||||
dMemset(sockAddr, 0, sizeof(SOCKADDR_IPX));
|
||||
sockAddr->sa_family = AF_INET;
|
||||
sockAddr->sa_socket = htons(address->port);
|
||||
sockAddr->sa_netnum[0] = address->netNum[0];
|
||||
sockAddr->sa_netnum[1] = address->netNum[1];
|
||||
sockAddr->sa_netnum[2] = address->netNum[2];
|
||||
sockAddr->sa_netnum[3] = address->netNum[3];
|
||||
sockAddr->sa_nodenum[0] = address->nodeNum[0];
|
||||
sockAddr->sa_nodenum[1] = address->nodeNum[1];
|
||||
sockAddr->sa_nodenum[2] = address->nodeNum[2];
|
||||
sockAddr->sa_nodenum[3] = address->nodeNum[3];
|
||||
sockAddr->sa_nodenum[4] = address->nodeNum[4];
|
||||
sockAddr->sa_nodenum[5] = address->nodeNum[5];
|
||||
#endif
|
||||
}
|
||||
|
||||
static void IPXSocketToNetAddress(const SOCKADDR_IPX *sockAddr, NetAddress *address)
|
||||
{
|
||||
#if !defined(NO_IPX_SUPPORT)
|
||||
address->type = NetAddress::IPXAddress;
|
||||
address->port = htons(sockAddr->sa_socket);
|
||||
address->netNum[0] = sockAddr->sa_netnum[0] ;
|
||||
address->netNum[1] = sockAddr->sa_netnum[1] ;
|
||||
address->netNum[2] = sockAddr->sa_netnum[2] ;
|
||||
address->netNum[3] = sockAddr->sa_netnum[3] ;
|
||||
address->nodeNum[0] = sockAddr->sa_nodenum[0];
|
||||
address->nodeNum[1] = sockAddr->sa_nodenum[1];
|
||||
address->nodeNum[2] = sockAddr->sa_nodenum[2];
|
||||
address->nodeNum[3] = sockAddr->sa_nodenum[3];
|
||||
address->nodeNum[4] = sockAddr->sa_nodenum[4];
|
||||
address->nodeNum[5] = sockAddr->sa_nodenum[5];
|
||||
#endif
|
||||
}
|
||||
|
||||
NetSocket Net::openListenPort(U16 port)
|
||||
{
|
||||
if(Game->isJournalReading())
|
||||
{
|
||||
U32 ret;
|
||||
Game->journalRead(&ret);
|
||||
return NetSocket(ret);
|
||||
}
|
||||
NetSocket sock = openSocket();
|
||||
bind(sock, port);
|
||||
listen(sock, 4);
|
||||
setBlocking(sock, false);
|
||||
if(WSAAsyncSelect ( sock, winsockWindow, WM_USER, FD_ACCEPT ))
|
||||
Con::printf("Connect error: %d", WSAGetLastError());
|
||||
if(Game->isJournalWriting())
|
||||
Game->journalWrite(U32(sock));
|
||||
return sock;
|
||||
}
|
||||
|
||||
NetSocket Net::openConnectTo(const char *addressString)
|
||||
{
|
||||
if(!dStrnicmp(addressString, "ipx:", 4))
|
||||
return InvalidSocket;
|
||||
if(!dStrnicmp(addressString, "ip:", 3))
|
||||
addressString += 3; // eat off the ip:
|
||||
char remoteAddr[256];
|
||||
dStrcpy(remoteAddr, addressString);
|
||||
|
||||
char *portString = dStrchr(remoteAddr, ':');
|
||||
|
||||
U16 port;
|
||||
if(portString)
|
||||
{
|
||||
*portString++ = 0;
|
||||
port = htons(dAtoi(portString));
|
||||
}
|
||||
else
|
||||
port = htons(defaultPort);
|
||||
|
||||
if(!dStricmp(remoteAddr, "broadcast"))
|
||||
return InvalidSocket;
|
||||
|
||||
if(Game->isJournalReading())
|
||||
{
|
||||
U32 ret;
|
||||
Game->journalRead(&ret);
|
||||
return NetSocket(ret);
|
||||
}
|
||||
NetSocket sock = openSocket();
|
||||
setBlocking(sock, false);
|
||||
|
||||
SOCKADDR_IN ipAddr;
|
||||
|
||||
ipAddr.sin_addr.s_addr = inet_addr(remoteAddr);
|
||||
|
||||
if(ipAddr.sin_addr.s_addr != INADDR_NONE)
|
||||
{
|
||||
ipAddr.sin_port = port;
|
||||
ipAddr.sin_family = AF_INET;
|
||||
WSAAsyncSelect(sock, winsockWindow, WM_USER, FD_READ | FD_CONNECT | FD_CLOSE);
|
||||
if(::connect(sock, (PSOCKADDR) &ipAddr, sizeof(ipAddr) ) )
|
||||
{
|
||||
if(WSAGetLastError() != WSAEWOULDBLOCK)
|
||||
{
|
||||
Con::printf("Connect error: %d", WSAGetLastError());
|
||||
::closesocket(sock);
|
||||
sock = InvalidSocket;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
NameLookup *lookup = new NameLookup;
|
||||
lookup->socket = sock;
|
||||
lookup->port = port;
|
||||
lookup->lookupHandle = WSAAsyncGetHostByName (winsockWindow, WM_USER + 1, remoteAddr, (char *) lookup->hostEntStruct, MAXGETHOSTSTRUCT );
|
||||
if(!lookup->lookupHandle)
|
||||
{
|
||||
delete lookup;
|
||||
::closesocket(sock);
|
||||
sock = InvalidSocket;
|
||||
}
|
||||
else
|
||||
{
|
||||
lookup->nextLookup = lookupList;
|
||||
lookupList = lookup;
|
||||
}
|
||||
}
|
||||
if(Game->isJournalWriting())
|
||||
Game->journalWrite(U32(sock));
|
||||
return sock;
|
||||
}
|
||||
|
||||
void Net::closeConnectTo(NetSocket sock)
|
||||
{
|
||||
if(Game->isJournalReading())
|
||||
return;
|
||||
|
||||
for(NameLookup **walk = &lookupList; *walk; walk = &((*walk)->nextLookup) )
|
||||
{
|
||||
NameLookup *lookup = *walk;
|
||||
if(lookup->socket == sock)
|
||||
{
|
||||
WSACancelAsyncRequest ( lookup->lookupHandle );
|
||||
closesocket(lookup->socket);
|
||||
*walk = lookup->nextLookup;
|
||||
delete lookup;
|
||||
return;
|
||||
}
|
||||
}
|
||||
closesocket(sock);
|
||||
}
|
||||
|
||||
Net::Error Net::sendtoSocket(NetSocket socket, const U8 *buffer, S32 bufferSize)
|
||||
{
|
||||
if(Game->isJournalReading())
|
||||
{
|
||||
U32 e;
|
||||
Game->journalRead(&e);
|
||||
|
||||
return (Net::Error) e;
|
||||
}
|
||||
Net::Error e = send(socket, buffer, bufferSize);
|
||||
if(Game->isJournalWriting())
|
||||
Game->journalWrite(U32(e));
|
||||
return e;
|
||||
}
|
||||
|
||||
bool Net::openPort(S32 port)
|
||||
{
|
||||
if(udpSocket != INVALID_SOCKET)
|
||||
closesocket(udpSocket);
|
||||
if(ipxSocket != INVALID_SOCKET)
|
||||
closesocket(ipxSocket);
|
||||
|
||||
udpSocket = socket(AF_INET, SOCK_DGRAM, 0);
|
||||
|
||||
#if !defined(NO_IPX_SUPPORT)
|
||||
ipxSocket = socket(AF_IPX, SOCK_DGRAM, NSPROTO_IPX);
|
||||
#else
|
||||
ipxSocket = INVALID_SOCKET;
|
||||
#endif
|
||||
|
||||
if(udpSocket != INVALID_SOCKET)
|
||||
{
|
||||
Net::Error error;
|
||||
error = bind(udpSocket, port);
|
||||
if(error == NoError)
|
||||
error = setBufferSize(udpSocket, 32768);
|
||||
if(error == NoError)
|
||||
error = setBroadcast(udpSocket, true);
|
||||
if(error == NoError)
|
||||
error = setBlocking(udpSocket, false);
|
||||
if(error == NoError)
|
||||
Con::printf("UDP initialized on port %d", port);
|
||||
else
|
||||
{
|
||||
closesocket(udpSocket);
|
||||
udpSocket = INVALID_SOCKET;
|
||||
Con::printf("Unable to initialize UDP - error %d", error);
|
||||
}
|
||||
}
|
||||
|
||||
#if !defined(NO_IPX_SUPPORT)
|
||||
if(ipxSocket != INVALID_SOCKET)
|
||||
{
|
||||
Net::Error error = NoError;
|
||||
SOCKADDR_IPX ipxAddress;
|
||||
memset((char *)&ipxAddress, 0, sizeof(ipxAddress));
|
||||
ipxAddress.sa_family = AF_IPX;
|
||||
ipxAddress.sa_socket = htons(port);
|
||||
S32 err = ::bind(ipxSocket, (PSOCKADDR) &ipxAddress, sizeof(ipxAddress));
|
||||
if(err)
|
||||
error = getLastError();
|
||||
if(error == NoError)
|
||||
error = setBufferSize(ipxSocket, 32768);
|
||||
if(error == NoError)
|
||||
error = setBroadcast(ipxSocket, true);
|
||||
if(error == NoError)
|
||||
error = setBlocking(ipxSocket, false);
|
||||
if(error == NoError)
|
||||
Con::printf("IPX initialized on port %d", port);
|
||||
else
|
||||
{
|
||||
closesocket(ipxSocket);
|
||||
ipxSocket = INVALID_SOCKET;
|
||||
Con::printf("Unable to initialize IPX - error %d", error);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
netPort = port;
|
||||
return ipxSocket != INVALID_SOCKET || udpSocket != INVALID_SOCKET;
|
||||
}
|
||||
|
||||
void Net::closePort()
|
||||
{
|
||||
if(ipxSocket != INVALID_SOCKET)
|
||||
closesocket(ipxSocket);
|
||||
if(udpSocket != INVALID_SOCKET)
|
||||
closesocket(udpSocket);
|
||||
}
|
||||
|
||||
Net::Error Net::sendto(const NetAddress *address, const U8 *buffer, S32 bufferSize)
|
||||
{
|
||||
if(Game->isJournalReading())
|
||||
return NoError;
|
||||
|
||||
if(address->type == NetAddress::IPXAddress)
|
||||
{
|
||||
SOCKADDR_IPX ipxAddr;
|
||||
netToIPXSocketAddress(address, &ipxAddr);
|
||||
if(::sendto(ipxSocket, (const char*)buffer, bufferSize, 0,
|
||||
(PSOCKADDR) &ipxAddr, sizeof(SOCKADDR_IPX)) == SOCKET_ERROR)
|
||||
return getLastError();
|
||||
else
|
||||
return NoError;
|
||||
}
|
||||
else
|
||||
{
|
||||
SOCKADDR_IN ipAddr;
|
||||
netToIPSocketAddress(address, &ipAddr);
|
||||
if(::sendto(udpSocket, (const char*)buffer, bufferSize, 0,
|
||||
(PSOCKADDR) &ipAddr, sizeof(SOCKADDR_IN)) == SOCKET_ERROR)
|
||||
return getLastError();
|
||||
else
|
||||
return NoError;
|
||||
}
|
||||
}
|
||||
|
||||
void Net::process()
|
||||
{
|
||||
SOCKADDR sa;
|
||||
|
||||
PacketReceiveEvent receiveEvent;
|
||||
for(;;)
|
||||
{
|
||||
S32 addrLen = sizeof(sa);
|
||||
S32 bytesRead = SOCKET_ERROR;
|
||||
if(udpSocket != INVALID_SOCKET)
|
||||
bytesRead = recvfrom(udpSocket, (char *) receiveEvent.data, MaxPacketDataSize, 0, &sa, &addrLen);
|
||||
if(bytesRead == SOCKET_ERROR && ipxSocket != INVALID_SOCKET)
|
||||
{
|
||||
addrLen = sizeof(sa);
|
||||
bytesRead = recvfrom(ipxSocket, (char *) receiveEvent.data, MaxPacketDataSize, 0, &sa, &addrLen);
|
||||
}
|
||||
|
||||
if(bytesRead == SOCKET_ERROR)
|
||||
break;
|
||||
|
||||
if(sa.sa_family == AF_INET)
|
||||
IPSocketToNetAddress((SOCKADDR_IN *) &sa, &receiveEvent.sourceAddress);
|
||||
else if(sa.sa_family == AF_IPX)
|
||||
IPXSocketToNetAddress((SOCKADDR_IPX *) &sa, &receiveEvent.sourceAddress);
|
||||
else
|
||||
continue;
|
||||
|
||||
NetAddress &na = receiveEvent.sourceAddress;
|
||||
if(na.type == NetAddress::IPAddress &&
|
||||
na.netNum[0] == 127 &&
|
||||
na.netNum[1] == 0 &&
|
||||
na.netNum[2] == 0 &&
|
||||
na.netNum[3] == 1 &&
|
||||
na.port == netPort)
|
||||
continue;
|
||||
if(bytesRead <= 0)
|
||||
continue;
|
||||
receiveEvent.size = PacketReceiveEventHeaderSize + bytesRead;
|
||||
Game->postEvent(receiveEvent);
|
||||
}
|
||||
}
|
||||
|
||||
NetSocket Net::openSocket()
|
||||
{
|
||||
SOCKET retSocket;
|
||||
retSocket = socket(AF_INET, SOCK_STREAM, 0);
|
||||
|
||||
if(retSocket == INVALID_SOCKET)
|
||||
return InvalidSocket;
|
||||
else
|
||||
return retSocket;
|
||||
}
|
||||
|
||||
Net::Error Net::closeSocket(NetSocket socket)
|
||||
{
|
||||
if(socket != InvalidSocket)
|
||||
{
|
||||
if(!closesocket(socket))
|
||||
return NoError;
|
||||
else
|
||||
return getLastError();
|
||||
}
|
||||
else
|
||||
return NotASocket;
|
||||
}
|
||||
|
||||
Net::Error Net::connect(NetSocket socket, const NetAddress *address)
|
||||
{
|
||||
if(address->type != NetAddress::IPAddress)
|
||||
return WrongProtocolType;
|
||||
SOCKADDR_IN socketAddress;
|
||||
netToIPSocketAddress(address, &socketAddress);
|
||||
if(!::connect(socket, (PSOCKADDR) &socketAddress, sizeof(socketAddress)))
|
||||
return NoError;
|
||||
return getLastError();
|
||||
}
|
||||
|
||||
Net::Error Net::listen(NetSocket socket, S32 backlog)
|
||||
{
|
||||
if(!::listen(socket, backlog))
|
||||
return NoError;
|
||||
return getLastError();
|
||||
}
|
||||
|
||||
NetSocket Net::accept(NetSocket acceptSocket, NetAddress *remoteAddress)
|
||||
{
|
||||
SOCKADDR_IN socketAddress;
|
||||
S32 addrLen = sizeof(socketAddress);
|
||||
|
||||
SOCKET retVal = ::accept(acceptSocket, (PSOCKADDR) &socketAddress, &addrLen);
|
||||
if(retVal != INVALID_SOCKET)
|
||||
{
|
||||
IPSocketToNetAddress(&socketAddress, remoteAddress);
|
||||
return retVal;
|
||||
}
|
||||
return InvalidSocket;
|
||||
}
|
||||
|
||||
Net::Error Net::bind(NetSocket socket, U16 port)
|
||||
{
|
||||
S32 error;
|
||||
|
||||
SOCKADDR_IN socketAddress;
|
||||
dMemset((char *)&socketAddress, 0, sizeof(socketAddress));
|
||||
socketAddress.sin_family = AF_INET;
|
||||
// It's entirely possible that there are two NIC cards.
|
||||
// We let the user specify which one the server runs on.
|
||||
|
||||
// thanks to [TPG]P1aGu3 for the name
|
||||
const char* serverIP = Con::getVariable( "Pref::Net::BindAddress" );
|
||||
// serverIP is guaranteed to be non-0.
|
||||
AssertFatal( serverIP, "serverIP is NULL!" );
|
||||
|
||||
if( serverIP[0] != '\0' ) {
|
||||
// we're not empty
|
||||
socketAddress.sin_addr.s_addr = inet_addr( serverIP );
|
||||
|
||||
if( socketAddress.sin_addr.s_addr != INADDR_NONE ) {
|
||||
Con::printf( "Binding server port to %s", serverIP );
|
||||
} else {
|
||||
Con::warnf( ConsoleLogEntry::General,
|
||||
"inet_addr() failed for %s while binding!",
|
||||
serverIP );
|
||||
socketAddress.sin_addr.s_addr = INADDR_ANY;
|
||||
}
|
||||
|
||||
} else {
|
||||
Con::printf( "Binding server port to default IP" );
|
||||
socketAddress.sin_addr.s_addr = INADDR_ANY;
|
||||
}
|
||||
|
||||
socketAddress.sin_port = htons(port);
|
||||
error = ::bind(socket, (PSOCKADDR) &socketAddress, sizeof(socketAddress));
|
||||
|
||||
if(!error)
|
||||
return NoError;
|
||||
return getLastError();
|
||||
}
|
||||
|
||||
Net::Error Net::setBufferSize(NetSocket socket, S32 bufferSize)
|
||||
{
|
||||
S32 error;
|
||||
error = setsockopt(socket, SOL_SOCKET, SO_RCVBUF, (char *) &bufferSize, sizeof(bufferSize));
|
||||
if(!error)
|
||||
error = setsockopt(socket, SOL_SOCKET, SO_SNDBUF, (char *) &bufferSize, sizeof(bufferSize));
|
||||
if(!error)
|
||||
return NoError;
|
||||
return getLastError();
|
||||
}
|
||||
|
||||
Net::Error Net::setBroadcast(NetSocket socket, bool broadcast)
|
||||
{
|
||||
S32 bc = broadcast;
|
||||
S32 error = setsockopt(socket, SOL_SOCKET, SO_BROADCAST, (char*)&bc, sizeof(bc));
|
||||
if(!error)
|
||||
return NoError;
|
||||
return getLastError();
|
||||
}
|
||||
|
||||
Net::Error Net::setBlocking(NetSocket socket, bool blockingIO)
|
||||
{
|
||||
DWORD notblock = !blockingIO;
|
||||
S32 error = ioctlsocket(socket, FIONBIO, ¬block);
|
||||
if(!error)
|
||||
return NoError;
|
||||
return getLastError();
|
||||
}
|
||||
|
||||
Net::Error Net::send(NetSocket socket, const U8 *buffer, S32 bufferSize)
|
||||
{
|
||||
S32 error = ::send(socket, (const char*)buffer, bufferSize, 0);
|
||||
if(!error)
|
||||
return NoError;
|
||||
return getLastError();
|
||||
}
|
||||
|
||||
Net::Error Net::recv(NetSocket socket, U8 *buffer, S32 bufferSize, S32 *bytesRead)
|
||||
{
|
||||
*bytesRead = ::recv(socket, (char*)buffer, bufferSize, 0);
|
||||
if(*bytesRead == SOCKET_ERROR)
|
||||
return getLastError();
|
||||
return NoError;
|
||||
}
|
||||
|
||||
bool Net::compareAddresses(const NetAddress *a1, const NetAddress *a2)
|
||||
{
|
||||
if((a1->type != a2->type) ||
|
||||
(*((U32 *)a1->netNum) != *((U32 *)a2->netNum)) ||
|
||||
(a1->port != a2->port))
|
||||
return false;
|
||||
|
||||
if(a1->type == NetAddress::IPAddress)
|
||||
return true;
|
||||
for(S32 i = 0; i < 6; i++)
|
||||
if(a1->nodeNum[i] != a2->nodeNum[i])
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Net::stringToAddress(const char *addressString, NetAddress *address)
|
||||
{
|
||||
if(dStrnicmp(addressString, "ipx:", 4))
|
||||
{
|
||||
// assume IP if it doesn't have ipx: at the front.
|
||||
|
||||
if(!dStrnicmp(addressString, "ip:", 3))
|
||||
addressString += 3; // eat off the ip:
|
||||
|
||||
SOCKADDR_IN ipAddr;
|
||||
char remoteAddr[256];
|
||||
if(strlen(addressString) > 255)
|
||||
return false;
|
||||
|
||||
dStrcpy(remoteAddr, addressString);
|
||||
|
||||
char *portString = dStrchr(remoteAddr, ':');
|
||||
if(portString)
|
||||
*portString++ = 0;
|
||||
|
||||
struct hostent *hp;
|
||||
|
||||
if(!dStricmp(remoteAddr, "broadcast"))
|
||||
ipAddr.sin_addr.s_addr = htonl(INADDR_BROADCAST);
|
||||
else
|
||||
{
|
||||
ipAddr.sin_addr.s_addr = inet_addr(remoteAddr);
|
||||
if(ipAddr.sin_addr.s_addr == INADDR_NONE)
|
||||
{
|
||||
if((hp = gethostbyname(remoteAddr)) == NULL)
|
||||
return false;
|
||||
else
|
||||
memcpy(&ipAddr.sin_addr.s_addr, hp->h_addr, sizeof(IN_ADDR));
|
||||
}
|
||||
}
|
||||
if(portString)
|
||||
ipAddr.sin_port = htons(dAtoi(portString));
|
||||
else
|
||||
ipAddr.sin_port = htons(defaultPort);
|
||||
ipAddr.sin_family = AF_INET;
|
||||
IPSocketToNetAddress(&ipAddr, address);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
S32 i;
|
||||
S32 port;
|
||||
|
||||
address->type = NetAddress::IPXAddress;
|
||||
for(i = 0; i < 6; i++)
|
||||
address->nodeNum[i] = 0xFF;
|
||||
|
||||
// it's an IPX string
|
||||
addressString += 4;
|
||||
if(!dStricmp(addressString, "broadcast"))
|
||||
{
|
||||
address->port = defaultPort;
|
||||
return true;
|
||||
}
|
||||
else if(sscanf(addressString, "broadcast:%d", &port) == 1)
|
||||
{
|
||||
address->port = port;
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
S32 nodeNum[6];
|
||||
S32 netNum[4];
|
||||
S32 count = dSscanf(addressString, "%2x%2x%2x%2x:%2x%2x%2x%2x%2x%2x:%d",
|
||||
&netNum[0], &netNum[1], &netNum[2], &netNum[3],
|
||||
&nodeNum[0], &nodeNum[1], &nodeNum[2], &nodeNum[3], &nodeNum[4], &nodeNum[5],
|
||||
&port);
|
||||
|
||||
if(count == 10)
|
||||
{
|
||||
port = defaultPort;
|
||||
count++;
|
||||
}
|
||||
if(count != 11)
|
||||
return false;
|
||||
|
||||
for(i = 0; i < 6; i++)
|
||||
address->nodeNum[i] = nodeNum[i];
|
||||
for(i = 0; i < 4; i++)
|
||||
address->netNum[i] = netNum[i];
|
||||
address->port = port;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Net::addressToString(const NetAddress *address, char addressString[256])
|
||||
{
|
||||
if(address->type == NetAddress::IPAddress)
|
||||
{
|
||||
SOCKADDR_IN ipAddr;
|
||||
netToIPSocketAddress(address, &ipAddr);
|
||||
|
||||
if(ipAddr.sin_addr.s_addr == htonl(INADDR_BROADCAST))
|
||||
dSprintf(addressString, 256, "IP:Broadcast:%d", ntohs(ipAddr.sin_port));
|
||||
else
|
||||
dSprintf(addressString, 256, "IP:%d.%d.%d.%d:%d", ipAddr.sin_addr.s_net,
|
||||
ipAddr.sin_addr.s_host, ipAddr.sin_addr.s_lh,
|
||||
ipAddr.sin_addr.s_impno, ntohs(ipAddr.sin_port));
|
||||
}
|
||||
else
|
||||
{
|
||||
dSprintf(addressString, 256, "IPX:%.2X%.2X%.2X%.2X:%.2X%.2X%.2X%.2X%.2X%.2X:%d",
|
||||
address->netNum[0], address->netNum[1], address->netNum[2], address->netNum[3],
|
||||
address->nodeNum[0], address->nodeNum[1], address->nodeNum[2], address->nodeNum[3], address->nodeNum[4], address->nodeNum[5],
|
||||
address->port);
|
||||
}
|
||||
}
|
||||
|
||||
Net::Error getLastError()
|
||||
{
|
||||
S32 err = WSAGetLastError();
|
||||
switch(err)
|
||||
{
|
||||
case WSAEWOULDBLOCK:
|
||||
return Net::WouldBlock;
|
||||
default:
|
||||
return Net::UnknownError;
|
||||
}
|
||||
}
|
1253
engine/platformWin32/winOGLVideo.cc
Executable file
1253
engine/platformWin32/winOGLVideo.cc
Executable file
File diff suppressed because it is too large
Load Diff
37
engine/platformWin32/winOGLVideo.h
Executable file
37
engine/platformWin32/winOGLVideo.h
Executable file
@ -0,0 +1,37 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// Torque Game Engine
|
||||
// Copyright (C) GarageGames.com, Inc.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#ifndef _WINOGLVIDEO_H_
|
||||
#define _WINOGLVIDEO_H_
|
||||
|
||||
#ifndef _PLATFORMVIDEO_H_
|
||||
#include "platform/platformVideo.h"
|
||||
#endif
|
||||
|
||||
class OpenGLDevice : public DisplayDevice
|
||||
{
|
||||
static bool smCanSwitchBitDepth;
|
||||
|
||||
bool mRestoreGamma;
|
||||
U16 mOriginalRamp[256*3];
|
||||
|
||||
public:
|
||||
OpenGLDevice();
|
||||
|
||||
void initDevice();
|
||||
bool activate( U32 width, U32 height, U32 bpp, bool fullScreen );
|
||||
void shutdown();
|
||||
void destroy();
|
||||
bool setScreenMode( U32 width, U32 height, U32 bpp, bool fullScreen, bool forceIt = false, bool repaint = true );
|
||||
void swapBuffers();
|
||||
const char* getDriverInfo();
|
||||
bool getGammaCorrection(F32 &g);
|
||||
bool setGammaCorrection(F32 g);
|
||||
bool setVerticalSync( bool on );
|
||||
|
||||
static DisplayDevice* create();
|
||||
};
|
||||
|
||||
#endif // _H_WINOGLVIDEO
|
131
engine/platformWin32/winOpenAL.cc
Executable file
131
engine/platformWin32/winOpenAL.cc
Executable file
@ -0,0 +1,131 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// Torque Game Engine
|
||||
// Copyright (C) GarageGames.com, Inc.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "platformWin32/platformWin32.h"
|
||||
#include "console/console.h"
|
||||
|
||||
#include "al/altypes.h"
|
||||
#include "al/alctypes.h"
|
||||
#define INITGUID
|
||||
#include "al/eaxtypes.h"
|
||||
|
||||
|
||||
// Define the OpenAL and Extension Stub functions
|
||||
#define AL_FUNCTION(fn_return, fn_name, fn_args, fn_value) fn_return stub_##fn_name fn_args{ fn_value }
|
||||
#include "al/al_func.h"
|
||||
#include "al/alc_func.h"
|
||||
#include "al/eax_func.h"
|
||||
#undef AL_FUNCTION
|
||||
|
||||
|
||||
// Declare the OpenAL and Extension Function pointers
|
||||
// And initialize them to the stub functions
|
||||
#define AL_FUNCTION(fn_return,fn_name,fn_args, fn_value) fn_return (*fn_name)fn_args = stub_##fn_name;
|
||||
#include "al/al_func.h"
|
||||
#include "al/alc_func.h"
|
||||
#include "al/eax_func.h"
|
||||
#undef AL_FUNCTION
|
||||
|
||||
|
||||
/*! Get a function address from the OpenAL DLL and bind it to the
|
||||
* function pointer
|
||||
*/
|
||||
static bool bindFunction( void *&fnAddress, const char *name )
|
||||
{
|
||||
// JMQ: MinGW gcc 3.2 needs the cast to void*
|
||||
fnAddress = (void*)(GetProcAddress( winState.hinstOpenAL, name ));
|
||||
if( !fnAddress )
|
||||
Con::errorf(ConsoleLogEntry::General, " Missing OpenAL function '%s'", name);
|
||||
return (fnAddress != NULL);
|
||||
}
|
||||
|
||||
/*! Get a function address for an OpenAL extension function and bind it
|
||||
* to it's function pointer
|
||||
*/
|
||||
static bool bindExtensionFunction( void *&fnAddress, const char *name )
|
||||
{
|
||||
fnAddress = alGetProcAddress( (ALubyte*)name );
|
||||
if( !fnAddress )
|
||||
Con::errorf(ConsoleLogEntry::General, " Missing OpenAL Extension function '%s'", name);
|
||||
return (fnAddress != NULL);
|
||||
}
|
||||
|
||||
/*! Bind the functions in the OpenAL DLL to the al interface functions
|
||||
*/
|
||||
static bool bindOpenALFunctions()
|
||||
{
|
||||
bool result = true;
|
||||
#define AL_FUNCTION(fn_return, fn_name, fn_args, fn_value) result &= bindFunction( *(void**)&fn_name, #fn_name);
|
||||
#include "al/al_func.h"
|
||||
#include "al/alc_func.h"
|
||||
#undef AL_FUNCTION
|
||||
return result;
|
||||
}
|
||||
|
||||
/*! Bind the stub functions to the al interface functions
|
||||
*/
|
||||
static void unbindOpenALFunctions()
|
||||
{
|
||||
#define AL_FUNCTION(fn_return, fn_name, fn_args, fn_value) fn_name = stub_##fn_name;
|
||||
#include "al/al_func.h"
|
||||
#include "al/alc_func.h"
|
||||
#include "al/eax_func.h"
|
||||
#undef AL_FUNCTION
|
||||
}
|
||||
|
||||
/*! Bind the EAX Extension functions to the EAX interface functions
|
||||
*/
|
||||
static bool bindEAXFunctions()
|
||||
{
|
||||
bool result = true;
|
||||
#define AL_FUNCTION(fn_return, fn_name, fn_args, fn_value) result &= bindExtensionFunction( *(void**)&fn_name, #fn_name);
|
||||
#include "al/eax_func.h"
|
||||
#undef AL_FUNCTION
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
|
||||
namespace Audio
|
||||
{
|
||||
|
||||
/*! Shutdown and Unload the OpenAL DLL
|
||||
*/
|
||||
void OpenALDLLShutdown()
|
||||
{
|
||||
if (winState.hinstOpenAL)
|
||||
FreeLibrary(winState.hinstOpenAL);
|
||||
winState.hinstOpenAL = NULL;
|
||||
|
||||
unbindOpenALFunctions();
|
||||
}
|
||||
|
||||
/*! Dynamically Loads the OpenAL DLL if present and binds all the functions.
|
||||
* If there is no DLL or an unexpected error occurs binding functions the
|
||||
* stub functions are automatically bound.
|
||||
*/
|
||||
bool OpenALDLLInit()
|
||||
{
|
||||
OpenALDLLShutdown();
|
||||
|
||||
winState.hinstOpenAL = LoadLibrary( dT("OpenAl32.dll") );
|
||||
if(winState.hinstOpenAL != NULL)
|
||||
{
|
||||
// if the DLL loaded bind the OpenAL function pointers
|
||||
if(bindOpenALFunctions())
|
||||
{
|
||||
// if EAX is available bind it's function pointers
|
||||
//if (alIsExtensionPresent((ALubyte*)"EAX" ))
|
||||
bindEAXFunctions();
|
||||
return(true);
|
||||
}
|
||||
|
||||
// an error occured, shutdown
|
||||
OpenALDLLShutdown();
|
||||
}
|
||||
return(false);
|
||||
}
|
||||
|
||||
} // end namespace Audio
|
21
engine/platformWin32/winProcessControl.cc
Executable file
21
engine/platformWin32/winProcessControl.cc
Executable file
@ -0,0 +1,21 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// Torque Game Engine
|
||||
// Copyright (C) GarageGames.com, Inc.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "platformWin32/platformWin32.h"
|
||||
|
||||
void Platform::postQuitMessage(const U32 in_quitVal)
|
||||
{
|
||||
PostQuitMessage(in_quitVal);
|
||||
}
|
||||
|
||||
void Platform::debugBreak()
|
||||
{
|
||||
DebugBreak();
|
||||
}
|
||||
|
||||
void Platform::forceShutdown(S32 returnValue)
|
||||
{
|
||||
ExitProcess(returnValue);
|
||||
}
|
479
engine/platformWin32/winRedbook.cc
Executable file
479
engine/platformWin32/winRedbook.cc
Executable file
@ -0,0 +1,479 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// Torque Game Engine
|
||||
// Copyright (C) GarageGames.com, Inc.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "platformWin32/platformWin32.h"
|
||||
#include "platform/platformRedBook.h"
|
||||
#include "core/unicode.h"
|
||||
|
||||
class Win32RedBookDevice : public RedBookDevice
|
||||
{
|
||||
private:
|
||||
typedef RedBookDevice Parent;
|
||||
|
||||
U32 mDeviceId;
|
||||
|
||||
void setLastError(const char *);
|
||||
void setLastError(U32);
|
||||
|
||||
MIXERCONTROLDETAILS mMixerVolumeDetails;
|
||||
MIXERCONTROLDETAILS_UNSIGNED mMixerVolumeValue;
|
||||
|
||||
union {
|
||||
HMIXEROBJ mVolumeDeviceId;
|
||||
UINT mAuxVolumeDeviceId;
|
||||
};
|
||||
|
||||
U32 mOriginalVolume;
|
||||
bool mVolumeInitialized;
|
||||
|
||||
bool mUsingMixer;
|
||||
|
||||
void openVolume();
|
||||
void closeVolume();
|
||||
|
||||
public:
|
||||
Win32RedBookDevice();
|
||||
~Win32RedBookDevice();
|
||||
|
||||
U32 getDeviceId();
|
||||
|
||||
bool open();
|
||||
bool close();
|
||||
bool play(U32);
|
||||
bool stop();
|
||||
bool getTrackCount(U32 *);
|
||||
bool getVolume(F32 *);
|
||||
bool setVolume(F32);
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Win32 specific
|
||||
//------------------------------------------------------------------------------
|
||||
void installRedBookDevices()
|
||||
{
|
||||
U32 bufSize = ::GetLogicalDriveStrings(0,0);
|
||||
|
||||
char * buf = new char[bufSize];
|
||||
|
||||
::GetLogicalDriveStringsA(bufSize, buf);
|
||||
|
||||
char * str = buf;
|
||||
while(*str)
|
||||
{
|
||||
if(::GetDriveTypeA(str) == DRIVE_CDROM)
|
||||
{
|
||||
Win32RedBookDevice * device = new Win32RedBookDevice;
|
||||
device->mDeviceName = new char[dStrlen(str) + 1];
|
||||
dStrcpy(device->mDeviceName, str);
|
||||
|
||||
RedBook::installDevice(device);
|
||||
}
|
||||
str += dStrlen(str) + 1;
|
||||
}
|
||||
|
||||
delete [] buf;
|
||||
}
|
||||
|
||||
void handleRedBookCallback(U32 code, U32 deviceId)
|
||||
{
|
||||
if(code != MCI_NOTIFY_SUCCESSFUL)
|
||||
return;
|
||||
|
||||
Win32RedBookDevice * device = dynamic_cast<Win32RedBookDevice*>(RedBook::getCurrentDevice());
|
||||
if(!device)
|
||||
return;
|
||||
|
||||
if(device->getDeviceId() != deviceId)
|
||||
return;
|
||||
|
||||
// only installed callback on play (no callback if play is aborted)
|
||||
RedBook::handleCallback(RedBook::PlayFinished);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Class: Win32RedBookDevice
|
||||
//------------------------------------------------------------------------------
|
||||
Win32RedBookDevice::Win32RedBookDevice()
|
||||
{
|
||||
mVolumeInitialized = false;
|
||||
}
|
||||
|
||||
Win32RedBookDevice::~Win32RedBookDevice()
|
||||
{
|
||||
close();
|
||||
}
|
||||
|
||||
U32 Win32RedBookDevice::getDeviceId()
|
||||
{
|
||||
return(mDeviceId);
|
||||
}
|
||||
|
||||
bool Win32RedBookDevice::open()
|
||||
{
|
||||
if(mAcquired)
|
||||
{
|
||||
setLastError("Device is already open.");
|
||||
return(false);
|
||||
}
|
||||
|
||||
U32 error;
|
||||
|
||||
// open the device
|
||||
MCI_OPEN_PARMS openParms;
|
||||
#ifdef UNICODE
|
||||
openParms.lpstrDeviceType = (LPCWSTR)MCI_DEVTYPE_CD_AUDIO;
|
||||
|
||||
UTF16 buf[512];
|
||||
convertUTF8toUTF16((UTF8 *)mDeviceName, buf, sizeof(buf));
|
||||
openParms.lpstrElementName = buf;
|
||||
#else
|
||||
openParms.lpstrDeviceType = (LPCSTR)MCI_DEVTYPE_CD_AUDIO;
|
||||
openParms.lpstrElementName = mDeviceName;
|
||||
#endif
|
||||
|
||||
error = mciSendCommand(0, MCI_OPEN, MCI_OPEN_TYPE | MCI_OPEN_TYPE_ID, (DWORD_PTR)(LPMCI_OPEN_PARMS)&openParms);
|
||||
if(error)
|
||||
{
|
||||
// attempt to open as a shared device
|
||||
error = mciSendCommand(NULL, MCI_OPEN, MCI_OPEN_TYPE | MCI_OPEN_TYPE_ID|MCI_OPEN_SHAREABLE, (DWORD_PTR)(LPMCI_OPEN_PARMS)&openParms);
|
||||
if(error)
|
||||
{
|
||||
setLastError(error);
|
||||
return(false);
|
||||
}
|
||||
}
|
||||
|
||||
// set time mode to milliseconds
|
||||
MCI_SET_PARMS setParms;
|
||||
setParms.dwTimeFormat = MCI_FORMAT_MILLISECONDS;
|
||||
|
||||
error = mciSendCommand(openParms.wDeviceID, MCI_SET, MCI_SET_TIME_FORMAT, (DWORD_PTR)(LPMCI_SET_PARMS)&setParms);
|
||||
if(error)
|
||||
{
|
||||
setLastError(error);
|
||||
return(false);
|
||||
}
|
||||
|
||||
//
|
||||
mDeviceId = openParms.wDeviceID;
|
||||
mAcquired = true;
|
||||
|
||||
openVolume();
|
||||
setLastError("");
|
||||
return(true);
|
||||
}
|
||||
|
||||
bool Win32RedBookDevice::close()
|
||||
{
|
||||
if(!mAcquired)
|
||||
{
|
||||
setLastError("Device has not been acquired");
|
||||
return(false);
|
||||
}
|
||||
|
||||
stop();
|
||||
|
||||
U32 error;
|
||||
|
||||
MCI_GENERIC_PARMS closeParms;
|
||||
error = mciSendCommand(mDeviceId, MCI_CLOSE, 0, (DWORD_PTR)(LPMCI_GENERIC_PARMS)&closeParms);
|
||||
if(error)
|
||||
{
|
||||
setLastError(error);
|
||||
return(false);
|
||||
}
|
||||
|
||||
mAcquired = false;
|
||||
closeVolume();
|
||||
setLastError("");
|
||||
return(true);
|
||||
}
|
||||
|
||||
bool Win32RedBookDevice::play(U32 track)
|
||||
{
|
||||
if(!mAcquired)
|
||||
{
|
||||
setLastError("Device has not been acquired");
|
||||
return(false);
|
||||
}
|
||||
|
||||
U32 numTracks;
|
||||
if(!getTrackCount(&numTracks))
|
||||
return(false);
|
||||
|
||||
if(track >= numTracks)
|
||||
{
|
||||
setLastError("Track index is out of range");
|
||||
return(false);
|
||||
}
|
||||
|
||||
MCI_STATUS_PARMS statusParms;
|
||||
|
||||
// get track start time
|
||||
statusParms.dwItem = MCI_STATUS_POSITION;
|
||||
statusParms.dwTrack = track + 1;
|
||||
|
||||
U32 error;
|
||||
error = mciSendCommand(mDeviceId, MCI_STATUS, MCI_STATUS_ITEM|MCI_TRACK|MCI_WAIT,
|
||||
(DWORD_PTR)(LPMCI_STATUS_PARMS)&statusParms);
|
||||
|
||||
if(error)
|
||||
{
|
||||
setLastError(error);
|
||||
return(false);
|
||||
}
|
||||
|
||||
MCI_PLAY_PARMS playParms;
|
||||
playParms.dwFrom = statusParms.dwReturn;
|
||||
|
||||
// get track end time
|
||||
statusParms.dwItem = MCI_STATUS_LENGTH;
|
||||
error = mciSendCommand(mDeviceId, MCI_STATUS, MCI_STATUS_ITEM|MCI_TRACK|MCI_WAIT,
|
||||
(DWORD_PTR)(LPMCI_STATUS_PARMS)&statusParms);
|
||||
|
||||
if(error)
|
||||
{
|
||||
setLastError(error);
|
||||
return(false);
|
||||
}
|
||||
|
||||
playParms.dwTo = playParms.dwFrom + statusParms.dwReturn;
|
||||
|
||||
// play the track
|
||||
playParms.dwCallback = MAKELONG(winState.appWindow, 0);
|
||||
error = mciSendCommand(mDeviceId, MCI_PLAY, MCI_FROM|MCI_TO|MCI_NOTIFY,
|
||||
(DWORD_PTR)(LPMCI_PLAY_PARMS)&playParms);
|
||||
|
||||
if(error)
|
||||
{
|
||||
setLastError(error);
|
||||
return(false);
|
||||
}
|
||||
|
||||
setLastError("");
|
||||
return(true);
|
||||
}
|
||||
|
||||
bool Win32RedBookDevice::stop()
|
||||
{
|
||||
if(!mAcquired)
|
||||
{
|
||||
setLastError("Device has not been acquired");
|
||||
return(false);
|
||||
}
|
||||
|
||||
MCI_GENERIC_PARMS genParms;
|
||||
|
||||
U32 error = mciSendCommand(mDeviceId, MCI_STOP, 0, (DWORD_PTR)(LPMCI_GENERIC_PARMS)&genParms);
|
||||
if(error)
|
||||
{
|
||||
setLastError(error);
|
||||
return(false);
|
||||
}
|
||||
|
||||
setLastError("");
|
||||
return(true);
|
||||
}
|
||||
|
||||
bool Win32RedBookDevice::getTrackCount(U32 * numTracks)
|
||||
{
|
||||
if(!mAcquired)
|
||||
{
|
||||
setLastError("Device has not been acquired");
|
||||
return(false);
|
||||
}
|
||||
|
||||
MCI_STATUS_PARMS statusParms;
|
||||
|
||||
statusParms.dwItem = MCI_STATUS_NUMBER_OF_TRACKS;
|
||||
U32 error = mciSendCommand(mDeviceId, MCI_STATUS, MCI_STATUS_ITEM | MCI_WAIT, (DWORD_PTR)(LPMCI_STATUS_PARMS)&statusParms);
|
||||
if(error)
|
||||
{
|
||||
setLastError(error);
|
||||
return(false);
|
||||
}
|
||||
|
||||
*numTracks = statusParms.dwReturn;
|
||||
return(true);
|
||||
}
|
||||
|
||||
bool Win32RedBookDevice::getVolume(F32 * volume)
|
||||
{
|
||||
if(!mAcquired)
|
||||
{
|
||||
setLastError("Device has not been acquired");
|
||||
return(false);
|
||||
}
|
||||
|
||||
if(!mVolumeInitialized)
|
||||
{
|
||||
setLastError("Volume failed to initialize");
|
||||
return(false);
|
||||
}
|
||||
|
||||
U32 vol = 0;
|
||||
if(mUsingMixer)
|
||||
{
|
||||
mixerGetControlDetails(mVolumeDeviceId, &mMixerVolumeDetails, MIXER_GETCONTROLDETAILSF_VALUE);
|
||||
vol = mMixerVolumeValue.dwValue;
|
||||
}
|
||||
else
|
||||
auxGetVolume(mAuxVolumeDeviceId, (unsigned long *)&vol);
|
||||
|
||||
vol &= 0xffff;
|
||||
*volume = F32(vol) / 65535.f;
|
||||
|
||||
setLastError("");
|
||||
return(true);
|
||||
}
|
||||
|
||||
bool Win32RedBookDevice::setVolume(F32 volume)
|
||||
{
|
||||
if(!mAcquired)
|
||||
{
|
||||
setLastError("Device has not been acquired");
|
||||
return(false);
|
||||
}
|
||||
|
||||
if(!mVolumeInitialized)
|
||||
{
|
||||
setLastError("Volume failed to initialize");
|
||||
return(false);
|
||||
}
|
||||
|
||||
// move into a U32 - left/right U16 volumes
|
||||
U32 vol = U32(volume * 65536.f);
|
||||
if(vol > 0xffff)
|
||||
vol = 0xffff;
|
||||
|
||||
if(mUsingMixer)
|
||||
{
|
||||
mMixerVolumeValue.dwValue = vol;
|
||||
mixerSetControlDetails(mVolumeDeviceId, &mMixerVolumeDetails, MIXER_SETCONTROLDETAILSF_VALUE);
|
||||
}
|
||||
else
|
||||
{
|
||||
vol |= vol << 16;
|
||||
auxSetVolume(mAuxVolumeDeviceId, vol);
|
||||
}
|
||||
|
||||
setLastError("");
|
||||
return(true);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
void Win32RedBookDevice::openVolume()
|
||||
{
|
||||
setLastError("");
|
||||
|
||||
// first attempt to get the volume control through the mixer API
|
||||
S32 i;
|
||||
for(i = mixerGetNumDevs() - 1; i >= 0; i--)
|
||||
{
|
||||
// open the mixer
|
||||
if(mixerOpen((HMIXER*)&mVolumeDeviceId, i, 0, 0, 0) == MMSYSERR_NOERROR)
|
||||
{
|
||||
MIXERLINE lineInfo;
|
||||
memset(&lineInfo, 0, sizeof(lineInfo));
|
||||
lineInfo.cbStruct = sizeof(lineInfo);
|
||||
lineInfo.dwComponentType = MIXERLINE_COMPONENTTYPE_SRC_COMPACTDISC;
|
||||
|
||||
// get the cdaudio line
|
||||
if(mixerGetLineInfo(mVolumeDeviceId, &lineInfo, MIXER_GETLINEINFOF_COMPONENTTYPE) == MMSYSERR_NOERROR)
|
||||
{
|
||||
MIXERLINECONTROLS lineControls;
|
||||
MIXERCONTROL volumeControl;
|
||||
|
||||
memset(&lineControls, 0, sizeof(lineControls));
|
||||
lineControls.cbStruct = sizeof(lineControls);
|
||||
lineControls.dwLineID = lineInfo.dwLineID;
|
||||
lineControls.dwControlType = MIXERCONTROL_CONTROLTYPE_VOLUME;
|
||||
lineControls.cControls = 1;
|
||||
lineControls.cbmxctrl = sizeof(volumeControl);
|
||||
lineControls.pamxctrl = &volumeControl;
|
||||
|
||||
memset(&volumeControl, 0, sizeof(volumeControl));
|
||||
volumeControl.cbStruct = sizeof(volumeControl);
|
||||
|
||||
// get the volume control
|
||||
if(mixerGetLineControls(mVolumeDeviceId, &lineControls, MIXER_GETLINECONTROLSF_ONEBYTYPE) == MMSYSERR_NOERROR)
|
||||
{
|
||||
memset(&mMixerVolumeDetails, 0, sizeof(mMixerVolumeDetails));
|
||||
mMixerVolumeDetails.cbStruct = sizeof(mMixerVolumeDetails);
|
||||
mMixerVolumeDetails.dwControlID = volumeControl.dwControlID;
|
||||
mMixerVolumeDetails.cChannels = 1;
|
||||
mMixerVolumeDetails.cbDetails = sizeof(mMixerVolumeValue);
|
||||
mMixerVolumeDetails.paDetails = &mMixerVolumeValue;
|
||||
|
||||
memset(&mMixerVolumeValue, 0, sizeof(mMixerVolumeValue));
|
||||
|
||||
// query the current value
|
||||
if(mixerGetControlDetails(mVolumeDeviceId, &mMixerVolumeDetails, MIXER_GETCONTROLDETAILSF_VALUE) == MMSYSERR_NOERROR)
|
||||
{
|
||||
mUsingMixer = true;
|
||||
mVolumeInitialized = true;
|
||||
mOriginalVolume = mMixerVolumeValue.dwValue;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mixerClose((HMIXER)mVolumeDeviceId);
|
||||
}
|
||||
|
||||
// try aux
|
||||
for(i = auxGetNumDevs() - 1; i >= 0; i--)
|
||||
{
|
||||
AUXCAPS caps;
|
||||
auxGetDevCaps(i, &caps, sizeof(AUXCAPS));
|
||||
if((caps.wTechnology == AUXCAPS_CDAUDIO) && (caps.dwSupport & AUXCAPS_VOLUME))
|
||||
{
|
||||
mAuxVolumeDeviceId = i;
|
||||
mVolumeInitialized = true;
|
||||
mUsingMixer = false;
|
||||
auxGetVolume(i, (unsigned long *)&mOriginalVolume);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
setLastError("Volume failed to initialize");
|
||||
}
|
||||
|
||||
void Win32RedBookDevice::closeVolume()
|
||||
{
|
||||
setLastError("");
|
||||
if(!mVolumeInitialized)
|
||||
return;
|
||||
|
||||
if(mUsingMixer)
|
||||
{
|
||||
mMixerVolumeValue.dwValue = mOriginalVolume;
|
||||
mixerSetControlDetails(mVolumeDeviceId, &mMixerVolumeDetails, MIXER_SETCONTROLDETAILSF_VALUE);
|
||||
mixerClose((HMIXER)mVolumeDeviceId);
|
||||
}
|
||||
else
|
||||
auxSetVolume(mAuxVolumeDeviceId, mOriginalVolume);
|
||||
|
||||
mVolumeInitialized = false;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
void Win32RedBookDevice::setLastError(const char * error)
|
||||
{
|
||||
RedBook::setLastError(error);
|
||||
}
|
||||
|
||||
void Win32RedBookDevice::setLastError(U32 errorId)
|
||||
{
|
||||
char buffer[256];
|
||||
if(!mciGetErrorStringA(errorId, buffer, sizeof(buffer) - 1))
|
||||
setLastError("Failed to get MCI error string!");
|
||||
else
|
||||
setLastError(buffer);
|
||||
}
|
||||
|
42
engine/platformWin32/winSemaphore.cc
Executable file
42
engine/platformWin32/winSemaphore.cc
Executable file
@ -0,0 +1,42 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// Torque Game Engine
|
||||
// Copyright (C) GarageGames.com, Inc.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "platformWin32/platformWin32.h"
|
||||
#include "platform/platformSemaphore.h"
|
||||
|
||||
void * Semaphore::createSemaphore(U32 initialCount)
|
||||
{
|
||||
HANDLE * semaphore = new HANDLE;
|
||||
*semaphore = CreateSemaphore(0, initialCount, S32_MAX, 0);
|
||||
return(semaphore);
|
||||
}
|
||||
|
||||
void Semaphore::destroySemaphore(void * semaphore)
|
||||
{
|
||||
AssertFatal(semaphore, "Semaphore::destroySemaphore: invalid semaphore");
|
||||
CloseHandle(*(HANDLE*)semaphore);
|
||||
delete semaphore;
|
||||
}
|
||||
|
||||
bool Semaphore::acquireSemaphore(void * semaphore, bool block)
|
||||
{
|
||||
AssertFatal(semaphore, "Semaphore::acquireSemaphore: invalid semaphore");
|
||||
if(block)
|
||||
{
|
||||
WaitForSingleObject(*(HANDLE*)semaphore, INFINITE);
|
||||
return(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
DWORD result = WaitForSingleObject(*(HANDLE*)semaphore, 0);
|
||||
return(result == WAIT_OBJECT_0);
|
||||
}
|
||||
}
|
||||
|
||||
void Semaphore::releaseSemaphore(void * semaphore)
|
||||
{
|
||||
AssertFatal(semaphore, "Semaphore::releaseSemaphore: invalid semaphore");
|
||||
ReleaseSemaphore(*(HANDLE*)semaphore, 1, 0);
|
||||
}
|
408
engine/platformWin32/winStrings.cc
Executable file
408
engine/platformWin32/winStrings.cc
Executable file
@ -0,0 +1,408 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// Torque Game Engine
|
||||
// Copyright (C) GarageGames.com, Inc.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "platformWin32/platformWin32.h"
|
||||
|
||||
#ifdef HAS_VSSCANF
|
||||
# undef HAS_VSSCANF
|
||||
#endif
|
||||
|
||||
#if defined(TORQUE_COMPILER_CODEWARRIOR)
|
||||
# define HAS_VSSCANF
|
||||
# define __vsscanf vsscanf
|
||||
#endif
|
||||
|
||||
#if defined(TORQUE_COMPILER_GCC)
|
||||
# include <stdlib.h>
|
||||
# include <ctype.h>
|
||||
#endif
|
||||
|
||||
|
||||
char *dStrdup_r(const char *src, const char *fileName, dsize_t lineNumber)
|
||||
{
|
||||
char *buffer = (char *) dMalloc_r(dStrlen(src) + 1, fileName, lineNumber);
|
||||
dStrcpy(buffer, src);
|
||||
return buffer;
|
||||
}
|
||||
|
||||
char* dStrcat(char *dst, const char *src)
|
||||
{
|
||||
return strcat(dst,src);
|
||||
}
|
||||
|
||||
/*UTF8* dStrcat(UTF8 *dst, const UTF8 *src)
|
||||
{
|
||||
return (UTF8*)strcat((char*)dst,(char*)src);
|
||||
} */
|
||||
|
||||
char* dStrncat(char *dst, const char *src, dsize_t len)
|
||||
{
|
||||
return strncat(dst,src,len);
|
||||
}
|
||||
|
||||
// concatenates a list of src's onto the end of dst
|
||||
// the list of src's MUST be terminated by a NULL parameter
|
||||
// dStrcatl(dst, sizeof(dst), src1, src2, NULL);
|
||||
char* dStrcatl(char *dst, dsize_t dstSize, ...)
|
||||
{
|
||||
const char* src;
|
||||
char *p = dst;
|
||||
|
||||
AssertFatal(dstSize > 0, "dStrcatl: destination size is set zero");
|
||||
dstSize--; // leave room for string termination
|
||||
|
||||
// find end of dst
|
||||
while (dstSize && *p++)
|
||||
dstSize--;
|
||||
|
||||
va_list args;
|
||||
va_start(args, dstSize);
|
||||
|
||||
// concatenate each src to end of dst
|
||||
while ( (src = va_arg(args, const char*)) != NULL )
|
||||
while( dstSize && *src )
|
||||
{
|
||||
*p++ = *src++;
|
||||
dstSize--;
|
||||
}
|
||||
|
||||
va_end(args);
|
||||
|
||||
// make sure the string is terminated
|
||||
*p = 0;
|
||||
|
||||
return dst;
|
||||
}
|
||||
|
||||
|
||||
// copy a list of src's into dst
|
||||
// the list of src's MUST be terminated by a NULL parameter
|
||||
// dStrccpyl(dst, sizeof(dst), src1, src2, NULL);
|
||||
char* dStrcpyl(char *dst, dsize_t dstSize, ...)
|
||||
{
|
||||
const char* src;
|
||||
char *p = dst;
|
||||
|
||||
AssertFatal(dstSize > 0, "dStrcpyl: destination size is set zero");
|
||||
dstSize--; // leave room for string termination
|
||||
|
||||
va_list args;
|
||||
va_start(args, dstSize);
|
||||
|
||||
// concatenate each src to end of dst
|
||||
while ( (src = va_arg(args, const char*)) != NULL )
|
||||
while( dstSize && *src )
|
||||
{
|
||||
*p++ = *src++;
|
||||
dstSize--;
|
||||
}
|
||||
|
||||
va_end(args);
|
||||
|
||||
// make sure the string is terminated
|
||||
*p = 0;
|
||||
|
||||
return dst;
|
||||
}
|
||||
|
||||
|
||||
int dStrcmp(const char *str1, const char *str2)
|
||||
{
|
||||
return strcmp(str1, str2);
|
||||
}
|
||||
|
||||
int dStrcmp(const UTF16 *str1, const UTF16 *str2)
|
||||
{
|
||||
return wcscmp(str1, str2);
|
||||
}
|
||||
|
||||
int dStricmp(const char *str1, const char *str2)
|
||||
{
|
||||
return stricmp(str1, str2);
|
||||
}
|
||||
|
||||
int dStrncmp(const char *str1, const char *str2, dsize_t len)
|
||||
{
|
||||
return strncmp(str1, str2, len);
|
||||
}
|
||||
|
||||
int dStrnicmp(const char *str1, const char *str2, dsize_t len)
|
||||
{
|
||||
return strnicmp(str1, str2, len);
|
||||
}
|
||||
|
||||
char* dStrcpy(UTF8 *dst, const UTF8 *src)
|
||||
{
|
||||
return strcpy((char*)dst,(char*)src);
|
||||
}
|
||||
|
||||
char* dStrncpy(char *dst, const char *src, dsize_t len)
|
||||
{
|
||||
return strncpy(dst,src,len);
|
||||
}
|
||||
|
||||
/*char* dStrncpy(UTF8 *dst, const UTF8 *src, dsize_t len)
|
||||
{
|
||||
return strncpy((char*)dst,(char*)src,len);
|
||||
} */
|
||||
|
||||
dsize_t dStrlen(const char *str)
|
||||
{
|
||||
return (dsize_t)strlen(str);
|
||||
}
|
||||
|
||||
/*dsize_t dStrlen(const UTF8 *str)
|
||||
{
|
||||
// [tom, 7/12/2005] http://mail.nl.linux.org/linux-utf8/2000-06/msg00002.html
|
||||
int c = 0;
|
||||
for(; str; str = getNextUTF8Char(str))
|
||||
c++;
|
||||
|
||||
return c;
|
||||
}*/
|
||||
|
||||
dsize_t dStrlen(const UTF16 *str)
|
||||
{
|
||||
return (dsize_t)wcslen(str);
|
||||
}
|
||||
|
||||
char* dStrupr(char *str)
|
||||
{
|
||||
#if defined(TORQUE_COMPILER_CODEWARRIOR)
|
||||
// metrowerks strupr is broken
|
||||
_strupr(str);
|
||||
return str;
|
||||
#else
|
||||
return strupr(str);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
char* dStrlwr(char *str)
|
||||
{
|
||||
return strlwr(str);
|
||||
}
|
||||
|
||||
|
||||
char* dStrchr(char *str, S32 c)
|
||||
{
|
||||
return strchr(str,c);
|
||||
}
|
||||
|
||||
|
||||
const char* dStrchr(const char *str, S32 c)
|
||||
{
|
||||
return strchr(str,c);
|
||||
}
|
||||
|
||||
|
||||
const char* dStrrchr(const char *str, S32 c)
|
||||
{
|
||||
return strrchr(str,c);
|
||||
}
|
||||
|
||||
char* dStrrchr(char *str, S32 c)
|
||||
{
|
||||
return strrchr(str,c);
|
||||
}
|
||||
|
||||
dsize_t dStrspn(const char *str, const char *set)
|
||||
{
|
||||
return (dsize_t)strspn(str, set);
|
||||
}
|
||||
|
||||
dsize_t dStrcspn(const char *str, const char *set)
|
||||
{
|
||||
return (dsize_t)strcspn(str, set);
|
||||
}
|
||||
|
||||
|
||||
char* dStrstr(char *str1, char *str2)
|
||||
{
|
||||
return strstr(str1,str2);
|
||||
}
|
||||
|
||||
char* dStrstr(const char *str1, const char *str2)
|
||||
{
|
||||
return strstr((char *)str1,str2);
|
||||
}
|
||||
|
||||
|
||||
char* dStrtok(char *str, const char *sep)
|
||||
{
|
||||
return strtok(str, sep);
|
||||
}
|
||||
|
||||
|
||||
S32 dAtoi(const char *str)
|
||||
{
|
||||
return atoi(str);
|
||||
}
|
||||
|
||||
F32 dAtof(const char *str)
|
||||
{
|
||||
// Warning: metrowerks crashes when strange strings are passed in '0x [enter]' for example!
|
||||
return (F32)atof(str);
|
||||
}
|
||||
|
||||
bool dAtob(const char *str)
|
||||
{
|
||||
return !dStricmp(str, "true") || dAtof(str);
|
||||
}
|
||||
|
||||
|
||||
bool dIsalnum(const char c)
|
||||
{
|
||||
return isalnum(c)!=0;
|
||||
}
|
||||
|
||||
bool dIsalpha(const char c)
|
||||
{
|
||||
return isalpha(c)!=0;
|
||||
}
|
||||
|
||||
bool dIsspace(const char c)
|
||||
{
|
||||
return isspace(c)!=0;
|
||||
}
|
||||
|
||||
bool dIsdigit(const char c)
|
||||
{
|
||||
return isdigit(c)!=0;
|
||||
}
|
||||
|
||||
void dPrintf(const char *format, ...)
|
||||
{
|
||||
va_list args;
|
||||
va_start(args, format);
|
||||
vprintf(format, args);
|
||||
}
|
||||
|
||||
S32 dVprintf(const char *format, void *arglist)
|
||||
{
|
||||
S32 len = vprintf(format, (char*)arglist);
|
||||
return (len);
|
||||
}
|
||||
|
||||
S32 dSprintf(char *buffer, U32 bufferSize, const char *format, ...)
|
||||
{
|
||||
va_list args;
|
||||
va_start(args, format);
|
||||
|
||||
#if defined(TORQUE_COMPILER_CODEWARRIOR)
|
||||
S32 len = vsnprintf(buffer, bufferSize, format, args);
|
||||
#else
|
||||
bufferSize;
|
||||
S32 len = vsprintf(buffer, format, args);
|
||||
#endif
|
||||
return (len);
|
||||
}
|
||||
|
||||
|
||||
S32 dVsprintf(char *buffer, U32 bufferSize, const char *format, void *arglist)
|
||||
{
|
||||
#if defined(TORQUE_COMPILER_CODEWARRIOR)
|
||||
S32 len = vsnprintf(buffer, bufferSize, format, (char*)arglist);
|
||||
#else
|
||||
bufferSize;
|
||||
S32 len = vsprintf(buffer, format, (char*)arglist);
|
||||
#endif
|
||||
// S32 len = vsnprintf(buffer, bufferSize, format, (char*)arglist);
|
||||
return (len);
|
||||
}
|
||||
|
||||
|
||||
S32 dSscanf(const char *buffer, const char *format, ...)
|
||||
{
|
||||
va_list args;
|
||||
#if defined(HAS_VSSCANF)
|
||||
va_start(args, format);
|
||||
return __vsscanf(buffer, format, args);
|
||||
#else
|
||||
va_start(args, format);
|
||||
|
||||
// Boy is this lame. We have to scan through the format string, and find out how many
|
||||
// arguments there are. We'll store them off as void*, and pass them to the sscanf
|
||||
// function through specialized calls. We're going to have to put a cap on the number of args that
|
||||
// can be passed, 8 for the moment. Sigh.
|
||||
static void* sVarArgs[20];
|
||||
U32 numArgs = 0;
|
||||
|
||||
for (const char* search = format; *search != '\0'; search++) {
|
||||
if (search[0] == '%' && search[1] != '%')
|
||||
numArgs++;
|
||||
}
|
||||
AssertFatal(numArgs <= 20, "Error, too many arguments to lame implementation of dSscanf. Fix implmentation");
|
||||
|
||||
// Ok, we have the number of arguments...
|
||||
for (U32 i = 0; i < numArgs; i++)
|
||||
sVarArgs[i] = va_arg(args, void*);
|
||||
va_end(args);
|
||||
|
||||
switch (numArgs) {
|
||||
case 0: return 0;
|
||||
case 1: return sscanf(buffer, format, sVarArgs[0]);
|
||||
case 2: return sscanf(buffer, format, sVarArgs[0], sVarArgs[1]);
|
||||
case 3: return sscanf(buffer, format, sVarArgs[0], sVarArgs[1], sVarArgs[2]);
|
||||
case 4: return sscanf(buffer, format, sVarArgs[0], sVarArgs[1], sVarArgs[2], sVarArgs[3]);
|
||||
case 5: return sscanf(buffer, format, sVarArgs[0], sVarArgs[1], sVarArgs[2], sVarArgs[3], sVarArgs[4]);
|
||||
case 6: return sscanf(buffer, format, sVarArgs[0], sVarArgs[1], sVarArgs[2], sVarArgs[3], sVarArgs[4], sVarArgs[5]);
|
||||
case 7: return sscanf(buffer, format, sVarArgs[0], sVarArgs[1], sVarArgs[2], sVarArgs[3], sVarArgs[4], sVarArgs[5], sVarArgs[6]);
|
||||
case 8: return sscanf(buffer, format, sVarArgs[0], sVarArgs[1], sVarArgs[2], sVarArgs[3], sVarArgs[4], sVarArgs[5], sVarArgs[6], sVarArgs[7]);
|
||||
case 9: return sscanf(buffer, format, sVarArgs[0], sVarArgs[1], sVarArgs[2], sVarArgs[3], sVarArgs[4], sVarArgs[5], sVarArgs[6], sVarArgs[7], sVarArgs[8]);
|
||||
case 10: return sscanf(buffer, format, sVarArgs[0], sVarArgs[1], sVarArgs[2], sVarArgs[3], sVarArgs[4], sVarArgs[5], sVarArgs[6], sVarArgs[7], sVarArgs[8], sVarArgs[9]);
|
||||
case 11: return sscanf(buffer, format, sVarArgs[0], sVarArgs[1], sVarArgs[2], sVarArgs[3], sVarArgs[4], sVarArgs[5], sVarArgs[6], sVarArgs[7], sVarArgs[8], sVarArgs[9], sVarArgs[10]);
|
||||
case 12: return sscanf(buffer, format, sVarArgs[0], sVarArgs[1], sVarArgs[2], sVarArgs[3], sVarArgs[4], sVarArgs[5], sVarArgs[6], sVarArgs[7], sVarArgs[8], sVarArgs[9], sVarArgs[10], sVarArgs[11]);
|
||||
case 13: return sscanf(buffer, format, sVarArgs[0], sVarArgs[1], sVarArgs[2], sVarArgs[3], sVarArgs[4], sVarArgs[5], sVarArgs[6], sVarArgs[7], sVarArgs[8], sVarArgs[9], sVarArgs[10], sVarArgs[11], sVarArgs[12]);
|
||||
case 14: return sscanf(buffer, format, sVarArgs[0], sVarArgs[1], sVarArgs[2], sVarArgs[3], sVarArgs[4], sVarArgs[5], sVarArgs[6], sVarArgs[7], sVarArgs[8], sVarArgs[9], sVarArgs[10], sVarArgs[11], sVarArgs[12], sVarArgs[13]);
|
||||
case 15: return sscanf(buffer, format, sVarArgs[0], sVarArgs[1], sVarArgs[2], sVarArgs[3], sVarArgs[4], sVarArgs[5], sVarArgs[6], sVarArgs[7], sVarArgs[8], sVarArgs[9], sVarArgs[10], sVarArgs[11], sVarArgs[12], sVarArgs[13], sVarArgs[14]);
|
||||
case 16: return sscanf(buffer, format, sVarArgs[0], sVarArgs[1], sVarArgs[2], sVarArgs[3], sVarArgs[4], sVarArgs[5], sVarArgs[6], sVarArgs[7], sVarArgs[8], sVarArgs[9], sVarArgs[10], sVarArgs[11], sVarArgs[12], sVarArgs[13], sVarArgs[14], sVarArgs[15]);
|
||||
case 17: return sscanf(buffer, format, sVarArgs[0], sVarArgs[1], sVarArgs[2], sVarArgs[3], sVarArgs[4], sVarArgs[5], sVarArgs[6], sVarArgs[7], sVarArgs[8], sVarArgs[9], sVarArgs[10], sVarArgs[11], sVarArgs[12], sVarArgs[13], sVarArgs[14], sVarArgs[15], sVarArgs[16]);
|
||||
case 18: return sscanf(buffer, format, sVarArgs[0], sVarArgs[1], sVarArgs[2], sVarArgs[3], sVarArgs[4], sVarArgs[5], sVarArgs[6], sVarArgs[7], sVarArgs[8], sVarArgs[9], sVarArgs[10], sVarArgs[11], sVarArgs[12], sVarArgs[13], sVarArgs[14], sVarArgs[15], sVarArgs[16], sVarArgs[17]);
|
||||
case 19: return sscanf(buffer, format, sVarArgs[0], sVarArgs[1], sVarArgs[2], sVarArgs[3], sVarArgs[4], sVarArgs[5], sVarArgs[6], sVarArgs[7], sVarArgs[8], sVarArgs[9], sVarArgs[10], sVarArgs[11], sVarArgs[12], sVarArgs[13], sVarArgs[14], sVarArgs[15], sVarArgs[16], sVarArgs[17], sVarArgs[18]);
|
||||
case 20: return sscanf(buffer, format, sVarArgs[0], sVarArgs[1], sVarArgs[2], sVarArgs[3], sVarArgs[4], sVarArgs[5], sVarArgs[6], sVarArgs[7], sVarArgs[8], sVarArgs[9], sVarArgs[10], sVarArgs[11], sVarArgs[12], sVarArgs[13], sVarArgs[14], sVarArgs[15], sVarArgs[16], sVarArgs[17], sVarArgs[18], sVarArgs[19]);
|
||||
}
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
S32 dFflushStdout()
|
||||
{
|
||||
return fflush(stdout);
|
||||
}
|
||||
|
||||
S32 dFflushStderr()
|
||||
{
|
||||
return fflush(stderr);
|
||||
}
|
||||
|
||||
void dQsort(void *base, U32 nelem, U32 width, S32 (QSORT_CALLBACK *fcmp)(const void *, const void *))
|
||||
{
|
||||
qsort(base, nelem, width, fcmp);
|
||||
}
|
||||
|
||||
UTF8 * convertUTF16toUTF8(const UTF16 *string, UTF8 *buffer, U32 bufsize)
|
||||
{
|
||||
int nRet;
|
||||
if((nRet = WideCharToMultiByte(CP_UTF8, 0, string, dStrlen(string), (LPSTR)buffer, bufsize, NULL, NULL)) != 0)
|
||||
{
|
||||
buffer[nRet] = 0;
|
||||
return buffer;
|
||||
}
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
UTF16 * convertUTF8toUTF16(const UTF8 *string, UTF16 *buffer, U32 bufsize)
|
||||
{
|
||||
int nRet;
|
||||
if((nRet = MultiByteToWideChar(CP_UTF8, 0, (LPCSTR)string, dStrlen((const char *)string), buffer, bufsize)) != 0)
|
||||
{
|
||||
buffer[nRet] = 0;
|
||||
return buffer;
|
||||
}
|
||||
else
|
||||
return NULL;
|
||||
}
|
101
engine/platformWin32/winThread.cc
Executable file
101
engine/platformWin32/winThread.cc
Executable file
@ -0,0 +1,101 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// Torque Game Engine
|
||||
// Copyright (C) GarageGames.com, Inc.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "platform/platformThread.h"
|
||||
#include "platformWin32/platformWin32.h"
|
||||
#include "platform/platformSemaphore.h"
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
struct WinThreadData
|
||||
{
|
||||
ThreadRunFunction mRunFunc;
|
||||
S32 mRunArg;
|
||||
Thread * mThread;
|
||||
void * mSemaphore;
|
||||
|
||||
WinThreadData()
|
||||
{
|
||||
mRunFunc = 0;
|
||||
mRunArg = 0;
|
||||
mThread = 0;
|
||||
mSemaphore = 0;
|
||||
};
|
||||
};
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
Thread::Thread(ThreadRunFunction func, S32 arg, bool start_thread)
|
||||
{
|
||||
WinThreadData * threadData = new WinThreadData();
|
||||
threadData->mRunFunc = func;
|
||||
threadData->mRunArg = arg;
|
||||
threadData->mThread = this;
|
||||
threadData->mSemaphore = Semaphore::createSemaphore();
|
||||
|
||||
mData = reinterpret_cast<void*>(threadData);
|
||||
if (start_thread)
|
||||
start();
|
||||
}
|
||||
|
||||
Thread::~Thread()
|
||||
{
|
||||
join();
|
||||
|
||||
WinThreadData * threadData = reinterpret_cast<WinThreadData*>(mData);
|
||||
Semaphore::destroySemaphore(threadData->mSemaphore);
|
||||
delete threadData;
|
||||
}
|
||||
|
||||
static DWORD WINAPI ThreadRunHandler(void * arg)
|
||||
{
|
||||
WinThreadData * threadData = reinterpret_cast<WinThreadData*>(arg);
|
||||
|
||||
threadData->mThread->run(threadData->mRunArg);
|
||||
Semaphore::releaseSemaphore(threadData->mSemaphore);
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
void Thread::start()
|
||||
{
|
||||
if(isAlive())
|
||||
return;
|
||||
|
||||
WinThreadData * threadData = reinterpret_cast<WinThreadData*>(mData);
|
||||
Semaphore::acquireSemaphore(threadData->mSemaphore);
|
||||
|
||||
DWORD threadID;
|
||||
CreateThread(0, 0, ThreadRunHandler, mData, 0, &threadID);
|
||||
}
|
||||
|
||||
bool Thread::join()
|
||||
{
|
||||
if(!isAlive())
|
||||
return(false);
|
||||
|
||||
WinThreadData * threadData = reinterpret_cast<WinThreadData*>(mData);
|
||||
return(Semaphore::acquireSemaphore(threadData->mSemaphore));
|
||||
}
|
||||
|
||||
void Thread::run(S32 arg)
|
||||
{
|
||||
WinThreadData * threadData = reinterpret_cast<WinThreadData*>(mData);
|
||||
if(threadData->mRunFunc)
|
||||
threadData->mRunFunc(arg);
|
||||
}
|
||||
|
||||
bool Thread::isAlive()
|
||||
{
|
||||
WinThreadData * threadData = reinterpret_cast<WinThreadData*>(mData);
|
||||
|
||||
bool signal = Semaphore::acquireSemaphore(threadData->mSemaphore, false);
|
||||
if(signal)
|
||||
Semaphore::releaseSemaphore(threadData->mSemaphore);
|
||||
return(!signal);
|
||||
}
|
||||
|
||||
U32 Thread::getCurrentThreadId()
|
||||
{
|
||||
return GetCurrentThreadId();
|
||||
}
|
93
engine/platformWin32/winTime.cc
Executable file
93
engine/platformWin32/winTime.cc
Executable file
@ -0,0 +1,93 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// Torque Game Engine
|
||||
// Copyright (C) GarageGames.com, Inc.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "platformWin32/platformWin32.h"
|
||||
#include "time.h"
|
||||
|
||||
void Platform::sleep(U32 ms)
|
||||
{
|
||||
Sleep(ms);
|
||||
}
|
||||
|
||||
//--------------------------------------
|
||||
void Platform::getLocalTime(LocalTime <)
|
||||
{
|
||||
struct tm *systime;
|
||||
time_t long_time;
|
||||
|
||||
time( &long_time ); // Get time as long integer.
|
||||
systime = localtime( &long_time ); // Convert to local time.
|
||||
|
||||
lt.sec = systime->tm_sec;
|
||||
lt.min = systime->tm_min;
|
||||
lt.hour = systime->tm_hour;
|
||||
lt.month = systime->tm_mon;
|
||||
lt.monthday = systime->tm_mday;
|
||||
lt.weekday = systime->tm_wday;
|
||||
lt.year = systime->tm_year;
|
||||
lt.yearday = systime->tm_yday;
|
||||
lt.isdst = systime->tm_isdst;
|
||||
}
|
||||
|
||||
U32 Platform::getTime()
|
||||
{
|
||||
time_t long_time;
|
||||
time( &long_time );
|
||||
return long_time;
|
||||
}
|
||||
|
||||
void Platform::fileToLocalTime(const FileTime & ft, LocalTime * lt)
|
||||
{
|
||||
if(!lt)
|
||||
return;
|
||||
|
||||
dMemset(lt, 0, sizeof(LocalTime));
|
||||
|
||||
FILETIME winFileTime;
|
||||
winFileTime.dwLowDateTime = ft.v1;
|
||||
winFileTime.dwHighDateTime = ft.v2;
|
||||
|
||||
SYSTEMTIME winSystemTime;
|
||||
|
||||
// convert the filetime to local time
|
||||
FILETIME convertedFileTime;
|
||||
if(::FileTimeToLocalFileTime(&winFileTime, &convertedFileTime))
|
||||
{
|
||||
// get the time into system time struct
|
||||
if(::FileTimeToSystemTime((const FILETIME *)&convertedFileTime, &winSystemTime))
|
||||
{
|
||||
SYSTEMTIME * time = &winSystemTime;
|
||||
|
||||
// fill it in...
|
||||
lt->sec = time->wSecond;
|
||||
lt->min = time->wMinute;
|
||||
lt->hour = time->wHour;
|
||||
lt->month = time->wMonth;
|
||||
lt->monthday = time->wDay;
|
||||
lt->weekday = time->wDayOfWeek;
|
||||
lt->year = (time->wYear < 1900) ? 1900 : (time->wYear - 1900);
|
||||
|
||||
// not calculated
|
||||
lt->yearday = 0;
|
||||
lt->isdst = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
U32 Platform::getRealMilliseconds()
|
||||
{
|
||||
return GetTickCount();
|
||||
}
|
||||
|
||||
U32 Platform::getVirtualMilliseconds()
|
||||
{
|
||||
return winState.currentTime;
|
||||
}
|
||||
|
||||
void Platform::advanceTime(U32 delta)
|
||||
{
|
||||
winState.currentTime += delta;
|
||||
}
|
||||
|
657
engine/platformWin32/winV2Video.cc
Executable file
657
engine/platformWin32/winV2Video.cc
Executable file
@ -0,0 +1,657 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// Torque Game Engine
|
||||
// Copyright (C) GarageGames.com, Inc.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "platformWin32/platformGL.h"
|
||||
#include "platformWin32/platformWin32.h"
|
||||
#include "platform/platformAudio.h"
|
||||
#include "platformWin32/winV2Video.h"
|
||||
#include "platform/3Dfx.h"
|
||||
#include "console/console.h"
|
||||
#include "math/mPoint.h"
|
||||
#include "platform/event.h"
|
||||
#include "platform/gameInterface.h"
|
||||
#include "console/consoleInternal.h"
|
||||
#include "console/ast.h"
|
||||
#include "core/fileStream.h"
|
||||
|
||||
|
||||
static U8 sResCode; // Used for initializing the resolution list only
|
||||
|
||||
static void execScript(const char *scriptFile)
|
||||
{
|
||||
// execute the script
|
||||
FileStream str;
|
||||
|
||||
if (!str.open(scriptFile, FileStream::Read))
|
||||
return;
|
||||
|
||||
U32 size = str.getStreamSize();
|
||||
char *script = new char[size + 1];
|
||||
|
||||
str.read(size, script);
|
||||
str.close();
|
||||
|
||||
script[size] = 0;
|
||||
Con::executef(2, "eval", script);
|
||||
delete[] script;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
Voodoo2Device::Voodoo2Device()
|
||||
{
|
||||
initDevice();
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void Voodoo2Device::initDevice()
|
||||
{
|
||||
// Set the device name:
|
||||
mDeviceName = "Voodoo2";
|
||||
|
||||
// Set some initial conditions:
|
||||
mResolutionList.clear();
|
||||
mFullScreenOnly = true;
|
||||
|
||||
// Enumerate all available resolutions:
|
||||
Resolution newRes;
|
||||
newRes = Resolution( 640, 480, 16 );
|
||||
mResolutionList.push_back( newRes );
|
||||
|
||||
if ( sResCode & 1 )
|
||||
{
|
||||
newRes = Resolution( 800, 600, 16 );
|
||||
mResolutionList.push_back( newRes );
|
||||
}
|
||||
|
||||
if ( sResCode & 2 )
|
||||
{
|
||||
Con::printf( "SLI detected." );
|
||||
|
||||
newRes = Resolution( 960, 720, 16 );
|
||||
mResolutionList.push_back( newRes );
|
||||
|
||||
newRes = Resolution( 1024, 768, 16 );
|
||||
mResolutionList.push_back( newRes );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
bool Voodoo2Device::activate( U32 width, U32 height, U32 /*bpp*/, bool /*fullScreen*/ )
|
||||
{
|
||||
bool needResurrect = false;
|
||||
|
||||
// If the rendering context exists, delete it:
|
||||
if ( winState.hGLRC )
|
||||
{
|
||||
Con::printf( "Killing the texture manager..." );
|
||||
Game->textureKill();
|
||||
needResurrect = true;
|
||||
|
||||
Con::printf( "Making the rendering context not current..." );
|
||||
if ( !dwglMakeCurrent( NULL, NULL ) )
|
||||
{
|
||||
AssertFatal( false, "Voodoo2Device::activate\ndwglMakeCurrent( NULL, NULL ) failed!" );
|
||||
return false;
|
||||
}
|
||||
|
||||
Con::printf( "Deleting the rendering context..." );
|
||||
if ( !dwglDeleteContext( winState.hGLRC ) )
|
||||
{
|
||||
AssertFatal( false, "Voodoo2Device::activate\ndwglDeleteContext failed!" );
|
||||
return false;
|
||||
}
|
||||
winState.hGLRC = NULL;
|
||||
}
|
||||
|
||||
// If window already exists, kill it so we can start fresh:
|
||||
if ( winState.appWindow )
|
||||
{
|
||||
Con::printf( "Releasing the device context..." );
|
||||
ReleaseDC( winState.appWindow, winState.appDC );
|
||||
winState.appDC = NULL;
|
||||
|
||||
Con::printf( "Destroying the window..." );
|
||||
DestroyWindow( winState.appWindow );
|
||||
winState.appWindow = NULL;
|
||||
}
|
||||
|
||||
// If OpenGL library already loaded, shut it down and reload the 3Dfx standalone driver:
|
||||
if ( winState.hinstOpenGL )
|
||||
GL_Shutdown();
|
||||
|
||||
GL_Init( "3dfxvgl", "glu32" );
|
||||
|
||||
// This device only supports full-screen, so force it:
|
||||
smIsFullScreen = true;
|
||||
Con::setVariable( "$pref::Video::fullScreen", "true" );
|
||||
|
||||
// Create the new window:
|
||||
Con::printf( "Creating a new full-screen window..." );
|
||||
winState.appWindow = CreateOpenGLWindow( width, height, true );
|
||||
if ( !winState.appWindow )
|
||||
{
|
||||
AssertFatal( false, "Voodoo2Device::activate\nFailed to create a window!" );
|
||||
return false;
|
||||
}
|
||||
|
||||
// Get a device context from the new window:
|
||||
HDC tempDC = GetDC( winState.appWindow );
|
||||
if ( !tempDC )
|
||||
{
|
||||
AssertFatal( false, "Voodoo2Device::activate\nFailed to get a device context!" );
|
||||
return false;
|
||||
}
|
||||
|
||||
// Set the pixel format of the new window:
|
||||
PIXELFORMATDESCRIPTOR pfd;
|
||||
CreatePixelFormat( &pfd, 16, 16, 8, false );
|
||||
S32 chosenFormat = ChooseBestPixelFormat( tempDC, &pfd );
|
||||
dwglDescribePixelFormat( tempDC, chosenFormat, sizeof( pfd ), &pfd );
|
||||
bool test = dwglSetPixelFormat( tempDC, chosenFormat, &pfd );
|
||||
ReleaseDC( winState.appWindow, tempDC );
|
||||
if ( !test )
|
||||
{
|
||||
AssertFatal( false, "Voodoo2Device::activate\nFailed to set the pixel format of the device context!" );
|
||||
return false;
|
||||
}
|
||||
Con::printf( "Pixel format set:" );
|
||||
Con::printf( " %d color bits, %d depth bits, %d stencil bits", pfd.cColorBits, pfd.cDepthBits, pfd.cStencilBits );
|
||||
|
||||
// Set the resolution:
|
||||
smCurrentRes.bpp = 16; // Force 16-bit color.
|
||||
if ( !setScreenMode( width, height, 16, true, true, false ) )
|
||||
return false;
|
||||
|
||||
// Output some driver info to the console:
|
||||
const char* vendorString = (const char*) glGetString( GL_VENDOR );
|
||||
const char* rendererString = (const char*) glGetString( GL_RENDERER );
|
||||
const char* versionString = (const char*) glGetString( GL_VERSION );
|
||||
Con::printf( "OpenGL driver information:" );
|
||||
if ( vendorString )
|
||||
Con::printf( " Vendor: %s", vendorString );
|
||||
if ( rendererString )
|
||||
Con::printf( " Renderer: %s", rendererString );
|
||||
if ( versionString )
|
||||
Con::printf( " Version: %s", versionString );
|
||||
|
||||
// Set a few variables:
|
||||
if ( Con::getIntVariable( "$pref::OpenGL::mipReduction" ) < 1 )
|
||||
Con::setIntVariable( "$pref::OpenGL::mipReduction", 1 );
|
||||
if ( Con::getIntVariable( "$pref::OpenGL::interiorMipReduction" ) < 1 )
|
||||
Con::setIntVariable( "$pref::OpenGL::interiorMipReduction", 1 );
|
||||
if ( Con::getIntVariable( "$pref::OpenGL::skyMipReduction" ) < 1 )
|
||||
Con::setIntVariable( "$pref::OpenGL::skyMipReduction", 1 );
|
||||
|
||||
if (dStrcmp(vendorString, Con::getVariable("$pref::Video::profiledVendor")) ||
|
||||
dStrcmp(rendererString, Con::getVariable("$pref::Video::profiledRenderer")))
|
||||
{
|
||||
// Voodoo2 defaults
|
||||
Con::setBoolVariable("$pref::OpenGL::disableEXTCompiledVertexArray", false);
|
||||
Con::setBoolVariable("$pref::OpenGL::disableSubImage", false);
|
||||
Con::setBoolVariable("$pref::OpenGL::noEnvColor", true);
|
||||
Con::setBoolVariable("$pref::OpenGL::disableARBTextureCompression", false);
|
||||
Con::setBoolVariable("$pref::Interior::lockArrays", true);
|
||||
Con::setBoolVariable("$pref::TS::skipFirstFog", false);
|
||||
Con::setBoolVariable("$pref::OpenGL::noDrawArraysAlpha", true);
|
||||
}
|
||||
|
||||
if ( needResurrect )
|
||||
{
|
||||
// Reload the textures:
|
||||
Con::printf( "Resurrecting the texture manager..." );
|
||||
Game->textureResurrect();
|
||||
}
|
||||
|
||||
// Set the new window to the foreground:
|
||||
ShowWindow( winState.appWindow, SW_SHOW );
|
||||
SetForegroundWindow( winState.appWindow );
|
||||
SetFocus( winState.appWindow );
|
||||
|
||||
GL_EXT_Init();
|
||||
|
||||
Con::setBoolVariable( "$SwapIntervalSupported", false );
|
||||
Con::setVariable( "$pref::Video::displayDevice", mDeviceName );
|
||||
Con::setBoolVariable("$pref::OpenGL::allowTexGen", true);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void Voodoo2Device::shutdown()
|
||||
{
|
||||
if ( winState.hGLRC )
|
||||
{
|
||||
dwglMakeCurrent( NULL, NULL );
|
||||
dwglDeleteContext( winState.hGLRC );
|
||||
winState.hGLRC = NULL;
|
||||
}
|
||||
|
||||
if ( winState.appDC )
|
||||
{
|
||||
ReleaseDC( winState.appWindow, winState.appDC );
|
||||
winState.appDC = NULL;
|
||||
}
|
||||
|
||||
ChangeDisplaySettings( NULL, 0 );
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
bool Voodoo2Device::setScreenMode( U32 width, U32 height, U32 bpp, bool fullScreen, bool forceIt, bool repaint )
|
||||
{
|
||||
HWND curtain = NULL;
|
||||
bool needResurrect = false;
|
||||
Resolution newRes( width, height, bpp );
|
||||
|
||||
if ( !fullScreen )
|
||||
{
|
||||
// The 3Dfx Voodoo2 OpenGL driver only runs in full-screen, so ignore:
|
||||
Con::warnf( ConsoleLogEntry::General, "Sorry, the Voodoo 2 display device only supports full-screen!" );
|
||||
}
|
||||
|
||||
// Force the res to be one of the ones in the supported list:
|
||||
U32 resIndex = 0;
|
||||
U32 bestScore = 0, thisScore = 0;
|
||||
for ( U32 i = 0; i < mResolutionList.size(); i++ )
|
||||
{
|
||||
if ( newRes == mResolutionList[i] )
|
||||
{
|
||||
resIndex = i;
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
thisScore = abs( S32( newRes.w ) - S32( mResolutionList[i].w ) ) + abs( S32( newRes.h ) - S32( mResolutionList[i].h ) );
|
||||
if ( !bestScore || thisScore < bestScore )
|
||||
{
|
||||
bestScore = thisScore;
|
||||
resIndex = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
newRes = mResolutionList[resIndex];
|
||||
|
||||
// Return if we aren't forcing it and we are already in the desired resolution:
|
||||
if ( !forceIt && newRes == smCurrentRes )
|
||||
return true;
|
||||
|
||||
Con::printf( "Setting screen mode to %dx%dx16 (fs)...", newRes.w, newRes.h );
|
||||
|
||||
// Delete the rendering context:
|
||||
if ( winState.hGLRC )
|
||||
{
|
||||
Con::printf( "Killing the texture manager..." );
|
||||
Game->textureKill();
|
||||
needResurrect = true;
|
||||
|
||||
Con::printf( "Making the rendering context not current..." );
|
||||
if ( !dwglMakeCurrent( NULL, NULL ) )
|
||||
{
|
||||
AssertFatal( false, "Voodoo2Device::setScreenMode\ndwglMakeCurrent( NULL, NULL ) failed!" );
|
||||
return false;
|
||||
}
|
||||
|
||||
Con::printf( "Deleting the rendering context..." );
|
||||
if ( !dwglDeleteContext( winState.hGLRC ) )
|
||||
{
|
||||
AssertFatal( false, "Voodoo2Device::setScreenMode\ndwglDeleteContext failed!" );
|
||||
return false;
|
||||
}
|
||||
winState.hGLRC = NULL;
|
||||
}
|
||||
|
||||
// Release the device context:
|
||||
if ( winState.appDC )
|
||||
{
|
||||
Con::printf( "Releasing the device context..." );
|
||||
ReleaseDC( winState.appWindow, winState.appDC );
|
||||
winState.appDC = NULL;
|
||||
}
|
||||
|
||||
// Change the display settings (shouldn't really be necessary, but is):
|
||||
U32 test;
|
||||
DEVMODE devMode;
|
||||
dMemset( &devMode, 0, sizeof( devMode ) );
|
||||
devMode.dmSize = sizeof( devMode );
|
||||
devMode.dmPelsWidth = newRes.w;
|
||||
devMode.dmPelsHeight = newRes.h;
|
||||
devMode.dmFields = DM_PELSWIDTH | DM_PELSHEIGHT;
|
||||
|
||||
Con::printf( "Changing the display settings to %dx%dx16...", newRes.w, newRes.h );
|
||||
curtain = CreateCurtain( newRes.w, newRes.h );
|
||||
test = ChangeDisplaySettings( &devMode, CDS_FULLSCREEN );
|
||||
if ( test != DISP_CHANGE_SUCCESSFUL )
|
||||
{
|
||||
ChangeDisplaySettings( NULL, 0 );
|
||||
switch( test )
|
||||
{
|
||||
case DISP_CHANGE_RESTART:
|
||||
Platform::AlertOK( "Display Change Failed", "You must restart your machine to get the specified mode." );
|
||||
break;
|
||||
|
||||
case DISP_CHANGE_BADMODE:
|
||||
Platform::AlertOK( "Display Change Failed", "The specified mode is not supported by this device." );
|
||||
break;
|
||||
|
||||
default:
|
||||
Platform::AlertOK( "Display Change Failed", "Hardware failed to switch to the specified mode." );
|
||||
break;
|
||||
};
|
||||
return false;
|
||||
}
|
||||
|
||||
// Resize the window:
|
||||
if ( !SetWindowPos( winState.appWindow, NULL, 0, 0, newRes.w, newRes.h, SWP_NOZORDER | SWP_NOMOVE ) )
|
||||
{
|
||||
Con::printf( "Voodoo2Device::setScreenMode - SetWindowPos sizing to %dx%d failed.", newRes.w, newRes.h );
|
||||
return false;
|
||||
}
|
||||
|
||||
// Get a new device context:
|
||||
Con::printf( "Acquiring a new device context..." );
|
||||
winState.appDC = GetDC( winState.appWindow );
|
||||
if ( !winState.appDC )
|
||||
{
|
||||
AssertFatal( false, "Voodoo2Device::setScreenMode\nFailed to get a valid device context!" );
|
||||
return false;
|
||||
}
|
||||
|
||||
// Create a new rendering context:
|
||||
Con::printf( "Creating a new rendering context..." );
|
||||
winState.hGLRC = dwglCreateContext( winState.appDC );
|
||||
if ( !winState.hGLRC )
|
||||
{
|
||||
AssertFatal( false, "Voodoo2Device::setScreenMode\nFailed to create a GL rendering context!" );
|
||||
return false;
|
||||
}
|
||||
|
||||
// Make the new rendering context current:
|
||||
Con::printf( "Making the new rendering context current..." );
|
||||
if ( !dwglMakeCurrent( winState.appDC, winState.hGLRC ) )
|
||||
{
|
||||
AssertFatal( false, "Voodoo2Device::setScreenMode\nFailed to make the rendering context current!" );
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( needResurrect )
|
||||
{
|
||||
// Reload the textures:
|
||||
Con::printf( "Resurrecting the texture manager..." );
|
||||
Game->textureResurrect();
|
||||
}
|
||||
|
||||
smCurrentRes = newRes;
|
||||
Platform::setWindowSize( newRes.w, newRes.h );
|
||||
char tempBuf[15];
|
||||
dSprintf( tempBuf, sizeof( tempBuf ), "%d %d %d", smCurrentRes.w, smCurrentRes.h, smCurrentRes.bpp );
|
||||
Con::setVariable( "$pref::Video::resolution", tempBuf );
|
||||
|
||||
if ( curtain )
|
||||
DestroyWindow( curtain );
|
||||
|
||||
if ( repaint )
|
||||
Con::evaluate( "resetCanvas();" );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void Voodoo2Device::swapBuffers()
|
||||
{
|
||||
dwglSwapBuffers( winState.appDC );
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
const char* Voodoo2Device::getDriverInfo()
|
||||
{
|
||||
// Output some driver info to the console:
|
||||
const char* vendorString = (const char*) glGetString( GL_VENDOR );
|
||||
const char* rendererString = (const char*) glGetString( GL_RENDERER );
|
||||
const char* versionString = (const char*) glGetString( GL_VERSION );
|
||||
const char* extensionsString = (const char*) glGetString( GL_EXTENSIONS );
|
||||
|
||||
// TODO - move strings out of code and into script...
|
||||
U32 bufferLen = ( vendorString ? dStrlen( vendorString ) : 0 )
|
||||
+ ( rendererString ? dStrlen( rendererString ) : 0 )
|
||||
+ ( versionString ? dStrlen( versionString ) : 0 )
|
||||
+ ( extensionsString ? dStrlen( extensionsString ) : 0 )
|
||||
+ 4;
|
||||
|
||||
char* returnString = Con::getReturnBuffer( bufferLen );
|
||||
dSprintf( returnString, bufferLen, "%s\t%s\t%s\t%s",
|
||||
( vendorString ? vendorString : "" ),
|
||||
( rendererString ? rendererString : "" ),
|
||||
( versionString ? versionString : "" ),
|
||||
( extensionsString ? extensionsString : "" ) );
|
||||
|
||||
return( returnString );
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
bool Voodoo2Device::getGammaCorrection(F32 &g)
|
||||
{
|
||||
// apparently the qwlGetDeviceGammaRamp3DFX doesn't actually work. So, this
|
||||
// is a good default. We don't need to worry about restoring the original
|
||||
// gamma. Anything we do is wiped out once we destroy the Voodoo2 window.
|
||||
g = 0.8;
|
||||
|
||||
return true;
|
||||
|
||||
U16 ramp[256*3];
|
||||
|
||||
if (!dwglGetDeviceGammaRamp3DFX(winState.appDC, ramp))
|
||||
return false;
|
||||
|
||||
F32 csum = 0.0;
|
||||
U32 ccount = 0;
|
||||
|
||||
for (U16 i = 0; i < 256; ++i)
|
||||
{
|
||||
if (i != 0 && ramp[i] != 0 && ramp[i] != 65535)
|
||||
{
|
||||
F64 b = (F64) i/256.0;
|
||||
F64 a = (F64) ramp[i]/65535.0;
|
||||
F32 c = (F32) (mLog(a)/mLog(b));
|
||||
|
||||
csum += c;
|
||||
++ccount;
|
||||
}
|
||||
}
|
||||
g = csum/ccount;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
bool Voodoo2Device::setGammaCorrection(F32 g)
|
||||
{
|
||||
U16 ramp[256*3];
|
||||
|
||||
for (U16 i = 0; i < 256; ++i)
|
||||
ramp[i] = mPow((F32) i/256.0f, g) * 65535.0f;
|
||||
dMemcpy(&ramp[256],ramp,256*sizeof(U16));
|
||||
dMemcpy(&ramp[512],ramp,256*sizeof(U16));
|
||||
|
||||
return dwglSetDeviceGammaRamp3DFX(winState.appDC, ramp);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
bool Voodoo2Device::setVerticalSync( bool on )
|
||||
{
|
||||
on;
|
||||
return( false );
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Stuff for Voodoo 2 detection:
|
||||
#ifndef GR_HARDWARE
|
||||
#define GR_HARDWARE 0xa1
|
||||
#endif
|
||||
|
||||
#define GLIDE_NUM_TMU 2
|
||||
#define MAX_NUM_SST 4
|
||||
|
||||
typedef S32 GrSstType;
|
||||
#define GR_SSTTYPE_VOODOO 0
|
||||
#define GR_SSTTYPE_SST96 1
|
||||
#define GR_SSTTYPE_AT3D 2
|
||||
|
||||
typedef struct GrTMUConfig_St
|
||||
{
|
||||
S32 tmuRev; /* Rev of Texelfx chip */
|
||||
S32 tmuRam; /* 1, 2, or 4 MB */
|
||||
} GrTMUConfig_t;
|
||||
|
||||
typedef struct GrVoodooConfig_St
|
||||
{
|
||||
S32 fbRam; /* 1, 2, or 4 MB */
|
||||
S32 fbiRev; /* Rev of Pixelfx chip */
|
||||
S32 nTexelfx; /* How many texelFX chips are there? */
|
||||
FxBool sliDetect; /* Is it a scan-line interleaved board? */
|
||||
GrTMUConfig_t tmuConfig[GLIDE_NUM_TMU]; /* Configuration of the Texelfx chips */
|
||||
} GrVoodooConfig_t;
|
||||
|
||||
typedef struct GrSst96Config_St
|
||||
{
|
||||
S32 fbRam; /* How much? */
|
||||
S32 nTexelfx;
|
||||
GrTMUConfig_t tmuConfig;
|
||||
} GrSst96Config_t;
|
||||
|
||||
typedef struct GrAT3DConfig_St
|
||||
{
|
||||
S32 rev;
|
||||
} GrAT3DConfig_t;
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
S32 num_sst; /* # of HW units in the system */
|
||||
struct
|
||||
{
|
||||
GrSstType type; /* Which hardware is it? */
|
||||
union SstBoard_u
|
||||
{
|
||||
GrVoodooConfig_t VoodooConfig;
|
||||
GrSst96Config_t SST96Config;
|
||||
GrAT3DConfig_t AT3DConfig;
|
||||
} sstBoard;
|
||||
} SSTs[MAX_NUM_SST]; /* configuration for each board */
|
||||
} GrHwConfiguration;
|
||||
|
||||
typedef FxBool( FX_CALL *grSstQueryBoards_fpt )( GrHwConfiguration *hwconfig );
|
||||
typedef FxBool( FX_CALL *grSstQueryHardware_fpt )( GrHwConfiguration *hwconfig );
|
||||
|
||||
typedef void ( FX_CALL *grGlideInit_fpt )( void );
|
||||
typedef const char* ( FX_CALL *grGetString_fpt )( FxU32 pName );
|
||||
typedef void( FX_CALL *grGlideShutdown_fpt )( void );
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
DisplayDevice* Voodoo2Device::create()
|
||||
{
|
||||
// Detect the Voodoo2 OpenGL driver:
|
||||
GrHwConfiguration hwConfig;
|
||||
bool result = true;
|
||||
|
||||
// Reset the available resolution specifier code:
|
||||
sResCode = 0;
|
||||
|
||||
grGlideInit_fpt grGlideInit = NULL;
|
||||
grGlideShutdown_fpt grGlideShutdown = NULL;
|
||||
grSstQueryBoards_fpt grSstQueryBoards = NULL;
|
||||
grSstQueryHardware_fpt grSstQueryHardware = NULL;
|
||||
grGetString_fpt grGetString = NULL;
|
||||
|
||||
// Let the Glide 2 stuff go first:
|
||||
HINSTANCE glide2DLL = LoadLibrary( dT("glide2x") );
|
||||
|
||||
if ( !glide2DLL )
|
||||
return NULL;
|
||||
|
||||
grSstQueryBoards = (grSstQueryBoards_fpt) GetProcAddress( glide2DLL, "_grSstQueryBoards@4" );
|
||||
|
||||
if ( grSstQueryBoards )
|
||||
{
|
||||
grSstQueryBoards( &hwConfig );
|
||||
if ( hwConfig.num_sst == 0 )
|
||||
result = false;
|
||||
else
|
||||
{
|
||||
grGlideInit = (grGlideInit_fpt) GetProcAddress( glide2DLL, "_grGlideInit@0" );
|
||||
grSstQueryHardware = (grSstQueryHardware_fpt) GetProcAddress( glide2DLL, "_grSstQueryHardware@4" );
|
||||
grGlideShutdown = (grGlideShutdown_fpt) GetProcAddress( glide2DLL, "_grGlideShutdown@0" );
|
||||
|
||||
if ( grGlideInit && grSstQueryHardware && grGlideShutdown )
|
||||
{
|
||||
grGlideInit();
|
||||
grSstQueryHardware( &hwConfig );
|
||||
|
||||
// Find out what resolutions are available:
|
||||
if ( hwConfig.SSTs[0].sstBoard.VoodooConfig.sliDetect == 0 ) // SLI not detected.
|
||||
{
|
||||
if ( hwConfig.SSTs[0].sstBoard.VoodooConfig.fbRam >= 4 )
|
||||
sResCode = 1; // low bit indicates 800x600
|
||||
}
|
||||
else // SLI detected.
|
||||
{
|
||||
sResCode = 1;
|
||||
|
||||
if ( hwConfig.SSTs[0].sstBoard.VoodooConfig.fbRam >= 4 )
|
||||
sResCode += 2;
|
||||
}
|
||||
|
||||
grGlideShutdown();
|
||||
}
|
||||
|
||||
grGlideInit = NULL;
|
||||
grGlideShutdown = NULL;
|
||||
}
|
||||
}
|
||||
else
|
||||
result = false;
|
||||
|
||||
FreeLibrary( glide2DLL );
|
||||
|
||||
if ( result )
|
||||
{
|
||||
// Glide 3's turn:
|
||||
HINSTANCE glide3DLL = LoadLibrary( dT("glide3x") );
|
||||
|
||||
if ( !glide3DLL )
|
||||
return NULL;
|
||||
|
||||
grGlideInit = (grGlideInit_fpt) GetProcAddress( glide3DLL, "_grGlideInit@0" );
|
||||
grGetString = (grGetString_fpt) GetProcAddress( glide3DLL, "_grGetString@4" );
|
||||
grGlideShutdown = (grGlideShutdown_fpt) GetProcAddress( glide3DLL, "_grGlideShutdown@0" );
|
||||
|
||||
if ( grGlideInit && grGetString && grGlideShutdown )
|
||||
{
|
||||
grGlideInit();
|
||||
|
||||
const char* hardware = grGetString( GR_HARDWARE );
|
||||
if ( dStrcmp( hardware, "Voodoo2" ) != 0 )
|
||||
result = false;
|
||||
|
||||
grGlideShutdown();
|
||||
}
|
||||
else
|
||||
result = false;
|
||||
|
||||
FreeLibrary( glide3DLL );
|
||||
}
|
||||
|
||||
if ( result )
|
||||
return new Voodoo2Device();
|
||||
else
|
||||
return NULL;
|
||||
}
|
33
engine/platformWin32/winV2Video.h
Executable file
33
engine/platformWin32/winV2Video.h
Executable file
@ -0,0 +1,33 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// Torque Game Engine
|
||||
// Copyright (C) GarageGames.com, Inc.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#ifndef _WINV2VIDEO_H_
|
||||
#define _WINV2VIDEO_H_
|
||||
|
||||
#ifndef _PLATFORMVIDEO_H_
|
||||
#include "platform/platformVideo.h"
|
||||
#endif
|
||||
|
||||
class Voodoo2Device : public DisplayDevice
|
||||
{
|
||||
public:
|
||||
Voodoo2Device();
|
||||
|
||||
void initDevice();
|
||||
bool activate( U32 width, U32 height, U32 bpp, bool fullScreen );
|
||||
void shutdown();
|
||||
void destroy();
|
||||
bool setScreenMode( U32 width, U32 height, U32 bpp, bool fullScreen, bool forceIt = false, bool repaint = true );
|
||||
void swapBuffers();
|
||||
const char* getDriverInfo();
|
||||
bool getGammaCorrection(F32 &g);
|
||||
bool setGammaCorrection(F32 g);
|
||||
bool setVerticalSync( bool on );
|
||||
|
||||
static DisplayDevice* create();
|
||||
};
|
||||
|
||||
|
||||
#endif // _H_WINV2VIDEO
|
1538
engine/platformWin32/winWindow.cc
Executable file
1538
engine/platformWin32/winWindow.cc
Executable file
File diff suppressed because it is too large
Load Diff
32
engine/platformWin32/win_common_prefix.h
Executable file
32
engine/platformWin32/win_common_prefix.h
Executable file
@ -0,0 +1,32 @@
|
||||
//------------------------------
|
||||
//win_common_prefix.h
|
||||
//------------------------------
|
||||
|
||||
//------------------------------
|
||||
// basic build defines
|
||||
|
||||
// define our platform
|
||||
//#define TARG_WIN32 1
|
||||
//#define WIN32 1
|
||||
|
||||
// normally, this should be on for a PC build
|
||||
//#define USEASSEMBLYTERRBLEND 1
|
||||
|
||||
|
||||
//------------------------------
|
||||
// setup compiler-specific flags
|
||||
|
||||
// METROWERKS CODEWARRIOR
|
||||
//#if __MWERKS__
|
||||
//#pragma once
|
||||
// we turn this on to use inlined CW6-safe ASM in CWProject builds.
|
||||
// ... and thus not require NASM for CWProject building ...
|
||||
//#define TARG_INLINED_ASM 1
|
||||
//#endif
|
||||
|
||||
|
||||
// these are general build flags Torque uses.
|
||||
//#define PNG_NO_READ_tIME 1
|
||||
//#define PNG_NO_WRITE_TIME 1
|
||||
|
||||
//#define NO_MILES_OPENAL 1
|
20
engine/platformWin32/win_debug_prefix.h
Executable file
20
engine/platformWin32/win_debug_prefix.h
Executable file
@ -0,0 +1,20 @@
|
||||
//win_debug_prefix.h
|
||||
|
||||
#include "win_common_prefix.h"
|
||||
|
||||
// our defines
|
||||
#define TORQUE_DEBUG
|
||||
//#define BUILD_SUFFIX "_DEBUG"
|
||||
//#define DEBUG 1
|
||||
//#define ENABLE_ASSERTS 1
|
||||
|
||||
// the PC doesn't need this. just the mac...
|
||||
//#define ITFDUMP_NOASM 1
|
||||
|
||||
|
||||
//#define USEASSEMBLYTERRBLEND 1
|
||||
|
||||
//#define PNG_NO_READ_tIME 1
|
||||
//#define PNG_NO_WRITE_TIME 1
|
||||
|
||||
//#define NO_MILES_OPENAL 1
|
23
engine/platformWin32/win_release_prefix.h
Executable file
23
engine/platformWin32/win_release_prefix.h
Executable file
@ -0,0 +1,23 @@
|
||||
//win_debug_prefix.h
|
||||
|
||||
#include "win_common_prefix.h"
|
||||
|
||||
// our defines
|
||||
//#define TGE_RELEASE 1
|
||||
//#define TGE_NO_ASSERTS 1
|
||||
//#define BUILD_SUFFIX ""
|
||||
|
||||
// these should be off in a release build
|
||||
//#define DEBUG 1
|
||||
//#define ENABLE_ASSERTS 1
|
||||
|
||||
// the PC doesn't need this. just the mac...
|
||||
//#define ITFDUMP_NOASM 1
|
||||
|
||||
|
||||
//#define USEASSEMBLYTERRBLEND 1
|
||||
|
||||
//#define PNG_NO_READ_tIME 1
|
||||
//#define PNG_NO_WRITE_TIME 1
|
||||
|
||||
//#define NO_MILES_OPENAL 1
|
Reference in New Issue
Block a user