From 4ce275c3814b40de6c6f471df1fdcf1720daecce Mon Sep 17 00:00:00 2001 From: Daniel Evans Date: Mon, 6 Jul 2015 00:54:13 +0100 Subject: [PATCH] Improve debug server functionality and appearence --- rwengine/include/script/ScriptMachine.hpp | 2 + rwengine/src/engine/SaveGame.cpp | 1 + rwgame/RWGame.cpp | 10 ++ rwgame/debug/HttpServer.cpp | 186 ++++++++++++++++++++-- rwgame/debug/HttpServer.hpp | 9 +- 5 files changed, 196 insertions(+), 12 deletions(-) diff --git a/rwengine/include/script/ScriptMachine.hpp b/rwengine/include/script/ScriptMachine.hpp index 1a68277a..76c3db82 100644 --- a/rwengine/include/script/ScriptMachine.hpp +++ b/rwengine/include/script/ScriptMachine.hpp @@ -174,6 +174,8 @@ public: SCMFile* getFile() const { return _file; } + SCMOpcodes* getOpcodes() const { return _ops; } + void startThread(SCMThread::pc_t start, bool mission = false); std::vector& getThreads() { return _activeThreads; } diff --git a/rwengine/src/engine/SaveGame.cpp b/rwengine/src/engine/SaveGame.cpp index 8202a93f..d84c1c18 100644 --- a/rwengine/src/engine/SaveGame.cpp +++ b/rwengine/src/engine/SaveGame.cpp @@ -415,6 +415,7 @@ bool SaveGame::loadGame(GameState& state, const std::string& file) state.script->startThread(scripts[s].programCounter); SCMThread& thread = threads.back(); // thread.baseAddress // ?? + strncpy(thread.name, scripts[s].name, sizeof(SCMThread::name)-1); thread.conditionResult = scripts[s].ifFlag; thread.conditionCount = scripts[s].ifNumber; thread.stackDepth = scripts[s].stackCounter; diff --git a/rwgame/RWGame.cpp b/rwgame/RWGame.cpp index e9154ec3..c64c2739 100644 --- a/rwgame/RWGame.cpp +++ b/rwgame/RWGame.cpp @@ -225,6 +225,11 @@ void RWGame::startScript(const std::string& name) opcodes->modules.push_back(new ObjectModule); script = new ScriptMachine(state, f, opcodes); + + /* If Debug server is available, break on the first opcode executed */ + if( httpserver ) { + script->interuptNext(); + } // Set up breakpoint handler script->setBreakpointHandler( @@ -328,6 +333,11 @@ int RWGame::run() window.display(); } + if( httpserver_thread ) + { + httpserver_thread->join(); + } + return 0; } diff --git a/rwgame/debug/HttpServer.cpp b/rwgame/debug/HttpServer.cpp index b35b2691..46b0f191 100644 --- a/rwgame/debug/HttpServer.cpp +++ b/rwgame/debug/HttpServer.cpp @@ -24,6 +24,12 @@ app.controller('DebugCtrl', function($scope,$http) { $scope.refresh(); }); } + $scope.step = function() { + var promise = $http.get('/step') + .success(function(data, status, headers, config) { + $scope.refresh(); + }); + } $scope.continue = function() { var promise = $http.get('/continue') .success(function(data, status, headers, config) { @@ -39,13 +45,32 @@ const char* src_page = R"(

OpenRW Debugger

- +
+ + + +
Game is running

Threads

@@ -54,6 +79,35 @@ const char* src_page = R"(

{{thread.name}}

program counter: {{thread.program_counter}}
wake counter: {{thread.wake_counter}} ms
+

Return Stack

+
    +
  1. + Address {{return_address}} +
  2. +
+

Disassembly

+
+
+ + {{ call.address }} + + + {{call.function }} + + + ( + + {{param.value}}, + + ) + +
+
+
    +
  1. + Address {{return_address}} +
  2. +
@@ -68,12 +122,12 @@ HttpServer::HttpServer(RWGame* game, GameWorld* world) void HttpServer::run() { - listener.listen(8091); - listener.reuse(); + listener.create(); + listener.listen(8091); std::cout << "STARTING HTTP SERVER" << std::endl; - while (true) { + while ( game->getWindow().isOpen() ) { sf::TcpSocket client; if (listener.accept(client) == sf::Socket::Done) { std::cout << "New connection from " @@ -113,6 +167,114 @@ void HttpServer::handleBreakpoint(const SCMBreakpoint &bp) // Do nothing } } +std::string thread_stack(SCMThread& th) +{ + std::stringstream ss; + for(unsigned int i = 0; i < th.stackDepth; ++i) + { + bool last = (th.stackDepth == i+1); + ss << th.calls[i] + << (last ? "" : ","); + } + return ss.str(); +} + +#include