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. #pragma once
  21.  
  22. #include <SDL_version.h>
  23. #if SDL_MAJOR_VERSION == 2
  24. #include <SDL_video.h>
  25. #endif
  26. #include <cstdint>
  27. #include <memory>
  28. #include <utility>
  29. #include "palette.h"
  30. #include "maths.h"
  31. #include "u_mem.h"
  32.  
  33. // some defines for transparency and blending
  34. constexpr auto TRANSPARENCY_COLOR = color_palette_index{255};            // palette entry of transparency color -- 255 on the PC
  35. #define GR_FADE_LEVELS       34u
  36. #define GR_FADE_OFF          GR_FADE_LEVELS // yes, max means OFF - don't screw that up
  37. enum class gr_blend {
  38.         normal,         // normal blending
  39.         additive_a,     // additive alpha blending
  40.         additive_c,     // additive color blending
  41. };
  42.  
  43. #define SWIDTH  (grd_curscreen->get_screen_width())
  44. #define SHEIGHT (grd_curscreen->get_screen_height())
  45.  
  46. #if defined(DXX_BUILD_DESCENT_I)
  47. namespace dsx {
  48. extern int HiresGFXAvailable;
  49. }
  50. #define HIRESMODE HiresGFXAvailable             // descent.pig either contains hires or lowres graphics, not both
  51. #elif defined(DXX_BUILD_DESCENT_II)
  52. #define HIRESMODE (SWIDTH >= 640 && SHEIGHT >= 480 && !GameArg.GfxSkipHiresGFX)
  53. #endif
  54. #define MAX_BMP_SIZE(width, height) (4 + ((width) + 2) * (height))
  55.  
  56. #define SCRNS_DIR "screenshots/"
  57.  
  58. //these are control characters that have special meaning in the font code
  59.  
  60. #define CC_COLOR        1   //next char is new foreground color
  61. #define CC_LSPACING     2   //next char specifies line spacing
  62. #define CC_UNDERLINE    3   //next char is underlined
  63.  
  64. //now have string versions of these control characters (can concat inside a string)
  65.  
  66. #define CC_COLOR_S      "\x1"   //next char is new foreground color
  67. #define CC_LSPACING_S   "\x2"   //next char specifies line spacing
  68. #define CC_UNDERLINE_S  "\x3"   //next char is underlined
  69.  
  70. enum bm_mode : uint8_t
  71. {
  72.         linear,
  73.         rgb15 = 3,      //5 bits each r,g,b stored at 16 bits
  74. #if DXX_USE_OGL
  75.         ogl = 5,
  76. #endif /* def OGL */
  77. };
  78.  
  79. #define BM_FLAG_TRANSPARENT         1
  80. #define BM_FLAG_SUPER_TRANSPARENT   2
  81. #define BM_FLAG_NO_LIGHTING         4
  82. #define BM_FLAG_RLE                 8   // A run-length encoded bitmap.
  83. #define BM_FLAG_PAGED_OUT           16  // This bitmap's data is paged out.
  84. #define BM_FLAG_RLE_BIG             32  // for bitmaps that RLE to > 255 per row (i.e. cockpits)
  85.  
  86. #ifdef __cplusplus
  87. #include "dxxsconf.h"
  88. #include "dsx-ns.h"
  89. #include <array>
  90.  
  91. struct grs_bitmap;
  92. struct grs_canvas;
  93. #define GRS_FONT_SIZE 28    // how much space it takes up on disk
  94. struct grs_point;
  95.  
  96. union screen_mode;
  97.  
  98. class grs_screen;
  99.  
  100. namespace dcx {
  101.  
  102. struct grs_main_canvas;
  103. typedef std::unique_ptr<grs_main_canvas> grs_canvas_ptr;
  104.  
  105. struct grs_subcanvas;
  106. typedef std::unique_ptr<grs_subcanvas> grs_subcanvas_ptr;
  107.  
  108. // Free the bitmap and its pixel data
  109. class grs_main_bitmap;
  110. typedef std::unique_ptr<grs_main_bitmap> grs_bitmap_ptr;
  111.  
  112. struct grs_font;
  113.  
  114. #if SDL_MAJOR_VERSION == 1
  115. uint_fast32_t gr_list_modes(std::array<screen_mode, 50> &modes);
  116. #elif SDL_MAJOR_VERSION == 2
  117. extern SDL_Window *g_pRebirthSDLMainWindow;
  118. #endif
  119.  
  120. }
  121.  
  122. #ifdef dsx
  123. namespace dsx {
  124. int gr_set_mode(screen_mode mode);
  125. void gr_set_mode_from_window_size();
  126.  
  127. int gr_init();
  128. #if DXX_USE_OGL
  129. void gr_set_attributes();
  130. #endif
  131. void gr_close();
  132. }
  133. #endif
  134.  
  135. namespace dcx {
  136.  
  137. grs_canvas_ptr gr_create_canvas(uint16_t w, uint16_t h);
  138.  
  139. grs_subcanvas_ptr gr_create_sub_canvas(grs_canvas &canv,uint16_t x,uint16_t y,uint16_t w, uint16_t h);
  140.  
  141. // Initialize the specified canvas. the raw pixel data buffer is passed as
  142. // a parameter. no memory allocation is performed.
  143.  
  144. void gr_init_canvas(grs_canvas &canv,unsigned char *pixdata, bm_mode pixtype, uint16_t w, uint16_t h);
  145.  
  146. // Initialize the specified sub canvas. no memory allocation is performed.
  147.  
  148. void gr_init_sub_canvas(grs_canvas &n, grs_canvas &src, uint16_t x, uint16_t y, uint16_t w, uint16_t h);
  149.  
  150. // Clear the current canvas to the specified color
  151. void gr_clear_canvas(grs_canvas &, color_t color);
  152.  
  153. //=========================================================================
  154. // Bitmap functions:
  155.  
  156. // these are the two workhorses, the others just use these
  157. void gr_init_bitmap(grs_bitmap &bm, bm_mode mode, uint16_t x, uint16_t y, uint16_t w, uint16_t h, uint16_t bytesperline, const uint8_t *data) noexcept;
  158. void gr_init_main_bitmap(grs_main_bitmap &bm, bm_mode mode, uint16_t x, uint16_t y, uint16_t w, uint16_t h, uint16_t bytesperline, RAIIdmem<uint8_t[]> data);
  159. void gr_init_sub_bitmap (grs_bitmap &bm, grs_bitmap &bmParent, uint16_t x, uint16_t y, uint16_t w, uint16_t h);
  160.  
  161. void gr_init_bitmap_alloc(grs_main_bitmap &bm, bm_mode mode, uint16_t x, uint16_t y, uint16_t w, uint16_t h, uint16_t bytesperline);
  162. void gr_free_bitmap_data(grs_bitmap &bm);
  163.  
  164. // Allocate a bitmap and its pixel data buffer.
  165. grs_bitmap_ptr gr_create_bitmap(uint16_t w,uint16_t h);
  166.  
  167. // Free the bitmap, but not the pixel data buffer
  168. class grs_subbitmap;
  169. typedef std::unique_ptr<grs_subbitmap> grs_subbitmap_ptr;
  170.  
  171. // Creates a bitmap which is part of another bitmap
  172. grs_subbitmap_ptr gr_create_sub_bitmap(grs_bitmap &bm, uint16_t x, uint16_t y, uint16_t w, uint16_t h);
  173.  
  174. // Free the bitmap's data
  175.  
  176. #if !DXX_USE_OGL
  177. void gr_bm_ubitblt(grs_canvas &dest, unsigned w, unsigned h, int dx, int dy, int sx, int sy, const grs_bitmap &src);
  178. void gr_bm_ubitbltm(grs_canvas &dest, unsigned w, unsigned h, unsigned dx, unsigned dy, unsigned sx, unsigned sy, const grs_bitmap &src);
  179. #define gr_bm_pixel(C,B,X,Y,C2) gr_bm_pixel(B,X,Y,C2)
  180. #define gr_settransblend(A,B,C) gr_settransblend(A,B)
  181. #endif
  182. void gr_bm_pixel(grs_canvas &, grs_bitmap &bm, uint_fast32_t x, uint_fast32_t y, uint8_t color);
  183. void gr_set_bitmap_data(grs_bitmap &bm, const uint8_t *data);
  184. }
  185.  
  186. #ifdef dsx
  187. namespace dsx {
  188.  
  189. //=========================================================================
  190. // Color functions:
  191.  
  192. // When this function is called, the guns are set to gr_palette, and
  193. // the palette stays the same until gr_close is called
  194.  
  195. void gr_use_palette_table(const char * filename);
  196.  
  197. }
  198. #endif
  199.  
  200. //=========================================================================
  201. // Drawing functions:
  202.  
  203. namespace dcx {
  204.  
  205. // Sets transparency and blending function
  206. void gr_settransblend(grs_canvas &, int fade_level, gr_blend blend_func);
  207.  
  208. // Draws a point into the current canvas in the current color and drawmode.
  209. void gr_pixel(grs_bitmap &, unsigned x, unsigned y, color_palette_index color);
  210. void gr_upixel(grs_bitmap &, unsigned x, unsigned y, color_palette_index color);
  211.  
  212. // Gets a pixel;
  213. color_palette_index gr_gpixel(const grs_bitmap &bitmap, unsigned x, unsigned y);
  214. color_palette_index gr_ugpixel(const grs_bitmap &bitmap, int x, int y);
  215.  
  216. // Draws a line into the current canvas in the current color and drawmode.
  217. void gr_line(grs_canvas &, fix x0,fix y0,fix x1,fix y1, color_palette_index color);
  218. void gr_uline(grs_canvas &canvas, fix x0,fix y0,fix x1,fix y1, color_palette_index color);
  219.  
  220. // Draw the bitmap into the current canvas at the specified location.
  221. void gr_bitmap(grs_canvas &, unsigned x,unsigned y,grs_bitmap &bm);
  222. void gr_ubitmap(grs_canvas &, grs_bitmap &bm);
  223. void show_fullscr(grs_canvas &, grs_bitmap &bm);
  224.  
  225. // Find transparent area in bitmap
  226. void gr_bitblt_find_transparent_area(const grs_bitmap &bm, unsigned &minx, unsigned &miny, unsigned &maxx, unsigned &maxy);
  227.  
  228. // bitmap function with transparency
  229. #if !DXX_USE_OGL
  230. void gr_bitmapm(grs_canvas &, unsigned x, unsigned y, const grs_bitmap &bm);
  231. void gr_ubitmapm(grs_canvas &, unsigned x, unsigned y, grs_bitmap &bm);
  232. #endif
  233.  
  234. // Draw a rectangle into the current canvas.
  235. void gr_rect(grs_canvas &, int left,int top,int right,int bot, color_palette_index color);
  236. void gr_urect(grs_canvas &, int left,int top,int right,int bot, color_palette_index color);
  237.  
  238. // Draw a filled circle
  239. int gr_disk(grs_canvas &, fix x,fix y,fix r, color_palette_index color);
  240.  
  241. // Draw an outline circle
  242. int gr_ucircle(grs_canvas &, fix x,fix y,fix r, color_palette_index color);
  243.  
  244. // Draw an unfilled rectangle into the current canvas
  245. #if DXX_USE_EDITOR
  246. void gr_box(grs_canvas &, uint_fast32_t left,uint_fast32_t top,uint_fast32_t right,uint_fast32_t bot, color_palette_index color);
  247. #endif
  248. void gr_ubox(grs_canvas &, int left,int top,int right,int bot, color_palette_index color);
  249.  
  250. void gr_scanline(grs_canvas &canvas, int x1, int x2, unsigned y, color_palette_index color);
  251. #if !DXX_USE_OGL
  252. void gr_uscanline(grs_canvas &canvas, unsigned x1, unsigned x2, unsigned y, color_palette_index color);
  253. #endif
  254. void gr_close_font(std::unique_ptr<grs_font> font);
  255.  
  256. struct font_delete;
  257. typedef std::unique_ptr<grs_font, font_delete> grs_font_ptr;
  258.  
  259. // Reads in a font file... current font set to this one.
  260. grs_font_ptr gr_init_font(grs_canvas &canvas, const char * fontfile);
  261.  
  262. }
  263.  
  264. #ifdef dsx
  265. namespace dsx {
  266.  
  267. #if defined(DXX_BUILD_DESCENT_I)
  268. #define DXX_SDL_WINDOW_CAPTION  "Descent"
  269. #define DXX_SDL_WINDOW_ICON_BITMAP      "d1x-rebirth.bmp"
  270. #elif defined(DXX_BUILD_DESCENT_II)
  271. #define DXX_SDL_WINDOW_CAPTION  "Descent II"
  272. #define DXX_SDL_WINDOW_ICON_BITMAP      "d2x-rebirth.bmp"
  273. void gr_copy_palette(palette_array_t &gr_palette, const palette_array_t &pal);
  274. #endif
  275.  
  276. }
  277. #endif
  278.  
  279. // Writes a string using current font. Returns the next column after last char.
  280. namespace dcx {
  281.  
  282. //remap (by re-reading) all the color fonts
  283. void gr_remap_color_fonts();
  284. void gr_set_curfont(grs_canvas &, const grs_font *);
  285. void gr_string(grs_canvas &, const grs_font &, int x, int y, const char *s, int w, int h);
  286. void gr_string(grs_canvas &, const grs_font &, int x, int y, const char *s);
  287. void gr_ustring(grs_canvas &, const grs_font &, int x, int y, const char *s);
  288. template <void (&)(grs_canvas &, const grs_font &, int, int, const char *)>
  289. void gr_printt(grs_canvas &, const grs_font &, int x, int y, const char *format, ...) __attribute_format_printf(5, 6);
  290. #define gr_printfs(...) gr_printt<gr_string>(__VA_ARGS__)
  291. #define gr_printfus(...)        gr_printt<gr_ustring>(__VA_ARGS__)
  292. #define gr_printf(A1,A2,A3,A4,F,...)    dxx_call_printf_checked(gr_printfs,gr_string,(A1,A2,A3,A4),(F),##__VA_ARGS__)
  293. #define gr_uprintf(A1,A2,A3,A4,F,...)   dxx_call_printf_checked(gr_printfus,gr_ustring,(A1,A2,A3,A4),(F),##__VA_ARGS__)
  294. std::pair<const char *, unsigned> gr_get_string_wrap(const grs_font &, const char *s, unsigned limit);
  295. int gr_get_string_height(const grs_font &cv_font, unsigned lines);
  296. void gr_get_string_size(const grs_font &, const char *s, int *string_width, int *string_height, int *average_width);
  297. void gr_get_string_size(const grs_font &, const char *s, int *string_width, int *string_height, int *average_width, const unsigned max_chars_per_line);
  298.  
  299. // From scale.c
  300. void scale_bitmap(const grs_bitmap &bp, const std::array<grs_point, 3> &vertbuf, int orientation, grs_bitmap &);
  301.  
  302. //===========================================================================
  303. // Global variables
  304. extern grs_canvas *grd_curcanv;             //active canvas
  305. extern std::unique_ptr<grs_screen> grd_curscreen;           //active screen
  306.  
  307. /* Define `DXX_DEBUG_CURRENT_CANVAS_ORIGIN` to a positive integer N to
  308.  * save __FILE__+__LINE__ of the N most recent callers.  If
  309.  * `DXX_DEBUG_CURRENT_CANVAS_ORIGIN` is not a positive integer, the
  310.  * file+line is not passed to the canvas update functions.
  311.  *
  312.  * Use this to trace which functions update the global canvas pointer
  313.  * without requiring a debugger trap on every update.
  314.  */
  315. #define DXX_DEBUG_CURRENT_CANVAS_ORIGIN 0
  316.  
  317. #if DXX_DEBUG_CURRENT_CANVAS_ORIGIN > 0
  318. #define DXX_DEBUG_CURRENT_CANVAS_FILE_LINE_COMMA_N_DECL_VARS    const char *const file, const unsigned line
  319. #define DXX_DEBUG_CURRENT_CANVAS_FILE_LINE_COMMA_L_DECL_VARS    , DXX_DEBUG_CURRENT_CANVAS_FILE_LINE_COMMA_N_DECL_VARS
  320. #define DXX_DEBUG_CURRENT_CANVAS_FILE_LINE_COMMA_N_PASS_VARS    file, line
  321. #define DXX_DEBUG_CURRENT_CANVAS_FILE_LINE_COMMA_L_PASS_VARS    , DXX_DEBUG_CURRENT_CANVAS_FILE_LINE_COMMA_N_PASS_VARS
  322. #define gr_set_default_canvas() gr_set_default_canvas(__FILE__, __LINE__)
  323. #define gr_set_current_canvas(C)        gr_set_current_canvas(C, __FILE__, __LINE__)
  324. #else
  325. #define DXX_DEBUG_CURRENT_CANVAS_FILE_LINE_COMMA_N_DECL_VARS
  326. #define DXX_DEBUG_CURRENT_CANVAS_FILE_LINE_COMMA_L_DECL_VARS
  327. #define DXX_DEBUG_CURRENT_CANVAS_FILE_LINE_COMMA_N_PASS_VARS
  328. #define DXX_DEBUG_CURRENT_CANVAS_FILE_LINE_COMMA_L_PASS_VARS
  329. #endif
  330. void (gr_set_default_canvas)(DXX_DEBUG_CURRENT_CANVAS_FILE_LINE_COMMA_N_DECL_VARS);
  331. void (gr_set_current_canvas)(grs_canvas & DXX_DEBUG_CURRENT_CANVAS_FILE_LINE_COMMA_L_DECL_VARS);
  332. void (gr_set_current_canvas)(std::nullptr_t DXX_DEBUG_CURRENT_CANVAS_FILE_LINE_COMMA_L_DECL_VARS) = delete;
  333. void gr_set_current_canvas2(grs_canvas * DXX_DEBUG_CURRENT_CANVAS_FILE_LINE_COMMA_L_DECL_VARS);
  334.  
  335. static inline void gr_set_current_canvas_inline(grs_canvas *const canv DXX_DEBUG_CURRENT_CANVAS_FILE_LINE_COMMA_L_DECL_VARS)
  336. {
  337.         if (canv)
  338.                 (gr_set_current_canvas)(*canv DXX_DEBUG_CURRENT_CANVAS_FILE_LINE_COMMA_L_PASS_VARS);
  339.         else
  340.                 (gr_set_default_canvas)(DXX_DEBUG_CURRENT_CANVAS_FILE_LINE_COMMA_N_PASS_VARS);
  341. }
  342.  
  343. static inline void (gr_set_current_canvas)(grs_canvas *const canv DXX_DEBUG_CURRENT_CANVAS_FILE_LINE_COMMA_L_DECL_VARS)
  344. {
  345. #ifdef DXX_HAVE_BUILTIN_CONSTANT_P
  346.         if (dxx_builtin_constant_p(!canv))
  347.                 gr_set_current_canvas_inline(canv DXX_DEBUG_CURRENT_CANVAS_FILE_LINE_COMMA_L_PASS_VARS);
  348.         else
  349. #endif
  350.                 gr_set_current_canvas2(canv DXX_DEBUG_CURRENT_CANVAS_FILE_LINE_COMMA_L_PASS_VARS);
  351. }
  352.  
  353. //flags for fonts
  354. #define FT_COLOR        1
  355. #define FT_PROPORTIONAL 2
  356. #define FT_KERNED       4
  357.  
  358. extern palette_array_t gr_palette;
  359. using gft_array1 = std::array<std::array<color_t, 256>, GR_FADE_LEVELS>;
  360. extern gft_array1 gr_fade_table;
  361. }
  362.  
  363. extern uint16_t gr_palette_selector;
  364. extern uint16_t gr_inverse_table_selector;
  365. extern uint16_t gr_fade_table_selector;
  366.  
  367. // Remaps a bitmap into the current palette. If transparent_color is
  368. // between 0 and 255 then all occurances of that color are mapped to
  369. // whatever color the 2d uses for transparency. This is normally used
  370. // right after a call to iff_read_bitmap like this:
  371. //              iff_error = iff_read_bitmap(filename,new,bm_mode::linear,newpal);
  372. //              if (iff_error != IFF_NO_ERROR) Error("Can't load IFF file <%s>, error=%d",filename,iff_error);
  373. //              if (iff_has_transparency)
  374. //                      gr_remap_bitmap(new, newpal, iff_transparent_color);
  375. //              else
  376. //                      gr_remap_bitmap(new, newpal, -1);
  377.  
  378. // Same as above, but searches using gr_find_closest_color which uses
  379. // 18-bit accurracy instead of 15bit when translating colors.
  380. namespace dcx {
  381. void gr_remap_bitmap_good(grs_bitmap &bmp, palette_array_t &palette, uint_fast32_t transparent_color, uint_fast32_t super_transparent_color);
  382.  
  383. void gr_palette_step_up(int r, int g, int b);
  384.  
  385. #define BM_RGB(r,g,b) ((((r)&31)<<10) | (((g)&31)<<5) | ((b)&31))
  386. #define BM_XRGB(r,g,b) gr_find_closest_color((r)*2,(g)*2,(b)*2)
  387.  
  388. // Given: r,g,b, each in range of 0-63, return the color index that
  389. // best matches the input.
  390. color_palette_index gr_find_closest_color(int r, int g, int b);
  391. color_palette_index gr_find_closest_color_15bpp(int rgb);
  392. void gr_flip();
  393.  
  394. /*
  395.  * must return 0 if windowed, 1 if fullscreen
  396.  */
  397. int gr_check_fullscreen();
  398.  
  399. /*
  400.  * returns state after toggling (ie, same as if you had called
  401.  * check_fullscreen immediatly after)
  402.  */
  403. void gr_toggle_fullscreen();
  404.  
  405. void ogl_do_palfx();
  406. void ogl_init_pixel_buffers(unsigned w, unsigned h);
  407. void ogl_close_pixel_buffers();
  408. }
  409. void ogl_cache_polymodel_textures(unsigned model_num);
  410.  
  411. #endif
  412.