OpenClonk
C4GraphicsSystem.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 /* Operates viewports, message board and draws the game */
19 
20 #include "C4Include.h"
22 #include "game/C4GraphicsSystem.h"
23 
24 #include "editor/C4Console.h"
25 #include "game/C4Application.h"
26 #include "game/C4FullScreen.h"
27 #include "game/C4Viewport.h"
28 #include "graphics/C4Draw.h"
30 #include "graphics/StdPNG.h"
31 #include "gui/C4Gui.h"
32 #include "gui/C4LoaderScreen.h"
33 #include "landscape/C4Landscape.h"
34 #include "landscape/C4Sky.h"
35 #include "network/C4Network2.h"
36 #include "object/C4GameObjects.h"
37 
38 static const int MAX_BACKGROUND_FPS = 5;
39 
41 {
42  Default();
43 }
44 
46 {
47  Clear();
48 }
49 
51 {
52  // Success
53  return true;
54 }
55 
57 {
58  // Clear message board
59  MessageBoard.reset();
60  // clear loader
61  if (pLoaderScreen)
62  {
63  delete pLoaderScreen;
64  pLoaderScreen = nullptr;
65  }
66  // Close viewports
68  // No debug stuff
70 }
71 
73 {
74  // only if ddraw is ready
75  if (!pDraw)
76  {
77  return false;
78  }
79  if (!pDraw->Active)
80  {
81  return false;
82  }
83 
84  // if the window is not focused, draw no more than MAX_BACKGROUND_FPS frames per second
85  if (!Application.Active && (C4TimeMilliseconds::Now() - lastFrame) < 1000 / MAX_BACKGROUND_FPS)
86  {
87  return false;
88  }
89 
90  // drawing OK
91  return true;
92 }
93 
95 {
96  if (!Application.isEditor)
97  {
99  }
100  lastFrame = C4TimeMilliseconds::Now();
101 }
102 
104 {
105  // activity check
106  if (!StartDrawing())
107  {
108  return;
109  }
110 
111  bool did_draw_background = false;
112 
113  // If lobby running, message board only (page flip done by startup message board)
114  if (!::pGUI->HasFullscreenDialog(true)) // allow for message board behind GUI
115  {
116  if (::Network.isLobbyActive() || !Game.IsRunning)
117  {
118  if (!Application.isEditor)
119  {
120  // Message board
121  if (iRedrawBackground)
122  {
123  ClearFullscreenBackground();
124  }
125  MessageBoard->Execute();
126  if (!C4GUI::IsActive())
127  {
128  FinishDrawing();
129  return;
130  }
131  did_draw_background = true;
132  }
133  }
134  }
135 
136  // fullscreen GUI?
138  {
139  if (!did_draw_background && iRedrawBackground)
140  {
141  ClearFullscreenBackground();
142  }
143  ::pGUI->Render(!did_draw_background);
144  FinishDrawing();
145  return;
146  }
147 
148 
149  // Reset object audibility
151 
152  // some hack to ensure the mouse is drawn after a dialog close and before any
153  // movement messages
154  if (!C4GUI::IsActive())
155  {
156  ::pGUI->SetMouseInGUI(false, false);
157  }
158 
159  // Viewports
161  if (iRedrawBackground)
162  {
164  }
165 
166  if (!Application.isEditor)
167  {
168  // Upper board
170 
171  // Message board
172  MessageBoard->Execute();
173 
174  // Help & Messages
175  DrawHelp();
176  DrawHoldMessages();
177  DrawFlashMessage();
178  }
179 
180  // InGame-GUI
181  if (C4GUI::IsActive())
182  {
183  ::pGUI->Render(false);
184  }
185 
186  // done
187  FinishDrawing();
188 }
189 
191 {
192  MessageBoard = std::make_unique<C4MessageBoard>();
193  InvalidateBg();
194  ShowVertices = false;
195  ShowAction = false;
196  ShowCommand = false;
197  ShowEntrance = false;
198  ShowPathfinder = false;
199  ShowNetstatus = false;
200  Show8BitSurface = 0;
201  ShowLights = false;
202  ShowMenuInfo = false;
203  ShowHelp = false;
204  FlashMessageText[0] = 0;
205  FlashMessageTime = 0;
206  FlashMessageX = 0;
207  FlashMessageY = 0;
208  pLoaderScreen = nullptr;
209 }
210 
211 void C4GraphicsSystem::ClearFullscreenBackground()
212 {
213  pDraw->FillBG(0);
215 }
216 
217 bool C4GraphicsSystem::InitLoaderScreen(const char *image_name)
218 {
219  // create new loader; overwrite current only if successful
220  C4LoaderScreen *loader = new C4LoaderScreen();
221  loader->SetBlackScreen(false);
222  if (!loader->Init(image_name))
223  {
224  delete loader;
225  return false;
226  }
227  if (pLoaderScreen)
228  {
229  delete pLoaderScreen;
230  }
231  pLoaderScreen = loader;
232  // done, success
233  return true;
234 }
235 
237 {
238  // reset black screen loader flag
239  if (pLoaderScreen)
240  {
242  }
243 }
244 
245 bool C4GraphicsSystem::SaveScreenshot(bool save_all, float zoom_factor_all)
246 {
247  // Find a unique screenshot filename by iterating over all possible names
248  // Keep static counter so multiple screenshots in succession do not use same filename even if the background thread hasn't started writing the file yet
249  char filename[_MAX_PATH_LEN];
250  static int32_t screenshot_index = 1;
251  const char *filepath = nullptr;
252  do
253  {
254  sprintf(filename,"Screenshot%03i.png", screenshot_index++);
255  }
256  while (FileExists(filepath = Config.AtScreenshotPath(filename)));
257 
258  // log if successful/where it has been stored
259  bool can_save = DoSaveScreenshot(save_all, filepath, zoom_factor_all);
260  if (!can_save)
261  {
262  LogF(LoadResStr("IDS_PRC_SCREENSHOTERROR"), Config.AtUserDataRelativePath(Config.AtScreenshotPath(filename)));
263  }
264  else
265  {
266  LogF(LoadResStr("IDS_PRC_SCREENSHOT"), Config.AtUserDataRelativePath(Config.AtScreenshotPath(filename)));
267  }
268 
269  // return success
270  return !!can_save;
271 }
272 
273 bool C4GraphicsSystem::DoSaveScreenshot(bool save_all, const char *filename, float zoom_factor_all)
274 {
275  // Fullscreen only
276  if (Application.isEditor)
277  {
278  Log(LoadResStr("IDS_PRC_SCREENSHOTERROREDITOR"));
279  return false;
280  }
281 
282  // back surface must be present
283  if (!FullScreen.pSurface)
284  {
285  return false;
286  }
287 
288  // save landscape
289  if (save_all)
290  {
291  // Create full map screenshots at zoom 2x. Fractional zooms (like 1.7x) should work but might cause some trouble at screen borders.
292  float zoom = zoom_factor_all;
293 
294  // get viewport to draw in
296  if (!viewport)
297  {
298  return false;
299  }
300 
301  // create image large enough to hold the landscape
302  std::unique_ptr<CPNGFile> png(new CPNGFile());
303  int32_t lWdt = ::Landscape.GetWidth() * zoom;
304  int32_t lHgt = ::Landscape.GetHeight() * zoom;
305  if (!png->Create(lWdt, lHgt, false))
306  {
307  return false;
308  }
309 
310  // get backbuffer size
311  int32_t bkWdt = C4GUI::GetScreenWdt();
312  int32_t bkHgt = C4GUI::GetScreenHgt();
313  if (!bkWdt || !bkHgt)
314  {
315  return false;
316  }
317 
318  // facet for blitting
319  C4TargetFacet bkFct;
320  // mark background to be redrawn
321  InvalidateBg();
322  // draw on one big viewport
323  viewport->SetOutputSize(0, 0, 0, 0, bkWdt, bkHgt);
324  // backup and clear sky parallaxity
325  int32_t SkyParX = ::Landscape.GetSky().ParX;
326  ::Landscape.GetSky().ParX = 10;
327  int32_t SkyParY = ::Landscape.GetSky().ParY;
328  ::Landscape.GetSky().ParY = 10;
329 
330  // backup and clear viewport borders
331  FLOAT_RECT vp_borders = { viewport->BorderLeft, viewport->BorderRight, viewport->BorderTop, viewport->BorderBottom };
332  viewport->BorderLeft = viewport->BorderRight = viewport->BorderTop = viewport->BorderBottom = 0.0f;
333 
334  // temporarily change viewport player
335  int32_t viewport_player = viewport->Player;
336  viewport->Player = NO_OWNER;
337 
338  // blit all tiles needed
339  for (int32_t iY = 0; iY < lHgt; iY += bkHgt)
340  {
341  for (int32_t iX = 0; iX < lWdt; iX += bkWdt)
342  {
343  // get max width/height
344  int32_t bkWdt2 = bkWdt;
345  int32_t bkHgt2 = bkHgt;
346  if (iX + bkWdt2 > lWdt)
347  {
348  bkWdt2 -= iX + bkWdt2 - lWdt;
349  }
350  if (iY + bkHgt2 > lHgt)
351  {
352  bkHgt2 -= iY + bkHgt2 - lHgt;
353  }
354  // update facet
355  bkFct.Set(FullScreen.pSurface, 0, 0, ceil(float(bkWdt2)/zoom), ceil(float(bkHgt2)/zoom), iX/zoom, iY/zoom, zoom, 0, 0);
356  // draw there
357  viewport->Draw(bkFct, true, false);
358  // render
361 
362  // get output (locking primary!)
363  if (FullScreen.pSurface->Lock())
364  {
365  // transfer each pixel - slooow...
366  for (int32_t iY2 = 0; iY2 < bkHgt2; ++iY2)
367  {
368 #ifndef USE_CONSOLE
369  glReadPixels(0, FullScreen.pSurface->Hgt - iY2 - 1, bkWdt2, 1, GL_BGR, GL_UNSIGNED_BYTE, reinterpret_cast<BYTE *>(png->GetRow(iY + iY2)) + iX * 3);
370 #else
371  for (int32_t iX2 = 0; iX2 < bkWdt2; ++iX2)
372  {
373  png->SetPix(iX + iX2, iY + iY2, FullScreen.pSurface->GetPixDw(iX2, iY2, false));
374  }
375 #endif
376  }
377  // done; unlock
379  // This can take a long time and we would like to pump messages
380  // However, we're currently hogging the primary surface and horrible things might happen if we do that, including initiation of another screenshot
381  // The only thing that can be safely run is music (sound could play but that would just make them out of sync of the game)
383  }
384  }
385  }
386 
387  // restore viewport player
388  viewport->Player = viewport_player;
389  // restore viewport borders
390  viewport->BorderLeft = vp_borders.left;
391  viewport->BorderTop = vp_borders.top;
392  viewport->BorderRight = vp_borders.right;
393  viewport->BorderBottom = vp_borders.bottom;
394 
395  // restore parallaxity
396  ::Landscape.GetSky().ParX = SkyParX;
397  ::Landscape.GetSky().ParY = SkyParY;
398 
399  // restore viewport size
401 
402  // save!
403  CPNGFile::ScheduleSaving(png.release(), filename);
404  return true;
405  }
406  // Save primary surface in background thread
407  return FullScreen.pSurface->SavePNG(filename, false, false, true);
408 }
409 
411 {
412  ShowVertices = false;
413  ShowAction = false;
414  ShowCommand = false;
415  ShowEntrance = false;
416  ShowPathfinder = false; // allow pathfinder! - why this??
417  ShowLights = false;
418  Show8BitSurface = 0;
419  ShowNetstatus = false;
420  ShowMenuInfo = false;
421 }
422 
423 void C4GraphicsSystem::DrawHoldMessages()
424 {
426  {
427  pDraw->TextOut("Pause", ::GraphicsResource.FontRegular, 1.0,
432  }
433 }
434 
435 void C4GraphicsSystem::FlashMessage(const char *message)
436 {
437  // Store message
438  SCopy(message, FlashMessageText, C4MaxTitle);
439  // Calculate message time
440  FlashMessageTime = SLen(FlashMessageText) * 2;
441  // Initial position
442  FlashMessageX = -1;
443  FlashMessageY = 10;
444  // Upper board active: stay below upper board
446  {
447  FlashMessageY += C4UpperBoardHeight;
448  }
449  // More than one viewport: try to stay below portraits etc.
450  if (::Viewports.GetViewportCount() > 1)
451  {
452  FlashMessageY += 64;
453  }
454  // New flash message: redraw background (might be drawing one message on top of another)
455  InvalidateBg();
456 }
457 
458 void C4GraphicsSystem::FlashMessageOnOff(const char *description, bool switch_on)
459 {
460  StdStrBuf message;
461  message.Format("%s: %s", description, LoadResStr(switch_on ? "IDS_CTL_ON" : "IDS_CTL_OFF"));
462  FlashMessage(message.getData());
463 }
464 
465 void C4GraphicsSystem::DrawFlashMessage()
466 {
467  if (!FlashMessageTime || Application.isEditor)
468  {
469  return;
470  }
471  pDraw->TextOut(FlashMessageText, ::GraphicsResource.FontRegular, 1.0, FullScreen.pSurface,
472  (FlashMessageX==-1) ? C4GUI::GetScreenWdt()/2 : FlashMessageX,
473  (FlashMessageY==-1) ? C4GUI::GetScreenHgt()/2 : FlashMessageY,
475  (FlashMessageX==-1) ? ACenter : ALeft);
476  FlashMessageTime--;
477  // Flash message timed out: redraw background
478  if (!FlashMessageTime)
479  {
480  InvalidateBg();
481  }
482 }
483 
484 void C4GraphicsSystem::DrawHelp()
485 {
486  if (!ShowHelp || Application.isEditor)
487  {
488  return;
489  }
490  int32_t x = ::Viewports.ViewportArea.X;
491  int32_t y = ::Viewports.ViewportArea.Y;
492  int32_t wdt = ::Viewports.ViewportArea.Wdt;
493  StdStrBuf text;
494  // left coloumn
495  text.AppendFormat("[%s]\n\n", LoadResStr("IDS_CTL_GAMEFUNCTIONS"));
496  // main functions
497  text.AppendFormat("<c ffff00>%s</c> - %s\n", GetKeyboardInputName("ToggleShowHelp").getData(), LoadResStr("IDS_CON_HELP"));
498  text.AppendFormat("<c ffff00>%s</c> - %s\n", GetKeyboardInputName("MusicToggle").getData(), LoadResStr("IDS_CTL_MUSIC"));
499  text.AppendFormat("<c ffff00>%s</c> - %s\n", GetKeyboardInputName("NetClientListDlgToggle").getData(), LoadResStr("IDS_DLG_NETWORK"));
500  // messages
501  StdCopyStrBuf strAltChatKey(GetKeyboardInputName("ChatOpen", false, 0));
502  text.AppendFormat("\n<c ffff00>%s/%s</c> - %s\n", GetKeyboardInputName("ChatOpen", false, 1).getData(), strAltChatKey.getData(), LoadResStr("IDS_CTL_SENDMESSAGE"));
503  text.AppendFormat("<c ffff00>%s</c> - %s\n", GetKeyboardInputName("MsgBoardScrollUp").getData(), LoadResStr("IDS_CTL_MESSAGEBOARDBACK"));
504  text.AppendFormat("<c ffff00>%s</c> - %s\n", GetKeyboardInputName("MsgBoardScrollDown").getData(), LoadResStr("IDS_CTL_MESSAGEBOARDFORWARD"));
505  // irc chat
506  text.AppendFormat("\n<c ffff00>%s</c> - %s\n", GetKeyboardInputName("ToggleChat").getData(), LoadResStr("IDS_CTL_IRCCHAT"));
507  // scoreboard
508  text.AppendFormat("\n<c ffff00>%s</c> - %s\n", GetKeyboardInputName("ScoreboardToggle").getData(), LoadResStr("IDS_CTL_SCOREBOARD"));
509  // screenshots
510  text.AppendFormat("\n<c ffff00>%s</c> - %s\n", GetKeyboardInputName("Screenshot").getData(), LoadResStr("IDS_CTL_SCREENSHOT"));
511  text.AppendFormat("<c ffff00>%s</c> - %s\n", GetKeyboardInputName("ScreenshotEx").getData(), LoadResStr("IDS_CTL_SCREENSHOTEX"));
512 
514 
515  // right coloumn
516  text.Clear();
517  // game speed
518  text.AppendFormat("\n\n<c ffff00>%s</c> - %s\n", GetKeyboardInputName("GameSpeedUp").getData(), LoadResStr("IDS_CTL_GAMESPEEDUP"));
519  text.AppendFormat("<c ffff00>%s</c> - %s\n", GetKeyboardInputName("GameSlowDown").getData(), LoadResStr("IDS_CTL_GAMESPEEDDOWN"));
520  // debug
521  text.AppendFormat("\n\n[%s]\n\n", "Debug");
522  text.AppendFormat("<c ffff00>%s</c> - %s\n", GetKeyboardInputName("DbgModeToggle").getData(), LoadResStr("IDS_CTL_DEBUGMODE"));
523  text.AppendFormat("<c ffff00>%s</c> - %s\n", GetKeyboardInputName("DbgShowVtxToggle").getData(), "Entrance+Vertices");
524  text.AppendFormat("<c ffff00>%s</c> - %s\n", GetKeyboardInputName("DbgShowActionToggle").getData(), "Actions/Commands/Pathfinder/Lights/Menus");
525  text.AppendFormat("<c ffff00>%s</c> - %s\n", GetKeyboardInputName("DbgShow8BitSurface").getData(), "8-bit surfaces");
527 }
528 
530 {
532  return true;
533 }
534 
536 {
537  if (!Game.DebugMode && !Console.Active)
538  {
539  FlashMessage(LoadResStr("IDS_MSG_NODEBUGMODE"));
540  return false;
541  }
543  ShowEntrance = !ShowEntrance; // vertices and entrance now toggled together
544  FlashMessageOnOff("Entrance+Vertices", ShowVertices || ShowEntrance);
545  return true;
546 }
547 
549 {
550  if (!Game.DebugMode && !Console.Active)
551  {
552  FlashMessage(LoadResStr("IDS_MSG_NODEBUGMODE"));
553  return false;
554  }
556  {
557  ShowAction = true;
558  FlashMessage("Actions");
559  }
560  else if (ShowAction)
561  {
562  ShowAction = false;
563  ShowCommand = true;
564  FlashMessage("Commands");
565  }
566  else if (ShowCommand)
567  {
568  ShowCommand = false;
569  ShowPathfinder = true;
570  FlashMessage("Pathfinder");
571  }
572  else if (ShowPathfinder)
573  {
574  ShowPathfinder = false;
575  ShowLights = true;
576  FlashMessage("Lights");
577  }
578  else if (ShowLights)
579  {
580  ShowLights = false;
581  ShowMenuInfo = true;
582  FlashMessage("Menu Info");
583  }
584  else if (ShowMenuInfo)
585  {
586  ShowMenuInfo = false;
587  FlashMessageOnOff("Actions/Commands/Pathfinder/Lights/Menus", false);
588  }
589  return true;
590 }
591 
593 {
594  if (!Game.DebugMode && !Console.Active)
595  {
596  FlashMessage(LoadResStr("IDS_MSG_NODEBUGMODE"));
597  return false;
598  }
599  Show8BitSurface = (Show8BitSurface + 1) % 3;
600  if (Show8BitSurface == 0)
601  {
602  FlashMessage("Default view");
603  }
604  else if (Show8BitSurface == 1)
605  {
606  FlashMessage("Foreground 8-bit landscape");
607  }
608  else if (Show8BitSurface == 2)
609  {
610  FlashMessage("Background 8-bit landscape");
611  }
612  return true;
613 }
614 
616 {
617  ShowHelp = !ShowHelp;
618  // Turned off? Invalidate background.
619  if (!ShowHelp)
620  {
621  InvalidateBg();
622  }
623  return true;
624 }
625 
C4Config Config
Definition: C4Config.cpp:930
const size_t C4MaxTitle
Definition: C4Constants.h:25
const int C4UpperBoardHeight
Definition: C4Constants.h:59
const int NO_OWNER
Definition: C4Constants.h:137
C4Draw * pDraw
Definition: C4Draw.cpp:42
StdStrBuf GetKeyboardInputName(const char *key_name, bool abbreviated=false, int32_t index=0)
Definition: C4Game.h:302
C4Game Game
Definition: C4Globals.cpp:52
C4Console Console
Definition: C4Globals.cpp:45
C4Application Application
Definition: C4Globals.cpp:44
C4GameObjects Objects
Definition: C4Globals.cpp:48
C4Network2 Network
Definition: C4Globals.cpp:53
C4FullScreen FullScreen
Definition: C4Globals.cpp:46
C4GraphicsSystem GraphicsSystem
Definition: C4Globals.cpp:51
C4GraphicsResource GraphicsResource
C4GUIScreen * pGUI
Definition: C4Gui.cpp:1191
C4Landscape Landscape
const char * LoadResStr(const char *id)
Definition: C4Language.h:83
bool Log(const char *szMessage)
Definition: C4Log.cpp:204
bool LogF(const char *strMessage,...)
Definition: C4Log.cpp:262
float bottom
Definition: C4Rect.h:25
float top
Definition: C4Rect.h:25
float right
Definition: C4Rect.h:25
float left
Definition: C4Rect.h:25
const int ALeft
Definition: C4Surface.h:41
const int ACenter
Definition: C4Surface.h:41
C4ViewportList Viewports
#define _MAX_PATH_LEN
uint8_t BYTE
void SCopy(const char *szSource, char *sTarget, size_t iMaxL)
Definition: Standard.cpp:152
#define sprintf
Definition: Standard.h:162
size_t SLen(const char *sptr)
Definition: Standard.h:74
bool FileExists(const char *szFileName)
bool Active
Definition: C4App.h:63
C4MusicSystem MusicSystem
Definition: C4Application.h:41
int32_t UpperBoard
Definition: C4Config.h:102
const char * AtScreenshotPath(const char *filename)
Definition: C4Config.cpp:615
const char * AtUserDataRelativePath(const char *filename)
Definition: C4Config.cpp:729
C4ConfigGraphics Graphics
Definition: C4Config.h:257
virtual void FillBG(DWORD dwClr=0)=0
@ DEFAULT_MESSAGE_COLOR
Definition: C4Draw.h:167
bool Active
Definition: C4Draw.h:96
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:561
float Wdt
Definition: C4Facet.h:118
float Y
Definition: C4Facet.h:118
float X
Definition: C4Facet.h:118
void Render(bool fDoBG)
Definition: C4Gui.cpp:730
void SetMouseInGUI(bool fInGUI, bool fByMouse)
Definition: C4Gui.cpp:824
bool HasFullscreenDialog(bool fIncludeFading)
Definition: C4Gui.cpp:1032
bool IsRunning
Definition: C4Game.h:140
bool DebugMode
Definition: C4Game.h:145
int32_t HaltCount
Definition: C4Game.h:112
void ResetAudibility()
C4UpperBoard UpperBoard
bool SaveScreenshot(bool save_all, float zoom_factor_all)
bool DoSaveScreenshot(bool save_all, const char *filename, float zoom_factor_all)
bool InitLoaderScreen(const char *image_name)
std::unique_ptr< C4MessageBoard > MessageBoard
void FlashMessage(const char *message)
C4LoaderScreen * pLoaderScreen
void FlashMessageOnOff(const char *description, bool switch_on)
int32_t GetWidth() const
class C4Sky & GetSky()
int32_t GetHeight() const
void SetBlackScreen(bool fIsBlack)
bool Init(std::string szLoaderSpec)
void Execute(bool force_buffer_checks=false)
bool isLobbyActive() const
Definition: C4Network2.h:204
int32_t ParX
Definition: C4Sky.h:57
int32_t ParY
Definition: C4Sky.h:57
DWORD GetPixDw(int iX, int iY, bool fApplyModulation)
Definition: C4Surface.cpp:491
bool Unlock()
Definition: C4Surface.cpp:464
bool Lock()
Definition: C4Surface.cpp:453
bool PageFlip(C4Rect *pSrcRt=nullptr, C4Rect *pDstRt=nullptr)
Definition: C4Surface.cpp:310
bool SavePNG(C4Group &hGroup, const char *szFilename, bool fSaveAlpha=true, bool fSaveOverlayOnly=false)
int Hgt
Definition: C4Surface.h:65
void Set(const C4Facet &cpy)
Definition: C4Facet.h:182
static C4TimeMilliseconds Now()
float BorderTop
Definition: C4Viewport.h:39
float BorderRight
Definition: C4Viewport.h:39
float BorderLeft
Definition: C4Viewport.h:39
void SetOutputSize(int32_t draw_x, int32_t draw_y, int32_t out_x, int32_t out_y, int32_t out_wdt, int32_t out_hgt)
Definition: C4Viewport.cpp:926
int32_t Player
Definition: C4Viewport.h:108
void Draw(C4TargetFacet &cgo, bool draw_game, bool draw_overlay)
Definition: C4Viewport.cpp:235
float BorderBottom
Definition: C4Viewport.h:39
int32_t GetViewportCount()
C4Viewport * GetFirstViewport()
Definition: C4Viewport.h:159
void RecalculateViewports()
void Execute(bool DrawBackground)
C4Facet ViewportArea
Definition: C4Viewport.h:174
C4Surface * pSurface
Definition: C4Window.h:275
bool Active
Definition: C4Window.h:274
static void ScheduleSaving(CPNGFile *png, const char *filename)
Definition: StdPNG.cpp:354
int GetLineHeight() const
Definition: C4FontLoader.h:125
const char * getData() const
Definition: StdBuf.h:442
void Format(const char *szFmt,...) GNUC_FORMAT_ATTRIBUTE_O
Definition: StdBuf.cpp:174
int32_t GetScreenHgt()
Definition: C4Gui.h:2825
bool IsActive()
Definition: C4Gui.h:2820
int32_t GetScreenWdt()
Definition: C4Gui.h:2824