Files
scummvm/engines/twine/debugger/debug_scene.cpp
T

225 lines
11 KiB
C++

/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* 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 3 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, see <http://www.gnu.org/licenses/>.
*
*/
#include "twine/debugger/debug_scene.h"
#include "twine/menu/interface.h"
#include "twine/menu/menu.h"
#include "twine/renderer/redraw.h"
#include "twine/renderer/renderer.h"
#include "twine/scene/grid.h"
#include "twine/scene/scene.h"
#include "twine/text.h"
#include "twine/twine.h"
namespace TwinE {
DebugScene::DebugScene(TwinEEngine *engine) : _engine(engine) {}
void DebugScene::drawClip(const Common::Rect &rect) {
if (!_showingClips) {
return;
}
_engine->_menu->drawRectBorders(rect);
}
void DebugScene::projectBoundingBoxPoints(IVec3 *pPoint3d, IVec3 *pPoint3dProjected) {
*pPoint3dProjected = _engine->_renderer->projectPositionOnScreen(*pPoint3d);
}
bool DebugScene::checkZoneType(ZoneType type) const {
switch (type) {
case ZoneType::kCube:
return (_typeZones & 0x01) != 0;
case ZoneType::kCamera:
return (_typeZones & 0x02) != 0;
case ZoneType::kSceneric:
return (_typeZones & 0x04) != 0;
case ZoneType::kGrid:
return (_typeZones & 0x08) != 0;
case ZoneType::kObject:
return (_typeZones & 0x10) != 0;
case ZoneType::kText:
return (_typeZones & 0x20) != 0;
case ZoneType::kLadder:
return (_typeZones & 0x40) != 0;
default:
return true;
}
return false;
}
DebugScene::ScenePositionsProjected DebugScene::calculateBoxPositions(const IVec3 &mins, const IVec3 &maxs) {
ScenePositionsProjected positions;
// compute the points in 3D
positions.frontBottomLeftPoint.x = mins.x - _engine->_grid->_camera.x;
positions.frontBottomLeftPoint.y = mins.y - _engine->_grid->_camera.y;
positions.frontBottomLeftPoint.z = maxs.z - _engine->_grid->_camera.z;
positions.frontBottomRightPoint.x = maxs.x - _engine->_grid->_camera.x;
positions.frontBottomRightPoint.y = mins.y - _engine->_grid->_camera.y;
positions.frontBottomRightPoint.z = maxs.z - _engine->_grid->_camera.z;
positions.frontTopLeftPoint.x = mins.x - _engine->_grid->_camera.x;
positions.frontTopLeftPoint.y = maxs.y - _engine->_grid->_camera.y;
positions.frontTopLeftPoint.z = maxs.z - _engine->_grid->_camera.z;
positions.frontTopRightPoint = maxs - _engine->_grid->_camera;
positions.backBottomLeftPoint = mins - _engine->_grid->_camera;
positions.backBottomRightPoint.x = maxs.x - _engine->_grid->_camera.x;
positions.backBottomRightPoint.y = mins.y - _engine->_grid->_camera.y;
positions.backBottomRightPoint.z = mins.z - _engine->_grid->_camera.z;
positions.backTopLeftPoint.x = mins.x - _engine->_grid->_camera.x;
positions.backTopLeftPoint.y = maxs.y - _engine->_grid->_camera.y;
positions.backTopLeftPoint.z = mins.z - _engine->_grid->_camera.z;
positions.backTopRightPoint.x = maxs.x - _engine->_grid->_camera.x;
positions.backTopRightPoint.y = maxs.y - _engine->_grid->_camera.y;
positions.backTopRightPoint.z = mins.z - _engine->_grid->_camera.z;
// project all points
projectBoundingBoxPoints(&positions.frontBottomLeftPoint, &positions.frontBottomLeftPoint2D);
projectBoundingBoxPoints(&positions.frontBottomRightPoint, &positions.frontBottomRightPoint2D);
projectBoundingBoxPoints(&positions.frontTopLeftPoint, &positions.frontTopLeftPoint2D);
projectBoundingBoxPoints(&positions.frontTopRightPoint, &positions.frontTopRightPoint2D);
projectBoundingBoxPoints(&positions.backBottomLeftPoint, &positions.backBottomLeftPoint2D);
projectBoundingBoxPoints(&positions.backBottomRightPoint, &positions.backBottomRightPoint2D);
projectBoundingBoxPoints(&positions.backTopLeftPoint, &positions.backTopLeftPoint2D);
projectBoundingBoxPoints(&positions.backTopRightPoint, &positions.backTopRightPoint2D);
return positions;
}
bool DebugScene::drawBox(const ScenePositionsProjected &positions, uint8 color) {
bool state = false;
// draw front part
state |= _engine->_interface->drawLine(positions.frontBottomLeftPoint2D.x, positions.frontBottomLeftPoint2D.y, positions.frontTopLeftPoint2D.x, positions.frontTopLeftPoint2D.y, color);
state |= _engine->_interface->drawLine(positions.frontTopLeftPoint2D.x, positions.frontTopLeftPoint2D.y, positions.frontTopRightPoint2D.x, positions.frontTopRightPoint2D.y, color);
state |= _engine->_interface->drawLine(positions.frontTopRightPoint2D.x, positions.frontTopRightPoint2D.y, positions.frontBottomRightPoint2D.x, positions.frontBottomRightPoint2D.y, color);
state |= _engine->_interface->drawLine(positions.frontBottomRightPoint2D.x, positions.frontBottomRightPoint2D.y, positions.frontBottomLeftPoint2D.x, positions.frontBottomLeftPoint2D.y, color);
// draw top part
state |= _engine->_interface->drawLine(positions.frontTopLeftPoint2D.x, positions.frontTopLeftPoint2D.y, positions.backTopLeftPoint2D.x, positions.backTopLeftPoint2D.y, color);
state |= _engine->_interface->drawLine(positions.backTopLeftPoint2D.x, positions.backTopLeftPoint2D.y, positions.backTopRightPoint2D.x, positions.backTopRightPoint2D.y, color);
state |= _engine->_interface->drawLine(positions.backTopRightPoint2D.x, positions.backTopRightPoint2D.y, positions.frontTopRightPoint2D.x, positions.frontTopRightPoint2D.y, color);
state |= _engine->_interface->drawLine(positions.frontTopRightPoint2D.x, positions.frontTopRightPoint2D.y, positions.frontTopLeftPoint2D.x, positions.frontTopLeftPoint2D.y, color);
// draw back part
state |= _engine->_interface->drawLine(positions.backBottomLeftPoint2D.x, positions.backBottomLeftPoint2D.y, positions.backTopLeftPoint2D.x, positions.backTopLeftPoint2D.y, color);
state |= _engine->_interface->drawLine(positions.backTopLeftPoint2D.x, positions.backTopLeftPoint2D.y, positions.backTopRightPoint2D.x, positions.backTopRightPoint2D.y, color);
state |= _engine->_interface->drawLine(positions.backTopRightPoint2D.x, positions.backTopRightPoint2D.y, positions.backBottomRightPoint2D.x, positions.backBottomRightPoint2D.y, color);
state |= _engine->_interface->drawLine(positions.backBottomRightPoint2D.x, positions.backBottomRightPoint2D.y, positions.backBottomLeftPoint2D.x, positions.backBottomLeftPoint2D.y, color);
// draw bottom part
state |= _engine->_interface->drawLine(positions.frontBottomLeftPoint2D.x, positions.frontBottomLeftPoint2D.y, positions.backBottomLeftPoint2D.x, positions.backBottomLeftPoint2D.y, color);
state |= _engine->_interface->drawLine(positions.backBottomLeftPoint2D.x, positions.backBottomLeftPoint2D.y, positions.backBottomRightPoint2D.x, positions.backBottomRightPoint2D.y, color);
state |= _engine->_interface->drawLine(positions.backBottomRightPoint2D.x, positions.backBottomRightPoint2D.y, positions.frontBottomRightPoint2D.x, positions.frontBottomRightPoint2D.y, color);
state |= _engine->_interface->drawLine(positions.frontBottomRightPoint2D.x, positions.frontBottomRightPoint2D.y, positions.frontBottomLeftPoint2D.x, positions.frontBottomLeftPoint2D.y, color);
return state;
}
bool DebugScene::displayActors() {
bool state = false;
for (int32 a = 0; a < _engine->_scene->_sceneNumActors; a++) {
const ActorStruct *actorPtr = _engine->_scene->getActor(a);
const IVec3 &pos = actorPtr->posObj();
const BoundingBox &bbox = actorPtr->_boundingBox;
const ScenePositionsProjected &positions = calculateBoxPositions(pos + bbox.mins, pos + bbox.maxs);
if (!drawBox(positions, COLOR_WHITE)) {
continue;
}
const int boxwidth = 150;
const int lineHeight = 14;
const int boxheight = 2 * lineHeight;
const Common::Rect filledRect(positions.frontTopRightPoint2D.x, positions.frontTopRightPoint2D.y, positions.frontTopRightPoint2D.x + boxwidth, positions.frontTopRightPoint2D.y + boxheight);
_engine->_interface->drawFilledRect(filledRect, COLOR_WHITE);
_engine->_menu->drawRectBorders(filledRect);
_engine->drawText(positions.frontTopRightPoint2D.x, positions.frontTopRightPoint2D.y, Common::String::format("Actor: %i", a), true, true, boxwidth);
_engine->drawText(positions.frontTopRightPoint2D.x, positions.frontTopRightPoint2D.y + lineHeight, Common::String::format("pos: %i:%i:%i", pos.x, pos.y, pos.z), true, true, boxwidth);
const int16 rleft = positions.frontTopLeftPoint2D.x;
const int16 rtop = positions.backTopLeftPoint2D.y;
const int16 rright = positions.backTopRightPoint2D.x;
const int16 rbottom = positions.frontBottomRightPoint2D.y;
Common::Rect actorRect(rleft, rtop, rright, rbottom);
actorRect.extend(filledRect);
_engine->_redraw->addRedrawArea(actorRect);
state = true;
}
return state;
}
// TODO: implement the rendering points of all tracks as a dot with the id
bool DebugScene::displayTracks() {
#if 0
for (int i = 0; i < _engine->_scene->sceneNumTracks; i++) {
const Vec3 *trackPoint = &_engine->_scene->sceneTracks[i];
}
#endif
return false;
}
bool DebugScene::displayZones() {
bool state = false;
for (int i = 0; i < _engine->_scene->_sceneNumZones; i++) {
const ZoneStruct *zonePtr = &_engine->_scene->_sceneZones[i];
if (!checkZoneType(zonePtr->type)) {
continue;
}
const ScenePositionsProjected &positions = calculateBoxPositions(zonePtr->mins, zonePtr->maxs);
const uint8 color = 15 * 3 + (int)zonePtr->type * 16;
if (!drawBox(positions, color)) {
continue;
}
const int boxwidth = 150;
const int lineHeight = 14;
const int boxheight = 2 * lineHeight;
const Common::Rect filledRect(positions.frontTopRightPoint2D.x, positions.frontTopRightPoint2D.y, positions.frontTopRightPoint2D.x + boxwidth, positions.frontTopRightPoint2D.y + boxheight);
_engine->_interface->drawFilledRect(filledRect, COLOR_WHITE);
_engine->_menu->drawRectBorders(filledRect);
_engine->drawText(positions.frontTopRightPoint2D.x, positions.frontTopRightPoint2D.y, Common::String::format("Type: %i (%i)", (int)zonePtr->type, i), true, false, boxwidth);
_engine->drawText(positions.frontTopRightPoint2D.x, positions.frontTopRightPoint2D.y + lineHeight, Common::String::format("pos: %i:%i:%i", positions.frontTopRightPoint.x, positions.frontTopRightPoint.y, positions.frontTopRightPoint.z), true, false, boxwidth);
state = true;
}
return state;
}
void DebugScene::renderDebugView() {
if (_showingZones) {
displayZones();
}
if (_showingActors) {
displayActors();
}
if (_showingTracks) {
displayTracks();
}
}
} // namespace TwinE