OpenClonk
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros
C4Viewport.cpp
Go to the documentation of this file.
1 /*
2  * OpenClonk, http://www.openclonk.org
3  *
4  * Copyright (c) 1998-2000, Matthes Bender
5  * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de/
6  * Copyright (c) 2009-2016, The OpenClonk Team and contributors
7  *
8  * Distributed under the terms of the ISC license; see accompanying file
9  * "COPYING" for details.
10  *
11  * "Clonk" is a registered trademark of Matthes Bender, used with permission.
12  * See accompanying file "TRADEMARK" for details.
13  *
14  * To redistribute this file separately, substitute the full license texts
15  * for the above references.
16  */
17 
18 /* A viewport to each player */
19 
20 #include "C4Include.h"
22 #include "game/C4Viewport.h"
23 
25 #include "editor/C4Console.h"
26 #include "object/C4Def.h"
27 #include "object/C4Object.h"
28 #include "game/C4FullScreen.h"
29 #include "lib/C4Stat.h"
30 #include "player/C4Player.h"
31 #include "object/C4ObjectMenu.h"
32 #include "gui/C4MouseControl.h"
33 #include "landscape/C4PXS.h"
34 #include "gui/C4GameMessage.h"
35 #include "gui/C4ScriptGuiWindow.h"
37 #include "game/C4GraphicsSystem.h"
38 #include "landscape/C4Landscape.h"
39 #include "landscape/C4Sky.h"
40 #include "player/C4PlayerList.h"
41 #include "object/C4GameObjects.h"
42 #include "network/C4Network2.h"
44 #include "landscape/C4Particles.h"
45 #include "graphics/C4Draw.h"
46 
47 void C4Viewport::DropFile(const char* fileName, float x, float y)
48 {
49  Game.DropFile(fileName, GetViewX()+x/Zoom, GetViewY()+y/Zoom);
50 }
51 
52 bool C4Viewport::UpdateOutputSize(int32_t new_width, int32_t new_height)
53 {
54  if (!pWindow) return false;
55  // Output size
56  C4Rect rect;
57  if (new_width)
58  {
59  rect.x = rect.y = 0;
60  rect.Wdt = new_width;
61  rect.Hgt = new_height;
62  }
63  else
64  {
65 #if defined(WITH_QT_EDITOR)
66  // Never query the window - size is always passed from Qt.
67  return false;
68 #else
69  if (!pWindow->GetSize(&rect)) return false;
70 #endif
71  }
72  OutX=rect.x; OutY=rect.y;
73  ViewWdt=rect.Wdt; ViewHgt=rect.Hgt;
74  ScrollView(0,0);
75  // Scroll bars
77  // Reset menus
78  ResetMenuPositions=true;
79  // update internal GL size
80  if (pWindow && pWindow->pSurface)
81  pWindow->pSurface->UpdateSize(ViewWdt, ViewHgt);
82  // Update zoom limits based on new size
83  C4Player *plr = ::Players.Get(Player);
84  if (plr) plr->ZoomLimitsToViewport(this);
85  // Done
86  return true;
87 }
88 
90 {
91  Player = 0;
92  viewX = viewY = 0;
93  targetViewX = targetViewY = 0;
94  ViewWdt = ViewHgt = 0;
96  OutX = OutY = ViewWdt = ViewHgt = 0;
97  DrawX = DrawY = 0;
98  Zoom = 1.0;
99  ZoomTarget = 0.0;
100  ViewportOpenFrame = 0;
101  ZoomLimitMin = ZoomLimitMax = 0; // no limit
102  Next = nullptr;
103  PlayerLock = true;
104  ResetMenuPositions = false;
105  viewOffsX = viewOffsY = 0;
106  fIsNoOwnerViewport = false;
107 }
108 
110 {
111  DisableFoW();
112  if (pWindow) { delete pWindow->pSurface; pWindow->Clear(); }
113 }
114 
115 void C4Viewport::DrawOverlay(C4TargetFacet &cgo, const ZoomData &GameZoom)
116 {
117  if (!Game.C4S.Head.Film || !Game.C4S.Head.Replay)
118  {
119  // Player info
120  C4ST_STARTNEW(PInfoStat, "C4Viewport::DrawOverlay: Player Info")
121  DrawPlayerInfo(cgo);
122  C4ST_STOP(PInfoStat)
123  C4ST_STARTNEW(MenuStat, "C4Viewport::DrawOverlay: Menu")
124  DrawMenu(cgo);
125  C4ST_STOP(MenuStat)
126  }
127 
128  // Control overlays (if not film/replay)
129  if (!Game.C4S.Head.Film || !Game.C4S.Head.Replay)
130  {
131  // Mouse control
132  if (::MouseControl.IsViewport(this))
133  {
134  C4ST_STARTNEW(MouseStat, "C4Viewport::DrawOverlay: Mouse")
135  ::MouseControl.Draw(cgo, GameZoom);
136  // Draw GUI-mouse in EM if active
137  if (pWindow) ::pGUI->RenderMouse(cgo);
138  C4ST_STOP(MouseStat)
139  }
140  }
141 }
142 
144 {
145  // Get player
146  C4Player *pPlr = ::Players.Get(Player);
147 
148  // for menus, cgo is using GUI-syntax: TargetX/Y marks the drawing offset; x/y/Wdt/Hgt marks the offset rect
149  C4TargetFacet cgo; cgo.Set(cgo0);
150  cgo.X = 0; cgo.Y = 0;
151  cgo.Wdt = cgo0.Wdt * cgo0.Zoom; cgo.Hgt = cgo0.Hgt * cgo0.Zoom;
152  cgo.TargetX = float(cgo0.X); cgo.TargetY = float(cgo0.Y);
153  cgo.Zoom = 1;
154  pDraw->SetZoom(cgo.X, cgo.Y, cgo.Zoom);
155 
156  // Player eliminated
157  if (pPlr && pPlr->Eliminated)
158  {
159  pDraw->TextOut(FormatString(LoadResStr(pPlr->Surrendered ? "IDS_PLR_SURRENDERED" : "IDS_PLR_ELIMINATED"),pPlr->GetName()).getData(),
160  ::GraphicsResource.FontRegular, 1.0, cgo.Surface,cgo.TargetX+cgo.Wdt/2,cgo.TargetY+2*cgo.Hgt/3,0xfaFF0000,ACenter);
161  return;
162  }
163 
164  // Player cursor object menu
165  if (pPlr && pPlr->Cursor && pPlr->Cursor->Menu)
166  {
168  // if mouse is dragging, make it transparent to easy construction site drag+drop
169  bool fDragging=false;
171  {
172  fDragging = true;
173  pDraw->ActivateBlitModulation(0x4fffffff);
174  }
175  // draw menu
176  pPlr->Cursor->Menu->Draw(cgo);
177  // reset modulation for dragging
178  if (fDragging) pDraw->DeactivateBlitModulation();
179  }
180  // Player menu
181  if (pPlr && pPlr->Menu.IsActive())
182  {
184  pPlr->Menu.Draw(cgo);
185  }
186  // Fullscreen menu
188  {
190  FullScreen.pMenu->Draw(cgo);
191  }
192 
193  // Flag done
194  ResetMenuPositions=false;
195 
196  // restore Zoom
197  pDraw->SetZoom(cgo0.X, cgo0.Y, cgo0.Zoom);
198 }
199 
200 void C4Viewport::Draw(C4TargetFacet &cgo0, bool fDrawGame, bool fDrawOverlay)
201 {
202 #ifdef USE_CONSOLE
203  // No drawing in console mode
204  return;
205 #endif
206  C4TargetFacet cgo; cgo.Set(cgo0);
207  ZoomData GameZoom;
208  GameZoom.X = cgo.X; GameZoom.Y = cgo.Y;
209  GameZoom.Zoom = cgo.Zoom;
210 
211  // Draw landscape borders
216 
217  // Compute non-bordered viewport area
218  cgo.X += BorderLeft; cgo.Y += BorderTop; cgo.Wdt -= (BorderLeft + BorderRight) / cgo.Zoom; cgo.Hgt -= (BorderTop + BorderBottom) / cgo.Zoom;
219  cgo.TargetX += BorderLeft / Zoom; cgo.TargetY += BorderTop / Zoom;
220 
221  // Apply Zoom
222  GameZoom.X = cgo.X; GameZoom.Y = cgo.Y;
223  pDraw->SetZoom(GameZoom);
224  // Set clipper to integer bounds around floating point viewport region
226  const C4Rect& clipRectInt(clipRect);
227  pDraw->SetPrimaryClipper(clipRectInt.x, clipRectInt.y, clipRectInt.x + clipRectInt.Wdt - 1, clipRectInt.y + clipRectInt.Hgt - 1);
228 
229  last_game_draw_cgo = cgo;
230 
231  if (fDrawGame)
232  {
233  // --- activate FoW here ---
234 
235  // Render FoW only if active for player
236  C4Player *pPlr = ::Players.Get(Player);
237  C4FoWRegion* pFoW = nullptr;
238  if (pPlr && pPlr->fFogOfWar) pFoW = this->pFoW.get();
239 
240  // Update FoW
241  if (pFoW)
242  {
243  // Viewport region in landscape coordinates
244  const FLOAT_RECT vpRect = { cgo.TargetX, cgo.TargetX + cgo.Wdt, cgo.TargetY, cgo.TargetY + cgo.Hgt };
245  // Region in which the light is calculated
246  // At the moment, just choose integer coordinates to surround the viewport
247  const C4Rect lightRect(vpRect);
248  if (!lightRect.Wdt || !lightRect.Hgt)
249  {
250  // Do not bother initializing FoW on empty region; would cause errors in drawing proc
251  pFoW = nullptr;
252  }
253  else
254  {
255  pFoW->Update(lightRect, vpRect);
256 
257  if (!pFoW->Render())
258  {
259  // If FoW init fails, do not set it for further drawing
260  pFoW = nullptr;
261  }
262  }
263  }
264 
265  pDraw->SetFoW(pFoW);
266 
267  C4ST_STARTNEW(SkyStat, "C4Viewport::Draw: Sky")
268  ::Landscape.GetSky().Draw(cgo);
269  C4ST_STOP(SkyStat)
270 
271  ::Objects.Draw(cgo, Player, -2147483647 - 1 /* INT32_MIN */, 0);
272 
273  // Draw Landscape
274  C4ST_STARTNEW(LandStat, "C4Viewport::Draw: Landscape")
275  ::Landscape.Draw(cgo, pFoW);
276  C4ST_STOP(LandStat)
277 
278  // draw PXS (unclipped!)
279  C4ST_STARTNEW(PXSStat, "C4Viewport::Draw: PXS")
280  ::PXS.Draw(cgo);
281  C4ST_STOP(PXSStat)
282 
283  // Draw objects which are behind the particle plane.
284  const int particlePlane = 900;
285  C4ST_STARTNEW(ObjStat, "C4Viewport::Draw: Objects (1)")
286  ::Objects.Draw(cgo, Player, 1, particlePlane);
287  C4ST_STOP(ObjStat)
288 
289  // Draw global dynamic particles on a specific Plane
290  // to enable scripters to put objects both behind and in front of particles.
291  C4ST_STARTNEW(PartStat, "C4Viewport::Draw: Dynamic Particles")
293  C4ST_STOP(PartStat)
294 
295  // Now the remaining objects in front of the particles (e.g. GUI elements)
296  C4ST_STARTNEW(Obj2Stat, "C4Viewport::Draw: Objects (2)")
297  ::Objects.Draw(cgo, Player, particlePlane + 1, 2147483647 /* INT32_MAX */);
298  C4ST_STOP(Obj2Stat)
299 
300  // Draw everything else without FoW
301  pDraw->SetFoW(nullptr);
302  }
303  else
304  {
305  pDraw->DrawBoxDw(cgo.Surface, cgo.X, cgo.Y, cgo.X + cgo.Wdt, cgo.Y + cgo.Hgt, 0xff000000);
306  }
307 
308  // Draw PathFinder
310 
311  // Draw overlay
313 
314  // Lights overlay
315  if (::GraphicsSystem.ShowLights && pFoW) pFoW->Render(&cgo);
316 
317  if (fDrawOverlay)
318  {
319  // Determine zoom of overlay
320  float fGUIZoom = GetGUIZoom();
321  // now restore complete cgo range for overlay drawing
322  pDraw->SetZoom(DrawX,DrawY, fGUIZoom);
324  C4TargetFacet gui_cgo;
325  gui_cgo.Set(cgo0);
326 
327  gui_cgo.X = DrawX; gui_cgo.Y = DrawY; gui_cgo.Zoom = fGUIZoom;
328  gui_cgo.Wdt = int(float(ViewWdt)/fGUIZoom); gui_cgo.Hgt = int(float(ViewHgt)/fGUIZoom);
329  gui_cgo.TargetX = GetViewX(); gui_cgo.TargetY = GetViewY();
330 
331  last_gui_draw_cgo = gui_cgo;
332 
333  // draw custom GUI objects
335 
336  // Draw overlay
337  C4ST_STARTNEW(OvrStat, "C4Viewport::Draw: Overlay")
338 
340 
341  // Game messages
342  C4ST_STARTNEW(MsgStat, "C4Viewport::DrawOverlay: Messages")
343  pDraw->SetZoom(0, 0, 1.0);
344  ::Messages.Draw(gui_cgo, cgo, Player);
345  C4ST_STOP(MsgStat)
346 
347  // ingame menus
348  C4ST_STARTNEW(GuiWindowStat, "C4Viewport::DrawOverlay: Menus")
349  pDraw->SetZoom(0, 0, 1.0);
350  ::Game.ScriptGuiRoot->DrawAll(gui_cgo, Player);
351  C4ST_STOP(GuiWindowStat)
352 
353  DrawOverlay(gui_cgo, GameZoom);
354 
355  // Netstats
357  ::Network.DrawStatus(gui_cgo);
358 
359  C4ST_STOP(OvrStat)
360 
361  }
362 
363  // Remove zoom n clippers
364  pDraw->SetZoom(0, 0, 1.0);
366 
367 }
368 
370 {
371  if (pWindow)
372  {
373  C4Rect rtSrc,rtDst;
374  rtSrc.x = DrawX; rtSrc.y = DrawY; rtSrc.Wdt = ViewWdt; rtSrc.Hgt = ViewHgt;
375  rtDst.x = OutX; rtDst.y = OutY; rtDst.Wdt = ViewWdt; rtDst.Hgt = ViewHgt;
376  pWindow->pSurface->PageFlip(&rtSrc, &rtDst);
377  }
378 }
379 
381 {
382  // Adjust position
384  // Current graphics output
385  C4TargetFacet cgo;
386  C4Surface *target = pWindow ? pWindow->pSurface : FullScreen.pSurface;
387  cgo.Set(target,DrawX,DrawY,float(ViewWdt)/Zoom,float(ViewHgt)/Zoom,GetViewX(),GetViewY(),Zoom);
388  pDraw->PrepareRendering(target);
389  // Load script uniforms from Global.Uniforms
390  auto uniform_pop = pDraw->scriptUniform.Push(::GameScript.ScenPropList.getPropList());
391  // Do not spoil game contents on owner-less viewport
392  bool draw_game = true;
393  if (Player == NO_OWNER)
394  if (!::Application.isEditor && !::Game.DebugMode)
396  if (::Game.PlayerInfos.GetJoinIssuedPlayerCount() > 0) // free scrolling allowed if the scenario was started explicitely without players to inspect the landscape
397  if (Game.C4S.Landscape.Secret)
398  draw_game = false;
399  // Draw
400  Draw(cgo, draw_game, true);
401  // Blit output
402  BlitOutput();
403 }
404 
405 /* This method is called whenever the viewport size is changed. Thus, its job
406  is to recalculate the zoom and zoom limits with the new values for ViewWdt
407  and ViewHgt. */
409 {
410  // Zoom is only initialized by player or global setting during viewport creation time, because after that
411  // the player may have changed to another preferred zoom.
412  // However, viewports may change multiple times during startup (because of NO_OWNER viewport being deleted
413  // and possible other player joins). So check by frame counter. Zoom changes done in paused mode on the
414  // player init frame will be lost, but that should not be a problem.
416  InitZoom();
417 
418  C4Player *plr = Players.Get(Player);
419  if (plr)
420  plr->ZoomLimitsToViewport(this);
421  else
422  SetZoomLimits(0.8*std::min<float>(float(ViewWdt)/::Landscape.GetWidth(),float(ViewHgt)/::Landscape.GetHeight()), 8);
423 
424 }
425 
427 {
428  C4Player *plr = Players.Get(Player);
429  if (plr)
430  {
431  plr->ZoomToViewport(this, true);
432  }
433  else
434  {
435  ZoomTarget = std::max<float>(float(ViewWdt)/::Landscape.GetWidth(), 1.0f);
436  Zoom = ZoomTarget;
437  }
438 }
439 
440 void C4Viewport::ChangeZoom(float by_factor)
441 {
442  ZoomTarget *= by_factor;
445 }
446 
447 void C4Viewport::SetZoom(float to_value, bool direct)
448 {
449  ZoomTarget = to_value;
450  if (Player != NO_OWNER || !::Application.isEditor)
451  {
454  }
455  // direct: Set zoom without scrolling to it
456  if (direct) Zoom = ZoomTarget;
457 }
458 
459 void C4Viewport::SetZoomLimits(float to_min_zoom, float to_max_zoom)
460 {
461  ZoomLimitMin = to_min_zoom;
462  ZoomLimitMax = to_max_zoom;
464  ChangeZoom(1); // Constrains zoom to limit.
465 }
466 
467 float C4Viewport::GetZoomByViewRange(int32_t size_x, int32_t size_y) const
468 {
469  // set zoom such that both size_x and size_y are guarantueed to fit into the viewport range
470  // determine whether zoom is to be calculated by x or by y
471  bool zoom_by_y = false;
472  if (size_x && size_y)
473  {
474  zoom_by_y = (size_y * ViewWdt > size_x * ViewHgt);
475  }
476  else if (size_y)
477  {
478  // no x size passed - zoom by y
479  zoom_by_y = true;
480  }
481  else
482  {
483  // 0/0 size passed - zoom to default
484  if (!size_x)
485  size_x = C4VP_DefViewRangeX * 2;
486  zoom_by_y = false;
487  }
488  // zoom calculation
489  if (zoom_by_y)
490  return float(ViewHgt) / size_y;
491  else
492  return float(ViewWdt) / size_x;
493 }
494 
495 void C4Viewport::SetZoom(float zoomValue)
496 {
497  Zoom = zoomValue;
498  // also set target to prevent zoom from changing back
499  ZoomTarget = zoomValue;
500 }
501 
503 {
504  // Move zoom towards target zoom
505  if (ZoomTarget < 0.000001f) CalculateZoom();
506  // Change Zoom
507 
508  if (Zoom != ZoomTarget)
509  {
510  float DeltaZoom = Zoom / ZoomTarget;
511  if (DeltaZoom<1) DeltaZoom = 1 / DeltaZoom;
512 
513  // Minimal Zoom change factor
514  static const float Z0 = pow(C4GFX_ZoomStep, 1.0f / 8.0f);
515 
516  // We change zoom based on (logarithmic) distance of current zoom
517  // to target zoom. The greater the distance the more we adjust the
518  // zoom in one frame. There is a minimal zoom change Z0 to make sure
519  // we reach ZoomTarget in finite time.
520  float ZoomAdjustFactor = Z0 * pow(DeltaZoom, 1.0f / 8.0f);
521 
522  if (Zoom == 0)
523  Zoom = ZoomTarget;
524  else
525  {
526  // Remember old viewport center
527  float view_mid_x = this->viewX + float(this->ViewWdt) / Zoom / 2.0f;
528  float view_mid_y = this->viewY + float(this->ViewHgt) / Zoom / 2.0f;
529 
530  if (Zoom < ZoomTarget)
531  Zoom = std::min(Zoom * ZoomAdjustFactor, ZoomTarget);
532  if (Zoom > ZoomTarget)
533  Zoom = std::max(Zoom / ZoomAdjustFactor, ZoomTarget);
534 
535  // Restore new viewport center
536  this->viewX = view_mid_x - float(this->ViewWdt) / Zoom / 2.0f;
537  this->viewY = view_mid_y - float(this->ViewHgt) / Zoom / 2.0f;
538  }
539  }
540  // Adjust position
541  AdjustPosition(false);
542 }
543 
544 void C4Viewport::AdjustPosition(bool immediate)
545 {
546  if (ViewWdt == 0 || ViewHgt == 0)
547  {
548  // zero-sized viewport, possibly minimized editor window
549  // don't do anything then
550  return;
551  }
552 
553  assert(Zoom>0);
554  assert(ZoomTarget>0);
555 
556  float ViewportScrollBorder = fIsNoOwnerViewport ? 0 : float(C4ViewportScrollBorder);
557  C4Player *pPlr = ::Players.Get(Player);
558 
559  // View position
560  if (PlayerLock && ValidPlr(Player))
561  {
562  float scrollRange, extraBoundsX, extraBoundsY;
563 
564  scrollRange = extraBoundsX = extraBoundsY = 0;
565 
566  // target view position (landscape coordinates)
567  float targetCenterViewX = fixtof(pPlr->ViewX);
568  float targetCenterViewY = fixtof(pPlr->ViewY);
569 
570  if (pPlr->ViewMode == C4PVM_Scrolling)
571  {
572  extraBoundsX = extraBoundsY = ViewportScrollBorder;
573  }
574  else
575  {
576  scrollRange = std::min(ViewWdt/(10*Zoom),ViewHgt/(10*Zoom));
577 
578  // if view is close to border, allow scrolling
579  if (targetCenterViewX < ViewportScrollBorder) extraBoundsX = std::min<float>(ViewportScrollBorder - targetCenterViewX, ViewportScrollBorder);
580  else if (targetCenterViewX >= ::Landscape.GetWidth() - ViewportScrollBorder) extraBoundsX = std::min<float>(targetCenterViewX - ::Landscape.GetWidth(), 0) + ViewportScrollBorder;
581  if (targetCenterViewY < ViewportScrollBorder) extraBoundsY = std::min<float>(ViewportScrollBorder - targetCenterViewY, ViewportScrollBorder);
582  else if (targetCenterViewY >= ::Landscape.GetHeight() - ViewportScrollBorder) extraBoundsY = std::min<float>(targetCenterViewY - ::Landscape.GetHeight(), 0) + ViewportScrollBorder;
583  }
584 
585  extraBoundsX = std::max(extraBoundsX, (ViewWdt/Zoom - ::Landscape.GetWidth())/2 + 1);
586  extraBoundsY = std::max(extraBoundsY, (ViewHgt/Zoom - ::Landscape.GetHeight())/2 + 1);
587 
588  // add mouse auto scroll
590  {
591  float strength = Config.Controls.MouseAutoScroll/100.0f;
592  targetCenterViewX += strength*(::MouseControl.VpX - ViewWdt/2.0f)/Zoom;
593  targetCenterViewY += strength*(::MouseControl.VpY - ViewHgt/2.0f)/Zoom;
594  }
595 
596  // scroll range
597  if (!immediate)
598  {
599  targetCenterViewX = Clamp(targetCenterViewX, targetCenterViewX - scrollRange, targetCenterViewX + scrollRange);
600  targetCenterViewY = Clamp(targetCenterViewY, targetCenterViewY - scrollRange, targetCenterViewY + scrollRange);
601  }
602  // bounds
603  targetCenterViewX = Clamp(targetCenterViewX, ViewWdt/Zoom/2 - extraBoundsX, ::Landscape.GetWidth() - ViewWdt/Zoom/2 + extraBoundsX);
604  targetCenterViewY = Clamp(targetCenterViewY, ViewHgt/Zoom/2 - extraBoundsY, ::Landscape.GetHeight() - ViewHgt/Zoom/2 + extraBoundsY);
605 
606  targetViewX = targetCenterViewX - ViewWdt/Zoom/2 + viewOffsX;
607  targetViewY = targetCenterViewY - ViewHgt/Zoom/2 + viewOffsY;
608 
609  if (immediate)
610  {
611  // immediate scroll
612  SetViewX(targetViewX);
613  SetViewY(targetViewY);
614  }
615  else
616  {
617  // smooth scroll
618  int32_t smooth = Clamp<int32_t>(Config.General.ScrollSmooth, 1, 50);
619  ScrollView((targetViewX - viewX) / smooth, (targetViewY - viewY) / smooth);
620  }
621  }
622 
623  UpdateBordersX();
624  UpdateBordersY();
625 
626  // NO_OWNER can't scroll
627  if (fIsNoOwnerViewport) { viewOffsX=0; viewOffsY=0; }
628 }
629 
631 {
632  // center viewport position on map
633  // set center position
636 }
637 
638 void C4Viewport::UpdateBordersX()
639 {
640  BorderLeft = std::max(-GetViewX() * Zoom, 0.0f);
641  BorderRight = std::max(ViewWdt - ::Landscape.GetWidth() * Zoom + GetViewX() * Zoom, 0.0f);
642 }
643 
644 void C4Viewport::UpdateBordersY()
645 {
646  BorderTop = std::max(-GetViewY() * Zoom, 0.0f);
647  BorderBottom = std::max(ViewHgt - ::Landscape.GetHeight() * Zoom + GetViewY() * Zoom, 0.0f);
648 }
649 
651 {
652  C4Facet ccgo;
653  if (!ValidPlr(Player)) return;
654  // Controls
655  DrawPlayerStartup(cgo);
656 }
657 
658 bool C4Viewport::Init(int32_t iPlayer, bool fSetTempOnly)
659 {
660  // Fullscreen viewport initialization
661  // Set Player
662  if (!ValidPlr(iPlayer)) iPlayer = NO_OWNER;
663  Player=iPlayer;
665  if (!fSetTempOnly) fIsNoOwnerViewport = (iPlayer == NO_OWNER);
666  if (Application.isEditor)
667  {
668  // Console viewport initialization
669  // Create window
670  pWindow.reset(new C4ViewportWindow(this));
671  if (!pWindow->Init(Player))
672  return false;
674  // Disable player lock on unowned viewports
676  // Don't call Execute right away since it is not yet guaranteed that
677  // the Player has set this as its Viewport, and the drawing routines rely
678  // on that.
679  }
680  else
681  {
682  // Owned viewport: clear any flash message explaining observer menu
683  if (ValidPlr(iPlayer)) ::GraphicsSystem.FlashMessage("");
684  }
685 
686  EnableFoW();
687  return true;
688 }
689 
691 {
692  pFoW.reset();
693 }
694 
696 {
697  if (::Landscape.HasFoW() && Player != NO_OWNER)
698  {
699  pFoW.reset(new C4FoWRegion(::Landscape.GetFoW(), ::Players.Get(Player)));
700  }
701  else
702  {
703  DisableFoW();
704  }
705 }
706 
707 extern int32_t DrawMessageOffset;
708 
710 {
711  C4Player *pPlr;
712  if (!(pPlr = ::Players.Get(Player))) return;
713  if (!pPlr->LocalControl || !pPlr->ShowStartup) return;
714  int32_t iNameHgtOff=0;
715 
716  // Control
717  // unnecessary with the current control sets
718  if (pPlr && pPlr->ControlSet)
719  {
720  C4Facet controlset_facet = pPlr->ControlSet->GetPicture();
721  if (controlset_facet.Wdt) controlset_facet.Draw(cgo.Surface,
722  cgo.X+(cgo.Wdt-controlset_facet.Wdt)/2,
723  cgo.Y+cgo.Hgt * 2/3 + DrawMessageOffset,
724  0,0);
725  iNameHgtOff=GfxR->fctKeyboard.Hgt;
726  }
727 
728  // Name
730  cgo.X+cgo.Wdt/2,cgo.Y+cgo.Hgt*2/3+iNameHgtOff + DrawMessageOffset,
731  pPlr->ColorDw | 0xff000000, ACenter);
732 }
733 
734 void C4Viewport::ScrollView(float byX, float byY)
735 {
736  SetViewX(viewX + byX);
737  SetViewY(viewY + byY);
738 }
739 
740 void C4Viewport::SetViewX(float x)
741 {
742  viewX = x;
743 
744  if (fIsNoOwnerViewport)
745  {
746  if(::Landscape.GetWidth() < ViewWdt / Zoom)
747  {
748  viewX = ::Landscape.GetWidth()/2 - ViewWdt / Zoom / 2;
749  }
750  else
751  {
752  viewX = Clamp(x, 0.0f, ::Landscape.GetWidth() - ViewWdt / Zoom);
753  }
754  }
755 
756  UpdateBordersX();
757 }
758 
759 void C4Viewport::SetViewY(float y)
760 {
761  viewY = y;
762 
763  if (fIsNoOwnerViewport)
764  {
765  if(::Landscape.GetHeight() < ViewHgt / Zoom)
766  {
767  viewY = ::Landscape.GetHeight()/2 - ViewHgt / Zoom / 2;
768  }
769  else
770  {
771  viewY = Clamp(y, 0.0f, ::Landscape.GetHeight() - ViewHgt / Zoom);
772  }
773  }
774 
775  UpdateBordersY();
776 }
777 
778 void C4Viewport::SetOutputSize(int32_t iDrawX, int32_t iDrawY, int32_t iOutX, int32_t iOutY, int32_t iOutWdt, int32_t iOutHgt)
779 {
780  int32_t deltaWidth = ViewWdt-iOutWdt;
781  int32_t deltaHeight = ViewHgt-iOutHgt;
782  // update output parameters
783  DrawX=iDrawX; DrawY=iDrawY;
784  OutX=iOutX; OutY=iOutY;
785  ViewWdt=iOutWdt; ViewHgt=iOutHgt;
786  // update view position: Remain centered at previous position
787  // scrolling the view must be done after setting the new view width and height
788  ScrollView(deltaWidth/2, deltaHeight/2);
789  CalculateZoom();
790  // Reset menus
791  ResetMenuPositions=true;
792  // player uses mouse control? then clip the cursor
793  C4Player *pPlr;
794  if ((pPlr=::Players.Get(Player)))
795  if (pPlr->MouseControl)
796  {
798  // and inform GUI
799  ::pGUI->SetPreferredDlgRect(C4Rect(iOutX, iOutY, iOutWdt, iOutHgt));
800  }
801 }
802 
804 {
805 
806 }
807 
809 {
810  C4Player *pPlr; int32_t iPlr;
811  if (!(pPlr = ::Players.Get(Player)))
812  {
813  if (!(pPlr = ::Players.First)) return;
814  }
815  else if (!(pPlr = pPlr->Next))
816  if (Game.C4S.Head.Film && Game.C4S.Head.Replay)
817  pPlr = ::Players.First; // cycle to first in film mode only; in network obs mode allow NO_OWNER-view
818  if (pPlr) iPlr = pPlr->Number; else iPlr = NO_OWNER;
819  if (iPlr != Player) Init(iPlr, true);
820 }
821 
823 {
824  // check all associated menus
825  // Get player
826  C4Player *pPlr = ::Players.Get(Player);
827  // Player eliminated: No menu
828  if (pPlr && pPlr->Eliminated) return false;
829  // Player cursor object menu
830  if (pPlr && pPlr->Cursor && pPlr->Cursor->Menu == pMenu) return true;
831  // Player menu
832  if (pPlr && pPlr->Menu.IsActive() && &(pPlr->Menu) == pMenu) return true;
833  // Fullscreen menu (if active, only one viewport can exist)
834  if (FullScreen.pMenu && FullScreen.pMenu->IsActive() && FullScreen.pMenu == pMenu) return true;
835  // no match
836  return false;
837 }
838 
839 // C4ViewportList
840 
842 
844  FirstViewport(nullptr)
845 {
847 }
849 {
850 }
852 {
853  C4Viewport *next;
854  while (FirstViewport)
855  {
856  next=FirstViewport->Next;
857  delete FirstViewport;
858  FirstViewport=next;
859  }
860  FirstViewport=nullptr;
861 }
862 
863 void C4ViewportList::Execute(bool DrawBackground)
864 {
865  // Background redraw
866  if (DrawBackground)
868  for (C4Viewport *cvp=FirstViewport; cvp; cvp=cvp->Next)
869  {
870  if (cvp->GetWindow())
871  cvp->GetWindow()->RequestUpdate();
872  else
873  cvp->Execute();
874  }
875 }
876 
878 {
879  for (int i=0, iNum=BackgroundAreas.GetCount(); i<iNum; ++i)
880  {
881  const C4Rect &rc = BackgroundAreas.Get(i);
883  }
884 }
885 
887 {
888  if (!cvp) return false;
889  // Chop the start of the chain off
890  if (FirstViewport == cvp)
891  {
892  FirstViewport = cvp->Next;
893  delete cvp;
894  StartSoundEffect("UI::CloseViewport");
895  }
896  // Take out of the chain
897  else for (C4Viewport * prev = FirstViewport; prev; prev = prev->Next)
898  {
899  if (prev->Next == cvp)
900  {
901  prev->Next = cvp->Next;
902  delete cvp;
903  StartSoundEffect("UI::CloseViewport");
904  }
905  }
906  // Recalculate viewports
908  // Done
909  return true;
910 }
911 #ifdef USE_WIN32_WINDOWS
913 {
914  for (C4Viewport *cvp=FirstViewport; cvp; cvp=cvp->Next)
915  if (cvp->pWindow->hWindow==hwnd)
916  return cvp;
917  return nullptr;
918 }
919 #endif
920 bool C4ViewportList::CreateViewport(int32_t iPlayer, bool fSilent)
921 {
922  // Create and init new viewport, add to viewport list
923  int32_t iLastCount = GetViewportCount();
924  C4Viewport *nvp = new C4Viewport;
925  bool fOkay = nvp->Init(iPlayer, false);
926  if (!fOkay) { delete nvp; return false; }
927  C4Viewport *pLast;
928  for (pLast=FirstViewport; pLast && pLast->Next; pLast=pLast->Next) {}
929  if (pLast) pLast->Next=nvp; else FirstViewport=nvp;
930  // Recalculate viewports
932  // Viewports start off at centered position
933  nvp->CenterPosition();
934  // Initial player zoom values to viewport (in case they were set early in InitializePlayer, loaded from savegame, etc.)
935  C4Player *plr = ::Players.Get(iPlayer);
936  if (plr)
937  {
938  plr->ZoomToViewport(nvp, true, false, false);
939  plr->ZoomLimitsToViewport(nvp);
940  }
941  // Action sound
942  if (GetViewportCount()!=iLastCount) if (!fSilent)
943  StartSoundEffect("UI::CloseViewport");
944  return true;
945 }
946 
948 {
949  for (C4Viewport *cvp=FirstViewport; cvp; cvp=cvp->Next)
950  cvp->DisableFoW();
951 }
952 
954 {
955  for (C4Viewport *cvp=FirstViewport; cvp; cvp=cvp->Next)
956  cvp->EnableFoW();
957 }
958 
960 {
961  for (C4Viewport *cvp=FirstViewport; cvp; cvp=cvp->Next)
962  cvp->ClearPointers(pObj);
963 }
964 bool C4ViewportList::CloseViewport(int32_t iPlayer, bool fSilent)
965 {
966  // Close all matching viewports
967  int32_t iLastCount = GetViewportCount();
968  C4Viewport *next,*prev=nullptr;
969  for (C4Viewport *cvp=FirstViewport; cvp; cvp=next)
970  {
971  next=cvp->Next;
972  if (cvp->Player==iPlayer || (iPlayer==NO_OWNER && cvp->fIsNoOwnerViewport))
973  {
974  delete cvp;
975  if (prev) prev->Next=next;
976  else FirstViewport=next;
977  }
978  else
979  prev=cvp;
980  }
981  // Anything was done?
982  if (GetViewportCount()!=iLastCount)
983  {
984  // Recalculate viewports
986  // Action sound
987  if (!fSilent) StartSoundEffect("UI::CloseViewport");
988  }
989  return true;
990 }
991 
993 {
994 
995  // Fullscreen only
996  if (Application.isEditor) return;
997 
998  // Sort viewports
1000 
1001  // Viewport area
1002  int32_t iBorderTop = 0;
1004  iBorderTop = C4UpperBoardHeight;
1006 
1007  // Redraw flag
1009 #ifdef _WIN32
1010  // reset mouse clipping
1011  ClipCursor(nullptr);
1012 #else
1013  // StdWindow handles this.
1014 #endif
1015  // reset GUI dlg pos
1017 
1018  // fullscreen background: First, cover all of screen
1021 
1022  // Viewports
1023  C4Viewport *cvp;
1024  int32_t iViews = 0;
1025  for (cvp=FirstViewport; cvp; cvp=cvp->Next) iViews++;
1026  if (!iViews) return;
1027  int32_t iViewsH = (int32_t) sqrt(float(iViews));
1028  int32_t iViewsX = iViews / iViewsH;
1029  int32_t iViewsL = iViews % iViewsH;
1030  int32_t cViewH,cViewX,ciViewsX;
1031  int32_t cViewWdt,cViewHgt,cOffWdt,cOffHgt,cOffX,cOffY;
1032  cvp=FirstViewport;
1033  for (cViewH=0; cViewH<iViewsH; cViewH++)
1034  {
1035  ciViewsX = iViewsX; if (cViewH<iViewsL) ciViewsX++;
1036  for (cViewX=0; cViewX<ciViewsX; cViewX++)
1037  {
1038  cViewWdt = ViewportArea.Wdt/ciViewsX;
1039  cViewHgt = ViewportArea.Hgt/iViewsH;
1040  cOffX = ViewportArea.X;
1041  cOffY = ViewportArea.Y;
1042  cOffWdt = cOffHgt = 0;
1043  if (ciViewsX * cViewWdt < ViewportArea.Wdt)
1044  cOffX = (ViewportArea.Wdt - ciViewsX * cViewWdt) / 2;
1045  if (iViewsH * cViewHgt < ViewportArea.Hgt)
1046  cOffY = (ViewportArea.Hgt - iViewsH * cViewHgt) / 2 + ViewportArea.Y;
1048  {
1049  if (cViewX < ciViewsX - 1) cOffWdt=4;
1050  if (cViewH < iViewsH - 1) cOffHgt=4;
1051  }
1052  int32_t coViewWdt=cViewWdt-cOffWdt;
1053  int32_t coViewHgt=cViewHgt-cOffHgt;
1054  C4Rect rcOut(cOffX+cViewX*cViewWdt, cOffY+cViewH*cViewHgt, coViewWdt, coViewHgt);
1055  cvp->SetOutputSize(rcOut.x,rcOut.y,rcOut.x,rcOut.y,rcOut.Wdt,rcOut.Hgt);
1056  cvp=cvp->Next;
1057  // clip down area avaiable for background drawing
1058  BackgroundAreas.ClipByRect(rcOut);
1059  }
1060  }
1061  // and finally recalculate script menus
1062  if (::Game.ScriptGuiRoot)
1063  ::Game.ScriptGuiRoot->RequestLayoutUpdate();
1064 }
1065 
1067 {
1068  int32_t iResult = 0;
1069  for (C4Viewport *cvp=FirstViewport; cvp; cvp=cvp->Next) iResult++;
1070  return iResult;
1071 }
1072 
1074 {
1075  for (C4Viewport *cvp=pPrev ? pPrev->Next : FirstViewport; cvp; cvp=cvp->Next)
1076  if (cvp->Player==iPlayer || (iPlayer==NO_OWNER && cvp->fIsNoOwnerViewport))
1077  return cvp;
1078  return nullptr;
1079 }
1080 
1081 int32_t C4ViewportList::GetAudibility(int32_t iX, int32_t iY, int32_t *iPan, int32_t iAudibilityRadius, int32_t *outPlayer)
1082 {
1083  // default audibility radius
1084  if (!iAudibilityRadius) iAudibilityRadius = C4AudibilityRadius;
1085  // Accumulate audibility by viewports
1086  int32_t iAudible=0; *iPan = 0;
1087  for (C4Viewport *cvp=FirstViewport; cvp; cvp=cvp->Next)
1088  {
1089  float distanceToCenterOfViewport = Distance(cvp->GetViewCenterX(),cvp->GetViewCenterY(),iX,iY);
1090  int32_t audibility = Clamp<int32_t>(100 - 100 * distanceToCenterOfViewport / C4AudibilityRadius, 0, 100);
1091  if (audibility > iAudible)
1092  {
1093  iAudible = audibility;
1094  if (outPlayer) *outPlayer = cvp->Player;
1095  }
1096  *iPan += (iX-(cvp->GetViewCenterX())) / 5;
1097  }
1098  *iPan = Clamp<int32_t>(*iPan, -100, 100);
1099  return iAudible;
1100 }
1101 
1103 {
1104 
1105  // Sort
1106  bool fSorted;
1107  C4Player *pPlr1,*pPlr2;
1108  C4Viewport *pView,*pNext,*pPrev;
1109  do
1110  {
1111  fSorted = true;
1112  for (pPrev=nullptr,pView=FirstViewport; pView && (pNext = pView->Next); pView=pNext)
1113  {
1114  // Get players
1115  pPlr1 = ::Players.Get(pView->Player);
1116  pPlr2 = ::Players.Get(pNext->Player);
1117  // Swap order
1118  if (pPlr1 && pPlr2 && pPlr1->ControlSet && pPlr2->ControlSet && ( pPlr1->ControlSet->GetLayoutOrder() > pPlr2->ControlSet->GetLayoutOrder() ))
1119  {
1120  if (pPrev) pPrev->Next = pNext; else FirstViewport = pNext;
1121  pView->Next = pNext->Next;
1122  pNext->Next = pView;
1123  pPrev = pNext;
1124  pNext = pView;
1125  fSorted = false;
1126  }
1127  // Don't swap
1128  else
1129  {
1130  pPrev = pView;
1131  }
1132  }
1133  }
1134  while (!fSorted);
1135 
1136 }
1137 
1139 {
1140  // safety: switch valid?
1141  if ((!Game.C4S.Head.Film || !Game.C4S.Head.Replay) && !GetViewport(NO_OWNER)) return false;
1142  // do switch then
1143  C4Viewport *vp = GetFirstViewport();
1144  if (!vp) return false;
1145  vp->NextPlayer();
1146  return true;
1147 }
1148 
1150 {
1151  // safety: move valid?
1152  if ((!Game.C4S.Head.Replay || !Game.C4S.Head.Film) && !GetViewport(NO_OWNER)) return false;
1153  C4Viewport *vp = GetFirstViewport();
1154  if (!vp) return false;
1155  // move then (old static code crap...)
1156  static int32_t vp_vx=0; static int32_t vp_vy=0; static int32_t vp_vf=0;
1157  int32_t dx=vScrollBy.x; int32_t dy=vScrollBy.y;
1158  if (Game.FrameCounter-vp_vf < 5)
1159  { dx += vp_vx; dy += vp_vy; }
1160  vp_vx=dx; vp_vy=dy; vp_vf=Game.FrameCounter;
1161  vp->ScrollView(dx, dy);
1162  return true;
1163 }
1164 
1166 {
1167  for (C4Viewport *vp = FirstViewport; vp; vp = vp->Next) vp->ChangeZoom(1.0f/C4GFX_ZoomStep);
1168  return true;
1169 }
1170 
1172 {
1173  for (C4Viewport *vp = FirstViewport; vp; vp = vp->Next) vp->ChangeZoom(C4GFX_ZoomStep);
1174  return true;
1175 }
1176 
1177 void C4ViewportList::MouseMoveToViewport(int32_t iButton, int32_t iX, int32_t iY, DWORD dwKeyParam)
1178 {
1179  // Pass on to mouse controlled viewport
1180  for (C4Viewport *cvp=FirstViewport; cvp; cvp=cvp->Next)
1181  if (::MouseControl.IsViewport(cvp))
1182  ::MouseControl.Move( iButton,
1183  Clamp<int32_t>(iX-cvp->OutX,0,cvp->ViewWdt-1),
1184  Clamp<int32_t>(iY-cvp->OutY,0,cvp->ViewHgt-1),
1185  dwKeyParam );
1186 }
int32_t MouseAutoScroll
Definition: C4Config.h:231
const int32_t C4PVM_Scrolling
Definition: C4Player.h:35
C4EditCursor EditCursor
Definition: C4Console.h:90
void AddRect(const C4Rect &rNewRect)
Definition: C4Rect.h:103
int32_t OutX
Definition: C4Viewport.h:107
void ResetLocation()
Definition: C4Menu.h:195
void Draw(C4TargetFacet &cgo, bool fDrawGame, bool fDrawOverlay)
Definition: C4Viewport.cpp:200
void SetFoW(const C4FoWRegion *fow)
Definition: C4Draw.h:193
bool isObserver() const
C4Viewport * GetFirstViewport()
Definition: C4Viewport.h:156
int32_t MouseControl
Definition: C4Player.h:94
C4Config Config
Definition: C4Config.cpp:837
int32_t OutY
Definition: C4Viewport.h:107
void InitZoom()
Definition: C4Viewport.cpp:426
size_t GetCount() const
Definition: C4Rect.h:108
float Y
Definition: C4Facet.h:120
C4ObjectPtr Cursor
Definition: C4Player.h:132
float Zoom
Definition: C4Facet.h:167
#define GfxR
C4Console Console
Definition: C4Globals.cpp:45
friend class C4ViewportWindow
Definition: C4Viewport.h:135
C4MainMenu * pMenu
Definition: C4FullScreen.h:30
C4MainMenu Menu
Definition: C4Player.h:105
int32_t ViewMode
Definition: C4Player.h:107
int32_t DrawY
Definition: C4Viewport.h:39
C4Game Game
Definition: C4Globals.cpp:52
int32_t Number
Definition: C4Player.h:88
C4GameScriptHost GameScript
C4ScriptUniform scriptUniform
Definition: C4Draw.h:100
C4Scenario C4S
Definition: C4Game.h:76
C4ConfigGeneral General
Definition: C4Config.h:252
C4ParticleSystem Particles
void ZoomLimitsToViewport(C4Viewport *vp)
Definition: C4Player.cpp:1862
void CalculateZoom()
Definition: C4Viewport.cpp:408
int32_t DrawX
Definition: C4Viewport.h:39
void RecalculateViewports()
Definition: C4Viewport.cpp:992
C4Facet ViewportArea
Definition: C4Viewport.h:171
bool Replay
Definition: C4Scenario.h:72
void DrawFullscreenBackground()
Definition: C4Viewport.cpp:877
C4Surface * pSurface
Definition: C4Window.h:279
C4SLandscape Landscape
Definition: C4Scenario.h:234
bool UpdateOutputSize(int32_t new_width=0, int32_t new_height=0)
Definition: C4Viewport.cpp:52
bool PlayerLock
Definition: C4Viewport.h:106
bool TextOut(const char *szText, CStdFont &rFont, float fZoom, C4Surface *sfcDest, float iTx, float iTy, DWORD dwFCol=0xffffffff, BYTE byForm=ALeft, bool fDoMarkup=true)
Definition: C4Draw.cpp:570
bool ShowStartup
Definition: C4Player.h:111
C4FullScreen FullScreen
Definition: C4Globals.cpp:46
float Y
Definition: C4Draw.h:71
bool HasFoW() const
Definition: C4Rect.h:29
class C4FoW * GetFoW()
int32_t GetScreenWdt()
Definition: C4Gui.h:2821
void Update(C4Rect r, const FLOAT_RECT &vp)
C4Player * First
Definition: C4PlayerList.h:31
void DrawGlobalParticles(C4TargetFacet cgo)
Definition: C4Particles.h:489
Definition: C4Menu.h:122
int32_t y
Definition: C4Facet.h:42
void MouseMoveToViewport(int32_t iButton, int32_t iX, int32_t iY, DWORD dwKeyParam)
const int C4ViewportScrollBorder
Definition: C4Constants.h:65
void Draw(C4TargetFacet &cgo, int iPlayer, int MinPlane, int MaxPlane)
C4Viewport * GetViewport(int32_t iPlayer, C4Viewport *pPrev=nullptr)
void SetPreferredDlgRect(const C4Rect &rtNewPref)
Definition: C4Gui.h:2648
const int C4UpperBoardHeight
Definition: C4Constants.h:59
bool ViewportZoomIn()
bool IsViewportMenu(class C4Menu *pMenu)
Definition: C4Viewport.cpp:822
C4MouseControl MouseControl
Definition: C4Globals.cpp:47
void Set(C4Surface &rSfc)
Definition: C4Facet.cpp:459
C4GraphicsResource GraphicsResource
void Draw(C4TargetFacet &cgo)
C4TargetFacet last_gui_draw_cgo
Definition: C4Viewport.h:41
void ChangeZoom(float by_factor)
Definition: C4Viewport.cpp:440
void BlitOutput()
Definition: C4Viewport.cpp:369
void ZoomToViewport(C4Viewport *vp, bool direct, bool no_increase=false, bool no_decrease=false)
Definition: C4Player.cpp:1846
const char * LoadResStr(const char *id)
Definition: C4Language.h:83
T Clamp(T bval, T lbound, T rbound)
Definition: Standard.h:46
int32_t UpperBoard
Definition: C4Config.h:102
void SortViewportsByPlayerControl()
int32_t Distance(int32_t iX1, int32_t iY1, int32_t iX2, int32_t iY2)
Definition: Standard.cpp:24
uint32_t ColorDw
Definition: C4Player.h:91
C4SoundInstance * StartSoundEffect(const char *szSndName, bool fLoop, int32_t iVolume, C4Object *pObj, int32_t iCustomFalloffDistance, int32_t iPitch, C4SoundModifier *modifier)
int32_t ViewHgt
Definition: C4Viewport.h:36
std::unique_ptr< C4FoWRegion > pFoW
Definition: C4Viewport.h:111
C4ConfigGraphics Graphics
Definition: C4Config.h:254
void DrawOverlay(C4TargetFacet &cgo, const ZoomData &GameZoom)
Definition: C4Viewport.cpp:115
int32_t Wdt
Definition: C4Rect.h:32
virtual bool PrepareRendering(C4Surface *sfcToSurface)=0
void DrawIfCategory(C4TargetFacet &cgo, int iPlayer, uint32_t dwCat, bool fInvert)
int32_t GetAudibility(int32_t iX, int32_t iY, int32_t *iPan, int32_t iAudibilityRadius=0, int32_t *outPlayer=nullptr)
void Draw(C4TargetFacet &cgo, const ZoomData &GameZoom)
C4Player * Get(int iPlayer) const
class C4ObjectMenu * Menu
Definition: C4Object.h:140
int32_t FrameCounter
Definition: C4Game.h:130
void EnableFoW()
Definition: C4Viewport.cpp:695
C4GUIScreen * pGUI
Definition: C4Gui.cpp:1194
int iResult
Definition: C4GroupMain.cpp:39
class C4PlayerControlAssignmentSet * ControlSet
Definition: C4Player.h:92
bool BlitSurfaceTile(C4Surface *sfcSurface, C4Surface *sfcTarget, float iToX, float iToY, float iToWdt, float iToHgt, float iOffsetX, float iOffsetY, C4ShaderCall *shader_call)
Definition: C4Draw.cpp:538
C4Network2 Network
Definition: C4Globals.cpp:53
void SetZoomLimits(float to_min_zoom, float to_max_zoom)
Definition: C4Viewport.cpp:459
int32_t GetJoinIssuedPlayerCount() const
int32_t ViewWdt
Definition: C4Viewport.h:36
int32_t y
Definition: C4Rect.h:32
C4RectList BackgroundAreas
Definition: C4Viewport.h:172
const int ACenter
Definition: C4Surface.h:43
bool IsViewport(C4Viewport *pViewport)
bool ViewportNextPlayer()
void Default()
Definition: C4Facet.cpp:31
void Draw(C4TargetFacet &cgo)
Definition: C4Sky.cpp:181
void Move(int32_t iButton, int32_t iX, int32_t iY, DWORD dwKeyFlags, bool fCenter=false)
bool fIsNoOwnerViewport
Definition: C4Viewport.h:43
C4Landscape Landscape
C4GraphicsSystem GraphicsSystem
Definition: C4Globals.cpp:51
void DrawBoxDw(C4Surface *sfcDest, int iX1, int iY1, int iX2, int iY2, DWORD dwClr)
Definition: C4Draw.cpp:849
void SetZoom(float zoomValue)
Definition: C4Viewport.cpp:495
C4Value ScenPropList
Definition: C4ScriptHost.h:163
bool ResetMenuPositions
Definition: C4Viewport.h:108
void RenderMouse(C4TargetFacet &cgo)
Definition: C4Gui.cpp:742
void Set(const C4Facet &cpy)
Definition: C4Facet.h:184
void ScrollView(float byX, float byY)
Definition: C4Viewport.cpp:734
C4PlayerList Players
class C4Sky & GetSky()
#define C4ST_STOP(StatName)
Definition: C4Stat.h:153
void Draw(C4Facet &cgo, bool fAspect=true, int32_t iPhaseX=0, int32_t iPhaseY=0, bool fTransparent=true)
Definition: C4Facet.cpp:154
void DisableFoW()
Definition: C4Viewport.cpp:690
C4Viewport * FirstViewport
Definition: C4Viewport.h:170
const int NO_OWNER
Definition: C4Constants.h:138
C4Draw * pDraw
Definition: C4Draw.cpp:45
void SetViewX(float x)
Definition: C4Viewport.cpp:740
C4PXSSystem PXS
Definition: C4PXS.cpp:532
void DrawPlayerInfo(C4TargetFacet &cgo)
Definition: C4Viewport.cpp:650
void NextPlayer()
Definition: C4Viewport.cpp:808
void Draw(C4TargetFacet &cgo)
Definition: C4PXS.cpp:247
bool SetPrimaryClipper(int iX1, int iY1, int iX2, int iY2)
Definition: C4Draw.cpp:220
void SetViewY(float y)
Definition: C4Viewport.cpp:759
C4Rect & Get(size_t idx)
Definition: C4Rect.h:109
void AdjustPosition(bool immediate=false)
Definition: C4Viewport.cpp:544
bool isEnabled() const
Definition: C4Network2.h:203
int32_t GetScreenHgt()
Definition: C4Gui.h:2822
bool CreateViewport(int32_t iPlayer, bool fSilent=false)
Definition: C4Viewport.cpp:920
int32_t Surrendered
Definition: C4Player.h:86
bool FreeScroll(C4Vec2D vScrollBy)
int32_t Eliminated
Definition: C4Player.h:85
bool TogglePlayerLock()
Definition: C4Console.cpp:715
float Zoom
Definition: C4Viewport.h:101
void CenterPosition()
Definition: C4Viewport.cpp:630
bool IsActive()
Definition: C4Menu.cpp:483
C4TargetFacet last_game_draw_cgo
Definition: C4Viewport.h:41
void DrawMenu(C4TargetFacet &cgo)
Definition: C4Viewport.cpp:143
const int32_t C4AudibilityRadius
Definition: C4SoundSystem.h:30
int32_t x
Definition: C4Rect.h:32
int32_t GetHeight() const
C4Viewport * Next
Definition: C4Viewport.h:109
C4Network2ClientList Clients
Definition: C4Network2.h:116
float TargetX
Definition: C4Facet.h:167
C4PlayerInfoList & PlayerInfos
Definition: C4Game.h:73
bool Init(int32_t iPlayer, bool fSetTempOnly)
Definition: C4Viewport.cpp:658
#define C4ST_STARTNEW(StatName, strName)
Definition: C4Stat.h:150
C4ViewportList Viewports
Definition: C4Viewport.cpp:841
int32_t SplitscreenDividers
Definition: C4Config.h:98
float GetViewY()
Definition: C4Viewport.h:75
float BorderBottom
Definition: C4Viewport.h:38
const char * GetName() const
Definition: C4Player.h:153
float GetZoomByViewRange(int32_t size_x, int32_t size_y) const
Definition: C4Viewport.cpp:467
C4Real ViewY
Definition: C4Player.h:108
C4ConfigControls Controls
Definition: C4Config.h:260
void ClipByRect(const C4Rect &rClip)
Definition: C4Rect.cpp:173
void AdjustZoomAndPosition()
Definition: C4Viewport.cpp:502
void Draw(C4TargetFacet &cgo)
void DrawStatus(C4TargetFacet &cgo)
void FlashMessage(const char *szMessage)
virtual void Draw(C4TargetFacet &cgo)
Definition: C4Menu.cpp:778
float Hgt
Definition: C4Facet.h:120
C4PathFinder PathFinder
Definition: C4Game.h:86
const float C4GFX_ZoomStep
int32_t ValidPlr(int32_t plr)
void Draw(C4TargetFacet &cgo, class C4FoWRegion *pLight=nullptr)
C4ObjectList ForeObjects
Definition: C4GameObjects.h:44
bool ScrollBarsByViewPosition()
Definition: C4Console.cpp:714
void DrawPlayerStartup(C4TargetFacet &cgo)
Definition: C4Viewport.cpp:709
C4Player * Next
Definition: C4Player.h:144
float fixtof(const C4Fixed &x)
Definition: C4Real.h:257
float GetGUIZoom() const
Definition: C4Viewport.h:47
bool CloseViewport(int32_t iPlayer, bool fSilent)
Definition: C4Viewport.cpp:964
void ClearPointers(C4Object *pObj)
Definition: C4Viewport.cpp:959
std::unique_ptr< C4ViewportWindow > pWindow
Definition: C4Viewport.h:110
void DeactivateBlitModulation()
Definition: C4Draw.h:189
int32_t GetViewportCount()
float X
Definition: C4Draw.h:71
float ZoomTarget
Definition: C4Viewport.h:102
C4Network2Client * GetLocal() const
void ActivateBlitModulation(DWORD dwWithClr)
Definition: C4Draw.h:188
int32_t Hgt
Definition: C4Rect.h:32
bool DropFile(const char *szFilename, float iX, float iY)
Definition: C4Game.cpp:1377
void DropFile(const char *fileName, float x, float y)
Definition: C4Viewport.cpp:47
C4SHead Head
Definition: C4Scenario.h:230
bool fFogOfWar
Definition: C4Player.h:113
void ClearPointers(C4Object *pObj)
Definition: C4Viewport.cpp:803
C4GameMessageList Messages
bool ViewportZoomOut()
void Execute(bool DrawBackground)
Definition: C4Viewport.cpp:863
std::unique_ptr< C4ScriptGuiWindow > ScriptGuiRoot
Definition: C4Game.h:235
bool NoPrimaryClipper()
Definition: C4Draw.cpp:240
float BorderTop
Definition: C4Viewport.h:38
C4Surface * Surface
Definition: C4Facet.h:119
void Execute()
Definition: C4Viewport.cpp:380
float TargetY
Definition: C4Facet.h:167
int32_t ViewportOpenFrame
Definition: C4Viewport.h:104
uint32_t DWORD
float GetViewX()
Definition: C4Viewport.h:73
int32_t Player
Definition: C4Viewport.h:105
float ZoomLimitMax
Definition: C4Viewport.h:103
void Clear()
Definition: C4Rect.h:107
bool Render(const C4TargetFacet *pOnScreen=nullptr)
float Wdt
Definition: C4Facet.h:120
void SetZoom(float X, float Y, float Zoom)
Definition: C4Draw.cpp:782
float X
Definition: C4Facet.h:120
float Zoom
Definition: C4Draw.h:70
void SetOutputSize(int32_t iDrawX, int32_t iDrawY, int32_t iOutX, int32_t iOutY, int32_t iOutWdt, int32_t iOutHgt)
Definition: C4Viewport.cpp:778
C4Application Application
Definition: C4Globals.cpp:44
int32_t ScrollSmooth
Definition: C4Config.h:50
const int32_t C4D_Foreground
Definition: C4Def.h:55
std::unique_ptr< Popper > Push(C4PropList *proplist)
Definition: C4Shader.cpp:759
int32_t GetWidth() const
bool DebugMode
Definition: C4Game.h:146
float BorderRight
Definition: C4Viewport.h:38
int32_t Film
Definition: C4Scenario.h:73
void DrawCrewOverheadText(C4TargetFacet &cgo, int32_t iPlayer)
Definition: C4Game.cpp:1536
C4GameObjects Objects
Definition: C4Globals.cpp:48
void Draw(C4TargetFacet &gui_cgo, C4TargetFacet &cgo, int32_t iPlayer)
float BorderLeft
Definition: C4Viewport.h:38
int32_t x
Definition: C4Facet.h:42
bool LocalControl
Definition: C4Player.h:101
float ZoomLimitMin
Definition: C4Viewport.h:103
C4Real ViewX
Definition: C4Player.h:108
StdStrBuf FormatString(const char *szFmt,...)
Definition: StdBuf.cpp:277
C4PropList * getPropList() const
Definition: C4Value.h:116
int32_t DrawMessageOffset