rubysdl 2.1.2 → 2.1.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (78) hide show
  1. data/NEWS.en +8 -0
  2. data/NEWS.ja +8 -0
  3. data/README.en +22 -15
  4. data/README.ja +31 -20
  5. data/depend +2 -0
  6. data/doc-en/event.rsd +3 -0
  7. data/doc-en/time.rsd +1 -1
  8. data/doc-en/video.rsd +8 -8
  9. data/doc.txt +32 -0
  10. data/doc/event.rsd +5 -0
  11. data/doc/opengl.rsd +160 -0
  12. data/doc/rsd.rb +4 -3
  13. data/doc/time.rsd +1 -1
  14. data/doc/video.rsd +8 -8
  15. data/extconf.rb +30 -15
  16. data/lib/sdl.rb +2 -1
  17. data/lib/sdl1_compatible.rb +20 -0
  18. data/mkpkg.sh +28 -0
  19. data/rubysdl.gemspec +21 -0
  20. data/rubysdl.h +1 -0
  21. data/rubysdl_cdrom.c +0 -10
  22. data/rubysdl_event.c +30 -11
  23. data/rubysdl_event_key.c +0 -5
  24. data/rubysdl_image.c +2 -2
  25. data/rubysdl_joystick.c +0 -18
  26. data/rubysdl_kanji.c +0 -5
  27. data/rubysdl_main.c +0 -2
  28. data/rubysdl_mixer.c +2 -18
  29. data/rubysdl_mouse.c +0 -4
  30. data/rubysdl_rwops.c +4 -0
  31. data/rubysdl_sdlskk.c +0 -3
  32. data/rubysdl_sge_video.c +0 -14
  33. data/rubysdl_smpeg.c +0 -1
  34. data/rubysdl_time.c +0 -10
  35. data/rubysdl_ttf.c +0 -3
  36. data/rubysdl_video.c +2 -30
  37. data/rubysdl_wm.c +0 -5
  38. data/sample/caption.rb +21 -0
  39. data/sge/INSTALL +72 -0
  40. data/sge/LICENSE +504 -0
  41. data/sge/Makefile +83 -0
  42. data/sge/Makefile.conf +63 -0
  43. data/sge/README +219 -0
  44. data/sge/Todo +7 -0
  45. data/sge/WhatsNew +224 -0
  46. data/sge/sge.h +31 -0
  47. data/sge/sge_blib.cpp +1939 -0
  48. data/sge/sge_blib.h +68 -0
  49. data/sge/sge_bm_text.cpp +451 -0
  50. data/sge/sge_bm_text.h +71 -0
  51. data/sge/sge_collision.cpp +388 -0
  52. data/sge/sge_collision.h +54 -0
  53. data/sge/sge_config.h +6 -0
  54. data/sge/sge_internal.h +152 -0
  55. data/sge/sge_misc.cpp +92 -0
  56. data/sge/sge_misc.h +37 -0
  57. data/sge/sge_primitives.cpp +2516 -0
  58. data/sge/sge_primitives.h +111 -0
  59. data/sge/sge_rotation.cpp +683 -0
  60. data/sge/sge_rotation.h +46 -0
  61. data/sge/sge_shape.cpp +762 -0
  62. data/sge/sge_shape.h +365 -0
  63. data/sge/sge_surface.cpp +1090 -0
  64. data/sge/sge_surface.h +100 -0
  65. data/sge/sge_textpp.cpp +785 -0
  66. data/sge/sge_textpp.h +270 -0
  67. data/sge/sge_tt_text.cpp +1456 -0
  68. data/sge/sge_tt_text.h +114 -0
  69. data/utils/buildtest.sh +29 -0
  70. data/win32/README.en.win32 +72 -0
  71. data/win32/README.ja.win32 +80 -0
  72. data/win32/install_rubysdl.rb +30 -0
  73. data/win32/mkpkg.sh +72 -0
  74. metadata +136 -113
  75. data/rubysdl_ref.en.html +0 -5879
  76. data/rubysdl_ref.en.rd +0 -6601
  77. data/rubysdl_ref.html +0 -6194
  78. data/rubysdl_ref.rd +0 -6950
@@ -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
+