www.pudn.com > coolMEMORY.rar > AS.cpp
//-----------------------------------------------------------------------------
// File: AS.cpp
//-----------------------------------------------------------------------------
#include "AS_Engine.h"
// Variables: *****************************************************************
AS_PROGRAM_INFO _ASProgramInfo;
AS_ENGINE *_AS;
UCHAR ASKeys[256];
BOOL ASKeyPressed[256], ASKeyFirst[256];
int iASResult;
DEVMODE ASSavedDisplayMode;
// Multi-texture:
PFNGLMULTITEXCOORD2FARBPROC glMultiTexCoord2fARB = 0;
PFNGLACTIVETEXTUREARBPROC glActiveTextureARB = 0;
PFNGLCLIENTACTIVETEXTUREARBPROC glClientActiveTextureARB = 0;
// Compiled array vertex:
PFNGLLOCKARRAYSEXTPROC glLockArraysEXT = 0;
PFNGLUNLOCKARRAYSEXTPROC glUnlockArraysEXT = 0;
// General speed variables
long g_lProgramStartTime = 0; // The Program Start Time
long g_lGameLength = 0; // Application Run Time Variable
long g_lNow = 0; // The Actual Time
long g_lLastlooptime = 0; // Time When Last Loop Was Started
long g_lDeltatime = 0; // Change In Time Since Last Iteration
long g_lGameTimer = 0; // The game timer. Could be paused
///////////////////////////////////////////////////////////////////////////////
// Functions: *****************************************************************
HRESULT ASDraw(AS_WINDOW *);
HRESULT ASCheck(AS_WINDOW *);
void ASSwapBuffers(HDC, AS_WINDOW *, BOOL);
char *ASGetFileName(HWND, char *, char *, BOOL, BOOL, char *);
void ASLoadTextures(char (*)[256], int, AS_TEXTURE *);
void ASDestroyTextures(int, AS_TEXTURE *);
void ASGenOpenGLTextures(int, AS_TEXTURE *);
void ASDestroyOpenGLTextures(int, AS_TEXTURE *);
int ASCheckTextureSize(int);
BOOL ASLoadJpegRGB(AS_TEXTURE *, char *);
BOOL ASLoadBmp(AS_TEXTURE *, char *);
BOOL ASLoadPpm(AS_TEXTURE *, char *);
BOOL ASLoadTga(AS_TEXTURE *, char *);
void ASSavePpm(AS_TEXTURE *, char *);
DWORD ASGetCpuSpeed(void);
void ASRemoveDirectory(char *);
void ASDrawBoundingBox(float [2][3], float);
///////////////////////////////////////////////////////////////////////////////
// AS_PROGRAM_INFO functions: *************************************************
void AS_PROGRAM_INFO::Init(void)
{ // begin AS_PROGRAM_INFO()
strcpy(byVersion, GAME_VERSION);
strcpy(byDate, __DATE__);
strcpy(byTime, __TIME__);
} // end AS_PROGRAM_INFO()
// AS_ENGINE functions: *******************************************************
AS_ENGINE::AS_ENGINE(HINSTANCE hInstanceT, LPSTR lpCmdLineT, int iCmdShowT, BOOL bOnlyOne)
{ // begin AS_ENGINE::AS_ENGINE()
DWORD i = 256;
int AS_WINDOW_ID;
BOOL bTemp;
char byTemp[256], *pbyTemp;
// Init all:
memset((this), 0, sizeof(AS_ENGINE));
_AS = this;
GetLocalTime(&StartTime);
// Set important stuff
hInstance = hInstanceT;
lpCmdLine = lpCmdLineT;
iCmdShow = iCmdShowT;
hMutex = OpenMutex(SYNCHRONIZE, FALSE, GAME_NAME);
if(hMutex)
{
if(bOnlyOne)
{
CloseHandle(hMutex);
MessageBox(0, M_TheProgramIsAlreadyRunning, GAME_NAME, MB_ICONERROR | MB_OK);
bShutDown = TRUE;
return;
}
}
else
hMutex = CreateMutex(NULL, TRUE, GAME_NAME);
SetPriorityClass(hInstance, 31);
SetThreadPriority(hInstance, 31);
_ASProgramInfo.Init();
bActive = TRUE;
ASBuildSqrtTable();
// Initalize the random generator
srand((unsigned) time(NULL));
// Find path info
GetModuleFileName(hInstance, byProgramExeName, 256);
_splitpath(byProgramExeName, byProgramDrive, byProgramDir, NULL, NULL);
sprintf(byProgramPath, "%s%s", byProgramDrive, byProgramDir);
SetCurrentDirectory(byProgramPath);
GetUserName(byUserName, &i);
// Get general game information:
sprintf(byTemp, "%s"AS_GAME_INFO_FILE"", byProgramPath);
bLog = GetPrivateProfileInt("general", "log", 1, byTemp);
bDebugMode = GetPrivateProfileInt("general", "debug_mode", 0, byTemp);
bStartErrorMessage = GetPrivateProfileInt("general", "start_error_message", 1, byTemp);
bShowIntro = GetPrivateProfileInt("general", "show_intro", 1, byTemp);
// Get directories information:
GetPrivateProfileString("directories", "languages", "Data\\Languages", byLanguagesDirectory, 256, byTemp);
GetPrivateProfileString("directories", "objects", "Data\\Objects", byObjectsDirectory, 256, byTemp);
GetPrivateProfileString("directories", "bitmaps", "Data\\Bitmaps", byBitmapsDirectory, 256, byTemp);
GetPrivateProfileString("directories", "music", "Data\\Music", byMusicDirectory, 256, byTemp);
GetPrivateProfileString("directories", "sound", "Data\\Sound", bySoundDirectory, 256, byTemp);
GetPrivateProfileString("directories", "card_styles", "Data\\CardStyles", byCardStylesDirectory, 256, byTemp);
GetPrivateProfileString("directories", "screenshots", "Data\\CardStyles", byScreenshotsDirectory, 256, byTemp);
// Get filenames:
GetPrivateProfileString("filenames", "log_filename", "Config.ini", byLogFilename, 256, byTemp);
GetPrivateProfileString("filenames", "config_filename", "Config.ini", byConfigFilename, 256, byTemp);
// Get other game information:
GetPrivateProfileString("other", "standart_card_style", "Animals", byStandartCardStyle, 256, byTemp);
GetPrivateProfileString("other", "standart_music", "r-summer.xm", byStandartMusic, 256, byTemp);
// Load the configuration:
_ASConfig = new AS_CONFIG;
sprintf(byTemp, "%s%s", byProgramPath, byConfigFilename);
_ASConfig->Load(byTemp);
//
// Open the log:
// Clear the log contents:
if(!(pLogFile = fopen(byLogFilename, "w")))
{ // Give out an error message:
sprintf(byTemp, "Couldn't open the log (%s)\nGo sure that all program-files ready for writing!", AS_LOG_FILE);
MessageBox(NULL, byTemp, T_Error, MB_OK | MB_ICONINFORMATION);
bLog = FALSE; // Disable the log
}
// Create the log header:
WriteLogMessage("Log-system activated");
WriteLogMessage("\n");
WriteLogMessage("< "GAME_NAME" "GAME_VERSION" >");
WriteLogMessage("Build: %s %s", _ASProgramInfo.byDate, _ASProgramInfo.byTime);
WriteLogMessage("Program start time: Date: %d.%d.%d - Time: %d:%d:%d:%d", StartTime.wMonth, StartTime.wDay, StartTime.wYear,
StartTime.wHour, StartTime.wMinute,
StartTime.wSecond, StartTime.wMilliseconds);
WriteLogMessage("\n");
// Print out the general system info:
WriteLogMessage("General system info:");
WriteLogMessage("User name: %s", byUserName);
WriteLogMessage("CPU: %d Mhz", ASGetCpuSpeed());
if(GetSystemMetrics(SM_MOUSEPRESENT))
WriteLogMessage("There is a mouse");
else
WriteLogMessage("There is no mouse");
WriteLogMessage("Number of mouse buttons: %d", GetSystemMetrics(SM_CMOUSEBUTTONS));
WriteLogMessage("Display resolution: %dx%d", GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN));
// Print out path information:
WriteLogMessage("Path information:");
WriteLogMessage("Program path: %s", byProgramPath);
WriteLogMessage("Game info file: "AS_GAME_INFO_FILE"");
WriteLogMessage("Config filename: %s", byConfigFilename);
WriteLogMessage("Languages directory: %s", byLanguagesDirectory);
WriteLogMessage("Objects directory: %s", byObjectsDirectory);
WriteLogMessage("Bitmaps directory: %s", byBitmapsDirectory);
WriteLogMessage("Music directory: %s", byMusicDirectory);
WriteLogMessage("Sound directory: %s", bySoundDirectory);
WriteLogMessage("Card styles directory: %s", byCardStylesDirectory);
WriteLogMessage("Screenshot directory: %s", byScreenshotsDirectory);
// Last log setup text:
WriteLogMessage("\n\n");
WriteLogMessage("Messages:");
// Init FPS:
dwFPSTimeNow = GetTickCount();
dwFPSTimeLast = GetTickCount();
dwFPSTimeDifference = 0;
iFPSRenderedFrames = iFPSFramesSinceCheck = 0;
fFPS = 0.0f;
EnumerateDisplayModeInfos();
// Enumerate the languages:
EnumerateLanguages();
// Initalize DirectInput:
WriteLogMessage("Initalize DirectInput");
// Get the OpenGL stuff:
WriteLogMessage("Get OpenGL information");
bTemp = _ASConfig->bFullScreen;
_ASConfig->bFullScreen = 0;
ASCreateWindow(WindowProc, AS_WINDOW_NAME, AS_WINDOW_NAME, _ASConfig->iWindowWidth, _ASConfig->iWindowHeight, NULL, FALSE, ASDraw, ASCheck, NULL, TRUE);
AS_WINDOW_ID = GetWindows()-1;
ASInitOpenGL(&pWindow[AS_WINDOW_ID],
NULL,
pWindow[AS_WINDOW_ID].GethDC(),
pWindow[AS_WINDOW_ID].GethRC(), FALSE);
glGetIntegerv(GL_MAX_LIGHTS, &iMaxLights);
InitExtensions();
glGetIntegerv(GL_MAX_TEXTURE_SIZE, &iMaxTextureSize);
ASDestroyOpenGL(&pWindow[AS_WINDOW_ID],
NULL,
*pWindow[AS_WINDOW_ID].GethDC(),
*pWindow[AS_WINDOW_ID].GethRC());
ASDestroyWindow(pWindow[AS_WINDOW_ID].GethWnd(), AS_WINDOW_NAME);
_ASConfig->bFullScreen = bTemp;
WriteLogMessage("OpenGL information received");
// Print out the OpenGL information:
WriteLogMessage("Show OpenGL information");
WriteLogMessage("Version:");
WriteLogMessageS(pbyOpenGLVersion);
WriteLogMessage("Chip info:");
WriteLogMessageS(pbyOpenGLChipInfo);
WriteLogMessage("Renderer info:");
WriteLogMessageS(pbyOpenGLRendererInfo);
WriteLogMessage("Extensions info:");
pbyTemp = pbyOpenGLExtensionInfo;
for(;;)
{
if(sscanf(pbyTemp, "%s", byTemp) == EOF)
break;
WriteLogMessage(byTemp);
if(*(pbyTemp+strlen(byTemp)+1) == 0)
break;
pbyTemp += strlen((const char *) byTemp)+1;
}
WriteLogMessage("Max texture size: %dx%d", iMaxTextureSize, iMaxTextureSize);
WriteLogMessage("That's all from OpenGL");
if(!bOnlyConfig)
ASInitFmod();
// Init complete:
g_lProgramStartTime = GetTickCount();
WriteLogMessage("AS-Engine init complete");
} // end AS_ENGINE::AS_ENGINE()
AS_ENGINE::~AS_ENGINE(void)
{ // begin AS_ENGINE::~AS_ENGINE()
char byTemp[256];
// Shut down the program:
WriteLogMessage("Program loop left");
WriteLogMessage("Shut down program");
if(!bOnlyConfig)
ASDestroyFmod();
// Check if there was an error:
_ASConfig->bError = _ASConfig->bSetError;
_ASConfig->bFirstRun = FALSE;
if(_ASConfig->bError)
MessageBox(NULL, M_ProgramEndErrorDetected, GAME_NAME, MB_OK | MB_ICONINFORMATION);
// Save the configuration:
sprintf(byTemp, "%s%s", byProgramPath, byConfigFilename);
_ASConfig->Save(byTemp);
// Delete OpenGL information
SAFE_DELETE(pbyOpenGLVersion);
SAFE_DELETE(pbyOpenGLChipInfo);
SAFE_DELETE(pbyOpenGLRendererInfo);
SAFE_DELETE(pbyOpenGLExtensionInfo);
// Delete last stuff:
DestroyDisplayModeInfo();
DestroyLanguage();
// Close the Log:
WriteLogMessage("Shut down AS-Engine");
WriteLogMessage("Close log");
if(pLogFile)
fclose(pLogFile);
delete _ASConfig;
} // end AS_ENGINE::~AS_ENGINE()
void AS_ENGINE::WriteLogMessage(const char *pbyMessage, ...)
{ // begin AS_ENGINE::WriteLogMessage()
va_list arg_list;
// Could we write into the log?
if(!bLog || !pLogFile)
return; // Nope!
// Initialize variable argument list:
va_start(arg_list, pbyMessage);
// Write the text and a newline:
vfprintf(pLogFile, pbyMessage, arg_list);
putc('\n', pLogFile);
fflush(pLogFile);
va_end(arg_list);
} // end AS_ENGINE::WriteLogMessage()
void AS_ENGINE::WriteLogMessageS(const char *pbyMessage)
{ // begin AS_ENGINE::WriteLogMessageS()
// Could we write into the log?
if(!bLog || !pLogFile)
return; // Nope!
// Write the text and a newline:
fprintf(pLogFile, pbyMessage);
putc('\n', pLogFile);
fflush(pLogFile);
} // end AS_ENGINE::WriteLogMessageS()
HWND AS_ENGINE::ASCreateWindow(WNDPROC WindowProc,
LPCTSTR pbyTitle,
LPCTSTR pbyName,
DWORD dwWidth,
DWORD dwHeight,
HMENU Menu,
BOOL bFullScreen,
HRESULT (*pDrawTemp)(AS_WINDOW *),
HRESULT (*pCheckTemp)(AS_WINDOW *),
HBRUSH hBackground,
BOOL bIsMainWindowT)
{ // begin AS_ENGINE::ASCreateWindow()
HWND hWnd;
WriteLogMessage("Create window");
if(bMainWindow && bIsMainWindowT)
{
WriteLogMessage("There is already a main window!");
return NULL;
}
WriteLogMessage("Titel: %s", pbyTitle);
WriteLogMessage("Name: %s", pbyName);
WriteLogMessage("Width: %d", dwWidth);
WriteLogMessage("Height: %d", dwHeight);
WriteLogMessage("Full screen: %d", bFullScreen);
iWindows++;
pWindow = (AS_WINDOW *) realloc(pWindow, sizeof(AS_WINDOW)*iWindows);
hWnd = pWindow[iWindows-1].ASCreateWindow(WindowProc,
pbyTitle,
pbyName,
dwWidth,
dwHeight,
Menu,
bFullScreen,
pDrawTemp,
pCheckTemp,
hBackground,
bIsMainWindowT);
pWindow[iWindows-1].SetID(iWindows-1);
WriteLogMessage("Window(ID: %d) successful created", iWindows-1);
if(!bMainWindow && bIsMainWindowT)
bMainWindow = TRUE;
return hWnd;
} // end AS_ENGINE::ASCreateWindow()
HRESULT AS_ENGINE::ASDestroyWindow(HWND *hWnd, LPCTSTR pbyName)
{ // begin AS_ENGINE::ASDestroyWindow()
LPTSTR lpClassName = new char[MAX_PATH];
int i;
WriteLogMessage("Destroy window");
WriteLogMessage("Name: %s", pbyName);
if(!hWnd)
{ // Find the window self:
for(i = 0; i < iWindows; i++)
{
GetClassName(*pWindow[i].GethWnd(), lpClassName, MAX_PATH);
if(!strcmp(lpClassName, pbyName))
{ // We´ve found the window!
HWND hTemp;
hTemp = *pWindow[i].GethWnd();
hWnd = &hTemp;
break;
}
}
}
if(!hWnd)
return 1;
for(i = 0; i < iWindows; i++)
if(*pWindow[i].GethWnd() == *hWnd)
{
WriteLogMessage("ID: %d", i);
if(pWindow[i].GetIsMainWindow())
bMainWindow = FALSE;
pWindow[i].ASDestroyWindow(hWnd, pbyName);
pWindow[i] = pWindow[iWindows-1];
iWindows--;
pWindow = (AS_WINDOW *) realloc(pWindow, sizeof(AS_WINDOW)*iWindows);
WriteLogMessage("Window successful destroyed");
return 0;
}
return 1;
} // end AS_ENGINE::ASDestroyWindow()
HRESULT AS_ENGINE::EnumerateDisplayModeInfos(void)
{ // begin AS_ENGINE::EnumerateDisplayModeInfos()
DEVMODE devMode;
DestroyDisplayModeInfo();
WriteLogMessage("Enumerate display modes...");
for(int i = 0;;i++)
{
if(!EnumDisplaySettings(NULL, i, &devMode))
break;
AddDisplayModeInfo(devMode);
}
WriteLogMessage("Complete");
return 0;
} // end AS_ENGINE::EnumerateDisplayModeInfos()
HRESULT AS_ENGINE::AddDisplayModeInfo(DEVMODE lpDevMode)
{ // begin AS_ENGINE::AddDisplayModeInfo()
if(lpDevMode.dmBitsPerPel < 16)
return 1;
DisplayModeInfo.Number++;
DisplayModeInfo.pDevMode = (DEVMODE *) realloc(DisplayModeInfo.pDevMode, sizeof(DEVMODE)*DisplayModeInfo.Number);
if(!DisplayModeInfo.pDevMode)
return 1;
CopyMemory(&DisplayModeInfo.pDevMode[DisplayModeInfo.Number-1], &lpDevMode, sizeof(DEVMODE));
WriteLogMessage("Found: %dx%dx%d", DisplayModeInfo.pDevMode[DisplayModeInfo.Number-1].dmPelsWidth,
DisplayModeInfo.pDevMode[DisplayModeInfo.Number-1].dmPelsHeight,
DisplayModeInfo.pDevMode[DisplayModeInfo.Number-1].dmBitsPerPel);
return 0;
} // end AS_ENGINE::AddDisplayModeInfo()
HRESULT AS_ENGINE::DestroyDisplayModeInfo(void)
{ // begin AS_ENGINE::DestroyDisplayModeInfo()
if(DisplayModeInfo.pDevMode)
free(DisplayModeInfo.pDevMode);
DisplayModeInfo.pDevMode = NULL;
DisplayModeInfo.Number = 0;
return 0;
} // end AS_ENGINE::DestroyDisplayModeInfo()
void AS_ENGINE::UpdateWindows(void)
{ // begin AS_ENGINE::UpdateWindows()
// Check the speed control stuff
g_lNow = GetTickCount();
g_lDeltatime = g_lNow-g_lLastlooptime;
if(!bPause && g_lDeltatime)
g_lGameTimer += g_lDeltatime;
if(g_lDeltatime > 100)
g_lDeltatime = 100;
g_lLastlooptime = g_lNow;
g_lGameLength = (g_lNow-g_lProgramStartTime)/1000;
// Check the windows
for(int i = 0; i < iWindows; i++)
{
pWindow[i].Check();
pWindow[i].Draw();
}
UpdateFPS();
} // end AS_ENGINE::UpdateWindows()
int AS_ENGINE::FindWindowID(HWND hWnd)
{ // begin AS_ENGINE::FindWindowID()
for(int i = 0; i < iWindows; i++)
if(*pWindow[i].GethWnd() == hWnd)
return i;
return -1;
} // end AS_ENGINE::FindWindowID()
float AS_ENGINE::UpdateFPS(void)
{ // begin AS_ENGINE::UpdateFPS()
dwFPSTimeNow = GetTickCount();
dwFPSTimeDifference = dwFPSTimeNow-dwFPSTimeLast;
iFPSRenderedFrames++;
iFPSFramesSinceCheck++;
if(dwFPSTimeDifference > 1000)
{
fFPS = (float) iFPSFramesSinceCheck*1000/dwFPSTimeDifference;
dwFPSTimeLast = dwFPSTimeNow;
iFPSFramesSinceCheck = 0;
}
return fFPS;
} // end AS_ENGINE::UpdateFPS()
void AS_ENGINE::ShowMouseCursor(BOOL bState)
{ // begin AS_ENGINE::ShowMouseCursor()
int i;
// Disables/Enables the mouse cursor:
if(!bState)
{
for(;;)
{
i = ShowCursor(FALSE);
if(i < 0)
break;
}
}
else
{
for(;;)
{
i = ShowCursor(TRUE);
if(i >= 0)
break;
}
}
} // end AS_ENGINE::ShowMouseCursor()
BOOL AS_ENGINE::IsExtensionSupported(const char *pbyExtension)
{ // begin AS_ENGINE::IsExtensionSupported()
const GLubyte *pbyExtensions = NULL;
const GLubyte *pbyStart;
GLubyte *pbyWhere, *pbyTerminator;
// Extension names should not have spaces:
pbyWhere = (GLubyte *) strchr(pbyExtension, ' ');
if(pbyWhere || *pbyExtension == '\0')
return 0;
pbyExtensions = glGetString(GL_EXTENSIONS);
// It takes a bit of care to be fool-proof about parsing the
// OpenGL extensions string. Don't be fooled by sub-strings,
// etc:
pbyStart = pbyExtensions;
for(;;)
{
pbyWhere = (GLubyte *) strstr((const char *) pbyStart, pbyExtension);
if(!pbyWhere)
break;
pbyTerminator = pbyWhere+strlen(pbyExtension);
if(pbyWhere == pbyStart || *(pbyWhere - 1) == ' ')
if(*pbyTerminator == ' ' || *pbyTerminator == '\0')
return 1;
pbyStart = pbyTerminator;
}
return 0;
} // end AS_ENGINE::IsExtensionSupported()
void AS_ENGINE::InitExtensions(void)
{ // begin AS_ENGINE::InitExtensions()
// Multi-texture:
bMultitexSupported = FALSE;
if(!IsExtensionSupported("GL_ARB_multitexture"))
{
_AS->WriteLogMessage("Extension GL_ARB_multitexture not found!");
_ASConfig->bMultitexturing = FALSE;
}
else
{
glActiveTextureARB = (PFNGLCLIENTACTIVETEXTUREARBPROC) wglGetProcAddress("glActiveTextureARB");
glMultiTexCoord2fARB = (PFNGLMULTITEXCOORD2FARBPROC) wglGetProcAddress("glMultiTexCoord2fARB");
glClientActiveTextureARB = (PFNGLACTIVETEXTUREARBPROC) wglGetProcAddress("glClientActiveTextureARB");
if(!glActiveTextureARB || !glMultiTexCoord2fARB || !glClientActiveTextureARB)
{
_AS->WriteLogMessage("Couldn't use extension GL_ARB_multitexture!");
_ASConfig->bMultitexturing = FALSE;
}
else
bMultitexSupported = TRUE;
}
// Compiled-vertex-arrays:
bCompiledVertexArraySupported = FALSE;
if(!IsExtensionSupported("GL_EXT_compiled_vertex_array"))
{
_AS->WriteLogMessage("Extension GL_EXT_compiled_vertex_array not found!");
_ASConfig->bMultitexturing = FALSE;
}
else
{
glLockArraysEXT = (PFNGLLOCKARRAYSEXTPROC) wglGetProcAddress("glLockArraysEXT");
glUnlockArraysEXT = (PFNGLUNLOCKARRAYSEXTPROC) wglGetProcAddress("glUnlockArraysEXT");
if(!glLockArraysEXT || !glUnlockArraysEXT)
_AS->WriteLogMessage("Couldn't use extension GL_EXT_compiled_vertex_array!");
else
bCompiledVertexArraySupported = TRUE;
}
} // end AS_ENGINE::InitExtensions()
// Functions: *****************************************************************
// Temporarily draw function:
HRESULT ASDraw(AS_WINDOW *pWindow)
{ // begin ASDraw()
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
ASSwapBuffers(*pWindow->GethDC(), pWindow, FALSE);
return 0;
} // end ASDraw()
// Temporarily check function:
HRESULT ASCheck(AS_WINDOW *pWindow)
{ // begin ASCheck()
return 0;
} // end ASCheck()
void ASSwapBuffers(HDC hDC, AS_WINDOW *pWindow, BOOL bShowInfo)
{ // begin ASSwapBuffers()
char byTemp[256];
glEnable(GL_TEXTURE_2D);
glEnable(GL_BLEND);
glDisable(GL_LIGHTING);
// Deactivate all lights:
if(_ASConfig->byLight)
{
for(int i = 0; i < 8; i++)
glDisable(GL_LIGHT0+i);
}
_AS->iActiveLights = 0;
glColor4f(1.0f, 1.0f, 1.0f, 0.95f);
if(_ASConfig->bShowFPS && bShowInfo)
{ // Display FPS:
sprintf(byTemp, "FPS: %.2f", _AS->GetFPS());
if(!pWindow)
ASPrint(0, 10, byTemp, 0);
else
pWindow->Print(0, 10, byTemp, 0, 0);
}
glFlush();
SwapBuffers(hDC);
// Check for screenshot:
if(_AS->bMakeScreenshot)
{
_AS->bMakeScreenshot = FALSE;
pWindow->MakeScreenshot(NULL);
}
} // end ASSwapBuffers()
///////////////////////////////////////////////////////////////////////////////
// Opens an dialog to get an filename:
char *ASGetFileName(HWND hWnd, char *pbyTitle, char *pbyFilter,
BOOL bMode, BOOL bMultiSelect, char *pbyInitalDir)
{ // begin ASGetFileName()
static char file[256];
static char fileTitle[256];
OPENFILENAME ofn;
lstrcpy( file, "");
lstrcpy( fileTitle, "");
ofn.lStructSize = sizeof(OPENFILENAME);
ofn.hwndOwner = hWnd;
#ifdef WIN32
ofn.hInstance = (HINSTANCE) GetWindowLong(hWnd, GWL_HINSTANCE);
#else
ofn.hInstance = (HINSTANCE) GetWindowWord(hWnd, GWW_HINSTANCE);
#endif
ofn.lpstrFilter = pbyFilter;
ofn.lpstrCustomFilter = (LPSTR) NULL;
ofn.nMaxCustFilter = 0L;
ofn.nFilterIndex = 1L;
ofn.lpstrFile = file;
ofn.nMaxFile = sizeof(file);
ofn.lpstrFileTitle = fileTitle;
ofn.nMaxFileTitle = sizeof(fileTitle);
ofn.lpstrInitialDir = pbyInitalDir;
ofn.lpstrTitle = pbyTitle;
ofn.nFileOffset = 0;
ofn.nFileExtension = 0;
ofn.lpstrDefExt = pbyFilter;
ofn.lCustData = 0;
ofn.Flags = OFN_PATHMUSTEXIST | OFN_ENABLESIZING | OFN_HIDEREADONLY | OFN_NONETWORKBUTTON;
if(!bMode) // We load a file...
ofn.Flags |= OFN_FILEMUSTEXIST;
if(bMultiSelect)
ofn.Flags |= OFN_ALLOWMULTISELECT;
if (GetOpenFileName(&ofn))
return (char *) ofn.lpstrFile;
return NULL;
} // end ASGetFileName()
///////////////////////////////////////////////////////////////////////////////
// Loads all textures in the list:
void ASLoadTextures(char (*byFilename)[256], int iTextures, AS_TEXTURE *Texture)
{ // begin ASLoadTextures()
char byTemp[256];
int i;
_AS->WriteLogMessage("Load textures");
for(i = 0; i < iTextures; i++)
{
sprintf(byTemp, "%s%s\\%s", _AS->byProgramPath, _AS->byBitmapsDirectory, byFilename[i]);
strcpy(Texture[i].byFilename, byTemp);
if(ASCheckStringEnding(byTemp, "jpg"))
ASLoadJpegRGB(&Texture[i], byTemp);
else
if(ASCheckStringEnding(byTemp, "bmp"))
ASLoadBmp(&Texture[i], byTemp);
else
if(ASCheckStringEnding(byTemp, "ppm"))
ASLoadPpm(&Texture[i], byTemp);
else
if(ASCheckStringEnding(byTemp, "tga"))
ASLoadTga(&Texture[i], byTemp);
}
_AS->WriteLogMessage("Load textures: OK");
} // begin ASLoadTextures()
///////////////////////////////////////////////////////////////////////////////
// Destroy all textures in the list:
void ASDestroyTextures(int iTextures, AS_TEXTURE *Texture)
{ // begin ASDestroyTextures()
if(!Texture[0].pbyData)
return;
_AS->WriteLogMessage("Destroy textures");
for(int i = 0; i < iTextures; i++)
{
_AS->WriteLogMessage(Texture[i].byFilename);
free(Texture[i].pbyData);
Texture[i].pbyData = NULL;
}
} // end ASDestroyTextures()
///////////////////////////////////////////////////////////////////////////////
// Generates all OpenGL textures:
void ASGenOpenGLTextures(int iTextures, AS_TEXTURE *Texture)
{ // begin ASGenOpenGLTextures()
if(!Texture[0].pbyData)
return;
_AS->WriteLogMessage("Generate OpenGL textures");
for(int i = 0; i < iTextures; i++)
{
_AS->WriteLogMessage(Texture[i].byFilename);
glGenTextures(1, &Texture[i].iOpenGLID);
glBindTexture(GL_TEXTURE_2D, Texture[i].iOpenGLID);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
if(_ASConfig->bUseMipmaps)
{
if(_ASConfig->bFastTexturing)
{
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST_MIPMAP_NEAREST);
gluBuild2DMipmaps(GL_TEXTURE_2D, Texture[i].byColorComponents, Texture[i].iWidth,
Texture[i].iHeight, Texture[i].iFormat, GL_UNSIGNED_BYTE,
Texture[i].pbyData);
}
else
{
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR_MIPMAP_LINEAR);
gluBuild2DMipmaps(GL_TEXTURE_2D, Texture[i].byColorComponents, Texture[i].iWidth,
Texture[i].iHeight, Texture[i].iFormat, GL_UNSIGNED_BYTE,
Texture[i].pbyData);
}
}
else
{
if(_ASConfig->bFastTexturing)
{
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST);
glTexImage2D(GL_TEXTURE_2D, 0, Texture[i].byColorComponents, Texture[i].iWidth,
Texture[i].iHeight, 0, Texture[i].iFormat, GL_UNSIGNED_BYTE,
Texture[i].pbyData);
}
else
{
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D, 0, Texture[i].byColorComponents, Texture[i].iWidth,
Texture[i].iHeight, 0, Texture[i].iFormat, GL_UNSIGNED_BYTE,
Texture[i].pbyData);
}
}
}
_AS->WriteLogMessage("Generate OpenGL textures: OK");
} // end ASGenOpenGLTextures()
///////////////////////////////////////////////////////////////////////////////
// Destroys all OpenGL textures:
void ASDestroyOpenGLTextures(int iTextures, AS_TEXTURE *Texture)
{ // begin ASDestroyOpenGLTextures()
if(!Texture[0].pbyData)
return;
_AS->WriteLogMessage("Destroy OpenGL textures");
for(int i = 0; i < iTextures; i++)
{
_AS->WriteLogMessage(Texture[i].byFilename);
glDeleteTextures(1, &Texture[i].iOpenGLID);
}
} // end ASDestroyOpenGLTextures()
///////////////////////////////////////////////////////////////////////////////
// Make sure dimension is a power of 2:
int ASCheckTextureSize(int iX)
{ // begin ASCheckTextureSize()
if (iX == 2 || iX == 4 ||
iX == 8 || iX == 16 ||
iX == 32 || iX == 64 ||
iX == 128 || iX == 256 ||
iX == 512 || iX == 1024)
return true;
return false;
} // end ASCheckTextureSize()
///////////////////////////////////////////////////////////////////////////////
// Loads a jpg texture:
BOOL ASLoadJpegRGB(AS_TEXTURE *pTexture, char *pbyFilename)
{ // begin ASLoadJpegRGB()
JPEG_CORE_PROPERTIES jcProps;
_AS->WriteLogMessage("Load jpg: %s", pbyFilename);
memset(&jcProps, 0, sizeof(JPEG_CORE_PROPERTIES));
ijlInit(&jcProps);
jcProps.JPGFile = pbyFilename;
ijlRead(&jcProps, IJL_JFILE_READPARAMS);
pTexture->iWidth = (int) jcProps.JPGWidth;
pTexture->iHeight = (int) jcProps.JPGHeight;
// Make sure dimension is a power of 2:
if(!ASCheckTextureSize(pTexture->iWidth) || !ASCheckTextureSize(pTexture->iHeight))
_AS->WriteLogMessage("Texture size is no dimension of 2. Maybe there could be some troubles with it!");
if(pTexture->iWidth > _AS->iMaxTextureSize || pTexture->iHeight > _AS->iMaxTextureSize)
_AS->WriteLogMessage("Texture size is to large for that system! (max: %dx%d)", _AS->iMaxTextureSize, _AS->iMaxTextureSize);
// Setup texture information:
pTexture->iFormat = GL_RGB;
pTexture->iImageBits = 24;
pTexture->byColorComponents = 3;
pTexture->pbyData = (BYTE *) malloc(pTexture->iWidth*pTexture->iHeight*pTexture->byColorComponents);
jcProps.DIBWidth = jcProps.JPGWidth;
jcProps.DIBHeight = jcProps.JPGHeight;
jcProps.DIBChannels = 3;
jcProps.DIBColor = IJL_RGB;
jcProps.DIBPadBytes = 0;
jcProps.DIBBytes = (BYTE *) pTexture->pbyData;
jcProps.JPGColor = IJL_YCBCR;
if(ijlRead(&jcProps, IJL_JFILE_READWHOLEIMAGE) != IJL_OK)
{
SAFE_DELETE(pTexture->pbyData);
return true;
}
ijlFree(&jcProps);
return false;
} // end ASLoadJpegRGB()
///////////////////////////////////////////////////////////////////////////////
// Loads a bmp texture:
BOOL ASLoadBmp(AS_TEXTURE *pTexture, char *pbyFilename)
{ // begin ASLoadBmp()
AUX_RGBImageRec *pImage;
int i;
if(!(pImage = auxDIBImageLoad(pbyFilename)))
return true;
// Get texture dimension:
pTexture->iWidth = pImage->sizeX;
pTexture->iHeight = pImage->sizeY;
// Setup texture information:
pTexture->iFormat = GL_RGB;
pTexture->iImageBits = 24;
pTexture->byColorComponents = 3;
// Make sure dimension is a power of 2:
if(!ASCheckTextureSize(pTexture->iWidth) || !ASCheckTextureSize(pTexture->iHeight))
_AS->WriteLogMessage("Texture size is no dimension of 2. Maybe there could be some troubles with it!");
if(pTexture->iWidth > _AS->iMaxTextureSize || pTexture->iHeight > _AS->iMaxTextureSize)
_AS->WriteLogMessage("Texture size is to large for that system! (max: %dx%d)", _AS->iMaxTextureSize, _AS->iMaxTextureSize);
pTexture->pbyData = (BYTE *) malloc(pTexture->iWidth*pTexture->iHeight*pTexture->byColorComponents);
// Get the fliped texture data:
for(i = 0; i < pTexture->iHeight; i++)
memcpy(&pTexture->pbyData[pTexture->byColorComponents*i*pTexture->iWidth],
&pImage->data[pTexture->byColorComponents*(pTexture->iHeight-i-1)*pTexture->iWidth],
pTexture->byColorComponents*pTexture->iWidth);
free(pImage->data);
return false;
} // end ASLoadBmp()
///////////////////////////////////////////////////////////////////////////////
// Loads a ppm texture:
BOOL ASLoadPpm(AS_TEXTURE *pTexture, char *pbyFilename)
{ // begin ASLoadPpm()
int x, y;
FILE *fp;
fp = fopen(pbyFilename, "rb");
if(!fp)
return true;
// Get the PPM bitmap size:
fscanf(fp, "P6\n%d %d\n255\n", &pTexture->iWidth, &pTexture->iHeight);
pTexture->iFormat = GL_RGB;
pTexture->iImageBits = 16;
pTexture->byColorComponents = 3;
// Go sure dimension is a power of 2:
if(!ASCheckTextureSize(pTexture->iWidth) || !ASCheckTextureSize(pTexture->iHeight))
_AS->WriteLogMessage("Texture size is no dimension of 2. Maybe there could be some troubles with it!");
if(pTexture->iWidth > _AS->iMaxTextureSize || pTexture->iHeight > _AS->iMaxTextureSize)
_AS->WriteLogMessage("Texture size is to large for that system! (max: %dx%d)", _AS->iMaxTextureSize, _AS->iMaxTextureSize);
pTexture->pbyData = (BYTE *) malloc(pTexture->iWidth*pTexture->iHeight*3);
if(!pTexture->pbyData)
return true;
// Now load in the bitmap:
for(y = 0; y < pTexture->iHeight; y++)
{
for(x = 0; x < pTexture->iWidth; x++)
{
pTexture->pbyData[(y*pTexture->iWidth+x)*3] = fgetc(fp);
pTexture->pbyData[(y*pTexture->iWidth+x)*3+1] = fgetc(fp);
pTexture->pbyData[(y*pTexture->iWidth+x)*3+2] = fgetc(fp);
}
}
fclose(fp);
return false;
} // end ASLoadPpm()
///////////////////////////////////////////////////////////////////////////////
// Loads up a targa file. Supported types are 8,24 and 32 uncompressed images.
BOOL ASLoadTga(AS_TEXTURE *pTexture, char *pbyFilename)
{ // begin ASLoadTga()
BYTE byType[4], byInfo[7];
BYTE byTemp, *pbyData;
int i, iSize, iBread;
FILE *fp;
if(!(fp = fopen(pbyFilename, "r+bt")))
return true;
fread(&byType, sizeof(BYTE), 3, fp); // Read in colormap info and image type, byte 0 ignored
fseek(fp, 12, SEEK_SET); // Seek past the header and useless info
fread(&byInfo, sizeof(BYTE), 6, fp);
if(byType[1] != 0 || (byType[2] != 2 && byType[2] != 3))
return true;
pTexture->iWidth = byInfo[0]+byInfo[1]*256;
pTexture->iHeight = byInfo[2]+byInfo[3]*256;
// Make sure dimension is a power of 2:
if(!ASCheckTextureSize(pTexture->iWidth) || !ASCheckTextureSize(pTexture->iHeight))
_AS->WriteLogMessage("Texture size is no dimension of 2. Maybe there could be some troubles with it!");
if(pTexture->iWidth > _AS->iMaxTextureSize || pTexture->iHeight > _AS->iMaxTextureSize)
_AS->WriteLogMessage("Texture size is to large for that system! (max: %dx%d)", _AS->iMaxTextureSize, _AS->iMaxTextureSize);
pTexture->iImageBits = byInfo[4];
iSize = pTexture->iWidth*pTexture->iHeight;
// Make sure we are load a supported type:
if(pTexture->iImageBits != 32 && pTexture->iImageBits != 24 && pTexture->iImageBits != 8)
return true;
pTexture->byColorComponents = (char) pTexture->iImageBits/8;
// Get texture data:
switch(pTexture->iImageBits)
{
case 32:
if(!(pbyData = (BYTE *) malloc(iSize*4)))
return true;
if(!(pTexture->pbyData = (BYTE *) malloc(iSize*4)))
return true;
iBread = fread(pbyData, sizeof(BYTE), iSize*4, fp);
// TGA is stored in BGRA:
if(iBread != iSize*4)
{
free(pbyData);
free(pTexture->pbyData);
return true;
}
for(i = 0; i < iSize*4; i += 4)
{
byTemp = pbyData[i];
pbyData[i] = pbyData[i+2];
pbyData[i+2] = byTemp;
}
pTexture->iFormat = GL_RGBA;
break;
case 24:
if(!(pbyData = (BYTE *) malloc(iSize*3)))
return true;
if(!(pTexture->pbyData = (BYTE *) malloc(iSize*3)))
return true;
iBread = fread(pbyData, sizeof(BYTE), iSize*3, fp);
// TGA is stored in BGR:
if(iBread != iSize*3)
{
free(pbyData);
free(pTexture->pbyData);
return true;
}
for(i = 0; i < iSize*3; i += 3)
{
byTemp = pbyData[i];
pbyData[i] = pbyData[i+2];
pbyData[i+2] = byTemp;
}
pTexture->iFormat = GL_RGB;
break;
case 8:
if(!(pbyData = (BYTE *) malloc(iSize)))
return true;
if(!(pTexture->pbyData = (BYTE *) malloc(iSize)))
return true;
iBread = fread(pbyData, sizeof(BYTE), iSize, fp);
if(iBread != iSize)
{
free(pbyData);
free(pTexture->pbyData);
return true;
}
pTexture->iFormat = GL_LUMINANCE;
break;
default: return true;
}
fclose(fp);
// Flip texture data:
for(i = 0; i < pTexture->iHeight; i++)
memcpy(&pTexture->pbyData[pTexture->byColorComponents*i*pTexture->iWidth],
&pbyData[pTexture->byColorComponents*(pTexture->iHeight-i-1)*pTexture->iWidth],
pTexture->byColorComponents*pTexture->iWidth);
free(pbyData);
return false;
} // end ASLoadTga()
///////////////////////////////////////////////////////////////////////////////
// Saves a ppm texture:
void ASSavePpm(AS_TEXTURE *pTextureT, char *pbyFilename)
{ // begin ASSavePpm()
int x, y, c;
FILE *fp;
if(!pTextureT->pbyData)
return;
fp = fopen(pbyFilename, "wb");
if(!fp)
return;
// Write the PPM file:
fprintf (fp, "P6\n%d %d\n255\n", pTextureT->iWidth, pTextureT->iHeight);
for(y = 0; y < pTextureT->iHeight; y++)
{
for(x = 0; x < pTextureT->iWidth; x++)
{
c = 0xff & pTextureT->pbyData[((pTextureT->iHeight-1-y)*pTextureT->iWidth+x)*3];
fputc(c, fp);
c = 0xff & pTextureT->pbyData[((pTextureT->iHeight-1-y)*pTextureT->iWidth+x)*3+1];
fputc (c, fp);
c = 0xff & pTextureT->pbyData[((pTextureT->iHeight-1-y)*pTextureT->iWidth+x)*3+2];
fputc(c, fp);
}
}
fclose(fp);
} // end ASSavePpm()
///////////////////////////////////////////////////////////////////////////////
// Gets the CPU speed:
DWORD ASGetCpuSpeed(void)
{ // begin ASGetCpuSpeed()
int timeStart = 0;
int timeStop = 0;
unsigned long StartTicks = 0;
unsigned long EndTicks = 0;
unsigned long TotalTicks = 0;
unsigned long cpuSpeed = 0;
timeStart = timeGetTime();
for(;;)
{
timeStop = timeGetTime();
if((timeStop-timeStart) > 1)
{ // rollover past 1
__asm
{
xor eax, eax
xor ebx, ebx
xor ecx, ecx
xor edx, edx
_emit 0x0f // CPUID
_emit 0xa2
_emit 0x0f // RTDSC
_emit 0x31
mov [StartTicks], eax // Tick counter starts here
}
break;
}
}
timeStart = timeStop;
for(;;)
{
timeStop = timeGetTime();
if((timeStop-timeStart) > 1000)
{ // one second
__asm
{
xor eax, eax
xor ebx, ebx
xor ecx, ecx
xor edx, edx
_emit 0x0f
_emit 0xa2
_emit 0x0f
_emit 0x31
mov [EndTicks], eax
}
break;
}
}
TotalTicks = EndTicks-StartTicks; // total
cpuSpeed = TotalTicks/1000000; // speed
return((DWORD) cpuSpeed);
} // end ASGetCpuSpeed()
///////////////////////////////////////////////////////////////////////////////
// Removes an directory, but first it removes all files in it:
void ASRemoveDirectory(char *pbyFilename)
{ // begin ASRemoveDirectory()
WIN32_FIND_DATA FindFileData;
char byTemp[256];
HANDLE Find;
// Delete all files in this dictory:
sprintf(byTemp, "%s*.*", pbyFilename);
Find = FindFirstFile(byTemp, &FindFileData);
for(;;)
{
if(FindFileData.cFileName[0] != '.' && FindFileData.dwFileAttributes == FILE_ATTRIBUTE_DIRECTORY)
{ // We found a new sub directory:
sprintf(byTemp, "%s%s\\", pbyFilename, FindFileData.cFileName);
ASRemoveDirectory(byTemp);
}
else
{
sprintf(byTemp, "%s%s", pbyFilename, FindFileData.cFileName);
remove(byTemp);
}
if(!FindNextFile(Find, &FindFileData))
break;
}
FindClose(Find);
// Remove the empty dictory:
RemoveDirectory(pbyFilename);
} // end ASRemoveDirectory()
///////////////////////////////////////////////////////////////////////////////
// Checks if a string ends which a given string:
BOOL ASCheckStringEnding(char *pbyText, char byEnding[256])
{ // begin ASCheckStringEnding()
_strlwr(pbyText);
for(int i = 0; i < (signed) strlen(byEnding); i++)
{
if(pbyText[strlen(pbyText)-(strlen(byEnding)-i)] != byEnding[i])
break;
}
if(i == (signed) strlen(byEnding))
return true;
return false;
} // end ASCheckStringEnding()