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.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +0 -0
- data.tar.gz.sig +0 -0
- data/History.rdoc +30 -0
- data/Manifest.txt +39 -7
- data/README.rdoc +48 -4
- data/Rakefile +8 -2
- data/examples/boid.rb +9 -18
- data/examples/bounce.rb +15 -23
- data/examples/canvas.rb +75 -0
- data/examples/collision.rb +6 -6
- data/examples/demo.rb +5 -7
- data/examples/editor.rb +12 -9
- data/examples/fluid.rb +2 -3
- data/examples/fluid2.rb +1 -1
- data/examples/{lito2.rb → gol.rb} +0 -0
- data/examples/{zenspider4.rb → gol2.rb} +0 -0
- data/examples/logo.rb +4 -7
- data/examples/maze.rb +136 -0
- data/examples/tank.rb +10 -11
- data/examples/tank2.rb +12 -17
- data/examples/targeting.rb +1 -1
- data/examples/vants.rb +1 -1
- data/examples/walker.rb +3 -12
- data/examples/walker2.rb +197 -0
- data/examples/zombies.rb +31 -35
- data/ext/sdl/extconf.rb +31 -0
- data/ext/sdl/sdl.c +1067 -0
- data/ext/sdl/sge/INSTALL +72 -0
- data/ext/sdl/sge/LICENSE +504 -0
- data/ext/sdl/sge/Makefile +83 -0
- data/ext/sdl/sge/Makefile.conf +63 -0
- data/ext/sdl/sge/README +219 -0
- data/ext/sdl/sge/Todo +7 -0
- data/ext/sdl/sge/WhatsNew +224 -0
- data/ext/sdl/sge/sge.h +31 -0
- data/ext/sdl/sge/sge_blib.cpp +1939 -0
- data/ext/sdl/sge/sge_blib.h +68 -0
- data/ext/sdl/sge/sge_bm_text.cpp +451 -0
- data/ext/sdl/sge/sge_bm_text.h +71 -0
- data/ext/sdl/sge/sge_collision.cpp +388 -0
- data/ext/sdl/sge/sge_collision.h +54 -0
- data/ext/sdl/sge/sge_config.h +6 -0
- data/ext/sdl/sge/sge_internal.h +152 -0
- data/ext/sdl/sge/sge_misc.cpp +92 -0
- data/ext/sdl/sge/sge_misc.h +37 -0
- data/ext/sdl/sge/sge_primitives.cpp +2516 -0
- data/ext/sdl/sge/sge_primitives.h +111 -0
- data/ext/sdl/sge/sge_rotation.cpp +683 -0
- data/ext/sdl/sge/sge_rotation.h +46 -0
- data/ext/sdl/sge/sge_shape.cpp +762 -0
- data/ext/sdl/sge/sge_shape.h +365 -0
- data/ext/sdl/sge/sge_surface.cpp +1090 -0
- data/ext/sdl/sge/sge_surface.h +100 -0
- data/ext/sdl/sge/sge_textpp.cpp +785 -0
- data/ext/sdl/sge/sge_textpp.h +270 -0
- data/ext/sdl/sge/sge_tt_text.cpp +1456 -0
- data/ext/sdl/sge/sge_tt_text.h +114 -0
- data/graphics_setup.sh +26 -0
- data/lib/graphics.rb +1 -1
- data/lib/graphics/body.rb +50 -3
- data/lib/graphics/extensions.rb +13 -7
- data/lib/graphics/simulation.rb +126 -46
- data/test/test_graphics.rb +52 -12
- data/test/test_sdl.rb +1 -0
- metadata +54 -23
- metadata.gz.sig +0 -0
- data/.gemtest +0 -0
- data/examples/lito.rb +0 -108
- data/examples/zenspider1.rb +0 -93
- data/examples/zenspider2.rb +0 -123
- data/examples/zenspider3.rb +0 -104
- 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
|
+
|