Subversion Repositories Games.Descent

Rev

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