2013-06-26 15:22:04 -07:00
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//
//=============================================================================//
# include "glos.h"
# include <gl/gl.h>
# if _MSC_VER < 1600
# include <gl/glaux.h>
# endif
# include <gl/glu.h>
# include <stdarg.h>
# include <string.h>
# include <stdio.h>
# include <math.h>
# include "cmdlib.h"
# include "mathlib/mathlib.h"
# include "cmodel.h"
# include "tier1/strtools.h"
# include "physdll.h"
# include "phyfile.h"
# include "vphysics_interface.h"
# include "tier0/icommandline.h"
# include "tier0/vprof.h"
HDC camdc ;
HGLRC baseRC ;
HWND camerawindow ;
HANDLE main_instance ;
/* YWB: 3/13/98
You run the program like normal with any file . If you want to read portals for the
file type , you type : glview - portal filename . gl0 ( or whatever ) . glview will then
try to read in the . prt file filename . prt .
The portals are shown as white lines superimposed over your image . You can toggle the
view between showing portals or not by hitting the ' 2 ' key . The ' 1 ' key toggles
world polygons .
The ' b ' key toggles blending modes .
If you don ' t want to depth buffer the portals , hit ' p ' .
The command line parsing is inelegant but functional .
I sped up the KB movement and turn speed , too .
*/
// Vars added by YWB
Vector g_Center ; // Center of all read points, so camera is in a sensible place
int g_nTotalPoints = 0 ; // Total points read, for calculating center
int g_UseBlending = 0 ; // Toggle to use blending mode or not
BOOL g_bReadPortals = 0 ; // Did we read in a portal file?
BOOL g_bNoDepthPortals = 0 ; // Do we zbuffer the lines of the portals?
int g_nPortalHighlight = - 1 ; // The leaf we're viewing
int g_nLeafHighlight = - 1 ; // The leaf we're viewing
BOOL g_bShowList1 = 1 ; // Show regular polygons?
BOOL g_bShowList2 = 1 ; // Show portals?
BOOL g_bShowLines = 0 ; // Show outlines of faces
BOOL g_Active = TRUE ;
BOOL g_Update = TRUE ;
BOOL g_bDisp = FALSE ;
IPhysicsCollision * physcollision = NULL ;
// -----------
2014-02-28 14:08:09 -05:00
static int g_Keys [ 256 ] ;
2013-06-26 15:22:04 -07:00
void AppKeyDown ( int key ) ;
void AppKeyUp ( int key ) ;
BOOL ReadDisplacementFile ( const char * filename ) ;
void DrawDisplacementData ( void ) ;
# define BENCHMARK_PHY 0
/*
= = = = = = = = = = = = = = = = =
Error
For abnormal program terminations
= = = = = = = = = = = = = = = = =
*/
void Error ( char * error , . . . )
{
va_list argptr ;
char text [ 1024 ] ;
va_start ( argptr , error ) ;
vsprintf ( text , error , argptr ) ;
va_end ( argptr ) ;
MessageBox ( NULL , text , " Error " , 0 /* MB_OK */ ) ;
exit ( 1 ) ;
}
float origin [ 3 ] = { 32 , 32 , 48 } ;
float angles [ 3 ] ;
float forward [ 3 ] , right [ 3 ] , vup [ 3 ] , vpn [ 3 ] , vright [ 3 ] ;
float width = 1024 ;
float height = 768 ;
float g_flMovementSpeed = 320.f ; // Units / second (run speed of HL)
# define SPEED_TURN 90 // Degrees / second
# define VK_COMMA 188
# define VK_PERIOD 190
void KeyDown ( int key )
{
switch ( key )
{
case VK_ESCAPE :
g_Active = FALSE ;
break ;
case VK_F1 :
glEnable ( GL_CULL_FACE ) ;
glCullFace ( GL_FRONT ) ;
break ;
case ' B ' :
g_UseBlending ^ = 1 ;
if ( g_UseBlending )
glEnable ( GL_BLEND ) ; // YWB TESTING
else
glDisable ( GL_BLEND ) ;
break ;
case ' 1 ' :
g_bShowList1 ^ = 1 ;
break ;
case ' 2 ' :
g_bShowList2 ^ = 1 ;
break ;
case ' P ' :
g_bNoDepthPortals ^ = 1 ;
break ;
case ' L ' :
g_bShowLines ^ = 1 ;
break ;
}
g_Update = TRUE ;
}
static BOOL g_Capture = FALSE ;
# define MOUSE_SENSITIVITY 0.2f
# define MOUSE_SENSITIVITY_X (MOUSE_SENSITIVITY*1)
# define MOUSE_SENSITIVITY_Y (MOUSE_SENSITIVITY*1)
void Cam_MouseMoved ( void )
{
if ( g_Capture )
{
RECT rect ;
int centerx , centery ;
float deltax , deltay ;
POINT cursorPoint ;
GetWindowRect ( camerawindow , & rect ) ;
if ( rect . top < 0 )
rect . top = 0 ;
if ( rect . left < 0 )
rect . left = 0 ;
centerx = ( rect . left + rect . right ) / 2 ;
centery = ( rect . top + rect . bottom ) / 2 ;
GetCursorPos ( & cursorPoint ) ;
SetCursorPos ( centerx , centery ) ;
deltax = ( cursorPoint . x - centerx ) * MOUSE_SENSITIVITY_X ;
deltay = ( cursorPoint . y - centery ) * MOUSE_SENSITIVITY_Y ;
angles [ 1 ] - = deltax ;
angles [ 0 ] - = deltay ;
g_Update = TRUE ;
}
}
int Test_Key ( int key )
{
int r = ( g_Keys [ key ] ! = 0 ) ;
g_Keys [ key ] & = 0x01 ; // clear out debounce bit
if ( r )
g_Update = TRUE ;
return r ;
}
// UNDONE: Probably should change the controls to match the game - but I don't know who relies on them
// as of now.
void Cam_Update ( float frametime )
{
if ( Test_Key ( ' W ' ) )
{
VectorMA ( origin , g_flMovementSpeed * frametime , vpn , origin ) ;
}
if ( Test_Key ( ' S ' ) )
{
VectorMA ( origin , - g_flMovementSpeed * frametime , vpn , origin ) ;
}
if ( Test_Key ( ' A ' ) )
{
VectorMA ( origin , - g_flMovementSpeed * frametime , vright , origin ) ;
}
if ( Test_Key ( ' D ' ) )
{
VectorMA ( origin , g_flMovementSpeed * frametime , vright , origin ) ;
}
if ( Test_Key ( VK_UP ) )
{
VectorMA ( origin , g_flMovementSpeed * frametime , forward , origin ) ;
}
if ( Test_Key ( VK_DOWN ) )
{
VectorMA ( origin , - g_flMovementSpeed * frametime , forward , origin ) ;
}
if ( Test_Key ( VK_LEFT ) )
{
angles [ 1 ] + = SPEED_TURN * frametime ;
}
if ( Test_Key ( VK_RIGHT ) )
{
angles [ 1 ] - = SPEED_TURN * frametime ;
}
if ( Test_Key ( ' F ' ) )
{
origin [ 2 ] + = g_flMovementSpeed * frametime ;
}
if ( Test_Key ( ' C ' ) )
{
origin [ 2 ] - = g_flMovementSpeed * frametime ;
}
if ( Test_Key ( VK_INSERT ) )
{
angles [ 0 ] + = SPEED_TURN * frametime ;
if ( angles [ 0 ] > 85 )
angles [ 0 ] = 85 ;
}
if ( Test_Key ( VK_DELETE ) )
{
angles [ 0 ] - = SPEED_TURN * frametime ;
if ( angles [ 0 ] < - 85 )
angles [ 0 ] = - 85 ;
}
Cam_MouseMoved ( ) ;
}
void Cam_BuildMatrix ( void )
{
float xa , ya ;
float matrix [ 4 ] [ 4 ] ;
int i ;
xa = angles [ 0 ] / 180 * M_PI ;
ya = angles [ 1 ] / 180 * M_PI ;
// the movement matrix is kept 2d ?? do we want this?
forward [ 0 ] = cos ( ya ) ;
forward [ 1 ] = sin ( ya ) ;
right [ 0 ] = forward [ 1 ] ;
right [ 1 ] = - forward [ 0 ] ;
glGetFloatv ( GL_PROJECTION_MATRIX , & matrix [ 0 ] [ 0 ] ) ;
for ( i = 0 ; i < 3 ; i + + )
{
vright [ i ] = matrix [ i ] [ 0 ] ;
vup [ i ] = matrix [ i ] [ 1 ] ;
vpn [ i ] = matrix [ i ] [ 2 ] ;
}
VectorNormalize ( vright ) ;
VectorNormalize ( vup ) ;
VectorNormalize ( vpn ) ;
}
void Draw ( void )
{
float screenaspect ;
float yfov ;
//glClearColor (0.5, 0.5, 0.5, 0);
glClearColor ( 0.0 , 0.0 , 0.0 , 0 ) ; // Black Clearing YWB
glClear ( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ) ;
//
// set up viewpoint
//
glMatrixMode ( GL_PROJECTION ) ;
glLoadIdentity ( ) ;
screenaspect = ( float ) width / height ;
yfov = 2 * atan ( ( float ) height / width ) * 180 / M_PI ;
gluPerspective ( yfov , screenaspect , 6 , 20000 ) ;
glRotatef ( - 90 , 1 , 0 , 0 ) ; // put Z going up
glRotatef ( 90 , 0 , 0 , 1 ) ; // put Z going up
glRotatef ( angles [ 0 ] , 0 , 1 , 0 ) ;
glRotatef ( - angles [ 1 ] , 0 , 0 , 1 ) ;
glTranslatef ( - origin [ 0 ] , - origin [ 1 ] , - origin [ 2 ] ) ;
Cam_BuildMatrix ( ) ;
//
// set drawing parms
//
glShadeModel ( GL_SMOOTH ) ;
glPolygonMode ( GL_FRONT_AND_BACK , GL_FILL ) ;
glFrontFace ( GL_CW ) ; // YWB Carmack goes backward
glCullFace ( GL_BACK ) ; // Cull backfaces (qcsg used to spit out two sides, doesn't for -glview now)
glEnable ( GL_CULL_FACE ) ; // Enable face culling, just in case...
glDisable ( GL_TEXTURE_2D ) ;
// Blending function if enabled..
glBlendFunc ( GL_SRC_ALPHA , GL_ONE_MINUS_SRC_ALPHA ) ;
if ( g_UseBlending )
{
glEnable ( GL_BLEND ) ; // YWB TESTING
glDisable ( GL_DEPTH_TEST ) ;
glDisable ( GL_CULL_FACE ) ; // Enable face culling, just in case...
}
else
{
glDisable ( GL_BLEND ) ;
glEnable ( GL_DEPTH_TEST ) ;
}
glDepthFunc ( GL_LEQUAL ) ;
if ( g_bDisp )
{
DrawDisplacementData ( ) ;
}
else
{
//
// draw the list
//
if ( g_bShowList1 )
glCallList ( 1 ) ;
if ( g_bReadPortals )
{
if ( g_bNoDepthPortals )
glDisable ( GL_DEPTH_TEST ) ;
glDisable ( GL_CULL_FACE ) ; // Disable face culling
if ( g_bShowList2 )
glCallList ( 2 ) ;
} ;
if ( g_bShowLines )
glCallList ( 3 ) ;
}
}
void ReadPolyFileType ( const char * name , int nList , BOOL drawLines )
{
FILE * f ;
int i , j , numverts ;
float v [ 8 ] ;
int c ;
int r ;
float divisor ;
f = fopen ( name , " rt " ) ;
if ( ! f )
Error ( " Couldn't open %s " , name ) ;
if ( g_bReadPortals )
divisor = 2.0f ;
else
divisor = 1.0f ;
c = 0 ;
glNewList ( nList , GL_COMPILE ) ;
for ( i = 0 ; i < 3 ; i + + ) // Find the center point so we can put the viewer there by default
g_Center [ i ] = 0.0f ;
if ( drawLines ) // Slight hilite
glLineWidth ( 1.5 ) ;
while ( 1 )
{
r = fscanf ( f , " %i \n " , & numverts ) ;
if ( ! r | | r = = EOF )
break ;
if ( c > 65534 * 8 )
break ;
if ( drawLines | | numverts = = 2 )
glBegin ( GL_LINE_LOOP ) ;
else
glBegin ( GL_POLYGON ) ;
for ( i = 0 ; i < numverts ; i + + )
{
r = fscanf ( f , " %f %f %f %f %f %f \n " , & v [ 0 ] , & v [ 1 ] ,
& v [ 2 ] , & v [ 3 ] , & v [ 4 ] , & v [ 5 ] ) ;
/*
if ( ! ( fabs ( v [ 0 ] ) < 32768.0 & & fabs ( v [ 1 ] ) < 32768.0 & & fabs ( v [ 2 ] ) < 32768.0 ) )
Error ( " Out of range data \n " ) ;
*/
/*
if ( v [ 3 ] < = 0.1 & & v [ 4 ] < = 0.1 & & v [ 5 ] < = 0.1 )
continue ;
*/
if ( drawLines ) // YELLOW OUTLINES
glColor4f ( 1.0 , 1.0 , 0.0 , 0.5 ) ;
else
{
if ( g_bReadPortals ) // Gray scale it, leave portals blue
{
if ( fabs ( fabs ( v [ 5 ] ) - 1.0f ) < 0.01 ) // Is this a detail brush (color 0,0,1 blue)
{
glColor4f ( v [ 3 ] , v [ 4 ] , v [ 5 ] , 0.5 ) ;
}
else // Normal brush, gray scale it...
{
v [ 3 ] + = v [ 4 ] + v [ 5 ] ;
v [ 3 ] / = 3.0f ;
glColor4f ( v [ 3 ] / divisor , v [ 3 ] / divisor , v [ 3 ] / divisor , 0.6 ) ;
}
}
else
{
v [ 3 ] = pow ( v [ 3 ] , ( float ) ( 1.0 / 2.2 ) ) ;
v [ 4 ] = pow ( v [ 4 ] , ( float ) ( 1.0 / 2.2 ) ) ;
v [ 5 ] = pow ( v [ 5 ] , ( float ) ( 1.0 / 2.2 ) ) ;
glColor4f ( v [ 3 ] / divisor , v [ 4 ] / divisor , v [ 5 ] / divisor , 0.6 ) ; // divisor is one, bright colors
} ;
} ;
glVertex3f ( v [ 0 ] , v [ 1 ] , v [ 2 ] ) ;
for ( j = 0 ; j < 3 ; j + + )
{
g_Center [ j ] + = v [ j ] ;
}
g_nTotalPoints + + ;
}
glEnd ( ) ;
c + + ;
}
if ( f )
fclose ( f ) ;
glEndList ( ) ;
if ( g_nTotalPoints > 0 ) // Avoid division by zero
{
for ( i = 0 ; i < 3 ; i + + )
{
g_Center [ i ] = g_Center [ i ] / ( float ) g_nTotalPoints ; // Calculate center...
origin [ i ] = g_Center [ i ] ;
}
}
}
# if BENCHMARK_PHY
# define NUM_COLLISION_TESTS 2500
# include "gametrace.h"
# include "fmtstr.h"
struct testlist_t
{
Vector start ;
Vector end ;
Vector normal ;
bool hit ;
} ;
const float baselineTotal = 120.16f ;
const float baselineRay = 28.25f ;
const float baselineBox = 91.91f ;
# define IMPROVEMENT_FACTOR(x,baseline) (baseline / (x))
# define IMPROVEMENT_PERCENT(x,baseline) (((baseline-(x)) / baseline) * 100.0f)
testlist_t g_Traces [ NUM_COLLISION_TESTS ] ;
void Benchmark_PHY ( const CPhysCollide * pCollide )
{
int i ;
Msg ( " Testing collision system \n " ) ;
Vector start = vec3_origin ;
static Vector * targets = NULL ;
static bool first = true ;
static float test [ 2 ] = { 1 , 1 } ;
if ( first )
{
float radius = 0 ;
float theta = 0 ;
float phi = 0 ;
for ( int i = 0 ; i < NUM_COLLISION_TESTS ; i + + )
{
radius + = NUM_COLLISION_TESTS * 123.123f ;
radius = fabs ( fmod ( radius , 128 ) ) ;
theta + = NUM_COLLISION_TESTS * 0.76f ;
theta = fabs ( fmod ( theta , DEG2RAD ( 360 ) ) ) ;
phi + = NUM_COLLISION_TESTS * 0.16666666f ;
phi = fabs ( fmod ( phi , DEG2RAD ( 180 ) ) ) ;
float st , ct , sp , cp ;
SinCos ( theta , & st , & ct ) ;
SinCos ( phi , & sp , & cp ) ;
st = sin ( theta ) ;
ct = cos ( theta ) ;
sp = sin ( phi ) ;
cp = cos ( phi ) ;
g_Traces [ i ] . start . x = radius * ct * sp ;
g_Traces [ i ] . start . y = radius * st * sp ;
g_Traces [ i ] . start . z = radius * cp ;
}
first = false ;
}
float duration = 0 ;
Vector size [ 2 ] ;
size [ 0 ] . Init ( 0 , 0 , 0 ) ;
size [ 1 ] . Init ( 16 , 16 , 16 ) ;
unsigned int dots = 0 ;
# if VPROF_LEVEL > 0
g_VProfCurrentProfile . Reset ( ) ;
g_VProfCurrentProfile . ResetPeaks ( ) ;
g_VProfCurrentProfile . Start ( ) ;
# endif
unsigned int hitCount = 0 ;
double startTime = Plat_FloatTime ( ) ;
trace_t tr ;
for ( i = 0 ; i < NUM_COLLISION_TESTS ; i + + )
{
physcollision - > TraceBox ( g_Traces [ i ] . start , start , - size [ 0 ] , size [ 0 ] , pCollide , vec3_origin , vec3_angle , & tr ) ;
if ( tr . DidHit ( ) )
{
g_Traces [ i ] . end = tr . endpos ;
g_Traces [ i ] . normal = tr . plane . normal ;
g_Traces [ i ] . hit = true ;
hitCount + + ;
}
else
{
g_Traces [ i ] . hit = false ;
}
}
for ( i = 0 ; i < NUM_COLLISION_TESTS ; i + + )
{
physcollision - > TraceBox ( g_Traces [ i ] . start , start , - size [ 1 ] , size [ 1 ] , pCollide , vec3_origin , vec3_angle , & tr ) ;
}
duration = Plat_FloatTime ( ) - startTime ;
{
unsigned int msSupp = physcollision - > ReadStat ( 100 ) ;
unsigned int msGJK = physcollision - > ReadStat ( 101 ) ;
unsigned int msMesh = physcollision - > ReadStat ( 102 ) ;
CFmtStr str ( " %d ms total %d ms gjk %d mesh solve \n " , msSupp , msGJK , msMesh ) ;
OutputDebugStr ( str . Access ( ) ) ;
}
# if VPROF_LEVEL > 0
g_VProfCurrentProfile . MarkFrame ( ) ;
g_VProfCurrentProfile . Stop ( ) ;
g_VProfCurrentProfile . Reset ( ) ;
g_VProfCurrentProfile . ResetPeaks ( ) ;
g_VProfCurrentProfile . Start ( ) ;
# endif
hitCount = 0 ;
startTime = Plat_FloatTime ( ) ;
for ( i = 0 ; i < NUM_COLLISION_TESTS ; i + + )
{
physcollision - > TraceBox ( g_Traces [ i ] . start , start , - size [ 0 ] , size [ 0 ] , pCollide , vec3_origin , vec3_angle , & tr ) ;
if ( tr . DidHit ( ) )
{
g_Traces [ i ] . end = tr . endpos ;
g_Traces [ i ] . normal = tr . plane . normal ;
g_Traces [ i ] . hit = true ;
hitCount + + ;
}
else
{
g_Traces [ i ] . hit = false ;
}
# if VPROF_LEVEL > 0
g_VProfCurrentProfile . MarkFrame ( ) ;
# endif
}
double midTime = Plat_FloatTime ( ) ;
for ( i = 0 ; i < NUM_COLLISION_TESTS ; i + + )
{
physcollision - > TraceBox ( g_Traces [ i ] . start , start , - size [ 1 ] , size [ 1 ] , pCollide , vec3_origin , vec3_angle , & tr ) ;
# if VPROF_LEVEL > 0
g_VProfCurrentProfile . MarkFrame ( ) ;
# endif
}
double endTime = Plat_FloatTime ( ) ;
duration = endTime - startTime ;
{
CFmtStr str ( " %d collisions in %.2f ms [%.2f X] %d hits \n " , NUM_COLLISION_TESTS , duration * 1000 , IMPROVEMENT_FACTOR ( duration * 1000.0f , baselineTotal ) , hitCount ) ;
OutputDebugStr ( str . Access ( ) ) ;
}
{
float rayTime = ( midTime - startTime ) * 1000.0f ;
float boxTime = ( endTime - midTime ) * 1000.0f ;
CFmtStr str ( " %.2f ms rays [%.2f X] %.2f ms boxes [%.2f X] \n " , rayTime , IMPROVEMENT_FACTOR ( rayTime , baselineRay ) , boxTime , IMPROVEMENT_FACTOR ( boxTime , baselineBox ) ) ;
OutputDebugStr ( str . Access ( ) ) ;
}
{
unsigned int msSupp = physcollision - > ReadStat ( 100 ) ;
unsigned int msGJK = physcollision - > ReadStat ( 101 ) ;
unsigned int msMesh = physcollision - > ReadStat ( 102 ) ;
CFmtStr str ( " %d ms total %d ms gjk %d mesh solve \n " , msSupp , msGJK , msMesh ) ;
OutputDebugStr ( str . Access ( ) ) ;
}
# if VPROF_LEVEL > 0
g_VProfCurrentProfile . Stop ( ) ;
g_VProfCurrentProfile . OutputReport ( VPRT_FULL & ~ VPRT_HIERARCHY , NULL ) ;
# endif
// draw the traces in yellow
glColor3f ( 1.0f , 1.0f , 0.0f ) ;
glBegin ( GL_LINES ) ;
for ( int i = 0 ; i < NUM_COLLISION_TESTS ; i + + )
{
if ( ! g_Traces [ i ] . hit )
continue ;
glVertex3fv ( g_Traces [ i ] . end . Base ( ) ) ;
Vector tmp = g_Traces [ i ] . end + g_Traces [ i ] . normal * 10.0f ;
glVertex3fv ( tmp . Base ( ) ) ;
}
glEnd ( ) ;
}
# endif
struct phyviewparams_t
{
Vector mins ;
Vector maxs ;
Vector offset ;
QAngle angles ;
int outputType ;
void Defaults ( )
{
ClearBounds ( mins , maxs ) ;
offset . Init ( ) ;
outputType = GL_POLYGON ;
angles . Init ( ) ;
}
} ;
void AddVCollideToList ( phyheader_t & header , vcollide_t & collide , phyviewparams_t & params )
{
matrix3x4_t xform ;
AngleMatrix ( params . angles , params . offset , xform ) ;
ClearBounds ( params . mins , params . maxs ) ;
for ( int i = 0 ; i < header . solidCount ; i + + )
{
ICollisionQuery * pQuery = physcollision - > CreateQueryModel ( collide . solids [ i ] ) ;
for ( int j = 0 ; j < pQuery - > ConvexCount ( ) ; j + + )
{
for ( int k = 0 ; k < pQuery - > TriangleCount ( j ) ; k + + )
{
Vector verts [ 3 ] ;
pQuery - > GetTriangleVerts ( j , k , verts ) ;
Vector v0 , v1 , v2 ;
VectorTransform ( verts [ 0 ] , xform , v0 ) ;
VectorTransform ( verts [ 1 ] , xform , v1 ) ;
VectorTransform ( verts [ 2 ] , xform , v2 ) ;
AddPointToBounds ( v0 , params . mins , params . maxs ) ;
AddPointToBounds ( v1 , params . mins , params . maxs ) ;
AddPointToBounds ( v2 , params . mins , params . maxs ) ;
glBegin ( params . outputType ) ;
glColor3ub ( 255 , 0 , 0 ) ;
glVertex3fv ( v0 . Base ( ) ) ;
glColor3ub ( 0 , 255 , 0 ) ;
glVertex3fv ( v1 . Base ( ) ) ;
glColor3ub ( 0 , 0 , 255 ) ;
glVertex3fv ( v2 . Base ( ) ) ;
glEnd ( ) ;
}
}
physcollision - > DestroyQueryModel ( pQuery ) ;
}
}
void GL_DrawLine ( const Vector & start , const Vector & dir , float length , int r , int g , int b )
{
Vector end = start + ( dir * length ) ;
glBegin ( GL_LINES ) ;
glColor3ub ( r , g , b ) ;
glVertex3fv ( start . Base ( ) ) ;
glVertex3fv ( end . Base ( ) ) ;
glEnd ( ) ;
}
void GL_DrawBox ( Vector origin , float size , int r , int g , int b )
{
Vector mins = origin - Vector ( size , size , size ) ;
Vector maxs = origin + Vector ( size , size , size ) ;
const float * v [ 2 ] = { mins . Base ( ) , maxs . Base ( ) } ;
Vector start , end ;
{
for ( int i = 0 ; i < 3 ; i + + )
{
int a0 = i ;
int a1 = ( i + 1 ) % 3 ;
int a2 = ( i + 2 ) % 3 ;
for ( int j = 0 ; j < 2 ; j + + )
{
for ( int k = 0 ; k < 2 ; k + + )
{
start [ a0 ] = v [ 0 ] [ a0 ] ;
end [ a0 ] = v [ 1 ] [ a0 ] ;
start [ a1 ] = v [ j ] [ a1 ] ;
end [ a1 ] = v [ j ] [ a1 ] ;
start [ a2 ] = v [ k ] [ a2 ] ;
end [ a2 ] = v [ k ] [ a2 ] ;
GL_DrawLine ( start , end - start , 1 , r , g , b ) ;
}
}
}
}
for ( int axis = 0 ; axis < 3 ; axis + + )
{
int a0 = axis ;
int a1 = ( axis + 1 ) % 3 ;
int a2 = ( axis + 2 ) % 3 ;
start [ a0 ] = v [ 0 ] [ a0 ] ;
end [ a0 ] = v [ 1 ] [ a0 ] ;
start [ a1 ] = 0.5f * ( v [ 0 ] [ a1 ] + v [ 1 ] [ a1 ] ) ;
end [ a1 ] = 0.5f * ( v [ 0 ] [ a1 ] + v [ 1 ] [ a1 ] ) ;
start [ a2 ] = 0.5f * ( v [ 0 ] [ a2 ] + v [ 1 ] [ a2 ] ) ;
end [ a2 ] = 0.5f * ( v [ 0 ] [ a2 ] + v [ 1 ] [ a2 ] ) ;
GL_DrawLine ( start , end - start , 1 , r , g , b ) ;
}
}
void ReadPHYFile ( const char * name , phyviewparams_t & params )
{
FILE * fp = fopen ( name , " rb " ) ;
if ( ! fp )
Error ( " Couldn't open %s " , name ) ;
phyheader_t header ;
fread ( & header , sizeof ( header ) , 1 , fp ) ;
if ( header . size ! = sizeof ( header ) | | header . solidCount < = 0 )
return ;
int pos = ftell ( fp ) ;
fseek ( fp , 0 , SEEK_END ) ;
int fileSize = ftell ( fp ) - pos ;
fseek ( fp , pos , SEEK_SET ) ;
char * buf = ( char * ) _alloca ( fileSize ) ;
fread ( buf , fileSize , 1 , fp ) ;
fclose ( fp ) ;
vcollide_t collide ;
physcollision - > VCollideLoad ( & collide , header . solidCount , ( const char * ) buf , fileSize ) ;
#if 0
Vector start0 ( - 3859.1199 , - 2050.8674 , 64.031250 ) ;
Vector end0 ( - 3859.2246 , - 2051.2817 , 64.031250 ) ;
Vector modelPosition ( - 3840 , - 2068.0000 , 82.889099 ) ;
QAngle modelAngles ( 0 , 90 , 0 ) ;
{
Ray_t ray ;
ray . Init ( start0 , end0 , Vector ( - 16 , - 16 , 0 ) , Vector ( 16 , 16 , 72 ) ) ;
trace_t tr ;
physcollision - > TraceBox ( ray , collide . solids [ 0 ] , modelPosition , modelAngles , & tr ) ;
Assert ( ! tr . startsolid ) ;
if ( tr . DidHit ( ) )
{
Ray_t ray2 ;
ray2 . Init ( tr . endpos , tr . endpos , Vector ( - 16 , - 16 , 0 ) , Vector ( 16 , 16 , 72 ) ) ;
trace_t tr2 ;
physcollision - > TraceBox ( ray2 , collide . solids [ 0 ] , modelPosition , modelAngles , & tr2 ) ;
Assert ( ! tr2 . startsolid ) ;
}
}
# endif
# if BENCHMARK_PHY
Benchmark_PHY ( collide . solids [ 0 ] ) ;
# endif
AddVCollideToList ( header , collide , params ) ;
}
void ReadPolyFile ( const char * name )
{
char ext [ 4 ] ;
Q_ExtractFileExtension ( name , ext , 4 ) ;
bool isPHY = ! Q_stricmp ( ext , " phy " ) ;
if ( isPHY )
{
CreateInterfaceFn physicsFactory = GetPhysicsFactory ( ) ;
physcollision = ( IPhysicsCollision * ) physicsFactory ( VPHYSICS_COLLISION_INTERFACE_VERSION , NULL ) ;
if ( physcollision )
{
phyviewparams_t params ;
params . Defaults ( ) ;
glNewList ( 1 , GL_COMPILE ) ;
ReadPHYFile ( name , params ) ;
Vector tmp = ( params . mins + params . maxs ) * 0.5 ;
tmp . CopyToArray ( origin ) ;
glEndList ( ) ;
}
}
else
{
// Read in polys...
ReadPolyFileType ( name , 1 , false ) ;
// Make list 3 just the lines... so we can draw outlines
ReadPolyFileType ( name , 3 , true ) ;
}
}
void ReadPortalFile ( char * name )
{
FILE * f ;
int i , numverts ;
float v [ 8 ] ;
int c ;
int r ;
// For Portal type reading...
char szDummy [ 80 ] ;
int nNumLeafs ;
int nNumPortals ;
int nLeafIndex [ 2 ] ;
f = fopen ( name , " r " ) ;
if ( ! f )
Error ( " Couldn't open %s " , name ) ;
c = 0 ;
glNewList ( 2 , GL_COMPILE ) ;
// Read in header
fscanf ( f , " %79s \n " , szDummy ) ;
fscanf ( f , " %i \n " , & nNumLeafs ) ;
fscanf ( f , " %i \n " , & nNumPortals ) ;
glLineWidth ( 1.5 ) ;
while ( 1 )
{
r = fscanf ( f , " %i %i %i " , & numverts , & nLeafIndex [ 0 ] , & nLeafIndex [ 1 ] ) ;
if ( ! r | | r = = EOF )
break ;
glBegin ( GL_LINE_LOOP ) ;
for ( i = 0 ; i < numverts ; i + + )
{
r = fscanf ( f , " (%f %f %f ) \n " , & v [ 0 ] , & v [ 1 ] ,
& v [ 2 ] ) ;
if ( ! r | | ( r ! = 3 ) | | r = = EOF )
break ;
if ( c = = g_nPortalHighlight | | nLeafIndex [ 0 ] = = g_nLeafHighlight | | nLeafIndex [ 1 ] = = g_nLeafHighlight )
{
glColor4f ( 1.0 , 0.0 , 0.0 , 1.0 ) ;
}
else
{
glColor4f ( 1.0f , 1.0f , 1.0f , 1.0f ) ; // WHITE portals
}
glVertex3f ( v [ 0 ] , v [ 1 ] , v [ 2 ] ) ;
}
glEnd ( ) ;
c + + ;
}
if ( f )
fclose ( f ) ;
glEndList ( ) ;
}
# define MAX_DISP_COUNT 4096
static Vector dispPoints [ MAX_DISP_COUNT ] ;
static Vector dispNormals [ MAX_DISP_COUNT ] ;
static int dispPointCount = 0 ;
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
BOOL ReadDisplacementFile ( const char * filename )
{
FILE * pFile ;
int fileCount ;
//
// open the file
//
pFile = fopen ( filename , " r " ) ;
if ( ! pFile )
Error ( " Couldn't open %s " , filename ) ;
//
// read data in file
//
while ( 1 )
{
// overflow test
if ( dispPointCount > = MAX_DISP_COUNT )
break ;
fileCount = fscanf ( pFile , " %f %f %f %f %f %f " ,
& dispPoints [ dispPointCount ] [ 0 ] , & dispPoints [ dispPointCount ] [ 1 ] , & dispPoints [ dispPointCount ] [ 2 ] ,
& dispNormals [ dispPointCount ] [ 0 ] , & dispNormals [ dispPointCount ] [ 1 ] , & dispNormals [ dispPointCount ] [ 2 ] ) ;
dispPointCount + + ;
// end of file check
if ( ! fileCount | | ( fileCount = = EOF ) )
break ;
}
fclose ( pFile ) ;
return TRUE ;
}
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
void DrawDisplacementData ( void )
{
int i , j ;
int width , halfCount ;
GLUquadricObj * pObject = gluNewQuadric ( ) ;
glEnable ( GL_DEPTH_TEST ) ;
for ( i = 0 ; i < dispPointCount ; i + + )
{
// draw a sphere where the point is (in red)
glColor3f ( 1.0f , 0.0f , 0.0f ) ;
glPushMatrix ( ) ;
glTranslatef ( dispPoints [ i ] [ 0 ] , dispPoints [ i ] [ 1 ] , dispPoints [ i ] [ 2 ] ) ;
gluSphere ( pObject , 5 , 5 , 5 ) ;
glPopMatrix ( ) ;
// draw the normal (in yellow)
glColor3f ( 1.0f , 1.0f , 0.0f ) ;
glBegin ( GL_LINES ) ;
glVertex3f ( dispPoints [ i ] [ 0 ] , dispPoints [ i ] [ 1 ] , dispPoints [ i ] [ 2 ] ) ;
glVertex3f ( dispPoints [ i ] [ 0 ] + ( dispNormals [ i ] [ 0 ] * 50.0f ) , dispPoints [ i ] [ 1 ] + ( dispNormals [ i ] [ 1 ] * 50.0f ) , dispPoints [ i ] [ 2 ] + ( dispNormals [ i ] [ 2 ] * 50.0f ) ) ;
glEnd ( ) ;
}
halfCount = dispPointCount / 2 ;
width = sqrt ( ( float ) halfCount ) ;
glDisable ( GL_CULL_FACE ) ;
glColor3f ( 0.0f , 0.0f , 1.0f ) ;
for ( i = 0 ; i < width - 1 ; i + + )
{
for ( j = 0 ; j < width - 1 ; j + + )
{
glBegin ( GL_POLYGON ) ;
glVertex3f ( dispPoints [ i * width + j ] [ 0 ] , dispPoints [ i * width + j ] [ 1 ] , dispPoints [ i * width + j ] [ 2 ] ) ;
glVertex3f ( dispPoints [ ( i + 1 ) * width + j ] [ 0 ] , dispPoints [ ( i + 1 ) * width + j ] [ 1 ] , dispPoints [ ( i + 1 ) * width + j ] [ 2 ] ) ;
glVertex3f ( dispPoints [ ( i + 1 ) * width + ( j + 1 ) ] [ 0 ] , dispPoints [ ( i + 1 ) * width + ( j + 1 ) ] [ 1 ] , dispPoints [ ( i + 1 ) * width + ( j + 1 ) ] [ 2 ] ) ;
glVertex3f ( dispPoints [ i * width + ( j + 1 ) ] [ 0 ] , dispPoints [ i * width + ( j + 1 ) ] [ 1 ] , dispPoints [ i * width + ( j + 1 ) ] [ 2 ] ) ;
glEnd ( ) ;
}
}
#if 0
for ( i = 0 ; i < width - 1 ; i + + )
{
for ( j = 0 ; j < width - 1 ; j + + )
{
glBegin ( GL_POLYGON ) ;
glVertex3f ( dispPoints [ halfCount + ( i * width + j ) ] [ 0 ] , dispPoints [ halfCount + ( i * width + j ) ] [ 1 ] , dispPoints [ halfCount + ( i * width + j ) ] [ 2 ] ) ;
glVertex3f ( dispPoints [ halfCount + ( ( i + 1 ) * width + j ) ] [ 0 ] , dispPoints [ halfCount + ( i + 1 ) * width + j ] [ 1 ] , dispPoints [ halfCount + ( ( i + 1 ) * width + j ) ] [ 2 ] ) ;
glVertex3f ( dispPoints [ halfCount + ( ( i + 1 ) * width + ( j + 1 ) ) ] [ 0 ] , dispPoints [ halfCount + ( i + 1 ) * width + ( j + 1 ) ] [ 1 ] , dispPoints [ halfCount + ( ( i + 1 ) * width + ( j + 1 ) ) ] [ 2 ] ) ;
glVertex3f ( dispPoints [ halfCount + ( i * width + ( j + 1 ) ) ] [ 0 ] , dispPoints [ halfCount + ( i * width + ( j + 1 ) ) ] [ 1 ] , dispPoints [ halfCount + ( i * width + ( j + 1 ) ) ] [ 2 ] ) ;
glEnd ( ) ;
}
}
# endif
glColor3f ( 0.0f , 1.0f , 0.0f ) ;
for ( i = 0 ; i < width - 1 ; i + + )
{
for ( j = 0 ; j < width - 1 ; j + + )
{
glBegin ( GL_POLYGON ) ;
glVertex3f ( dispPoints [ i * width + j ] [ 0 ] + ( dispNormals [ i * width + j ] [ 0 ] * 150.0f ) ,
dispPoints [ i * width + j ] [ 1 ] + ( dispNormals [ i * width + j ] [ 1 ] * 150.0f ) ,
dispPoints [ i * width + j ] [ 2 ] + ( dispNormals [ i * width + j ] [ 2 ] * 150.0f ) ) ;
glVertex3f ( dispPoints [ ( i + 1 ) * width + j ] [ 0 ] + ( dispNormals [ ( i + 1 ) * width + j ] [ 0 ] * 150.0f ) ,
dispPoints [ ( i + 1 ) * width + j ] [ 1 ] + ( dispNormals [ ( i + 1 ) * width + j ] [ 1 ] * 150.0f ) ,
dispPoints [ ( i + 1 ) * width + j ] [ 2 ] + ( dispNormals [ ( i + 1 ) * width + j ] [ 2 ] * 150.0f ) ) ;
glVertex3f ( dispPoints [ ( i + 1 ) * width + ( j + 1 ) ] [ 0 ] + ( dispNormals [ ( i + 1 ) * width + ( j + 1 ) ] [ 0 ] * 150.0f ) ,
dispPoints [ ( i + 1 ) * width + ( j + 1 ) ] [ 1 ] + ( dispNormals [ ( i + 1 ) * width + ( j + 1 ) ] [ 1 ] * 150.0f ) ,
dispPoints [ ( i + 1 ) * width + ( j + 1 ) ] [ 2 ] + ( dispNormals [ ( i + 1 ) * width + ( j + 1 ) ] [ 2 ] * 150.0f ) ) ;
glVertex3f ( dispPoints [ i * width + ( j + 1 ) ] [ 0 ] + ( dispNormals [ i * width + ( j + 1 ) ] [ 0 ] * 150.0f ) ,
dispPoints [ i * width + ( j + 1 ) ] [ 1 ] + ( dispNormals [ i * width + ( j + 1 ) ] [ 1 ] * 150.0f ) ,
dispPoints [ i * width + ( j + 1 ) ] [ 2 ] + ( dispNormals [ i * width + ( j + 1 ) ] [ 2 ] * 150.0f ) ) ;
glEnd ( ) ;
}
}
glDisable ( GL_DEPTH_TEST ) ;
glColor3f ( 0.0f , 0.0f , 1.0f ) ;
for ( i = 0 ; i < width - 1 ; i + + )
{
for ( j = 0 ; j < width - 1 ; j + + )
{
glBegin ( GL_LINE_LOOP ) ;
glVertex3f ( dispPoints [ i * width + j ] [ 0 ] + ( dispNormals [ i * width + j ] [ 0 ] * 150.0f ) ,
dispPoints [ i * width + j ] [ 1 ] + ( dispNormals [ i * width + j ] [ 1 ] * 150.0f ) ,
dispPoints [ i * width + j ] [ 2 ] + ( dispNormals [ i * width + j ] [ 2 ] * 150.0f ) ) ;
glVertex3f ( dispPoints [ ( i + 1 ) * width + j ] [ 0 ] + ( dispNormals [ ( i + 1 ) * width + j ] [ 0 ] * 150.0f ) ,
dispPoints [ ( i + 1 ) * width + j ] [ 1 ] + ( dispNormals [ ( i + 1 ) * width + j ] [ 1 ] * 150.0f ) ,
dispPoints [ ( i + 1 ) * width + j ] [ 2 ] + ( dispNormals [ ( i + 1 ) * width + j ] [ 2 ] * 150.0f ) ) ;
glVertex3f ( dispPoints [ ( i + 1 ) * width + ( j + 1 ) ] [ 0 ] + ( dispNormals [ ( i + 1 ) * width + ( j + 1 ) ] [ 0 ] * 150.0f ) ,
dispPoints [ ( i + 1 ) * width + ( j + 1 ) ] [ 1 ] + ( dispNormals [ ( i + 1 ) * width + ( j + 1 ) ] [ 1 ] * 150.0f ) ,
dispPoints [ ( i + 1 ) * width + ( j + 1 ) ] [ 2 ] + ( dispNormals [ ( i + 1 ) * width + ( j + 1 ) ] [ 2 ] * 150.0f ) ) ;
glVertex3f ( dispPoints [ i * width + ( j + 1 ) ] [ 0 ] + ( dispNormals [ i * width + ( j + 1 ) ] [ 0 ] * 150.0f ) ,
dispPoints [ i * width + ( j + 1 ) ] [ 1 ] + ( dispNormals [ i * width + ( j + 1 ) ] [ 1 ] * 150.0f ) ,
dispPoints [ i * width + ( j + 1 ) ] [ 2 ] + ( dispNormals [ i * width + ( j + 1 ) ] [ 2 ] * 150.0f ) ) ;
glEnd ( ) ;
}
}
gluDeleteQuadric ( pObject ) ;
}
//=====================================================================
BOOL bSetupPixelFormat ( HDC hDC )
{
static PIXELFORMATDESCRIPTOR pfd = {
sizeof ( PIXELFORMATDESCRIPTOR ) , // size of this pfd
1 , // version number
PFD_DRAW_TO_WINDOW | // support window
PFD_SUPPORT_OPENGL | // support OpenGL
PFD_DOUBLEBUFFER , // double buffered
PFD_TYPE_RGBA , // RGBA type
24 , // 24-bit color depth
0 , 0 , 0 , 0 , 0 , 0 , // color bits ignored
0 , // no alpha buffer
0 , // shift bit ignored
0 , // no accumulation buffer
0 , 0 , 0 , 0 , // accum bits ignored
32 , // 32-bit z-buffer
0 , // no stencil buffer
0 , // no auxiliary buffer
PFD_MAIN_PLANE , // main layer
0 , // reserved
0 , 0 , 0 // layer masks ignored
} ;
int pixelformat = 0 ;
if ( ( pixelformat = ChoosePixelFormat ( hDC , & pfd ) ) = = 0 )
Error ( " ChoosePixelFormat failed " ) ;
if ( ! SetPixelFormat ( hDC , pixelformat , & pfd ) )
Error ( " SetPixelFormat failed " ) ;
return TRUE ;
}
/*
= = = = = = = = = = = =
CameraWndProc
= = = = = = = = = = = =
*/
LONG WINAPI WCam_WndProc (
HWND hWnd ,
UINT uMsg ,
WPARAM wParam ,
LPARAM lParam )
{
LONG lRet = 1 ;
RECT rect ;
GetClientRect ( hWnd , & rect ) ;
switch ( uMsg )
{
case WM_CREATE :
{
camdc = GetDC ( hWnd ) ;
bSetupPixelFormat ( camdc ) ;
baseRC = wglCreateContext ( camdc ) ;
if ( ! baseRC )
Error ( " wglCreateContext failed " ) ;
if ( ! wglMakeCurrent ( camdc , baseRC ) )
Error ( " wglMakeCurrent failed " ) ;
glCullFace ( GL_FRONT ) ;
glEnable ( GL_CULL_FACE ) ;
}
break ;
case WM_PAINT :
{
PAINTSTRUCT ps ;
BeginPaint ( hWnd , & ps ) ;
if ( ! wglMakeCurrent ( camdc , baseRC ) )
Error ( " wglMakeCurrent failed " ) ;
Draw ( ) ;
SwapBuffers ( camdc ) ;
EndPaint ( hWnd , & ps ) ;
}
break ;
case WM_KEYDOWN :
KeyDown ( wParam ) ;
AppKeyDown ( wParam ) ;
break ;
case WM_KEYUP :
AppKeyUp ( wParam ) ;
break ;
case WM_MBUTTONDOWN :
case WM_RBUTTONDOWN :
case WM_LBUTTONDOWN :
SetCapture ( camerawindow ) ;
ShowCursor ( FALSE ) ;
g_Capture = TRUE ;
break ;
case WM_MBUTTONUP :
case WM_RBUTTONUP :
case WM_LBUTTONUP :
if ( ! ( wParam & ( MK_LBUTTON | MK_RBUTTON | MK_MBUTTON ) ) )
{
g_Capture = FALSE ;
ReleaseCapture ( ) ;
ShowCursor ( TRUE ) ;
}
break ;
case WM_SIZE :
InvalidateRect ( camerawindow , NULL , false ) ;
break ;
case WM_NCCALCSIZE : // don't let windows copy pixels
lRet = DefWindowProc ( hWnd , uMsg , wParam , lParam ) ;
return WVR_REDRAW ;
case WM_CLOSE :
/* call destroy window to cleanup and go away */
DestroyWindow ( hWnd ) ;
break ;
case WM_DESTROY :
{
HGLRC hRC ;
HDC hDC ;
/* release and free the device context and rendering context */
hRC = wglGetCurrentContext ( ) ;
hDC = wglGetCurrentDC ( ) ;
wglMakeCurrent ( NULL , NULL ) ;
if ( hRC )
wglDeleteContext ( hRC ) ;
if ( hDC )
ReleaseDC ( hWnd , hDC ) ;
PostQuitMessage ( 0 ) ;
}
break ;
default :
/* pass all unhandled messages to DefWindowProc */
lRet = DefWindowProc ( hWnd , uMsg , wParam , lParam ) ;
break ;
}
/* return 1 if handled message, 0 if not */
return lRet ;
}
/*
= = = = = = = = = = = = = =
WCam_Register
= = = = = = = = = = = = = =
*/
void WCam_Register ( HINSTANCE hInstance )
{
WNDCLASS wc ;
/* Register the camera class */
memset ( & wc , 0 , sizeof ( wc ) ) ;
wc . style = 0 ;
wc . lpfnWndProc = ( WNDPROC ) WCam_WndProc ;
wc . cbClsExtra = 0 ;
wc . cbWndExtra = 0 ;
wc . hInstance = hInstance ;
wc . hIcon = 0 ;
wc . hCursor = LoadCursor ( NULL , IDC_ARROW ) ;
wc . hbrBackground = NULL ;
wc . lpszMenuName = 0 ;
wc . lpszClassName = " camera " ;
if ( ! RegisterClass ( & wc ) )
Error ( " WCam_Register: failed " ) ;
}
void WCam_Create ( HINSTANCE hInstance )
{
// Center it
int nScx , nScy ;
int w , h ;
int x , y ;
WCam_Register ( hInstance ) ;
w = : : width ;
h = : : height ;
nScx = GetSystemMetrics ( SM_CXSCREEN ) ;
nScy = GetSystemMetrics ( SM_CYSCREEN ) ;
x = ( nScx - w ) / 2 ;
y = ( nScy - h ) / 2 ;
camerawindow = CreateWindow ( " camera " ,
" Camera View " ,
WS_OVERLAPPED |
WS_CAPTION |
WS_SYSMENU |
WS_THICKFRAME |
WS_MAXIMIZEBOX |
WS_CLIPSIBLINGS |
WS_CLIPCHILDREN ,
x ,
y ,
w ,
h , // size
NULL , // parent window
0 , // no menu
hInstance ,
0 ) ;
if ( ! camerawindow )
Error ( " Couldn't create camerawindow " ) ;
ShowWindow ( camerawindow , SW_SHOWDEFAULT ) ;
}
void AppKeyDown ( int key )
{
key & = 0xFF ;
g_Keys [ key ] = 0x03 ; // add debounce bit
}
void AppKeyUp ( int key )
{
key & = 0xFF ;
g_Keys [ key ] & = 0x02 ;
}
void AppRender ( void )
{
static double lastTime = 0 ;
double time = timeGetTime ( ) * 0.001f ;
double frametime = time - lastTime ;
// clamp too large frames (like first frame)
if ( frametime > 0.2 )
frametime = 0.2 ;
lastTime = time ;
if ( ! wglMakeCurrent ( camdc , baseRC ) )
Error ( " wglMakeCurrent failed " ) ;
Cam_Update ( frametime ) ;
if ( g_Update )
{
Draw ( ) ;
SwapBuffers ( camdc ) ;
g_Update = FALSE ;
}
else
{
Sleep ( 1.0 ) ;
}
}
SpewRetval_t Sys_SpewFunc ( SpewType_t type , const char * pMsg )
{
OutputDebugString ( pMsg ) ;
if ( type = = SPEW_ASSERT )
return SPEW_DEBUGGER ;
else if ( type = = SPEW_ERROR )
return SPEW_ABORT ;
else
return SPEW_CONTINUE ;
}
/*
= = = = = = = = = = = = = = = = = =
WinMain
= = = = = = = = = = = = = = = = = =
*/
int WINAPI WinMain ( HINSTANCE hInstance , HINSTANCE hPrevInstance
, LPSTR lpCmdLine , int nCmdShow )
{
CommandLine ( ) - > CreateCmdLine ( Plat_GetCommandLine ( ) ) ;
MathLib_Init ( 2.2f , 2.2f , 0.0f , 2.0f ) ;
MSG msg ;
if ( ! lpCmdLine | | ! lpCmdLine [ 0 ] )
Error ( " No file specified " ) ;
main_instance = hInstance ;
WCam_Create ( hInstance ) ;
// Last argument is the file name
const char * pFileName = CommandLine ( ) - > GetParm ( CommandLine ( ) - > ParmCount ( ) - 1 ) ;
CmdLib_InitFileSystem ( pFileName ) ;
if ( CommandLine ( ) - > CheckParm ( " -portal " ) )
{
g_bReadPortals = 1 ;
g_nPortalHighlight = CommandLine ( ) - > ParmValue ( " -portalhighlight " , - 1 ) ;
g_nLeafHighlight = CommandLine ( ) - > ParmValue ( " -leafhighlight " , - 1 ) ;
}
g_flMovementSpeed = CommandLine ( ) - > ParmValue ( " -speed " , 320 ) ;
if ( CommandLine ( ) - > CheckParm ( " -disp " ) )
{
ReadDisplacementFile ( pFileName ) ;
g_bDisp = TRUE ;
}
SpewOutputFunc ( Sys_SpewFunc ) ;
// Any chunk of original left is the filename.
if ( pFileName & & pFileName [ 0 ] & & ! g_bDisp )
{
ReadPolyFile ( pFileName ) ;
}
if ( g_bReadPortals )
{
// Copy file again and this time look for the . from .gl? so we can concatenate .prt
// and open the portal file.
char szTempCmd [ MAX_PATH ] ;
strcpy ( szTempCmd , pFileName ) ;
char * pTmp = szTempCmd ;
while ( pTmp & & * pTmp & & * pTmp ! = ' . ' )
{
pTmp + + ;
}
* pTmp = ' \0 ' ;
strcat ( szTempCmd , " .prt " ) ;
ReadPortalFile ( szTempCmd ) ;
} ;
/* main window message loop */
while ( g_Active )
{
while ( PeekMessage ( & msg , NULL , 0 , 0 , PM_REMOVE ) )
{
TranslateMessage ( & msg ) ;
DispatchMessage ( & msg ) ;
}
AppRender ( ) ;
}
/* return success of application */
return TRUE ;
}