📄 system.cpp
字号:
// This code based on engine "Engine1"
// which written by David Dufke
// http://www.efd.lth.se/~e98dd/home/
#include <windows.h>
#include <stdlib.h>
#include <stdio.h>
#include <gl\gl.h>
#include <gl\glu.h>
#include <gl\glaux.h>
#include <mmsystem.h>
#include <malloc.h>
#include <stdio.h>
#include <stdarg.h>
#include <math.h>
#include <fstream.h>
#include <iomanip.h>
#include "system.h"
#include "app.h"
#include "game.h"
extern int win_width;
extern int win_height;
extern int bpp;
extern int HeightmapCollide;
extern float min_frustum, max_frustum;
extern int fullscreen;
extern float LOD;
extern char FileName[50];//static
extern char zip_file[50];
extern char texture_file[50];
extern char variance_file[50];
extern float h_scale, v_scale;
extern int SecondCulling, norm_distance;
extern float YCollide;
extern float farPlane, nearPlane;
extern float fov;
extern int cicle;
extern int size_of_map;
extern int g_tenFrames[10];
int sys_memUsed = 0;
static unsigned char sys_normTable[0xFF * 2];
/*** int sysTime ***
Gives a time value in milliseconds.
Should only be used to calculate relative time values.*/
int sysTime()
{
return timeGetTime();
}
void rDrawTimeGraph(SpeedMeter *times)
{
int i, t;
float avg;
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();
gluOrtho2D(win_width, 0.0, 0.0, win_height);
/* Since line width is measured in pixels,
//it is best to draw lines in window coords.
//To prevent them landing on each other...
//The downside being that the time graph is
//the only part of the interface that doesn't
//scale with resolution. */
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glLoadIdentity();
glPushAttrib(GL_CURRENT_BIT | GL_DEPTH_BUFFER_BIT);
glColor4f(0.0f, 0.0f, 0.0f, 1.0f);
glDisable(GL_DEPTH_TEST);
glDisable(GL_TEXTURE_2D);
glDepthMask(GL_FALSE);
glBegin(GL_LINES);
for(i=5; i<=70;i+=5)
{
glVertex2f(0, (float)i);
if(i%15)
glVertex2f(3, (float)i);
else
glVertex2f(6, (float)i);
}
for(i=0;i < times->getSize(); i++)
{
t = times->getSpot(i);
if(t < 30)
glColor4f(0.0f, 0.5f, 0.0f, 1.0f);
else if(t < 60)
glColor4f(1.0f, 1.0f, 0.0f, 1.0f);
else
glColor4f(1.0f, 0.0f, 0.0f, 1.0f);
glVertex2f((float)i+7, 0);
glVertex2f((float)(i+7), (float)t);
}
glColor3f(0.8f, 0.8f, 0.8f);
avg = times->getAvg();
glVertex2f(7, avg);
glVertex2f((float)(7+times->getSize()), avg);
glEnd();
glPopAttrib();
glEnable(GL_TEXTURE_2D);
glMatrixMode(GL_PROJECTION);
glPopMatrix();
glMatrixMode(GL_MODELVIEW);
glPopMatrix();
}
int sysLoadSettings(char * config_file)
{
FILE * configFile=fopen(config_file, "rt");
if(!configFile){
MessageBox(NULL,"File error","Cannot open config file",MB_OK|MB_ICONINFORMATION);
return false;
}
fclose(configFile);
char size_of_map_name[10];
char NameSpeed[10];
char CamXname[10], CamYname[10], CamZname[10];
char OrientationXZname[10], OrientationYZname[10], radiusName[10];
char FullScreenName[10];
char MapName[10];
char TextureName[10];
char NameLod[10];
char NameZip[10];
char MinFrustum[10], MaxFrustum[10];
char HscaleName[10], VscaleName[10];
char VarFileName[10];
char SecondCullingName[10];
char win_widthName[10], win_heightName[10], bppName[10];
char accelerationName[10], maxTurnRateName[10];
char HeightmapCollideName[10], YCollideName[10];
char farPlaneName[10], nearPlaneName[10];
char fovName[10];
char norm_distance_name[10];
char cicleName[10];
fstream file;
file.open(config_file, ios::in|ios::nocreate);
file>>size_of_map_name; file>>size_of_map;
file>>NameZip; file>>zip_file;
file>>MapName; file>>FileName;
file>>TextureName; file>>texture_file;
file>>NameLod; file>>LOD;
file>>norm_distance_name; file>>norm_distance;
file>>MinFrustum; file>>min_frustum;
file>>MaxFrustum; file>>max_frustum;
file>>HscaleName; file>>h_scale;
file>>VscaleName; file>>v_scale;
file>>VarFileName; file>>variance_file;
file>>SecondCullingName; file>>SecondCulling;
file>>win_widthName; file>>win_width;
file>>win_heightName; file>>win_height;
file>>bppName; file>>bpp;
file>>NameSpeed; file>>g_maxSpeed;
file>>CamXname; file>>g_current.XPos;
file>>CamYname; file>>g_current.YPos;
file>>CamZname; file>>g_current.ZPos;
file>>OrientationXZname; file>>g_current.XZAngle;
file>>OrientationYZname; file>>g_current.YZAngle;
file>>radiusName; file>>g_current.radius;
file>>FullScreenName; file>>fullscreen;
file>>accelerationName; file>>g_acceleration;
file>>maxTurnRateName; file>>g_maxTurnRate;
file>>HeightmapCollideName; file>>HeightmapCollide;
file>>YCollideName; file>>YCollide;
file>>farPlaneName; file>>farPlane;
file>>nearPlaneName; file>>nearPlane;
file>>fovName; file>>fov;
file>>cicleName; file>>cicle;
file.close();
g_current.XPos*=h_scale;
g_current.ZPos*=h_scale;
int i; for(i=0;i < 10;i++) g_tenFrames[i] = 30;
g_current.timeStamp = sysTime();
return TRUE;
}
void sysLogPrintf(const char *string, ...)
{
va_list args;
FILE *log_file;
log_file = fopen("log.txt", "a+t");
if(!log_file) /* Write errors are silently ignored. Lets you run it from a CD. */
return;
va_start(args, string);
vfprintf(log_file, string, args);
va_end(args);
fclose(log_file);
}
/*** sysNorm ***
Find approx. length of 3D vector.
WARNING: sysBuildNormTable MUST be called once
before this function, or it will return b0rk. */
float sysNorm(float x, float y, float z)
{
float result;
__asm
{
/* Sum squares */
FLD x
FMUL ST(0), ST(0)
FLD y
FMUL ST(0), ST(0)
FADDP ST(1), ST(0)
FLD z
FMUL ST(0), ST(0)
FADDP ST(1), ST(0)
FSTP result
/* Find approx. root thru look-up table */
MOV eax, result
MOV ebx, eax
AND eax, 2139095040
SHR eax, 23
SUB eax, 127
MOV ecx, eax
AND ecx, 1
SHR eax, 1
ADD eax, 127
SHL eax, 23
AND ebx, 8388607 /* Sorry about the magic numbers. :-> */
SHR ebx, 15
SHL ebx, 1
OR ebx, ecx
ADD ebx, OFFSET sys_normTable
MOVZX edx, BYTE PTR [ebx]
SHL edx, 15
OR edx, eax
MOV result, edx
}
return result;
}
/*** sysBuildNormTable *** Build look-up table for sysNorm(). */
void sysBuildNormTable()
{
int m;
unsigned int is, ir;
float s, r;
for(m = 0;m < 0xFF;m++)
{
is = ((127 << 23) | (m << 15));
s = *((float *)(&is));
r = sqrtf(s);
ir = *((unsigned int *)(&r));
sys_normTable[2*m] = (ir & (0xFF << 15)) >> 15;
is = (((127+1) << 23) | (m << 15));
s = *((float *)(&is));
r = sqrtf(s);
ir = *((unsigned int *)(&r));
sys_normTable[2*m+1] = (ir & (0xFF << 15)) >> 15;
}
}
/*** sysLog2 ***
Find log2 of a number. The number must be a positive
exact power of two, or -1 will be returned. */
int sysLog2(int i)
{
int log = 0;
if(i < 0)
return -1;
while(!(i & 1))
{
i >>= 1;
log++;
}
if(i & 0xFFFFFFFE)
return -1;
return log;
}
/*** sysMalloc *** Wrapper for malloc, for stats and alignment issues. */
void *sysMalloc(int size)
{
void *ptr;
unsigned int adress;
void *aligned_ptr;
sys_memHdr_type hdr;
hdr.size = size;
ptr = malloc(size + SYS_MEMALIGN + sizeof(sys_memHdr_type));
if(!ptr)
{
sysLogPrintf("Failed to allocate %d bytes.\n", size);
return NULL;
}
sys_memUsed += (size + SYS_MEMALIGN + sizeof(sys_memHdr_type));
hdr.orig_ptr = ptr;
adress = (unsigned int)ptr + sizeof(sys_memHdr_type);
adress = adress + SYS_MEMALIGN - adress%SYS_MEMALIGN;
aligned_ptr = (void *)adress;
memcpy((void *)(adress - sizeof(sys_memHdr_type)), &hdr, sizeof(sys_memHdr_type));
return aligned_ptr;
}
/*** sysCalloc *** Ditto for calloc... */
void *sysCalloc(int size)
{
void *ptr;
ptr = sysMalloc(size);
if(!ptr)
return NULL;
memset(ptr, 0, size);
return ptr;
}
/*** sysFree *** ... and free. */
void sysFree(void *ptr)
{
sys_memHdr_type *hdr;
hdr = (sys_memHdr_type *)((unsigned int)ptr - sizeof(sys_memHdr_type));
sys_memUsed -= (hdr->size + SYS_MEMALIGN + sizeof(sys_memHdr_type));
free(hdr->orig_ptr);
}
/*** sysSnapshot *** Prints a snapshot of current engine state to the log file */
void sysSnapshot()
{
sysLogPrintf("Snapshot taken:\n");
sysLogPrintf("%d kbytes memory allocated by sys\n", sys_memUsed/1024);
sysLogPrintf("Position: %.1f %.1f %.1f\n", g_current.XPos, g_current.YPos, g_current.ZPos);
}
/****** SpeedMeter class implementation ******
This class is used to measure the duration of events. */
void SpeedMeter::init(int storesize)
{
m_buffer = (int *)sysCalloc(storesize * sizeof(int));
m_current = 0;
m_storesize = storesize;
}
float SpeedMeter::getAvg()
{
if(!m_buffer)
return -1.0f;
int i;
float total = 0.0f;
for(i = 0; i < m_storesize; i++)
{
total += (float)m_buffer[i];
}
return total / (float)m_storesize;
}
int SpeedMeter::getSpot(int index)
{
if(!m_buffer)
return -1;
int item = m_current - index;
while(item < 0)
item += m_storesize;
return m_buffer[item];
}
void SpeedMeter::startMeter()
{
m_start = sysTime();
}
void SpeedMeter::stopMeter()
{
if(!m_buffer)
return;
m_current = (m_current + 1)%m_storesize;
m_buffer[m_current] = sysTime() - m_start;
}
SpeedMeter::~SpeedMeter()
{
if(!m_buffer)
return;
sysFree(m_buffer);
}
int SpeedMeter::getSize()
{
return m_storesize;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -