File: sge_shape.h

package info (click to toggle)
ruby-sdl 2.1.3-1
  • links: PTS, VCS
  • area: main
  • in suites: jessie, jessie-kfreebsd
  • size: 4,344 kB
  • ctags: 4,200
  • sloc: cpp: 7,598; ansic: 4,475; ruby: 2,258; sh: 102; makefile: 97
file content (365 lines) | stat: -rw-r--r-- 11,834 bytes parent folder | download | duplicates (8)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
/*
*	SDL Graphics Extension
*	SGE shape (header)
*
*	Started 000430
*
*	License: LGPL v2+ (see the file LICENSE)
*	(c)2000-2003 Anders Lindstrm
*/

/*********************************************************************
 *  This library is free software; you can redistribute it and/or    *
 *  modify it under the terms of the GNU Library General Public      *
 *  License as published by the Free Software Foundation; either     *
 *  version 2 of the License, or (at your option) any later version. *
 *********************************************************************/

#ifndef sge_shape_H
#define sge_shape_H

#include "SDL.h"
#include "sge_internal.h"

#ifndef _SGE_NO_CLASSES

// Remove "class 'std::list<>' needs to have dll-interface to be used" warnings
// from MS VisualC++
#ifdef _MSC_VER
  #pragma warning(push)
  #pragma warning(disable: 4251)
#endif


#include <list>
#include "sge_surface.h"
#include "sge_collision.h"

class DECLSPEC sge_shape;

//==================================================================================
// The screen class
//==================================================================================
class DECLSPEC sge_screen
{
protected:
	SDL_Surface *screen;       //The SDL screen surface
	std::list<SDL_Rect> rects; //The list of rectangles to be updated
	
	std::list<sge_shape*> shapes;   //The list of shapes to draw on screen
	std::list<sge_shape*> shapes_p; //The list of permanent shapes to draw on screen
	
	typedef std::list<SDL_Rect>::const_iterator RI;   //List iterator (for rects)
	typedef std::list<sge_shape*>::const_iterator SI; //List iterator (for shapes)
	
	bool HW, DB, FS;  //video memory, double-buffered or/and fullscreen?

public:
	sge_screen(SDL_Surface *screen);
	~sge_screen(void){rects.clear();shapes.clear();shapes_p.clear();}
	void add_rect(SDL_Rect rect);
	void add_rect(Sint16 x, Sint16 y, Uint32 w, Uint32 h);
	
	void add_shape(sge_shape *shape);
	void add_shape_p(sge_shape *shape); //Adds an shape permanently
	
	void remove_shape_p(sge_shape *shape);
	void clear_all(void);
	
	void update(void);
};


//==================================================================================
// sge_shape
// Abstract base class for different shapes (surfaces, sprites, ...)
//==================================================================================
class sge_shape
{
protected:
	SDL_Rect current_pos; //The *current* (maybe undrawn) position of the shape	
	SDL_Rect last_pos;    //The *last* drawn position of shape
	SDL_Rect prev_pos;    //The previous drawn position of shape (used to update a cleared area)

	SDL_Surface *dest;    //The surface to perform operations on
	
public:
	virtual ~sge_shape(void){} //Destructor
	virtual void draw(void)=0; //Draws the shape - prev_pos = last_pos; last_pos = the new position of shape
	
	//Updates the screen (last_pos+prev_pos)
	//If sge_screen is used this member will use it (the_screen) instead of doing it directly!
	virtual void UpdateRects(void)=0;
	
	//Some functions to clear (remove) shape
	virtual void clear(Uint32 color)=0; //Clears to color
	virtual void clear(SDL_Surface *src, Sint16 srcX, Sint16 srcY)=0; //Clears by blitting src
	
	inline SDL_Rect get_pos(void) const{return current_pos;}   //Returns the current position
	inline SDL_Rect get_last_pos(void) const{return last_pos;} //Returns the last updated position

	inline SDL_Surface* get_dest(void) const{return dest;} 
	
	/*
	//NW N NE
	//  \|/
	// W-C-E
	//  /|\
	//SW S SE
	//
	//Returns some usefull coords in shape (current)
	*/
	inline Sint16 c_x(void)  const{return current_pos.x+current_pos.w/2;}
	inline Sint16 c_y(void)  const{return current_pos.y+current_pos.h/2;}

	inline Sint16 nw_x(void) const{return current_pos.x;}
	inline Sint16 nw_y(void) const{return current_pos.y;}

	inline Sint16 n_x(void)  const{return current_pos.x+current_pos.w/2;}
	inline Sint16 n_y(void)  const{return current_pos.y;}

	inline Sint16 ne_x(void) const{return current_pos.x+current_pos.w-1;}
	inline Sint16 ne_y(void) const{return current_pos.y;}

	inline Sint16 e_x(void)  const{return current_pos.x+current_pos.w-1;}
	inline Sint16 e_y(void)  const{return current_pos.y+current_pos.h/2;}

	inline Sint16 se_x(void) const{return current_pos.x+current_pos.w-1;}
	inline Sint16 se_y(void) const{return current_pos.y+current_pos.h-1;}

	inline Sint16 s_x(void)  const{return current_pos.x+current_pos.w/2;}
	inline Sint16 s_y(void)  const{return current_pos.y+current_pos.h-1;}

	inline Sint16 sw_x(void) const{return current_pos.x;}
	inline Sint16 sw_y(void) const{return current_pos.y+current_pos.h-1;}

	inline Sint16 w_x(void)  const{return current_pos.x;}
	inline Sint16 w_y(void)  const{return current_pos.y+current_pos.h/2;}

	inline Sint16 get_xpos(void) const{return current_pos.x;}
	inline Sint16 get_ypos(void) const{return current_pos.y;}
	inline Sint16 get_w(void) const{return current_pos.w;}
	inline Sint16 get_h(void) const{return current_pos.h;}
};



//==================================================================================
// sge_surface (derived from sge_shape)
// A class for moving/blitting surfaces
//==================================================================================
class DECLSPEC sge_surface: public sge_shape
{
protected:
	SDL_Surface *surface; //The source surface *NOT COPIED*

	//Do warp logic
	bool check_warp(void);
	
	//Handles outside screen problems (But not in this class)
	virtual bool check_border(void){return check_warp();}
	
	//The border box (default: the screen size)
	SDL_Rect border;
	
	//Should we warp around the border box? (not in this class
	//but some methods here must know)
	bool warp_border;
	
	//Decode a warp pos rectangle
	int get_warp(SDL_Rect rec, SDL_Rect &r1, SDL_Rect &r2, SDL_Rect &r3, SDL_Rect &r4);
	
	//Helper functions
	void warp_draw(void);
	void warp_update(SDL_Rect rec);
	void warp_clear(Uint32 color);
	void warp_clear(SDL_Surface *src, Sint16 srcX, Sint16 srcY);
	
public:
	sge_surface(SDL_Surface *dest, SDL_Surface *src, Sint16 x=0, Sint16 y=0);
	~sge_surface(void);
	
	//Draws the surface
	virtual void draw(void);
	
	virtual inline void clear(Uint32 color);
	virtual inline void clear(SDL_Surface *src, Sint16 srcX, Sint16 srcY);
	//virtual inline void clear(SDL_Surface *src){clear(src,last_pos.x,last_pos.y);}
	
	virtual void UpdateRects(void);
	
	//Move the surface
	virtual inline void move_to(Sint16 x, Sint16 y){current_pos.x=x; current_pos.y=y;check_border();}
	virtual inline void move(Sint16 x_step, Sint16 y_step){current_pos.x+=x_step; current_pos.y+=y_step; check_border();}

	//Get pointer to surface
	SDL_Surface* get_img(void) const{return surface;}
	
	//Sets the border box
	void set_border(SDL_Rect box){border=box;}
};



//==================================================================================
// The frame struct (for sge_ssprite)
//==================================================================================
struct sge_frame
{
	//The image
	SDL_Surface *img;
	
	//Collision data
	sge_cdata *cdata;
};


//==================================================================================
// sge_ssprite (derived from sge_surface)
// A simple sprite class
//==================================================================================
class DECLSPEC sge_ssprite: public sge_surface
{
public:enum playing_mode{loop, play_once, stop}; //This must be public	

protected:
	//Linked list with the frames
	//Obs! 'surface' always points to the current frame image
	std::list<sge_frame*> frames;
	typedef std::list<sge_frame*>::const_iterator FI; //List iterator (for frames)

	FI current_fi;
	FI fi_start;   //first frame in the playing sequence loop
	FI fi_stop;    //last frame + 1
	
	//The pointer to the current frame
	sge_frame *current_frame; //Should at all times be *current_fi
	
	//The speed of the sprite (pixels/update)
	Sint16 xvel, yvel;
	
	bool bounce_border;  //Do we want the sprite to bounce at the border?
	virtual bool check_border(void);
	
	//Playing sequence mode
	playing_mode seq_mode;
	
public:

	//Constructor and destructor
	sge_ssprite(SDL_Surface *screen, SDL_Surface *img, Sint16 x=0, Sint16 y=0);
	sge_ssprite(SDL_Surface *screen, SDL_Surface *img, sge_cdata *cdata, Sint16 x=0, Sint16 y=0);
	~sge_ssprite(void);
	
	//Updates the internal status
	//Returns true if the sprite moved
	virtual inline bool update(void);
	
	//Sets the speed
	void set_vel(Sint16 x, Sint16 y){xvel=x;yvel=y;}
	void set_xvel(Sint16 x){xvel=x;}
	void set_yvel(Sint16 y){yvel=y;}
	
	//Gets the speed
	Sint16 get_xvel(void) const{return xvel;}
	Sint16 get_yvel(void) const{return yvel;}
	
	//Add a frame
	//Obs! Resets playing sequence
	void add_frame(SDL_Surface *img);
	void add_frame(SDL_Surface *img, sge_cdata *cdata);	
	
	//Change frame
	void skip_frame(int skips); //A negative 'skips' indicates backwards
	void next_frame(void){skip_frame(1);}
	void prev_frame(void){skip_frame(-1);}
	void first_frame(void);     //Does NOT change the sequence
	void last_frame(void);      //             "
	
	//Changes playing sequence (0- first frame)
	//playing_mode:
	// sge_ssprite::loop - loops forever
	// sge_ssprite::play_once - just once then stops
	// sge_ssprite::stop - is returned by get_PlayingMode() if stoped
	void set_seq(int start, int stop, playing_mode mode=loop);
	void reset_seq(void);
	playing_mode get_PlayingMode(void){return seq_mode;}
	
	//Get cdata for current frame
	sge_cdata* get_cdata(void){return current_frame->cdata;}
	
	//Get the current frame
	sge_frame* get_frame(void){return current_frame;}
	
	//Get the frame list
	//DO NOT ADD OR REMOVE ELEMENTS without using
	//reset_seq() when done!!
	std::list<sge_frame*>* get_list(void){return &frames;}
	
	//Set border mode:
	//Bounce - sprite bounces (default)
	//Warp - sprite warps at border
	void border_bounce(bool mode){bounce_border=mode; if(warp_border){warp_border=false;}}
	void border_warp(bool mode){warp_border=mode; if(bounce_border){bounce_border=false;}}
};


//==================================================================================
// sge_sprite (derived from sge_ssprite)
// A timed sprite class
//==================================================================================
class DECLSPEC sge_sprite: public sge_ssprite
{
protected:
	//Pixels/ms
	double xppms, yppms;
	
	//Frames/ms
	double fpms;

	//The float pos
	double xpos, ypos, fpos;
	
	//Ticks since last pos update
	Uint32 tlast;
	
	virtual bool check_border(void);
public:
	//Constructor
	sge_sprite(SDL_Surface *screen, SDL_Surface *img, Sint16 x=0, Sint16 y=0):
		sge_ssprite(screen,img,x,y){xppms=yppms=fpms=0;tlast=0;xpos=x;ypos=y;fpos=0;}
		
	sge_sprite(SDL_Surface *screen, SDL_Surface *img, sge_cdata *cdata, Sint16 x=0, Sint16 y=0):
		sge_ssprite(screen,img,cdata,x,y){xppms=yppms=fpms=0;tlast=0;xpos=x;ypos=y;fpos=0;}
	
	//Change the speeds
	void set_pps(Sint16 x, Sint16 y){xppms=x/1000.0; yppms=y/1000.0;}
	void set_xpps(Sint16 x){xppms=x/1000.0;}
	void set_ypps(Sint16 y){yppms=y/1000.0;}
	void set_fps(Sint16 f){fpms=f/1000.0;}
	
	//Get the speeds
	Sint16 get_xpps(void) const{return Sint16(xppms*1000);}
	Sint16 get_ypps(void) const{return Sint16(yppms*1000);}
	Sint16 get_fps(void) const{return Sint16(fpms*1000);}
			
	//Update position and frame
	//Returns true if something changed
	bool update(Uint32 ticks);
	bool update(void){return update(SDL_GetTicks());}
	
	//Correct move members for this class
	void move_to(Sint16 x, Sint16 y){sge_surface::move_to(x,y); xpos=current_pos.x; ypos=current_pos.y;}
	void move(Sint16 x_step, Sint16 y_step){sge_surface::move(x_step,y_step); xpos=current_pos.x; ypos=current_pos.y;}

	//Freeze time until next update
	void pause(void){tlast=0;}
};


#ifdef _MSC_VER
  #pragma warning(pop)
#endif

#endif /* _SGE_NO_CLASSES */
#endif /* sge_shape_H */