TRECISION: Move PaintObjAnm and PaintScreen to Renderer3D, remove regen.cpp

This commit is contained in:
Strangerke 2021-05-12 00:58:07 +01:00 committed by SupSuper
parent a7eb879904
commit 2f18be7fb0
10 changed files with 354 additions and 361 deletions

View file

@ -21,6 +21,9 @@
*/ */
#include "trecision/3d.h" #include "trecision/3d.h"
#include "trecision/anim.h"
#include "trecision/sound.h"
#include "trecision/text.h"
#include "trecision/actor.h" #include "trecision/actor.h"
#include "trecision/graphics.h" #include "trecision/graphics.h"
#include "trecision/trecision.h" #include "trecision/trecision.h"
@ -129,18 +132,12 @@ Renderer3D::Renderer3D(TrecisionEngine *vm) : _vm(vm) {
_shadowIntens[i] = 0; _shadowIntens[i] = 0;
for (int i = 0; i < MAXVERTEX; ++i) { for (int i = 0; i < MAXVERTEX; ++i) {
_vVertex[i]._x = 0; _vVertex[i].clear();
_vVertex[i]._y = 0; _shVertex[i].clear();
_vVertex[i]._z = 0;
_vVertex[i]._angle = 0;
_shVertex[i]._x = 0;
_shVertex[i]._y = 0;
_shVertex[i]._z = 0;
_shVertex[i]._nx = 0;
_shVertex[i]._ny = 0;
_shVertex[i]._nz = 0;
} }
DObj.rect = Common::Rect(0, 0, 0, 0);
DObj.l = Common::Rect(0, 0, 0, 0);
} }
Renderer3D::~Renderer3D() { Renderer3D::~Renderer3D() {
@ -841,6 +838,198 @@ void Renderer3D::drawCharacter(uint8 flag) {
} }
} }
void Renderer3D::paintScreen(bool flag) {
_vm->_animTypeMgr->next();
_vm->_actorRect = nullptr;
_vm->_dirtyRects.clear();
_vm->_flagPaintCharacter = true; // always redraws the character
int x1 = _vm->_actor->_lim[0];
int y1 = _vm->_actor->_lim[2] - TOP;
int x2 = _vm->_actor->_lim[1];
int y2 = _vm->_actor->_lim[3] - TOP;
// erase character
if (_vm->_flagShowCharacter && x2 > x1 && y2 > y1) { // if a description exists
DObj.rect = Common::Rect(0, TOP, MAXX, AREA + TOP);
DObj.l = Common::Rect(x1, y1, x2, y2);
DObj.objIndex = -1;
DObj.drawMask = false;
_vm->_graphicsMgr->DrawObj(DObj);
_vm->addDirtyRect(DObj.l);
_vm->_actorRect = &_vm->_dirtyRects.back();
} else if (_vm->_animMgr->_animRect.left != MAXX) {
DObj.rect = Common::Rect(0, TOP, MAXX, AREA + TOP);
DObj.l = _vm->_animMgr->_animRect;
DObj.objIndex = -1;
DObj.drawMask = false;
_vm->_graphicsMgr->DrawObj(DObj);
_vm->addDirtyRect(DObj.l);
_vm->_actorRect = &_vm->_dirtyRects.back();
}
// If there's text to remove
if (TextStatus & TEXT_DEL) {
// remove text
DObj.rect = Common::Rect(0, TOP, MAXX, MAXY + TOP);
DObj.l = _vm->_textMgr->getOldTextRect();
DObj.l.translate(0, -TOP);
DObj.objIndex = -1;
DObj.drawMask = false;
if (DObj.l.top >= 0 && DObj.l.bottom < AREA) {
_vm->_graphicsMgr->DrawObj(DObj);
} else {
_vm->_graphicsMgr->EraseObj(DObj);
}
_vm->_textMgr->clearOldText();
_vm->addDirtyRect(DObj.l);
if (!(TextStatus & TEXT_DRAW)) // if there's no new text
TextStatus = TEXT_OFF; // stop updating text
}
// Suppress all the objects you removed
for (Common::List<SSortTable>::iterator i = _vm->_sortTable.begin(); i != _vm->_sortTable.end(); ++i) {
if (i->_remove) {
DObj.rect = Common::Rect(0, TOP, MAXX, AREA + TOP);
DObj.l = _vm->_obj[i->_objectId]._rect;
DObj.objIndex = -1;
DObj.drawMask = false;
_vm->_graphicsMgr->DrawObj(DObj);
_vm->addDirtyRect(DObj.l);
}
}
// Find the position of the character
_vm->_pathFind->actorOrder();
// For every box from the horizon forward...
// Copy per level
for (int liv = _vm->_pathFind->_numSortPan; liv >= 0; liv--) {
uint16 curBox = _vm->_pathFind->_sortPan[liv]._num;
// draws all objects and animations that intersect the boundaries and refer to the current box
paintObjAnm(curBox);
}
if (TextStatus & TEXT_DRAW) {
_vm->_textMgr->drawCurString();
TextStatus = TEXT_DRAW; // Activate text update
}
_vm->_soundMgr->SoundPasso((_vm->_actor->_lim[1] + _vm->_actor->_lim[0]) / 2, (_vm->_actor->_lim[5] + _vm->_actor->_lim[4]) / 2, _vm->_actor->_curAction, _vm->_actor->_curFrame, _vm->_room[_vm->_curRoom]._sounds);
if (!flag && !_vm->_flagDialogActive) {
_vm->_graphicsMgr->copyToScreen(0, 0, MAXX, MAXY);
}
_vm->_sortTable.clear();
_vm->_flagPaintCharacter = false;
_vm->_flagWaitRegen = false;
// Handle papaverine delayed action
if ((_vm->_curRoom == kRoom4A) && (_vm->_obj[oCHOCOLATES4A]._flag & kObjFlagExtra)) {
if (_vm->_animMgr->smkCurFrame(kSmackerBackground) > 480) {
_vm->playScript(s4AHELLEN);
_vm->_obj[oCHOCOLATES4A]._flag &= ~kObjFlagExtra;
}
}
//
}
/* -------------------------------------------------
Draw all objects and animations that intersect
boundaries belonging to curbox
--------------------------------------------------*/
void Renderer3D::paintObjAnm(uint16 curBox) {
_vm->_animMgr->refreshAnim(curBox);
// draws new cards belonging to the current box
for (Common::List<SSortTable>::iterator i = _vm->_sortTable.begin(); i != _vm->_sortTable.end(); ++i) {
if (!i->_remove && _vm->_obj[i->_objectId]._nbox == curBox) {
// the bitmap object at the desired level
SObject obj = _vm->_obj[i->_objectId];
DObj.rect = obj._rect;
DObj.rect.translate(0, TOP);
DObj.l = Common::Rect(DObj.rect.width(), DObj.rect.height());
DObj.objIndex = _vm->getRoomObjectIndex(i->_objectId);
DObj.drawMask = obj._mode & OBJMODE_MASK;
_vm->_graphicsMgr->DrawObj(DObj);
_vm->_dirtyRects.push_back(DObj.rect);
}
}
for (DirtyRectsIterator d = _vm->_dirtyRects.begin(); d != _vm->_dirtyRects.end(); ++d) {
for (int b = 0; b < MAXOBJINROOM; b++) {
const uint16 curObject = _vm->_room[_vm->_curRoom]._object[b];
if (!curObject)
break;
SObject obj = _vm->_obj[curObject];
if ((obj._mode & (OBJMODE_FULL | OBJMODE_MASK)) && _vm->isObjectVisible(curObject) && (obj._nbox == curBox)) {
Common::Rect r = *d;
Common::Rect r2 = obj._rect;
r2.translate(0, TOP);
// Include the bottom right of the rect in the intersects() check
r2.bottom++;
r2.right++;
if (r.intersects(r2)) {
DObj.rect = obj._rect;
DObj.rect.translate(0, TOP);
// Restore the bottom right of the rect
r2.bottom--;
r2.right--;
// TODO: Simplify this?
const int16 xr1 = (r2.left > r.left) ? 0 : r.left - r2.left;
const int16 yr1 = (r2.top > r.top) ? 0 : r.top - r2.top;
const int16 xr2 = MIN<int16>(r.right, r2.right) - r2.left;
const int16 yr2 = MIN<int16>(r.bottom, r2.bottom) - r2.top;
DObj.l = Common::Rect(xr1, yr1, xr2, yr2);
DObj.objIndex = b;
DObj.drawMask = obj._mode & OBJMODE_MASK;
_vm->_graphicsMgr->DrawObj(DObj);
}
}
}
}
if (_vm->_actorPos == curBox && _vm->_flagShowCharacter && _vm->_flagCharacterExists) {
drawCharacter(CALCPOINTS);
int x1 = _vm->_actor->_lim[0];
int y1 = _vm->_actor->_lim[2];
int x2 = _vm->_actor->_lim[1];
int y2 = _vm->_actor->_lim[3];
if (x2 > x1 && y2 > y1) {
// enlarge the rectangle of the character
Common::Rect l(x1, y1, x2, y2);
if (_vm->_actorRect)
_vm->_actorRect->extend(l);
resetZBuffer(x1, y1, x2, y2);
}
drawCharacter(DRAWFACES);
} else if (_vm->_actorPos == curBox && !_vm->_flagDialogActive) {
_vm->_animMgr->refreshSmkAnim(_vm->_animMgr->_playingAnims[kSmackerAction]);
}
}
// Path Finding // Path Finding
PathFinding3D::PathFinding3D(TrecisionEngine *vm) : _vm(vm) { PathFinding3D::PathFinding3D(TrecisionEngine *vm) : _vm(vm) {
_lookX = 0.0f; _lookX = 0.0f;
@ -853,13 +1042,8 @@ PathFinding3D::PathFinding3D(TrecisionEngine *vm) : _vm(vm) {
_panelNum = 0; _panelNum = 0;
for (int i = 0; i < MAXPATHNODES; ++i) { for (int i = 0; i < MAXPATHNODES; ++i)
_pathNode[i]._x = 0.0f; _pathNode[i].clear();
_pathNode[i]._z = 0.0f;
_pathNode[i]._dist = 0.0f;
_pathNode[i]._oldPanel = 0;
_pathNode[i]._curPanel = 0;
}
_curPanel = -1; _curPanel = -1;
_oldPanel = -1; _oldPanel = -1;
@ -872,6 +1056,23 @@ PathFinding3D::PathFinding3D(TrecisionEngine *vm) : _vm(vm) {
_curX = 0.0f; _curX = 0.0f;
_curZ = 0.0f; _curZ = 0.0f;
for (int i = 0; i < 3; ++i) {
_invP[i][0] = 0.0f;
_invP[i][1] = 0.0f;
_invP[i][2] = 0.0f;
}
for (int i = 0; i < MAXPANELSINROOM; ++i)
_panel[i].clear();
for (int i = 0; i < 32; ++i) {
_sortPan[i]._num = 0;
_sortPan[i]._min = 0.0f;
}
for (int i = 0; i < MAXSTEP; ++i)
_step[i].clear();
} }
PathFinding3D::~PathFinding3D() { PathFinding3D::~PathFinding3D() {
@ -1345,7 +1546,7 @@ void PathFinding3D::findShortPath() {
--------------------------------------------------*/ --------------------------------------------------*/
float PathFinding3D::evalPath(int a, float destX, float destZ, int nearP) { float PathFinding3D::evalPath(int a, float destX, float destZ, int nearP) {
int b = 0; int b = 0;
float len = 0.0; float len = 0.0f;
int curPanel = _pathNode[a]._curPanel; int curPanel = _pathNode[a]._curPanel;
float curX = _pathNode[a]._x; float curX = _pathNode[a]._x;
@ -1635,7 +1836,7 @@ void PathFinding3D::buildFramelist() {
} }
float len = 0.0; float len = 0.0;
float curlen = 0.0; float curLen = 0.0;
float ox = _pathNode[0]._x; float ox = _pathNode[0]._x;
float oz = _pathNode[0]._z; float oz = _pathNode[0]._z;
@ -1655,77 +1856,77 @@ void PathFinding3D::buildFramelist() {
int a = 0; int a = 0;
// compute offset // compute offset
SVertex *v = _vm->_actor->_characterArea; SVertex *v = _vm->_actor->_characterArea;
float firstframe = _vm->_actor->FRAMECENTER(v); float firstFrame = _vm->_actor->FRAMECENTER(v);
float startpos = 0.0; float startPos = 0.0;
// if he was already walking // if he was already walking
int CurA, CurF, cfp; int curAction, curFrame, cfp;
if (_vm->_actor->_curAction == hWALK) { if (_vm->_actor->_curAction == hWALK) {
// compute current frame // compute current frame
cfp = _vm->_defActionLen[hSTART] + 1 + _vm->_actor->_curFrame; cfp = _vm->_defActionLen[hSTART] + 1 + _vm->_actor->_curFrame;
v += cfp * _vm->_actor->_vertexNum; v += cfp * _vm->_actor->_vertexNum;
CurA = hWALK; curAction = hWALK;
CurF = _vm->_actor->_curFrame; curFrame = _vm->_actor->_curFrame;
// if it wasn't the last frame, take the next step // if it wasn't the last frame, take the next step
if (_vm->_actor->_curFrame < _vm->_defActionLen[hWALK] - 1) { if (_vm->_actor->_curFrame < _vm->_defActionLen[hWALK] - 1) {
cfp++; cfp++;
CurF++; curFrame++;
v += _vm->_actor->_vertexNum; v += _vm->_actor->_vertexNum;
} }
} else if ((_vm->_actor->_curAction >= hSTOP0) && (_vm->_actor->_curAction <= hSTOP9)) { } else if ((_vm->_actor->_curAction >= hSTOP0) && (_vm->_actor->_curAction <= hSTOP9)) {
// if he was stopped, starts moving again // if he was stopped, starts moving again
// compute current frame // compute current frame
CurA = hWALK; curAction = hWALK;
//o CurF = _vm->_actor->_curAction - hSTOP1; //o CurF = _vm->_actor->_curAction - hSTOP1;
CurF = _vm->_actor->_curAction - hSTOP0; curFrame = _vm->_actor->_curAction - hSTOP0;
cfp = _vm->_defActionLen[hSTART] + 1 + CurF; cfp = _vm->_defActionLen[hSTART] + 1 + curFrame;
v += cfp * _vm->_actor->_vertexNum; v += cfp * _vm->_actor->_vertexNum;
} else { } else {
// if he was standing, start working or turn // if he was standing, start working or turn
oz = 0.0; oz = 0.0;
cfp = 1; cfp = 1;
CurA = hSTART; curAction = hSTART;
CurF = 0; curFrame = 0;
// start from the first frame // start from the first frame
v += _vm->_actor->_vertexNum; v += _vm->_actor->_vertexNum;
} }
oz = -_vm->_actor->FRAMECENTER(v) + firstframe; oz = -_vm->_actor->FRAMECENTER(v) + firstFrame;
// at this point, CurA / _curAction is either hSTART or hWALK // at this point, CurA / _curAction is either hSTART or hWALK
// until it arrives at the destination // until it arrives at the destination
while (((curlen = oz + _vm->_actor->FRAMECENTER(v) - firstframe) < len) || (!a)) { while (((curLen = oz + _vm->_actor->FRAMECENTER(v) - firstFrame) < len) || (!a)) {
_step[a]._pz = oz - firstframe; // where to render _step[a]._pz = oz - firstFrame; // where to render
_step[a]._dz = curlen; // where it is _step[a]._dz = curLen; // where it is
_step[a]._curAction = CurA; _step[a]._curAction = curAction;
_step[a]._curFrame = CurF; _step[a]._curFrame = curFrame;
a++; a++;
v += _vm->_actor->_vertexNum; v += _vm->_actor->_vertexNum;
CurF++; curFrame++;
cfp++; cfp++;
if (CurF >= _vm->_defActionLen[CurA]) { if (curFrame >= _vm->_defActionLen[curAction]) {
if (CurA == hSTART) { if (curAction == hSTART) {
CurA = hWALK; curAction = hWALK;
CurF = 0; curFrame = 0;
cfp = _vm->_defActionLen[hSTART] + 1; cfp = _vm->_defActionLen[hSTART] + 1;
ox = 0.0; ox = 0.0;
} else if (CurA == hWALK) { } else if (curAction == hWALK) {
CurA = hWALK; curAction = hWALK;
CurF = 0; curFrame = 0;
cfp = _vm->_defActionLen[hSTART] + 1; cfp = _vm->_defActionLen[hSTART] + 1;
// end walk frame // end walk frame
ox = _vm->_actor->FRAMECENTER(v) - firstframe; ox = _vm->_actor->FRAMECENTER(v) - firstFrame;
v = &_vm->_actor->_characterArea[cfp * _vm->_actor->_vertexNum]; v = &_vm->_actor->_characterArea[cfp * _vm->_actor->_vertexNum];
ox -= _vm->_actor->FRAMECENTER(v); ox -= _vm->_actor->FRAMECENTER(v);
@ -1734,7 +1935,7 @@ void PathFinding3D::buildFramelist() {
v = &_vm->_actor->_characterArea[cfp * _vm->_actor->_vertexNum]; v = &_vm->_actor->_characterArea[cfp * _vm->_actor->_vertexNum];
// only if it doesn't end // only if it doesn't end
if ((oz + ox + _vm->_actor->FRAMECENTER(v) - firstframe) < len) if ((oz + ox + _vm->_actor->FRAMECENTER(v) - firstFrame) < len)
oz += ox; oz += ox;
else else
break; break;
@ -1748,35 +1949,35 @@ void PathFinding3D::buildFramelist() {
// if he was walking // if he was walking
if (_step[a - 1]._curAction == hWALK) if (_step[a - 1]._curAction == hWALK)
CurA = _step[a - 1]._curFrame + hSTOP0; // stop previous step. curAction = _step[a - 1]._curFrame + hSTOP0; // stop previous step.
else else
CurA = hSTOP0; // stop step 01 curAction = hSTOP0; // stop step 01
assert(CurA <= hLAST); // _defActionLen below has a size of hLAST + 1 assert(curAction <= hLAST); // _defActionLen below has a size of hLAST + 1
CurF = 0; curFrame = 0;
int b = 0; int b = 0;
cfp = 0; cfp = 0;
while (b != CurA) while (b != curAction)
cfp += _vm->_defActionLen[b++]; cfp += _vm->_defActionLen[b++];
v = &_vm->_actor->_characterArea[cfp * _vm->_actor->_vertexNum]; v = &_vm->_actor->_characterArea[cfp * _vm->_actor->_vertexNum];
for (b = 0; b < _vm->_defActionLen[CurA]; b++) { for (b = 0; b < _vm->_defActionLen[curAction]; b++) {
curlen = oz + _vm->_actor->FRAMECENTER(v) - firstframe; curLen = oz + _vm->_actor->FRAMECENTER(v) - firstFrame;
_step[a]._pz = oz - firstframe; // where to render _step[a]._pz = oz - firstFrame; // where to render
_step[a]._dz = curlen; // where it is _step[a]._dz = curLen; // where it is
_step[a]._curAction = CurA; _step[a]._curAction = curAction;
_step[a]._curFrame = CurF; _step[a]._curFrame = curFrame;
a++; a++;
CurF++; curFrame++;
v += _vm->_actor->_vertexNum; v += _vm->_actor->_vertexNum;
} }
// how far is it from the destination? // how far is it from the destination?
float approx = (len - curlen - EPSILON) / (a - 2); float approx = (len - curLen - EPSILON) / (a - 2);
float theta = 0.0; float theta = 0.0;
// Adjust all the steps so it arrives exactly where clicked // Adjust all the steps so it arrives exactly where clicked
for (b = 1; b < a; b++) { for (b = 1; b < a; b++) {
@ -1799,9 +2000,9 @@ void PathFinding3D::buildFramelist() {
b = 0; b = 0;
len = 0.0; len = 0.0;
startpos = 0.0; startPos = 0.0;
for (a = 0; a < _numPathNodes - 1; a++) { for (a = 0; a < _numPathNodes - 1; a++) {
curlen = 0.0; curLen = 0.0;
len += _vm->dist3D(_pathNode[a]._x, 0.0, _pathNode[a]._z, len += _vm->dist3D(_pathNode[a]._x, 0.0, _pathNode[a]._z,
_pathNode[a + 1]._x, 0.0, _pathNode[a + 1]._z); _pathNode[a + 1]._x, 0.0, _pathNode[a + 1]._z);
@ -1824,19 +2025,19 @@ void PathFinding3D::buildFramelist() {
theta += 360.0; theta += 360.0;
while ((b < _lastStep) && (_step[b]._dz <= len)) { while ((b < _lastStep) && (_step[b]._dz <= len)) {
curlen = (_step[b]._dz - _step[b]._pz); curLen = (_step[b]._dz - _step[b]._pz);
_step[b]._px = _pathNode[a]._x + (_step[b]._pz - startpos) * ox; _step[b]._px = _pathNode[a]._x + (_step[b]._pz - startPos) * ox;
_step[b]._pz = _pathNode[a]._z + (_step[b]._pz - startpos) * oz; _step[b]._pz = _pathNode[a]._z + (_step[b]._pz - startPos) * oz;
_step[b]._dx = curlen * ox; _step[b]._dx = curLen * ox;
_step[b]._dz = curlen * oz; _step[b]._dz = curLen * oz;
_step[b]._theta = theta; _step[b]._theta = theta;
_step[b]._curPanel = _pathNode[a]._curPanel; _step[b]._curPanel = _pathNode[a]._curPanel;
b++; b++;
} }
startpos = len; startPos = len;
} }
reset(b, _curX, _curZ, theta); reset(b, _curX, _curZ, theta);
@ -1845,13 +2046,13 @@ void PathFinding3D::buildFramelist() {
_curStep = 0; // current step _curStep = 0; // current step
// starting angle // starting angle
float oldtheta = _vm->_actor->_theta; float oldTheta = _vm->_actor->_theta;
// first angle walk // first angle walk
theta = _step[0]._theta; theta = _step[0]._theta;
// if he starts from standstill position // if he starts from standstill position
if ((_step[0]._curAction == hSTART) && (_step[0]._curFrame == 0) && (_lastStep > 4) && (_step[0]._theta == _step[1]._theta)) { if ((_step[0]._curAction == hSTART) && (_step[0]._curFrame == 0) && (_lastStep > 4) && (_step[0]._theta == _step[1]._theta)) {
approx = theta - oldtheta; approx = theta - oldTheta;
if (approx > 180.0) if (approx > 180.0)
approx = -360.0 + approx; approx = -360.0 + approx;
@ -1861,16 +2062,16 @@ void PathFinding3D::buildFramelist() {
approx /= 3.0; approx /= 3.0;
for (b = 0; b < 2; b++) { for (b = 0; b < 2; b++) {
_step[b]._theta = oldtheta + (float)(b + 1) * approx; _step[b]._theta = oldTheta + (float)(b + 1) * approx;
_step[b]._theta = (_step[b]._theta > 360.0) ? _step[b]._theta - 360.0 : (_step[b]._theta < 0.0) ? _step[b]._theta + 360.0 : _step[b]._theta; _step[b]._theta = (_step[b]._theta > 360.0) ? _step[b]._theta - 360.0 : (_step[b]._theta < 0.0) ? _step[b]._theta + 360.0 : _step[b]._theta;
theta = _step[b]._theta; theta = _step[b]._theta;
curlen = sqrt(_step[b]._dx * _step[b]._dx + _step[b]._dz * _step[b]._dz); curLen = sqrt(_step[b]._dx * _step[b]._dx + _step[b]._dz * _step[b]._dz);
theta = ((270.0 - theta) * PI) / 180.0; theta = ((270.0 - theta) * PI) / 180.0;
ox = cos(theta) * curlen; ox = cos(theta) * curLen;
oz = sin(theta) * curlen; oz = sin(theta) * curLen;
cx = _step[b]._px + _step[b]._dx; cx = _step[b]._px + _step[b]._dx;
float cz = _step[b]._pz + _step[b]._dz; float cz = _step[b]._pz + _step[b]._dz;
@ -1884,13 +2085,13 @@ void PathFinding3D::buildFramelist() {
} }
// makes the curve // makes the curve
oldtheta = _step[2]._theta; oldTheta = _step[2]._theta;
for (b = 3; b <= _lastStep; b++) { for (b = 3; b <= _lastStep; b++) {
theta = _step[b]._theta; theta = _step[b]._theta;
// if it made a curve // if it made a curve
if (oldtheta != theta) { if (oldTheta != theta) {
approx = theta - oldtheta; approx = theta - oldTheta;
if (approx > 180.0) if (approx > 180.0)
approx = -360.0 + approx; approx = -360.0 + approx;
@ -1903,14 +2104,14 @@ void PathFinding3D::buildFramelist() {
_step[b - 1]._theta += approx; _step[b - 1]._theta += approx;
_step[b - 1]._theta = (_step[b - 1]._theta > 360.0) ? _step[b - 1]._theta - 360.0 : (_step[b - 1]._theta < 0.0) ? _step[b - 1]._theta + 360.0 : _step[b - 1]._theta; _step[b - 1]._theta = (_step[b - 1]._theta > 360.0) ? _step[b - 1]._theta - 360.0 : (_step[b - 1]._theta < 0.0) ? _step[b - 1]._theta + 360.0 : _step[b - 1]._theta;
oldtheta = _step[b - 1]._theta; oldTheta = _step[b - 1]._theta;
startpos = oldtheta; startPos = oldTheta;
curlen = sqrt(_step[b - 1]._dx * _step[b - 1]._dx + _step[b - 1]._dz * _step[b - 1]._dz); curLen = sqrt(_step[b - 1]._dx * _step[b - 1]._dx + _step[b - 1]._dz * _step[b - 1]._dz);
oldtheta = ((270.0 - oldtheta) * PI) / 180.0; oldTheta = ((270.0 - oldTheta) * PI) / 180.0;
ox = cos(oldtheta) * curlen; ox = cos(oldTheta) * curLen;
oz = sin(oldtheta) * curlen; oz = sin(oldTheta) * curLen;
cx = _step[b - 1]._px + _step[b - 1]._dx; cx = _step[b - 1]._px + _step[b - 1]._dx;
float cz = _step[b - 1]._pz + _step[b - 1]._dz; float cz = _step[b - 1]._pz + _step[b - 1]._dz;
@ -1925,14 +2126,14 @@ void PathFinding3D::buildFramelist() {
_step[b]._theta -= approx; _step[b]._theta -= approx;
_step[b]._theta = (_step[b]._theta > 360.0) ? _step[b]._theta - 360.0 : (_step[b]._theta < 0.0) ? _step[b]._theta + 360.0 : _step[b]._theta; _step[b]._theta = (_step[b]._theta > 360.0) ? _step[b]._theta - 360.0 : (_step[b]._theta < 0.0) ? _step[b]._theta + 360.0 : _step[b]._theta;
oldtheta = theta; oldTheta = theta;
theta = _step[b]._theta; theta = _step[b]._theta;
curlen = sqrt(_step[b]._dx * _step[b]._dx + _step[b]._dz * _step[b]._dz); curLen = sqrt(_step[b]._dx * _step[b]._dx + _step[b]._dz * _step[b]._dz);
theta = ((270.0 - theta) * PI) / 180.0; theta = ((270.0 - theta) * PI) / 180.0;
ox = cos(theta) * curlen; ox = cos(theta) * curLen;
oz = sin(theta) * curlen; oz = sin(theta) * curLen;
cx = _step[b]._px + _step[b]._dx; cx = _step[b]._px + _step[b]._dx;
cz = _step[b]._pz + _step[b]._dz; cz = _step[b]._pz + _step[b]._dz;
@ -1944,7 +2145,7 @@ void PathFinding3D::buildFramelist() {
_step[b]._dz = cz - _step[b]._pz; _step[b]._dz = cz - _step[b]._pz;
} else } else
oldtheta = theta; oldTheta = theta;
} }
lookAt(_lookX, _lookZ); lookAt(_lookX, _lookZ);

View file

@ -30,6 +30,11 @@ namespace Trecision {
struct SVVertex { struct SVVertex {
int32 _x, _y, _z; int32 _x, _y, _z;
int32 _angle; int32 _angle;
void clear() {
_x = _y = _z = 0;
_angle = 0;
}
}; };
struct SSortPan { struct SSortPan {
@ -42,6 +47,13 @@ struct SPathNode {
float _dist; float _dist;
int16 _oldPanel; int16 _oldPanel;
int16 _curPanel; int16 _curPanel;
void clear() {
_x = _z = 0.0f;
_dist = 0.0f;
_oldPanel = 0;
_curPanel = 0;
}
}; };
struct SPan { struct SPan {
@ -53,6 +65,15 @@ struct SPan {
char _near2; char _near2;
char _col1; char _col1;
char _col2; char _col2;
void clear() {
_x1 = _z1 = 0.0f;
_x2 = _z2 = 0.0f;
_h = 0.0f;
_flags = 0;
_near1 = _near2 = 0;
_col1 = _col2 = 0;
}
}; };
struct SStep { struct SStep {
@ -62,6 +83,15 @@ struct SStep {
int _curAction; int _curAction;
int _curFrame; int _curFrame;
int16 _curPanel; int16 _curPanel;
void clear() {
_px = _pz = 0.0f;
_dx = _dz = 0.0f;
_theta = 0.0f;
_curAction = 0;
_curFrame = 0;
_curPanel = 0;
}
}; };
class Renderer3D { class Renderer3D {
@ -100,12 +130,15 @@ private:
uint16 _lTextY[480]; uint16 _lTextY[480];
uint16 _rTextY[480]; uint16 _rTextY[480];
SDObj DObj;
void setZBufferRegion(int16 sx, int16 sy, int16 dx); void setZBufferRegion(int16 sx, int16 sy, int16 dx);
int8 clockWise(int16 x1, int16 y1, int16 x2, int16 y2, int16 x3, int16 y3); int8 clockWise(int16 x1, int16 y1, int16 x2, int16 y2, int16 x3, int16 y3);
void textureTriangle(int32 x1, int32 y1, int32 z1, int32 c1, int32 tx1, int32 ty1, int32 x2, int32 y2, int32 z2, int32 c2, int32 tx2, int32 ty2, int32 x3, int32 y3, int32 z3, int32 c3, int32 tx3, int32 ty3, STexture *t); void textureTriangle(int32 x1, int32 y1, int32 z1, int32 c1, int32 tx1, int32 ty1, int32 x2, int32 y2, int32 z2, int32 c2, int32 tx2, int32 ty2, int32 x3, int32 y3, int32 z3, int32 c3, int32 tx3, int32 ty3, STexture *t);
void textureScanEdge(int32 x1, int32 y1, int32 z1, int32 c1, int32 tx1, int32 ty1, int32 x2, int32 y2, int32 z2, int32 c2, int32 tx2, int32 ty2); void textureScanEdge(int32 x1, int32 y1, int32 z1, int32 c1, int32 tx1, int32 ty1, int32 x2, int32 y2, int32 z2, int32 c2, int32 tx2, int32 ty2);
void shadowTriangle(int32 x1, int32 y1, int32 x2, int32 y2, int32 x3, int32 y3, uint8 cv, int32 zv); void shadowTriangle(int32 x1, int32 y1, int32 x2, int32 y2, int32 x3, int32 y3, uint8 cv, int32 zv);
void shadowScanEdge(int32 x1, int32 y1, int32 x2, int32 y2); void shadowScanEdge(int32 x1, int32 y1, int32 x2, int32 y2);
void paintObjAnm(uint16 curBox);
public: public:
Renderer3D(TrecisionEngine *vm); Renderer3D(TrecisionEngine *vm);
@ -115,6 +148,8 @@ public:
void resetZBuffer(int x1, int y1, int x2, int y2); void resetZBuffer(int x1, int y1, int x2, int y2);
void setClipping(int16 x1, int16 y1, int16 x2, int16 y2); void setClipping(int16 x1, int16 y1, int16 x2, int16 y2);
void drawCharacter(uint8 flag); void drawCharacter(uint8 flag);
void paintScreen(bool flag);
}; // end of class }; // end of class
class PathFinding3D { class PathFinding3D {

View file

@ -126,7 +126,7 @@ void DialogManager::playDialog(uint16 i) {
_vm->_inventoryCounter = INVENTORY_HIDE; _vm->_inventoryCounter = INVENTORY_HIDE;
_vm->_textMgr->clearLastText(); _vm->_textMgr->clearLastText();
_vm->_textMgr->drawTexts(); _vm->_textMgr->drawTexts();
PaintScreen(true); g_vm->_renderer->paintScreen(true);
_vm->_graphicsMgr->clearScreenBufferTop(); _vm->_graphicsMgr->clearScreenBufferTop();
_vm->_graphicsMgr->copyToScreen(0, 0, MAXX, TOP); _vm->_graphicsMgr->copyToScreen(0, 0, MAXX, TOP);

View file

@ -3055,7 +3055,7 @@ bool LogicManager::mouseOperate(uint16 curObj) {
_comb49[0] = curObj; _comb49[0] = curObj;
_vm->_soundMgr->play(wASTA49); _vm->_soundMgr->play(wASTA49);
if ((_comb49[3] == oFORO749) && (_comb49[2] == oFORO849) && (_comb49[1] == oFORO449) && (_comb49[0] == oFORO549)) { if ((_comb49[3] == oFORO749) && (_comb49[2] == oFORO849) && (_comb49[1] == oFORO449) && (_comb49[0] == oFORO549)) {
PaintScreen(false); _vm->_renderer->paintScreen(false);
_vm->waitDelay(60); _vm->waitDelay(60);
_vm->setObjectVisible(oOMBRAS49, true); _vm->setObjectVisible(oOMBRAS49, true);
_vm->setObjectVisible(oSCOMPARTO49, true); _vm->setObjectVisible(oSCOMPARTO49, true);
@ -3111,7 +3111,7 @@ bool LogicManager::mouseOperate(uint16 curObj) {
_vm->_soundMgr->play(wPAD1 + curObj - oNUMERO14C); _vm->_soundMgr->play(wPAD1 + curObj - oNUMERO14C);
if (a < 5) if (a < 5)
break; break;
PaintScreen(false); _vm->_renderer->paintScreen(false);
_vm->waitDelay(60); _vm->waitDelay(60);
if ((_comb4CT[0] == 5) && (_comb4CT[1] == 6) && (_comb4CT[2] == 2) && if ((_comb4CT[0] == 5) && (_comb4CT[1] == 6) && (_comb4CT[2] == 2) &&
(_comb4CT[3] == 3) && (_comb4CT[4] == 9) && (_comb4CT[5] == 6)) { (_comb4CT[3] == 3) && (_comb4CT[4] == 9) && (_comb4CT[5] == 6)) {
@ -3283,7 +3283,7 @@ bool LogicManager::mouseOperate(uint16 curObj) {
if (_count58 < 6) if (_count58 < 6)
break; break;
PaintScreen(false); _vm->_renderer->paintScreen(false);
_vm->waitDelay(60); _vm->waitDelay(60);
_count58 = 0; _count58 = 0;
for (int a = 0; a < 6; a++) for (int a = 0; a < 6; a++)

View file

@ -18,7 +18,6 @@ MODULE_OBJS = \
utils.o \ utils.o \
3d.o \ 3d.o \
video.o \ video.o \
nl/regen.o \
nl/schedule.o \ nl/schedule.o \
nl/3d/3dwalk.o \ nl/3d/3dwalk.o \
nl/ll/llmouse.o \ nl/ll/llmouse.o \

View file

@ -24,6 +24,7 @@
#include "common/scummsys.h" #include "common/scummsys.h"
#include "common/str.h" #include "common/str.h"
#include "common/system.h" #include "common/system.h"
#include "trecision/3d.h"
#include "trecision/anim.h" #include "trecision/anim.h"
#include "trecision/defines.h" #include "trecision/defines.h"
@ -32,7 +33,6 @@
#include "trecision/sound.h" #include "trecision/sound.h"
#include "trecision/trecision.h" #include "trecision/trecision.h"
#include "trecision/video.h" #include "trecision/video.h"
#include "trecision/nl/proto.h"
#include "trecision/nl/struct.h" #include "trecision/nl/struct.h"
#include "trecision/nl/ll/llinc.h" #include "trecision/nl/ll/llinc.h"
@ -93,7 +93,7 @@ void TendIn() {
g_vm->_flagPaintCharacter = true; g_vm->_flagPaintCharacter = true;
g_vm->_soundMgr->waitEndFading(); g_vm->_soundMgr->waitEndFading();
PaintScreen(true); g_vm->_renderer->paintScreen(true);
g_vm->_graphicsMgr->copyToScreen(0, 0, MAXX, MAXY); g_vm->_graphicsMgr->copyToScreen(0, 0, MAXX, MAXY);
} }
@ -230,7 +230,7 @@ void RedrawRoom() {
TextStatus = TEXT_OFF; TextStatus = TEXT_OFF;
g_vm->_flagPaintCharacter = true; g_vm->_flagPaintCharacter = true;
PaintScreen(true); g_vm->_renderer->paintScreen(true);
g_vm->_graphicsMgr->copyToScreen(0, 0, 640, 480); g_vm->_graphicsMgr->copyToScreen(0, 0, 640, 480);
} }

View file

@ -23,21 +23,14 @@
#ifndef TRECISION_PROTO_H #ifndef TRECISION_PROTO_H
#define TRECISION_PROTO_H #define TRECISION_PROTO_H
#include "common/scummsys.h"
namespace Common { namespace Common {
class SeekableReadStream; class SeekableReadStream;
} }
namespace Trecision { namespace Trecision {
struct SDObj;
struct STexture;
void PaintScreen(bool flag);
void PaintObjAnm(uint16 CurBox);
void ProcessTheMessage(); void ProcessTheMessage();
#endif
} // End of namespace Trecision } // End of namespace Trecision
#endif

View file

@ -1,254 +0,0 @@
/* 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 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.
*
*/
#include "common/util.h"
#include "common/scummsys.h"
#include "trecision/3d.h"
#include "trecision/actor.h"
#include "trecision/anim.h"
#include "trecision/defines.h"
#include "trecision/graphics.h"
#include "trecision/sound.h"
#include "trecision/text.h"
#include "trecision/trecision.h"
#include "trecision/video.h"
#include "trecision/nl/proto.h"
#include "trecision/nl/struct.h"
#include "trecision/nl/ll/llinc.h"
namespace Trecision {
SDObj DObj;
void PaintScreen(bool flag) {
g_vm->_animTypeMgr->next();
g_vm->_actorRect = nullptr;
g_vm->_dirtyRects.clear();
g_vm->_flagPaintCharacter = true; // always redraws the character
int x1 = g_vm->_actor->_lim[0];
int y1 = g_vm->_actor->_lim[2] - TOP;
int x2 = g_vm->_actor->_lim[1];
int y2 = g_vm->_actor->_lim[3] - TOP;
// erase character
if (g_vm->_flagShowCharacter && x2 > x1 && y2 > y1) { // if a description exists
DObj.rect = Common::Rect(0, TOP, MAXX, AREA + TOP);
DObj.l = Common::Rect(x1, y1, x2, y2);
DObj.objIndex = -1;
DObj.drawMask = false;
g_vm->_graphicsMgr->DrawObj(DObj);
g_vm->addDirtyRect(DObj.l);
g_vm->_actorRect = &g_vm->_dirtyRects.back();
} else if (g_vm->_animMgr->_animRect.left != MAXX) {
DObj.rect = Common::Rect(0, TOP, MAXX, AREA + TOP);
DObj.l = g_vm->_animMgr->_animRect;
DObj.objIndex = -1;
DObj.drawMask = false;
g_vm->_graphicsMgr->DrawObj(DObj);
g_vm->addDirtyRect(DObj.l);
g_vm->_actorRect = &g_vm->_dirtyRects.back();
}
// CANCELLO LA SCRITTA
if (TextStatus & TEXT_DEL) {
// cancello scritta
DObj.rect = Common::Rect(0, TOP, MAXX, MAXY + TOP);
DObj.l = g_vm->_textMgr->getOldTextRect();
DObj.l.translate(0, -TOP);
DObj.objIndex = -1;
DObj.drawMask = false;
if (DObj.l.top >= 0 && DObj.l.bottom < AREA) {
g_vm->_graphicsMgr->DrawObj(DObj);
} else {
g_vm->_graphicsMgr->EraseObj(DObj);
}
g_vm->_textMgr->clearOldText();
g_vm->addDirtyRect(DObj.l);
if (!(TextStatus & TEXT_DRAW)) // se non c'e' nuova scritta
TextStatus = TEXT_OFF; // non aggiorna piu' scritta
}
// CANCELLA TUTTI GLI OGGETTI TOGLI
for (Common::List<SSortTable>::iterator i = g_vm->_sortTable.begin(); i != g_vm->_sortTable.end(); ++i) {
if (i->_remove) {
DObj.rect = Common::Rect(0, TOP, MAXX, AREA + TOP);
DObj.l = g_vm->_obj[i->_objectId]._rect;
DObj.objIndex = -1;
DObj.drawMask = false;
g_vm->_graphicsMgr->DrawObj(DObj);
g_vm->addDirtyRect(DObj.l);
}
}
// trova la posizione dell'omino
g_vm->_pathFind->actorOrder();
// PER OGNI BOX DALL'ORIZZONTE IN AVANTI...
// COPIA PER LIVELLO
for (int liv = g_vm->_pathFind->_numSortPan; liv >= 0; liv--) {
uint16 CurBox = g_vm->_pathFind->_sortPan[liv]._num;
// disegna tutti gli oggetti e le animazioni che intersecano
// i limiti e si riferiscono al box corrente
PaintObjAnm(CurBox);
}
if (TextStatus & TEXT_DRAW) {
g_vm->_textMgr->drawCurString();
TextStatus = TEXT_DRAW; // Activate text update
}
g_vm->_soundMgr->SoundPasso((g_vm->_actor->_lim[1] + g_vm->_actor->_lim[0]) / 2, (g_vm->_actor->_lim[5] + g_vm->_actor->_lim[4]) / 2, g_vm->_actor->_curAction, g_vm->_actor->_curFrame, g_vm->_room[g_vm->_curRoom]._sounds);
if (!flag && !g_vm->_flagDialogActive) {
g_vm->_graphicsMgr->copyToScreen(0, 0, MAXX, MAXY);
}
g_vm->_sortTable.clear();
g_vm->_flagPaintCharacter = false;
g_vm->_flagWaitRegen = false;
// Handle papaverine delayed action
if ((g_vm->_curRoom == kRoom4A) && (g_vm->_obj[oCHOCOLATES4A]._flag & kObjFlagExtra)) {
if (g_vm->_animMgr->smkCurFrame(kSmackerBackground) > 480) {
g_vm->playScript(s4AHELLEN);
g_vm->_obj[oCHOCOLATES4A]._flag &= ~kObjFlagExtra;
}
}
//
}
int getRoomObjectIndex(uint16 objectId) {
for (uint16 index = 0; index < MAXOBJINROOM; index++) {
const uint16 curObjId = g_vm->_room[g_vm->_curRoom]._object[index];
if (curObjId == 0)
return -1;
if (curObjId == objectId)
return index;
}
return -1;
}
/* -----------------12/06/97 21.35-------------------
Disegna tutti gli oggetti e le animazioni che intersecano i limiti
appartenenti a curbox
--------------------------------------------------*/
void PaintObjAnm(uint16 CurBox) {
g_vm->_animMgr->refreshAnim(CurBox);
// disegna nuove schede appartenenti al box corrente
for (Common::List<SSortTable>::iterator i = g_vm->_sortTable.begin(); i != g_vm->_sortTable.end(); ++i) {
if (!i->_remove) {
if (g_vm->_obj[i->_objectId]._nbox == CurBox) {
// l'oggetto bitmap al livello desiderato
SObject o = g_vm->_obj[i->_objectId];
DObj.rect = o._rect;
DObj.rect.translate(0, TOP);
DObj.l = Common::Rect(DObj.rect.width(), DObj.rect.height());
DObj.objIndex = getRoomObjectIndex(i->_objectId);
DObj.drawMask = o._mode & OBJMODE_MASK;
g_vm->_graphicsMgr->DrawObj(DObj);
g_vm->_dirtyRects.push_back(DObj.rect);
}
}
}
for (DirtyRectsIterator d = g_vm->_dirtyRects.begin(); d != g_vm->_dirtyRects.end(); ++d) {
for (int b = 0; b < MAXOBJINROOM; b++) {
const uint16 curObject = g_vm->_room[g_vm->_curRoom]._object[b];
if (!curObject)
break;
SObject obj = g_vm->_obj[curObject];
if ((obj._mode & (OBJMODE_FULL | OBJMODE_MASK)) &&
g_vm->isObjectVisible(curObject) &&
(obj._nbox == CurBox)) {
Common::Rect r = *d;
Common::Rect r2 = obj._rect;
r2.translate(0, TOP);
// Include the bottom right of the rect in the intersects() check
r2.bottom++;
r2.right++;
if (r.intersects(r2)) {
DObj.rect = obj._rect;
DObj.rect.translate(0, TOP);
// Restore the bottom right of the rect
r2.bottom--;
r2.right--;
// TODO: Simplify this?
const int16 xr1 = (r2.left > r.left) ? 0 : r.left - r2.left;
const int16 yr1 = (r2.top > r.top) ? 0 : r.top - r2.top;
const int16 xr2 = MIN<int16>(r.right, r2.right) - r2.left;
const int16 yr2 = MIN<int16>(r.bottom, r2.bottom) - r2.top;
DObj.l = Common::Rect(xr1, yr1, xr2, yr2);
DObj.objIndex = b;
DObj.drawMask = obj._mode & OBJMODE_MASK;
g_vm->_graphicsMgr->DrawObj(DObj);
}
}
}
}
if (g_vm->_actorPos == CurBox && g_vm->_flagShowCharacter && g_vm->_flagCharacterExists) {
g_vm->_renderer->drawCharacter(CALCPOINTS);
int x1 = g_vm->_actor->_lim[0];
int y1 = g_vm->_actor->_lim[2];
int x2 = g_vm->_actor->_lim[1];
int y2 = g_vm->_actor->_lim[3];
if (x2 > x1 && y2 > y1) {
// enlarge the rectangle of the character
Common::Rect l(x1, y1, x2, y2);
if (g_vm->_actorRect)
g_vm->_actorRect->extend(l);
g_vm->_renderer->resetZBuffer(x1, y1, x2, y2);
}
g_vm->_renderer->drawCharacter(DRAWFACES);
} else if (g_vm->_actorPos == CurBox && !g_vm->_flagDialogActive) {
g_vm->_animMgr->refreshSmkAnim(g_vm->_animMgr->_playingAnims[kSmackerAction]);
}
}
} // End of namespace Trecision

View file

@ -76,6 +76,11 @@ typedef Common::List<Common::Rect>::iterator DirtyRectsIterator;
struct SVertex { struct SVertex {
float _x, _y, _z; float _x, _y, _z;
float _nx, _ny, _nz; float _nx, _ny, _nz;
void clear() {
_x = _y = _z = 0.0f;
_nx = _ny = _nz = 0.0f;
}
}; };
struct SFace { struct SFace {
@ -202,7 +207,8 @@ public:
static bool isGameArea(Common::Point pos); static bool isGameArea(Common::Point pos);
static bool isInventoryArea(Common::Point pos); static bool isInventoryArea(Common::Point pos);
static bool isIconArea(Common::Point pos); static bool isIconArea(Common::Point pos);
int getRoomObjectIndex(uint16 objectId);
// Others // Others
void checkSystem(); void checkSystem();
bool dataSave(); bool dataSave();

View file

@ -20,6 +20,7 @@
* *
*/ */
#include "3d.h"
#include "common/system.h" #include "common/system.h"
#include "trecision/scheduler.h" #include "trecision/scheduler.h"
@ -269,7 +270,7 @@ void TrecisionEngine::ProcessTime() {
OldLightIcon = _lightIcon; OldLightIcon = _lightIcon;
} }
PaintScreen(false); _renderer->paintScreen(false);
_textMgr->clearTextStack(); _textMgr->clearTextStack();
uint32 paintTime = readTime(); uint32 paintTime = readTime();
@ -350,4 +351,16 @@ bool TrecisionEngine::isIconArea(Common::Point pos) {
return pos.y >= TOP + AREA && pos.y < MAXY && pos.x >= ICONMARGSX && pos.x <= MAXX - ICONMARGDX; return pos.y >= TOP + AREA && pos.y < MAXY && pos.x >= ICONMARGSX && pos.x <= MAXX - ICONMARGDX;
} }
int TrecisionEngine::getRoomObjectIndex(uint16 objectId) {
for (uint16 index = 0; index < MAXOBJINROOM; index++) {
const uint16 curObjId = _room[g_vm->_curRoom]._object[index];
if (curObjId == 0)
return -1;
if (curObjId == objectId)
return index;
}
return -1;
}
} // End of namespace Trecision } // End of namespace Trecision