mirror of
https://github.com/dhewm/dhewm3.git
synced 2025-02-21 11:31:49 +00:00
Merge branch 'debugger'
This commit is contained in:
commit
5e4e1d61be
42 changed files with 2048 additions and 658 deletions
2
.gitignore
vendored
2
.gitignore
vendored
|
@ -11,4 +11,6 @@
|
||||||
/neo/.vs*
|
/neo/.vs*
|
||||||
/neo/out*
|
/neo/out*
|
||||||
/neo/build*
|
/neo/build*
|
||||||
|
/.vs*
|
||||||
|
|
||||||
|
/neo/CMakeSettings.json
|
||||||
|
|
|
@ -801,6 +801,17 @@ set(src_d3xp
|
||||||
|
|
||||||
add_globbed_headers(src_d3xp "d3xp")
|
add_globbed_headers(src_d3xp "d3xp")
|
||||||
|
|
||||||
|
set(src_debuggerServer
|
||||||
|
tools/debugger/DebuggerBreakpoint.h
|
||||||
|
tools/debugger/DebuggerBreakpoint.cpp
|
||||||
|
tools/debugger/DebuggerServer.h
|
||||||
|
tools/debugger/DebuggerServer.cpp
|
||||||
|
tools/debugger/DebuggerScript.h
|
||||||
|
tools/debugger/DebuggerScript.cpp
|
||||||
|
tools/debugger/DebuggerMessages.h
|
||||||
|
tools/debugger/debugger.cpp
|
||||||
|
)
|
||||||
|
|
||||||
set(src_core
|
set(src_core
|
||||||
${src_renderer}
|
${src_renderer}
|
||||||
${src_framework}
|
${src_framework}
|
||||||
|
@ -862,6 +873,23 @@ if (TOOLS AND MFC_FOUND AND MSVC)
|
||||||
# Script editor
|
# Script editor
|
||||||
file(GLOB src_script_editor "tools/script/*.cpp")
|
file(GLOB src_script_editor "tools/script/*.cpp")
|
||||||
add_globbed_headers(src_script_editor "tools/script")
|
add_globbed_headers(src_script_editor "tools/script")
|
||||||
|
# Script Debugger
|
||||||
|
set(src_debuggerClient
|
||||||
|
tools/debugger/DebuggerClient.h
|
||||||
|
tools/debugger/DebuggerClient.cpp
|
||||||
|
tools/debugger/DebuggerApp.h
|
||||||
|
tools/debugger/DebuggerApp.cpp
|
||||||
|
tools/debugger/DebuggerQuickWatchDlg.h
|
||||||
|
tools/debugger/DebuggerQuickWatchDlg.cpp
|
||||||
|
tools/debugger/DebuggerWindow.h
|
||||||
|
tools/debugger/DebuggerWindow.cpp
|
||||||
|
tools/debugger/DebuggerFindDlg.h
|
||||||
|
tools/debugger/DebuggerFindDlg.cpp
|
||||||
|
)
|
||||||
|
set(src_script_debugger
|
||||||
|
${src_debuggerServer}
|
||||||
|
${src_debuggerClient}
|
||||||
|
)
|
||||||
# sound editor?
|
# sound editor?
|
||||||
file(GLOB src_sound_editor "tools/sound/*.cpp")
|
file(GLOB src_sound_editor "tools/sound/*.cpp")
|
||||||
add_globbed_headers(src_sound_editor "tools/sound")
|
add_globbed_headers(src_sound_editor "tools/sound")
|
||||||
|
@ -881,13 +909,17 @@ if (TOOLS AND MFC_FOUND AND MSVC)
|
||||||
${src_map_editor}
|
${src_map_editor}
|
||||||
${src_script_editor}
|
${src_script_editor}
|
||||||
${src_sound_editor}
|
${src_sound_editor}
|
||||||
|
${src_script_debugger}
|
||||||
"tools/edit_public.h"
|
"tools/edit_public.h"
|
||||||
"tools/edit_gui_common.h"
|
"tools/edit_gui_common.h"
|
||||||
)
|
)
|
||||||
SET(CMAKE_MFC_FLAG 2)
|
SET(CMAKE_MFC_FLAG 2)
|
||||||
set(TOOLS_DEFINES "ID_ALLOW_TOOLS;_AFXDLL")
|
set(TOOLS_DEFINES "ID_ALLOW_TOOLS;_AFXDLL")
|
||||||
else()
|
else()
|
||||||
set(src_editor_tools "tools/edit_stub.cpp" "tools/edit_public.h")
|
set(src_editor_tools "tools/edit_stub.cpp" "tools/edit_public.h" "tools/debugger/debugger_common.h")
|
||||||
|
list(APPEND src_editor_tools
|
||||||
|
${src_debuggerServer}
|
||||||
|
)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
|
||||||
|
@ -1052,9 +1084,10 @@ if(DEDICATED)
|
||||||
${src_stub_openal}
|
${src_stub_openal}
|
||||||
${src_stub_gl}
|
${src_stub_gl}
|
||||||
${src_sys_base}
|
${src_sys_base}
|
||||||
|
${src_debuggerServer}
|
||||||
)
|
)
|
||||||
|
|
||||||
source_group(TREE ${CMAKE_CURRENT_SOURCE_DIR} PREFIX neo FILES ${src_core} ${src_sys_base} ${src_stub_openal} ${src_stub_gl})
|
source_group(TREE ${CMAKE_CURRENT_SOURCE_DIR} PREFIX neo FILES ${src_core} ${src_sys_base} ${src_stub_openal} ${src_stub_gl} ${src_debuggerServer})
|
||||||
|
|
||||||
set_target_properties(${DHEWM3BINARY}ded PROPERTIES COMPILE_DEFINITIONS "ID_DEDICATED;__DOOM_DLL__")
|
set_target_properties(${DHEWM3BINARY}ded PROPERTIES COMPILE_DEFINITIONS "ID_DEDICATED;__DOOM_DLL__")
|
||||||
set_target_properties(${DHEWM3BINARY}ded PROPERTIES LINK_FLAGS "${ldflags}")
|
set_target_properties(${DHEWM3BINARY}ded PROPERTIES LINK_FLAGS "${ldflags}")
|
||||||
|
|
|
@ -670,7 +670,7 @@ void idEditEntities::DisplayEntities( void ) {
|
||||||
===============================================================================
|
===============================================================================
|
||||||
*/
|
*/
|
||||||
|
|
||||||
idGameEdit gameEditLocal;
|
idGameEditExt gameEditLocal;
|
||||||
idGameEdit * gameEdit = &gameEditLocal;
|
idGameEdit * gameEdit = &gameEditLocal;
|
||||||
|
|
||||||
|
|
||||||
|
@ -1146,3 +1146,62 @@ void idGameEdit::MapEntityTranslate( const char *name, const idVec3 &v ) const {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
|
||||||
|
Debugger
|
||||||
|
|
||||||
|
***********************************************************************/
|
||||||
|
|
||||||
|
bool idGameEditExt::IsLineCode( const char *filename, int linenumber ) const {
|
||||||
|
idStr fileStr;
|
||||||
|
idProgram *program = &gameLocal.program;
|
||||||
|
for ( int i = 0; i < program->NumStatements( ); i++ ) {
|
||||||
|
fileStr = program->GetFilename( program->GetStatement( i ).file );
|
||||||
|
fileStr.BackSlashesToSlashes( );
|
||||||
|
|
||||||
|
if ( strcmp( filename, fileStr.c_str( ) ) == 0
|
||||||
|
&& program->GetStatement( i ).linenumber == linenumber
|
||||||
|
) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void idGameEditExt::GetLoadedScripts(idStrList** result)
|
||||||
|
{
|
||||||
|
(*result)->Clear();
|
||||||
|
idProgram* program = &gameLocal.program;
|
||||||
|
|
||||||
|
for (int i = 0; i < program->NumFilenames(); i++)
|
||||||
|
{
|
||||||
|
(*result)->AddUnique(idStr(program->GetFilename(i)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void idGameEditExt::MSG_WriteScriptList(idBitMsg* msg)
|
||||||
|
{
|
||||||
|
idProgram* program = &gameLocal.program;
|
||||||
|
|
||||||
|
msg->WriteInt(program->NumFilenames());
|
||||||
|
for (int i = 0; i < program->NumFilenames(); i++)
|
||||||
|
{
|
||||||
|
idStr file = program->GetFilename(i);
|
||||||
|
//fix this. it seams that scripts triggered by the runtime are stored with a wrong path
|
||||||
|
//the use // instead of '\'
|
||||||
|
file.BackSlashesToSlashes();
|
||||||
|
msg->WriteString(file);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* idGameEditExt::GetFilenameForStatement(idProgram* program, int index) const
|
||||||
|
{
|
||||||
|
return program->GetFilenameForStatement(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
int idGameEditExt::GetLineNumberForStatement(idProgram* program, int index) const
|
||||||
|
{
|
||||||
|
return program->GetLineNumberForStatement(index);
|
||||||
|
}
|
||||||
|
|
|
@ -302,6 +302,16 @@ void idGameLocal::Clear( void ) {
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool ( *updateDebuggerFnPtr )( idInterpreter *interpreter, idProgram *program, int instructionPointer ) = NULL;
|
||||||
|
bool updateGameDebugger( idInterpreter *interpreter, idProgram *program, int instructionPointer ) {
|
||||||
|
bool ret = false;
|
||||||
|
if ( interpreter != nullptr && program != nullptr ) {
|
||||||
|
ret = updateDebuggerFnPtr ? updateDebuggerFnPtr( interpreter , program, instructionPointer ) : false;
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
===========
|
===========
|
||||||
idGameLocal::Init
|
idGameLocal::Init
|
||||||
|
@ -410,6 +420,10 @@ void idGameLocal::Init( void ) {
|
||||||
gamestate = GAMESTATE_NOMAP;
|
gamestate = GAMESTATE_NOMAP;
|
||||||
|
|
||||||
Printf( "...%d aas types\n", aasList.Num() );
|
Printf( "...%d aas types\n", aasList.Num() );
|
||||||
|
|
||||||
|
//debugger support
|
||||||
|
common->GetAdditionalFunction( idCommon::FT_UpdateDebugger,( idCommon::FunctionPointer * ) &updateDebuggerFnPtr,NULL);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -1312,7 +1326,7 @@ void idGameLocal::MapPopulate( void ) {
|
||||||
idGameLocal::InitFromNewMap
|
idGameLocal::InitFromNewMap
|
||||||
===================
|
===================
|
||||||
*/
|
*/
|
||||||
void idGameLocal::InitFromNewMap( const char *mapName, idRenderWorld *renderWorld, idSoundWorld *soundWorld, bool isServer, bool isClient, int randseed ) {
|
void idGameLocal::InitFromNewMap(const char* mapName, idRenderWorld* renderWorld, idSoundWorld* soundWorld, bool isServer, bool isClient, int randseed) {
|
||||||
|
|
||||||
this->isServer = isServer;
|
this->isServer = isServer;
|
||||||
this->isClient = isClient;
|
this->isClient = isClient;
|
||||||
|
@ -2436,14 +2450,14 @@ void idGameLocal::RunTimeGroup2() {
|
||||||
idGameLocal::RunFrame
|
idGameLocal::RunFrame
|
||||||
================
|
================
|
||||||
*/
|
*/
|
||||||
gameReturn_t idGameLocal::RunFrame( const usercmd_t *clientCmds ) {
|
gameReturn_t idGameLocal::RunFrame(const usercmd_t* clientCmds) {
|
||||||
idEntity * ent;
|
idEntity* ent;
|
||||||
int num;
|
int num;
|
||||||
float ms;
|
float ms;
|
||||||
idTimer timer_think, timer_events, timer_singlethink;
|
idTimer timer_think, timer_events, timer_singlethink;
|
||||||
gameReturn_t ret;
|
gameReturn_t ret;
|
||||||
idPlayer *player;
|
idPlayer* player;
|
||||||
const renderView_t *view;
|
const renderView_t* view;
|
||||||
|
|
||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
if ( isMultiplayer ) {
|
if ( isMultiplayer ) {
|
||||||
|
|
|
@ -365,13 +365,13 @@ public:
|
||||||
|
|
||||||
virtual const idDict & GetPersistentPlayerInfo( int clientNum );
|
virtual const idDict & GetPersistentPlayerInfo( int clientNum );
|
||||||
virtual void SetPersistentPlayerInfo( int clientNum, const idDict &playerInfo );
|
virtual void SetPersistentPlayerInfo( int clientNum, const idDict &playerInfo );
|
||||||
virtual void InitFromNewMap( const char *mapName, idRenderWorld *renderWorld, idSoundWorld *soundWorld, bool isServer, bool isClient, int randSeed );
|
virtual void InitFromNewMap(const char* mapName, idRenderWorld* renderWorld, idSoundWorld* soundWorld, bool isServer, bool isClient, int randSeed );
|
||||||
virtual bool InitFromSaveGame( const char *mapName, idRenderWorld *renderWorld, idSoundWorld *soundWorld, idFile *saveGameFile );
|
virtual bool InitFromSaveGame(const char* mapName, idRenderWorld* renderWorld, idSoundWorld* soundWorld, idFile* saveGameFile );
|
||||||
virtual void SaveGame( idFile *saveGameFile );
|
virtual void SaveGame( idFile *saveGameFile );
|
||||||
virtual void MapShutdown( void );
|
virtual void MapShutdown( void );
|
||||||
virtual void CacheDictionaryMedia( const idDict *dict );
|
virtual void CacheDictionaryMedia( const idDict *dict );
|
||||||
virtual void SpawnPlayer( int clientNum );
|
virtual void SpawnPlayer( int clientNum );
|
||||||
virtual gameReturn_t RunFrame( const usercmd_t *clientCmds );
|
virtual gameReturn_t RunFrame(const usercmd_t* clientCmds );
|
||||||
virtual bool Draw( int clientNum );
|
virtual bool Draw( int clientNum );
|
||||||
virtual escReply_t HandleESC( idUserInterface **gui );
|
virtual escReply_t HandleESC( idUserInterface **gui );
|
||||||
virtual idUserInterface *StartMenu( void );
|
virtual idUserInterface *StartMenu( void );
|
||||||
|
|
|
@ -33,6 +33,11 @@ If you have questions concerning this license or the applicable additional terms
|
||||||
|
|
||||||
#include "script/Script_Interpreter.h"
|
#include "script/Script_Interpreter.h"
|
||||||
|
|
||||||
|
#include "framework/FileSystem.h"
|
||||||
|
|
||||||
|
// HvG: Debugger support
|
||||||
|
extern bool updateGameDebugger( idInterpreter *interpreter, idProgram *program, int instructionPointer );
|
||||||
|
|
||||||
/*
|
/*
|
||||||
================
|
================
|
||||||
idInterpreter::idInterpreter()
|
idInterpreter::idInterpreter()
|
||||||
|
@ -183,7 +188,6 @@ idInterpreter::GetRegisterValue
|
||||||
Returns a string representation of the value of the register. This is
|
Returns a string representation of the value of the register. This is
|
||||||
used primarily for the debugger and debugging
|
used primarily for the debugger and debugging
|
||||||
|
|
||||||
//FIXME: This is pretty much wrong. won't access data in most situations.
|
|
||||||
================
|
================
|
||||||
*/
|
*/
|
||||||
bool idInterpreter::GetRegisterValue( const char *name, idStr &out, int scopeDepth ) {
|
bool idInterpreter::GetRegisterValue( const char *name, idStr &out, int scopeDepth ) {
|
||||||
|
@ -191,17 +195,17 @@ bool idInterpreter::GetRegisterValue( const char *name, idStr &out, int scopeDep
|
||||||
idVarDef *d;
|
idVarDef *d;
|
||||||
char funcObject[ 1024 ];
|
char funcObject[ 1024 ];
|
||||||
char *funcName;
|
char *funcName;
|
||||||
const idVarDef *scope;
|
const idVarDef *scope = NULL;
|
||||||
|
const idVarDef *scopeObj;
|
||||||
const idTypeDef *field;
|
const idTypeDef *field;
|
||||||
const idScriptObject *obj;
|
|
||||||
const function_t *func;
|
const function_t *func;
|
||||||
|
|
||||||
out.Empty();
|
out.Empty();
|
||||||
|
|
||||||
if ( scopeDepth == -1 ) {
|
if ( scopeDepth == -1 ) {
|
||||||
scopeDepth = callStackDepth;
|
scopeDepth = callStackDepth;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( scopeDepth == callStackDepth ) {
|
if ( scopeDepth == callStackDepth ) {
|
||||||
func = currentFunction;
|
func = currentFunction;
|
||||||
} else {
|
} else {
|
||||||
|
@ -215,35 +219,44 @@ bool idInterpreter::GetRegisterValue( const char *name, idStr &out, int scopeDep
|
||||||
funcName = strstr( funcObject, "::" );
|
funcName = strstr( funcObject, "::" );
|
||||||
if ( funcName ) {
|
if ( funcName ) {
|
||||||
*funcName = '\0';
|
*funcName = '\0';
|
||||||
scope = gameLocal.program.GetDef( NULL, funcObject, &def_namespace );
|
scopeObj = gameLocal.program.GetDef( NULL, funcObject, &def_namespace );
|
||||||
funcName += 2;
|
funcName += 2;
|
||||||
|
if ( scopeObj )
|
||||||
|
{
|
||||||
|
scope = gameLocal.program.GetDef( NULL, funcName, scopeObj );
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
funcName = funcObject;
|
funcName = funcObject;
|
||||||
scope = &def_namespace;
|
scope = gameLocal.program.GetDef( NULL, func->Name(), &def_namespace );
|
||||||
|
scopeObj = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get the function from the object
|
if ( !scope )
|
||||||
d = gameLocal.program.GetDef( NULL, funcName, scope );
|
{
|
||||||
if ( !d ) {
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get the variable itself and check various namespaces
|
d = gameLocal.program.GetDef( NULL, name, scope );
|
||||||
d = gameLocal.program.GetDef( NULL, name, d );
|
|
||||||
if ( !d ) {
|
// Check the objects for it if it wasnt local to the function
|
||||||
if ( scope == &def_namespace ) {
|
if ( !d )
|
||||||
return false;
|
{
|
||||||
}
|
for ( ; scopeObj && scopeObj->TypeDef()->SuperClass(); scopeObj = scopeObj->TypeDef()->SuperClass()->def )
|
||||||
|
{
|
||||||
d = gameLocal.program.GetDef( NULL, name, scope );
|
d = gameLocal.program.GetDef( NULL, name, scopeObj );
|
||||||
if ( !d ) {
|
if ( d )
|
||||||
d = gameLocal.program.GetDef( NULL, name, &def_namespace );
|
{
|
||||||
if ( !d ) {
|
break;
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ( !d )
|
||||||
|
{
|
||||||
|
out = "???";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
reg = GetVariable( d );
|
reg = GetVariable( d );
|
||||||
switch( d->Type() ) {
|
switch( d->Type() ) {
|
||||||
case ev_float:
|
case ev_float:
|
||||||
|
@ -256,7 +269,7 @@ bool idInterpreter::GetRegisterValue( const char *name, idStr &out, int scopeDep
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ev_vector:
|
case ev_vector:
|
||||||
if ( reg.vectorPtr ) {
|
if ( reg.vectorPtr ) {
|
||||||
out = va( "%g,%g,%g", reg.vectorPtr->x, reg.vectorPtr->y, reg.vectorPtr->z );
|
out = va( "%g,%g,%g", reg.vectorPtr->x, reg.vectorPtr->y, reg.vectorPtr->z );
|
||||||
} else {
|
} else {
|
||||||
out = "0,0,0";
|
out = "0,0,0";
|
||||||
|
@ -274,30 +287,55 @@ bool idInterpreter::GetRegisterValue( const char *name, idStr &out, int scopeDep
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ev_field:
|
case ev_field:
|
||||||
|
{
|
||||||
|
idEntity* entity;
|
||||||
|
idScriptObject* obj;
|
||||||
|
|
||||||
if ( scope == &def_namespace ) {
|
if ( scope == &def_namespace ) {
|
||||||
// should never happen, but handle it safely anyway
|
// should never happen, but handle it safely anyway
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
field = scope->TypeDef()->GetParmType( reg.ptrOffset )->FieldType();
|
field = d->TypeDef()->FieldType();
|
||||||
obj = *reinterpret_cast<const idScriptObject **>( &localstack[ callStack[ callStackDepth ].stackbase ] );
|
entity = GetEntity ( *((int*)&localstack[ localstackBase ]) );
|
||||||
if ( !field || !obj ) {
|
if ( !entity || !field )
|
||||||
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
obj = &entity->scriptObject;
|
||||||
|
if ( !obj ) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
switch ( field->Type() ) {
|
switch ( field->Type() ) {
|
||||||
case ev_boolean:
|
case ev_boolean:
|
||||||
out = va( "%d", *( reinterpret_cast<int *>( &obj->data[ reg.ptrOffset ] ) ) );
|
out = va( "%d", *( reinterpret_cast<int *>( &obj->data[ reg.ptrOffset ] ) ) );
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
case ev_float:
|
case ev_float:
|
||||||
out = va( "%g", *( reinterpret_cast<float *>( &obj->data[ reg.ptrOffset ] ) ) );
|
out = va( "%g", *( reinterpret_cast<float *>( &obj->data[ reg.ptrOffset ] ) ) );
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
case ev_string: {
|
||||||
|
const char* str;
|
||||||
|
str = reinterpret_cast<const char*>( &obj->data[ reg.ptrOffset ] );
|
||||||
|
if ( !str ) {
|
||||||
|
out = "\"\"";
|
||||||
|
} else {
|
||||||
|
out = "\"";
|
||||||
|
out += str;
|
||||||
|
out += "\"";
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case ev_string:
|
case ev_string:
|
||||||
if ( reg.stringPtr ) {
|
if ( reg.stringPtr ) {
|
||||||
|
@ -313,7 +351,6 @@ bool idInterpreter::GetRegisterValue( const char *name, idStr &out, int scopeDep
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
================
|
================
|
||||||
idInterpreter::GetCallstackDepth
|
idInterpreter::GetCallstackDepth
|
||||||
|
@ -969,6 +1006,19 @@ bool idInterpreter::Execute( void ) {
|
||||||
// next statement
|
// next statement
|
||||||
st = &gameLocal.program.GetStatement( instructionPointer );
|
st = &gameLocal.program.GetStatement( instructionPointer );
|
||||||
|
|
||||||
|
if ( !updateGameDebugger( this, &gameLocal.program, instructionPointer )
|
||||||
|
&& g_debugScript.GetBool( ) )
|
||||||
|
{
|
||||||
|
static int lastLineNumber = -1;
|
||||||
|
if (lastLineNumber != gameLocal.program.GetStatement(instructionPointer).linenumber) {
|
||||||
|
gameLocal.Printf("%s (%d)\n",
|
||||||
|
gameLocal.program.GetFilename(gameLocal.program.GetStatement(instructionPointer).file),
|
||||||
|
gameLocal.program.GetStatement(instructionPointer).linenumber
|
||||||
|
);
|
||||||
|
lastLineNumber = gameLocal.program.GetStatement(instructionPointer).linenumber;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
switch( st->op ) {
|
switch( st->op ) {
|
||||||
case OP_RETURN:
|
case OP_RETURN:
|
||||||
LeaveFunction( st->a );
|
LeaveFunction( st->a );
|
||||||
|
@ -1833,3 +1883,99 @@ bool idInterpreter::Execute( void ) {
|
||||||
|
|
||||||
return threadDying;
|
return threadDying;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool idGameEditExt::CheckForBreakPointHit(const idInterpreter* interpreter, const function_t* function1, const function_t* function2, int depth) const
|
||||||
|
{
|
||||||
|
return ((interpreter->GetCurrentFunction() == function1 ||
|
||||||
|
interpreter->GetCurrentFunction() == function2) &&
|
||||||
|
(interpreter->GetCallstackDepth() <= depth));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool idGameEditExt::ReturnedFromFunction(const idProgram* program, const idInterpreter* interpreter, int index) const
|
||||||
|
{
|
||||||
|
|
||||||
|
return (const_cast<idProgram*>(program)->GetStatement(index).op == OP_RETURN && interpreter->GetCallstackDepth() <= 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool idGameEditExt::GetRegisterValue(const idInterpreter* interpreter, const char* name, idStr& out, int scopeDepth) const
|
||||||
|
{
|
||||||
|
return const_cast<idInterpreter*>(interpreter)->GetRegisterValue(name, out, scopeDepth);
|
||||||
|
}
|
||||||
|
|
||||||
|
const idThread* idGameEditExt::GetThread(const idInterpreter* interpreter) const
|
||||||
|
{
|
||||||
|
return interpreter->GetThread();
|
||||||
|
}
|
||||||
|
|
||||||
|
void idGameEditExt::MSG_WriteCallstackFunc(idBitMsg* msg, const prstack_t* stack, const idProgram* program, int instructionPtr)
|
||||||
|
{
|
||||||
|
const statement_t* st;
|
||||||
|
const function_t* func;
|
||||||
|
|
||||||
|
func = stack->f;
|
||||||
|
|
||||||
|
// If the function is unknown then just fill in with default data.
|
||||||
|
if (!func)
|
||||||
|
{
|
||||||
|
msg->WriteString("<UNKNOWN>");
|
||||||
|
msg->WriteString("<UNKNOWN>");
|
||||||
|
msg->WriteInt(0);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
msg->WriteString(va("%s( )", func->Name()));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (stack->s == -1) //this is a fake stack created by debugger, use intruction pointer for retrieval.
|
||||||
|
st = &const_cast<idProgram*>(program)->GetStatement(instructionPtr);
|
||||||
|
else // Use the calling statement as the filename and linenumber where the call was made from
|
||||||
|
st = &const_cast<idProgram*>(program)->GetStatement(stack->s);
|
||||||
|
|
||||||
|
if (st)
|
||||||
|
{
|
||||||
|
idStr qpath = const_cast<idProgram*>(program)->GetFilename(st->file);
|
||||||
|
if (idStr::FindChar(qpath, ':') != -1)
|
||||||
|
qpath = fileSystem->OSPathToRelativePath(qpath.c_str());
|
||||||
|
qpath.BackSlashesToSlashes();
|
||||||
|
msg->WriteString(qpath);
|
||||||
|
msg->WriteInt(st->linenumber);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
msg->WriteString("<UNKNOWN>");
|
||||||
|
msg->WriteInt(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void idGameEditExt::MSG_WriteInterpreterInfo(idBitMsg* msg, const idInterpreter* interpreter, const idProgram* program, int instructionPtr)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
prstack_s temp;
|
||||||
|
|
||||||
|
msg->WriteShort((int)interpreter->GetCallstackDepth());
|
||||||
|
|
||||||
|
// write out the current function
|
||||||
|
temp.f = interpreter->GetCurrentFunction();
|
||||||
|
temp.s = -1;
|
||||||
|
temp.stackbase = 0;
|
||||||
|
MSG_WriteCallstackFunc(msg, &temp, program, instructionPtr);
|
||||||
|
|
||||||
|
// Run through all of the callstack and write each to the msg
|
||||||
|
for (i = interpreter->GetCallstackDepth() - 1; i > 0; i--)
|
||||||
|
{
|
||||||
|
MSG_WriteCallstackFunc(msg, interpreter->GetCallstack() + i, program, instructionPtr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int idGameEditExt::GetInterpreterCallStackDepth(const idInterpreter* interpreter)
|
||||||
|
{
|
||||||
|
return interpreter->GetCallstackDepth();
|
||||||
|
}
|
||||||
|
|
||||||
|
const function_t* idGameEditExt::GetInterpreterCallStackFunction(const idInterpreter* interpreter, int stackDepth/* = -1*/)
|
||||||
|
{
|
||||||
|
return interpreter->GetCallstack()[stackDepth > -1 ? stackDepth : interpreter->GetCallstackDepth()].f;
|
||||||
|
}
|
|
@ -1921,3 +1921,49 @@ void idThread::Event_InfluenceActive( void ) {
|
||||||
idThread::ReturnInt( false );
|
idThread::ReturnInt( false );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int idGameEditExt::ThreadGetNum(const idThread* thread) const
|
||||||
|
{
|
||||||
|
return const_cast<idThread*>(thread)->GetThreadNum();
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* idGameEditExt::ThreadGetName(const idThread* thread) const
|
||||||
|
{
|
||||||
|
return const_cast<idThread*>(thread)->GetThreadName();
|
||||||
|
}
|
||||||
|
|
||||||
|
int idGameEditExt::GetTotalScriptThreads() const
|
||||||
|
{
|
||||||
|
return idThread::GetThreads().Num();
|
||||||
|
}
|
||||||
|
|
||||||
|
const idThread* idGameEditExt::GetThreadByIndex(int index) const
|
||||||
|
{
|
||||||
|
return idThread::GetThreads()[index];
|
||||||
|
}
|
||||||
|
|
||||||
|
bool idGameEditExt::ThreadIsDoneProcessing(const idThread* thread) const
|
||||||
|
{
|
||||||
|
return const_cast<idThread*>(thread)->IsDoneProcessing();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool idGameEditExt::ThreadIsWaiting(const idThread* thread) const
|
||||||
|
{
|
||||||
|
return const_cast<idThread*>(thread)->IsWaiting();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool idGameEditExt::ThreadIsDying(const idThread* thread) const
|
||||||
|
{
|
||||||
|
return const_cast<idThread*>(thread)->IsDying();
|
||||||
|
}
|
||||||
|
|
||||||
|
void idGameEditExt::MSG_WriteThreadInfo(idBitMsg* msg, const idThread* thread, const idInterpreter* interpreter)
|
||||||
|
{
|
||||||
|
msg->WriteString(const_cast<idThread*>(thread)->GetThreadName());
|
||||||
|
msg->WriteInt(const_cast<idThread*>(thread)->GetThreadNum());
|
||||||
|
|
||||||
|
msg->WriteBits((int)(thread == interpreter->GetThread()), 1);
|
||||||
|
msg->WriteBits((int)const_cast<idThread*>(thread)->IsDoneProcessing(), 1);
|
||||||
|
msg->WriteBits((int)const_cast<idThread*>(thread)->IsWaiting(), 1);
|
||||||
|
msg->WriteBits((int)const_cast<idThread*>(thread)->IsDying(), 1);
|
||||||
|
}
|
|
@ -244,7 +244,7 @@ void idInternalCVar::UpdateValue( void ) {
|
||||||
clamped = true;
|
clamped = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ( clamped || !idStr::IsNumeric( value ) || idStr::FindChar( value, '.' ) ) {
|
if ( clamped || !idStr::IsNumeric( value ) || (idStr::FindChar( value, '.' )!=-1) ) {
|
||||||
valueString = idStr( integerValue );
|
valueString = idStr( integerValue );
|
||||||
value = valueString.c_str();
|
value = valueString.c_str();
|
||||||
}
|
}
|
||||||
|
|
|
@ -98,6 +98,10 @@ idCVar com_timescale( "timescale", "1", CVAR_SYSTEM | CVAR_FLOAT, "scales the ti
|
||||||
idCVar com_makingBuild( "com_makingBuild", "0", CVAR_BOOL | CVAR_SYSTEM, "1 when making a build" );
|
idCVar com_makingBuild( "com_makingBuild", "0", CVAR_BOOL | CVAR_SYSTEM, "1 when making a build" );
|
||||||
idCVar com_updateLoadSize( "com_updateLoadSize", "0", CVAR_BOOL | CVAR_SYSTEM | CVAR_NOCHEAT, "update the load size after loading a map" );
|
idCVar com_updateLoadSize( "com_updateLoadSize", "0", CVAR_BOOL | CVAR_SYSTEM | CVAR_NOCHEAT, "update the load size after loading a map" );
|
||||||
|
|
||||||
|
idCVar com_enableDebuggerServer( "com_enableDebuggerServer", "0", CVAR_BOOL | CVAR_SYSTEM, "toggle debugger server and try to connect to com_dbgClientAdr" );
|
||||||
|
idCVar com_dbgClientAdr( "com_dbgClientAdr", "localhost", CVAR_SYSTEM | CVAR_ARCHIVE, "debuggerApp client address" );
|
||||||
|
idCVar com_dbgServerAdr( "com_dbgServerAdr", "localhost", CVAR_SYSTEM | CVAR_ARCHIVE, "debugger server address" );
|
||||||
|
|
||||||
idCVar com_product_lang_ext( "com_product_lang_ext", "1", CVAR_INTEGER | CVAR_SYSTEM | CVAR_ARCHIVE, "Extension to use when creating language files." );
|
idCVar com_product_lang_ext( "com_product_lang_ext", "1", CVAR_INTEGER | CVAR_SYSTEM | CVAR_ARCHIVE, "Extension to use when creating language files." );
|
||||||
|
|
||||||
// com_speeds times
|
// com_speeds times
|
||||||
|
@ -112,6 +116,8 @@ volatile int com_ticNumber; // 60 hz tics
|
||||||
int com_editors; // currently opened editor(s)
|
int com_editors; // currently opened editor(s)
|
||||||
bool com_editorActive; // true if an editor has focus
|
bool com_editorActive; // true if an editor has focus
|
||||||
|
|
||||||
|
bool com_debuggerSupported; // only set to true when the updateDebugger function is set. see GetAdditionalFunction()
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
HWND com_hwndMsg = NULL;
|
HWND com_hwndMsg = NULL;
|
||||||
bool com_outputMsg = false;
|
bool com_outputMsg = false;
|
||||||
|
@ -245,6 +251,7 @@ idCommonLocal::idCommonLocal( void ) {
|
||||||
com_fullyInitialized = false;
|
com_fullyInitialized = false;
|
||||||
com_refreshOnPrint = false;
|
com_refreshOnPrint = false;
|
||||||
com_errorEntered = 0;
|
com_errorEntered = 0;
|
||||||
|
com_debuggerSupported = false;
|
||||||
|
|
||||||
strcpy( errorMessage, "" );
|
strcpy( errorMessage, "" );
|
||||||
|
|
||||||
|
@ -382,12 +389,17 @@ void idCommonLocal::VPrintf( const char *fmt, va_list args ) {
|
||||||
// remove any color codes
|
// remove any color codes
|
||||||
idStr::RemoveColors( msg );
|
idStr::RemoveColors( msg );
|
||||||
|
|
||||||
// echo to dedicated console and early console
|
if ( com_enableDebuggerServer.GetBool( ) ) {
|
||||||
Sys_Printf( "%s", msg );
|
// print to script debugger server
|
||||||
|
if ( com_editors & EDITOR_DEBUGGER )
|
||||||
// print to script debugger server
|
DebuggerServerPrint( msg );
|
||||||
// DebuggerServerPrint( msg );
|
else
|
||||||
|
// only echo to dedicated console and early console when debugger is not running so no
|
||||||
|
// deadlocks occur if engine functions called from the debuggerthread trace stuff..
|
||||||
|
Sys_Printf( "%s", msg );
|
||||||
|
} else {
|
||||||
|
Sys_Printf( "%s", msg );
|
||||||
|
}
|
||||||
#if 0 // !@#
|
#if 0 // !@#
|
||||||
#if defined(_DEBUG) && defined(WIN32)
|
#if defined(_DEBUG) && defined(WIN32)
|
||||||
if ( strlen( msg ) < 512 ) {
|
if ( strlen( msg ) < 512 ) {
|
||||||
|
@ -1134,8 +1146,14 @@ Com_ScriptDebugger_f
|
||||||
static void Com_ScriptDebugger_f( const idCmdArgs &args ) {
|
static void Com_ScriptDebugger_f( const idCmdArgs &args ) {
|
||||||
// Make sure it wasnt on the command line
|
// Make sure it wasnt on the command line
|
||||||
if ( !( com_editors & EDITOR_DEBUGGER ) ) {
|
if ( !( com_editors & EDITOR_DEBUGGER ) ) {
|
||||||
common->Printf( "Script debugger is currently disabled\n" );
|
|
||||||
// DebuggerClientLaunch();
|
//start debugger server if needed
|
||||||
|
if ( !com_enableDebuggerServer.GetBool() )
|
||||||
|
com_enableDebuggerServer.SetBool( true );
|
||||||
|
|
||||||
|
//start debugger client.
|
||||||
|
DebuggerClientLaunch();
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2020,6 +2038,7 @@ void Com_LocalizeMaps_f( const idCmdArgs &args ) {
|
||||||
strCount += LocalizeMap(args.Argv(2), strTable, listHash, excludeList, write);
|
strCount += LocalizeMap(args.Argv(2), strTable, listHash, excludeList, write);
|
||||||
} else {
|
} else {
|
||||||
idStrList files;
|
idStrList files;
|
||||||
|
//wow, what now? a hardcoded path?
|
||||||
GetFileList("z:/d3xp/d3xp/maps/game", "*.map", files);
|
GetFileList("z:/d3xp/d3xp/maps/game", "*.map", files);
|
||||||
for ( int i = 0; i < files.Num(); i++ ) {
|
for ( int i = 0; i < files.Num(); i++ ) {
|
||||||
idStr file = fileSystem->OSPathToRelativePath(files[i]);
|
idStr file = fileSystem->OSPathToRelativePath(files[i]);
|
||||||
|
@ -2398,6 +2417,14 @@ void idCommonLocal::Frame( void ) {
|
||||||
InitSIMD();
|
InitSIMD();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ( com_enableDebuggerServer.IsModified() ) {
|
||||||
|
if ( com_enableDebuggerServer.GetBool() ) {
|
||||||
|
DebuggerServerInit();
|
||||||
|
} else {
|
||||||
|
DebuggerServerShutdown();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
eventLoop->RunEventLoop();
|
eventLoop->RunEventLoop();
|
||||||
|
|
||||||
com_frameTime = com_ticNumber * USERCMD_MSEC;
|
com_frameTime = com_ticNumber * USERCMD_MSEC;
|
||||||
|
@ -2666,7 +2693,7 @@ void idCommonLocal::LoadGameDLL( void ) {
|
||||||
gameImport.AASFileManager = ::AASFileManager;
|
gameImport.AASFileManager = ::AASFileManager;
|
||||||
gameImport.collisionModelManager = ::collisionModelManager;
|
gameImport.collisionModelManager = ::collisionModelManager;
|
||||||
|
|
||||||
gameExport = *GetGameAPI( &gameImport );
|
gameExport = *GetGameAPI( &gameImport);
|
||||||
|
|
||||||
if ( gameExport.version != GAME_API_VERSION ) {
|
if ( gameExport.version != GAME_API_VERSION ) {
|
||||||
Sys_DLL_Unload( gameDLL );
|
Sys_DLL_Unload( gameDLL );
|
||||||
|
@ -2709,6 +2736,7 @@ void idCommonLocal::UnloadGameDLL( void ) {
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
com_debuggerSupported = false; // HvG: Reset debugger availability.
|
||||||
gameCallbacks.Reset(); // DG: these callbacks are invalid now because DLL has been unloaded
|
gameCallbacks.Reset(); // DG: these callbacks are invalid now because DLL has been unloaded
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3175,14 +3203,15 @@ void idCommonLocal::InitGame( void ) {
|
||||||
// initialize the user interfaces
|
// initialize the user interfaces
|
||||||
uiManager->Init();
|
uiManager->Init();
|
||||||
|
|
||||||
// startup the script debugger
|
|
||||||
// DebuggerServerInit();
|
|
||||||
|
|
||||||
PrintLoadingMessage( common->GetLanguageDict()->GetString( "#str_04350" ) );
|
PrintLoadingMessage( common->GetLanguageDict()->GetString( "#str_04350" ) );
|
||||||
|
|
||||||
// load the game dll
|
// load the game dll
|
||||||
LoadGameDLL();
|
LoadGameDLL();
|
||||||
|
|
||||||
|
// startup the script debugger
|
||||||
|
if ( com_enableDebuggerServer.GetBool( ) )
|
||||||
|
DebuggerServerInit( );
|
||||||
|
|
||||||
PrintLoadingMessage( common->GetLanguageDict()->GetString( "#str_04351" ) );
|
PrintLoadingMessage( common->GetLanguageDict()->GetString( "#str_04351" ) );
|
||||||
|
|
||||||
// init the session
|
// init the session
|
||||||
|
@ -3214,7 +3243,8 @@ void idCommonLocal::ShutdownGame( bool reloading ) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// shutdown the script debugger
|
// shutdown the script debugger
|
||||||
// DebuggerServerShutdown();
|
if ( com_enableDebuggerServer.GetBool() )
|
||||||
|
DebuggerServerShutdown();
|
||||||
|
|
||||||
idAsyncNetwork::client.Shutdown();
|
idAsyncNetwork::client.Shutdown();
|
||||||
|
|
||||||
|
@ -3277,11 +3307,21 @@ bool idCommonLocal::SetCallback(idCommon::CallbackType cbt, idCommon::FunctionPo
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool isDemo(void)
|
static bool isDemo( void )
|
||||||
{
|
{
|
||||||
return sessLocal.IsDemoVersion();
|
return sessLocal.IsDemoVersion();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool updateDebugger( idInterpreter *interpreter, idProgram *program, int instructionPointer )
|
||||||
|
{
|
||||||
|
if (com_editors & EDITOR_DEBUGGER)
|
||||||
|
{
|
||||||
|
DebuggerServerCheckBreakpoint( interpreter, program, instructionPointer );
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// returns true if that function is available in this version of dhewm3
|
// returns true if that function is available in this version of dhewm3
|
||||||
// *out_fnptr will be the function (you'll have to cast it probably)
|
// *out_fnptr will be the function (you'll have to cast it probably)
|
||||||
// *out_userArg will be an argument you have to pass to the function, if appropriate (else NULL)
|
// *out_userArg will be an argument you have to pass to the function, if appropriate (else NULL)
|
||||||
|
@ -3295,6 +3335,7 @@ bool idCommonLocal::GetAdditionalFunction(idCommon::FunctionType ft, idCommon::F
|
||||||
Warning("Called idCommon::GetAdditionalFunction() with out_fnptr == NULL!\n");
|
Warning("Called idCommon::GetAdditionalFunction() with out_fnptr == NULL!\n");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch(ft)
|
switch(ft)
|
||||||
{
|
{
|
||||||
case idCommon::FT_IsDemo:
|
case idCommon::FT_IsDemo:
|
||||||
|
@ -3302,6 +3343,11 @@ bool idCommonLocal::GetAdditionalFunction(idCommon::FunctionType ft, idCommon::F
|
||||||
// don't set *out_userArg, this function takes no arguments
|
// don't set *out_userArg, this function takes no arguments
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
case idCommon::FT_UpdateDebugger:
|
||||||
|
*out_fnptr = (idCommon::FunctionPointer)updateDebugger;
|
||||||
|
com_debuggerSupported = true;
|
||||||
|
return true;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
*out_fnptr = NULL;
|
*out_fnptr = NULL;
|
||||||
Warning("Called idCommon::SetCallback() with unknown FunctionType %d!\n", ft);
|
Warning("Called idCommon::SetCallback() with unknown FunctionType %d!\n", ft);
|
||||||
|
@ -3309,7 +3355,6 @@ bool idCommonLocal::GetAdditionalFunction(idCommon::FunctionType ft, idCommon::F
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
idGameCallbacks gameCallbacks;
|
idGameCallbacks gameCallbacks;
|
||||||
|
|
||||||
idGameCallbacks::idGameCallbacks()
|
idGameCallbacks::idGameCallbacks()
|
||||||
|
|
|
@ -73,6 +73,9 @@ extern idCVar com_showAsyncStats;
|
||||||
extern idCVar com_showSoundDecoders;
|
extern idCVar com_showSoundDecoders;
|
||||||
extern idCVar com_makingBuild;
|
extern idCVar com_makingBuild;
|
||||||
extern idCVar com_updateLoadSize;
|
extern idCVar com_updateLoadSize;
|
||||||
|
extern idCVar com_enableDebuggerServer;
|
||||||
|
extern idCVar com_dbgClientAdr;
|
||||||
|
extern idCVar com_dbgServerAdr;
|
||||||
|
|
||||||
extern int time_gameFrame; // game logic time
|
extern int time_gameFrame; // game logic time
|
||||||
extern int time_gameDraw; // game present time
|
extern int time_gameDraw; // game present time
|
||||||
|
@ -84,6 +87,8 @@ extern volatile int com_ticNumber; // 60 hz tics, incremented by async functio
|
||||||
extern int com_editors; // current active editor(s)
|
extern int com_editors; // current active editor(s)
|
||||||
extern bool com_editorActive; // true if an editor has focus
|
extern bool com_editorActive; // true if an editor has focus
|
||||||
|
|
||||||
|
extern bool com_debuggerSupported; // only set to true when the updateDebugger function is set. see GetAdditionalFunction()
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
const char DMAP_MSGID[] = "DMAPOutput";
|
const char DMAP_MSGID[] = "DMAPOutput";
|
||||||
const char DMAP_DONE[] = "DMAPDone";
|
const char DMAP_DONE[] = "DMAPDone";
|
||||||
|
@ -111,6 +116,8 @@ struct MemInfo_t {
|
||||||
};
|
};
|
||||||
|
|
||||||
class idLangDict;
|
class idLangDict;
|
||||||
|
class idInterpreter;
|
||||||
|
class idProgram;
|
||||||
|
|
||||||
class idCommon {
|
class idCommon {
|
||||||
public:
|
public:
|
||||||
|
@ -158,6 +165,7 @@ public:
|
||||||
// Writes cvars with the given flags to a file.
|
// Writes cvars with the given flags to a file.
|
||||||
virtual void WriteFlaggedCVarsToFile( const char *filename, int flags, const char *setCmd ) = 0;
|
virtual void WriteFlaggedCVarsToFile( const char *filename, int flags, const char *setCmd ) = 0;
|
||||||
|
|
||||||
|
|
||||||
// Begins redirection of console output to the given buffer.
|
// Begins redirection of console output to the given buffer.
|
||||||
virtual void BeginRedirect( char *buffer, int buffersize, void (*flush)( const char * ) ) = 0;
|
virtual void BeginRedirect( char *buffer, int buffersize, void (*flush)( const char * ) ) = 0;
|
||||||
|
|
||||||
|
@ -265,6 +273,11 @@ public:
|
||||||
// it returns true if we're currently running the doom3 demo
|
// it returns true if we're currently running the doom3 demo
|
||||||
// not relevant for mods, only for game/ aka base.dll/base.so/...
|
// not relevant for mods, only for game/ aka base.dll/base.so/...
|
||||||
FT_IsDemo = 1,
|
FT_IsDemo = 1,
|
||||||
|
// the function's signature is bool fn(idInterpreter,idProgram,int) with arguments:
|
||||||
|
// idInterpreter *interpreter, idProgram *program, int instructionPointer
|
||||||
|
// it returns true if the game debugger is active.
|
||||||
|
// relevant for mods.
|
||||||
|
FT_UpdateDebugger,
|
||||||
};
|
};
|
||||||
|
|
||||||
// returns true if that function is available in this version of dhewm3
|
// returns true if that function is available in this version of dhewm3
|
||||||
|
|
|
@ -886,10 +886,20 @@ const char *idFileSystemLocal::OSPathToRelativePath( const char *OSPath ) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( base ) {
|
if ( base ) {
|
||||||
s = strstr( base, "/" );
|
// DG: on Windows base might look like "base\\pak008.pk4/script/doom_util.script"
|
||||||
if ( !s ) {
|
// while on Linux it'll be more like "base/pak008.pk4/script/doom_util.script"
|
||||||
s = strstr( base, "\\" );
|
// I /think/ we want to get rid of the bla.pk4 part, at least that's what happens implicitly on Windows
|
||||||
|
// (I hope these problems don't exist if the file is not from a .pk4, so that case is handled like before)
|
||||||
|
s = strstr( base, ".pk4/" );
|
||||||
|
if ( s != NULL ) {
|
||||||
|
s += 4; // skip ".pk4", but *not* the following '/', that'll be skipped below
|
||||||
|
} else {
|
||||||
|
s = strchr( base, '/' );
|
||||||
|
if ( s == NULL ) {
|
||||||
|
s = strchr( base, '\\' );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( s ) {
|
if ( s ) {
|
||||||
strcpy( relativePath, s + 1 );
|
strcpy( relativePath, s + 1 );
|
||||||
if ( fs_debug.GetInteger() > 1 ) {
|
if ( fs_debug.GetInteger() > 1 ) {
|
||||||
|
|
|
@ -31,6 +31,7 @@ If you have questions concerning this license or the applicable additional terms
|
||||||
|
|
||||||
#include "idlib/BitMsg.h"
|
#include "idlib/BitMsg.h"
|
||||||
#include "idlib/Dict.h"
|
#include "idlib/Dict.h"
|
||||||
|
#include "idlib/containers/StrList.h"
|
||||||
#include "framework/UsercmdGen.h"
|
#include "framework/UsercmdGen.h"
|
||||||
#include "renderer/RenderWorld.h"
|
#include "renderer/RenderWorld.h"
|
||||||
#include "sound/sound.h"
|
#include "sound/sound.h"
|
||||||
|
@ -232,6 +233,11 @@ enum {
|
||||||
|
|
||||||
class idEntity;
|
class idEntity;
|
||||||
class idMD5Anim;
|
class idMD5Anim;
|
||||||
|
class idThread;
|
||||||
|
class function_t;
|
||||||
|
class idProgram;
|
||||||
|
class idInterpreter;
|
||||||
|
typedef struct prstack_s prstack_t;
|
||||||
|
|
||||||
// FIXME: this interface needs to be reworked but it properly separates code for the time being
|
// FIXME: this interface needs to be reworked but it properly separates code for the time being
|
||||||
class idGameEdit {
|
class idGameEdit {
|
||||||
|
@ -294,7 +300,7 @@ public:
|
||||||
virtual void EntitySetColor( idEntity *ent, const idVec3 color );
|
virtual void EntitySetColor( idEntity *ent, const idVec3 color );
|
||||||
|
|
||||||
// Player methods.
|
// Player methods.
|
||||||
virtual bool PlayerIsValid() const;
|
virtual bool PlayerIsValid( ) const;
|
||||||
virtual void PlayerGetOrigin( idVec3 &org ) const;
|
virtual void PlayerGetOrigin( idVec3 &org ) const;
|
||||||
virtual void PlayerGetAxis( idMat3 &axis ) const;
|
virtual void PlayerGetAxis( idMat3 &axis ) const;
|
||||||
virtual void PlayerGetViewAngles( idAngles &angles ) const;
|
virtual void PlayerGetViewAngles( idAngles &angles ) const;
|
||||||
|
@ -310,11 +316,44 @@ public:
|
||||||
virtual int MapGetEntitiesMatchingClassWithString( const char *classname, const char *match, const char *list[], const int max ) const;
|
virtual int MapGetEntitiesMatchingClassWithString( const char *classname, const char *match, const char *list[], const int max ) const;
|
||||||
virtual void MapRemoveEntity( const char *name ) const;
|
virtual void MapRemoveEntity( const char *name ) const;
|
||||||
virtual void MapEntityTranslate( const char *name, const idVec3 &v ) const;
|
virtual void MapEntityTranslate( const char *name, const idVec3 &v ) const;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
extern idGameEdit * gameEdit;
|
extern idGameEdit * gameEdit;
|
||||||
|
|
||||||
|
// In game script Debugging Support
|
||||||
|
class idGameEditExt : public idGameEdit {
|
||||||
|
public:
|
||||||
|
virtual ~idGameEditExt( void ) { }
|
||||||
|
// IdProgram
|
||||||
|
virtual void GetLoadedScripts( idStrList ** result );
|
||||||
|
virtual bool IsLineCode( const char* filename, int linenumber) const;
|
||||||
|
virtual const char * GetFilenameForStatement( idProgram* program, int index ) const;
|
||||||
|
virtual int GetLineNumberForStatement( idProgram* program, int index ) const;
|
||||||
|
|
||||||
|
// idInterpreter
|
||||||
|
virtual bool CheckForBreakPointHit( const idInterpreter* interpreter, const function_t* function1, const function_t* function2, int depth ) const;
|
||||||
|
virtual bool ReturnedFromFunction( const idProgram* program, const idInterpreter* interpreter, int index ) const;
|
||||||
|
virtual bool GetRegisterValue( const idInterpreter* interpreter, const char* name, idStr& out, int scopeDepth ) const;
|
||||||
|
virtual const idThread* GetThread( const idInterpreter* interpreter ) const;
|
||||||
|
virtual int GetInterpreterCallStackDepth( const idInterpreter* interpreter );
|
||||||
|
virtual const function_t* GetInterpreterCallStackFunction( const idInterpreter* interpreter, int stackDepth = -1 );
|
||||||
|
|
||||||
|
// IdThread
|
||||||
|
virtual const char * ThreadGetName( const idThread* thread ) const;
|
||||||
|
virtual int ThreadGetNum( const idThread* thread ) const;
|
||||||
|
virtual bool ThreadIsDoneProcessing( const idThread* thread ) const;
|
||||||
|
virtual bool ThreadIsWaiting( const idThread* thread ) const;
|
||||||
|
virtual bool ThreadIsDying( const idThread* thread ) const;
|
||||||
|
virtual int GetTotalScriptThreads( ) const;
|
||||||
|
virtual const idThread* GetThreadByIndex( int index ) const;
|
||||||
|
|
||||||
|
// MSG helpers
|
||||||
|
virtual void MSG_WriteThreadInfo( idBitMsg* msg, const idThread* thread, const idInterpreter* interpreter );
|
||||||
|
virtual void MSG_WriteCallstackFunc( idBitMsg* msg, const prstack_t* stack, const idProgram* program, int instructionPtr );
|
||||||
|
virtual void MSG_WriteInterpreterInfo( idBitMsg* msg, const idInterpreter* interpreter, const idProgram* program, int instructionPtr );
|
||||||
|
virtual void MSG_WriteScriptList( idBitMsg* msg );
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
===============================================================================
|
===============================================================================
|
||||||
|
|
|
@ -40,9 +40,8 @@ If you have questions concerning this license or the applicable additional terms
|
||||||
struct idGameCallbacks {
|
struct idGameCallbacks {
|
||||||
|
|
||||||
typedef void (*ReloadImagesCallback)(void* userArg, const idCmdArgs &args);
|
typedef void (*ReloadImagesCallback)(void* userArg, const idCmdArgs &args);
|
||||||
ReloadImagesCallback reloadImagesCB;
|
ReloadImagesCallback reloadImagesCB;
|
||||||
void* reloadImagesUserArg;
|
void* reloadImagesUserArg;
|
||||||
|
|
||||||
|
|
||||||
idGameCallbacks();
|
idGameCallbacks();
|
||||||
|
|
||||||
|
|
|
@ -670,7 +670,7 @@ void idEditEntities::DisplayEntities( void ) {
|
||||||
===============================================================================
|
===============================================================================
|
||||||
*/
|
*/
|
||||||
|
|
||||||
idGameEdit gameEditLocal;
|
idGameEditExt gameEditLocal;
|
||||||
idGameEdit * gameEdit = &gameEditLocal;
|
idGameEdit * gameEdit = &gameEditLocal;
|
||||||
|
|
||||||
|
|
||||||
|
@ -1146,3 +1146,64 @@ void idGameEdit::MapEntityTranslate( const char *name, const idVec3 &v ) const {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
|
||||||
|
Debugger
|
||||||
|
|
||||||
|
***********************************************************************/
|
||||||
|
|
||||||
|
bool idGameEditExt::IsLineCode(const char* filename, int linenumber) const
|
||||||
|
{
|
||||||
|
idStr fileStr;
|
||||||
|
idProgram* program = &gameLocal.program;
|
||||||
|
for (int i = 0; i < program->NumStatements(); i++)
|
||||||
|
{
|
||||||
|
fileStr = program->GetFilename(program->GetStatement(i).file);
|
||||||
|
fileStr.BackSlashesToSlashes();
|
||||||
|
|
||||||
|
if (strcmp(filename, fileStr.c_str()) == 0
|
||||||
|
&& program->GetStatement(i).linenumber == linenumber
|
||||||
|
)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void idGameEditExt::GetLoadedScripts( idStrList** result )
|
||||||
|
{
|
||||||
|
(*result)->Clear();
|
||||||
|
idProgram* program = &gameLocal.program;
|
||||||
|
|
||||||
|
for (int i = 0; i < program->NumFilenames(); i++)
|
||||||
|
{
|
||||||
|
(*result)->AddUnique( idStr(program->GetFilename( i )) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void idGameEditExt::MSG_WriteScriptList( idBitMsg* msg)
|
||||||
|
{
|
||||||
|
idProgram* program = &gameLocal.program;
|
||||||
|
|
||||||
|
msg->WriteInt( program->NumFilenames() );
|
||||||
|
for (int i = 0; i < program->NumFilenames(); i++)
|
||||||
|
{
|
||||||
|
idStr file = program->GetFilename(i);
|
||||||
|
//fix this. it seams that scripts triggered by the runtime are stored with a wrong path
|
||||||
|
//the use // instead of '\'
|
||||||
|
file.BackSlashesToSlashes();
|
||||||
|
msg->WriteString(file);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const char*idGameEditExt::GetFilenameForStatement(idProgram* program, int index) const
|
||||||
|
{
|
||||||
|
return program->GetFilenameForStatement(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
int idGameEditExt::GetLineNumberForStatement(idProgram* program, int index) const
|
||||||
|
{
|
||||||
|
return program->GetLineNumberForStatement(index);
|
||||||
|
}
|
|
@ -270,6 +270,14 @@ bool IsDoom3DemoVersion()
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool ( *updateDebuggerFnPtr )( idInterpreter *interpreter, idProgram *program, int instructionPointer ) = NULL;
|
||||||
|
bool updateGameDebugger( idInterpreter *interpreter, idProgram *program, int instructionPointer ) {
|
||||||
|
bool ret = false;
|
||||||
|
if ( interpreter != nullptr && program != nullptr ) {
|
||||||
|
ret = updateDebuggerFnPtr ? updateDebuggerFnPtr( interpreter, program, instructionPointer ) : false;
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -352,6 +360,8 @@ void idGameLocal::Init( void ) {
|
||||||
|
|
||||||
// DG: hack to support the Demo version of Doom3
|
// DG: hack to support the Demo version of Doom3
|
||||||
common->GetAdditionalFunction(idCommon::FT_IsDemo, (idCommon::FunctionPointer*)&isDemoFnPtr, NULL);
|
common->GetAdditionalFunction(idCommon::FT_IsDemo, (idCommon::FunctionPointer*)&isDemoFnPtr, NULL);
|
||||||
|
//debugger support
|
||||||
|
common->GetAdditionalFunction(idCommon::FT_UpdateDebugger,(idCommon::FunctionPointer*) &updateDebuggerFnPtr,NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -1192,7 +1202,7 @@ void idGameLocal::MapPopulate( void ) {
|
||||||
idGameLocal::InitFromNewMap
|
idGameLocal::InitFromNewMap
|
||||||
===================
|
===================
|
||||||
*/
|
*/
|
||||||
void idGameLocal::InitFromNewMap( const char *mapName, idRenderWorld *renderWorld, idSoundWorld *soundWorld, bool isServer, bool isClient, int randseed ) {
|
void idGameLocal::InitFromNewMap( const char *mapName, idRenderWorld *renderWorld, idSoundWorld *soundWorld, bool isServer, bool isClient, int randseed) {
|
||||||
|
|
||||||
this->isServer = isServer;
|
this->isServer = isServer;
|
||||||
this->isClient = isClient;
|
this->isClient = isClient;
|
||||||
|
@ -2216,13 +2226,13 @@ idGameLocal::RunFrame
|
||||||
================
|
================
|
||||||
*/
|
*/
|
||||||
gameReturn_t idGameLocal::RunFrame( const usercmd_t *clientCmds ) {
|
gameReturn_t idGameLocal::RunFrame( const usercmd_t *clientCmds ) {
|
||||||
idEntity * ent;
|
idEntity * ent;
|
||||||
int num;
|
int num;
|
||||||
float ms;
|
float ms;
|
||||||
idTimer timer_think, timer_events, timer_singlethink;
|
idTimer timer_think, timer_events, timer_singlethink;
|
||||||
gameReturn_t ret;
|
gameReturn_t ret;
|
||||||
idPlayer *player;
|
idPlayer *player;
|
||||||
const renderView_t *view;
|
const renderView_t *view;
|
||||||
|
|
||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
if ( isMultiplayer ) {
|
if ( isMultiplayer ) {
|
||||||
|
|
|
@ -33,6 +33,11 @@ If you have questions concerning this license or the applicable additional terms
|
||||||
|
|
||||||
#include "script/Script_Interpreter.h"
|
#include "script/Script_Interpreter.h"
|
||||||
|
|
||||||
|
#include "framework/FileSystem.h"
|
||||||
|
|
||||||
|
// HvG: Debugger support
|
||||||
|
extern bool updateGameDebugger( idInterpreter *interpreter, idProgram *program, int instructionPointer );
|
||||||
|
|
||||||
/*
|
/*
|
||||||
================
|
================
|
||||||
idInterpreter::idInterpreter()
|
idInterpreter::idInterpreter()
|
||||||
|
@ -183,7 +188,6 @@ idInterpreter::GetRegisterValue
|
||||||
Returns a string representation of the value of the register. This is
|
Returns a string representation of the value of the register. This is
|
||||||
used primarily for the debugger and debugging
|
used primarily for the debugger and debugging
|
||||||
|
|
||||||
//FIXME: This is pretty much wrong. won't access data in most situations.
|
|
||||||
================
|
================
|
||||||
*/
|
*/
|
||||||
bool idInterpreter::GetRegisterValue( const char *name, idStr &out, int scopeDepth ) {
|
bool idInterpreter::GetRegisterValue( const char *name, idStr &out, int scopeDepth ) {
|
||||||
|
@ -191,17 +195,17 @@ bool idInterpreter::GetRegisterValue( const char *name, idStr &out, int scopeDep
|
||||||
idVarDef *d;
|
idVarDef *d;
|
||||||
char funcObject[ 1024 ];
|
char funcObject[ 1024 ];
|
||||||
char *funcName;
|
char *funcName;
|
||||||
const idVarDef *scope;
|
const idVarDef *scope = NULL;
|
||||||
|
const idVarDef *scopeObj;
|
||||||
const idTypeDef *field;
|
const idTypeDef *field;
|
||||||
const idScriptObject *obj;
|
|
||||||
const function_t *func;
|
const function_t *func;
|
||||||
|
|
||||||
out.Empty();
|
out.Empty();
|
||||||
|
|
||||||
if ( scopeDepth == -1 ) {
|
if ( scopeDepth == -1 ) {
|
||||||
scopeDepth = callStackDepth;
|
scopeDepth = callStackDepth;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( scopeDepth == callStackDepth ) {
|
if ( scopeDepth == callStackDepth ) {
|
||||||
func = currentFunction;
|
func = currentFunction;
|
||||||
} else {
|
} else {
|
||||||
|
@ -215,35 +219,44 @@ bool idInterpreter::GetRegisterValue( const char *name, idStr &out, int scopeDep
|
||||||
funcName = strstr( funcObject, "::" );
|
funcName = strstr( funcObject, "::" );
|
||||||
if ( funcName ) {
|
if ( funcName ) {
|
||||||
*funcName = '\0';
|
*funcName = '\0';
|
||||||
scope = gameLocal.program.GetDef( NULL, funcObject, &def_namespace );
|
scopeObj = gameLocal.program.GetDef( NULL, funcObject, &def_namespace );
|
||||||
funcName += 2;
|
funcName += 2;
|
||||||
|
if ( scopeObj )
|
||||||
|
{
|
||||||
|
scope = gameLocal.program.GetDef( NULL, funcName, scopeObj );
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
funcName = funcObject;
|
funcName = funcObject;
|
||||||
scope = &def_namespace;
|
scope = gameLocal.program.GetDef( NULL, func->Name(), &def_namespace );
|
||||||
|
scopeObj = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get the function from the object
|
if ( !scope )
|
||||||
d = gameLocal.program.GetDef( NULL, funcName, scope );
|
{
|
||||||
if ( !d ) {
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get the variable itself and check various namespaces
|
d = gameLocal.program.GetDef( NULL, name, scope );
|
||||||
d = gameLocal.program.GetDef( NULL, name, d );
|
|
||||||
if ( !d ) {
|
// Check the objects for it if it wasnt local to the function
|
||||||
if ( scope == &def_namespace ) {
|
if ( !d )
|
||||||
return false;
|
{
|
||||||
}
|
for ( ; scopeObj && scopeObj->TypeDef()->SuperClass(); scopeObj = scopeObj->TypeDef()->SuperClass()->def )
|
||||||
|
{
|
||||||
d = gameLocal.program.GetDef( NULL, name, scope );
|
d = gameLocal.program.GetDef( NULL, name, scopeObj );
|
||||||
if ( !d ) {
|
if ( d )
|
||||||
d = gameLocal.program.GetDef( NULL, name, &def_namespace );
|
{
|
||||||
if ( !d ) {
|
break;
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ( !d )
|
||||||
|
{
|
||||||
|
out = "???";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
reg = GetVariable( d );
|
reg = GetVariable( d );
|
||||||
switch( d->Type() ) {
|
switch( d->Type() ) {
|
||||||
case ev_float:
|
case ev_float:
|
||||||
|
@ -256,7 +269,7 @@ bool idInterpreter::GetRegisterValue( const char *name, idStr &out, int scopeDep
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ev_vector:
|
case ev_vector:
|
||||||
if ( reg.vectorPtr ) {
|
if ( reg.vectorPtr ) {
|
||||||
out = va( "%g,%g,%g", reg.vectorPtr->x, reg.vectorPtr->y, reg.vectorPtr->z );
|
out = va( "%g,%g,%g", reg.vectorPtr->x, reg.vectorPtr->y, reg.vectorPtr->z );
|
||||||
} else {
|
} else {
|
||||||
out = "0,0,0";
|
out = "0,0,0";
|
||||||
|
@ -274,30 +287,55 @@ bool idInterpreter::GetRegisterValue( const char *name, idStr &out, int scopeDep
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ev_field:
|
case ev_field:
|
||||||
|
{
|
||||||
|
idEntity* entity;
|
||||||
|
idScriptObject* obj;
|
||||||
|
|
||||||
if ( scope == &def_namespace ) {
|
if ( scope == &def_namespace ) {
|
||||||
// should never happen, but handle it safely anyway
|
// should never happen, but handle it safely anyway
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
field = scope->TypeDef()->GetParmType( reg.ptrOffset )->FieldType();
|
field = d->TypeDef()->FieldType();
|
||||||
obj = *reinterpret_cast<const idScriptObject **>( &localstack[ callStack[ callStackDepth ].stackbase ] );
|
entity = GetEntity ( *((int*)&localstack[ localstackBase ]) );
|
||||||
if ( !field || !obj ) {
|
if ( !entity || !field )
|
||||||
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
obj = &entity->scriptObject;
|
||||||
|
if ( !obj ) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
switch ( field->Type() ) {
|
switch ( field->Type() ) {
|
||||||
case ev_boolean:
|
case ev_boolean:
|
||||||
out = va( "%d", *( reinterpret_cast<int *>( &obj->data[ reg.ptrOffset ] ) ) );
|
out = va( "%d", *( reinterpret_cast<int *>( &obj->data[ reg.ptrOffset ] ) ) );
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
case ev_float:
|
case ev_float:
|
||||||
out = va( "%g", *( reinterpret_cast<float *>( &obj->data[ reg.ptrOffset ] ) ) );
|
out = va( "%g", *( reinterpret_cast<float *>( &obj->data[ reg.ptrOffset ] ) ) );
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
case ev_string: {
|
||||||
|
const char* str;
|
||||||
|
str = reinterpret_cast<const char*>( &obj->data[ reg.ptrOffset ] );
|
||||||
|
if ( !str ) {
|
||||||
|
out = "\"\"";
|
||||||
|
} else {
|
||||||
|
out = "\"";
|
||||||
|
out += str;
|
||||||
|
out += "\"";
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case ev_string:
|
case ev_string:
|
||||||
if ( reg.stringPtr ) {
|
if ( reg.stringPtr ) {
|
||||||
|
@ -969,6 +1007,19 @@ bool idInterpreter::Execute( void ) {
|
||||||
// next statement
|
// next statement
|
||||||
st = &gameLocal.program.GetStatement( instructionPointer );
|
st = &gameLocal.program.GetStatement( instructionPointer );
|
||||||
|
|
||||||
|
if ( !updateGameDebugger( this, &gameLocal.program, instructionPointer )
|
||||||
|
&& g_debugScript.GetBool( ) )
|
||||||
|
{
|
||||||
|
static int lastLineNumber = -1;
|
||||||
|
if ( lastLineNumber != gameLocal.program.GetStatement ( instructionPointer ).linenumber ) {
|
||||||
|
gameLocal.Printf ( "%s (%d)\n",
|
||||||
|
gameLocal.program.GetFilename ( gameLocal.program.GetStatement ( instructionPointer ).file ),
|
||||||
|
gameLocal.program.GetStatement ( instructionPointer ).linenumber
|
||||||
|
);
|
||||||
|
lastLineNumber = gameLocal.program.GetStatement ( instructionPointer ).linenumber;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
switch( st->op ) {
|
switch( st->op ) {
|
||||||
case OP_RETURN:
|
case OP_RETURN:
|
||||||
LeaveFunction( st->a );
|
LeaveFunction( st->a );
|
||||||
|
@ -1833,3 +1884,98 @@ bool idInterpreter::Execute( void ) {
|
||||||
|
|
||||||
return threadDying;
|
return threadDying;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool idGameEditExt::CheckForBreakPointHit(const idInterpreter* interpreter, const function_t* function1, const function_t* function2, int depth) const
|
||||||
|
{
|
||||||
|
return ( ( interpreter->GetCurrentFunction ( ) == function1 ||
|
||||||
|
interpreter->GetCurrentFunction ( ) == function2)&&
|
||||||
|
( interpreter->GetCallstackDepth ( ) <= depth) );
|
||||||
|
}
|
||||||
|
|
||||||
|
bool idGameEditExt::ReturnedFromFunction(const idProgram* program, const idInterpreter* interpreter, int index) const
|
||||||
|
{
|
||||||
|
|
||||||
|
return ( const_cast<idProgram*>(program)->GetStatement(index).op == OP_RETURN && interpreter->GetCallstackDepth ( ) <= 1 );
|
||||||
|
}
|
||||||
|
|
||||||
|
bool idGameEditExt::GetRegisterValue(const idInterpreter* interpreter, const char* name, idStr& out, int scopeDepth) const
|
||||||
|
{
|
||||||
|
return const_cast<idInterpreter*>(interpreter)->GetRegisterValue(name, out, scopeDepth);
|
||||||
|
}
|
||||||
|
|
||||||
|
const idThread*idGameEditExt::GetThread(const idInterpreter* interpreter) const
|
||||||
|
{
|
||||||
|
return interpreter->GetThread();
|
||||||
|
}
|
||||||
|
|
||||||
|
void idGameEditExt::MSG_WriteCallstackFunc(idBitMsg* msg, const prstack_t* stack, const idProgram * program, int instructionPtr)
|
||||||
|
{
|
||||||
|
const statement_t* st;
|
||||||
|
const function_t* func;
|
||||||
|
|
||||||
|
func = stack->f;
|
||||||
|
|
||||||
|
// If the function is unknown then just fill in with default data.
|
||||||
|
if ( !func )
|
||||||
|
{
|
||||||
|
msg->WriteString ( "<UNKNOWN>" );
|
||||||
|
msg->WriteString ( "<UNKNOWN>" );
|
||||||
|
msg->WriteInt ( 0 );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
msg->WriteString ( va("%s( )", func->Name() ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
if (stack->s == -1) //this is a fake stack created by debugger, use intruction pointer for retrieval.
|
||||||
|
st = &const_cast<idProgram*>( program )->GetStatement( instructionPtr );
|
||||||
|
else // Use the calling statement as the filename and linenumber where the call was made from
|
||||||
|
st = &const_cast<idProgram*>( program )->GetStatement ( stack->s );
|
||||||
|
|
||||||
|
if ( st )
|
||||||
|
{
|
||||||
|
idStr qpath = const_cast<idProgram*>( program )->GetFilename( st->file );
|
||||||
|
if (idStr::FindChar( qpath, ':' ) != -1)
|
||||||
|
qpath = fileSystem->OSPathToRelativePath( qpath.c_str() );
|
||||||
|
qpath.BackSlashesToSlashes ( );
|
||||||
|
msg->WriteString( qpath );
|
||||||
|
msg->WriteInt( st->linenumber );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
msg->WriteString ( "<UNKNOWN>" );
|
||||||
|
msg->WriteInt ( 0 );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void idGameEditExt::MSG_WriteInterpreterInfo(idBitMsg* msg, const idInterpreter* interpreter, const idProgram* program, int instructionPtr)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
prstack_s temp;
|
||||||
|
|
||||||
|
msg->WriteShort((int)interpreter->GetCallstackDepth( ) );
|
||||||
|
|
||||||
|
// write out the current function
|
||||||
|
temp.f = interpreter->GetCurrentFunction( );
|
||||||
|
temp.s = -1;
|
||||||
|
temp.stackbase = 0;
|
||||||
|
MSG_WriteCallstackFunc( msg, &temp, program, instructionPtr);
|
||||||
|
|
||||||
|
// Run through all of the callstack and write each to the msg
|
||||||
|
for (i = interpreter->GetCallstackDepth() - 1; i > 0; i--)
|
||||||
|
{
|
||||||
|
MSG_WriteCallstackFunc( msg, interpreter->GetCallstack( ) + i, program, instructionPtr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int idGameEditExt::GetInterpreterCallStackDepth(const idInterpreter* interpreter)
|
||||||
|
{
|
||||||
|
return interpreter->GetCallstackDepth();
|
||||||
|
}
|
||||||
|
|
||||||
|
const function_t*idGameEditExt::GetInterpreterCallStackFunction( const idInterpreter* interpreter, int stackDepth/* = -1*/)
|
||||||
|
{
|
||||||
|
return interpreter->GetCallstack( )[ stackDepth > -1 ? stackDepth :interpreter->GetCallstackDepth( ) ].f;
|
||||||
|
}
|
|
@ -28,11 +28,11 @@ If you have questions concerning this license or the applicable additional terms
|
||||||
|
|
||||||
#include "sys/platform.h"
|
#include "sys/platform.h"
|
||||||
|
|
||||||
#include "gamesys/SysCvar.h"
|
#include "game/gamesys/SysCvar.h"
|
||||||
#include "Player.h"
|
#include "game/Player.h"
|
||||||
#include "Camera.h"
|
#include "game/Camera.h"
|
||||||
|
|
||||||
#include "script/Script_Thread.h"
|
#include "Script_Thread.h"
|
||||||
|
|
||||||
const idEventDef EV_Thread_Execute( "<execute>", NULL );
|
const idEventDef EV_Thread_Execute( "<execute>", NULL );
|
||||||
const idEventDef EV_Thread_SetCallback( "<script_setcallback>", NULL );
|
const idEventDef EV_Thread_SetCallback( "<script_setcallback>", NULL );
|
||||||
|
@ -1841,3 +1841,49 @@ void idThread::Event_InfluenceActive( void ) {
|
||||||
idThread::ReturnInt( false );
|
idThread::ReturnInt( false );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int idGameEditExt::ThreadGetNum(const idThread* thread) const
|
||||||
|
{
|
||||||
|
return const_cast<idThread*>(thread)->GetThreadNum();
|
||||||
|
}
|
||||||
|
|
||||||
|
const char*idGameEditExt::ThreadGetName(const idThread* thread) const
|
||||||
|
{
|
||||||
|
return const_cast<idThread*>(thread)->GetThreadName();
|
||||||
|
}
|
||||||
|
|
||||||
|
int idGameEditExt::GetTotalScriptThreads() const
|
||||||
|
{
|
||||||
|
return idThread::GetThreads().Num();
|
||||||
|
}
|
||||||
|
|
||||||
|
const idThread*idGameEditExt::GetThreadByIndex(int index) const
|
||||||
|
{
|
||||||
|
return idThread::GetThreads()[index];
|
||||||
|
}
|
||||||
|
|
||||||
|
bool idGameEditExt::ThreadIsDoneProcessing(const idThread* thread) const
|
||||||
|
{
|
||||||
|
return const_cast<idThread*>(thread)->IsDoneProcessing();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool idGameEditExt::ThreadIsWaiting(const idThread* thread) const
|
||||||
|
{
|
||||||
|
return const_cast<idThread*>(thread)->IsWaiting();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool idGameEditExt::ThreadIsDying(const idThread* thread) const
|
||||||
|
{
|
||||||
|
return const_cast<idThread*>(thread)->IsDying();
|
||||||
|
}
|
||||||
|
|
||||||
|
void idGameEditExt::MSG_WriteThreadInfo(idBitMsg* msg, const idThread* thread, const idInterpreter* interpreter)
|
||||||
|
{
|
||||||
|
msg->WriteString(const_cast<idThread*>(thread)->GetThreadName());
|
||||||
|
msg->WriteInt(const_cast<idThread*>(thread)->GetThreadNum());
|
||||||
|
|
||||||
|
msg->WriteBits((int)(thread == interpreter->GetThread()), 1);
|
||||||
|
msg->WriteBits((int)const_cast<idThread*>(thread)->IsDoneProcessing(), 1);
|
||||||
|
msg->WriteBits((int)const_cast<idThread*>(thread)->IsWaiting(), 1);
|
||||||
|
msg->WriteBits((int)const_cast<idThread*>(thread)->IsDying(), 1);
|
||||||
|
}
|
|
@ -85,7 +85,7 @@ public:
|
||||||
void WriteShort( int c );
|
void WriteShort( int c );
|
||||||
void WriteUShort( int c );
|
void WriteUShort( int c );
|
||||||
void WriteInt( int c );
|
void WriteInt( int c );
|
||||||
void WriteFloat( float f );
|
void WriteFloat( float f );
|
||||||
void WriteFloat( float f, int exponentBits, int mantissaBits );
|
void WriteFloat( float f, int exponentBits, int mantissaBits );
|
||||||
void WriteAngle8( float f );
|
void WriteAngle8( float f );
|
||||||
void WriteAngle16( float f );
|
void WriteAngle16( float f );
|
||||||
|
|
|
@ -2169,6 +2169,8 @@ idRenderSystemLocal::Shutdown
|
||||||
void idRenderSystemLocal::Shutdown( void ) {
|
void idRenderSystemLocal::Shutdown( void ) {
|
||||||
common->Printf( "idRenderSystem::Shutdown()\n" );
|
common->Printf( "idRenderSystem::Shutdown()\n" );
|
||||||
|
|
||||||
|
common->SetRefreshOnPrint( false ); // without a renderer there's nothing to refresh
|
||||||
|
|
||||||
R_DoneFreeType( );
|
R_DoneFreeType( );
|
||||||
|
|
||||||
if ( glConfig.isInitialized ) {
|
if ( glConfig.isInitialized ) {
|
||||||
|
|
|
@ -126,21 +126,21 @@ IDI_DBG_EMPTY ICON "res\\dbg_empty.ico"
|
||||||
|
|
||||||
IDR_DBG_ACCELERATORS ACCELERATORS
|
IDR_DBG_ACCELERATORS ACCELERATORS
|
||||||
BEGIN
|
BEGIN
|
||||||
VK_F9, ID_DBG_DEBUG_QUICKWATCH, VIRTKEY, SHIFT, NOINVERT
|
VK_F9, ID_DBG_DEBUG_QUICKWATCH, VIRTKEY, SHIFT, NOINVERT
|
||||||
VK_F5, ID_DBG_DEBUG_RUN, VIRTKEY, NOINVERT
|
VK_F5, ID_DBG_DEBUG_RUN, VIRTKEY, NOINVERT
|
||||||
VK_F11, ID_DBG_DEBUG_STEPINTO, VIRTKEY, NOINVERT
|
VK_F11, ID_DBG_DEBUG_STEPINTO, VIRTKEY, NOINVERT
|
||||||
VK_F10, ID_DBG_DEBUG_STEPOVER, VIRTKEY, NOINVERT
|
VK_F10, ID_DBG_DEBUG_STEPOVER, VIRTKEY, NOINVERT
|
||||||
VK_F9, ID_DBG_DEBUG_TOGGLEBREAKPOINT, VIRTKEY, NOINVERT
|
VK_F9, ID_DBG_DEBUG_TOGGLEBREAKPOINT, VIRTKEY, NOINVERT
|
||||||
VK_F3, ID_DBG_EDIT_FINDNEXT, VIRTKEY, NOINVERT
|
VK_F3, ID_DBG_EDIT_FINDNEXT, VIRTKEY, NOINVERT
|
||||||
VK_F3, ID_DBG_EDIT_FINDPREV, VIRTKEY, SHIFT, NOINVERT
|
VK_F3, ID_DBG_EDIT_FINDPREV, VIRTKEY, SHIFT, NOINVERT
|
||||||
VK_F3, ID_DBG_EDIT_FINDSELECTED, VIRTKEY, CONTROL, NOINVERT
|
VK_F3, ID_DBG_EDIT_FINDSELECTED, VIRTKEY, CONTROL, NOINVERT
|
||||||
VK_F3, ID_DBG_EDIT_FINDSELECTED, VIRTKEY, CONTROL, NOINVERT
|
VK_F3, ID_DBG_EDIT_FINDSELECTEDPREV, VIRTKEY, SHIFT, CONTROL,NOINVERT
|
||||||
VK_F3, ID_DBG_EDIT_FINDSELECTEDPREV, VIRTKEY, SHIFT, CONTROL,
|
VK_F4, ID_DBG_FILE_CLOSE, VIRTKEY, CONTROL, NOINVERT
|
||||||
NOINVERT
|
VK_TAB, ID_DBG_FILE_NEXT, VIRTKEY, CONTROL, NOINVERT
|
||||||
VK_F4, ID_DBG_FILE_CLOSE, VIRTKEY, CONTROL, NOINVERT
|
VK_RETURN, ID_DBG_SEND_COMMAND, VIRTKEY, NOINVERT
|
||||||
VK_TAB, ID_DBG_FILE_NEXT, VIRTKEY, CONTROL, NOINVERT
|
"O", ID_DBG_FILE_OPEN, VIRTKEY, CONTROL, NOINVERT
|
||||||
"O", ID_DBG_FILE_OPEN, VIRTKEY, CONTROL, NOINVERT
|
"F", ID_DBG_EDIT_FIND, VIRTKEY, CONTROL, NOINVERT
|
||||||
"F", ID_DBG_EDIT_FIND, VIRTKEY, CONTROL, NOINVERT
|
|
||||||
END
|
END
|
||||||
|
|
||||||
|
|
||||||
|
@ -149,17 +149,17 @@ END
|
||||||
// Dialog
|
// Dialog
|
||||||
//
|
//
|
||||||
|
|
||||||
IDD_DBG_ABOUT DIALOGEX 0, 0, 222, 71
|
IDD_DBG_ABOUT DIALOGEX 0, 0, 250, 90
|
||||||
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | DS_CENTER | WS_POPUP |
|
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | DS_CENTER | WS_POPUP |
|
||||||
WS_CAPTION | WS_SYSMENU
|
WS_CAPTION | WS_SYSMENU
|
||||||
CAPTION "About Script Debugger"
|
CAPTION "About Script Debugger"
|
||||||
FONT 8, "MS Shell Dlg", 400, 0, 0x1
|
FONT 8, "MS Shell Dlg", 400, 0, 0x1
|
||||||
BEGIN
|
BEGIN
|
||||||
LTEXT "Script Debugger",IDC_STATIC,35,7,81,8
|
LTEXT "Script Debugger",IDC_STATIC,35,7,81,8
|
||||||
LTEXT "Version 0.01",IDC_STATIC,35,17,41,8
|
LTEXT "Version 1.1",IDC_STATIC,35,17,41,8
|
||||||
LTEXT "Original version by Raven",IDC_STATIC,35,
|
LTEXT "Original version by Raven", IDC_STATIC, 35,28, 134, 8
|
||||||
28,134,8
|
LTEXT "Dhewm3 version by Harrie van Ginneken \n\t\t\t\tand\n\t\t\t Daniel Gibson", IDC_STATIC, 35, 38, 134, 32
|
||||||
DEFPUSHBUTTON "OK",IDOK,165,50,50,14
|
DEFPUSHBUTTON "OK",IDOK,100,68,50,14
|
||||||
ICON 5098,IDC_STATIC,7,7,20,20
|
ICON 5098,IDC_STATIC,7,7,20,20
|
||||||
END
|
END
|
||||||
|
|
||||||
|
|
|
@ -76,6 +76,7 @@ If you have questions concerning this license or the applicable additional terms
|
||||||
#define ID_DBG_EDIT_FINDPREV 22022
|
#define ID_DBG_EDIT_FINDPREV 22022
|
||||||
#define ID_DBG_EDIT_FINDSELECTEDPREV 22023
|
#define ID_DBG_EDIT_FINDSELECTEDPREV 22023
|
||||||
#define ID_DBG_HELP_ABOUT 22024
|
#define ID_DBG_HELP_ABOUT 22024
|
||||||
|
#define ID_DBG_SEND_COMMAND 22025
|
||||||
|
|
||||||
// Next default values for new objects
|
// Next default values for new objects
|
||||||
//
|
//
|
||||||
|
|
|
@ -269,8 +269,7 @@ FONT 8, "MS Shell Dlg", 400, 0, 0x1
|
||||||
BEGIN
|
BEGIN
|
||||||
LTEXT "GUI Editor",IDC_STATIC,35,7,62,8
|
LTEXT "GUI Editor",IDC_STATIC,35,7,62,8
|
||||||
LTEXT "Version 0.15",IDC_STATIC,35,17,41,8
|
LTEXT "Version 0.15",IDC_STATIC,35,17,41,8
|
||||||
LTEXT "Original version by Raven",IDC_STATIC,35,
|
LTEXT "Original version by Raven", IDC_STATIC, 35,28, 134, 8
|
||||||
28,134,8
|
|
||||||
DEFPUSHBUTTON "OK",IDOK,165,50,50,14
|
DEFPUSHBUTTON "OK",IDOK,165,50,50,14
|
||||||
ICON IDI_GUIED,IDC_STATIC,7,7,20,20
|
ICON IDI_GUIED,IDC_STATIC,7,7,20,20
|
||||||
END
|
END
|
||||||
|
|
|
@ -673,7 +673,30 @@ Sys_DLL_GetProcAddress
|
||||||
=====================
|
=====================
|
||||||
*/
|
*/
|
||||||
void *Sys_DLL_GetProcAddress( uintptr_t dllHandle, const char *procName ) {
|
void *Sys_DLL_GetProcAddress( uintptr_t dllHandle, const char *procName ) {
|
||||||
return (void *)GetProcAddress( (HINSTANCE)dllHandle, procName );
|
void * adr = (void*)GetProcAddress((HINSTANCE)dllHandle, procName);
|
||||||
|
if (!adr)
|
||||||
|
{
|
||||||
|
DWORD e = GetLastError();
|
||||||
|
LPVOID msgBuf = nullptr;
|
||||||
|
|
||||||
|
FormatMessage(
|
||||||
|
FORMAT_MESSAGE_ALLOCATE_BUFFER |
|
||||||
|
FORMAT_MESSAGE_FROM_SYSTEM |
|
||||||
|
FORMAT_MESSAGE_IGNORE_INSERTS,
|
||||||
|
NULL,
|
||||||
|
e,
|
||||||
|
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
|
||||||
|
(LPTSTR)&msgBuf,
|
||||||
|
0, NULL);
|
||||||
|
|
||||||
|
idStr errorStr = va("[%i (0x%X)]\t%s", e, e, msgBuf);
|
||||||
|
|
||||||
|
if (errorStr.Length())
|
||||||
|
common->Warning("GetProcAddress( %i %s) Failed ! %s", dllHandle, procName, errorStr.c_str());
|
||||||
|
|
||||||
|
::LocalFree(msgBuf);
|
||||||
|
}
|
||||||
|
return adr;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -1031,7 +1054,10 @@ int main(int argc, char *argv[]) {
|
||||||
|
|
||||||
// Launch the script debugger
|
// Launch the script debugger
|
||||||
if ( strstr( GetCommandLine(), "+debugger" ) ) {
|
if ( strstr( GetCommandLine(), "+debugger" ) ) {
|
||||||
// DebuggerClientInit( lpCmdLine );
|
|
||||||
|
#ifdef ID_ALLOW_TOOLS
|
||||||
|
DebuggerClientInit(GetCommandLine());
|
||||||
|
#endif
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -392,7 +392,8 @@ void rvOpenFileDialog::SetFilter ( const char* s )
|
||||||
if ( semi != -1 )
|
if ( semi != -1 )
|
||||||
{
|
{
|
||||||
filter = filters.Left ( semi );
|
filter = filters.Left ( semi );
|
||||||
filters = filters.Right ( filters.Length ( ) - semi );
|
filters = filters.Right ( filters.Length ( ) - (semi + 1));
|
||||||
|
filters.Strip(' ');
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
@ -37,8 +37,8 @@ If you have questions concerning this license or the applicable additional terms
|
||||||
rvDebuggerApp::rvDebuggerApp
|
rvDebuggerApp::rvDebuggerApp
|
||||||
================
|
================
|
||||||
*/
|
*/
|
||||||
rvDebuggerApp::rvDebuggerApp ( ) :
|
rvDebuggerApp::rvDebuggerApp ( ) //:
|
||||||
mOptions ( "Software\\id Software\\DOOM3\\Tools\\Debugger" )
|
//mOptions ( "Software\\id Software\\DOOM3\\Tools\\Debugger" )
|
||||||
{
|
{
|
||||||
mInstance = NULL;
|
mInstance = NULL;
|
||||||
mDebuggerWindow = NULL;
|
mDebuggerWindow = NULL;
|
||||||
|
|
|
@ -29,7 +29,7 @@ If you have questions concerning this license or the applicable additional terms
|
||||||
#define DEBUGGERAPP_H_
|
#define DEBUGGERAPP_H_
|
||||||
|
|
||||||
#include "../../sys/win32/win_local.h"
|
#include "../../sys/win32/win_local.h"
|
||||||
#include "../../framework/sync/Msg.h"
|
//#include "../../framework/sync/Msg.h"
|
||||||
|
|
||||||
#ifndef REGISTRYOPTIONS_H_
|
#ifndef REGISTRYOPTIONS_H_
|
||||||
#include "../common/RegistryOptions.h"
|
#include "../common/RegistryOptions.h"
|
||||||
|
@ -49,13 +49,15 @@ If you have questions concerning this license or the applicable additional terms
|
||||||
|
|
||||||
// These were changed to static by ID so to make it easy we just throw them
|
// These were changed to static by ID so to make it easy we just throw them
|
||||||
// in this header
|
// in this header
|
||||||
const int MAX_MSGLEN = 1400;
|
// we need a lot to be able to list all threads in mars_city1
|
||||||
|
const int MAX_MSGLEN = 8600;
|
||||||
|
|
||||||
class rvDebuggerApp
|
class rvDebuggerApp
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
rvDebuggerApp ( );
|
rvDebuggerApp ( );
|
||||||
|
~rvDebuggerApp();
|
||||||
|
|
||||||
bool Initialize ( HINSTANCE hInstance );
|
bool Initialize ( HINSTANCE hInstance );
|
||||||
int Run ( void );
|
int Run ( void );
|
||||||
|
|
|
@ -25,20 +25,23 @@ If you have questions concerning this license or the applicable additional terms
|
||||||
|
|
||||||
===========================================================================
|
===========================================================================
|
||||||
*/
|
*/
|
||||||
|
#if defined( ID_ALLOW_TOOLS )
|
||||||
#include "tools/edit_gui_common.h"
|
#include "tools/edit_gui_common.h"
|
||||||
|
|
||||||
|
|
||||||
#include "DebuggerApp.h"
|
#include "DebuggerApp.h"
|
||||||
|
#else
|
||||||
|
#include "debugger_common.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "DebuggerBreakpoint.h"
|
#include "DebuggerBreakpoint.h"
|
||||||
|
|
||||||
int rvDebuggerBreakpoint::mNextID = 1;
|
int rvDebuggerBreakpoint::mNextID = 1;
|
||||||
|
|
||||||
rvDebuggerBreakpoint::rvDebuggerBreakpoint ( const char* filename, int linenumber, int id )
|
rvDebuggerBreakpoint::rvDebuggerBreakpoint ( const char* filename, int linenumber, int id, bool onceOnly )
|
||||||
{
|
{
|
||||||
mFilename = filename;
|
mFilename = filename;
|
||||||
mLineNumber = linenumber;
|
mLineNumber = linenumber;
|
||||||
mEnabled = true;
|
mEnabled = true;
|
||||||
|
mOnceOnly = onceOnly;
|
||||||
|
|
||||||
if ( id == -1 )
|
if ( id == -1 )
|
||||||
{
|
{
|
||||||
|
|
|
@ -28,25 +28,28 @@ If you have questions concerning this license or the applicable additional terms
|
||||||
#ifndef DEBUGGERBREAKPOINT_H_
|
#ifndef DEBUGGERBREAKPOINT_H_
|
||||||
#define DEBUGGERBREAKPOINT_H_
|
#define DEBUGGERBREAKPOINT_H_
|
||||||
|
|
||||||
|
class idProgram;
|
||||||
|
|
||||||
class rvDebuggerBreakpoint
|
class rvDebuggerBreakpoint
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
rvDebuggerBreakpoint ( const char* filename, int linenumber, int id = -1 );
|
rvDebuggerBreakpoint ( const char* filename, int linenumber, int id = -1, bool onceOnly = false );
|
||||||
rvDebuggerBreakpoint ( rvDebuggerBreakpoint& bp );
|
rvDebuggerBreakpoint ( rvDebuggerBreakpoint& bp );
|
||||||
~rvDebuggerBreakpoint ( void );
|
~rvDebuggerBreakpoint ( void );
|
||||||
|
|
||||||
const char* GetFilename ( void );
|
const char* GetFilename ( void );
|
||||||
int GetLineNumber ( void );
|
int GetLineNumber ( void );
|
||||||
int GetID ( void );
|
int GetID ( void );
|
||||||
|
bool GetOnceOnly ( void );
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
bool mEnabled;
|
bool mEnabled;
|
||||||
|
bool mOnceOnly;
|
||||||
int mID;
|
int mID;
|
||||||
int mLineNumber;
|
int mLineNumber;
|
||||||
idStr mFilename;
|
idStr mFilename;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
static int mNextID;
|
static int mNextID;
|
||||||
|
@ -67,4 +70,9 @@ ID_INLINE int rvDebuggerBreakpoint::GetID ( void )
|
||||||
return mID;
|
return mID;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ID_INLINE bool rvDebuggerBreakpoint::GetOnceOnly( void )
|
||||||
|
{
|
||||||
|
return mOnceOnly;
|
||||||
|
}
|
||||||
|
|
||||||
#endif // DEBUGGERBREAKPOINT_H_
|
#endif // DEBUGGERBREAKPOINT_H_
|
||||||
|
|
|
@ -73,7 +73,7 @@ bool rvDebuggerClient::Initialize ( void )
|
||||||
}
|
}
|
||||||
|
|
||||||
// Server must be running on the local host on port 28980
|
// Server must be running on the local host on port 28980
|
||||||
Sys_StringToNetAdr ( "localhost", &mServerAdrt, true );
|
Sys_StringToNetAdr ( com_dbgServerAdr.GetString( ), &mServerAdr, true );
|
||||||
mServerAdr.port = 27980;
|
mServerAdr.port = 27980;
|
||||||
|
|
||||||
// Attempt to let the server know we are here. The server may not be running so this
|
// Attempt to let the server know we are here. The server may not be running so this
|
||||||
|
@ -110,25 +110,29 @@ Process all incomding messages from the debugger server
|
||||||
bool rvDebuggerClient::ProcessMessages ( void )
|
bool rvDebuggerClient::ProcessMessages ( void )
|
||||||
{
|
{
|
||||||
netadr_t adrFrom;
|
netadr_t adrFrom;
|
||||||
msg_t msg;
|
idBitMsg msg;
|
||||||
byte buffer[MAX_MSGLEN];
|
byte buffer[MAX_MSGLEN];
|
||||||
|
|
||||||
MSG_Init( &msg, buffer, sizeof( buffer ) );
|
msg.SetSize(MAX_MSGLEN);
|
||||||
|
msg.BeginReading();
|
||||||
|
|
||||||
|
int msgSize;
|
||||||
// Check for pending udp packets on the debugger port
|
// Check for pending udp packets on the debugger port
|
||||||
while ( mPort.GetPacket ( adrFrom, msg.data, msg.cursize, msg.maxsize ) )
|
while ( mPort.GetPacket ( adrFrom, buffer,msgSize, MAX_MSGLEN) )
|
||||||
{
|
{
|
||||||
unsigned short command;
|
short command;
|
||||||
|
msg.Init(buffer, sizeof(buffer));
|
||||||
|
msg.SetSize(msgSize);
|
||||||
|
msg.BeginReading();
|
||||||
|
|
||||||
// Only accept packets from the debugger server for security reasons
|
// Only accept packets from the debugger server for security reasons
|
||||||
if ( !Sys_CompareNetAdrBase ( adrFrom, mServerAdr ) )
|
if ( !Sys_CompareNetAdrBase ( adrFrom, mServerAdr ) )
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
command = msg.ReadShort ( );
|
||||||
|
|
||||||
command = (unsigned short) MSG_ReadShort ( &msg );
|
// Is this what we are waiting for?
|
||||||
|
|
||||||
// Is this what we are waiting for?
|
|
||||||
if ( command == mWaitFor )
|
if ( command == mWaitFor )
|
||||||
{
|
{
|
||||||
mWaitFor = DBMSG_UNKNOWN;
|
mWaitFor = DBMSG_UNKNOWN;
|
||||||
|
@ -168,17 +172,39 @@ bool rvDebuggerClient::ProcessMessages ( void )
|
||||||
case DBMSG_INSPECTVARIABLE:
|
case DBMSG_INSPECTVARIABLE:
|
||||||
HandleInspectVariable ( &msg );
|
HandleInspectVariable ( &msg );
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case DBMSG_REMOVEBREAKPOINT:
|
||||||
|
HandleRemoveBreakpoint( &msg );
|
||||||
|
break;
|
||||||
|
case DBMSG_INSPECTSCRIPTS:
|
||||||
|
HandleInspectScripts( &msg );
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Give the window a chance to process the message
|
// Give the window a chance to process the message
|
||||||
msg.readcount = 0;
|
msg.SetReadCount(0);
|
||||||
msg.bit = 0;
|
msg.SetReadBit(0);
|
||||||
gDebuggerApp.GetWindow().ProcessNetMessage ( &msg );
|
gDebuggerApp.GetWindow().ProcessNetMessage ( &msg );
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void rvDebuggerClient::HandleRemoveBreakpoint(idBitMsg* msg)
|
||||||
|
{
|
||||||
|
long lineNumber;
|
||||||
|
char filename[MAX_PATH];
|
||||||
|
|
||||||
|
// Read the breakpoint info
|
||||||
|
|
||||||
|
lineNumber = msg->ReadInt();
|
||||||
|
msg->ReadString(filename, MAX_PATH);
|
||||||
|
|
||||||
|
rvDebuggerBreakpoint* bp = FindBreakpoint(filename, lineNumber);
|
||||||
|
if(bp)
|
||||||
|
RemoveBreakpoint(bp->GetID());
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
================
|
================
|
||||||
rvDebuggerClient::HandleBreak
|
rvDebuggerClient::HandleBreak
|
||||||
|
@ -187,19 +213,22 @@ Handle the DBMSG_BREAK message send from the server. This message is handled
|
||||||
by caching the file and linenumber where the break occured.
|
by caching the file and linenumber where the break occured.
|
||||||
================
|
================
|
||||||
*/
|
*/
|
||||||
void rvDebuggerClient::HandleBreak ( msg_t* msg )
|
void rvDebuggerClient::HandleBreak ( idBitMsg* msg )
|
||||||
{
|
{
|
||||||
char filename[MAX_PATH];
|
char filename[MAX_PATH];
|
||||||
|
|
||||||
mBreak = true;
|
mBreak = true;
|
||||||
|
|
||||||
// Line number
|
// Line number
|
||||||
mBreakLineNumber = MSG_ReadInt ( msg );
|
mBreakLineNumber = msg->ReadInt ( );
|
||||||
|
|
||||||
// Filename
|
// Filename
|
||||||
MSG_ReadString ( msg, filename, MAX_PATH );
|
msg->ReadString ( filename, MAX_PATH );
|
||||||
mBreakFilename = filename;
|
mBreakFilename = filename;
|
||||||
|
|
||||||
|
//int64_t ptr64b = msg->ReadInt64();
|
||||||
|
//mBreakProgram = (idProgram*)ptr64b;
|
||||||
|
|
||||||
// Clear the variables
|
// Clear the variables
|
||||||
mVariables.Clear ( );
|
mVariables.Clear ( );
|
||||||
|
|
||||||
|
@ -211,6 +240,26 @@ void rvDebuggerClient::HandleBreak ( msg_t* msg )
|
||||||
WaitFor ( DBMSG_INSPECTTHREADS, 2000 );
|
WaitFor ( DBMSG_INSPECTTHREADS, 2000 );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
================
|
||||||
|
rvDebuggerClient::InspectScripts
|
||||||
|
|
||||||
|
Instructs the client to inspect the loaded scripts
|
||||||
|
================
|
||||||
|
*/
|
||||||
|
void rvDebuggerClient::InspectScripts ( void )
|
||||||
|
{
|
||||||
|
idBitMsg msg;
|
||||||
|
byte buffer[MAX_MSGLEN];
|
||||||
|
|
||||||
|
msg.Init(buffer, sizeof(buffer));
|
||||||
|
msg.BeginWriting();
|
||||||
|
msg.WriteShort((short)DBMSG_INSPECTSCRIPTS);
|
||||||
|
SendPacket(msg.GetData(), msg.GetSize());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
================
|
================
|
||||||
rvDebuggerClient::InspectVariable
|
rvDebuggerClient::InspectVariable
|
||||||
|
@ -222,15 +271,41 @@ will in turn respond back to the client with the variable value
|
||||||
*/
|
*/
|
||||||
void rvDebuggerClient::InspectVariable ( const char* name, int callstackDepth )
|
void rvDebuggerClient::InspectVariable ( const char* name, int callstackDepth )
|
||||||
{
|
{
|
||||||
msg_t msg;
|
idBitMsg msg;
|
||||||
byte buffer[MAX_MSGLEN];
|
byte buffer[MAX_MSGLEN];
|
||||||
|
|
||||||
MSG_Init( &msg, buffer, sizeof( buffer ) );
|
msg.Init( buffer, sizeof( buffer ) );
|
||||||
MSG_WriteShort ( &msg, (int)DBMSG_INSPECTVARIABLE );
|
msg.BeginWriting();
|
||||||
MSG_WriteShort ( &msg, (short)(mCallstack.Num()-callstackDepth) );
|
msg.WriteShort ( (short)DBMSG_INSPECTVARIABLE );
|
||||||
MSG_WriteString ( &msg, name );
|
msg.WriteShort ( (short)(mCallstack.Num()-callstackDepth) );
|
||||||
|
msg.WriteString ( name );
|
||||||
|
|
||||||
SendPacket ( msg.data, msg.cursize );
|
SendPacket ( msg.GetData(), msg.GetSize());
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
================
|
||||||
|
rvDebuggerClient::HandleInspectScripts
|
||||||
|
|
||||||
|
Handle the message DBMSG_INSPECTSCRIPTS being sent from the server. This message
|
||||||
|
is handled by adding the script entries to a list for later lookup.
|
||||||
|
================
|
||||||
|
*/
|
||||||
|
void rvDebuggerClient::HandleInspectScripts( idBitMsg* msg )
|
||||||
|
{
|
||||||
|
int totalScripts;
|
||||||
|
|
||||||
|
mServerScripts.Clear();
|
||||||
|
|
||||||
|
// Read all of the callstack entries specfied in the message
|
||||||
|
for (totalScripts = msg->ReadInt(); totalScripts > 0; totalScripts--)
|
||||||
|
{
|
||||||
|
char temp[1024];
|
||||||
|
|
||||||
|
// Script Name
|
||||||
|
msg->ReadString(temp, 1024);
|
||||||
|
mServerScripts.Append(temp);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -241,29 +316,29 @@ Handle the message DBMSG_INSPECTCALLSTACK being sent from the server. This mess
|
||||||
is handled by adding the callstack entries to a list for later lookup.
|
is handled by adding the callstack entries to a list for later lookup.
|
||||||
================
|
================
|
||||||
*/
|
*/
|
||||||
void rvDebuggerClient::HandleInspectCallstack ( msg_t* msg )
|
void rvDebuggerClient::HandleInspectCallstack ( idBitMsg* msg )
|
||||||
{
|
{
|
||||||
int depth;
|
int depth;
|
||||||
|
|
||||||
ClearCallstack ( );
|
ClearCallstack ( );
|
||||||
|
|
||||||
// Read all of the callstack entries specfied in the message
|
// Read all of the callstack entries specfied in the message
|
||||||
for ( depth = (short)MSG_ReadShort ( msg ) ; depth > 0; depth -- )
|
for ( depth = (short)msg->ReadShort ( ) ; depth > 0; depth -- )
|
||||||
{
|
{
|
||||||
rvDebuggerCallstack* entry = new rvDebuggerCallstack;
|
rvDebuggerCallstack* entry = new rvDebuggerCallstack;
|
||||||
|
|
||||||
char temp[1024];
|
char temp[1024];
|
||||||
|
|
||||||
// Function name
|
// Function name
|
||||||
MSG_ReadString ( msg, temp, 1024 );
|
msg->ReadString ( temp, 1024 );
|
||||||
entry->mFunction = temp;
|
entry->mFunction = idStr(temp);
|
||||||
|
|
||||||
// Filename
|
// Filename
|
||||||
MSG_ReadString ( msg, temp, 1024 );
|
msg->ReadString ( temp, 1024 );
|
||||||
entry->mFilename = temp;
|
entry->mFilename = idStr(temp);
|
||||||
|
|
||||||
// Line Number
|
// Line Number
|
||||||
entry->mLineNumber = MSG_ReadInt ( msg );
|
entry->mLineNumber = msg->ReadInt ( );
|
||||||
|
|
||||||
// Add to list
|
// Add to list
|
||||||
mCallstack.Append ( entry );
|
mCallstack.Append ( entry );
|
||||||
|
@ -278,31 +353,31 @@ Handle the message DBMSG_INSPECTTHREADS being sent from the server. This messag
|
||||||
is handled by adding the list of threads to a list for later lookup.
|
is handled by adding the list of threads to a list for later lookup.
|
||||||
================
|
================
|
||||||
*/
|
*/
|
||||||
void rvDebuggerClient::HandleInspectThreads ( msg_t* msg )
|
void rvDebuggerClient::HandleInspectThreads ( idBitMsg* msg )
|
||||||
{
|
{
|
||||||
int count;
|
int count;
|
||||||
|
|
||||||
ClearThreads ( );
|
ClearThreads ( );
|
||||||
|
|
||||||
// Loop over the number of threads in the message
|
// Loop over the number of threads in the message
|
||||||
for ( count = (short)MSG_ReadShort ( msg ) ; count > 0; count -- )
|
for ( count = (short)msg->ReadShort ( ) ; count > 0; count -- )
|
||||||
{
|
{
|
||||||
rvDebuggerThread* entry = new rvDebuggerThread;
|
rvDebuggerThread* entry = new rvDebuggerThread;
|
||||||
|
|
||||||
char temp[1024];
|
char temp[1024];
|
||||||
|
|
||||||
// Thread name
|
// Thread name
|
||||||
MSG_ReadString ( msg, temp, 1024 );
|
msg->ReadString ( temp, 1024 );
|
||||||
entry->mName = temp;
|
entry->mName = temp;
|
||||||
|
|
||||||
// Thread ID
|
// Thread ID
|
||||||
entry->mID = MSG_ReadInt ( msg );
|
entry->mID = msg->ReadInt ( );
|
||||||
|
|
||||||
// Thread state
|
// Thread state
|
||||||
entry->mCurrent = MSG_ReadBits ( msg, 1 ) ? true : false;
|
entry->mCurrent = msg->ReadBits ( 1 ) ? true : false;
|
||||||
entry->mDoneProcessing = MSG_ReadBits ( msg, 1 ) ? true : false;
|
entry->mDoneProcessing = msg->ReadBits ( 1 ) ? true : false;
|
||||||
entry->mWaiting = MSG_ReadBits ( msg, 1 ) ? true : false;
|
entry->mWaiting = msg->ReadBits ( 1 ) ? true : false;
|
||||||
entry->mDying = MSG_ReadBits ( msg, 1 ) ? true : false;
|
entry->mDying = msg->ReadBits ( 1 ) ? true : false;
|
||||||
|
|
||||||
// Add thread to list
|
// Add thread to list
|
||||||
mThreads.Append ( entry );
|
mThreads.Append ( entry );
|
||||||
|
@ -317,15 +392,15 @@ Handle the message DBMSG_INSPECTVARIABLE being sent from the server. This messa
|
||||||
is handled by adding the inspected variable to a dictionary for later lookup
|
is handled by adding the inspected variable to a dictionary for later lookup
|
||||||
================
|
================
|
||||||
*/
|
*/
|
||||||
void rvDebuggerClient::HandleInspectVariable ( msg_t* msg )
|
void rvDebuggerClient::HandleInspectVariable ( idBitMsg* msg )
|
||||||
{
|
{
|
||||||
char var[1024];
|
char var[1024];
|
||||||
char value[1024];
|
char value[1024];
|
||||||
int callDepth;
|
int callDepth;
|
||||||
|
|
||||||
callDepth = (short)MSG_ReadShort ( msg );
|
callDepth = (short)msg->ReadShort ( );
|
||||||
MSG_ReadString ( msg, var, 1024 );
|
msg->ReadString ( var, 1024 );
|
||||||
MSG_ReadString ( msg, value, 1024 );
|
msg->ReadString ( value, 1024 );
|
||||||
|
|
||||||
mVariables.Set ( va("%d:%s", mCallstack.Num()-callDepth, var), value );
|
mVariables.Set ( va("%d:%s", mCallstack.Num()-callDepth, var), value );
|
||||||
}
|
}
|
||||||
|
@ -422,7 +497,7 @@ Adds a breakpoint to the client and server with the give nfilename and linenumbe
|
||||||
*/
|
*/
|
||||||
int rvDebuggerClient::AddBreakpoint ( const char* filename, int lineNumber, bool onceOnly )
|
int rvDebuggerClient::AddBreakpoint ( const char* filename, int lineNumber, bool onceOnly )
|
||||||
{
|
{
|
||||||
int index = mBreakpoints.Append ( new rvDebuggerBreakpoint ( filename, lineNumber ) );
|
int index = mBreakpoints.Append ( new rvDebuggerBreakpoint ( filename, lineNumber, -1, onceOnly ) );
|
||||||
|
|
||||||
SendAddBreakpoint ( *mBreakpoints[index] );
|
SendAddBreakpoint ( *mBreakpoints[index] );
|
||||||
|
|
||||||
|
@ -463,13 +538,14 @@ Send a message with no data to the debugger server
|
||||||
*/
|
*/
|
||||||
void rvDebuggerClient::SendMessage ( EDebuggerMessage dbmsg )
|
void rvDebuggerClient::SendMessage ( EDebuggerMessage dbmsg )
|
||||||
{
|
{
|
||||||
msg_t msg;
|
idBitMsg msg;
|
||||||
byte buffer[MAX_MSGLEN];
|
byte buffer[MAX_MSGLEN];
|
||||||
|
|
||||||
MSG_Init( &msg, buffer, sizeof( buffer ) );
|
msg.Init ( buffer, sizeof( buffer ) );
|
||||||
MSG_WriteShort ( &msg, (int)dbmsg );
|
msg.BeginWriting ( );
|
||||||
|
msg.WriteShort ( (short)dbmsg );
|
||||||
|
|
||||||
SendPacket ( msg.data, msg.cursize );
|
SendPacket ( msg.GetData(), msg.GetSize() );
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -502,9 +578,9 @@ rvDebuggerClient::SendAddBreakpoint
|
||||||
Send an individual breakpoint over to the debugger server
|
Send an individual breakpoint over to the debugger server
|
||||||
================
|
================
|
||||||
*/
|
*/
|
||||||
void rvDebuggerClient::SendAddBreakpoint ( rvDebuggerBreakpoint& bp, bool onceOnly )
|
void rvDebuggerClient::SendAddBreakpoint ( rvDebuggerBreakpoint& bp )
|
||||||
{
|
{
|
||||||
msg_t msg;
|
idBitMsg msg;
|
||||||
byte buffer[MAX_MSGLEN];
|
byte buffer[MAX_MSGLEN];
|
||||||
|
|
||||||
if ( !mConnected )
|
if ( !mConnected )
|
||||||
|
@ -512,14 +588,15 @@ void rvDebuggerClient::SendAddBreakpoint ( rvDebuggerBreakpoint& bp, bool onceOn
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
MSG_Init( &msg, buffer, sizeof( buffer ) );
|
msg.Init( buffer, sizeof( buffer ) );
|
||||||
MSG_WriteShort ( &msg, (int)DBMSG_ADDBREAKPOINT );
|
msg.BeginWriting();
|
||||||
MSG_WriteBits ( &msg, onceOnly?1:0, 1 );
|
msg.WriteShort ( (short)DBMSG_ADDBREAKPOINT );
|
||||||
MSG_WriteInt ( &msg, (unsigned long) bp.GetLineNumber ( ) );
|
msg.WriteBits ( bp.GetOnceOnly() ? 1 : 0, 1 );
|
||||||
MSG_WriteInt ( &msg, bp.GetID ( ) );
|
msg.WriteInt ( (unsigned long) bp.GetLineNumber ( ) );
|
||||||
MSG_WriteString ( &msg, bp.GetFilename() );
|
msg.WriteInt ( bp.GetID ( ) );
|
||||||
|
msg.WriteString ( bp.GetFilename() ); // FIXME: this implies make7bit ?!
|
||||||
|
|
||||||
SendPacket ( msg.data, msg.cursize );
|
SendPacket ( msg.GetData(), msg.GetSize() );
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -531,7 +608,7 @@ Sends a remove breakpoint message to the debugger server
|
||||||
*/
|
*/
|
||||||
void rvDebuggerClient::SendRemoveBreakpoint ( rvDebuggerBreakpoint& bp )
|
void rvDebuggerClient::SendRemoveBreakpoint ( rvDebuggerBreakpoint& bp )
|
||||||
{
|
{
|
||||||
msg_t msg;
|
idBitMsg msg;
|
||||||
byte buffer[MAX_MSGLEN];
|
byte buffer[MAX_MSGLEN];
|
||||||
|
|
||||||
if ( !mConnected )
|
if ( !mConnected )
|
||||||
|
@ -539,11 +616,12 @@ void rvDebuggerClient::SendRemoveBreakpoint ( rvDebuggerBreakpoint& bp )
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
MSG_Init( &msg, buffer, sizeof( buffer ) );
|
msg.Init ( buffer, sizeof( buffer ) );
|
||||||
MSG_WriteShort ( &msg, (int)DBMSG_REMOVEBREAKPOINT );
|
msg.BeginWriting( );
|
||||||
MSG_WriteInt ( &msg, bp.GetID() );
|
msg.WriteShort ( (short)DBMSG_REMOVEBREAKPOINT );
|
||||||
|
msg.WriteInt ( bp.GetID() );
|
||||||
|
|
||||||
SendPacket ( msg.data, msg.cursize );
|
SendPacket ( msg.GetData(), msg.GetSize() );
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -583,3 +661,25 @@ void rvDebuggerClient::ClearThreads ( void )
|
||||||
|
|
||||||
mThreads.Clear ( );
|
mThreads.Clear ( );
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
|
================
|
||||||
|
rvDebuggerClient::SendCommand
|
||||||
|
================
|
||||||
|
*/
|
||||||
|
void rvDebuggerClient::SendCommand( const char *cmdStr )
|
||||||
|
{
|
||||||
|
idBitMsg msg;
|
||||||
|
byte buffer[MAX_MSGLEN];
|
||||||
|
|
||||||
|
if ( !mConnected ) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
msg.Init( buffer, sizeof( buffer ) );
|
||||||
|
msg.BeginWriting( );
|
||||||
|
msg.WriteShort( ( short ) DBMSG_EXECCOMMAND );
|
||||||
|
msg.WriteString( cmdStr ); // FIXME: this implies make7bit ?!
|
||||||
|
|
||||||
|
SendPacket( msg.GetData( ), msg.GetSize( ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -28,6 +28,9 @@ If you have questions concerning this license or the applicable additional terms
|
||||||
#ifndef DEBUGGERCLIENT_H_
|
#ifndef DEBUGGERCLIENT_H_
|
||||||
#define DEBUGGERCLIENT_H_
|
#define DEBUGGERCLIENT_H_
|
||||||
|
|
||||||
|
#include "DebuggerBreakpoint.h"
|
||||||
|
#include "idlib/containers/StrList.h"
|
||||||
|
|
||||||
class rvDebuggerCallstack
|
class rvDebuggerCallstack
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -49,9 +52,6 @@ public:
|
||||||
bool mDoneProcessing;
|
bool mDoneProcessing;
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifndef DEBUGGERBREAKPOINT_H_
|
|
||||||
#include "DebuggerBreakpoint.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
typedef idList<rvDebuggerCallstack*> rvDebuggerCallstackList;
|
typedef idList<rvDebuggerCallstack*> rvDebuggerCallstackList;
|
||||||
typedef idList<rvDebuggerThread*> rvDebuggerThreadList;
|
typedef idList<rvDebuggerThread*> rvDebuggerThreadList;
|
||||||
|
@ -75,19 +75,23 @@ public:
|
||||||
int GetActiveBreakpointID ( void );
|
int GetActiveBreakpointID ( void );
|
||||||
const char* GetBreakFilename ( void );
|
const char* GetBreakFilename ( void );
|
||||||
int GetBreakLineNumber ( void );
|
int GetBreakLineNumber ( void );
|
||||||
|
idProgram* GetBreakProgram ( void );
|
||||||
rvDebuggerCallstackList& GetCallstack ( void );
|
rvDebuggerCallstackList& GetCallstack ( void );
|
||||||
rvDebuggerThreadList& GetThreads ( void );
|
rvDebuggerThreadList& GetThreads ( void );
|
||||||
const char* GetVariableValue ( const char* name, int stackDepth );
|
const char* GetVariableValue ( const char* name, int stackDepth );
|
||||||
|
idStrList& GetServerScripts ( void );
|
||||||
|
|
||||||
void InspectVariable ( const char* name, int callstackDepth );
|
void InspectVariable ( const char* name, int callstackDepth );
|
||||||
|
void InspectScripts ( void );
|
||||||
void Break ( void );
|
void Break ( void );
|
||||||
void Resume ( void );
|
void Resume ( void );
|
||||||
void StepInto ( void );
|
void StepInto ( void );
|
||||||
void StepOver ( void );
|
void StepOver ( void );
|
||||||
|
|
||||||
|
void SendCommand ( const char* cmdStr );
|
||||||
|
|
||||||
// Breakpoints
|
// Breakpoints
|
||||||
int AddBreakpoint ( const char* filename, int lineNumber, bool onceOnly = false );
|
int AddBreakpoint ( const char* filename, int lineNumber, bool onceOnly = false);
|
||||||
bool RemoveBreakpoint ( int bpID );
|
bool RemoveBreakpoint ( int bpID );
|
||||||
void ClearBreakpoints ( void );
|
void ClearBreakpoints ( void );
|
||||||
int GetBreakpointCount ( void );
|
int GetBreakpointCount ( void );
|
||||||
|
@ -98,7 +102,7 @@ protected:
|
||||||
|
|
||||||
void SendMessage ( EDebuggerMessage dbmsg );
|
void SendMessage ( EDebuggerMessage dbmsg );
|
||||||
void SendBreakpoints ( void );
|
void SendBreakpoints ( void );
|
||||||
void SendAddBreakpoint ( rvDebuggerBreakpoint& bp, bool onceOnly = false );
|
void SendAddBreakpoint ( rvDebuggerBreakpoint& bp );
|
||||||
void SendRemoveBreakpoint ( rvDebuggerBreakpoint& bp );
|
void SendRemoveBreakpoint ( rvDebuggerBreakpoint& bp );
|
||||||
void SendPacket ( void* data, int datasize );
|
void SendPacket ( void* data, int datasize );
|
||||||
|
|
||||||
|
@ -119,6 +123,8 @@ protected:
|
||||||
|
|
||||||
EDebuggerMessage mWaitFor;
|
EDebuggerMessage mWaitFor;
|
||||||
|
|
||||||
|
idStrList mServerScripts;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
void ClearCallstack ( void );
|
void ClearCallstack ( void );
|
||||||
|
@ -127,10 +133,13 @@ private:
|
||||||
void UpdateWatches ( void );
|
void UpdateWatches ( void );
|
||||||
|
|
||||||
// Network message handlers
|
// Network message handlers
|
||||||
void HandleBreak ( msg_t* msg );
|
void HandleBreak ( idBitMsg* msg );
|
||||||
void HandleInspectCallstack ( msg_t* msg );
|
void HandleInspectScripts ( idBitMsg* msg );
|
||||||
void HandleInspectThreads ( msg_t* msg );
|
void HandleInspectCallstack ( idBitMsg* msg );
|
||||||
void HandleInspectVariable ( msg_t* msg );
|
void HandleInspectThreads ( idBitMsg* msg );
|
||||||
|
void HandleInspectVariable ( idBitMsg* msg );
|
||||||
|
void HandleGameDLLHandle ( idBitMsg* msg );
|
||||||
|
void HandleRemoveBreakpoint ( idBitMsg* msg );
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -286,4 +295,14 @@ ID_INLINE void rvDebuggerClient::SendPacket ( void* data, int size )
|
||||||
mPort.SendPacket ( mServerAdr, data, size );
|
mPort.SendPacket ( mServerAdr, data, size );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
================
|
||||||
|
rvDebuggerClient::GetServerScripts
|
||||||
|
================
|
||||||
|
*/
|
||||||
|
ID_INLINE idStrList& rvDebuggerClient::GetServerScripts( void )
|
||||||
|
{
|
||||||
|
return mServerScripts;
|
||||||
|
}
|
||||||
#endif // DEBUGGERCLIENT_H_
|
#endif // DEBUGGERCLIENT_H_
|
||||||
|
|
|
@ -53,7 +53,7 @@ Launch the dialog
|
||||||
*/
|
*/
|
||||||
bool rvDebuggerFindDlg::DoModal ( rvDebuggerWindow* parent )
|
bool rvDebuggerFindDlg::DoModal ( rvDebuggerWindow* parent )
|
||||||
{
|
{
|
||||||
if ( DialogBoxParam ( parent->GetInstance(), MAKEINTRESOURCE(IDD_DBG_FIND), parent->GetWindow(), DlgProc, (LONG)this ) )
|
if ( DialogBoxParam ( parent->GetInstance(), MAKEINTRESOURCE(IDD_DBG_FIND), parent->GetWindow(), DlgProc, (LPARAM)this ) )
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -70,7 +70,7 @@ Dialog Procedure for the find dialog
|
||||||
*/
|
*/
|
||||||
INT_PTR CALLBACK rvDebuggerFindDlg::DlgProc ( HWND wnd, UINT msg, WPARAM wparam, LPARAM lparam )
|
INT_PTR CALLBACK rvDebuggerFindDlg::DlgProc ( HWND wnd, UINT msg, WPARAM wparam, LPARAM lparam )
|
||||||
{
|
{
|
||||||
rvDebuggerFindDlg* dlg = (rvDebuggerFindDlg*) GetWindowLong ( wnd, GWL_USERDATA );
|
rvDebuggerFindDlg* dlg = (rvDebuggerFindDlg*) GetWindowLongPtr ( wnd, GWLP_USERDATA);
|
||||||
|
|
||||||
switch ( msg )
|
switch ( msg )
|
||||||
{
|
{
|
||||||
|
@ -80,7 +80,8 @@ INT_PTR CALLBACK rvDebuggerFindDlg::DlgProc ( HWND wnd, UINT msg, WPARAM wparam,
|
||||||
|
|
||||||
case WM_INITDIALOG:
|
case WM_INITDIALOG:
|
||||||
dlg = (rvDebuggerFindDlg*) lparam;
|
dlg = (rvDebuggerFindDlg*) lparam;
|
||||||
SetWindowLong ( wnd, GWL_USERDATA, (LONG) dlg );
|
|
||||||
|
SetWindowLongPtr ( wnd, GWLP_USERDATA, (LONG_PTR) dlg );
|
||||||
dlg->mWnd = wnd;
|
dlg->mWnd = wnd;
|
||||||
SetWindowText ( GetDlgItem ( dlg->mWnd, IDC_DBG_FIND ), dlg->mFindText );
|
SetWindowText ( GetDlgItem ( dlg->mWnd, IDC_DBG_FIND ), dlg->mFindText );
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
|
@ -46,6 +46,8 @@ enum EDebuggerMessage
|
||||||
DBMSG_INSPECTTHREADS,
|
DBMSG_INSPECTTHREADS,
|
||||||
DBMSG_STEPOVER,
|
DBMSG_STEPOVER,
|
||||||
DBMSG_STEPINTO,
|
DBMSG_STEPINTO,
|
||||||
|
DBMSG_INSPECTSCRIPTS,
|
||||||
|
DBMSG_EXECCOMMAND
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // DEBUGGER_MESSAGES_H_
|
#endif // DEBUGGER_MESSAGES_H_
|
|
@ -55,7 +55,7 @@ bool rvDebuggerQuickWatchDlg::DoModal ( rvDebuggerWindow* window, int callstackD
|
||||||
mDebuggerWindow = window;
|
mDebuggerWindow = window;
|
||||||
mVariable = variable?variable:"";
|
mVariable = variable?variable:"";
|
||||||
|
|
||||||
DialogBoxParam ( window->GetInstance(), MAKEINTRESOURCE(IDD_DBG_QUICKWATCH), window->GetWindow(), DlgProc, (LONG)this );
|
DialogBoxParam ( window->GetInstance(), MAKEINTRESOURCE(IDD_DBG_QUICKWATCH), window->GetWindow(), DlgProc, (LPARAM)this );
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -69,7 +69,7 @@ Dialog Procedure for the quick watch dialog
|
||||||
*/
|
*/
|
||||||
INT_PTR CALLBACK rvDebuggerQuickWatchDlg::DlgProc ( HWND wnd, UINT msg, WPARAM wparam, LPARAM lparam )
|
INT_PTR CALLBACK rvDebuggerQuickWatchDlg::DlgProc ( HWND wnd, UINT msg, WPARAM wparam, LPARAM lparam )
|
||||||
{
|
{
|
||||||
rvDebuggerQuickWatchDlg* dlg = (rvDebuggerQuickWatchDlg*) GetWindowLong ( wnd, GWL_USERDATA );
|
rvDebuggerQuickWatchDlg* dlg = (rvDebuggerQuickWatchDlg*) GetWindowLongPtr ( wnd, GWLP_USERDATA);
|
||||||
|
|
||||||
switch ( msg )
|
switch ( msg )
|
||||||
{
|
{
|
||||||
|
@ -128,7 +128,7 @@ INT_PTR CALLBACK rvDebuggerQuickWatchDlg::DlgProc ( HWND wnd, UINT msg, WPARAM w
|
||||||
|
|
||||||
// Attach the dialog class pointer to the window
|
// Attach the dialog class pointer to the window
|
||||||
dlg = (rvDebuggerQuickWatchDlg*) lparam;
|
dlg = (rvDebuggerQuickWatchDlg*) lparam;
|
||||||
SetWindowLong ( wnd, GWL_USERDATA, lparam );
|
SetWindowLongPtr ( wnd, GWLP_USERDATA, lparam );
|
||||||
dlg->mWnd = wnd;
|
dlg->mWnd = wnd;
|
||||||
|
|
||||||
GetClientRect ( wnd, &client );
|
GetClientRect ( wnd, &client );
|
||||||
|
|
|
@ -26,12 +26,14 @@ If you have questions concerning this license or the applicable additional terms
|
||||||
===========================================================================
|
===========================================================================
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#if defined( ID_ALLOW_TOOLS )
|
||||||
#include "tools/edit_gui_common.h"
|
#include "tools/edit_gui_common.h"
|
||||||
|
|
||||||
|
|
||||||
#include "DebuggerApp.h"
|
#include "DebuggerApp.h"
|
||||||
|
#else
|
||||||
|
#include "debugger_common.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "DebuggerScript.h"
|
#include "DebuggerScript.h"
|
||||||
#include "../../game/script/Script_Program.h"
|
|
||||||
#include "../../ui/Window.h"
|
#include "../../ui/Window.h"
|
||||||
#include "../../ui/UserInterfaceLocal.h"
|
#include "../../ui/UserInterfaceLocal.h"
|
||||||
|
|
||||||
|
@ -57,6 +59,7 @@ rvDebuggerScript::~rvDebuggerScript ( void )
|
||||||
Unload ( );
|
Unload ( );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
================
|
================
|
||||||
rvDebuggerScript::Unload
|
rvDebuggerScript::Unload
|
||||||
|
@ -72,10 +75,6 @@ void rvDebuggerScript::Unload ( void )
|
||||||
{
|
{
|
||||||
delete mInterface;
|
delete mInterface;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
delete mProgram;
|
|
||||||
}
|
|
||||||
|
|
||||||
mContents = NULL;
|
mContents = NULL;
|
||||||
mProgram = NULL;
|
mProgram = NULL;
|
||||||
|
@ -116,60 +115,7 @@ bool rvDebuggerScript::Load ( const char* filename )
|
||||||
|
|
||||||
// Cleanup
|
// Cleanup
|
||||||
fileSystem->FreeFile ( buffer );
|
fileSystem->FreeFile ( buffer );
|
||||||
|
|
||||||
// Now compile the script so we can tell what a valid line is, etc.. If its
|
|
||||||
// a gui file then we need to parse it using the userinterface system rather
|
|
||||||
// than the normal script compiler.
|
|
||||||
try
|
|
||||||
{
|
|
||||||
// Parse the script using the script compiler
|
|
||||||
mProgram = new idProgram;
|
|
||||||
mProgram->BeginCompilation ( );
|
|
||||||
mProgram->CompileFile ( SCRIPT_DEFAULT );
|
|
||||||
|
|
||||||
//BSM Nerve: Loads a game specific main script file
|
|
||||||
idStr gamedir = cvarSystem->GetCVarString( "fs_game" );
|
|
||||||
if(gamedir.Length() > 0) {
|
|
||||||
|
|
||||||
idStr scriptFile = va("script/%s_main.script", gamedir.c_str());
|
|
||||||
if(fileSystem->ReadFile(scriptFile.c_str(), NULL) > 0) {
|
|
||||||
mProgram.CompileFile(scriptFile.c_str());
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// Make sure the file isnt already compiled before trying to compile it again
|
|
||||||
for ( int f = mProgram->NumFilenames() - 1; f >= 0; f -- )
|
|
||||||
{
|
|
||||||
idStr qpath;
|
|
||||||
qpath = fileSystem->OSPathToRelativePath ( mProgram->GetFilename ( f ) );
|
|
||||||
qpath.BackSlashesToSlashes ( );
|
|
||||||
if ( !qpath.Cmp ( filename ) )
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( f < 0 )
|
|
||||||
{
|
|
||||||
mProgram->CompileText ( filename, mContents, false );
|
|
||||||
}
|
|
||||||
|
|
||||||
mProgram->FinishCompilation ( );
|
|
||||||
}
|
|
||||||
catch ( idException& )
|
|
||||||
{
|
|
||||||
// Failed to parse the script so fail to load the file
|
|
||||||
delete mProgram;
|
|
||||||
mProgram = NULL;
|
|
||||||
delete[] mContents;
|
|
||||||
mContents = NULL;
|
|
||||||
|
|
||||||
// TODO: Should cache the error for the dialog box
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -194,21 +140,8 @@ Determines whether or not the given line number within the script is a valid lin
|
||||||
*/
|
*/
|
||||||
bool rvDebuggerScript::IsLineCode ( int linenumber )
|
bool rvDebuggerScript::IsLineCode ( int linenumber )
|
||||||
{
|
{
|
||||||
int i;
|
//we let server decide.
|
||||||
|
return true;
|
||||||
assert ( mProgram );
|
|
||||||
|
|
||||||
// Run through all the statements in the program and see if any match the
|
|
||||||
// linenumber that we are checking.
|
|
||||||
for ( i = 0; i < mProgram->NumStatements ( ); i ++ )
|
|
||||||
{
|
|
||||||
if ( mProgram->GetStatement ( i ).linenumber == linenumber )
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -43,21 +43,22 @@ public:
|
||||||
|
|
||||||
const char* GetFilename ( void );
|
const char* GetFilename ( void );
|
||||||
const char* GetContents ( void );
|
const char* GetContents ( void );
|
||||||
|
idProgram* GetProgram ( void );
|
||||||
|
#if 0// Test code
|
||||||
idProgram& GetProgram ( void );
|
idProgram& GetProgram ( void );
|
||||||
|
#endif
|
||||||
|
|
||||||
bool IsLineCode ( int linenumber );
|
bool IsLineCode ( int linenumber );
|
||||||
bool IsFileModified ( bool updateTime = false );
|
bool IsFileModified ( bool updateTime = false );
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
void Unload ( void );
|
void Unload ( void );
|
||||||
|
|
||||||
idProgram* mProgram;
|
idProgram* mProgram;
|
||||||
idUserInterfaceLocal* mInterface;
|
idUserInterfaceLocal* mInterface;
|
||||||
char* mContents;
|
char* mContents;
|
||||||
idStr mFilename;
|
idStr mFilename;
|
||||||
ID_TIME_T mModifiedTime;
|
ID_TIME_T mModifiedTime;
|
||||||
};
|
};
|
||||||
|
|
||||||
ID_INLINE const char* rvDebuggerScript::GetFilename ( void )
|
ID_INLINE const char* rvDebuggerScript::GetFilename ( void )
|
||||||
|
@ -70,9 +71,10 @@ ID_INLINE const char* rvDebuggerScript::GetContents ( void )
|
||||||
return mContents?mContents:"";
|
return mContents?mContents:"";
|
||||||
}
|
}
|
||||||
|
|
||||||
ID_INLINE idProgram& rvDebuggerScript::GetProgram ( void )
|
ID_INLINE idProgram* rvDebuggerScript::GetProgram ( void )
|
||||||
{
|
{
|
||||||
return *mProgram;
|
return mProgram;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#endif // DEBUGGERSCRIPT_H_
|
#endif // DEBUGGERSCRIPT_H_
|
|
@ -3,6 +3,8 @@
|
||||||
|
|
||||||
Doom 3 GPL Source Code
|
Doom 3 GPL Source Code
|
||||||
Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
|
Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
|
||||||
|
Copyright (C) 1999-2011 Raven Software
|
||||||
|
Copyright (C) 2021 Harrie van Ginneken
|
||||||
|
|
||||||
This file is part of the Doom 3 GPL Source Code ("Doom 3 Source Code").
|
This file is part of the Doom 3 GPL Source Code ("Doom 3 Source Code").
|
||||||
|
|
||||||
|
@ -26,17 +28,16 @@ If you have questions concerning this license or the applicable additional terms
|
||||||
===========================================================================
|
===========================================================================
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#if defined( ID_ALLOW_TOOLS )
|
||||||
#include "tools/edit_gui_common.h"
|
#include "tools/edit_gui_common.h"
|
||||||
|
|
||||||
|
|
||||||
#include "../../game/gamesys/Event.h"
|
|
||||||
#include "../../game/gamesys/Class.h"
|
|
||||||
#include "../../game/script/Script_Program.h"
|
|
||||||
#include "../../game/script/Script_Interpreter.h"
|
|
||||||
#include "../../game/script/Script_Thread.h"
|
|
||||||
#include "../../game/script/Script_Compiler.h"
|
|
||||||
#include "../../framework/sync/Msg.h"
|
|
||||||
#include "DebuggerApp.h"
|
#include "DebuggerApp.h"
|
||||||
|
#else
|
||||||
|
#include "debugger_common.h"
|
||||||
|
// we need a lot to be able to list all threads in mars_city1
|
||||||
|
const int MAX_MSGLEN = 8600;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#include "DebuggerServer.h"
|
#include "DebuggerServer.h"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -51,10 +52,17 @@ rvDebuggerServer::rvDebuggerServer ( )
|
||||||
mBreak = false;
|
mBreak = false;
|
||||||
mBreakStepOver = false;
|
mBreakStepOver = false;
|
||||||
mBreakStepInto = false;
|
mBreakStepInto = false;
|
||||||
mGameThread = NULL;
|
mGameThreadBreakCond = NULL;
|
||||||
|
mGameThreadBreakLock = NULL;
|
||||||
mLastStatementLine = -1;
|
mLastStatementLine = -1;
|
||||||
mBreakStepOverFunc1 = NULL;
|
mBreakStepOverFunc1 = NULL;
|
||||||
mBreakStepOverFunc2 = NULL;
|
mBreakStepOverFunc2 = NULL;
|
||||||
|
mBreakInstructionPointer = 0;
|
||||||
|
mBreakInterpreter = NULL;
|
||||||
|
mBreakProgram = NULL;
|
||||||
|
mGameDLLHandle = 0;
|
||||||
|
mBreakStepOverDepth = 0;
|
||||||
|
mCriticalSection = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -82,15 +90,17 @@ bool rvDebuggerServer::Initialize ( void )
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get a copy of the game thread handle so we can suspend the thread on a break
|
// we're using a condition variable to pause the game thread in rbDebuggerServer::Break()
|
||||||
DuplicateHandle ( GetCurrentProcess(), GetCurrentThread ( ), GetCurrentProcess(), &mGameThread, 0, FALSE, DUPLICATE_SAME_ACCESS );
|
// until rvDebuggerServer::Resume() is called (from another thread)
|
||||||
|
mGameThreadBreakCond = SDL_CreateCond();
|
||||||
|
mGameThreadBreakLock = SDL_CreateMutex();
|
||||||
|
|
||||||
// Create a critical section to ensure that the shared thread
|
// Create a critical section to ensure that the shared thread
|
||||||
// variables are protected
|
// variables are protected
|
||||||
InitializeCriticalSection ( &mCriticalSection );
|
mCriticalSection = SDL_CreateMutex();
|
||||||
|
|
||||||
// Server must be running on the local host on port 28980
|
// Server must be running on the local host on port 28980
|
||||||
Sys_StringToNetAdr ( "localhost", &mClientAdr, true );
|
Sys_StringToNetAdr ( com_dbgClientAdr.GetString( ), &mClientAdr, true );
|
||||||
mClientAdr.port = 27981;
|
mClientAdr.port = 27981;
|
||||||
|
|
||||||
// Attempt to let the server know we are here. The server may not be running so this
|
// Attempt to let the server know we are here. The server may not be running so this
|
||||||
|
@ -102,7 +112,7 @@ bool rvDebuggerServer::Initialize ( void )
|
||||||
|
|
||||||
void rvDebuggerServer::OSPathToRelativePath( const char *osPath, idStr &qpath )
|
void rvDebuggerServer::OSPathToRelativePath( const char *osPath, idStr &qpath )
|
||||||
{
|
{
|
||||||
if ( strchr( osPath, ':' ) )
|
if ( strchr( osPath, ':' ) ) // XXX: what about linux?
|
||||||
{
|
{
|
||||||
qpath = fileSystem->OSPathToRelativePath( osPath );
|
qpath = fileSystem->OSPathToRelativePath( osPath );
|
||||||
}
|
}
|
||||||
|
@ -130,8 +140,16 @@ void rvDebuggerServer::Shutdown ( void )
|
||||||
|
|
||||||
mPort.Close();
|
mPort.Close();
|
||||||
|
|
||||||
|
Resume(); // just in case we're still paused
|
||||||
|
|
||||||
// dont need the crit section anymore
|
// dont need the crit section anymore
|
||||||
DeleteCriticalSection ( &mCriticalSection );
|
SDL_DestroyMutex( mCriticalSection );
|
||||||
|
mCriticalSection = NULL;
|
||||||
|
|
||||||
|
SDL_DestroyCond( mGameThreadBreakCond );
|
||||||
|
mGameThreadBreakCond = NULL;
|
||||||
|
SDL_DestroyMutex( mGameThreadBreakLock );
|
||||||
|
mGameThreadBreakLock = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -144,39 +162,46 @@ Process all incoming network messages from the debugger client
|
||||||
bool rvDebuggerServer::ProcessMessages ( void )
|
bool rvDebuggerServer::ProcessMessages ( void )
|
||||||
{
|
{
|
||||||
netadr_t adrFrom;
|
netadr_t adrFrom;
|
||||||
msg_t msg;
|
idBitMsg msg;
|
||||||
byte buffer[MAX_MSGLEN];
|
byte buffer[MAX_MSGLEN];
|
||||||
|
|
||||||
MSG_Init( &msg, buffer, sizeof( buffer ) );
|
|
||||||
|
|
||||||
// Check for pending udp packets on the debugger port
|
// Check for pending udp packets on the debugger port
|
||||||
while ( mPort.GetPacket ( adrFrom, msg.data, msg.cursize, msg.maxsize ) )
|
int msgSize;
|
||||||
|
while ( mPort.GetPacket ( adrFrom, buffer, msgSize, MAX_MSGLEN) )
|
||||||
{
|
{
|
||||||
unsigned short command;
|
short command;
|
||||||
|
msg.Init(buffer, sizeof(buffer));
|
||||||
// Only accept packets from the debugger server for security reasons
|
msg.SetSize(msgSize);
|
||||||
if ( !Sys_CompareNetAdrBase ( adrFrom, mClientAdr ) )
|
msg.BeginReading();
|
||||||
{
|
|
||||||
continue;
|
if ( adrFrom.type != NA_LOOPBACK ) {
|
||||||
|
// Only accept packets from the debugger server for security reasons
|
||||||
|
if ( !Sys_CompareNetAdrBase( adrFrom, mClientAdr ) )
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
command = (unsigned short) MSG_ReadShort ( &msg );
|
command = msg.ReadShort( );
|
||||||
|
|
||||||
switch ( command )
|
switch ( command )
|
||||||
{
|
{
|
||||||
case DBMSG_CONNECT:
|
case DBMSG_CONNECT:
|
||||||
mConnected = true;
|
mConnected = true;
|
||||||
SendMessage ( DBMSG_CONNECTED );
|
SendMessage ( DBMSG_CONNECTED );
|
||||||
|
HandleInspectScripts ( nullptr );
|
||||||
|
com_editors |= EDITOR_DEBUGGER;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case DBMSG_CONNECTED:
|
case DBMSG_CONNECTED:
|
||||||
mConnected = true;
|
mConnected = true;
|
||||||
|
HandleInspectScripts( nullptr );
|
||||||
|
com_editors |= EDITOR_DEBUGGER;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case DBMSG_DISCONNECT:
|
case DBMSG_DISCONNECT:
|
||||||
ClearBreakpoints ( );
|
ClearBreakpoints ( );
|
||||||
Resume ( );
|
Resume ( );
|
||||||
mConnected = false;
|
mConnected = false;
|
||||||
|
com_editors &= ~EDITOR_DEBUGGER;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case DBMSG_ADDBREAKPOINT:
|
case DBMSG_ADDBREAKPOINT:
|
||||||
|
@ -188,7 +213,7 @@ bool rvDebuggerServer::ProcessMessages ( void )
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case DBMSG_RESUME:
|
case DBMSG_RESUME:
|
||||||
Resume ( );
|
HandleResume ( &msg );
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case DBMSG_BREAK:
|
case DBMSG_BREAK:
|
||||||
|
@ -197,11 +222,11 @@ bool rvDebuggerServer::ProcessMessages ( void )
|
||||||
|
|
||||||
case DBMSG_STEPOVER:
|
case DBMSG_STEPOVER:
|
||||||
mBreakStepOver = true;
|
mBreakStepOver = true;
|
||||||
mBreakStepOverDepth = mBreakInterpreter->GetCallstackDepth ( );
|
mBreakStepOverDepth = ((idGameEditExt*) gameEdit)->GetInterpreterCallStackDepth(mBreakInterpreter);
|
||||||
mBreakStepOverFunc1 = mBreakInterpreter->GetCallstack()[mBreakInterpreter->GetCallstackDepth()].f;
|
mBreakStepOverFunc1 = ((idGameEditExt*) gameEdit)->GetInterpreterCallStackFunction(mBreakInterpreter);
|
||||||
if ( mBreakInterpreter->GetCallstackDepth() > 0 )
|
if (mBreakStepOverDepth)
|
||||||
{
|
{
|
||||||
mBreakStepOverFunc2 = mBreakInterpreter->GetCallstack()[mBreakInterpreter->GetCallstackDepth()-1].f;
|
mBreakStepOverFunc2 = ((idGameEditExt*) gameEdit)->GetInterpreterCallStackFunction(mBreakInterpreter,mBreakStepOverDepth - 1);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -226,6 +251,14 @@ bool rvDebuggerServer::ProcessMessages ( void )
|
||||||
case DBMSG_INSPECTTHREADS:
|
case DBMSG_INSPECTTHREADS:
|
||||||
HandleInspectThreads ( &msg );
|
HandleInspectThreads ( &msg );
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case DBMSG_INSPECTSCRIPTS:
|
||||||
|
HandleInspectScripts( &msg );
|
||||||
|
break;
|
||||||
|
|
||||||
|
case DBMSG_EXECCOMMAND:
|
||||||
|
HandleExecCommand( &msg );
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -241,13 +274,14 @@ Send a message with no data to the debugger server.
|
||||||
*/
|
*/
|
||||||
void rvDebuggerServer::SendMessage ( EDebuggerMessage dbmsg )
|
void rvDebuggerServer::SendMessage ( EDebuggerMessage dbmsg )
|
||||||
{
|
{
|
||||||
msg_t msg;
|
idBitMsg msg;
|
||||||
byte buffer[MAX_MSGLEN];
|
byte buffer[MAX_MSGLEN];
|
||||||
|
|
||||||
MSG_Init( &msg, buffer, sizeof( buffer ) );
|
msg.Init( buffer, sizeof( buffer ) );
|
||||||
MSG_WriteShort ( &msg, (int)dbmsg );
|
msg.BeginWriting();
|
||||||
|
msg.WriteShort ( (short)dbmsg );
|
||||||
|
|
||||||
SendPacket ( msg.data, msg.cursize );
|
SendPacket ( msg.GetData(), msg.GetSize() );
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -255,29 +289,44 @@ void rvDebuggerServer::SendMessage ( EDebuggerMessage dbmsg )
|
||||||
rvDebuggerServer::HandleAddBreakpoint
|
rvDebuggerServer::HandleAddBreakpoint
|
||||||
|
|
||||||
Handle the DBMSG_ADDBREAKPOINT message being sent by the debugger client. This
|
Handle the DBMSG_ADDBREAKPOINT message being sent by the debugger client. This
|
||||||
message is handled by adding a new breakpoint to the breakpoint list with the
|
message is handled by first checking if it is valid
|
||||||
|
and is added as a new breakpoint to the breakpoint list with the
|
||||||
data supplied in the message.
|
data supplied in the message.
|
||||||
================
|
================
|
||||||
*/
|
*/
|
||||||
void rvDebuggerServer::HandleAddBreakpoint ( msg_t* msg )
|
void rvDebuggerServer::HandleAddBreakpoint ( idBitMsg* msg )
|
||||||
{
|
{
|
||||||
bool onceOnly = false;
|
bool onceOnly = false;
|
||||||
long lineNumber;
|
long lineNumber;
|
||||||
long id;
|
long id;
|
||||||
char filename[MAX_PATH];
|
char filename[2048]; // DG: randomly chose this size
|
||||||
|
|
||||||
// Read the breakpoint info
|
// Read the breakpoint info
|
||||||
onceOnly = MSG_ReadBits ( msg, 1 ) ? true : false;
|
onceOnly = msg->ReadBits( 1 ) ? true : false;
|
||||||
lineNumber = MSG_ReadInt ( msg );
|
lineNumber = msg->ReadInt ( );
|
||||||
id = MSG_ReadInt ( msg );
|
id = msg->ReadInt ( );
|
||||||
|
|
||||||
MSG_ReadString ( msg, filename, MAX_PATH );
|
msg->ReadString ( filename, sizeof(filename) );
|
||||||
|
|
||||||
// Since breakpoints are used by both threads we need to
|
//check for statement on requested breakpoint location
|
||||||
// protect them with a crit section
|
if (!((idGameEditExt*) gameEdit)->IsLineCode(filename, lineNumber))
|
||||||
EnterCriticalSection ( &mCriticalSection );
|
{
|
||||||
mBreakpoints.Append ( new rvDebuggerBreakpoint ( filename, lineNumber, id ) );
|
idBitMsg msgOut;
|
||||||
LeaveCriticalSection ( &mCriticalSection );
|
byte buffer[MAX_MSGLEN];
|
||||||
|
|
||||||
|
msgOut.Init(buffer, sizeof(buffer));
|
||||||
|
msgOut.BeginWriting();
|
||||||
|
msgOut.WriteShort((short)DBMSG_REMOVEBREAKPOINT);
|
||||||
|
msgOut.WriteInt(lineNumber);
|
||||||
|
msgOut.WriteString(filename);
|
||||||
|
SendPacket(msgOut.GetData(), msgOut.GetSize());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
SDL_LockMutex( mCriticalSection );
|
||||||
|
mBreakpoints.Append ( new rvDebuggerBreakpoint ( filename, lineNumber, id, onceOnly ) );
|
||||||
|
SDL_UnlockMutex( mCriticalSection );
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -289,17 +338,17 @@ message is handled by removing the breakpoint that matches the given id from the
|
||||||
list.
|
list.
|
||||||
================
|
================
|
||||||
*/
|
*/
|
||||||
void rvDebuggerServer::HandleRemoveBreakpoint ( msg_t* msg )
|
void rvDebuggerServer::HandleRemoveBreakpoint ( idBitMsg* msg )
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
int id;
|
int id;
|
||||||
|
|
||||||
// ID that we are to remove
|
// ID that we are to remove
|
||||||
id = MSG_ReadInt ( msg );
|
id = msg->ReadInt ( );
|
||||||
|
|
||||||
// Since breakpoints are used by both threads we need to
|
// Since breakpoints are used by both threads we need to
|
||||||
// protect them with a crit section
|
// protect them with a crit section
|
||||||
EnterCriticalSection ( &mCriticalSection );
|
SDL_LockMutex( mCriticalSection );
|
||||||
|
|
||||||
// Find the breakpoint that matches the given id and remove it from the list
|
// Find the breakpoint that matches the given id and remove it from the list
|
||||||
for ( i = 0; i < mBreakpoints.Num(); i ++ )
|
for ( i = 0; i < mBreakpoints.Num(); i ++ )
|
||||||
|
@ -312,52 +361,21 @@ void rvDebuggerServer::HandleRemoveBreakpoint ( msg_t* msg )
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
LeaveCriticalSection ( &mCriticalSection );
|
SDL_UnlockMutex( mCriticalSection );
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
================
|
================
|
||||||
rvDebuggerServer::MSG_WriteCallstackFunc
|
rvDebuggerServer::HandleResume
|
||||||
|
|
||||||
Writes a single callstack entry to the given message
|
Resume the game thread.
|
||||||
================
|
================
|
||||||
|
|
||||||
*/
|
*/
|
||||||
void rvDebuggerServer::MSG_WriteCallstackFunc ( msg_t* msg, const prstack_t* stack )
|
void rvDebuggerServer::HandleResume(idBitMsg* msg)
|
||||||
{
|
{
|
||||||
const statement_t* st;
|
//Empty msg
|
||||||
const function_t* func;
|
Resume();
|
||||||
|
|
||||||
func = stack->f;
|
|
||||||
|
|
||||||
// If the function is unknown then just fill in with default data.
|
|
||||||
if ( !func )
|
|
||||||
{
|
|
||||||
MSG_WriteString ( msg, "<UNKNOWN>" );
|
|
||||||
MSG_WriteString ( msg, "<UNKNOWN>" );
|
|
||||||
MSG_WriteInt ( msg, 0 );
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
MSG_WriteString ( msg, va("%s( ??? )", func->Name() ) );
|
|
||||||
}
|
|
||||||
|
|
||||||
// Use the calling statement as the filename and linenumber where
|
|
||||||
// the call was made from
|
|
||||||
st = &mBreakProgram->GetStatement ( stack->s );
|
|
||||||
if ( st )
|
|
||||||
{
|
|
||||||
idStr qpath;
|
|
||||||
OSPathToRelativePath(mBreakProgram->GetFilename( st->file ), qpath);
|
|
||||||
qpath.BackSlashesToSlashes ( );
|
|
||||||
MSG_WriteString ( msg, qpath );
|
|
||||||
MSG_WriteInt ( msg, st->linenumber );
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
MSG_WriteString ( msg, "<UNKNOWN>" );
|
|
||||||
MSG_WriteInt ( msg, 0 );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -368,31 +386,18 @@ Handle an incoming inspect callstack message by sending a message
|
||||||
back to the client with the callstack data.
|
back to the client with the callstack data.
|
||||||
================
|
================
|
||||||
*/
|
*/
|
||||||
void rvDebuggerServer::HandleInspectCallstack ( msg_t* in_msg )
|
void rvDebuggerServer::HandleInspectCallstack ( idBitMsg* msg )
|
||||||
{
|
{
|
||||||
msg_t msg;
|
idBitMsg msgOut;
|
||||||
byte buffer[MAX_MSGLEN];
|
byte buffer[MAX_MSGLEN];
|
||||||
int i;
|
|
||||||
prstack_t temp;
|
|
||||||
|
|
||||||
MSG_Init( &msg, buffer, sizeof( buffer ) );
|
msgOut.Init(buffer, sizeof( buffer ) );
|
||||||
MSG_WriteShort ( &msg, (int)DBMSG_INSPECTCALLSTACK );
|
msgOut.BeginWriting();
|
||||||
|
msgOut.WriteShort ( (short)DBMSG_INSPECTCALLSTACK );
|
||||||
|
|
||||||
MSG_WriteShort ( &msg, (int)mBreakInterpreter->GetCallstackDepth ( ) );
|
((idGameEditExt*) gameEdit)->MSG_WriteInterpreterInfo(&msgOut, mBreakInterpreter, mBreakProgram, mBreakInstructionPointer);
|
||||||
|
|
||||||
// write out the current function
|
SendPacket (msgOut.GetData(), msgOut.GetSize() );
|
||||||
temp.f = mBreakInterpreter->GetCurrentFunction ( );
|
|
||||||
temp.s = 0;
|
|
||||||
temp.stackbase = 0;
|
|
||||||
MSG_WriteCallstackFunc ( &msg, &temp );
|
|
||||||
|
|
||||||
// Run through all of the callstack and write each to the msg
|
|
||||||
for ( i = mBreakInterpreter->GetCallstackDepth ( ) - 1; i > 0; i -- )
|
|
||||||
{
|
|
||||||
MSG_WriteCallstackFunc ( &msg, mBreakInterpreter->GetCallstack ( ) + i );
|
|
||||||
}
|
|
||||||
|
|
||||||
SendPacket ( msg.data, msg.cursize );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -402,35 +407,67 @@ rvDebuggerServer::HandleInspectThreads
|
||||||
Send the list of the current threads in the interpreter back to the debugger client
|
Send the list of the current threads in the interpreter back to the debugger client
|
||||||
================
|
================
|
||||||
*/
|
*/
|
||||||
void rvDebuggerServer::HandleInspectThreads ( msg_t* in_msg )
|
void rvDebuggerServer::HandleInspectThreads ( idBitMsg* msg )
|
||||||
{
|
{
|
||||||
msg_t msg;
|
idBitMsg msgOut;
|
||||||
byte buffer[MAX_MSGLEN];
|
byte buffer[MAX_MSGLEN];
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
// Initialize the message
|
// Initialize the message
|
||||||
MSG_Init( &msg, buffer, sizeof( buffer ) );
|
msgOut.Init( buffer, sizeof( buffer ) );
|
||||||
MSG_WriteShort ( &msg, (int)DBMSG_INSPECTTHREADS );
|
msgOut.SetAllowOverflow(true);
|
||||||
|
msgOut.BeginWriting();
|
||||||
|
msgOut.WriteShort ( (short)DBMSG_INSPECTTHREADS );
|
||||||
|
|
||||||
// Write the number of threads to the message
|
// Write the number of threads to the message
|
||||||
MSG_WriteShort ( &msg, (int)idThread::GetThreads().Num() );
|
msgOut.WriteShort ((short)((idGameEditExt*) gameEdit)->GetTotalScriptThreads() );
|
||||||
|
|
||||||
// Loop through all of the threads and write their name and number to the message
|
// Loop through all of the threads and write their name and number to the message
|
||||||
for ( i = 0; i < idThread::GetThreads().Num(); i ++ )
|
for ( i = 0; i < ((idGameEditExt*) gameEdit)->GetTotalScriptThreads(); i ++ )
|
||||||
{
|
{
|
||||||
idThread* thread = idThread::GetThreads()[i];
|
((idGameEditExt*) gameEdit)->MSG_WriteThreadInfo(&msgOut,((idGameEditExt*) gameEdit)->GetThreadByIndex(i), mBreakInterpreter);
|
||||||
|
|
||||||
MSG_WriteString ( &msg, thread->GetThreadName ( ) );
|
|
||||||
MSG_WriteInt ( &msg, thread->GetThreadNum ( ) );
|
|
||||||
|
|
||||||
MSG_WriteBits ( &msg, (int)(thread == mBreakInterpreter->GetThread ( )), 1 );
|
|
||||||
MSG_WriteBits ( &msg, (int)thread->IsDoneProcessing(), 1 );
|
|
||||||
MSG_WriteBits ( &msg, (int)thread->IsWaiting(), 1 );
|
|
||||||
MSG_WriteBits ( &msg, (int)thread->IsDying(), 1 );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Send off the inspect threads packet to the debugger client
|
// Send off the inspect threads packet to the debugger client
|
||||||
SendPacket ( msg.data, msg.cursize );
|
SendPacket (msgOut.GetData(), msgOut.GetSize() );
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
================
|
||||||
|
rvDebuggerServer::HandleExecCommand
|
||||||
|
|
||||||
|
Send the list of the current loaded scripts in the interpreter back to the debugger client
|
||||||
|
================
|
||||||
|
*/
|
||||||
|
void rvDebuggerServer::HandleExecCommand( idBitMsg *msg ) {
|
||||||
|
char cmdStr[2048]; // HvG: randomly chose this size
|
||||||
|
|
||||||
|
msg->ReadString( cmdStr, sizeof( cmdStr ) );
|
||||||
|
cmdSystem->BufferCommandText( CMD_EXEC_APPEND, cmdStr ); // valid command
|
||||||
|
cmdSystem->BufferCommandText( CMD_EXEC_APPEND, "\n" );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
================
|
||||||
|
rvDebuggerServer::HandleInspectScripts
|
||||||
|
|
||||||
|
Send the list of the current loaded scripts in the interpreter back to the debugger client
|
||||||
|
================
|
||||||
|
*/
|
||||||
|
void rvDebuggerServer::HandleInspectScripts( idBitMsg* msg )
|
||||||
|
{
|
||||||
|
idBitMsg msgOut;
|
||||||
|
byte buffer[MAX_MSGLEN];
|
||||||
|
|
||||||
|
// Initialize the message
|
||||||
|
msgOut.Init(buffer, sizeof(buffer));
|
||||||
|
msgOut.BeginWriting();
|
||||||
|
msgOut.WriteShort((short)DBMSG_INSPECTSCRIPTS);
|
||||||
|
|
||||||
|
((idGameEditExt*) gameEdit)->MSG_WriteScriptList( &msgOut );
|
||||||
|
|
||||||
|
SendPacket(msgOut.GetData(), msgOut.GetSize());
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -440,7 +477,7 @@ rvDebuggerServer::HandleInspectVariable
|
||||||
Respondes to a request from the debugger client to inspect the value of a given variable
|
Respondes to a request from the debugger client to inspect the value of a given variable
|
||||||
================
|
================
|
||||||
*/
|
*/
|
||||||
void rvDebuggerServer::HandleInspectVariable ( msg_t* in_msg )
|
void rvDebuggerServer::HandleInspectVariable ( idBitMsg* msg )
|
||||||
{
|
{
|
||||||
char varname[256];
|
char varname[256];
|
||||||
int scopeDepth;
|
int scopeDepth;
|
||||||
|
@ -450,28 +487,29 @@ void rvDebuggerServer::HandleInspectVariable ( msg_t* in_msg )
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
scopeDepth = (short)MSG_ReadShort ( in_msg );
|
scopeDepth = (short)msg->ReadShort ( );
|
||||||
MSG_ReadString ( in_msg, varname, 256 );
|
msg->ReadString ( varname, 256 );
|
||||||
|
|
||||||
idStr varvalue;
|
idStr varvalue;
|
||||||
|
|
||||||
msg_t msg;
|
idBitMsg msgOut;
|
||||||
byte buffer[MAX_MSGLEN];
|
byte buffer[MAX_MSGLEN];
|
||||||
|
|
||||||
// Initialize the message
|
// Initialize the message
|
||||||
MSG_Init( &msg, buffer, sizeof( buffer ) );
|
msgOut.Init( buffer, sizeof( buffer ) );
|
||||||
MSG_WriteShort ( &msg, (int)DBMSG_INSPECTVARIABLE );
|
msgOut.BeginWriting();
|
||||||
|
msgOut.WriteShort ( (short)DBMSG_INSPECTVARIABLE );
|
||||||
|
|
||||||
if ( !mBreakInterpreter->GetRegisterValue ( varname, varvalue, scopeDepth ) )
|
if (!((idGameEditExt*) gameEdit)->GetRegisterValue(mBreakInterpreter, varname, varvalue, scopeDepth ) )
|
||||||
{
|
{
|
||||||
varvalue = "???";
|
varvalue = "???";
|
||||||
}
|
}
|
||||||
|
|
||||||
MSG_WriteShort ( &msg, (short)scopeDepth );
|
msgOut.WriteShort ( (short)scopeDepth );
|
||||||
MSG_WriteString ( &msg, varname );
|
msgOut.WriteString ( varname );
|
||||||
MSG_WriteString ( &msg, varvalue );
|
msgOut.WriteString ( varvalue );
|
||||||
|
|
||||||
SendPacket ( msg.data, msg.cursize );
|
SendPacket (msgOut.GetData(), msgOut.GetSize() );
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -484,7 +522,6 @@ Check to see if any breakpoints have been hit. This includes "break next",
|
||||||
*/
|
*/
|
||||||
void rvDebuggerServer::CheckBreakpoints ( idInterpreter* interpreter, idProgram* program, int instructionPointer )
|
void rvDebuggerServer::CheckBreakpoints ( idInterpreter* interpreter, idProgram* program, int instructionPointer )
|
||||||
{
|
{
|
||||||
const statement_t* st;
|
|
||||||
const char* filename;
|
const char* filename;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
@ -492,23 +529,24 @@ void rvDebuggerServer::CheckBreakpoints ( idInterpreter* interpreter, idProgram*
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Grab the current statement and the filename that it came from
|
// Grab the current statement and the filename that it came from
|
||||||
st = &program->GetStatement ( instructionPointer );
|
filename = ((idGameEditExt*) gameEdit)->GetFilenameForStatement(program, instructionPointer);
|
||||||
filename = program->GetFilename ( st->file );
|
int linenumber = ((idGameEditExt*) gameEdit)->GetLineNumberForStatement(program, instructionPointer);
|
||||||
|
|
||||||
// Operate on lines, not statements
|
// Operate on lines, not statements
|
||||||
if ( mLastStatementLine == st->linenumber && mLastStatementFile == st->file )
|
if ( mLastStatementLine == linenumber && mLastStatementFile == filename)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Save the last visited line and file so we can prevent
|
// Save the last visited line and file so we can prevent
|
||||||
// double breaks on lines with more than one statement
|
// double breaks on lines with more than one statement
|
||||||
mLastStatementFile = idStr( st->file );
|
mLastStatementFile = idStr(filename);
|
||||||
mLastStatementLine = st->linenumber;
|
mLastStatementLine = linenumber;
|
||||||
|
|
||||||
// Reset stepping when the last function on the callstack is returned from
|
// Reset stepping when the last function on the callstack is returned from
|
||||||
if ( st->op == OP_RETURN && interpreter->GetCallstackDepth ( ) <= 1 )
|
if ( ((idGameEditExt*) gameEdit)->ReturnedFromFunction(program, interpreter,instructionPointer))
|
||||||
{
|
{
|
||||||
mBreakStepOver = false;
|
mBreakStepOver = false;
|
||||||
mBreakStepInto = false;
|
mBreakStepInto = false;
|
||||||
|
@ -517,6 +555,7 @@ void rvDebuggerServer::CheckBreakpoints ( idInterpreter* interpreter, idProgram*
|
||||||
// See if we are supposed to break on the next script line
|
// See if we are supposed to break on the next script line
|
||||||
if ( mBreakNext )
|
if ( mBreakNext )
|
||||||
{
|
{
|
||||||
|
HandleInspectScripts(nullptr);
|
||||||
Break ( interpreter, program, instructionPointer );
|
Break ( interpreter, program, instructionPointer );
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -524,9 +563,8 @@ void rvDebuggerServer::CheckBreakpoints ( idInterpreter* interpreter, idProgram*
|
||||||
// Only break on the same callstack depth and thread as the break over
|
// Only break on the same callstack depth and thread as the break over
|
||||||
if ( mBreakStepOver )
|
if ( mBreakStepOver )
|
||||||
{
|
{
|
||||||
if ( ( interpreter->GetCurrentFunction ( ) == mBreakStepOverFunc1 ||
|
//virtual bool CheckForBreakpointHit(interpreter,function1,function2,depth)
|
||||||
interpreter->GetCurrentFunction ( ) == mBreakStepOverFunc2 )&&
|
if (((idGameEditExt*) gameEdit)->CheckForBreakPointHit(interpreter, mBreakStepOverFunc1, mBreakStepOverFunc2, mBreakStepOverDepth))
|
||||||
( interpreter->GetCallstackDepth ( ) <= mBreakStepOverDepth ) )
|
|
||||||
{
|
{
|
||||||
Break ( interpreter, program, instructionPointer );
|
Break ( interpreter, program, instructionPointer );
|
||||||
return;
|
return;
|
||||||
|
@ -536,6 +574,7 @@ void rvDebuggerServer::CheckBreakpoints ( idInterpreter* interpreter, idProgram*
|
||||||
// See if we are supposed to break on the next line
|
// See if we are supposed to break on the next line
|
||||||
if ( mBreakStepInto )
|
if ( mBreakStepInto )
|
||||||
{
|
{
|
||||||
|
HandleInspectScripts(nullptr);
|
||||||
// Break
|
// Break
|
||||||
Break ( interpreter, program, instructionPointer );
|
Break ( interpreter, program, instructionPointer );
|
||||||
return;
|
return;
|
||||||
|
@ -545,7 +584,7 @@ void rvDebuggerServer::CheckBreakpoints ( idInterpreter* interpreter, idProgram*
|
||||||
OSPathToRelativePath(filename,qpath);
|
OSPathToRelativePath(filename,qpath);
|
||||||
qpath.BackSlashesToSlashes ( );
|
qpath.BackSlashesToSlashes ( );
|
||||||
|
|
||||||
EnterCriticalSection ( &mCriticalSection );
|
SDL_LockMutex( mCriticalSection );
|
||||||
|
|
||||||
// Check all the breakpoints
|
// Check all the breakpoints
|
||||||
for ( i = 0; i < mBreakpoints.Num ( ); i ++ )
|
for ( i = 0; i < mBreakpoints.Num ( ); i ++ )
|
||||||
|
@ -553,30 +592,50 @@ void rvDebuggerServer::CheckBreakpoints ( idInterpreter* interpreter, idProgram*
|
||||||
rvDebuggerBreakpoint* bp = mBreakpoints[i];
|
rvDebuggerBreakpoint* bp = mBreakpoints[i];
|
||||||
|
|
||||||
// Skip if not match of the line number
|
// Skip if not match of the line number
|
||||||
if ( st->linenumber != bp->GetLineNumber ( ) )
|
if ( linenumber != bp->GetLineNumber ( ) )
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Skip if no match of the filename
|
// Skip if no match of the filename
|
||||||
if ( idStr::Icmp ( bp->GetFilename(), qpath ) )
|
if ( idStr::Icmp ( bp->GetFilename(), qpath.c_str() ) )
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Pop out of the critical section so we dont get stuck
|
// DG: onceOnly support
|
||||||
LeaveCriticalSection ( &mCriticalSection );
|
if ( bp->GetOnceOnly() ) {
|
||||||
|
// we'll do the one Break() a few lines below; remove it here while mBreakpoints is unmodified
|
||||||
|
// (it can be modifed from the client while in Break() below)
|
||||||
|
mBreakpoints.RemoveIndex( i );
|
||||||
|
delete bp;
|
||||||
|
|
||||||
|
// also tell client to remove the breakpoint
|
||||||
|
idBitMsg msgOut;
|
||||||
|
byte buffer[MAX_MSGLEN];
|
||||||
|
msgOut.Init( buffer, sizeof( buffer ) );
|
||||||
|
msgOut.BeginWriting();
|
||||||
|
msgOut.WriteShort( (short)DBMSG_REMOVEBREAKPOINT );
|
||||||
|
msgOut.WriteInt( linenumber );
|
||||||
|
msgOut.WriteString( qpath.c_str() );
|
||||||
|
SendPacket( msgOut.GetData(), msgOut.GetSize() );
|
||||||
|
}
|
||||||
|
// DG end
|
||||||
|
|
||||||
|
// Pop out of the critical section so we dont get stuck
|
||||||
|
SDL_UnlockMutex( mCriticalSection );
|
||||||
|
|
||||||
|
HandleInspectScripts(nullptr);
|
||||||
// We hit a breakpoint, so break
|
// We hit a breakpoint, so break
|
||||||
Break ( interpreter, program, instructionPointer );
|
Break ( interpreter, program, instructionPointer );
|
||||||
|
|
||||||
// Back into the critical section since we are going to have to leave it
|
// Back into the critical section since we are going to have to leave it
|
||||||
EnterCriticalSection ( &mCriticalSection );
|
SDL_LockMutex( mCriticalSection );
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
LeaveCriticalSection ( &mCriticalSection );
|
SDL_UnlockMutex( mCriticalSection );
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -589,9 +648,8 @@ the game has been halted
|
||||||
*/
|
*/
|
||||||
void rvDebuggerServer::Break ( idInterpreter* interpreter, idProgram* program, int instructionPointer )
|
void rvDebuggerServer::Break ( idInterpreter* interpreter, idProgram* program, int instructionPointer )
|
||||||
{
|
{
|
||||||
msg_t msg;
|
idBitMsg msg;
|
||||||
byte buffer[MAX_MSGLEN];
|
byte buffer[MAX_MSGLEN];
|
||||||
const statement_t* st;
|
|
||||||
const char* filename;
|
const char* filename;
|
||||||
|
|
||||||
// Clear all the break types
|
// Clear all the break types
|
||||||
|
@ -600,12 +658,10 @@ void rvDebuggerServer::Break ( idInterpreter* interpreter, idProgram* program, i
|
||||||
mBreakNext = false;
|
mBreakNext = false;
|
||||||
|
|
||||||
// Grab the current statement and the filename that it came from
|
// Grab the current statement and the filename that it came from
|
||||||
st = &program->GetStatement ( instructionPointer );
|
filename = ((idGameEditExt*) gameEdit)->GetFilenameForStatement(program,instructionPointer);
|
||||||
filename = program->GetFilename ( st->file );
|
int linenumber = ((idGameEditExt*) gameEdit)->GetLineNumberForStatement(program, instructionPointer);
|
||||||
|
idStr fileStr = filename;
|
||||||
idStr qpath;
|
fileStr.BackSlashesToSlashes();
|
||||||
OSPathToRelativePath(filename, qpath);
|
|
||||||
qpath.BackSlashesToSlashes ( );
|
|
||||||
|
|
||||||
// Give the mouse cursor back to the world
|
// Give the mouse cursor back to the world
|
||||||
Sys_GrabMouseCursor( false );
|
Sys_GrabMouseCursor( false );
|
||||||
|
@ -617,19 +673,33 @@ void rvDebuggerServer::Break ( idInterpreter* interpreter, idProgram* program, i
|
||||||
mBreakInstructionPointer = instructionPointer;
|
mBreakInstructionPointer = instructionPointer;
|
||||||
|
|
||||||
// Inform the debugger of the breakpoint hit
|
// Inform the debugger of the breakpoint hit
|
||||||
MSG_Init( &msg, buffer, sizeof( buffer ) );
|
msg.Init( buffer, sizeof( buffer ) );
|
||||||
MSG_WriteShort ( &msg, (int)DBMSG_BREAK );
|
msg.BeginWriting();
|
||||||
MSG_WriteInt ( &msg, st->linenumber );
|
msg.WriteShort ( (short)DBMSG_BREAK );
|
||||||
MSG_WriteString ( &msg, qpath );
|
msg.WriteInt ( linenumber );
|
||||||
SendPacket ( msg.data, msg.cursize );
|
msg.WriteString ( fileStr.c_str() );
|
||||||
|
|
||||||
|
//msg.WriteInt64( (int64_t)mBreakProgram );
|
||||||
|
|
||||||
|
SendPacket ( msg.GetData(), msg.GetSize() );
|
||||||
|
|
||||||
// Suspend the game thread. Since this will be called from within the main game thread
|
// Suspend the game thread. Since this will be called from within the main game thread
|
||||||
// execution wont return until after the thread is resumed
|
// execution wont return until after the thread is resumed
|
||||||
SuspendThread ( mGameThread );
|
// DG: the original code used Win32 SuspendThread() here, but as there is no equivalent
|
||||||
|
// function in SDL and as this is only called within the main game thread anyway,
|
||||||
|
// just use a condition variable to put this thread to sleep until Resume() has set mBreak
|
||||||
|
SDL_LockMutex( mGameThreadBreakLock );
|
||||||
|
while ( mBreak ) {
|
||||||
|
SDL_CondWait( mGameThreadBreakCond, mGameThreadBreakLock );
|
||||||
|
}
|
||||||
|
SDL_UnlockMutex( mGameThreadBreakLock );
|
||||||
|
|
||||||
// Let the debugger client know that we have started back up again
|
// Let the debugger client know that we have started back up again
|
||||||
SendMessage ( DBMSG_RESUMED );
|
SendMessage ( DBMSG_RESUMED );
|
||||||
|
|
||||||
|
// this should be platform specific
|
||||||
|
// TODO: maybe replace with SDL code? or does it not matter if debugger client runs on another machine?
|
||||||
|
#if defined( ID_ALLOW_TOOLS )
|
||||||
// This is to give some time between the keypress that
|
// This is to give some time between the keypress that
|
||||||
// told us to resume and the setforeground window. Otherwise the quake window
|
// told us to resume and the setforeground window. Otherwise the quake window
|
||||||
// would just flash
|
// would just flash
|
||||||
|
@ -640,8 +710,10 @@ void rvDebuggerServer::Break ( idInterpreter* interpreter, idProgram* program, i
|
||||||
SetActiveWindow ( win32.hWnd );
|
SetActiveWindow ( win32.hWnd );
|
||||||
UpdateWindow ( win32.hWnd );
|
UpdateWindow ( win32.hWnd );
|
||||||
SetFocus ( win32.hWnd );
|
SetFocus ( win32.hWnd );
|
||||||
|
#endif
|
||||||
|
|
||||||
// Give the mouse cursor back to the game
|
// Give the mouse cursor back to the game
|
||||||
|
// HVG_Note : there be dragons here. somewhere.
|
||||||
Sys_GrabMouseCursor( true );
|
Sys_GrabMouseCursor( true );
|
||||||
|
|
||||||
// Clear all commands that were generated before we went into suspended mode. This is
|
// Clear all commands that were generated before we went into suspended mode. This is
|
||||||
|
@ -664,10 +736,11 @@ void rvDebuggerServer::Resume ( void )
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
mBreak = false;
|
|
||||||
|
|
||||||
// Start the game thread back up
|
// Start the game thread back up
|
||||||
ResumeThread ( mGameThread );
|
SDL_LockMutex( mGameThreadBreakLock );
|
||||||
|
mBreak = false;
|
||||||
|
SDL_CondSignal( mGameThreadBreakCond);
|
||||||
|
SDL_UnlockMutex( mGameThreadBreakLock );
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -703,12 +776,13 @@ void rvDebuggerServer::Print ( const char* text )
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
msg_t msg;
|
idBitMsg msg;
|
||||||
byte buffer[MAX_MSGLEN];
|
byte buffer[MAX_MSGLEN];
|
||||||
|
|
||||||
MSG_Init( &msg, buffer, sizeof( buffer ) );
|
msg.Init( buffer, sizeof( buffer ) );
|
||||||
MSG_WriteShort ( &msg, (int)DBMSG_PRINT );
|
msg.BeginWriting();
|
||||||
MSG_WriteString ( &msg, text );
|
msg.WriteShort ( (short)DBMSG_PRINT );
|
||||||
|
msg.WriteString ( text );
|
||||||
|
|
||||||
SendPacket ( msg.data, msg.cursize );
|
SendPacket ( msg.GetData(), msg.GetSize() );
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,20 +28,16 @@ If you have questions concerning this license or the applicable additional terms
|
||||||
#ifndef DEBUGGERSERVER_H_
|
#ifndef DEBUGGERSERVER_H_
|
||||||
#define DEBUGGERSERVER_H_
|
#define DEBUGGERSERVER_H_
|
||||||
|
|
||||||
#ifndef DEBUGGERMESSAGES_H_
|
|
||||||
#include "DebuggerMessages.h"
|
#include "DebuggerMessages.h"
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef DEBUGGERBREAKPOINT_H_
|
|
||||||
#include "DebuggerBreakpoint.h"
|
#include "DebuggerBreakpoint.h"
|
||||||
#endif
|
#include "framework/Game.h"
|
||||||
|
#include <SDL.h>
|
||||||
|
|
||||||
#ifndef __GAME_LOCAL_H__
|
|
||||||
#include "../../game/Game.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
class idInterpreter;
|
|
||||||
class idProgram;
|
class function_t;
|
||||||
|
typedef struct prstack_s prstack_t;
|
||||||
|
|
||||||
class rvDebuggerServer
|
class rvDebuggerServer
|
||||||
{
|
{
|
||||||
|
@ -50,31 +46,52 @@ public:
|
||||||
rvDebuggerServer ( );
|
rvDebuggerServer ( );
|
||||||
~rvDebuggerServer ( );
|
~rvDebuggerServer ( );
|
||||||
|
|
||||||
bool Initialize ( void );
|
bool Initialize ( void );
|
||||||
void Shutdown ( void );
|
void Shutdown ( void );
|
||||||
|
|
||||||
bool ProcessMessages ( void );
|
bool ProcessMessages ( void );
|
||||||
|
|
||||||
bool IsConnected ( void );
|
bool IsConnected ( void );
|
||||||
|
|
||||||
void CheckBreakpoints ( idInterpreter* interpreter, idProgram* program, int instructionPointer );
|
void CheckBreakpoints ( idInterpreter *interpreter, idProgram *program, int instructionPointer );
|
||||||
|
|
||||||
void Print ( const char* text );
|
void Print ( const char *text );
|
||||||
|
|
||||||
void OSPathToRelativePath( const char *osPath, idStr &qpath );
|
void OSPathToRelativePath ( const char *osPath, idStr &qpath );
|
||||||
|
|
||||||
protected:
|
bool GameSuspended ( void );
|
||||||
|
private:
|
||||||
|
|
||||||
|
void ClearBreakpoints ( void );
|
||||||
|
|
||||||
|
void Break ( idInterpreter *interpreter, idProgram *program, int instructionPointer );
|
||||||
|
void Resume ( void );
|
||||||
|
|
||||||
|
void SendMessage ( EDebuggerMessage dbmsg );
|
||||||
|
void SendPacket ( void* data, int datasize );
|
||||||
|
|
||||||
|
// Message handlers
|
||||||
|
void HandleAddBreakpoint ( idBitMsg *msg );
|
||||||
|
void HandleRemoveBreakpoint ( idBitMsg *msg );
|
||||||
|
void HandleResume ( idBitMsg *msg );
|
||||||
|
void HandleInspectVariable ( idBitMsg *msg );
|
||||||
|
void HandleInspectCallstack ( idBitMsg *msg );
|
||||||
|
void HandleInspectThreads ( idBitMsg *msg );
|
||||||
|
void HandleInspectScripts ( idBitMsg *msg );
|
||||||
|
void HandleExecCommand ( idBitMsg *msg );
|
||||||
|
////
|
||||||
|
|
||||||
// protected member variables
|
|
||||||
bool mConnected;
|
bool mConnected;
|
||||||
netadr_t mClientAdr;
|
netadr_t mClientAdr;
|
||||||
idPort mPort;
|
idPort mPort;
|
||||||
idList<rvDebuggerBreakpoint*> mBreakpoints;
|
idList<rvDebuggerBreakpoint*> mBreakpoints;
|
||||||
CRITICAL_SECTION mCriticalSection;
|
SDL_mutex* mCriticalSection;
|
||||||
|
|
||||||
HANDLE mGameThread;
|
|
||||||
|
|
||||||
|
SDL_cond* mGameThreadBreakCond;
|
||||||
|
SDL_mutex* mGameThreadBreakLock;
|
||||||
bool mBreak;
|
bool mBreak;
|
||||||
|
|
||||||
bool mBreakNext;
|
bool mBreakNext;
|
||||||
bool mBreakStepOver;
|
bool mBreakStepOver;
|
||||||
bool mBreakStepInto;
|
bool mBreakStepInto;
|
||||||
|
@ -87,27 +104,9 @@ protected:
|
||||||
|
|
||||||
idStr mLastStatementFile;
|
idStr mLastStatementFile;
|
||||||
int mLastStatementLine;
|
int mLastStatementLine;
|
||||||
|
uintptr_t mGameDLLHandle;
|
||||||
|
idStrList mScriptFileList;
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
void ClearBreakpoints ( void );
|
|
||||||
|
|
||||||
void Break ( idInterpreter* interpreter, idProgram* program, int instructionPointer );
|
|
||||||
void Resume ( void );
|
|
||||||
|
|
||||||
void SendMessage ( EDebuggerMessage dbmsg );
|
|
||||||
void SendPacket ( void* data, int datasize );
|
|
||||||
|
|
||||||
// Message handlers
|
|
||||||
void HandleAddBreakpoint ( msg_t* msg );
|
|
||||||
void HandleRemoveBreakpoint ( msg_t* msg );
|
|
||||||
void HandleResume ( msg_t* msg );
|
|
||||||
void HandleInspectVariable ( msg_t* msg );
|
|
||||||
void HandleInspectCallstack ( msg_t* msg );
|
|
||||||
void HandleInspectThreads ( msg_t* msg );
|
|
||||||
|
|
||||||
// MSG helper routines
|
|
||||||
void MSG_WriteCallstackFunc ( msg_t* msg, const prstack_t* stack );
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -125,9 +124,19 @@ ID_INLINE bool rvDebuggerServer::IsConnected ( void )
|
||||||
rvDebuggerServer::SendPacket
|
rvDebuggerServer::SendPacket
|
||||||
================
|
================
|
||||||
*/
|
*/
|
||||||
ID_INLINE void rvDebuggerServer::SendPacket ( void* data, int size )
|
ID_INLINE void rvDebuggerServer::SendPacket ( void *data, int size )
|
||||||
{
|
{
|
||||||
mPort.SendPacket ( mClientAdr, data, size );
|
mPort.SendPacket ( mClientAdr, data, size );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
================
|
||||||
|
rvDebuggerServer::GameSuspended
|
||||||
|
================
|
||||||
|
*/
|
||||||
|
ID_INLINE bool rvDebuggerServer::GameSuspended( void )
|
||||||
|
{
|
||||||
|
return mBreak;
|
||||||
|
}
|
||||||
|
|
||||||
#endif // DEBUGGERSERVER_H_
|
#endif // DEBUGGERSERVER_H_
|
||||||
|
|
|
@ -35,7 +35,7 @@ If you have questions concerning this license or the applicable additional terms
|
||||||
#include "DebuggerQuickWatchDlg.h"
|
#include "DebuggerQuickWatchDlg.h"
|
||||||
#include "DebuggerFindDlg.h"
|
#include "DebuggerFindDlg.h"
|
||||||
|
|
||||||
#define DEBUGGERWINDOWCLASS "QUAKE4_DEBUGGER_WINDOW"
|
#define DEBUGGERWINDOWCLASS "DHEWM3_DEBUGGER_WINDOW"
|
||||||
#define ID_DBG_WINDOWMIN 18900
|
#define ID_DBG_WINDOWMIN 18900
|
||||||
#define ID_DBG_WINDOWMAX 19900
|
#define ID_DBG_WINDOWMAX 19900
|
||||||
|
|
||||||
|
@ -49,6 +49,9 @@ If you have questions concerning this license or the applicable additional terms
|
||||||
#define IDC_DBG_WATCH 31007
|
#define IDC_DBG_WATCH 31007
|
||||||
#define IDC_DBG_THREADS 31008
|
#define IDC_DBG_THREADS 31008
|
||||||
#define IDC_DBG_TOOLBAR 31009
|
#define IDC_DBG_TOOLBAR 31009
|
||||||
|
#define IDC_DBG_SCRIPTLIST 31010
|
||||||
|
#define IDC_DBG_CONSOLEINPUT 31011
|
||||||
|
#define IDC_DBG_BREAKLIST 31012
|
||||||
|
|
||||||
#define ID_DBG_FILE_MRU1 10000
|
#define ID_DBG_FILE_MRU1 10000
|
||||||
|
|
||||||
|
@ -167,7 +170,7 @@ bool rvDebuggerWindow::Create ( HINSTANCE instance )
|
||||||
|
|
||||||
UpdateTitle ( );
|
UpdateTitle ( );
|
||||||
|
|
||||||
Printf ( "Quake 4 Script Debugger v0.1\n\n" );
|
Printf ( "Dhewm3 Script Debugger v1.1\n\n" );
|
||||||
|
|
||||||
ShowWindow ( mWnd, SW_SHOW );
|
ShowWindow ( mWnd, SW_SHOW );
|
||||||
UpdateWindow ( mWnd );
|
UpdateWindow ( mWnd );
|
||||||
|
@ -248,7 +251,7 @@ LRESULT CALLBACK rvDebuggerWindow::ScriptWndProc ( HWND wnd, UINT msg, WPARAM wp
|
||||||
{
|
{
|
||||||
static int lastStart = -1;
|
static int lastStart = -1;
|
||||||
static int lastEnd = -1;
|
static int lastEnd = -1;
|
||||||
rvDebuggerWindow* window = (rvDebuggerWindow*)GetWindowLong ( wnd, GWL_USERDATA );
|
rvDebuggerWindow* window = (rvDebuggerWindow*)GetWindowLongPtr ( wnd, GWLP_USERDATA );
|
||||||
WNDPROC wndproc = window->mOldScriptProc;
|
WNDPROC wndproc = window->mOldScriptProc;
|
||||||
|
|
||||||
switch ( msg )
|
switch ( msg )
|
||||||
|
@ -347,6 +350,23 @@ LRESULT CALLBACK rvDebuggerWindow::ScriptWndProc ( HWND wnd, UINT msg, WPARAM wp
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case WM_SIZE:
|
||||||
|
{
|
||||||
|
float scaling_factor = Win_GetWindowScalingFactor(wnd);
|
||||||
|
int s18 = int(18 * scaling_factor);
|
||||||
|
int s10 = int(10 * scaling_factor);
|
||||||
|
|
||||||
|
RECT rect;
|
||||||
|
window->mMarginSize = window->mZoomScaleDem ? ((long)(s18 * (float)window->mZoomScaleNum / (float)window->mZoomScaleDem)) : s18;
|
||||||
|
|
||||||
|
GetWindowRect(window->mWndToolbar, &rect);
|
||||||
|
MoveWindow(window->mWndMargin, 0, 0, window->mMarginSize, window->mSplitterRect.top - (rect.bottom - rect.top), TRUE);
|
||||||
|
// FIXME: was *2.25, increased for line numbers up to 9999; but neither works particularly well
|
||||||
|
// if DPI scaling is involved, because script code text and linenumbers aren't DPI scaled
|
||||||
|
int lmargin = s18 * 3.5;
|
||||||
|
SendMessage(window->mWndScript, EM_SETMARGINS, EC_LEFTMARGIN | EC_RIGHTMARGIN, MAKELONG(lmargin, s10));
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return CallWindowProc ( wndproc, wnd, msg, wparam, lparam );
|
return CallWindowProc ( wndproc, wnd, msg, wparam, lparam );
|
||||||
|
@ -354,7 +374,7 @@ LRESULT CALLBACK rvDebuggerWindow::ScriptWndProc ( HWND wnd, UINT msg, WPARAM wp
|
||||||
|
|
||||||
LRESULT CALLBACK rvDebuggerWindow::MarginWndProc ( HWND wnd, UINT msg, WPARAM wparam, LPARAM lparam )
|
LRESULT CALLBACK rvDebuggerWindow::MarginWndProc ( HWND wnd, UINT msg, WPARAM wparam, LPARAM lparam )
|
||||||
{
|
{
|
||||||
rvDebuggerWindow* window = (rvDebuggerWindow*) GetWindowLong ( wnd, GWL_USERDATA );
|
rvDebuggerWindow* window = (rvDebuggerWindow*) GetWindowLongPtr ( wnd, GWLP_USERDATA );
|
||||||
|
|
||||||
switch ( msg )
|
switch ( msg )
|
||||||
{
|
{
|
||||||
|
@ -384,15 +404,57 @@ LRESULT CALLBACK rvDebuggerWindow::MarginWndProc ( HWND wnd, UINT msg, WPARAM wp
|
||||||
case WM_PAINT:
|
case WM_PAINT:
|
||||||
{
|
{
|
||||||
HDC dc;
|
HDC dc;
|
||||||
|
float scaling_factor = Win_GetWindowScalingFactor(wnd);
|
||||||
|
int s2 = int(2 * scaling_factor);
|
||||||
|
int s4 = int(4 * scaling_factor);
|
||||||
|
int width,height;
|
||||||
|
|
||||||
int size = window->mMarginSize - 2;
|
window->ResizeImageList(width,height);
|
||||||
|
|
||||||
PAINTSTRUCT ps;
|
PAINTSTRUCT ps;
|
||||||
RECT rect;
|
RECT rect;
|
||||||
GetClientRect ( wnd, &rect );
|
GetClientRect ( wnd, &rect );
|
||||||
dc = BeginPaint ( wnd, &ps );
|
dc = BeginPaint( wnd, &ps );
|
||||||
FillRect ( dc, &rect, GetSysColorBrush ( COLOR_3DFACE ) );
|
FillRect( dc, &rect, GetSysColorBrush( COLOR_3DSHADOW ) );
|
||||||
|
|
||||||
|
//draw line nrs
|
||||||
|
int iMaxNumberOfLines = ( (rect.bottom - rect.top ) / height ) + height;
|
||||||
|
int iFirstVisibleLine = SendMessage( window->mWndScript, EM_GETFIRSTVISIBLELINE, 0, 0 );
|
||||||
|
HFONT hf = CreateFont( height, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "Courier New" );
|
||||||
|
HFONT hfOld = ( HFONT ) SelectObject( dc, hf );
|
||||||
|
SetBkMode( dc, OPAQUE );
|
||||||
|
// I think it looks nicer when the line number background is white
|
||||||
|
SetBkColor( dc, RGB( 255, 255, 255 ) );
|
||||||
|
SetTextColor( dc, RGB( 0, 0, 255 ) );
|
||||||
|
|
||||||
|
int lnrWidth = 8;
|
||||||
|
GetCharWidth32( dc, '9', '9', &lnrWidth );
|
||||||
|
lnrWidth *= 4; // we want enough width for 4 chars ("9999"), not just one
|
||||||
|
lnrWidth += 2 * s4; // we want some space around the line number
|
||||||
|
|
||||||
|
RECT lnrRect = rect;
|
||||||
|
lnrRect.left = rect.right;
|
||||||
|
lnrRect.right = lnrRect.left + lnrWidth;
|
||||||
|
FillRect( dc, &lnrRect, WHITE_BRUSH );
|
||||||
|
|
||||||
|
for (int i = 0; i < iMaxNumberOfLines; ++i )
|
||||||
|
{
|
||||||
|
int c;
|
||||||
|
POINTL pos;
|
||||||
|
c = SendMessage( window->mWndScript, EM_LINEINDEX, iFirstVisibleLine + i , 0 );
|
||||||
|
SendMessage( window->mWndScript, EM_POSFROMCHAR, ( WPARAM ) &pos, c );
|
||||||
|
|
||||||
|
RECT t = lnrRect;
|
||||||
|
t.top = pos.y;
|
||||||
|
t.bottom = t.top + height;
|
||||||
|
t.right -= s4; // a little space between text and "border" to code part of window
|
||||||
|
|
||||||
|
idStr lntxt( iFirstVisibleLine + i + 1);
|
||||||
|
DrawText( dc, lntxt, lntxt.Length(), &t, DT_RIGHT );
|
||||||
|
}
|
||||||
|
DeleteObject( hf );
|
||||||
|
|
||||||
|
//draw breakpoints
|
||||||
if ( window->mScripts.Num ( ) )
|
if ( window->mScripts.Num ( ) )
|
||||||
{
|
{
|
||||||
for ( int i = 0; i < window->mClient->GetBreakpointCount(); i ++ )
|
for ( int i = 0; i < window->mClient->GetBreakpointCount(); i ++ )
|
||||||
|
@ -407,7 +469,8 @@ LRESULT CALLBACK rvDebuggerWindow::MarginWndProc ( HWND wnd, UINT msg, WPARAM wp
|
||||||
|
|
||||||
c = SendMessage ( window->mWndScript, EM_LINEINDEX, bp->GetLineNumber ( ) - 1, 0 );
|
c = SendMessage ( window->mWndScript, EM_LINEINDEX, bp->GetLineNumber ( ) - 1, 0 );
|
||||||
SendMessage ( window->mWndScript, EM_POSFROMCHAR, (WPARAM)&pos, c );
|
SendMessage ( window->mWndScript, EM_POSFROMCHAR, (WPARAM)&pos, c );
|
||||||
ImageList_DrawEx ( window->mImageList, 2, dc, rect.left, pos.y, size, size, CLR_NONE, CLR_NONE, ILD_NORMAL );
|
ImageList_DrawEx ( window->mTmpImageList, 2, dc, rect.left, pos.y, width, height, CLR_NONE, CLR_NONE, ILD_NORMAL );
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -421,7 +484,7 @@ LRESULT CALLBACK rvDebuggerWindow::MarginWndProc ( HWND wnd, UINT msg, WPARAM wp
|
||||||
|
|
||||||
c = SendMessage ( window->mWndScript, EM_LINEINDEX, window->mClient->GetBreakLineNumber() - 1, 0 );
|
c = SendMessage ( window->mWndScript, EM_LINEINDEX, window->mClient->GetBreakLineNumber() - 1, 0 );
|
||||||
SendMessage ( window->mWndScript, EM_POSFROMCHAR, (WPARAM)&pos, c );
|
SendMessage ( window->mWndScript, EM_POSFROMCHAR, (WPARAM)&pos, c );
|
||||||
ImageList_DrawEx ( window->mImageList, 3, dc, rect.left, pos.y, size, size, CLR_NONE, CLR_NONE, ILD_NORMAL );
|
ImageList_DrawEx ( window->mTmpImageList, 3, dc, rect.left, pos.y, width, height, CLR_NONE, CLR_NONE, ILD_NORMAL );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -434,17 +497,19 @@ LRESULT CALLBACK rvDebuggerWindow::MarginWndProc ( HWND wnd, UINT msg, WPARAM wp
|
||||||
|
|
||||||
c = SendMessage ( window->mWndScript, EM_LINEINDEX, window->mClient->GetCallstack()[window->mCurrentStackDepth]->mLineNumber - 1, 0 );
|
c = SendMessage ( window->mWndScript, EM_LINEINDEX, window->mClient->GetCallstack()[window->mCurrentStackDepth]->mLineNumber - 1, 0 );
|
||||||
SendMessage ( window->mWndScript, EM_POSFROMCHAR, (WPARAM)&pos, c );
|
SendMessage ( window->mWndScript, EM_POSFROMCHAR, (WPARAM)&pos, c );
|
||||||
ImageList_DrawEx ( window->mImageList, 1, dc, rect.left, pos.y, size, size, CLR_NONE, CLR_NONE, ILD_NORMAL );
|
ImageList_DrawEx ( window->mTmpImageList, 1, dc, rect.left, pos.y, width, height, CLR_NONE, CLR_NONE, ILD_NORMAL );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
RECT tmp = rect;
|
||||||
|
|
||||||
rect.right-=2;
|
rect.right -= s2;
|
||||||
rect.left = rect.right + 1;
|
rect.left = rect.right + s2;
|
||||||
HPEN pen = CreatePen ( PS_SOLID, 1, GetSysColor ( COLOR_3DSHADOW ) );
|
HPEN pen = CreatePen ( PS_SOLID, s2, GetSysColor ( COLOR_BACKGROUND ) );
|
||||||
HPEN old = (HPEN)SelectObject ( dc, pen );
|
HPEN old = (HPEN)SelectObject ( dc, pen );
|
||||||
MoveToEx ( dc, rect.right, rect.top, NULL );
|
MoveToEx ( dc, rect.right, rect.top, NULL );
|
||||||
LineTo ( dc, rect.right, rect.bottom );
|
LineTo ( dc, rect.right, rect.bottom );
|
||||||
|
|
||||||
SelectObject ( dc, old );
|
SelectObject ( dc, old );
|
||||||
DeleteObject ( pen );
|
DeleteObject ( pen );
|
||||||
EndPaint ( wnd, &ps );
|
EndPaint ( wnd, &ps );
|
||||||
|
@ -466,7 +531,7 @@ void rvDebuggerWindow::UpdateTitle ( void )
|
||||||
{
|
{
|
||||||
idStr title;
|
idStr title;
|
||||||
|
|
||||||
title = "Quake 4 Script Debugger - ";
|
title = "Dhewm3 Script Debugger - ";
|
||||||
|
|
||||||
if ( mClient->IsConnected ( ) )
|
if ( mClient->IsConnected ( ) )
|
||||||
{
|
{
|
||||||
|
@ -487,7 +552,10 @@ void rvDebuggerWindow::UpdateTitle ( void )
|
||||||
if ( mScripts.Num ( ) )
|
if ( mScripts.Num ( ) )
|
||||||
{
|
{
|
||||||
title += " - [";
|
title += " - [";
|
||||||
title += idStr( mScripts[mActiveScript]->GetFilename() ).StripPath ( );
|
if (mActiveScript != -1)
|
||||||
|
title += idStr( mScripts[mActiveScript]->GetFilename() ).StripPath ( );
|
||||||
|
else
|
||||||
|
title += "Load Error";
|
||||||
title += "]";
|
title += "]";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -590,6 +658,56 @@ void rvDebuggerWindow::UpdateCallstack ( void )
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void rvDebuggerWindow::UpdateScriptList(void)
|
||||||
|
{
|
||||||
|
LVITEM item;
|
||||||
|
ListView_DeleteAllItems(mWndScriptList);
|
||||||
|
ZeroMemory(&item, sizeof(item));
|
||||||
|
item.mask = LVIF_TEXT | LVIF_IMAGE;
|
||||||
|
|
||||||
|
idStrList& scripts = mClient->GetServerScripts();
|
||||||
|
for (int i = 0; i < scripts.Num(); i++)
|
||||||
|
{
|
||||||
|
item.iItem = ListView_GetItemCount(mWndScriptList);
|
||||||
|
item.pszText = "";
|
||||||
|
//find in activeScripts
|
||||||
|
item.iImage = 0;
|
||||||
|
for (int j = 0; j < mScripts.Num(); j++)
|
||||||
|
{
|
||||||
|
if (!idStr::Icmp(mScripts[j]->GetFilename(), scripts[i]))
|
||||||
|
{
|
||||||
|
item.iImage = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ListView_InsertItem(mWndScriptList, &item);
|
||||||
|
ListView_SetItemText(mWndScriptList, item.iItem, 1, (LPSTR)scripts[i].c_str());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void rvDebuggerWindow::UpdateBreakpointList( void )
|
||||||
|
{
|
||||||
|
LVITEM item;
|
||||||
|
ListView_DeleteAllItems( mWndBreakList );
|
||||||
|
ZeroMemory( &item, sizeof( item ) );
|
||||||
|
item.mask = LVIF_TEXT | LVIF_IMAGE;
|
||||||
|
|
||||||
|
int numBreakPoints = mClient->GetBreakpointCount();
|
||||||
|
for ( int i = 0; i < numBreakPoints; i++ )
|
||||||
|
{
|
||||||
|
rvDebuggerBreakpoint* bp = mClient->GetBreakpoint( i );
|
||||||
|
item.iItem = ListView_GetItemCount( mWndBreakList );
|
||||||
|
item.pszText = "";
|
||||||
|
item.iImage = 2; // breakpoint
|
||||||
|
ListView_InsertItem( mWndBreakList, &item );
|
||||||
|
|
||||||
|
idStr lineStr( bp->GetLineNumber() );
|
||||||
|
ListView_SetItemText( mWndBreakList, item.iItem, 1, (LPSTR)bp->GetFilename() );
|
||||||
|
ListView_SetItemText( mWndBreakList, item.iItem, 2, (LPSTR)lineStr.c_str() );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
================
|
================
|
||||||
rvDebuggerWindow::UpdateWatch
|
rvDebuggerWindow::UpdateWatch
|
||||||
|
@ -712,7 +830,7 @@ int rvDebuggerWindow::HandleInitMenu ( WPARAM wParam, LPARAM lParam )
|
||||||
case ID_DBG_DEBUG_STEPOVER:
|
case ID_DBG_DEBUG_STEPOVER:
|
||||||
case ID_DBG_DEBUG_STEPINTO:
|
case ID_DBG_DEBUG_STEPINTO:
|
||||||
case ID_DBG_DEBUG_SHOWNEXTSTATEMENT:
|
case ID_DBG_DEBUG_SHOWNEXTSTATEMENT:
|
||||||
// case ID_DBG_DEBUG_QUICKWATCH:
|
case ID_DBG_DEBUG_QUICKWATCH:
|
||||||
if ( !mClient->IsConnected() || !mClient->IsStopped() )
|
if ( !mClient->IsConnected() || !mClient->IsStopped() )
|
||||||
{
|
{
|
||||||
EnableMenuItem ( hmenu, nPos, MF_GRAYED|MF_BYPOSITION );
|
EnableMenuItem ( hmenu, nPos, MF_GRAYED|MF_BYPOSITION );
|
||||||
|
@ -737,6 +855,33 @@ int rvDebuggerWindow::HandleInitMenu ( WPARAM wParam, LPARAM lParam )
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void rvDebuggerWindow::ResizeImageList(int& widthOut, int& heightOut)
|
||||||
|
{
|
||||||
|
//mTmpImageList
|
||||||
|
float scaling_factor = Win_GetWindowScalingFactor(mWnd);
|
||||||
|
int s16 = int(16 * scaling_factor);
|
||||||
|
|
||||||
|
TEXTMETRIC tm;
|
||||||
|
HDC dc;
|
||||||
|
dc = GetDC(mWndScript);
|
||||||
|
|
||||||
|
GetTextMetrics(dc, &tm);
|
||||||
|
int height = mZoomScaleDem ? (tm.tmHeight * (float)mZoomScaleNum / (float)mZoomScaleDem) : 16;
|
||||||
|
height *= scaling_factor;
|
||||||
|
int width = mZoomScaleDem ? (s16 * (float)mZoomScaleNum / (float)mZoomScaleDem) : s16;
|
||||||
|
|
||||||
|
ImageList_Destroy(mTmpImageList);
|
||||||
|
mTmpImageList = ImageList_Create(width, height, ILC_COLOR | ILC_MASK , 0, 2);
|
||||||
|
ImageList_AddIcon(mTmpImageList, (HICON)LoadImage(mInstance, MAKEINTRESOURCE(IDI_DBG_EMPTY), IMAGE_ICON, width, height, LR_DEFAULTSIZE | LR_DEFAULTCOLOR));
|
||||||
|
ImageList_AddIcon(mTmpImageList, (HICON)LoadImage(mInstance, MAKEINTRESOURCE(IDI_DBG_CURRENT), IMAGE_ICON, width, height, LR_DEFAULTSIZE | LR_DEFAULTCOLOR));
|
||||||
|
ImageList_AddIcon(mTmpImageList, (HICON)LoadImage(mInstance, MAKEINTRESOURCE(IDI_DBG_BREAKPOINT), IMAGE_ICON, width, height, LR_DEFAULTSIZE | LR_DEFAULTCOLOR));
|
||||||
|
ImageList_AddIcon(mTmpImageList, (HICON)LoadImage(mInstance, MAKEINTRESOURCE(IDI_DBG_CURRENTLINE), IMAGE_ICON, width, height, LR_DEFAULTSIZE | LR_DEFAULTCOLOR));
|
||||||
|
|
||||||
|
widthOut = width;
|
||||||
|
heightOut = height;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
================
|
================
|
||||||
rvDebuggerWindow::HandleCreate
|
rvDebuggerWindow::HandleCreate
|
||||||
|
@ -760,18 +905,18 @@ int rvDebuggerWindow::HandleCreate ( WPARAM wparam, LPARAM lparam )
|
||||||
// Create the script window
|
// Create the script window
|
||||||
LoadLibrary ( "Riched20.dll" );
|
LoadLibrary ( "Riched20.dll" );
|
||||||
mWndScript = CreateWindow ( "RichEdit20A", "", WS_CHILD|WS_BORDER|ES_NOHIDESEL|ES_READONLY|ES_MULTILINE|ES_WANTRETURN|ES_AUTOVSCROLL|ES_AUTOHSCROLL|WS_VSCROLL|WS_HSCROLL, 0, 0, 100, 100, mWnd, (HMENU) IDC_DBG_SCRIPT, mInstance, 0 );
|
mWndScript = CreateWindow ( "RichEdit20A", "", WS_CHILD|WS_BORDER|ES_NOHIDESEL|ES_READONLY|ES_MULTILINE|ES_WANTRETURN|ES_AUTOVSCROLL|ES_AUTOHSCROLL|WS_VSCROLL|WS_HSCROLL, 0, 0, 100, 100, mWnd, (HMENU) IDC_DBG_SCRIPT, mInstance, 0 );
|
||||||
SendMessage ( mWndScript, EM_SETEVENTMASK, 0, ENM_SCROLL|ENM_CHANGE );
|
SendMessage ( mWndScript, EM_SETEVENTMASK, 0, ENM_SCROLL | ENM_CHANGE | ENM_UPDATE | ENM_SCROLLEVENTS | ENM_REQUESTRESIZE) ;
|
||||||
SendMessage ( mWndScript, EM_SETWORDBREAKPROC, 0, (LPARAM) ScriptWordBreakProc );
|
SendMessage ( mWndScript, EM_SETWORDBREAKPROC, 0, (LPARAM) ScriptWordBreakProc );
|
||||||
mOldScriptProc = (WNDPROC)GetWindowLong ( mWndScript, GWL_WNDPROC );
|
mOldScriptProc = (WNDPROC)GetWindowLongPtr ( mWndScript, GWLP_WNDPROC );
|
||||||
SetWindowLong ( mWndScript, GWL_USERDATA, (LONG)this );
|
SetWindowLongPtr ( mWndScript, GWLP_USERDATA, (LONG_PTR)this );
|
||||||
SetWindowLong ( mWndScript, GWL_WNDPROC, (LONG)ScriptWndProc );
|
SetWindowLongPtr ( mWndScript, GWLP_WNDPROC, (LONG_PTR)ScriptWndProc );
|
||||||
|
|
||||||
SendMessage ( mWndScript, EM_SETTABSTOPS, 1, (LPARAM)&tabsize );
|
SendMessage ( mWndScript, EM_SETTABSTOPS, 1, (LPARAM)&tabsize );
|
||||||
|
|
||||||
dc = GetDC ( mWndScript );
|
dc = GetDC ( mWndScript );
|
||||||
GetTextMetrics ( dc, &tm );
|
GetTextMetrics ( dc, &tm );
|
||||||
ZeroMemory ( &lf, sizeof(lf) );
|
ZeroMemory ( &lf, sizeof(lf) );
|
||||||
lf.lfHeight = tm.tmHeight;
|
lf.lfHeight = tm.tmHeight * Win_GetWindowScalingFactor( mWndScript );
|
||||||
strcpy ( lf.lfFaceName, "Courier New" );
|
strcpy ( lf.lfFaceName, "Courier New" );
|
||||||
|
|
||||||
SendMessage ( mWndScript, WM_SETFONT, (WPARAM)CreateFontIndirect ( &lf ), 0 );
|
SendMessage ( mWndScript, WM_SETFONT, (WPARAM)CreateFontIndirect ( &lf ), 0 );
|
||||||
|
@ -782,15 +927,22 @@ int rvDebuggerWindow::HandleCreate ( WPARAM wparam, LPARAM lparam )
|
||||||
SendMessage ( mWndOutput, WM_SETFONT, (WPARAM)CreateFontIndirect ( &lf ), 0 );
|
SendMessage ( mWndOutput, WM_SETFONT, (WPARAM)CreateFontIndirect ( &lf ), 0 );
|
||||||
SendMessage ( mWndOutput, EM_SETMARGINS, EC_LEFTMARGIN|EC_RIGHTMARGIN, MAKELONG(18,10) );
|
SendMessage ( mWndOutput, EM_SETMARGINS, EC_LEFTMARGIN|EC_RIGHTMARGIN, MAKELONG(18,10) );
|
||||||
SendMessage ( mWndOutput, EM_SETBKGNDCOLOR, 0, GetSysColor ( COLOR_3DFACE ) );
|
SendMessage ( mWndOutput, EM_SETBKGNDCOLOR, 0, GetSysColor ( COLOR_3DFACE ) );
|
||||||
|
SendMessage ( mWndOutput, EM_SETEVENTMASK, 0, ENM_SCROLL | ENM_CHANGE | ENM_UPDATE | ENM_SCROLLEVENTS);
|
||||||
|
|
||||||
mWndConsole = CreateWindow ( "RichEdit20A", "", WS_CHILD|ES_READONLY|ES_MULTILINE|ES_WANTRETURN|ES_AUTOVSCROLL|ES_AUTOHSCROLL|WS_VSCROLL|WS_HSCROLL, 0, 0, 100, 100, mWnd, (HMENU) IDC_DBG_CONSOLE, mInstance, 0 );
|
mWndConsole = CreateWindow ( "RichEdit20A", "", WS_CHILD|ES_READONLY|ES_MULTILINE|ES_WANTRETURN|ES_AUTOVSCROLL|ES_AUTOHSCROLL|WS_VSCROLL|WS_HSCROLL, 0, 0, 100, 100, mWnd, (HMENU) IDC_DBG_CONSOLE, mInstance, 0 );
|
||||||
SendMessage ( mWndConsole, WM_SETFONT, (WPARAM)CreateFontIndirect ( &lf ), 0 );
|
SendMessage ( mWndConsole, WM_SETFONT, (WPARAM)CreateFontIndirect ( &lf ), 0 );
|
||||||
SendMessage ( mWndConsole, EM_SETMARGINS, EC_LEFTMARGIN|EC_RIGHTMARGIN, MAKELONG(18,10) );
|
SendMessage ( mWndConsole, EM_SETMARGINS, EC_LEFTMARGIN|EC_RIGHTMARGIN, MAKELONG(18,10) );
|
||||||
SendMessage ( mWndConsole, EM_SETBKGNDCOLOR, 0, GetSysColor ( COLOR_3DFACE ) );
|
SendMessage ( mWndConsole, EM_SETBKGNDCOLOR, 0, GetSysColor ( COLOR_3DFACE ) );
|
||||||
|
|
||||||
|
mWndConsoleInput = CreateWindow( "RichEdit20A", "", WS_CHILD | ES_WANTRETURN | ES_AUTOVSCROLL | WS_VSCROLL | WS_BORDER, 0, 0, 100, 18, mWnd, ( HMENU ) IDC_DBG_CONSOLEINPUT, mInstance, 0 );
|
||||||
|
lf.lfHeight = -MulDiv( 8, GetDeviceCaps( dc, LOGPIXELSY ), 72 );
|
||||||
|
strcpy( lf.lfFaceName, "Arial" );
|
||||||
|
SendMessage( mWndConsoleInput, WM_SETFONT, ( WPARAM ) CreateFontIndirect( &lf ), 0 );
|
||||||
|
SendMessage( mWndConsoleInput, EM_SETMARGINS, EC_LEFTMARGIN | EC_RIGHTMARGIN, MAKELONG( 18, 10 ) );
|
||||||
|
|
||||||
mWndMargin = CreateWindow ( "STATIC", "", WS_VISIBLE|WS_CHILD, 0, 0, 0, 0, mWndScript, (HMENU)IDC_DBG_SPLITTER, mInstance, NULL );
|
mWndMargin = CreateWindow ( "STATIC", "", WS_VISIBLE|WS_CHILD, 0, 0, 0, 0, mWndScript, (HMENU)IDC_DBG_SPLITTER, mInstance, NULL );
|
||||||
SetWindowLong ( mWndMargin, GWL_USERDATA, (LONG)this );
|
SetWindowLongPtr ( mWndMargin, GWLP_USERDATA, (LONG_PTR)this );
|
||||||
SetWindowLong ( mWndMargin, GWL_WNDPROC, (LONG)MarginWndProc );
|
SetWindowLongPtr ( mWndMargin, GWLP_WNDPROC, (LONG_PTR)MarginWndProc );
|
||||||
|
|
||||||
mWndBorder = CreateWindow ( "STATIC", "", WS_VISIBLE|WS_CHILD|SS_GRAYFRAME, 0, 0, 0, 0, mWnd, (HMENU)IDC_DBG_BORDER, mInstance, NULL );
|
mWndBorder = CreateWindow ( "STATIC", "", WS_VISIBLE|WS_CHILD|SS_GRAYFRAME, 0, 0, 0, 0, mWnd, (HMENU)IDC_DBG_BORDER, mInstance, NULL );
|
||||||
|
|
||||||
|
@ -816,23 +968,52 @@ int rvDebuggerWindow::HandleCreate ( WPARAM wparam, LPARAM lparam )
|
||||||
TabCtrl_InsertItem ( mWndTabs, 3, &item );
|
TabCtrl_InsertItem ( mWndTabs, 3, &item );
|
||||||
item.pszText = "Threads";
|
item.pszText = "Threads";
|
||||||
TabCtrl_InsertItem ( mWndTabs, 4, &item );
|
TabCtrl_InsertItem ( mWndTabs, 4, &item );
|
||||||
|
item.pszText = "Scripts";
|
||||||
|
TabCtrl_InsertItem ( mWndTabs, 5, &item );
|
||||||
|
item.pszText = "Breakpoints";
|
||||||
|
TabCtrl_InsertItem ( mWndTabs, 6, &item );
|
||||||
|
|
||||||
mWndCallstack = CreateWindow ( WC_LISTVIEW, "", LVS_REPORT|WS_CHILD|LVS_SHAREIMAGELISTS, 0, 0, 0, 0, mWnd, (HMENU)IDC_DBG_CALLSTACK, mInstance, NULL );
|
mWndCallstack = CreateWindow ( WC_LISTVIEW, "", LVS_REPORT|WS_CHILD|LVS_SHAREIMAGELISTS, 0, 0, 0, 0, mWnd, (HMENU)IDC_DBG_CALLSTACK, mInstance, NULL );
|
||||||
mWndWatch = CreateWindow ( WC_LISTVIEW, "", LVS_REPORT|WS_CHILD|LVS_EDITLABELS|LVS_OWNERDRAWFIXED, 0, 0, 0, 0, mWnd, (HMENU)IDC_DBG_WATCH, mInstance, NULL );
|
mWndWatch = CreateWindow ( WC_LISTVIEW, "", LVS_REPORT|WS_CHILD|LVS_EDITLABELS|LVS_OWNERDRAWFIXED, 0, 0, 0, 0, mWnd, (HMENU)IDC_DBG_WATCH, mInstance, NULL );
|
||||||
mWndThreads = CreateWindow ( WC_LISTVIEW, "", LVS_REPORT|WS_CHILD|LVS_SHAREIMAGELISTS, 0, 0, 0, 0, mWnd, (HMENU)IDC_DBG_THREADS, mInstance, NULL );
|
mWndThreads = CreateWindow ( WC_LISTVIEW, "", LVS_REPORT|WS_CHILD|LVS_SHAREIMAGELISTS, 0, 0, 0, 0, mWnd, (HMENU)IDC_DBG_THREADS, mInstance, NULL );
|
||||||
|
mWndScriptList = CreateWindow( WC_LISTVIEW, "", LVS_REPORT|WS_CHILD|LVS_SHAREIMAGELISTS, 0, 0, 0, 0, mWnd, (HMENU)IDC_DBG_SCRIPTLIST, mInstance, NULL );
|
||||||
|
mWndBreakList = CreateWindow( WC_LISTVIEW, "", LVS_REPORT|WS_CHILD|LVS_SHAREIMAGELISTS, 0, 0, 0, 0, mWnd, (HMENU)IDC_DBG_BREAKLIST, mInstance, NULL );
|
||||||
|
|
||||||
LVCOLUMN col;
|
LVCOLUMN col;
|
||||||
col.mask = LVCF_WIDTH|LVCF_TEXT;
|
col.mask = LVCF_WIDTH|LVCF_TEXT;
|
||||||
|
|
||||||
|
col.cx = 20;
|
||||||
|
col.pszText = "";
|
||||||
|
ListView_InsertColumn( mWndBreakList, 0, &col );
|
||||||
|
#if 0 // TODO: figure out how to get the function name in UpdateBreakpointList()
|
||||||
|
col.cx = 150;
|
||||||
|
col.pszText = "Function";
|
||||||
|
ListView_InsertColumn( mWndBreakList, 1, &col );
|
||||||
|
#endif
|
||||||
|
col.cx = 350;
|
||||||
|
col.pszText = "Filename";
|
||||||
|
ListView_InsertColumn( mWndBreakList, 1, &col );
|
||||||
|
col.cx = 50;
|
||||||
|
col.pszText = "Line";
|
||||||
|
ListView_InsertColumn( mWndBreakList, 2, &col );
|
||||||
|
|
||||||
|
col.cx = 20;
|
||||||
|
col.pszText = "";
|
||||||
|
ListView_InsertColumn ( mWndScriptList, 0, &col);
|
||||||
|
col.cx = 350;
|
||||||
|
col.pszText = "Filename";
|
||||||
|
ListView_InsertColumn ( mWndScriptList, 1, &col );
|
||||||
|
|
||||||
col.cx = 20;
|
col.cx = 20;
|
||||||
col.pszText = "";
|
col.pszText = "";
|
||||||
ListView_InsertColumn ( mWndCallstack, 0, &col );
|
ListView_InsertColumn ( mWndCallstack, 0, &col );
|
||||||
col.cx = 150;
|
col.cx = 150;
|
||||||
col.pszText = "Function";
|
col.pszText = "Function";
|
||||||
ListView_InsertColumn ( mWndCallstack, 1, &col );
|
ListView_InsertColumn ( mWndCallstack, 1, &col );
|
||||||
col.cx = 150;
|
col.cx = 50;
|
||||||
col.pszText = "Line";
|
col.pszText = "Line";
|
||||||
ListView_InsertColumn ( mWndCallstack, 2, &col );
|
ListView_InsertColumn ( mWndCallstack, 2, &col );
|
||||||
col.cx = 150;
|
col.cx = 350;
|
||||||
col.pszText = "Filename";
|
col.pszText = "Filename";
|
||||||
ListView_InsertColumn ( mWndCallstack, 3, &col );
|
ListView_InsertColumn ( mWndCallstack, 3, &col );
|
||||||
|
|
||||||
|
@ -863,13 +1044,21 @@ int rvDebuggerWindow::HandleCreate ( WPARAM wparam, LPARAM lparam )
|
||||||
ImageList_AddIcon ( mImageList, (HICON)LoadImage ( mInstance, MAKEINTRESOURCE(IDI_DBG_CURRENT), IMAGE_ICON, 16, 16, LR_DEFAULTSIZE|LR_DEFAULTCOLOR) );
|
ImageList_AddIcon ( mImageList, (HICON)LoadImage ( mInstance, MAKEINTRESOURCE(IDI_DBG_CURRENT), IMAGE_ICON, 16, 16, LR_DEFAULTSIZE|LR_DEFAULTCOLOR) );
|
||||||
ImageList_AddIcon ( mImageList, (HICON)LoadImage ( mInstance, MAKEINTRESOURCE(IDI_DBG_BREAKPOINT), IMAGE_ICON, 16, 16, LR_DEFAULTSIZE|LR_DEFAULTCOLOR) );
|
ImageList_AddIcon ( mImageList, (HICON)LoadImage ( mInstance, MAKEINTRESOURCE(IDI_DBG_BREAKPOINT), IMAGE_ICON, 16, 16, LR_DEFAULTSIZE|LR_DEFAULTCOLOR) );
|
||||||
ImageList_AddIcon ( mImageList, (HICON)LoadImage ( mInstance, MAKEINTRESOURCE(IDI_DBG_CURRENTLINE), IMAGE_ICON, 16, 16, LR_DEFAULTSIZE|LR_DEFAULTCOLOR) );
|
ImageList_AddIcon ( mImageList, (HICON)LoadImage ( mInstance, MAKEINTRESOURCE(IDI_DBG_CURRENTLINE), IMAGE_ICON, 16, 16, LR_DEFAULTSIZE|LR_DEFAULTCOLOR) );
|
||||||
|
|
||||||
|
int w, h;
|
||||||
|
ResizeImageList(w, h);
|
||||||
|
ListView_SetImageList ( mWndScriptList, mTmpImageList, LVSIL_SMALL );
|
||||||
ListView_SetImageList ( mWndThreads, mImageList, LVSIL_SMALL );
|
ListView_SetImageList ( mWndThreads, mImageList, LVSIL_SMALL );
|
||||||
ListView_SetImageList ( mWndCallstack, mImageList, LVSIL_SMALL );
|
ListView_SetImageList ( mWndCallstack, mImageList, LVSIL_SMALL );
|
||||||
|
ListView_SetImageList ( mWndBreakList, mImageList, LVSIL_SMALL );
|
||||||
|
|
||||||
EnableWindows ( FALSE );
|
EnableWindows ( FALSE );
|
||||||
|
EnableWindow ( mWndScriptList, true );
|
||||||
|
|
||||||
ListView_SetExtendedListViewStyle ( mWndCallstack, LVS_EX_FULLROWSELECT );
|
ListView_SetExtendedListViewStyle ( mWndCallstack, LVS_EX_FULLROWSELECT );
|
||||||
ListView_SetExtendedListViewStyle ( mWndThreads, LVS_EX_FULLROWSELECT );
|
ListView_SetExtendedListViewStyle ( mWndThreads, LVS_EX_FULLROWSELECT );
|
||||||
|
ListView_SetExtendedListViewStyle ( mWndScriptList, LVS_EX_FULLROWSELECT );
|
||||||
|
ListView_SetExtendedListViewStyle ( mWndBreakList, LVS_EX_FULLROWSELECT );
|
||||||
|
|
||||||
gDebuggerApp.GetOptions().GetColumnWidths ( "cw_callstack", mWndCallstack );
|
gDebuggerApp.GetOptions().GetColumnWidths ( "cw_callstack", mWndCallstack );
|
||||||
gDebuggerApp.GetOptions().GetColumnWidths ( "cw_threads", mWndThreads );
|
gDebuggerApp.GetOptions().GetColumnWidths ( "cw_threads", mWndThreads );
|
||||||
|
@ -920,6 +1109,10 @@ int rvDebuggerWindow::HandleCreate ( WPARAM wparam, LPARAM lparam )
|
||||||
AddWatch ( s );
|
AddWatch ( s );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
RECT t;
|
||||||
|
GetClientRect(mWndScript, &t);
|
||||||
|
SendMessage(mWndScript, WM_SIZE, 0, MAKELPARAM(t.right - t.left, t.bottom - t.top));
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -957,6 +1150,36 @@ int rvDebuggerWindow::HandleCommand ( WPARAM wparam, LPARAM lparam )
|
||||||
|
|
||||||
switch ( id )
|
switch ( id )
|
||||||
{
|
{
|
||||||
|
case ID_DBG_SEND_COMMAND:
|
||||||
|
{
|
||||||
|
if ( mClient->IsConnected( ) && GetFocus( ) == mWndConsoleInput ) {
|
||||||
|
GETTEXTLENGTHEX textLen;
|
||||||
|
int chars;
|
||||||
|
textLen.flags = GTL_DEFAULT | GTL_USECRLF;
|
||||||
|
textLen.codepage = CP_ACP;
|
||||||
|
chars = SendMessage( mWndConsoleInput, EM_GETTEXTLENGTHEX, ( WPARAM ) &textLen, 0 );
|
||||||
|
|
||||||
|
char *text = new char[chars + 1];
|
||||||
|
|
||||||
|
GETTEXTEX getText;
|
||||||
|
getText.cb = chars + 1;
|
||||||
|
getText.codepage = CP_ACP;
|
||||||
|
getText.flags = GT_DEFAULT | GT_USECRLF;
|
||||||
|
getText.lpDefaultChar = NULL;
|
||||||
|
getText.lpUsedDefChar = NULL;
|
||||||
|
SendMessage( mWndConsoleInput, EM_GETTEXTEX, ( WPARAM ) &getText, ( LPARAM ) text );
|
||||||
|
idStr parse = text;
|
||||||
|
delete[] text;
|
||||||
|
|
||||||
|
mClient->SendCommand( parse.c_str() );
|
||||||
|
|
||||||
|
SendMessage( mWndConsoleInput, EM_SETSEL, 0, -1 );
|
||||||
|
SendMessage( mWndConsoleInput, EM_REPLACESEL, FALSE, ( LPARAM ) "" );
|
||||||
|
UpdateWindow( mWndConsoleInput );
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case ID_DBG_EDIT_FINDSELECTED:
|
case ID_DBG_EDIT_FINDSELECTED:
|
||||||
{
|
{
|
||||||
idStr text;
|
idStr text;
|
||||||
|
@ -1025,7 +1248,7 @@ int rvDebuggerWindow::HandleCommand ( WPARAM wparam, LPARAM lparam )
|
||||||
GetCurrentDirectory ( MAX_PATH, curDir );
|
GetCurrentDirectory ( MAX_PATH, curDir );
|
||||||
|
|
||||||
GetModuleFileName ( NULL, exeFile, MAX_PATH );
|
GetModuleFileName ( NULL, exeFile, MAX_PATH );
|
||||||
const char* s = va("%s +set fs_game %s +set fs_cdpath %s", exeFile, cvarSystem->GetCVarString( "fs_game" ), cvarSystem->GetCVarString( "fs_cdpath" ) );
|
const char* s = va("%s +set fs_game %s +set fs_cdpath %s +set com_enableDebuggerServer 1", exeFile, cvarSystem->GetCVarString( "fs_game" ), cvarSystem->GetCVarString( "fs_cdpath" ) );
|
||||||
CreateProcess ( NULL, (LPSTR)s,
|
CreateProcess ( NULL, (LPSTR)s,
|
||||||
NULL, NULL, FALSE, 0, NULL, curDir, &startup, &process );
|
NULL, NULL, FALSE, 0, NULL, curDir, &startup, &process );
|
||||||
|
|
||||||
|
@ -1049,13 +1272,13 @@ int rvDebuggerWindow::HandleCommand ( WPARAM wparam, LPARAM lparam )
|
||||||
LONG num;
|
LONG num;
|
||||||
LONG dem;
|
LONG dem;
|
||||||
|
|
||||||
SendMessage ( mWndScript, EM_GETZOOM, (LONG)&num, (LONG)&dem );
|
SendMessage ( mWndScript, EM_GETZOOM, (WPARAM)&num, (LPARAM)&dem );
|
||||||
if ( num != mZoomScaleNum || dem != mZoomScaleDem )
|
if ( num != mZoomScaleNum || dem != mZoomScaleDem )
|
||||||
{
|
{
|
||||||
mZoomScaleNum = num;
|
mZoomScaleNum = num;
|
||||||
mZoomScaleDem = dem;
|
mZoomScaleDem = dem;
|
||||||
GetClientRect ( mWndScript, &t );
|
GetClientRect ( mWndScript, &t );
|
||||||
SendMessage ( mWnd, WM_SIZE, 0, MAKELPARAM(t.right-t.left,t.bottom-t.top) );
|
SendMessage ( mWndScript, WM_SIZE, 0, MAKELPARAM(t.right-t.left ,t.bottom-t.top) );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -1064,6 +1287,7 @@ int rvDebuggerWindow::HandleCommand ( WPARAM wparam, LPARAM lparam )
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case 111: // DG: Debugger.rc has 'MENUITEM "Toggle &Breakpoint\tF9", 111' for the context menu no idea why 111 but this works
|
||||||
case ID_DBG_DEBUG_TOGGLEBREAKPOINT:
|
case ID_DBG_DEBUG_TOGGLEBREAKPOINT:
|
||||||
ToggleBreakpoint ( );
|
ToggleBreakpoint ( );
|
||||||
break;
|
break;
|
||||||
|
@ -1139,6 +1363,23 @@ int rvDebuggerWindow::HandleCommand ( WPARAM wparam, LPARAM lparam )
|
||||||
UpdateScript ( );
|
UpdateScript ( );
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// DG: support "Run To Cursor" from context menu
|
||||||
|
case ID_DBG_DEBUG_RUNTOCURSOR:
|
||||||
|
{
|
||||||
|
// Find the currently selected line
|
||||||
|
DWORD sel;
|
||||||
|
SendMessage( mWndScript, EM_GETSEL, (WPARAM)&sel, 0 );
|
||||||
|
int lineNumber = SendMessage( mWndScript, EM_LINEFROMCHAR, sel, 0 ) + 1;
|
||||||
|
|
||||||
|
const char* filename = mScripts[mActiveScript]->GetFilename();
|
||||||
|
mClient->AddBreakpoint( filename, lineNumber, true );
|
||||||
|
mClient->Resume();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: case ID_DBG_DEBUG_SHOWNEXTSTATEMENT:
|
||||||
|
// whatever this is supposed to do (also from context menu)
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -1153,7 +1394,7 @@ Window procedure for the deubgger window
|
||||||
*/
|
*/
|
||||||
LRESULT CALLBACK rvDebuggerWindow::WndProc ( HWND wnd, UINT msg, WPARAM wparam, LPARAM lparam )
|
LRESULT CALLBACK rvDebuggerWindow::WndProc ( HWND wnd, UINT msg, WPARAM wparam, LPARAM lparam )
|
||||||
{
|
{
|
||||||
rvDebuggerWindow* window = (rvDebuggerWindow*) GetWindowLong ( wnd, GWL_USERDATA );
|
rvDebuggerWindow* window = (rvDebuggerWindow*) GetWindowLongPtr ( wnd, GWLP_USERDATA );
|
||||||
|
|
||||||
switch ( msg )
|
switch ( msg )
|
||||||
{
|
{
|
||||||
|
@ -1176,7 +1417,7 @@ LRESULT CALLBACK rvDebuggerWindow::WndProc ( HWND wnd, UINT msg, WPARAM wparam,
|
||||||
gDebuggerApp.GetOptions().SetString ( va("watch%d", i ), "" );
|
gDebuggerApp.GetOptions().SetString ( va("watch%d", i ), "" );
|
||||||
|
|
||||||
window->mWnd = NULL;
|
window->mWnd = NULL;
|
||||||
SetWindowLong ( wnd, GWL_USERDATA, 0 );
|
SetWindowLongPtr ( wnd, GWLP_USERDATA, 0 );
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1202,8 +1443,13 @@ LRESULT CALLBACK rvDebuggerWindow::WndProc ( HWND wnd, UINT msg, WPARAM wparam,
|
||||||
|
|
||||||
case WM_SIZE:
|
case WM_SIZE:
|
||||||
{
|
{
|
||||||
|
float scaling_factor = Win_GetWindowScalingFactor(wnd);
|
||||||
|
int s18 = int(18 * scaling_factor);
|
||||||
|
int s4 = int(4 * scaling_factor);
|
||||||
|
int s10 = int(10 * scaling_factor);
|
||||||
|
|
||||||
RECT rect;
|
RECT rect;
|
||||||
window->mMarginSize = window->mZoomScaleDem ? ((long)(18.0f * (float)window->mZoomScaleNum / (float)window->mZoomScaleDem)):18;
|
window->mMarginSize = window->mZoomScaleDem ? ((long)(s18 * (float)window->mZoomScaleNum / (float)window->mZoomScaleDem)): s18;
|
||||||
window->mSplitterRect.left = 0;
|
window->mSplitterRect.left = 0;
|
||||||
window->mSplitterRect.right = LOWORD(lparam);
|
window->mSplitterRect.right = LOWORD(lparam);
|
||||||
|
|
||||||
|
@ -1215,14 +1461,27 @@ LRESULT CALLBACK rvDebuggerWindow::WndProc ( HWND wnd, UINT msg, WPARAM wparam,
|
||||||
SetRect ( &rect, 0, window->mSplitterRect.bottom, LOWORD(lparam), HIWORD(lparam) );
|
SetRect ( &rect, 0, window->mSplitterRect.bottom, LOWORD(lparam), HIWORD(lparam) );
|
||||||
MoveWindow ( window->mWndTabs, rect.left, rect.top, rect.right-rect.left, rect.bottom-rect.top, TRUE );
|
MoveWindow ( window->mWndTabs, rect.left, rect.top, rect.right-rect.left, rect.bottom-rect.top, TRUE );
|
||||||
SendMessage ( window->mWndTabs, TCM_ADJUSTRECT, FALSE, (LPARAM)&rect );
|
SendMessage ( window->mWndTabs, TCM_ADJUSTRECT, FALSE, (LPARAM)&rect );
|
||||||
rect.bottom -= 4 ;
|
rect.bottom -= s4;
|
||||||
MoveWindow ( window->mWndBorder, rect.left, rect.top, rect.right-rect.left, rect.bottom-rect.top, TRUE );
|
MoveWindow ( window->mWndBorder, rect.left, rect.top, rect.right-rect.left, rect.bottom-rect.top, TRUE );
|
||||||
InflateRect ( &rect, -1, -1 );
|
InflateRect ( &rect, -1, -1 );
|
||||||
MoveWindow ( window->mWndOutput, rect.left, rect.top, rect.right-rect.left, rect.bottom-rect.top, TRUE );
|
MoveWindow ( window->mWndOutput, rect.left, rect.top, rect.right-rect.left, rect.bottom-rect.top, TRUE );
|
||||||
MoveWindow ( window->mWndConsole, rect.left, rect.top, rect.right-rect.left, rect.bottom-rect.top, TRUE );
|
MoveWindow ( window->mWndConsole, rect.left, rect.top, rect.right-rect.left, rect.bottom-rect.top - s18, TRUE );
|
||||||
|
MoveWindow ( window->mWndConsoleInput, rect.left, rect.bottom-s18, rect.right - rect.left, s18, TRUE );
|
||||||
MoveWindow ( window->mWndCallstack, rect.left, rect.top, rect.right-rect.left, rect.bottom-rect.top, TRUE );
|
MoveWindow ( window->mWndCallstack, rect.left, rect.top, rect.right-rect.left, rect.bottom-rect.top, TRUE );
|
||||||
MoveWindow ( window->mWndWatch, rect.left, rect.top, rect.right-rect.left, rect.bottom-rect.top, TRUE );
|
MoveWindow ( window->mWndWatch, rect.left, rect.top, rect.right-rect.left, rect.bottom-rect.top, TRUE );
|
||||||
MoveWindow ( window->mWndThreads, rect.left, rect.top, rect.right-rect.left, rect.bottom-rect.top, TRUE );
|
MoveWindow ( window->mWndThreads, rect.left, rect.top, rect.right-rect.left, rect.bottom-rect.top, TRUE );
|
||||||
|
MoveWindow ( window->mWndScriptList, rect.left, rect.top, rect.right-rect.left, rect.bottom-rect.top, TRUE );
|
||||||
|
MoveWindow ( window->mWndBreakList, rect.left, rect.top, rect.right-rect.left, rect.bottom-rect.top, TRUE );
|
||||||
|
|
||||||
|
// FIXME: was *2.25, increased for line numbers up to 9999; but neither works particularly well
|
||||||
|
// if DPI scaling is involved, because script code text and linenumbers aren't DPI scaled
|
||||||
|
int lmargin = s18 * 3.5;
|
||||||
|
SendMessage(window->mWndScript, EM_SETMARGINS, EC_LEFTMARGIN | EC_RIGHTMARGIN, MAKELONG(lmargin, s10));
|
||||||
|
SendMessage(window->mWndCallstack, EM_SETMARGINS, EC_LEFTMARGIN | EC_RIGHTMARGIN, MAKELONG(s18, s10));
|
||||||
|
SendMessage(window->mWndOutput, EM_SETMARGINS, EC_LEFTMARGIN | EC_RIGHTMARGIN, MAKELONG(s18, s10));
|
||||||
|
SendMessage(window->mWndConsole, EM_SETMARGINS, EC_LEFTMARGIN | EC_RIGHTMARGIN, MAKELONG(s18, s10));
|
||||||
|
SendMessage( window->mWndConsoleInput, EM_SETMARGINS, EC_LEFTMARGIN | EC_RIGHTMARGIN, MAKELONG( s18, s10 ) );
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1258,7 +1517,17 @@ LRESULT CALLBACK rvDebuggerWindow::WndProc ( HWND wnd, UINT msg, WPARAM wparam,
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case WM_MOUSEWHEEL:
|
||||||
|
{
|
||||||
|
HDC dc = GetDC(wnd);
|
||||||
|
DrawFocusRect(dc, &window->mSplitterRect);
|
||||||
|
ReleaseDC(wnd, dc);
|
||||||
|
|
||||||
|
RECT client;
|
||||||
|
GetClientRect(wnd, &client);
|
||||||
|
SendMessage(wnd, WM_SIZE, 0, MAKELPARAM(client.right - client.left, client.bottom - client.top));
|
||||||
|
|
||||||
|
}
|
||||||
case WM_LBUTTONUP:
|
case WM_LBUTTONUP:
|
||||||
if ( window->mSplitterDrag )
|
if ( window->mSplitterDrag )
|
||||||
{
|
{
|
||||||
|
@ -1320,7 +1589,7 @@ LRESULT CALLBACK rvDebuggerWindow::WndProc ( HWND wnd, UINT msg, WPARAM wparam,
|
||||||
{
|
{
|
||||||
CREATESTRUCT* cs = (CREATESTRUCT*) lparam;
|
CREATESTRUCT* cs = (CREATESTRUCT*) lparam;
|
||||||
window = (rvDebuggerWindow*) cs->lpCreateParams;
|
window = (rvDebuggerWindow*) cs->lpCreateParams;
|
||||||
SetWindowLong ( wnd, GWL_USERDATA, (LONG)cs->lpCreateParams );
|
SetWindowLongPtr ( wnd, GWLP_USERDATA, (LONG_PTR)cs->lpCreateParams );
|
||||||
|
|
||||||
window->mWnd = wnd;
|
window->mWnd = wnd;
|
||||||
window->HandleCreate ( wparam, lparam );
|
window->HandleCreate ( wparam, lparam );
|
||||||
|
@ -1439,7 +1708,6 @@ LRESULT CALLBACK rvDebuggerWindow::WndProc ( HWND wnd, UINT msg, WPARAM wparam,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case IDC_DBG_CALLSTACK:
|
case IDC_DBG_CALLSTACK:
|
||||||
if ( hdr->code == NM_DBLCLK )
|
if ( hdr->code == NM_DBLCLK )
|
||||||
{
|
{
|
||||||
|
@ -1454,14 +1722,74 @@ LRESULT CALLBACK rvDebuggerWindow::WndProc ( HWND wnd, UINT msg, WPARAM wparam,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case IDC_DBG_SCRIPTLIST:
|
||||||
|
if ( hdr->code == NM_DBLCLK )
|
||||||
|
{
|
||||||
|
int sel = ListView_GetNextItem(hdr->hwndFrom, -1, LVNI_SELECTED);
|
||||||
|
|
||||||
|
if (sel != -1)
|
||||||
|
{
|
||||||
|
LVITEM item = { 0 };
|
||||||
|
char temp[1024] = { 0 };
|
||||||
|
item.mask = LVIF_TEXT;
|
||||||
|
item.pszText = temp;
|
||||||
|
item.cchTextMax = sizeof(temp) - 1;
|
||||||
|
item.iSubItem = 1;
|
||||||
|
item.iItem = sel;
|
||||||
|
|
||||||
|
ListView_GetItem(hdr->hwndFrom, &item);
|
||||||
|
|
||||||
|
if (strlen(item.pszText) > 0)
|
||||||
|
{
|
||||||
|
window->OpenScript(item.pszText);
|
||||||
|
window->UpdateScriptList();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case IDC_DBG_BREAKLIST:
|
||||||
|
if ( hdr->code == NM_DBLCLK || hdr->code == NM_CLICK ) {
|
||||||
|
LPNMITEMACTIVATE ia = (LPNMITEMACTIVATE)lparam;
|
||||||
|
int sel = ia->iItem;
|
||||||
|
if ( sel != -1 ) {
|
||||||
|
rvDebuggerBreakpoint* bp = window->mClient->GetBreakpoint( sel );
|
||||||
|
if ( bp != NULL ) {
|
||||||
|
if ( hdr->code == NM_DBLCLK ) {
|
||||||
|
// double clicked breakpoint => show it in its file
|
||||||
|
window->OpenScript( bp->GetFilename(), bp->GetLineNumber() - 1 );
|
||||||
|
} else if( ia->iSubItem == 0 ) {
|
||||||
|
// clicked breakpoint symbol => delete breakpoint
|
||||||
|
window->mClient->RemoveBreakpoint( bp->GetID() );
|
||||||
|
window->UpdateBreakpointList();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if ( hdr->code == LVN_KEYDOWN ) {
|
||||||
|
// when user selects a breakpoints and presses the Del key, remove the breakpoint
|
||||||
|
int sel = ListView_GetNextItem( hdr->hwndFrom, -1, LVNI_SELECTED );
|
||||||
|
if ( sel != -1 ) {
|
||||||
|
LPNMLVKEYDOWN kd = (LPNMLVKEYDOWN)lparam;
|
||||||
|
rvDebuggerBreakpoint* bp = window->mClient->GetBreakpoint( sel );
|
||||||
|
if ( kd->wVKey == VK_DELETE && bp != NULL ) {
|
||||||
|
window->mClient->RemoveBreakpoint( bp->GetID() );
|
||||||
|
window->UpdateBreakpointList();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
case IDC_DBG_TABS:
|
case IDC_DBG_TABS:
|
||||||
if ( hdr->code == TCN_SELCHANGE )
|
if ( hdr->code == TCN_SELCHANGE )
|
||||||
{
|
{
|
||||||
ShowWindow ( window->mWndOutput, SW_HIDE );
|
ShowWindow ( window->mWndOutput, SW_HIDE );
|
||||||
ShowWindow ( window->mWndConsole, SW_HIDE );
|
ShowWindow ( window->mWndConsole, SW_HIDE );
|
||||||
|
ShowWindow ( window->mWndConsoleInput, SW_HIDE );
|
||||||
ShowWindow ( window->mWndCallstack, SW_HIDE );
|
ShowWindow ( window->mWndCallstack, SW_HIDE );
|
||||||
ShowWindow ( window->mWndWatch, SW_HIDE );
|
ShowWindow ( window->mWndWatch, SW_HIDE );
|
||||||
ShowWindow ( window->mWndThreads, SW_HIDE );
|
ShowWindow ( window->mWndThreads, SW_HIDE );
|
||||||
|
ShowWindow ( window->mWndScriptList, SW_HIDE );
|
||||||
|
ShowWindow ( window->mWndBreakList, SW_HIDE );
|
||||||
switch ( TabCtrl_GetCurSel ( hdr->hwndFrom ) )
|
switch ( TabCtrl_GetCurSel ( hdr->hwndFrom ) )
|
||||||
{
|
{
|
||||||
case 0:
|
case 0:
|
||||||
|
@ -1470,6 +1798,7 @@ LRESULT CALLBACK rvDebuggerWindow::WndProc ( HWND wnd, UINT msg, WPARAM wparam,
|
||||||
|
|
||||||
case 1:
|
case 1:
|
||||||
ShowWindow ( window->mWndConsole, SW_SHOW );
|
ShowWindow ( window->mWndConsole, SW_SHOW );
|
||||||
|
ShowWindow( window->mWndConsoleInput, SW_SHOW );
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 2:
|
case 2:
|
||||||
|
@ -1483,6 +1812,14 @@ LRESULT CALLBACK rvDebuggerWindow::WndProc ( HWND wnd, UINT msg, WPARAM wparam,
|
||||||
case 4:
|
case 4:
|
||||||
ShowWindow ( window->mWndThreads, SW_SHOW );
|
ShowWindow ( window->mWndThreads, SW_SHOW );
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case 5:
|
||||||
|
ShowWindow(window->mWndScriptList, SW_SHOW);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 6:
|
||||||
|
ShowWindow( window->mWndBreakList, SW_SHOW );
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -1493,7 +1830,7 @@ LRESULT CALLBACK rvDebuggerWindow::WndProc ( HWND wnd, UINT msg, WPARAM wparam,
|
||||||
case WM_CLOSE:
|
case WM_CLOSE:
|
||||||
if ( window->mClient->IsConnected ( ) )
|
if ( window->mClient->IsConnected ( ) )
|
||||||
{
|
{
|
||||||
if ( IDNO == MessageBox ( wnd, "The debugger is currently connected to a running version of the game. Are you sure you want to close now?", "Quake 4 Script Debugger", MB_YESNO|MB_ICONQUESTION ) )
|
if ( IDNO == MessageBox ( wnd, "The debugger is currently connected to a running version of the game. Are you sure you want to close now?", "Dhewm3 Script Debugger", MB_YESNO|MB_ICONQUESTION ) )
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -1535,14 +1872,20 @@ rvDebuggerWindow::ProcessNetMessage
|
||||||
Process an incoming network message
|
Process an incoming network message
|
||||||
================
|
================
|
||||||
*/
|
*/
|
||||||
void rvDebuggerWindow::ProcessNetMessage ( msg_t* msg )
|
void rvDebuggerWindow::ProcessNetMessage ( idBitMsg* msg )
|
||||||
{
|
{
|
||||||
unsigned short command;
|
short command;
|
||||||
|
|
||||||
command = (unsigned short)MSG_ReadShort ( msg );
|
command = msg->ReadShort( );
|
||||||
|
|
||||||
switch ( command )
|
switch ( command )
|
||||||
{
|
{
|
||||||
|
case DBMSG_REMOVEBREAKPOINT:
|
||||||
|
MessageBeep(MB_ICONEXCLAMATION);
|
||||||
|
InvalidateRect(mWndScript, NULL, FALSE);
|
||||||
|
UpdateBreakpointList();
|
||||||
|
break;
|
||||||
|
|
||||||
case DBMSG_RESUMED:
|
case DBMSG_RESUMED:
|
||||||
UpdateTitle ( );
|
UpdateTitle ( );
|
||||||
UpdateToolbar ( );
|
UpdateToolbar ( );
|
||||||
|
@ -1554,9 +1897,9 @@ void rvDebuggerWindow::ProcessNetMessage ( msg_t* msg )
|
||||||
char temp2[1024];
|
char temp2[1024];
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
MSG_ReadShort ( msg );
|
msg->ReadShort ( );
|
||||||
MSG_ReadString ( msg, temp, 1024 );
|
msg->ReadString ( temp, 1024 );
|
||||||
MSG_ReadString ( msg, temp2, 1024 );
|
msg->ReadString ( temp2, 1024 );
|
||||||
if ( mTooltipVar.Icmp ( temp ) == 0 )
|
if ( mTooltipVar.Icmp ( temp ) == 0 )
|
||||||
{
|
{
|
||||||
mTooltipValue = temp2;
|
mTooltipValue = temp2;
|
||||||
|
@ -1624,10 +1967,17 @@ void rvDebuggerWindow::ProcessNetMessage ( msg_t* msg )
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case DBMSG_PRINT:
|
case DBMSG_PRINT:
|
||||||
|
{
|
||||||
|
HWND prevFocus = GetFocus();
|
||||||
|
SetFocus ( mWndConsole );
|
||||||
SendMessage ( mWndConsole, EM_SETSEL, -1, -1 );
|
SendMessage ( mWndConsole, EM_SETSEL, -1, -1 );
|
||||||
SendMessage ( mWndConsole, EM_REPLACESEL, 0, (LPARAM)(const char*)(msg->data) + msg->readcount );
|
SendMessage ( mWndConsole, EM_REPLACESEL, 0, (LPARAM)(const char*)(msg->GetData()) + msg->GetReadCount() );
|
||||||
|
SendMessage( mWndConsole, EM_SETSEL, -1, -1 );
|
||||||
SendMessage ( mWndConsole, EM_SCROLLCARET, 0, 0 );
|
SendMessage ( mWndConsole, EM_SCROLLCARET, 0, 0 );
|
||||||
|
UpdateWindow( mWndConsole );
|
||||||
|
SetFocus( prevFocus );
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case DBMSG_BREAK:
|
case DBMSG_BREAK:
|
||||||
{
|
{
|
||||||
|
@ -1636,6 +1986,7 @@ void rvDebuggerWindow::ProcessNetMessage ( msg_t* msg )
|
||||||
mCurrentStackDepth = 0;
|
mCurrentStackDepth = 0;
|
||||||
mClient->InspectVariable ( mTooltipVar, mCurrentStackDepth );
|
mClient->InspectVariable ( mTooltipVar, mCurrentStackDepth );
|
||||||
UpdateWatch ( );
|
UpdateWatch ( );
|
||||||
|
UpdateBreakpointList();
|
||||||
EnableWindows ( TRUE );
|
EnableWindows ( TRUE );
|
||||||
OpenScript ( mClient->GetBreakFilename(), mClient->GetBreakLineNumber() - 1 );
|
OpenScript ( mClient->GetBreakFilename(), mClient->GetBreakLineNumber() - 1 );
|
||||||
UpdateTitle ( );
|
UpdateTitle ( );
|
||||||
|
@ -1643,7 +1994,11 @@ void rvDebuggerWindow::ProcessNetMessage ( msg_t* msg )
|
||||||
SetForegroundWindow ( mWnd );
|
SetForegroundWindow ( mWnd );
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case DBMSG_INSPECTSCRIPTS:
|
||||||
|
{
|
||||||
|
UpdateScriptList ( );
|
||||||
|
break;
|
||||||
|
}
|
||||||
case DBMSG_INSPECTCALLSTACK:
|
case DBMSG_INSPECTCALLSTACK:
|
||||||
{
|
{
|
||||||
UpdateCallstack ( );
|
UpdateCallstack ( );
|
||||||
|
@ -1719,7 +2074,7 @@ Opens the script with the given filename and will scroll to the given line
|
||||||
number if one is specified
|
number if one is specified
|
||||||
================
|
================
|
||||||
*/
|
*/
|
||||||
bool rvDebuggerWindow::OpenScript ( const char* filename, int lineNumber )
|
bool rvDebuggerWindow::OpenScript ( const char* filename, int lineNumber, idProgram* program )
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
@ -1748,7 +2103,6 @@ bool rvDebuggerWindow::OpenScript ( const char* filename, int lineNumber )
|
||||||
// Load the script
|
// Load the script
|
||||||
if ( !script->Load ( filename ) )
|
if ( !script->Load ( filename ) )
|
||||||
{
|
{
|
||||||
delete script;
|
|
||||||
SetCursor ( LoadCursor ( NULL, IDC_ARROW ) );
|
SetCursor ( LoadCursor ( NULL, IDC_ARROW ) );
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -1777,7 +2131,7 @@ bool rvDebuggerWindow::OpenScript ( const char* filename, int lineNumber )
|
||||||
// Move to a specific line number?
|
// Move to a specific line number?
|
||||||
if ( lineNumber != -1 )
|
if ( lineNumber != -1 )
|
||||||
{
|
{
|
||||||
int c;
|
long c;
|
||||||
|
|
||||||
// Put the caret on the line number specified and scroll it into position.
|
// Put the caret on the line number specified and scroll it into position.
|
||||||
// This is a bit of a hack since we set the selection twice, but setting the
|
// This is a bit of a hack since we set the selection twice, but setting the
|
||||||
|
@ -1785,10 +2139,10 @@ bool rvDebuggerWindow::OpenScript ( const char* filename, int lineNumber )
|
||||||
// and then scroll before going back to (c,c).
|
// and then scroll before going back to (c,c).
|
||||||
// NOTE: We scroll to the line before the one we want so its more visible
|
// NOTE: We scroll to the line before the one we want so its more visible
|
||||||
SetFocus ( mWndScript );
|
SetFocus ( mWndScript );
|
||||||
c = SendMessage ( mWndScript, EM_LINEINDEX, lineNumber - 1, 0 );
|
c = SendMessage ( mWndScript, EM_LINEINDEX, (long)lineNumber - 1, 0 );
|
||||||
SendMessage ( mWndScript, EM_SETSEL, c, c + 1 );
|
SendMessage ( mWndScript, EM_SETSEL, c, c + 1 );
|
||||||
SendMessage ( mWndScript, EM_SCROLLCARET, 0, 0 );
|
SendMessage ( mWndScript, EM_SCROLLCARET, 0, 0 );
|
||||||
c = SendMessage ( mWndScript, EM_LINEINDEX, lineNumber, 0 );
|
c = SendMessage ( mWndScript, EM_LINEINDEX, (long)lineNumber, 0 );
|
||||||
SendMessage ( mWndScript, EM_SETSEL, c, c );
|
SendMessage ( mWndScript, EM_SETSEL, c, c );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -1843,6 +2197,8 @@ void rvDebuggerWindow::ToggleBreakpoint ( void )
|
||||||
|
|
||||||
// Force a repaint of the script window
|
// Force a repaint of the script window
|
||||||
InvalidateRect ( mWndScript, NULL, FALSE );
|
InvalidateRect ( mWndScript, NULL, FALSE );
|
||||||
|
|
||||||
|
UpdateBreakpointList();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -1895,6 +2251,8 @@ void rvDebuggerWindow::CreateToolbar ( void )
|
||||||
SendMessage( mWndToolbar, TB_ADDBITMAP, (WPARAM)4, (LPARAM) &tbab );
|
SendMessage( mWndToolbar, TB_ADDBITMAP, (WPARAM)4, (LPARAM) &tbab );
|
||||||
|
|
||||||
// Add the buttons to the toolbar
|
// Add the buttons to the toolbar
|
||||||
|
// FIXME: warning C4838: conversion from 'int' to 'BYTE' requires a narrowing conversion
|
||||||
|
// most probably because TBBUTTON has 4 more bytes in bReserved for alignment on _WIN64
|
||||||
TBBUTTON tbb[] = { { 0, 0, TBSTATE_ENABLED, BTNS_SEP, 0, 0, -1 },
|
TBBUTTON tbb[] = { { 0, 0, TBSTATE_ENABLED, BTNS_SEP, 0, 0, -1 },
|
||||||
{ 8, ID_DBG_FILE_OPEN, TBSTATE_ENABLED, BTNS_BUTTON, 0, 0, -1 },
|
{ 8, ID_DBG_FILE_OPEN, TBSTATE_ENABLED, BTNS_BUTTON, 0, 0, -1 },
|
||||||
{ 0, 0, TBSTATE_ENABLED, BTNS_SEP, 0, 0, -1 },
|
{ 0, 0, TBSTATE_ENABLED, BTNS_SEP, 0, 0, -1 },
|
||||||
|
@ -2013,6 +2371,7 @@ int rvDebuggerWindow::HandleActivate ( WPARAM wparam, LPARAM lparam )
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
UpdateBreakpointList();
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -2193,7 +2552,7 @@ then the last text used will be searched for.
|
||||||
*/
|
*/
|
||||||
bool rvDebuggerWindow::FindNext ( const char* text )
|
bool rvDebuggerWindow::FindNext ( const char* text )
|
||||||
{
|
{
|
||||||
int start;
|
long start;
|
||||||
FINDTEXT ft;
|
FINDTEXT ft;
|
||||||
|
|
||||||
if ( text )
|
if ( text )
|
||||||
|
@ -2230,7 +2589,7 @@ bool rvDebuggerWindow::FindNext ( const char* text )
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SendMessage ( mWndScript, EM_SETSEL, start, start + mFind.Length() );
|
SendMessage ( mWndScript, EM_SETSEL, start, start + (long)mFind.Length() );
|
||||||
SendMessage ( mWndScript, EM_SCROLLCARET, 0, 0 );
|
SendMessage ( mWndScript, EM_SCROLLCARET, 0, 0 );
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -2247,7 +2606,7 @@ then the last text used will be searched for.
|
||||||
*/
|
*/
|
||||||
bool rvDebuggerWindow::FindPrev ( const char* text )
|
bool rvDebuggerWindow::FindPrev ( const char* text )
|
||||||
{
|
{
|
||||||
int start;
|
long start;
|
||||||
FINDTEXT ft;
|
FINDTEXT ft;
|
||||||
|
|
||||||
if ( text )
|
if ( text )
|
||||||
|
|
|
@ -52,38 +52,57 @@ public:
|
||||||
rvDebuggerWindow ( );
|
rvDebuggerWindow ( );
|
||||||
~rvDebuggerWindow ( );
|
~rvDebuggerWindow ( );
|
||||||
|
|
||||||
bool Create ( HINSTANCE hInstance );
|
bool Create ( HINSTANCE hInstance );
|
||||||
|
|
||||||
static bool Activate ( void );
|
static bool Activate ( void );
|
||||||
|
|
||||||
void ProcessNetMessage ( msg_t* msg );
|
void ProcessNetMessage ( idBitMsg * msg );
|
||||||
|
|
||||||
void Printf ( const char* format, ... );
|
void Printf ( const char* format, ... );
|
||||||
|
|
||||||
HWND GetWindow ( void );
|
HWND GetWindow ( void );
|
||||||
|
|
||||||
void AddWatch ( const char* name, bool update = true );
|
void AddWatch ( const char* name, bool update = true );
|
||||||
|
|
||||||
HINSTANCE GetInstance ( void );
|
HINSTANCE GetInstance ( void );
|
||||||
|
|
||||||
protected:
|
private:
|
||||||
|
bool RegisterClass ( void );
|
||||||
|
void CreateToolbar ( void );
|
||||||
|
bool InitRecentFiles ( void );
|
||||||
|
|
||||||
bool FindPrev ( const char* text = NULL );
|
int HandleInitMenu ( WPARAM wParam, LPARAM lParam );
|
||||||
bool FindNext ( const char* text = NULL );
|
int HandleCommand ( WPARAM wParam, LPARAM lParam );
|
||||||
|
int HandleCreate ( WPARAM wparam, LPARAM lparam );
|
||||||
|
int HandleActivate ( WPARAM wparam, LPARAM lparam );
|
||||||
|
int HandleDrawItem ( WPARAM wparam, LPARAM lparam );
|
||||||
|
void HandleTooltipGetDispInfo( WPARAM wparam, LPARAM lparam );
|
||||||
|
|
||||||
void UpdateWatch ( void );
|
void ResizeImageList ( int& widthOut, int& heightOut);
|
||||||
void UpdateWindowMenu ( void );
|
static LRESULT CALLBACK WndProc ( HWND wnd, UINT msg, WPARAM wparam, LPARAM lparam );
|
||||||
void UpdateScript ( void );
|
static LRESULT CALLBACK MarginWndProc ( HWND wnd, UINT msg, WPARAM wparam, LPARAM lparam );
|
||||||
void UpdateToolbar ( void );
|
static LRESULT CALLBACK ScriptWndProc ( HWND wnd, UINT msg, WPARAM wparam, LPARAM lparam );
|
||||||
void UpdateTitle ( void );
|
static INT_PTR CALLBACK AboutDlgProc ( HWND wnd, UINT msg, WPARAM wparam, LPARAM lparam );
|
||||||
void UpdateCallstack ( void );
|
static int CALLBACK ScriptWordBreakProc( LPTSTR text, int current, int max, int action );
|
||||||
void UpdateRecentFiles ( void );
|
|
||||||
bool OpenScript ( const char* filename, int lineNumber = -1 );
|
|
||||||
void EnableWindows ( bool state );
|
|
||||||
|
|
||||||
int GetSelectedText ( idStr& text );
|
bool FindPrev ( const char* text = NULL );
|
||||||
|
bool FindNext ( const char* text = NULL );
|
||||||
|
|
||||||
void ToggleBreakpoint ( void );
|
void UpdateBreakpointList( void );
|
||||||
|
void UpdateScriptList ( void );
|
||||||
|
void UpdateWatch ( void );
|
||||||
|
void UpdateWindowMenu ( void );
|
||||||
|
void UpdateScript ( void );
|
||||||
|
void UpdateToolbar ( void );
|
||||||
|
void UpdateTitle ( void );
|
||||||
|
void UpdateCallstack ( void );
|
||||||
|
void UpdateRecentFiles ( void );
|
||||||
|
bool OpenScript ( const char* filename, int lineNumber = -1, idProgram* program = nullptr );
|
||||||
|
void EnableWindows ( bool state );
|
||||||
|
|
||||||
|
int GetSelectedText ( idStr& text );
|
||||||
|
|
||||||
|
void ToggleBreakpoint ( void );
|
||||||
|
|
||||||
HWND mWnd;
|
HWND mWnd;
|
||||||
HWND mWndScript;
|
HWND mWndScript;
|
||||||
|
@ -92,7 +111,10 @@ protected:
|
||||||
HWND mWndTabs;
|
HWND mWndTabs;
|
||||||
HWND mWndBorder;
|
HWND mWndBorder;
|
||||||
HWND mWndConsole;
|
HWND mWndConsole;
|
||||||
|
HWND mWndConsoleInput;
|
||||||
HWND mWndCallstack;
|
HWND mWndCallstack;
|
||||||
|
HWND mWndScriptList;
|
||||||
|
HWND mWndBreakList; // list of breakpoints
|
||||||
HWND mWndWatch;
|
HWND mWndWatch;
|
||||||
HWND mWndThreads;
|
HWND mWndThreads;
|
||||||
HWND mWndToolTips;
|
HWND mWndToolTips;
|
||||||
|
@ -108,6 +130,7 @@ protected:
|
||||||
|
|
||||||
HINSTANCE mInstance;
|
HINSTANCE mInstance;
|
||||||
HIMAGELIST mImageList;
|
HIMAGELIST mImageList;
|
||||||
|
HIMAGELIST mTmpImageList;
|
||||||
|
|
||||||
RECT mSplitterRect;
|
RECT mSplitterRect;
|
||||||
bool mSplitterDrag;
|
bool mSplitterDrag;
|
||||||
|
@ -129,25 +152,6 @@ protected:
|
||||||
rvDebuggerClient* mClient;
|
rvDebuggerClient* mClient;
|
||||||
|
|
||||||
rvDebuggerWatchList mWatches;
|
rvDebuggerWatchList mWatches;
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
bool RegisterClass ( void );
|
|
||||||
void CreateToolbar ( void );
|
|
||||||
bool InitRecentFiles ( void );
|
|
||||||
|
|
||||||
int HandleInitMenu ( WPARAM wParam, LPARAM lParam );
|
|
||||||
int HandleCommand ( WPARAM wParam, LPARAM lParam );
|
|
||||||
int HandleCreate ( WPARAM wparam, LPARAM lparam );
|
|
||||||
int HandleActivate ( WPARAM wparam, LPARAM lparam );
|
|
||||||
int HandleDrawItem ( WPARAM wparam, LPARAM lparam );
|
|
||||||
void HandleTooltipGetDispInfo ( WPARAM wparam, LPARAM lparam );
|
|
||||||
|
|
||||||
static LRESULT CALLBACK WndProc ( HWND wnd, UINT msg, WPARAM wparam, LPARAM lparam );
|
|
||||||
static LRESULT CALLBACK MarginWndProc ( HWND wnd, UINT msg, WPARAM wparam, LPARAM lparam );
|
|
||||||
static LRESULT CALLBACK ScriptWndProc ( HWND wnd, UINT msg, WPARAM wparam, LPARAM lparam );
|
|
||||||
static INT_PTR CALLBACK AboutDlgProc ( HWND wnd, UINT msg, WPARAM wparam, LPARAM lparam );
|
|
||||||
static int CALLBACK ScriptWordBreakProc ( LPTSTR text, int current, int max, int action );
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -26,26 +26,26 @@ If you have questions concerning this license or the applicable additional terms
|
||||||
===========================================================================
|
===========================================================================
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#if defined( ID_ALLOW_TOOLS )
|
||||||
#include "tools/edit_gui_common.h"
|
#include "tools/edit_gui_common.h"
|
||||||
|
|
||||||
|
|
||||||
#include "../../sys/win32/rc/debugger_resource.h"
|
#include "../../sys/win32/rc/debugger_resource.h"
|
||||||
#include "DebuggerApp.h"
|
#include "DebuggerApp.h"
|
||||||
|
#else
|
||||||
|
#include "debugger_common.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "DebuggerServer.h"
|
#include "DebuggerServer.h"
|
||||||
|
|
||||||
DWORD CALLBACK DebuggerThread ( LPVOID param );
|
#if defined( ID_ALLOW_TOOLS )
|
||||||
|
rvDebuggerApp gDebuggerApp; // this is also used in other source files
|
||||||
|
static HWND gDebuggerWindow = NULL;
|
||||||
|
#endif
|
||||||
|
|
||||||
rvDebuggerApp gDebuggerApp;
|
static rvDebuggerServer* gDebuggerServer = NULL;
|
||||||
HWND gDebuggerWindow = NULL;
|
static SDL_Thread* gDebuggerServerThread = NULL;
|
||||||
bool gDebuggerSuspend = false;
|
static bool gDebuggerServerQuit = false;
|
||||||
bool gDebuggerConnnected = false;
|
|
||||||
HANDLE gDebuggerGameThread = NULL;
|
|
||||||
|
|
||||||
rvDebuggerServer* gDebuggerServer = NULL;
|
|
||||||
HANDLE gDebuggerServerThread = NULL;
|
|
||||||
DWORD gDebuggerServerThreadID = 0;
|
|
||||||
bool gDebuggerServerQuit = false;
|
|
||||||
|
|
||||||
|
#if defined( ID_ALLOW_TOOLS )
|
||||||
/*
|
/*
|
||||||
================
|
================
|
||||||
DebuggerMain
|
DebuggerMain
|
||||||
|
@ -65,6 +65,9 @@ void DebuggerClientInit( const char *cmdline )
|
||||||
{
|
{
|
||||||
goto DebuggerClientInitDone;
|
goto DebuggerClientInitDone;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// hide the doom window by default
|
||||||
|
::ShowWindow( win32.hWnd, SW_HIDE );
|
||||||
|
|
||||||
gDebuggerApp.Run ( );
|
gDebuggerApp.Run ( );
|
||||||
|
|
||||||
|
@ -113,6 +116,7 @@ void DebuggerClientLaunch ( void )
|
||||||
CloseHandle ( process.hThread );
|
CloseHandle ( process.hThread );
|
||||||
CloseHandle ( process.hProcess );
|
CloseHandle ( process.hProcess );
|
||||||
}
|
}
|
||||||
|
#endif // #if defined( ID_ALLOW_TOOLS )
|
||||||
|
|
||||||
/*
|
/*
|
||||||
================
|
================
|
||||||
|
@ -121,14 +125,14 @@ DebuggerServerThread
|
||||||
Thread proc for the debugger server
|
Thread proc for the debugger server
|
||||||
================
|
================
|
||||||
*/
|
*/
|
||||||
DWORD CALLBACK DebuggerServerThread ( LPVOID param )
|
static int SDLCALL DebuggerServerThread ( void *param )
|
||||||
{
|
{
|
||||||
assert ( gDebuggerServer );
|
assert ( gDebuggerServer );
|
||||||
|
|
||||||
while ( !gDebuggerServerQuit )
|
while ( !gDebuggerServerQuit )
|
||||||
{
|
{
|
||||||
gDebuggerServer->ProcessMessages ( );
|
gDebuggerServer->ProcessMessages ( );
|
||||||
Sleep ( 1 );
|
SDL_Delay( 1 );
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -143,8 +147,17 @@ Starts up the debugger server
|
||||||
*/
|
*/
|
||||||
bool DebuggerServerInit ( void )
|
bool DebuggerServerInit ( void )
|
||||||
{
|
{
|
||||||
|
com_enableDebuggerServer.ClearModified( );
|
||||||
|
|
||||||
|
if ( !com_debuggerSupported )
|
||||||
|
{
|
||||||
|
common->Warning( "Called DebuggerServerInit() without the gameDLL supporting it!\n" );
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// Dont do this if we are in the debugger already
|
// Dont do this if we are in the debugger already
|
||||||
if ( com_editors & EDITOR_DEBUGGER )
|
if ( gDebuggerServer != NULL
|
||||||
|
|| ( com_editors & EDITOR_DEBUGGER ) )
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -163,9 +176,13 @@ bool DebuggerServerInit ( void )
|
||||||
gDebuggerServer = NULL;
|
gDebuggerServer = NULL;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Start the debugger server thread
|
// Start the debugger server thread
|
||||||
gDebuggerServerThread = CreateThread ( NULL, 0, DebuggerServerThread, 0, 0, &gDebuggerServerThreadID );
|
#if SDL_VERSION_ATLEAST(2, 0, 0)
|
||||||
|
gDebuggerServerThread = SDL_CreateThread( DebuggerServerThread, "DebuggerServer", NULL );
|
||||||
|
#else // SDL 1.2
|
||||||
|
gDebuggerServerThread = SDL_CreateThread( DebuggerServerThread, NULL );
|
||||||
|
#endif
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -179,13 +196,14 @@ Shuts down the debugger server
|
||||||
*/
|
*/
|
||||||
void DebuggerServerShutdown ( void )
|
void DebuggerServerShutdown ( void )
|
||||||
{
|
{
|
||||||
if ( gDebuggerServerThread )
|
if ( gDebuggerServerThread != NULL )
|
||||||
{
|
{
|
||||||
// Signal the debugger server to quit
|
// Signal the debugger server to quit
|
||||||
gDebuggerServerQuit = true;
|
gDebuggerServerQuit = true;
|
||||||
|
|
||||||
// Wait for the thread to finish
|
// Wait for the thread to finish
|
||||||
WaitForSingleObject ( gDebuggerServerThread, INFINITE );
|
SDL_WaitThread( gDebuggerServerThread, NULL );
|
||||||
|
gDebuggerServerThread = NULL;
|
||||||
|
|
||||||
// Shutdown the server now
|
// Shutdown the server now
|
||||||
gDebuggerServer->Shutdown();
|
gDebuggerServer->Shutdown();
|
||||||
|
@ -193,10 +211,10 @@ void DebuggerServerShutdown ( void )
|
||||||
delete gDebuggerServer;
|
delete gDebuggerServer;
|
||||||
gDebuggerServer = NULL;
|
gDebuggerServer = NULL;
|
||||||
|
|
||||||
// Cleanup the thread handle
|
com_editors &= ~EDITOR_DEBUGGER;
|
||||||
CloseHandle ( gDebuggerServerThread );
|
|
||||||
gDebuggerServerThread = NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
com_enableDebuggerServer.ClearModified( );
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
162
neo/tools/debugger/debugger_common.h
Normal file
162
neo/tools/debugger/debugger_common.h
Normal file
|
@ -0,0 +1,162 @@
|
||||||
|
// header that includes all the other needed headers, replacement for precompiled.h (only used by debugger)
|
||||||
|
// this could be cleaned up more.
|
||||||
|
|
||||||
|
#ifndef DEBUGGER_COMMON_H
|
||||||
|
#define DEBUGGER_COMMON_H
|
||||||
|
|
||||||
|
#include "framework/Game.h"
|
||||||
|
|
||||||
|
// non-portable system services
|
||||||
|
#include "sys/platform.h"
|
||||||
|
#include "sys/sys_public.h"
|
||||||
|
|
||||||
|
// id lib
|
||||||
|
#include "idlib/Lib.h"
|
||||||
|
|
||||||
|
// memory management and arrays
|
||||||
|
#include "idlib/Heap.h"
|
||||||
|
#include "idlib/containers/List.h"
|
||||||
|
|
||||||
|
// math
|
||||||
|
#include "idlib/math/Simd.h"
|
||||||
|
#include "idlib/math/Math.h"
|
||||||
|
#include "idlib/math/Random.h"
|
||||||
|
#include "idlib/math/Complex.h"
|
||||||
|
#include "idlib/math/Vector.h"
|
||||||
|
#include "idlib/math/Matrix.h"
|
||||||
|
#include "idlib/math/Angles.h"
|
||||||
|
#include "idlib/math/Quat.h"
|
||||||
|
#include "idlib/math/Rotation.h"
|
||||||
|
#include "idlib/math/Plane.h"
|
||||||
|
#include "idlib/math/Pluecker.h"
|
||||||
|
#include "idlib/math/Polynomial.h"
|
||||||
|
#include "idlib/math/Extrapolate.h"
|
||||||
|
#include "idlib/math/Interpolate.h"
|
||||||
|
#include "idlib/math/Curve.h"
|
||||||
|
#include "idlib/math/Ode.h"
|
||||||
|
#include "idlib/math/Lcp.h"
|
||||||
|
|
||||||
|
// bounding volumes
|
||||||
|
#include "idlib/bv/Sphere.h"
|
||||||
|
#include "idlib/bv/Bounds.h"
|
||||||
|
#include "idlib/bv/Box.h"
|
||||||
|
#include "idlib/bv/Frustum.h"
|
||||||
|
|
||||||
|
// geometry
|
||||||
|
#include "idlib/geometry/DrawVert.h"
|
||||||
|
#include "idlib/geometry/JointTransform.h"
|
||||||
|
#include "idlib/geometry/Winding.h"
|
||||||
|
#include "idlib/geometry/Winding2D.h"
|
||||||
|
#include "idlib/geometry/Surface.h"
|
||||||
|
#include "idlib/geometry/Surface_Patch.h"
|
||||||
|
#include "idlib/geometry/Surface_Polytope.h"
|
||||||
|
#include "idlib/geometry/Surface_SweptSpline.h"
|
||||||
|
#include "idlib/geometry/TraceModel.h"
|
||||||
|
|
||||||
|
// text manipulation
|
||||||
|
#include "idlib/Str.h"
|
||||||
|
#include "idlib/Token.h"
|
||||||
|
#include "idlib/Lexer.h"
|
||||||
|
#include "idlib/Parser.h"
|
||||||
|
#include "idlib/Base64.h"
|
||||||
|
#include "idlib/CmdArgs.h"
|
||||||
|
|
||||||
|
// containers
|
||||||
|
#include "idlib/containers/BTree.h"
|
||||||
|
#include "idlib/containers/BinSearch.h"
|
||||||
|
#include "idlib/containers/HashIndex.h"
|
||||||
|
#include "idlib/containers/HashTable.h"
|
||||||
|
#include "idlib/containers/StaticList.h"
|
||||||
|
#include "idlib/containers/LinkList.h"
|
||||||
|
#include "idlib/containers/Hierarchy.h"
|
||||||
|
#include "idlib/containers/Queue.h"
|
||||||
|
#include "idlib/containers/Stack.h"
|
||||||
|
#include "idlib/containers/StrList.h"
|
||||||
|
#include "idlib/containers/StrPool.h"
|
||||||
|
#include "idlib/containers/VectorSet.h"
|
||||||
|
#include "idlib/containers/PlaneSet.h"
|
||||||
|
|
||||||
|
// hashing
|
||||||
|
#include "idlib/hashing/CRC32.h"
|
||||||
|
#include "idlib/hashing/MD4.h"
|
||||||
|
#include "idlib/hashing/MD5.h"
|
||||||
|
|
||||||
|
// misc
|
||||||
|
#include "idlib/Dict.h"
|
||||||
|
#include "idlib/LangDict.h"
|
||||||
|
#include "idlib/BitMsg.h"
|
||||||
|
#include "idlib/MapFile.h"
|
||||||
|
#include "idlib/Timer.h"
|
||||||
|
|
||||||
|
// framework
|
||||||
|
#include "framework/BuildVersion.h"
|
||||||
|
#include "framework/Licensee.h"
|
||||||
|
#include "framework/CmdSystem.h"
|
||||||
|
#include "framework/CVarSystem.h"
|
||||||
|
#include "framework/Common.h"
|
||||||
|
#include "framework/File.h"
|
||||||
|
#include "framework/FileSystem.h"
|
||||||
|
#include "framework/UsercmdGen.h"
|
||||||
|
|
||||||
|
// decls
|
||||||
|
#include "framework/DeclManager.h"
|
||||||
|
#include "framework/DeclTable.h"
|
||||||
|
#include "framework/DeclSkin.h"
|
||||||
|
#include "framework/DeclEntityDef.h"
|
||||||
|
#include "framework/DeclFX.h"
|
||||||
|
#include "framework/DeclParticle.h"
|
||||||
|
#include "framework/DeclAF.h"
|
||||||
|
#include "framework/DeclPDA.h"
|
||||||
|
|
||||||
|
// We have expression parsing and evaluation code in multiple places:
|
||||||
|
// materials, sound shaders, and guis. We should unify them.
|
||||||
|
|
||||||
|
// renderer
|
||||||
|
#include "renderer/qgl.h"
|
||||||
|
#include "renderer/Cinematic.h"
|
||||||
|
#include "renderer/Material.h"
|
||||||
|
#include "renderer/Model.h"
|
||||||
|
#include "renderer/ModelManager.h"
|
||||||
|
#include "renderer/RenderSystem.h"
|
||||||
|
#include "renderer/RenderWorld.h"
|
||||||
|
|
||||||
|
// sound engine
|
||||||
|
#include "sound/sound.h"
|
||||||
|
|
||||||
|
// asynchronous networking
|
||||||
|
#include "framework/async/NetworkSystem.h"
|
||||||
|
|
||||||
|
// user interfaces
|
||||||
|
#include "ui/ListGUI.h"
|
||||||
|
#include "ui/UserInterface.h"
|
||||||
|
|
||||||
|
// collision detection system
|
||||||
|
#include "cm/CollisionModel.h"
|
||||||
|
|
||||||
|
// AAS files and manager
|
||||||
|
#include "tools/compilers/aas/AASFile.h"
|
||||||
|
#include "tools/compilers/aas/AASFileManager.h"
|
||||||
|
|
||||||
|
// game interface
|
||||||
|
#include "framework/Game.h"
|
||||||
|
|
||||||
|
//-----------------------------------------------------
|
||||||
|
|
||||||
|
#include "framework/DemoChecksum.h"
|
||||||
|
|
||||||
|
// framework
|
||||||
|
#include "framework/Compressor.h"
|
||||||
|
#include "framework/EventLoop.h"
|
||||||
|
#include "framework/KeyInput.h"
|
||||||
|
#include "framework/EditField.h"
|
||||||
|
#include "framework/Console.h"
|
||||||
|
#include "framework/DemoFile.h"
|
||||||
|
#include "framework/Session.h"
|
||||||
|
|
||||||
|
// asynchronous networking
|
||||||
|
#include "framework/async/AsyncNetwork.h"
|
||||||
|
|
||||||
|
// Compilers for map, model, video etc. processing.
|
||||||
|
#include "tools/compilers/compiler_public.h"
|
||||||
|
|
||||||
|
#endif // DEBUGGER_COMMON_H
|
|
@ -67,10 +67,6 @@ bool GUIEditorHandleMessage( void *msg ) { return false; }
|
||||||
|
|
||||||
void DebuggerClientLaunch( void ) {}
|
void DebuggerClientLaunch( void ) {}
|
||||||
void DebuggerClientInit( const char *cmdline ) { common->Printf( "The Script Debugger Client only runs on Win32\n" ); }
|
void DebuggerClientInit( const char *cmdline ) { common->Printf( "The Script Debugger Client only runs on Win32\n" ); }
|
||||||
bool DebuggerServerInit( void ) { return false; }
|
|
||||||
void DebuggerServerShutdown( void ) {}
|
|
||||||
void DebuggerServerPrint( const char *text ) {}
|
|
||||||
void DebuggerServerCheckBreakpoint( idInterpreter *interpreter, idProgram *program, int instructionPointer ) {}
|
|
||||||
|
|
||||||
void PDAEditorInit( const idDict *spawnArgs ) { common->Printf( "The PDA editor only runs on Win32\n" ); }
|
void PDAEditorInit( const idDict *spawnArgs ) { common->Printf( "The PDA editor only runs on Win32\n" ); }
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue