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 namespace TwinE {
56 
57 class BodyData;
58 class TwinEEngine;
59 
61  int16 intensity = 0;
62  int16 x = 0;
63  int16 y = 0;
64 };
65 
66 bool isPolygonVisible(const ComputedVertex *vertices);
67 
69  uint8 renderType = 0;
70  uint8 numVertices = 0;
71  int16 colorIndex = 0; // intensity
72  // followed by Vertex array
73 };
74 
75 struct IMatrix3x3 {
76  IVec3 row1;
77  IVec3 row2;
78  IVec3 row3;
79 };
80 
81 inline IMatrix3x3 operator*(const IMatrix3x3 &matrix, const IVec3 &vec) {
82  IMatrix3x3 out;
83  out.row1.x = matrix.row1.x * vec.x;
84  out.row1.y = matrix.row1.y * vec.x;
85  out.row1.z = matrix.row1.z * vec.x;
86 
87  out.row2.x = matrix.row2.x * vec.y;
88  out.row2.y = matrix.row2.y * vec.y;
89  out.row2.z = matrix.row2.z * vec.y;
90 
91  out.row3.x = matrix.row3.x * vec.z;
92  out.row3.y = matrix.row3.y * vec.z;
93  out.row3.z = matrix.row3.z * vec.z;
94  return out;
95 }
96 
97 class Renderer {
98 private:
99  TwinEEngine *_engine;
100 
101  struct RenderCommand {
102  int16 depth = 0;
103  int16 renderType = 0;
111  uint8 *dataPtr = nullptr;
112  };
113 
119  struct CmdRenderLine {
120  uint8 colorIndex = 0;
121  uint8 unk1 = 0;
122  uint8 unk2 = 0;
123  uint8 unk3 = 0;
124  int16 x1 = 0;
125  int16 y1 = 0;
126  int16 x2 = 0;
127  int16 y2 = 0;
128  };
129 
135  struct CmdRenderSphere {
136  uint16 color = 0; // color start and end values
137  uint8 polyRenderType = 0;
138  int16 radius = 0;
139  int16 x = 0;
140  int16 y = 0;
141  int16 z = 0;
142  };
143 
144  struct ModelData {
145  I16Vec3 computedPoints[800];
146  I16Vec3 flattenPoints[800];
147  int16 normalTable[500]{0};
148  };
149 
150  // this is a member var, because 10k on the stack is not supported by every platform
151  ModelData _modelData;
152 
153  // AnimNuage
154  void animModel(ModelData *modelData, const BodyData &bodyData, RenderCommand *renderCmds, const IVec3 &angleVec, const IVec3 &renderPos, Common::Rect &modelRect);
155  bool computeSphere(int32 x, int32 y, int32 radius, int &vtop, int &vbottom);
156  bool renderObjectIso(const BodyData &bodyData, RenderCommand **renderCmds, ModelData *modelData, Common::Rect &modelRect); // RenderObjetIso
157  IVec3 longInverseRot(int32 x, int32 y, int32 z);
158  inline IVec3 getCameraAnglePositions(const IVec3 &vec) {
159  return longInverseRot(vec.x, vec.y, vec.z);
160  }
161  void rotMatIndex2(IMatrix3x3 *targetMatrix, const IMatrix3x3 *currentMatrix, const IVec3 &angleVec);
162  void rotList(const Common::Array<BodyVertex>& vertices, int32 firstPoint, int32 numPoints, I16Vec3 *destPoints, const IMatrix3x3 *rotationMatrix, const IVec3 &destPos);
163  void processRotatedElement(IMatrix3x3 *targetMatrix, const Common::Array<BodyVertex>& vertices, int32 rotX, int32 rotY, int32 rotZ, const BodyBone &bone, ModelData *modelData);
164  void transRotList(const Common::Array<BodyVertex>& vertices, int32 firstPoint, int32 numPoints, I16Vec3 *destPoints, const IMatrix3x3 *translationMatrix, const IVec3 &angleVec, const IVec3 &destPos);
165  void translateGroup(IMatrix3x3 *targetMatrix, const Common::Array<BodyVertex>& vertices, int32 rotX, int32 rotY, int32 rotZ, const BodyBone &bone, ModelData *modelData);
169  IVec3 rot(const IMatrix3x3 &matrix, int32 x, int32 y, int32 z);
170 
171  IVec3 _cameraPos;
172  IVec3 _projectionCenter{320, 200, 0};
173 
174  int32 _kFactor = 128;
175  int32 _lFactorX = 1024;
176  int32 _lFactorY = 840;
177 
178  IMatrix3x3 _matrixWorld;
179  IMatrix3x3 _matricesTable[30 + 1];
180  IVec3 _normalLight; // NormalXLight, NormalYLight, NormalZLight
181  IVec3 _cameraRot;
182 
183  RenderCommand _renderCmds[1000];
188  uint8 _renderCoordinatesBuffer[10000]{0};
189  ComputedVertex _clippedPolygonVertices1[128];
190  ComputedVertex _clippedPolygonVertices2[128];
191 
192  int16* _tabVerticG = nullptr;
193  int16* _tabVerticD = nullptr;
194  int16* _tabCoulG = nullptr;
195  int16* _tabCoulD = nullptr;
196  int16* _taby0 = nullptr;
197  int16* _taby1 = nullptr;
198  int16* _tabx0 = nullptr; // also _tabCoulG
199  int16* _tabx1 = nullptr; // also _tabCoulD
200 
201  bool _isUsingIsoProjection = false;
202 
203  void svgaPolyCopper(int16 vtop, int16 vbottom, uint16 color) const;
204  void svgaPolyBopper(int16 vtop, int16 vbottom, uint16 color) const;
205  void svgaPolyTriste(int16 vtop, int16 vbottom, uint16 color) const;
206  void svgaPolyTele(int16 vtop, int16 vbottom, uint16 color) const;
207  void svgaPolyTrans(int16 vtop, int16 vbottom, uint16 color) const;
208  void svgaPolyTrame(int16 vtop, int16 vbottom, uint16 color) const;
209  void svgaPolyGouraud(int16 vtop, int16 vbottom) const;
210  void svgaPolyDith(int16 vtop, int16 vbottom) const;
211  void svgaPolyMarbre(int16 vtop, int16 vbottom, uint16 color) const;
212  void svgaPolyTriche(int16 vtop, int16 vbottom, uint16 color) const;
213  bool computePoly(int16 polyRenderType, const ComputedVertex *vertices, int32 numVertices, int16 &vtop, int16 &vbottom);
214 
215  const RenderCommand *depthSortRenderCommands(int32 numOfPrimitives);
216  uint8 *preparePolygons(const Common::Array<BodyPolygon>& polygons, int32 &numOfPrimitives, RenderCommand **renderCmds, uint8 *renderBufferPtr, ModelData *modelData);
217  uint8 *prepareSpheres(const Common::Array<BodySphere>& spheres, int32 &numOfPrimitives, RenderCommand **renderCmds, uint8 *renderBufferPtr, ModelData *modelData);
218  uint8 *prepareLines(const Common::Array<BodyLine>& lines, int32 &numOfPrimitives, RenderCommand **renderCmds, uint8 *renderBufferPtr, ModelData *modelData);
219 
220  void flipMatrix();
221 
222  void fillTextPolyNoClip(int32 top, int32 bottom, const uint8 *holomapImage, uint32 holomapImageSize);
223  void fillHolomapTriangle(int16 *pDest, int32 x1, int32 y1, int32 x2, int32 y2);
224  void fillHolomapTriangles(const ComputedVertex &vertex1, const ComputedVertex &vertex2, const ComputedVertex &texCoord1, const ComputedVertex &texCoord2, int32 &top, int32 &bottom);
225 
226  int16 leftClip(int16 polyRenderType, ComputedVertex** offTabPoly, int32 numVertices);
227  int16 rightClip(int16 polyRenderType, ComputedVertex** offTabPoly, int32 numVertices);
228  int16 topClip(int16 polyRenderType, ComputedVertex** offTabPoly, int32 numVertices);
229  int16 bottomClip(int16 polyRenderType, ComputedVertex** offTabPoly, int32 numVertices);
230  int32 computePolyMinMax(int16 polyRenderType, ComputedVertex **offTabPoly, int32 numVertices, int16 &vtop, int16 &vbottom);
231 public:
232  Renderer(TwinEEngine *engine);
233  ~Renderer();
234 
235  void init(int32 w, int32 h);
236 
237  void setCameraRotation(int32 x, int32 y, int32 z);
238 
245  IVec2 rotate(int32 side, int32 forward, int32 angle) const;
246 
247  void setLightVector(int32 angleX, int32 angleY, int32 angleZ);
248  IVec3 longWorldRot(int32 x, int32 y, int32 z);
249 
250  IVec3 worldRotatePoint(const IVec3& vec);
251 
252  void fillVertices(int16 vtop, int16 vbottom, uint8 renderType, uint16 color);
253  void renderPolygons(const CmdRenderPolygon &polygon, ComputedVertex *vertices);
254 
255  inline IVec3 projectPoint(const IVec3& pos) { // ProjettePoint
256  return projectPoint(pos.x, pos.y, pos.z);
257  }
258 
259  void projIso(IVec3 &pos, int32 x, int32 y, int32 z);
260 
261  IVec3 projectPoint(int32 cX, int32 cY, int32 cZ);
262 
263  void setFollowCamera(int32 transPosX, int32 transPosY, int32 transPosZ, int32 cameraAlpha, int32 cameraBeta, int32 cameraGamma, int32 cameraZoom);
264  void setPosCamera(int32 x, int32 y, int32 z);
265  IVec3 setAngleCamera(int32 x, int32 y, int32 z);
266  IVec3 setInverseAngleCamera(int32 x, int32 y, int32 z);
267 
268  inline IVec3 setBaseRotation(const IVec3 &rot) {
269  return setAngleCamera(rot.x, rot.y, rot.z);
270  }
271 
272  void setProjection(int32 x, int32 y, int32 depthOffset, int32 scaleX, int32 scaleY);
273  void setIsoProjection(int32 x, int32 y, int32 scale);
274 
275  bool affObjetIso(int32 x, int32 y, int32 z, int32 angleX, int32 angleY, int32 angleZ, const BodyData &bodyData, Common::Rect &modelRect);
276 
277  inline bool renderIsoModel(const IVec3 &pos, int32 angleX, int32 angleY, int32 angleZ, const BodyData &bodyData, Common::Rect &modelRect) {
278  return affObjetIso(pos.x, pos.y, pos.z, angleX, angleY, angleZ, bodyData, modelRect);
279  }
280 
284  void renderBehaviourModel(int32 boxLeft, int32 boxTop, int32 boxRight, int32 boxBottom, int32 y, int32 angle, const BodyData &bodyData, ActorMoveStruct &move);
288  void drawObj3D(const Common::Rect &rect, int32 y, int32 angle, const BodyData &bodyData, ActorMoveStruct &move);
289 
293  void draw3dObject(int32 x, int32 y, const BodyData &bodyData, int32 angle, int32 cameraZoom);
294 
295  void asmTexturedTriangleNoClip(const ComputedVertex vertexCoordinates[3], const ComputedVertex textureCoordinates[3], const uint8 *holomapImage, uint32 holomapImageSize);
296 };
297 
298 inline void Renderer::setCameraRotation(int32 x, int32 y, int32 z) {
299  _cameraRot.x = x;
300  _cameraRot.y = y;
301  _cameraRot.z = z;
302 }
303 
304 } // namespace TwinE
305 
306 #endif
Definition: shared.h:94
Definition: array.h:52
Definition: shared.h:113
Definition: rect.h:144
Definition: renderer.h:75
Graphics::Surface * scale(const Graphics::Surface &srcImage, int xSize, int ySize)
Definition: renderer.h:97
Definition: shared.h:86
Definition: renderer.h:68
constexpr remove_reference_t< T > && move(T &&t) noexcept
Definition: util.h:209
Definition: twine.h:200
Definition: achievements_tables.h:27
Definition: actor.h:40
Definition: renderer.h:60
Definition: bodytypes.h:54
Definition: body.h:35