graphics 1.0.0b1 → 1.0.0b4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (73) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data.tar.gz.sig +0 -0
  4. data/History.rdoc +30 -0
  5. data/Manifest.txt +39 -7
  6. data/README.rdoc +48 -4
  7. data/Rakefile +8 -2
  8. data/examples/boid.rb +9 -18
  9. data/examples/bounce.rb +15 -23
  10. data/examples/canvas.rb +75 -0
  11. data/examples/collision.rb +6 -6
  12. data/examples/demo.rb +5 -7
  13. data/examples/editor.rb +12 -9
  14. data/examples/fluid.rb +2 -3
  15. data/examples/fluid2.rb +1 -1
  16. data/examples/{lito2.rb → gol.rb} +0 -0
  17. data/examples/{zenspider4.rb → gol2.rb} +0 -0
  18. data/examples/logo.rb +4 -7
  19. data/examples/maze.rb +136 -0
  20. data/examples/tank.rb +10 -11
  21. data/examples/tank2.rb +12 -17
  22. data/examples/targeting.rb +1 -1
  23. data/examples/vants.rb +1 -1
  24. data/examples/walker.rb +3 -12
  25. data/examples/walker2.rb +197 -0
  26. data/examples/zombies.rb +31 -35
  27. data/ext/sdl/extconf.rb +31 -0
  28. data/ext/sdl/sdl.c +1067 -0
  29. data/ext/sdl/sge/INSTALL +72 -0
  30. data/ext/sdl/sge/LICENSE +504 -0
  31. data/ext/sdl/sge/Makefile +83 -0
  32. data/ext/sdl/sge/Makefile.conf +63 -0
  33. data/ext/sdl/sge/README +219 -0
  34. data/ext/sdl/sge/Todo +7 -0
  35. data/ext/sdl/sge/WhatsNew +224 -0
  36. data/ext/sdl/sge/sge.h +31 -0
  37. data/ext/sdl/sge/sge_blib.cpp +1939 -0
  38. data/ext/sdl/sge/sge_blib.h +68 -0
  39. data/ext/sdl/sge/sge_bm_text.cpp +451 -0
  40. data/ext/sdl/sge/sge_bm_text.h +71 -0
  41. data/ext/sdl/sge/sge_collision.cpp +388 -0
  42. data/ext/sdl/sge/sge_collision.h +54 -0
  43. data/ext/sdl/sge/sge_config.h +6 -0
  44. data/ext/sdl/sge/sge_internal.h +152 -0
  45. data/ext/sdl/sge/sge_misc.cpp +92 -0
  46. data/ext/sdl/sge/sge_misc.h +37 -0
  47. data/ext/sdl/sge/sge_primitives.cpp +2516 -0
  48. data/ext/sdl/sge/sge_primitives.h +111 -0
  49. data/ext/sdl/sge/sge_rotation.cpp +683 -0
  50. data/ext/sdl/sge/sge_rotation.h +46 -0
  51. data/ext/sdl/sge/sge_shape.cpp +762 -0
  52. data/ext/sdl/sge/sge_shape.h +365 -0
  53. data/ext/sdl/sge/sge_surface.cpp +1090 -0
  54. data/ext/sdl/sge/sge_surface.h +100 -0
  55. data/ext/sdl/sge/sge_textpp.cpp +785 -0
  56. data/ext/sdl/sge/sge_textpp.h +270 -0
  57. data/ext/sdl/sge/sge_tt_text.cpp +1456 -0
  58. data/ext/sdl/sge/sge_tt_text.h +114 -0
  59. data/graphics_setup.sh +26 -0
  60. data/lib/graphics.rb +1 -1
  61. data/lib/graphics/body.rb +50 -3
  62. data/lib/graphics/extensions.rb +13 -7
  63. data/lib/graphics/simulation.rb +126 -46
  64. data/test/test_graphics.rb +52 -12
  65. data/test/test_sdl.rb +1 -0
  66. metadata +54 -23
  67. metadata.gz.sig +0 -0
  68. data/.gemtest +0 -0
  69. data/examples/lito.rb +0 -108
  70. data/examples/zenspider1.rb +0 -93
  71. data/examples/zenspider2.rb +0 -123
  72. data/examples/zenspider3.rb +0 -104
  73. data/rubysdl_setup.sh +0 -34
@@ -0,0 +1,46 @@
1
+ /*
2
+ * SDL Graphics Extension
3
+ * Rotation routines (header)
4
+ *
5
+ * Started 000625
6
+ *
7
+ * License: LGPL v2+ (see the file LICENSE)
8
+ * (c)1999-2003 Anders Lindstr�m
9
+ */
10
+
11
+ /*********************************************************************
12
+ * This library is free software; you can redistribute it and/or *
13
+ * modify it under the terms of the GNU Library General Public *
14
+ * License as published by the Free Software Foundation; either *
15
+ * version 2 of the License, or (at your option) any later version. *
16
+ *********************************************************************/
17
+
18
+ #ifndef sge_rotation_H
19
+ #define sge_rotation_H
20
+
21
+ #include "SDL.h"
22
+ #include "sge_internal.h"
23
+
24
+ /* Transformation flags */
25
+ #define SGE_TAA SGE_FLAG1
26
+ #define SGE_TSAFE SGE_FLAG2
27
+ #define SGE_TTMAP SGE_FLAG3
28
+
29
+ #ifdef _SGE_C
30
+ extern "C" {
31
+ #endif
32
+ DECLSPEC SDL_Rect sge_transform(SDL_Surface *src, SDL_Surface *dst, float angle, float xscale, float yscale ,Uint16 px, Uint16 py, Uint16 qx, Uint16 qy, Uint8 flags);
33
+ DECLSPEC SDL_Surface *sge_transform_surface(SDL_Surface *src, Uint32 bcol, float angle, float xscale, float yscale, Uint8 flags);
34
+
35
+
36
+ /* Old obolete functions - now uses sge_transform() anyway */
37
+ DECLSPEC SDL_Surface *sge_rotate_scaled_surface(SDL_Surface *src, int angle, double scale, Uint32 bcol);
38
+ DECLSPEC SDL_Surface *sge_rotate_surface(SDL_Surface *src, int angle, Uint32 bcol);
39
+ DECLSPEC SDL_Rect sge_rotate_xyscaled(SDL_Surface *dest, SDL_Surface *src, Sint16 x, Sint16 y, int angle, double xscale, double yscale);
40
+ DECLSPEC SDL_Rect sge_rotate_scaled(SDL_Surface *dest, SDL_Surface *src, Sint16 x, Sint16 y, int angle, double scale);
41
+ DECLSPEC SDL_Rect sge_rotate(SDL_Surface *dest, SDL_Surface *src, Sint16 x, Sint16 y, int angle);
42
+ #ifdef _SGE_C
43
+ }
44
+ #endif
45
+
46
+ #endif /* sge_rotation_H */
@@ -0,0 +1,762 @@
1
+ /*
2
+ * SDL Graphics Extension
3
+ * SGE shape
4
+ *
5
+ * Started 000430
6
+ *
7
+ * License: LGPL v2+ (see the file LICENSE)
8
+ * (c)2000-2003 Anders Lindstr�m
9
+ */
10
+
11
+ /*********************************************************************
12
+ * This library is free software; you can redistribute it and/or *
13
+ * modify it under the terms of the GNU Library General Public *
14
+ * License as published by the Free Software Foundation; either *
15
+ * version 2 of the License, or (at your option) any later version. *
16
+ *********************************************************************/
17
+
18
+ #include "SDL.h"
19
+ #include <stdio.h>
20
+ #include <math.h>
21
+ #include "sge_surface.h"
22
+ #include "sge_primitives.h"
23
+ #include "sge_shape.h"
24
+ #include "sge_misc.h"
25
+
26
+ #ifndef _SGE_NO_CLASSES
27
+
28
+ using namespace std;
29
+
30
+
31
+ sge_screen *the_screen=NULL; //The pointer to the active screen class (or NULL)
32
+
33
+ //==================================================================================
34
+ // sge_screen
35
+ //==================================================================================
36
+ sge_screen::sge_screen(SDL_Surface *screen)
37
+ {
38
+ sge_screen::screen=screen; //Our screen pointer
39
+
40
+ /* Test some flags */
41
+ HW=(((screen->flags) & SDL_HWSURFACE) != 0);
42
+ DB=(((screen->flags) & SDL_DOUBLEBUF) != 0);
43
+ FS=(((screen->flags) & SDL_FULLSCREEN) != 0);
44
+
45
+ /* Test the resolution of SDL_Delay() */
46
+ //sge_CalibrateDelay();
47
+
48
+ /* Register us as the screen class */
49
+ the_screen=this;
50
+
51
+ #ifdef sge_debug
52
+ if(HW)
53
+ printf("Screen surface is in video memory (");
54
+ else
55
+ printf("Screen surface is in system memory (");
56
+ if(DB)
57
+ printf("double-buffered ");
58
+ else
59
+ printf("single-buffered ");
60
+ if(FS)
61
+ printf("fullscreen mode).\n");
62
+ else
63
+ printf("window mode).\n");
64
+
65
+ //printf("The resolution of SDL_Delay() is %d ms.\n",sge_DelayRes());
66
+ #endif
67
+ }
68
+
69
+ void sge_screen::add_rect(SDL_Rect rect)
70
+ {
71
+ if(!(HW||DB)){
72
+ /* Corrects the coords */
73
+ if(rect.x>=screen->w || rect.y>=screen->h){return;}
74
+ Sint16 a=rect.w,b=rect.h;
75
+ if(rect.x < 0){rect.x=0;}
76
+ if(rect.y < 0){rect.y=0;}
77
+ if(a+rect.x > screen->w)
78
+ a=screen->w-rect.x;
79
+ if(b+rect.y > screen->h)
80
+ b=screen->h-rect.y;
81
+
82
+ rect.w=a; rect.h=b;
83
+
84
+ /* Put the rectangle last in the list */
85
+ rects.push_back(rect);
86
+ }
87
+ }
88
+
89
+ void sge_screen::add_rect(Sint16 x, Sint16 y, Uint32 w, Uint32 h)
90
+ {
91
+ if(!(HW||DB)){
92
+ SDL_Rect rect; rect.x=x; rect.y=y; rect.w=w; rect.h=h;
93
+ add_rect(rect);
94
+ }
95
+ }
96
+
97
+ void sge_screen::add_shape(sge_shape *shape)
98
+ {
99
+ shapes.push_back(shape);
100
+ }
101
+
102
+ void sge_screen::add_shape_p(sge_shape *shape)
103
+ {
104
+ shapes_p.push_back(shape);
105
+ }
106
+
107
+ void sge_screen::remove_shape_p(sge_shape *shape)
108
+ {
109
+ shapes_p.remove(shape);
110
+ }
111
+
112
+ void sge_screen::clear_all(void)
113
+ {
114
+ shapes.clear();
115
+ shapes_p.clear();
116
+ rects.clear();
117
+ }
118
+
119
+ void sge_screen::update(void)
120
+ {
121
+ SI i;
122
+
123
+ //Draw shapes in list
124
+ for(i=shapes.begin(); i != shapes.end(); i++){
125
+ (*i)->draw();
126
+ (*i)->UpdateRects(); //Adds rectangles with add_rect() automaticly
127
+ }
128
+ shapes.clear();
129
+
130
+ //Draw permanent shapes in list
131
+ for(i=shapes_p.begin(); i != shapes_p.end(); i++){
132
+ (*i)->draw();
133
+ (*i)->UpdateRects(); //Adds rectangles with add_rect() automaticly
134
+ }
135
+
136
+ //Updates the list of rectangles on screen
137
+ if(!(HW||DB)){
138
+ int j=0;
139
+
140
+ SDL_Rect *r=new SDL_Rect[rects.size()]; //ANSI C++
141
+
142
+ /* Copy every element in the linked list to the array */
143
+ for(RI i=rects.begin(); i != rects.end(); i++){
144
+ r[j++]=*i;
145
+ }
146
+
147
+ SDL_UpdateRects(screen,rects.size(), r); //Let SDL update the rectangles
148
+
149
+ delete[] r;
150
+
151
+ rects.clear(); //Empty the list
152
+ }
153
+ else if(DB) //double-buffered
154
+ SDL_Flip(screen);
155
+ }
156
+
157
+
158
+ //==================================================================================
159
+ // sge_surface (derived from sge_shape)
160
+ // A class for moving/blitting surfaces
161
+ //==================================================================================
162
+ sge_surface::sge_surface(SDL_Surface *dest, SDL_Surface *src, Sint16 x, Sint16 y)
163
+ {
164
+ surface=src;
165
+ sge_surface::dest=dest;
166
+
167
+ current_pos.x=x;current_pos.y=y;current_pos.w=src->w;current_pos.h=src->h;
168
+ last_pos.x=last_pos.y=last_pos.w=last_pos.h=0;
169
+ prev_pos=last_pos;
170
+
171
+ border.x=border.y=0;border.w=dest->w;border.h=dest->h;
172
+ warp_border=false;
173
+ }
174
+
175
+ sge_surface::~sge_surface(void)
176
+ {
177
+ //Nothing for now...
178
+ }
179
+
180
+
181
+ bool sge_surface::check_warp(void)
182
+ {
183
+ bool flag=false;
184
+
185
+ if(warp_border){
186
+ if(current_pos.x+current_pos.w<border.x){
187
+ current_pos.x=border.x+border.w-current_pos.w;
188
+ flag=true;
189
+ }else if(current_pos.x>border.x+border.w){
190
+ current_pos.x=border.x;
191
+ flag=true;
192
+ }if(current_pos.y+current_pos.h<border.y){
193
+ current_pos.y=border.y+border.h-current_pos.h;
194
+ flag=true;
195
+ }else if(current_pos.y>border.y+border.h){
196
+ current_pos.y=border.y;
197
+ flag=true;
198
+ }
199
+ }
200
+ return flag;
201
+ }
202
+
203
+ int sge_surface::get_warp(SDL_Rect rec, SDL_Rect &r1, SDL_Rect &r2, SDL_Rect &r3, SDL_Rect &r4)
204
+ {
205
+ //We want to decode the pos rectangle into two or four rectangles.
206
+
207
+ r1.x = r2.x = r3.x = r4.x = rec.x, r1.y = r2.y = r3.y = r4.y = rec.y;
208
+ r1.w = r2.w = r3.w = r4.w = rec.w, r1.h = r2.h = r3.h = r4.h = rec.h;
209
+
210
+ int rects=0;
211
+
212
+ if(warp_border){
213
+
214
+ if(rec.x<border.x){
215
+ r1.w = border.x - rec.x;
216
+ r1.x = border.x + border.w - r1.w;
217
+ r2.w = abs(rec.w - r1.w); //SDL_Rect w/h is unsigned
218
+ r2.x = border.x;
219
+ rects=2;
220
+ }else if(rec.x+rec.w > border.x + border.w){
221
+ r1.x = rec.x;
222
+ r1.w = border.x + border.w - rec.x;
223
+ r2.x = border.x;
224
+ r2.w = abs(rec.w - r1.w);
225
+ rects=2;
226
+ }
227
+
228
+ r3.x = r1.x; r3.w = r1.w;
229
+ r4.x = r2.x; r4.w = r2.w;
230
+
231
+ if(rec.y<border.y){
232
+ if(rects==0){
233
+ r1.h = border.y - rec.y;
234
+ r1.y = border.y + border.h - r1.h;
235
+ r2.h = abs(rec.h - r1.h);
236
+ r2.y = border.y;
237
+ rects=2;
238
+ }else{
239
+ r2.h = r1.h= border.y - rec.y;
240
+ r2.y = r1.y= border.y + border.h - r1.h;
241
+ r4.h = r3.h= abs(rec.h - r1.h);
242
+ r4.y = r3.y= border.y;
243
+ rects=4;
244
+ }
245
+ }else if(rec.y+rec.h > border.y + border.h){
246
+ if(rects==0){
247
+ r1.y = rec.y;
248
+ r1.h = border.y + border.h - rec.y;
249
+ r2.y = border.y;
250
+ r2.h = abs(rec.h - r1.h);
251
+ rects=2;
252
+ }else{
253
+ r2.y = r1.y = rec.y;
254
+ r2.h = r1.h = border.y + border.h - rec.y;
255
+ r4.y = r3.y = border.y;
256
+ r4.h = r3.h = abs(rec.h - r1.h);
257
+ rects=4;
258
+ }
259
+ }
260
+ }
261
+ return rects;
262
+ }
263
+
264
+ void sge_surface::warp_draw(void)
265
+ {
266
+ SDL_Rect r1,r2,r3,r4;
267
+ int rects=get_warp(current_pos,r1,r2,r3,r4);
268
+
269
+ if(rects==2){
270
+ sge_Blit(surface, dest, 0,0, r1.x, r1.y, r1.w, r1.h);
271
+ sge_Blit(surface, dest, surface->w-r2.w,surface->h-r2.h, r2.x, r2.y, r2.w, r2.h);
272
+ }
273
+ else if(rects==4){
274
+ sge_Blit(surface, dest, 0,0, r1.x, r1.y, r1.w, r1.h);
275
+ sge_Blit(surface, dest, surface->w-r2.w,0, r2.x, r2.y, r2.w, r2.h);
276
+ sge_Blit(surface, dest, 0,surface->h-r3.h, r3.x, r3.y, r3.w, r3.h);
277
+ sge_Blit(surface, dest, surface->w-r4.w,surface->h-r4.h, r4.x, r4.y, r4.w, r4.h);
278
+ }
279
+ else
280
+ sge_Blit(surface, dest, 0,0, current_pos.x, current_pos.y, surface->w, surface->h);
281
+ }
282
+
283
+ void sge_surface::warp_update(SDL_Rect rec)
284
+ {
285
+ SDL_Rect r1,r2,r3,r4;
286
+ int rects=get_warp(rec,r1,r2,r3,r4);
287
+
288
+ if(rects>0){
289
+ if(the_screen){ //Use the screen class?
290
+ the_screen->add_rect(r1.x, r1.y, r1.w, r1.h);
291
+ the_screen->add_rect(r2.x, r2.y, r2.w, r2.h);
292
+ if(rects>2){
293
+ the_screen->add_rect(r3.x, r3.y, r3.w, r3.h);
294
+ the_screen->add_rect(r4.x, r4.y, r4.w, r4.h);
295
+ }
296
+ }else{
297
+ sge_UpdateRect(dest, r1.x, r1.y, r1.w, r1.h);
298
+ sge_UpdateRect(dest, r2.x, r2.y, r2.w, r2.h);
299
+ if(rects>2){
300
+ sge_UpdateRect(dest, r3.x, r3.y, r3.w, r3.h);
301
+ sge_UpdateRect(dest, r4.x, r4.y, r4.w, r4.h);
302
+ }
303
+ }
304
+ }
305
+ else{
306
+ if(the_screen)
307
+ the_screen->add_rect(rec.x, rec.y, rec.w, rec.h);
308
+ else
309
+ sge_UpdateRect(dest, rec.x, rec.y, rec.w, rec.h);
310
+ }
311
+ }
312
+
313
+ void sge_surface::warp_clear(Uint32 color)
314
+ {
315
+ SDL_Rect r1,r2,r3,r4;
316
+ int rects=get_warp(last_pos,r1,r2,r3,r4);
317
+
318
+ if(rects>0){
319
+ sge_FilledRect(dest, r1.x, r1.y, r1.x+r1.w-1, r1.y+r1.h-1, color);
320
+ sge_FilledRect(dest, r2.x, r2.y, r2.x+r2.w-1, r2.y+r2.h-1, color);
321
+ if(rects>2){
322
+ sge_FilledRect(dest, r3.x, r3.y, r3.x+r3.w-1, r3.y+r3.h-1, color);
323
+ sge_FilledRect(dest, r4.x, r4.y, r4.x+r4.w-1, r4.y+r4.h-1, color);
324
+ }
325
+ }
326
+ else
327
+ sge_FilledRect(dest, last_pos.x, last_pos.y, last_pos.x+last_pos.w-1, last_pos.y+last_pos.h-1,color);
328
+ }
329
+
330
+
331
+ void sge_surface::warp_clear(SDL_Surface *src, Sint16 srcX, Sint16 srcY)
332
+ {
333
+ SDL_Rect r1,r2,r3,r4;
334
+ int rects=get_warp(current_pos,r1,r2,r3,r4);
335
+
336
+ if(rects>0){
337
+ sge_Blit(src, dest, r1.x,r1.y, r1.x, r1.y, r1.w, r1.h);
338
+ sge_Blit(src, dest, r2.x,r2.y, r2.x, r2.y, r2.w, r2.h);
339
+ if(rects>2){
340
+ sge_Blit(src, dest, r3.x,r3.y, r3.x, r3.y, r3.w, r3.h);
341
+ sge_Blit(src, dest, r4.x,r4.y, r4.x, r4.y, r4.w, r4.h);
342
+ }
343
+ }
344
+ else
345
+ sge_Blit(src,dest, srcX, srcY, last_pos.x, last_pos.y, last_pos.w, last_pos.h);
346
+ }
347
+
348
+
349
+ //Draws the surface
350
+ void sge_surface::draw(void)
351
+ {
352
+ if(!surface)
353
+ return;
354
+
355
+ current_pos.w=surface->w;
356
+ current_pos.h=surface->h;
357
+
358
+ if(warp_border)
359
+ warp_draw();
360
+ else
361
+ sge_Blit(surface, dest, 0,0, current_pos.x, current_pos.y, surface->w, surface->h);
362
+
363
+ prev_pos=last_pos;
364
+ last_pos=current_pos;
365
+ }
366
+
367
+ void sge_surface::UpdateRects(void)
368
+ {
369
+ Sint16 xoffs=last_pos.x-prev_pos.x, yoffs=last_pos.y-prev_pos.y;
370
+
371
+ //if the prev and last area to update is very near
372
+ //it's better to update both with one sge_UpdateRect call
373
+
374
+ if(xoffs<0)
375
+ xoffs=~xoffs+1; //abs(xoffs)
376
+ if(yoffs<0)
377
+ yoffs=~yoffs+1;
378
+
379
+ if(xoffs <= prev_pos.w/2 && yoffs <= prev_pos.h/2){
380
+ Sint16 minx, miny, maxx, maxy, w=prev_pos.w+xoffs, h=prev_pos.h+yoffs;
381
+
382
+ minx= (prev_pos.x<last_pos.x)? prev_pos.x : last_pos.x;
383
+ miny= (prev_pos.y<last_pos.y)? prev_pos.y : last_pos.y;
384
+
385
+ if(prev_pos.w!=last_pos.w){
386
+ maxx= (prev_pos.x+prev_pos.w > last_pos.x+last_pos.w)? prev_pos.x+prev_pos.w : last_pos.x+last_pos.w;
387
+ w=maxx-minx;
388
+ }
389
+ if(prev_pos.h!=last_pos.h){
390
+ maxy= (prev_pos.y+prev_pos.h > last_pos.y+last_pos.h)? prev_pos.y+prev_pos.h : last_pos.y+last_pos.h;
391
+ h=maxy-miny;
392
+ }
393
+
394
+
395
+ if(warp_border){
396
+ SDL_Rect r;
397
+ r.x=minx; r.y=miny; r.w=w; r.h=h;
398
+ warp_update(r);
399
+ }
400
+ else if(the_screen) //Use the screen class?
401
+ the_screen->add_rect(minx, miny, w, h);
402
+ else
403
+ sge_UpdateRect(dest, minx, miny, w, h);
404
+
405
+ }
406
+ else{
407
+ if(warp_border){
408
+ warp_update(prev_pos);
409
+ warp_update(last_pos);
410
+ }
411
+ else if(the_screen){
412
+ the_screen->add_rect(prev_pos.x, prev_pos.y, prev_pos.w, prev_pos.h);
413
+ the_screen->add_rect(last_pos.x, last_pos.y, last_pos.w, last_pos.h);
414
+ }
415
+ else{
416
+ sge_UpdateRect(dest, prev_pos.x, prev_pos.y, prev_pos.w, prev_pos.h);
417
+ sge_UpdateRect(dest, last_pos.x, last_pos.y, last_pos.w, last_pos.h);
418
+ }
419
+ }
420
+ }
421
+
422
+ void sge_surface::clear(Uint32 color)
423
+ {
424
+ if(warp_border)
425
+ warp_clear(color);
426
+ else
427
+ sge_FilledRect(dest, last_pos.x, last_pos.y, last_pos.x+last_pos.w-1, last_pos.y+last_pos.h-1,color);
428
+ }
429
+
430
+ void sge_surface::clear(SDL_Surface *src, Sint16 srcX, Sint16 srcY)
431
+ {
432
+ if(warp_border)
433
+ warp_clear(src,srcX,srcY);
434
+ else
435
+ sge_Blit(src,dest, srcX, srcY, last_pos.x, last_pos.y, last_pos.w, last_pos.h);
436
+ }
437
+
438
+
439
+
440
+ //==================================================================================
441
+ // sge_ssprite (derived from sge_surface)
442
+ // A simple sprite class
443
+ //==================================================================================
444
+ sge_ssprite::sge_ssprite(SDL_Surface *screen, SDL_Surface *img, Sint16 x, Sint16 y):
445
+ sge_surface(screen,img,x,y)
446
+ {
447
+ //Create the first frame
448
+ current_frame= new sge_frame; //User has to catch bad_alloc himself
449
+ current_frame->img = img;
450
+ current_frame->cdata=NULL;
451
+ frames.push_back(current_frame);
452
+
453
+ current_fi=frames.begin();
454
+ fi_start = current_fi;
455
+ fi_stop = frames.end();
456
+
457
+ //Default
458
+ xvel=yvel=0;
459
+ seq_mode=stop;
460
+
461
+ bounce_border=true;
462
+ }
463
+
464
+ sge_ssprite::sge_ssprite(SDL_Surface *screen, SDL_Surface *img, sge_cdata *cdata, Sint16 x, Sint16 y):
465
+ sge_surface(screen,img,x,y)
466
+ {
467
+ //Create the first frame
468
+ current_frame= new sge_frame; //User has to catch bad_alloc himself
469
+ current_frame->img = img;
470
+ current_frame->cdata=cdata;
471
+ frames.push_back(current_frame);
472
+
473
+ current_fi=frames.begin();
474
+ fi_start = current_fi;
475
+ fi_stop = frames.end();
476
+
477
+ //Default
478
+ xvel=yvel=0;
479
+ seq_mode=stop;
480
+
481
+ bounce_border=true;
482
+ }
483
+
484
+ sge_ssprite::~sge_ssprite(void)
485
+ {
486
+ //Empty the list
487
+ for(FI i=frames.begin(); i != frames.end(); i++)
488
+ delete *i;
489
+
490
+ frames.clear();
491
+ }
492
+
493
+ bool sge_ssprite::check_border(void)
494
+ {
495
+ if(!bounce_border)
496
+ return sge_surface::check_border();
497
+
498
+ bool flag=false;
499
+
500
+ if(current_pos.x<border.x){
501
+ current_pos.x=border.x;
502
+ xvel=-xvel;
503
+ flag=true;
504
+ }
505
+ if(current_pos.x+current_pos.w > border.x+border.w){
506
+ current_pos.x=border.x+border.w-current_pos.w;
507
+ xvel=-xvel;
508
+ flag=true;
509
+ }
510
+ if(current_pos.y<border.y){
511
+ current_pos.y=border.y;
512
+ yvel=-yvel;
513
+ flag=true;
514
+ }
515
+ if(current_pos.y+current_pos.h > border.y+border.h){
516
+ current_pos.y=border.y+border.h-current_pos.h;
517
+ yvel=-yvel;
518
+ flag=true;
519
+ }
520
+ return flag;
521
+ }
522
+
523
+
524
+ void sge_ssprite::add_frame(SDL_Surface *img)
525
+ {
526
+ add_frame(img, NULL);
527
+ }
528
+
529
+ void sge_ssprite::add_frame(SDL_Surface *img, sge_cdata *cdata)
530
+ {
531
+ //Create a new frame
532
+ sge_frame *frame = new sge_frame; //User has to catch bad_alloc himself
533
+ frame->img = img;
534
+ frame->cdata = cdata;
535
+ frames.push_back(frame);
536
+
537
+ fi_start = frames.begin();
538
+ fi_stop = frames.end();
539
+
540
+ seq_mode=loop;
541
+ }
542
+
543
+ void sge_ssprite::skip_frame(int skips)
544
+ {
545
+ if(skips > 0){
546
+ for(int i=0; i<skips; i++){
547
+ current_fi++;
548
+ if(current_fi == fi_stop){
549
+ if(seq_mode!=play_once)
550
+ current_fi=fi_start; //loop
551
+ else{ //stop
552
+ seq_mode=stop;
553
+ current_fi--; //current_fi = fi_stop -1
554
+ fi_start=current_fi;
555
+ }
556
+ }
557
+ }
558
+ }
559
+ else if(skips < 0){
560
+ for(int i=0; i<-skips; i++){
561
+ if(current_fi == fi_start){
562
+ if(seq_mode!=play_once)
563
+ current_fi=fi_stop; //loop
564
+ else{ //stop
565
+ seq_mode=stop;
566
+ current_fi++; //+1
567
+ fi_stop=current_fi;
568
+ }
569
+ }
570
+ current_fi--;
571
+ }
572
+ }
573
+ else
574
+ return;
575
+
576
+ current_frame = *current_fi;
577
+ surface = current_frame->img;
578
+ current_pos.w = surface->w;
579
+ current_pos.h = surface->h;
580
+ }
581
+
582
+ bool sge_ssprite::update(void)
583
+ {
584
+ move(xvel,yvel);
585
+ return !((xvel==0)&&(yvel==0));
586
+ }
587
+
588
+ void sge_ssprite::set_seq(int start, int stop, playing_mode mode)
589
+ {
590
+ //Handle stupid user errors
591
+ if(start < 0 || start > int(frames.size())-1)
592
+ return;
593
+ if(stop < start || stop > int(frames.size())-1)
594
+ return;
595
+
596
+ seq_mode=loop;
597
+ if(mode==play_once)
598
+ seq_mode=play_once;
599
+ if(start==stop)
600
+ seq_mode=sge_ssprite::stop;
601
+
602
+ fi_start=fi_stop=frames.begin();
603
+
604
+ for(int i=0; i<=stop; i++){
605
+ if(i<start)
606
+ fi_start++;
607
+
608
+ fi_stop++;
609
+
610
+ if(fi_stop == frames.end()){
611
+ if(fi_start == frames.end())
612
+ fi_start--;
613
+ break;
614
+ }
615
+ }
616
+
617
+ current_fi = fi_start;
618
+
619
+ current_frame = *current_fi;
620
+ surface = current_frame->img;
621
+ current_pos.w = surface->w;
622
+ current_pos.h = surface->h;
623
+ }
624
+
625
+ void sge_ssprite::reset_seq(void)
626
+ {
627
+ fi_start=frames.begin();
628
+ fi_stop=frames.end();
629
+
630
+ current_fi = fi_start;
631
+
632
+ current_frame = *current_fi;
633
+ surface = current_frame->img;
634
+ current_pos.w = surface->w;
635
+ current_pos.h = surface->h;
636
+
637
+ if(frames.size() > 1)
638
+ seq_mode=loop;
639
+ else
640
+ seq_mode=stop;
641
+ }
642
+
643
+ void sge_ssprite::first_frame(void)
644
+ {
645
+ current_fi = fi_start;
646
+
647
+ current_frame = *current_fi;
648
+ surface = current_frame->img;
649
+ current_pos.w = surface->w;
650
+ current_pos.h = surface->h;
651
+ }
652
+
653
+ void sge_ssprite::last_frame(void)
654
+ {
655
+ current_fi = fi_stop;
656
+ current_fi--;
657
+
658
+ current_frame = *current_fi;
659
+ surface = current_frame->img;
660
+ current_pos.w = surface->w;
661
+ current_pos.h = surface->h;
662
+ }
663
+
664
+
665
+
666
+ //==================================================================================
667
+ // sge_sprite (derived from sge_ssprite)
668
+ // A timed sprite class
669
+ //==================================================================================
670
+ bool sge_sprite::update(Uint32 ticks)
671
+ {
672
+ if(tlast==0){
673
+ tlast=ticks;
674
+ return false;
675
+ }
676
+
677
+ Sint16 tmp;
678
+ Uint32 time=ticks-tlast;
679
+ tlast=ticks; //Reset time
680
+
681
+ bool ret=false;
682
+
683
+ //Calculate new pos
684
+ if(xppms!=0){
685
+ xpos+=time*xppms;
686
+ tmp=int(xpos);
687
+ if(current_pos.x!=tmp){
688
+ current_pos.x=tmp;
689
+ ret=true;
690
+ }
691
+ }
692
+ if(yppms!=0){
693
+ ypos+=time*yppms;
694
+ tmp=int(ypos);
695
+ if(current_pos.y!=tmp){
696
+ current_pos.y=tmp;
697
+ ret=true;
698
+ }
699
+ }
700
+
701
+ if(ret) //Are we off-screen?
702
+ check_border();
703
+
704
+ //Calculate new frame
705
+ if(fpms!=0){
706
+ fpos+=time*fpms;
707
+ tmp=int(fpos);
708
+ if(tmp!=0){
709
+ skip_frame(tmp);
710
+ fpos-=tmp;
711
+ ret=true;
712
+ }
713
+ }
714
+
715
+ return ret;
716
+ }
717
+
718
+ bool sge_sprite::check_border(void)
719
+ {
720
+ if(warp_border){
721
+ if(sge_surface::check_warp()){
722
+ xpos=current_pos.x;
723
+ ypos=current_pos.y;
724
+ return true;
725
+ }
726
+ return false;
727
+ }
728
+ if(!bounce_border)
729
+ return false;
730
+
731
+ bool flag=false;
732
+
733
+ if(current_pos.x<border.x){
734
+ current_pos.x=border.x;
735
+ xpos=current_pos.x;
736
+ xppms=-xppms;
737
+ flag=true;
738
+ }
739
+ else if(current_pos.x+current_pos.w > border.x+border.w){
740
+ current_pos.x=border.x+border.w-current_pos.w;
741
+ xpos=current_pos.x;
742
+ xppms=-xppms;
743
+ flag=true;
744
+ }
745
+ if(current_pos.y<border.y){
746
+ current_pos.y=border.y;
747
+ ypos=current_pos.y;
748
+ yppms=-yppms;
749
+ flag=true;
750
+ }
751
+ else if(current_pos.y+current_pos.h > border.y+border.h){
752
+ current_pos.y=border.y+border.h-current_pos.h;
753
+ ypos=current_pos.y;
754
+ yppms=-yppms;
755
+ flag=true;
756
+ }
757
+ return flag;
758
+ }
759
+
760
+
761
+ #endif /* _SGE_NO_CLASSES */
762
+