1 // Shape class implementation file
2 // Author: M.D.Snellgrove
3 // Date: 13/2/2001
4 // History: Original Version 13/2/2001
5 // Collision added 27/1/2002
6
7 // Changes by M Harman for Windows version, June 2003:
8 // Changes for graphics related stuff.
9
10 // Changes by M Snellgrove 7/7/2003
11 // Bugfix in screengrab constructor
12
13 // Changes by M Snellgrove 10/7/2003
14 // Filename bugfix in readfile, writefile
15 // Palette bugfix in grab, copy constructor, assigment=
16 // Palette specification overloaded in read, readfile
17
18 #include "shape.h"
19
20 const int BYTESPERPIXEL = 1;
21
22 // Default Constructor
23
shape()24 shape :: shape(){
25 surface = NULL;
26 width = 0;
27 height = 0;
28 buffer = 0;
29 }
30
31 // Screengrab Constructor
32
shape(SDL_Surface * source,int x,int y,int w,int h)33 shape :: shape(SDL_Surface *source, int x, int y, int w, int h){
34 width = w;
35 height = h;
36 buffer = new char[w * h * BYTESPERPIXEL];
37 char *src_pixels = (char *)source->pixels;
38 for(int i=x;i<x+w;i++){
39 for(int j=y;j<y+h;j++){
40 buffer[ (j-y) * w + (i-x) ] = src_pixels[ j * source->pitch + i ];
41 }
42 }
43 surface = SDL_CreateRGBSurfaceFrom(buffer, width, height, 8 * BYTESPERPIXEL,
44 width * BYTESPERPIXEL, 0, 0, 0, 0);
45 for (int c=0;c<256;c++){
46 Uint8 rgb[3];
47 SDL_GetRGB(c, source->format, &rgb[0], &rgb[1], &rgb[2]);
48 SDL_Color col = { rgb[0], rgb[1], rgb[2], 0 };
49 SDL_SetColors(surface, &col, c, 1);
50 }
51
52 }
53
54 // Copy Constructor (deep copy)
55
shape(const shape & s)56 shape :: shape(const shape &s){
57 width = s.width;
58 height = s.height;
59 int buffersize = width * height * BYTESPERPIXEL;
60 buffer = new char[buffersize];
61 for (int i = 0; i < buffersize; i++)
62 buffer[i] = s.buffer[i];
63 surface = SDL_CreateRGBSurfaceFrom(buffer, width, height, 8 * BYTESPERPIXEL,
64 width * BYTESPERPIXEL, 0, 0, 0, 0);
65 for (int c=0;c<256;c++){
66 Uint8 rgb[3];
67 SDL_GetRGB(c, s.surface->format, &rgb[0], &rgb[1], &rgb[2]);
68 SDL_Color col = { rgb[0], rgb[1], rgb[2], 0 };
69 SDL_SetColors(surface, &col, c, 1);
70 }
71
72 }
73
74 // Destructor
75
~shape()76 shape :: ~shape(){
77 if (surface != NULL)
78 SDL_FreeSurface(surface);
79 if (buffer != 0) delete [ ]buffer;
80 }
81
82 // Assignment Operator
83
operator =(const shape & s)84 shape& shape :: operator= (const shape &s){
85 if (this != &s){
86 if (surface != NULL) SDL_FreeSurface(surface);
87 if (buffer != 0) delete [ ]buffer;
88 width = s.width;
89 height = s.height;
90 int buffersize = width * height * BYTESPERPIXEL;
91 buffer = new char[buffersize];
92 for (int i = 0; i < buffersize; i++)
93 buffer[i] = s.buffer[i];
94 surface = SDL_CreateRGBSurfaceFrom(buffer, width, height, 8 * BYTESPERPIXEL,
95 width * BYTESPERPIXEL, 0, 0, 0, 0);
96 for (int c=0;c<256;c++){
97 Uint8 rgb[3];
98 SDL_GetRGB(c, s.surface->format, &rgb[0], &rgb[1], &rgb[2]);
99 SDL_Color col = { rgb[0], rgb[1], rgb[2], 0 };
100 SDL_SetColors(surface, &col, c, 1);
101 }
102
103 }
104 return *this;
105 }
106
107 // Accessor functions for private variables
108
getwidth()109 int shape :: getwidth(){return width;}
getheight()110 int shape :: getheight(){return height;}
getSurface()111 SDL_Surface* shape :: getSurface(){return surface;}
112 //char* shape :: getbuffer(){return buffer;}
113
114 // Shape Grabber function
115
grab(SDL_Surface * source,int x,int y,int w,int h)116 void shape :: grab(SDL_Surface *source, int x, int y, int w, int h){
117 if (surface != NULL) SDL_FreeSurface(surface);
118 if (buffer != 0) delete [ ]buffer;
119 width = w;
120 height = h;
121
122 buffer = new char[w * h * BYTESPERPIXEL];
123 char *src_pixels = (char *)source->pixels;
124 for(int i=x;i<x+w;i++){
125 for(int j=y;j<y+h;j++){
126 buffer[ (j-y) * w + (i-x) ] = src_pixels[ j * source->pitch + i ];
127 }
128 }
129 surface = SDL_CreateRGBSurfaceFrom(buffer, width, height, 8 * BYTESPERPIXEL,
130 width * BYTESPERPIXEL, 0, 0, 0, 0);
131 for (int c=0;c<256;c++){
132 Uint8 rgb[3];
133 SDL_GetRGB(c, source->format, &rgb[0], &rgb[1], &rgb[2]);
134 SDL_Color col = { rgb[0], rgb[1], rgb[2], 0 };
135 SDL_SetColors(surface, &col, c, 1);
136 }
137
138
139 }
140
141 // Shape file read function (reference file)
142
read(ifstream & fin)143 bool shape :: read(ifstream &fin){
144 if (fin.fail()){
145 return false;
146 }
147
148 if (surface != NULL) SDL_FreeSurface(surface);
149 if (buffer != 0) delete [ ]buffer;
150 fin >> width >> height;
151 if (fin.fail()){
152 return false;
153 }
154 int buffersize = width * height * BYTESPERPIXEL;
155 buffer = new char[buffersize];
156 fin.read(buffer, 1); // Read the extra byte
157 fin.read(buffer, buffersize);
158 surface = SDL_CreateRGBSurfaceFrom(buffer, width, height, 8 * BYTESPERPIXEL,
159 width * BYTESPERPIXEL, 0, 0, 0, 0);
160
161 return true;
162 }
163
164 // Shape file read function (new file)
165
readfile(char * filename)166 bool shape :: readfile(char* filename){
167 ifstream fin(filename, ios::binary);
168
169 if (fin.fail()) return false;
170
171 if (surface != NULL) SDL_FreeSurface(surface);
172 if (buffer != 0) delete [ ]buffer;
173 fin >> width >> height;
174 int buffersize = width * height * BYTESPERPIXEL;
175 buffer = new char[buffersize];
176 fin.read(buffer, 1); // Read the extra byte
177 fin.read(buffer, buffersize);
178 fin.close();
179 surface = SDL_CreateRGBSurfaceFrom(buffer, width, height, 8 * BYTESPERPIXEL,
180 width * BYTESPERPIXEL, 0, 0, 0, 0);
181
182 return true;
183 }
184
185 // Shape file read function (reference file with palette)
186
read(SDL_Surface * palettesource,ifstream & fin)187 bool shape :: read(SDL_Surface *palettesource, ifstream &fin){
188 if (fin.fail()){
189 return false;
190 }
191
192 if (surface != NULL) SDL_FreeSurface(surface);
193 if (buffer != 0) delete [ ]buffer;
194 fin >> width >> height;
195 if (fin.fail()){
196 return false;
197 }
198 int buffersize = width * height * BYTESPERPIXEL;
199 buffer = new char[buffersize];
200 fin.read(buffer, 1); // Read the extra byte
201 fin.read(buffer, buffersize);
202 surface = SDL_CreateRGBSurfaceFrom(buffer, width, height, 8 * BYTESPERPIXEL,
203 width * BYTESPERPIXEL, 0, 0, 0, 0);
204
205 for (int c=0;c<256;c++){
206 Uint8 rgb[3];
207 SDL_GetRGB(c, palettesource->format, &rgb[0], &rgb[1], &rgb[2]);
208 SDL_Color col = { rgb[0], rgb[1], rgb[2], 0 };
209 SDL_SetColors(surface, &col, c, 1);
210 }
211
212 return true;
213 }
214
215 // Shape file read function (new file with palette)
216
readfile(SDL_Surface * palettesource,char * filename)217 bool shape :: readfile(SDL_Surface *palettesource, char* filename){
218 ifstream fin(filename, ios::binary);
219
220 if (fin.fail()) return false;
221
222 if (surface != NULL) SDL_FreeSurface(surface);
223 if (buffer != 0) delete [ ]buffer;
224 fin >> width >> height;
225 int buffersize = width * height * BYTESPERPIXEL;
226 buffer = new char[buffersize];
227 fin.read(buffer, 1); // Read the extra byte
228 fin.read(buffer, buffersize);
229 fin.close();
230 surface = SDL_CreateRGBSurfaceFrom(buffer, width, height, 8 * BYTESPERPIXEL,
231 width * BYTESPERPIXEL, 0, 0, 0, 0);
232 for (int c=0;c<256;c++){
233 Uint8 rgb[3];
234 SDL_GetRGB(c, palettesource->format, &rgb[0], &rgb[1], &rgb[2]);
235 SDL_Color col = { rgb[0], rgb[1], rgb[2], 0 };
236 SDL_SetColors(surface, &col, c, 1);
237 }
238
239
240 return true;
241 }
242
243
244 // Shape blitter (mask on)
245
blit(SDL_Surface * dest,int x,int y)246 void shape :: blit(SDL_Surface *dest,int x, int y){
247 SDL_SetColorKey(surface, SDL_SRCCOLORKEY, 0);
248 SDL_Rect srcrect;
249 srcrect.x = 0;
250 srcrect.y = 0;
251 srcrect.w = width;
252 srcrect.h = height;
253 SDL_Rect dstrect;
254 dstrect.x = x;
255 dstrect.y = y;
256 dstrect.w = 0;
257 dstrect.h = 0;
258 SDL_BlitSurface(surface, &srcrect, dest, &dstrect);
259 SDL_SetColorKey(surface, 0, 0);
260 }
261
262 // Shape blitter (mask chosen)
263
blit(SDL_Surface * dest,int x,int y,bool mask)264 void shape :: blit(SDL_Surface *dest,int x, int y, bool mask){
265 SDL_Rect srcrect;
266 srcrect.x = 0;
267 srcrect.y = 0;
268 srcrect.w = width;
269 srcrect.h = height;
270 SDL_Rect dstrect;
271 dstrect.x = x;
272 dstrect.y = y;
273 dstrect.w = 0;
274 dstrect.h = 0;
275 if (mask)
276 SDL_SetColorKey(surface, SDL_SRCCOLORKEY, 0);
277 SDL_BlitSurface(surface, &srcrect, dest, &dstrect);
278 if (mask)
279 SDL_SetColorKey(surface, 0, 0);
280 }
281
282 // Shape file write function (reference file)
283
write(ofstream & fout)284 bool shape :: write(ofstream &fout){
285 if (fout.fail()) return false;
286
287 fout << width << " " << height << " ";
288 fout.write(buffer, width * height * BYTESPERPIXEL);
289
290 return true;
291 }
292
293 // Shape file write function (new file)
294
writefile(char * filename)295 bool shape :: writefile(char* filename){
296 ofstream fout(filename, ios::binary);
297
298 if (fout.fail()) return false;
299
300 fout << width << " " << height << " ";
301 fout.write(buffer, width * height * BYTESPERPIXEL);
302 fout.close();
303
304 return true;
305 }
306
307 // Maximization function (for collision detection)
308
max(int a,int b)309 int shape :: max(int a, int b){
310 if (a > b) return a;
311 return b;
312 }
313
314 // Minimization function (for collision detection)
315
min(int a,int b)316 int shape :: min(int a, int b){
317 if (a < b) return a;
318 return b;
319 }
320
321 // Shape collision detection routine
322 // Checks if the shape at x,y collides with another shape s at sx,sy
323 // NB assumes BYTESPERPIXEL == 1
324
collide(int x,int y,const shape & s,int sx,int sy)325 bool shape :: collide(int x, int y, const shape &s, int sx, int sy){
326 for(int cx = max(x,sx);cx<min(x+width,sx+s.width);cx++){
327 for(int cy = max(y,sy);cy<min(y+height,sy+s.height);cy++){
328 if ((buffer[cx-x + width*(cy-y)] != 0) &&
329 (s.buffer[cx-sx + s.width*(cy-sy)] != 0)){
330 return true;
331 }
332 }
333 }
334
335 return false;
336 }
337