Freeciv-3.3
Loading...
Searching...
No Matches
graphics.h
Go to the documentation of this file.
1/***********************************************************************
2 Freeciv - Copyright (C) 1996 - A Kjeldberg, L Gregersen, P Unold
3 This program is free software; you can redistribute it and/or modify
4 it under the terms of the GNU General Public License as published by
5 the Free Software Foundation; either version 2, or (at your option)
6 any later version.
7
8 This program is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 GNU General Public License for more details.
12***********************************************************************/
13
14/***********************************************************************
15 graphics.h - description
16 -------------------
17 begin : Mon Jul 1 2002
18 copyright : (C) 2000 by Michael Speck
19 : (C) 2002 by Rafał Bursig
20 email : Michael Speck <kulkanie@gmx.net>
21 : Rafał Bursig <bursig@poczta.fm>
22***********************************************************************/
23
24#ifndef FC__GRAPHICS_H
25#define FC__GRAPHICS_H
26
27/* SDL3 */
28#include "SDL3_gfx/SDL3_rotozoom.h"
29
30/* client */
31#include "graphics_g.h"
32
33/* gui-sdl3 */
34#include "canvas.h"
35#include "gui_main.h"
36
37#define RECT_LIMIT 80
38
39/* DUFFS LOOPs come from SDL lib (LGPL) */
40/* DUFFS_LOOP_DOUBLE2 and DUFFS_LOOP_QUATRO2 was created by Rafal Bursig under GPL */
41
42/* This is a very useful loop for optimizing blitters */
43#if defined(_MSC_VER) && (_MSC_VER == 1300)
44/* There's a bug in the Visual C++ 7 optimizer when compiling this code */
45#else
46#define USE_DUFFS_LOOP
47#endif
48
49#ifdef USE_DUFFS_LOOP
50
51/* 8-times unrolled loop */
52#define DUFFS_LOOP8(pixel_copy_increment, width) \
53{ int n = (width + 7) / 8; \
54 switch (width & 7) { \
55 case 0: do { pixel_copy_increment; \
56 fc__fallthrough; \
57 case 7: pixel_copy_increment; \
58 fc__fallthrough; \
59 case 6: pixel_copy_increment; \
60 fc__fallthrough; \
61 case 5: pixel_copy_increment; \
62 fc__fallthrough; \
63 case 4: pixel_copy_increment; \
64 fc__fallthrough; \
65 case 3: pixel_copy_increment; \
66 fc__fallthrough; \
67 case 2: pixel_copy_increment; \
68 fc__fallthrough; \
69 case 1: pixel_copy_increment; \
70 } while ( --n > 0 ); \
71 } \
72}
73
74/* 4-times unrolled loop */
75#define DUFFS_LOOP4(pixel_copy_increment, width) \
76{ int n = (width + 3) / 4; \
77 switch (width & 3) { \
78 case 0: do { pixel_copy_increment; \
79 fc__fallthrough; \
80 case 3: pixel_copy_increment; \
81 fc__fallthrough; \
82 case 2: pixel_copy_increment; \
83 fc__fallthrough; \
84 case 1: pixel_copy_increment; \
85 } while ( --n > 0 ); \
86 } \
87}
88
89/* 2 - times unrolled loop */
90#define DUFFS_LOOP_DOUBLE2(pixel_copy_increment, \
91 double_pixel_copy_increment, width) \
92{ int n, w = width; \
93 if ( w & 1 ) { \
94 pixel_copy_increment; \
95 w--; \
96 } \
97 if ( w > 0 ) { \
98 n = ( w + 2 ) / 4; \
99 switch ( w & 2 ) { \
100 case 0: do { double_pixel_copy_increment; \
101 fc__fallthrough; \
102 case 2: double_pixel_copy_increment; \
103 } while ( --n > 0 ); \
104 } \
105 } \
106}
107
108/* 2 - times unrolled loop 4 pixels */
109#define DUFFS_LOOP_QUATRO2(pixel_copy_increment, \
110 double_pixel_copy_increment, \
111 quatro_pixel_copy_increment, width) \
112{ int n, w = width; \
113 if (w & 1) { \
114 pixel_copy_increment; \
115 w--; \
116 } \
117 if (w & 2) { \
118 double_pixel_copy_increment; \
119 w -= 2; \
120 } \
121 if ( w > 0 ) { \
122 n = ( w + 7 ) / 8; \
123 switch ( w & 4 ) { \
124 case 0: do { quatro_pixel_copy_increment; \
125 case 4: quatro_pixel_copy_increment; \
126 } while ( --n > 0 ); \
127 } \
128 } \
129}
130
131/* Use the 8-times version of the loop by default */
132#define DUFFS_LOOP(pixel_copy_increment, width) \
133 DUFFS_LOOP8(pixel_copy_increment, width)
134
135#else
136
137/* Don't use Duff's device to unroll loops */
138#define DUFFS_LOOP_DOUBLE2(pixel_copy_increment, \
139 double_pixel_copy_increment, width) \
140{ int n = width; \
141 if ( n & 1 ) { \
142 pixel_copy_increment; \
143 n--; \
144 } \
145 for (; n > 0; --n) { \
146 double_pixel_copy_increment; \
147 n--; \
148 } \
149}
150
151/* Don't use Duff's device to unroll loops */
152#define DUFFS_LOOP_QUATRO2(pixel_copy_increment, \
153 double_pixel_copy_increment, \
154 quatro_pixel_copy_increment, width) \
155{ int n = width; \
156 if (n & 1) { \
157 pixel_copy_increment; \
158 n--; \
159 } \
160 if (n & 2) { \
161 double_pixel_copy_increment; \
162 n -= 2; \
163 } \
164 for (; n > 0; --n) { \
165 quatro_pixel_copy_increment; \
166 n -= 3; \
167 } \
168}
169
170/* Don't use Duff's device to unroll loops */
171#define DUFFS_LOOP(pixel_copy_increment, width) \
172{ int n; \
173 for ( n=width; n > 0; --n ) { \
174 pixel_copy_increment; \
175 } \
176}
177
178#define DUFFS_LOOP8(pixel_copy_increment, width) \
179 DUFFS_LOOP(pixel_copy_increment, width)
180#define DUFFS_LOOP4(pixel_copy_increment, width) \
181 DUFFS_LOOP(pixel_copy_increment, width)
182
183#endif /* USE_DUFFS_LOOP */
184
185/* Shrink surface on 320x240 screen */
186#ifdef GUI_SDL3_SMALL_SCREEN
187#define DEFAULT_ZOOM 0.5
188#define adj_surf(surf) zoomSurface((surf), DEFAULT_ZOOM, DEFAULT_ZOOM, 0)
189#else
190#define DEFAULT_ZOOM 1.0
191/* Cannot return the original as callers free what we return */
192#define adj_surf(surf) copy_surface(surf)
193#endif
194
195struct gui_layer;
196
197struct sdl3_data {
198 int rects_count; /* Update rect. array counter */
199 int guis_count; /* Gui buffers array counter */
200 SDL_Rect rects[RECT_LIMIT]; /* Update rect. list */
201 SDL_Window *screen; /* Main screen buffer */
202 SDL_Surface *map; /* Map buffer */
203 SDL_Surface *dummy; /* Dummy surface for missing sprites */
207 struct gui_layer *gui; /* Gui buffer */
208 struct gui_layer **guis; /* Gui buffers used by sdl3-client widgets window menager */
209 SDL_Event event; /* Main event struct */
210};
211
212extern struct sdl3_data main_data;
213
214/* GUI layer */
215/* A gui_layer is a surface with its own origin. Each widget belongs
216 * to a gui_layer. gui_layers are stored in an array main_data.guis
217 * (a "window manager"). */
218
219struct gui_layer {
220 SDL_Rect dest_rect; /* origin: only x and y are used */
222};
223
224struct gui_layer *gui_layer_new(int x, int y, SDL_Surface *surface);
226
228
229struct gui_layer *add_gui_layer(int width, int height);
231
234
235/* ---------- */
236
239 unsigned char alpha_mod);
241 unsigned char alpha_mod);
242
243SDL_Surface *load_surf(const char *fname);
244
246 int width, int height);
247SDL_Surface *create_surf(int width, int height, Uint32 flags);
249
252
254 SDL_Rect *prect);
255
258
260
263
266
267void create_frame(SDL_Surface *dest, Sint16 left, Sint16 top,
268 Sint16 right, Sint16 bottom,
270
273
274/* SDL */
275void init_sdl(int f);
276void quit_sdl(void);
277bool set_video_mode(unsigned width, unsigned height, unsigned flags);
278bool create_surfaces(int width, int height);
279
280void update_main_screen(void);
281
282int main_window_width(void);
283int main_window_height(void);
284
285/* Rect */
287bool is_in_rect_area(int x, int y, const SDL_Rect *rect);
288
291
293
294/* ================================================================= */
295
298
301 int smooth, bool scale_up,
303
306
307#define map_rgba(format, color) \
308 SDL_MapRGBA(format, (color).r, (color).g, (color).b, (color).a)
309
310#define crop_rect_from_screen(rect) \
311 crop_rect_from_surface(main_data.screen, &rect)
312
313/* Free surface with check and clear pointer */
314#define FREESURFACE(ptr) \
315do { \
316 if (ptr) { \
317 SDL_DestroySurface(ptr); \
318 ptr = NULL; \
319 } \
320} while (FALSE)
321
322/*
323 * Lock surface
324 */
325#define lock_surf(surf) \
326do { \
327 if (SDL_MUSTLOCK(surf)) { \
328 SDL_LockSurface(surf); \
329 } \
330} while (FALSE)
331
332
333/*
334 * Unlock surface
335 */
336#define unlock_surf(surf) \
337do { \
338 if (SDL_MUSTLOCK(surf)) { \
339 SDL_UnlockSurface(surf); \
340 } \
341} while (FALSE)
342
343/*
344 * Lock screen surface
345 */
346#define lock_screen() lock_surf(main_data.screen)
347
348/*
349 * Unlock screen surface
350 */
351#define unlock_screen() unlock_surf(main_data.screen)
352
353#define putpixel(surf, x, y, pixel) \
354do { \
355 Uint8 *buf_ptr = ((Uint8 *)surf->pixels + (y * surf->pitch)); \
356 switch (surf->format->BytesPerPixel) { \
357 case 1: \
358 buf_ptr += x; \
359 *(Uint8 *)buf_ptr = pixel; \
360 break; \
361 case 2: \
362 buf_ptr += x << 1; \
363 *((Uint16 *)buf_ptr) = pixel; \
364 break; \
365 case 3: \
366 buf_ptr += (x << 1) + x; \
367 if (is_bigendian()) { \
368 buf_ptr[0] = (pixel >> 16) & 0xff; \
369 buf_ptr[1] = (pixel >> 8) & 0xff; \
370 buf_ptr[2] = pixel & 0xff; \
371 } else { \
372 buf_ptr[0] = pixel & 0xff; \
373 buf_ptr[1] = (pixel >> 8) & 0xff; \
374 buf_ptr[2] = (pixel >> 16) & 0xff; \
375 } \
376 break; \
377 case 4: \
378 buf_ptr += x << 2; \
379 *((Uint32 *)buf_ptr) = pixel; \
380 break; \
381 } \
382} while (FALSE)
383
384/* Blend the RGB values of two pixels based on a source alpha value */
385#define ALPHA_BLEND(sR, sG, sB, A, dR, dG, dB) \
386do { \
387 dR = (((sR-dR)*(A))>>8)+dR; \
388 dG = (((sG-dG)*(A))>>8)+dG; \
389 dB = (((sB-dB)*(A))>>8)+dB; \
390} while (FALSE)
391
392#define ALPHA_BLEND128(sR, sG, sB, dR, dG, dB) \
393do { \
394 Uint32 __Src = (sR << 16 | sG << 8 | sB); \
395 Uint32 __Dst = (dR << 16 | dG << 8 | dB); \
396 __Dst = ((((__Src & 0x00fefefe) + (__Dst & 0x00fefefe)) >> 1) \
397 + (__Src & __Dst & 0x00010101)) | 0xFF000000; \
398 dR = (__Dst >> 16) & 0xFF; \
399 dG = (__Dst >> 8 ) & 0xFF; \
400 dB = (__Dst ) & 0xFF; \
401} while (FALSE)
402
403#endif /* FC__GRAPHICS_H */
struct canvas int int struct sprite int int int int height
Definition canvas_g.h:44
struct canvas int int int int struct sprite *sprite struct canvas struct color * pcolor
Definition canvas_g.h:56
struct canvas int int struct sprite int int int width
Definition canvas_g.h:44
char * incite_cost
Definition comments.c:74
SDL_Surface * resize_surface(const SDL_Surface *psrc, Uint16 new_width, Uint16 new_height, int smooth)
Definition graphics.c:1237
Uint32 getpixel(SDL_Surface *surf, Sint16 x, Sint16 y)
Definition graphics.c:430
int main_window_width(void)
Definition graphics.c:685
void layer_rect_to_screen_rect(struct gui_layer *gui_layer, SDL_Rect *dest_rect)
Definition graphics.c:185
SDL_Surface * load_surf(const char *fname)
Definition graphics.c:307
SDL_Surface * create_surf_with_format(SDL_PixelFormat *pf, int width, int height, Uint32 flags)
Definition graphics.c:328
void update_main_screen(void)
Definition graphics.c:669
void remove_gui_layer(struct gui_layer *gui_layer)
Definition graphics.c:148
SDL_Surface * create_filled_surface(Uint16 w, Uint16 h, Uint32 flags, SDL_Color *pcolor)
Definition graphics.c:368
int fill_rect_alpha(SDL_Surface *surf, SDL_Rect *prect, SDL_Color *pcolor)
Definition graphics.c:865
void gui_layer_destroy(struct gui_layer **gui_layer)
Definition graphics.c:81
void create_line(SDL_Surface *dest, Sint16 x0, Sint16 y0, Sint16 x1, Sint16 y1, SDL_Color *pcolor)
Definition graphics.c:1381
SDL_Surface * copy_surface(SDL_Surface *src)
Definition graphics.c:1309
bool set_video_mode(unsigned width, unsigned height, unsigned flags)
Definition graphics.c:636
SDL_Surface * mask_surface(SDL_Surface *src, SDL_Surface *mask, int mask_offset_x, int mask_offset_y)
Definition graphics.c:262
struct gui_layer * gui_layer_new(int x, int y, SDL_Surface *surface)
Definition graphics.c:66
void quit_sdl(void)
Definition graphics.c:622
SDL_Surface * crop_visible_part_from_surface(SDL_Surface *psrc)
Definition graphics.c:1225
SDL_Surface * crop_rect_from_surface(SDL_Surface *psource, SDL_Rect *prect)
Definition graphics.c:236
void init_sdl(int f)
Definition graphics.c:506
int alphablit(SDL_Surface *src, SDL_Rect *srcrect, SDL_Surface *dst, SDL_Rect *dstrect, unsigned char alpha_mod)
Definition graphics.c:199
void create_frame(SDL_Surface *dest, Sint16 left, Sint16 top, Sint16 right, Sint16 bottom, SDL_Color *pcolor)
Definition graphics.c:1350
struct gui_layer * get_gui_layer(SDL_Surface *surface)
Definition graphics.c:90
bool is_in_rect_area(int x, int y, const SDL_Rect *rect)
Definition graphics.c:925
int screen_blit(SDL_Surface *src, SDL_Rect *srcrect, SDL_Rect *dstrect, unsigned char alpha_mod)
Definition graphics.c:223
struct sdl2_data main_data
Definition graphics.c:57
int blit_entire_src(SDL_Surface *psrc, SDL_Surface *pdest, Sint16 dest_x, Sint16 dest_y)
Definition graphics.c:417
Uint32 get_first_pixel(SDL_Surface *surf)
Definition graphics.c:468
SDL_Surface * convert_surf(SDL_Surface *surf_in)
Definition graphics.c:359
SDL_Surface * create_surf(int width, int height, Uint32 flags)
Definition graphics.c:351
void get_smaller_surface_rect(SDL_Surface *surf, SDL_Rect *rect)
Definition graphics.c:936
struct gui_layer * add_gui_layer(int width, int height)
Definition graphics.c:112
int clear_surface(SDL_Surface *surf, SDL_Rect *dstrect)
Definition graphics.c:400
bool correct_rect_region(SDL_Rect *prect)
Definition graphics.c:888
void screen_rect_to_layer_rect(struct gui_layer *gui_layer, SDL_Rect *dest_rect)
Definition graphics.c:173
bool create_surfaces(int width, int height)
Definition graphics.c:556
int main_window_height(void)
Definition graphics.c:693
SDL_Surface * resize_surface_box(const SDL_Surface *psrc, Uint16 new_width, Uint16 new_height, int smooth, bool scale_up, bool absolute_dimensions)
Definition graphics.c:1257
#define RECT_LIMIT
Definition graphics.h:37
struct sprite int int int int struct sprite * mask
Definition sprite_g.h:32
struct sprite int int y
Definition sprite_g.h:31
struct sprite int int int int struct sprite int mask_offset_x
Definition sprite_g.h:32
struct sprite int x
Definition sprite_g.h:31
struct sprite int int int int struct sprite int int mask_offset_y
Definition sprite_g.h:32
SDL_Surface * surface
Definition graphics.h:229
SDL_Rect dest_rect
Definition graphics.h:228
struct gui_layer ** guis
Definition graphics.h:208
int guis_count
Definition graphics.h:199
struct canvas map_canvas
Definition graphics.h:206
SDL_Rect rects[RECT_LIMIT]
Definition graphics.h:200
SDL_Renderer * renderer
Definition graphics.h:205
SDL_Event event
Definition graphics.h:209
SDL_Window * screen
Definition graphics.h:201
SDL_Surface * map
Definition graphics.h:202
SDL_Texture * maintext
Definition graphics.h:204
struct gui_layer * gui
Definition graphics.h:207
int rects_count
Definition graphics.h:198
SDL_Surface * dummy
Definition graphics.h:203