ScummVM API documentation
renderer.h
1 /* ScummVM - Graphic Adventure Engine
2  *
3  * ScummVM is the legal property of its developers, whose names
4  * are too numerous to list here. Please refer to the COPYRIGHT
5  * file distributed with this source distribution.
6  *
7  * This program is free software: you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation, either version 3 of the License, or
10  * (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program. If not, see <http://www.gnu.org/licenses/>.
19  *
20  */
21 
22 #ifndef TWINE_RENDERER_RENDERER_H
23 #define TWINE_RENDERER_RENDERER_H
24 
25 #include "common/endian.h"
26 #include "common/rect.h"
27 #include "common/scummsys.h"
28 #include "twine/parser/bodytypes.h"
29 #include "twine/twine.h"
30 
31 #define POLYGONTYPE_FLAT 0
32 #define POLYGONTYPE_TELE 1
33 // horizontal color adjustment with changing pattern over the polygon
34 #define POLYGONTYPE_COPPER 2
35 #define POLYGONTYPE_BOPPER 3
36 #define POLYGONTYPE_MARBLE 4
37 #define POLYGONTYPE_TRANS 5
38 #define POLYGONTYPE_TRAME 6
39 #define POLYGONTYPE_GOURAUD 7
40 #define POLYGONTYPE_DITHER 8
41 #define POLYGONTYPE_OUTLINE 9
42 
43 #define MAT_TRISTE 0
44 #define MAT_PIERRE 1
45 #define MAT_COPPER 2
46 #define MAT_BOPPER 3
47 #define MAT_MARBRE 4
48 #define MAT_TRANS 5
49 #define MAT_TRAME 6
50 #define MAT_FLAT 7
51 #define MAT_GRANIT 8
52 #define MAT_GOURAUD 9
53 #define MAT_DITHER 10
54 
55 #define TYPE_3D 0
56 #define TYPE_ISO 1
57 
58 namespace TwinE {
59 
60 class BodyData;
61 class TwinEEngine;
62 
64  int16 intensity = 0;
65  int16 x = 0;
66  int16 y = 0;
67 };
68 
69 bool isPolygonVisible(const ComputedVertex *vertices);
70 
72  uint8 renderType = 0;
73  uint8 numVertices = 0;
74  int16 colorIndex = 0; // intensity
75  // followed by Vertex array
76 };
77 
78 struct IMatrix3x3 {
79  IVec3 row1;
80  IVec3 row2;
81  IVec3 row3;
82 };
83 
84 inline IMatrix3x3 operator*(const IMatrix3x3 &matrix, const IVec3 &vec) {
85  IMatrix3x3 out;
86  out.row1.x = matrix.row1.x * vec.x;
87  out.row1.y = matrix.row1.y * vec.x;
88  out.row1.z = matrix.row1.z * vec.x;
89 
90  out.row2.x = matrix.row2.x * vec.y;
91  out.row2.y = matrix.row2.y * vec.y;
92  out.row2.z = matrix.row2.z * vec.y;
93 
94  out.row3.x = matrix.row3.x * vec.z;
95  out.row3.y = matrix.row3.y * vec.z;
96  out.row3.z = matrix.row3.z * vec.z;
97  return out;
98 }
99 
100 class Renderer {
101 private:
102  TwinEEngine *_engine;
103 
104  struct RenderCommand {
105  int16 depth = 0;
106  int16 renderType = 0;
114  uint8 *dataPtr = nullptr;
115  };
116 
122  struct CmdRenderLine {
123  uint8 colorIndex = 0;
124  uint8 unk1 = 0;
125  uint8 unk2 = 0;
126  uint8 unk3 = 0;
127  int16 x1 = 0;
128  int16 y1 = 0;
129  int16 x2 = 0;
130  int16 y2 = 0;
131  };
132 
138  struct CmdRenderSphere {
139  uint16 color = 0; // color start and end values
140  uint8 polyRenderType = 0;
141  int16 radius = 0;
142  int16 x = 0;
143  int16 y = 0;
144  int16 z = 0;
145  };
146 
147  struct ModelData {
148  I16Vec3 computedPoints[800]; // List_Anim_Point
149  I16Vec3 flattenPoints[800];
150  int16 normalTable[500]{0};
151  };
152 
153  // this is a member var, because 10k on the stack is not supported by every platform
154  ModelData _modelData;
155 
156  // AnimNuage
157  void animModel(ModelData *modelData, const BodyData &bodyData, RenderCommand *renderCmds, const IVec3 &angleVec, const IVec3 &renderPos, Common::Rect &modelRect);
158  bool computeSphere(int32 x, int32 y, int32 radius, int &vtop, int &vbottom);
159  bool renderObjectIso(const BodyData &bodyData, RenderCommand **renderCmds, ModelData *modelData, Common::Rect &modelRect); // RenderObjetIso
160  IVec3 longInverseRot(int32 x, int32 y, int32 z);
161  inline IVec3 getCameraAnglePositions(const IVec3 &vec) {
162  return longInverseRot(vec.x, vec.y, vec.z);
163  }
164  void rotMatIndex2(IMatrix3x3 *targetMatrix, const IMatrix3x3 *currentMatrix, const IVec3 &angleVec);
165  void rotList(const Common::Array<BodyVertex>& vertices, int32 firstPoint, int32 numPoints, I16Vec3 *destPoints, const IMatrix3x3 *rotationMatrix, const IVec3 &destPos);
166  void processRotatedElement(IMatrix3x3 *targetMatrix, const Common::Array<BodyVertex>& vertices, int32 rotX, int32 rotY, int32 rotZ, const BodyBone &bone, ModelData *modelData);
167  void transRotList(const Common::Array<BodyVertex>& vertices, int32 firstPoint, int32 numPoints, I16Vec3 *destPoints, const IMatrix3x3 *translationMatrix, const IVec3 &angleVec, const IVec3 &destPos);
168  void translateGroup(IMatrix3x3 *targetMatrix, const Common::Array<BodyVertex>& vertices, int32 rotX, int32 rotY, int32 rotZ, const BodyBone &bone, ModelData *modelData);
172  IVec3 rot(const IMatrix3x3 &matrix, int32 x, int32 y, int32 z);
173 
174  IVec3 _cameraPos; // CameraX, CameraY, CameraZ
175  IVec3 _projectionCenter{320, 200, 0}; // XCentre, YCentre, IsoScale
176 
177  int32 _kFactor = 128;
178  int32 _lFactorX = 1024;
179  int32 _lFactorY = 840;
180 
181  IMatrix3x3 _matrixWorld; // LMatriceWorld
182  IMatrix3x3 _matricesTable[30 + 1];
183  IVec3 _normalLight; // NormalXLight, NormalYLight, NormalZLight
184  IVec3 _cameraRot; // CameraXr, CameraYr, CameraZr
185 
186  RenderCommand _renderCmds[1000];
191  uint8 _renderCoordinatesBuffer[10000]{0};
192  ComputedVertex _clippedPolygonVertices1[128];
193  ComputedVertex _clippedPolygonVertices2[128];
194 
195  int16* _tabVerticG = nullptr;
196  int16* _tabVerticD = nullptr;
197  int16* _tabCoulG = nullptr;
198  int16* _tabCoulD = nullptr;
199  int16* _taby0 = nullptr;
200  int16* _taby1 = nullptr;
201  int16* _tabx0 = nullptr; // also _tabCoulG
202  int16* _tabx1 = nullptr; // also _tabCoulD
203 
204  bool _typeProj = TYPE_3D;
205 
206  void svgaPolyCopper(int16 vtop, int16 vbottom, uint16 color) const;
207  void svgaPolyBopper(int16 vtop, int16 vbottom, uint16 color) const;
208  void svgaPolyTriste(int16 vtop, int16 vbottom, uint16 color) const;
209  void svgaPolyTele(int16 vtop, int16 vbottom, uint16 color) const;
210  void svgaPolyTrans(int16 vtop, int16 vbottom, uint16 color) const;
211  void svgaPolyTrame(int16 vtop, int16 vbottom, uint16 color) const;
212  void svgaPolyGouraud(int16 vtop, int16 vbottom) const;
213  void svgaPolyDith(int16 vtop, int16 vbottom) const;
214  void svgaPolyMarbre(int16 vtop, int16 vbottom, uint16 color) const;
215  void svgaPolyTriche(int16 vtop, int16 vbottom, uint16 color) const;
216  bool computePoly(int16 polyRenderType, const ComputedVertex *vertices, int32 numVertices, int16 &vtop, int16 &vbottom);
217 
218  const RenderCommand *depthSortRenderCommands(int32 numOfPrimitives);
219  uint8 *preparePolygons(const Common::Array<BodyPolygon>& polygons, int32 &numOfPrimitives, RenderCommand **renderCmds, uint8 *renderBufferPtr, ModelData *modelData);
220  uint8 *prepareSpheres(const Common::Array<BodySphere>& spheres, int32 &numOfPrimitives, RenderCommand **renderCmds, uint8 *renderBufferPtr, ModelData *modelData);
221  uint8 *prepareLines(const Common::Array<BodyLine>& lines, int32 &numOfPrimitives, RenderCommand **renderCmds, uint8 *renderBufferPtr, ModelData *modelData);
222 
223  void flipMatrix();
224 
225  void fillTextPolyNoClip(int32 top, int32 bottom, const uint8 *holomapImage, uint32 holomapImageSize);
226  void fillHolomapTriangle(int16 *pDest, int32 x1, int32 y1, int32 x2, int32 y2);
227  void fillHolomapTriangles(const ComputedVertex &vertex1, const ComputedVertex &vertex2, const ComputedVertex &texCoord1, const ComputedVertex &texCoord2, int32 &top, int32 &bottom);
228 
229  // ClipGauche, ClipDroite, ClipHaut, ClipBas
230  int16 leftClip(int16 polyRenderType, ComputedVertex** offTabPoly, int32 numVertices);
231  int16 rightClip(int16 polyRenderType, ComputedVertex** offTabPoly, int32 numVertices);
232  int16 topClip(int16 polyRenderType, ComputedVertex** offTabPoly, int32 numVertices);
233  int16 bottomClip(int16 polyRenderType, ComputedVertex** offTabPoly, int32 numVertices);
234  int32 computePolyMinMax(int16 polyRenderType, ComputedVertex **offTabPoly, int32 numVertices, int16 &vtop, int16 &vbottom);
235 public:
236  Renderer(TwinEEngine *engine);
237  ~Renderer();
238 
239  void init(int32 w, int32 h);
240 
241  void setCameraRotation(int32 x, int32 y, int32 z);
242 
249  IVec2 rotate(int32 side, int32 forward, int32 angle) const;
250 
251  void setLightVector(int32 angleX, int32 angleY, int32 angleZ);
252  IVec3 longWorldRot(int32 x, int32 y, int32 z);
253 
254  IVec3 worldRotatePoint(const IVec3& vec);
255 
256  void fillVertices(int16 vtop, int16 vbottom, uint8 renderType, uint16 color);
257  void renderPolygons(const CmdRenderPolygon &polygon, ComputedVertex *vertices);
258 
259  inline IVec3 projectPoint(const IVec3& pos) { // ProjettePoint
260  return projectPoint(pos.x, pos.y, pos.z);
261  }
262 
263  void projIso(IVec3 &pos, int32 x, int32 y, int32 z);
264 
265  IVec3 projectPoint(int32 cX, int32 cY, int32 cZ);
266 
267  void setFollowCamera(int32 transPosX, int32 transPosY, int32 transPosZ, int32 cameraAlpha, int32 cameraBeta, int32 cameraGamma, int32 cameraZoom);
268  void setPosCamera(int32 x, int32 y, int32 z);
269  IVec3 setAngleCamera(int32 alpha, int32 beta, int32 gamma);
270  IVec3 setInverseAngleCamera(int32 alpha, int32 beta, int32 gamma);
271 
272  inline IVec3 setBaseRotation(const IVec3 &rot) {
273  return setAngleCamera(rot.x, rot.y, rot.z);
274  }
275 
276  void setProjection(int32 x, int32 y, int32 depthOffset, int32 scaleX, int32 scaleY);
277  void setIsoProjection(int32 x, int32 y, int32 scale);
278 
279  bool affObjetIso(int32 x, int32 y, int32 z, int32 angleX, int32 angleY, int32 angleZ, const BodyData &bodyData, Common::Rect &modelRect);
280 
281  inline bool renderIsoModel(const IVec3 &pos, int32 angleX, int32 angleY, int32 angleZ, const BodyData &bodyData, Common::Rect &modelRect) {
282  return affObjetIso(pos.x, pos.y, pos.z, angleX, angleY, angleZ, bodyData, modelRect);
283  }
284 
288  void renderBehaviourModel(int32 boxLeft, int32 boxTop, int32 boxRight, int32 boxBottom, int32 y, int32 angle, const BodyData &bodyData, RealValue &move);
292  void drawObj3D(const Common::Rect &rect, int32 y, int32 angle, const BodyData &bodyData, RealValue &move);
293 
297  void draw3dObject(int32 x, int32 y, const BodyData &bodyData, int32 angle, int32 cameraZoom);
298 
299  void asmTexturedTriangleNoClip(const ComputedVertex vertexCoordinates[3], const ComputedVertex textureCoordinates[3], const uint8 *holomapImage, uint32 holomapImageSize);
300 };
301 
302 inline void Renderer::setCameraRotation(int32 x, int32 y, int32 z) {
303  _cameraRot.x = x;
304  _cameraRot.y = y;
305  _cameraRot.z = z;
306 }
307 
308 } // namespace TwinE
309 
310 #endif
Definition: shared.h:103
Definition: array.h:52
Definition: shared.h:122
Definition: rect.h:144
Definition: renderer.h:78
Graphics::Surface * scale(const Graphics::Surface &srcImage, int xSize, int ySize)
Definition: renderer.h:100
Definition: shared.h:95
Definition: renderer.h:71
Definition: actor.h:40
Definition: twine.h:207
Definition: achievements_tables.h:27
Out move(In first, In last, Out dst)
Definition: algorithm.h:109
Definition: renderer.h:63
Definition: bodytypes.h:54
Definition: body.h:35