ScummVM API documentation
draw.h
1 /* ScummVM - Graphic Adventure Engine
2  *
3  * ScummVM is the legal property of its developers, whose names
4  * are too numerous to list here. Please refer to the COPYRIGHT
5  * file distributed with this source distribution.
6  *
7  * This program is free software: you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation, either version 3 of the License, or
10  * (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program. If not, see <http://www.gnu.org/licenses/>.
19  *
20  */
21 
22 #ifndef AGS_ENGINE_AC_DRAW_H
23 #define AGS_ENGINE_AC_DRAW_H
24 
25 #include "common/std/memory.h"
26 #include "ags/shared/core/types.h"
27 #include "ags/shared/ac/common_defines.h"
28 #include "ags/shared/gfx/gfx_def.h"
29 #include "ags/shared/gfx/allegro_bitmap.h"
30 #include "ags/shared/gfx/bitmap.h"
31 #include "ags/shared/game/room_struct.h"
32 #include "ags/engine/ac/runtime_defines.h"
33 #include "ags/engine/ac/walk_behind.h"
34 
35 namespace AGS3 {
36 namespace AGS {
37 namespace Shared {
38 typedef std::shared_ptr<Shared::Bitmap> PBitmap;
39 } // namespace Shared
40 
41 namespace Engine {
42 class IDriverDependantBitmap;
43 } // namespace Engine
44 } // namespace AGS
45 
46 using namespace AGS; // FIXME later
47 
48 #define IS_ANTIALIAS_SPRITES _GP(usetup).enable_antialiasing && (_GP(play).disable_antialiasing == 0)
49 
50 // Render stage flags, for filtering out certain elements
51 // during room transitions, capturing screenshots, etc.
52 // NOTE: these values are internal and purely arbitrary atm.
53 #define RENDER_BATCH_ENGINE_OVERLAY 0x0001
54 #define RENDER_BATCH_MOUSE_CURSOR 0x0002
55 #define RENDER_SHOT_SKIP_ON_FADE (RENDER_BATCH_ENGINE_OVERLAY | RENDER_BATCH_MOUSE_CURSOR)
56 
61  // Intermediate bitmap for the software drawing method.
62  // We use this bitmap in case room camera has scaling enabled, we draw dirty room rects on it,
63  // and then pass to software renderer which draws sprite on top and then either blits or stretch-blits
64  // to the virtual screen.
65  // For more details see comment in ALSoftwareGraphicsDriver::RenderToBackBuffer().
66  AGS::Shared::PBitmap Buffer; // this is the actual bitmap
67  AGS::Shared::PBitmap Frame; // this is either same bitmap reference or sub-bitmap of virtual screen
68  bool IsOffscreen; // whether room viewport was offscreen (cannot use sub-bitmap)
69  bool IsOverlap; // whether room viewport overlaps any others (marking dirty rects is complicated)
70 };
71 
72 typedef int32_t sprkey_t;
73 // TODO: refactor the draw unit into a virtual interface with
74 // two implementations: for software and video-texture render,
75 // instead of checking whether the current method is "software".
76 struct DrawState {
77  // Whether we should use software rendering methods
78  // (aka raw draw), as opposed to video texture transform & fx
79  bool SoftwareRender = false;
80  // Whether we should redraw whole game screen each frame
81  bool FullFrameRedraw = false;
82  // Walk-behinds representation
83  WalkBehindMethodEnum WalkBehindMethod = DrawAsSeparateSprite;
84  // Whether there are currently remnants of a on-screen effect
85  bool ScreenIsDirty = false;
86 
87  // A map of shared "control blocks" per each sprite used
88  // when preparing object textures. "Control block" is currently just
89  // an integer which lets to check whether the object texture is in sync
90  // with the sprite. When the dynamic sprite is updated or deleted,
91  // the control block is marked as invalid and removed from the map;
92  // but certain objects may keep the shared ptr to the old block with
93  // "invalid" mark, thus they know that they must reset their texture.
94  //
95  // TODO: investigate an alternative of having a equivalent of
96  // "shared texture" with sprite ID ref in Software renderer too,
97  // which would allow to use same method of testing DDB ID for both
98  // kinds of renderers, thus saving on 1 extra notification mechanism.
100  SpriteNotifyMap;
101 };
102 
103 // ObjTexture is a helper struct that pairs a raw bitmap with
104 // a renderer's texture and an optional position
105 struct ObjTexture {
106  // Sprite ID
107  uint32_t SpriteID = UINT32_MAX;
108  // Raw bitmap; used for software render mode,
109  // or when particular object types require generated image.
111  // Corresponding texture, created by renderer
112  Engine::IDriverDependantBitmap *Ddb = nullptr;
113  // Sprite notification block: becomes invalid to notify an updated
114  // or deleted sprtie
115  std::shared_ptr<uint32_t> SpriteNotify;
116  // Sprite's position
117  Point Pos;
118  // Texture's offset, *relative* to the logical sprite's position;
119  // may be used in case the texture's size is different for any reason
120  Point Off;
121 
122  ObjTexture() = default;
123  ObjTexture(uint32_t sprite_id, Shared::Bitmap *bmp, Engine::IDriverDependantBitmap *ddb, int x, int y, int xoff = 0, int yoff = 0)
124  : SpriteID(sprite_id), Bmp(bmp), Ddb(ddb), Pos(x, y), Off(xoff, yoff) {
125  }
126  ObjTexture(ObjTexture &&o);
127  ~ObjTexture();
128 
129  ObjTexture &operator =(ObjTexture &&o);
130 
131  // Tests if the sprite change was notified
132  inline bool IsChangeNotified() const {
133  return SpriteNotify && (*SpriteNotify != SpriteID);
134  }
135 };
136 
137 // ObjectCache stores cached object data, used to determine
138 // if active sprite / texture should be reconstructed
139 struct ObjectCache {
141  bool in_use = false; // CHECKME: possibly may be removed
142  int sppic = 0;
143  short tintr = 0, tintg = 0, tintb = 0, tintamnt = 0, tintlight = 0;
144  short lightlev = 0, zoom = 0;
145  bool mirrored = 0;
146  int x = 0, y = 0;
147 
148  ObjectCache() = default;
149  ObjectCache(int pic_, int tintr_, int tintg_, int tintb_, int tint_amnt_, int tint_light_,
150  int light_, int zoom_, bool mirror_, int posx_, int posy_)
151  : sppic(pic_), tintr(tintr_), tintg(tintg_), tintb(tintb_), tintamnt(tint_amnt_), tintlight(tint_light_)
152  , lightlev(light_), zoom(zoom_), mirrored(mirror_), x(posx_), y(posy_) {}
153 };
154 
155 struct DrawFPS {
156  Engine::IDriverDependantBitmap *ddb = nullptr;
158  int font = -1; // in case normal font changes at runtime
159 };
160 
161 // Converts AGS color index to the actual bitmap color using game's color depth
162 int MakeColor(int color_index);
163 
164 class Viewport;
165 class Camera;
166 
167 // Initializes drawing methods and optimisation
168 void init_draw_method();
169 // Initializes global game drawing resources
170 void init_game_drawdata();
171 // Initializes drawing resources upon entering new room
172 void init_room_drawdata();
173 // Disposes resources related to the current drawing methods
174 void dispose_draw_method();
175 // Disposes global game drawing resources
176 void dispose_game_drawdata();
177 // Disposes any temporary resources on leaving current room
178 void dispose_room_drawdata();
179 // Releases all the cached textures of game objects
180 void clear_drawobj_cache();
181 // Updates drawing settings depending on main viewport's size and position on screen
182 void on_mainviewport_changed();
183 // Notifies that a new room viewport was created
184 void on_roomviewport_created(int index);
185 // Notifies that a new room viewport was deleted
186 void on_roomviewport_deleted(int index);
187 // Updates drawing settings if room viewport's position or size has changed
188 void on_roomviewport_changed(Viewport *view);
189 // Detects overlapping viewports, starting from the given index in z-sorted array
190 void detect_roomviewport_overlaps(size_t z_index);
191 // Updates drawing settings if room camera's size has changed
192 void on_roomcamera_changed(Camera *cam);
193 // Marks particular object as need to update the texture
194 void mark_object_changed(int objid);
195 // TODO: write a generic drawable/objcache system where each object
196 // allocates a drawable for itself, and disposes one if being removed.
197 void reset_drawobj_for_overlay(int objnum);
198 // Marks all game objects which reference this sprite for redraw
199 void notify_sprite_changed(int sprnum, bool deleted);
200 
201 // whether there are currently remnants of a DisplaySpeech
202 void mark_screen_dirty();
203 bool is_screen_dirty();
204 
205 // marks whole screen as needing a redraw
206 void invalidate_screen();
207 // marks all the camera frame as needing a redraw
208 void invalidate_camera_frame(int index);
209 // marks certain rectangle on screen as needing a redraw
210 // in_room flag tells how to interpret the coordinates: as in-room coords or screen viewport coordinates.
211 void invalidate_rect(int x1, int y1, int x2, int y2, bool in_room);
212 
213 void mark_current_background_dirty();
214 
215 // Avoid freeing and reallocating the memory if possible
216 Shared::Bitmap *recycle_bitmap(Shared::Bitmap *bimp, int coldep, int wid, int hit, bool make_transparent = false);
217 void recycle_bitmap(std::unique_ptr<Shared::Bitmap> &bimp, int coldep, int wid, int hit, bool make_transparent = false);
218 Engine::IDriverDependantBitmap* recycle_ddb_sprite(Engine::IDriverDependantBitmap *ddb, uint32_t sprite_id, Shared::Bitmap *source, bool has_alpha = false, bool opaque = false);
219 inline Engine::IDriverDependantBitmap* recycle_ddb_bitmap(Engine::IDriverDependantBitmap *ddb, Shared::Bitmap *source, bool has_alpha = false, bool opaque = false) {
220  return recycle_ddb_sprite(ddb, UINT32_MAX, source, has_alpha, opaque);
221 }
222 // Draw everything
223 void render_graphics(Engine::IDriverDependantBitmap *extraBitmap = nullptr, int extraX = 0, int extraY = 0);
224 // Construct game scene, scheduling drawing list for the renderer
225 void construct_game_scene(bool full_redraw = false);
226 // Construct final game screen elements; updates and draws mouse cursor
227 void construct_game_screen_overlay(bool draw_mouse = true);
228 // Construct engine overlay with debugging tools (fps, console)
229 void construct_engine_overlay();
230 // Clears black game borders in legacy letterbox mode
231 void clear_letterbox_borders();
232 
233 void debug_draw_room_mask(RoomAreaMask mask);
234 void debug_draw_movelist(int charnum);
235 void update_room_debug();
236 
237 void tint_image(Shared::Bitmap *g, Shared::Bitmap *source, int red, int grn, int blu, int light_level, int luminance = 255);
238 void draw_sprite_support_alpha(Shared::Bitmap *ds, bool ds_has_alpha, int xpos, int ypos, Shared::Bitmap *image, bool src_has_alpha,
239  Shared::BlendMode blend_mode = Shared::kBlendMode_Alpha, int alpha = 0xFF);
240 void draw_sprite_slot_support_alpha(Shared::Bitmap *ds, bool ds_has_alpha, int xpos, int ypos, int src_slot,
241  Shared::BlendMode blend_mode = Shared::kBlendMode_Alpha, int alpha = 0xFF);
242 void draw_gui_sprite(Shared::Bitmap *ds, int pic, int x, int y, bool use_alpha = true, Shared::BlendMode blend_mode = Shared::kBlendMode_Alpha);
243 void draw_gui_sprite_v330(Shared::Bitmap *ds, int pic, int x, int y, bool use_alpha = true, Shared::BlendMode blend_mode = Shared::kBlendMode_Alpha);
244 void draw_gui_sprite(Shared::Bitmap *ds, bool use_alpha, int xpos, int ypos,
245  Shared::Bitmap *image, bool src_has_alpha, Shared::BlendMode blend_mode = Shared::kBlendMode_Alpha, int alpha = 0xFF);
246 
247 // Render game on screen
248 void render_to_screen();
249 // Callbacks for the graphics driver
250 void draw_game_screen_callback();
251 void GfxDriverOnInitCallback(void *data);
252 bool GfxDriverSpriteEvtCallback(int evt, int data);
253 void putpixel_compensate(Shared::Bitmap *g, int xx, int yy, int col);
254 // Create the actsps[objid] image with the object drawn correctly.
255 // Returns true if nothing at all has changed and actsps is still
256 // intact from last time; false otherwise.
257 // Hardware-accelerated do not require altering the raw bitmap itself,
258 // so they only detect whether the sprite ID itself has changed.
259 // Software renderers modify the cached bitmap whenever any visual
260 // effect changes (scaling, tint, etc).
261 // * force_software option forces HW renderers to construct the image
262 // in software mode as well.
263 bool construct_object_gfx(int objid, bool force_software);
264 bool construct_char_gfx(int charid, bool force_software);
265 // Returns a cached character image prepared for the render
266 Shared::Bitmap *get_cached_character_image(int charid);
267 // Returns a cached object image prepared for the render
268 Shared::Bitmap *get_cached_object_image(int objid);
269 // Adds a walk-behind sprite to the list for the given slot
270 // (reuses existing texture if possible)
271 void add_walkbehind_image(size_t index, Shared::Bitmap *bmp, int x, int y);
272 
273 void draw_and_invalidate_text(Shared::Bitmap *ds, int x1, int y1, int font, color_t text_color, const char *text);
274 
275 void setpal();
276 
277 // These functions are converting coordinates between data resolution and
278 // game resolution units. The first are units used by game data and script,
279 // and second define the game's screen resolution, sprite and font sizes.
280 // This conversion is done before anything else (like moving from room to
281 // viewport on screen, or scaling game further in the window by the graphic
282 // renderer).
283 int get_fixed_pixel_size(int pixels);
284 // coordinate conversion data,script ---> final game resolution
285 extern int data_to_game_coord(int coord);
286 extern void data_to_game_coords(int *x, int *y);
287 extern void data_to_game_round_up(int *x, int *y);
288 // coordinate conversion final game resolution ---> data,script
289 extern int game_to_data_coord(int coord);
290 extern void game_to_data_coords(int &x, int &y);
291 extern int game_to_data_round_up(int coord);
292 // convert contextual data coordinates to final game resolution
293 extern void ctx_data_to_game_coord(int &x, int &y, bool hires_ctx);
294 extern void ctx_data_to_game_size(int &x, int &y, bool hires_ctx);
295 extern int ctx_data_to_game_size(int size, bool hires_ctx);
296 extern int game_to_ctx_data_size(int size, bool hires_ctx);
297 // This function converts game coordinates coming from script to the actual game resolution.
298 extern void defgame_to_finalgame_coords(int &x, int &y);
299 
300 // Creates bitmap of a format compatible with the gfxdriver;
301 // if col_depth is 0, uses game's native color depth.
302 Shared::Bitmap *CreateCompatBitmap(int width, int height, int col_depth = 0);
303 // Checks if the bitmap is compatible with the gfxdriver;
304 // returns same bitmap or its copy of a compatible format.
305 Shared::Bitmap *ReplaceBitmapWithSupportedFormat(Shared::Bitmap *bitmap);
306 // Checks if the bitmap needs any kind of adjustments before it may be used
307 // in AGS sprite operations. Also handles number of certain special cases
308 // (old systems or uncommon gfx modes, and similar stuff).
309 // Original bitmap **gets deleted** if a new bitmap had to be created.
310 Shared::Bitmap *PrepareSpriteForUse(Shared::Bitmap *bitmap, bool has_alpha);
311 // Same as above, but compatible for std::shared_ptr.
312 Shared::PBitmap PrepareSpriteForUse(Shared::PBitmap bitmap, bool has_alpha);
313 // Makes a screenshot corresponding to the last screen render and returns it as a bitmap
314 // of the requested width and height and game's native color depth.
315 Shared::Bitmap *CopyScreenIntoBitmap(int width, int height, const Rect *src_rect = nullptr,
316  bool at_native_res = false, uint32_t batch_skip_filter = 0u);
317 
318 } // namespace AGS3
319 
320 #endif
Definition: achievements_tables.h:27
Definition: map.h:204
Definition: allegro_bitmap.h:44
Definition: draw.h:76
Definition: geometry.h:87
Definition: draw.h:105
Definition: ptr.h:572
Definition: draw.h:60
Definition: viewport.h:128
Definition: draw.h:139
Definition: draw.h:155
Definition: viewport.h:63
Definition: geometry.h:219
Definition: display_client.h:113
Definition: ptr.h:159
Definition: engine.h:144
Definition: ags.h:40