1 // _________ __ __
2 // / _____// |_____________ _/ |______ ____ __ __ ______
3 // \_____ \\ __\_ __ \__ \\ __\__ \ / ___\| | \/ ___/
4 // / \| | | | \// __ \| | / __ \_/ /_/ > | /\___ |
5 // /_______ /|__| |__| (____ /__| (____ /\___ /|____//____ >
6 // \/ \/ \//_____/ \/
7 // ______________________ ______________________
8 // T H E W A R B E G I N S
9 // Stratagus - A free fantasy real time strategy game engine
10 //
11 /**@name video.h - The video headerfile. */
12 //
13 // (c) Copyright 1999-2011 by Lutz Sammer, Nehal Mistry, Jimmy Salmon and
14 // Pali Rohár
15 //
16 // This program is free software; you can redistribute it and/or modify
17 // it under the terms of the GNU General Public License as published by
18 // the Free Software Foundation; only version 2 of the License.
19 //
20 // This program is distributed in the hope that it will be useful,
21 // but WITHOUT ANY WARRANTY; without even the implied warranty of
22 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 // GNU General Public License for more details.
24 //
25 // You should have received a copy of the GNU General Public License
26 // along with this program; if not, write to the Free Software
27 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
28 // 02111-1307, USA.
29 //
30
31 #ifndef __VIDEO_H__
32 #define __VIDEO_H__
33
34 //@{
35
36 #include "SDL.h"
37 #include "shaders.h"
38 #include "guichan.h"
39
40 #include "color.h"
41 #include "vec2i.h"
42
43 class CFont;
44
45 /// The SDL screen
46 extern SDL_Window *TheWindow;
47 extern SDL_Renderer *TheRenderer;
48 extern SDL_Surface *TheScreen;
49 extern SDL_Texture *TheTexture;
50
51 #if SDL_BYTEORDER == SDL_LIL_ENDIAN
52 #define RSHIFT 16
53 #define GSHIFT 8
54 #define BSHIFT 0
55 #define ASHIFT 24
56 #define RMASK 0x00ff0000
57 #define GMASK 0x0000ff00
58 #define BMASK 0x000000ff
59 #define AMASK 0xff000000
60 #else
61 #define RSHIFT 8
62 #define GSHIFT 16
63 #define BSHIFT 24
64 #define ASHIFT 0
65 #define RMASK 0x0000ff00
66 #define GMASK 0x00ff0000
67 #define BMASK 0xff000000
68 #define AMASK 0x000000ff
69 #endif
70
71 using pixelModifier = uint32_t(*)(const uint32_t, const uint32_t, const uint32_t); // type alias
72
73 /// Class for modifiers for custom pixel manipulations
74 class PixelModifier
75 {
76 public:
77 /// This one returns srcRGB+A(modulated) only if srcA is present. Otherwise returns dstRGBA.
78 /// Used to copy (without alpha modulating) those pixels which has alpha chanel values
CopyWithSrcAlphaKey(const uint32_t srcPixel,const uint32_t dstPixel,const uint32_t reqAlpha)79 static uint32_t CopyWithSrcAlphaKey(const uint32_t srcPixel, const uint32_t dstPixel, const uint32_t reqAlpha)
80 {
81 uint32_t srcAlpha = (srcPixel >> ASHIFT) & 0xFF;
82 if (srcAlpha) {
83 srcAlpha = (srcAlpha * reqAlpha) >> 8;
84 return (srcPixel - (srcPixel & AMASK)) + (srcAlpha << ASHIFT);
85 }
86 return dstPixel;
87 }
88 /// Add more modifiers here
89 };
90
91 class CGraphic : public gcn::Image
92 {
93
94 struct frame_pos_t {
95 short int x;
96 short int y;
97 };
98
99 protected:
CGraphic()100 CGraphic() : Surface(NULL), SurfaceFlip(NULL), frame_map(NULL),
101 Width(0), Height(0), NumFrames(1), GraphicWidth(0), GraphicHeight(0),
102 Refs(1), Resized(false)
103 {
104 frameFlip_map = NULL;
105 }
~CGraphic()106 ~CGraphic() {}
107
108 public:
109 // Draw
110 void DrawClip(int x, int y,
111 SDL_Surface *surface = TheScreen) const;
112 void DrawSub(int gx, int gy, int w, int h, int x, int y,
113 SDL_Surface *surface = TheScreen) const;
114
115 void DrawSubCustomMod(int gx, int gy, int w, int h, int x, int y,
116 pixelModifier modifier,
117 const uint32_t param,
118 SDL_Surface *surface = TheScreen) const;
119
120 void DrawSubClip(int gx, int gy, int w, int h, int x, int y,
121 SDL_Surface *surface = TheScreen) const;
122 void DrawSubTrans(int gx, int gy, int w, int h, int x, int y,
123 unsigned char alpha,
124 SDL_Surface *surface = TheScreen) const;
125 void DrawSubClipTrans(int gx, int gy, int w, int h, int x, int y,
126 unsigned char alpha,
127 SDL_Surface *surface = TheScreen) const;
128
129 void DrawSubClipCustomMod(int gx, int gy, int w, int h, int x, int y,
130 pixelModifier modifier,
131 const uint32_t param,
132 SDL_Surface *surface = TheScreen) const;
133
134 // Draw frame
135 void DrawFrame(unsigned frame, int x, int y,
136 SDL_Surface *surface = TheScreen) const;
137 void DrawFrameClip(unsigned frame, int x, int y,
138 SDL_Surface *surface = TheScreen) const;
139 void DrawFrameTrans(unsigned frame, int x, int y, int alpha,
140 SDL_Surface *surface = TheScreen) const;
141 void DrawFrameClipTrans(unsigned frame, int x, int y, int alpha,
142 SDL_Surface *surface = TheScreen) const;
143
144 void DrawFrameClipCustomMod(unsigned frame, int x, int y,
145 pixelModifier modifier,
146 const uint32_t param,
147 SDL_Surface *surface = TheScreen) const;
148
149 // Draw frame flipped horizontally
150 void DrawFrameX(unsigned frame, int x, int y,
151 SDL_Surface *surface = TheScreen) const;
152 void DrawFrameClipX(unsigned frame, int x, int y,
153 SDL_Surface *surface = TheScreen) const;
154 void DrawFrameTransX(unsigned frame, int x, int y, int alpha,
155 SDL_Surface *surface = TheScreen) const;
156 void DrawFrameClipTransX(unsigned frame, int x, int y, int alpha,
157 SDL_Surface *surface = TheScreen) const;
158
159
160 static CGraphic *New(const std::string &file, int w = 0, int h = 0);
161 static CGraphic *ForceNew(const std::string &file, int w = 0, int h = 0);
162 static CGraphic *Get(const std::string &file);
163
164 static void Free(CGraphic *g);
165
166 void Load(bool grayscale = false);
167 void Flip();
168 void Resize(int w, int h);
169 void SetOriginalSize();
170 bool TransparentPixel(int x, int y);
171 void SetPaletteColor(int idx, int r, int g, int b);
172 void MakeShadow();
173
IsLoaded()174 inline bool IsLoaded() const { return Surface != NULL; }
175
176 //guichan
_getData()177 virtual void *_getData() const { return Surface; }
getWidth()178 virtual int getWidth() const { return Width; }
getHeight()179 virtual int getHeight() const { return Height; }
180
181 std::string File; /// Filename
182 std::string HashFile; /// Filename used in hash
183 SDL_Surface *Surface; /// Surface
184 SDL_Surface *SurfaceFlip; /// Flipped surface
185 frame_pos_t *frame_map;
186 frame_pos_t *frameFlip_map;
187 void GenFramesMap();
188 int Width; /// Width of a frame
189 int Height; /// Height of a frame
190 int NumFrames; /// Number of frames
191 int GraphicWidth; /// Original graphic width
192 int GraphicHeight; /// Original graphic height
193 int Refs; /// Uses of this graphic
194 bool Resized; /// Image has been resized
195
196 friend class CFont;
197 };
198
199 class CPlayerColorGraphic : public CGraphic
200 {
201 protected:
CPlayerColorGraphic()202 CPlayerColorGraphic()
203 {
204 }
205
206 public:
207 void DrawPlayerColorFrameClipX(int player, unsigned frame, int x, int y,
208 SDL_Surface *surface = TheScreen);
209 void DrawPlayerColorFrameClip(int player, unsigned frame, int x, int y,
210 SDL_Surface *surface = TheScreen);
211
212 static CPlayerColorGraphic *New(const std::string &file, int w = 0, int h = 0);
213 static CPlayerColorGraphic *ForceNew(const std::string &file, int w = 0, int h = 0);
214 static CPlayerColorGraphic *Get(const std::string &file);
215
216 CPlayerColorGraphic *Clone(bool grayscale = false) const;
217 };
218
219 #ifdef USE_MNG
220 #ifdef WIN32
221 #ifdef HAVE_STDDEF_H
222 #undef HAVE_STDDEF_H
223 #endif
224 #endif
225 #include <libmng.h>
226 #ifdef WIN32
227 #ifndef HAVE_STDDEF_H
228 #undef HAVE_STDDEF_H
229 #endif
230 #endif
231
232 class Mng : public gcn::Image
233 {
234 public:
235 Mng();
236 ~Mng();
237 bool Load(const std::string &name);
238 void Reset();
239 void Draw(int x, int y);
240
241 //guichan
242 virtual void *_getData() const;
getWidth()243 virtual int getWidth() const { return surface->h; }
getHeight()244 virtual int getHeight() const { return surface->w; }
isDirty()245 virtual bool isDirty() const { return is_dirty; }
246
247 mutable bool is_dirty;
248 std::string name;
249 FILE *fd;
250 mng_handle handle;
251 SDL_Surface *surface;
252 unsigned char *buffer;
253 unsigned long ticks;
254 int iteration;
255 };
256 #else
257 /// empty class for lua scripts
258 class Mng : public gcn::Image
259 {
260 public:
Mng()261 Mng() {};
~Mng()262 ~Mng() {};
Load(const std::string & name)263 bool Load(const std::string &name) { return false; };
Reset()264 void Reset() {};
Draw(int x,int y)265 void Draw(int x, int y) {};
266
267 //guichan
_getData()268 virtual void *_getData() const { return NULL; };
getWidth()269 virtual int getWidth() const { return 0; };
getHeight()270 virtual int getHeight() const { return 0; };
isDirty()271 virtual bool isDirty() const { return false; };
272 };
273 #endif
274
275 /**
276 ** Event call back.
277 **
278 ** This is placed in the video part, because it depends on the video
279 ** hardware driver.
280 */
281 struct EventCallback {
282
283 /// Callback for mouse button press
284 void (*ButtonPressed)(unsigned buttons);
285 /// Callback for mouse button release
286 void (*ButtonReleased)(unsigned buttons);
287 /// Callback for mouse move
288 void (*MouseMoved)(const PixelPos &screenPos);
289 /// Callback for mouse exit of game window
290 void (*MouseExit)();
291
292 /// Callback for key press
293 void (*KeyPressed)(unsigned keycode, unsigned keychar);
294 /// Callback for key release
295 void (*KeyReleased)(unsigned keycode, unsigned keychar);
296 /// Callback for key repeated
297 void (*KeyRepeated)(unsigned keycode, unsigned keychar);
298
299 /// Callback for network event
300 void (*NetworkEvent)();
301
302 };
303
304
305 class CVideo
306 {
307 public:
CVideo()308 CVideo() : Width(0), Height(0), WindowWidth(0), WindowHeight(0), VerticalPixelSize(1), Depth(0), FullScreen(false) {}
309
310 void LockScreen();
311 void UnlockScreen();
312
313 void ClearScreen();
314 bool ResizeScreen(int width, int height);
315
316 void DrawPixelClip(Uint32 color, int x, int y);
317 void DrawTransPixelClip(Uint32 color, int x, int y, unsigned char alpha);
318
319 void DrawVLine(Uint32 color, int x, int y, int height);
320 void DrawTransVLine(Uint32 color, int x, int y, int height, unsigned char alpha);
321 void DrawVLineClip(Uint32 color, int x, int y, int height);
322 void DrawTransVLineClip(Uint32 color, int x, int y, int height, unsigned char alpha);
323
324 void DrawHLine(Uint32 color, int x, int y, int width);
325 void DrawTransHLine(Uint32 color, int x, int y, int width, unsigned char alpha);
326 void DrawHLineClip(Uint32 color, int x, int y, int width);
327 void DrawTransHLineClip(Uint32 color, int x, int y, int width, unsigned char alpha);
328
329 void DrawLine(Uint32 color, int sx, int sy, int dx, int dy);
330 void DrawTransLine(Uint32 color, int sx, int sy, int dx, int dy, unsigned char alpha);
331 void DrawLineClip(Uint32 color, const PixelPos &pos1, const PixelPos &pos2);
332 void DrawTransLineClip(Uint32 color, int sx, int sy, int dx, int dy, unsigned char alpha);
333
334 void DrawRectangle(Uint32 color, int x, int y, int w, int h);
335 void DrawTransRectangle(Uint32 color, int x, int y, int w, int h, unsigned char alpha);
336 void DrawRectangleClip(Uint32 color, int x, int y, int w, int h);
337 void DrawTransRectangleClip(Uint32 color, int x, int y, int w, int h, unsigned char alpha);
338
339 void FillRectangle(Uint32 color, int x, int y, int w, int h);
340 void FillTransRectangle(Uint32 color, int x, int y, int w, int h, unsigned char alpha);
341 void FillRectangleClip(Uint32 color, int x, int y, int w, int h);
342 void FillTransRectangleClip(Uint32 color, int x, int y, int w, int h, unsigned char alpha);
343
344 void DrawCircle(Uint32 color, int x, int y, int r);
345 void DrawTransCircle(Uint32 color, int x, int y, int r, unsigned char alpha);
346 void DrawCircleClip(Uint32 color, int x, int y, int r);
347 void DrawTransCircleClip(Uint32 color, int x, int y, int r, unsigned char alpha);
348
349 void FillCircle(Uint32 color, int x, int y, int radius);
350 void FillTransCircle(Uint32 color, int x, int y, int radius, unsigned char alpha);
351 void FillCircleClip(Uint32 color, const PixelPos &screenPos, int radius);
352 void FillTransCircleClip(Uint32 color, int x, int y, int radius, unsigned char alpha);
353
MapRGB(SDL_PixelFormat * f,Uint8 r,Uint8 g,Uint8 b)354 inline Uint32 MapRGB(SDL_PixelFormat *f, Uint8 r, Uint8 g, Uint8 b)
355 {
356 return SDL_MapRGB(f, r, g, b);
357 }
MapRGB(SDL_PixelFormat * f,const CColor & color)358 inline Uint32 MapRGB(SDL_PixelFormat *f, const CColor &color)
359 {
360 return MapRGB(f, color.R, color.G, color.B);
361 }
MapRGBA(SDL_PixelFormat * f,Uint8 r,Uint8 g,Uint8 b,Uint8 a)362 inline Uint32 MapRGBA(SDL_PixelFormat *f, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
363 {
364 return SDL_MapRGBA(f, r, g, b, a);
365 }
MapRGBA(SDL_PixelFormat * f,const CColor & color)366 inline Uint32 MapRGBA(SDL_PixelFormat *f, const CColor &color)
367 {
368 return MapRGBA(f, color.R, color.G, color.B, color.A);
369 }
GetRGB(Uint32 c,SDL_PixelFormat * f,Uint8 * r,Uint8 * g,Uint8 * b)370 inline void GetRGB(Uint32 c, SDL_PixelFormat *f, Uint8 *r, Uint8 *g, Uint8 *b)
371 {
372 SDL_GetRGB(c, f, r, g, b);
373 }
GetRGBA(Uint32 c,SDL_PixelFormat * f,Uint8 * r,Uint8 * g,Uint8 * b,Uint8 * a)374 inline void GetRGBA(Uint32 c, SDL_PixelFormat *f, Uint8 *r, Uint8 *g, Uint8 *b, Uint8 *a)
375 {
376 SDL_GetRGBA(c, f, r, g, b, a);
377 }
378
379 int Width;
380 int Height;
381 int WindowWidth;
382 int WindowHeight;
383 double VerticalPixelSize;
384 SDL_Cursor *blankCursor;
385 int Depth;
386 bool FullScreen;
387 };
388
389 extern CVideo Video;
390
391 /**
392 ** Video synchronization speed. Synchronization time in percent.
393 ** If =0, video framerate is not synchronized. 100 is exact
394 ** CYCLES_PER_SECOND (30). Game will try to redraw screen within
395 ** intervals of VideoSyncSpeed, not more, not less.
396 ** @see CYCLES_PER_SECOND
397 */
398 extern int VideoSyncSpeed;
399
400 extern int SkipFrames;
401
402 /// Fullscreen or windowed set from commandline.
403 extern char VideoForceFullScreen;
404
405 /// Next frame ticks
406 extern double NextFrameTicks;
407
408 /// Counts frames
409 extern unsigned long FrameCounter;
410
411 /// Counts quantity of slow frames
412 extern unsigned long SlowFrameCounter;
413
414 /// Initialize Pixels[] for all players.
415 /// (bring Players[] in sync with Pixels[])
416 extern void SetPlayersPalette();
417
418 /// register lua function
419 extern void VideoCclRegister();
420
421 /// initialize the image loaders part
422 extern void InitImageLoaders();
423
424 /// deinitialize the image loaders
425 extern void DeInitImageLoaders();
426
427 /// initialize the video part
428 extern void InitVideo();
429
430 /// deinitliaize the video part
431 void DeInitVideo();
432
433 /// Check if a resolution is valid
434 extern int VideoValidResolution(int w, int h);
435
436 /// Initializes video synchronization.
437 extern void SetVideoSync();
438
439 /// Init line draw
440 extern void InitLineDraw();
441
442 /// Simply invalidates whole window or screen.
443 extern void Invalidate();
444
445 /// Invalidates selected area on window or screen. Use for accurate
446 /// redrawing. in so
447 extern void InvalidateArea(int x, int y, int w, int h);
448
449 /// Set clipping for nearly all vector primitives. Functions which support
450 /// clipping will be marked Clip. Set the system-wide clipping rectangle.
451 extern void SetClipping(int left, int top, int right, int bottom);
452
453 /// Realize video memory.
454 extern void RealizeVideoMemory();
455
456 /// Save a screenshot to a PNG file
457 extern void SaveScreenshotPNG(const char *name);
458
459 /// Save a screenshot to a PNG file
460 extern void SaveMapPNG(const char *name);
461
462 /// Set the current callbacks
463 extern void SetCallbacks(const EventCallback *callbacks);
464 /// Get the current callbacks
465 extern const EventCallback *GetCallbacks();
466
467 /// Process all system events. Returns if the time for a frame is over
468 extern void WaitEventsOneFrame();
469
470 /// Toggle full screen mode
471 extern void ToggleFullScreen();
472
473 /// Push current clipping.
474 extern void PushClipping();
475
476 /// Pop current clipping.
477 extern void PopClipping();
478
479 /// Returns the ticks in ms since start
480 extern unsigned long GetTicks();
481
482 /// Convert a SDLKey to a string
483 extern const char *SdlKey2Str(int key);
484
485 /// Check if the mouse is grabbed
486 extern bool SdlGetGrabMouse();
487 /// Toggle mouse grab mode
488 extern void ToggleGrabMouse(int mode);
489
490 extern EventCallback GameCallbacks; /// Game callbacks
491 extern EventCallback EditorCallbacks; /// Editor callbacks
492
493 extern Uint32 ColorBlack;
494 extern Uint32 ColorDarkGreen;
495 extern Uint32 ColorLightBlue;
496 extern Uint32 ColorBlue;
497 extern Uint32 ColorOrange;
498 extern Uint32 ColorWhite;
499 extern Uint32 ColorLightGray;
500 extern Uint32 ColorGray;
501 extern Uint32 ColorDarkGray;
502 extern Uint32 ColorRed;
503 extern Uint32 ColorGreen;
504 extern Uint32 ColorYellow;
505
IndexToColor(unsigned int index)506 inline Uint32 IndexToColor(unsigned int index) {
507 // FIXME: this only works after video was initialized, so we do it dynamically
508 static const Uint32 ColorValues[] = {ColorRed, ColorYellow, ColorGreen, ColorLightGray,
509 ColorGray, ColorDarkGray, ColorWhite, ColorOrange,
510 ColorLightBlue, ColorBlue, ColorDarkGreen, ColorBlack};
511 return ColorValues[index];
512 }
513
514 static const char *ColorNames[] = {"red", "yellow", "green", "light-gray",
515 "gray", "dark-gray", "white", "orange",
516 "light-blue", "blue", "dark-green", "black", NULL};
517
GetColorIndexByName(const char * colorName)518 inline int GetColorIndexByName(const char *colorName) {
519 int i = 0;
520 while (ColorNames[i] != NULL) {
521 if (!strcmp(colorName, ColorNames[i])) {
522 return i;
523 }
524 i++;
525 }
526 return -1;
527 }
528
529 extern void FreeGraphics();
530
531 //
532 // Color Cycling stuff
533 //
534
535 extern void VideoPaletteListAdd(SDL_Surface *surface);
536 extern void VideoPaletteListRemove(SDL_Surface *surface);
537 extern void ClearAllColorCyclingRange();
538 extern void AddColorCyclingRange(unsigned int begin, unsigned int end);
539 extern void SetColorCycleAll(bool value);
540 extern void RestoreColorCyclingSurface();
541
542 /// Does ColorCycling..
543 extern void ColorCycle();
544
545 /// Blit a surface into another with alpha blending
546 extern void BlitSurfaceAlphaBlending_32bpp(const SDL_Surface *srcSurface, const SDL_Rect *srcRect,
547 SDL_Surface *dstSurface, const SDL_Rect *dstRect, const bool enableMT = true);
548
549 //@}
550
551 #endif // !__VIDEO_H__
552