321 lines
5.6 KiB
C++
321 lines
5.6 KiB
C++
#define _USE_MATH_DEFINES
|
|
#include <math.h>
|
|
#include <stdio.h>
|
|
#include <stdarg.h>
|
|
#include "SampleInterfaces.h"
|
|
#include "Recast.h"
|
|
#include "RecastDebugDraw.h"
|
|
#include "DetourDebugDraw.h"
|
|
#include "SDL.h"
|
|
#include "SDL_opengl.h"
|
|
|
|
#ifdef WIN32
|
|
# define snprintf _snprintf
|
|
#endif
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
BuildContext::BuildContext() :
|
|
m_messageCount(0),
|
|
m_textPoolSize(0)
|
|
{
|
|
resetBuildTimes();
|
|
}
|
|
|
|
BuildContext::~BuildContext()
|
|
{
|
|
}
|
|
|
|
|
|
#if defined(WIN32)
|
|
|
|
// Win32
|
|
#include <windows.h>
|
|
|
|
rcTimeVal BuildContext::getTime()
|
|
{
|
|
__int64 count;
|
|
QueryPerformanceCounter((LARGE_INTEGER*)&count);
|
|
return count;
|
|
}
|
|
|
|
int BuildContext::getDeltaTimeUsec(const rcTimeVal start, const rcTimeVal end)
|
|
{
|
|
static __int64 freq = 0;
|
|
if (freq == 0)
|
|
QueryPerformanceFrequency((LARGE_INTEGER*)&freq);
|
|
__int64 elapsed = end - start;
|
|
return (int)(elapsed*1000000 / freq);
|
|
}
|
|
|
|
#else
|
|
|
|
// Linux, BSD, OSX
|
|
|
|
#include <sys/time.h>
|
|
|
|
rcTimeVal BuildContext::getTime()
|
|
{
|
|
timeval now;
|
|
gettimeofday(&now, 0);
|
|
return (rcTimeVal)now.tv_sec*1000000L + (rcTimeVal)now.tv_usec;
|
|
}
|
|
|
|
int BuildContext::getDeltaTimeUsec(const rcTimeVal start, const rcTimeVal end)
|
|
{
|
|
return (int)(end - start);
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
void BuildContext::resetLog()
|
|
{
|
|
m_messageCount = 0;
|
|
m_textPoolSize = 0;
|
|
}
|
|
|
|
void BuildContext::log(const rcLogCategory category, const char* format, ...)
|
|
{
|
|
if (m_messageCount >= MAX_MESSAGES)
|
|
return;
|
|
char* dst = &m_textPool[m_textPoolSize];
|
|
int n = TEXT_POOL_SIZE - m_textPoolSize;
|
|
if (n < 2)
|
|
return;
|
|
// Store category
|
|
*dst = (char)category;
|
|
n--;
|
|
// Store message
|
|
va_list ap;
|
|
va_start(ap, format);
|
|
int ret = vsnprintf(dst+1, n-1, format, ap);
|
|
va_end(ap);
|
|
if (ret > 0)
|
|
m_textPoolSize += ret+2;
|
|
m_messages[m_messageCount++] = dst;
|
|
}
|
|
|
|
void BuildContext::dumpLog(const char* format, ...)
|
|
{
|
|
// Print header.
|
|
va_list ap;
|
|
va_start(ap, format);
|
|
vprintf(format, ap);
|
|
va_end(ap);
|
|
printf("\n");
|
|
|
|
// Print messages
|
|
const int TAB_STOPS[4] = { 28, 36, 44, 52 };
|
|
for (int i = 0; i < m_messageCount; ++i)
|
|
{
|
|
const char* msg = m_messages[i]+1;
|
|
int n = 0;
|
|
while (*msg)
|
|
{
|
|
if (*msg == '\t')
|
|
{
|
|
int count = 1;
|
|
for (int j = 0; j < 4; ++j)
|
|
{
|
|
if (n < TAB_STOPS[j])
|
|
{
|
|
count = TAB_STOPS[j] - n;
|
|
break;
|
|
}
|
|
}
|
|
while (--count)
|
|
{
|
|
putchar(' ');
|
|
n++;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
putchar(*msg);
|
|
n++;
|
|
}
|
|
msg++;
|
|
}
|
|
putchar('\n');
|
|
}
|
|
}
|
|
|
|
int BuildContext::getLogCount() const
|
|
{
|
|
return m_messageCount;
|
|
}
|
|
|
|
const char* BuildContext::getLogText(const int i) const
|
|
{
|
|
return m_messages[i]+1;
|
|
}
|
|
|
|
void BuildContext::resetBuildTimes()
|
|
{
|
|
for (int i = 0; i < RC_MAX_TIMES; ++i)
|
|
m_buildTime[i] = -1;
|
|
}
|
|
|
|
void BuildContext::reportBuildTime(const rcBuildTimeLabel label, const int time)
|
|
{
|
|
const int idx = (int)label;
|
|
// The build times are initialized to negative to indicate no samples collected.
|
|
if (m_buildTime[idx] < 0)
|
|
m_buildTime[idx] = time;
|
|
else
|
|
m_buildTime[idx] += time;
|
|
}
|
|
|
|
int BuildContext::getBuildTime(const rcBuildTimeLabel label)
|
|
{
|
|
return m_buildTime[label];
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
#if defined(WIN32)
|
|
|
|
// Win32
|
|
#include <windows.h>
|
|
|
|
rcTimeVal getPerfTime()
|
|
{
|
|
__int64 count;
|
|
QueryPerformanceCounter((LARGE_INTEGER*)&count);
|
|
return count;
|
|
}
|
|
|
|
int getPerfDeltaTimeUsec(const rcTimeVal start, const rcTimeVal end)
|
|
{
|
|
static __int64 freq = 0;
|
|
if (freq == 0)
|
|
QueryPerformanceFrequency((LARGE_INTEGER*)&freq);
|
|
__int64 elapsed = end - start;
|
|
return (int)(elapsed*1000000 / freq);
|
|
}
|
|
|
|
#else
|
|
|
|
// Linux, BSD, OSX
|
|
|
|
#include <sys/time.h>
|
|
|
|
rcTimeVal getPerfTime()
|
|
{
|
|
timeval now;
|
|
gettimeofday(&now, 0);
|
|
return (rcTimeVal)now.tv_sec*1000000L + (rcTimeVal)now.tv_usec;
|
|
}
|
|
|
|
int getPerfDeltaTimeUsec(const rcTimeVal start, const rcTimeVal end)
|
|
{
|
|
return (int)(end - start);
|
|
}
|
|
|
|
#endif
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
void DebugDrawGL::depthMask(bool state)
|
|
{
|
|
glDepthMask(state ? GL_TRUE : GL_FALSE);
|
|
}
|
|
|
|
void DebugDrawGL::begin(duDebugDrawPrimitives prim, float size)
|
|
{
|
|
switch (prim)
|
|
{
|
|
case DU_DRAW_POINTS:
|
|
glPointSize(size);
|
|
glBegin(GL_POINTS);
|
|
break;
|
|
case DU_DRAW_LINES:
|
|
glLineWidth(size);
|
|
glBegin(GL_LINES);
|
|
break;
|
|
case DU_DRAW_TRIS:
|
|
glBegin(GL_TRIANGLES);
|
|
break;
|
|
case DU_DRAW_QUADS:
|
|
glBegin(GL_QUADS);
|
|
break;
|
|
};
|
|
}
|
|
|
|
void DebugDrawGL::vertex(const float* pos, unsigned int color)
|
|
{
|
|
glColor4ubv((GLubyte*)&color);
|
|
glVertex3fv(pos);
|
|
}
|
|
|
|
void DebugDrawGL::vertex(const float x, const float y, const float z, unsigned int color)
|
|
{
|
|
glColor4ubv((GLubyte*)&color);
|
|
glVertex3f(x,y,z);
|
|
}
|
|
|
|
void DebugDrawGL::end()
|
|
{
|
|
glEnd();
|
|
glLineWidth(1.0f);
|
|
glPointSize(1.0f);
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
FileIO::FileIO() :
|
|
m_fp(0),
|
|
m_mode(-1)
|
|
{
|
|
}
|
|
|
|
FileIO::~FileIO()
|
|
{
|
|
if (m_fp) fclose(m_fp);
|
|
}
|
|
|
|
bool FileIO::openForWrite(const char* path)
|
|
{
|
|
if (m_fp) return false;
|
|
m_fp = fopen(path, "wb");
|
|
if (!m_fp) return false;
|
|
m_mode = 1;
|
|
return true;
|
|
}
|
|
|
|
bool FileIO::openForRead(const char* path)
|
|
{
|
|
if (m_fp) return false;
|
|
m_fp = fopen(path, "rb");
|
|
if (!m_fp) return false;
|
|
m_mode = 2;
|
|
return true;
|
|
}
|
|
|
|
bool FileIO::isWriting() const
|
|
{
|
|
return m_mode == 1;
|
|
}
|
|
|
|
bool FileIO::isReading() const
|
|
{
|
|
return m_mode == 2;
|
|
}
|
|
|
|
bool FileIO::write(const void* ptr, const size_t size)
|
|
{
|
|
if (!m_fp || m_mode != 1) return false;
|
|
fwrite(ptr, size, 1, m_fp);
|
|
return true;
|
|
}
|
|
|
|
bool FileIO::read(void* ptr, const size_t size)
|
|
{
|
|
if (!m_fp || m_mode != 2) return false;
|
|
fread(ptr, size, 1, m_fp);
|
|
return true;
|
|
}
|
|
|
|
|