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-1998 PARALLAX SOFTWARE CORPORATION.  ALL RIGHTS RESERVED.
  18. */
  19.  
  20. /*
  21.  *
  22.  * Graphical routines for manipulating grs_bitmaps.
  23.  *
  24.  */
  25.  
  26. #include <algorithm>
  27. #include <stdexcept>
  28. #include <stdlib.h>
  29. #include <stdio.h>
  30. #include "u_mem.h"
  31. #include "gr.h"
  32. #include "grdef.h"
  33. #include "dxxerror.h"
  34. #if DXX_USE_OGL
  35. #include "ogl_init.h"
  36. #endif
  37. #include "bitmap.h"
  38. #include <memory>
  39.  
  40. namespace dcx {
  41.  
  42. // Allocated a bitmap and makes its data be raw_data that is already somewhere.
  43. static grs_bitmap_ptr gr_create_bitmap_raw(uint16_t w, uint16_t h, RAIIdmem<uint8_t[]> raw_data);
  44.  
  45. void gr_set_bitmap_data(grs_bitmap &bm, const uint8_t *data)
  46. {
  47. #if DXX_USE_OGL
  48.         ogl_freebmtexture(bm);
  49. #endif
  50.         bm.bm_data = data;
  51. }
  52.  
  53. grs_bitmap_ptr gr_create_bitmap(uint16_t w, uint16_t h )
  54. {
  55.         RAIIdmem<uint8_t[]> d;
  56.         MALLOC(d, unsigned char, MAX_BMP_SIZE(w, h));
  57.         return gr_create_bitmap_raw(w, h, std::move(d));
  58. }
  59.  
  60. grs_bitmap_ptr gr_create_bitmap_raw(const uint16_t w, const uint16_t h, RAIIdmem<uint8_t[]> raw_data)
  61. {
  62.         auto n = std::make_unique<grs_main_bitmap>();
  63.         gr_init_main_bitmap(*n.get(), bm_mode::linear, 0, 0, w, h, w, std::move(raw_data));
  64.         return n;
  65. }
  66.  
  67. // TODO: virtualize
  68. void gr_init_bitmap(grs_bitmap &bm, const bm_mode mode, const uint16_t x, const uint16_t y, const uint16_t w, const uint16_t h, const uint16_t bytesperline, const uint8_t *const data) noexcept
  69. {
  70.         bm.bm_x = x;
  71.         bm.bm_y = y;
  72.         bm.bm_w = w;
  73.         bm.bm_h = h;
  74.         bm.set_flags(0);
  75.         bm.set_type(mode);
  76.         bm.bm_rowsize = bytesperline;
  77.  
  78.         bm.bm_data = data;
  79. #if DXX_USE_OGL
  80.         bm.bm_parent = nullptr;
  81.         bm.gltexture = nullptr;
  82. #endif
  83. }
  84.  
  85. void gr_init_main_bitmap(grs_main_bitmap &bm, const bm_mode mode, const uint16_t x, const uint16_t y, const uint16_t w, const uint16_t h, const uint16_t bytesperline, RAIIdmem<uint8_t[]> data)
  86. {
  87.         bm.reset();
  88.         gr_init_bitmap(bm, mode, x, y, w, h, bytesperline, data.get());
  89.         data.release();
  90. }
  91.  
  92. void gr_init_bitmap_alloc(grs_main_bitmap &bm, const bm_mode mode, const uint16_t x, const uint16_t y, const uint16_t w, const uint16_t h, const uint16_t bytesperline)
  93. {
  94.         RAIIdmem<uint8_t[]> d;
  95.         MALLOC(d, unsigned char, MAX_BMP_SIZE(w, h));
  96.         gr_init_main_bitmap(bm, mode, x, y, w, h, bytesperline, std::move(d));
  97. }
  98.  
  99. grs_main_bitmap::grs_main_bitmap()
  100. {
  101.         static_cast<grs_bitmap &>(*this) = {};
  102. }
  103.  
  104. grs_subbitmap_ptr gr_create_sub_bitmap(grs_bitmap &bm, uint16_t x, uint16_t y, uint16_t w, uint16_t h)
  105. {
  106.         auto n = std::make_unique<grs_subbitmap>();
  107.         gr_init_sub_bitmap(*n.get(), bm, x, y, w, h);
  108.         return n;
  109. }
  110.  
  111. void gr_free_bitmap_data (grs_bitmap &bm) // TODO: virtulize
  112. {
  113.         if (auto &d = bm.bm_mdata)
  114.                 d_free(d);
  115. #if DXX_USE_OGL
  116.         ogl_freebmtexture(bm);
  117. #endif
  118. }
  119.  
  120. void gr_init_sub_bitmap (grs_bitmap &bm, grs_bitmap &bmParent, uint16_t x, uint16_t y, uint16_t w, uint16_t h ) // TODO: virtualize
  121. {
  122.         uint32_t subx = x + bmParent.bm_x;
  123.         uint32_t suby = y + bmParent.bm_y;
  124.         if (subx != (bm.bm_x = static_cast<uint16_t>(subx)) ||
  125.                 suby != (bm.bm_y = static_cast<uint16_t>(suby)))
  126.                 throw std::overflow_error("offset overflow");
  127.         bm.bm_w = w;
  128.         bm.bm_h = h;
  129.         bm.set_flags(bmParent.get_flags());
  130.         bm.set_type(bmParent.get_type());
  131.         bm.bm_rowsize = bmParent.bm_rowsize;
  132.  
  133. #if DXX_USE_OGL
  134.         bm.gltexture = bmParent.gltexture;
  135. #endif
  136.         bm.bm_parent = &bmParent;
  137.         bm.bm_data = &bmParent.bm_data[static_cast<uint32_t>((y*bmParent.bm_rowsize)+x)];
  138. }
  139.  
  140. void decode_data(color_palette_index *const data, uint_fast32_t num_pixels, std::array<color_palette_index, 256> &colormap, std::bitset<256> &used)
  141. {
  142.         const auto a = [&](uint8_t mapped) {
  143.                 return used[mapped] = true, colormap[mapped];
  144.         };
  145.         std::transform(data, data + num_pixels, data, a);
  146. }
  147.  
  148. static void gr_set_super_transparent(grs_bitmap &bm, bool bOpaque)
  149. {
  150.         bm.set_flag_mask(!bOpaque, BM_FLAG_SUPER_TRANSPARENT);
  151. }
  152.  
  153. void build_colormap_good(const palette_array_t &palette, std::array<color_palette_index, 256> &colormap)
  154. {
  155.         const auto a = [](const rgb_t &p) {
  156.                 return gr_find_closest_color(p.r, p.g, p.b);
  157.         };
  158.         std::transform(palette.begin(), palette.end(), colormap.begin(), a);
  159. }
  160.  
  161. void gr_remap_bitmap_good(grs_bitmap &bmp, palette_array_t &palette, uint_fast32_t transparent_color, uint_fast32_t super_transparent_color)
  162. {
  163.         std::array<color_palette_index, 256> colormap;
  164.         build_colormap_good(palette, colormap);
  165.  
  166.         if (super_transparent_color < colormap.size())
  167.                 colormap[super_transparent_color] = color_palette_index{254};
  168.  
  169.         if (transparent_color < colormap.size())
  170.                 colormap[transparent_color] = TRANSPARENCY_COLOR;
  171.  
  172.         std::bitset<256> freq{};
  173.         if (bmp.bm_w == bmp.bm_rowsize)
  174.                 decode_data(bmp.get_bitmap_data(), bmp.bm_w * bmp.bm_h, colormap, freq );
  175.         else {
  176.                 auto p = bmp.get_bitmap_data();
  177.                 for (uint_fast32_t y = bmp.bm_h; y--; p += bmp.bm_rowsize)
  178.                         decode_data(p, bmp.bm_w, colormap, freq );
  179.         }
  180.  
  181.         if (transparent_color < freq.size() && freq[transparent_color])
  182.                 gr_set_transparent(bmp, 1);
  183.  
  184.         if (super_transparent_color < freq.size() && freq[super_transparent_color])
  185.                 gr_set_super_transparent(bmp, 1);
  186. }
  187.  
  188. }
  189.