mirror of
https://github.com/scummvm/scummvm.git
synced 2025-04-02 10:52:32 -04:00
237 lines
11 KiB
C++
237 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_state.h"
|
|
#include "common/util.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 {
|
|
|
|
DebugState::DebugState(TwinEEngine *engine) : _engine(engine) {}
|
|
|
|
void DebugState::update() {
|
|
changeGridCamera();
|
|
}
|
|
|
|
void DebugState::drawClip(const Common::Rect &rect) {
|
|
if (!_showingClips) {
|
|
return;
|
|
}
|
|
_engine->_menu->drawRectBorders(rect);
|
|
}
|
|
|
|
void DebugState::projectBoundingBoxPoints(IVec3 *pPoint3d, IVec3 *pPoint3dProjected) {
|
|
*pPoint3dProjected = _engine->_renderer->projectPoint(*pPoint3d);
|
|
}
|
|
|
|
bool DebugState::checkZoneType(ZoneType type) const {
|
|
return (_typeZones & (1u << (uint32)type)) != 0u;
|
|
}
|
|
|
|
DebugState::ScenePositionsProjected DebugState::calculateBoxPositions(const IVec3 &mins, const IVec3 &maxs) {
|
|
ScenePositionsProjected positions;
|
|
// compute the points in 3D
|
|
positions.frontBottomLeftPoint.x = mins.x - _engine->_grid->_worldCube.x;
|
|
positions.frontBottomLeftPoint.y = mins.y - _engine->_grid->_worldCube.y;
|
|
positions.frontBottomLeftPoint.z = maxs.z - _engine->_grid->_worldCube.z;
|
|
|
|
positions.frontBottomRightPoint.x = maxs.x - _engine->_grid->_worldCube.x;
|
|
positions.frontBottomRightPoint.y = mins.y - _engine->_grid->_worldCube.y;
|
|
positions.frontBottomRightPoint.z = maxs.z - _engine->_grid->_worldCube.z;
|
|
|
|
positions.frontTopLeftPoint.x = mins.x - _engine->_grid->_worldCube.x;
|
|
positions.frontTopLeftPoint.y = maxs.y - _engine->_grid->_worldCube.y;
|
|
positions.frontTopLeftPoint.z = maxs.z - _engine->_grid->_worldCube.z;
|
|
|
|
positions.frontTopRightPoint = maxs - _engine->_grid->_worldCube;
|
|
positions.backBottomLeftPoint = mins - _engine->_grid->_worldCube;
|
|
|
|
positions.backBottomRightPoint.x = maxs.x - _engine->_grid->_worldCube.x;
|
|
positions.backBottomRightPoint.y = mins.y - _engine->_grid->_worldCube.y;
|
|
positions.backBottomRightPoint.z = mins.z - _engine->_grid->_worldCube.z;
|
|
|
|
positions.backTopLeftPoint.x = mins.x - _engine->_grid->_worldCube.x;
|
|
positions.backTopLeftPoint.y = maxs.y - _engine->_grid->_worldCube.y;
|
|
positions.backTopLeftPoint.z = mins.z - _engine->_grid->_worldCube.z;
|
|
|
|
positions.backTopRightPoint.x = maxs.x - _engine->_grid->_worldCube.x;
|
|
positions.backTopRightPoint.y = maxs.y - _engine->_grid->_worldCube.y;
|
|
positions.backTopRightPoint.z = mins.z - _engine->_grid->_worldCube.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 DebugState::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;
|
|
}
|
|
|
|
void DebugState::changeGridCamera() {
|
|
if (!_useFreeCamera) {
|
|
return;
|
|
}
|
|
|
|
Grid *grid = _engine->_grid;
|
|
Redraw *redraw = _engine->_redraw;
|
|
Input *input = _engine->_input;
|
|
if (input->isActionActive(TwinEActionType::DebugGridCameraPressUp)) {
|
|
grid->_startCube.z--;
|
|
redraw->_firstTime = true;
|
|
} else if (input->isActionActive(TwinEActionType::DebugGridCameraPressDown)) {
|
|
grid->_startCube.z++;
|
|
redraw->_firstTime = true;
|
|
}
|
|
if (input->isActionActive(TwinEActionType::DebugGridCameraPressLeft)) {
|
|
grid->_startCube.x--;
|
|
redraw->_firstTime = true;
|
|
} else if (input->isActionActive(TwinEActionType::DebugGridCameraPressRight)) {
|
|
grid->_startCube.x++;
|
|
redraw->_firstTime = true;
|
|
}
|
|
}
|
|
|
|
bool DebugState::displayActors() {
|
|
bool state = false;
|
|
for (int32 a = 0; a < _engine->_scene->_nbObjets; 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 = 75;
|
|
const int lineHeight = 14;
|
|
const Common::Rect filledRect(positions.frontTopRightPoint2D.x, positions.frontTopRightPoint2D.y, positions.frontTopRightPoint2D.x + boxwidth, positions.frontTopRightPoint2D.y + lineHeight);
|
|
_engine->_interface->box(filledRect, COLOR_WHITE);
|
|
_engine->_menu->drawRectBorders(filledRect);
|
|
_engine->drawText(positions.frontTopRightPoint2D.x, positions.frontTopRightPoint2D.y, Common::String::format("Actor: %i", a), true, false, 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->addPhysBox(actorRect);
|
|
state = true;
|
|
}
|
|
return state;
|
|
}
|
|
|
|
// TODO: implement the rendering points of all tracks as a dot with the id
|
|
bool DebugState::displayTracks() {
|
|
#if 0
|
|
for (int i = 0; i < _engine->_scene->sceneNumTracks; i++) {
|
|
const Vec3 *trackPoint = &_engine->_scene->sceneTracks[i];
|
|
|
|
}
|
|
#endif
|
|
return false;
|
|
}
|
|
|
|
bool DebugState::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 = 50;
|
|
const int lineHeight = 14;
|
|
const Common::Rect filledRect(positions.frontTopRightPoint2D.x, positions.frontTopRightPoint2D.y, positions.frontTopRightPoint2D.x + boxwidth, positions.frontTopRightPoint2D.y + lineHeight);
|
|
_engine->_interface->box(filledRect, COLOR_WHITE);
|
|
_engine->_menu->drawRectBorders(filledRect);
|
|
_engine->drawText(positions.frontTopRightPoint2D.x, positions.frontTopRightPoint2D.y, Common::String::format("ID: %i", i), true, false, boxwidth);
|
|
state = true;
|
|
}
|
|
return state;
|
|
}
|
|
|
|
void DebugState::addFrameData(uint32 frameTime, int32 waitMillis, uint32 maxDelay) {
|
|
if (!_frameDataRecording) {
|
|
return;
|
|
}
|
|
_frameData.emplace_back(frameTime, waitMillis, maxDelay);
|
|
}
|
|
|
|
void DebugState::renderDebugView() {
|
|
if (_showingZones) {
|
|
displayZones();
|
|
}
|
|
if (_showingActors) {
|
|
displayActors();
|
|
}
|
|
if (_showingTracks) {
|
|
displayTracks();
|
|
}
|
|
}
|
|
|
|
} // namespace TwinE
|