World of Might and Magic  0.2.0
Open reimplementation of Might and Magic 6 7 8 game engine
Render.cpp
См. документацию.
2 
3 #include <d3d.h>
4 #include <ddraw.h>
5 
6 #include <algorithm>
7 
8 #include "Engine/Engine.h"
9 #include "Engine/LOD.h"
10 #include "Engine/OurMath.h"
11 #include "Engine/Party.h"
12 #include "Engine/SpellFxRenderer.h"
13 #include "Engine/Time.h"
14 
15 #include "Engine/Objects/Actor.h"
18 
25 #include "Engine/Graphics/Lights.h"
27 #include "Engine/Graphics/PCX.h"
32 #include "Engine/Graphics/Vis.h"
34 
36 
37 #include "GUI/GUIWindow.h"
38 
39 #include "IO/Mouse.h"
40 
41 #include "Arcomage/Arcomage.h"
42 
43 #include "Platform/Api.h"
44 
45 #pragma comment(lib, "GdiPlus.lib")
46 
48 
49 struct IDirectDrawClipper *pDDrawClipper;
51 
52 RenderVertexSoft VertexRenderList[50]; // array_50AC10
54 
56 
57 DDPIXELFORMAT ddpfPrimarySuface;
58 
59 void ErrHR(HRESULT hr, const char *pAPI, const char *pFunction,
60  const char *pFile, int line) {
61  if (SUCCEEDED(hr)) {
62  return;
63  }
64 
65  char msg[4096];
66  sprintf(msg, "%s error (%08X) in\n\t%s\nin\n\t%s:%u", pAPI, hr, pFunction,
67  pFile, line);
68 
69  char caption[1024];
70  sprintf(caption, "%s error", pAPI);
71 
72  Error(msg);
73 }
74 
75 unsigned int Render::GetRenderWidth() const { return window->GetWidth(); }
76 unsigned int Render::GetRenderHeight() const { return window->GetHeight(); }
77 
78 
79 
81  return TextureD3D::Create(new ColorKey_LOD_Loader(pIcons_LOD, name, colorkey));
82 }
83 
86 }
87 
90 }
91 
94 }
95 
98 }
99 
102 }
103 
104 Texture *Render::CreateTexture_Blank(unsigned int width, unsigned int height,
105  IMAGE_FORMAT format, const void *pixels) {
106 
108 }
109 
110 
111 
114 }
115 
116 Texture *Render::CreateSprite(const String &name, unsigned int palette_id,
117  unsigned int lod_sprite_id) {
118  return TextureD3D::Create(
119  new Sprites_LOD_Loader(pSprites_LOD, palette_id, name, lod_sprite_id));
120 }
121 
123  // do not use this - slow
124  __debugbreak();
125  logger->Info(L"Reduce use of WritePixel16");
126 
127  unsigned int b = (color & 0x1F) << 3;
128  unsigned int g = ((color >> 5) & 0x3F) << 2;
129  unsigned int r = ((color >> 11) & 0x1F) << 3;
130 
131  Gdiplus::Color c(r, g, b);
132  p2DSurface->SetPixel(x, y, c);
133 }
134 
136  bool bResult = false;
137 
138  IDirectDrawSurface4 *pSurface1 = nullptr;
139  IDirect3DTexture2 *pTexture1 = nullptr;
140  pRenderD3D->CreateTexture(64, 64, &pSurface1, &pTexture1, true, false, 32);
141  ErrD3D(pRenderD3D->pDevice->SetTexture(0, pTexture1));
142  ErrD3D(pRenderD3D->pDevice->SetTextureStageState(0, D3DTSS_ADDRESS,
143  D3DTADDRESS_WRAP));
144  ErrD3D(pRenderD3D->pDevice->SetTextureStageState(0, D3DTSS_COLOROP, 2));
145  ErrD3D(pRenderD3D->pDevice->SetTextureStageState(0, D3DTSS_COLORARG1, 2));
146  ErrD3D(pRenderD3D->pDevice->SetTextureStageState(0, D3DTSS_MAGFILTER, 2));
147  ErrD3D(pRenderD3D->pDevice->SetTextureStageState(0, D3DTSS_MINFILTER, 2));
148  ErrD3D(pRenderD3D->pDevice->SetTextureStageState(0, D3DTSS_MIPFILTER, 1));
149 
150  IDirectDrawSurface4 *pSurface2 = nullptr;
151  IDirect3DTexture2 *pTexture2 = nullptr;
152  pRenderD3D->CreateTexture(64, 64, &pSurface2, &pTexture2, true, false, 32);
153  ErrD3D(pRenderD3D->pDevice->SetTexture(0, pTexture2));
154  ErrD3D(pRenderD3D->pDevice->SetTextureStageState(1, D3DTSS_ADDRESS,
155  D3DTADDRESS_CLAMP));
156  ErrD3D(
157  pRenderD3D->pDevice->SetTextureStageState(1, D3DTSS_TEXCOORDINDEX, 1));
158  ErrD3D(pRenderD3D->pDevice->SetTextureStageState(1, D3DTSS_COLOROP, 7));
159  ErrD3D(pRenderD3D->pDevice->SetTextureStageState(1, D3DTSS_COLORARG1, 2));
160  ErrD3D(pRenderD3D->pDevice->SetTextureStageState(1, D3DTSS_COLORARG2, 1));
161  ErrD3D(pRenderD3D->pDevice->SetTextureStageState(1, D3DTSS_MAGFILTER, 2));
162  ErrD3D(pRenderD3D->pDevice->SetTextureStageState(1, D3DTSS_MINFILTER, 2));
163  ErrD3D(pRenderD3D->pDevice->SetTextureStageState(1, D3DTSS_MIPFILTER, 1));
164 
165  DWORD v4 = 0;
166  if (!pRenderD3D->pDevice->ValidateDevice(&v4) && v4 == 1) {
167  bResult = true;
168  }
169  ErrD3D(pRenderD3D->pDevice->SetTextureStageState(1, D3DTSS_COLOROP, 1));
170  pTexture1->Release();
171  pTexture2->Release();
172  pSurface1->Release();
173  pSurface2->Release();
174 
175  return bResult;
176 }
177 
179  SoftwareBillboard soft_billboard = {0};
180  soft_billboard.sParentBillboardID = -1;
181  // soft_billboard.pTarget = pBLVRenderParams->pRenderTarget;
182  soft_billboard.pTargetZ = pBLVRenderParams->pTargetZBuffer;
183  // soft_billboard.uTargetPitch = uTargetSurfacePitch;
184  soft_billboard.uViewportX = pBLVRenderParams->uViewportX;
185  soft_billboard.uViewportY = pBLVRenderParams->uViewportY;
186  soft_billboard.uViewportZ = pBLVRenderParams->uViewportZ - 1;
187  soft_billboard.uViewportW = pBLVRenderParams->uViewportW;
188 
190  for (uint i = 0; i < ::uNumBillboardsToDraw; ++i) {
192  if (p->hwsprite) {
193  soft_billboard.screen_space_x = p->screen_space_x;
194  soft_billboard.screen_space_y = p->screen_space_y;
195  soft_billboard.screen_space_z = p->screen_space_z;
196  soft_billboard.sParentBillboardID = i;
197  soft_billboard.screenspace_projection_factor_x =
198  p->screenspace_projection_factor_x;
199  soft_billboard.screenspace_projection_factor_y =
200  p->screenspace_projection_factor_y;
201  soft_billboard.object_pid = p->object_pid;
202  soft_billboard.uFlags = p->field_1E;
203  soft_billboard.sTintColor = p->sTintColor;
204 
205  DrawBillboard_Indoor(&soft_billboard, p);
206  }
207  }
208 }
209 
211 
212 extern unsigned int BlendColors(unsigned int a1, unsigned int a2);
213 
214 void Render::RenderTerrainD3D() { // New function
215  // warning: the game uses CW culling by default, ccw is incosistent
216  pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_CULLMODE, D3DCULL_CW);
217 
218  static RenderVertexSoft
219  pTerrainVertices[128 * 128]; // vertexCountX and vertexCountZ
220 
221  //Генерация местоположения
222  //вершин-------------------------------------------------------------------------
223  //решётка вершин делится на две части от -64 до 0 и от 0 до 64
224  //
225  // -64 X 0 64
226  // --------------- 64
227  // | | |
228  // | | |
229  // | | |
230  // 0|------+------| Z
231  // | | |
232  // | | |
233  // | | |
234  // ---------------
235  // -64
236 
237  int blockScale = 512;
238  int heightScale = 32;
239  for (unsigned int z = 0; z < 128; ++z) {
240  for (unsigned int x = 0; x < 128; ++x) {
241  pTerrainVertices[z * 128 + x].vWorldPosition.x =
242  (-64 + (signed)x) * blockScale;
243  pTerrainVertices[z * 128 + x].vWorldPosition.y =
244  (64 - (signed)z) * blockScale;
245  pTerrainVertices[z * 128 + x].vWorldPosition.z =
246  heightScale * pOutdoor->pTerrain.pHeightmap[z * 128 + x];
247  pIndoorCameraD3D->ViewTransform(&pTerrainVertices[z * 128 + x], 1);
248  pIndoorCameraD3D->Project(&pTerrainVertices[z * 128 + x], 1, 0);
249  }
250  }
251  //-------(Отсечение невидимой части
252  //карты)------------------------------------------------------------------------------------------
253  float direction = (float)(pIndoorCameraD3D->sRotationY /
254  256); // direction of the camera(напрвление
255  // камеры) 0-East(B) 1-NorthEast(CB)
256  // 2-North(C)
257  // 3-WestNorth(CЗ)
258  // 4-West(З)
259  // 5-SouthWest(ЮЗ)
260  // 6-South(Ю)
261  // 7-SouthEast(ЮВ)
262  unsigned int Start_X, End_X, Start_Z, End_Z;
263  if (direction >= 0 && direction < 1.0) { // East(B) - NorthEast(CB)
264  Start_X = pODMRenderParams->uMapGridCellX - 2, End_X = 128;
265  Start_Z = 0, End_Z = 128;
266  } else if (direction >= 1.0 &&
267  direction < 3.0) { // NorthEast(CB) - WestNorth(CЗ)
268  Start_X = 0, End_X = 128;
269  Start_Z = 0, End_Z = pODMRenderParams->uMapGridCellZ + 2;
270  } else if (direction >= 3.0 &&
271  direction < 5.0) { // WestNorth(CЗ) - SouthWest(ЮЗ)
272  Start_X = 0, End_X = pODMRenderParams->uMapGridCellX + 2;
273  Start_Z = 0, End_Z = 128;
274  } else if (direction >= 5.0 &&
275  direction < 7.0) { // SouthWest(ЮЗ) - //SouthEast(ЮВ)
276  Start_X = 0, End_X = 128;
277  Start_Z = pODMRenderParams->uMapGridCellZ - 2, End_Z = 128;
278  } else { // SouthEast(ЮВ) - East(B)
279  Start_X = pODMRenderParams->uMapGridCellX - 2, End_X = 128;
280  Start_Z = 0, End_Z = 128;
281  }
282 
283  int camx = pODMRenderParams->uMapGridCellX;
284  int camz = pODMRenderParams->uMapGridCellZ - 1;
285  int tilerange = (pIndoorCameraD3D->GetFarClip() / blockScale) + 1;
286 
287  float Light_tile_dist;
288 
289  for (unsigned int z = Start_Z; z < End_Z; ++z) {
290  for (unsigned int x = Start_X; x < End_X; ++x) {
291  // tile culling
292  int xdist = camx - x;
293  int zdist = camz - z;
294 
295  if (xdist > tilerange || zdist > tilerange) continue;
296 
297  int dist = sqrt((xdist)*(xdist)+(zdist)*(zdist));
298  if (dist > tilerange) continue; // crude distance culling
299 
300 
301  struct Polygon *pTilePolygon = &array_77EC08[pODMRenderParams->uNumPolygons];
302  pTilePolygon->flags = 0;
303  pTilePolygon->field_32 = 0;
304  // pTilePolygon->uTileBitmapID = pOutdoor->DoGetTileTexture(x, z);
305  // pTilePolygon->pTexture = (Texture_MM7
306  // *)&pBitmaps_LOD->pHardwareTextures[pTilePolygon->uTileBitmapID];
307  // if (pTilePolygon->uTileBitmapID == 0xFFFF)
308  // continue;
309  auto tile = pOutdoor->DoGetTile(x, z);
310  if (!tile) continue;
311 
312  // pTile->flags = 0x8010 |pOutdoor->GetSomeOtherTileInfo(x, z);
313  pTilePolygon->flags = pOutdoor->GetSomeOtherTileInfo(x, z);
314  pTilePolygon->field_32 = 0;
315  pTilePolygon->field_59 = 1;
316  pTilePolygon->sTextureDeltaU = 0;
317  pTilePolygon->sTextureDeltaV = 0;
318  // x,z x+1,z
319  // .____________.
320  // | |
321  // | |
322  // | |
323  // | |
324  // | |
325  // .____________.
326  // x,z+1 x+1,z+1
327 
328  // verts are CW
329  // memcpy(&array_73D150[0], &pTerrainVertices[z * 128 + x],
330  // sizeof(RenderVertexSoft)); // x, z
331  // array_73D150[0].u = 0;
332  // array_73D150[0].v = 0;
333  // memcpy(&array_73D150[1], &pTerrainVertices[z * 128 + x + 1],
334  // sizeof(RenderVertexSoft)); // x + 1, z
335  // array_73D150[1].u = 1;
336  // array_73D150[1].v = 0;
337  // memcpy(&array_73D150[2], &pTerrainVertices[(z + 1) * 128 + x + 1],
338  // sizeof(RenderVertexSoft)); // x + 1, z + 1
339  // array_73D150[2].u = 1;
340  // array_73D150[2].v = 1;
341  // memcpy(&array_73D150[3], &pTerrainVertices[(z + 1) * 128 + x],
342  // sizeof(RenderVertexSoft)); // x, z + 1
343  // array_73D150[3].u = 0;
344  // array_73D150[3].v = 1;
345 
346  // verts CCW - for testing
347  memcpy(&array_73D150[0], &pTerrainVertices[z * 128 + x],
348  sizeof(RenderVertexSoft)); // x, z
349  array_73D150[0].u = 0;
350  array_73D150[0].v = 0;
351  memcpy(&array_73D150[3], &pTerrainVertices[z * 128 + x + 1],
352  sizeof(RenderVertexSoft)); // x + 1, z
353  array_73D150[3].u = 1;
354  array_73D150[3].v = 0;
355  memcpy(&array_73D150[2], &pTerrainVertices[(z + 1) * 128 + x + 1],
356  sizeof(RenderVertexSoft)); // x + 1, z + 1
357  array_73D150[2].u = 1;
358  array_73D150[2].v = 1;
359  memcpy(&array_73D150[1], &pTerrainVertices[(z + 1) * 128 + x],
360  sizeof(RenderVertexSoft)); // x, z + 1
361  array_73D150[1].u = 0;
362  array_73D150[1].v = 1;
363 
364  // v58 = 0;
365  // if (v58 == 4) // if all y == first y; primitive in xz plane
366  // pTile->field_32 |= 0x0001;
367  pTilePolygon->pODMFace = nullptr;
368  pTilePolygon->uNumVertices = 4;
369  pTilePolygon->field_59 = 5;
370 
371  if (array_73D150[0].vWorldViewPosition.x < pIndoorCameraD3D->GetNearClip() &&
375  continue;
376 
381  continue;
382 
383  //----------------------------------------------------------------------------
384 
386  // ++pODMRenderParams->field_44;
387  assert(pODMRenderParams->uNumPolygons < 20000);
388 
389  pTilePolygon->uBModelID = 0;
390  pTilePolygon->uBModelFaceID = 0;
391  pTilePolygon->pid = (8 * (0 | (0 << 6))) | 6;
392  for (unsigned int k = 0; k < pTilePolygon->uNumVertices; ++k) {
393  memcpy(&VertexRenderList[k], &array_73D150[k], sizeof(struct RenderVertexSoft));
394  VertexRenderList[k]._rhw = 1.0 / (array_73D150[k].vWorldViewPosition.x + 0.0000001000000011686097);
395  }
396 
397  // shading
398  // (затенение)----------------------------------------------------------------------------
399  // uint norm_idx = pTerrainNormalIndices[2 * (z * 128 + x) + 1];
400  uint norm_idx = pTerrainNormalIndices[(2 * x * 128) + (2 * z) + 2 /*+ 1*/ ]; // 2 is top tri // 3 is bottom
401  uint bottnormidx = pTerrainNormalIndices[(2 * x * 128) + (2 * z) + 3];
402 
403  assert(norm_idx < uNumTerrainNormals);
404  assert(bottnormidx < uNumTerrainNormals);
405 
406  Vec3_float_ *norm = &pTerrainNormals[norm_idx];
407  Vec3_float_ *norm2 = &pTerrainNormals[bottnormidx];
408 
409  if (norm_idx < 0 || norm_idx > uNumTerrainNormals - 1)
410  norm = 0;
411  else
412  norm = &pTerrainNormals[norm_idx];
413 
414  if (bottnormidx < 0 || bottnormidx > uNumTerrainNormals - 1)
415  norm2 = 0;
416  else
417  norm2 = &pTerrainNormals[bottnormidx];
418 
419 
420  if (norm_idx != bottnormidx) {
421  // we have a split poly - need to apply lights and decals seperately to each half
422 
423  pTilePolygon->uNumVertices = 3;
424 
426 
427  // verts CCW - for testing
428  memcpy(&array_73D150[0], &pTerrainVertices[z * 128 + x],
429  sizeof(RenderVertexSoft)); // x, z
430  array_73D150[0].u = 0;
431  array_73D150[0].v = 0;
432  memcpy(&array_73D150[2], &pTerrainVertices[z * 128 + x + 1],
433  sizeof(RenderVertexSoft)); // x + 1, z
434  array_73D150[2].u = 1;
435  array_73D150[2].v = 0;
436  memcpy(&array_73D150[1], &pTerrainVertices[(z + 1) * 128 + x + 1],
437  sizeof(RenderVertexSoft)); // x + 1, z + 1
438  array_73D150[1].u = 1;
439  array_73D150[1].v = 1;
440  // memcpy(&array_73D150[2], &pTerrainVertices[(z + 1) * 128 + x],
441  // sizeof(RenderVertexSoft)); // x, z + 1
442  // array_73D150[2].u = 0;
443  // array_73D150[2].v = 1;
444 
445  for (unsigned int k = 0; k < pTilePolygon->uNumVertices; ++k) {
446  memcpy(&VertexRenderList[k], &array_73D150[k], sizeof(struct RenderVertexSoft));
447  VertexRenderList[k]._rhw = 1.0 / (array_73D150[k].vWorldViewPosition.x + 0.0000001000000011686097);
448  }
449 
450  float _f = ((norm->x * (float)pOutdoor->vSunlight.x / 65536.0) -
451  (norm->y * (float)pOutdoor->vSunlight.y / 65536.0) -
452  (norm->z * (float)pOutdoor->vSunlight.z / 65536.0));
453  pTilePolygon->dimming_level = 20.0 - floorf(20.0 * _f + 0.5f);
454 
455  lightmap_builder->StackLights_TerrainFace(norm, &Light_tile_dist, VertexRenderList, 3, 1);
456  decal_builder->ApplyBloodSplatToTerrain(pTilePolygon, norm, &Light_tile_dist, VertexRenderList, 3, 1);
457 
458  unsigned int a5 = 4;
459 
460  // ---------Draw distance(Дальность отрисовки)-------------------------------
461  int far_clip_distance = pIndoorCameraD3D->GetFarClip();
462  float near_clip_distance = pIndoorCameraD3D->GetNearClip();
463 
464 
465  bool neer_clip = array_73D150[0].vWorldViewPosition.x < near_clip_distance ||
466  array_73D150[1].vWorldViewPosition.x < near_clip_distance ||
467  array_73D150[2].vWorldViewPosition.x < near_clip_distance;
468  bool far_clip =
469  (float)far_clip_distance < array_73D150[0].vWorldViewPosition.x ||
470  (float)far_clip_distance < array_73D150[1].vWorldViewPosition.x ||
471  (float)far_clip_distance < array_73D150[2].vWorldViewPosition.x;
472 
473  int uClipFlag = 0;
474  static stru154 static_sub_0048034E_stru_154;
477  if (neer_clip)
478  uClipFlag = 3;
479  else
480  uClipFlag = far_clip != 0 ? 5 : 0;
481  static_sub_0048034E_stru_154.ClassifyPolygon(norm, Light_tile_dist);
482 
483  if (decal_builder->uNumDecals > 0)
484  decal_builder->ApplyDecals(31 - pTilePolygon->dimming_level,
485  4, &static_sub_0048034E_stru_154,
486  3, VertexRenderList, 0,
487  *(float *)&uClipFlag, -1);
488  if (Lights.uNumLightsApplied > 0)
490  &Lights, &static_sub_0048034E_stru_154, 3,
491  VertexRenderList, 0, uClipFlag);
492  }
493 
494 
495 
496 
497 
498 
499 
500  // pODMRenderParams->shading_dist_mist = temp;
501 
502  // check the transparency and texture (tiles) mapping (проверка
503  // прозрачности и наложение текстур (тайлов))----------------------
504  bool transparent = false;
505 
506  auto tile_texture = tile->GetTexture();
507  if (!(pTilePolygon->flags & 1)) {
508  // не поддерживается TextureFrameTable
509  if (/*pTile->flags & 2 && */ tile->IsWaterTile()) {
510  tile_texture =
512  } else if (tile->IsWaterBorderTile()) {
513  // for all shore tiles - draw a tile water under them since
514  // they're half-empty
515  DrawBorderTiles(pTilePolygon);
516  transparent = true;
517  }
518  pTilePolygon->texture = tile_texture;
519 
520  render->DrawTerrainPolygon(pTilePolygon, transparent, true);
521  }
522 
524  {
525  // verts CCW - for testing
526  memcpy(&array_73D150[0], &pTerrainVertices[z * 128 + x],
527  sizeof(RenderVertexSoft)); // x, z
528  array_73D150[0].u = 0;
529  array_73D150[0].v = 0;
530  // memcpy(&array_73D150[2], &pTerrainVertices[z * 128 + x + 1],
531  // sizeof(RenderVertexSoft)); // x + 1, z
532  // array_73D150[2].u = 1;
533  // array_73D150[2].v = 0;
534  memcpy(&array_73D150[2], &pTerrainVertices[(z + 1) * 128 + x + 1],
535  sizeof(RenderVertexSoft)); // x + 1, z + 1
536  array_73D150[2].u = 1;
537  array_73D150[2].v = 1;
538  memcpy(&array_73D150[1], &pTerrainVertices[(z + 1) * 128 + x],
539  sizeof(RenderVertexSoft)); // x, z + 1
540  array_73D150[1].u = 0;
541  array_73D150[1].v = 1;
542 
543  for (unsigned int k = 0; k < pTilePolygon->uNumVertices; ++k) {
544  memcpy(&VertexRenderList[k], &array_73D150[k], sizeof(struct RenderVertexSoft));
545  VertexRenderList[k]._rhw = 1.0 / (array_73D150[k].vWorldViewPosition.x + 0.0000001000000011686097);
546  }
547 
548  float _f2 = ((norm2->x * (float)pOutdoor->vSunlight.x / 65536.0) -
549  (norm2->y * (float)pOutdoor->vSunlight.y / 65536.0) -
550  (norm2->z * (float)pOutdoor->vSunlight.z / 65536.0));
551  pTilePolygon->dimming_level = 20.0 - floorf(20.0 * _f2 + 0.5f);
552 
553 
554  lightmap_builder->StackLights_TerrainFace(norm2, &Light_tile_dist, VertexRenderList, 3, 0);
555 
556  decal_builder->ApplyBloodSplatToTerrain(pTilePolygon, norm2,
557  &Light_tile_dist, VertexRenderList, 3, 0);
558 
559 
560  unsigned int a5_2 = 4;
561 
562  // ---------Draw distance(Дальность отрисовки)-------------------------------
563  int far_clip_distance_2 = pIndoorCameraD3D->GetFarClip();
564  float near_clip_distance_2 = pIndoorCameraD3D->GetNearClip();
565 
566 
567  bool neer_clip_2 = array_73D150[0].vWorldViewPosition.x < near_clip_distance_2 ||
568  array_73D150[1].vWorldViewPosition.x < near_clip_distance_2 ||
569  array_73D150[2].vWorldViewPosition.x < near_clip_distance_2;
570  bool far_clip_2 =
571  (float)far_clip_distance_2 < array_73D150[0].vWorldViewPosition.x ||
572  (float)far_clip_distance_2 < array_73D150[1].vWorldViewPosition.x ||
573  (float)far_clip_distance_2 < array_73D150[2].vWorldViewPosition.x;
574 
575  int uClipFlag_2 = 0;
576  static stru154 static_sub_0048034E_stru_154_2;
579  if (neer_clip_2)
580  uClipFlag_2 = 3;
581  else
582  uClipFlag_2 = far_clip_2 != 0 ? 5 : 0;
583  static_sub_0048034E_stru_154_2.ClassifyPolygon(norm2, Light_tile_dist);
584 
585  if (decal_builder->uNumDecals > 0)
586  decal_builder->ApplyDecals(31 - pTilePolygon->dimming_level,
587  4, &static_sub_0048034E_stru_154_2,
588  3, VertexRenderList, 0,
589  *(float *)&uClipFlag_2, -1);
590  if (Lights.uNumLightsApplied > 0)
592  &Lights, &static_sub_0048034E_stru_154_2, 3,
593  VertexRenderList, 0, uClipFlag_2);
594  }
595 
596 
597 
598 
599 
600 
601 
602  // pODMRenderParams->shading_dist_mist = temp;
603 
604  // check the transparency and texture (tiles) mapping (проверка
605  // прозрачности и наложение текстур (тайлов))----------------------
606  bool transparent = false;
607 
608  auto tile_texture = tile->GetTexture();
609  if (!(pTilePolygon->flags & 1)) {
610  // не поддерживается TextureFrameTable
611  if (/*pTile->flags & 2 && */ tile->IsWaterTile()) {
612  tile_texture =
614  } else if (tile->IsWaterBorderTile()) {
615  // for all shore tiles - draw a tile water under them since
616  // they're half-empty
617  DrawBorderTiles(pTilePolygon);
618  transparent = true;
619  }
620  pTilePolygon->texture = tile_texture;
621 
622  render->DrawTerrainPolygon(pTilePolygon, transparent, true);
623  }
624  } // end split trinagles
625  } else {
626  float _f = ((norm->x * (float)pOutdoor->vSunlight.x / 65536.0) -
627  (norm->y * (float)pOutdoor->vSunlight.y / 65536.0) -
628  (norm->z * (float)pOutdoor->vSunlight.z / 65536.0));
629  pTilePolygon->dimming_level = 20.0 - floorf(20.0 * _f + 0.5f);
630 
631  lightmap_builder->StackLights_TerrainFace(norm, &Light_tile_dist, VertexRenderList, pTilePolygon->uNumVertices, 1);
632  decal_builder->ApplyBloodSplatToTerrain(pTilePolygon, norm, &Light_tile_dist, VertexRenderList, pTilePolygon->uNumVertices, 1);
633 
634  unsigned int a5 = 4;
635 
636  // ---------Draw distance(Дальность отрисовки)-------------------------------
637  int far_clip_distance = pIndoorCameraD3D->GetFarClip();
638  float near_clip_distance = pIndoorCameraD3D->GetNearClip();
639 
640  if (engine->config->extended_draw_distance)
641  far_clip_distance = 0x5000;
642  bool neer_clip = array_73D150[0].vWorldViewPosition.x < near_clip_distance ||
643  array_73D150[1].vWorldViewPosition.x < near_clip_distance ||
644  array_73D150[2].vWorldViewPosition.x < near_clip_distance ||
645  array_73D150[3].vWorldViewPosition.x < near_clip_distance;
646  bool far_clip =
647  (float)far_clip_distance < array_73D150[0].vWorldViewPosition.x ||
648  (float)far_clip_distance < array_73D150[1].vWorldViewPosition.x ||
649  (float)far_clip_distance < array_73D150[2].vWorldViewPosition.x ||
650  (float)far_clip_distance < array_73D150[3].vWorldViewPosition.x;
651 
652  int uClipFlag = 0;
653  static stru154 static_sub_0048034E_stru_154;
656  if (neer_clip)
657  uClipFlag = 3;
658  else
659  uClipFlag = far_clip != 0 ? 5 : 0;
660  static_sub_0048034E_stru_154.ClassifyPolygon(norm, Light_tile_dist);
661 
662  if (decal_builder->uNumDecals > 0)
663  decal_builder->ApplyDecals(31 - pTilePolygon->dimming_level,
664  4, &static_sub_0048034E_stru_154,
665  a5, VertexRenderList, 0,
666  *(float *)&uClipFlag, -1);
667 
668  if (Lights.uNumLightsApplied > 0)
669  lightmap_builder->ApplyLights(&Lights, &static_sub_0048034E_stru_154, a5, VertexRenderList, 0, uClipFlag);
670  }
671 
672 
673  // pODMRenderParams->shading_dist_mist = temp;
674 
675  // check the transparency and texture (tiles) mapping (проверка
676  // прозрачности и наложение текстур (тайлов))----------------------
677  bool transparent = false;
678 
679  auto tile_texture = tile->GetTexture();
680  if (!(pTilePolygon->flags & 1)) {
681  // не поддерживается TextureFrameTable
682  if (/*pTile->flags & 2 && */ tile->IsWaterTile()) {
683  tile_texture =
685  } else if (tile->IsWaterBorderTile()) {
686  // for all shore tiles - draw a tile water under them since
687  // they're half-empty
688  DrawBorderTiles(pTilePolygon);
689  transparent = true;
690  }
691  pTilePolygon->texture = tile_texture;
692 
693  render->DrawTerrainPolygon(pTilePolygon, transparent, true);
694  }
695  // end norm split
696  }
697  }
698  }
699 }
700 
701 void Render::DrawBorderTiles(struct Polygon *poly) {
702  struct Polygon poly_clone;
703  memcpy(&poly_clone, poly, sizeof(poly_clone));
704  poly_clone.texture = this->hd_water_tile_anim[this->hd_water_current_frame];
705 
706  pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ZWRITEENABLE, false);
707  DrawTerrainPolygon(&poly_clone, true, true);
708 
709  pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ZWRITEENABLE, true);
710 }
711 
712 
714  unsigned int v6; // edi@9
715  int v7; // eax@9
716  SpriteFrame *frame; // eax@9
717  unsigned __int16 *v10; // eax@9
718  int v13; // ecx@9
719  char r; // ecx@20
720  char g; // dl@20
721  char b_; // eax@20
722  Particle_sw local_0; // [sp+Ch] [bp-98h]@7
723  unsigned __int16 *v37; // [sp+84h] [bp-20h]@9
724  int v38; // [sp+88h] [bp-1Ch]@9
725 
726  for (unsigned int i = 0; i < uNumLevelDecorations; ++i) {
727  // LevelDecoration* decor = &pLevelDecorations[i];
729  pLevelDecorations[i].IsObeliskChestActive()) &&
731  DecorationDesc *decor_desc = pDecorationList->GetDecoration(pLevelDecorations[i].uDecorationDescID);
732  if (!(decor_desc->uFlags & 0x80)) {
733  if (!(decor_desc->uFlags & 0x22)) {
735  v7 = abs(pLevelDecorations[i].vPosition.x +
736  pLevelDecorations[i].vPosition.y);
737 
738  frame = pSpriteFrameTable->GetFrame(decor_desc->uSpriteID,
739  v6 + v7);
740 
741  if (engine->config->seasons_change) {
742  frame = LevelDecorationChangeSeason(decor_desc, v6 + v7, pParty->uCurrentMonth);
743  }
744 
745  if (!frame) {
746  continue;
747  }
748 
749  // v8 = pSpriteFrameTable->GetFrame(decor_desc->uSpriteID,
750  // v6 + v7);
751 
752  v10 = (unsigned __int16 *)stru_5C6E00->Atan2(
753  pLevelDecorations[i].vPosition.x -
755  pLevelDecorations[i].vPosition.y -
757  v38 = 0;
758  v13 = ((signed int)(stru_5C6E00->uIntegerPi +
759  ((signed int)stru_5C6E00->uIntegerPi >>
760  3) +
761  pLevelDecorations[i].field_10_y_rot -
762  (signed int)v10) >>
763  8) &
764  7;
765  v37 = (unsigned __int16 *)v13;
766  if (frame->uFlags & 2) v38 = 2;
767  if ((256 << v13) & frame->uFlags) v38 |= 4;
768  if (frame->uFlags & 0x40000) v38 |= 0x40;
769  if (frame->uFlags & 0x20000) v38 |= 0x80;
770 
771  // for light
772  if (frame->uGlowRadius) {
773  r = 255;
774  g = 255;
775  b_ = 255;
776  if (render->config->is_using_colored_lights) {
777  r = decor_desc->uColoredLightRed;
778  g = decor_desc->uColoredLightGreen;
779  b_ = decor_desc->uColoredLightBlue;
780  }
782  pLevelDecorations[i].vPosition.x,
783  pLevelDecorations[i].vPosition.y,
784  pLevelDecorations[i].vPosition.z +
785  decor_desc->uDecorationHeight / 2,
786  frame->uGlowRadius, r, g, b_, _4E94D0_light_type);
787  } // for light
788 
789  // v17 = (pLevelDecorations[i].vPosition.x -
790  // pIndoorCameraD3D->vPartyPos.x) << 16; v40 =
791  // (pLevelDecorations[i].vPosition.y -
792  // pIndoorCameraD3D->vPartyPos.y) << 16;
793  int party_to_decor_x = pLevelDecorations[i].vPosition.x -
795  int party_to_decor_y = pLevelDecorations[i].vPosition.y -
797  int party_to_decor_z = pLevelDecorations[i].vPosition.z -
799 
800  int view_x = 0;
801  int view_y = 0;
802  int view_z = 0;
803  bool visible = pIndoorCameraD3D->ViewClip(
804  pLevelDecorations[i].vPosition.x,
805  pLevelDecorations[i].vPosition.y,
806  pLevelDecorations[i].vPosition.z, &view_x, &view_y,
807  &view_z);
808 
809  if (visible) {
810  // if (2 * abs(view_x) >= abs(view_y)) {
811  int projected_x = 0;
812  int projected_y = 0;
813  pIndoorCameraD3D->Project(view_x, view_y, view_z,
814  &projected_x,
815  &projected_y);
816 
817  auto _v41 =
818  frame->scale *
820  fixed::FromInt(view_x);
821 
822  int screen_space_half_width = 0;
823  screen_space_half_width =
824  _v41.GetFloat() *
825  frame->hw_sprites[(int)v37]->uBufferWidth / 2;
826 
827 
828  if (projected_x + screen_space_half_width >=
829  (signed int)pViewport->uViewportTL_X &&
830  projected_x - screen_space_half_width <=
831  (signed int)pViewport->uViewportBR_X) {
832  if (::uNumBillboardsToDraw >= 500) return;
835 
837  .hwsprite = frame->hw_sprites[(int)v37];
838 
839  // error catching
840  if (frame->hw_sprites[(int)v37]->texture->GetHeight() == 0 || frame->hw_sprites[(int)v37]->texture->GetWidth() == 0)
841  __debugbreak();
842 
844  .world_x = pLevelDecorations[i].vPosition.x;
846  .world_y = pLevelDecorations[i].vPosition.y;
848  .world_z = pLevelDecorations[i].vPosition.z;
850  .screen_space_x = projected_x;
852  .screen_space_y = projected_y;
854  .screen_space_z = view_x;
856  .screenspace_projection_factor_x = _v41.GetFloat();
858  .screenspace_projection_factor_y = _v41.GetFloat();
860  .uPalette = frame->uPaletteIndex;
862  .field_1E = v38 | 0x200;
864  .uIndoorSectorID = 0;
866  .object_pid = PID(OBJECT_Decoration, i);
868  .dimming_level = 0;
870  .pSpriteFrame = frame;
872  .sTintColor = 0;
873  } else {
874  // temp
875  }
876  // }
877  }
878  }
879  } else {
880  memset(&local_0, 0, 0x68);
883  local_0.uDiffuse = 0xFF3C1E;
884  local_0.x = (double)pLevelDecorations[i].vPosition.x;
885  local_0.y = (double)pLevelDecorations[i].vPosition.y;
886  local_0.z = (double)pLevelDecorations[i].vPosition.z;
887  local_0.r = 0.0;
888  local_0.g = 0.0;
889  local_0.b = 0.0;
890  local_0.particle_size = 1.0;
891  local_0.timeToLive = (rand() & 0x80) + 128;
893  particle_engine->AddParticle(&local_0);
894  }
895  }
896  }
897 }
898 
899 void Render::DrawPolygon(struct Polygon *pPolygon) {
900  if ((uNumD3DSceneBegins == 0) || (pPolygon->uNumVertices < 3)) {
901  return;
902  }
903 
904  unsigned int v41; // eax@29
905  unsigned int sCorrectedColor; // [sp+64h] [bp-4h]@4
906 
907  auto texture = (TextureD3D *)pPolygon->texture;
908  ODMFace *pFace = pPolygon->pODMFace;
909  auto uNumVertices = pPolygon->uNumVertices;
910 
912  sCorrectedColor = -1;
913  }
914  engine->AlterGamma_ODM(pFace, &sCorrectedColor);
915  if (_4D864C_force_sw_render_rules && engine->config->Flag1_1()) {
916  int v8 = ::GetActorTintColor(
917  pPolygon->dimming_level, 0,
919  lightmap_builder->DrawLightmaps(v8 /*, 0*/);
920  } else {
922  _4D864C_force_sw_render_rules && engine->config->Flag1_2()) {
923  ErrD3D(pRenderD3D->pDevice->SetTextureStageState(0, D3DTSS_ADDRESS,
924  D3DTADDRESS_WRAP));
925  ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_CULLMODE,
926  D3DCULL_CW));
927  if (config->is_using_specular) {
928  ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ALPHABLENDENABLE, TRUE));
929  ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_SRCBLEND, D3DBLEND_ONE));
930  ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_DESTBLEND, D3DBLEND_ZERO));
931  }
932  for (uint i = 0; i < uNumVertices; ++i) {
933  d3d_vertex_buffer[i].pos.x =
935  d3d_vertex_buffer[i].pos.y =
937  d3d_vertex_buffer[i].pos.z =
938  1.0 -
939  1.0 / ((VertexRenderList[i].vWorldViewPosition.x * 1000) /
942  1.0 /
943  (VertexRenderList[i].vWorldViewPosition.x + 0.0000001);
945  pPolygon->dimming_level, 0,
947  engine->AlterGamma_ODM(pFace, &d3d_vertex_buffer[i].diffuse);
948 
949  if (config->is_using_specular)
951  0, 0, VertexRenderList[i].vWorldViewPosition.x);
952  else
956  }
957 
958  if (pFace->uAttributes & FACE_OUTLINED) {
959  int color;
960  if (OS_GetTime() % 300 >= 150)
961  color = 0xFFFF2020;
962  else
963  color = 0xFF901010;
964 
965  for (uint i = 0; i < uNumVertices; ++i)
966  d3d_vertex_buffer[i].diffuse = color;
967  }
968 
969  ErrD3D(pRenderD3D->pDevice->SetTexture(
970  0, texture->GetDirect3DTexture()));
971  ErrD3D(pRenderD3D->pDevice->DrawPrimitive(
972  D3DPT_TRIANGLEFAN,
973  D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR | D3DFVF_TEX1,
974  d3d_vertex_buffer, uNumVertices, D3DDP_DONOTLIGHT));
975  } else {
976  for (uint i = 0; i < uNumVertices; ++i) {
977  d3d_vertex_buffer[i].pos.x =
979  d3d_vertex_buffer[i].pos.y =
981  d3d_vertex_buffer[i].pos.z =
982  1.0 -
983  1.0 / ((VertexRenderList[i].vWorldViewPosition.x * 1000) /
986  1.0 /
987  (VertexRenderList[i].vWorldViewPosition.x + 0.0000001);
989  pPolygon->dimming_level, 0,
991  if (config->is_using_specular)
993  0, 0, VertexRenderList[i].vWorldViewPosition.x);
994  else
998  }
999 
1000  ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ZWRITEENABLE, FALSE));
1001  ErrD3D(pRenderD3D->pDevice->SetTextureStageState(0, D3DTSS_ADDRESS,
1002  D3DTADDRESS_WRAP));
1003  if (config->is_using_specular)
1004  ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_FOGENABLE, FALSE));
1005 
1006  ErrD3D(pRenderD3D->pDevice->SetTexture(0, nullptr));
1007  ErrD3D(pRenderD3D->pDevice->DrawPrimitive(
1008  D3DPT_TRIANGLEFAN,
1009  D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR | D3DFVF_TEX1,
1010  d3d_vertex_buffer, uNumVertices, D3DDP_DONOTLIGHT));
1011  // v50 = (const char *)v5->pRenderD3D->pDevice;
1012  ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_CULLMODE,
1013  D3DCULL_NONE));
1014  // (*(void (**)(void))(*(int *)v50 + 88))();
1016  for (uint i = 0; i < uNumVertices; ++i) {
1017  d3d_vertex_buffer[i].diffuse = sCorrectedColor;
1018  }
1019  ErrD3D(pRenderD3D->pDevice->SetTexture(
1020  0, texture->GetDirect3DTexture()));
1021  ErrD3D(pRenderD3D->pDevice->SetTextureStageState(0, D3DTSS_ADDRESS,
1022  D3DTADDRESS_WRAP));
1023  if (!config->is_using_specular)
1024  ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ZWRITEENABLE, TRUE));
1025 
1026  ErrD3D(pRenderD3D->pDevice->SetRenderState(
1027  D3DRENDERSTATE_ALPHABLENDENABLE, TRUE));
1028  ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_SRCBLEND,
1029  D3DBLEND_ZERO));
1030  ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_DESTBLEND,
1031  D3DBLEND_SRCCOLOR));
1032  ErrD3D(pRenderD3D->pDevice->DrawPrimitive(
1033  D3DPT_TRIANGLEFAN,
1034  D3DFVF_XYZRHW | D3DFVF_TEX1 | D3DFVF_DIFFUSE | D3DFVF_SPECULAR,
1035  d3d_vertex_buffer, uNumVertices, D3DDP_DONOTLIGHT));
1036  if (config->is_using_specular) {
1037  ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ZWRITEENABLE, TRUE));
1038 
1039  for (uint i = 0; i < uNumVertices; ++i) {
1041  render->uFogColor |
1042  d3d_vertex_buffer[i].specular & 0xFF000000;
1043  d3d_vertex_buffer[i].specular = 0;
1044  }
1045 
1046  ErrD3D(pRenderD3D->pDevice->SetTexture(0, nullptr));
1047  ErrD3D(pRenderD3D->pDevice->SetRenderState(
1048  D3DRENDERSTATE_SRCBLEND, D3DBLEND_INVSRCALPHA));
1049  ErrD3D(pRenderD3D->pDevice->SetRenderState(
1050  D3DRENDERSTATE_DESTBLEND, D3DBLEND_SRCALPHA));
1051  ErrD3D(pRenderD3D->pDevice->DrawPrimitive(
1052  D3DPT_TRIANGLEFAN,
1053  D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR |
1054  D3DFVF_TEX1,
1055  d3d_vertex_buffer, uNumVertices, D3DDP_DONOTLIGHT));
1056  ErrD3D(pRenderD3D->pDevice->SetRenderState(
1057  D3DRENDERSTATE_FOGENABLE, TRUE));
1058  // v40 = render->pRenderD3D->pDevice->lpVtbl;
1059  v41 = GetLevelFogColor();
1060  pRenderD3D->pDevice->SetRenderState(
1061  D3DRENDERSTATE_FOGCOLOR, GetLevelFogColor() & 0xFFFFFF);
1062  pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_FOGTABLEMODE,
1063  0);
1064  }
1065  ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_SRCBLEND,
1066  D3DBLEND_ONE));
1067  ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_DESTBLEND,
1068  D3DBLEND_ZERO));
1069  ErrD3D(pRenderD3D->pDevice->SetRenderState(
1070  D3DRENDERSTATE_ALPHABLENDENABLE, FALSE));
1071  }
1072  }
1073 }
1074 
1076  : RenderBase() {
1077  this->pDirectDraw4 = nullptr;
1078  this->pFrontBuffer4 = nullptr;
1079  this->pBackBuffer4 = nullptr;
1080  this->bWindowMode = 1;
1081  this->pActiveZBuffer = nullptr;
1082  this->pDefaultZBuffer = nullptr;
1083  this->pRenderD3D = 0;
1084  this->uNumD3DSceneBegins = 0;
1086 
1088 
1089  hd_water_tile_id = -1;
1091 
1092  Gdiplus::GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);
1093 }
1094 
1096  free(pDefaultZBuffer);
1097  Release();
1098  Gdiplus::GdiplusShutdown(gdiplusToken);
1099 }
1100 
1103  return false;
1104  }
1105 
1106  uDesiredDirect3DDevice = OS_GetAppInt("D3D Device", 0);
1107 
1109 
1110  return true;
1111 }
1112 
1113 void Render::ClearBlack() { pRenderD3D->ClearTarget(true, 0, false, 0.0); }
1114 
1116  RECT dest_rect = {0};
1117  GetWindowRect((HWND)window->GetWinApiHandle(), &dest_rect);
1118 
1119  DDBLTFX lpDDBltFx = {0};
1120  lpDDBltFx.dwSize = sizeof(DDBLTFX);
1121  lpDDBltFx.dwFillColor = 0;
1122  pBackBuffer4->Blt(&dest_rect, NULL, NULL, DDBLT_COLORFILL, &lpDDBltFx);
1123  render->Present();
1124 }
1125 
1127  char file_name[40];
1128  sprintf(file_name, "screen%0.2i.pcx", ScreenshotFileNumber++ % 100);
1129 
1130  SaveWinnersCertificate(file_name);
1131 }
1132 
1133 void Render::SaveWinnersCertificate(const char *file_name) {
1134  BeginScene();
1135  // SavePCXImage32(file_name, (uint16_t*)render->pTargetSurface,
1136  // render->GetRenderWidth(), render->GetRenderHeight());
1137  EndScene();
1138 }
1139 
1140 void Render::SavePCXImage32(const String &filename, uint16_t *picture_data,
1141  int width, int height) {
1142  FILE *result = fopen(filename.c_str(), "wb");
1143  if (result == nullptr) {
1144  return;
1145  }
1146 
1147  unsigned int pcx_data_size = width * height * 5;
1148  uint8_t *pcx_data = new uint8_t[pcx_data_size];
1149  unsigned int pcx_data_real_size = 0;
1150  PCX::Encode32(picture_data, width, height, pcx_data, pcx_data_size,
1151  &pcx_data_real_size);
1152  fwrite(pcx_data, pcx_data_real_size, 1, result);
1153  delete[] pcx_data;
1154  fclose(result);
1155 }
1156 
1157 void Render::SavePCXImage16(const String &filename, uint16_t *picture_data,
1158  int width, int height) {
1159  FILE *result = fopen(filename.c_str(), "wb");
1160  if (result == nullptr) {
1161  return;
1162  }
1163 
1164  unsigned int pcx_data_size = width * height * 5;
1165  uint8_t *pcx_data = new uint8_t[pcx_data_size];
1166  unsigned int pcx_data_real_size = 0;
1167  PCX::Encode16(picture_data, width, height, pcx_data, pcx_data_size,
1168  &pcx_data_real_size);
1169  fwrite(pcx_data, pcx_data_real_size, 1, result);
1170  delete[] pcx_data;
1171  fclose(result);
1172 }
1173 
1174 void Render::ClearTarget(unsigned int uColor) {
1175  pRenderD3D->ClearTarget(true, uColor, false, 0.0);
1176 }
1177 
1180  if (pRenderD3D) {
1181  pRenderD3D->Present(false);
1182  } else {
1183  assert(false);
1184  }
1185 }
1186 
1188  if (!pDefaultZBuffer) {
1189  pDefaultZBuffer = pActiveZBuffer = (int *)malloc(0x12C000);
1190  memset32(pActiveZBuffer, 0xFFFF0000,
1191  0x4B000u); // // inlined Render::ClearActiveZBuffer
1192  // (mm8::004A085B)
1193  }
1194 }
1195 
1197  if (pRenderD3D) {
1198  pRenderD3D->ClearTarget(true, 0, false, 1.0);
1199  pRenderD3D->Present(0);
1200  pRenderD3D->ClearTarget(true, 0, false, 1.0);
1201  this->pBackBuffer4 = nullptr;
1202  this->pFrontBuffer4 = nullptr;
1203  this->pDirectDraw4 = nullptr;
1204  if (pRenderD3D) {
1205  pRenderD3D->Release();
1206  delete pRenderD3D;
1207  }
1208  pRenderD3D = nullptr;
1209  }
1210 }
1211 
1212 void Present32(uint32_t *src, unsigned int src_pitch, uint32_t *dst,
1213  unsigned int dst_pitch) {
1214  // return;
1215 
1216  for (uint y = 0; y < 8; ++y) {
1217  memcpy(dst + y * dst_pitch, src + y * src_pitch,
1218  src_pitch * sizeof(uint32_t));
1219  }
1220 
1221  for (uint y = 8; y < 352; ++y) {
1222  memcpy(dst + y * dst_pitch, src + y * src_pitch, 8 * sizeof(uint32_t));
1223  memcpy(dst + 8 + game_viewport_width + y * dst_pitch,
1224  src + 8 + game_viewport_width + y * src_pitch,
1225  174 /*172*/ * sizeof(uint32_t));
1226  }
1227 
1228  for (uint y = 352; y < 480; ++y) {
1229  memcpy(dst + y * dst_pitch, src + y * src_pitch,
1230  src_pitch * sizeof(uint32_t));
1231  }
1232 
1233  for (uint y = pViewport->uViewportTL_Y; y < pViewport->uViewportBR_Y + 1;
1234  ++y) {
1235  for (uint x = pViewport->uViewportTL_X; x < pViewport->uViewportBR_X;
1236  ++x) {
1237  if (src[x + y * src_pitch] !=
1238  0xFF00FCF8) { // FFF8FCF8 = Color32(Color16(g_mask | b_mask))
1239  dst[x + y * dst_pitch] = src[x + y * src_pitch];
1240  }
1241  }
1242  }
1243 }
1244 
1246  Render *r = (Render *)render.get();
1247 
1248  DDSURFACEDESC2 Dst = {0};
1249  Dst.dwSize = sizeof(Dst);
1250  if (r->LockSurface_DDraw4(r->pBackBuffer4, &Dst, DDLOCK_WAIT)) {
1251  Gdiplus::Rect rect(0, 0, Dst.dwWidth, Dst.dwHeight);
1252  Gdiplus::BitmapData bitmapData;
1253  r->p2DSurface->LockBits(&rect, Gdiplus::ImageLockModeRead,
1254  PixelFormat32bppARGB, &bitmapData);
1255  Present32((uint32_t *)bitmapData.Scan0, bitmapData.Width,
1256  (uint32_t *)Dst.lpSurface, Dst.lPitch / 4);
1257  r->p2DSurface->UnlockBits(&bitmapData);
1258  ErrD3D(r->pBackBuffer4->Unlock(NULL));
1259  }
1260 }
1261 
1263  this->pBackBuffer4 = nullptr;
1264  this->pFrontBuffer4 = nullptr;
1265  this->pDirectDraw4 = nullptr;
1266  Release();
1267  this->window = window;
1268  CreateZBuffer();
1269 
1270  pRenderD3D = new RenderD3D;
1271 
1272  int v29 = -1;
1274  bool v8 = false;
1278  } else {
1279  if (v7[1].bIsDeviceCompatible) {
1280  v8 = pRenderD3D->CreateDevice(1, true, window);
1281  } else {
1282  if (!v7->bIsDeviceCompatible)
1283  Error("There aren't any D3D devices to create.");
1284 
1285  v8 = pRenderD3D->CreateDevice(0, true, window);
1286  }
1287  }
1288  if (!v8) {
1289  Error("D3Drend->Init failed.");
1290  }
1291 
1295 
1296  unsigned int v10 = pRenderD3D->GetDeviceCaps();
1297  if (v10 & 1) {
1298  if (pRenderD3D) {
1299  pRenderD3D->Release();
1300  delete pRenderD3D;
1301  }
1302  pRenderD3D = nullptr;
1303  pBackBuffer4 = nullptr;
1304  pFrontBuffer4 = nullptr;
1305  pDirectDraw4 = nullptr;
1306  Error("Direct3D renderer: The device failed to return capabilities.");
1307  }
1308  if (v10 & 0x3E) {
1309  if (pRenderD3D) {
1310  pRenderD3D->Release();
1311  delete pRenderD3D;
1312  }
1313  pRenderD3D = nullptr;
1314  pBackBuffer4 = nullptr;
1315  pFrontBuffer4 = nullptr;
1316  pDirectDraw4 = nullptr;
1317  Error(
1318  "Direct3D renderer: The device doesn't support the necessary "
1319  "alpha blending modes.");
1320  }
1321  if ((v10 & 0x80) != 0) {
1322  if (pRenderD3D) {
1323  pRenderD3D->Release();
1324  delete pRenderD3D;
1325  }
1326  pRenderD3D = nullptr;
1327  pBackBuffer4 = nullptr;
1328  pFrontBuffer4 = nullptr;
1329  pDirectDraw4 = nullptr;
1330  Error(
1331  "Direct3D renderer: The device doesn't support non-square "
1332  "textures.");
1333  }
1334 
1336 
1337  D3DDEVICEDESC halCaps = {0};
1338  halCaps.dwSize = sizeof(halCaps);
1339 
1340  D3DDEVICEDESC refCaps = {0};
1341  refCaps.dwSize = sizeof(refCaps);
1342 
1343  ErrD3D(pRenderD3D->pDevice->GetCaps(&halCaps, &refCaps));
1344 
1345  uMinDeviceTextureDim = halCaps.dwMinTextureWidth;
1346  if ((unsigned int)halCaps.dwMinTextureWidth >= halCaps.dwMinTextureHeight)
1347  uMinDeviceTextureDim = halCaps.dwMinTextureHeight;
1348  uMinDeviceTextureDim = halCaps.dwMaxTextureWidth;
1349  if ((unsigned int)halCaps.dwMaxTextureWidth < halCaps.dwMaxTextureHeight)
1350  uMinDeviceTextureDim = halCaps.dwMaxTextureHeight;
1351  if ((unsigned int)uMinDeviceTextureDim < 4) uMinDeviceTextureDim = 4;
1352 
1353  ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ZENABLE, true));
1354  ErrD3D(
1355  pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ZWRITEENABLE, true));
1356  ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ZFUNC, 2));
1357  ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_SPECULARENABLE,
1358  false));
1359  ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_COLORKEYENABLE,
1360  false));
1361  ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ALPHATESTENABLE,
1362  false));
1363  ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_CULLMODE, 1));
1364  ErrD3D(pRenderD3D->pDevice->SetTextureStageState(0, D3DTSS_MAGFILTER, 2));
1365  ErrD3D(pRenderD3D->pDevice->SetTextureStageState(0, D3DTSS_MINFILTER, 2));
1366  ErrD3D(pRenderD3D->pDevice->SetTextureStageState(0, D3DTSS_MIPFILTER, 3));
1367  ErrD3D(pRenderD3D->pDevice->SetTextureStageState(0, D3DTSS_ALPHAARG1, 2));
1368  ErrD3D(pRenderD3D->pDevice->SetTextureStageState(0, D3DTSS_ALPHAARG2, 0));
1369  ErrD3D(pRenderD3D->pDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, 2));
1370  ErrD3D(pRenderD3D->pDevice->SetTextureStageState(0, D3DTSS_COLORARG1, 2));
1371  ErrD3D(pRenderD3D->pDevice->SetTextureStageState(0, D3DTSS_COLORARG2, 0));
1372  ErrD3D(pRenderD3D->pDevice->SetTextureStageState(0, D3DTSS_COLOROP, 4));
1373 
1374  ddpfPrimarySuface.dwSize = sizeof(DDPIXELFORMAT);
1377 
1378  if (!pRenderD3D) {
1379  __debugbreak();
1381  }
1382 
1383  p2DSurface = new Gdiplus::Bitmap(window->GetWidth(), window->GetHeight(),
1384  PixelFormat32bppRGB);
1385  p2DGraphics = new Gdiplus::Graphics(p2DSurface);
1387 
1388  bWindowMode = 0;
1389  pParty->uFlags |= 2;
1391 
1392  return true;
1393 }
1394 
1395 bool Render::DrawLightmap(Lightmap *pLightmap, Vec3_float_ *pColorMult,
1396  float z_bias) {
1397  // For outdoor terrain and indoor light (VII)(VII)
1398  if (pLightmap->NumVertices < 3) {
1399  log->Warning(L"Lightmap uNumVertices < 3");
1400  return false;
1401  }
1402 
1403  unsigned int uLightmapColorMaskR = (pLightmap->uColorMask >> 16) & 0xFF;
1404  unsigned int uLightmapColorMaskG = (pLightmap->uColorMask >> 8) & 0xFF;
1405  unsigned int uLightmapColorMaskB = pLightmap->uColorMask & 0xFF;
1406 
1407  unsigned int uLightmapColorR = floorf(
1408  uLightmapColorMaskR * pLightmap->fBrightness * pColorMult->x + 0.5f);
1409  unsigned int uLightmapColorG = floorf(
1410  uLightmapColorMaskG * pLightmap->fBrightness * pColorMult->y + 0.5f);
1411  unsigned int uLightmapColorB = floorf(
1412  uLightmapColorMaskB * pLightmap->fBrightness * pColorMult->z + 0.5f);
1413 
1414  RenderVertexD3D3 pVerticesD3D[64];
1415  for (uint i = 0; i < pLightmap->NumVertices; ++i) {
1416  float v18;
1417  if (fabs(z_bias) < 1e-5) {
1418  v18 = 1.0 - 1.0 / ((1.0f / 16192.0) * pLightmap->pVertices[i].vWorldViewPosition.x * 1000.0);
1419  } else {
1420  v18 = 1.0 - 1.0 / ((1.0f / 16192.0) * pLightmap->pVertices[i].vWorldViewPosition.x * 1000.0) - z_bias;
1421 
1422  if (v18 < 0.000099999997) {
1423  v18 = 0.000099999997;
1424  }
1425  }
1426 
1427  pVerticesD3D[i].pos.x = pLightmap->pVertices[i].vWorldViewProjX;
1428  pVerticesD3D[i].pos.y = pLightmap->pVertices[i].vWorldViewProjY;
1429  pVerticesD3D[i].pos.z = v18;
1430 
1431  pVerticesD3D[i].rhw = 1.0 / pLightmap->pVertices[i].vWorldViewPosition.x;
1432  pVerticesD3D[i].diffuse = (uLightmapColorR << 16) | (uLightmapColorG << 8) | uLightmapColorB;
1433  pVerticesD3D[i].specular = 0;
1434 
1435  pVerticesD3D[i].texcoord.x = pLightmap->pVertices[i].u;
1436  pVerticesD3D[i].texcoord.y = pLightmap->pVertices[i].v;
1437  }
1438 
1439  int dwFlags = D3DDP_DONOTLIGHT;
1441  dwFlags |= D3DDP_DONOTCLIP | D3DDP_DONOTUPDATEEXTENTS;
1442  }
1443 
1444  ErrD3D(pRenderD3D->pDevice->DrawPrimitive(
1445  D3DPT_TRIANGLEFAN,
1446  D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR | D3DFVF_TEX1,
1447  pVerticesD3D, pLightmap->NumVertices, dwFlags));
1448 
1449  return true;
1450 }
1451 
1452 // blue mask
1453 void Render::am_Blt_Chroma(Rect *pSrcRect, Point *pTargetPoint, int a3, int blend_mode) {
1454  uint16_t *pSrc; // eax@2
1455  int uSrcTotalWidth = 0; // ecx@4
1456  unsigned int v10; // esi@9
1457  int v21; // [sp+Ch] [bp-18h]@8
1458  uint16_t *src_surf_pos; // [sp+10h] [bp-14h]@9
1459  int32_t src_width; // [sp+14h] [bp-10h]@3
1460  int32_t src_height; // [sp+18h] [bp-Ch]@3
1461  int uSrcPitch; // [sp+1Ch] [bp-8h]@5
1462 
1464  __debugbreak();
1465  return;
1466  }
1467 
1468  src_width = pSrcRect->z - pSrcRect->x;
1469  src_height = pSrcRect->w - pSrcRect->y;
1470 
1471  /*if (pArcomageGame->pBlit_Copy_pixels == pArcomageGame->pBackgroundPixels)
1472  uSrcTotalWidth = pArcomageGame->pGameBackground->GetWidth();
1474  uSrcTotalWidth = pArcomageGame->pSprites->GetWidth();
1475 
1477  uSrcPitch = uSrcTotalWidth;
1478  src_surf_pos = &pSrc[pSrcRect->x + uSrcPitch * pSrcRect->y];
1479  v10 = 0x1F;
1480  v21 = (uTargetGBits != 6 ? 0x31EF : 0x7BEF);
1481 
1482  Image *temp = Image::Create(src_width, src_height, IMAGE_FORMAT_A8R8G8B8);
1483  uint32_t *temppix = (uint32_t *)temp->GetPixels(IMAGE_FORMAT_A8R8G8B8);
1484 
1485  if (blend_mode == 2) {
1486  uSrcPitch = (uSrcPitch - src_width);
1487  for (int i = 0; i < src_height; ++i) {
1488  for (int j = 0; j < src_width; ++j) {
1489  if (*src_surf_pos != v10) {
1490  if (pTargetPoint->x + j >= 0 &&
1491  pTargetPoint->x + j <= window->GetWidth() - 1 &&
1492  pTargetPoint->y + i >= 0 &&
1493  pTargetPoint->y + i <= window->GetHeight() - 1)
1494  temppix[j + i * src_width] = Color32(*src_surf_pos);
1495  }
1496  ++src_surf_pos;
1497  }
1498  src_surf_pos += uSrcPitch;
1499  }
1500  } else {
1501  uSrcPitch = (uSrcPitch - src_width);
1502  for (int i = 0; i < src_height; ++i) {
1503  for (int j = 0; j < src_width; ++j) {
1504  if (*src_surf_pos != v10) {
1505  if (pTargetPoint->x + j >= 0 &&//
1506  pTargetPoint->x + j <= window->GetWidth() - 1 &&//
1507  pTargetPoint->y + i >= 0 &&//
1508  pTargetPoint->y + i <= window->GetHeight() - 1)//
1509  temppix[j + i * src_width] = Color32((0x7BEF & (*src_surf_pos / 2)));//
1510  }//
1511  ++src_surf_pos;//
1512  }//
1513  src_surf_pos += uSrcPitch;//
1514  }//
1515  }//
1516  render->DrawTextureAlphaNew(pTargetPoint->x / 640., pTargetPoint->y / 480., temp);//
1517  temp->Release();//
1518 }
1519 
1521  // pParty->uFlags |= PARTY_FLAGS_1_0002;
1523  Release();
1524 
1525  pBackBuffer4 = nullptr;
1526  pFrontBuffer4 = nullptr;
1527  pDirectDraw4 = nullptr;
1528  CreateZBuffer();
1529  pRenderD3D = new RenderD3D;
1530 
1531  bool v7 = false;
1534  uDesiredDirect3DDevice != 1) {
1536  } else {
1538  Error("There aren't any D3D devices to init.");
1539  }
1540  v7 = pRenderD3D->CreateDevice(0, true, window);
1541  }
1542  if (!v7) Error("D3Drend->Init failed.");
1543 
1547 
1548  unsigned int device_caps = pRenderD3D->GetDeviceCaps();
1549  if (device_caps & 1) {
1550  if (pRenderD3D) {
1551  pRenderD3D->Release();
1552  delete pRenderD3D;
1553  }
1554  pRenderD3D = nullptr;
1555  pBackBuffer4 = nullptr;
1556  pFrontBuffer4 = nullptr;
1557  pDirectDraw4 = nullptr;
1558  Error("Direct3D renderer: The device failed to return capabilities.");
1559  }
1560  if (device_caps & 0x3E) {
1561  if (pRenderD3D) {
1562  pRenderD3D->Release();
1563  delete pRenderD3D;
1564  }
1565  pRenderD3D = nullptr;
1566  pBackBuffer4 = nullptr;
1567  pFrontBuffer4 = nullptr;
1568  pDirectDraw4 = nullptr;
1569  Error(
1570  "Direct3D renderer: The device doesn't support the necessary "
1571  "alpha blending modes.");
1572  }
1573  if (device_caps & 0x80) {
1574  if (pRenderD3D) {
1575  pRenderD3D->Release();
1576  delete pRenderD3D;
1577  }
1578  pRenderD3D = nullptr;
1579  pBackBuffer4 = nullptr;
1580  pFrontBuffer4 = nullptr;
1581  pDirectDraw4 = nullptr;
1582  Error(
1583  "Direct3D renderer: The device doesn't support non-square "
1584  "textures.");
1585  }
1586 
1588 
1589  D3DDEVICEDESC halCaps = {0};
1590  halCaps.dwSize = sizeof(halCaps);
1591 
1592  D3DDEVICEDESC refCaps = {0};
1593  refCaps.dwSize = sizeof(refCaps);
1594 
1595  ErrD3D(pRenderD3D->pDevice->GetCaps(&halCaps, &refCaps));
1596  int v12 = halCaps.dwMinTextureWidth;
1597  if ((unsigned int)halCaps.dwMinTextureWidth > halCaps.dwMinTextureHeight)
1598  v12 = halCaps.dwMinTextureHeight;
1599  uMinDeviceTextureDim = v12;
1600  int v13 = halCaps.dwMaxTextureWidth;
1601  if ((unsigned int)halCaps.dwMaxTextureWidth < halCaps.dwMaxTextureHeight)
1602  v13 = halCaps.dwMaxTextureHeight;
1603  uMaxDeviceTextureDim = v13;
1604  ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ZENABLE, 1));
1605  ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ZWRITEENABLE, 1));
1606  ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ZFUNC, 2));
1607  ErrD3D(
1608  pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_SPECULARENABLE, 0));
1609  ErrD3D(
1610  pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_COLORKEYENABLE, 0));
1611  ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_CULLMODE, 1));
1612  ErrD3D(pRenderD3D->pDevice->SetTextureStageState(0, D3DTSS_MAGFILTER, 2));
1613  ErrD3D(pRenderD3D->pDevice->SetTextureStageState(0, D3DTSS_MINFILTER, 2));
1614  ErrD3D(pRenderD3D->pDevice->SetTextureStageState(0, D3DTSS_MIPFILTER, 3));
1615  ErrD3D(pRenderD3D->pDevice->SetTextureStageState(0, D3DTSS_ALPHAARG1, 2));
1616  ErrD3D(pRenderD3D->pDevice->SetTextureStageState(0, D3DTSS_ALPHAARG2, 0));
1617  ErrD3D(pRenderD3D->pDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, 2));
1618  ErrD3D(pRenderD3D->pDevice->SetTextureStageState(0, D3DTSS_COLORARG1, 2));
1619  ErrD3D(pRenderD3D->pDevice->SetTextureStageState(0, D3DTSS_COLORARG2, 0));
1620  ErrD3D(pRenderD3D->pDevice->SetTextureStageState(0, D3DTSS_COLOROP, 4));
1621 
1622  ddpfPrimarySuface.dwSize = sizeof(DDPIXELFORMAT);
1625 
1626  if (!pRenderD3D) {
1627  __debugbreak();
1628  }
1629 
1630  p2DSurface = new Gdiplus::Bitmap(window->GetWidth(), window->GetHeight(),
1631  PixelFormat32bppRGB);
1632  p2DGraphics = new Gdiplus::Graphics(p2DSurface);
1634 
1635  return true;
1636 }
1637 
1638 void Render::RasterLine2D(int uX, int uY, int uZ, int uW, uint16_t color) {
1639  // change to 32bit clor input??
1640 
1641  unsigned int b = (color & 0x1F) << 3;
1642  unsigned int g = ((color >> 5) & 0x3F) << 2;
1643  unsigned int r = ((color >> 11) & 0x1F) << 3;
1644  Gdiplus::Pen pen(Gdiplus::Color(r, g, b));
1645  p2DGraphics->DrawLine(&pen, uX, uY, uZ, uW);
1646 }
1647 
1648 void Render::ClearZBuffer(int a2, int a3) {
1649  memset32(this->pActiveZBuffer, -65536, 0x4B000);
1650 }
1651 
1653  int v2 = 0;
1654  unsigned int uRedMask = ddpfPrimarySuface.dwRBitMask;
1655  this->uTargetBBits = 0;
1656  do {
1657  if ((1 << v2) & uRedMask) {
1658  ++this->uTargetRBits;
1659  }
1660  ++v2;
1661  } while (v2 < 32);
1662 
1663  unsigned int uGreenMask = ddpfPrimarySuface.dwGBitMask;
1664  int v5 = 0;
1665  do {
1666  if ((1 << v5) & uGreenMask) ++this->uTargetGBits;
1667  ++v5;
1668  } while (v5 < 32);
1669 
1670  unsigned int uBlueMask = ddpfPrimarySuface.dwBBitMask;
1671  int v7 = 0;
1672  do {
1673  if ((1 << v7) & uBlueMask) ++this->uTargetBBits;
1674  ++v7;
1675  } while (v7 < 32);
1676 }
1677 
1678 bool Render::LockSurface_DDraw4(IDirectDrawSurface4 *pSurface,
1679  DDSURFACEDESC2 *pDesc,
1680  unsigned int uLockFlags) {
1681  HRESULT result = pSurface->Lock(NULL, pDesc, uLockFlags, NULL);
1682  /*
1683  Когда объект DirectDrawSurface теряет поверхностную память, методы возвратят
1684  DDERR_SURFACELOST и не выполнят никакую другую функцию. Метод
1685  IDirectDrawSurface::Restore перераспределит поверхностную память и повторно
1686  присоединит ее к объекту DirectDrawSurface.
1687  */
1688  if (result == DDERR_SURFACELOST) {
1689  HRESULT v6 =
1690  pSurface->Restore(); //Восстанавливает потерянную поверхность. Это
1691  //происходит, когда поверхностная память,
1692  //связанная с объектом DirectDrawSurface была
1693  //освобождена.
1694  if (v6) {
1695  if (v6 !=
1696  DDERR_IMPLICITLYCREATED) { // DDERR_IMPLICITLYCREATED -
1697  // Поверхность не может быть
1698  // восстановлена, потому что она -
1699  // неявно созданная поверхность.
1700  result = (bool)memset(pDesc, 0, 4);
1701  return 0;
1702  }
1703  this->pFrontBuffer4->Restore();
1704  pSurface->Restore();
1705  }
1706  result = pSurface->Lock(NULL, pDesc, DDLOCK_WAIT, NULL);
1707  if (result == DDERR_INVALIDRECT ||
1708  result ==
1709  DDERR_SURFACEBUSY) { // DDERR_SURFACEBUSY - Доступ к этой
1710  // поверхности отказан, потому что
1711  // поверхность блокирована другой нитью.
1712  // DDERR_INVALIDRECT - Обеспечиваемый
1713  // прямоугольник недопустим.
1714  result = (bool)memset(pDesc, 0, 4);
1715  return 0;
1716  }
1717  ErrD3D(result);
1718  if (result) {
1719  result = (bool)memset(pDesc, 0, 4);
1720  return result;
1721  }
1722  if (pRenderD3D) {
1724  }
1725  result = this->pDirectDraw4->RestoreAllSurfaces();
1726  } else {
1727  if (result) {
1728  if (result == DDERR_INVALIDRECT || result == DDERR_SURFACEBUSY) {
1729  result = (bool)memset(pDesc, 0, 4);
1730  return result;
1731  }
1732  ErrD3D(result);
1733  }
1734  }
1735  return true;
1736 }
1737 
1739  ErrD3D(pDirectDraw4->CreateClipper(0, &pDDrawClipper, NULL));
1740  ErrD3D(pDDrawClipper->SetHWnd(0, (HWND)window->GetWinApiHandle()));
1741  ErrD3D(pFrontBuffer4->SetClipper(pDDrawClipper));
1742 }
1743 
1744 void Render::GetTargetPixelFormat(DDPIXELFORMAT *pOut) {
1745  pFrontBuffer4->GetPixelFormat(pOut);
1746 }
1747 
1749  if (pFrontBuffer4->IsLost() == DDERR_SURFACELOST) {
1750  pFrontBuffer4->Restore();
1751  }
1752 }
1753 
1755  if (pBackBuffer4->IsLost() == DDERR_SURFACELOST) {
1756  pBackBuffer4->Restore();
1757  }
1758 }
1759 
1760 void Render::BltBackToFontFast(int a2, int a3, Rect *pSrcRect) {
1761  IDirectDrawSurface *pFront;
1762  IDirectDrawSurface *pBack;
1763  pFront = (IDirectDrawSurface *)this->pFrontBuffer4;
1764  pBack = (IDirectDrawSurface *)this->pBackBuffer4;
1765  pFront->BltFast(NULL, NULL, pBack, (RECT *)pSrcRect, DDBLTFAST_WAIT);
1766 }
1767 
1769  return render->uNumBillboardsToDraw;
1770 }
1771 
1772 unsigned int Render::GetParentBillboardID(unsigned int uBillboardID) {
1773  return render->pBillboardRenderListD3D[uBillboardID].sParentBillboardID;
1774 }
1775 
1777  if (!uNumD3DSceneBegins++) {
1778  pRenderD3D->ClearTarget(true, 0x00F08020, true, 1.0);
1779  render->uNumBillboardsToDraw = 0;
1780  pRenderD3D->pDevice->BeginScene();
1781 
1784  else
1785  uFogColor = 0;
1786 
1787  if (uFogColor & 0xFF000000) {
1788  pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_FOGENABLE, 1);
1789  pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_FOGCOLOR,
1790  uFogColor & 0xFFFFFF);
1791  pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_FOGTABLEMODE, 0);
1792  SetUsingSpecular(true);
1793  } else {
1794  pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_FOGENABLE, 0);
1795  SetUsingSpecular(false);
1796  }
1797  }
1798 }
1799 
1802  if (uNumD3DSceneBegins == 0) {
1803  engine->draw_debug_outlines();
1806  pRenderD3D->pDevice->EndScene();
1807  }
1808 }
1809 
1810 unsigned int Render::GetActorTintColor(int DimLevel, int tint, float WorldViewX, int a5, RenderBillboard *Billboard) {
1811  // GetActorTintColor(int max_dimm, int min_dimm, float distance, int a4, RenderBillboard *a5)
1812  return ::GetActorTintColor(DimLevel, tint, WorldViewX, a5, Billboard);
1813 }
1814 
1815 void Render::DrawTerrainPolygon(struct Polygon *a4, bool transparent,
1816  bool clampAtTextureBorders) {
1817  int v11; // eax@5
1818  unsigned int v45; // eax@28
1819 
1820  unsigned int uNumVertices = a4->uNumVertices;
1821 
1822  auto texture = (TextureD3D *)a4->texture;
1823 
1824  if (!this->uNumD3DSceneBegins) return;
1825  if (uNumVertices < 3) return;
1826 
1827  if (_4D864C_force_sw_render_rules && engine->config->Flag1_1()) {
1828  v11 =
1831  lightmap_builder->DrawLightmaps(v11 /*, 0*/);
1832  } else if (transparent || !lightmap_builder->StationaryLightsCount ||
1833  _4D864C_force_sw_render_rules && engine->config->Flag1_2()) {
1834  if (clampAtTextureBorders)
1835  this->pRenderD3D->pDevice->SetTextureStageState(0, D3DTSS_ADDRESS,
1836  D3DTADDRESS_CLAMP);
1837  else
1838  this->pRenderD3D->pDevice->SetTextureStageState(0, D3DTSS_ADDRESS,
1839  D3DTADDRESS_WRAP);
1840 
1841  if (transparent || config->is_using_specular) {
1842  this->pRenderD3D->pDevice->SetRenderState(
1843  D3DRENDERSTATE_ALPHABLENDENABLE, TRUE);
1844  if (transparent) {
1845  this->pRenderD3D->pDevice->SetRenderState(
1846  D3DRENDERSTATE_SRCBLEND, D3DBLEND_SRCALPHA);
1847  this->pRenderD3D->pDevice->SetRenderState(
1848  D3DRENDERSTATE_DESTBLEND, D3DBLEND_INVSRCALPHA);
1849  // this->pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_SRCBLEND,
1850  // D3DBLEND_ZERO);
1851  // this->pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_DESTBLEND,
1852  // D3DBLEND_ONE);
1853  } else {
1854  this->pRenderD3D->pDevice->SetRenderState(
1855  D3DRENDERSTATE_SRCBLEND, D3DBLEND_ONE);
1856  this->pRenderD3D->pDevice->SetRenderState(
1857  D3DRENDERSTATE_DESTBLEND, D3DBLEND_ZERO);
1858  }
1859  }
1860 
1861  for (uint i = 0; i < uNumVertices; ++i) {
1864  d3d_vertex_buffer[i].pos.z =
1865  1.0 - 1.0 / ((VertexRenderList[i].vWorldViewPosition.x * 1000) /
1867  d3d_vertex_buffer[i].rhw =
1868  1.0 / (VertexRenderList[i].vWorldViewPosition.x + 0.0000001);
1871  0, 0);
1872  d3d_vertex_buffer[i].specular = 0;
1873  if (config->is_using_specular)
1875  0, 0, VertexRenderList[i].vWorldViewPosition.x);
1876 
1879  }
1880 
1881  this->pRenderD3D->pDevice->SetTexture(0, texture->GetDirect3DTexture());
1882  this->pRenderD3D->pDevice->DrawPrimitive(
1883  D3DPT_TRIANGLEFAN,
1884  D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR | D3DFVF_TEX1,
1885  d3d_vertex_buffer, uNumVertices, D3DDP_DONOTLIGHT);
1886  if (transparent) {
1887  ErrD3D(pRenderD3D->pDevice->SetRenderState(
1888  D3DRENDERSTATE_ALPHABLENDENABLE, FALSE));
1889  ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_SRCBLEND,
1890  D3DBLEND_ONE));
1891  ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_DESTBLEND,
1892  D3DBLEND_ZERO));
1893  }
1895  for (uint i = 0; i < uNumVertices; ++i) {
1898  d3d_vertex_buffer[i].pos.z =
1899  1.0 - 1.0 / ((VertexRenderList[i].vWorldViewPosition.x * 1000) /
1901  d3d_vertex_buffer[i].rhw =
1902  1.0 / (VertexRenderList[i].vWorldViewPosition.x + 0.0000001);
1904  d3d_vertex_buffer[i].specular = 0;
1905  if (config->is_using_specular)
1907  0, 0, VertexRenderList[i].vWorldViewPosition.x);
1910  }
1911  ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ZWRITEENABLE,
1912  FALSE));
1913  ErrD3D(pRenderD3D->pDevice->SetTextureStageState(0, D3DTSS_ADDRESS,
1914  D3DTADDRESS_WRAP));
1915  if (config->is_using_specular)
1916  ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_FOGENABLE, FALSE));
1917 
1918  ErrD3D(pRenderD3D->pDevice->SetTexture(0, 0));
1919  ErrD3D(pRenderD3D->pDevice->DrawPrimitive(
1920  D3DPT_TRIANGLEFAN, //рисуется текстурка с светом
1921  D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR | D3DFVF_TEX1,
1922  d3d_vertex_buffer, uNumVertices, D3DDP_DONOTLIGHT));
1923 
1924  ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_CULLMODE, D3DCULL_NONE));
1925 
1926  lightmap_builder->DrawLightmaps(-1 /*, 0*/);
1927 
1928  for (uint i = 0; i < uNumVertices; ++i) {
1929  d3d_vertex_buffer[i].diffuse = 0xFFFFFFFF; /*-1;*/
1930  }
1931  ErrD3D(pRenderD3D->pDevice->SetTexture(0, texture->GetDirect3DTexture())); //текстурка
1932  ErrD3D(pRenderD3D->pDevice->SetTextureStageState(0, D3DTSS_ADDRESS, D3DTADDRESS_WRAP));
1933  if (!config->is_using_specular) {
1934  ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ZWRITEENABLE, TRUE));
1935  }
1936  ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ALPHABLENDENABLE, TRUE));
1937  ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_SRCBLEND,
1938  D3DBLEND_ZERO));
1939  ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_DESTBLEND,
1940  D3DBLEND_SRCCOLOR));
1941  ErrD3D(pRenderD3D->pDevice->DrawPrimitive(
1942  D3DPT_TRIANGLEFAN,
1943  D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR | D3DFVF_TEX1,
1944  d3d_vertex_buffer, uNumVertices, D3DDP_DONOTLIGHT));
1945 
1946  if (config->is_using_specular) {
1947  ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ZWRITEENABLE, TRUE));
1948  ErrD3D(pRenderD3D->pDevice->SetTexture(0, 0));
1949  for (uint i = 0; i < uNumVertices; ++i) {
1951  render->uFogColor |
1952  d3d_vertex_buffer[i].specular & 0xFF000000;
1953  d3d_vertex_buffer[i].specular = 0;
1954  }
1955 
1956  ErrD3D(pRenderD3D->pDevice->SetTexture(0, 0)); // problem
1957  ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_SRCBLEND,
1958  D3DBLEND_INVSRCALPHA));
1959  ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_DESTBLEND,
1960  D3DBLEND_SRCALPHA));
1961  ErrD3D(pRenderD3D->pDevice->DrawPrimitive(
1962  D3DPT_TRIANGLEFAN,
1963  D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR | D3DFVF_TEX1,
1964  d3d_vertex_buffer, uNumVertices, D3DDP_DONOTLIGHT));
1965  ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_FOGENABLE,
1966  TRUE));
1967  v45 = GetLevelFogColor();
1968  ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_FOGCOLOR,
1969  v45 & 0xFFFFFF));
1970  ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_FOGTABLEMODE, FALSE));
1971  }
1972  ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_SRCBLEND, D3DBLEND_ONE));
1973  ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_DESTBLEND, D3DBLEND_ZERO));
1974  ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ALPHABLENDENABLE, FALSE));
1975  //}
1976  }
1977 
1978  // if (pIndoorCamera->flags & INDOOR_CAMERA_DRAW_TERRAIN_OUTLINES ||
1979  // pBLVRenderParams->uFlags & INDOOR_CAMERA_DRAW_TERRAIN_OUTLINES) if
1980  // (pIndoorCameraD3D->debug_flags & ODM_RENDER_DRAW_TERRAIN_OUTLINES)
1981  if (engine->config->debug_terrain)
1983  0x00FFFFFF, 0.0);
1984 }
1985 
1986 
1987 
1988 
1989 
1990 
1991 
1993  int uPackedID, unsigned int uColor, int a8) {
1994  if (!uNumD3DSceneBegins || uNumVertices < 3) {
1995  return;
1996  }
1997 
1998  unsigned int sCorrectedColor = uColor;
1999 
2000  TextureD3D *texture = (TextureD3D *)pFace->GetTexture();
2001 
2003  sCorrectedColor = 0xFFFFFFFF/*-1*/;
2004  }
2005 
2006 
2007  // perception
2008  // engine->AlterGamma_BLV(pFace, &sCorrectedColor);
2009 
2010  if (engine->CanSaturateFaces() && (pFace->uAttributes & FACE_CAN_SATURATE_COLOR)) {
2011  uint eightSeconds = OS_GetTime() % 3000;
2012  float angle = (eightSeconds / 3000.0f) * 2 * 3.1415f;
2013 
2014  int redstart = (sCorrectedColor & 0x00FF0000) >> 16;
2015 
2016  int col = (redstart - 64) - (64 * cosf(angle));
2017  // (a << 24) | (r << 16) | (g << 8) | b;
2018  sCorrectedColor = (0xFF << 24) | (redstart << 16) | (col << 8) | col;
2019  }
2020 
2021  if (pFace->uAttributes & FACE_OUTLINED) {
2022  if (OS_GetTime() % 300 >= 150)
2023  uColor = sCorrectedColor = 0xFF20FF20;
2024  else
2025  uColor = sCorrectedColor = 0xFF109010;
2026  }
2027 
2028  if (_4D864C_force_sw_render_rules && engine->config->Flag1_1()) {
2029  __debugbreak();
2030  ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ZWRITEENABLE, false));
2031  ErrD3D(pRenderD3D->pDevice->SetTextureStageState(0, D3DTSS_ADDRESS, D3DTADDRESS_WRAP));
2032  for (uint i = 0; i < uNumVertices; ++i) {
2035  d3d_vertex_buffer[i].pos.z =
2036  1.0 -
2037  1.0 / (array_507D30[i].vWorldViewPosition.x * 0.061758894);
2038  d3d_vertex_buffer[i].rhw =
2040  d3d_vertex_buffer[i].diffuse = sCorrectedColor;
2041  d3d_vertex_buffer[i].specular = 0;
2043  array_507D30[i].u / (double)pFace->GetTexture()->GetWidth();
2045  array_507D30[i].v / (double)pFace->GetTexture()->GetHeight();
2046  }
2047 
2048  ErrD3D(pRenderD3D->pDevice->SetTextureStageState(0, D3DTSS_ADDRESS,
2049  D3DTADDRESS_WRAP));
2050  ErrD3D(pRenderD3D->pDevice->SetTexture(0, nullptr));
2051  ErrD3D(pRenderD3D->pDevice->DrawPrimitive(
2052  D3DPT_TRIANGLEFAN,
2053  D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR | D3DFVF_TEX1,
2054  d3d_vertex_buffer, uNumVertices, D3DDP_DONOTLIGHT));
2055  lightmap_builder->DrawLightmaps(-1 /*, 0*/);
2056  } else {
2058  _4D864C_force_sw_render_rules && engine->config->Flag1_2()) {
2059  // return;
2060 
2061  for (uint i = 0; i < uNumVertices; ++i) {
2064  d3d_vertex_buffer[i].pos.z =
2065  1.0 -
2066  1.0 / (array_507D30[i].vWorldViewPosition.x * 0.061758894);
2067  d3d_vertex_buffer[i].rhw =
2069  d3d_vertex_buffer[i].diffuse = sCorrectedColor;
2070  d3d_vertex_buffer[i].specular = 0;
2072  array_507D30[i].u / (double)pFace->GetTexture()->GetWidth();
2074  array_507D30[i].v /
2075  (double)pFace->GetTexture()->GetHeight();
2076  }
2077 
2078  ErrD3D(pRenderD3D->pDevice->SetTextureStageState(0, D3DTSS_ADDRESS,
2079  D3DTADDRESS_WRAP));
2080  ErrD3D(pRenderD3D->pDevice->SetTexture(
2081  0, texture->GetDirect3DTexture()));
2082  ErrD3D(pRenderD3D->pDevice->DrawPrimitive(
2083  D3DPT_TRIANGLEFAN,
2084  D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR | D3DFVF_TEX1,
2085  d3d_vertex_buffer, uNumVertices, D3DDP_DONOTLIGHT));
2086  } else {
2087  for (uint i = 0; i < uNumVertices; ++i) {
2090  d3d_vertex_buffer[i].pos.z =
2091  1.0 -
2092  1.0 / (array_507D30[i].vWorldViewPosition.x * 0.061758894);
2094  d3d_vertex_buffer[i].diffuse = uColor;
2095  d3d_vertex_buffer[i].specular = 0;
2097  array_507D30[i].u / (double)pFace->GetTexture()->GetWidth();
2099  array_507D30[i].v /
2100  (double)pFace->GetTexture()->GetHeight();
2101  }
2102 
2103  ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ZWRITEENABLE, FALSE));
2104  ErrD3D(pRenderD3D->pDevice->SetTextureStageState(0, D3DTSS_ADDRESS, D3DTADDRESS_WRAP));
2105  ErrD3D(pRenderD3D->pDevice->SetTexture(0, nullptr));
2106 
2107  ErrD3D(pRenderD3D->pDevice->DrawPrimitive(
2108  D3DPT_TRIANGLEFAN,
2109  D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR | D3DFVF_TEX1,
2110  d3d_vertex_buffer, uNumVertices, D3DDP_DONOTLIGHT));
2111 
2112  ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_CULLMODE, D3DCULL_NONE));
2113 
2114  lightmap_builder->DrawLightmaps(-1 /*, 0*/);
2115 
2116  for (uint i = 0; i < uNumVertices; ++i) {
2117  d3d_vertex_buffer[i].diffuse = sCorrectedColor;
2118  }
2119 
2120  ErrD3D(pRenderD3D->pDevice->SetTexture(0, texture->GetDirect3DTexture()));
2121  ErrD3D(pRenderD3D->pDevice->SetTextureStageState(0, D3DTSS_ADDRESS, D3DTADDRESS_WRAP));
2122 
2123  ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ZWRITEENABLE, TRUE));
2124  ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ALPHABLENDENABLE, TRUE));
2125  ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_SRCBLEND, D3DBLEND_ZERO));
2126  ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_DESTBLEND, D3DBLEND_SRCCOLOR));
2127 
2128  ErrD3D(pRenderD3D->pDevice->DrawPrimitive(
2129  D3DPT_TRIANGLEFAN,
2130  D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR | D3DFVF_TEX1,
2131  d3d_vertex_buffer, uNumVertices, D3DDP_DONOTLIGHT));
2132 
2133  ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_SRCBLEND, D3DBLEND_ONE));
2134  ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_DESTBLEND, D3DBLEND_ZERO));
2135  ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ALPHABLENDENABLE, FALSE));
2136  }
2137  }
2138 }
2139 
2141  RenderBillboard *billboard) {
2142  int v11; // eax@9
2143  int v12; // eax@9
2144  double v15; // st5@12
2145  double v16; // st4@12
2146  double v17; // st3@12
2147  double v18; // st2@12
2148  int v19; // ecx@14
2149  double v20; // st3@14
2150  int v21; // ecx@16
2151  double v22; // st3@16
2152  float v27; // [sp+24h] [bp-Ch]@5
2153  float v29; // [sp+2Ch] [bp-4h]@5
2154  float v31; // [sp+3Ch] [bp+Ch]@5
2155  float a1; // [sp+40h] [bp+10h]@5
2156 
2157  if (this->uNumD3DSceneBegins == 0) {
2158  return;
2159  }
2160 
2161  Sprite *pSprite = billboard->hwsprite;
2162  int dimming_level = billboard->dimming_level;
2163 
2164  // v4 = pSoftBillboard;
2165  // v5 = (double)pSoftBillboard->zbuffer_depth;
2166  // pSoftBillboarda = pSoftBillboard->zbuffer_depth;
2167  // v6 = pSoftBillboard->zbuffer_depth;
2169  pSoftBillboard->screen_space_z);
2170  // v8 = dimming_level;
2171  // device_caps = v7;
2172  int v28 = dimming_level & 0xFF000000;
2173  if (dimming_level & 0xFF000000) {
2175  } else {
2177  }
2178  // v10 = a3;
2179  pBillboardRenderListD3D[v7].field_90 = pSoftBillboard->field_44;
2181  pBillboardRenderListD3D[v7].object_pid = pSoftBillboard->object_pid;
2183  pSoftBillboard->sParentBillboardID;
2184  // v25 = pSoftBillboard->uScreenSpaceX;
2185  // v24 = pSoftBillboard->uScreenSpaceY;
2186  a1 = pSoftBillboard->screenspace_projection_factor_x;
2187  v29 = pSoftBillboard->screenspace_projection_factor_y;
2188  v31 = (double)((pSprite->uBufferWidth >> 1) - pSprite->uAreaX);
2189  v27 = (double)(pSprite->uBufferHeight - pSprite->uAreaY);
2190  if (pSoftBillboard->uFlags & 4) {
2191  v31 = v31 * -1.0;
2192  }
2193  if (config->is_tinting && pSoftBillboard->sTintColor) {
2195  pSoftBillboard->screen_space_z, 0, 0);
2196  v12 = BlendColors(pSoftBillboard->sTintColor, v11);
2197  if (v28)
2198  v12 =
2199  (unsigned int)((char *)&array_77EC08[1852].pEdgeList1[17] + 3) &
2200  ((unsigned int)v12 >> 1);
2201  } else {
2203  pSoftBillboard->screen_space_z, 0, 0);
2204  }
2205  // v13 = (double)v25;
2207  pBillboardRenderListD3D[v7].pQuads[0].diffuse = v12;
2209  pSoftBillboard->screen_space_x - v31 * a1;
2210  // v14 = (double)v24;
2211  // v32 = v14;
2213  pSoftBillboard->screen_space_y - v27 * v29;
2214  v15 = 1.0 - 1.0 / (pSoftBillboard->screen_space_z * 0.061758894);
2215  pBillboardRenderListD3D[v7].pQuads[0].pos.z = v15;
2216  v16 = 1.0 / pSoftBillboard->screen_space_z;
2218  1.0 / pSoftBillboard->screen_space_z;
2219  pBillboardRenderListD3D[v7].pQuads[0].texcoord.x = 0.0;
2220  pBillboardRenderListD3D[v7].pQuads[0].texcoord.y = 0.0;
2221  v17 = (double)((pSprite->uBufferWidth >> 1) - pSprite->uAreaX);
2222  v18 = (double)(pSprite->uBufferHeight - pSprite->uAreaY -
2223  pSprite->uAreaHeight);
2224  if (pSoftBillboard->uFlags & 4) {
2225  v17 = v17 * -1.0;
2226  }
2228  pBillboardRenderListD3D[v7].pQuads[1].diffuse = v12;
2230  pSoftBillboard->screen_space_x - v17 * a1;
2232  pSoftBillboard->screen_space_y - v18 * v29;
2233  pBillboardRenderListD3D[v7].pQuads[1].pos.z = v15;
2234  pBillboardRenderListD3D[v7].pQuads[1].rhw = v16;
2235  pBillboardRenderListD3D[v7].pQuads[1].texcoord.x = 0.0;
2236  pBillboardRenderListD3D[v7].pQuads[1].texcoord.y = 1.0;
2237  v19 = pSprite->uBufferHeight - pSprite->uAreaY - pSprite->uAreaHeight;
2238  v20 = (double)(pSprite->uAreaX + pSprite->uAreaWidth +
2239  (pSprite->uBufferWidth >> 1) - pSprite->uBufferWidth);
2240  if (pSoftBillboard->uFlags & 4) {
2241  v20 = v20 * -1.0;
2242  }
2244  pBillboardRenderListD3D[v7].pQuads[2].diffuse = v12;
2246  v20 * a1 + pSoftBillboard->screen_space_x;
2248  pSoftBillboard->screen_space_y - (double)v19 * v29;
2249  pBillboardRenderListD3D[v7].pQuads[2].pos.z = v15;
2250  pBillboardRenderListD3D[v7].pQuads[2].rhw = v16;
2251  pBillboardRenderListD3D[v7].pQuads[2].texcoord.x = 1.0;
2252  pBillboardRenderListD3D[v7].pQuads[2].texcoord.y = 1.0;
2253  v21 = pSprite->uBufferHeight - pSprite->uAreaY;
2254  v22 = (double)(pSprite->uAreaX + pSprite->uAreaWidth +
2255  (pSprite->uBufferWidth >> 1) - pSprite->uBufferWidth);
2256  if (pSoftBillboard->uFlags & 4) {
2257  v22 = v22 * -1.0;
2258  }
2260  pBillboardRenderListD3D[v7].pQuads[3].diffuse = v12;
2262  v22 * a1 + pSoftBillboard->screen_space_x;
2264  pSoftBillboard->screen_space_y - (double)v21 * v29;
2265  pBillboardRenderListD3D[v7].pQuads[3].pos.z = v15;
2266  pBillboardRenderListD3D[v7].pQuads[3].rhw = v16;
2267  pBillboardRenderListD3D[v7].pQuads[3].texcoord.x = 1.0;
2268  pBillboardRenderListD3D[v7].pQuads[3].texcoord.y = 0.0;
2269  // v23 = pSprite->pTexture;
2271  pBillboardRenderListD3D[v7].z_order = pSoftBillboard->screen_space_z;
2272  pBillboardRenderListD3D[v7].texture = pSprite->texture;
2273 
2274  if (pSprite->texture->GetHeight() == 0 || pSprite->texture->GetWidth() == 0) __debugbreak();
2275 }
2276 
2277 void Render::DrawProjectile(float srcX, float srcY, float a3, float a4,
2278  float dstX, float dstY, float a7, float a8,
2279  Texture *texture) {
2280  double v20; // st4@8
2281  double v21; // st4@10
2282  double v22; // st4@10
2283  double v23; // st4@10
2284  double v25; // st4@11
2285  double v26; // st4@13
2286  double v28; // st4@13
2287 
2288  TextureD3D *textured3d = (TextureD3D *)texture;
2289 
2290  int xDifference = bankersRounding(dstX - srcX);
2291  int yDifference = bankersRounding(dstY - srcY);
2292  int absYDifference = abs(yDifference);
2293  int absXDifference = abs(xDifference);
2294  unsigned int smallerabsdiff = min(absXDifference, absYDifference);
2295  unsigned int largerabsdiff = max(absXDifference, absYDifference);
2296  int v32 = (11 * smallerabsdiff >> 5) + largerabsdiff;
2297  double v16 = 1.0 / (double)v32;
2298  double v17 = (double)yDifference * v16 * a4;
2299  double v18 = (double)xDifference * v16 * a4;
2301  v20 = a3 * 1000.0 / pIndoorCameraD3D->GetFarClip();
2302  v25 = a7 * 1000.0 / pIndoorCameraD3D->GetFarClip();
2303  } else {
2304  v20 = a3 * 0.061758894;
2305  v25 = a7 * 0.061758894;
2306  }
2307  v21 = 1.0 / a3;
2308  v22 = (double)yDifference * v16 * a8;
2309  v23 = (double)xDifference * v16 * a8;
2310  v26 = 1.0 - 1.0 / v25;
2311  v28 = 1.0 / a7;
2312 
2313  RenderVertexD3D3 v29[4];
2314  v29[0].pos.x = srcX + v17;
2315  v29[0].pos.y = srcY - v18;
2316  v29[0].pos.z = 1.0 - 1.0 / v20;
2317  v29[0].rhw = v21;
2318  v29[0].diffuse = -1;
2319  v29[0].specular = 0;
2320  v29[0].texcoord.x = 1.0;
2321  v29[0].texcoord.y = 0.0;
2322 
2323  v29[1].pos.x = v22 + dstX;
2324  v29[1].pos.y = dstY - v23;
2325  v29[1].pos.z = v26;
2326  v29[1].rhw = v28;
2327  v29[1].diffuse = -16711936;
2328  v29[1].specular = 0;
2329  v29[1].texcoord.x = 1.0;
2330  v29[1].texcoord.y = 1.0;
2331 
2332  v29[2].pos.x = dstX - v22;
2333  v29[2].pos.y = v23 + dstY;
2334  v29[2].pos.z = v26;
2335  v29[2].rhw = v28;
2336  v29[2].diffuse = -1;
2337  v29[2].specular = 0;
2338  v29[2].texcoord.x = 0.0;
2339  v29[2].texcoord.y = 1.0;
2340 
2341  v29[3].pos.x = srcX - v17;
2342  v29[3].pos.y = v18 + srcY;
2343  v29[3].pos.z = v29[0].pos.z;
2344  v29[3].rhw = v21;
2345  v29[3].diffuse = -1;
2346  v29[3].specular = 0;
2347  v29[3].texcoord.x = 0.0;
2348  v29[3].texcoord.y = 0.0;
2349 
2350  ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ALPHABLENDENABLE,
2351  TRUE));
2352  ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_SRCBLEND,
2353  D3DBLEND_ONE));
2354  ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_DESTBLEND,
2355  D3DBLEND_ONE));
2356  ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_DITHERENABLE,
2357  FALSE));
2358  ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ZWRITEENABLE,
2359  FALSE));
2360  ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_CULLMODE,
2361  D3DCULL_NONE));
2362  ErrD3D(
2363  pRenderD3D->pDevice->SetTexture(0, textured3d->GetDirect3DTexture()));
2364  ErrD3D(pRenderD3D->pDevice->DrawPrimitive(
2365  D3DPT_TRIANGLEFAN,
2366  D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR | D3DFVF_TEX1, v29, 4,
2367  24));
2368  ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ALPHABLENDENABLE,
2369  FALSE));
2370  ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_SRCBLEND,
2371  D3DBLEND_ONE));
2372  ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_DESTBLEND,
2373  D3DBLEND_ZERO));
2374  ErrD3D(
2375  pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_DITHERENABLE, TRUE));
2376  ErrD3D(
2377  pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ZWRITEENABLE, TRUE));
2378  ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_CULLMODE,
2379  D3DCULL_CW));
2380 }
2381 
2383  int diffuse) {
2384  if (a1->uNumVertices < 3) {
2385  return;
2386  }
2387 
2388  float depth = 1000000.0;
2389  for (uint i = 0; i < (unsigned int)a1->uNumVertices; ++i) {
2390  if (a1->field_104[i].z < depth) {
2391  depth = a1->field_104[i].z;
2392  }
2393  }
2394 
2402 
2403  for (unsigned int i = 0; i < (unsigned int)a1->uNumVertices; ++i) {
2404  pBillboardRenderListD3D[v5].pQuads[i].pos.x = a1->field_104[i].x;
2405  pBillboardRenderListD3D[v5].pQuads[i].pos.y = a1->field_104[i].y;
2406 
2407 
2408 
2409  // if (a1->field_104[i].z < 17) a1->field_104[i].z = 17;
2410  float rhw = 1.f / a1->field_104[i].z;
2411  float z = 1.f - 1.f / (a1->field_104[i].z * 1000.f / pIndoorCameraD3D->GetFarClip());
2412 
2413 
2414 
2415  double v10 = a1->field_104[i].z;
2417  v10 *= 1000.f / 16192.f;
2418  } else {
2419  v10 *= 1000.f / pIndoorCameraD3D->GetFarClip();
2420  }
2421 
2422 
2423  pBillboardRenderListD3D[v5].pQuads[i].pos.z = z; // 1.0 - 1.0 / v10;
2424  pBillboardRenderListD3D[v5].pQuads[i].rhw = rhw; // 1.0 / a1->field_104[i].z;
2425 
2426  int v12;
2427  if (diffuse & 0xFF000000) {
2428  v12 = a1->field_104[i].diffuse;
2429  } else {
2430  v12 = diffuse;
2431  }
2432  pBillboardRenderListD3D[v5].pQuads[i].diffuse = v12;
2434 
2435  pBillboardRenderListD3D[v5].pQuads[i].texcoord.x = 0.0;
2436  pBillboardRenderListD3D[v5].pQuads[i].texcoord.y = 0.0;
2437  }
2438 }
2439 
2441  return pD3DBitmaps.LoadTexture(name);
2442 }
2443 
2445  return pD3DSprites.LoadTexture(name);
2446 }
2447 
2449  // nothing
2450 }
2452  // nothing
2453 }
2454 
2456  auto t = (TextureD3D*)texture;
2457  if (t->initialized) {
2458  IDirectDrawSurface* dds_get = t->GetDirectDrawSurface();
2459  IDirect3DTexture2* d3dt_get = t->GetDirect3DTexture();
2460  if (dds_get) dds_get->Release();
2461  if (d3dt_get) d3dt_get->Release();
2462  }
2463 }
2464 
2466  auto t = (TextureD3D *)texture;
2467  if (t) {
2468  auto pixels = (uint16_t *)t->GetPixels(IMAGE_FORMAT_A1R5G5B5);
2469 
2470  IDirectDrawSurface4 *dds;
2471  IDirect3DTexture2 *d3dt;
2472 
2473  if (!pRenderD3D->CreateTexture(t->GetWidth(), t->GetHeight(), &dds,
2474  &d3dt, true, false,
2476  Error(
2477  "HiScreen16::LoadTexture - D3Drend->CreateTexture() failed: %x",
2478  0);
2479 
2480  DDSCAPS2 v19;
2481  memset(&v19, 0, sizeof(DDSCAPS2));
2482  v19.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_MIPMAP;
2483 
2484  DDSURFACEDESC2 desc;
2485  memset(&desc, 0, sizeof(DDSURFACEDESC2));
2486  desc.dwSize = sizeof(DDSURFACEDESC2);
2487 
2488  if (LockSurface_DDraw4(dds, &desc, DDLOCK_WAIT | DDLOCK_WRITEONLY)) {
2489  auto v13 = pixels;
2490  auto v14 = (unsigned __int16 *)desc.lpSurface;
2491  for (uint bMipMaps = 0; bMipMaps < desc.dwHeight; bMipMaps++) {
2492  for (auto v15 = 0; v15 < desc.dwWidth; v15++) {
2493  *v14 = *v13;
2494  ++v14;
2495  ++v13;
2496  }
2497  v14 += (desc.lPitch >> 1) - desc.dwWidth;
2498  }
2499  ErrD3D(dds->Unlock(NULL));
2500  }
2501 
2502  t->SetDirect3DTexture2(d3dt);
2503  t->SetDirectDrawSurface((IDirectDrawSurface *)dds);
2504 
2505  return true;
2506  }
2507  return false;
2508 }
2509 
2511 
2513 
2514 void Render::ScreenFade(unsigned int color, float t) {
2515  unsigned int v3 = 0;
2516 
2517  //{
2518  if (t > 1.0f)
2519  t = 1.0f;
2520  else if (t < 0.0f)
2521  t = 0.0f;
2522 
2523  int v40 = (char)floorf(t * 255.0f + 0.5f);
2524 
2525  unsigned int v7 = color | (v40 << 24);
2526 
2527  RenderVertexD3D3 v36[4];
2528  v36[0].specular = 0;
2529  v36[0].pos.x = pViewport->uViewportTL_X;
2530  v36[0].pos.y = (double)pViewport->uViewportTL_Y;
2531  v36[0].pos.z = 0.0;
2532  v36[0].diffuse = v7;
2533  v36[0].rhw = 1.0;
2534  v36[0].texcoord.x = 0.0;
2535  v36[0].texcoord.y = 0.0;
2536 
2537  v36[1].specular = 0;
2538  v36[1].pos.x = pViewport->uViewportTL_X;
2539  v36[1].pos.y = (double)(pViewport->uViewportBR_Y + 1);
2540  v36[1].pos.z = 0.0;
2541  v36[1].diffuse = v7;
2542  v36[1].rhw = 1.0;
2543  v36[1].texcoord.x = 0.0;
2544  v36[1].texcoord.y = 0.0;
2545 
2546  v36[2].specular = 0;
2547  v36[2].pos.x = (double)pViewport->uViewportBR_X;
2548  v36[2].pos.y = (double)(pViewport->uViewportBR_Y + 1);
2549  v36[2].pos.z = 0.0;
2550  v36[2].diffuse = v7;
2551  v36[2].rhw = 1.0;
2552  v36[2].texcoord.x = 0.0;
2553  v36[2].texcoord.y = 0.0;
2554 
2555  v36[3].specular = 0;
2556  v36[3].pos.x = (double)pViewport->uViewportBR_X;
2557  v36[3].pos.y = (double)pViewport->uViewportTL_Y;
2558  v36[3].pos.z = 0.0;
2559  v36[3].diffuse = v7;
2560  v36[3].rhw = 1.0;
2561  v36[3].texcoord.x = 0.0;
2562  v36[3].texcoord.y = 0.0;
2563 
2564  ErrD3D(pRenderD3D->pDevice->SetTexture(0, 0));
2565  ErrD3D(
2566  pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_FOGENABLE, FALSE));
2567  ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ALPHABLENDENABLE,
2568  TRUE));
2569  ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ZWRITEENABLE,
2570  FALSE));
2571  ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_SRCBLEND,
2572  D3DBLEND_SRCALPHA));
2573  ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_DESTBLEND,
2574  D3DBLEND_INVSRCALPHA));
2575  ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_DITHERENABLE,
2576  FALSE));
2577  ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ZFUNC,
2578  D3DCMP_ALWAYS));
2579  ErrD3D(pRenderD3D->pDevice->DrawPrimitive(
2580  D3DPT_TRIANGLEFAN,
2581  D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR | D3DFVF_TEX1, v36, 4,
2582  28));
2583  ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_SRCBLEND,
2584  D3DBLEND_ONE));
2585  ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_DESTBLEND,
2586  D3DBLEND_ZERO));
2587  ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ALPHABLENDENABLE,
2588  FALSE));
2589  ErrD3D(
2590  pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ZWRITEENABLE, TRUE));
2591  ErrD3D(
2592  pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_DITHERENABLE, TRUE));
2593  ErrD3D(
2594  pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ZFUNC, D3DCMP_LESS));
2595  /*}
2596  else
2597  {
2598  v40 = (1.0 - a3) * 65536.0;
2599  v39 = v40 + 6.7553994e15;
2600  LODWORD(a3) = LODWORD(v39);
2601  v38 = (signed int)(pViewport->uViewportBR_X - pViewport->uViewportTL_X) >>
2602  1; HIDWORD(v39) = pViewport->uViewportBR_Y - pViewport->uViewportTL_Y + 1;
2603  v13 = pViewport->uViewportTL_X + ecx0->uTargetSurfacePitch -
2604  pViewport->uViewportBR_X; v14 =
2605  &ecx0->pTargetSurface[pViewport->uViewportTL_X + pViewport->uViewportTL_Y *
2606  ecx0->uTargetSurfacePitch]; v37 = 2 * v13; LODWORD(v40) = (int)v14;
2607 
2608  int __i = 0;
2609  v15 = dword_F1B430.data();
2610  do
2611  {
2612  v16 = v3;
2613  v3 += LODWORD(a3);
2614  dword_F1B430[__i++] = v16 >> 16;
2615  }
2616  //while ( (signed int)v15 < (signed int)&Aureal3D_SplashScreen );
2617  while (__i < 32);
2618 
2619  if ( render->uTargetGBits == 6 )
2620  {
2621  v17 = sr_42690D_colors_cvt(this_);
2622  v18 = (65536 - LODWORD(a3)) * (v17 & 0x1F);
2623  this_ = (((65536 - LODWORD(a3)) * (unsigned __int16)(v17 & 0xF800) &
2624  0xF800FFFF | v18 & 0x1F0000 | (65536 - LODWORD(a3)) * (v17 & 0x7E0) &
2625  0x7E00000u) >> 16 << 16) | (((65536 - LODWORD(a3)) * (unsigned __int16)(v17
2626  & 0xF800) & 0xF800FFFF | v18 & 0x1F0000 | (65536 - LODWORD(a3)) * (v17 &
2627  0x7E0) & 0x7E00000u) >> 16); v19 = v40; v20 = off_4EFDB0; v21 =
2628  HIDWORD(v39); do
2629  {
2630  v22 = v38;
2631  v31 = v21;
2632  do
2633  {
2634  v23 = (*(int *)((char *)v20
2635  + ((((unsigned __int16)(*(short *)((char *)v20 + ((*(unsigned int
2636  *)LODWORD(v19) & 0xF800u) >> 9)) << 11) | *(unsigned int *)LODWORD(v19) &
2637  0x7FF) & 0x7C0u) >> 4)) << 6) | (*(int *)((char *)v20 + ((((*(int *)((char
2638  *)v20 + ((*(unsigned int *)LODWORD(v19) & 0xF800u) >> 9)) << 11) | (*(int
2639  *)((char *)v20 + ((*(unsigned int *)LODWORD(v19) & 0xF8000000u) >> 25)) <<
2640  27) | *(unsigned int *)LODWORD(v19) & 0x7FF07FF) & 0x7C00000u) >> 20)) <<
2641  22) | ((*(int *)((char *)v20 + ((*(unsigned int *)LODWORD(v19) & 0xF800u) >>
2642  9)) << 11) | (*(int *)((char *)v20 + ((*(unsigned int *)LODWORD(v19) &
2643  0xF8000000u) >> 25)) << 27) | *(unsigned int *)LODWORD(v19) & 0x7FF07FF) &
2644  0xF81FF81F; result = this_
2645  + (*((int *)v20
2646  + (((unsigned __int8)(*((char *)v20
2647  + ((((unsigned __int16)(*(short *)((char *)v20
2648  + ((*(unsigned int *)LODWORD(v19) & 0xF800u) >> 9)) << 11) | *(unsigned int
2649  *)LODWORD(v19) & 0x7FF) & 0x7C0u) >> 4)) << 6) | *(unsigned int
2650  *)LODWORD(v19) & 0x1F) & 0x1F)) | (*(int *)((char *)v20 + ((v23 & 0x1F0000u)
2651  >> 14)) << 16) | ((*(int *)((char *)v20 + ((((unsigned __int16)(*(short
2652  *)((char *)v20 + ((*(unsigned int *)LODWORD(v19) & 0xF800u) >> 9)) << 11) |
2653  *(unsigned int *)LODWORD(v19) & 0x7FF) & 0x7C0u) >> 4)) << 6) | (*(int
2654  *)((char *)v20 + ((((*(int *)((char *)v20 + ((*(unsigned int *)LODWORD(v19)
2655  & 0xF800u) >> 9)) << 11) | (*(int *)((char *)v20 + ((*(unsigned int
2656  *)LODWORD(v19) & 0xF8000000u) >> 25)) << 27) | *(unsigned int *)LODWORD(v19)
2657  & 0x7FF07FF) & 0x7C00000u) >> 20)) << 22) | ((*(int *)((char *)v20 +
2658  ((*(unsigned int *)LODWORD(v19) & 0xF800u) >> 9)) << 11) | (*(int *)((char
2659  *)v20 + ((*(unsigned int *)LODWORD(v19) & 0xF8000000u) >> 25)) << 27) |
2660  *(unsigned int *)LODWORD(v19) & 0x7FF07FF) & 0xF81FF81F) & 0xFFE0FFE0);
2661  *(unsigned int *)LODWORD(v19) = result;
2662  LODWORD(v19) += 4;
2663  --v22;
2664  }
2665  while ( v22 );
2666  LODWORD(v19) += v37;
2667  v21 = v31 - 1;
2668  }
2669  while ( v31 != 1 );
2670  }
2671  else
2672  {
2673  v24 = sr_4268E3_smthn_to_a1r5g5b5(this_);
2674  v25 = (65536 - LODWORD(a3)) * (v24 & 0x1F);
2675  this_ = (((65536 - LODWORD(a3)) * (v24 & 0x7C00) & 0x7C000000 | v25 &
2676  0x1F0000 | (65536 - LODWORD(a3))
2677  * (v24 & 0x3E0) & 0x3E00000u) >> 16 << 16) | (((65536 - LODWORD(a3)) * (v24
2678  & 0x7C00) & 0x7C000000 | v25 & 0x1F0000 | (65536 - LODWORD(a3)) * (v24 &
2679  0x3E0) & 0x3E00000u) >> 16); v26 = v40; v27 = (char *)off_4EFDB0; v28 =
2680  HIDWORD(v39); do
2681  {
2682  v29 = v38;
2683  v32 = v28;
2684  do
2685  {
2686  v30 = 32
2687  * *(int *)&v27[(((unsigned __int16)(*(short *)&v27[(*(unsigned int
2688  *)LODWORD(v26) & 0x7C00u) >> 8] << 10) | *(unsigned int *)LODWORD(v26) &
2689  0x3FF) & 0x3E0u) >> 3] | (*(int *)&v27[(((*(int *)&v27[(*(unsigned int
2690  *)LODWORD(v26) & 0x7C00u) >> 8] << 10) | (*(int *)&v27[(*(unsigned int
2691  *)LODWORD(v26) & 0x7C000000u) >> 24] << 26) | *(unsigned int *)LODWORD(v26)
2692  & 0x3FF03FF) & 0x3E00000u) >> 19] << 21) | ((*(int *)&v27[(*(unsigned int
2693  *)LODWORD(v26) & 0x7C00u) >> 8] << 10) | (*(int *)&v27[(*(unsigned int
2694  *)LODWORD(v26) & 0x7C000000u) >> 24] << 26) | *(unsigned int *)LODWORD(v26)
2695  & 0x3FF03FF) & 0x7C1F7C1F; result = this_
2696  + (*(int *)&v27[4
2697  * (((unsigned __int8)(32
2698  * v27[(((unsigned __int16)(*(short *)&v27[(*(unsigned int *)LODWORD(v26) &
2699  0x7C00u) >> 8] << 10) | *(unsigned int *)LODWORD(v26) & 0x3FF) & 0x3E0u) >>
2700  3]) | *(unsigned int *)LODWORD(v26) & 0x1F) & 0x1F)] | (*(int *)&v27[(v30 &
2701  0x1F0000u) >> 14] << 16) | (32 * *(int *)&v27[(((unsigned __int16)(*(short
2702  *)&v27[(*(unsigned int *)LODWORD(v26) & 0x7C00u) >> 8] << 10) | *(unsigned
2703  int *)LODWORD(v26) & 0x3FF) & 0x3E0u) >> 3] | (*(int *)&v27[(((*(int
2704  *)&v27[(*(unsigned int *)LODWORD(v26) & 0x7C00u) >> 8] << 10) | (*(int
2705  *)&v27[(*(unsigned int *)LODWORD(v26) & 0x7C000000u) >> 24] << 26) |
2706  *(unsigned int *)LODWORD(v26) & 0x3FF03FF) & 0x3E00000u) >> 19] << 21) |
2707  ((*(int *)&v27[(*(unsigned int *)LODWORD(v26) & 0x7C00u) >> 8] << 10) |
2708  (*(int *)&v27[(*(unsigned int *)LODWORD(v26) & 0x7C000000u) >> 24] << 26) |
2709  *(unsigned int *)LODWORD(v26) & 0x3FF03FF) & 0x7C1F7C1F) & 0xFFE0FFE0);
2710  *(unsigned int *)LODWORD(v26) = result;
2711  LODWORD(v26) += 4;
2712  --v29;
2713  }
2714  while ( v29 );
2715  LODWORD(v26) += v37;
2716  v28 = v32 - 1;
2717  }
2718  while ( v32 != 1 );
2719  }
2720  }*/
2721 }
2722 
2723 void Render::SetUIClipRect(unsigned int uX, unsigned int uY, unsigned int uZ,
2724  unsigned int uW) {
2725  p2DGraphics->SetClip(Gdiplus::Rect(uX, uY, uZ - uX, uW - uY));
2726 }
2727 
2729  p2DGraphics->SetClip(
2730  Gdiplus::Rect(0, 0, window->GetWidth(), window->GetHeight()));
2731 }
2732 
2734  uint32_t c = color16;
2735  unsigned int b = (c & 31) * 8;
2736  unsigned int g = ((c >> 5) & 63) * 4;
2737  unsigned int r = ((c >> 11) & 31) * 8;
2738 
2739  return (b << 16) | (g << 8) | r;
2740 }
2741 
2743  if (image == nullptr) {
2744  return nullptr;
2745  }
2746 
2747  Gdiplus::PixelFormat format = 0;
2748  uint8_t *data = nullptr;
2749  int stride = image->GetWidth();
2750 
2751  switch (image->GetFormat()) {
2752  case IMAGE_FORMAT_R5G6B5: {
2753  format = PixelFormat16bppRGB565;
2754  data = (uint8_t *)image->GetPixels(IMAGE_FORMAT_R5G6B5);
2755  stride *= 2;
2756  break;
2757  }
2758  case IMAGE_FORMAT_A1R5G5B5: {
2759  format = PixelFormat16bppARGB1555;
2760  data = (uint8_t *)image->GetPixels(IMAGE_FORMAT_A1R5G5B5);
2761  stride *= 2;
2762  break;
2763  }
2764  case IMAGE_FORMAT_A8R8G8B8: {
2765  format = PixelFormat32bppARGB;
2766  data = (uint8_t *)image->GetPixels(IMAGE_FORMAT_A8R8G8B8);
2767  stride *= 4;
2768  break;
2769  }
2770  case IMAGE_FORMAT_R8G8B8: {
2771  format = PixelFormat32bppRGB;
2772  data = (uint8_t *)image->GetPixels(IMAGE_FORMAT_R8G8B8);
2773  stride *= 4;
2774  break;
2775  }
2776  case IMAGE_FORMAT_R8G8B8A8:
2777  default:
2778  return nullptr;
2779  }
2780 
2781  if (data == nullptr) {
2782  return nullptr;
2783  }
2784 
2785  Gdiplus::Bitmap *bitmap = new Gdiplus::Bitmap(
2786  image->GetWidth(), image->GetHeight(), stride, format, data);
2787  if (bitmap->GetLastStatus() != Gdiplus::Ok) {
2788  delete bitmap;
2789  bitmap = nullptr;
2790  }
2791 
2792  return bitmap;
2793 }
2794 
2795 void Render::DrawTextureCustomHeight(float u, float v, class Image *image,
2796  int custom_height) {
2797  Gdiplus::Bitmap *bitmap = BitmapWithImage(image);
2798  if (bitmap == nullptr) {
2799  return;
2800  }
2801 
2802  int x = 640 * u;
2803  int y = 480 * v;
2804 
2805  p2DGraphics->DrawImage(bitmap, x, y, 0, 0, image->GetWidth(), custom_height,
2806  Gdiplus::UnitPixel);
2807 
2808  delete bitmap;
2809 }
2810 
2811 void Render::DrawTextureNew(float u, float v, Image *bmp) {
2812  DrawTextureCustomHeight(u, v, bmp, bmp->GetHeight());
2813 }
2814 
2815 void Render::DrawTextureOffset(int x, int y, int offset_x, int offset_y,
2816  Image *image) {
2817  Gdiplus::Bitmap *bitmap = BitmapWithImage(image);
2818  if (bitmap == nullptr) {
2819  return;
2820  }
2821 
2822  p2DGraphics->DrawImage(bitmap, x, y, offset_x, offset_y,
2823  image->GetWidth() - offset_x,
2824  image->GetHeight() - offset_y, Gdiplus::UnitPixel);
2825 
2826  delete bitmap;
2827 }
2828 
2829 void Render::DrawImage(Image *image, const Rect &rect) {
2830  Gdiplus::Bitmap *bitmap = BitmapWithImage(image);
2831  if (bitmap == nullptr) {
2832  return;
2833  }
2834 
2835  Gdiplus::Rect r(rect.x, rect.y, rect.z - rect.x, rect.w - rect.y);
2836  p2DGraphics->DrawImage(bitmap, r);
2837 
2838  delete bitmap;
2839 }
2840 
2841 void Render::DrawTextureGrayShade(float u, float v, Image *img) {
2842  DrawMasked(u, v, img, 1, 0x7BEF);
2843 }
2844 
2845 void Render::FillRectFast(unsigned int uX, unsigned int uY, unsigned int uWidth,
2846  unsigned int uHeight, unsigned int color) {
2847  unsigned int b = (color & 0x1F) << 3;
2848  unsigned int g = ((color >> 5) & 0x3F) << 2;
2849  unsigned int r = ((color >> 11) & 0x1F) << 3;
2850 
2851  Gdiplus::Color c(r, g, b);
2852  Gdiplus::SolidBrush brush(c);
2853  p2DGraphics->FillRectangle(&brush, (INT)uX, (INT)uY, (INT)uWidth,
2854  (INT)uHeight);
2855 }
2856 
2857 void Render::DrawText(int uOutX, int uOutY, uint8_t *pFontPixels,
2858  unsigned int uCharWidth, unsigned int uCharHeight,
2859  uint8_t *pFontPalette, uint16_t uFaceColor,
2860  uint16_t uShadowColor) {
2861  Image *fonttemp = Image::Create(uCharWidth, uCharHeight, IMAGE_FORMAT_A8R8G8B8);
2862  uint32_t *fontpix = (uint32_t*)fonttemp->GetPixels(IMAGE_FORMAT_A8R8G8B8);
2863 
2864  for (uint y = 0; y < uCharHeight; ++y) {
2865  for (uint x = 0; x < uCharWidth; ++x) {
2866  if (*pFontPixels) {
2867  uint16_t color = uShadowColor;
2868  if (*pFontPixels != 1) {
2869  color = uFaceColor;
2870  }
2871  fontpix[x + y * uCharWidth] = Color32(color);
2872  }
2873  ++pFontPixels;
2874  }
2875  }
2876  render->DrawTextureAlphaNew(uOutX / 640., uOutY / 480., fonttemp);
2877  fonttemp->Release();
2878 }
2879 
2880 void Render::DrawTextAlpha(int x, int y, uint8_t *font_pixels, int uCharWidth,
2881  unsigned int uFontHeight, uint8_t *pPalette,
2882  bool present_time_transparency) {
2883  Image *fonttemp = Image::Create(uCharWidth, uFontHeight, IMAGE_FORMAT_A8R8G8B8);
2884  uint32_t *fontpix = (uint32_t *)fonttemp->GetPixels(IMAGE_FORMAT_A8R8G8B8);
2885 
2886  if (present_time_transparency) {
2887  for (unsigned int dy = 0; dy < uFontHeight; ++dy) {
2888  for (unsigned int dx = 0; dx < uCharWidth; ++dx) {
2889  uint16_t color = (*font_pixels)
2890  ? pPalette[*font_pixels]
2891  : 0x7FF; // transparent color 16bit
2892  // render->uTargetGMask |
2893  // render->uTargetBMask;
2894  fontpix[dx + dy * uCharWidth] = Color32(color);
2895  ++font_pixels;
2896  }
2897  }
2898  } else {
2899  for (unsigned int dy = 0; dy < uFontHeight; ++dy) {
2900  for (unsigned int dx = 0; dx < uCharWidth; ++dx) {
2901  if (*font_pixels) {
2902  uint8_t index = *font_pixels;
2903  uint8_t r = pPalette[index * 3 + 0];
2904  uint8_t g = pPalette[index * 3 + 1];
2905  uint8_t b = pPalette[index * 3 + 2];
2906  fontpix[dx + dy * uCharWidth] = Color32(r, g, b);
2907  }
2908  ++font_pixels;
2909  }
2910  }
2911  }
2912  render->DrawTextureAlphaNew(x / 640., y / 480., fonttemp);
2913  fonttemp->Release();
2914 }
2915 
2916 void Render::DrawTransparentGreenShade(float u, float v, Image *pTexture) {
2917  DrawMasked(u, v, pTexture, 0, 0x07E0);
2918 }
2919 
2920 void Render::DrawTransparentRedShade(float u, float v, Image *a4) {
2921  DrawMasked(u, v, a4, 0, 0xF800);
2922 }
2923 
2924 void Render::DrawMasked(float u, float v, Image *pTexture,
2925  unsigned int color_dimming_level, uint16_t mask) {
2926  if (!pTexture) {
2927  return;
2928  }
2929  uint32_t width = pTexture->GetWidth();
2931  Image *temp = Image::Create(width, pTexture->GetHeight(), IMAGE_FORMAT_A8R8G8B8);
2932  uint32_t *temppix = (uint32_t *)temp->GetPixels(IMAGE_FORMAT_A8R8G8B8);
2933 
2934  for (unsigned int dy = 0; dy < pTexture->GetHeight(); ++dy) {
2935  for (unsigned int dx = 0; dx < width; ++dx) {
2936  if (*pixels & 0xFF000000)
2937  temppix[dx + dy * width] = Color32((((*pixels >> 16) & 0xFF) >> color_dimming_level),
2938  (((*pixels >> 8) & 0xFF) >> color_dimming_level), ((*pixels & 0xFF) >> color_dimming_level))
2939  & Color32(mask);
2940  ++pixels;
2941  }
2942  }
2943  render->DrawTextureAlphaNew(u, v, temp);
2944  temp->Release();
2945 }
2946 
2947 void Render::TexturePixelRotateDraw(float u, float v, Image *img, int time) {
2948  if (img) {
2949  auto pixelpoint = (const uint32_t *)img->GetPixels(IMAGE_FORMAT_A8R8G8B8);
2950  int width = img->GetWidth();
2951  int height = img->GetHeight();
2953  uint32_t *temppix = (uint32_t *)temp->GetPixels(IMAGE_FORMAT_A8R8G8B8);
2954 
2955  int brightloc = -1;
2956  int brightval = 0;
2957  int darkloc = -1;
2958  int darkval = 765;
2959 
2960  for (int x = 0; x < width; x++) {
2961  for (int y = 0; y < height; y++) {
2962  int nudge = x + y * width;
2963  // Test the brightness against the threshold
2964  int bright = (*(pixelpoint + nudge) & 0xFF) + ((*(pixelpoint + nudge) >> 8) & 0xFF) + ((*(pixelpoint + nudge) >> 16) & 0xFF);
2965  if (bright == 0) continue;
2966 
2967  if (bright > brightval) {
2968  brightval = bright;
2969  brightloc = nudge;
2970  }
2971  if (bright < darkval) {
2972  darkval = bright;
2973  darkloc = nudge;
2974  }
2975  }
2976  }
2977 
2978  // find brightest
2979  unsigned int bmax = (*(pixelpoint + brightloc) & 0xFF);
2980  unsigned int gmax = ((*(pixelpoint + brightloc) >> 8) & 0xFF);
2981  unsigned int rmax = ((*(pixelpoint + brightloc) >> 16) & 0xFF);
2982 
2983  // find darkest not black
2984  unsigned int bmin = (*(pixelpoint + darkloc) & 0xFF);
2985  unsigned int gmin = ((*(pixelpoint + darkloc) >> 8) & 0xFF);
2986  unsigned int rmin = ((*(pixelpoint + darkloc) >> 16) & 0xFF);
2987 
2988  // steps pixels
2989  float bstep = (bmax - bmin) / 128.;
2990  float gstep = (gmax - gmin) / 128.;
2991  float rstep = (rmax - rmin) / 128.;
2992 
2993  int timestep = time % 256;
2994 
2995  // loop through
2996  for (int ydraw = 0; ydraw < height; ++ydraw) {
2997  for (int xdraw = 0; xdraw < width; ++xdraw) {
2998  if (*pixelpoint) { // check orig item not got blakc pixel
2999  unsigned int bcur = (*(pixelpoint) & 0xFF);
3000  unsigned int gcur = ((*(pixelpoint) >> 8) & 0xFF);
3001  unsigned int rcur = ((*(pixelpoint) >> 16) & 0xFF);
3002  int pixstepb = (bcur - bmin) / bstep + timestep;
3003  if (pixstepb > 255) pixstepb = pixstepb - 256;
3004  if (pixstepb >= 0 && pixstepb < 128) // 0-127
3005  bcur = bmin + pixstepb * bstep;
3006  if (pixstepb >= 128 && pixstepb < 256) { // 128-255
3007  pixstepb = pixstepb - 128;
3008  bcur = bmax - pixstepb * bstep;
3009  }
3010  int pixstepr = (rcur - rmin) / rstep + timestep;
3011  if (pixstepr > 255) pixstepr = pixstepr - 256;
3012  if (pixstepr >= 0 && pixstepr < 128) // 0-127
3013  rcur = rmin + pixstepr * rstep;
3014  if (pixstepr >= 128 && pixstepr < 256) { // 128-255
3015  pixstepr = pixstepr - 128;
3016  rcur = rmax - pixstepr * rstep;
3017  }
3018  int pixstepg = (gcur - gmin) / gstep + timestep;
3019  if (pixstepg > 255) pixstepg = pixstepg - 256;
3020  if (pixstepg >= 0 && pixstepg < 128) // 0-127
3021  gcur = gmin + pixstepg * gstep;
3022  if (pixstepg >= 128 && pixstepg < 256) { // 128-255
3023  pixstepg = pixstepg - 128;
3024  gcur = gmax - pixstepg * gstep;
3025  }
3026  // out pixel
3027  temppix[xdraw + ydraw * width] = Color32(rcur, gcur, bcur);
3028  }
3029  pixelpoint++;
3030  }
3031  }
3032  // draw image
3033  render->DrawTextureAlphaNew(u, v, temp);
3034  temp->Release();
3035  }
3036 }
3037 
3039  int x, int y, Image *imgin, Image *imgblend, int time, int start_opacity,
3040  int end_opacity) { // thrown together as a crude estimate of the enchaintg
3041  // effects
3042 
3043  // leaves gap where it shouldnt on dark pixels currently
3044  // doesnt use opacity params
3045 
3046  const uint32_t *pixelpoint;
3047  const uint32_t *pixelpointblend;
3048 
3049  if (imgin && imgblend) { // 2 images to blend
3050  pixelpoint = (const uint32_t *)imgin->GetPixels(IMAGE_FORMAT_A8R8G8B8);
3051  pixelpointblend =
3052  (const uint32_t *)imgblend->GetPixels(IMAGE_FORMAT_A8R8G8B8);
3053 
3054  int Width = imgin->GetWidth();
3055  int Height = imgin->GetHeight();
3056  Image *temp = Image::Create(Width, Height, IMAGE_FORMAT_A8R8G8B8);
3057  uint32_t *temppix = (uint32_t *)temp->GetPixels(IMAGE_FORMAT_A8R8G8B8);
3058 
3059  uint32_t c = *(pixelpointblend + 2700); // guess at brightest pixel
3060  unsigned int bmax = (c & 0xFF);
3061  unsigned int gmax = ((c >> 8) & 0xFF);
3062  unsigned int rmax = ((c >> 16) & 0xFF);
3063 
3064  unsigned int bmin = bmax / 10;
3065  unsigned int gmin = gmax / 10;
3066  unsigned int rmin = rmax / 10;
3067 
3068  unsigned int bstep = (bmax - bmin) / 128;
3069  unsigned int gstep = (gmax - gmin) / 128;
3070  unsigned int rstep = (rmax - rmin) / 128;
3071 
3072  for (int ydraw = 0; ydraw < Height; ++ydraw) {
3073  for (int xdraw = 0; xdraw < Width; ++xdraw) {
3074  // should go blue -> black -> blue reverse
3075  // patchy -> solid -> patchy
3076 
3077  if (*pixelpoint) { // check orig item not got blakc pixel
3078  uint32_t nudge =
3079  (xdraw % imgblend->GetWidth()) +
3080  (ydraw % imgblend->GetHeight()) * imgblend->GetWidth();
3081  uint32_t pixcol = *(pixelpointblend + nudge);
3082 
3083  unsigned int bcur = (pixcol & 0xFF);
3084  unsigned int gcur = ((pixcol >> 8) & 0xFF);
3085  unsigned int rcur = ((pixcol >> 16) & 0xFF);
3086 
3087  int steps = (time) % 128;
3088 
3089  if ((time) % 256 >= 128) { // step down
3090  bcur += bstep * (128 - steps);
3091  gcur += gstep * (128 - steps);
3092  rcur += rstep * (128 - steps);
3093  } else { // step up
3094  bcur += bstep * steps;
3095  gcur += gstep * steps;
3096  rcur += rstep * steps;
3097  }
3098 
3099  if (bcur > bmax) bcur = bmax; // limit check
3100  if (gcur > gmax) gcur = gmax;
3101  if (rcur > rmax) rcur = rmax;
3102  if (bcur < bmin) bcur = bmin;
3103  if (gcur < gmin) gcur = gmin;
3104  if (rcur < rmin) rcur = rmin;
3105 
3106  temppix[xdraw + ydraw * Width] = Color32(rcur, gcur, bcur);
3107  }
3108 
3109  pixelpoint++;
3110  }
3111 
3112  pixelpoint += imgin->GetWidth() - Width;
3113  }
3114  // draw image
3115  render->DrawTextureAlphaNew(x/640., y/480., temp);
3116  temp->Release();
3117  }
3118 }
3119 
3120 void Render::DrawMonsterPortrait(Rect rc, SpriteFrame *Portrait, int Y_Offset) {
3121  int dst_x = rc.x + 64 + Portrait->hw_sprites[0]->uAreaX - Portrait->hw_sprites[0]->uBufferWidth / 2;
3122  int dst_y = rc.y + Y_Offset + Portrait->hw_sprites[0]->uAreaY;
3123  uint dst_z = dst_x + Portrait->hw_sprites[0]->uAreaWidth;
3124  uint dst_w = dst_y + Portrait->hw_sprites[0]->uAreaHeight;
3125 
3126  uint Clipped_X = 0;
3127  uint Clipped_Y = 0;
3128 
3129  if (dst_x < rc.x) {
3130  Clipped_X = rc.x - dst_x;
3131  dst_x = rc.x;
3132  }
3133 
3134  if (dst_y < rc.y) {
3135  Clipped_Y = rc.y - dst_y;
3136  dst_y = rc.y;
3137  }
3138 
3139  if (dst_z > rc.z)
3140  dst_z = rc.z;
3141  if (dst_w > rc.w)
3142  dst_w = rc.w;
3143 
3144  Image *temp = Image::Create(128, 128, IMAGE_FORMAT_R5G6B5);
3145  uint16_t *temppix = (uint16_t *)temp->GetPixels(IMAGE_FORMAT_R5G6B5);
3146 
3147  int width = Portrait->hw_sprites[0]->texture->GetWidth();
3148  int height = Portrait->hw_sprites[0]->texture->GetHeight();
3149 
3150  ushort* src = (unsigned __int16 *)Portrait->hw_sprites[0]->texture->GetPixels(IMAGE_FORMAT_A1R5G5B5);
3151  int num_top_scanlines_above_frame_y = Clipped_Y - dst_y;
3152 
3153  for (uint y = dst_y; y < dst_w; ++y) {
3154  uint src_y = num_top_scanlines_above_frame_y + y;
3155 
3156  for (uint x = dst_x; x < dst_z; ++x) {
3157  uint src_x = Clipped_X - dst_x + x; // num scanlines left to frame_x + current x
3158 
3159  uint idx =
3160  height * src_y / Portrait->hw_sprites[0]->uAreaHeight * width +
3161  width * src_x / Portrait->hw_sprites[0]->uAreaWidth;
3162 
3163  uint a = 2 * (src[idx] & 0xFFE0);
3164  uint b = src[idx] & 0x1F;
3165 
3166  temppix[(x-dst_x) + 128*(y-dst_y)] = (b | a);
3167  }
3168  }
3169 
3170  render->SetUIClipRect(rc.x, rc.y, rc.z, rc.w);
3171  render->DrawTextureAlphaNew(dst_x / 640., dst_y / 480., temp);
3172  temp->Release();
3173  render->ResetUIClipRect();
3174 }
3175 
3176 void Render::DrawTextureAlphaNew(float u, float v, Image *image) {
3177  Gdiplus::Bitmap *bitmap = BitmapWithImage(image);
3178  if (!bitmap) {
3179  return;
3180  }
3181 
3182  int uX = u * 640.0f;
3183  int uY = v * 480.0f;
3184  p2DGraphics->DrawImage(bitmap, uX, uY);
3185 
3186  delete bitmap;
3187 }
3188 
3189 void Render::ZDrawTextureAlpha(float u, float v, Image *img, int zVal) {
3190  if (!img) return;
3191 
3192  int uOutX = u * this->window->GetWidth();
3193  int uOutY = v * this->window->GetHeight();
3194  unsigned int imgheight = img->GetHeight();
3195  unsigned int imgwidth = img->GetWidth();
3196  auto pixels = (uint32_t *)img->GetPixels(IMAGE_FORMAT_A8R8G8B8);
3197 
3198  for (int xs = 0; xs < imgwidth; xs++) {
3199  for (int ys = 0; ys < imgheight; ys++) {
3200  if (pixels[xs + imgwidth * ys] & 0xFF000000) {
3201  this->pActiveZBuffer[uOutX + xs + window->GetWidth() * (uOutY + ys)] = zVal;
3202  }
3203  }
3204  }
3205 }
3206 
3207 void Render::ZBuffer_Fill_2(signed int a2, signed int a3, Image *pTexture,
3208  int a5) {}
3209 
3211  ErrD3D(pRenderD3D->pDevice->SetTextureStageState(0, D3DTSS_ADDRESS, D3DTADDRESS_CLAMP));
3212  ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ALPHABLENDENABLE, TRUE));
3213  ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ZWRITEENABLE, FALSE));
3214  ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_CULLMODE, D3DCULL_NONE));
3215 
3216  for (int i = uNumBillboardsToDraw - 1; i >= 0; --i) {
3219  }
3220 
3222  pRenderD3D->pDevice->SetTexture(
3224  ->GetDirect3DTexture());
3225  } else {
3226  // auto hwsplat04 = assets->GetBitmap("hwsplat04");
3227  // ErrD3D(pRenderD3D->pDevice->SetTexture(0, ((TextureD3D *)hwsplat04)->GetDirect3DTexture()));
3228  // testing
3229  ErrD3D(pRenderD3D->pDevice->SetTexture(0, 0));
3230  }
3231 
3232  ErrD3D(pRenderD3D->pDevice->DrawPrimitive(
3233  D3DPT_TRIANGLEFAN,
3234  D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR | D3DFVF_TEX1,
3237  D3DDP_DONOTLIGHT | D3DDP_DONOTUPDATEEXTENTS));
3238  }
3239 
3240  if (config->is_using_fog) {
3241  ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_FOGENABLE, TRUE));
3242  ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_FOGCOLOR, GetLevelFogColor() & 0xFFFFFF));
3243  ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_FOGTABLEMODE, 0));
3244  }
3245  ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_CULLMODE, D3DCULL_CW));
3246  ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ZWRITEENABLE, TRUE));
3247  ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ALPHABLENDENABLE, FALSE));
3248  ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_SRCBLEND, D3DBLEND_ONE));
3249  ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_DESTBLEND, D3DBLEND_ZERO));
3250  ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_DITHERENABLE, TRUE));
3251 }
3252 
3254  switch (a1) {
3256  if (config->is_using_fog) {
3257  SetUsingFog(false);
3258  ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_FOGENABLE, TRUE));
3259  ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_FOGCOLOR, GetLevelFogColor() & 0xFFFFFF));
3260  ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_FOGTABLEMODE, 0));
3261  }
3262 
3263  ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_SRCBLEND, D3DBLEND_SRCALPHA));
3264  ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_DESTBLEND, D3DBLEND_INVSRCALPHA));
3265  ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_DITHERENABLE, TRUE));
3266 
3267  break;
3268  }
3269 
3273  if (config->is_using_specular) {
3274  if (!config->is_using_fog) {
3275  SetUsingFog(true);
3276  ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_FOGENABLE, FALSE));
3277  }
3278  }
3279 
3280  ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_SRCBLEND, D3DBLEND_ONE));
3281  ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_DESTBLEND, D3DBLEND_ONE));
3282  ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_DITHERENABLE, FALSE));
3283 
3284  break;
3285  }
3286 
3287  default: {
3288  log->Warning(
3289  L"SetBillboardBlendOptions: invalid opacity type (%u)", a1);
3290  assert(false); // fireball and impolision can crash here - maybe clipping related
3291  break;
3292  }
3293  }
3294 }
3295 
3296 int ODM_NearClip(unsigned int num_vertices) {
3297  float nearclip = pIndoorCameraD3D->GetNearClip();
3298  bool current_vertices_flag; // edi@1
3299  bool next_vertices_flag; // [sp+Ch] [bp-24h]@6
3300  double t; // st6@10
3301  bool bFound = false;
3302 
3303  if (!num_vertices) return 0;
3304  for (uint i = 0; i < num_vertices; ++i) { // есть ли пограничные вершины
3305  if (VertexRenderList[i].vWorldViewPosition.x > nearclip) {
3306  bFound = true;
3307  break;
3308  }
3309  }
3310  if (!bFound) return 0;
3311 
3312  memcpy(&VertexRenderList[num_vertices], &VertexRenderList[0],
3313  sizeof(VertexRenderList[0]));
3314  next_vertices_flag = false;
3315  current_vertices_flag = false;
3316  if (VertexRenderList[0].vWorldViewPosition.x <= nearclip)
3317  current_vertices_flag = true;
3318  // check for near clip plane(проверка по ближней границе)
3319  //
3320  // v3.__________________. v0
3321  // | |
3322  // | |
3323  // | |
3324  // ----------------------- 8.0(near_clip - 8.0)
3325  // | |
3326  // .__________________.
3327  // v2 v1
3328 
3329  int out_num_vertices = 0;
3330  for (uint i = 0; i < num_vertices; ++i) {
3331  next_vertices_flag =
3332  VertexRenderList[i + 1].vWorldViewPosition.x <= nearclip; //
3333  if (current_vertices_flag ^ next_vertices_flag) {
3334  if (next_vertices_flag) { // следующая вершина за ближней границей
3335  // t = near_clip - v0.x / v1.x - v0.x (формула получения
3336  // точки пересечения отрезка с плоскостью)
3337  t = (nearclip - VertexRenderList[i].vWorldViewPosition.x) /
3338  (VertexRenderList[i + 1].vWorldViewPosition.x -
3340  array_507D30[out_num_vertices].vWorldViewPosition.x = nearclip;
3341  array_507D30[out_num_vertices].vWorldViewPosition.y =
3345  t;
3346  array_507D30[out_num_vertices].vWorldViewPosition.z =
3350  t;
3351  array_507D30[out_num_vertices].u =
3352  VertexRenderList[i].u +
3353  (VertexRenderList[i + 1].u - VertexRenderList[i].u) * t;
3354  array_507D30[out_num_vertices].v =
3355  VertexRenderList[i].v +
3356  (VertexRenderList[i + 1].v - VertexRenderList[i].v) * t;
3357  array_507D30[out_num_vertices]._rhw = 1.0 / nearclip;
3358  } else { // текущая вершина за ближней границей
3359  t = (nearclip - VertexRenderList[i].vWorldViewPosition.x) /
3360  (VertexRenderList[i].vWorldViewPosition.x -
3362  array_507D30[out_num_vertices].vWorldViewPosition.x = nearclip;
3363  array_507D30[out_num_vertices].vWorldViewPosition.y =
3367  t;
3368  array_507D30[out_num_vertices].vWorldViewPosition.z =
3372  t;
3373  array_507D30[out_num_vertices].u =
3374  VertexRenderList[i].u +
3375  (VertexRenderList[i].u - VertexRenderList[i + 1].u) * t;
3376  array_507D30[out_num_vertices].v =
3377  VertexRenderList[i].v +
3378  (VertexRenderList[i].v - VertexRenderList[i + 1].v) * t;
3379  array_507D30[out_num_vertices]._rhw = 1.0 / nearclip;
3380  }
3381  // array_507D30[out_num_vertices]._rhw = 0x3E000000u;
3382  ++out_num_vertices;
3383  }
3384  if (!next_vertices_flag) {
3385  memcpy(&array_507D30[out_num_vertices], &VertexRenderList[i + 1],
3386  sizeof(VertexRenderList[i + 1]));
3387  out_num_vertices++;
3388  }
3389  current_vertices_flag = next_vertices_flag;
3390  }
3391  return out_num_vertices >= 3 ? out_num_vertices : 0;
3392 }
3393 
3394 int ODM_FarClip(unsigned int uNumVertices) {
3395  bool current_vertices_flag; // [sp+Ch] [bp-28h]@6
3396  bool next_vertices_flag; // edi@1
3397  double t; // st6@10
3398  signed int depth_num_vertices; // [sp+18h] [bp-1Ch]@1
3399  bool bFound;
3400  //Доп инфо "Программирование трёхмерных игр для windows" Ламот стр 910
3401 
3402  bFound = false;
3403 
3405  sizeof(VertexRenderList[uNumVertices]));
3406  depth_num_vertices = 0;
3407  current_vertices_flag = false;
3408  if (VertexRenderList[0].vWorldViewPosition.x >=
3410  current_vertices_flag =
3411  true; //настоящая вершина больше границы видимости
3412  if ((signed int)uNumVertices <= 0) return 0;
3413  for (uint i = 0; i < uNumVertices; ++i) { // есть ли пограничные вершины
3414  if (VertexRenderList[i].vWorldViewPosition.x <
3416  bFound = true;
3417  break;
3418  }
3419  }
3420  if (!bFound) return 0;
3421  // check for far clip plane(проверка по дальней границе)
3422  //
3423  // v3.__________________. v0
3424  // | |
3425  // | |
3426  // | |
3427  // ----------------------- 8192.0(far_clip - 0x2000)
3428  // | |
3429  // .__________________.
3430  // v2 v1
3431 
3432  for (uint i = 0; i < uNumVertices; ++i) {
3433  next_vertices_flag = VertexRenderList[i + 1].vWorldViewPosition.x >=
3435  if (current_vertices_flag ^
3436  next_vertices_flag) { // одна из граней за границей видимости
3437  if (next_vertices_flag) { // следующая вершина больше границы
3438  // видимости(настоящая вершина меньше
3439  // границы видимости) - v3
3440  // t = far_clip - v2.x / v3.x - v2.x (формула получения точки
3441  // пересечения отрезка с плоскостью)
3442  t = (pIndoorCameraD3D->GetFarClip() -
3444  (VertexRenderList[i].vWorldViewPosition.x -
3446  array_507D30[depth_num_vertices].vWorldViewPosition.x =
3448  // New_y = v2.y + (v3.y - v2.y)*t
3449  array_507D30[depth_num_vertices].vWorldViewPosition.y =
3453  t;
3454  // New_z = v2.z + (v3.z - v2.z)*t
3455  array_507D30[depth_num_vertices].vWorldViewPosition.z =
3459  t;
3460  array_507D30[depth_num_vertices].u =
3461  VertexRenderList[i].u +
3462  (VertexRenderList[i].u - VertexRenderList[i + 1].u) * t;
3463  array_507D30[depth_num_vertices].v =
3464  VertexRenderList[i].v +
3465  (VertexRenderList[i].v - VertexRenderList[i + 1].v) * t;
3466  array_507D30[depth_num_vertices]._rhw =
3467  1.0 / pIndoorCameraD3D->GetFarClip();
3468  } else { // настоящая вершина больше границы видимости(следующая
3469  // вершина меньше границы видимости) - v0
3470  // t = far_clip - v1.x / v0.x - v1.x
3471  t = (pIndoorCameraD3D->GetFarClip() -
3473  (VertexRenderList[i + 1].vWorldViewPosition.x -
3475  array_507D30[depth_num_vertices].vWorldViewPosition.x =
3477  // New_y = (v0.y - v1.y)*t + v1.y
3478  array_507D30[depth_num_vertices].vWorldViewPosition.y =
3482  t;
3483  // New_z = (v0.z - v1.z)*t + v1.z
3484  array_507D30[depth_num_vertices].vWorldViewPosition.z =
3488  t;
3489  array_507D30[depth_num_vertices].u =
3490  VertexRenderList[i].u +
3491  (VertexRenderList[i + 1].u - VertexRenderList[i].u) * t;
3492  array_507D30[depth_num_vertices].v =
3493  VertexRenderList[i].v +
3494  (VertexRenderList[i + 1].v - VertexRenderList[i].v) * t;
3495  array_507D30[depth_num_vertices]._rhw =
3496  1.0 / pIndoorCameraD3D->GetFarClip();
3497  }
3498  ++depth_num_vertices;
3499  }
3500  if (!next_vertices_flag) { //оба в границе видимости
3501  memcpy(&array_507D30[depth_num_vertices], &VertexRenderList[i + 1],
3502  sizeof(array_507D30[depth_num_vertices]));
3503  depth_num_vertices++;
3504  }
3505  current_vertices_flag = next_vertices_flag;
3506  }
3507  return depth_num_vertices >= 3 ? depth_num_vertices : 0;
3508 }
3509 
3511  // int v27; // eax@57
3512  int farclip; // [sp+2Ch] [bp-2Ch]@10
3513  int nearclip; // [sp+30h] [bp-28h]@34
3514  int v51; // [sp+34h] [bp-24h]@35
3515  int v52; // [sp+38h] [bp-20h]@36
3516  int v53; // [sp+3Ch] [bp-1Ch]@8
3517 
3518  for (BSPModel &model : pOutdoor->pBModels) {
3519  int reachable;
3520  if (!IsBModelVisible(&model, &reachable)) {
3521  continue;
3522  }
3523  model.field_40 |= 1;
3524  if (model.pFaces.empty()) {
3525  continue;
3526  }
3527 
3528  for (ODMFace &face : model.pFaces) {
3529  if (face.Invisible()) {
3530  continue;
3531  }
3532 
3533  v53 = 0;
3535 
3536  poly->flags = 0;
3537  poly->field_32 = 0;
3538  poly->texture = face.GetTexture();
3539 
3540  if (face.uAttributes & FACE_FLUID) poly->flags |= 2;
3541  if (face.uAttributes & FACE_INDOOR_SKY) poly->flags |= 0x400;
3542 
3543  if (face.uAttributes & FACE_FLOW_DIAGONAL)
3544  poly->flags |= 0x400;
3545  else if (face.uAttributes & FACE_FLOW_VERTICAL)
3546  poly->flags |= 0x800;
3547 
3548  if (face.uAttributes & FACE_FLOW_HORIZONTAL)
3549  poly->flags |= 0x2000;
3550  else if (face.uAttributes & FACE_DONT_CACHE_TEXTURE)
3551  poly->flags |= 0x1000;
3552 
3553  poly->sTextureDeltaU = face.sTextureDeltaU;
3554  poly->sTextureDeltaV = face.sTextureDeltaV;
3555 
3556  unsigned int flow_anim_timer = OS_GetTime() >> 4;
3557  unsigned int flow_u_mod = poly->texture->GetWidth() - 1;
3558  unsigned int flow_v_mod = poly->texture->GetHeight() - 1;
3559 
3560  if (face.pFacePlane.vNormal.z &&
3561  abs(face.pFacePlane.vNormal.z) >= 59082) {
3562  if (poly->flags & 0x400)
3563  poly->sTextureDeltaV += flow_anim_timer & flow_v_mod;
3564  if (poly->flags & 0x800)
3565  poly->sTextureDeltaV -= flow_anim_timer & flow_v_mod;
3566  } else {
3567  if (poly->flags & 0x400)
3568  poly->sTextureDeltaV -= flow_anim_timer & flow_v_mod;
3569  if (poly->flags & 0x800)
3570  poly->sTextureDeltaV += flow_anim_timer & flow_v_mod;
3571  }
3572 
3573  if (poly->flags & 0x1000)
3574  poly->sTextureDeltaU -= flow_anim_timer & flow_u_mod;
3575  else if (poly->flags & 0x2000)
3576  poly->sTextureDeltaU += flow_anim_timer & flow_u_mod;
3577 
3578  nearclip = 0;
3579  farclip = 0;
3580 
3581  for (uint vertex_id = 1; vertex_id <= face.uNumVertices;
3582  vertex_id++) {
3583  array_73D150[vertex_id - 1].vWorldPosition.x =
3584  model.pVertices.pVertices[face.pVertexIDs[vertex_id - 1]].x;
3585  array_73D150[vertex_id - 1].vWorldPosition.y =
3586  model.pVertices.pVertices[face.pVertexIDs[vertex_id - 1]].y;
3587  array_73D150[vertex_id - 1].vWorldPosition.z =
3588  model.pVertices.pVertices[face.pVertexIDs[vertex_id - 1]].z;
3589  array_73D150[vertex_id - 1].u =
3590  (poly->sTextureDeltaU +
3591  (__int16)face.pTextureUIDs[vertex_id - 1]) *
3592  (1.0 / (double)poly->texture->GetWidth());
3593  array_73D150[vertex_id - 1].v =
3594  (poly->sTextureDeltaV +
3595  (__int16)face.pTextureVIDs[vertex_id - 1]) *
3596  (1.0 / (double)poly->texture->GetHeight());
3597  }
3598  for (uint i = 1; i <= face.uNumVertices; i++) {
3599  if (model.pVertices.pVertices[face.pVertexIDs[0]].z ==
3600  array_73D150[i - 1].vWorldPosition.z)
3601  ++v53;
3603  if (array_73D150[i - 1].vWorldViewPosition.x <
3607  if (array_73D150[i - 1].vWorldViewPosition.x >=
3609  farclip = 1;
3610  else
3611  nearclip = 1;
3612  } else {
3613  pIndoorCameraD3D->Project(&array_73D150[i - 1], 1, 0);
3614  }
3615  }
3616 
3617  if (v53 == face.uNumVertices) poly->field_32 |= 1;
3618  poly->pODMFace = &face;
3619  poly->uNumVertices = face.uNumVertices;
3620  poly->field_59 = 5;
3621  v51 =
3622  fixpoint_mul(-pOutdoor->vSunlight.x, face.pFacePlane.vNormal.x);
3623  v53 =
3624  fixpoint_mul(-pOutdoor->vSunlight.y, face.pFacePlane.vNormal.y);
3625  v52 =
3626  fixpoint_mul(-pOutdoor->vSunlight.z, face.pFacePlane.vNormal.z);
3627  poly->dimming_level = 20 - fixpoint_mul(20, v51 + v53 + v52);
3628  if (poly->dimming_level < 0) poly->dimming_level = 0;
3629  if (poly->dimming_level > 31) poly->dimming_level = 31;
3630  if (pODMRenderParams->uNumPolygons >= 1999 + 5000) return;
3632  face.bVisible = 1;
3633  poly->uBModelFaceID = face.index;
3634  poly->uBModelID = model.index;
3635  poly->pid =
3636  PID(OBJECT_BModel, (face.index | (model.index << 6)));
3637  for (int vertex_id = 0; vertex_id < face.uNumVertices;
3638  ++vertex_id) {
3639  memcpy(&VertexRenderList[vertex_id],
3640  &array_73D150[vertex_id],
3641  sizeof(VertexRenderList[vertex_id]));
3642  VertexRenderList[vertex_id]._rhw =
3643  1.0 / (array_73D150[vertex_id].vWorldViewPosition.x +
3644  0.0000001);
3645  }
3646  static stru154 static_RenderBuildingsD3D_stru_73C834;
3647 
3651  int v31 = 0;
3653  v31 = nearclip ? 3 : farclip != 0 ? 5 : 0;
3654 
3655  // if (face.uAttributes & FACE_OUTLINED) __debugbreak();
3656 
3657  static_RenderBuildingsD3D_stru_73C834.GetFacePlaneAndClassify(&face, &model.pVertices);
3658  if (decal_builder->uNumDecals > 0) {
3660  31 - poly->dimming_level, 2,
3661  &static_RenderBuildingsD3D_stru_73C834,
3662  face.uNumVertices, VertexRenderList, 0, (char)v31,
3663  -1);
3664  }
3665  }
3666  if (Lights.uNumLightsApplied > 0)
3667  // if (face.uAttributes & FACE_OUTLINED)
3669  &Lights, &static_RenderBuildingsD3D_stru_73C834,
3670  poly->uNumVertices, VertexRenderList, 0, (char)v31);
3671 
3672  if (nearclip) {
3673  poly->uNumVertices = ODM_NearClip(face.uNumVertices);
3674  ODM_Project(poly->uNumVertices);
3675  }
3676  if (farclip) {
3677  poly->uNumVertices = ODM_FarClip(face.uNumVertices);
3678  ODM_Project(poly->uNumVertices);
3679  }
3680 
3681  if (poly->uNumVertices) {
3682  if (poly->IsWater()) {
3683  if (poly->IsWaterAnimDisabled())
3684  poly->texture = render->hd_water_tile_anim[0];
3685  else
3686  poly->texture =
3687  render->hd_water_tile_anim
3688  [render->hd_water_current_frame];
3689  }
3690 
3691  render->DrawPolygon(poly);
3692  }
3693  }
3694  }
3695  }
3696 }
3697 
3698 unsigned short *Render::MakeScreenshot(int width, int height) {
3699  uint16_t *for_pixels; // ebx@1
3700  DDSURFACEDESC2 Dst; // [sp+4h] [bp-A0h]@6
3701 
3702  float interval_x = game_viewport_width / (double)width;
3703  float interval_y = game_viewport_height / (double)height;
3704 
3705  uint16_t *pPixels = (uint16_t *)malloc(sizeof(uint16_t) * height * width);
3706  memset(pPixels, 0, sizeof(uint16_t) * height * width);
3707 
3708  for_pixels = pPixels;
3709 
3710  BeginSceneD3D();
3711 
3713  pIndoor->Draw();
3714  } else if (uCurrentlyLoadedLevelType == LEVEL_Outdoor) {
3715  pOutdoor->Draw();
3716  }
3718  memset(&Dst, 0, sizeof(Dst));
3719  Dst.dwSize = sizeof(Dst);
3720 
3721  if (LockSurface_DDraw4(pBackBuffer4, &Dst, DDLOCK_WAIT)) {
3723  memset(&for_pixels, 0, sizeof(for_pixels));
3724  } else {
3725  for (uint y = 0; y < (unsigned int)height; ++y) {
3726  for (uint x = 0; x < (unsigned int)width; ++x) {
3727  if (Dst.ddpfPixelFormat.dwRGBBitCount == 32) {
3728  unsigned __int32 *p =
3729  (unsigned __int32 *)Dst.lpSurface +
3730  (int)(x * interval_x + 8.0) +
3731  (int)(y * interval_y + 8.0) * (Dst.lPitch >> 2);
3732  *for_pixels = Color16((*p >> 16) & 255, (*p >> 8) & 255,
3733  *p & 255);
3734  } else if (Dst.ddpfPixelFormat.dwRGBBitCount == 16) {
3735  uint16_t *p =
3736  (uint16_t*)Dst.lpSurface +
3737  (int)(x * interval_x + 8.0) + y * Dst.lPitch;
3738  *for_pixels = *p;
3739  } else {
3740  assert(false);
3741  }
3742  ++for_pixels;
3743  }
3744  }
3745  }
3746  ErrD3D(pBackBuffer4->Unlock(NULL));
3747  }
3748  return pPixels;
3749 }
3750 
3751 Image *Render::TakeScreenshot(unsigned int width, unsigned int height) {
3752  auto pixels = MakeScreenshot(width, height);
3754  return image;
3755 }
3756 
3757 void Render::SaveScreenshot(const String &filename, unsigned int width,
3758  unsigned int height) {
3759  auto pixels = MakeScreenshot(width, height);
3760  SavePCXImage16(filename, pixels, width, height);
3761  free(pixels);
3762 }
3763 
3764 void Render::PackScreenshot(unsigned int width, unsigned int height, void *data,
3765  unsigned int data_size,
3766  unsigned int *out_screenshot_size) {
3767  auto pixels = MakeScreenshot(150, 112);
3768  PCX::Encode16(pixels, width, height, data, data_size, out_screenshot_size);
3769  free(pixels);
3770 }
3771 
3773  unsigned int
3774  v3; // eax@2 применяется в закле Жар печи для подсчёта кол-ва монстров
3775  // видимых группе и заполнения массива id видимых монстров
3776  unsigned int v5; // eax@2
3777  unsigned int v6; // eax@4
3778  unsigned int v12; // [sp+10h] [bp-14h]@1
3779  int mon_num; // [sp+1Ch] [bp-8h]@1
3780  unsigned int a1a; // [sp+20h] [bp-4h]@1
3781 
3782  mon_num = 0;
3783  v12 = GetBillboardDrawListSize();
3784  if ((signed int)GetBillboardDrawListSize() > 0) {
3785  for (a1a = 0; (signed int)a1a < (signed int)v12; ++a1a) {
3786  v3 = GetParentBillboardID(a1a);
3787  v5 = (unsigned __int16)pBillboardRenderList[v3].object_pid;
3788  if (PID_TYPE(v5) == OBJECT_Actor) {
3789  if (pBillboardRenderList[v3].screen_space_z <= pDepth) {
3790  v6 = PID_ID(v5);
3791  if (pActors[v6].uAIState != Dead &&
3792  pActors[v6].uAIState != Dying &&
3793  pActors[v6].uAIState != Removed &&
3794  pActors[v6].uAIState != Disabled &&
3795  pActors[v6].uAIState != Summoned) {
3797  (double)pDepth, a1a)) {
3798  if (mon_num < 100) {
3799  _50BF30_actors_in_viewport_ids[mon_num] = v6;
3800  mon_num++;
3801  }
3802  }
3803  }
3804  }
3805  }
3806  }
3807  }
3808  return mon_num;
3809 }
3810 
3812  ErrD3D(pRenderD3D->pDevice->SetTextureStageState(0, D3DTSS_ADDRESS, D3DTADDRESS_CLAMP));
3813 
3814  if (config->is_using_specular)
3815  pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_FOGENABLE, FALSE);
3816 
3817  ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ALPHABLENDENABLE, TRUE));
3818  ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_DITHERENABLE, FALSE));
3819 
3820  // ErrD3D(pRenderD3D->pDevice->SetTexture(0,
3821  // pIndoorCameraD3D->LoadTextureAndGetHardwarePtr("effpar03")));
3822  auto effpar03 = assets->GetBitmap("effpar03");
3823  ErrD3D(pRenderD3D->pDevice->SetTexture(
3824  0, ((TextureD3D *)effpar03)->GetDirect3DTexture()));
3825 
3826  ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_SRCBLEND,
3827  D3DBLEND_ONE));
3828  ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_DESTBLEND,
3829  D3DBLEND_ONE));
3830 }
3831 
3833  ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_SRCBLEND, D3DBLEND_ONE));
3834  ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_DESTBLEND, D3DBLEND_ZERO));
3835  ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ALPHABLENDENABLE, FALSE));
3836  ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_DITHERENABLE, TRUE));
3837 
3838  if (config->is_using_specular) {
3839  ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_FOGENABLE, TRUE));
3840  ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_FOGCOLOR, uFogColor));
3841  ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_FOGTABLEMODE, 0));
3842  }
3843 }
3844 
3846  if (config->is_using_specular)
3847  ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_FOGENABLE, FALSE));
3848 
3849  ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_CULLMODE, D3DCULL_NONE));
3850  ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ZWRITEENABLE, FALSE));
3851  ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ALPHABLENDENABLE, TRUE));
3852  ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_DITHERENABLE, FALSE));
3853 
3854  // ErrD3D(pRenderD3D->pDevice->SetTexture(0,
3855  // pIndoorCameraD3D->LoadTextureAndGetHardwarePtr("effpar03")));
3856  auto effpar03 = assets->GetBitmap("effpar03");
3857  ErrD3D(pRenderD3D->pDevice->SetTexture(
3858  0, ((TextureD3D *)effpar03)->GetDirect3DTexture()));
3859 
3860  ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_SRCBLEND, D3DBLEND_ONE));
3861  ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_DESTBLEND, D3DBLEND_ONE));
3862 }
3863 
3865  ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_SRCBLEND, D3DBLEND_ONE));
3866  ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_DESTBLEND, D3DBLEND_ZERO));
3867  ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ALPHABLENDENABLE, FALSE));
3868  ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_DITHERENABLE, TRUE));
3869  ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ZWRITEENABLE, TRUE));
3870  ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_CULLMODE, D3DCULL_CW));
3871 
3872  if (config->is_using_specular)
3873  ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_FOGENABLE, TRUE));
3874 }
3875 
3877  signed int sDiffuseBegin,
3878  const RenderVertexD3D3 *pLineEnd,
3879  signed int sDiffuseEnd, float z_stuff) {
3880  RenderVertexD3D3 vertices[2]; // [sp+8h] [bp-40h]@2
3881 
3882  memcpy(&vertices[0], pLineBegin, sizeof(vertices[0]));
3883  memcpy(&vertices[1], pLineEnd, sizeof(vertices[1]));
3884 
3885  vertices[0].pos.z = 0.001 - z_stuff;
3886  vertices[1].pos.z = 0.001 - z_stuff;
3887 
3888  vertices[0].diffuse = sDiffuseBegin;
3889  vertices[1].diffuse = sDiffuseEnd;
3890 
3891  ErrD3D(pRenderD3D->pDevice->SetTexture(0, nullptr));
3892  ErrD3D(pRenderD3D->pDevice->DrawPrimitive(D3DPT_LINELIST, 452, vertices, 2,
3893  D3DDP_DONOTLIGHT));
3894 }
3895 
3897  unsigned int num_vertices) {
3898  ErrD3D(pRenderD3D->pDevice->SetTexture(0, nullptr));
3899  ErrD3D(pRenderD3D->pDevice->DrawPrimitive(
3900  D3DPT_LINELIST,
3901  D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR | D3DFVF_TEX1,
3902  (void *)vertices, num_vertices, D3DDP_DONOTLIGHT));
3903 }
3904 
3906  unsigned int num_vertices) {
3907  // ErrD3D(render->pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ZWRITEENABLE,
3908  // false));
3909  // ErrD3D(render->pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ZENABLE,
3910  // false));
3911  ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ALPHABLENDENABLE,
3912  TRUE));
3913  ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_SRCBLEND,
3914  D3DBLEND_SRCALPHA));
3915  ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_DESTBLEND,
3916  D3DBLEND_INVSRCALPHA));
3917 
3918  ErrD3D(pRenderD3D->pDevice->SetTexture(0, nullptr));
3919  ErrD3D(pRenderD3D->pDevice->DrawPrimitive(
3920  D3DPT_TRIANGLEFAN,
3921  D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR | D3DFVF_TEX1,
3922  (void *)vertices, num_vertices, 28));
3923 
3924  ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_SRCBLEND,
3925  D3DBLEND_ONE));
3926  ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_DESTBLEND,
3927  D3DBLEND_ZERO));
3928  ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ALPHABLENDENABLE,
3929  FALSE));
3930  // ErrD3D(render->pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ZENABLE,
3931  // TRUE));
3932  // ErrD3D(render->pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ZWRITEENABLE,
3933  // TRUE));
3934 }
3935 
3937  // code chunk from 0049C304
3938  if (config->is_using_specular)
3939  ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_FOGENABLE, FALSE));
3940  ErrD3D(pRenderD3D->pDevice->SetTextureStageState(0, D3DTSS_ADDRESS, D3DTADDRESS_CLAMP));
3941 
3942  ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ALPHABLENDENABLE, TRUE));
3943  ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ZWRITEENABLE, FALSE));
3944  ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_CULLMODE, D3DCULL_NONE));
3945  ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_SRCBLEND, D3DBLEND_ONE));
3946  ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_DESTBLEND, D3DBLEND_ONE));
3947  ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_DITHERENABLE, FALSE));
3948 
3949  // ErrD3D(pRenderD3D->pDevice->SetTexture(0,
3950  // pIndoorCameraD3D->LoadTextureAndGetHardwarePtr("hwsplat04")));
3951  auto hwsplat04 = assets->GetBitmap("hwsplat04");
3952  ErrD3D(pRenderD3D->pDevice->SetTexture(0, ((TextureD3D *)hwsplat04)->GetDirect3DTexture()));
3953 }
3954 
3956  // code chunk from 0049C304
3957  ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_CULLMODE, D3DCULL_CW));
3958  ErrD3D(
3959  pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ZWRITEENABLE, TRUE));
3960  ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ALPHABLENDENABLE, FALSE));
3961  ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_SRCBLEND, D3DBLEND_ONE));
3962  ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_DESTBLEND, D3DBLEND_ZERO));
3963 
3964  if (config->is_using_specular)
3965  ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_FOGENABLE, TRUE));
3966 }
3967 
3968 void Render::DrawDecal(Decal *pDecal, float z_bias) {
3969  int dwFlags; // [sp+Ch] [bp-864h]@15
3970  RenderVertexD3D3 pVerticesD3D[64]; // [sp+20h] [bp-850h]@6
3971 
3972  if (pDecal->uNumVertices < 3) {
3973  log->Warning(L"Decal has < 3 vertices");
3974  return;
3975  }
3976 
3977  float color_mult;
3978  if (pDecal->field_C1C & 1)
3979  color_mult = 1.0;
3980  else
3981  color_mult = pDecal->field_C18->_43B570_get_color_mult_by_time();
3982 
3983  // temp - bloodsplat persistance
3984  color_mult = 1;
3985 
3986  for (uint i = 0; i < (unsigned int)pDecal->uNumVertices; ++i) {
3987  uint uTint =
3988  Render::GetActorTintColor(pDecal->field_C14, 0, pDecal->pVertices[i].vWorldViewPosition.x, 0, nullptr);
3989 
3990  uint uTintR = (uTint >> 16) & 0xFF, uTintG = (uTint >> 8) & 0xFF,
3991  uTintB = uTint & 0xFF;
3992 
3993  uint uDecalColorMultR = (pDecal->uColorMultiplier >> 16) & 0xFF,
3994  uDecalColorMultG = (pDecal->uColorMultiplier >> 8) & 0xFF,
3995  uDecalColorMultB = pDecal->uColorMultiplier & 0xFF;
3996 
3997  uint uFinalR =
3998  floorf(uTintR / 255.0 * color_mult * uDecalColorMultR + 0.0f),
3999  uFinalG =
4000  floorf(uTintG / 255.0 * color_mult * uDecalColorMultG + 0.0f),
4001  uFinalB =
4002  floorf(uTintB / 255.0 * color_mult * uDecalColorMultB + 0.0f);
4003 
4004  // temp - make yellow for easier spotting
4005  // uFinalR = 255;
4006  // uFinalG = 255;
4007 
4008  float v15;
4009  if (fabs(z_bias) < 1e-5) {
4010  v15 = 1.0 -
4011  1.0 / ((1.0f / pIndoorCameraD3D->GetFarClip()) *
4012  pDecal->pVertices[i].vWorldViewPosition.x * 1000.0);
4013  } else {
4014  v15 = 1.0 -
4015  1.0 / ((1.0f / pIndoorCameraD3D->GetFarClip()) *
4016  pDecal->pVertices[i].vWorldViewPosition.x * 1000.0) -
4017  z_bias;
4018  if (v15 < 0.000099999997) v15 = 0.000099999997;
4019  }
4020 
4021  pVerticesD3D[i].pos.x = pDecal->pVertices[i].vWorldViewProjX;
4022  pVerticesD3D[i].pos.y = pDecal->pVertices[i].vWorldViewProjY;
4023  pVerticesD3D[i].pos.z = v15;
4024 
4025  pVerticesD3D[i].rhw = 1.0 / pDecal->pVertices[i].vWorldViewPosition.x;
4026  pVerticesD3D[i].diffuse = (uFinalR << 16) | (uFinalG << 8) | uFinalB;
4027  pVerticesD3D[i].specular = 0;
4028 
4029  pVerticesD3D[i].texcoord.x = pDecal->pVertices[i].u;
4030  pVerticesD3D[i].texcoord.y = pDecal->pVertices[i].v;
4031  }
4032 
4034  dwFlags = D3DDP_DONOTLIGHT | D3DDP_DONOTCLIP | D3DDP_DONOTUPDATEEXTENTS;
4035  else
4036  dwFlags = D3DDP_DONOTLIGHT;
4037 
4038  ErrD3D(pRenderD3D->pDevice->DrawPrimitive(
4039  D3DPT_TRIANGLEFAN,
4040  D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR | D3DFVF_TEX1,
4041  pVerticesD3D, pDecal->uNumVertices, dwFlags));
4042 }
4043 
4045  Texture *texture) {
4046  auto gapi_texture = ((TextureD3D *)texture)->GetDirect3DTexture();
4047  ErrD3D(
4048  pRenderD3D->pDevice->SetTexture(0, (IDirect3DTexture2 *)gapi_texture));
4049  ErrD3D(
4050  pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_FOGENABLE, FALSE));
4051  ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ALPHABLENDENABLE,
4052  TRUE));
4053  ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ZWRITEENABLE,
4054  FALSE));
4055  ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_SRCBLEND,
4056  D3DBLEND_ONE));
4057  ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_DESTBLEND,
4058  D3DBLEND_ONE));
4059  ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_DITHERENABLE,
4060  FALSE));
4061  ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ZFUNC,
4062  D3DCMP_ALWAYS));
4063  ErrD3D(pRenderD3D->pDevice->DrawPrimitive(
4064  D3DPT_TRIANGLEFAN,
4065  D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR | D3DFVF_TEX1,
4066  (void *)vertices, 4, 28));
4067  ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_SRCBLEND,
4068  D3DBLEND_ONE));
4069  ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_DESTBLEND,
4070  D3DBLEND_ZERO));
4071  ErrD3D(pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ALPHABLENDENABLE,
4072  FALSE));
4073  ErrD3D(
4074  pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ZWRITEENABLE, TRUE));
4075  ErrD3D(
4076  pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_DITHERENABLE, TRUE));
4077  ErrD3D(
4078  pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ZFUNC, D3DCMP_LESS));
4079 }
4080 
4081 unsigned int _452442_color_cvt(unsigned __int16 a1, unsigned __int16 a2, int a3,
4082  int a4) {
4083  int v4; // ebx@0
4084  __int16 v5; // ST14_2@1
4085  __int16 v6; // dx@1
4086  int v7; // ecx@1
4087  __int16 v8; // ST10_2@1
4088  int v9; // edi@1
4089  unsigned __int16 v10 = 0; // dh@1@1
4090  int v11; // ebx@1
4091  int v12; // ebx@1
4092  __int16 a3a; // [sp+1Ch] [bp+8h]@1
4093 
4094  v5 = a2 >> 2;
4095  v6 = (unsigned __int16)a4 >> 2;
4096  v8 = a1 >> 2;
4097  a3a = (unsigned __int16)a3 >> 2;
4098  HEXRAYS_LOWORD(v7) = a3a;
4099  v9 = v7;
4100  HEXRAYS_LOWORD(v4) = ((unsigned __int16)a4 >> 2) & 0xE0;
4101  HEXRAYS_LOWORD(v7) = a3a & 0xE0;
4102  HEXRAYS_LOWORD(v9) = v9 & 0x1C00;
4103  v11 = v7 + v4;
4104  HEXRAYS_LOWORD(v7) = v5 & 0xE0;
4105  v12 = v7 + v11;
4106  HEXRAYS_LOWORD(v7) = v8 & 0xE0;
4107  __debugbreak(); // warning C4700: uninitialized local variable 'v10' used
4108  return (PID_TYPE(v8) + PID_TYPE(v5) + PID_TYPE(a3a) + PID_TYPE(v6)) |
4109  (v7 + v12) |
4110  ((v8 & 0x1C00) + (v5 & 0x1C00) + v9 +
4111  (__PAIR__(v10, (unsigned __int16)a4 >> 2) & 0x1C00));
4112 }
4113 
4114 int GetActorTintColor(int max_dimm, int min_dimm, float distance, int a4, RenderBillboard *a5) {
4115  signed int v6; // edx@1
4116  int v8; // eax@3
4117  double v9; // st7@12
4118  int v11; // ecx@28
4119  double v15; // st7@44
4120  int v18; // ST14_4@44
4121  signed int v20; // [sp+10h] [bp-4h]@10
4122  float a3c; // [sp+1Ch] [bp+8h]@44
4123  int a5a; // [sp+24h] [bp+10h]@44
4124 
4125  // v5 = a2;
4126  v6 = 0;
4127 
4129  return 8 * (31 - max_dimm) | ((8 * (31 - max_dimm) | ((31 - max_dimm) << 11)) << 8);
4130 
4131  if (pParty->armageddon_timer) return 0xFFFF0000;
4132 
4133  v8 = pWeather->bNight;
4134  if (engine->IsUnderwater())
4135  v8 = 0;
4136  if (v8) {
4137  v20 = 1;
4138  if (pParty->pPartyBuffs[PARTY_BUFF_TORCHLIGHT].Active())
4139  v20 = pParty->pPartyBuffs[PARTY_BUFF_TORCHLIGHT].uPower;
4140  v9 = (double)v20 * 1024.0;
4141  if (a4) {
4142  v6 = 216;
4143  goto LABEL_20;
4144  }
4145  if (distance <= v9) {
4146  if (distance > 0.0) {
4147  // a4b = distance * 216.0 / device_caps;
4148  // v10 = a4b + 6.7553994e15;
4149  // v6 = LODWORD(v10);
4150  v6 = floorf(0.5f + distance * 216.0 / v9);
4151  if (v6 > 216) {
4152  v6 = 216;
4153  goto LABEL_20;
4154  }
4155  }
4156  } else {
4157  v6 = 216;
4158  }
4159  if (distance != 0.0) {
4160  LABEL_20:
4161  if (a5) v6 = 8 * _43F55F_get_billboard_light_level(a5, v6 >> 3);
4162  if (v6 > 216) v6 = 216;
4163  return (255 - v6) | ((255 - v6) << 16) | ((255 - v6) << 8);
4164  }
4165  // LABEL_19:
4166  v6 = 216;
4167  goto LABEL_20;
4168  }
4169 
4170  if (fabsf(distance) < 1.0e-6f) return 0xFFF8F8F8;
4171 
4172  // dim in measured in 8-steps
4173  v11 = 8 * (max_dimm - min_dimm);
4174  // v12 = v11;
4175  if (v11 >= 0) {
4176  if (v11 > 216) v11 = 216;
4177  } else {
4178  v11 = 0;
4179  }
4180 
4181  float fog_density_mult = 216.0f;
4182  if (a4)
4183  fog_density_mult +=
4184  distance / (double)pODMRenderParams->shading_dist_shade * 32.0;
4185 
4186  v6 = v11 + floorf(pOutdoor->fFogDensity * fog_density_mult + 0.5f);
4187 
4188  if (a5) v6 = 8 * _43F55F_get_billboard_light_level(a5, v6 >> 3);
4189  if (v6 > 216) v6 = 216;
4190  if (v6 < v11) v6 = v11;
4191  if (v6 > 8 * pOutdoor->max_terrain_dimming_level)
4193  if (!engine->IsUnderwater()) {
4194  return (255 - v6) | ((255 - v6) << 16) | ((255 - v6) << 8);
4195  } else {
4196  v15 = (double)(255 - v6) * 0.0039215689;
4197  a3c = v15;
4198  // a4c = v15 * 16.0;
4199  // v16 = a4c + 6.7553994e15;
4200  a5a = floorf(v15 * 16.0 + 0.5f); // LODWORD(v16);
4201  // a4d = a3c * 194.0;
4202  // v17 = a4d + 6.7553994e15;
4203  v18 = floorf(a3c * 194.0 + 0.5f); // LODWORD(v17);
4204  // a3d = a3c * 153.0;
4205  // v19 = a3d + 6.7553994e15;
4206  return (int)floorf(a3c * 153.0 + 0.5f) /*LODWORD(v19)*/ |
4207  ((v18 | (a5a << 8)) << 8);
4208  }
4209 }
4210 
4212  int uBaseLightLevel) {
4213  int v3 = 0;
4214 
4217  } else {
4218  if (uBaseLightLevel == -1) {
4219  v3 = a1->dimming_level;
4220  } else {
4221  v3 = uBaseLightLevel;
4222  }
4223  }
4224 
4226  v3, a1->uIndoorSectorID, a1->world_x, a1->world_y, a1->world_z);
4227 }
4228 
4230  unsigned int uBaseLightLevel, int uSectorID, float x, float y, float z) {
4231  signed int v6; // edi@1
4232  int v8; // eax@6
4233  int v9; // ebx@6
4234  unsigned int v10; // ecx@6
4235  unsigned int v11; // edx@9
4236  unsigned int v12; // edx@11
4237  signed int v13; // ecx@12
4238  BLVLightMM7 *v16; // esi@20
4239  int v17; // ebx@21
4240  signed int v24; // ecx@30
4241  int v26; // ebx@35
4242  int v37; // [sp+Ch] [bp-18h]@37
4243  int v39; // [sp+10h] [bp-14h]@23
4244  int v40; // [sp+10h] [bp-14h]@36
4245  int v42; // [sp+14h] [bp-10h]@22
4246  unsigned int v43; // [sp+18h] [bp-Ch]@12
4247  unsigned int v44; // [sp+18h] [bp-Ch]@30
4248  unsigned int v45; // [sp+18h] [bp-Ch]@44
4249 
4250  v6 = uBaseLightLevel;
4251  for (uint i = 0; i < pMobileLightsStack->uNumLightsActive; ++i) {
4253 
4254  float distX = abs(p->vPosition.x - x);
4255  if (distX <= p->uRadius) {
4256  float distY = abs(p->vPosition.y - y);
4257  if (distY <= p->uRadius) {
4258  float distZ = abs(p->vPosition.z - z);
4259  if (distZ <= p->uRadius) {
4260  v8 = distX;
4261  v9 = distY;
4262  v10 = distZ;
4263  if (distX < distY) {
4264  v8 = distY;
4265  v9 = distX;
4266  }
4267  if (v8 < distZ) {
4268  v11 = v8;
4269  v8 = distZ;
4270  v10 = v11;
4271  }
4272  if (v9 < (signed int)v10) {
4273  v12 = v10;
4274  v10 = v9;
4275  v9 = v12;
4276  }
4277  v43 = ((unsigned int)(11 * v9) / 32) + (v10 / 4) + v8;
4278  v13 = p->uRadius;
4279  if ((signed int)v43 < v13)
4280  v6 += ((unsigned __int64)(30i64 *
4281  (signed int)(v43 << 16) /
4282  v13) >>
4283  16) -
4284  30;
4285  }
4286  }
4287  }
4288  }
4289 
4291  BLVSector *pSector = &pIndoor->pSectors[uSectorID];
4292 
4293  for (uint i = 0; i < pSector->uNumLights; ++i) {
4294  v16 = pIndoor->pLights + pSector->pLights[i];
4295  if (~v16->uAtributes & 8) {
4296  v17 = abs(v16->vPosition.x - x);
4297  if (v17 <= v16->uRadius) {
4298  v42 = abs(v16->vPosition.y - y);
4299  if (v42 <= v16->uRadius) {
4300  v39 = abs(v16->vPosition.z - z);
4301  if (v39 <= v16->uRadius) {
4302  v44 = int_get_vector_length(v17, v42, v39);
4303  v24 = v16->uRadius;
4304  if ((signed int)v44 < v24)
4305  v6 += ((unsigned __int64)(30i64 *
4306  (signed int)(v44
4307  << 16) /
4308  v24) >>
4309  16) -
4310  30;
4311  }
4312  }
4313  }
4314  }
4315  }
4316  }
4317 
4318  for (uint i = 0; i < pStationaryLightsStack->uNumLightsActive; ++i) {
4319  // StationaryLight* p = &pStationaryLightsStack->pLights[i];
4320  v26 = abs(pStationaryLightsStack->pLights[i].vPosition.x - x);
4321  if (v26 <= pStationaryLightsStack->pLights[i].uRadius) {
4322  v40 = abs(pStationaryLightsStack->pLights[i].vPosition.y - y);
4323  if (v40 <= pStationaryLightsStack->pLights[i].uRadius) {
4324  v37 = abs(pStationaryLightsStack->pLights[i].vPosition.z - z);
4325  if (v37 <= pStationaryLightsStack->pLights[i].uRadius) {
4326  v45 = int_get_vector_length(v26, v40, v37);
4327  // v33 = pStationaryLightsStack->pLights[i].uRadius;
4328  if ((signed int)v45 <
4330  v6 += ((unsigned __int64)(30i64 *
4331  (signed int)(v45 << 16) /
4333  ->pLights[i]
4334  .uRadius) >>
4335  16) -
4336  30;
4337  }
4338  }
4339  }
4340  }
4341 
4342  if (v6 <= 31) {
4343  if (v6 < 0) v6 = 0;
4344  } else {
4345  v6 = 31;
4346  }
4347  return v6;
4348 }
4349 
4351  BLVSector *pSector; // edi@1
4352  int v2; // ebx@1
4353  BLVFace *pFace; // esi@2
4354  __int16 pNextSector; // si@10
4355  int pArrayNum; // ecx@12
4356  unsigned __int8 v6; // sf@12
4357  unsigned __int8 v7; // of@12
4358  int result; // eax@14
4359  // int v10; // ecx@15
4360  int pFloor; // eax@16
4361  int v15; // eax@24
4362  int v16; // edx@25
4363  int v17; // eax@29
4364  unsigned int v18; // eax@33
4365  int v21; // eax@35
4366  int v22; // ecx@36
4367  int v23; // eax@40
4368  unsigned int v24; // eax@44
4369  int a3; // [sp+10h] [bp-48h]@28
4370  int v26; // [sp+14h] [bp-44h]@15
4371  int i; // [sp+18h] [bp-40h]@1
4372  int a10; // [sp+1Ch] [bp-3Ch]@1
4373  int v29; // [sp+20h] [bp-38h]@14
4374  int v32; // [sp+2Ch] [bp-2Ch]@15
4375  int pSectorsArray[10]; // [sp+30h] [bp-28h]@1
4376 
4377  pSector = &pIndoor->pSectors[stru_721530.uSectorID];
4378  i = 1;
4379  a10 = b1;
4380  pSectorsArray[0] = stru_721530.uSectorID;
4381  for (v2 = 0; v2 < pSector->uNumPortals; ++v2) {
4382  pFace = &pIndoor->pFaces[pSector->pPortals[v2]];
4383  if (stru_721530.sMaxX <= pFace->pBounding.x2 &&
4384  stru_721530.sMinX >= pFace->pBounding.x1 &&
4385  stru_721530.sMaxY <= pFace->pBounding.y2 &&
4386  stru_721530.sMinY >= pFace->pBounding.y1 &&
4387  stru_721530.sMaxZ <= pFace->pBounding.z2 &&
4388  stru_721530.sMinZ >= pFace->pBounding.z1 &&
4389  abs((pFace->pFacePlane_old.dist +
4390  stru_721530.normal.x * pFace->pFacePlane_old.vNormal.x +
4391  stru_721530.normal.y * pFace->pFacePlane_old.vNormal.y +
4392  stru_721530.normal.z * pFace->pFacePlane_old.vNormal.z) >>
4393  16) <= stru_721530.field_6C + 16) {
4394  pNextSector = pFace->uSectorID == stru_721530.uSectorID
4395  ? pFace->uBackSectorID
4396  : pFace->uSectorID; // FrontSectorID
4397  pArrayNum = i++;
4398  v7 = i < 10;
4399  v6 = i - 10 < 0;
4400  pSectorsArray[pArrayNum] = pNextSector;
4401  if (!(v6 ^ v7)) break;
4402  }
4403  }
4404  result = 0;
4405  for (v29 = 0; v29 < i; v29++) {
4406  pSector = &pIndoor->pSectors[pSectorsArray[v29]];
4407  v32 = pSector->uNumFloors + pSector->uNumWalls + pSector->uNumCeilings;
4408  for (v26 = 0; v26 < v32; v26++) {
4409  pFloor = pSector->pFloors[v26];
4410  pFace = &pIndoor->pFaces[pSector->pFloors[v26]];
4411  if (!pFace->Portal() && stru_721530.sMaxX <= pFace->pBounding.x2 &&
4412  stru_721530.sMinX >= pFace->pBounding.x1 &&
4413  stru_721530.sMaxY <= pFace->pBounding.y2 &&
4414  stru_721530.sMinY >= pFace->pBounding.y1 &&
4415  stru_721530.sMaxZ <= pFace->pBounding.z2 &&
4416  stru_721530.sMinZ >= pFace->pBounding.z1 &&
4417  pFloor != stru_721530.field_84) {
4418  v15 =
4419  (pFace->pFacePlane_old.dist +
4420  stru_721530.normal.x * pFace->pFacePlane_old.vNormal.x +
4421  stru_721530.normal.y * pFace->pFacePlane_old.vNormal.y +
4422  stru_721530.normal.z * pFace->pFacePlane_old.vNormal.z) >>
4423  16;
4424  if (v15 > 0) {
4425  v16 = (pFace->pFacePlane_old.dist +
4426  stru_721530.normal2.x *
4427  pFace->pFacePlane_old.vNormal.x +
4428  stru_721530.normal2.y *
4429  pFace->pFacePlane_old.vNormal.y +
4430  stru_721530.normal2.z *
4431  pFace->pFacePlane_old.vNormal.z) >>
4432  16;
4433  if (v15 <= stru_721530.prolly_normal_d ||
4434  v16 <= stru_721530.prolly_normal_d) {
4435  if (v16 <= v15) {
4436  a3 = stru_721530.field_6C;
4437  if (sub_47531C(
4440  stru_721530.normal.z,
4443  stru_721530.direction.z, pFace, a10)) {
4444  v17 = a3;
4445  } else {
4446  a3 = stru_721530.field_6C +
4449  &stru_721530.direction, &a3,
4450  pFace))
4451  goto LABEL_34;
4452  v17 = a3 - stru_721530.prolly_normal_d;
4454  }
4455  if (v17 < stru_721530.field_7C) {
4456  stru_721530.field_7C = v17;
4457  v18 = 8 * pSector->pFloors[v26];
4458  v18 |= 6;
4459  stru_721530.pid = v18;
4460  }
4461  }
4462  }
4463  }
4464  LABEL_34:
4465  if (!(stru_721530.field_0 & 1) ||
4466  (v21 = (pFace->pFacePlane_old.dist +
4467  stru_721530.position.x *
4468  pFace->pFacePlane_old.vNormal.x +
4469  stru_721530.position.y *
4470  pFace->pFacePlane_old.vNormal.y +
4471  stru_721530.position.z *
4472  pFace->pFacePlane_old.vNormal.z) >>
4473  16,
4474  v21 <= 0) ||
4475  (v22 = (pFace->pFacePlane_old.dist +
4477  pFace->pFacePlane_old.vNormal.x +
4479  pFace->pFacePlane_old.vNormal.y +
4481  pFace->pFacePlane_old.vNormal.z) >>
4482  16,
4483  v21 > stru_721530.prolly_normal_d) &&
4484  v22 > stru_721530.prolly_normal_d ||
4485  v22 > v21)
4486  continue;
4487  a3 = stru_721530.field_6C;
4492  pFace, a10)) {
4493  v23 = a3;
4494  goto LABEL_43;
4495  }
4498  &a3, pFace)) {
4499  v23 = a3 - stru_721530.prolly_normal_d;
4501  LABEL_43:
4502  if (v23 < stru_721530.field_7C) {
4503  stru_721530.field_7C = v23;
4504  v24 = 8 * pSector->pFloors[v26];
4505  v24 |= 6;
4506  stru_721530.pid = v24;
4507  }
4508  }
4509  }
4510  }
4511  result = v29 + 1;
4512  }
4513  return result;
4514 }
4515 
4516 void _46E889_collide_against_bmodels(unsigned int ecx0) {
4517  int v8; // eax@19
4518  int v9; // ecx@20
4519  int v10; // eax@24
4520  // unsigned int v14; // eax@28
4521  int v15; // eax@30
4522  int v16; // ecx@31
4523  // unsigned int v17; // eax@36
4524  int v21; // eax@42
4525  // unsigned int v22; // eax@43
4526  int a2; // [sp+84h] [bp-4h]@23
4527  BLVFace face; // [sp+Ch] [bp-7Ch]@1
4528 
4529  for (BSPModel &model : pOutdoor->pBModels) {
4530  if (stru_721530.sMaxX <= model.sMaxX &&
4531  stru_721530.sMinX >= model.sMinX &&
4532  stru_721530.sMaxY <= model.sMaxY &&
4533  stru_721530.sMinY >= model.sMinY &&
4534  stru_721530.sMaxZ <= model.sMaxZ &&
4535  stru_721530.sMinZ >= model.sMinZ) {
4536  for (ODMFace &mface : model.pFaces) {
4537  if (stru_721530.sMaxX <= mface.pBoundingBox.x2 &&
4538  stru_721530.sMinX >= mface.pBoundingBox.x1 &&
4539  stru_721530.sMaxY <= mface.pBoundingBox.y2 &&
4540  stru_721530.sMinY >= mface.pBoundingBox.y1 &&
4541  stru_721530.sMaxZ <= mface.pBoundingBox.z2 &&
4542  stru_721530.sMinZ >= mface.pBoundingBox.z1) {
4543  face.pFacePlane_old.vNormal.x = mface.pFacePlane.vNormal.x;
4544  face.pFacePlane_old.vNormal.y = mface.pFacePlane.vNormal.y;
4545  face.pFacePlane_old.vNormal.z = mface.pFacePlane.vNormal.z;
4546 
4547  face.pFacePlane_old.dist =
4548  mface.pFacePlane.dist; // incorrect
4549 
4550  face.uAttributes = mface.uAttributes;
4551 
4552  face.pBounding.x1 = mface.pBoundingBox.x1;
4553  face.pBounding.y1 = mface.pBoundingBox.y1;
4554  face.pBounding.z1 = mface.pBoundingBox.z1;
4555 
4556  face.pBounding.x2 = mface.pBoundingBox.x2;
4557  face.pBounding.y2 = mface.pBoundingBox.y2;
4558  face.pBounding.z2 = mface.pBoundingBox.z2;
4559 
4560  face.zCalc1 = mface.zCalc1;
4561  face.zCalc2 = mface.zCalc2;
4562  face.zCalc3 = mface.zCalc3;
4563 
4564  face.pXInterceptDisplacements =
4566  face.pYInterceptDisplacements =
4568  face.pZInterceptDisplacements =
4570 
4571  face.uPolygonType = (PolygonType)mface.uPolygonType;
4572 
4573  face.uNumVertices = mface.uNumVertices;
4574 
4575  // face.uBitmapID = model.pFaces[j].uTextureID;
4576  face.resource = mface.resource;
4577 
4578  face.pVertexIDs = mface.pVertexIDs;
4579 
4580  if (!face.Ethereal() && !face.Portal()) {
4581  v8 = (face.pFacePlane_old.dist +
4582  face.pFacePlane_old.vNormal.x *
4583  stru_721530.normal.x +
4584  face.pFacePlane_old.vNormal.y *
4585  stru_721530.normal.y +
4586  face.pFacePlane_old.vNormal.z *
4587  stru_721530.normal.z) >>
4588  16;
4589  if (v8 > 0) {
4590  v9 = (face.pFacePlane_old.dist +
4591  face.pFacePlane_old.vNormal.x *
4592  stru_721530.normal2.x +
4593  face.pFacePlane_old.vNormal.y *
4594  stru_721530.normal2.y +
4595  face.pFacePlane_old.vNormal.z *
4596  stru_721530.normal2.z) >>
4597  16;
4598  if (v8 <= stru_721530.prolly_normal_d ||
4599  v9 <= stru_721530.prolly_normal_d) {
4600  if (v9 <= v8) {
4601  a2 = stru_721530.field_6C;
4603  &a2, stru_721530.normal.x,
4604  stru_721530.normal.y,
4605  stru_721530.normal.z,
4609  &face, model.index, ecx0)) {
4610  v10 = a2;
4611  } else {
4614  if (!sub_475F30(&a2, &face,
4615  stru_721530.normal.x,
4616  stru_721530.normal.y,
4617  stru_721530.normal.z,
4621  model.index))
4622  goto LABEL_29;
4623  v10 = a2 - stru_721530.prolly_normal_d;
4625  }
4626  if (v10 < stru_721530.field_7C) {
4627  stru_721530.field_7C = v10;
4628  stru_721530.pid = PID(
4629  OBJECT_BModel,
4630  (mface.index | (model.index << 6)));
4631  }
4632  }
4633  }
4634  }
4635  LABEL_29:
4636  if (stru_721530.field_0 & 1) {
4637  v15 = (face.pFacePlane_old.dist +
4638  face.pFacePlane_old.vNormal.x *
4639  stru_721530.position.x +
4640  face.pFacePlane_old.vNormal.y *
4641  stru_721530.position.y +
4642  face.pFacePlane_old.vNormal.z *
4643  stru_721530.position.z) >>
4644  16;
4645  if (v15 > 0) {
4646  v16 = (face.pFacePlane_old.dist +
4647  face.pFacePlane_old.vNormal.x *
4649  face.pFacePlane_old.vNormal.y *
4651  face.pFacePlane_old.vNormal.z *
4652  stru_721530.field_54) >>
4653  16;
4654  if (v15 <= stru_721530.prolly_normal_d ||
4655  v16 <= stru_721530.prolly_normal_d) {
4656  if (v16 <= v15) {
4657  a2 = stru_721530.field_6C;
4658  if (sub_4754BF(
4666  model.index, ecx0)) {
4667  if (a2 < stru_721530.field_7C) {
4668  stru_721530.field_7C = a2;
4669  stru_721530.pid =
4670  PID(OBJECT_BModel,
4671  (mface.index |
4672  (model.index << 6)));
4673  }
4674  } else {
4675  a2 = stru_721530.field_6C +
4677  if (sub_475F30(
4678  &a2, &face,
4685  model.index)) {
4686  v21 =
4687  a2 -
4689  a2 -=
4691  if (a2 < stru_721530.field_7C) {
4692  stru_721530.field_7C = v21;
4693  stru_721530.pid = PID(
4694  OBJECT_BModel,
4695  (mface.index |
4696  (model.index << 6)));
4697  }
4698  }
4699  }
4700  }
4701  }
4702  }
4703  }
4704  }
4705  }
4706  }
4707  }
4708  }
4709 }
4710 
4711 int collide_against_floor(int x, int y, int z, unsigned int *pSectorID,
4712  unsigned int *pFaceID) {
4713  uint uFaceID = -1;
4714  int floor_level = BLV_GetFloorLevel(x, y, z, *pSectorID, &uFaceID);
4715 
4716  if (floor_level != -30000 && floor_level <= z + 50) {
4717  *pFaceID = uFaceID;
4718  return floor_level;
4719  }
4720 
4721  uint uSectorID = pIndoor->GetSector(x, y, z);
4722  *pSectorID = uSectorID;
4723 
4724  floor_level = BLV_GetFloorLevel(x, y, z, uSectorID, &uFaceID);
4725  if (uSectorID && floor_level != -30000)
4726  *pFaceID = uFaceID;
4727  else
4728  return -30000;
4729  return floor_level;
4730 }
4731 
4732 void _46ED8A_collide_against_sprite_objects(unsigned int _this) {
4733  ObjectDesc *object; // edx@4
4734  int v10; // ecx@12
4735  int v11; // esi@13
4736 
4737  for (uint i = 0; i < uNumSpriteObjects; ++i) {
4738  if (pSpriteObjects[i].uObjectDescID) {
4739  object = &pObjectList->pObjects[pSpriteObjects[i].uObjectDescID];
4740  if (!(object->uFlags & OBJECT_DESC_NO_COLLISION)) {
4741  if (stru_721530.sMaxX <=
4742  pSpriteObjects[i].vPosition.x + object->uRadius &&
4743  stru_721530.sMinX >=
4744  pSpriteObjects[i].vPosition.x - object->uRadius &&
4745  stru_721530.sMaxY <=
4746  pSpriteObjects[i].vPosition.y + object->uRadius &&
4747  stru_721530.sMinY >=
4748  pSpriteObjects[i].vPosition.y - object->uRadius &&
4749  stru_721530.sMaxZ <=
4750  pSpriteObjects[i].vPosition.z + object->uHeight &&
4751  stru_721530.sMinZ >= pSpriteObjects[i].vPosition.z) {
4752  if (abs(((pSpriteObjects[i].vPosition.x -
4753  stru_721530.normal.x) *
4755  (pSpriteObjects[i].vPosition.y -
4756  stru_721530.normal.y) *
4757  stru_721530.direction.x) >>
4758  16) <=
4759  object->uHeight + stru_721530.prolly_normal_d) {
4760  v10 = ((pSpriteObjects[i].vPosition.x -
4761  stru_721530.normal.x) *
4763  (pSpriteObjects[i].vPosition.y -
4764  stru_721530.normal.y) *
4765  stru_721530.direction.y) >>
4766  16;
4767  if (v10 > 0) {
4768  v11 = stru_721530.normal.z +
4769  ((unsigned __int64)(stru_721530.direction.z *
4770  (signed __int64)v10) >>
4771  16);
4772  if (v11 >= pSpriteObjects[i].vPosition.z -
4774  if (v11 <= object->uHeight +
4776  pSpriteObjects[i].vPosition.z) {
4777  if (v10 < stru_721530.field_7C) {
4778  sub_46DEF2(_this, i);
4779  }
4780  }
4781  }
4782  }
4783  }
4784  }
4785  }
4786  }
4787  }
4788 }
4789 
4791  int result; // eax@1
4792  int v3; // ebx@7
4793  int v4; // esi@7
4794  int v5; // edi@8
4795  int v6; // ecx@9
4796  int v7; // edi@12
4797  int v10; // [sp+14h] [bp-8h]@7
4798  int v11; // [sp+18h] [bp-4h]@7
4799 
4800  result = pParty->vPosition.x;
4801  // device_caps = pParty->uPartyHeight;
4802  if (stru_721530.sMaxX <=
4803  pParty->vPosition.x + (2 * pParty->field_14_radius) &&
4804  stru_721530.sMinX >=
4805  pParty->vPosition.x - (2 * pParty->field_14_radius) &&
4806  stru_721530.sMaxY <=
4807  pParty->vPosition.y + (2 * pParty->field_14_radius) &&
4808  stru_721530.sMinY >=
4809  pParty->vPosition.y - (2 * pParty->field_14_radius) &&
4810  stru_721530.sMinZ/*sMaxZ*/ <= (pParty->vPosition.z + (int)pParty->uPartyHeight) &&
4811  stru_721530.sMaxZ/*sMinZ*/ >= pParty->vPosition.z) {
4813  v11 = pParty->vPosition.x - stru_721530.normal.x;
4814  v4 = ((pParty->vPosition.x - stru_721530.normal.x) *
4816  (pParty->vPosition.y - stru_721530.normal.y) *
4817  stru_721530.direction.x) >>
4818  16;
4819  v10 = pParty->vPosition.y - stru_721530.normal.y;
4820  result = abs(((pParty->vPosition.x - stru_721530.normal.x) *
4822  (pParty->vPosition.y - stru_721530.normal.y) *
4823  stru_721530.direction.x) >>
4824  16);
4825  if (result <=
4827  result = v10 * stru_721530.direction.y;
4828  v5 = (v10 * stru_721530.direction.y +
4829  v11 * stru_721530.direction.x) >>
4830  16;
4831  if (v5 > 0) {
4832  v6 = fixpoint_mul(stru_721530.direction.z, v5) +
4833  stru_721530.normal.z;
4834  result = pParty->vPosition.z;
4835  if (v6 >= pParty->vPosition.z) {
4837  if (v6 <= (signed int)(pParty->uPartyHeight +
4838  pParty->vPosition.z) ||
4839  a1) {
4840  result = integer_sqrt(v3 * v3 - v4 * v4);
4841  v7 = v5 - integer_sqrt(v3 * v3 - v4 * v4);
4842  if (v7 < 0) v7 = 0;
4843  if (v7 < stru_721530.field_7C) {
4844  stru_721530.field_7C = v7;
4845  stru_721530.pid = 4;
4846  }
4847  }
4848  }
4849  }
4850  }
4851  }
4852  return result;
4853 }
4854 
4857  for (unsigned int i = 0; i < sector->uNumDecorations; ++i) {
4858  LevelDecoration *decor = &pLevelDecorations[sector->pDecorationIDs[i]];
4859  if (!(decor->uFlags & LEVEL_DECORATION_INVISIBLE)) {
4861  if (!decor_desc->CanMoveThrough()) {
4862  if (stru_721530.sMaxX <= decor->vPosition.x + decor_desc->uRadius &&
4863  stru_721530.sMinX >= decor->vPosition.x - decor_desc->uRadius &&
4864  stru_721530.sMaxY <= decor->vPosition.y + decor_desc->uRadius &&
4865  stru_721530.sMinY >= decor->vPosition.y - decor_desc->uRadius &&
4866  stru_721530.sMaxZ <= decor->vPosition.z + decor_desc->uDecorationHeight &&
4867  stru_721530.sMinZ >= decor->vPosition.z) {
4868  int v16 = decor->vPosition.x - stru_721530.normal.x;
4869  int v15 = decor->vPosition.y - stru_721530.normal.y;
4870  int v8 = stru_721530.prolly_normal_d + decor_desc->uRadius;
4871  int v17 = ((decor->vPosition.x - stru_721530.normal.x) * stru_721530.direction.y -
4872  (decor->vPosition.y - stru_721530.normal.y) * stru_721530.direction.x) >> 16;
4873  if (abs(v17) <= stru_721530.prolly_normal_d + decor_desc->uRadius) {
4874  int v9 = (v16 * stru_721530.direction.x + v15 * stru_721530.direction.y) >> 16;
4875  if (v9 > 0) {
4876  int v11 = stru_721530.normal.z + fixpoint_mul(stru_721530.direction.z, v9);
4877  if (v11 >= decor->vPosition.z) {
4878  if (v11 <= decor_desc->uDecorationHeight + decor->vPosition.z) {
4879  int v12 = v9 - integer_sqrt(v8 * v8 - v17 * v17);
4880  if (v12 < 0) v12 = 0;
4881  if (v12 < stru_721530.field_7C) {
4882  stru_721530.field_7C = v12;
4883  stru_721530.pid = PID(OBJECT_Decoration, sector->pDecorationIDs[i]);
4884  }
4885  }
4886  }
4887  }
4888  }
4889  }
4890  }
4891  }
4892  }
4893 }
4894 
4896  int a3; // [sp+Ch] [bp-8h]@13
4897  int v12 = 0; // [sp+10h] [bp-4h]@15
4898 
4899  unsigned int v1 = 0xFFFFFF;
4900  unsigned int v10 = 0xFFFFFF;
4901  for (unsigned int i = 0; i < pIndoor->pSectors[stru_721530.uSectorID].uNumPortals; ++i) {
4905  if (stru_721530.sMaxX <= face->pBounding.x2 &&
4906  stru_721530.sMinX >= face->pBounding.x1 &&
4907  stru_721530.sMaxY <= face->pBounding.y2 &&
4908  stru_721530.sMinY >= face->pBounding.y1 &&
4909  stru_721530.sMaxZ <= face->pBounding.z2 &&
4910  stru_721530.sMinZ >= face->pBounding.z1) {
4911  int v4 = (stru_721530.normal.x * face->pFacePlane_old.vNormal.x +
4912  face->pFacePlane_old.dist +
4913  stru_721530.normal.y * face->pFacePlane_old.vNormal.y +
4914  stru_721530.normal.z * face->pFacePlane_old.vNormal.z) >> 16;
4915  int v5 = (stru_721530.normal2.z * face->pFacePlane_old.vNormal.z +
4916  face->pFacePlane_old.dist +
4917  stru_721530.normal2.x * face->pFacePlane_old.vNormal.x +
4918  stru_721530.normal2.y * face->pFacePlane_old.vNormal.y) >> 16;
4921  (a3 = stru_721530.field_6C, sub_475D85(&stru_721530.normal, &stru_721530.direction, &a3, face)) && a3 < (int)v10) {
4922  v10 = a3;
4924  }
4925  }
4926  }
4927  }
4928 
4929  v1 = v10;
4930 
4931  int result = 1;
4932 
4933  if (stru_721530.field_7C >= (int)v1 && (int)v1 <= stru_721530.field_6C) {
4934  stru_721530.field_80 = v12;
4935  if (pIndoor->pFaces[v12].uSectorID == stru_721530.uSectorID) {
4937  } else {
4939  }
4940  stru_721530.field_7C = 268435455; // 0xFFFFFFF
4941  result = 0;
4942  }
4943 
4944  return result;
4945 }
4946 
4947 unsigned int sub_46DEF2(signed int a2, unsigned int uLayingItemID) {
4948  unsigned int result = uLayingItemID;
4949  if (pObjectList->pObjects[pSpriteObjects[uLayingItemID].uObjectDescID].uFlags & 0x10) {
4950  result = _46BFFA_update_spell_fx(uLayingItemID, a2);
4951  }
4952  return result;
4953 }
4954 
4956  int v5; // ecx@6
4957  int v7; // eax@9
4958  int v11; // eax@17
4959  int v12; // edi@27
4960  int v18; // [sp+4h] [bp-10h]@27
4961  int v19; // [sp+8h] [bp-Ch]@27
4962 
4963  for (uint i = 0; i < uNumSpriteObjects; ++i) {
4964  if (pSpriteObjects[i].uAttributes & OBJECT_40) {
4965  pSpriteObjects[i].uAttributes &= ~OBJECT_40;
4966  } else {
4967  ObjectDesc *object =
4968  &pObjectList->pObjects[pSpriteObjects[i].uObjectDescID];
4969  if (pSpriteObjects[i].AttachedToActor()) {
4970  v5 = PID_ID(pSpriteObjects[i].spell_target_pid);
4971  pSpriteObjects[i].vPosition.x = pActors[v5].vPosition.x;
4972  pSpriteObjects[i].vPosition.y = pActors[v5].vPosition.y;
4973  pSpriteObjects[i].vPosition.z =
4974  pActors[v5].vPosition.z + pActors[v5].uActorHeight;
4975  if (!pSpriteObjects[i].uObjectDescID) continue;
4976  pSpriteObjects[i].uSpriteFrameID += pEventTimer->uTimeElapsed;
4977  if (!(object->uFlags & OBJECT_DESC_TEMPORARY)) continue;
4978  if (pSpriteObjects[i].uSpriteFrameID >= 0) {
4979  v7 = object->uLifetime;
4980  if (pSpriteObjects[i].uAttributes & ITEM_BROKEN)
4981  v7 = pSpriteObjects[i].field_20;
4982  if (pSpriteObjects[i].uSpriteFrameID < v7) continue;
4983  }
4985  continue;
4986  }
4987  if (pSpriteObjects[i].uObjectDescID) {
4988  pSpriteObjects[i].uSpriteFrameID += pEventTimer->uTimeElapsed;
4989  if (object->uFlags & OBJECT_DESC_TEMPORARY) {
4990  if (pSpriteObjects[i].uSpriteFrameID < 0) {
4992  continue;
4993  }
4994  v11 = object->uLifetime;
4995  if (pSpriteObjects[i].uAttributes & ITEM_BROKEN)
4996  v11 = pSpriteObjects[i].field_20;
4997  }
4998  if (!(object->uFlags & OBJECT_DESC_TEMPORARY) ||
4999  pSpriteObjects[i].uSpriteFrameID < v11) {
5002  else
5004  if (!pParty->bTurnBasedModeOn || !(pSpriteObjects[i].uSectorID & 4)) {
5005  continue;
5006  }
5007  v12 = abs(pParty->vPosition.x -
5008  pSpriteObjects[i].vPosition.x);
5009  v18 = abs(pParty->vPosition.y -
5010  pSpriteObjects[i].vPosition.y);
5011  v19 = abs(pParty->vPosition.z -
5012  pSpriteObjects[i].vPosition.z);
5013  if (int_get_vector_length(v12, v18, v19) <= 5120) continue;
5015  continue;
5016  }
5017  if (!(object->uFlags & OBJECT_DESC_INTERACTABLE)) {
5019  continue;
5020  }
5022  }
5023  }
5024  }
5025 }
5026 
5027 bool sub_47531C(int a1, int *a2, int pos_x, int pos_y, int pos_z, int dir_x,
5028  int dir_y, int dir_z, BLVFace *face, int a10) {
5029  int v11; // ST1C_4@3
5030  int v12; // edi@3
5031  int v13; // esi@3
5032  int v14; // edi@4
5033  __int64 v15; // qtt@6
5034  // __int16 v16; // si@7
5035  int a7a; // [sp+30h] [bp+18h]@7
5036  int a9b; // [sp+38h] [bp+20h]@3
5037  int a9a; // [sp+38h] [bp+20h]@3
5038  int a10b; // [sp+3Ch] [bp+24h]@3
5039  signed int a10a; // [sp+3Ch] [bp+24h]@4
5040  int a10c; // [sp+3Ch] [bp+24h]@5
5041 
5042  if (a10 && face->Ethereal()) return 0;
5043  v11 = fixpoint_mul(dir_x, face->pFacePlane_old.vNormal.x);
5044  a10b = fixpoint_mul(dir_y, face->pFacePlane_old.vNormal.y);
5045  a9b = fixpoint_mul(dir_z, face->pFacePlane_old.vNormal.z);
5046  v12 = v11 + a9b + a10b;
5047  a9a = v11 + a9b + a10b;
5048  v13 = (a1 << 16) - pos_x * face->pFacePlane_old.vNormal.x -
5049  pos_y * face->pFacePlane_old.vNormal.y -
5050  pos_z * face->pFacePlane_old.vNormal.z - face->pFacePlane_old.dist;
5051  if (abs((a1 << 16) - pos_x * face->pFacePlane_old.vNormal.x -
5052  pos_y * face->pFacePlane_old.vNormal.y -
5053  pos_z * face->pFacePlane_old.vNormal.z -
5054  face->pFacePlane_old.dist) >= a1 << 16) {
5055  a10c = abs(v13) >> 14;
5056  if (a10c > abs(v12)) return 0;
5057  HEXRAYS_LODWORD(v15) = v13 << 16;
5058  HEXRAYS_HIDWORD(v15) = v13 >> 16;
5059  v14 = a1;
5060  a10a = v15 / a9a;
5061  } else {
5062  a10a = 0;
5063  v14 = abs(v13) >> 16;
5064  }
5065  // v16 = pos_y + ((unsigned int)fixpoint_mul(a10a, dir_y) >> 16);
5066  HEXRAYS_LOWORD(a7a) = (short)pos_x +
5067  ((unsigned int)fixpoint_mul(a10a, dir_x) >> 16) -
5068  fixpoint_mul(v14, face->pFacePlane_old.vNormal.x);
5069  HEXRAYS_HIWORD(a7a) = pos_y +
5070  ((unsigned int)fixpoint_mul(a10a, dir_y) >> 16) -
5071  fixpoint_mul(v14, face->pFacePlane_old.vNormal.y);
5072  if (!sub_475665(face, a7a,
5073  (short)pos_z +
5074  ((unsigned int)fixpoint_mul(a10a, dir_z) >> 16) -
5075  fixpoint_mul(v14, face->pFacePlane_old.vNormal.z)))
5076  return 0;
5077  *a2 = a10a >> 16;
5078  if (a10a >> 16 < 0) *a2 = 0;
5079  return 1;
5080 }
5081 
5082 bool sub_4754BF(int a1, int *a2, int X, int Y, int Z, int dir_x, int dir_y,
5083  int dir_z, BLVFace *face, int a10, int a11) {
5084  int v12; // ST1C_4@3
5085  int v13; // edi@3
5086  int v14; // esi@3
5087  int v15; // edi@4
5088  int64_t v16; // qtt@6
5089  // __int16 v17; // si@7
5090  int a7a; // [sp+30h] [bp+18h]@7
5091  int a1b; // [sp+38h] [bp+20h]@3
5092  int a1a; // [sp+38h] [bp+20h]@3
5093  int a11b; // [sp+40h] [bp+28h]@3
5094  int a11a; // [sp+40h] [bp+28h]@4
5095  int a11c; // [sp+40h] [bp+28h]@5
5096 
5097  if (a11 && face->Ethereal()) return false;
5098  v12 = fixpoint_mul(dir_x, face->pFacePlane_old.vNormal.x);
5099  a11b = fixpoint_mul(dir_y, face->pFacePlane_old.vNormal.y);
5100  a1b = fixpoint_mul(dir_z, face->pFacePlane_old.vNormal.z);
5101  v13 = v12 + a1b + a11b;
5102  a1a = v12 + a1b + a11b;
5103  v14 = (a1 << 16) - X * face->pFacePlane_old.vNormal.x -
5104  Y * face->pFacePlane_old.vNormal.y -
5105  Z * face->pFacePlane_old.vNormal.z - face->pFacePlane_old.dist;
5106  if (abs((a1 << 16) - X * face->pFacePlane_old.vNormal.x -
5107  Y * face->pFacePlane_old.vNormal.y -
5108  Z * face->pFacePlane_old.vNormal.z - face->pFacePlane_old.dist) >=
5109  a1 << 16) {
5110  a11c = abs(v14) >> 14;
5111  if (a11c > abs(v13)) return false;
5112  HEXRAYS_LODWORD(v16) = v14 << 16;
5113  HEXRAYS_HIDWORD(v16) = v14 >> 16;
5114  v15 = a1;
5115  a11a = v16 / a1a;
5116  } else {
5117  a11a = 0;
5118  v15 = abs(v14) >> 16;
5119  }
5120  // v17 = Y + ((unsigned int)fixpoint_mul(a11a, dir_y) >> 16);
5121  HEXRAYS_LOWORD(a7a) = (short)X +
5122  ((unsigned int)fixpoint_mul(a11a, dir_x) >> 16) -
5123  fixpoint_mul(v15, face->pFacePlane_old.vNormal.x);
5124  HEXRAYS_HIWORD(a7a) = Y + ((unsigned int)fixpoint_mul(a11a, dir_y) >> 16) -
5125  fixpoint_mul(v15, face->pFacePlane_old.vNormal.y);
5126  if (!sub_4759C9(face, a10, a7a,
5127  (short)Z + ((unsigned int)fixpoint_mul(a11a, dir_z) >> 16) -
5128  fixpoint_mul(v15, face->pFacePlane_old.vNormal.z)))
5129  return false;
5130  *a2 = a11a >> 16;
5131  if (a11a >> 16 < 0) *a2 = 0;
5132  return true;
5133 }
5134 
5135 int sub_475665(BLVFace *face, int a2, __int16 a3) {
5136  bool v16; // edi@14
5137  int v20; // ebx@18
5138  int v21; // edi@20
5139  int v22; // ST14_4@22
5140  __int64 v23; // qtt@22
5141  int result; // eax@25
5142  int v25; // [sp+14h] [bp-10h]@14
5143  int v26; // [sp+1Ch] [bp-8h]@2
5144  int v27; // [sp+20h] [bp-4h]@2
5145  int v28; // [sp+30h] [bp+Ch]@2
5146  int v29; // [sp+30h] [bp+Ch]@7
5147  int v30; // [sp+30h] [bp+Ch]@11
5148  int v31; // [sp+30h] [bp+Ch]@14
5149 
5150  if (face->uAttributes & FACE_XY_PLANE) {
5151  v26 = (signed __int16)a2;
5152  v27 = HEXRAYS_SHIWORD(a2);
5153  if (face->uNumVertices) {
5154  for (v28 = 0; v28 < face->uNumVertices; v28++) {
5155  word_720C10_intercepts_xs[2 * v28] =
5156  face->pXInterceptDisplacements[v28] +
5157  pIndoor->pVertices[face->pVertexIDs[v28]].x;
5158  word_720B40_intercepts_zs[2 * v28] =
5159  face->pYInterceptDisplacements[v28] +
5160  pIndoor->pVertices[face->pVertexIDs[v28]].y;
5161  word_720C10_intercepts_xs[2 * v28 + 1] =
5162  face->pXInterceptDisplacements[v28 + 1] +
5163  pIndoor->pVertices[face->pVertexIDs[v28 + 1]].x;
5164  word_720B40_intercepts_zs[2 * v28 + 1] =
5165  face->pYInterceptDisplacements[v28 + 1] +
5166  pIndoor->pVertices[face->pVertexIDs[v28 + 1]].y;
5167  }
5168  }
5169  } else {
5170  if (face->uAttributes & FACE_XZ_PLANE) {
5171  v26 = (signed __int16)a2;
5172  v27 = a3;
5173  if (face->uNumVertices) {
5174  for (v29 = 0; v29 < face->uNumVertices; v29++) {
5175  word_720C10_intercepts_xs[2 * v29] =
5176  face->pXInterceptDisplacements[v29] +
5177  pIndoor->pVertices[face->pVertexIDs[v29]].x;
5178  word_720B40_intercepts_zs[2 * v29] =
5179  face->pZInterceptDisplacements[v29] +
5180  pIndoor->pVertices[face->pVertexIDs[v29]].z;
5181  word_720C10_intercepts_xs[2 * v29 + 1] =
5182  face->pXInterceptDisplacements[v29 + 1] +
5183  pIndoor->pVertices[face->pVertexIDs[v29 + 1]].x;
5184  word_720B40_intercepts_zs[2 * v29 + 1] =
5185  face->pZInterceptDisplacements[v29 + 1] +
5186  pIndoor->pVertices[face->pVertexIDs[v29 + 1]].z;
5187  }
5188  }
5189  } else {
5190  v26 = HEXRAYS_SHIWORD(a2);
5191  v27 = a3;
5192  if (face->uNumVertices) {
5193  for (v30 = 0; v30 < face->uNumVertices; v30++) {
5194  word_720C10_intercepts_xs[2 * v30] =
5195  face->pYInterceptDisplacements[v30] +
5196  pIndoor->pVertices[face->pVertexIDs[v30]].y;
5197  word_720B40_intercepts_zs[2 * v30] =
5198  face->pZInterceptDisplacements[v30] +
5199  pIndoor->pVertices[face->pVertexIDs[v30]].z;
5200  word_720C10_intercepts_xs[2 * v30 + 1] =
5201  face->pYInterceptDisplacements[v30 + 1] +
5202  pIndoor->pVertices[face->pVertexIDs[v30 + 1]].y;
5203  word_720B40_intercepts_zs[2 * v30 + 1] =
5204  face->pZInterceptDisplacements[v30 + 1] +
5205  pIndoor->pVertices[face->pVertexIDs[v30 + 1]].z;
5206  }
5207  }
5208  }
5209  }
5210  v31 = 0;
5211  word_720C10_intercepts_xs[2 * face->uNumVertices] =
5213  word_720B40_intercepts_zs[2 * face->uNumVertices] =
5215  v16 = word_720B40_intercepts_zs[0] >= v27;
5216  if (2 * face->uNumVertices <= 0) return 0;
5217  for (v25 = 0; v25 < 2 * face->uNumVertices; ++v25) {
5218  if (v31 >= 2) break;
5219  if (v16 ^ (word_720B40_intercepts_zs[v25 + 1] >= v27)) {
5220  if (word_720C10_intercepts_xs[v25 + 1] >= v26)
5221  v20 = 0;
5222  else
5223  v20 = 2;
5224  v21 = v20 | (word_720C10_intercepts_xs[v25] < v26);
5225  if (v21 != 3) {
5226  v22 = word_720C10_intercepts_xs[v25 + 1] -
5228  HEXRAYS_LODWORD(v23) = v22 << 16;
5229  HEXRAYS_HIDWORD(v23) = v22 >> 16;
5230  if (!v21 ||
5232  ((signed int)(((unsigned __int64)(v23 /
5234  [v25 + 1] -
5236  [v25]) *
5237  ((v27 -
5238  (signed int)
5240  [v25])
5241  << 16)) >>
5242  16) +
5243  32768) >>
5244  16) >=
5245  v26))
5246  ++v31;
5247  }
5248  }
5249  v16 = word_720B40_intercepts_zs[v25 + 1] >= v27;
5250  }
5251  result = 1;
5252  if (v31 != 1) result = 0;
5253  return result;
5254 }
5255 
5256 bool sub_4759C9(BLVFace *face, int a2, int a3, __int16 a4) {
5257  bool v12; // edi@14
5258  signed int v16; // ebx@18
5259  int v17; // edi@20
5260  signed int v18; // ST14_4@22
5261  signed __int64 v19; // qtt@22
5262  bool result; // eax@25
5263  int v21; // [sp+14h] [bp-10h]@14
5264  signed int v22; // [sp+18h] [bp-Ch]@1
5265  int v23; // [sp+1Ch] [bp-8h]@2
5266  signed int v24; // [sp+20h] [bp-4h]@2
5267  signed int a4d; // [sp+30h] [bp+Ch]@14
5268 
5269  if (face->uAttributes & FACE_XY_PLANE) {
5270  v23 = (signed __int16)a3;
5271  v24 = HEXRAYS_SHIWORD(a3);
5272  if (face->uNumVertices) {
5273  for (v22 = 0; v22 < face->uNumVertices; ++v22) {
5275  face->pXInterceptDisplacements[v22] +
5276  LOWORD(pOutdoor->pBModels[a2]
5277  .pVertices.pVertices[face->pVertexIDs[v22]]
5278  .x);
5280  face->pYInterceptDisplacements[v22] +
5281  LOWORD(pOutdoor->pBModels[a2]
5282  .pVertices.pVertices[face->pVertexIDs[v22]]
5283  .y);
5284  word_720A70_intercepts_xs_plus_xs[2 * v22 + 1] =
5285  face->pXInterceptDisplacements[v22 + 1] +
5286  LOWORD(pOutdoor->pBModels[a2]
5287  .pVertices.pVertices[face->pVertexIDs[v22 + 1]]
5288  .x);
5289  word_7209A0_intercepts_ys_plus_ys[2 * v22 + 1] =
5290  face->pYInterceptDisplacements[v22 + 1] +
5291  LOWORD(pOutdoor->pBModels[a2]
5292  .pVertices.pVertices[face->pVertexIDs[v22 + 1]]
5293  .y);
5294  }
5295  }
5296  } else {
5297  if (face->uAttributes & FACE_XZ_PLANE) {
5298  v23 = (signed __int16)a3;
5299  v24 = a4;
5300  if (face->uNumVertices) {
5301  for (v22 = 0; v22 < face->uNumVertices; ++v22) {
5303  face->pXInterceptDisplacements[v22] +
5304  LOWORD(pOutdoor->pBModels[a2]
5305  .pVertices.pVertices[face->pVertexIDs[v22]]
5306  .x);
5308  face->pZInterceptDisplacements[v22] +
5309  LOWORD(pOutdoor->pBModels[a2]
5310  .pVertices.pVertices[face->pVertexIDs[v22]]
5311  .z);
5312  word_720A70_intercepts_xs_plus_xs[2 * v22 + 1] =
5313  face->pXInterceptDisplacements[v22 + 1] +
5314  LOWORD(
5315  pOutdoor->pBModels[a2]
5316  .pVertices.pVertices[face->pVertexIDs[v22 + 1]]
5317  .x);
5318  word_7209A0_intercepts_ys_plus_ys[2 * v22 + 1] =
5319  face->pZInterceptDisplacements[v22 + 1] +
5320  LOWORD(
5321  pOutdoor->pBModels[a2]
5322  .pVertices.pVertices[face->pVertexIDs[v22 + 1]]
5323  .z);
5324  }
5325  }
5326  } else {
5327  v23 = HEXRAYS_SHIWORD(a3);
5328  v24 = a4;
5329  if (face->uNumVertices) {
5330  for (v22 = 0; v22 < face->uNumVertices; ++v22) {
5332  face->pYInterceptDisplacements[v22] +
5333  LOWORD(pOutdoor->pBModels[a2]
5334  .pVertices.pVertices[face->pVertexIDs[v22]]
5335  .y);
5337  face->pZInterceptDisplacements[v22] +
5338  LOWORD(pOutdoor->pBModels[a2]
5339  .pVertices.pVertices[face->pVertexIDs[v22]]
5340  .z);
5341  word_720A70_intercepts_xs_plus_xs[2 * v22 + 1] =
5342  face->pYInterceptDisplacements[v22 + 1] +
5343  LOWORD(
5344  pOutdoor->pBModels[a2]
5345  .pVertices.pVertices[face->pVertexIDs[v22 + 1]]
5346  .y);
5347  word_7209A0_intercepts_ys_plus_ys[2 * v22 + 1] =
5348  face->pZInterceptDisplacements[v22 + 1] +
5349  LOWORD(
5350  pOutdoor->pBModels[a2]
5351  .pVertices.pVertices[face->pVertexIDs[v22 + 1]]
5352  .z);
5353  }
5354  }
5355  }
5356  }
5357  a4d = 0;
5358  word_720A70_intercepts_xs_plus_xs[2 * face->uNumVertices] =
5360  word_7209A0_intercepts_ys_plus_ys[2 * face->uNumVertices] =
5362  v12 = word_7209A0_intercepts_ys_plus_ys[0] >= v24;
5363  if (2 * face->uNumVertices <= 0) return 0;
5364  for (v21 = 0; v21 < 2 * face->uNumVertices; ++v21) {
5365  if (a4d >= 2) break;
5366  if (v12 ^ (word_7209A0_intercepts_ys_plus_ys[v21 + 1] >= v24)) {
5367  if (word_720A70_intercepts_xs_plus_xs[v21 + 1] >= v23)
5368  v16 = 0;
5369  else
5370  v16 = 2;
5371  v17 = v16 | (word_720A70_intercepts_xs_plus_xs[v21] < v23);
5372  if (v17 != 3) {
5373  v18 = word_720A70_intercepts_xs_plus_xs[v21 + 1] -
5375  HEXRAYS_LODWORD(v19) = v18 << 16;
5376  HEXRAYS_HIDWORD(v19) = v18 >> 16;
5377  if (!v17 ||
5379  ((signed int)(((unsigned __int64)(v19 /
5381  [v21 + 1] -
5383  [v21]) *
5384  ((v24 -
5385  (signed int)
5387  [v21])
5388  << 16)) >>
5389  16) +
5390  0x8000) >>
5391  16) >=
5392  v23))
5393  ++a4d;
5394  }
5395  }
5396  v12 = word_7209A0_intercepts_ys_plus_ys[v21 + 1] >= v24;
5397  }
5398  result = 1;
5399  if (a4d != 1) result = 0;
5400  return result;
5401 }
5402 
5403 bool sub_475D85(Vec3_int_ *a1, Vec3_int_ *a2, int *a3, BLVFace *a4) {
5404  BLVFace *v4; // ebx@1
5405  int v5; // ST24_4@2
5406  int v6; // ST28_4@2
5407  int v7; // edi@2
5408  int v8; // eax@5
5409  signed int v9; // esi@5
5410  signed __int64 v10; // qtt@10
5411  Vec3_int_ *v11; // esi@11
5412  int v12; // ST14_4@11
5413  Vec3_int_ *v14; // [sp+Ch] [bp-18h]@1
5414  Vec3_int_ *v15; // [sp+14h] [bp-10h]@1
5415  int v17; // [sp+20h] [bp-4h]@10
5416  int a4b; // [sp+30h] [bp+Ch]@2
5417  int a4c; // [sp+30h] [bp+Ch]@9
5418  int a4a; // [sp+30h] [bp+Ch]@10
5419 
5420  v4 = a4;
5421  v15 = a2;
5422  v14 = a1;
5423  v5 = fixpoint_mul(a2->x, a4->pFacePlane_old.vNormal.x);
5424  a4b = fixpoint_mul(a2->y, a4->pFacePlane_old.vNormal.y);
5425  v6 = fixpoint_mul(a2->z, v4->pFacePlane_old.vNormal.z);
5426  v7 = v5 + v6 + a4b;
5427  // (v16 = v5 + v6 + a4b) == 0;
5428  if (a4->uAttributes & FACE_ETHEREAL || !v7 || v7 > 0 && !v4->Portal())
5429  return 0;
5430  v8 = v4->pFacePlane_old.vNormal.z * a1->z;
5431  v9 = -(v4->pFacePlane_old.dist + v8 + a1->y * v4->pFacePlane_old.vNormal.y +
5432  a1->x * v4->pFacePlane_old.vNormal.x);
5433  if (v7 <= 0) {
5434  if (v4->pFacePlane_old.dist + v8 +
5435  a1->y * v4->pFacePlane_old.vNormal.y +
5436  a1->x * v4->pFacePlane_old.vNormal.x <
5437  0)
5438  return 0;
5439  } else {
5440  if (v9 < 0) return 0;
5441  }
5442  a4c = abs(-(v4->pFacePlane_old.dist + v8 +
5443  a1->y * v4->pFacePlane_old.vNormal.y +
5444  a1->x * v4->pFacePlane_old.vNormal.x)) >>
5445  14;
5446  v11 = v14;
5447  HEXRAYS_LODWORD(v10) = v9 << 16;
5448  HEXRAYS_HIDWORD(v10) = v9 >> 16;
5449  a4a = v10 / v7;
5450  v17 = v10 / v7;
5451  HEXRAYS_LOWORD(v12) =
5452  HEXRAYS_LOWORD(v14->x) +
5453  (((unsigned int)fixpoint_mul(v17, v15->x) + 0x8000) >> 16);
5454  HEXRAYS_HIWORD(v12) =
5455  HEXRAYS_LOWORD(v11->y) +
5456  (((unsigned int)fixpoint_mul(v17, v15->y) + 0x8000) >> 16);
5457  if (a4c > abs(v7) || (v17 > *a3 << 16) ||
5458  !sub_475665(
5459  v4, v12,
5460  LOWORD(v11->z) +
5461  (((unsigned int)fixpoint_mul(v17, v15->z) + 0x8000) >> 16)))
5462  return 0;
5463  *a3 = a4a >> 16;
5464  return 1;
5465 }
5466 
5467 bool sub_475F30(int *a1, BLVFace *a2, int a3, int a4, int a5, int a6, int a7,
5468  int a8, int a9) {
5469  int v10 = fixpoint_mul(a6, a2->pFacePlane_old.vNormal.x);
5470  int v11 = fixpoint_mul(a7, a2->pFacePlane_old.vNormal.y);
5471  int v12 = fixpoint_mul(a8, a2->pFacePlane_old.vNormal.z);
5472  int v13 = v10 + v12 + v11;
5473  int v14 = v10 + v12 + v11;
5474  int v22 = v10 + v12 + v11;
5475  if (a2->Ethereal() || !v13 || v14 > 0 && !a2->Portal()) {
5476  return false;
5477  }
5478  int v16 = -(a2->pFacePlane_old.dist + a4 * a2->pFacePlane_old.vNormal.y +
5479  a3 * a2->pFacePlane_old.vNormal.x +
5480  a5 * a2->pFacePlane_old.vNormal.z);
5481  if (v14 <= 0) {
5482  if (a2->pFacePlane_old.dist + a4 * a2->pFacePlane_old.vNormal.y +
5483  a3 * a2->pFacePlane_old.vNormal.x +
5484  a5 * a2->pFacePlane_old.vNormal.z <
5485  0)
5486  return 0;
5487  } else {
5488  if (v16 < 0) {
5489  return 0;
5490  }
5491  }
5492  int v17 =
5493  abs(-(a2->pFacePlane_old.dist + a4 * a2->pFacePlane_old.vNormal.y +
5494  a3 * a2->pFacePlane_old.vNormal.x +
5495  a5 * a2->pFacePlane_old.vNormal.z)) >>
5496  14;
5497  int64_t v18;
5498  HEXRAYS_LODWORD(v18) = v16 << 16;
5499  HEXRAYS_HIDWORD(v18) = v16 >> 16;
5500  int v24 = v18 / v22;
5501  int v23 = v18 / v22;
5502  int v19;
5503  HEXRAYS_LOWORD(v19) =
5504  a3 + (((unsigned int)fixpoint_mul(v23, a6) + 0x8000) >> 16);
5505  HEXRAYS_HIWORD(v19) =
5506  a4 + (((unsigned int)fixpoint_mul(v23, a7) + 0x8000) >> 16);
5507  if (v17 > abs(v14) || v23 > *a1 << 16 ||
5508  !sub_4759C9(
5509  a2, a9, v19,
5510  a5 + (((unsigned int)fixpoint_mul(v23, a8) + 0x8000) >> 16)))
5511  return 0;
5512  *a1 = v24 >> 16;
5513  return 1;
5514 }
5515 
5516 bool IsBModelVisible(BSPModel *model, int *reachable) {
5517  int v11; // esi@6
5518  int v12; // esi@8
5519  bool result; // eax@9
5520 
5521  int angle = (int)(pODMRenderParams->uCameraFovInDegrees << 11) / 360 / 2;
5522  int v3 = model->vBoundingCenter.x - pIndoorCameraD3D->vPartyPos.x;
5523  int v4 = model->vBoundingCenter.y - pIndoorCameraD3D->vPartyPos.y;
5525  int v17 = v3 * stru_5C6E00->Cos(pIndoorCameraD3D->sRotationY) +
5529  }
5530  int v19 = v4 * stru_5C6E00->Cos(pIndoorCameraD3D->sRotationY) -
5532  int v9 = int_get_vector_length(abs(v3), abs(v4), 0);
5533  // v10 = v14 * 188;
5534  // v22 = device_caps;
5535  *reachable = false;
5536  if (v9 < model->sBoundingRadius + 256) *reachable = true;
5537  if (v19 >= 0)
5538  v11 = fixpoint_mul(stru_5C6E00->Sin(angle), v17) -
5540  else
5541  v11 = fixpoint_mul(stru_5C6E00->Cos(angle), v19) +
5543  v12 = v11 >> 16;
5544  if (v9 <= pIndoorCameraD3D->GetFarClip() + 2048) {
5545  // if ( abs(v12) > *(int *)((char *)&pOutdoor->pBModels->sBoundingRadius
5546  // + v10) + 512 )
5547  if (abs(v12) > model->sBoundingRadius + 512) {
5548  result = v12 < 0;
5549  HEXRAYS_LOBYTE(result) = v12 >= 0;
5550  return result;
5551  } else {
5552  return true;
5553  }
5554  }
5555  return false;
5556 }
5557 
5558 // int Polygon::_479295() {
5559 // int v3; // ecx@4
5560 // int v4; // eax@4
5561 // int v5; // edx@4
5562 // Vec3_int_ thisa; // [sp+Ch] [bp-10h]@8
5563 // int v11; // [sp+18h] [bp-4h]@4
5564 //
5565 // if (!this->pODMFace->pFacePlane.vNormal.z) {
5566 // v3 = this->pODMFace->pFacePlane.vNormal.x;
5567 // v4 = -this->pODMFace->pFacePlane.vNormal.y;
5568 // v5 = 0;
5569 // v11 = 65536;
5570 // } else if ((this->pODMFace->pFacePlane.vNormal.x ||
5571 // this->pODMFace->pFacePlane.vNormal.y) &&
5572 // abs(this->pODMFace->pFacePlane.vNormal.z) < 59082) {
5573 // thisa.x = -this->pODMFace->pFacePlane.vNormal.y;
5574 // thisa.y = this->pODMFace->pFacePlane.vNormal.x;
5575 // thisa.z = 0;
5576 // thisa.Normalize_float();
5577 // v4 = thisa.x;
5578 // v3 = thisa.y;
5579 // v5 = 0;
5580 // v11 = 65536;
5581 // } else {
5582 // v3 = 0;
5583 // v4 = 65536;
5584 // v11 = 0;
5585 // v5 = -65536;
5586 // }
5587 // sTextureDeltaU = this->pODMFace->sTextureDeltaU;
5588 // sTextureDeltaV = this->pODMFace->sTextureDeltaV;
5589 // ptr_38->CalcSkyFrustumVec(v4, v3, 0, 0, v5, v11);
5590 // return 1;
5591 //}
5592 
5593 void sr_485F53(Vec2_int_ *v) {
5594  ++v->y;
5595  if (v->y > 1000) v->y = 0;
5596 }
5597 
5599  float len = sqrt((double)this->v_18.z * (double)this->v_18.z +
5600  (double)this->v_18.y * (double)this->v_18.y +
5601  (double)this->v_18.x * (double)this->v_18.x);
5602  if (fabsf(len) < 1e-6f) {
5603  v_18.x = 0;
5604  v_18.y = 0;
5605  v_18.z = 65536;
5606  } else {
5607  v_18.x = round_to_int((double)this->v_18.x / len * 65536.0);
5608  v_18.y = round_to_int((double)this->v_18.y / len * 65536.0);
5609  v_18.z = round_to_int((double)this->v_18.z / len * 65536.0);
5610  }
5611 }
5612 
5614  int v13; // edi@6
5615  int v14; // ecx@6
5616  int v15; // eax@8
5617  int v16; // eax@12
5618  int v32; // [sp+13Ch] [bp-28h]@6
5619  int v35; // [sp+148h] [bp-1Ch]@4
5620  int v36; // [sp+14Ch] [bp-18h]@2
5621  int v37; // [sp+154h] [bp-10h]@8
5622  int v39; // [sp+15Ch] [bp-8h]@4
5623 
5624 
5625  double rot_to_rads = ((2 * pi_double) / 2048);
5626 
5627  // lowers clouds as party goes up
5628  int horizon_height_offset =
5629  (signed __int64)((double)(pODMRenderParams->int_fov_rad * pIndoorCameraD3D->vPartyPos.z)
5630  / ((double)pODMRenderParams->int_fov_rad + 8192.0)
5631  + (double)(pViewport->uScreenCenterY));
5632 
5633  // magnitude in up direction
5634  signed __int64 cam_vec_up = cos((double)pIndoorCameraD3D->sRotationX * rot_to_rads) *
5636 
5637  int bot_y_proj = (signed __int64)((double)(pViewport->uScreenCenterY) -
5638  (double)pODMRenderParams->int_fov_rad /
5639  (cam_vec_up + 0.0000001) *
5640  (sin((double)pIndoorCameraD3D->sRotationX * rot_to_rads)
5641  *
5643  (double)pIndoorCameraD3D->vPartyPos.z));
5644 
5645  struct Polygon pSkyPolygon;
5646  pSkyPolygon.texture = nullptr;
5647  pSkyPolygon.ptr_38 = &SkyBillboard;
5648 
5649 
5650  // if ( pParty->uCurrentHour > 20 || pParty->uCurrentHour < 5 )
5651  // pSkyPolygon.uTileBitmapID = pOutdoor->New_SKY_NIGHT_ID;
5652  // else
5653  // pSkyPolygon.uTileBitmapID = pOutdoor->sSky_TextureID;//179(original 166)
5654  // pSkyPolygon.pTexture = (Texture_MM7 *)(pSkyPolygon.uTileBitmapID != -1 ?
5655  // (int)&pBitmaps_LOD->pTextures[pSkyPolygon.uTileBitmapID] : 0);
5656 
5657  pSkyPolygon.texture = pOutdoor->sky_texture;
5658  if (pSkyPolygon.texture) {
5659  pSkyPolygon.dimming_level = 0;
5660  pSkyPolygon.uNumVertices = 4;
5661 
5662  // centering(центруем)-----------------------------------------------------------------
5663  // plane of sky polygon rotation vector
5664  pSkyPolygon.v_18.x =
5666  pSkyPolygon.v_18.y = 0;
5667  pSkyPolygon.v_18.z =
5669 
5670  // sky wiew position(положение неба на
5671  // экране)------------------------------------------
5672  // X
5673  // 0._____________________________.3
5674  // |8,8 468,8 |
5675  // | |
5676  // | |
5677  // Y| |
5678  // | |
5679  // |8,351 468,351 |
5680  // 1._____________________________.2
5681  //
5683  (double)(signed int)pViewport->uViewportTL_X; // 8
5685  (double)(signed int)pViewport->uViewportTL_Y; // 8
5686 
5688  (double)(signed int)pViewport->uViewportTL_X; // 8
5689  VertexRenderList[1].vWorldViewProjY = (double)bot_y_proj + 1; // 247
5690 
5692  (double)(signed int)pViewport->uViewportBR_X; // 468
5693  VertexRenderList[2].vWorldViewProjY = (double)bot_y_proj + 1; // 247
5694 
5696  (double)(signed int)pViewport->uViewportBR_X; // 468
5698  (double)(signed int)pViewport->uViewportTL_Y; // 8
5699 
5700  double half_fov_angle_rads = ((pODMRenderParams->uCameraFovInDegrees - 1) * pi_double) / 360;
5701 
5702  // far width per pixel??
5703  int widthperpixel = 65536 /
5704  (signed int)(signed __int64)(((double)(pViewport->uViewportBR_X - pViewport->uViewportTL_X) / 2)
5705  / tan(half_fov_angle_rads) +
5706  0.5);
5707 
5708  for (uint i = 0; i < pSkyPolygon.uNumVertices; ++i) {
5709  // rotate skydome(вращение купола
5710  // неба)--------------------------------------
5711  // В игре принята своя система измерения углов. Полный угол (180).
5712  // Значению угла 0 соответствует направление на север и/или юг (либо
5713  // на восток и/или запад), значению 65536 еденицам(0х10000)
5714  // соответствует угол 90. две переменные хранят данные по углу
5715  // обзора. field_14 по западу и востоку. field_20 по югу и северу от
5716  // -25080 до 25080
5717 
5718  v13 = widthperpixel * (pViewport->uScreenCenterX -
5719  (signed __int64)VertexRenderList[i].vWorldViewProjX);
5720 
5721 
5722  v39 = fixpoint_mul(
5723  pSkyPolygon.ptr_38->CamVecLeft_Y,
5724  widthperpixel * (horizon_height_offset - floor(VertexRenderList[i].vWorldViewProjY + 0.5)));
5725  v35 = v39 + pSkyPolygon.ptr_38->CamVecLeft_Z;
5726 
5727  int skyfinalleft = v35 + fixpoint_mul(pSkyPolygon.ptr_38->CamVecLeft_X, v13);
5728 
5729  v39 = fixpoint_mul(
5730  pSkyPolygon.ptr_38->CamVecFront_Y,
5731  widthperpixel * (horizon_height_offset - floor(VertexRenderList[i].vWorldViewProjY + 0.f)));
5732  v36 = v39 + pSkyPolygon.ptr_38->CamVecFront_Z;
5733 
5734  int finalskyfront = v36 + fixpoint_mul(pSkyPolygon.ptr_38->CamVecFront_X, v13);
5735 
5736 
5737  int v9 = fixpoint_mul(
5738  pSkyPolygon.v_18.z,
5739  widthperpixel * (horizon_height_offset - floor(VertexRenderList[i].vWorldViewProjY + 0.5)));
5740 
5741 
5742 
5743 
5744  int top_y_proj = pSkyPolygon.v_18.x + v9;
5745  if (top_y_proj > 0) top_y_proj = 0;
5746 
5747  v32 = (signed __int64)VertexRenderList[i].vWorldViewProjY - 1.0;
5748  v14 = widthperpixel * (horizon_height_offset - v32);
5749  while (1) {
5750  if (top_y_proj) {
5751  v37 = 2048; // abs((int)cam_vec_up >> 14);
5752  v15 = abs(top_y_proj);
5753  if (v37 <= v15 ||
5754  v32 <= (signed int)pViewport->uViewportTL_Y) {
5755  if (top_y_proj <= 0) break;
5756  }
5757  }
5758  v16 = fixpoint_mul(pSkyPolygon.v_18.z, v14); // does this bit ever get called?
5759  --v32;
5760  v14 += widthperpixel;
5761  top_y_proj = pSkyPolygon.v_18.x + v16;
5762  }
5763 
5764  signed int worldviewdepth = (__int64(-512) * 65536 * 65536) / top_y_proj;
5765  if (worldviewdepth < 0) worldviewdepth = pIndoorCameraD3D->GetFarClip();
5766 
5767  int texoffset_U = 224 * pMiscTimer->uTotalGameTimeElapsed +
5768  ((signed int)fixpoint_mul(skyfinalleft, worldviewdepth) >> 3);
5769  VertexRenderList[i].u = (double)texoffset_U /
5770  ((double)pSkyPolygon.texture->GetWidth() * 65536.0);
5771 
5772  int texoffset_V = 224 * pMiscTimer->uTotalGameTimeElapsed +
5773  ((signed int)fixpoint_mul(finalskyfront, worldviewdepth) >> 3);
5774  VertexRenderList[i].v = (double)texoffset_V /
5775  ((double)pSkyPolygon.texture->GetHeight() * 65536.0);
5776 
5778  VertexRenderList[i]._rhw = 1.0 / (double)(worldviewdepth >> 16);
5779  }
5780 
5781  DrawOutdoorSkyPolygon(&pSkyPolygon);
5782 
5783  // adjust and draw again to fill gap below horizon
5784  // could mirror over??
5785 
5790 
5791  DrawOutdoorSkyPolygon(&pSkyPolygon);
5792  }
5793 }
5794 
5795 void Render::DrawIndoorSky(unsigned int uNumVertices, unsigned int uFaceID) { // can this be combined with outdoor or removed?
5796  BLVFace *pFace; // esi@1
5797  double v5; // st7@3
5798  signed __int64 v6; // qax@3
5799  int v12; // edx@7
5800  int v13; // eax@7
5801  int v17; // edi@9
5802  double v18; // st7@9
5803  signed int v19; // ebx@9
5804  void *v20; // ecx@9
5805  int v21; // ebx@11
5806  int v22; // eax@14
5807  signed __int64 v23; // qtt@16
5808  double v28; // st7@20
5809  double v33; // st6@23
5810  const void *v35; // ecx@31
5811  int v36; // eax@31
5812  const void *v37; // edi@31
5813  signed __int64 v38; // qax@31
5814  int v39; // ecx@31
5815  int v40; // ebx@33
5816  int v41; // eax@36
5817  signed __int64 v42; // qtt@39
5818  int v43; // eax@39
5819  double v48; // st7@41
5820  double v51; // st7@46
5821  struct Polygon pSkyPolygon; // [sp+14h] [bp-160h]@6
5822  unsigned int v63; // [sp+120h] [bp-54h]@7
5823  unsigned int v65; // [sp+128h] [bp-4Ch]@1
5824  unsigned int v66; // [sp+12Ch] [bp-48h]@7
5825  __int64 v69; // [sp+13Ch] [bp-38h]@3
5826  int v70; // [sp+144h] [bp-30h]@3
5827  int X; // [sp+148h] [bp-2Ch]@9
5828  int v72; // [sp+14Ch] [bp-28h]@7
5829  float v73; // [sp+150h] [bp-24h]@16
5830  unsigned int v74; // [sp+154h] [bp-20h]@3
5831  unsigned int v74_; // [sp+154h] [bp-20h]@3
5832  RenderVertexSoft *v75; // [sp+158h] [bp-1Ch]@3
5833  float v76; // [sp+15Ch] [bp-18h]@9
5834  int v77; // [sp+160h] [bp-14h]@9
5835  int v78; // [sp+164h] [bp-10h]@7
5836  void *v79; // [sp+168h] [bp-Ch]@9
5837  float v80; // [sp+16Ch] [bp-8h]@3
5838  const void *v81; // [sp+170h] [bp-4h]@7
5839 
5840  pFace = &pIndoor->pFaces[uFaceID];
5841  // for floor and wall(for example Selesta)-------------------
5843  pFace->uPolygonType == POLYGON_Floor) {
5844  int v69 = (OS_GetTime() / 32) - pIndoorCameraD3D->vPartyPos.x;
5845  int v55 = (OS_GetTime() / 32) + pIndoorCameraD3D->vPartyPos.y;
5846  for (uint i = 0; i < uNumVertices; ++i) {
5847  array_507D30[i].u = (v69 + array_507D30[i].u) * 0.25f;
5848  array_507D30[i].v = (v55 + array_507D30[i].v) * 0.25f;
5849  }
5850  render->DrawIndoorPolygon(uNumVertices, pFace,
5851  PID(OBJECT_BModel, uFaceID), -1, 0);
5852  return;
5853  }
5854  //---------------------------------------
5855  v70 = (signed __int64)((double)(pBLVRenderParams->bsp_fov_rad *
5856  pIndoorCameraD3D->vPartyPos.z) // 179
5857  / (((double)pBLVRenderParams->bsp_fov_rad +
5858  16192.0) *
5859  65536.0) +
5861  v5 = (double)pIndoorCameraD3D->sRotationX * 0.0030664064; // 0
5862  v6 = (signed __int64)((double)pBLVRenderParams->uViewportCenterY // 183
5863  - (double)pBLVRenderParams->bsp_fov_rad /
5864  ((cos(v5) * 16192.0 + 0.0000001) * 65535.0) *
5865  (sin(v5) * -16192.0 -
5866  (double)pIndoorCameraD3D->vPartyPos.z));
5867 
5868  SkyBillboard.CalcSkyFrustumVec(65536, 0, 0, 0, 65536, 0);
5869  // CalcSkyFrustumVec use as same
5870 
5871  pSkyPolygon.texture = nullptr;
5872  pSkyPolygon.ptr_38 = &SkyBillboard;
5873 
5874  // pSkyPolygon.uTileBitmapID = pFace->uBitmapID;
5875  pSkyPolygon.texture = pFace->GetTexture();
5876 
5877  // pSkyPolygon.pTexture =
5878  // pBitmaps_LOD->GetTexture(pSkyPolygon.uTileBitmapID);
5879  if (!pSkyPolygon.texture) return;
5880 
5881  pSkyPolygon.dimming_level = 0;
5882  pSkyPolygon.uNumVertices = uNumVertices;
5883 
5884  pSkyPolygon.v_18.x = -stru_5C6E00->Sin(pIndoorCameraD3D->sRotationX + 16);
5885  pSkyPolygon.v_18.y = 0;
5886  pSkyPolygon.v_18.z = -stru_5C6E00->Cos(pIndoorCameraD3D->sRotationX + 16);
5887 
5889  sizeof(array_507D30[uNumVertices]));
5890  pSkyPolygon.field_24 = 0x2000000;
5891 
5892  extern float _calc_fov(int viewport_width, int angle_degree);
5893  // v64 = (double)(signed int)(pBLVRenderParams->uViewportZ -
5894  // pBLVRenderParams->uViewportX) * 0.5; v72 = 65536 / (signed int)(signed
5895  // __int64)(v64 / tan(0.6457717418670654) + 0.5);
5896  v72 = 65536.0f /
5898  74);
5899  v12 = pSkyPolygon.texture->GetWidth() - 1;
5900  v13 = pSkyPolygon.texture->GetHeight() - 1;
5901  // v67 = 1.0 / (double)pSkyPolygon.pTexture->uTextureWidth;
5902  v63 = 224 * pMiscTimer->uTotalGameTimeElapsed & v13;
5903  v66 = 224 * pMiscTimer->uTotalGameTimeElapsed & v12;
5904  v78 = 0;
5905  // v81 = 0;
5906  float v68 = 1.0 / (double)pSkyPolygon.texture->GetHeight();
5907  if ((signed int)pSkyPolygon.uNumVertices <= 0) return;
5908 
5909  int _507D30_idx = 0;
5910  for (_507D30_idx; _507D30_idx < pSkyPolygon.uNumVertices; _507D30_idx++) {
5911  // v15 = (void *)(v72 * (v70 -
5912  // (int)array_507D30[_507D30_idx].vWorldViewProjY));
5913  v77 = fixpoint_mul(
5914  pSkyPolygon.ptr_38->CamVecLeft_Y,
5915  v72 * (v70 - array_507D30[_507D30_idx].vWorldViewProjY));
5916  v74 = v77 + pSkyPolygon.ptr_38->CamVecLeft_Z;
5917 
5918  v77 = fixpoint_mul(
5919  pSkyPolygon.ptr_38->CamVecFront_Y,
5920  v72 * (v70 - array_507D30[_507D30_idx].vWorldViewProjY));
5921  v74_ = v77 + pSkyPolygon.ptr_38->CamVecFront_Z;
5922 
5923  v79 = (void *)(fixpoint_mul(
5924  pSkyPolygon.v_18.z,
5925  v72 * (v70 - (int)array_507D30[_507D30_idx].vWorldViewProjY)));
5926  v17 = v72 * (pBLVRenderParams->uViewportCenterX -
5927  (int)array_507D30[_507D30_idx].vWorldViewProjX);
5928  v18 = array_507D30[_507D30_idx].vWorldViewProjY - 1.0;
5929  v19 = -pSkyPolygon.field_24;
5930  v77 = -pSkyPolygon.field_24;
5931  X = (int)((char *)v79 + pSkyPolygon.v_18.x);
5932  HEXRAYS_LODWORD(v76) = (signed __int64)v18;
5933  v20 = (void *)(v72 * (v70 - HEXRAYS_LODWORD(v76)));
5934  while (1) {
5935  v79 = v20;
5936  if (!X) goto LABEL_14;
5937  v21 = abs(v19 >> 14);
5938  if (v21 <= abs(X)) // 0x800 <= 0x28652
5939  break;
5940  if (HEXRAYS_SLODWORD(v76) <= (signed int)pViewport->uViewportTL_Y)
5941  break;
5942  v19 = v77;
5943  v20 = v79;
5944  LABEL_14:
5945  v79 = (void *)fixpoint_mul(pSkyPolygon.v_18.z, (int)v20);
5946  v22 = fixpoint_mul(pSkyPolygon.v_18.z, (int)v20);
5947  --HEXRAYS_LODWORD(v76);
5948  v20 = (char *)v20 + v72;
5949  X = v22 + pSkyPolygon.v_18.x;
5950  v78 = 1;
5951  }
5952  if (!v78) {
5953  HEXRAYS_LODWORD(v23) = v77 << 16;
5954  HEXRAYS_HIDWORD(v23) = v77 >> 16; // v23 = 0xfffffe0000000000
5955  v79 = (void *)(v23 / X); // X = FFFF9014(-28652)
5956  v77 = v17;
5957  __int64 s = v74 + fixpoint_mul(pSkyPolygon.ptr_38->CamVecLeft_X,
5958  v17); // s = 0xFFFFFFFF FFFF3EE6
5959  HEXRAYS_LODWORD(v80) =
5960  v66 +
5961  ((signed int)fixpoint_mul(HEXRAYS_SLODWORD(s), v23 / X) >> 4);
5962  array_507D30[_507D30_idx].u =
5963  ((double)HEXRAYS_SLODWORD(v80) * 0.000015259022) *
5964  (1.0 / (double)pSkyPolygon.texture->GetWidth());
5965 
5966  __int64 s2 =
5967  v74_ + fixpoint_mul(pSkyPolygon.ptr_38->CamVecFront_X, v17);
5968  HEXRAYS_LODWORD(v80) =
5969  v63 +
5970  ((signed int)fixpoint_mul(HEXRAYS_SLODWORD(s2), v23 / X) >> 4);
5971  array_507D30[_507D30_idx].v =
5972  ((double)HEXRAYS_SLODWORD(v80) * 0.000015259022) * v68;
5973 
5974  v77 = fixpoint_mul(HEXRAYS_SLODWORD(s), v23 / X);
5975  HEXRAYS_LODWORD(v73) = fixpoint_mul(HEXRAYS_SLODWORD(s2), v23 / X);
5976  array_507D30[_507D30_idx]._rhw = 65536.0 / (double)(signed int)v79;
5977 
5978  // if ( (int)v81 >= pSkyPolygon.uNumVertices )
5979  //{
5980  // render->DrawIndoorSkyPolygon(pSkyPolygon.uNumVertices,
5981  // &pSkyPolygon,
5982  // pBitmaps_LOD->pHardwareTextures[(signed
5983  // __int16)pSkyPolygon.uTileBitmapID]);
5984  // return;
5985  //}
5986  continue;
5987  }
5988  break;
5989  }
5990  if (_507D30_idx >= pSkyPolygon.uNumVertices) {
5991  DrawIndoorSkyPolygon(pSkyPolygon.uNumVertices, &pSkyPolygon);
5992  return;
5993  }
5994  HEXRAYS_LODWORD(v73) = 0;
5995  v80 = v76;
5996  if ((signed int)pSkyPolygon.uNumVertices > 0) {
5997  v28 = (double)HEXRAYS_SLODWORD(v76);
5998  HEXRAYS_LODWORD(v76) = (int)(char *)VertexRenderList + 28;
5999  uint i = 0;
6000  for (v78 = pSkyPolygon.uNumVertices; v78; --v78) {
6001  ++HEXRAYS_LODWORD(v73);
6002  memcpy(&VertexRenderList[i], &array_507D30[i], 0x30u);
6003  HEXRAYS_LODWORD(v76) += 48;
6004  if (v28 < array_507D30[i].vWorldViewProjY |
6005  v28 == array_507D30[i].vWorldViewProjY ||
6006  v28 >= array_507D30[i + 1].vWorldViewProjY) {
6007  if (v28 >= array_507D30[i].vWorldViewProjY ||
6008  v28 <= array_507D30[i + 1].vWorldViewProjY) {
6009  i++;
6010  continue;
6011  }
6012  v33 = (array_507D30[i + 1].vWorldViewProjX -
6014  v28 /
6015  (array_507D30[i + 1].vWorldViewProjY -
6016  array_507D30[i].vWorldViewProjY) +
6018  } else {
6019  v33 = (array_507D30[i].vWorldViewProjX -
6020  array_507D30[i + 1].vWorldViewProjX) *
6021  v28 /
6022  (array_507D30[i].vWorldViewProjY -
6023  array_507D30[i + 1].vWorldViewProjY) +
6025  }
6026  VertexRenderList[i + 1].vWorldViewProjX = v33;
6027  ++HEXRAYS_LODWORD(v73);
6028  *(unsigned int *)HEXRAYS_LODWORD(v76) = v28;
6029  HEXRAYS_LODWORD(v76) += 48;
6030  i++;
6031  }
6032  }
6033  if (HEXRAYS_SLODWORD(v73) <= 0) goto LABEL_40;
6034  // v34 = (char *)&VertexRenderList[0].vWorldViewProjY;
6035  uint j = 0;
6036  v65 = v77 >> 14;
6037  // HIDWORD(v69) = LODWORD(v73);
6038  for (int t = (int)HEXRAYS_LODWORD(v73); t > 1; t--) {
6039  v35 = (const void *)(v72 * (v70 - (unsigned __int64)(signed __int64)
6040  VertexRenderList[j]
6041  .vWorldViewProjY));
6042 
6043  // v78 = pSkyPolygon.ptr_38->viewing_angle_from_west_east;
6044  // v81 = (const void
6045  // *)fixpoint_mul(pSkyPolygon.ptr_38->viewing_angle_from_west_east, v35);
6046  v36 =
6047  (int)(fixpoint_mul(pSkyPolygon.ptr_38->CamVecLeft_Y,
6048  (int)v35) +
6049  pSkyPolygon.ptr_38->CamVecLeft_Z);
6050 
6051  v81 = v35;
6052  v74 = v36;
6053  // v78 = pSkyPolygon.ptr_38->viewing_angle_from_north_south;
6054  v81 = (const void *)fixpoint_mul(
6055  pSkyPolygon.ptr_38->CamVecFront_Y, (int)v35);
6056  v78 = (int)v35;
6057  v75 = (RenderVertexSoft *)((char *)v81 +
6058  pSkyPolygon.ptr_38->CamVecFront_Z);
6059  // v81 = (const void *)pSkyPolygon.v_18.z;
6060  v78 = fixpoint_mul(pSkyPolygon.v_18.z, (int)v35);
6061  v37 = (const void *)(v72 * (pBLVRenderParams->uViewportCenterX -
6062  (unsigned __int64)(signed __int64)
6063  VertexRenderList[j]
6064  .vWorldViewProjX));
6065  v38 = (signed __int64)(VertexRenderList[j].vWorldViewProjY - 1.0);
6066  v81 = 0;
6067  HEXRAYS_LODWORD(v76) = v38;
6068  v39 = v72 * (v70 - v38);
6069  while (1) {
6070  v78 = v39;
6071  if (!X) goto LABEL_36;
6072  v40 = abs(X);
6073  if (abs((signed __int64)v65) <= v40) break;
6074  if (HEXRAYS_SLODWORD(v76) <= (signed int)pViewport->uViewportTL_Y)
6075  break;
6076  v39 = v78;
6077  LABEL_36:
6078  v78 = pSkyPolygon.v_18.z;
6079  v41 = fixpoint_mul(pSkyPolygon.v_18.z, v39);
6080  --HEXRAYS_LODWORD(v76);
6081  v39 += v72;
6082  X = v41 + pSkyPolygon.v_18.x;
6083  v81 = (const void *)1;
6084  }
6085  if (v81) {
6086  v79 = (void *)pSkyPolygon.v_18.z;
6087  v78 = 2 * HEXRAYS_LODWORD(v76);
6088  v81 = (const void *)fixpoint_mul(
6089  pSkyPolygon.v_18.z,
6090  (((double)v70 - ((double)(2 * HEXRAYS_LODWORD(v76)) -
6091  VertexRenderList[j].vWorldViewProjY)) *
6092  (double)v72));
6093  X = (int)((char *)v81 + pSkyPolygon.v_18.x);
6094  }
6095  HEXRAYS_LODWORD(v42) = v77 << 16;
6096  HEXRAYS_HIDWORD(v42) = v77 >> 16;
6097  v79 = (void *)(v42 / X);
6098  v81 = v37;
6099 
6100  // v78 = pSkyPolygon.ptr_38->angle_from_west;
6101  v81 = (const void *)fixpoint_mul(pSkyPolygon.ptr_38->CamVecLeft_X,
6102  (int)v37);
6103  v43 = v74 + fixpoint_mul(pSkyPolygon.ptr_38->CamVecLeft_X, (int)v37);
6104  v74 = (unsigned int)v37;
6105  HEXRAYS_LODWORD(v76) = v43;
6106 
6107  // v78 = pSkyPolygon.ptr_38->angle_from_south;
6108  v75 = (RenderVertexSoft *)((char *)v75 +
6109  fixpoint_mul(
6110  pSkyPolygon.ptr_38->CamVecFront_X,
6111  (int)v37));
6112  // v74 = fixpoint_mul(v43, v42 / X);
6113  v81 = (const void *)fixpoint_mul((int)v75, v42 / X);
6114 
6115  // v34 += 48;
6116  // v78 = v66 + ((signed int)fixpoint_mul(v43, v42 / X) >> 4);
6117  // v44 = HIDWORD(v69)-- == 1;
6118  // v45 = (double)(v66 + ((signed int)fixpoint_mul(v43, v42 / X) >> 4)) *
6119  // 0.000015259022; v78 = v63 + ((signed int)fixpoint_mul((int)v75, v42 /
6120  // X) >> 4);
6121  VertexRenderList[j].u =
6122  ((double)(v66 + ((signed int)fixpoint_mul(v43, v42 / X) >> 4)) *
6123  0.000015259022) *
6124  (1.0 / (double)pSkyPolygon.texture->GetWidth());
6125  VertexRenderList[j].v =
6126  ((double)(v66 + ((signed int)fixpoint_mul(v43, v42 / X) >> 4)) *
6127  0.000015259022) *
6128  v68;
6129  // v46 = (double)(signed int)v79;
6131  0.000015258789 * (double)(signed int)v79;
6132  VertexRenderList[j]._rhw = 65536.0 / (double)(signed int)v79;
6133  ++j;
6134  }
6135  // while ( !v44 );
6136 LABEL_40:
6137  uint i = 0;
6138  if (HEXRAYS_SLODWORD(v73) > 0) {
6139  v48 = (double)HEXRAYS_SLODWORD(v80);
6140  for (HEXRAYS_HIDWORD(v69) = HEXRAYS_LODWORD(v73); HEXRAYS_HIDWORD(v69);
6141  --HEXRAYS_HIDWORD(v69)) {
6142  if (v48 >= VertexRenderList[i].vWorldViewProjY) {
6143  ++i;
6144  memcpy(&array_507D30[i], &VertexRenderList[i], 0x30u);
6145  }
6146  }
6147  }
6148  pSkyPolygon.uNumVertices = i;
6149  DrawIndoorSkyPolygon(pSkyPolygon.uNumVertices, &pSkyPolygon);
6150  int pNumVertices = 0;
6151  if (HEXRAYS_SLODWORD(v73) > 0) {
6152  v51 = (double)HEXRAYS_SLODWORD(v80);
6153  for (v80 = v73; v80 != 0.0; --HEXRAYS_LODWORD(v80)) {
6154  if (v51 <= VertexRenderList[pNumVertices].vWorldViewProjY) {
6155  ++pNumVertices;
6156  memcpy(&array_507D30[pNumVertices],
6157  &VertexRenderList[pNumVertices], 0x30u);
6158  }
6159  }
6160  }
6161  DrawIndoorSkyPolygon(pNumVertices, &pSkyPolygon);
6162 }
6163 
6164 void Render::DrawOutdoorSkyPolygon(struct Polygon *pSkyPolygon) {
6165  if (uNumD3DSceneBegins == 0) {
6166  return;
6167  }
6168 
6169  unsigned int uNumVertices = pSkyPolygon->uNumVertices;
6170  TextureD3D *texture = (TextureD3D *)pSkyPolygon->texture;
6171 
6172  if (uNumVertices >= 3) {
6173  this->pRenderD3D->pDevice->SetTextureStageState(0, D3DTSS_ADDRESS,
6174  D3DTADDRESS_WRAP);
6175  if (config->is_using_specular) {
6176  this->pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_ALPHABLENDENABLE, TRUE);
6177  this->pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_SRCBLEND, D3DBLEND_ONE);
6178  this->pRenderD3D->pDevice->SetRenderState(D3DRENDERSTATE_DESTBLEND, D3DBLEND_ZERO);
6179  }
6180  for (unsigned int i = 0; i < uNumVertices; ++i) {
6183  pVertices[i].pos.z = 0.99989998;
6185 
6186  pVertices[i].diffuse = ::GetActorTintColor(31, 0, VertexRenderList[i].vWorldViewPosition.x, 1, 0);
6187  int v7 = 0;
6188  if (config->is_using_specular)
6189  v7 = sub_47C3D7_get_fog_specular(0, 1, VertexRenderList[i].vWorldViewPosition.x);
6190  pVertices[i].specular = v7;
6193  }
6194  pRenderD3D->pDevice->SetTexture(0, texture->GetDirect3DTexture());
6195  pRenderD3D->pDevice->DrawPrimitive(
6196  D3DPT_TRIANGLEFAN,
6197  D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR | D3DFVF_TEX1,
6199  D3DDP_DONOTUPDATEEXTENTS | D3DDP_DONOTLIGHT);
6200  }
6201 }
6202 
6203 void Render::DrawIndoorSkyPolygon(int uNumVertices, struct Polygon *pSkyPolygon) {
6204  TextureD3D *texture = (TextureD3D *)pSkyPolygon->texture;
6205 
6206  if (uNumD3DSceneBegins == 0) {
6207  return;
6208  }
6209 
6210  if (uNumVertices >= 3) {
6211  ErrD3D(pRenderD3D->pDevice->SetTextureStageState(0, D3DTSS_ADDRESS,
6212  D3DTADDRESS_WRAP));
6213  int v5 = 31 - (pSkyPolygon->dimming_level & 0x1F);
6214  if (v5 < pOutdoor->max_terrain_dimming_level) {
6216  }
6217  for (uint i = 0; i < (unsigned int)uNumVertices; ++i) {
6220  d3d_vertex_buffer[i].pos.z =
6221  1.0 -
6222  1.0 / (array_507D30[i].vWorldViewPosition.x * 0.061758894);
6225  8 * v5 | ((8 * v5 | (v5 << 11)) << 8);
6226  d3d_vertex_buffer[i].specular = 0;
6229  }
6230  ErrD3D(
6231  pRenderD3D->pDevice->SetTexture(0, texture->GetDirect3DTexture()));
6232  ErrD3D(pRenderD3D->pDevice->DrawPrimitive(
6233  D3DPT_TRIANGLEFAN,
6234  D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR | D3DFVF_TEX1,
6236  }
6237 }
sr_485F53
void sr_485F53(Vec2_int_ *v)
Definition: Render.cpp:5593
stru141_actor_collision_object::field_50
int field_50
Definition: Indoor.h:163
BLVFace::uPolygonType
PolygonType uPolygonType
Definition: Indoor.h:487
uint16_t
unsigned __int16 uint16_t
Definition: SDL_config.h:37
ArcomageGame::pSprites
Texture * pSprites
Definition: Arcomage.h:150
RenderBillboardD3D::Opaque_2
@ Opaque_2
Definition: IRender.h:152
OBJECT_DESC_NO_COLLISION
@ OBJECT_DESC_NO_COLLISION
Definition: ObjectList.h:7
LightsStack_StationaryLight_::uNumLightsActive
unsigned int uNumLightsActive
Definition: Lights.h:65
Render::RemoveTextureFromDevice
virtual void RemoveTextureFromDevice(Texture *texture)
Definition: Render.cpp:2455
Render::DrawTextureGrayShade
virtual void DrawTextureGrayShade(float u, float v, class Image *a4)
Definition: Render.cpp:2841
Particle_sw::z
float z
Definition: ParticleEngine.h:22
OutdoorLocationTerrain::pHeightmap
uint8_t * pHeightmap
Definition: Outdoor.h:55
Render::GetActorTintColor
virtual unsigned int GetActorTintColor(int DimLevel, int tint, float WorldViewX, int a5, RenderBillboard *Billboard)
Definition: Render.cpp:1810
Vec3_float_
Definition: VectorTypes.h:74
sub_46DEF2
unsigned int sub_46DEF2(signed int a2, unsigned int uLayingItemID)
Definition: Render.cpp:4947
ParticleEngine.h
MobileLight
Definition: Lights.h:21
BLVFace::Portal
bool Portal() const
Definition: Indoor.h:448
LevelDecorationChangeSeason
SpriteFrame * LevelDecorationChangeSeason(DecorationDesc *desc, int t, int month)
Definition: Sprites.cpp:614
Party::vPosition
Vec3_int_ vPosition
Definition: Party.h:250
Engine_::IocContainer
Definition: IocContainer.h:15
Polygon::field_32
__int16 field_32
Definition: Polygon.h:36
BSPModel::pVertices
struct BSPVertexBuffer pVertices
Definition: BSPModel.h:189
face
GLenum GLuint GLint GLenum face
Definition: SDL_opengl_glext.h:3022
s
GLdouble s
Definition: SDL_opengl.h:2063
stru154
Definition: Indoor.h:229
pNew_LOD
LOD::WriteableFile * pNew_LOD
Definition: LOD.cpp:24
Render::gdiplusStartupInput
Gdiplus::GdiplusStartupInput gdiplusStartupInput
Definition: Render.h:209
int_get_vector_length
uint32_t int_get_vector_length(int32_t x, int32_t y, int32_t z)
Definition: VectorTypes.cpp:8
Decal::uNumVertices
int uNumVertices
Definition: DecalBuilder.h:108
Render::RenderTerrainD3D
virtual void RenderTerrainD3D()
Definition: Render.cpp:214
SpriteFrame::hw_sprites
Sprite * hw_sprites[8]
Definition: Sprites.h:46
array_507D30
RenderVertexSoft array_507D30[50]
Definition: RenderOpenGL.cpp:58
sub_47531C
bool sub_47531C(int a1, int *a2, int pos_x, int pos_y, int pos_z, int dir_x, int dir_y, int dir_z, BLVFace *face, int a10)
Definition: Render.cpp:5027
pLevelDecorations
std::array< LevelDecoration, 3000 > pLevelDecorations
Definition: Decoration.cpp:8
SpellFX_Billboard
Definition: SpellFxRenderer.h:13
DecorationDesc_mm6::uFlags
int16_t uFlags
Definition: DecorationList.h:44
mask
GLenum GLint GLuint mask
Definition: SDL_opengl_glext.h:660
RenderBillboard::hwsprite
Sprite * hwsprite
Definition: IRender.h:32
Render::RasterLine2D
virtual void RasterLine2D(int uX, int uY, int uZ, int uW, uint16_t uColor)
Definition: Render.cpp:1638
Dying
@ Dying
Definition: Actor.h:79
Viewport.h
Render::SavePCXImage16
void SavePCXImage16(const String &filename, uint16_t *picture_data, int width, int height)
Definition: Render.cpp:1157
Particle_sw::b
float b
Definition: ParticleEngine.h:25
ODMFace::zCalc1
int zCalc1
Definition: BSPModel.h:132
Timer::uTimeElapsed
unsigned int uTimeElapsed
Definition: Time.h:133
IndoorCameraD3D::sRotationY
int sRotationY
Definition: IndoorCameraD3D.h:247
v
const GLdouble * v
Definition: SDL_opengl.h:2064
Party::uCurrentMonth
unsigned int uCurrentMonth
Definition: Party.h:272
stru141_actor_collision_object::field_6C
int field_6C
Definition: Indoor.h:168
Polygon::sTextureDeltaU
int sTextureDeltaU
Definition: Polygon.h:33
LOD.h
Image::GetHeight
unsigned int GetHeight()
Definition: Image.cpp:230
ODMFace::pYInterceptDisplacements
int16_t pYInterceptDisplacements[20]
Definition: BSPModel.h:140
DecorationList::GetDecoration
DecorationDesc * GetDecoration(unsigned int index)
Definition: DecorationList.h:65
RenderBillboard::screen_space_x
int16_t screen_space_x
Definition: IRender.h:39
Render::SavePCXScreenshot
virtual void SavePCXScreenshot()
Definition: Render.cpp:1126
SkyBillboardStruct::CamVecLeft_Y
int CamVecLeft_Y
Definition: IRender.h:473
Render::ClearTarget
virtual void ClearTarget(unsigned int uColor)
Definition: Render.cpp:1174
BLVFace::pFacePlane_old
struct Plane_int_ pFacePlane_old
Definition: Indoor.h:471
Render::CreateTexture_Alpha
virtual Texture * CreateTexture_Alpha(const String &name)
Definition: Render.cpp:88
Lights
LightsData Lights
Definition: Indoor.cpp:54
Vec2::x
T x
Definition: VectorTypes.h:12
SpriteFrame::uGlowRadius
int uGlowRadius
Definition: Sprites.h:49
ODMRenderParams::uNumBillboards
unsigned int uNumBillboards
Definition: IRender.h:90
Render::DrawBuildingsD3D
virtual void DrawBuildingsD3D()
Definition: Render.cpp:3510
DecorationList.h
Render::DrawTextureCustomHeight
virtual void DrawTextureCustomHeight(float u, float v, class Image *, int height)
Definition: Render.cpp:2795
RenderD3D::pFrontBuffer
IDirectDrawSurface4 * pFrontBuffer
Definition: RenderD3D.h:96
Rect::x
int x
Definition: Rect.h:4
DecalBuilder::ApplyBloodSplatToTerrain
bool ApplyBloodSplatToTerrain(struct Polygon *a2, Vec3_float_ *a3, float *a4, struct RenderVertexSoft *a5, unsigned int uStripType, char a7)
Definition: DecalBuilder.cpp:392
dstX
GLenum GLint GLint GLint GLint GLuint GLenum GLint GLint dstX
Definition: SDL_opengl_glext.h:2453
pSpriteFrameTable
struct SpriteFrameTable * pSpriteFrameTable
Definition: Sprites.cpp:22
IndoorLocation::pSectors
struct BLVSector * pSectors
Definition: Indoor.h:634
Render::GetBillboardDrawListSize
unsigned int GetBillboardDrawListSize()
Definition: Render.cpp:1768
OutdoorLocation::pBModels
BSPModelList pBModels
Definition: Outdoor.h:119
pSpriteObjects
std::array< SpriteObject, MAX_SPRITE_OBJECTS > pSpriteObjects
Definition: SpriteObject.cpp:34
pSprites_LOD
LODFile_Sprites * pSprites_LOD
Definition: LOD.cpp:20
stru141_actor_collision_object::sMaxZ
int sMaxZ
Definition: Indoor.h:180
Viewport::uViewportTL_Y
int uViewportTL_Y
Definition: Viewport.h:23
Render::AreRenderSurfacesOk
virtual bool AreRenderSurfacesOk()
Definition: Render.cpp:210
RenderBillboard::uIndoorSectorID
int16_t uIndoorSectorID
Definition: IRender.h:34
Lightmap::NumVertices
signed int NumVertices
Definition: LightmapBuilder.h:17
Polygon
Definition: Polygon.h:14
DecorationDesc::uColoredLightRed
uint8_t uColoredLightRed
Definition: DecorationList.h:50
PCX::Encode16
void Encode16(const void *picture_data, unsigned int width, unsigned int height, void *pcx_data, int max_buff_size, unsigned int *packed_size)
Definition: PCX.cpp:297
OBJECT_Item
@ OBJECT_Item
Definition: Actor.h:66
Sprites_LOD_Loader
Definition: ImageLoader.h:137
Vec3_float_::x
float x
Definition: VectorTypes.h:89
BSPModel::index
unsigned int index
Definition: BSPModel.h:167
RenderBase::Initialize
virtual bool Initialize(OSWindow *window)
Definition: RenderBase.cpp:22
uNumTerrainNormals
uint32_t uNumTerrainNormals
Definition: mm7_data.cpp:755
stru141_actor_collision_object::uSectorID
unsigned int uSectorID
Definition: Indoor.h:170
RenderBillboardD3D::Opaque_1
@ Opaque_1
Definition: IRender.h:151
IMAGE_FORMAT_R8G8B8A8
@ IMAGE_FORMAT_R8G8B8A8
Definition: Image.h:9
Render::do_draw_debug_line_d3d
virtual void do_draw_debug_line_d3d(const RenderVertexD3D3 *pLineBegin, signed int sDiffuseBegin, const RenderVertexD3D3 *pLineEnd, signed int sDiffuseEnd, float z_stuff)
Definition: Render.cpp:3876
Render::ClearZBuffer
virtual void ClearZBuffer(int a2, int a3)
Definition: Render.cpp:1648
pArcomageGame
ArcomageGame * pArcomageGame
Definition: Arcomage.cpp:97
RenderVertexD3D3::pos
Vec3_float_ pos
Definition: IRender.h:130
Rect::w
int w
Definition: Rect.h:7
RenderD3D__DevInfo
Definition: RenderD3D.h:19
Render::uNumD3DSceneBegins
unsigned int uNumD3DSceneBegins
Definition: Render.h:203
z
GLdouble GLdouble z
Definition: SDL_opengl_glext.h:407
Render::PresentBlackScreen
virtual void PresentBlackScreen()
Definition: Render.cpp:1115
pBLVRenderParams
BLVRenderParams * pBLVRenderParams
Definition: Indoor.cpp:50
_43F5C8_get_point_light_level_with_respect_to_lights
int _43F5C8_get_point_light_level_with_respect_to_lights(unsigned int uBaseLightLevel, int uSectorID, float x, float y, float z)
Definition: Render.cpp:4229
RenderVertexSoft::u
float u
Definition: IRender.h:121
ArcomageGame::pBlit_Copy_pixels
uint16_t * pBlit_Copy_pixels
Definition: Arcomage.h:144
height
EGLSurface EGLint EGLint EGLint EGLint height
Definition: SDL_egl.h:1596
ODM_Project
void ODM_Project(unsigned int uNumVertices)
Definition: Outdoor.cpp:2180
ODMRenderParams::uNumPolygons
int uNumPolygons
Definition: IRender.h:86
Render::DrawTextureOffset
virtual void DrawTextureOffset(int x, int y, int offset_x, int offset_y, Image *)
Definition: Render.cpp:2815
Render::DrawDecal
virtual void DrawDecal(struct Decal *pDecal, float z_bias)
Definition: Render.cpp:3968
Render::DrawBorderTiles
void DrawBorderTiles(struct Polygon *poly)
Definition: Render.cpp:701
Render::Update_Texture
virtual void Update_Texture(Texture *texture)
Definition: Render.cpp:2448
Render::DrawBillboards_And_MaybeRenderSpecialEffects_And_EndScene
virtual void DrawBillboards_And_MaybeRenderSpecialEffects_And_EndScene()
Definition: Render.cpp:1800
ODMRenderParams::uMapGridCellX
unsigned int uMapGridCellX
Definition: IRender.h:105
OutdoorLocation::sky_texture
Texture * sky_texture
Definition: Outdoor.h:123
Render::EndLightmaps2
virtual void EndLightmaps2()
Definition: Render.cpp:3864
RenderD3D::pHost
IDirectDraw4 * pHost
Definition: RenderD3D.h:92
Decal
Definition: DecalBuilder.h:98
POLYGON_InBetweenFloorAndWall
@ POLYGON_InBetweenFloorAndWall
Definition: Indoor.h:221
BBox_short_::x1
int16_t x1
Definition: VectorTypes.h:114
SpriteObject.h
Render::EndScene
virtual void EndScene()
Definition: Render.cpp:2512
engine
std::shared_ptr< Engine > engine
Definition: Engine.cpp:130
Render::BitmapWithImage
Gdiplus::Bitmap * BitmapWithImage(Image *image)
Definition: Render.cpp:2742
BSPModel::sMaxX
int32_t sMaxX
Definition: BSPModel.h:177
SpriteFrame::scale
fixed scale
Definition: Sprites.h:47
Color32_SwapRedBlue
uint32_t Color32_SwapRedBlue(uint16_t color16)
Definition: Render.cpp:2733
Render::TexturePixelRotateDraw
virtual void TexturePixelRotateDraw(float u, float v, Image *img, int time)
Definition: Render.cpp:2947
Rect::z
int z
Definition: Rect.h:6
Render::bWindowMode
unsigned int bWindowMode
Definition: Render.h:198
Texture
Definition: Texture.h:4
game_viewport_width
unsigned int game_viewport_width
Definition: mm7_data.cpp:194
Render::DrawSpecialEffectsQuad
virtual void DrawSpecialEffectsQuad(const RenderVertexD3D3 *vertices, Texture *texture)
Definition: Render.cpp:4044
Render::Present_NoColorKey
friend void Present_NoColorKey()
Definition: Render.cpp:1245
RenderBillboard::dimming_level
uint16_t dimming_level
Definition: IRender.h:43
SoftwareBillboard::screenspace_projection_factor_y
float screenspace_projection_factor_y
Definition: IRender.h:177
Render::MoveTextureToDevice
virtual bool MoveTextureToDevice(Texture *texture)
Definition: Render.cpp:2465
IRender::pBeforePresentFunction
void(* pBeforePresentFunction)()
Definition: IRender.h:427
SpellFX_Billboard::local_01::x
float x
Definition: SpellFxRenderer.h:36
Alpha_LOD_Loader
Definition: ImageLoader.h:57
BSPModel::sBoundingRadius
int32_t sBoundingRadius
Definition: BSPModel.h:187
round_to_int
int round_to_int(float x)
Definition: OurMath.h:18
Render::pRenderD3D
RenderD3D * pRenderD3D
Definition: Render.h:199
ObjectDesc
Definition: ObjectList.h:20
Render::DrawIndoorSky
virtual void DrawIndoorSky(unsigned int uNumVertices, unsigned int uFaceID)
Definition: Render.cpp:5795
Polygon::field_59
char field_59
Definition: Polygon.h:49
RenderBillboardD3D::OpacityType
OpacityType
Definition: IRender.h:149
ODMFace::zCalc3
int zCalc3
Definition: BSPModel.h:134
srcX
GLenum GLint GLint srcX
Definition: SDL_opengl_glext.h:2453
Render::EndLightmaps
virtual void EndLightmaps()
Definition: Render.cpp:3832
IRender::vis
Vis * vis
Definition: IRender.h:436
Decal::pVertices
RenderVertexSoft pVertices[64]
Definition: DecalBuilder.h:109
Render
Definition: Render.h:20
LEVEL_null
@ LEVEL_null
Definition: Indoor.h:285
Render::DrawImage
virtual void DrawImage(Image *, const Rect &rect)
Definition: Render.cpp:2829
Point::x
unsigned int x
Definition: Point.h:7
sub_475F30
bool sub_475F30(int *a1, BLVFace *a2, int a3, int a4, int a5, int a6, int a7, int a8, int a9)
Definition: Render.cpp:5467
Render::DrawTransparentGreenShade
virtual void DrawTransparentGreenShade(float u, float v, class Image *pTexture)
Definition: Render.cpp:2916
IndoorCameraD3D::sRotationX
int sRotationX
Definition: IndoorCameraD3D.h:248
RenderBillboardD3D::field_90
int field_90
Definition: IRender.h:163
Render::SaveScreenshot
virtual void SaveScreenshot(const String &filename, unsigned int width, unsigned int height)
Definition: Render.cpp:3757
Render::CreateTexture_Blank
virtual Texture * CreateTexture_Blank(unsigned int width, unsigned int height, IMAGE_FORMAT format, const void *pixels=nullptr)
Definition: Render.cpp:104
RenderVertexD3D3
Definition: IRender.h:129
BBox_short_::y1
int16_t y1
Definition: VectorTypes.h:116
PaletteManager.h
LightmapBuilder.h
Color32
uint32_t Color32(uint16_t color16)
Definition: Engine.cpp:135
RenderBillboard::screen_space_z
int16_t screen_space_z
Definition: IRender.h:41
UpdateObjects
void UpdateObjects()
Definition: Render.cpp:4955
stru141_actor_collision_object::normal
Vec3_int_ normal
Definition: Indoor.h:159
PCX.h
int64_t
__int64 int64_t
Definition: alext.h:31
SoftwareBillboard::screenspace_projection_factor_x
float screenspace_projection_factor_x
Definition: IRender.h:176
Render::WritePixel16
virtual void WritePixel16(int x, int y, uint16_t color)
Definition: Render.cpp:122
Render::ScreenFade
virtual void ScreenFade(unsigned int color, float t)
Definition: Render.cpp:2514
RenderBillboard::world_z
int16_t world_z
Definition: IRender.h:38
RenderBillboardD3D::Transparent
@ Transparent
Definition: IRender.h:150
SkyBillboardStruct::CamVecLeft_Z
int CamVecLeft_Z
Definition: IRender.h:471
RenderD3D.h
Sprite::uBufferHeight
int uBufferHeight
Definition: Sprites.h:32
Render::SetBillboardBlendOptions
void SetBillboardBlendOptions(RenderBillboardD3D::OpacityType a1)
Definition: Render.cpp:3253
Render::DrawLightmap
virtual bool DrawLightmap(struct Lightmap *pLightmap, struct Vec3_float_ *pColorMult, float z_bias)
Definition: Render.cpp:1395
Lightmap::uColorMask
unsigned int uColorMask
Definition: LightmapBuilder.h:23
SpriteFrame::uPaletteIndex
int uPaletteIndex
Definition: Sprites.h:51
OutdoorLocation::fFogDensity
float fFogDensity
Definition: Outdoor.h:176
ODMFace::uPolygonType
uint8_t uPolygonType
Definition: BSPModel.h:156
texture
GLenum GLenum GLuint texture
Definition: SDL_opengl_glext.h:1181
SpellFxRenderer.h
sub_475665
int sub_475665(BLVFace *face, int a2, __int16 a3)
Definition: Render.cpp:5135
Particle_sw::r
float r
Definition: ParticleEngine.h:23
Render::CreateTexture_ColorKey
virtual Texture * CreateTexture_ColorKey(const String &name, uint16_t colorkey)
Definition: Render.cpp:80
POLYGON_Floor
@ POLYGON_Floor
Definition: Indoor.h:220
IndoorLocation::pLights
struct BLVLightMM7 * pLights
Definition: Indoor.h:636
OBJECT_Decoration
@ OBJECT_Decoration
Definition: Actor.h:69
ImageLoader.h
RenderBillboardD3D::z_order
float z_order
Definition: IRender.h:161
Lightmap
Definition: LightmapBuilder.h:12
SoftwareBillboard::field_44
int field_44
Definition: IRender.h:187
Sprite::texture
Texture * texture
Definition: Sprites.h:28
SpellFX_Billboard::field_104
local_01 field_104[5]
Definition: SpellFxRenderer.h:53
RenderBillboard::pSpriteFrame
SpriteFrame * pSpriteFrame
Definition: IRender.h:45
HWLTexture
Definition: HWLContainer.h:9
Vec3_float_::y
float y
Definition: VectorTypes.h:90
BSPModel::sMinZ
int32_t sMinZ
Definition: BSPModel.h:176
stru154::ClassifyPolygon
void ClassifyPolygon(struct Vec3_float_ *pNormal, float dist)
Definition: Indoor.cpp:5578
Vec3_float_::z
float z
Definition: VectorTypes.h:91
index
GLuint index
Definition: SDL_opengl_glext.h:663
DecorationDesc_mm6::uRadius
int16_t uRadius
Definition: DecorationList.h:41
RenderVertexSoft::vWorldViewProjY
float vWorldViewProjY
Definition: IRender.h:119
game_viewport_height
unsigned int game_viewport_height
Definition: mm7_data.cpp:195
PCX_LOD_Loader
Definition: ImageLoader.h:108
BBox_short_::z2
int16_t z2
Definition: VectorTypes.h:119
Render::ResetUIClipRect
virtual void ResetUIClipRect()
Definition: Render.cpp:2728
IRender::decal_builder
DecalBuilder * decal_builder
Definition: IRender.h:432
BLVRenderParams::bsp_fov_rad
int bsp_fov_rad
Definition: Indoor.h:692
pIndoor
IndoorLocation * pIndoor
Definition: Indoor.cpp:49
RenderBase::Billboard_ProbablyAddToListAndSortByZOrder
unsigned int Billboard_ProbablyAddToListAndSortByZOrder(float z)
Definition: RenderBase.cpp:49
BLVSector::pLights
uint16_t * pLights
Definition: Indoor.h:556
Engine.h
Lights.h
LightmapBuilder::DrawLightmaps
void DrawLightmaps(int indices)
Definition: LightmapBuilder.cpp:802
collide_against_floor
int collide_against_floor(int x, int y, int z, unsigned int *pSectorID, unsigned int *pFaceID)
Definition: Render.cpp:4711
PARTY_BUFF_TORCHLIGHT
@ PARTY_BUFF_TORCHLIGHT
Definition: Party.h:87
Render::DrawMasked
virtual void DrawMasked(float u, float v, class Image *img, unsigned int color_dimming_level, uint16_t mask)
Definition: Render.cpp:2924
Sprite
Definition: Sprites.h:10
Plane_int_::vNormal
Vec3_int_ vNormal
Definition: VectorTypes.h:107
Render::~Render
virtual ~Render()
Definition: Render.cpp:1095
BLVSector::uNumWalls
uint16_t uNumWalls
Definition: Indoor.h:527
Dead
@ Dead
Definition: Actor.h:80
Render::RestoreBackBuffer
virtual void RestoreBackBuffer()
Definition: Render.cpp:1754
result
GLuint64EXT * result
Definition: SDL_opengl_glext.h:9435
OBJECT_DESC_INTERACTABLE
@ OBJECT_DESC_INTERACTABLE
Definition: ObjectList.h:12
Polygon::field_24
int field_24
Definition: Polygon.h:32
Party::pPartyBuffs
std::array< SpellBuff, 20 > pPartyBuffs
Definition: Party.h:309
RenderVertexD3D3::texcoord
Vec2_float_ texcoord
Definition: IRender.h:134
OutdoorLocation::DoGetTile
TileDesc * DoGetTile(int uX, int uZ)
Definition: Outdoor.cpp:1389
Render::BeginScene
virtual void BeginScene()
Definition: Render.cpp:2510
HWLContainer::LoadTexture
HWLTexture * LoadTexture(const String &pName)
Definition: HWLContainer.cpp:88
OBJECT_Actor
@ OBJECT_Actor
Definition: Actor.h:67
RenderBillboard::field_1E
int16_t field_1E
Definition: IRender.h:35
BLVSector::uNumFloors
uint16_t uNumFloors
Definition: Indoor.h:524
Vis::DoesRayIntersectBillboard
bool DoesRayIntersectBillboard(float fDepth, unsigned int uD3DBillboardIdx)
Definition: Vis.cpp:1418
Render::GetParentBillboardID
unsigned int GetParentBillboardID(unsigned int uBillboardID)
Definition: Render.cpp:1772
BLVRenderParams::uViewportZ
unsigned int uViewportZ
Definition: Indoor.h:698
fixed::FromInt
static fixed FromInt(int value)
Definition: OurMath.h:29
Party::uPartyHeight
unsigned int uPartyHeight
Definition: Party.h:237
Actor.h
ODMFace::pBoundingBox
struct BBox_short_ pBoundingBox
Definition: BSPModel.h:145
SpellFX_Billboard::local_01::z
float z
Definition: SpellFxRenderer.h:38
IMAGE_FORMAT_A8R8G8B8
@ IMAGE_FORMAT_A8R8G8B8
Definition: Image.h:7
_4E94D0_light_type
char _4E94D0_light_type
Definition: mm7_data.cpp:305
OSWindow
Definition: OSWindow.h:12
Particle_sw::type
unsigned int type
Definition: ParticleEngine.h:19
Sprite::uAreaY
int uAreaY
Definition: Sprites.h:30
RenderVertexSoft::vWorldViewPosition
Vec3_float_ vWorldViewPosition
Definition: IRender.h:117
Render::Present
virtual void Present()
Definition: Render.cpp:1178
format
SDL_AudioFormat format
Definition: SDL_audio.h:194
ODM_NearClip
int ODM_NearClip(unsigned int num_vertices)
Definition: Render.cpp:3296
Render::BeginSceneD3D
virtual void BeginSceneD3D()
Definition: Render.cpp:1776
RenderD3D::pAvailableDevices
RenderD3D__DevInfo * pAvailableDevices
Definition: RenderD3D.h:91
pWeather
Weather * pWeather
Definition: Weather.cpp:8
IRender::SetUsingSpecular
void SetUsingSpecular(bool is_using_specular)
Definition: IRender.h:402
pVertices
struct RenderVertexD3D3 pVertices[50]
Definition: Render.cpp:50
Bitmaps_LOD_Loader
Definition: ImageLoader.h:122
y
EGLSurface EGLint EGLint y
Definition: SDL_egl.h:1596
Render::LockSurface_DDraw4
bool LockSurface_DDraw4(IDirectDrawSurface4 *pSurface, DDSURFACEDESC2 *pDesc, unsigned int uLockFlags)
Definition: Render.cpp:1678
RenderVertexD3D3::rhw
float rhw
Definition: IRender.h:131
Image::GetWidth
unsigned int GetWidth()
Definition: Image.cpp:217
Render::bRequiredTextureStagesAvailable
unsigned int bRequiredTextureStagesAvailable
Definition: Render.h:204
OutdoorLocation::GetSomeOtherTileInfo
int GetSomeOtherTileInfo(int sX, int sY)
Definition: Outdoor.cpp:197
IMAGE_FORMAT_R8G8B8
@ IMAGE_FORMAT_R8G8B8
Definition: Image.h:8
IRender::uFogColor
uint32_t uFogColor
Definition: IRender.h:422
array_73D150
RenderVertexSoft array_73D150[20]
Definition: Render.cpp:53
Render::pDirectDraw4
IDirectDraw4 * pDirectDraw4
Definition: Render.h:192
LevelDecoration::vPosition
Vec3_int_ vPosition
Definition: Decoration.h:28
IndoorCameraD3D::vPartyPos
Vec3< int > vPartyPos
Definition: IndoorCameraD3D.h:253
Render::DrawTransparentRedShade
virtual void DrawTransparentRedShade(float u, float v, class Image *a4)
Definition: Render.cpp:2920
BLVFace::Ethereal
bool Ethereal() const
Definition: Indoor.h:459
Render::DoRenderBillboards_D3D
void DoRenderBillboards_D3D()
Definition: Render.cpp:3210
IRender::log
Log * log
Definition: IRender.h:431
Render::RestoreFrontBuffer
virtual void RestoreFrontBuffer()
Definition: Render.cpp:1748
Vec2::y
T y
Definition: VectorTypes.h:13
Sprite::uBufferWidth
int uBufferWidth
Definition: Sprites.h:31
_452442_color_cvt
unsigned int _452442_color_cvt(unsigned __int16 a1, unsigned __int16 a2, int a3, int a4)
Definition: Render.cpp:4081
Render::BeginLightmaps
virtual void BeginLightmaps()
Definition: Render.cpp:3811
srcY
GLenum GLint GLint GLint srcY
Definition: SDL_opengl_glext.h:2453
BSPModel::sMinY
int32_t sMinY
Definition: BSPModel.h:175
RenderBase
Definition: RenderBase.h:6
Render::CheckTextureStages
bool CheckTextureStages()
Definition: Render.cpp:135
Decal::field_C18
DecalBuilder_stru0 * field_C18
Definition: DecalBuilder.h:116
stru141_actor_collision_object::field_0
int field_0
Definition: Indoor.h:151
pParty
Party * pParty
Definition: Party.cpp:30
Polygon::dimming_level
char dimming_level
Definition: Polygon.h:48
Image
Definition: Image.h:19
len
GLenum GLsizei len
Definition: SDL_opengl_glext.h:2929
Polygon::texture
Texture * texture
Definition: Polygon.h:39
ODMRenderParams::shading_dist_shade
int shading_dist_shade
Definition: IRender.h:74
bankersRounding
int bankersRounding(const FloatType &value)
Definition: OurMath.h:98
Render::CreateClipper
void CreateClipper(OSWindow *)
Definition: Render.cpp:1738
object
GLuint object
Definition: SDL_opengl_glext.h:6060
ODM_FarClip
int ODM_FarClip(unsigned int uNumVertices)
Definition: Render.cpp:3394
_46ED8A_collide_against_sprite_objects
void _46ED8A_collide_against_sprite_objects(unsigned int _this)
Definition: Render.cpp:4732
RenderVertexSoft::vWorldViewProjX
float vWorldViewProjX
Definition: IRender.h:118
ODMFace::pVertexIDs
uint16_t pVertexIDs[20]
Definition: BSPModel.h:136
SoftwareBillboard
Definition: IRender.h:170
Polygon::uNumVertices
unsigned int uNumVertices
Definition: Polygon.h:30
Render::SaveWinnersCertificate
virtual void SaveWinnersCertificate(const char *a1)
Definition: Render.cpp:1133
stru141_actor_collision_object::field_8_radius
int field_8_radius
Definition: Indoor.h:153
BLVRenderParams::uViewportW
unsigned int uViewportW
Definition: Indoor.h:699
stru141_actor_collision_object::sMinY
int sMinY
Definition: Indoor.h:179
LEVEL_DECORATION_INVISIBLE
@ LEVEL_DECORATION_INVISIBLE
Definition: Decoration.h:14
RenderBillboard::uPalette
int16_t uPalette
Definition: IRender.h:33
RenderBillboard
Definition: IRender.h:26
p
GLfloat GLfloat p
Definition: SDL_opengl_glext.h:11093
RenderBillboard::object_pid
uint16_t object_pid
Definition: IRender.h:42
pTerrainNormals
struct Vec3_float_ * pTerrainNormals
Definition: mm7_data.cpp:756
ODMFace::pXInterceptDisplacements
int16_t pXInterceptDisplacements[20]
Definition: BSPModel.h:139
Render::DrawMonsterPortrait
virtual void DrawMonsterPortrait(Rect rc, SpriteFrame *Portrait, int Y_Offset)
Definition: Render.cpp:3120
stru141_actor_collision_object::normal2
Vec3_int_ normal2
Definition: Indoor.h:161
Render::uTargetGBits
unsigned int uTargetGBits
Definition: Render.h:201
OBJECT_BModel
@ OBJECT_BModel
Definition: Actor.h:70
SpriteObject::UpdateObject_fn0_BLV
static void UpdateObject_fn0_BLV(unsigned int uLayingItemID)
Definition: SpriteObject.cpp:463
PCX::Encode32
void Encode32(const void *picture_data, unsigned int width, unsigned int height, void *pcx_data, int max_buff_size, unsigned int *packed_size)
Definition: PCX.cpp:305
BLVSector::pPortals
uint16_t * pPortals
Definition: Indoor.h:538
Render::uDesiredDirect3DDevice
unsigned int uDesiredDirect3DDevice
Definition: Render.h:196
x
EGLSurface EGLint x
Definition: SDL_egl.h:1596
Render::GetActorsInViewport
virtual int GetActorsInViewport(int pDepth)
Definition: Render.cpp:3772
Render::PrepareDecorationsRenderList_ODM
virtual void PrepareDecorationsRenderList_ODM()
Definition: Render.cpp:713
Render::ParseTargetPixelFormat
void ParseTargetPixelFormat()
Definition: Render.cpp:1652
sub_4759C9
bool sub_4759C9(BLVFace *face, int a2, int a3, __int16 a4)
Definition: Render.cpp:5256
BLVSector::uNumLights
uint16_t uNumLights
Definition: Indoor.h:554
Render::BlendTextures
virtual void BlendTextures(int x, int y, Image *imgin, Image *imgblend, int time, int start_opacity, int end_opacity)
Definition: Render.cpp:3038
color
GLuint color
Definition: SDL_opengl_glext.h:1151
SkyBillboardStruct::CalcSkyFrustumVec
void CalcSkyFrustumVec(int a2, int a3, int a4, int a5, int a6, int a7)
Definition: RenderOpenGL.cpp:62
Render::TakeScreenshot
virtual Image * TakeScreenshot(unsigned int width, unsigned int height)
Definition: Render.cpp:3751
_43F55F_get_billboard_light_level
int _43F55F_get_billboard_light_level(RenderBillboard *a1, int uBaseLightLevel)
Definition: Render.cpp:4211
IRender::lightmap_builder
LightmapBuilder * lightmap_builder
Definition: IRender.h:434
Particle_sw::timeToLive
int timeToLive
Definition: ParticleEngine.h:27
stru141_actor_collision_object::field_7C
int field_7C
Definition: Indoor.h:172
src
GLenum src
Definition: SDL_opengl_glext.h:1740
SpriteFrameTable::GetFrame
SpriteFrame * GetFrame(unsigned int uSpriteID, unsigned int uTime)
Definition: Sprites.cpp:277
Render::DrawTextureNew
virtual void DrawTextureNew(float u, float v, class Image *)
Definition: Render.cpp:2811
Log::Info
void Info(const wchar_t *pFormat,...)
Definition: Log.cpp:11
OS_GetTime
unsigned int OS_GetTime()
Definition: Lin.cpp:12
Disabled
@ Disabled
Definition: Actor.h:94
DecalBuilder_stru0::_43B570_get_color_mult_by_time
double _43B570_get_color_mult_by_time()
Definition: DecalBuilder.cpp:17
IRender::particle_engine
ParticleEngine * particle_engine
Definition: IRender.h:435
IRender::SetUsingFog
void SetUsingFog(bool is_using_fog)
Definition: IRender.h:409
Viewport::SetFOV
void SetFOV(float fov)
Definition: Viewport.cpp:62
RenderBase::pD3DBitmaps
HWLContainer pD3DBitmaps
Definition: RenderBase.h:32
DecorationDesc_mm6::CanMoveThrough
bool CanMoveThrough()
Definition: DecorationList.h:26
Polygon::v_18
Vec3_int_ v_18
Definition: Polygon.h:31
SoftwareBillboard::screen_space_z
short screen_space_z
Definition: IRender.h:175
RenderBase::PostInitialization
void PostInitialization()
Definition: RenderBase.cpp:38
ODMRenderParams::uCameraFovInDegrees
unsigned int uCameraFovInDegrees
Definition: IRender.h:78
_46BFFA_update_spell_fx
bool _46BFFA_update_spell_fx(unsigned int uLayingItemID, int a2)
Definition: SpriteObject.cpp:1017
_46E889_collide_against_bmodels
void _46E889_collide_against_bmodels(unsigned int ecx0)
Definition: Render.cpp:4516
BBox_short_::y2
int16_t y2
Definition: VectorTypes.h:117
BLVFace::uSectorID
uint16_t uSectorID
Definition: Indoor.h:484
BLVLightMM7::uAtributes
int16_t uAtributes
Definition: Indoor.h:364
IMAGE_FORMAT_R5G6B5
@ IMAGE_FORMAT_R5G6B5
Definition: Image.h:5
BLVFace
Definition: Indoor.h:424
Render::pBackBuffer4
IDirectDrawSurface4 * pBackBuffer4
Definition: Render.h:194
Render::BltBackToFontFast
virtual void BltBackToFontFast(int a2, int a3, Rect *pSrcRect)
Definition: Render.cpp:1760
IndoorLocation::Draw
void Draw()
Definition: Indoor.cpp:322
Present_NoColorKey
void Present_NoColorKey()
Definition: Render.cpp:1245
Render::DrawBillboard_Indoor
virtual void DrawBillboard_Indoor(SoftwareBillboard *pSoftBillboard, RenderBillboard *billboard)
Definition: Render.cpp:2140
OBJECT_DESC_TEMPORARY
@ OBJECT_DESC_TEMPORARY
Definition: ObjectList.h:8
RenderD3D::HandleLostResources
void HandleLostResources()
Definition: RenderD3D.cpp:856
RenderBase::window
OSWindow * window
Definition: RenderBase.h:25
IndoorCameraD3D::ViewClip
bool ViewClip(int x, int y, int z, int *transformed_x, int *transformed_y, int *transformed_z, bool dont_show=false)
Definition: IndoorCameraD3D.cpp:172
v1
GLfloat GLfloat v1
Definition: SDL_opengl_glext.h:694
Sprite::uAreaWidth
int uAreaWidth
Definition: Sprites.h:33
RenderD3D::pDevice
IDirect3DDevice3 * pDevice
Definition: RenderD3D.h:98
stride
EGLImageKHR EGLint EGLint EGLint * stride
Definition: SDL_egl.h:1497
Polygon::_normalize_v_18
void _normalize_v_18()
Definition: Render.cpp:5598
ObjectDesc::uFlags
int16_t uFlags
Definition: ObjectList.h:27
width
EGLSurface EGLint EGLint EGLint width
Definition: SDL_egl.h:1596
Render::pDefaultZBuffer
int * pDefaultZBuffer
Definition: Render.h:197
Log::Warning
void Warning(const wchar_t *pFormat,...)
Definition: Log.cpp:28
PCX_File_Loader
Definition: ImageLoader.h:77
pIcons_LOD
LODFile_IconsBitmaps * pIcons_LOD
Definition: LOD.cpp:12
RenderVertexD3D3::diffuse
unsigned int diffuse
Definition: IRender.h:132
IRender::pBillboardRenderListD3D
RenderBillboardD3D pBillboardRenderListD3D[1000]
Definition: IRender.h:428
IndoorCameraD3D::Project
void Project(int x, int y, int z, int *screenspace_x, int *screenspace_y)
Definition: IndoorCameraD3D.cpp:1137
LevelDecoration::uFlags
uint16_t uFlags
Definition: Decoration.h:27
Render::DrawBillboardList_BLV
virtual void DrawBillboardList_BLV()
Definition: Render.cpp:178
Render::EndDecals
virtual void EndDecals()
Definition: Render.cpp:3955
Render::_4A4CC9_AddSomeBillboard
virtual void _4A4CC9_AddSomeBillboard(struct SpellFX_Billboard *a1, int diffuse)
Definition: Render.cpp:2382
DecalBuilder::ApplyDecals
char ApplyDecals(int light_level, char a3, struct stru154 *a4, int a5, struct RenderVertexSoft *a6, struct IndoorCameraD3D_Vec4 *a7, char a8, unsigned int uSectorID)
Definition: DecalBuilder.cpp:67
fixpoint_mul
__int64 fixpoint_mul(int a1, int a2)
Definition: OurMath.cpp:138
DecalBuilder::ApplyDecals_OutdoorFace
char ApplyDecals_OutdoorFace(ODMFace *pFace)
Definition: DecalBuilder.cpp:358
SkyBillboardStruct::CamVecFront_Z
int CamVecFront_Z
Definition: IRender.h:474
pActors
std::array< Actor, 500 > pActors
Definition: Actor.cpp:38
int32_t
signed __int32 int32_t
Definition: SDL_config.h:38
TextureD3D::GetDirect3DTexture
IDirect3DTexture2 * GetDirect3DTexture()
Definition: TextureD3D.cpp:57
Render::LoadHwlBitmap
virtual HWLTexture * LoadHwlBitmap(const char *name)
Definition: Render.cpp:2440
Render::MakeScreenshot
unsigned short * MakeScreenshot(signed int width, signed int height)
Definition: Render.cpp:3698
Polygon::uBModelID
unsigned __int8 uBModelID
Definition: Polygon.h:54
Arcomage.h
LightsStack_MobileLight_::pLights
MobileLight pLights[400]
Definition: Lights.h:87
BSPModel::sMinX
int32_t sMinX
Definition: BSPModel.h:174
Party.h
Render::DrawFansTransparent
virtual void DrawFansTransparent(const RenderVertexD3D3 *vertices, unsigned int num_vertices)
Definition: Render.cpp:3905
Render::DrawText
virtual void DrawText(int uOutX, int uOutY, uint8_t *pFontPixels, unsigned int uCharWidth, unsigned int uCharHeight, uint8_t *pFontPalette, uint16_t uFaceColor, uint16_t uShadowColor)
Definition: Render.cpp:2857
Particle_sw
Definition: ParticleEngine.h:18
BLVRenderParams::uViewportCenterY
int uViewportCenterY
Definition: Indoor.h:705
Viewport::uViewportBR_X
int uViewportBR_X
Definition: Viewport.h:24
uNumLevelDecorations
size_t uNumLevelDecorations
Definition: Decoration.cpp:9
Render::DrawProjectile
virtual void DrawProjectile(float srcX, float srcY, float a3, float a4, float dstX, float dstY, float a7, float a8, Texture *texture)
Definition: Render.cpp:2277
window
EGLSurface EGLNativeWindowType * window
Definition: SDL_egl.h:1580
Render::gdiplusToken
ULONG_PTR gdiplusToken
Definition: Render.h:210
Render::PackScreenshot
virtual void PackScreenshot(unsigned int width, unsigned int height, void *out_data, unsigned int data_size, unsigned int *screenshot_size)
Definition: Render.cpp:3764
BLVRenderParams::uViewportX
unsigned int uViewportX
Definition: Indoor.h:696
Party::uFlags
unsigned int uFlags
Definition: Party.h:313
f
GLfloat f
Definition: SDL_opengl_glext.h:1873
_46EF01_collision_chech_player
int _46EF01_collision_chech_player(int a1)
Definition: Render.cpp:4790
Decal::field_C1C
int field_C1C
Definition: DecalBuilder.h:117
RenderD3D::CreateDevice
bool CreateDevice(unsigned int uDeviceID, int bWindowed, OSWindow *window)
Definition: RenderD3D.cpp:291
Weather.h
Render::uMinDeviceTextureDim
unsigned int uMinDeviceTextureDim
Definition: Render.h:206
Render::DrawIndoorSkyPolygon
void DrawIndoorSkyPolygon(int uNumVertices, struct Polygon *pSkyPolygon)
Definition: Render.cpp:6203
RenderBillboardD3D::uNumVertices
unsigned int uNumVertices
Definition: IRender.h:159
pDDrawClipper
struct IDirectDrawClipper * pDDrawClipper
Definition: Render.cpp:49
BLVSector::uNumPortals
int16_t uNumPortals
Definition: Indoor.h:536
ODMFace::resource
void * resource
Definition: BSPModel.h:142
LEVEL_Outdoor
@ LEVEL_Outdoor
Definition: Indoor.h:287
Particle_sw::y
float y
Definition: ParticleEngine.h:21
_50BF30_actors_in_viewport_ids
std::array< int, 100 > _50BF30_actors_in_viewport_ids
Definition: mm7_data.cpp:567
Viewport::uScreenCenterY
int uScreenCenterY
Definition: Viewport.h:29
Rect
Definition: Rect.h:3
Particle_sw::g
float g
Definition: ParticleEngine.h:24
ODMFace::uNumVertices
uint8_t uNumVertices
Definition: BSPModel.h:155
Render::DrawTextAlpha
virtual void DrawTextAlpha(int x, int y, uint8_t *font_pixels, int a5, unsigned int uFontHeight, uint8_t *pPalette, bool present_time_transparency)
Definition: Render.cpp:2880
stru154::GetFacePlaneAndClassify
void GetFacePlaneAndClassify(struct ODMFace *a2, struct BSPVertexBuffer *a3)
Definition: Indoor.cpp:5554
ddpfPrimarySuface
DDPIXELFORMAT ddpfPrimarySuface
Definition: Render.cpp:57
SpellFX_Billboard::uNumVertices
int uNumVertices
Definition: SpellFxRenderer.h:49
AssetsManager::GetBitmap
Texture * GetBitmap(const String &name)
Definition: AssetsManager.cpp:126
Render::DeleteTexture
virtual void DeleteTexture(Texture *texture)
Definition: Render.cpp:2451
ODMFace::IsBackfaceNotCulled
static bool IsBackfaceNotCulled(struct RenderVertexSoft *a2, struct Polygon *polygon)
Definition: Outdoor.cpp:522
Lightmap::fBrightness
float fBrightness
Definition: LightmapBuilder.h:24
SoftwareBillboard::screen_space_x
int screen_space_x
Definition: IRender.h:173
BLVSector::pFloors
uint16_t * pFloors
Definition: Indoor.h:526
BLVRenderParams::pTargetZBuffer
int * pTargetZBuffer
Definition: Indoor.h:701
dst
GLenum GLenum dst
Definition: SDL_opengl_glext.h:1740
RenderBillboardD3D::opacity
OpacityType opacity
Definition: IRender.h:162
depth
GLint GLint GLsizei GLsizei GLsizei depth
Definition: SDL_opengl.h:1572
LevelDecoration
Definition: Decoration.h:20
IRender::pActiveZBuffer
int * pActiveZBuffer
Definition: IRender.h:421
LEVEL_DECORATION_OBELISK_CHEST
@ LEVEL_DECORATION_OBELISK_CHEST
Definition: Decoration.h:15
Removed
@ Removed
Definition: Actor.h:86
DecalBuilder::uNumDecals
int uNumDecals
Definition: DecalBuilder.h:164
Render::GetRenderHeight
virtual unsigned int GetRenderHeight() const
Definition: Render.cpp:76
OutdoorLocation::vSunlight
Vec3_int_ vSunlight
Definition: Outdoor.h:163
stru141_actor_collision_object::sMaxX
int sMaxX
Definition: Indoor.h:176
ScreenshotFileNumber
int ScreenshotFileNumber
Definition: mm7_data.cpp:478
d3d_vertex_buffer
RenderVertexD3D3 d3d_vertex_buffer[50]
Definition: Render.cpp:55
Decal::uColorMultiplier
uint32_t uColorMultiplier
Definition: DecalBuilder.h:114
Render::CreateTexture_PCXFromFile
virtual Texture * CreateTexture_PCXFromFile(const String &name)
Definition: Render.cpp:100
stru141_actor_collision_object::sMinX
int sMinX
Definition: Indoor.h:177
Render::uTargetBBits
unsigned int uTargetBBits
Definition: Render.h:202
Render::SetUIClipRect
virtual void SetUIClipRect(unsigned int uX, unsigned int uY, unsigned int uZ, unsigned int uW)
Definition: Render.cpp:2723
BLVLightMM7::vPosition
struct Vec3_short_ vPosition
Definition: Indoor.h:358
ParticleEngine::AddParticle
void AddParticle(Particle_sw *a2)
Definition: ParticleEngine.cpp:65
SkyBillboardStruct::CamVecFront_Y
int CamVecFront_Y
Definition: IRender.h:476
BLVFace::uBackSectorID
int16_t uBackSectorID
Definition: Indoor.h:485
BlendColors
unsigned int BlendColors(unsigned int a1, unsigned int a2)
Definition: RenderBase.cpp:265
Viewport::uViewportBR_Y
int uViewportBR_Y
Definition: Viewport.h:25
BLVFace::pBounding
struct BBox_short_ pBounding
Definition: Indoor.h:486
pMiscTimer
Timer * pMiscTimer
Definition: Time.cpp:7
SpellFX_Billboard::local_01::y
float y
Definition: SpellFxRenderer.h:37
stru141_actor_collision_object::sMaxY
int sMaxY
Definition: Indoor.h:178
t
GLdouble GLdouble t
Definition: SDL_opengl.h:2071
OutdoorLocation::max_terrain_dimming_level
int max_terrain_dimming_level
Definition: Outdoor.h:140
RenderBillboardD3D::texture
Texture * texture
Definition: IRender.h:158
SoftwareBillboard::uViewportY
unsigned int uViewportY
Definition: IRender.h:184
ODMFace::index
unsigned int index
Definition: BSPModel.h:130
word_720C10_intercepts_xs
std::array< __int16, 102 > word_720C10_intercepts_xs
Definition: mm7_data.cpp:726
RenderBillboard::screenspace_projection_factor_y
float screenspace_projection_factor_y
Definition: IRender.h:28
Render::p2DSurface
Gdiplus::Bitmap * p2DSurface
Definition: Render.h:211
Outdoor.h
Render::GetRenderWidth
virtual unsigned int GetRenderWidth() const
Definition: Render.cpp:75
Lightmap::pVertices
RenderVertexSoft pVertices[64]
Definition: LightmapBuilder.h:18
Render::Initialize
virtual bool Initialize(OSWindow *window)
Definition: Render.cpp:1101
RenderBillboardD3D::object_pid
unsigned short object_pid
Definition: IRender.h:165
IMAGE_FORMAT
IMAGE_FORMAT
Definition: Image.h:4
LevelDecoration::uDecorationDescID
uint16_t uDecorationDescID
Definition: Decoration.h:26
LEVEL_Indoor
@ LEVEL_Indoor
Definition: Indoor.h:286
SoftwareBillboard::uViewportX
unsigned int uViewportX
Definition: IRender.h:183
SkyBillboard
SkyBillboardStruct SkyBillboard
Definition: Outdoor.cpp:51
Plane_int_::dist
int dist
Definition: VectorTypes.h:108
_46E44E_collide_against_faces_and_portals
int _46E44E_collide_against_faces_and_portals(unsigned int b1)
Definition: Render.cpp:4350
SkyBillboardStruct::CamVecLeft_X
int CamVecLeft_X
Definition: IRender.h:472
TextureD3D.h
ColorKey_LOD_Loader
Definition: ImageLoader.h:25
memset32
void memset32(void *ptr, uint32_t value, int count)
Definition: MM7.h:14
bitmap
GLsizei GLfixed GLfixed GLfixed GLfixed const GLubyte * bitmap
Definition: SDL_opengl_glext.h:4537
distance
GLsizei GLsizei GLfloat distance
Definition: SDL_opengl_glext.h:9203
RenderD3D::Release
void Release()
Definition: RenderD3D.cpp:201
RenderBillboard::screen_space_y
int16_t screen_space_y
Definition: IRender.h:40
Party::bTurnBasedModeOn
bool bTurnBasedModeOn
Definition: Party.h:305
SoftwareBillboard::screen_space_y
int screen_space_y
Definition: IRender.h:174
pViewport
struct Viewport * pViewport
Definition: mm7_data.cpp:21
Summoned
@ Summoned
Definition: Actor.h:92
GetActorTintColor
int GetActorTintColor(int max_dimm, int min_dimm, float distance, int a4, RenderBillboard *a5)
Definition: Render.cpp:4114
Render::pFrontBuffer4
IDirectDrawSurface4 * pFrontBuffer4
Definition: Render.h:193
RenderD3D::GetDeviceCaps
unsigned int GetDeviceCaps()
Definition: RenderD3D.cpp:702
ArcomageGame::pSpritesPixels
uint16_t * pSpritesPixels
Definition: Arcomage.h:143
TextureD3D
Definition: TextureD3D.h:6
RenderD3D::pBackBuffer
IDirectDrawSurface4 * pBackBuffer
Definition: RenderD3D.h:95
uNumDecorationsDrawnThisFrame
int uNumDecorationsDrawnThisFrame
Definition: RenderOpenGL.cpp:53
Weather::bNight
bool bNight
Definition: Weather.h:17
_4D864C_force_sw_render_rules
char _4D864C_force_sw_render_rules
Definition: mm7_data.cpp:208
BSPModel::sMaxY
int32_t sMaxY
Definition: BSPModel.h:178
Party::armageddon_timer
int armageddon_timer
Definition: Party.h:320
uint8_t
unsigned __int8 uint8_t
Definition: SDL_config.h:35
Render::ClearBlack
virtual void ClearBlack()
Definition: Render.cpp:1113
Render::DrawOutdoorSkyPolygon
void DrawOutdoorSkyPolygon(struct Polygon *pSkyPolygon)
Definition: Render.cpp:6164
LightsStack_MobileLight_::uNumLightsActive
unsigned int uNumLightsActive
Definition: Lights.h:88
GetLevelFogColor
unsigned int GetLevelFogColor()
Definition: Outdoor.cpp:3871
word_720A70_intercepts_xs_plus_xs
std::array< __int16, 104 > word_720A70_intercepts_xs_plus_xs
Definition: mm7_data.cpp:724
Polygon::flags
__int16 flags
Definition: Polygon.h:35
StationaryLight::vPosition
Vec3_short_ vPosition
Definition: Lights.h:11
Render::Release
virtual void Release()
Definition: Render.cpp:1196
pODMRenderParams
ODMRenderParams * pODMRenderParams
Definition: Outdoor.cpp:49
uNumSpriteObjects
size_t uNumSpriteObjects
Definition: SpriteObject.cpp:33
BLVLightMM7::uRadius
int16_t uRadius
Definition: Indoor.h:359
IRender::uNumBillboardsToDraw
unsigned int uNumBillboardsToDraw
Definition: IRender.h:429
LightsStack_StationaryLight_::pLights
StationaryLight pLights[400]
Definition: Lights.h:64
RenderD3D::Present
void Present(bool bForceBlit)
Definition: RenderD3D.cpp:747
RenderBillboardD3D::Opaque_3
@ Opaque_3
Definition: IRender.h:153
Render::DrawLines
virtual void DrawLines(const RenderVertexD3D3 *vertices, unsigned int num_vertices)
Definition: Render.cpp:3896
IRender::spell_fx_renderer
SpellFxRenderer * spell_fx_renderer
Definition: IRender.h:433
Point::y
unsigned int y
Definition: Point.h:8
b
GLboolean GLboolean GLboolean b
Definition: SDL_opengl_glext.h:1112
stru193_math::Atan2
unsigned int Atan2(int x, int y)
Definition: OurMath.cpp:46
data
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: SDL_opengl.h:1974
dstY
GLenum GLint GLint GLint GLint GLuint GLenum GLint GLint GLint dstY
Definition: SDL_opengl_glext.h:2453
Render::LoadHwlSprite
virtual HWLTexture * LoadHwlSprite(const char *name)
Definition: Render.cpp:2444
VertexRenderList
RenderVertexSoft VertexRenderList[50]
Definition: Render.cpp:52
stru141_actor_collision_object::field_84
int field_84
Definition: Indoor.h:174
name
EGLImageKHR EGLint * name
Definition: SDL_egl.h:1497
Rect::y
int y
Definition: Rect.h:5
r
GLdouble GLdouble GLdouble r
Definition: SDL_opengl.h:2079
Sprite::uAreaX
int uAreaX
Definition: Sprites.h:29
RenderBillboard::world_y
int16_t world_y
Definition: IRender.h:37
Party::field_14_radius
int field_14_radius
Definition: Party.h:241
sub_475D85
bool sub_475D85(Vec3_int_ *a1, Vec3_int_ *a2, int *a3, BLVFace *a4)
Definition: Render.cpp:5403
Polygon::sTextureDeltaV
int sTextureDeltaV
Definition: Polygon.h:34
SoftwareBillboard::uViewportW
unsigned int uViewportW
Definition: IRender.h:186
ParticleType_8
@ ParticleType_8
Definition: ParticleEngine.h:9
stru141_actor_collision_object::prolly_normal_d
int prolly_normal_d
Definition: Indoor.h:152
Particle_sw::texture
Texture * texture
Definition: ParticleEngine.h:28
BLVSector::pDecorationIDs
uint16_t * pDecorationIDs
Definition: Indoor.h:550
Render::GetTargetPixelFormat
void GetTargetPixelFormat(DDPIXELFORMAT *pOut)
Definition: Render.cpp:1744
Viewport::uScreenCenterX
int uScreenCenterX
Definition: Viewport.h:28
DecorationDesc_mm6::uSpriteID
uint16_t uSpriteID
Definition: DecorationList.h:43
IsBModelVisible
bool IsBModelVisible(BSPModel *model, int *reachable)
Definition: Render.cpp:5516
Render::CreateTexture_Solid
virtual Texture * CreateTexture_Solid(const String &name)
Definition: Render.cpp:84
Image::Create
static Image * Create(unsigned int width, unsigned int height, IMAGE_FORMAT format, const void *pixels=nullptr)
Definition: Image.cpp:243
c
const GLubyte * c
Definition: SDL_opengl_glext.h:11096
Render.h
v2
GLfloat GLfloat GLfloat v2
Definition: SDL_opengl_glext.h:695
ODMRenderParams::uMapGridCellZ
unsigned int uMapGridCellZ
Definition: IRender.h:106
SpriteFrame
Definition: Sprites.h:39
RenderVertexSoft::v
float v
Definition: IRender.h:122
IRender::hd_water_current_frame
int hd_water_current_frame
Definition: IRender.h:424
assets
AssetsManager * assets
Definition: AssetsManager.cpp:12
Render::CreateTexture_PCXFromNewLOD
virtual Texture * CreateTexture_PCXFromNewLOD(const String &name)
Definition: Render.cpp:96
Polygon::pODMFace
ODMFace * pODMFace
Definition: Polygon.h:47
integer_sqrt
int integer_sqrt(int val)
Definition: OurMath.cpp:164
RenderVertexSoft::_rhw
float _rhw
Definition: IRender.h:120
uint
unsigned int uint
Definition: MM7.h:4
RenderBillboardD3D::NoBlend
@ NoBlend
Definition: IRender.h:154
stru141_actor_collision_object::field_54
int field_54
Definition: Indoor.h:164
array_77EC08
std::array< struct Polygon, 2000+18000 > array_77EC08
Definition: Outdoor.cpp:52
ITEM_BROKEN
@ ITEM_BROKEN
Definition: Items.h:27
v3
GLfloat GLfloat GLfloat GLfloat v3
Definition: SDL_opengl_glext.h:696
SoftwareBillboard::uViewportZ
unsigned int uViewportZ
Definition: IRender.h:185
pStationaryLightsStack
LightsStack_StationaryLight_ * pStationaryLightsStack
Definition: LightmapBuilder.cpp:11
SoftwareBillboard::uFlags
unsigned int uFlags
Definition: IRender.h:181
SoftwareBillboard::sParentBillboardID
int sParentBillboardID
Definition: IRender.h:188
__debugbreak
void __cdecl __debugbreak(void)
Render::ZBuffer_Fill_2
virtual void ZBuffer_Fill_2(signed int a2, signed int a3, Image *pTexture, int a5)
Definition: Render.cpp:3207
stru141_actor_collision_object::field_80
int field_80
Definition: Indoor.h:173
DecorationDesc_mm6::uDecorationHeight
uint16_t uDecorationHeight
Definition: DecorationList.h:40
OutdoorLocation::pTerrain
struct OutdoorLocationTerrain pTerrain
Definition: Outdoor.h:117
IMAGE_FORMAT_A1R5G5B5
@ IMAGE_FORMAT_A1R5G5B5
Definition: Image.h:6
__PAIR__
int16 __PAIR__(int8 high, T low)
Definition: MM7.h:135
SkyBillboardStruct::CamVecFront_X
int CamVecFront_X
Definition: IRender.h:475
Render::DrawTextureAlphaNew
virtual void DrawTextureAlphaNew(float u, float v, class Image *)
Definition: Render.cpp:3176
BLVRenderParams::uViewportCenterX
int uViewportCenterX
Definition: Indoor.h:704
BSPModel::pFaces
std::vector< ODMFace > pFaces
Definition: BSPModel.h:190
RenderVertexSoft::vWorldPosition
Vec3_float_ vWorldPosition
Definition: IRender.h:116
LightmapBuilder::ApplyLights_OutdoorFace
bool ApplyLights_OutdoorFace(struct ODMFace *pFace)
Definition: LightmapBuilder.cpp:48
_6BE3A0_fov
float _6BE3A0_fov
Definition: mm7_data.cpp:715
ODMFace
Definition: BSPModel.h:93
Render::SavePCXImage32
void SavePCXImage32(const String &filename, uint16_t *picture_data, int width, int height)
Definition: Render.cpp:1140
stru141_actor_collision_object::direction
Vec3_int_ direction
Definition: Indoor.h:165
BSPModel::vBoundingCenter
Vec3_int_ vBoundingCenter
Definition: BSPModel.h:186
pBitmaps_LOD
LODFile_IconsBitmaps * pBitmaps_LOD
Definition: LOD.cpp:16
Image::GetPixels
const void * GetPixels(IMAGE_FORMAT format)
Definition: Image.cpp:270
Particle_sw::particle_size
float particle_size
Definition: ParticleEngine.h:30
stru193_math::Cos
int Cos(int angle)
Definition: OurMath.cpp:28
ParticleType_Rotating
@ ParticleType_Rotating
Definition: ParticleEngine.h:8
Decoration.h
ODMFace::uAttributes
uint32_t uAttributes
Definition: BSPModel.h:135
stru_5C6E00
struct stru193_math * stru_5C6E00
Definition: mm7_data.cpp:19
word_7209A0_intercepts_ys_plus_ys
std::array< __int16, 104 > word_7209A0_intercepts_ys_plus_ys
Definition: mm7_data.cpp:723
IRender::hd_water_tile_anim
Texture * hd_water_tile_anim[7]
Definition: IRender.h:426
Render::uMaxDeviceTextureDim
unsigned int uMaxDeviceTextureDim
Definition: Render.h:205
BLVFace::GetTexture
Texture * GetTexture()
Definition: Indoor.cpp:738
angle
GLfloat angle
Definition: SDL_opengl_glext.h:6100
BLVLightMM7
Definition: Indoor.h:357
ODMFace::pFacePlane
struct Plane_int_ pFacePlane
Definition: BSPModel.h:131
SpellFX_Billboard::local_01::diffuse
int diffuse
Definition: SpellFxRenderer.h:39
BSPVertexBuffer::pVertices
Vec3_int_ * pVertices
Definition: BSPModel.h:53
Polygon::pid
__int16 pid
Definition: Polygon.h:45
IndoorLocation::pVertices
struct Vec3_short_ * pVertices
Definition: Indoor.h:628
DecorationDesc
Definition: DecorationList.h:49
Particle_sw::x
float x
Definition: ParticleEngine.h:20
BLVSector::uNumCeilings
uint16_t uNumCeilings
Definition: Indoor.h:530
sub_47C3D7_get_fog_specular
int sub_47C3D7_get_fog_specular(int a1, int a2, float a3)
Definition: Outdoor.cpp:3898
OurMath.h
LightsData::uNumLightsApplied
unsigned int uNumLightsApplied
Definition: Indoor.h:39
Decal::field_C14
int field_C14
Definition: DecalBuilder.h:115
word_720B40_intercepts_zs
std::array< __int16, 104 > word_720B40_intercepts_zs
Definition: mm7_data.cpp:725
pBillboardRenderList
RenderBillboard pBillboardRenderList[500]
Definition: RenderOpenGL.cpp:54
uCurrentlyLoadedLevelType
LEVEL_TYPE uCurrentlyLoadedLevelType
Definition: Indoor.cpp:52
a
GLboolean GLboolean GLboolean GLboolean a
Definition: SDL_opengl_glext.h:1112
Present32
void Present32(uint32_t *src, unsigned int src_pitch, uint32_t *dst, unsigned int dst_pitch)
Definition: Render.cpp:1212
pTerrainNormalIndices
std::array< unsigned short, 128 *128 *2 > pTerrainNormalIndices
Definition: mm7_data.cpp:757
ODMRenderParams::int_fov_rad
int int_fov_rad
Definition: IRender.h:79
stru_721530
stru141_actor_collision_object stru_721530
Definition: Indoor.cpp:58
StationaryLight::uRadius
int16_t uRadius
Definition: Lights.h:12
RenderD3D__DevInfo::bIsDeviceCompatible
unsigned int bIsDeviceCompatible
Definition: RenderD3D.h:32
ODMFace::zCalc2
int zCalc2
Definition: BSPModel.h:133
LightmapBuilder::ApplyLights
bool ApplyLights(struct LightsData *a2, struct stru154 *a3, unsigned int uNumVertices, struct RenderVertexSoft *a5, struct IndoorCameraD3D_Vec4 *, char uClipFlag)
Definition: LightmapBuilder.cpp:494
IndoorLocation::GetSector
int GetSector(int sX, int sY, int sZ)
Definition: Indoor.cpp:1279
IndoorLocation::pFaces
struct BLVFace * pFaces
Definition: Indoor.h:630
BSPModel::field_40
int32_t field_40
Definition: BSPModel.h:170
IndoorCameraD3D::GetFarClip
float GetFarClip() const
Definition: IndoorCameraD3D.cpp:159
Polygon::ptr_38
struct SkyBillboardStruct * ptr_38
Definition: Polygon.h:38
ObjectList::pObjects
struct ObjectDesc * pObjects
Definition: ObjectList.h:54
RenderBillboard::screenspace_projection_factor_x
float screenspace_projection_factor_x
Definition: IRender.h:27
stru193_math::Sin
int Sin(int angle)
Definition: OurMath.cpp:133
LightsStack_StationaryLight_::AddLight
bool AddLight(int16_t x, int16_t y, int16_t z, int16_t a5, unsigned char r, unsigned char g, unsigned char b, char uLightType)
Definition: LightsStack.cpp:30
TextureD3D::Create
static Texture * Create(unsigned int width, unsigned int height, IMAGE_FORMAT format, const void *pixels)
Definition: TextureD3D.cpp:6
Render::SwitchToWindow
virtual bool SwitchToWindow()
Definition: Render.cpp:1520
IndoorCameraD3D::ViewTransform
void ViewTransform(int x, int y, int z, int *transformed_x, int *transformed_y, int *transformed_z)
Definition: IndoorCameraD3D.cpp:184
BBox_short_::x2
int16_t x2
Definition: VectorTypes.h:115
Render::FillRectFast
virtual void FillRectFast(unsigned int uX, unsigned int uY, unsigned int uWidth, unsigned int uHeight, unsigned int uColor16)
Definition: Render.cpp:2845
Render::InitializeFullscreen
virtual bool InitializeFullscreen()
Definition: Render.cpp:1262
SpriteObject::OnInteraction
static void OnInteraction(unsigned int uLayingItemID)
Definition: SpriteObject.cpp:872
_calc_fov
float _calc_fov(int viewport_width, int angle_degree)
Definition: IndoorCameraD3D.cpp:17
BSPModel
Definition: BSPModel.h:163
Render::CreateZBuffer
virtual void CreateZBuffer()
Definition: Render.cpp:1187
GUIWindow.h
Point
Definition: Point.h:3
RenderD3D::ClearTarget
void ClearTarget(unsigned int bClearColor, unsigned int uClearColor, unsigned int bClearDepth, float z_clear)
Definition: RenderD3D.cpp:735
BLVSector
Definition: Indoor.h:522
IRender::hd_water_tile_id
int hd_water_tile_id
Definition: IRender.h:425
RenderVertexSoft
Definition: IRender.h:113
ParticleType_Bitmap
@ ParticleType_Bitmap
Definition: ParticleEngine.h:12
Render::CreateTexture_PCXFromIconsLOD
virtual Texture * CreateTexture_PCXFromIconsLOD(const String &name)
Definition: Render.cpp:92
ObjectList.h
IndoorCameraD3D::GetNearClip
float GetNearClip() const
Definition: IndoorCameraD3D.cpp:146
logger
Log * logger
Definition: IocContainer.cpp:47
sub_4754BF
bool sub_4754BF(int a1, int *a2, int X, int Y, int Z, int dir_x, int dir_y, int dir_z, BLVFace *face, int a10, int a11)
Definition: Render.cpp:5082
Render::CreateSprite
virtual Texture * CreateSprite(const String &name, unsigned int palette_id, unsigned int lod_sprite_id)
Definition: Render.cpp:116
Render::DrawTerrainPolygon
virtual void DrawTerrainPolygon(struct Polygon *a4, bool transparent, bool clampAtTextureBorders)
Definition: Render.cpp:1815
RenderBillboardD3D::sParentBillboardID
int sParentBillboardID
Definition: IRender.h:167
pMobileLightsStack
LightsStack_MobileLight_ * pMobileLightsStack
Definition: LightmapBuilder.cpp:14
Render::p2DGraphics
Gdiplus::Graphics * p2DGraphics
Definition: Render.h:212
Render::DrawOutdoorSkyD3D
virtual void DrawOutdoorSkyD3D()
Definition: Render.cpp:5613
stru141_actor_collision_object::field_4C
int field_4C
Definition: Indoor.h:162
DecorationDesc::uColoredLightBlue
uint8_t uColoredLightBlue
Definition: DecorationList.h:52
Color16
uint16_t Color16(uint32_t r, uint32_t g, uint32_t b)
Definition: Engine.cpp:148
LightmapBuilder::StationaryLightsCount
unsigned int StationaryLightsCount
Definition: LightmapBuilder.h:83
pOutdoor
OutdoorLocation * pOutdoor
Definition: Outdoor.cpp:48
RenderBase::pD3DSprites
HWLContainer pD3DSprites
Definition: RenderBase.h:33
LightmapBuilder::StackLights_TerrainFace
bool StackLights_TerrainFace(struct Vec3_float_ *pNormal, float *a3, struct RenderVertexSoft *a1, unsigned int uStripType, bool bLightBackfaces)
Definition: LightmapBuilder.cpp:465
SpellFxRenderer::RenderSpecialEffects
void RenderSpecialEffects()
Definition: SpellFxRenderer.cpp:1239
RenderBillboardD3D::screen_space_z
short screen_space_z
Definition: IRender.h:166
RenderVertexD3D3::specular
unsigned int specular
Definition: IRender.h:133
BBox_short_::z1
int16_t z1
Definition: VectorTypes.h:118
Image16bit_LOD_Loader
Definition: ImageLoader.h:42
BLVSector::uNumDecorations
uint16_t uNumDecorations
Definition: Indoor.h:548
RenderD3D::CreateTexture
bool CreateTexture(unsigned int uTextureWidth, unsigned int uTextureHeight, IDirectDrawSurface4 **pOutSurface, IDirect3DTexture2 **pOutTexture, bool bAlphaChannel, bool bMipmaps, unsigned int uMinDeviceTexDim)
Definition: RenderD3D.cpp:781
RenderBillboardD3D::pQuads
RenderVertexD3D3 pQuads[4]
Definition: IRender.h:160
IndoorCameraD3D::debug_outline_d3d
void debug_outline_d3d(const struct RenderVertexD3D3 *pLineVertices, unsigned int uNumLines, int uDiffuse, float z_stuff)
Definition: IndoorCameraD3D.cpp:390
Render::ZDrawTextureAlpha
virtual void ZDrawTextureAlpha(float u, float v, Image *pTexture, int zVal)
Definition: Render.cpp:3189
SoftwareBillboard::pTargetZ
int * pTargetZ
Definition: IRender.h:172
pIndoorCameraD3D
IndoorCameraD3D * pIndoorCameraD3D
Definition: IndoorCameraD3D.cpp:21
image
EGLImageKHR image
Definition: SDL_egl.h:953
_46E0B2_collide_against_decorations
void _46E0B2_collide_against_decorations()
Definition: Render.cpp:4855
stru141_actor_collision_object::position
Vec3_int_ position
Definition: Indoor.h:160
g
GLboolean GLboolean g
Definition: SDL_opengl_glext.h:1112
_46F04E_collide_against_portals
int _46F04E_collide_against_portals()
Definition: Render.cpp:4895
Viewport::uViewportTL_X
int uViewportTL_X
Definition: Viewport.h:22
pixels
GLint GLint GLsizei GLsizei GLsizei GLint GLenum GLenum const GLvoid * pixels
Definition: SDL_opengl.h:1572
uint32_t
unsigned __int32 uint32_t
Definition: SDL_config.h:39
BLVRenderParams::uViewportY
unsigned int uViewportY
Definition: Indoor.h:697
OutdoorLocation::Draw
void Draw()
Definition: Outdoor.cpp:160
BLV_GetFloorLevel
int BLV_GetFloorLevel(int x, int y, int z, unsigned int uSectorID, unsigned int *pFaceID)
Definition: Indoor.cpp:2530
Timer::uTotalGameTimeElapsed
unsigned int uTotalGameTimeElapsed
Definition: Time.h:135
OBJECT_40
@ OBJECT_40
Definition: SpriteObject.h:182
stru193_math::uIntegerPi
static const unsigned int uIntegerPi
Definition: OurMath.h:88
DecalBuilder.h
String
std::string String
Definition: Strings.h:10
ErrHR
void ErrHR(HRESULT hr, const char *pAPI, const char *pFunction, const char *pFile, int line)
Definition: Render.cpp:59
ODMFace::pZInterceptDisplacements
int16_t pZInterceptDisplacements[20]
Definition: BSPModel.h:141
pEventTimer
Timer * pEventTimer
Definition: Time.cpp:8
PolygonType
PolygonType
Definition: Indoor.h:216
SoftwareBillboard::sTintColor
int sTintColor
Definition: IRender.h:189
BLVFace::uAttributes
unsigned int uAttributes
Definition: Indoor.h:475
Sprites.h
RenderBillboard::world_x
int16_t world_x
Definition: IRender.h:36
RenderD3D
Definition: RenderD3D.h:67
config
EGLConfig config
Definition: SDL_egl.h:1149
Sprite::uAreaHeight
int uAreaHeight
Definition: Sprites.h:34
BSPModel::sMaxZ
int32_t sMaxZ
Definition: BSPModel.h:179
Render::uTargetRBits
unsigned int uTargetRBits
Definition: Render.h:200
Render::Render
Render()
Definition: Render.cpp:1075
ushort
unsigned short ushort
Definition: MM7.h:45
DecorationDesc::uColoredLightGreen
uint8_t uColoredLightGreen
Definition: DecorationList.h:51
Render::BeginDecals
virtual void BeginDecals()
Definition: Render.cpp:3936
SpriteFrame::uFlags
int uFlags
Definition: Sprites.h:48
Polygon::uBModelFaceID
unsigned __int8 uBModelFaceID
Definition: Polygon.h:55
Vec3::z
T z
Definition: VectorTypes.h:27
pObjectList
struct ObjectList * pObjectList
Definition: ObjectList.cpp:5
Image::Release
bool Release()
Definition: Image.cpp:335
RenderBillboard::sTintColor
unsigned int sTintColor
Definition: IRender.h:44
Render::BeginLightmaps2
virtual void BeginLightmaps2()
Definition: Render.cpp:3845
Mouse.h
Render::CreateTexture
virtual Texture * CreateTexture(const String &name)
Definition: Render.cpp:112
img
GLint GLvoid * img
Definition: SDL_opengl.h:1980
Api.h
SoftwareBillboard::object_pid
unsigned short object_pid
Definition: IRender.h:190
OS_GetAppInt
int OS_GetAppInt(const char *pKey, int uDefValue)
Definition: Lin.cpp:89
pDecorationList
struct DecorationList * pDecorationList
Definition: DecorationList.cpp:11
Render::DrawIndoorPolygon
virtual void DrawIndoorPolygon(unsigned int uNumVertices, struct BLVFace *a3, int uPackedID, unsigned int uColor, int a8)
Definition: Render.cpp:1992
BLVSector::uMinAmbientLightLevel
int16_t uMinAmbientLightLevel
Definition: Indoor.h:560
SpriteObject::UpdateObject_fn0_ODM
static void UpdateObject_fn0_ODM(unsigned int uLayingItemID)
Definition: SpriteObject.cpp:130
stru141_actor_collision_object::pid
unsigned int pid
Definition: Indoor.h:171
Vis.h
Render::am_Blt_Chroma
virtual void am_Blt_Chroma(Rect *pSrcRect, Point *pTargetPoint, int a3, int blend_mode)
Definition: Render.cpp:1453
Time.h
Render::DrawPolygon
virtual void DrawPolygon(struct Polygon *a3)
Definition: Render.cpp:899
SpellFxRenderer::effpar01
Texture * effpar01
Definition: SpellFxRenderer.h:166
stru141_actor_collision_object::sMinZ
int sMinZ
Definition: Indoor.h:181
Particle_sw::uDiffuse
unsigned int uDiffuse
Definition: ParticleEngine.h:26
render
std::shared_ptr< IRender > render
Definition: RenderOpenGL.cpp:52