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,365 @@
1
+ /*
2
+ * SDL Graphics Extension
3
+ * SGE shape (header)
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
+ #ifndef sge_shape_H
19
+ #define sge_shape_H
20
+
21
+ #include "SDL.h"
22
+ #include "sge_internal.h"
23
+
24
+ #ifndef _SGE_NO_CLASSES
25
+
26
+ // Remove "class 'std::list<>' needs to have dll-interface to be used" warnings
27
+ // from MS VisualC++
28
+ #ifdef _MSC_VER
29
+ #pragma warning(push)
30
+ #pragma warning(disable: 4251)
31
+ #endif
32
+
33
+
34
+ #include <list>
35
+ #include "sge_surface.h"
36
+ #include "sge_collision.h"
37
+
38
+ class DECLSPEC sge_shape;
39
+
40
+ //==================================================================================
41
+ // The screen class
42
+ //==================================================================================
43
+ class DECLSPEC sge_screen
44
+ {
45
+ protected:
46
+ SDL_Surface *screen; //The SDL screen surface
47
+ std::list<SDL_Rect> rects; //The list of rectangles to be updated
48
+
49
+ std::list<sge_shape*> shapes; //The list of shapes to draw on screen
50
+ std::list<sge_shape*> shapes_p; //The list of permanent shapes to draw on screen
51
+
52
+ typedef std::list<SDL_Rect>::const_iterator RI; //List iterator (for rects)
53
+ typedef std::list<sge_shape*>::const_iterator SI; //List iterator (for shapes)
54
+
55
+ bool HW, DB, FS; //video memory, double-buffered or/and fullscreen?
56
+
57
+ public:
58
+ sge_screen(SDL_Surface *screen);
59
+ ~sge_screen(void){rects.clear();shapes.clear();shapes_p.clear();}
60
+ void add_rect(SDL_Rect rect);
61
+ void add_rect(Sint16 x, Sint16 y, Uint32 w, Uint32 h);
62
+
63
+ void add_shape(sge_shape *shape);
64
+ void add_shape_p(sge_shape *shape); //Adds an shape permanently
65
+
66
+ void remove_shape_p(sge_shape *shape);
67
+ void clear_all(void);
68
+
69
+ void update(void);
70
+ };
71
+
72
+
73
+ //==================================================================================
74
+ // sge_shape
75
+ // Abstract base class for different shapes (surfaces, sprites, ...)
76
+ //==================================================================================
77
+ class sge_shape
78
+ {
79
+ protected:
80
+ SDL_Rect current_pos; //The *current* (maybe undrawn) position of the shape
81
+ SDL_Rect last_pos; //The *last* drawn position of shape
82
+ SDL_Rect prev_pos; //The previous drawn position of shape (used to update a cleared area)
83
+
84
+ SDL_Surface *dest; //The surface to perform operations on
85
+
86
+ public:
87
+ virtual ~sge_shape(void){} //Destructor
88
+ virtual void draw(void)=0; //Draws the shape - prev_pos = last_pos; last_pos = the new position of shape
89
+
90
+ //Updates the screen (last_pos+prev_pos)
91
+ //If sge_screen is used this member will use it (the_screen) instead of doing it directly!
92
+ virtual void UpdateRects(void)=0;
93
+
94
+ //Some functions to clear (remove) shape
95
+ virtual void clear(Uint32 color)=0; //Clears to color
96
+ virtual void clear(SDL_Surface *src, Sint16 srcX, Sint16 srcY)=0; //Clears by blitting src
97
+
98
+ inline SDL_Rect get_pos(void) const{return current_pos;} //Returns the current position
99
+ inline SDL_Rect get_last_pos(void) const{return last_pos;} //Returns the last updated position
100
+
101
+ inline SDL_Surface* get_dest(void) const{return dest;}
102
+
103
+ /*
104
+ //NW N NE
105
+ // \|/
106
+ // W-C-E
107
+ // /|\
108
+ //SW S SE
109
+ //
110
+ //Returns some usefull coords in shape (current)
111
+ */
112
+ inline Sint16 c_x(void) const{return current_pos.x+current_pos.w/2;}
113
+ inline Sint16 c_y(void) const{return current_pos.y+current_pos.h/2;}
114
+
115
+ inline Sint16 nw_x(void) const{return current_pos.x;}
116
+ inline Sint16 nw_y(void) const{return current_pos.y;}
117
+
118
+ inline Sint16 n_x(void) const{return current_pos.x+current_pos.w/2;}
119
+ inline Sint16 n_y(void) const{return current_pos.y;}
120
+
121
+ inline Sint16 ne_x(void) const{return current_pos.x+current_pos.w-1;}
122
+ inline Sint16 ne_y(void) const{return current_pos.y;}
123
+
124
+ inline Sint16 e_x(void) const{return current_pos.x+current_pos.w-1;}
125
+ inline Sint16 e_y(void) const{return current_pos.y+current_pos.h/2;}
126
+
127
+ inline Sint16 se_x(void) const{return current_pos.x+current_pos.w-1;}
128
+ inline Sint16 se_y(void) const{return current_pos.y+current_pos.h-1;}
129
+
130
+ inline Sint16 s_x(void) const{return current_pos.x+current_pos.w/2;}
131
+ inline Sint16 s_y(void) const{return current_pos.y+current_pos.h-1;}
132
+
133
+ inline Sint16 sw_x(void) const{return current_pos.x;}
134
+ inline Sint16 sw_y(void) const{return current_pos.y+current_pos.h-1;}
135
+
136
+ inline Sint16 w_x(void) const{return current_pos.x;}
137
+ inline Sint16 w_y(void) const{return current_pos.y+current_pos.h/2;}
138
+
139
+ inline Sint16 get_xpos(void) const{return current_pos.x;}
140
+ inline Sint16 get_ypos(void) const{return current_pos.y;}
141
+ inline Sint16 get_w(void) const{return current_pos.w;}
142
+ inline Sint16 get_h(void) const{return current_pos.h;}
143
+ };
144
+
145
+
146
+
147
+ //==================================================================================
148
+ // sge_surface (derived from sge_shape)
149
+ // A class for moving/blitting surfaces
150
+ //==================================================================================
151
+ class DECLSPEC sge_surface: public sge_shape
152
+ {
153
+ protected:
154
+ SDL_Surface *surface; //The source surface *NOT COPIED*
155
+
156
+ //Do warp logic
157
+ bool check_warp(void);
158
+
159
+ //Handles outside screen problems (But not in this class)
160
+ virtual bool check_border(void){return check_warp();}
161
+
162
+ //The border box (default: the screen size)
163
+ SDL_Rect border;
164
+
165
+ //Should we warp around the border box? (not in this class
166
+ //but some methods here must know)
167
+ bool warp_border;
168
+
169
+ //Decode a warp pos rectangle
170
+ int get_warp(SDL_Rect rec, SDL_Rect &r1, SDL_Rect &r2, SDL_Rect &r3, SDL_Rect &r4);
171
+
172
+ //Helper functions
173
+ void warp_draw(void);
174
+ void warp_update(SDL_Rect rec);
175
+ void warp_clear(Uint32 color);
176
+ void warp_clear(SDL_Surface *src, Sint16 srcX, Sint16 srcY);
177
+
178
+ public:
179
+ sge_surface(SDL_Surface *dest, SDL_Surface *src, Sint16 x=0, Sint16 y=0);
180
+ ~sge_surface(void);
181
+
182
+ //Draws the surface
183
+ virtual void draw(void);
184
+
185
+ virtual inline void clear(Uint32 color);
186
+ virtual inline void clear(SDL_Surface *src, Sint16 srcX, Sint16 srcY);
187
+ //virtual inline void clear(SDL_Surface *src){clear(src,last_pos.x,last_pos.y);}
188
+
189
+ virtual void UpdateRects(void);
190
+
191
+ //Move the surface
192
+ virtual inline void move_to(Sint16 x, Sint16 y){current_pos.x=x; current_pos.y=y;check_border();}
193
+ virtual inline void move(Sint16 x_step, Sint16 y_step){current_pos.x+=x_step; current_pos.y+=y_step; check_border();}
194
+
195
+ //Get pointer to surface
196
+ SDL_Surface* get_img(void) const{return surface;}
197
+
198
+ //Sets the border box
199
+ void set_border(SDL_Rect box){border=box;}
200
+ };
201
+
202
+
203
+
204
+ //==================================================================================
205
+ // The frame struct (for sge_ssprite)
206
+ //==================================================================================
207
+ struct sge_frame
208
+ {
209
+ //The image
210
+ SDL_Surface *img;
211
+
212
+ //Collision data
213
+ sge_cdata *cdata;
214
+ };
215
+
216
+
217
+ //==================================================================================
218
+ // sge_ssprite (derived from sge_surface)
219
+ // A simple sprite class
220
+ //==================================================================================
221
+ class DECLSPEC sge_ssprite: public sge_surface
222
+ {
223
+ public:enum playing_mode{loop, play_once, stop}; //This must be public
224
+
225
+ protected:
226
+ //Linked list with the frames
227
+ //Obs! 'surface' always points to the current frame image
228
+ std::list<sge_frame*> frames;
229
+ typedef std::list<sge_frame*>::const_iterator FI; //List iterator (for frames)
230
+
231
+ FI current_fi;
232
+ FI fi_start; //first frame in the playing sequence loop
233
+ FI fi_stop; //last frame + 1
234
+
235
+ //The pointer to the current frame
236
+ sge_frame *current_frame; //Should at all times be *current_fi
237
+
238
+ //The speed of the sprite (pixels/update)
239
+ Sint16 xvel, yvel;
240
+
241
+ bool bounce_border; //Do we want the sprite to bounce at the border?
242
+ virtual bool check_border(void);
243
+
244
+ //Playing sequence mode
245
+ playing_mode seq_mode;
246
+
247
+ public:
248
+
249
+ //Constructor and destructor
250
+ sge_ssprite(SDL_Surface *screen, SDL_Surface *img, Sint16 x=0, Sint16 y=0);
251
+ sge_ssprite(SDL_Surface *screen, SDL_Surface *img, sge_cdata *cdata, Sint16 x=0, Sint16 y=0);
252
+ ~sge_ssprite(void);
253
+
254
+ //Updates the internal status
255
+ //Returns true if the sprite moved
256
+ virtual inline bool update(void);
257
+
258
+ //Sets the speed
259
+ void set_vel(Sint16 x, Sint16 y){xvel=x;yvel=y;}
260
+ void set_xvel(Sint16 x){xvel=x;}
261
+ void set_yvel(Sint16 y){yvel=y;}
262
+
263
+ //Gets the speed
264
+ Sint16 get_xvel(void) const{return xvel;}
265
+ Sint16 get_yvel(void) const{return yvel;}
266
+
267
+ //Add a frame
268
+ //Obs! Resets playing sequence
269
+ void add_frame(SDL_Surface *img);
270
+ void add_frame(SDL_Surface *img, sge_cdata *cdata);
271
+
272
+ //Change frame
273
+ void skip_frame(int skips); //A negative 'skips' indicates backwards
274
+ void next_frame(void){skip_frame(1);}
275
+ void prev_frame(void){skip_frame(-1);}
276
+ void first_frame(void); //Does NOT change the sequence
277
+ void last_frame(void); // "
278
+
279
+ //Changes playing sequence (0- first frame)
280
+ //playing_mode:
281
+ // sge_ssprite::loop - loops forever
282
+ // sge_ssprite::play_once - just once then stops
283
+ // sge_ssprite::stop - is returned by get_PlayingMode() if stoped
284
+ void set_seq(int start, int stop, playing_mode mode=loop);
285
+ void reset_seq(void);
286
+ playing_mode get_PlayingMode(void){return seq_mode;}
287
+
288
+ //Get cdata for current frame
289
+ sge_cdata* get_cdata(void){return current_frame->cdata;}
290
+
291
+ //Get the current frame
292
+ sge_frame* get_frame(void){return current_frame;}
293
+
294
+ //Get the frame list
295
+ //DO NOT ADD OR REMOVE ELEMENTS without using
296
+ //reset_seq() when done!!
297
+ std::list<sge_frame*>* get_list(void){return &frames;}
298
+
299
+ //Set border mode:
300
+ //Bounce - sprite bounces (default)
301
+ //Warp - sprite warps at border
302
+ void border_bounce(bool mode){bounce_border=mode; if(warp_border){warp_border=false;}}
303
+ void border_warp(bool mode){warp_border=mode; if(bounce_border){bounce_border=false;}}
304
+ };
305
+
306
+
307
+ //==================================================================================
308
+ // sge_sprite (derived from sge_ssprite)
309
+ // A timed sprite class
310
+ //==================================================================================
311
+ class DECLSPEC sge_sprite: public sge_ssprite
312
+ {
313
+ protected:
314
+ //Pixels/ms
315
+ double xppms, yppms;
316
+
317
+ //Frames/ms
318
+ double fpms;
319
+
320
+ //The float pos
321
+ double xpos, ypos, fpos;
322
+
323
+ //Ticks since last pos update
324
+ Uint32 tlast;
325
+
326
+ virtual bool check_border(void);
327
+ public:
328
+ //Constructor
329
+ sge_sprite(SDL_Surface *screen, SDL_Surface *img, Sint16 x=0, Sint16 y=0):
330
+ sge_ssprite(screen,img,x,y){xppms=yppms=fpms=0;tlast=0;xpos=x;ypos=y;fpos=0;}
331
+
332
+ sge_sprite(SDL_Surface *screen, SDL_Surface *img, sge_cdata *cdata, Sint16 x=0, Sint16 y=0):
333
+ sge_ssprite(screen,img,cdata,x,y){xppms=yppms=fpms=0;tlast=0;xpos=x;ypos=y;fpos=0;}
334
+
335
+ //Change the speeds
336
+ void set_pps(Sint16 x, Sint16 y){xppms=x/1000.0; yppms=y/1000.0;}
337
+ void set_xpps(Sint16 x){xppms=x/1000.0;}
338
+ void set_ypps(Sint16 y){yppms=y/1000.0;}
339
+ void set_fps(Sint16 f){fpms=f/1000.0;}
340
+
341
+ //Get the speeds
342
+ Sint16 get_xpps(void) const{return Sint16(xppms*1000);}
343
+ Sint16 get_ypps(void) const{return Sint16(yppms*1000);}
344
+ Sint16 get_fps(void) const{return Sint16(fpms*1000);}
345
+
346
+ //Update position and frame
347
+ //Returns true if something changed
348
+ bool update(Uint32 ticks);
349
+ bool update(void){return update(SDL_GetTicks());}
350
+
351
+ //Correct move members for this class
352
+ void move_to(Sint16 x, Sint16 y){sge_surface::move_to(x,y); xpos=current_pos.x; ypos=current_pos.y;}
353
+ void move(Sint16 x_step, Sint16 y_step){sge_surface::move(x_step,y_step); xpos=current_pos.x; ypos=current_pos.y;}
354
+
355
+ //Freeze time until next update
356
+ void pause(void){tlast=0;}
357
+ };
358
+
359
+
360
+ #ifdef _MSC_VER
361
+ #pragma warning(pop)
362
+ #endif
363
+
364
+ #endif /* _SGE_NO_CLASSES */
365
+ #endif /* sge_shape_H */
@@ -0,0 +1,1090 @@
1
+ /*
2
+ * SDL Graphics Extension
3
+ * Pixel, surface and color functions
4
+ *
5
+ * Started 990815 (split from sge_draw 010611)
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
+ /*
19
+ * Some of this code is taken from the "Introduction to SDL" and
20
+ * John Garrison's PowerPak
21
+ */
22
+
23
+ #include "SDL.h"
24
+ #include <math.h>
25
+ #include <string.h>
26
+ #include <stdarg.h>
27
+ #include "sge_surface.h"
28
+
29
+
30
+ /* Globals used for sge_Update/sge_Lock */
31
+ Uint8 _sge_update=1;
32
+ Uint8 _sge_lock=1;
33
+
34
+
35
+ /**********************************************************************************/
36
+ /** Misc. functions **/
37
+ /**********************************************************************************/
38
+
39
+ //==================================================================================
40
+ // Turns off automatic update (to avoid tearing).
41
+ //==================================================================================
42
+ void sge_Update_OFF(void)
43
+ {
44
+ _sge_update=0;
45
+ }
46
+
47
+ //==================================================================================
48
+ // Turns on automatic update (default)
49
+ //==================================================================================
50
+ void sge_Update_ON(void)
51
+ {
52
+ _sge_update=1;
53
+ }
54
+
55
+ //==================================================================================
56
+ // Turns off automatic locking of surfaces
57
+ //==================================================================================
58
+ void sge_Lock_OFF(void)
59
+ {
60
+ _sge_lock=0;
61
+ }
62
+
63
+ //==================================================================================
64
+ // Turns on automatic locking (default)
65
+ //==================================================================================
66
+ void sge_Lock_ON(void)
67
+ {
68
+ _sge_lock=1;
69
+ }
70
+
71
+ //==================================================================================
72
+ // Returns update&locking mode (1-on and 0-off)
73
+ //==================================================================================
74
+ Uint8 sge_getUpdate(void)
75
+ {
76
+ return _sge_update;
77
+ }
78
+ Uint8 sge_getLock(void)
79
+ {
80
+ return _sge_lock;
81
+ }
82
+
83
+
84
+ //==================================================================================
85
+ // SDL_UpdateRect does nothing if any part of the rectangle is outside the surface
86
+ // --- This version always work
87
+ //==================================================================================
88
+ void sge_UpdateRect(SDL_Surface *screen, Sint16 x, Sint16 y, Uint16 w, Uint16 h)
89
+ {
90
+ if(_sge_update!=1 || screen != SDL_GetVideoSurface()){return;}
91
+
92
+ if(x>=screen->w || y>=screen->h){return;}
93
+
94
+ Sint16 a,b;
95
+
96
+ a=w; b=h;
97
+
98
+
99
+ if(x < 0){x=0;}
100
+ if(y < 0){y=0;}
101
+
102
+ if(a+x > screen->w){a=screen->w-x;}
103
+ if(b+y > screen->h){b=screen->h-y;}
104
+
105
+ SDL_UpdateRect(screen,x,y,a,b);
106
+ }
107
+
108
+
109
+ //==================================================================================
110
+ // Creates a 32bit (8/8/8/8) alpha surface
111
+ // Map colors with sge_MapAlpha() and then use the Uint32 color versions of
112
+ // SGEs routines
113
+ //==================================================================================
114
+ SDL_Surface *sge_CreateAlphaSurface(Uint32 flags, int width, int height)
115
+ {
116
+ return SDL_CreateRGBSurface(flags,width,height,32, 0xFF000000, 0x00FF0000, 0x0000FF00, 0x000000FF);
117
+ }
118
+
119
+
120
+ //==================================================================================
121
+ // Returns the Uint32 color value for a 32bit (8/8/8/8) alpha surface
122
+ //==================================================================================
123
+ Uint32 sge_MapAlpha(Uint8 R, Uint8 G, Uint8 B, Uint8 A)
124
+ {
125
+ Uint32 color=0;
126
+
127
+ color|=R<<24;
128
+ color|=G<<16;
129
+ color|=B<<8;
130
+ color|=A;
131
+
132
+ return color;
133
+ }
134
+
135
+
136
+ //==================================================================================
137
+ // Sets an SDL error string
138
+ // Accepts formated argument - like printf()
139
+ // SDL_SetError() also does this, but it does not use standard syntax (why?)
140
+ //==================================================================================
141
+ void sge_SetError(const char *format, ...)
142
+ {
143
+ char buf[256];
144
+
145
+ va_list ap;
146
+
147
+ #ifdef __WIN32__
148
+ va_start((va_list*)ap, format); //Stupid w32 crosscompiler
149
+ #else
150
+ va_start(ap, format);
151
+ #endif
152
+
153
+ vsprintf(buf, format, ap);
154
+ va_end(ap);
155
+
156
+ SDL_SetError(buf);
157
+ }
158
+
159
+
160
+
161
+ /**********************************************************************************/
162
+ /** Pixel functions **/
163
+ /**********************************************************************************/
164
+
165
+ //==================================================================================
166
+ // Fast put pixel
167
+ //==================================================================================
168
+ void _PutPixel(SDL_Surface *surface, Sint16 x, Sint16 y, Uint32 color)
169
+ {
170
+ if(x>=sge_clip_xmin(surface) && x<=sge_clip_xmax(surface) && y>=sge_clip_ymin(surface) && y<=sge_clip_ymax(surface)){
171
+ switch (surface->format->BytesPerPixel) {
172
+ case 1: { /* Assuming 8-bpp */
173
+ *((Uint8 *)surface->pixels + y*surface->pitch + x) = color;
174
+ }
175
+ break;
176
+
177
+ case 2: { /* Probably 15-bpp or 16-bpp */
178
+ *((Uint16 *)surface->pixels + y*surface->pitch/2 + x) = color;
179
+ }
180
+ break;
181
+
182
+ case 3: { /* Slow 24-bpp mode, usually not used */
183
+ Uint8 *pix = (Uint8 *)surface->pixels + y * surface->pitch + x*3;
184
+
185
+ /* Gack - slow, but endian correct */
186
+ *(pix+surface->format->Rshift/8) = color>>surface->format->Rshift;
187
+ *(pix+surface->format->Gshift/8) = color>>surface->format->Gshift;
188
+ *(pix+surface->format->Bshift/8) = color>>surface->format->Bshift;
189
+ *(pix+surface->format->Ashift/8) = color>>surface->format->Ashift;
190
+ }
191
+ break;
192
+
193
+ case 4: { /* Probably 32-bpp */
194
+ *((Uint32 *)surface->pixels + y*surface->pitch/4 + x) = color;
195
+ }
196
+ break;
197
+ }
198
+ }
199
+
200
+ }
201
+
202
+
203
+ //==================================================================================
204
+ // Fast put pixel (RGB)
205
+ //==================================================================================
206
+ void _PutPixel(SDL_Surface *surface, Sint16 x, Sint16 y, Uint8 R, Uint8 G, Uint8 B)
207
+ {
208
+ _PutPixel(surface,x,y, SDL_MapRGB(surface->format, R, G, B));
209
+ }
210
+
211
+
212
+ //==================================================================================
213
+ // Fastest put pixel functions (don't mess up indata, thank you)
214
+ //==================================================================================
215
+ void _PutPixel8(SDL_Surface *surface, Sint16 x, Sint16 y, Uint32 color)
216
+ {
217
+ *((Uint8 *)surface->pixels + y*surface->pitch + x) = color;
218
+ }
219
+ void _PutPixel16(SDL_Surface *surface, Sint16 x, Sint16 y, Uint32 color)
220
+ {
221
+ *((Uint16 *)surface->pixels + y*surface->pitch/2 + x) = color;
222
+ }
223
+ void _PutPixel24(SDL_Surface *surface, Sint16 x, Sint16 y, Uint32 color)
224
+ {
225
+ Uint8 *pix = (Uint8 *)surface->pixels + y * surface->pitch + x*3;
226
+
227
+ /* Gack - slow, but endian correct */
228
+ *(pix+surface->format->Rshift/8) = color>>surface->format->Rshift;
229
+ *(pix+surface->format->Gshift/8) = color>>surface->format->Gshift;
230
+ *(pix+surface->format->Bshift/8) = color>>surface->format->Bshift;
231
+ *(pix+surface->format->Ashift/8) = color>>surface->format->Ashift;
232
+ }
233
+ void _PutPixel32(SDL_Surface *surface, Sint16 x, Sint16 y, Uint32 color)
234
+ {
235
+ *((Uint32 *)surface->pixels + y*surface->pitch/4 + x) = color;
236
+ }
237
+ void _PutPixelX(SDL_Surface *dest,Sint16 x,Sint16 y,Uint32 color)
238
+ {
239
+ switch ( dest->format->BytesPerPixel ) {
240
+ case 1:
241
+ *((Uint8 *)dest->pixels + y*dest->pitch + x) = color;
242
+ break;
243
+ case 2:
244
+ *((Uint16 *)dest->pixels + y*dest->pitch/2 + x) = color;
245
+ break;
246
+ case 3:
247
+ _PutPixel24(dest,x,y,color);
248
+ break;
249
+ case 4:
250
+ *((Uint32 *)dest->pixels + y*dest->pitch/4 + x) = color;
251
+ break;
252
+ }
253
+ }
254
+
255
+
256
+ //==================================================================================
257
+ // Safe put pixel
258
+ //==================================================================================
259
+ void sge_PutPixel(SDL_Surface *surface, Sint16 x, Sint16 y, Uint32 color)
260
+ {
261
+
262
+ if ( SDL_MUSTLOCK(surface) && _sge_lock ) {
263
+ if ( SDL_LockSurface(surface) < 0 ) {
264
+ return;
265
+ }
266
+ }
267
+
268
+ _PutPixel(surface, x, y, color);
269
+
270
+ if ( SDL_MUSTLOCK(surface) && _sge_lock ) {
271
+ SDL_UnlockSurface(surface);
272
+ }
273
+
274
+ if(_sge_update!=1){return;}
275
+ sge_UpdateRect(surface, x, y, 1, 1);
276
+ }
277
+
278
+
279
+ //==================================================================================
280
+ // Safe put pixel (RGB)
281
+ //==================================================================================
282
+ void sge_PutPixel(SDL_Surface *surface, Sint16 x, Sint16 y, Uint8 R, Uint8 G, Uint8 B)
283
+ {
284
+ sge_PutPixel(surface,x,y, SDL_MapRGB(surface->format, R, G, B));
285
+ }
286
+
287
+
288
+ //==================================================================================
289
+ // Calculate y pitch offset
290
+ // (the y pitch offset is constant for the same y coord and surface)
291
+ //==================================================================================
292
+ Sint32 sge_CalcYPitch(SDL_Surface *dest,Sint16 y)
293
+ {
294
+ if(y>=sge_clip_ymin(dest) && y<=sge_clip_ymax(dest)){
295
+ switch ( dest->format->BytesPerPixel ) {
296
+ case 1:
297
+ return y*dest->pitch;
298
+ break;
299
+ case 2:
300
+ return y*dest->pitch/2;
301
+ break;
302
+ case 3:
303
+ return y*dest->pitch;
304
+ break;
305
+ case 4:
306
+ return y*dest->pitch/4;
307
+ break;
308
+ }
309
+ }
310
+
311
+ return -1;
312
+ }
313
+
314
+
315
+ //==================================================================================
316
+ // Put pixel with precalculated y pitch offset
317
+ //==================================================================================
318
+ void sge_pPutPixel(SDL_Surface *surface, Sint16 x, Sint32 ypitch, Uint32 color)
319
+ {
320
+ if(x>=sge_clip_xmin(surface) && x<=sge_clip_xmax(surface) && ypitch>=0){
321
+ switch (surface->format->BytesPerPixel) {
322
+ case 1: { /* Assuming 8-bpp */
323
+ *((Uint8 *)surface->pixels + ypitch + x) = color;
324
+ }
325
+ break;
326
+
327
+ case 2: { /* Probably 15-bpp or 16-bpp */
328
+ *((Uint16 *)surface->pixels + ypitch + x) = color;
329
+ }
330
+ break;
331
+
332
+ case 3: { /* Slow 24-bpp mode, usually not used */
333
+ /* Gack - slow, but endian correct */
334
+ Uint8 *pix = (Uint8 *)surface->pixels + ypitch + x*3;
335
+
336
+ *(pix+surface->format->Rshift/8) = color>>surface->format->Rshift;
337
+ *(pix+surface->format->Gshift/8) = color>>surface->format->Gshift;
338
+ *(pix+surface->format->Bshift/8) = color>>surface->format->Bshift;
339
+ *(pix+surface->format->Ashift/8) = color>>surface->format->Ashift;
340
+ }
341
+ break;
342
+
343
+ case 4: { /* Probably 32-bpp */
344
+ *((Uint32 *)surface->pixels + ypitch + x) = color;
345
+ }
346
+ break;
347
+ }
348
+ }
349
+ }
350
+
351
+
352
+ //==================================================================================
353
+ // Get pixel
354
+ //==================================================================================
355
+ Uint32 sge_GetPixel(SDL_Surface *surface, Sint16 x, Sint16 y)
356
+ {
357
+ if(x<0 || x>=surface->w || y<0 || y>=surface->h)
358
+ return 0;
359
+
360
+ switch (surface->format->BytesPerPixel) {
361
+ case 1: { /* Assuming 8-bpp */
362
+ return *((Uint8 *)surface->pixels + y*surface->pitch + x);
363
+ }
364
+ break;
365
+
366
+ case 2: { /* Probably 15-bpp or 16-bpp */
367
+ return *((Uint16 *)surface->pixels + y*surface->pitch/2 + x);
368
+ }
369
+ break;
370
+
371
+ case 3: { /* Slow 24-bpp mode, usually not used */
372
+ Uint8 *pix;
373
+ int shift;
374
+ Uint32 color=0;
375
+
376
+ pix = (Uint8 *)surface->pixels + y * surface->pitch + x*3;
377
+ shift = surface->format->Rshift;
378
+ color = *(pix+shift/8)<<shift;
379
+ shift = surface->format->Gshift;
380
+ color|= *(pix+shift/8)<<shift;
381
+ shift = surface->format->Bshift;
382
+ color|= *(pix+shift/8)<<shift;
383
+ shift = surface->format->Ashift;
384
+ color|= *(pix+shift/8)<<shift;
385
+ return color;
386
+ }
387
+ break;
388
+
389
+ case 4: { /* Probably 32-bpp */
390
+ return *((Uint32 *)surface->pixels + y*surface->pitch/4 + x);
391
+ }
392
+ break;
393
+ }
394
+ return 0;
395
+ }
396
+
397
+
398
+ //==================================================================================
399
+ // Put pixel with alpha blending
400
+ //==================================================================================
401
+ void _PutPixelAlpha(SDL_Surface *surface, Sint16 x, Sint16 y, Uint32 color, Uint8 alpha)
402
+ {
403
+ if(x>=sge_clip_xmin(surface) && x<=sge_clip_xmax(surface) && y>=sge_clip_ymin(surface) && y<=sge_clip_ymax(surface)){
404
+ Uint32 Rmask = surface->format->Rmask, Gmask = surface->format->Gmask, Bmask = surface->format->Bmask, Amask = surface->format->Amask;
405
+ Uint32 R,G,B,A=0;
406
+
407
+ switch (surface->format->BytesPerPixel) {
408
+ case 1: { /* Assuming 8-bpp */
409
+ if( alpha == 255 ){
410
+ *((Uint8 *)surface->pixels + y*surface->pitch + x) = color;
411
+ }else{
412
+ Uint8 *pixel = (Uint8 *)surface->pixels + y*surface->pitch + x;
413
+
414
+ Uint8 dR = surface->format->palette->colors[*pixel].r;
415
+ Uint8 dG = surface->format->palette->colors[*pixel].g;
416
+ Uint8 dB = surface->format->palette->colors[*pixel].b;
417
+ Uint8 sR = surface->format->palette->colors[color].r;
418
+ Uint8 sG = surface->format->palette->colors[color].g;
419
+ Uint8 sB = surface->format->palette->colors[color].b;
420
+
421
+ dR = dR + ((sR-dR)*alpha >> 8);
422
+ dG = dG + ((sG-dG)*alpha >> 8);
423
+ dB = dB + ((sB-dB)*alpha >> 8);
424
+
425
+ *pixel = SDL_MapRGB(surface->format, dR, dG, dB);
426
+ }
427
+ }
428
+ break;
429
+
430
+ case 2: { /* Probably 15-bpp or 16-bpp */
431
+ if( alpha == 255 ){
432
+ *((Uint16 *)surface->pixels + y*surface->pitch/2 + x) = color;
433
+ }else{
434
+ Uint16 *pixel = (Uint16 *)surface->pixels + y*surface->pitch/2 + x;
435
+ Uint32 dc = *pixel;
436
+
437
+ R = ((dc & Rmask) + (( (color & Rmask) - (dc & Rmask) ) * alpha >> 8)) & Rmask;
438
+ G = ((dc & Gmask) + (( (color & Gmask) - (dc & Gmask) ) * alpha >> 8)) & Gmask;
439
+ B = ((dc & Bmask) + (( (color & Bmask) - (dc & Bmask) ) * alpha >> 8)) & Bmask;
440
+ if( Amask )
441
+ A = ((dc & Amask) + (( (color & Amask) - (dc & Amask) ) * alpha >> 8)) & Amask;
442
+
443
+ *pixel= R | G | B | A;
444
+ }
445
+ }
446
+ break;
447
+
448
+ case 3: { /* Slow 24-bpp mode, usually not used */
449
+ Uint8 *pix = (Uint8 *)surface->pixels + y * surface->pitch + x*3;
450
+ Uint8 rshift8=surface->format->Rshift/8;
451
+ Uint8 gshift8=surface->format->Gshift/8;
452
+ Uint8 bshift8=surface->format->Bshift/8;
453
+ Uint8 ashift8=surface->format->Ashift/8;
454
+
455
+
456
+ if( alpha == 255 ){
457
+ *(pix+rshift8) = color>>surface->format->Rshift;
458
+ *(pix+gshift8) = color>>surface->format->Gshift;
459
+ *(pix+bshift8) = color>>surface->format->Bshift;
460
+ *(pix+ashift8) = color>>surface->format->Ashift;
461
+ }else{
462
+ Uint8 dR, dG, dB, dA=0;
463
+ Uint8 sR, sG, sB, sA=0;
464
+
465
+ pix = (Uint8 *)surface->pixels + y * surface->pitch + x*3;
466
+
467
+ dR = *((pix)+rshift8);
468
+ dG = *((pix)+gshift8);
469
+ dB = *((pix)+bshift8);
470
+ dA = *((pix)+ashift8);
471
+
472
+ sR = (color>>surface->format->Rshift)&0xff;
473
+ sG = (color>>surface->format->Gshift)&0xff;
474
+ sB = (color>>surface->format->Bshift)&0xff;
475
+ sA = (color>>surface->format->Ashift)&0xff;
476
+
477
+ dR = dR + ((sR-dR)*alpha >> 8);
478
+ dG = dG + ((sG-dG)*alpha >> 8);
479
+ dB = dB + ((sB-dB)*alpha >> 8);
480
+ dA = dA + ((sA-dA)*alpha >> 8);
481
+
482
+ *((pix)+rshift8) = dR;
483
+ *((pix)+gshift8) = dG;
484
+ *((pix)+bshift8) = dB;
485
+ *((pix)+ashift8) = dA;
486
+ }
487
+ }
488
+ break;
489
+
490
+ case 4: { /* Probably 32-bpp */
491
+ if( alpha == 255 ){
492
+ *((Uint32 *)surface->pixels + y*surface->pitch/4 + x) = color;
493
+ }else{
494
+ Uint32 *pixel = (Uint32 *)surface->pixels + y*surface->pitch/4 + x;
495
+ Uint32 dc = *pixel;
496
+
497
+ R = ((dc & Rmask) + (( (color & Rmask) - (dc & Rmask) ) * alpha >> 8)) & Rmask;
498
+ G = ((dc & Gmask) + (( (color & Gmask) - (dc & Gmask) ) * alpha >> 8)) & Gmask;
499
+ B = ((dc & Bmask) + (( (color & Bmask) - (dc & Bmask) ) * alpha >> 8)) & Bmask;
500
+ if( Amask )
501
+ A = ((dc & Amask) + (( (color & Amask) - (dc & Amask) ) * alpha >> 8)) & Amask;
502
+
503
+ *pixel = R | G | B | A;
504
+ }
505
+ }
506
+ break;
507
+ }
508
+ }
509
+ }
510
+
511
+ void sge_PutPixelAlpha(SDL_Surface *surface, Sint16 x, Sint16 y, Uint32 color, Uint8 alpha)
512
+ {
513
+ if ( SDL_MUSTLOCK(surface) && _sge_lock )
514
+ if ( SDL_LockSurface(surface) < 0 )
515
+ return;
516
+
517
+ _PutPixelAlpha(surface,x,y,color,alpha);
518
+
519
+ /* unlock the display */
520
+ if (SDL_MUSTLOCK(surface) && _sge_lock) {
521
+ SDL_UnlockSurface(surface);
522
+ }
523
+
524
+ if(_sge_update!=1){return;}
525
+ sge_UpdateRect(surface, x, y, 1, 1);
526
+ }
527
+
528
+
529
+ void _PutPixelAlpha(SDL_Surface *surface, Sint16 x, Sint16 y, Uint8 R, Uint8 G, Uint8 B, Uint8 alpha)
530
+ {
531
+ _PutPixelAlpha(surface,x,y, SDL_MapRGB(surface->format, R, G, B),alpha);
532
+ }
533
+ void sge_PutPixelAlpha(SDL_Surface *surface, Sint16 x, Sint16 y, Uint8 R, Uint8 G, Uint8 B, Uint8 alpha)
534
+ {
535
+ sge_PutPixelAlpha(surface,x,y, SDL_MapRGB(surface->format, R, G, B), alpha);
536
+ }
537
+
538
+
539
+
540
+ /**********************************************************************************/
541
+ /** Block functions **/
542
+ /**********************************************************************************/
543
+
544
+ //==================================================================================
545
+ // The sge_write_block* functions copies the given block (a surface line) directly
546
+ // to the surface. This is *much* faster then using the put pixel functions to
547
+ // update a line. The block consist of Surface->w (the width of the surface) numbers
548
+ // of color values. Note the difference in byte size for the block elements for
549
+ // different color dephts. 24 bpp is slow and not included!
550
+ //==================================================================================
551
+ void sge_write_block8(SDL_Surface *Surface, Uint8 *block, Sint16 y)
552
+ {
553
+ memcpy( (Uint8 *)Surface->pixels + y*Surface->pitch, block, sizeof(Uint8)*Surface->w );
554
+ }
555
+ void sge_write_block16(SDL_Surface *Surface, Uint16 *block, Sint16 y)
556
+ {
557
+ memcpy( (Uint16 *)Surface->pixels + y*Surface->pitch/2, block, sizeof(Uint16)*Surface->w );
558
+ }
559
+ void sge_write_block32(SDL_Surface *Surface, Uint32 *block, Sint16 y)
560
+ {
561
+ memcpy( (Uint32 *)Surface->pixels + y*Surface->pitch/4, block, sizeof(Uint32)*Surface->w );
562
+ }
563
+
564
+
565
+ //==================================================================================
566
+ // ...and get
567
+ //==================================================================================
568
+ void sge_read_block8(SDL_Surface *Surface, Uint8 *block, Sint16 y)
569
+ {
570
+ memcpy( block,(Uint8 *)Surface->pixels + y*Surface->pitch, sizeof(Uint8)*Surface->w );
571
+ }
572
+ void sge_read_block16(SDL_Surface *Surface, Uint16 *block, Sint16 y)
573
+ {
574
+ memcpy( block,(Uint16 *)Surface->pixels + y*Surface->pitch/2, sizeof(Uint16)*Surface->w );
575
+ }
576
+ void sge_read_block32(SDL_Surface *Surface, Uint32 *block, Sint16 y)
577
+ {
578
+ memcpy( block,(Uint32 *)Surface->pixels + y*Surface->pitch/4, sizeof(Uint32)*Surface->w );
579
+ }
580
+
581
+
582
+
583
+ /**********************************************************************************/
584
+ /** Blitting/surface functions **/
585
+ /**********************************************************************************/
586
+
587
+ //==================================================================================
588
+ // Clear surface to color
589
+ //==================================================================================
590
+ void sge_ClearSurface(SDL_Surface *Surface, Uint32 color)
591
+ {
592
+
593
+ SDL_FillRect(Surface,NULL, color);
594
+
595
+ if(_sge_update!=1){return;}
596
+ SDL_UpdateRect(Surface, 0,0,0,0);
597
+ }
598
+
599
+
600
+ //==================================================================================
601
+ // Clear surface to color (RGB)
602
+ //==================================================================================
603
+ void sge_ClearSurface(SDL_Surface *Surface, Uint8 R, Uint8 G, Uint8 B)
604
+ {
605
+ sge_ClearSurface(Surface,SDL_MapRGB(Surface->format, R, G, B));
606
+ }
607
+
608
+
609
+ //==================================================================================
610
+ // Blit from one surface to another
611
+ // Warning! Alpha and color key is lost (=0) on Src surface
612
+ //==================================================================================
613
+ int sge_BlitTransparent(SDL_Surface *Src, SDL_Surface *Dest, Sint16 SrcX, Sint16 SrcY, Sint16 DestX, Sint16 DestY, Sint16 W, Sint16 H, Uint32 Clear, Uint8 Alpha)
614
+ {
615
+ SDL_Rect src, dest;
616
+ int ret;
617
+
618
+ /* Dest clipping */
619
+ #if SDL_VERSIONNUM(SDL_MAJOR_VERSION, SDL_MINOR_VERSION, SDL_PATCHLEVEL) < \
620
+ SDL_VERSIONNUM(1, 1, 5)
621
+ int flag=0;
622
+ if (DestX < Dest->clip_minx){
623
+ SrcX += Dest->clip_minx-DestX;
624
+ W -= Dest->clip_minx-DestX-1;
625
+ DestX=Dest->clip_minx;
626
+ }
627
+ if (DestY < Dest->clip_miny){
628
+ SrcY +=Dest->clip_miny-DestY;
629
+ H -= Dest->clip_miny-DestY-1;
630
+ DestY=Dest->clip_miny;
631
+ }
632
+ if ((DestX + W) > Dest->clip_maxx){
633
+ W = W - ((DestX + W) - Dest->clip_maxx)+1;
634
+ if(W<=0){SDL_SetError("SGE - Blit error");return -1;}
635
+ }
636
+ if ((DestY + H) > Dest->clip_maxy){
637
+ H = H - ((DestY + H) - Dest->clip_maxy)+1;
638
+ if(H<=0){SDL_SetError("SGE - Blit error");return -1;}
639
+ }
640
+ #endif
641
+
642
+ /* Initialize our rectangles */
643
+ src.x = SrcX;
644
+ src.y = SrcY;
645
+ src.w = W;
646
+ src.h = H;
647
+
648
+ dest.x = DestX;
649
+ dest.y = DestY;
650
+ dest.w = W;
651
+ dest.h = H;
652
+
653
+ /* We don't care about src clipping, only dest! */
654
+ #if SDL_VERSIONNUM(SDL_MAJOR_VERSION, SDL_MINOR_VERSION, SDL_PATCHLEVEL) < \
655
+ SDL_VERSIONNUM(1, 1, 5)
656
+ if ( (Src->flags & SDL_SRCCLIPPING) == SDL_SRCCLIPPING){
657
+ Src->flags &= ~SDL_SRCCLIPPING; flag=1;
658
+ }
659
+ #endif
660
+
661
+ /* Set the color to be transparent */
662
+ SDL_SetColorKey(Src, SDL_SRCCOLORKEY, Clear);
663
+
664
+ /* Set the alpha value */
665
+ SDL_SetAlpha(Src, SDL_SRCALPHA, Alpha);
666
+
667
+ /* Blit */
668
+ ret=SDL_BlitSurface(Src, &src, Dest, &dest);
669
+
670
+ /* Set the correct flag */
671
+ #if SDL_VERSIONNUM(SDL_MAJOR_VERSION, SDL_MINOR_VERSION, SDL_PATCHLEVEL) < \
672
+ SDL_VERSIONNUM(1, 1, 5)
673
+ if (flag==1){
674
+ Src->flags |= SDL_SRCCLIPPING;
675
+ }
676
+ #endif
677
+
678
+ /* Set normal levels */
679
+ SDL_SetAlpha(Src,0,0);
680
+ SDL_SetColorKey(Src,0,0);
681
+
682
+ return ret;
683
+ }
684
+
685
+
686
+ //==================================================================================
687
+ // Blit from one surface to another (not touching alpha or color key -
688
+ // use SDL_SetColorKey and SDL_SetAlpha)
689
+ //==================================================================================
690
+ int sge_Blit(SDL_Surface *Src, SDL_Surface *Dest, Sint16 SrcX, Sint16 SrcY, Sint16 DestX, Sint16 DestY, Sint16 W, Sint16 H)
691
+ {
692
+ SDL_Rect src, dest;
693
+ int ret;
694
+
695
+ /* Dest clipping */
696
+ #if SDL_VERSIONNUM(SDL_MAJOR_VERSION, SDL_MINOR_VERSION, SDL_PATCHLEVEL) < \
697
+ SDL_VERSIONNUM(1, 1, 5)
698
+ int flag=0;
699
+ if (DestX < Dest->clip_minx){
700
+ SrcX += Dest->clip_minx-DestX;
701
+ W -= Dest->clip_minx-DestX -1;
702
+ DestX=Dest->clip_minx;
703
+ }
704
+ if (DestY < Dest->clip_miny){
705
+ SrcY +=Dest->clip_miny-DestY;
706
+ H -= Dest->clip_miny-DestY -1;
707
+ DestY=Dest->clip_miny;
708
+ }
709
+ if ((DestX + W) > Dest->clip_maxx){
710
+ W = W - ((DestX + W) - Dest->clip_maxx)+1;
711
+ if(W<=0){SDL_SetError("SGE - Blit error");return -1;}
712
+ }
713
+ if ((DestY + H) > Dest->clip_maxy){
714
+ H = H - ((DestY + H) - Dest->clip_maxy)+1;
715
+ if(H<=0){SDL_SetError("SGE - Blit error");return -1;}
716
+ }
717
+ #endif
718
+
719
+ /* Initialize our rectangles */
720
+ src.x = SrcX;
721
+ src.y = SrcY;
722
+ src.w = W;
723
+ src.h = H;
724
+
725
+ dest.x = DestX;
726
+ dest.y = DestY;
727
+ dest.w = W;
728
+ dest.h = H;
729
+
730
+ /* We don't care about src clipping, only dest! */
731
+ #if SDL_VERSIONNUM(SDL_MAJOR_VERSION, SDL_MINOR_VERSION, SDL_PATCHLEVEL) < \
732
+ SDL_VERSIONNUM(1, 1, 5)
733
+ if ( (Src->flags & SDL_SRCCLIPPING) == SDL_SRCCLIPPING){
734
+ Src->flags &= ~SDL_SRCCLIPPING; flag=1;
735
+ }
736
+ #endif
737
+
738
+ /* Blit */
739
+ ret=SDL_BlitSurface(Src, &src, Dest, &dest);
740
+
741
+ /* Set the correct flag */
742
+ #if SDL_VERSIONNUM(SDL_MAJOR_VERSION, SDL_MINOR_VERSION, SDL_PATCHLEVEL) < \
743
+ SDL_VERSIONNUM(1, 1, 5)
744
+ if (flag==1){
745
+ Src->flags |= SDL_SRCCLIPPING;
746
+ }
747
+ #endif
748
+
749
+ return ret;
750
+ }
751
+
752
+
753
+ //==================================================================================
754
+ // Copies a surface to a new...
755
+ //==================================================================================
756
+ SDL_Surface *sge_copy_surface(SDL_Surface *src)
757
+ {
758
+ return SDL_ConvertSurface(src, src->format,SDL_SWSURFACE);
759
+ }
760
+
761
+
762
+
763
+
764
+ /**********************************************************************************/
765
+ /** Palette functions **/
766
+ /**********************************************************************************/
767
+ //==================================================================================
768
+ // Fill in a palette entry with R, G, B componenets
769
+ //==================================================================================
770
+ SDL_Color sge_FillPaletteEntry(Uint8 R, Uint8 G, Uint8 B)
771
+ {
772
+ SDL_Color color;
773
+
774
+ color.r = R;
775
+ color.g = G;
776
+ color.b = B;
777
+
778
+ return color;
779
+ }
780
+
781
+
782
+ //==================================================================================
783
+ // Get the RGB of a color value
784
+ // Needed in those dark days before SDL 1.0
785
+ //==================================================================================
786
+ SDL_Color sge_GetRGB(SDL_Surface *Surface, Uint32 Color)
787
+ {
788
+ SDL_Color rgb;
789
+ SDL_GetRGB(Color, Surface->format, &(rgb.r), &(rgb.g), &(rgb.b));
790
+
791
+ return(rgb);
792
+ }
793
+
794
+
795
+ //==================================================================================
796
+ // Fades from (sR,sG,sB) to (dR,dG,dB), puts result in ctab[start] to ctab[stop]
797
+ //==================================================================================
798
+ void sge_Fader(SDL_Surface *Surface, Uint8 sR,Uint8 sG,Uint8 sB, Uint8 dR,Uint8 dG,Uint8 dB,Uint32 *ctab,int start, int stop)
799
+ {
800
+ // (sR,sG,sB) and (dR,dG,dB) are two points in space (the RGB cube).
801
+
802
+ /* The vector for the straight line */
803
+ int v[3];
804
+ v[0]=dR-sR; v[1]=dG-sG; v[2]=dB-sB;
805
+
806
+ /* Ref. point */
807
+ int x0=sR, y0=sG, z0=sB;
808
+
809
+ // The line's equation is:
810
+ // x= x0 + v[0] * t
811
+ // y= y0 + v[1] * t
812
+ // z= z0 + v[2] * t
813
+ //
814
+ // (x,y,z) will travel between the two points when t goes from 0 to 1.
815
+
816
+ int i=start;
817
+ double step=1.0/((stop+1)-start);
818
+
819
+ for(double t=0.0; t<=1.0 && i<=stop ; t+=step){
820
+ ctab[i++]=SDL_MapRGB(Surface->format, (Uint8)(x0+v[0]*t), (Uint8)(y0+v[1]*t), (Uint8)(z0+v[2]*t) );
821
+ }
822
+ }
823
+
824
+
825
+ //==================================================================================
826
+ // Fades from (sR,sG,sB,sA) to (dR,dG,dB,dA), puts result in ctab[start] to ctab[stop]
827
+ //==================================================================================
828
+ void sge_AlphaFader(Uint8 sR,Uint8 sG,Uint8 sB,Uint8 sA, Uint8 dR,Uint8 dG,Uint8 dB,Uint8 dA, Uint32 *ctab,int start, int stop)
829
+ {
830
+ // (sR,sG,sB,sA) and (dR,dG,dB,dA) are two points in hyperspace (the RGBA hypercube).
831
+
832
+ /* The vector for the straight line */
833
+ int v[4];
834
+ v[0]=dR-sR; v[1]=dG-sG; v[2]=dB-sB; v[3]=dA-sA;
835
+
836
+ /* Ref. point */
837
+ int x0=sR, y0=sG, z0=sB, w0=sA;
838
+
839
+ // The line's equation is:
840
+ // x= x0 + v[0] * t
841
+ // y= y0 + v[1] * t
842
+ // z= z0 + v[2] * t
843
+ // w= w0 + v[3] * t
844
+ //
845
+ // (x,y,z,w) will travel between the two points when t goes from 0 to 1.
846
+
847
+ int i=start;
848
+ double step=1.0/((stop+1)-start);
849
+
850
+ for(double t=0.0; t<=1.0 && i<=stop ; t+=step)
851
+ ctab[i++]=sge_MapAlpha((Uint8)(x0+v[0]*t), (Uint8)(y0+v[1]*t), (Uint8)(z0+v[2]*t), (Uint8)(w0+v[3]*t));
852
+
853
+ }
854
+
855
+
856
+ //==================================================================================
857
+ // Copies a nice rainbow palette to the color table (ctab[start] to ctab[stop]).
858
+ // You must also set the intensity of the palette (0-bright 255-dark)
859
+ //==================================================================================
860
+ void sge_SetupRainbowPalette(SDL_Surface *Surface,Uint32 *ctab,int intensity, int start, int stop)
861
+ {
862
+ int slice=(int)((stop-start)/6);
863
+
864
+ /* Red-Yellow */
865
+ sge_Fader(Surface, 255,intensity,intensity, 255,255,intensity, ctab, start,slice);
866
+ /* Yellow-Green */
867
+ sge_Fader(Surface, 255,255,intensity, intensity,255,intensity, ctab, slice+1, 2*slice);
868
+ /* Green-Turquoise blue */
869
+ sge_Fader(Surface, intensity,255,intensity, intensity,255,255, ctab, 2*slice+1, 3*slice);
870
+ /* Turquoise blue-Blue */
871
+ sge_Fader(Surface, intensity,255,255, intensity,intensity,255, ctab, 3*slice+1, 4*slice);
872
+ /* Blue-Purple */
873
+ sge_Fader(Surface, intensity,intensity,255, 255,intensity,255, ctab, 4*slice+1, 5*slice);
874
+ /* Purple-Red */
875
+ sge_Fader(Surface, 255,intensity,255, 255,intensity,intensity, ctab, 5*slice+1, stop);
876
+ }
877
+
878
+
879
+ //==================================================================================
880
+ // Copies a B&W palette to the color table (ctab[start] to ctab[stop]).
881
+ //==================================================================================
882
+ void sge_SetupBWPalette(SDL_Surface *Surface,Uint32 *ctab,int start, int stop)
883
+ {
884
+ sge_Fader(Surface, 0,0,0, 255,255,255, ctab,start,stop);
885
+ }
886
+
887
+
888
+
889
+ /**********************************************************************************/
890
+ /** Color filling functions **/
891
+ /**********************************************************************************/
892
+
893
+ //==================================================================================
894
+ // sge_FloodFill: Fast non-recursive flood fill
895
+ //
896
+ // Algorithm originally written by
897
+ // Paul Heckbert, 13 Sept 1982, 28 Jan 1987
898
+ //==================================================================================
899
+ /* horizontal segment of scan line y */
900
+ struct seg{
901
+ Sint16 y, xl, xr, dy;
902
+ };
903
+
904
+ #define MAX 1000 /* max depth of stack */
905
+
906
+ #define PUSH(Y, XL, XR, DY){\
907
+ if (sp<stack+MAX && Y+(DY)>=sge_clip_ymin(dst) && Y+(DY)<=sge_clip_ymax(dst)){\
908
+ sp->y = Y;\
909
+ sp->xl = XL;\
910
+ sp->xr = XR;\
911
+ sp->dy = DY;\
912
+ sp++;\
913
+ }\
914
+ }
915
+
916
+ #define POP(Y, XL, XR, DY){\
917
+ sp--;\
918
+ DY = sp->dy;\
919
+ Y = sp->y + sp->dy;\
920
+ XL = sp->xl;\
921
+ XR = sp->xr;\
922
+ }
923
+
924
+
925
+ /*
926
+ * set the pixel at (x,y) and all of its 4-connected neighbors
927
+ * with the same pixel value to the new pixel color.
928
+ * A 4-connected neighbor is a pixel above, below, left, or right of a pixel.
929
+ */
930
+ // First a generic (slow) version and then 8/16/32 bpp versions
931
+ void _FloodFillX(SDL_Surface *dst, Sint16 x, Sint16 y, Uint32 color)
932
+ {
933
+ Sint16 l, x1, x2, dy;
934
+ Uint32 oc; /* old pixel color */
935
+ seg stack[MAX], *sp = stack; /* stack of filled segments */
936
+
937
+ if (x<sge_clip_xmin(dst) || x>sge_clip_xmax(dst) || y<sge_clip_ymin(dst) || y>sge_clip_ymax(dst))
938
+ return;
939
+
940
+ oc = sge_GetPixel(dst, x,y); /* read color at seed point */
941
+
942
+ if (oc == color)
943
+ return;
944
+
945
+ PUSH(y, x, x, 1); /* needed in some cases */
946
+ PUSH(y+1, x, x, -1); /* seed segment (popped 1st) */
947
+
948
+ while (sp>stack) {
949
+ /* pop segment off stack and fill a neighboring scan line */
950
+ POP(y, x1, x2, dy);
951
+
952
+ /*
953
+ * segment of scan line y-dy for x1<=x<=x2 was previously filled,
954
+ * now explore adjacent pixels in scan line y
955
+ */
956
+ for (x=x1; x>=sge_clip_xmin(dst); x--){
957
+ if( sge_GetPixel(dst, x,y) != oc )
958
+ break;
959
+
960
+ _PutPixel(dst, x, y, color);
961
+ }
962
+
963
+ if (x>=x1)
964
+ goto skip;
965
+
966
+ l = x+1;
967
+ if (l<x1)
968
+ PUSH(y, l, x1-1, -dy); /* leak on left? */
969
+
970
+ x = x1+1;
971
+
972
+ do {
973
+ for (; x<=sge_clip_xmax(dst); x++){
974
+ if( sge_GetPixel(dst, x,y) != oc )
975
+ break;
976
+
977
+ _PutPixel(dst, x, y, color);
978
+ }
979
+
980
+ PUSH(y, l, x-1, dy);
981
+
982
+ if (x>x2+1)
983
+ PUSH(y, x2+1, x-1, -dy); /* leak on right? */
984
+ skip:
985
+ for (x++; x<=x2; x++)
986
+ if( sge_GetPixel(dst, x,y) == oc )
987
+ break;
988
+
989
+ l = x;
990
+ } while (x<=x2);
991
+ }
992
+ }
993
+
994
+ /* Macro for 8/16/32 bpp */
995
+ #define DO_FILL(UintXX, label)\
996
+ {\
997
+ Sint16 l, x1, x2, dy;\
998
+ Uint32 oc; /* old pixel color */\
999
+ seg stack[MAX], *sp = stack; /* stack of filled segments */\
1000
+ Uint16 pitch = dst->pitch/dst->format->BytesPerPixel;\
1001
+ UintXX *row = (UintXX*)dst->pixels + y*pitch;\
1002
+ UintXX *pixel = row + x;\
1003
+ \
1004
+ if (x<sge_clip_xmin(dst) || x>sge_clip_xmax(dst) || y<sge_clip_ymin(dst) || y>sge_clip_ymax(dst))\
1005
+ return;\
1006
+ \
1007
+ oc = *pixel; /* read color at seed point */\
1008
+ \
1009
+ if (oc == color)\
1010
+ return;\
1011
+ \
1012
+ PUSH(y, x, x, 1); /* needed in some cases */\
1013
+ PUSH(y+1, x, x, -1); /* seed segment (popped 1st) */\
1014
+ \
1015
+ while (sp>stack) {\
1016
+ /* pop segment off stack and fill a neighboring scan line */\
1017
+ POP(y, x1, x2, dy);\
1018
+ row = (UintXX*)dst->pixels + y*pitch;\
1019
+ pixel = row + x1;\
1020
+ \
1021
+ /*\
1022
+ * segment of scan line y-dy for x1<=x<=x2 was previously filled,
1023
+ * now explore adjacent pixels in scan line y
1024
+ */\
1025
+ for (x=x1; x>=sge_clip_xmin(dst) && *pixel == oc; x--, pixel--)\
1026
+ *pixel = color;\
1027
+ \
1028
+ if (x>=x1)\
1029
+ goto label;\
1030
+ \
1031
+ l = x+1;\
1032
+ if (l<x1)\
1033
+ PUSH(y, l, x1-1, -dy); /* leak on left? */\
1034
+ \
1035
+ x = x1+1;\
1036
+ pixel = row + x;\
1037
+ \
1038
+ do {\
1039
+ for (; x<=sge_clip_xmax(dst) && *pixel == oc; x++, pixel++)\
1040
+ *pixel = color;\
1041
+ \
1042
+ PUSH(y, l, x-1, dy);\
1043
+ \
1044
+ if (x>x2+1)\
1045
+ PUSH(y, x2+1, x-1, -dy); /* leak on right? */\
1046
+ label:\
1047
+ pixel++;\
1048
+ \
1049
+ for (x++; x<=x2 && *pixel != oc; x++, pixel++);\
1050
+ \
1051
+ l = x;\
1052
+ } while (x<=x2);\
1053
+ }\
1054
+ }
1055
+
1056
+ // Wrapper function
1057
+ void sge_FloodFill(SDL_Surface *dst, Sint16 x, Sint16 y, Uint32 color)
1058
+ {
1059
+ if ( SDL_MUSTLOCK(dst) && _sge_lock )
1060
+ if ( SDL_LockSurface(dst) < 0 )
1061
+ return;
1062
+
1063
+ switch (dst->format->BytesPerPixel) {
1064
+ case 1: /* Assuming 8-bpp */
1065
+ DO_FILL(Uint8, skip8)
1066
+ break;
1067
+
1068
+ case 2: /* Probably 15-bpp or 16-bpp */
1069
+ DO_FILL(Uint16, skip16)
1070
+ break;
1071
+
1072
+ case 3: /* Slow 24-bpp mode, usually not used */
1073
+ _FloodFillX(dst, x,y, color);
1074
+ break;
1075
+
1076
+ case 4: /* Probably 32-bpp */
1077
+ DO_FILL(Uint32, skip32)
1078
+ break;
1079
+ }
1080
+
1081
+ if ( SDL_MUSTLOCK(dst) && _sge_lock ){
1082
+ SDL_UnlockSurface(dst);
1083
+ }
1084
+ }
1085
+
1086
+ void sge_FloodFill(SDL_Surface *dst, Sint16 x, Sint16 y, Uint8 R, Uint8 G, Uint8 B)
1087
+ {
1088
+ sge_FloodFill(dst, x, y, SDL_MapRGB(dst->format, R,G,B));
1089
+ }
1090
+