diff options
Diffstat (limited to 'engines/sword2/debug.cpp')
-rw-r--r-- | engines/sword2/debug.cpp | 377 |
1 files changed, 377 insertions, 0 deletions
diff --git a/engines/sword2/debug.cpp b/engines/sword2/debug.cpp new file mode 100644 index 0000000000..53fc200241 --- /dev/null +++ b/engines/sword2/debug.cpp @@ -0,0 +1,377 @@ +/* Copyright (C) 1994-1998 Revolution Software Ltd. + * Copyright (C) 2003-2006 The ScummVM project + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * $URL$ + * $Id$ + */ + +#include "common/stdafx.h" +#include "sword2/sword2.h" +#include "sword2/console.h" +#include "sword2/defs.h" +#include "sword2/logic.h" +#include "sword2/maketext.h" +#include "sword2/memory.h" +#include "sword2/mouse.h" +#include "sword2/resman.h" +#include "sword2/router.h" + +namespace Sword2 { + +void Debugger::clearDebugTextBlocks() { + uint8 blockNo = 0; + + while (blockNo < MAX_DEBUG_TEXTS && _debugTextBlocks[blockNo] > 0) { + // kill the system text block + _vm->_fontRenderer->killTextBloc(_debugTextBlocks[blockNo]); + + // clear this element of our array of block numbers + _debugTextBlocks[blockNo] = 0; + + blockNo++; + } +} + +void Debugger::makeDebugTextBlock(char *text, int16 x, int16 y) { + uint8 blockNo = 0; + + while (blockNo < MAX_DEBUG_TEXTS && _debugTextBlocks[blockNo] > 0) + blockNo++; + + assert(blockNo < MAX_DEBUG_TEXTS); + + _debugTextBlocks[blockNo] = _vm->_fontRenderer->buildNewBloc((byte *)text, x, y, 640 - x, 0, RDSPR_DISPLAYALIGN, CONSOLE_FONT_ID, NO_JUSTIFICATION); +} + +void Debugger::buildDebugText() { + char buf[128]; + + int32 showVarNo; // for variable watching + int32 showVarPos; + int32 varNo; + + ScreenInfo *screenInfo = _vm->_screen->getScreenInfo(); + + // clear the array of text block numbers for the debug text + clearDebugTextBlocks(); + + // mouse coords + // print mouse coords beside mouse-marker, if it's being displayed + if (_displayMouseMarker) { + int mouseX, mouseY; + + _vm->_mouse->getPos(mouseX, mouseY); + + sprintf(buf, "%d,%d", mouseX + screenInfo->scroll_offset_x, mouseY + screenInfo->scroll_offset_y); + if (mouseX > 560) + makeDebugTextBlock(buf, mouseX - 50, mouseY - 15); + else + makeDebugTextBlock(buf, mouseX + 5, mouseY - 15); + } + + // mouse area coords + + // defining a mouse area the easy way, by creating a box on-screen + if (_draggingRectangle || _vm->_logic->readVar(SYSTEM_TESTING_ANIMS)) { + // so we can see what's behind the lines + _rectFlicker = !_rectFlicker; + + sprintf(buf, "x1=%d", _rectX1); + makeDebugTextBlock(buf, 0, 120); + + sprintf(buf, "y1=%d", _rectY1); + makeDebugTextBlock(buf, 0, 135); + + sprintf(buf, "x2=%d", _rectX2); + makeDebugTextBlock(buf, 0, 150); + + sprintf(buf, "y2=%d", _rectY2); + makeDebugTextBlock(buf, 0, 165); + } + + // testingSnR indicator + + if (_testingSnR) { // see fnAddHuman() + sprintf(buf, "TESTING LOGIC STABILITY!"); + makeDebugTextBlock(buf, 0, 105); + } + +#ifdef SWORD2_DEBUG + // speed-up indicator + + if (_vm->_renderSkip) { // see sword2.cpp + sprintf(buf, "SKIPPING FRAMES FOR SPEED-UP!"); + makeDebugTextBlock(buf, 0, 120); + } +#endif + + // debug info at top of screen - enabled/disabled as one complete unit + + if (_displayTime) { + int32 time = _vm->getMillis(); + + if ((time - _startTime) / 1000 >= 10000) + _startTime = time; + + time -= _startTime; + sprintf(buf, "Time %.2d:%.2d:%.2d.%.3d", (time / 3600000) % 60, (time / 60000) % 60, (time / 1000) % 60, time % 1000); + makeDebugTextBlock(buf, 500, 360); + sprintf(buf, "Game %d", _vm->_gameCycle); + makeDebugTextBlock(buf, 500, 380); + } + + // current text number & speech-sample resource id + + if (_displayTextNumbers) { + if (_textNumber) { + if (_vm->_logic->readVar(SYSTEM_TESTING_TEXT)) { + if (_vm->_logic->readVar(SYSTEM_WANT_PREVIOUS_LINE)) + sprintf(buf, "backwards"); + else + sprintf(buf, "forwards"); + + makeDebugTextBlock(buf, 0, 340); + } + + sprintf(buf, "res: %d", _textNumber / SIZE); + makeDebugTextBlock(buf, 0, 355); + + sprintf(buf, "pos: %d", _textNumber & 0xffff); + makeDebugTextBlock(buf, 0, 370); + + sprintf(buf, "TEXT: %d", _vm->_logic->_officialTextNumber); + makeDebugTextBlock(buf, 0, 385); + } + } + + // resource number currently being checking for animation + + if (_vm->_logic->readVar(SYSTEM_TESTING_ANIMS)) { + sprintf(buf, "trying resource %d", _vm->_logic->readVar(SYSTEM_TESTING_ANIMS)); + makeDebugTextBlock(buf, 0, 90); + } + + // general debug info + + if (_displayDebugText) { + byte name[NAME_LEN]; + +/* + // CD in use + sprintf(buf, "CD-%d", currentCD); + makeDebugTextBlock(buf, 0, 0); +*/ + + // mouse coords & object pointed to + + if (_vm->_logic->readVar(CLICKED_ID)) + sprintf(buf, "last click at %d,%d (id %d: %s)", + _vm->_logic->readVar(MOUSE_X), + _vm->_logic->readVar(MOUSE_Y), + _vm->_logic->readVar(CLICKED_ID), + _vm->_resman->fetchName(_vm->_logic->readVar(CLICKED_ID), name)); + else + sprintf(buf, "last click at %d,%d (---)", + _vm->_logic->readVar(MOUSE_X), + _vm->_logic->readVar(MOUSE_Y)); + + makeDebugTextBlock(buf, 0, 15); + + uint32 mouseTouching = _vm->_mouse->getMouseTouching(); + + int mouseX, mouseY; + + _vm->_mouse->getPos(mouseX, mouseY); + + if (mouseTouching) + sprintf(buf, "mouse %d,%d (id %d: %s)", + mouseX + screenInfo->scroll_offset_x, + mouseY + screenInfo->scroll_offset_y, + mouseTouching, + _vm->_resman->fetchName(mouseTouching, name)); + else + sprintf(buf, "mouse %d,%d (not touching)", + mouseX + screenInfo->scroll_offset_x, + mouseY + screenInfo->scroll_offset_y); + + makeDebugTextBlock(buf, 0, 30); + + // player coords & graphic info + // if player objct has a graphic + + if (_graphAnimRes) + sprintf(buf, "player %d,%d %s (%d) #%d/%d", + screenInfo->player_feet_x, + screenInfo->player_feet_y, + _vm->_resman->fetchName(_graphAnimRes, name), + _graphAnimRes, + _graphAnimPc, + _graphNoFrames); + else + sprintf(buf, "player %d,%d --- %d", + screenInfo->player_feet_x, + screenInfo->player_feet_y, + _graphAnimPc); + + makeDebugTextBlock(buf, 0, 45); + + // frames-per-second counter + + sprintf(buf, "fps %d", _vm->_screen->getFps()); + makeDebugTextBlock(buf, 440, 0); + + // location number + + sprintf(buf, "location=%d", _vm->_logic->readVar(LOCATION)); + makeDebugTextBlock(buf, 440, 15); + + // "result" variable + + sprintf(buf, "result=%d", _vm->_logic->readVar(RESULT)); + makeDebugTextBlock(buf, 440, 30); + + // no. of events in event list + + sprintf(buf, "events=%d", _vm->_logic->countEvents()); + makeDebugTextBlock(buf, 440, 45); + + // sprite list usage + + sprintf(buf, "bgp0: %d/%d", _vm->_screen->getCurBgp0(), MAX_bgp0_sprites); + makeDebugTextBlock(buf, 560, 0); + + sprintf(buf, "bgp1: %d/%d", _vm->_screen->getCurBgp1(), MAX_bgp1_sprites); + makeDebugTextBlock(buf, 560, 15); + + sprintf(buf, "back: %d/%d", _vm->_screen->getCurBack(), MAX_back_sprites); + makeDebugTextBlock(buf, 560, 30); + + sprintf(buf, "sort: %d/%d", _vm->_screen->getCurSort(), MAX_sort_sprites); + makeDebugTextBlock(buf, 560, 45); + + sprintf(buf, "fore: %d/%d", _vm->_screen->getCurFore(), MAX_fore_sprites); + makeDebugTextBlock(buf, 560, 60); + + sprintf(buf, "fgp0: %d/%d", _vm->_screen->getCurFgp0(), MAX_fgp0_sprites); + makeDebugTextBlock(buf, 560, 75); + + sprintf(buf, "fgp1: %d/%d", _vm->_screen->getCurFgp1(), MAX_fgp1_sprites); + makeDebugTextBlock(buf, 560, 90); + + // largest layer & sprite + + // NB. Strings already constructed in Build_display.cpp + makeDebugTextBlock(_vm->_screen->getLargestLayerInfo(), 0, 60); + makeDebugTextBlock(_vm->_screen->getLargestSpriteInfo(), 0, 75); + + // "waiting for person" indicator - set form fnTheyDo and + // fnTheyDoWeWait + + if (_speechScriptWaiting) { + sprintf(buf, "script waiting for %s (%d)", + _vm->_resman->fetchName(_speechScriptWaiting, name), + _speechScriptWaiting); + makeDebugTextBlock(buf, 0, 90); + } + + // variable watch display + + showVarPos = 115; // y-coord for first showVar + + for (showVarNo = 0; showVarNo < MAX_SHOWVARS; showVarNo++) { + varNo = _showVar[showVarNo]; // get variable number + + // if non-zero ie. cannot watch 'id' but not needed + // anyway because it changes throughout the logic loop + + if (varNo) { + sprintf(buf, "var(%d) = %d", varNo, _vm->_logic->readVar(varNo)); + makeDebugTextBlock(buf, 530, showVarPos); + showVarPos += 15; // next line down + } + } + + // memory indicator - this should come last, to show all the + // sprite blocks above! + + uint32 totAlloc = _vm->_memory->getTotAlloc(); + int16 numBlocks = _vm->_memory->getNumBlocks(); + + if (totAlloc < 1024) + sprintf(buf, "%u bytes in %d memory blocks", totAlloc, numBlocks); + else if (totAlloc < 1024 * 1024) + sprintf(buf, "%uK in %d memory blocks", totAlloc / 1024, numBlocks); + else + sprintf(buf, "%.02fM in %d memory blocks", totAlloc / 1048576., numBlocks); + + makeDebugTextBlock(buf, 0, 0); + } +} + +void Debugger::drawDebugGraphics() { + ScreenInfo *screenInfo = _vm->_screen->getScreenInfo(); + // walk-grid + + if (_displayWalkGrid) + _vm->_logic->_router->plotWalkGrid(); + + // player feet coord marker + + if (_displayPlayerMarker) + plotCrossHair(screenInfo->player_feet_x, screenInfo->player_feet_y, 215); + + // mouse marker & coords + + if (_displayMouseMarker) { + int mouseX, mouseY; + + _vm->_mouse->getPos(mouseX, mouseY); + + plotCrossHair(mouseX + screenInfo->scroll_offset_x, mouseY + screenInfo->scroll_offset_y, 215); + } + + // mouse area rectangle / sprite box rectangle when testing anims + + if (_vm->_logic->readVar(SYSTEM_TESTING_ANIMS)) { + // draw box around current frame + drawRect(_rectX1, _rectY1, _rectX2, _rectY2, 184); + } else if (_draggingRectangle) { + // defining a mouse area the easy way, by creating a box + // on-screen + if (_rectFlicker) + drawRect(_rectX1, _rectY1, _rectX2, _rectY2, 184); + } +} + +void Debugger::plotCrossHair(int16 x, int16 y, uint8 pen) { + _vm->_screen->plotPoint(x, y, pen); + + _vm->_screen->drawLine(x - 2, y, x - 5, y, pen); + _vm->_screen->drawLine(x + 2, y, x + 5, y, pen); + + _vm->_screen->drawLine(x, y - 2, x, y - 5, pen); + _vm->_screen->drawLine(x, y + 2, x, y + 5, pen); +} + +void Debugger::drawRect(int16 x1, int16 y1, int16 x2, int16 y2, uint8 pen) { + _vm->_screen->drawLine(x1, y1, x2, y1, pen); // top edge + _vm->_screen->drawLine(x1, y2, x2, y2, pen); // bottom edge + _vm->_screen->drawLine(x1, y1, x1, y2, pen); // left edge + _vm->_screen->drawLine(x2, y1, x2, y2, pen); // right edge +} + +} // End of namespace Sword2 |