Rise
The Vieneo Province
grid.cpp
Go to the documentation of this file.
1 #include "grid.h"
2 #include "Viewscreen.h"
3 
4 grid::grid(Viewscreen* prmViewscreen)
5 {
6  viewscreen = prmViewscreen;
7 
8  g_bAboveCloudsOld = false; // if we change this to TRUE then we won't have to do the client init one?
9  oldtcp = VECTOR2SHORT();
10 }
11 
12 void grid::Trace(const char* msg, Logger::Level severity) const
13 {
14  char newmsg[999];
15  sprintf_s(newmsg, sizeof newmsg, "GRID: %s", msg);
16  viewscreen->logger->Log(newmsg, severity);
17 }
18 
19 void grid::ClearGrid(short l, short m) const
20 {
21  gridarray[l][m].position = centerC; // 4600
22  gridarray[l][m].cloudpos = centerC; // 4603
23  gridarray[l][m].specular = 0UL; // 4542
24  gridarray[l][m].clouddif = 0UL; // 4587
25  gridarray[l][m].pri_landform = 0; // 4553
26  gridarray[l][m].pri_transition = 0; // 4559
27  gridarray[l][m].sec_landform = 0; // 4564
28  gridarray[l][m].sec_transition = 0; // 4569
29  gridarray[l][m].ter_landform = 0; // 4574
30  gridarray[l][m].raster = 0UL; // 4545
31  gridarray[l][m].elevation = 0; // 4581
32 
33  if (gridarray[l][m].buildzoneOrdinal != -1)
34  {
35  char msg[99];
36  sprintf_s(msg, sizeof(msg), "HG2 released VB slot %i!", gridarray[l][m].buildzoneOrdinal);
37  Trace(msg);
38 
39  SAFE_RELEASE(buildzone[gridarray[l][m].buildzoneOrdinal].VB);
40  sprintf_s(msg, sizeof(msg), "buildzone[%i].VB", gridarray[l][m].buildzoneOrdinal);
42 
43  if (buildzone[gridarray[l][m].buildzoneOrdinal].RTSVB)
44  {
45  SAFE_RELEASE(buildzone[gridarray[l][m].buildzoneOrdinal].RTSVB);
46  sprintf_s(msg, sizeof(msg), "buildzone[%i].RTSVB", gridarray[l][m].buildzoneOrdinal);
48  }
49 
50  gridarray[l][m].buildzoneOrdinal = -1; // not assigned
51  }
52 
53  gridarray[l][m].type = PlotType::NotZoned; // 4541
54  gridarray[l][m].zone = 0; // 4535
55  gridarray[l][m].layout1 = gridarray[l][m].layout2 = gridarray[l][m].layout3 = gridarray[l][m].layout4 = 0L; // 4536-4539
56  gridarray[l][m].powered = false; // 4540
57 }
58 
60 {
61  Trace("ClearGrid");
62  viewscreen->logger->AddToCallStack("grid::ClearGrid");
63 
64  geometryReady = false; // VB not set
65  dataReady = false; // Wait on stuff until main grid is received, reset if above clouds
66  dataPending = 0;
67 
69 
70  for (short t = 0; t < 64; t++)
71  {
72  for (short s = 0; s < 64; s++)
73  {
74  ClearGrid(t, s);
75  }
76  }
77 }
78 
80 {
81  cube = viewscreen->CalculateCube(playerships[0].position);
82  if (cube == -1)
83  {
84  char msg[99];
85  sprintf_s(msg, sizeof(msg), "HG3 trapped a violation cube -1 for position x:%f y:%f z:%f", playerships[0].position.x, playerships[0].position.y, playerships[0].position.z);
86  Trace(msg, Logger::Fatal);
87  }
88 
89  tcp = viewscreen->CalculateCGC(playerships[0].position, cube);
90  char rotate;
91  tcp = viewscreen->CalculateWrap(tcp.u, tcp.v, cube, &rotate); // this grep found when he was out and about... left of NP goes to top of WP plate
92 }
93 
94 #ifdef DumpGridToWld
95 int grid::FindOrAddVertex(std::vector<struct D3DXVECTOR3>* unique_vertices, D3DXVECTOR3 position)
96 {
97  for (UINT i = 0; i < unique_vertices->size(); i++)
98  {
99  if (fabsf(unique_vertices->at(i).x - position.x) <= FLT_EPSILON &&
100  fabsf(unique_vertices->at(i).y - position.y) <= FLT_EPSILON &&
101  fabsf(unique_vertices->at(i).z - position.z) <= FLT_EPSILON)
102  return i;
103  }
104  unique_vertices->emplace_back(position);
105  return static_cast<int>(unique_vertices->size() - 1);
106 }
107 #endif
108 
109 void grid::ReceiveWholeGrid(SRenderGrid datapacket)
110 {
111  char msg[99];
112  sprintf_s(msg, sizeof(msg), "Received SRenderGrid center at u%i v%i (%i)", datapacket.tcp.u, datapacket.tcp.v, cube);
113  Trace(msg);
114 
115  for (short t = 0; t < 64; t++)
116  {
117  for (short s = 0; s < 64; s++)
118  {
119  // Just in case we clear the grid again ... because sometimes we ask for 2 back to back? Caused a lot of trouble
120  // THIS ISN"T JUST A NICE TO HAVE, IT IS ABSOLUTELY NECESSARY!
121  //ClearGrid(t, s);
122  gridarray[t][s] = viewscreen->CalculateSRV(t, s, datapacket.tcp, cube, datapacket.gridarray[t][s]);
123  }
124  }
125 
126  // Need to calculate previous first since we use surrounding vertices
127  for (short t = 16; t < 48; t++) // can't do outside edges
128  {
129  for (short s = 16; s < 48; s++)
130  {
131  CalculateInsideArray(t, s);
132  }
133  }
134 
135  geometryReady = false; // need to create new VB
136  dataReady = true; // data is ready though
137  dataPending = 0;
138 
139  oldtcp = datapacket.tcp;
140  oldcube = cube;
141 
142  Trace(" grid::ReceiveWholeGrid DONE");
143 }
144 
146 {
147  Trace("RequestWholeGrid");
148  viewscreen->logger->AddToCallStack("grid::RequestWholeGrid");
149 
150  ClearGrid();
151 
152  SClientPacket outpacket; // NOLINT
153  outpacket.type = 16; // Terrain request
154  outpacket.f_x = tcp.u;
155  outpacket.f_y = tcp.v;
156  outpacket.f_z = cube;
157  outpacket.f_w = 0.0f; // Whole grid
158  viewscreen->gameclass->networking->SendToServer(&outpacket, sizeof(SClientPacket), true, ORDERING_TERRAIN);
159 
160  oldtcp = tcp;
161  oldcube = cube;
162 
163  dataPending = 64; // waiting for RWG
164 }
165 
167 {
168  viewscreen->logger->AddToCallStack("grid::Process");
169 
170  if (g_bAboveClouds)
171  {
172  if (!g_bAboveCloudsOld)
173  {
174  g_bAboveCloudsOld = true;
175  ClearGrid();
176  }
177  return;
178  }
179 
180  char msg[199];
181  HRESULT hr;
182 
183  // Just came below cloud level ACL/BCL line
184  if (g_bAboveCloudsOld)
185  {
186  g_bAboveCloudsOld = false;
187 
188  Trace("Process calling RWG coming out of the clouds...");
189 
191 
193  }
194 
195  short t, s;
196 
197  bool keepgoing = true;
198  if (dataReady) // wait until main grid was received
199  {
201 
202  if (cube != oldcube) // cube face changed
203  {
204  sprintf_s(msg, sizeof(msg), "Process calling RWG changing gnomonic cube from %i to %i", oldcube, cube);
205  Trace(msg);
206 
208 
209  keepgoing = false;
210  }
211 
212  // by data 32x32 is worth getting a whole new grid... but time and overhead-wise it is 8
213  if (keepgoing && (abs(tcp.u - oldtcp.u) >= 8 || abs(tcp.v - oldtcp.v) >= 8))
214  {
215  sprintf_s(msg, sizeof(msg), "Process calling RWG moving u%i and v%i", abs(tcp.u - oldtcp.u), abs(tcp.v - oldtcp.v));
216  Trace(msg);
217 
219 
220  keepgoing = false;
221  }
222 
223  if (tcp.u != oldtcp.u && keepgoing)
224  {
225  SClientPacket outpacket = SClientPacket();
226 
227  if (tcp.u > oldtcp.u)
228  {
229  // Eastbound movement, shift map and red out flatten clear release beyond data
230  sprintf_s(msg, sizeof(msg), "Shifted base on movement EAST,%i,%i (%i,%i)", tcp.u, tcp.v, oldtcp.u, oldtcp.v);
231  Trace(msg);
232 
234  if (viewscreen->BCLoffsetu < 0)
235  viewscreen->BCLoffsetu += static_cast<short>(csC);
236 
237  for (t = 0; t < 63; t++) // shift buildzones to the left
238  {
239  memcpy(gridarray[t], gridarray[t + 1], sizeof(LOCALGRID2) * 64); // Shift left
240  if (t > 15 && t < 48) // don't want to do t==47
241  memcpy(insidearray[t], insidearray[t + 1], 36 * 63);// 3*D3DXVECTOR3
242  }
243 
244  for (s = 0; s < 64; s++) // blank out new column
245  {
246  ClearGrid(63, s);
247  }
248  for (s = 16; s < 48; s++) // east edge, s runs north to south
249  {
250  CalculateInsideArray(47, s);
251  }
252 
253  oldtcp.u++;
254  sprintf_s(msg, sizeof(msg), "Now 2,%i,%i", oldtcp.u, oldtcp.v);
255  Trace(msg);
256 
257  outpacket.type = 16; // Terrain request
258  outpacket.f_x = oldtcp.u;
259  outpacket.f_y = oldtcp.v;
260  outpacket.f_z = 0.0f; // NULL
261  outpacket.f_w = 3.0f; // East
262  viewscreen->gameclass->networking->SendToServer(&outpacket, sizeof(SClientPacket), true, ORDERING_TERRAIN);
263 
264  dataPending++;
265  }
266  else if (tcp.u < oldtcp.u)
267  {
268  // Westbound movement, shift map and red out flatten beyond data
269  sprintf_s(msg, sizeof(msg), "Shifted base on movement WEST %i,%i (%i,%i)", tcp.u, tcp.v, oldtcp.u, oldtcp.v);
270  Trace(msg);
271 
273  if (viewscreen->BCLoffsetu >= (short)csC)
274  viewscreen->BCLoffsetu -= (short)csC;
275 
276  for (t = 63; t > 0; t--) // was >-1
277  {
278  memcpy(gridarray[t], gridarray[t - 1], sizeof(LOCALGRID2) * 64); // Shift right
279  if (t > 16 && t < 48) // don't want to do t==16
280  memcpy(insidearray[t], insidearray[t - 1], 36 * 63);
281  }
282 
283  for (s = 0; s < 64; s++)
284  {
285  ClearGrid(0, s);
286  }
287  for (s = 16; s < 48; s++) // west edge, s runs north to south
288  {
289  CalculateInsideArray(16, s);
290  }
291 
292  oldtcp.u--;
293  sprintf_s(msg, sizeof(msg), "Now 3,%i,%i", oldtcp.u, oldtcp.v);
294  Trace(msg);
295 
296  outpacket.type = 16; // Terrain request
297  outpacket.f_x = oldtcp.u;
298  outpacket.f_y = oldtcp.v;
299  outpacket.f_z = 0.0f; // NULL
300  outpacket.f_w = 4.0f; // West
301  viewscreen->gameclass->networking->SendToServer(&outpacket, sizeof(SClientPacket), true, ORDERING_TERRAIN);
302 
303  dataPending++;
304  }
305  else
306  {
307  sprintf_s(msg, sizeof(msg), "Unhandled case for tcp.u %i oldtcp.u %i", tcp.u, oldtcp.u);
308  Trace(msg);
309  }
310  keepgoing = false;
311  }
312 
313  if (tcp.v != oldtcp.v && keepgoing)
314  {
315  SClientPacket outpacket = SClientPacket();
316 
317  if (tcp.v < oldtcp.v)
318  {
319  sprintf_s(msg, sizeof(msg), "Shifted base on movement NORTH %i,%i (%i,%i)", tcp.u, tcp.v, oldtcp.u, oldtcp.v);
320  Trace(msg);
321 
323  if (viewscreen->BCLoffsetv >= (short)csC)
324  viewscreen->BCLoffsetv -= (short)csC;
325 
326  // Northbound movement
327  for (t = 0; t < 64; t++)
328  {
329  for (s = 63; s > 0; s--)
330  {
331  gridarray[t][s] = gridarray[t][s - 1]; // Shift down
332  if (s > 16 && s < 48 && t > 15 && t < 48) // don't do s==16
333  memcpy(insidearray[t][s], insidearray[t][s - 1], 36);
334  }
335  }
336  for (t = 0; t < 64; t++)
337  {
338  ClearGrid(t, 0);
339  }
340  for (t = 16; t < 48; t++) // north edge, t runs west to east
341  {
342  CalculateInsideArray(t, 16);
343  }
344 
345  oldtcp.v--;
346  sprintf_s(msg, sizeof(msg), "Now 0,%i,%i", oldtcp.u, oldtcp.v);
347  Trace(msg);
348 
349  outpacket.type = 16; // Terrain request
350  outpacket.f_x = oldtcp.u;
351  outpacket.f_y = oldtcp.v;
352  outpacket.f_z = 0.0f; // NULL
353  outpacket.f_w = 1.0f; // North
354  viewscreen->gameclass->networking->SendToServer(&outpacket, sizeof(SClientPacket), true, ORDERING_TERRAIN);
355 
356  dataPending++;
357  }
358  else if (tcp.v > oldtcp.v)
359  {
360  sprintf_s(msg, sizeof(msg), "Shifted base on movement SOUTH,%i,%i (%i,%i)", tcp.u, tcp.v, oldtcp.u, oldtcp.v);
361  Trace(msg);
362 
364  if (viewscreen->BCLoffsetv < 0)
365  viewscreen->BCLoffsetv += (short)csC;
366 
367  // Southbound movement
368  for (t = 0; t < 64; t++)
369  {
370  for (s = 0; s < 63; s++)
371  {
372  gridarray[t][s] = gridarray[t][s + 1]; // Shift up
373  if (s > 15 && s < 47 && t > 15 && t < 48) // don't do s==47
374  memcpy(insidearray[t][s], insidearray[t][s + 1], 36);
375  }
376  }
377  for (t = 0; t < 64; t++)
378  {
379  ClearGrid(t, 63);
380  }
381  for (t = 16; t < 48; t++) // south edge, t runs west to east
382  {
383  CalculateInsideArray(t, 47);
384  }
385 
386  oldtcp.v++;
387  sprintf_s(msg, sizeof(msg), "Now 1,%i,%i", oldtcp.u, oldtcp.v);
388  Trace(msg);
389 
390  outpacket.type = 16; // Terrain request
391  outpacket.f_x = oldtcp.u;
392  outpacket.f_y = oldtcp.v;
393  outpacket.f_z = 0.0f; // NULL
394  outpacket.f_w = 2.0f; // South
395  viewscreen->gameclass->networking->SendToServer(&outpacket, sizeof(SClientPacket), true, ORDERING_TERRAIN);
396 
397  dataPending++;
398  }
399  else
400  {
401  sprintf_s(msg, sizeof(msg), "Unhandled case for tcp.v %i oldtcp.v %i", tcp.v, oldtcp.v);
402  Trace(msg, Logger::Level::Warn);
403  }
404  keepgoing = false;
405  }
406  }
407 
408 
409  // make sure it is still initialized and that the grid is now ready
410  if (dataReady && !geometryReady && keepgoing)
411  {
412  Trace("gridproc.cpp (NAF) rebuilding terrain matrix...");
413 
414  D3DLOCALGRID2* vtxg;
415  V(viewscreen->m_avLocalGrid->Lock(0, 0, reinterpret_cast<void**>(&vtxg), 0));
416 
421 
422  int n = 0;
423 
424 #ifdef DumpGridToWld
425  // create wld file for visualization
426  std::vector<D3DXVECTOR3> uniqueVertices;
427  struct Spoly
428  {
429  int a, b, c, d;
430  DWORD color;
431  };
432 
433  std::vector<Spoly> polygons;
434 #endif
435 
437  for (int r = 0; r < drawlistC; r++)
438  {
439  int t = drawlist[r].u;
440  int s = drawlist[r].v;
441 
442  if (t < 0 || t >= 64 || s < 0 || s >= 64)
443  {
444  viewscreen->logger->Log("t and/or s in drawlist[r].u/v out-of-bounds", Logger::Level::Fatal);
445  }
446 
447  // why are we storing ones we will never render? this gets regenerated each time we move
448  if (!viewscreen->visiblegrid[t][s])
449  {
450  drawlist[r].pri_landform = 255;
451  continue;
452  }
453 
456  if (gridarray[t][s].UsesRts())
457  drawlist[r].sec_landform = 255; // flag for RTS
458  else
462 
463  if (gridarray[t][s].type == PlotType::UserAirfield)
464  {
465  drawlist[r].runways = buildings::CheckLayout(98, gridarray[t][s]) ? 1 : 0;
466  drawlist[r].runwayLights = buildings::CheckLayout(99, gridarray[t][s]) ? 1 : 0;
467  }
468  else
470 
471  drawlist[r].roads = gridarray[t][s].roads;
472 
473  if (t + 1 >= 64 || s + 1 >= 64)
474  {
475  viewscreen->logger->Log("t+1 and/or s+1 in grid processing >= 64", Logger::Level::Fatal);
476  }
477 
478  if (gridarray[t + 1][s].type == PlotType::DoNotRender ||
479  gridarray[t + 1][s + 1].type == PlotType::DoNotRender ||
480  gridarray[t][s + 1].type == PlotType::DoNotRender)
481  drawlist[r].pri_landform = 255; // don't draw if attached to someone that is invalid
482 
483  // EVERYONE STARTS WITH TOP LEFT
484  (*vtxg).tu = 0; (*vtxg).tv = 0;
485  (*vtxg).position = gridarray[t][s].position - viewscreen->terpos;
486 #ifdef DumpGridToWld
487  if (drawlist[r].pri_landform != 255)
488  {
489  Spoly poly1;
490  poly1.a = FindOrAddVertex(&uniqueVertices, gridarray[t][s].position);
491  poly1.b = FindOrAddVertex(&uniqueVertices, gridarray[t + 1][s].position);
492  poly1.c = FindOrAddVertex(&uniqueVertices, gridarray[t + 1][s + 1].position);
493  poly1.d = FindOrAddVertex(&uniqueVertices, gridarray[t][s + 1].position);
494  if (t == 31 && s == 31)
495  poly1.color = D3DCOLOR_ARGB(0, t * 4, s * 4, 255);
496  else
497  poly1.color = D3DCOLOR_ARGB(0, t * 4, s * 4, 0);
498 
499  polygons.emplace_back(poly1);
500  }
501 #endif
502  (*vtxg).raster = gridarray[t][s].raster;
503  (*vtxg).specular = gridarray[t][s].specular;
504  vtxg++; n++;
505 
506 
507  D3DXCOLOR tempcolor;
508  // 0-15 (16) ... 16-46 (31) ... 47-63 (17)
509  // For patch data (embedded in buffer now for optimizations
510  if (t > 15 && t < 47 && s > 15 && s < 47)
511  {
512  const bool meld = t == 16 || t == 46 || s == 16 || s == 46;
513 
514  // MID UPPER
515  (*vtxg).tu = 0.5f; (*vtxg).tv = 0;
516  if (meld)
517  (*vtxg).position = gridarray[t][s].position * 0.5f + gridarray[t + 1][s].position * 0.5f - viewscreen->terpos;
518  else
519  (*vtxg).position = insidearray[t][s][0] - viewscreen->terpos;
520  D3DXColorLerp(&tempcolor, &gridarray[t][s].raster, &gridarray[t + 1][s].raster, 0.5f);
521  (*vtxg).raster = tempcolor;
522  (*vtxg).specular = gridarray[t][s].specular;
523  vtxg++; n++;
524 
525  // LEFT MID
526  (*vtxg).tu = 0; (*vtxg).tv = 0.5f;
527  if (meld)
528  (*vtxg).position = gridarray[t][s].position * 0.5f + gridarray[t][s + 1].position * 0.5f - viewscreen->terpos;
529  else
530  (*vtxg).position = insidearray[t][s][1] - viewscreen->terpos;
531  D3DXColorLerp(&tempcolor, &gridarray[t][s].raster, &gridarray[t][s + 1].raster, 0.5f);
532  (*vtxg).raster = tempcolor;
533  (*vtxg).specular = gridarray[t][s].specular;
534  vtxg++; n++;
535 
536 
537  // MID UPPER
538  (*vtxg).tu = 0.5f; (*vtxg).tv = 0;
539  if (meld)
540  (*vtxg).position = gridarray[t][s].position * 0.5f + gridarray[t + 1][s].position * 0.5f - viewscreen->terpos;
541  else
542  (*vtxg).position = insidearray[t][s][0] - viewscreen->terpos;
543  D3DXColorLerp(&tempcolor, &gridarray[t][s].raster, &gridarray[t + 1][s].raster, 0.5f);
544  (*vtxg).raster = tempcolor;
545  (*vtxg).specular = gridarray[t][s].specular;
546  vtxg++; n++;
547 
548  // CENTER
549  (*vtxg).tu = 0.5f; (*vtxg).tv = 0.5f;
550  if (meld)
551  (*vtxg).position = gridarray[t][s].position * 0.5f + gridarray[t + 1][s + 1].position * 0.5f - viewscreen->terpos;
552  else
553  (*vtxg).position = insidearray[t][s][2] - viewscreen->terpos;
554  D3DXColorLerp(&tempcolor, &gridarray[t][s].raster, &gridarray[t + 1][s + 1].raster, 0.5f);
555  (*vtxg).raster = tempcolor;
556  tempcolor.r = gridarray[t][s].specular.r * 2.0f;
557  tempcolor.g = gridarray[t][s].specular.g * 2.0f;
558  tempcolor.b = gridarray[t][s].specular.b * 2.0f;
559  (*vtxg).specular = tempcolor;
560  vtxg++; n++;
561 
562  // LEFT MID
563  (*vtxg).tu = 0; (*vtxg).tv = 0.5f;
564  if (meld)
565  (*vtxg).position = gridarray[t][s].position * 0.5f + gridarray[t][s + 1].position * 0.5f - viewscreen->terpos;
566  else
567  (*vtxg).position = insidearray[t][s][1] - viewscreen->terpos;
568  D3DXColorLerp(&tempcolor, &gridarray[t][s].raster, &gridarray[t][s + 1].raster, 0.5f);
569  (*vtxg).raster = tempcolor;
570  (*vtxg).specular = gridarray[t][s].specular;
571  vtxg++; n++;
572 
573 
574  // MID UPPER
575  (*vtxg).tu = 0.5f; (*vtxg).tv = 0;
576  if (meld)
577  (*vtxg).position = gridarray[t][s].position * 0.5f + gridarray[t + 1][s].position * 0.5f - viewscreen->terpos;
578  else
579  (*vtxg).position = insidearray[t][s][0] - viewscreen->terpos;
580  D3DXColorLerp(&tempcolor, &gridarray[t][s].raster, &gridarray[t + 1][s].raster, 0.5f);
581  (*vtxg).raster = tempcolor;
582  (*vtxg).specular = gridarray[t][s].specular;
583  vtxg++; n++;
584 
585  // UPPER RIGHT
586  (*vtxg).tu = 1; (*vtxg).tv = 0;
587  (*vtxg).position = gridarray[t + 1][s].position - viewscreen->terpos;
588  (*vtxg).raster = gridarray[t + 1][s].raster;
589  (*vtxg).specular = gridarray[t + 1][s].specular;
590  vtxg++; n++;
591 
592  // CENTER
593  (*vtxg).tu = 0.5f; (*vtxg).tv = 0.5f;
594  if (meld)
595  (*vtxg).position = gridarray[t][s].position * 0.5f + gridarray[t + 1][s + 1].position * 0.5f - viewscreen->terpos;
596  else
597  (*vtxg).position = insidearray[t][s][2] - viewscreen->terpos;
598  D3DXColorLerp(&tempcolor, &gridarray[t][s].raster, &gridarray[t + 1][s + 1].raster, 0.5f);
599  (*vtxg).raster = tempcolor;
600  tempcolor.r = gridarray[t][s].specular.r * 2.0f;
601  tempcolor.g = gridarray[t][s].specular.g * 2.0f;
602  tempcolor.b = gridarray[t][s].specular.b * 2.0f;
603  (*vtxg).specular = tempcolor;
604  vtxg++; n++;
605 
606  // UPPER RIGHT
607  (*vtxg).tu = 1; (*vtxg).tv = 0;
608  (*vtxg).position = gridarray[t + 1][s].position - viewscreen->terpos;
609  (*vtxg).raster = gridarray[t + 1][s].raster;
610  (*vtxg).specular = gridarray[t + 1][s].specular;
611  vtxg++; n++;
612 
613  // RIGHT MID
614  (*vtxg).tu = 1; (*vtxg).tv = 0.5f;
615  if (meld)
616  (*vtxg).position = gridarray[t + 1][s].position * 0.5f + gridarray[t + 1][s + 1].position * 0.5f - viewscreen->terpos;
617  else
618  (*vtxg).position = insidearray[t + 1][s][1] - viewscreen->terpos;
619  D3DXColorLerp(&tempcolor, &gridarray[t + 1][s].raster, &gridarray[t + 1][s + 1].raster, 0.5f);
620  (*vtxg).raster = tempcolor;
621  (*vtxg).specular = gridarray[t + 1][s].specular;
622  vtxg++; n++;
623 
624  // CENTER
625  (*vtxg).tu = 0.5f; (*vtxg).tv = 0.5f;
626  if (meld)
627  (*vtxg).position = gridarray[t][s].position * 0.5f + gridarray[t + 1][s + 1].position * 0.5f - viewscreen->terpos;
628  else
629  (*vtxg).position = insidearray[t][s][2] - viewscreen->terpos;
630  D3DXColorLerp(&tempcolor, &gridarray[t][s].raster, &gridarray[t + 1][s + 1].raster, 0.5f);
631  (*vtxg).raster = tempcolor;
632  tempcolor.r = gridarray[t][s].specular.r * 2.0f;
633  tempcolor.g = gridarray[t][s].specular.g * 2.0f;
634  tempcolor.b = gridarray[t][s].specular.b * 2.0f;
635  (*vtxg).specular = tempcolor;
636  vtxg++; n++;
637 
638 
639  // LEFT MID
640  (*vtxg).tu = 0; (*vtxg).tv = 0.5f;
641  if (meld)
642  (*vtxg).position = gridarray[t][s].position * 0.5f + gridarray[t][s + 1].position * 0.5f - viewscreen->terpos;
643  else
644  (*vtxg).position = insidearray[t][s][1] - viewscreen->terpos;
645  D3DXColorLerp(&tempcolor, &gridarray[t][s].raster, &gridarray[t][s + 1].raster, 0.5f);
646  (*vtxg).raster = tempcolor;
647  (*vtxg).specular = gridarray[t][s].specular;
648  vtxg++; n++;
649 
650  // CENTER
651  (*vtxg).tu = 0.5f; (*vtxg).tv = 0.5f;
652  if (meld)
653  (*vtxg).position = gridarray[t][s].position * 0.5f + gridarray[t + 1][s + 1].position * 0.5f - viewscreen->terpos;
654  else
655  (*vtxg).position = insidearray[t][s][2] - viewscreen->terpos;
656  D3DXColorLerp(&tempcolor, &gridarray[t][s].raster, &gridarray[t + 1][s + 1].raster, 0.5f);
657  (*vtxg).raster = tempcolor;
658  tempcolor.r = gridarray[t][s].specular.r * 2.0f;
659  tempcolor.g = gridarray[t][s].specular.g * 2.0f;
660  tempcolor.b = gridarray[t][s].specular.b * 2.0f;
661  (*vtxg).specular = tempcolor;
662  vtxg++; n++;
663 
664  // LOWER LEFT
665  (*vtxg).tu = 0; (*vtxg).tv = 1;
666  (*vtxg).position = gridarray[t][s + 1].position - viewscreen->terpos;
667  (*vtxg).raster = gridarray[t][s + 1].raster;
668  (*vtxg).specular = gridarray[t][s + 1].specular;
669  vtxg++; n++;
670 
671 
672  // CENTER
673  (*vtxg).tu = 0.5f; (*vtxg).tv = 0.5f;
674  if (meld)
675  (*vtxg).position = gridarray[t][s].position * 0.5f + gridarray[t + 1][s + 1].position * 0.5f - viewscreen->terpos;
676  else
677  (*vtxg).position = insidearray[t][s][2] - viewscreen->terpos;
678  D3DXColorLerp(&tempcolor, &gridarray[t][s].raster, &gridarray[t + 1][s + 1].raster, 0.5f);
679  (*vtxg).raster = tempcolor;
680  tempcolor.r = gridarray[t][s].specular.r * 2.0f;
681  tempcolor.g = gridarray[t][s].specular.g * 2.0f;
682  tempcolor.b = gridarray[t][s].specular.b * 2.0f;
683  (*vtxg).specular = tempcolor;
684  vtxg++; n++;
685 
686  // BOTTOM MID
687  (*vtxg).tu = 0.5f; (*vtxg).tv = 1;
688  if (meld)
689  (*vtxg).position = gridarray[t][s + 1].position * 0.5f + gridarray[t + 1][s + 1].position * 0.5f - viewscreen->terpos;
690  else
691  (*vtxg).position = insidearray[t][s + 1][0] - viewscreen->terpos;
692  D3DXColorLerp(&tempcolor, &gridarray[t][s + 1].raster, &gridarray[t + 1][s + 1].raster, 0.5f);
693  (*vtxg).raster = tempcolor;
694  (*vtxg).specular = gridarray[t][s + 1].specular;
695  vtxg++; n++;
696 
697  // LOWER LEFT
698  (*vtxg).tu = 0; (*vtxg).tv = 1;
699  (*vtxg).position = gridarray[t][s + 1].position - viewscreen->terpos;
700  (*vtxg).raster = gridarray[t][s + 1].raster;
701  (*vtxg).specular = gridarray[t][s + 1].specular;
702  vtxg++; n++;
703 
704 
705  // CENTER
706  (*vtxg).tu = 0.5f; (*vtxg).tv = 0.5f;
707  if (meld)
708  (*vtxg).position = gridarray[t][s].position * 0.5f + gridarray[t + 1][s + 1].position * 0.5f - viewscreen->terpos;
709  else
710  (*vtxg).position = insidearray[t][s][2] - viewscreen->terpos;
711  D3DXColorLerp(&tempcolor, &gridarray[t][s].raster, &gridarray[t + 1][s + 1].raster, 0.5f);
712  (*vtxg).raster = tempcolor;
713  tempcolor.r = gridarray[t][s].specular.r * 2.0f;
714  tempcolor.g = gridarray[t][s].specular.g * 2.0f;
715  tempcolor.b = gridarray[t][s].specular.b * 2.0f;
716  (*vtxg).specular = tempcolor;
717  vtxg++; n++;
718 
719  // RIGHT MID
720  (*vtxg).tu = 1; (*vtxg).tv = 0.5f;
721  if (meld)
722  (*vtxg).position = gridarray[t + 1][s].position * 0.5f + gridarray[t + 1][s + 1].position * 0.5f - viewscreen->terpos;
723  else
724  (*vtxg).position = insidearray[t + 1][s][1] - viewscreen->terpos;
725  D3DXColorLerp(&tempcolor, &gridarray[t + 1][s].raster, &gridarray[t + 1][s + 1].raster, 0.5f);
726  (*vtxg).raster = tempcolor;
727  (*vtxg).specular = gridarray[t + 1][s].specular;
728  vtxg++; n++;
729 
730  // BOTTOM MID
731  (*vtxg).tu = 0.5f; (*vtxg).tv = 1;
732  if (meld)
733  (*vtxg).position = gridarray[t][s + 1].position * 0.5f + gridarray[t + 1][s + 1].position * 0.5f - viewscreen->terpos;
734  else
735  (*vtxg).position = insidearray[t][s + 1][0] - viewscreen->terpos;
736  D3DXColorLerp(&tempcolor, &gridarray[t][s + 1].raster, &gridarray[t + 1][s + 1].raster, 0.5f);
737  (*vtxg).raster = tempcolor;
738  (*vtxg).specular = gridarray[t][s + 1].specular;
739  vtxg++; n++;
740 
741 
742  // RIGHT MID
743  (*vtxg).tu = 1; (*vtxg).tv = 0.5f;
744  if (meld)
745  (*vtxg).position = gridarray[t + 1][s].position * 0.5f + gridarray[t + 1][s + 1].position * 0.5f - viewscreen->terpos;
746  else
747  (*vtxg).position = insidearray[t + 1][s][1] - viewscreen->terpos;
748  D3DXColorLerp(&tempcolor, &gridarray[t + 1][s].raster, &gridarray[t + 1][s + 1].raster, 0.5f);
749  (*vtxg).raster = tempcolor;
750  (*vtxg).specular = gridarray[t + 1][s].specular;
751  vtxg++; n++;
752 
753  // LOWER RIGHT
754  (*vtxg).tu = 1; (*vtxg).tv = 1;
755  (*vtxg).position = gridarray[t + 1][s + 1].position - viewscreen->terpos;
756  (*vtxg).raster = gridarray[t + 1][s + 1].raster;
757  (*vtxg).specular = gridarray[t + 1][s + 1].specular;
758  vtxg++; n++;
759 
760  // BOTTOM MID
761  (*vtxg).tu = 0.5f; (*vtxg).tv = 1;
762  if (meld)
763  (*vtxg).position = gridarray[t][s + 1].position * 0.5f + gridarray[t + 1][s + 1].position * 0.5f - viewscreen->terpos;
764  else
765  (*vtxg).position = insidearray[t][s + 1][0] - viewscreen->terpos;
766  D3DXColorLerp(&tempcolor, &gridarray[t][s + 1].raster, &gridarray[t + 1][s + 1].raster, 0.5f);
767  (*vtxg).raster = tempcolor;
768  (*vtxg).specular = gridarray[t][s + 1].specular;
769  vtxg++; n++;
770 
771  // we have to be within 16 km (8 plots)
772  if (gridarray[t][s].powered && gridarray[t][s].type == PlotType::DeoisPort)
774  }
775  else // not in patch data
776  {
777  if (gridarray[t][s].buildzoneOrdinal != -1)
778  {
779  SAFE_RELEASE(buildzone[gridarray[t][s].buildzoneOrdinal].VB);
780  sprintf_s(msg, sizeof(msg), "buildzone[%i].VB", gridarray[t][s].buildzoneOrdinal);
782 
783  if (buildzone[gridarray[t][s].buildzoneOrdinal].RTSVB)
784  {
785  SAFE_RELEASE(buildzone[gridarray[t][s].buildzoneOrdinal].RTSVB);
786  sprintf_s(msg, sizeof(msg), "buildzone[%i].RTSVB", gridarray[t][s].buildzoneOrdinal);
788  }
789 
790  sprintf_s(msg, sizeof(msg), "NiPD released VB slot %i!", gridarray[t][s].buildzoneOrdinal);
791  Trace(msg);
792 
793  gridarray[t][s].buildzoneOrdinal = -1; // keep layout in case we move back into patch
794  }
795 
796  // UPPER RIGHT
797  (*vtxg).tu = 1; (*vtxg).tv = 0;
798  (*vtxg).position = gridarray[t + 1][s].position - viewscreen->terpos;
799  (*vtxg).raster = gridarray[t + 1][s].raster;
800  (*vtxg).specular = gridarray[t + 1][s].specular;
801  vtxg++; n++;
802 
803  // LOWER LEFT
804  (*vtxg).tu = 0; (*vtxg).tv = 1;
805  (*vtxg).position = gridarray[t][s + 1].position - viewscreen->terpos;
806  (*vtxg).raster = gridarray[t][s + 1].raster;
807  (*vtxg).specular = gridarray[t][s + 1].specular;
808  vtxg++; n++;
809 
810 
811  // UPPER RIGHT
812  (*vtxg).tu = 1; (*vtxg).tv = 0;
813  (*vtxg).position = gridarray[t + 1][s].position - viewscreen->terpos;
814  (*vtxg).raster = gridarray[t + 1][s].raster;
815  (*vtxg).specular = gridarray[t + 1][s].specular;
816  vtxg++; n++;
817 
818  // LOWER RIGHT
819  (*vtxg).tu = 1; (*vtxg).tv = 1;
820  (*vtxg).position = gridarray[t + 1][s + 1].position - viewscreen->terpos;
821  (*vtxg).raster = gridarray[t + 1][s + 1].raster;
822  (*vtxg).specular = gridarray[t + 1][s + 1].specular;
823  vtxg++; n++;
824 
825  // LOWER LEFT
826  (*vtxg).tu = 0; (*vtxg).tv = 1;
827  (*vtxg).position = gridarray[t][s + 1].position - viewscreen->terpos;
828  (*vtxg).raster = gridarray[t][s + 1].raster;
829  (*vtxg).specular = gridarray[t][s + 1].specular;
830  vtxg++; n++;
831  }
832  }
833 
834  sprintf_s(msg, sizeof(msg), "Total vertices in terrain vertex buffer: %i/%i", n, visiblevertC);
835  Trace(msg);
836  assert(n <= visiblevertC);
837 
838 #ifdef DumpGridToWld
839 
840  // dump to wld
841  sprintf_s(msg, sizeof(msg), "%04i%04i.wld", tcp.u + 3038, tcp.v + 2038);
842  int wldfile = -1;
843  _sopen_s(&wldfile, msg, _O_WRONLY | _O_CREAT | _O_TRUNC | O_TEXT, _SH_DENYNO, _S_IWRITE);
844  sprintf_s(msg, sizeof(msg), " 2.23\n %i ,\n", uniqueVertices.size());
845  _write(wldfile, msg, strlen(msg));
846  float largestX = -FLT_MAX, largestY = -FLT_MAX, largestZ = -FLT_MAX;
847  float smallestX = FLT_MAX, smallestY = FLT_MAX, smallestZ = FLT_MAX;
848  for (int i = 0; i < uniqueVertices.size(); i++)
849  {
850  if (uniqueVertices.at(i).x > largestX)
851  largestX = uniqueVertices.at(i).x;
852  if (uniqueVertices.at(i).y > largestY)
853  largestY = uniqueVertices.at(i).y;
854  if (uniqueVertices.at(i).z > largestZ)
855  largestZ = uniqueVertices.at(i).z;
856  if (uniqueVertices.at(i).x < smallestX)
857  smallestX = uniqueVertices.at(i).x;
858  if (uniqueVertices.at(i).y < smallestY)
859  smallestY = uniqueVertices.at(i).y;
860  if (uniqueVertices.at(i).z < smallestZ)
861  smallestZ = uniqueVertices.at(i).z;
862  }
863  float avgX = (largestX - smallestX) * 0.5f + smallestX;
864  float avgY = (largestY - smallestY) * 0.5f + smallestY;
865  float avgZ = (largestZ - smallestZ) * 0.5f + smallestZ;
866  for (int i = 0; i < uniqueVertices.size(); i++)
867  {
868  sprintf_s(msg, sizeof(msg), "%+f ,%+f ,%+f ,\n", uniqueVertices.at(i).x - avgX, uniqueVertices.at(i).y - avgY, uniqueVertices.at(i).z - avgZ);
869  _write(wldfile, msg, strlen(msg));
870  } sprintf_s(msg, sizeof(msg), " %i ,\n 0.125000 ,0.500000 ,0 ,0 ,1 ,\n", polygons.size());
871  _write(wldfile, msg, strlen(msg));
872  for (int i = 0; i < polygons.size(); i++)
873  {
874  sprintf_s(msg, sizeof(msg), " 4 , %i , %i , %i , %i , %x ,0.347995 ,0.248828 ,0.027999 ,0.248828 ,0.027999 ,0.246328 ,0.347995 ,0.246328 ,-1.000000 , 0 ,\n",
875  polygons.at(i).a, polygons.at(i).b, polygons.at(i).c, polygons.at(i).d, polygons.at(i).color);
876  _write(wldfile, msg, strlen(msg));
877  }
878  sprintf_s(msg, sizeof(msg), "unused\nunused\nunused\n");
879  _write(wldfile, msg, strlen(msg));
880  _close(wldfile);
881 
882 #endif
883 
884 
885  V(viewscreen->m_avLocalGrid->Unlock());
886 
887  makeBuildings = true;
888  makeClouds = true;
889 #ifdef treetestC
890  maketrees = true;
891 #endif
892  keepgoing = false;
893 
894 
895  // calculate view vector over grid for optimization
896  // commented out 6/17/2018 for https://jira.risetvp.com/view.php?id=918 because we need north vector above clouds too!
897  //D3DXVECTOR3 leftside = gridarray[31][32].position - gridarray[31][30].position;
898  //D3DXVec3Normalize(&leftside, &leftside);
899  //D3DXVECTOR3 rightside = gridarray[32][32].position - gridarray[32][30].position;
900  //D3DXVec3Normalize(&rightside, &rightside);
901  //D3DXVec3Add(&viewnorth, &leftside, &rightside);
902  //D3DXVec3Scale(&viewnorth, &viewnorth, -0.5f);
903  //D3DXVec3Normalize(&viewnorth, &viewnorth);
904 
905 
906  Trace("gridproc.cpp (NAF) finished!");
907 
908 
909  geometryReady = true;
910 
911  } // end of !gridready
912 
913 
914  if (dataReady && makeClouds && keepgoing)
915  {
916  sprintf_s(msg, sizeof(msg), "gridproc.cpp (NAC) started... BCLoffsetu: %i BCLoffsetv: %i", viewscreen->BCLoffsetu, viewscreen->BCLoffsetv);
917  Trace(msg);
918 
923 
924 
926  D3DLOCALGRID* vtxh;
927 
928  V(viewscreen->m_avCloudGrid->Lock(0, 0, reinterpret_cast<void**>(&vtxh), 0));
929  // Cycle through all the upper-left vertices (grid squares)
930  for (t = 0; t < 64; t++)
931  {
932  for (s = 0; s < 64; s++)
933  {
934  (*vtxh).tu = static_cast<float>(t - 31 - viewscreen->BCLoffsetu) / csC;
935  (*vtxh).tv = static_cast<float>(s - 31 - viewscreen->BCLoffsetv) / csC;
936  (*vtxh).position = gridarray[t][s].cloudpos - viewscreen->cloudpos;
937 
938 
939  //sprintf_s(msg, sizeof(msg), "\tcloudpos t%i s%i tu%.1f tv%.1f x%.3f y%.3f z%.3f", t, s, (*vtxh).tu, (*vtxh).tv , (*vtxh).position.x, (*vtxh).position.y, (*vtxh).position.z);
940  //Trace(msg);
941 
942 
943  if (t > 0 && t < 63 && s > 0 && s < 63)
944  {
945  // i think this is the light from the ground that is reflecting on the cloud base
946  D3DXCOLOR tempcolor;
947  tempcolor.r = gridarray[t][s].specular.r + gridarray[t - 1][s - 1].specular.r + gridarray[t][s - 1].specular.r + gridarray[t + 1][s - 1].specular.r + gridarray[t - 1][s].specular.r + gridarray[t + 1][s].specular.r + gridarray[t - 1][s + 1].specular.r + gridarray[t][s + 1].specular.r + gridarray[t + 1][s + 1].specular.r;
948  tempcolor.g = gridarray[t][s].specular.g + gridarray[t - 1][s - 1].specular.g + gridarray[t][s - 1].specular.g + gridarray[t + 1][s - 1].specular.g + gridarray[t - 1][s].specular.g + gridarray[t + 1][s].specular.g + gridarray[t - 1][s + 1].specular.g + gridarray[t][s + 1].specular.g + gridarray[t + 1][s + 1].specular.g;
949  tempcolor.b = gridarray[t][s].specular.b + gridarray[t - 1][s - 1].specular.b + gridarray[t][s - 1].specular.b + gridarray[t + 1][s - 1].specular.b + gridarray[t - 1][s].specular.b + gridarray[t + 1][s].specular.b + gridarray[t - 1][s + 1].specular.b + gridarray[t][s + 1].specular.b + gridarray[t + 1][s + 1].specular.b;
950  tempcolor.r /= 9.0f; tempcolor.g /= 9.0f; tempcolor.b /= 9.0f;
951  (*vtxh).specular = tempcolor;
952  }
953  else
954  {
955  (*vtxh).specular = gridarray[t][s].specular;
956  }
957  (*vtxh++).diffuse = gridarray[t][s].clouddif;
958  }
959  }
960  V(viewscreen->m_avCloudGrid->Unlock());
961 
962  makeClouds = false;
963  keepgoing = false;
964 
965  Trace("gridproc.cpp (NAC) finished!");
966  }
967 
968 
969  if (dataReady && makeBuildings && keepgoing)
970  {
971  Trace("gridproc.cpp (NAB) started...!");
972 
973  bool addedBuilding = false;
974  for (t = 16; t < 47; t++) // not 48 because zone 2 and 3 look to right
975  {
976  for (s = 16; s < 47; s++)
977  {
978  // if apn has construction whose VB hasn't been created
979  if (gridarray[t][s].type > PlotType::NotZoned &&
980  gridarray[t][s].type < PlotType::PlotTypeEnum &&
981  gridarray[t][s].buildzoneOrdinal == -1)
982  {
983  HRESULT hr;
984  if (gridarray[t][s].IsUserColony())
985  {
986  // we may not have yet gotten the SRenderBuilding data so hold off until we do!
987  if (gridarray[t][s].layout1 != 0L || gridarray[t][s].layout2 != 0L || gridarray[t][s].layout3 != 0L || gridarray[t][s].layout4 != 0L)
988  {
989  // if we got here the grid wasn't ready when we got case 16
990  V(viewscreen->ptrBuildings->Building(t, s));
991  addedBuilding = true;
992  }
993  else
994  {
995  sprintf_s(msg, sizeof msg, "We have a building on the grid with a type %i (u%i v%i) but no zone or layout information yet ... waiting!", gridarray[t][s].type, t + tcp.u, s + tcp.v);
996  Trace(msg, Logger::Warn);
997  }
998  }
999  else
1000  {
1001  // government
1002  V(viewscreen->ptrBuildings->Building(t, s));
1003  addedBuilding = true;
1004  }
1005  // lets offset the clouds by 1km and 1km so we can set the vertex
1006  // over the cities to be the specular highlight
1007  }
1008  if (addedBuilding)
1009  t = s = 48;
1010  }
1011  }
1012  if (addedBuilding)
1013  Trace("Added a building, leaving checkconstruct true!");
1014  else
1015  makeBuildings = false;
1016 
1017  Trace("gridproc.cpp (NAB) finished!");
1018  }
1019 
1020 
1021 
1022  // Trees
1023 #ifdef treetestC
1024 #define fracC 32 // must be power of 2, not function of 2
1025  if (ground.maketrees && keepgoing)
1026  {
1027  treesC = 0;
1028  float flux = 1.0f;
1029  for (t = 29; t < 34; t++)
1030  {
1031  for (s = 29; s < 34; s++)
1032  {
1033  if ((powf(31.0f - (float)t, 2.0f) + powf(31.0f - (float)s, 2.0f)) <= 4.0f)
1034  {
1035  unsigned int fudgefactor = ((long)(tcp.u + t - 31) + 2038L) + ((long)(tcp.v + s - 31) + 2038L) * 8152L;
1036  srand(fudgefactor);
1037  if (gridarray[t][s].texture != 6 && gridarray[t][s].totexture != 6)
1038  {
1039  float density = 1.0f;
1040  float rough = flux, halfr = rough * 0.5f;
1041  float fractal[fracC + 1][fracC + 1];
1042  fractal[0][0] = fractal[fracC][0] = fractal[fracC][fracC] = fractal[0][fracC] = 0.0f;
1043  short iterate = fracC;
1044  short p, q, midp, midq;
1045  float peak = -999.0f, lull = 999.0f;
1046 
1047 
1048  while (iterate != 1)
1049  {
1050  for (p = 0; p < fracC; p += iterate)
1051  {
1052  midp = p + iterate / 2;
1053  for (q = 0; q < fracC; q += iterate)
1054  {
1055  midq = q + iterate / 2;
1056  f_temp = RandomFloat() * rough - halfr;
1057  // Diamond point
1058  fractal[midp][midq] = (fractal[p][q] + fractal[p + iterate][q + iterate] + fractal[p + iterate][q] + fractal[p][q + iterate]) * 0.25f + f_temp;
1059  if (fractal[midp][midq] > peak)
1060  peak = fractal[midp][midq];
1061  if (fractal[midp][midq] < lull)
1062  lull = fractal[midp][midq];
1063  // Square
1064  f_temp = RandomFloat() * rough - halfr;
1065  fractal[midp][q] = (fractal[p][q] + fractal[p + iterate][q]) * 0.5f + f_temp;
1066  if (fractal[midp][q] > peak)
1067  peak = fractal[midp][q];
1068  if (fractal[midp][q] < lull)
1069  lull = fractal[midp][q];
1070  f_temp = RandomFloat() * rough - halfr;
1071  fractal[midp][q + iterate] = (fractal[p][q + iterate] + fractal[p + iterate][q + iterate]) * 0.5f + f_temp;
1072  if (fractal[midp][q + iterate] > peak)
1073  peak = fractal[midp][q + iterate];
1074  if (fractal[midp][q + iterate] < lull)
1075  lull = fractal[midp][q + iterate];
1076  f_temp = RandomFloat() * rough - halfr;
1077  fractal[p][midq] = (fractal[p][q] + fractal[p][q + iterate]) * 0.5f + f_temp;
1078  if (fractal[p][midq] > peak)
1079  peak = fractal[p][midq];
1080  if (fractal[p][midq] < lull)
1081  lull = fractal[p][midq];
1082  f_temp = RandomFloat() * rough - halfr;
1083  fractal[p + iterate][midq] = (fractal[p + iterate][q] + fractal[p + iterate][q + iterate]) * 0.5f + f_temp;
1084  if (fractal[p + iterate][midq] > peak)
1085  peak = fractal[p + iterate][midq];
1086  if (fractal[p + iterate][midq] < lull)
1087  lull = fractal[p + iterate][midq];
1088 
1089  // if (fractal[midp][midq]>1.0f)
1090  // fractal[midp][midq]=1.0f;
1091  // else if (fractal[midp][midq]<0.0f)
1092  // fractal[midp][midq]=0.0f;
1093  }
1094  }
1095  iterate /= 2;
1096  rough *= 0.5f; // 0.5 is perfect, 0.4 makes it fade to edges
1097  halfr *= 0.5f;
1098  }
1099 
1100  // if (t==32 && s==32)
1101  // {
1102  // sprintf_s(msg, sizeof(msg), "Making trees... density %f, peak %f avg %f", density, peak, average);
1103  // Trace(msg);
1104  // }
1105 
1106  for (p = 0; p < fracC; p++)
1107  {
1108  for (q = 0; q < fracC; q++)
1109  {
1110  float edgep, edgeq, edge;
1111  if (p < (fracC / 2))
1112  edgep = (float)p / (float)(fracC / 4);
1113  else
1114  edgep = (float)(fracC - p) / (float)(fracC / 4);
1115  if (q < (fracC / 2))
1116  edgeq = (float)q / (float)(fracC / 4);
1117  else
1118  edgeq = (float)(fracC - q) / (float)(fracC / 4);
1119  if (edgep < edgeq)
1120  edge = edgep;
1121  else
1122  edge = edgeq;
1123  if (edge > 1.0f)
1124  edge = 1.0f;
1125 
1126  short shorttest = (short)(fractal[p][q] * edge * 255.0f);
1127  if (
1128  shorttest % 3 == 1) // &&
1129  // shorttest>=(short)(((peak-lull)*(1.0f-density)+lull)*255.0f)
1130  // ) //.0039
1131  {
1132  float adjx = RandomFloat() * 1.0f / (float)(fracC / 2) * 0.75f - 1.0f / (float)(fracC / 2) * 0.375f;
1133  float adjy = RandomFloat() * 1.0f / (float)(fracC / 2) * 0.75f - 1.0f / (float)(fracC / 2) * 0.375f;
1134 
1135  if (p < (fracC / 2) && q < (fracC / 2))
1136  {
1137  result = (insidearray[t][s][0] - gridarray[t][s].position) * ((float)p / (float)(fracC / 2) + adjx);
1138  result += (insidearray[t][s][1] - gridarray[t][s].position) * ((float)q / (float)(fracC / 2) + adjy);
1139  result = -(result + gridarray[t][s].position);
1140  }
1141  else if (p >= (fracC / 2) && q < (fracC / 2))
1142  {
1143  result = (gridarray[t + 1][s].position - insidearray[t][s][0]) * ((float)(p - fracC / 2) / (float)(fracC / 2) + adjx);
1144  result += (insidearray[t][s][2] - insidearray[t][s][0]) * ((float)q / (float)(fracC / 2) + adjy);
1145  result = -(result + insidearray[t][s][0]);
1146  }
1147  else if (p < (fracC / 2) && q >= (fracC / 2))
1148  {
1149  result = (insidearray[t][s][2] - insidearray[t][s][1]) * ((float)p / (float)(fracC / 2) + adjx);
1150  result += (gridarray[t][s + 1].position - insidearray[t][s][1]) * ((float)(q - fracC / 2) / (float)(fracC / 2) + adjy);
1151  result = -(result + insidearray[t][s][1]);
1152  }
1153  else if (p >= (fracC / 2) && q >= (fracC / 2))
1154  {
1155  result = (insidearray[t + 1][s][1] - insidearray[t][s][2]) * ((float)(p - fracC / 2) / (float)(fracC / 2) + adjx);
1156  result += (insidearray[t][s + 1][0] - insidearray[t][s][2]) * ((float)(q - fracC / 2) / (float)(fracC / 2) + adjy);
1157  result = -(result + insidearray[t][s][2]);
1158  }
1159 
1160  treelist[treesC] = result;
1161  treesC++;
1162  if (treesC >= 16383)
1163  {
1164  p = q = fracC;
1165  t = s = 34;
1166  }
1167  }
1168  }
1169  }
1170  }
1171  }
1172  }
1173  }
1174  sprintf_s(msg, sizeof(msg), "Trees: %i", treesC);
1175  Trace(msg);
1176  ground.maketrees = false;
1177  }
1178 #endif
1179 }
1180 
1181 void grid::CalculateInsideArray(short t, short s) const
1182 {
1183  if (gridarray[t][s].pri_landform == 1 || gridarray[t][s].sec_landform == 1 || gridarray[t][s].ter_landform == 1 || // water
1184  gridarray[t - 1][s].pri_landform == 1 || gridarray[t - 1][s].sec_landform == 1 || gridarray[t - 1][s].ter_landform == 1 || // water
1185  gridarray[t][s - 1].pri_landform == 1 || gridarray[t][s - 1].sec_landform == 1 || gridarray[t][s - 1].ter_landform == 1 || // water
1186 
1187  gridarray[t - 1][s].pri_landform == 255 || gridarray[t][s - 1].pri_landform == 255 || // corners
1188 
1189  // Deois
1190  gridarray[t - 1][s].IsDeois() || gridarray[t][s - 1].IsDeois() || gridarray[t][s].IsDeois() ||
1191 
1192  // User Airfields
1193  gridarray[t][s].type == PlotType::UserAirfield || gridarray[t - 1][s].type == PlotType::UserAirfield || gridarray[t][s - 1].type == PlotType::UserAirfield ||
1194 
1195  // Arcridge
1196  gridarray[t][s].type == PlotType::Arcridge || gridarray[t - 1][s].type == PlotType::Arcridge || gridarray[t][s - 1].type == PlotType::Arcridge)
1197  {
1198  insidearray[t][s][0] = gridarray[t][s].position * 0.5f + gridarray[t + 1][s].position * 0.5f;
1199  insidearray[t][s][1] = gridarray[t][s].position * 0.5f + gridarray[t][s + 1].position * 0.5f;
1200  insidearray[t][s][2] = gridarray[t][s].position * 0.25f + gridarray[t + 1][s + 1].position * 0.25f +
1201  gridarray[t + 1][s].position * 0.25f + gridarray[t][s + 1].position * 0.25f;
1202  }
1203  else
1204  {
1206  // Upper left 1
1207  insidearray[t][s][0] = viewscreen->D3DXVec3Qerp(&gridarray[t - 1][s].position, &gridarray[t][s].position, &gridarray[t + 1][s].position, 1.5f);
1208  // Lower left 2
1209  insidearray[t][s][1] = viewscreen->D3DXVec3Qerp(&gridarray[t][s - 1].position, &gridarray[t][s].position, &gridarray[t][s + 1].position, 1.5f);
1210  // Lower right 3
1211  insidearray[t][s][2] = viewscreen->D3DXVec3Qerp(&gridarray[t - 1][s - 1].position, &gridarray[t][s].position, &gridarray[t + 1][s + 1].position, 1.5f);
1212  }
1213 }
unsigned char v
Definition: globals.h:334
void CalculateCubeAndTcp()
Definition: grid.cpp:79
LPDIRECT3DVERTEXBUFFER9 m_avCloudGrid
Definition: Viewscreen.h:109
bool powered
Definition: globals.h:297
VECTOR2SHORT tcp
Definition: grid.h:34
void ReceiveWholeGrid(SRenderGrid datapacket)
Definition: grid.cpp:109
double cloudprecisiony
Definition: Viewscreen.h:236
D3DXVECTOR3 D3DXVec3Qerp(D3DXVECTOR3 *vel0, D3DXVECTOR3 *vel1, D3DXVECTOR3 *vel2, float t) const
bool g_bAboveClouds
Definition: globals.cpp:22
D3DXVECTOR3 position
Definition: globals.h:549
void CalculateInsideArray(short t, short s) const
Definition: grid.cpp:1181
GameClass * gameclass
Definition: Viewscreen.h:292
unsigned char roads
Definition: globals.h:291
VECTOR2SHORT CalculateWrap(short u, short v, char cube, char *rotate) const
unsigned char zone
Definition: globals.h:291
long layout2
Definition: globals.h:293
void SendToServer(void *pData, DWORD dwSize, bool bGuaranteed, PacketOrdering order=ORDERING_NONE) const
Definition: Networking.cpp:59
unsigned char runways
Definition: globals.h:335
VECTOR2SHORT CalculateCGC(D3DXVECTOR3 position, char cube) const
bool visiblegrid[63][63]
Definition: Viewscreen.h:263
bool geometryReady
Definition: grid.h:30
double precisiony
Definition: globals.h:550
D3DXVECTOR3 position
Definition: globals.h:280
s_network_objects playerships[MAX_SCAN]
Definition: globals.cpp:174
LPDIRECT3DVERTEXBUFFER9 m_avLocalGrid
Definition: Viewscreen.h:111
unsigned char ter_landform
Definition: globals.h:338
void ClearGrid()
Definition: grid.cpp:59
float tu
Definition: globals.h:272
unsigned char pri_landform
Definition: globals.h:284
bool markerBeaconsPowered
Definition: GridProperties.h:5
unsigned char u
Definition: globals.h:334
char cube
Definition: grid.h:35
unsigned char sec_landform
Definition: globals.h:286
PlotType type
Definition: globals.h:282
double terprecisionx
Definition: Viewscreen.h:235
unsigned char pri_transition
Definition: globals.h:285
#define drawlistC
Definition: globals.h:55
double terprecisionz
Definition: Viewscreen.h:235
D3DXVECTOR3 terpos
Definition: Viewscreen.h:233
unsigned char sec_transition
Definition: globals.h:287
GridProperties gridProperties
Definition: grid.h:36
D3DXCOLOR raster
Definition: globals.h:289
long layout4
Definition: globals.h:293
Networking * networking
Definition: GameClass.h:107
buildings * ptrBuildings
Definition: Viewscreen.h:281
double terprecisiony
Definition: Viewscreen.h:235
double precisionx
Definition: globals.h:550
grid(Viewscreen *ptrGame)
Definition: grid.cpp:4
BATCHINDEX2 drawlist[drawlistC]
Definition: globals.cpp:156
unsigned char sec_landform
Definition: globals.h:338
long layout1
Definition: globals.h:293
char oldcube
Definition: grid.h:16
BUILDZONE buildzone[buildingVBC]
Definition: globals.cpp:165
unsigned char sec_transition
Definition: globals.h:338
void Process()
Definition: grid.cpp:166
#define visiblevertC
Definition: globals.h:56
#define csC
Definition: globals.h:17
D3DXCOLOR clouddif
Definition: globals.h:281
const D3DXVECTOR3 centerC
D3DXVECTOR3 insidearray[63][63][3]
Definition: globals.cpp:154
LOCALGRID2 CalculateSRV(short t, short s, VECTOR2SHORT tcp, char cube, SRenderVertex sourcedata)
VECTOR2SHORT oldtcp
Definition: grid.h:17
short buildzoneOrdinal
Definition: globals.h:292
void Log(const char *msg, Level level=Info, int errorCode=0)
Definition: Logger.cpp:11
unsigned char ter_landform
Definition: globals.h:288
unsigned char runwayLights
Definition: globals.h:336
unsigned char pri_landform
Definition: globals.h:338
D3DXVECTOR3 cloudpos
Definition: globals.h:280
bool g_bAboveCloudsOld
Definition: grid.h:18
bool dataReady
Definition: grid.h:29
D3DXVECTOR3 cloudpos
Definition: Viewscreen.h:258
double cloudprecisionz
Definition: Viewscreen.h:236
void RequestWholeGrid()
Definition: grid.cpp:145
char CalculateCube(D3DXVECTOR3 position) const
HRESULT Building(short t, short s) const
Definition: buildings.cpp:33
bool makeClouds
Definition: grid.h:33
long layout3
Definition: globals.h:293
short elevation
Definition: globals.h:294
short BCLoffsetu
Definition: Viewscreen.h:266
LOCALGRID2 gridarray[64][64]
Definition: globals.cpp:153
Viewscreen * viewscreen
Definition: grid.h:14
void Trace(const char *msg, Logger::Level severity=Logger::Level::Info) const
Definition: grid.cpp:12
unsigned char pri_transition
Definition: globals.h:338
Level
Definition: Logger.h:19
short BCLoffsetv
Definition: Viewscreen.h:266
static bool CheckLayout(unsigned i, LOCALGRID2 localgrid2)
Definition: buildings.cpp:16
float tu
Definition: globals.h:265
void UpdateTrackedResource(const char *name, int status)
Definition: GameClass.cpp:2725
void AddToCallStack(const char *msg)
Definition: Logger.cpp:86
bool makeBuildings
Definition: grid.h:32
float RandomFloat()
Definition: MathUtilities.h:98
Logger * logger
Definition: Viewscreen.h:293
double precisionz
Definition: globals.h:550
D3DXCOLOR specular
Definition: globals.h:281
char dataPending
Definition: grid.h:31
unsigned char roads
Definition: globals.h:335
double cloudprecisionx
Definition: Viewscreen.h:236