Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
1 | pmbaty | 1 | /* |
2 | * Portions of this file are copyright Rebirth contributors and licensed as |
||
3 | * described in COPYING.txt. |
||
4 | * Portions of this file are copyright Parallax Software and licensed |
||
5 | * according to the Parallax license below. |
||
6 | * See COPYING.txt for license details. |
||
7 | |||
8 | THE COMPUTER CODE CONTAINED HEREIN IS THE SOLE PROPERTY OF PARALLAX |
||
9 | SOFTWARE CORPORATION ("PARALLAX"). PARALLAX, IN DISTRIBUTING THE CODE TO |
||
10 | END-USERS, AND SUBJECT TO ALL OF THE TERMS AND CONDITIONS HEREIN, GRANTS A |
||
11 | ROYALTY-FREE, PERPETUAL LICENSE TO SUCH END-USERS FOR USE BY SUCH END-USERS |
||
12 | IN USING, DISPLAYING, AND CREATING DERIVATIVE WORKS THEREOF, SO LONG AS |
||
13 | SUCH USE, DISPLAY OR CREATION IS FOR NON-COMMERCIAL, ROYALTY OR REVENUE |
||
14 | FREE PURPOSES. IN NO EVENT SHALL THE END-USER USE THE COMPUTER CODE |
||
15 | CONTAINED HEREIN FOR REVENUE-BEARING PURPOSES. THE END-USER UNDERSTANDS |
||
16 | AND AGREES TO THE TERMS HEREIN AND ACCEPTS THE SAME BY USE OF THIS FILE. |
||
17 | COPYRIGHT 1993-1999 PARALLAX SOFTWARE CORPORATION. ALL RIGHTS RESERVED. |
||
18 | */ |
||
19 | |||
20 | /* |
||
21 | * |
||
22 | * Definitions for graphics lib. |
||
23 | * |
||
24 | */ |
||
25 | |||
26 | #pragma once |
||
27 | |||
28 | #include <cassert> |
||
29 | #include "fwd-gr.h" |
||
30 | #include "pstypes.h" |
||
31 | #include "maths.h" |
||
32 | #include "palette.h" |
||
33 | #include "dxxsconf.h" |
||
34 | #include "dsx-ns.h" |
||
35 | #include "fmtcheck.h" |
||
36 | #include "pack.h" |
||
37 | #include <array> |
||
38 | |||
39 | struct grs_point |
||
40 | { |
||
41 | fix x,y; |
||
42 | }; |
||
43 | |||
44 | struct grs_bitmap : prohibit_void_ptr<grs_bitmap> |
||
45 | { |
||
46 | uint16_t bm_x,bm_y; // Offset from parent's origin |
||
47 | uint16_t bm_w,bm_h; // width,height |
||
48 | private: |
||
49 | uint8_t bm_type; |
||
50 | uint8_t bm_flags; |
||
51 | public: |
||
52 | uint8_t get_type() const |
||
53 | { |
||
54 | return bm_type; |
||
55 | } |
||
56 | void set_type(uint8_t t) |
||
57 | { |
||
58 | bm_type = t; |
||
59 | } |
||
60 | uint8_t get_flags() const |
||
61 | { |
||
62 | return bm_flags; |
||
63 | } |
||
64 | uint8_t get_flag_mask(const uint8_t mask) const |
||
65 | { |
||
66 | return get_flags() & mask; |
||
67 | } |
||
68 | void set_flags(const uint8_t f) |
||
69 | { |
||
70 | bm_flags = f; |
||
71 | } |
||
72 | void clear_flags() |
||
73 | { |
||
74 | set_flags(0); |
||
75 | } |
||
76 | void set_flag_mask(const bool set, const uint8_t mask) |
||
77 | { |
||
78 | const auto f = get_flags(); |
||
79 | set_flags(set ? f | mask : f & ~mask); |
||
80 | } |
||
81 | void add_flags(const uint8_t f) |
||
82 | { |
||
83 | bm_flags |= f; |
||
84 | } |
||
85 | // bit 1 on means it has supertransparency |
||
86 | // bit 2 on means it doesn't get passed through lighting. |
||
87 | short bm_rowsize; // unsigned char offset to next row |
||
88 | std::array<fix, 3> avg_color_rgb; // same as above but real rgb value to be used to textured objects that should emit light |
||
89 | union { |
||
90 | const color_palette_index *bm_data; // ptr to pixel data... |
||
91 | // Linear = *parent+(rowsize*y+x) |
||
92 | // ModeX = *parent+(rowsize*y+x/4) |
||
93 | // SVGA = *parent+(rowsize*y+x) |
||
94 | color_palette_index *bm_mdata; |
||
95 | }; |
||
96 | const color_palette_index *get_bitmap_data() const { return bm_data; } |
||
97 | color_palette_index *get_bitmap_data() { return bm_mdata; } |
||
98 | struct grs_bitmap *bm_parent; |
||
99 | #if DXX_USE_OGL |
||
100 | struct ogl_texture *gltexture; |
||
101 | #else |
||
102 | uint8_t avg_color; // Average color of all pixels in texture map. |
||
103 | #endif /* def OGL */ |
||
104 | }; |
||
105 | |||
106 | struct grs_canvas : prohibit_void_ptr<grs_canvas> |
||
107 | { |
||
108 | ~grs_canvas() |
||
109 | { |
||
110 | /* `grd_curcanv` points to the currently active canvas. If it |
||
111 | * points to `this` when the destructor runs, then any further |
||
112 | * attempts to use the referenced canvas will access an |
||
113 | * out-of-scope variable, leading to undefined behavior. Assert |
||
114 | * that `grd_curcanv` does not point to the expiring variable so |
||
115 | * that potential misuses are detected before they manifest as |
||
116 | * undefined behavior. |
||
117 | * |
||
118 | * If you get an assertion failure here, enable |
||
119 | * `DXX_DEBUG_CURRENT_CANVAS_ORIGIN` to trace where the canvas |
||
120 | * was most recently set. |
||
121 | * |
||
122 | * Eventually, `grd_curcanv` will be removed and this test will |
||
123 | * become obsolete. |
||
124 | */ |
||
125 | assert(this != grd_curcanv); |
||
126 | /* If the canvas is reset before next use, then no crash. |
||
127 | * If the canvas is not reset, then crash instead of accessing |
||
128 | * freed memory. |
||
129 | */ |
||
130 | if (grd_curcanv == this) |
||
131 | grd_curcanv = nullptr; |
||
132 | } |
||
133 | grs_bitmap cv_bitmap; // the bitmap for this canvas |
||
134 | const grs_font * cv_font; // the currently selected font |
||
135 | short cv_font_fg_color; // current font foreground color (-1==Invisible) |
||
136 | short cv_font_bg_color; // current font background color (-1==Invisible) |
||
137 | unsigned cv_fade_level; // transparency level |
||
138 | }; |
||
139 | |||
140 | |||
141 | //========================================================================= |
||
142 | // System functions: |
||
143 | // setup and set mode. this creates a grs_screen structure and sets |
||
144 | // grd_curscreen to point to it. grs_curcanv points to this screen's |
||
145 | // canvas. Saves the current VGA state and screen mode. |
||
146 | |||
147 | #ifdef __cplusplus |
||
148 | union screen_mode |
||
149 | { |
||
150 | private: |
||
151 | uint32_t wh; |
||
152 | public: |
||
153 | struct { |
||
154 | uint16_t width, height; |
||
155 | }; |
||
156 | bool operator==(const screen_mode &rhs) |
||
157 | { |
||
158 | return wh == rhs.wh; |
||
159 | } |
||
160 | bool operator!=(const screen_mode &rhs) |
||
161 | { |
||
162 | return !(*this == rhs); |
||
163 | } |
||
164 | screen_mode() = default; |
||
165 | constexpr screen_mode(uint16_t &&w, uint16_t &&h) : |
||
166 | width(w), height(h) |
||
167 | { |
||
168 | } |
||
169 | }; |
||
170 | |||
171 | static inline uint16_t SM_W(const screen_mode &s) |
||
172 | { |
||
173 | return s.width; |
||
174 | } |
||
175 | |||
176 | static inline uint16_t SM_H(const screen_mode &s) |
||
177 | { |
||
178 | return s.height; |
||
179 | } |
||
180 | |||
181 | class grs_screen : prohibit_void_ptr<grs_screen> |
||
182 | { // This is a video screen |
||
183 | screen_mode sc_mode; |
||
184 | public: |
||
185 | grs_canvas sc_canvas; // Represents the entire screen |
||
186 | fix sc_aspect; //aspect ratio (w/h) for this screen |
||
187 | uint16_t get_screen_width() const |
||
188 | { |
||
189 | return SM_W(sc_mode); |
||
190 | } |
||
191 | uint16_t get_screen_height() const |
||
192 | { |
||
193 | return SM_H(sc_mode); |
||
194 | } |
||
195 | screen_mode get_screen_mode() const |
||
196 | { |
||
197 | return sc_mode; |
||
198 | } |
||
199 | void set_screen_width_height(uint16_t w, uint16_t h) |
||
200 | { |
||
201 | sc_mode.width = w; |
||
202 | sc_mode.height = h; |
||
203 | } |
||
204 | }; |
||
205 | |||
206 | //========================================================================= |
||
207 | // Canvas functions: |
||
208 | |||
209 | // Makes a new canvas. allocates memory for the canvas and its bitmap, |
||
210 | // including the raw pixel buffer. |
||
211 | |||
212 | namespace dcx { |
||
213 | |||
214 | struct grs_main_canvas : grs_canvas |
||
215 | { |
||
216 | ~grs_main_canvas(); |
||
217 | }; |
||
218 | |||
219 | // Creates a canvas that is part of another canvas. this can be used to make |
||
220 | // a window on the screen. the canvas structure is malloc'd; the address of |
||
221 | // the raw pixel data is inherited from the parent canvas. |
||
222 | |||
223 | struct grs_subcanvas : grs_canvas {}; |
||
224 | |||
225 | // Free the bitmap and its pixel data |
||
226 | class grs_main_bitmap : public grs_bitmap |
||
227 | { |
||
228 | public: |
||
229 | grs_main_bitmap(); |
||
230 | grs_main_bitmap(const grs_main_bitmap &) = delete; |
||
231 | grs_main_bitmap &operator=(const grs_main_bitmap &) = delete; |
||
232 | grs_main_bitmap(grs_main_bitmap &&r) : |
||
233 | grs_bitmap(std::move(static_cast<grs_bitmap &>(r))) |
||
234 | { |
||
235 | r.bm_data = nullptr; |
||
236 | #if DXX_USE_OGL |
||
237 | r.gltexture = nullptr; |
||
238 | #endif |
||
239 | } |
||
240 | grs_main_bitmap &operator=(grs_main_bitmap &&r) |
||
241 | { |
||
242 | if (this == &r) |
||
243 | return *this; |
||
244 | reset(); |
||
245 | grs_bitmap::operator=(std::move(static_cast<grs_bitmap &>(r))); |
||
246 | r.bm_data = nullptr; |
||
247 | #if DXX_USE_OGL |
||
248 | r.gltexture = nullptr; |
||
249 | #endif |
||
250 | return *this; |
||
251 | } |
||
252 | ~grs_main_bitmap() |
||
253 | { |
||
254 | reset(); |
||
255 | } |
||
256 | void reset() |
||
257 | { |
||
258 | gr_free_bitmap_data(*this); |
||
259 | } |
||
260 | }; |
||
261 | |||
262 | // Free the bitmap, but not the pixel data buffer |
||
263 | class grs_subbitmap : public grs_bitmap |
||
264 | { |
||
265 | }; |
||
266 | |||
267 | //font structure |
||
268 | struct grs_font : public prohibit_void_ptr<grs_font> |
||
269 | { |
||
270 | int16_t ft_w; // Width in pixels |
||
271 | int16_t ft_h; // Height in pixels |
||
272 | int16_t ft_flags; // Proportional? |
||
273 | int16_t ft_baseline; // |
||
274 | uint8_t ft_minchar; // First char defined by this font |
||
275 | uint8_t ft_maxchar; // Last char defined by this font |
||
276 | std::array<char, 13> ft_filename; |
||
277 | const uint8_t *ft_data = nullptr; // Ptr to raw data. |
||
278 | const uint8_t *const *ft_chars = nullptr; // Ptrs to data for each char (required for prop font) |
||
279 | const int16_t *ft_widths = nullptr; // Array of widths (required for prop font) |
||
280 | const uint8_t *ft_kerndata = nullptr; // Array of kerning triplet data |
||
281 | std::unique_ptr<uint8_t[]> ft_allocdata; |
||
282 | #if DXX_USE_OGL |
||
283 | // These fields do not participate in disk i/o! |
||
284 | std::unique_ptr<grs_bitmap[]> ft_bitmaps; |
||
285 | grs_main_bitmap ft_parent_bitmap; |
||
286 | #endif /* def OGL */ |
||
287 | }; |
||
288 | |||
289 | } |
||
290 | |||
291 | static inline void gr_set_bitmap_flags(grs_bitmap &bm, uint8_t flags) |
||
292 | { |
||
293 | bm.set_flags(flags); |
||
294 | } |
||
295 | |||
296 | static inline void gr_set_transparent(grs_bitmap &bm, bool bTransparent) |
||
297 | { |
||
298 | bm.set_flag_mask(bTransparent, BM_FLAG_TRANSPARENT); |
||
299 | } |
||
300 | |||
301 | namespace dcx { |
||
302 | |||
303 | static inline void gr_set_font_fg_color(grs_canvas &canvas, int fg_color) |
||
304 | { |
||
305 | canvas.cv_font_fg_color = fg_color; |
||
306 | } |
||
307 | |||
308 | static inline void gr_set_font_fg_color(grs_canvas &canvas, color_palette_index fg_color) |
||
309 | { |
||
310 | canvas.cv_font_fg_color = static_cast<int>(fg_color); |
||
311 | } |
||
312 | |||
313 | static inline void gr_set_font_bg_color(grs_canvas &canvas, int bg_color) |
||
314 | { |
||
315 | canvas.cv_font_bg_color = bg_color; |
||
316 | } |
||
317 | |||
318 | static inline void gr_set_font_bg_color(grs_canvas &canvas, color_palette_index bg_color) |
||
319 | { |
||
320 | canvas.cv_font_bg_color = static_cast<int>(bg_color); |
||
321 | } |
||
322 | |||
323 | #define gr_set_fontcolor(C,F,B) \ |
||
324 | ( DXX_BEGIN_COMPOUND_STATEMENT { \ |
||
325 | auto &gr_set_fontcolor = C; \ |
||
326 | gr_set_font_fg_color(gr_set_fontcolor, F); \ |
||
327 | gr_set_font_bg_color(gr_set_fontcolor, B); \ |
||
328 | } DXX_END_COMPOUND_STATEMENT ) |
||
329 | |||
330 | struct font_delete |
||
331 | { |
||
332 | void operator()(grs_font *p) const |
||
333 | { |
||
334 | gr_close_font(std::unique_ptr<grs_font>(p)); |
||
335 | } |
||
336 | }; |
||
337 | } |
||
338 | |||
339 | // Writes a string using current font. Returns the next column after last char. |
||
340 | static inline void gr_set_curfont(grs_canvas &canvas, const grs_font_ptr &p) |
||
341 | { |
||
342 | gr_set_curfont(canvas, p.get()); |
||
343 | } |
||
344 | |||
345 | static inline void (gr_set_current_canvas)(grs_canvas_ptr &canv DXX_DEBUG_CURRENT_CANVAS_FILE_LINE_COMMA_L_DECL_VARS) |
||
346 | { |
||
347 | (gr_set_current_canvas)(canv.get() DXX_DEBUG_CURRENT_CANVAS_FILE_LINE_COMMA_L_PASS_VARS); |
||
348 | } |
||
349 | |||
350 | static inline void (gr_set_current_canvas)(grs_subcanvas_ptr &canv DXX_DEBUG_CURRENT_CANVAS_FILE_LINE_COMMA_L_DECL_VARS) |
||
351 | { |
||
352 | (gr_set_current_canvas)(canv.get() DXX_DEBUG_CURRENT_CANVAS_FILE_LINE_COMMA_L_PASS_VARS); |
||
353 | } |
||
354 | |||
355 | #endif |