There is a serious bug in DarkGDK causing the first variable in your program to be modified whenever there is an error.
Also, there is currently no good way to detect when errors occured.
For these reasons I made these error functions, which let you handle errors however you want!
In addition, they prevent GDK from modifying the first variable in your program! (The error code output is redirected to a specially made variable)
GDKError.h
const char* GetRuntimeError(unsigned long code);
void SetErrorHandler(void (__stdcall *handler)(unsigned long, const char*));
GDKError.cpp
#include "GDKError.h"
#include "DarkGDK.h"
#include "globstruct.h"
class CRuntimeErrorHandler {};
extern CRuntimeErrorHandler* g_pErrorHandler; // ?g_pErrorHandler@@3PAVCRuntimeErrorHandler@@A
extern void* g_ErrorHandler; // ?g_ErrorHandler@@3PAXA
extern GlobStruct g_Glob; // ?g_Glob@@3UGlobStruct@@A
void __cdecl RunTimeError(unsigned long);
void __cdecl RunTimeError(unsigned long, char*);
void (__stdcall *GDK_ErrorHandler)(unsigned long, const char*);
int GDKErrorCode = 0;
const char* GetRuntimeError(unsigned long code)
{
switch (code)
{
case 0: return "An unknown error has occurred";
case 1: return "Broke from nested subroutine. Cannot resume program after CLI usage.";
case 21: return "The program tried to execute a function header declaration";
case 51: return "The index number you have used is bigger than the array size";
case 52: return "The index number you have used must be within the arrray";
case 53: return "The array is empty";
case 54: return "Array type is invalid";
case 55: return "Array specified must be a single dimension array for this type of command";
case 101: return "There was not enough memory to make such an array";
case 102: return "Unknown array error";
case 103: return "The file is too large";
case 104: return "The file is invalid";
case 105: return "File does not exist";
case 106: return "File already exists";
case 107: return "The string is to long";
case 108: return "Stack overflow error";
case 109: return "Cannot make an array of that type";
case 110: return "Only positive numbers are allowed";
case 111: return "Divide by zero error";
case 112: return "Illegal size error";
case 113: return "Only positive numbers are allowed";
case 114: return "You must use a variable";
case 115: return "You must use a variable";
case 116: return "This command is now obsolete";
case 117: return "Cannot access the file because it is being used by another process";
case 118: return "Array does not exist or array subscript out of bounds";
case 119: return "Division by zero";
case 300: return "Unknown sprite error";
case 301: return "Sprite number must be greater than zero";
case 302: return "Sprite does not exist";
case 303: return "Sprite backsave illegal";
case 304: return "Sprite transparency illegal";
case 310: return "Sprite rotation illegal";
case 311: return "Sprite scale illegal";
case 312: return "Sprite size illegal";
case 313: return "Sprite angle illegal";
case 314: return "Sprite alpha value illegal";
case 315: return "Sprite rgb value illegal";
case 316: return "Sprite animation delay value illegal";
case 317: return "Sprite vertex number illegal";
case 318: return "Sprite width illegal";
case 319: return "Sprite height illegal";
case 320: return "Sprite animation value illegal";
case 321: return "Sprite already exists";
case 500: return "Unknown image error";
case 501: return "Image number illegal";
case 502: return "Image does not exist";
case 503: return "Cannot grab image due to the area being too large";
case 504: return "Cannot grab image due to an illegal area";
case 505: return "Image is too large to be a texture";
case 506: return "Could not load image";
case 507: return "Cannot read an image currently locked by system";
case 1000: return "Unknown bitmap error";
case 1001: return "Bitmap number illegal";
case 1002: return "Bitmap does not exist";
case 1003: return "Could not load bitmap";
case 1004: return "Could not save bitmap";
case 1005: return "Could not create bitmap";
case 1006: return "Cannot delete bitmap zerp";
case 1007: return "Bitmap numbers are identical";
case 1008: return "Source bitmap is too large";
case 1009: return "Bitmap zero is reserved";
case 1010: return "Region has exceeded bitmap size";
case 1011: return "Bitmap area is illegal";
case 1012: return "Blur value illegal";
case 1013: return "Fade value illegal";
case 1014: return "Gamm value illegal";
case 1500: return "Unknown screen error";
case 1501: return "Screen size is illegal";
case 1502: return "Screen depth is illegal";
case 1503: return "Screen mode is illegal";
case 1504: return "Display cannot be created due to unknown DirectX error";
case 1505: return "Display using 16 bit is not supported by available hardware";
case 1506: return "Display using 24 bit is not supported by available hardware";
case 1507: return "Display using 32 bit is not supported by available hardware";
case 1508: return "Display does not support selected method of vertex processing";
case 1509: return "Display does not support selected method of backbuffer access";
case 1510: return "Display cannot be initialized due to absent DirectX interface";
case 1511: return "Display cannot be created due to invalid function parameters";
case 1512: return "Display is not supported by available hardware";
case 1513: return "Display cannot be created due to insufficient video memory";
case 1514: return "24 bit depth not supported. Select either 16 or 32 bit mode";
case 2000: return "Unknown animation error";
case 2001: return "Animation number illegal";
case 2002: return "Could not load animation";
case 2003: return "Animation already exists";
case 2004: return "Animation does not exist";
case 2005: return "Animation volume value illegal";
case 2006: return "Animation frequency value illegal";
case 2007: return "Animation is already playing";
case 2008: return "Animation is not playing";
case 2009: return "Animation is already paused";
case 2010: return "Animation is not paused";
case 3000: return "Unknown sound error";
case 3001: return "Sound number illegal";
case 3002: return "Could not load sound";
case 3003: return "Sound already exists";
case 3004: return "Sound does not exist";
case 3005: return "Sound volume value illegal";
case 3006: return "Sound frequency value illegal";
case 3007: return "Sound pan value illegal";
case 3008: return "Could not save sound";
case 3021: return "Could not clone sound";
case 3022: return "A sound must be specified";
case 3023: return "A sound must be specified to clone ";
case 3201: return "A speech engine cannot be found";
case 3500: return "Unknown music error";
case 3501: return "Music number illegal";
case 3502: return "Could not load music";
case 3503: return "Music already exists";
case 3504: return "Music does not exist";
case 3505: return "Music volume value illegal";
case 3506: return "Music speed value illegal";
case 3507: return "Music is not playing";
case 3508: return "Music track is illegal ";
case 4001: return "Unknown controller error";
case 4002: return "A controller has not been selected";
case 4101: return "No force-feedback controller found";
case 4102: return "Magnitude value illegal";
case 4103: return "Duration value illegal";
case 4104: return "Angle value illegal";
case 5101: return "Memblock range is illegal";
case 5102: return "Memblock already exists";
case 5103: return "Memblock does not exist";
case 5104: return "Could not create memblock";
case 5105: return "Memblock position outside range";
case 5106: return "Memblock size value illegal";
case 5107: return "Not a memblock byte";
case 5108: return "Not a memblock word";
case 5109: return "Not a memblock dword";
case 7000: return "Unknown 3D error";
case 7001: return "Mesh number illegal";
case 7002: return "Could not load mesh";
case 7003: return "Mesh does not exist";
case 7004: return "Mesh darken value illegal";
case 7005: return "Mesh lighten value illegal";
case 7006: return "Object number illegal";
case 7007: return "Object already exists";
case 7008: return "Object does not exist";
case 7009: return "Matrix already exists";
case 7010: return "Matrix number illegal";
case 7011: return "Matrix dimensions illegal";
case 7012: return "Matrix segments illegal";
case 7013: return "Matrix does not exist";
case 7014: return "Matrix height error";
case 7015: return "Matrix exceeds maximum size";
case 7016: return "Matrix tile illegal";
case 7017: return "Matrix coordinates illegal";
case 7018: return "Could not load 3D object";
case 7019: return "Object angle value illegal";
case 7020: return "Too many limbs exist in the object";
case 7021: return "Limb number illegal";
case 7022: return "Cannot add a limb with that number";
case 7023: return "Limb does not exist";
case 7024: return "Limb already exists";
case 7025: return "Cannot link a limb to that number";
case 7026: return "You must link limbs in chain sequence";
case 7027: return "You can only link new limbs";
case 7028: return "Mesh is too large for limb placement";
case 7029: return "3D Memory Error";
case 7030: return "You must use the .DBO extension for a saved DBPro object";
case 7031: return "Object fade value illegal";
case 7032: return "Limb does not contain a mesh";
case 7101: return "Particles object already exists";
case 7102: return "Particles object does not exist";
case 7103: return "Unknown particles objects error";
case 7104: return "Particle number illegal";
case 7105: return "Particle must have an emission value greater than zero";
case 7126: return "Could not create terrain";
case 7127: return "Terrain already exists";
case 7128: return "Terrain does not exist";
case 7129: return "Terrain data must be exactly square";
case 7130: return "Terrain number illegal";
case 7151: return "Could not load BSP file";
case 7152: return "BSP does not exist";
case 7153: return "BSP already exists";
case 7154: return "BSP collision index must be between 1 and 24";
case 7201: return "Camera number illegal";
case 7202: return "Camera already exists";
case 7203: return "Camera does not exist";
case 7204: return "Cannot create camera";
case 7205: return "Cannot use camera zero";
case 7301: return "Light number illegal";
case 7302: return "Light already exists";
case 7303: return "Light does not exist";
case 7304: return "Cannot create light ";
case 7305: return "Cannot use light zero";
case 7601: return "Animation frame number illegal";
case 7602: return "Animation keyframe does not exist";
case 7603: return "Animation speed value illegal";
case 7604: return "Animation interpolation illegal";
case 7605: return "Cannot append to the object";
case 7606: return "Append can only add to end of object animation";
case 7607: return "Failed to compile CSG file from X File";
case 7701: return "Vertex shader number illegal";
case 7702: return "Vertex shader count illegal";
case 7703: return "Cannot create vertex shader";
case 7704: return "Vertex shader stream position illegal";
case 7705: return "Vertex shader data illegal";
case 7706: return "Vertex shader stream illegal";
case 7707: return "Vertex shader cannot be assembled";
case 7708: return "Vertex shader is illegal";
case 7721: return "Effect number is illegal";
case 7722: return "Effect does not exist";
case 7723: return "Effect already exists";
case 7801: return "Vector does not exist";
case 7802: return "Matrix4 does not exist";
case 7901: return "Fogging effect is not available";
case 7911: return "Ambient percentage value illegal";
case 7912: return "Camera range value illegal";
case 7931: return "The source must be a 3DS file";
case 7932: return "The destination must be an X file";
case 8001: return "Could not scan current directory";
case 8002: return "There are no more files in directory";
case 8003: return "Could not find path";
case 8021: return "Could not make file";
case 8022: return "Could not delete file";
case 8023: return "Could not copy file";
case 8024: return "Could not rename file";
case 8025: return "Could not move file";
case 8101: return "Could not create directory";
case 8102: return "Could not delete directory";
case 8103: return "Could not execute file";
case 8201: return "Could not open file for reading";
case 8202: return "Could not open file for writing";
case 8203: return "File is already open";
case 8204: return "File is not open";
case 8211: return "Cannot read from file";
case 8212: return "Cannot write to file";
case 8213: return "File number illegal";
case 8301: return "Could not connect to FTP";
case 8302: return "Cannot find FTP path";
case 8303: return "Cannot put FTP file";
case 8304: return "Cannot delete FTP file";
case 8305: return "Cannot get FTP file";
case 8501: return "Could not establish multiplayer connection";
case 8502: return "Could not find session";
case 8503: return "Could not setup session";
case 8504: return "Could not create net game";
case 8505: return "Could not join net game";
case 8506: return "Could not send net game message";
case 8507: return "Only 2 to 255 players can be specified";
case 8508: return "Player name required";
case 8509: return "Game name required";
case 8510: return "Connection number illegal";
case 8511: return "Session number illegal";
case 8512: return "Player number illegal";
case 8513: return "Not currently in net game session";
case 8514: return "Player number does not exist";
case 8515: return "Session number does not exist";
case 8516: return "Player could not be created";
case 8517: return "Player could not be deleted";
case 8518: return "Too many players in session";
case 9001: return "Checklist number illegal";
case 9002: return "Checklist number illegal";
case 9003: return "Checklist contains only numbers";
case 9004: return "Checklist contains only strings";
case 9005: return "Checklist does not exist";
case 9011: return "Could not find the device";
case 9012: return "Could not get texture memory";
case 9013: return "Could not get video memory";
case 9014: return "Could not get system memory";
case 9701: return "Could not load DLL";
case 9702: return "DLL does not exist";
case 9703: return "DLL already exists";
case 9704: return "Could not call DLL function";
case 9705: return "Index number illegal";
}
return 0;
}
void SetErrorCode(int& variable)
{
g_pErrorHandler = (CRuntimeErrorHandler*)&variable;
g_ErrorHandler = &variable;
g_Glob.g_pErrorHandlerRef = &variable;
}
__declspec(naked) void _ErrorHandler()
{
__asm
{
mov ecx,dword ptr [esp+4];
mov dword ptr [eax],ecx;
mov ebx,dword ptr [esp+0x120];
pushad;
push ebx;
push ecx;
call GDK_ErrorHandler;
popad;
ret;
}
}
void SetErrorHandler(void (__stdcall *handler)(unsigned long, const char*))
{
SetErrorCode(GDKErrorCode);
void (__cdecl *rte1)(unsigned long) = &RunTimeError;
void (__cdecl *rte2)(unsigned long, char*) = &RunTimeError;
unsigned char* ptr = (unsigned char*)rte1;
ptr++;
int offset = *((unsigned int*)ptr);
ptr += offset + 4;
ptr += 0x7; // Correct byte offset
DWORD oldProtect;
DWORD tmp;
VirtualProtect(ptr,0x7,PAGE_READWRITE,&oldProtect);
*(ptr++) = 0x0F;
*(ptr++) = 0x85;
*((int*)ptr) = ((char*)&_ErrorHandler - (char*)ptr)-4; ptr += 4;
*(ptr++) = 0xC3;
VirtualProtect(ptr,0x7,oldProtect,&tmp);
GDK_ErrorHandler = handler;
}
Just add those two files to your project, and then include "GDKError.h" from your main source file.
At the very start of your program, call "SetErrorHandler" with a function to handle errors.
Here is an example program which catches and displays errors in the same way as DBPro (except that it doesn't end the program):
#include "DarkGDK.h"
#include "globstruct.h"
#include "GDKError.h"
void __stdcall ErrorHandler(unsigned long errorCode, const char* errorDesc)
{
char buffer[512];
const char* errorMsg = GetRuntimeError(errorCode);
sprintf_s(buffer,"Runtime Error %i - %s\n\n%s",errorCode,errorMsg,errorDesc);
MessageBox(0,buffer,"Error",0);
}
// the main entry point for the application is this function
void DarkGDK ( void )
{
SetErrorHandler(&ErrorHandler);
// turn on sync rate and set maximum rate to 60 fps
dbSyncOn ( );
dbSyncRate ( 60 );
dbLoadImage("None.png",1);
// our main loop
while ( LoopGDK ( ) )
{
// update the screen
dbSync ( );
}
// return back to windows
return;
}
As you can see, the "dbLoadImage" command will fail because the image does not exist. This will cause the "ErrorHandler" function to be called, which then displays the following error message:
Quote: "
---------------------------
Error
---------------------------
Runtime Error 506 - Could not load image
CWD:c:\Documents and Settings\John Smith\My Documents\Visual Studio 2008\Projects\Dark GDK - Game1\Dark GDK - Game1
LOAD IMAGE None.png,1
---------------------------
OK
---------------------------
"
Enjoy