1 /**
2 * @file bitmap_data.cc
3 * @brief Handle the bitmap
4 * @created 1996-06-29
5 * @date 2012-09-15
6 * @copyright 1991-2014 TLK Games
7 * @author Bruno Ethvignot
8 * @version $Revision: 24 $
9 */
10 /*
11 * copyright (c) 1991-2014 TLK Games all rights reserved
12 * $Id: bitmap_data.cc 24 2014-09-28 15:30:04Z bruno.ethvignot@gmail.com $
13 *
14 * TecnoballZ is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation; either version 3 of the License, or
17 * (at your option) any later version.
18 *
19 * TecnoballZ is distributed in the hope that it will be useful, but
20 * WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, write to the Free Software
26 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
27 * MA 02110-1301, USA.
28 */
29 #include <SDL/SDL_image.h>
30 #include "../include/bitmap_data.h"
31 #include "../include/handler_resources.h"
32 #include "../include/handler_display.h"
33
34 /**
35 * Create the object bitmap
36 */
bitmap_data()37 bitmap_data::bitmap_data ()
38 {
39 clear_members ();
40 }
41
42 /**
43 * Release the object bitmap
44 */
~bitmap_data()45 bitmap_data::~bitmap_data ()
46 {
47 release ();
48 }
49
50 /**
51 * Clear some members of the object
52 */
53 void
clear_members()54 bitmap_data::clear_members ()
55 {
56 surface = (SDL_Surface *) NULL;
57 pixel_data = (char *) NULL;
58 height = 0;
59 width = 0;
60 row_size = 0;
61 depth = 0;
62 bytes_size = 0;
63 }
64
65 /**
66 * Release bitmap surface or bitmap buffer
67 */
68 void
release()69 bitmap_data::release ()
70 {
71 if (surface != NULL)
72 {
73 SDL_FreeSurface (surface);
74 surface = (SDL_Surface *) NULL;
75 pixel_data = (char *) NULL;
76 }
77 else if (pixel_data != NULL)
78 {
79 delete[]pixel_data;
80 pixel_data = (char *) NULL;
81 }
82 }
83
84 /**
85 * Return width of the bitmap
86 * @return width in pixels
87 */
get_width()88 Uint32 bitmap_data::get_width ()
89 {
90 return width;
91 }
92
93 /**
94 * Return size of line in bytes
95 * @return row size in bytes
96 */
get_row_size()97 Uint32 bitmap_data::get_row_size ()
98 {
99 return row_size;
100 }
101
102 /**
103 * Return bitmap height
104 * @return the height of the bitmap in pixels
105 */
get_height()106 Uint32 bitmap_data::get_height ()
107 {
108 return height;
109 }
110
111 /**
112 * Return bitmap memory address from the corresponding coordinates
113 * @param xcoord x coordinate in the bitmap
114 * @param ycoord y coordinate in the bitmap
115 * @return a pointer to the pixel data
116 */
117 char *
get_pixel_data(Sint32 xcoord,Sint32 ycoord)118 bitmap_data::get_pixel_data (Sint32 xcoord, Sint32 ycoord)
119 {
120 return (pixel_data + ycoord * row_size + (xcoord * depth));
121 }
122
123 /**
124 * Return bitmap memory address
125 * @return a pointer to the buffer data
126 */
127 char *
get_pixel_data()128 bitmap_data::get_pixel_data ()
129 {
130 return pixel_data;
131 }
132
133 /**
134 * Return amount to add to get to the next line
135 * @param w width of source element in bytes
136 * return modulo line
137 */
get_line_modulo(Sint32 w)138 Sint32 bitmap_data::get_line_modulo (Sint32 w)
139 {
140 return (row_size - (w * depth));
141 }
142
143 /**
144 * Return bitmap memory offset from the corresponding coordinate
145 * @param xcoord x coordinate in the bitmap
146 * @param xcoord y coordinate in the bitmap
147 * @return offset to the pixel data
148 */
get_offset(Sint32 posX,Sint32 posY)149 Sint32 bitmap_data::get_offset (Sint32 posX, Sint32 posY)
150 {
151 return (posY * row_size + posX * depth);
152 }
153
154 /**
155 * Create a new SDL surface
156 * @param w width of the surface in pixels
157 * @param h height of the surface in pixels
158 */
159 void
create_surface(Uint32 w,Uint32 h)160 bitmap_data::create_surface (Uint32 w, Uint32 h)
161 {
162 Uint32 d = display->get_bits_per_pixel ();
163 dynamic_cast < surface_sdl * >(this)->create_surface (w, h, d);
164 width = w;
165 height = h;
166 depth = d / 8;
167 row_size = (Sint32) (width * depth);
168 bytes_size = height * row_size;
169 }
170
171 /**
172 * Allocate and return a copy of the current pixel data
173 * @return pointer to the new pixel data
174 */
175 char *
duplicate_pixel_data()176 bitmap_data::duplicate_pixel_data ()
177 {
178 char *pixel;
179 try
180 {
181 pixel = new char[bytes_size];
182 }
183 catch (std::bad_alloc &)
184 {
185 std::
186 cerr << "bitmap_data::duplicate_pixel_data() " <<
187 "not enough memory to allocate " <<
188 bytes_size << " bytes " << std::endl;
189 throw;
190 }
191 for (Uint32 i = 0; i < bytes_size; i++)
192 {
193 pixel[i] = pixel_data[i];
194 }
195 return pixel;
196 }
197
198 /**
199 * Enable palette of the bitmap
200 */
201 void
enable_palette()202 bitmap_data::enable_palette ()
203 {
204 display->enable_palette (palette);
205 }
206
207 /**
208 * Return palette of colors
209 * @return pointer to the palette
210 */
211 unsigned char *
get_palette()212 bitmap_data::get_palette ()
213 {
214 return palette;
215 }
216
217 /**
218 * Load a bitmap file
219 * @param fname filename specified by path
220 */
221 void
load(char * fname)222 bitmap_data::load (char *fname)
223 {
224 char *fpath = resources->locate_data_file (fname);
225 sdl_load_bmp (fpath);
226 }
227
228 /**
229 * Load a bitmap file
230 * @param ident filename specified by the ID
231 */
232 void
load(Sint32 id)233 bitmap_data::load (Sint32 id)
234 {
235 char *fpath = resources->get_full_pathname (id);
236 sdl_load_bmp (fpath);
237 }
238
239 /**
240 * Load a bitmap file
241 * @param fpath filename specified by path
242 */
243 void
sdl_load_bmp(char * fpath)244 bitmap_data::sdl_load_bmp (char *fpath)
245 {
246 release ();
247 //surface = SDL_LoadBMP (fpath);
248 surface = IMG_Load (fpath);
249 if (NULL == surface)
250 {
251 std::cerr << "(!)bitmap_data::sdl_load_bmp() "
252 << "SDL_LoadBMP return " << SDL_GetError () << std::endl;
253 throw std::runtime_error ("SDL_LoadBMP() failed!");
254 }
255 pixel_data = (char *) surface->pixels;
256 width = surface->w;
257 row_size = width;
258 height = surface->h;
259 bytes_size = height * width;
260 depth = 1;
261 bytes_per_pixel = surface->format->BytesPerPixel;
262 SDL_Color *couleurs = surface->format->palette->colors;
263 Sint32 k = 0;
264 for (Sint32 j = 0; j < surface->format->palette->ncolors; j++)
265 {
266 palette[k++] = couleurs->r;
267 palette[k++] = couleurs->g;
268 palette[k++] = couleurs->b;
269 couleurs++;
270 }
271 }
272
273 /**
274 * Copy a part of the surface in a new surface
275 * @param xcoord
276 * @param ycoord
277 * @param w width of the detination surface
278 * @param h height of the destination surface
279 */
280 bitmap_data *
cut_to_bitmap(Sint32 xcoord,Sint32 ycoord,Uint32 w,Uint32 h)281 bitmap_data::cut_to_bitmap (Sint32 xcoord, Sint32 ycoord, Uint32 w, Uint32 h)
282 {
283 bitmap_data *dest = new bitmap_data ();
284 dest->create_surface (w, h);
285 dynamic_cast < surface_sdl * >(this)->cut_to_surface (dest, xcoord, ycoord, w, h);
286 return dest;
287 }
288
289
290