mirror of
https://github.com/1dot13/source.git
synced 2026-07-22 13:40:22 +02:00
git-svn-id: https://ja2svn.mooo.com/source/ja2/trunk/GameSource/ja2_v1.13/Build@21 3b4a5df2-a311-0410-b5c6-a8a6f20db521
639 lines
15 KiB
C++
639 lines
15 KiB
C++
|
|
// JA2
|
|
|
|
//**************************************************************************
|
|
//
|
|
// Filename : debug.c
|
|
//
|
|
// Purpose : debug manager implementation
|
|
//
|
|
// Modification history :
|
|
//
|
|
// xxxxx96:LH - Creation
|
|
// xxnov96:HJH - made it work
|
|
//
|
|
//**************************************************************************
|
|
|
|
// Because we're in a library, define SGP_DEBUG here - the client may not always
|
|
// use the code to write text, because the header switches on the define
|
|
#define SGP_DEBUG
|
|
|
|
|
|
#ifdef JA2_PRECOMPILED_HEADERS
|
|
#include "JA2 SGP ALL.H"
|
|
#elif defined( WIZ8_PRECOMPILED_HEADERS )
|
|
#include "WIZ8 SGP ALL.H"
|
|
#else
|
|
#include "types.h"
|
|
#include <windows.h>
|
|
#include <ddeml.h>
|
|
#include <stdio.h>
|
|
#include "debug.h"
|
|
#include "WCheck.h"
|
|
#include "TopicIDs.h"
|
|
#include "TopicOps.h"
|
|
#include "WizShare.h"
|
|
|
|
//Kris addition
|
|
#ifdef JA2
|
|
#include "screenids.h"
|
|
#include "Sys Globals.h"
|
|
#include "jascreens.h"
|
|
#include "gameloop.h"
|
|
#include "input.h"
|
|
#endif
|
|
|
|
// CJC added
|
|
#ifndef _NO_DEBUG_TXT
|
|
#include "fileman.h"
|
|
#endif
|
|
#endif
|
|
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
#endif
|
|
|
|
BOOLEAN gfRecordToFile = FALSE;
|
|
BOOLEAN gfRecordToDebugger = TRUE;
|
|
|
|
// moved from header file: 24mar98:HJH
|
|
UINT32 guiProfileStart, guiExecutions, guiProfileTime;
|
|
INT32 giProfileCount;
|
|
|
|
// Had to move these outside the ifdef SGP_DEBUG below, because
|
|
// they are required for the String() function, which is NOT a
|
|
// debug-mode only function, it's used in release-mode as well! -- DB
|
|
|
|
UINT8 gubAssertString[128];
|
|
|
|
#define MAX_MSG_LENGTH2 512
|
|
UINT8 gbTmpDebugString[8][MAX_MSG_LENGTH2];
|
|
UINT8 gubStringIndex = 0;
|
|
|
|
#ifdef SGP_DEBUG
|
|
|
|
//**************************************************************************
|
|
//
|
|
// Defines
|
|
//
|
|
//**************************************************************************
|
|
|
|
#define BUFSIZE 100
|
|
#define TIMER_TIMEOUT 1000
|
|
|
|
//**************************************************************************
|
|
//
|
|
// Variables
|
|
//
|
|
//**************************************************************************
|
|
|
|
UINT16 TOPIC_MEMORY_MANAGER = INVALID_TOPIC;
|
|
UINT16 TOPIC_FILE_MANAGER = INVALID_TOPIC;
|
|
UINT16 TOPIC_DATABASE_MANAGER = INVALID_TOPIC;
|
|
UINT16 TOPIC_GAME = INVALID_TOPIC;
|
|
UINT16 TOPIC_SGP = INVALID_TOPIC;
|
|
UINT16 TOPIC_VIDEO = INVALID_TOPIC;
|
|
UINT16 TOPIC_INPUT = INVALID_TOPIC;
|
|
UINT16 TOPIC_STACK_CONTAINERS = INVALID_TOPIC;
|
|
UINT16 TOPIC_LIST_CONTAINERS = INVALID_TOPIC;
|
|
UINT16 TOPIC_QUEUE_CONTAINERS = INVALID_TOPIC;
|
|
UINT16 TOPIC_PRILIST_CONTAINERS = INVALID_TOPIC;
|
|
UINT16 TOPIC_HIMAGE = INVALID_TOPIC;
|
|
UINT16 TOPIC_ORDLIST_CONTAINERS = INVALID_TOPIC;
|
|
UINT16 TOPIC_3DENGINE = INVALID_TOPIC;
|
|
UINT16 TOPIC_VIDEOOBJECT = INVALID_TOPIC;
|
|
UINT16 TOPIC_FONT_HANDLER = INVALID_TOPIC;
|
|
UINT16 TOPIC_VIDEOSURFACE = INVALID_TOPIC;
|
|
UINT16 TOPIC_MOUSE_SYSTEM = INVALID_TOPIC;
|
|
UINT16 TOPIC_BUTTON_HANDLER = INVALID_TOPIC;
|
|
UINT16 TOPIC_MUTEX = INVALID_TOPIC;
|
|
UINT16 TOPIC_JA2 = 3;
|
|
UINT16 TOPIC_BLIT_QUEUE = INVALID_TOPIC;
|
|
UINT16 TOPIC_JA2OPPLIST = 2;
|
|
UINT16 TOPIC_JA2AI = 1;
|
|
|
|
|
|
UINT32 guiTimerID = 0;
|
|
UINT8 guiDebugLevels[NUM_TOPIC_IDS]; // don't change this, Luis!!!!
|
|
|
|
BOOLEAN gfDebugTopics[MAX_TOPICS_ALLOTED];
|
|
UINT16 *gpDbgTopicPtrs[MAX_TOPICS_ALLOTED];
|
|
|
|
|
|
// remove debug .txt file
|
|
void RemoveDebugText( void );
|
|
|
|
STRING512 gpcDebugLogFileName;
|
|
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif
|
|
|
|
//**************************************************************************
|
|
//
|
|
// Functions
|
|
//
|
|
//**************************************************************************
|
|
|
|
|
|
//**************************************************************************
|
|
//
|
|
// DbgGetLogFileName
|
|
//
|
|
//
|
|
//
|
|
// Parameter List :
|
|
// Return Value :
|
|
// Modification history :
|
|
//
|
|
// xxjun98:CJC -> creation
|
|
//
|
|
//**************************************************************************
|
|
BOOLEAN DbgGetLogFileName( STRING512 pcName )
|
|
{
|
|
// use the provided buffer to get the directory name, then tack on
|
|
// "\debug.txt"
|
|
#ifndef _NO_DEBUG_TXT
|
|
if ( ! GetExecutableDirectory( pcName ) )
|
|
{
|
|
return( FALSE );
|
|
}
|
|
|
|
if ( strlen( pcName ) > (512 - strlen( "\\debug.txt" ) - 1 ) )
|
|
{
|
|
// no room!
|
|
return( FALSE );
|
|
}
|
|
|
|
strcat( pcName, "\\debug.txt" );
|
|
#endif
|
|
|
|
return( TRUE );
|
|
}
|
|
|
|
|
|
//**************************************************************************
|
|
//
|
|
// DbgInitialize
|
|
//
|
|
//
|
|
//
|
|
// Parameter List :
|
|
// Return Value :
|
|
// Modification history :
|
|
//
|
|
// xxnov96:HJH -> creation
|
|
//
|
|
//**************************************************************************
|
|
|
|
BOOLEAN DbgInitialize(void)
|
|
{
|
|
INT32 iX;
|
|
|
|
for( iX = 0; iX < MAX_TOPICS_ALLOTED; iX++ )
|
|
{
|
|
gpDbgTopicPtrs[iX] = NULL;
|
|
}
|
|
|
|
DbgClearAllTopics();
|
|
|
|
gfRecordToFile = TRUE;
|
|
gfRecordToDebugger = TRUE;
|
|
gubAssertString[0] = '\0';
|
|
|
|
#ifndef _NO_DEBUG_TXT
|
|
if (! DbgGetLogFileName( gpcDebugLogFileName ) )
|
|
{
|
|
return( FALSE );
|
|
}
|
|
// clear debug text file out
|
|
RemoveDebugText( );
|
|
#endif
|
|
|
|
return(TRUE);
|
|
}
|
|
|
|
//**************************************************************************
|
|
//
|
|
// DbgShutdown
|
|
//
|
|
//
|
|
//
|
|
// Parameter List :
|
|
// Return Value :
|
|
// Modification history :
|
|
//
|
|
// xxnov96:HJH -> creation
|
|
//
|
|
//**************************************************************************
|
|
|
|
void DbgShutdown(void)
|
|
{
|
|
DbgMessageReal( (UINT16)(-1), CLIENT_SHUTDOWN, 0, "SGP Going Down" );
|
|
}
|
|
|
|
|
|
//**************************************************************************
|
|
//
|
|
// DbgTopicRegistration
|
|
//
|
|
//
|
|
// Parameter List :
|
|
// Return Value :
|
|
// Modification history :
|
|
//
|
|
// June 97: BR -> creation
|
|
//
|
|
//**************************************************************************
|
|
|
|
void DbgTopicRegistration( UINT8 ubCmd, UINT16 *usTopicID, CHAR8 *zMessage )
|
|
{
|
|
UINT16 usIndex,usUse;
|
|
BOOLEAN fFound;
|
|
|
|
if ( usTopicID == NULL )
|
|
return;
|
|
|
|
if( ubCmd == TOPIC_REGISTER )
|
|
{
|
|
usUse = INVALID_TOPIC;
|
|
fFound = FALSE;
|
|
for( usIndex = 0; usIndex < MAX_TOPICS_ALLOTED && !fFound; usIndex++)
|
|
{
|
|
if ( !gfDebugTopics[usIndex] )
|
|
{
|
|
fFound = TRUE;
|
|
usUse = usIndex;
|
|
}
|
|
}
|
|
|
|
gfDebugTopics[ usUse ] = TRUE;
|
|
*usTopicID = usUse;
|
|
gpDbgTopicPtrs[usUse] = usTopicID;
|
|
DbgMessageReal(usUse, TOPIC_MESSAGE, DBG_LEVEL_0, zMessage );
|
|
}
|
|
else if( ubCmd == TOPIC_UNREGISTER )
|
|
{
|
|
if ( *usTopicID >= MAX_TOPICS_ALLOTED )
|
|
return;
|
|
|
|
DbgMessageReal( *usTopicID, TOPIC_MESSAGE, DBG_LEVEL_0, zMessage );
|
|
gfDebugTopics[ *usTopicID ] = FALSE;
|
|
|
|
|
|
if (gpDbgTopicPtrs[ *usTopicID ] != NULL )
|
|
{
|
|
gpDbgTopicPtrs[ *usTopicID ] = NULL;
|
|
}
|
|
|
|
*usTopicID = INVALID_TOPIC;
|
|
}
|
|
}
|
|
|
|
|
|
// *************************************************************************
|
|
// Clear the debug txt file out to prevent it from getting huge
|
|
//
|
|
//
|
|
// *************************************************************************
|
|
|
|
void RemoveDebugText( void )
|
|
{
|
|
DeleteFile( gpcDebugLogFileName );
|
|
}
|
|
|
|
|
|
//**************************************************************************
|
|
//
|
|
// DbgClearAllTopics
|
|
//
|
|
//
|
|
// Parameter List :
|
|
// Return Value :
|
|
// Modification history :
|
|
//
|
|
// June 97: BR -> creation
|
|
//
|
|
//**************************************************************************
|
|
|
|
void DbgClearAllTopics( void )
|
|
{
|
|
UINT16 usIndex;
|
|
|
|
for( usIndex = 0; usIndex < MAX_TOPICS_ALLOTED; usIndex++)
|
|
{
|
|
gfDebugTopics[ usIndex ] = FALSE;
|
|
if ( gpDbgTopicPtrs[ usIndex ] != NULL )
|
|
{
|
|
*gpDbgTopicPtrs[usIndex] = INVALID_TOPIC;
|
|
gpDbgTopicPtrs[usIndex] = NULL;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
//**************************************************************************
|
|
//
|
|
// DbgMessageReal
|
|
//
|
|
//
|
|
//
|
|
// Parameter List :
|
|
// Return Value :
|
|
// Modification history :
|
|
//
|
|
// xxnov96:HJH -> creation
|
|
//
|
|
//**************************************************************************
|
|
template void DbgMessageReal<unsigned char *>(UINT16, UINT8, UINT8, unsigned char *);
|
|
template <typename type4>
|
|
void DbgMessageReal(UINT16 uiTopicId, UINT8 uiCommand, UINT8 uiDebugLevel, type4 strMessage)
|
|
{
|
|
#ifndef _NO_DEBUG_TXT
|
|
FILE *OutFile;
|
|
#endif
|
|
|
|
// Check for a registered topic ID
|
|
if ( uiTopicId < MAX_TOPICS_ALLOTED )//&& gfDebugTopics[uiTopicId] )
|
|
{
|
|
OutputDebugString ( (LPCSTR) strMessage );
|
|
OutputDebugString ( "\n" );
|
|
|
|
//add _NO_DEBUG_TXT to your SGP preprocessor definitions to avoid this f**king huge file from
|
|
//slowly growing behind the scenes!!!!
|
|
#ifndef _NO_DEBUG_TXT
|
|
if ((OutFile = fopen(gpcDebugLogFileName, "a+t")) != NULL)
|
|
{
|
|
fprintf(OutFile, "%s\n", strMessage);
|
|
fclose(OutFile);
|
|
}
|
|
#endif
|
|
}
|
|
|
|
}
|
|
|
|
//**************************************************************************
|
|
//
|
|
// DbgSetDebugLevel
|
|
//
|
|
//
|
|
//
|
|
// Parameter List :
|
|
// Return Value :
|
|
// Modification history :
|
|
//
|
|
// 11nov96:HJH -> creation
|
|
//
|
|
//**************************************************************************
|
|
|
|
BOOLEAN DbgSetDebugLevel(UINT16 uiTopicId, UINT8 uiDebugLevel)
|
|
{
|
|
return(TRUE);
|
|
}
|
|
|
|
//**************************************************************************
|
|
//
|
|
// DbgFailedAssertion
|
|
//
|
|
//
|
|
//
|
|
// Parameter List :
|
|
// Return Value :
|
|
// Modification history :
|
|
//
|
|
// xxnov96:HJH -> creation
|
|
//
|
|
//**************************************************************************
|
|
|
|
void DbgFailedAssertion( BOOLEAN fExpression, char *szFile, int nLine )
|
|
{
|
|
#ifndef _NO_DEBUG_TXT
|
|
FILE *OutFile;
|
|
|
|
if ( fExpression == FALSE )
|
|
{
|
|
if ((OutFile = fopen(gpcDebugLogFileName, "a+t")) != NULL)
|
|
{
|
|
fprintf(OutFile, "Assertion Failed at:\n line %i\n %s\n", nLine, szFile);
|
|
fclose(OutFile);
|
|
}
|
|
}
|
|
#endif
|
|
}
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
void _DebugRecordToFile(BOOLEAN gfState)
|
|
{
|
|
gfRecordToFile = gfState;
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
void _DebugRecordToDebugger(BOOLEAN gfState)
|
|
{
|
|
gfRecordToDebugger = gfState;
|
|
}
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
|
// Wiz8 compatible debug messaging
|
|
|
|
void _DebugMessage(UINT8 *pString, UINT32 uiLineNum, UINT8 *pSourceFile)
|
|
{
|
|
UINT8 ubOutputString[512];
|
|
#ifndef _NO_DEBUG_TXT
|
|
FILE *DebugFile;
|
|
#endif
|
|
|
|
//
|
|
// Build the output string
|
|
//
|
|
|
|
sprintf( (char *) ubOutputString, "{ %ld } %s [Line %d in %s]\n", GetTickCount(), pString, uiLineNum, pSourceFile );
|
|
|
|
//
|
|
// Output to debugger
|
|
//
|
|
|
|
if (gfRecordToDebugger)
|
|
{
|
|
OutputDebugString( (LPCSTR) ubOutputString );
|
|
}
|
|
|
|
//
|
|
// Record to file if required
|
|
//
|
|
|
|
#ifndef _NO_DEBUG_TXT
|
|
if (gfRecordToFile)
|
|
{
|
|
if ((DebugFile = fopen( gpcDebugLogFileName, "a+t" )) != NULL)
|
|
{
|
|
fputs( (const char *)ubOutputString, DebugFile );
|
|
fclose( DebugFile );
|
|
}
|
|
}
|
|
#endif
|
|
}
|
|
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
// This func is used by Assert()
|
|
void _Null(void)
|
|
{
|
|
}
|
|
|
|
extern HVOBJECT FontObjs[25];
|
|
|
|
#ifdef JA2 //JAGGED ALLIANCE 2 VERSION ONLY
|
|
template void _FailMessage<char *, char const *>(char *, unsigned int, char const *);
|
|
template void _FailMessage<char const *, char const *>(char const *, unsigned int, char const *);
|
|
template void _FailMessage<int, char const *>(int, unsigned int, char const *);
|
|
template void _FailMessage<int, char *>(int, unsigned int, char *);
|
|
template void _FailMessage<char *, char *>(char *, unsigned int, char *);
|
|
template void _FailMessage<char *, char *>(unsigned char *, unsigned int, char *);
|
|
template void _FailMessage<unsigned char *, char const *>(unsigned char *, unsigned int, char const *);
|
|
template <typename type1, typename type2>
|
|
void _FailMessage( type1 pString, UINT32 uiLineNum, type2 pSourceFile )
|
|
{
|
|
MSG Message;
|
|
UINT8 ubOutputString[512];
|
|
#ifndef _NO_DEBUG_TXT
|
|
FILE *DebugFile;
|
|
#endif
|
|
BOOLEAN fDone = FALSE;
|
|
//Build the output strings
|
|
sprintf( (char *)ubOutputString, "{ %ld } Assertion Failure [Line %d in %s]\n", GetTickCount(), uiLineNum, pSourceFile );
|
|
if( pString )
|
|
sprintf( (char *)gubAssertString, (const char *)pString );
|
|
else
|
|
sprintf( (char *)gubAssertString, "" );
|
|
|
|
//Output to debugger
|
|
if (gfRecordToDebugger)
|
|
OutputDebugString( (LPCSTR)ubOutputString );
|
|
|
|
//Record to file if required
|
|
#ifndef _NO_DEBUG_TXT
|
|
if (gfRecordToFile)
|
|
{
|
|
if ((DebugFile = fopen( gpcDebugLogFileName, "a+t" )) != NULL)
|
|
{
|
|
fputs( (const char *)ubOutputString, DebugFile );
|
|
fclose( DebugFile );
|
|
}
|
|
}
|
|
|
|
#if 0
|
|
if( !FontObjs[0] )
|
|
{ //Font manager hasn't yet been initialized so use the windows error system
|
|
sprintf( gubErrorText, "Assertion Failure -- Line %d in %s", uiLineNum, pSourceFile );
|
|
MessageBox( NULL, gubErrorText, "Jagged Alliance 2", MB_OK );
|
|
gfProgramIsRunning = FALSE;
|
|
return;
|
|
}
|
|
#endif
|
|
|
|
//Kris:
|
|
//NASTY HACK, THE GAME IS GOING TO DIE ANYWAY, SO WHO CARES WHAT WE DO.
|
|
//This will actually bring up a screen that prints out the assert message
|
|
//until the user hits esc or alt-x.
|
|
sprintf( (char *)gubErrorText, "Assertion Failure -- Line %d in %s", uiLineNum, pSourceFile );
|
|
SetPendingNewScreen( ERROR_SCREEN );
|
|
SetCurrentScreen( ERROR_SCREEN );
|
|
while (gfProgramIsRunning)
|
|
{
|
|
if (PeekMessage(&Message, NULL, 0, 0, PM_NOREMOVE))
|
|
{ // We have a message on the WIN95 queue, let's get it
|
|
if (!GetMessage(&Message, NULL, 0, 0))
|
|
{ // It's quitting time
|
|
continue;
|
|
}
|
|
// Ok, now that we have the message, let's handle it
|
|
TranslateMessage(&Message);
|
|
DispatchMessage(&Message);
|
|
}
|
|
else
|
|
{ // Windows hasn't processed any messages, therefore we handle the rest
|
|
GameLoop();
|
|
gfSGPInputReceived = FALSE;
|
|
}
|
|
}
|
|
#endif
|
|
exit(0);
|
|
}
|
|
|
|
#else //NOT JAGGED ALLIANCE 2
|
|
|
|
void _FailMessage(UINT8 *pString, UINT32 uiLineNum, UINT8 *pSourceFile)
|
|
{
|
|
UINT8 ubOutputString[512];
|
|
BOOLEAN fDone = FALSE;
|
|
|
|
#ifndef _NO_DEBUG_TXT
|
|
FILE *DebugFile;
|
|
#endif
|
|
|
|
|
|
// Build the output string
|
|
sprintf( ubOutputString, "{ %ld } Assertion Failure: %s [Line %d in %s]\n", GetTickCount(), pString, uiLineNum, pSourceFile );
|
|
if( pString )
|
|
sprintf( gubAssertString, pString );
|
|
// Output to debugger
|
|
if (gfRecordToDebugger)
|
|
{
|
|
OutputDebugString( ubOutputString );
|
|
if( pString )
|
|
{ //tag on the assert message
|
|
OutputDebugString( gubAssertString );
|
|
}
|
|
}
|
|
// Record to file if required
|
|
#ifndef _NO_DEBUG_TXT
|
|
if (gfRecordToFile)
|
|
{
|
|
if ((DebugFile = fopen( gpcDebugLogFileName, "a+t" )) != NULL)
|
|
{
|
|
fputs( ubOutputString, DebugFile );
|
|
if( pString )
|
|
{ //tag on the assert message
|
|
fputs( gubAssertString, DebugFile );
|
|
}
|
|
fclose( DebugFile );
|
|
}
|
|
}
|
|
#endif
|
|
exit( 0 );
|
|
}
|
|
|
|
#endif
|
|
|
|
#endif
|
|
|
|
// This is NOT a _DEBUG only function! It is also needed in
|
|
// release mode builds. -- DB
|
|
UINT8 *String(const char *String, ...)
|
|
{
|
|
|
|
va_list ArgPtr;
|
|
UINT8 usIndex;
|
|
|
|
// Record string index. This index is used since we live in a multitasking environment.
|
|
// It is still not bulletproof, but it's better than a single string
|
|
usIndex = gubStringIndex++;
|
|
if (gubStringIndex == 8)
|
|
{ // reset string pointer
|
|
gubStringIndex = 0;
|
|
}
|
|
|
|
va_start(ArgPtr, String);
|
|
vsprintf((char *) gbTmpDebugString[usIndex], String, ArgPtr);
|
|
va_end(ArgPtr);
|
|
|
|
return gbTmpDebugString[usIndex];
|
|
|
|
}
|