Subversion Repositories Games.Descent

Rev

Blame | Last modification | View Log | Download | RSS feed

  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
  356.