1 /*
2 * SDL Graphics Extension
3 * Drawing primitives
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 <stdlib.h>
28 #include "sge_primitives.h"
29 #include "sge_surface.h"
30
31
32 /* Globals used for sge_Update/sge_Lock (defined in sge_surface) */
33 extern Uint8 _sge_update;
34 extern Uint8 _sge_lock;
35
36 #define SWAP(x,y,temp) temp=x;x=y;y=temp
37
38 /**********************************************************************************/
39 /** Line functions **/
40 /**********************************************************************************/
41
42 //==================================================================================
43 // Internal draw horizontal line
44 //==================================================================================
_HLine(SDL_Surface * Surface,Sint16 x1,Sint16 x2,Sint16 y,Uint32 Color)45 void _HLine(SDL_Surface *Surface, Sint16 x1, Sint16 x2, Sint16 y, Uint32 Color)
46 {
47 if(x1>x2){Sint16 tmp=x1; x1=x2; x2=tmp;}
48
49 //Do the clipping
50 #if SDL_VERSIONNUM(SDL_MAJOR_VERSION, SDL_MINOR_VERSION, SDL_PATCHLEVEL) < \
51 SDL_VERSIONNUM(1, 1, 5)
52 if(y<Surface->clip_miny || y>Surface->clip_maxy || x1>Surface->clip_maxx || x2<Surface->clip_minx)
53 return;
54 if(x1<Surface->clip_minx)
55 x1=Surface->clip_minx;
56 if(x2>Surface->clip_maxx)
57 x2=Surface->clip_maxx;
58 #endif
59
60 SDL_Rect l;
61 l.x=x1; l.y=y; l.w=x2-x1+1; l.h=1;
62
63 SDL_FillRect(Surface, &l, Color);
64 }
65
66 //==================================================================================
67 // Draw horizontal line
68 //==================================================================================
sge_HLine(SDL_Surface * Surface,Sint16 x1,Sint16 x2,Sint16 y,Uint32 Color)69 void sge_HLine(SDL_Surface *Surface, Sint16 x1, Sint16 x2, Sint16 y, Uint32 Color)
70 {
71 if(x1>x2){Sint16 tmp=x1; x1=x2; x2=tmp;}
72
73 //Do the clipping
74 #if SDL_VERSIONNUM(SDL_MAJOR_VERSION, SDL_MINOR_VERSION, SDL_PATCHLEVEL) < \
75 SDL_VERSIONNUM(1, 1, 5)
76 if(y<Surface->clip_miny || y>Surface->clip_maxy || x1>Surface->clip_maxx || x2<Surface->clip_minx)
77 return;
78 if(x1<Surface->clip_minx)
79 x1=Surface->clip_minx;
80 if(x2>Surface->clip_maxx)
81 x2=Surface->clip_maxx;
82 #endif
83
84 SDL_Rect l;
85 l.x=x1; l.y=y; l.w=x2-x1+1; l.h=1;
86
87 SDL_FillRect(Surface, &l, Color);
88
89 sge_UpdateRect(Surface, x1, y, x2-x1+1, 1);
90 }
91
92 //==================================================================================
93 // Draw horizontal line (RGB)
94 //==================================================================================
sge_HLine(SDL_Surface * Surface,Sint16 x1,Sint16 x2,Sint16 y,Uint8 R,Uint8 G,Uint8 B)95 void sge_HLine(SDL_Surface *Surface, Sint16 x1, Sint16 x2, Sint16 y, Uint8 R, Uint8 G, Uint8 B)
96 {
97 sge_HLine(Surface,x1,x2,y, SDL_MapRGB(Surface->format, R, G, B));
98 }
99
100
101 //==================================================================================
102 // Internal draw horizontal line (alpha)
103 //==================================================================================
_HLineAlpha(SDL_Surface * Surface,Sint16 x1,Sint16 x2,Sint16 y,Uint32 Color,Uint8 alpha)104 void _HLineAlpha(SDL_Surface *Surface, Sint16 x1, Sint16 x2, Sint16 y, Uint32 Color, Uint8 alpha)
105 {
106 Uint8 update = _sge_update;
107 Uint8 lock = _sge_lock;
108 _sge_update = 0;
109 _sge_lock = 0;
110 sge_FilledRectAlpha(Surface, x1,y,x2,y, Color, alpha);
111 _sge_update = update;
112 _sge_lock = lock;
113 }
114
115 //==================================================================================
116 // Draw horizontal line (alpha)
117 //==================================================================================
sge_HLineAlpha(SDL_Surface * Surface,Sint16 x1,Sint16 x2,Sint16 y,Uint32 Color,Uint8 alpha)118 void sge_HLineAlpha(SDL_Surface *Surface, Sint16 x1, Sint16 x2, Sint16 y, Uint32 Color, Uint8 alpha)
119 {
120 sge_FilledRectAlpha(Surface, x1,y,x2,y, Color, alpha);
121 }
122
123 //==================================================================================
124 // Draw horizontal line (alpha RGB)
125 //==================================================================================
sge_HLineAlpha(SDL_Surface * Surface,Sint16 x1,Sint16 x2,Sint16 y,Uint8 R,Uint8 G,Uint8 B,Uint8 alpha)126 void sge_HLineAlpha(SDL_Surface *Surface, Sint16 x1, Sint16 x2, Sint16 y, Uint8 R, Uint8 G, Uint8 B, Uint8 alpha)
127 {
128 sge_HLineAlpha(Surface,x1,x2,y, SDL_MapRGB(Surface->format, R, G, B), alpha);
129 }
130
131
132 //==================================================================================
133 // Internal draw vertical line
134 //==================================================================================
_VLine(SDL_Surface * Surface,Sint16 x,Sint16 y1,Sint16 y2,Uint32 Color)135 void _VLine(SDL_Surface *Surface, Sint16 x, Sint16 y1, Sint16 y2, Uint32 Color)
136 {
137 if(y1>y2){Sint16 tmp=y1; y1=y2; y2=tmp;}
138
139 //Do the clipping
140 #if SDL_VERSIONNUM(SDL_MAJOR_VERSION, SDL_MINOR_VERSION, SDL_PATCHLEVEL) < \
141 SDL_VERSIONNUM(1, 1, 5)
142 if(x<Surface->clip_minx || x>Surface->clip_maxx || y1>Surface->clip_maxy || y2<Surface->clip_miny)
143 return;
144 if(y1<Surface->clip_miny)
145 y1=Surface->clip_miny;
146 if(y2>Surface->clip_maxy)
147 y2=Surface->clip_maxy;
148 #endif
149
150 SDL_Rect l;
151 l.x=x; l.y=y1; l.w=1; l.h=y2-y1+1;
152
153 SDL_FillRect(Surface, &l, Color);
154 }
155
156 //==================================================================================
157 // Draw vertical line
158 //==================================================================================
sge_VLine(SDL_Surface * Surface,Sint16 x,Sint16 y1,Sint16 y2,Uint32 Color)159 void sge_VLine(SDL_Surface *Surface, Sint16 x, Sint16 y1, Sint16 y2, Uint32 Color)
160 {
161 if(y1>y2){Sint16 tmp=y1; y1=y2; y2=tmp;}
162
163 //Do the clipping
164 #if SDL_VERSIONNUM(SDL_MAJOR_VERSION, SDL_MINOR_VERSION, SDL_PATCHLEVEL) < \
165 SDL_VERSIONNUM(1, 1, 5)
166 if(x<Surface->clip_minx || x>Surface->clip_maxx || y1>Surface->clip_maxy || y2<Surface->clip_miny)
167 return;
168 if(y1<Surface->clip_miny)
169 y1=Surface->clip_miny;
170 if(y2>Surface->clip_maxy)
171 y2=Surface->clip_maxy;
172 #endif
173
174 SDL_Rect l;
175 l.x=x; l.y=y1; l.w=1; l.h=y2-y1+1;
176
177 SDL_FillRect(Surface, &l, Color);
178
179 sge_UpdateRect(Surface, x, y1, 1, y2-y1+1);
180 }
181
182 //==================================================================================
183 // Draw vertical line (RGB)
184 //==================================================================================
sge_VLine(SDL_Surface * Surface,Sint16 x,Sint16 y1,Sint16 y2,Uint8 R,Uint8 G,Uint8 B)185 void sge_VLine(SDL_Surface *Surface, Sint16 x, Sint16 y1, Sint16 y2, Uint8 R, Uint8 G, Uint8 B)
186 {
187 sge_VLine(Surface,x,y1,y2, SDL_MapRGB(Surface->format, R, G, B));
188 }
189
190
191 //==================================================================================
192 // Internal draw vertical line (alpha - no update)
193 //==================================================================================
_VLineAlpha(SDL_Surface * Surface,Sint16 x,Sint16 y1,Sint16 y2,Uint32 Color,Uint8 alpha)194 void _VLineAlpha(SDL_Surface *Surface, Sint16 x, Sint16 y1, Sint16 y2, Uint32 Color, Uint8 alpha)
195 {
196 Uint8 update = _sge_update;
197 Uint8 lock = _sge_lock;
198 _sge_update = 0;
199 _sge_lock = 0;
200 sge_FilledRectAlpha(Surface, x,y1,x,y2, Color, alpha);
201 _sge_update = update;
202 _sge_lock = lock;
203 }
204
205 //==================================================================================
206 // Draw vertical line (alpha)
207 //==================================================================================
sge_VLineAlpha(SDL_Surface * Surface,Sint16 x,Sint16 y1,Sint16 y2,Uint32 Color,Uint8 alpha)208 void sge_VLineAlpha(SDL_Surface *Surface, Sint16 x, Sint16 y1, Sint16 y2, Uint32 Color, Uint8 alpha)
209 {
210 sge_FilledRectAlpha(Surface, x,y1,x,y2, Color, alpha);
211 }
212
213 //==================================================================================
214 // Draw vertical line (alpha RGB)
215 //==================================================================================
sge_VLineAlpha(SDL_Surface * Surface,Sint16 x,Sint16 y1,Sint16 y2,Uint8 R,Uint8 G,Uint8 B,Uint8 alpha)216 void sge_VLineAlpha(SDL_Surface *Surface, Sint16 x, Sint16 y1, Sint16 y2, Uint8 R, Uint8 G, Uint8 B, Uint8 alpha)
217 {
218 sge_VLineAlpha(Surface,x,y1,y2, SDL_MapRGB(Surface->format, R, G, B), alpha);
219 }
220
221
222
223 //==================================================================================
224 // Performs Callback at each line point. (From PowerPak)
225 //==================================================================================
sge_DoLine(SDL_Surface * Surface,Sint16 x1,Sint16 y1,Sint16 x2,Sint16 y2,Uint32 Color,void Callback (SDL_Surface * Surf,Sint16 X,Sint16 Y,Uint32 Color))226 void sge_DoLine(SDL_Surface *Surface, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint32 Color, void Callback(SDL_Surface *Surf, Sint16 X, Sint16 Y, Uint32 Color))
227 {
228 Sint16 dx, dy, sdx, sdy, x, y, px, py;
229
230 dx = x2 - x1;
231 dy = y2 - y1;
232
233 sdx = (dx < 0) ? -1 : 1;
234 sdy = (dy < 0) ? -1 : 1;
235
236 dx = sdx * dx + 1;
237 dy = sdy * dy + 1;
238
239 x = y = 0;
240
241 px = x1;
242 py = y1;
243
244 if (dx >= dy){
245 for (x = 0; x < dx; x++){
246 Callback(Surface, px, py, Color);
247
248 y += dy;
249 if (y >= dx){
250 y -= dx;
251 py += sdy;
252 }
253 px += sdx;
254 }
255 }
256 else{
257 for (y = 0; y < dy; y++){
258 Callback(Surface, px, py, Color);
259
260 x += dx;
261 if (x >= dy){
262 x -= dy;
263 px += sdx;
264 }
265 py += sdy;
266 }
267 }
268 }
269
270
271 //==================================================================================
272 // Performs Callback at each line point. (RGB)
273 //==================================================================================
sge_DoLine(SDL_Surface * Surface,Sint16 X1,Sint16 Y1,Sint16 X2,Sint16 Y2,Uint8 R,Uint8 G,Uint8 B,void Callback (SDL_Surface * Surf,Sint16 X,Sint16 Y,Uint32 Color))274 void sge_DoLine(SDL_Surface *Surface, Sint16 X1, Sint16 Y1, Sint16 X2, Sint16 Y2, Uint8 R, Uint8 G, Uint8 B, void Callback(SDL_Surface *Surf, Sint16 X, Sint16 Y, Uint32 Color))
275 {
276 sge_DoLine(Surface,X1,Y1,X2,Y2, SDL_MapRGB(Surface->format, R, G, B),Callback);
277 }
278
279
280 //==================================================================================
281 // Line clipping
282 // Standard Cohen-Sutherland algorithm (from gfxPrimitives)
283 //==================================================================================
284 #define CLIP_LEFT_EDGE 0x1
285 #define CLIP_RIGHT_EDGE 0x2
286 #define CLIP_BOTTOM_EDGE 0x4
287 #define CLIP_TOP_EDGE 0x8
288 #define CLIP_INSIDE(a) (!a)
289 #define CLIP_REJECT(a,b) (a&b)
290 #define CLIP_ACCEPT(a,b) (!(a|b))
291
clipEncode(Sint16 x,Sint16 y,Sint16 left,Sint16 top,Sint16 right,Sint16 bottom)292 int clipEncode(Sint16 x, Sint16 y, Sint16 left, Sint16 top, Sint16 right, Sint16 bottom)
293 {
294 int code = 0;
295
296 if (x < left)
297 code |= CLIP_LEFT_EDGE;
298 else if (x > right)
299 code |= CLIP_RIGHT_EDGE;
300
301 if (y < top)
302 code |= CLIP_TOP_EDGE;
303 else if (y > bottom)
304 code |= CLIP_BOTTOM_EDGE;
305
306 return code;
307 }
308
clipLine(SDL_Surface * dst,Sint16 * x1,Sint16 * y1,Sint16 * x2,Sint16 * y2)309 int clipLine(SDL_Surface *dst, Sint16 *x1, Sint16 *y1, Sint16 *x2, Sint16 *y2)
310 {
311 int code1, code2;
312 bool draw = false;
313
314 Sint16 tmp;
315 float m;
316
317 /* Get clipping boundary */
318 Sint16 left, right, top, bottom;
319 left = sge_clip_xmin(dst);
320 right = sge_clip_xmax(dst);
321 top = sge_clip_ymin(dst);
322 bottom = sge_clip_ymax(dst);
323
324 while (true){
325 code1 = clipEncode(*x1, *y1, left, top, right, bottom);
326 code2 = clipEncode(*x2, *y2, left, top, right, bottom);
327
328 if(CLIP_ACCEPT(code1, code2)){
329 draw = true;
330 break;
331 }else if(CLIP_REJECT(code1, code2))
332 break;
333 else{
334 if(CLIP_INSIDE(code1)){
335 tmp = *x2;
336 *x2 = *x1;
337 *x1 = tmp;
338 tmp = *y2;
339 *y2 = *y1;
340 *y1 = tmp;
341 tmp = code2;
342 code2 = code1;
343 code1 = tmp;
344 }
345 if(*x2 != *x1)
346 m = (*y2 - *y1) / float(*x2 - *x1);
347 else
348 m = 1.0;
349
350
351 if(code1 & CLIP_LEFT_EDGE){
352 *y1 += Sint16( (left - *x1) * m );
353 *x1 = left;
354 }else if(code1 & CLIP_RIGHT_EDGE){
355 *y1 += Sint16( (right - *x1) * m );
356 *x1 = right;
357 }else if(code1 & CLIP_BOTTOM_EDGE){
358 if (*x2 != *x1) {
359 *x1 += Sint16( (bottom - *y1) / m );
360 }
361 *y1 = bottom;
362 }else if(code1 & CLIP_TOP_EDGE){
363 if (*x2 != *x1) {
364 *x1 += Sint16( (top - *y1) / m );
365 }
366 *y1 = top;
367 }
368 }
369 }
370
371 return draw;
372 }
373
374
375 //==================================================================================
376 // Draws a line
377 //==================================================================================
_Line(SDL_Surface * surface,Sint16 x1,Sint16 y1,Sint16 x2,Sint16 y2,Uint32 color)378 void _Line(SDL_Surface *surface, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint32 color)
379 {
380 if( !clipLine(surface, &x1, &y1, &x2, &y2) )
381 return;
382
383 Sint16 dx, dy, sdx, sdy, x, y;
384
385 dx = x2 - x1;
386 dy = y2 - y1;
387
388 sdx = (dx < 0) ? -1 : 1;
389 sdy = (dy < 0) ? -1 : 1;
390
391 dx = sdx * dx + 1;
392 dy = sdy * dy + 1;
393
394 x = y = 0;
395
396 Sint16 pixx = surface->format->BytesPerPixel;
397 Sint16 pixy = surface->pitch;
398 Uint8 *pixel = (Uint8*)surface->pixels + y1*pixy + x1*pixx;
399
400 pixx *= sdx;
401 pixy *= sdy;
402
403 if (dx < dy) {
404 Sint32 tmp = dx; dx = dy; dy = Sint16(tmp);
405 tmp = pixx; pixx = pixy; pixy = tmp;
406 }
407
408 switch(surface->format->BytesPerPixel) {
409 case 1: {
410 for(x=0; x < dx; x++) {
411 *pixel = color;
412
413 y += dy;
414 if (y >= dx) {
415 y -= dx;
416 pixel += pixy;
417 }
418 pixel += pixx;
419 }
420 }
421 break;
422
423 case 2: {
424 for(x=0; x < dx; x++) {
425 *(Uint16*)pixel = color;
426
427 y += dy;
428 if (y >= dx) {
429 y -= dx;
430 pixel += pixy;
431 }
432 pixel += pixx;
433 }
434 }
435 break;
436
437 case 3: {
438 Uint8 rshift8 = surface->format->Rshift/8;
439 Uint8 gshift8 = surface->format->Gshift/8;
440 Uint8 bshift8 = surface->format->Bshift/8;
441 Uint8 ashift8 = surface->format->Ashift/8;
442
443 Uint8 R = (color>>surface->format->Rshift)&0xff;
444 Uint8 G = (color>>surface->format->Gshift)&0xff;
445 Uint8 B = (color>>surface->format->Bshift)&0xff;
446 Uint8 A = (color>>surface->format->Ashift)&0xff;
447
448 for(x=0; x < dx; x++) {
449 *(pixel+rshift8) = R;
450 *(pixel+gshift8) = G;
451 *(pixel+bshift8) = B;
452 *(pixel+ashift8) = A;
453
454 y += dy;
455 if (y >= dx) {
456 y -= dx;
457 pixel += pixy;
458 }
459 pixel += pixx;
460 }
461 }
462 break;
463
464 case 4: {
465 for(x=0; x < dx; x++) {
466 *(Uint32*)pixel = color;
467
468 y += dy;
469 if (y >= dx) {
470 y -= dx;
471 pixel += pixy;
472 }
473 pixel += pixx;
474 }
475 }
476 break;
477 }
478 }
479
sge_Line(SDL_Surface * Surface,Sint16 x1,Sint16 y1,Sint16 x2,Sint16 y2,Uint32 Color)480 void sge_Line(SDL_Surface *Surface, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint32 Color)
481 {
482 if (SDL_MUSTLOCK(Surface) && _sge_lock) {
483 if (SDL_LockSurface(Surface) < 0)
484 return;
485 }
486
487 /* Draw the line */
488 _Line(Surface, x1,y1, x2,y2, Color);
489
490 /* unlock the display */
491 if (SDL_MUSTLOCK(Surface) && _sge_lock) {
492 SDL_UnlockSurface(Surface);
493 }
494
495 sge_UpdateRect(Surface, (x1 < x2)? x1 : x2, (y1 < y2)? y1 : y2, ((x2-x1)<0)? (x1-x2+1) : (x2-x1+1), ((y2-y1)<0)? (y1-y2+1) : (y2-y1+1));
496 }
497
498
499 //==================================================================================
500 // Draws a line (RGB)
501 //==================================================================================
sge_Line(SDL_Surface * Surface,Sint16 x1,Sint16 y1,Sint16 x2,Sint16 y2,Uint8 R,Uint8 G,Uint8 B)502 void sge_Line(SDL_Surface *Surface, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint8 R, Uint8 G, Uint8 B)
503 {
504 sge_Line(Surface,x1,y1,x2,y2, SDL_MapRGB(Surface->format, R, G, B));
505 }
506
507
508 //==================================================================================
509 // A quick hack to get alpha working with callbacks
510 //==================================================================================
511 Uint8 _sge_alpha_hack = 0;
callback_alpha_hack(SDL_Surface * surf,Sint16 x,Sint16 y,Uint32 color)512 void callback_alpha_hack(SDL_Surface *surf, Sint16 x, Sint16 y, Uint32 color)
513 {
514 _PutPixelAlpha(surf,x,y,color,_sge_alpha_hack);
515 }
516
517 //==================================================================================
518 // Draws a line (alpha)
519 //==================================================================================
_LineAlpha(SDL_Surface * Surface,Sint16 x1,Sint16 y1,Sint16 x2,Sint16 y2,Uint32 Color,Uint8 alpha)520 void _LineAlpha(SDL_Surface *Surface, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint32 Color, Uint8 alpha)
521 {
522 _sge_alpha_hack = alpha;
523
524 /* Draw the line */
525 sge_DoLine(Surface, x1, y1, x2, y2, Color, callback_alpha_hack);
526 }
527
sge_LineAlpha(SDL_Surface * Surface,Sint16 x1,Sint16 y1,Sint16 x2,Sint16 y2,Uint32 Color,Uint8 alpha)528 void sge_LineAlpha(SDL_Surface *Surface, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint32 Color, Uint8 alpha)
529 {
530 if (SDL_MUSTLOCK(Surface) && _sge_lock)
531 if (SDL_LockSurface(Surface) < 0)
532 return;
533
534 _LineAlpha(Surface, x1, y1, x2, y2, Color, alpha);
535
536 /* unlock the display */
537 if (SDL_MUSTLOCK(Surface) && _sge_lock) {
538 SDL_UnlockSurface(Surface);
539 }
540
541 sge_UpdateRect(Surface, (x1 < x2)? x1 : x2, (y1 < y2)? y1 : y2, ((x2-x1)<0)? (x1-x2+1) : (x2-x1+1), ((y2-y1)<0)? (y1-y2+1) : (y2-y1+1));
542 }
543
544 //==================================================================================
545 // Draws a line (alpha - RGB)
546 //==================================================================================
sge_LineAlpha(SDL_Surface * Surface,Sint16 x1,Sint16 y1,Sint16 x2,Sint16 y2,Uint8 R,Uint8 G,Uint8 B,Uint8 alpha)547 void sge_LineAlpha(SDL_Surface *Surface, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint8 R, Uint8 G, Uint8 B, Uint8 alpha)
548 {
549 sge_LineAlpha(Surface,x1,y1,x2,y2, SDL_MapRGB(Surface->format, R, G, B), alpha);
550 }
551
552
553 //==================================================================================
554 // Anti-aliased line
555 // From SDL_gfxPrimitives written by A. Schiffler (aschiffler@home.com)
556 //==================================================================================
557 #define AAbits 8
558 #define AAlevels 256 /* 2^AAbits */
_AALineAlpha(SDL_Surface * dst,Sint16 x1,Sint16 y1,Sint16 x2,Sint16 y2,Uint32 color,Uint8 alpha)559 void _AALineAlpha(SDL_Surface *dst, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint32 color, Uint8 alpha)
560 {
561 Uint32 erracc=0, erradj;
562 Uint32 erracctmp, wgt;
563 Sint16 tmp, y0p1, x0pxdir;
564 Uint8 a;
565
566 /* Keep on working with 32bit numbers */
567 Sint32 xx0=x1;
568 Sint32 yy0=y1;
569 Sint32 xx1=x2;
570 Sint32 yy1=y2;
571
572 /* Reorder points if required */
573 if (yy0 > yy1) {
574 SWAP(yy0, yy1, tmp);
575 SWAP(xx0, xx1, tmp);
576 }
577
578 /* Calculate distance */
579 Sint16 dx = xx1 - xx0;
580 Sint16 dy = yy1 - yy0;
581
582 /* Adjust for negative dx and set xdir */
583 Sint16 xdir = 1;
584 if (dx < 0) {
585 xdir=-1;
586 dx=(-dx);
587 }
588
589 /* Check for special cases */
590 if (dx==0 || dy==0 || dx==dy) {
591 if(alpha==SDL_ALPHA_OPAQUE)
592 _Line(dst,x1,y1,x2,y2,color);
593 else
594 _LineAlpha(dst,x1,y1,x2,y2,color,alpha);
595 return;
596 }
597
598 float alpha_pp = float(alpha)/255; /* Used to calculate alpha level if alpha != 255 */
599
600 Uint32 intshift = 32 - AAbits; /* # of bits by which to shift erracc to get intensity level */
601
602 /* Draw the initial pixel in the foreground color */
603 if(alpha==SDL_ALPHA_OPAQUE)
604 _PutPixel(dst,x1,y1, color);
605 else
606 _PutPixelAlpha(dst,x1,y1, color, alpha);
607
608 /* x-major or y-major? */
609 if (dy > dx) {
610
611 /* y-major. Calculate 16-bit fixed point fractional part of a pixel that
612 X advances every time Y advances 1 pixel, truncating the result so that
613 we won't overrun the endpoint along the X axis */
614 erradj = ((dx << 16) / dy)<<16;
615
616 /* draw all pixels other than the first and last */
617 x0pxdir=xx0+xdir;
618 while (--dy) {
619 erracctmp = erracc;
620 erracc += erradj;
621 if (erracc <= erracctmp) {
622 /* rollover in error accumulator, x coord advances */
623 xx0=x0pxdir;
624 x0pxdir += xdir;
625 }
626 yy0++; /* y-major so always advance Y */
627
628 /* the AAbits most significant bits of erracc give us the intensity
629 weighting for this pixel, and the complement of the weighting for
630 the paired pixel. */
631 wgt = (erracc >> intshift) & 255;
632
633 a = Uint8(255-wgt);
634 if(alpha != SDL_ALPHA_OPAQUE)
635 a = Uint8(a*alpha_pp);
636
637 _PutPixelAlpha(dst,xx0,yy0,color,a);
638
639 a = Uint8(wgt);
640 if(alpha != SDL_ALPHA_OPAQUE)
641 a = Uint8(a*alpha_pp);
642
643 _PutPixelAlpha(dst,x0pxdir,yy0,color,a);
644 }
645 } else {
646
647 /* x-major line. Calculate 16-bit fixed-point fractional part of a pixel
648 that Y advances each time X advances 1 pixel, truncating the result so
649 that we won't overrun the endpoint along the X axis. */
650 erradj = ((dy << 16) / dx)<<16;
651
652 /* draw all pixels other than the first and last */
653 y0p1=yy0+1;
654 while (--dx) {
655
656 erracctmp = erracc;
657 erracc += erradj;
658 if (erracc <= erracctmp) {
659 /* Accumulator turned over, advance y */
660 yy0=y0p1;
661 y0p1++;
662 }
663 xx0 += xdir; /* x-major so always advance X */
664
665 /* the AAbits most significant bits of erracc give us the intensity
666 weighting for this pixel, and the complement of the weighting for
667 the paired pixel. */
668 wgt = (erracc >> intshift) & 255;
669
670 a = Uint8(255-wgt);
671 if(alpha != SDL_ALPHA_OPAQUE)
672 a = Uint8(a*alpha_pp);
673
674 _PutPixelAlpha(dst,xx0,yy0,color,a);
675
676 a = Uint8(wgt);
677 if(alpha != SDL_ALPHA_OPAQUE)
678 a = Uint8(a*alpha_pp);
679
680 _PutPixelAlpha(dst,xx0,y0p1,color,a);
681 }
682 }
683
684 /* Draw final pixel, always exactly intersected by the line and doesn't
685 need to be weighted. */
686 if(alpha==SDL_ALPHA_OPAQUE)
687 _PutPixel(dst,x2,y2, color);
688 else
689 _PutPixelAlpha(dst,x2,y2, color, alpha);
690
691 }
692
sge_AALineAlpha(SDL_Surface * dst,Sint16 x1,Sint16 y1,Sint16 x2,Sint16 y2,Uint32 color,Uint8 alpha)693 void sge_AALineAlpha(SDL_Surface *dst, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint32 color, Uint8 alpha)
694 {
695 /* Lock surface */
696 if ( SDL_MUSTLOCK(dst) && _sge_lock )
697 if ( SDL_LockSurface(dst) < 0 )
698 return;
699
700 _AALineAlpha(dst,x1,y1,x2,y2,color,alpha);
701
702 /* unlock the display */
703 if (SDL_MUSTLOCK(dst) && _sge_lock) {
704 SDL_UnlockSurface(dst);
705 }
706
707 sge_UpdateRect(dst, (x1 < x2)? x1 : x2, (y1 < y2)? y1 : y2, ((x2-x1)<0)? (x1-x2+1) : (x2-x1+1), ((y2-y1)<0)? (y1-y2+1) : (y2-y1+1));
708 }
709
sge_AALineAlpha(SDL_Surface * dst,Sint16 x1,Sint16 y1,Sint16 x2,Sint16 y2,Uint8 r,Uint8 g,Uint8 b,Uint8 alpha)710 void sge_AALineAlpha(SDL_Surface *dst, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint8 r, Uint8 g, Uint8 b, Uint8 alpha)
711 {
712 sge_AALineAlpha(dst,x1,y1,x2,y2,SDL_MapRGB(dst->format, r, g, b),alpha);
713 }
714
sge_AALine(SDL_Surface * dst,Sint16 x1,Sint16 y1,Sint16 x2,Sint16 y2,Uint32 color)715 void sge_AALine(SDL_Surface *dst, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint32 color)
716 {
717 sge_AALineAlpha(dst, x1,y1, x2,y2, color, SDL_ALPHA_OPAQUE);
718 }
719
sge_AALine(SDL_Surface * dst,Sint16 x1,Sint16 y1,Sint16 x2,Sint16 y2,Uint8 r,Uint8 g,Uint8 b)720 void sge_AALine(SDL_Surface *dst, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint8 r, Uint8 g, Uint8 b)
721 {
722 sge_AALineAlpha(dst,x1,y1,x2,y2,SDL_MapRGB(dst->format, r, g, b),SDL_ALPHA_OPAQUE);
723 }
724
725
726
727 //==================================================================================
728 // Draws a multicolored line
729 //==================================================================================
sge_DomcLine(SDL_Surface * surface,Sint16 x1,Sint16 y1,Sint16 x2,Sint16 y2,Uint8 r1,Uint8 g1,Uint8 b1,Uint8 r2,Uint8 g2,Uint8 b2,void Callback (SDL_Surface * Surf,Sint16 X,Sint16 Y,Uint32 Color))730 void sge_DomcLine(SDL_Surface *surface, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint8 r1, Uint8 g1, Uint8 b1, Uint8 r2, Uint8 g2, Uint8 b2, void Callback(SDL_Surface *Surf, Sint16 X, Sint16 Y, Uint32 Color))
731 {
732 Sint16 dx, dy, sdx, sdy, x, y, px, py;
733
734 dx = x2 - x1;
735 dy = y2 - y1;
736
737 sdx = (dx < 0) ? -1 : 1;
738 sdy = (dy < 0) ? -1 : 1;
739
740 dx = sdx * dx + 1;
741 dy = sdy * dy + 1;
742
743 x = y = 0;
744
745 px = x1;
746 py = y1;
747
748 /* We use fixedpoint math for the color fading */
749 Sint32 R = r1<<16;
750 Sint32 G = g1<<16;
751 Sint32 B = b1<<16;
752 Sint32 rstep;
753 Sint32 gstep;
754 Sint32 bstep;
755
756 if (dx >= dy){
757 rstep = Sint32((r2-r1)<<16) / Sint32(dx);
758 gstep = Sint32((g2-g1)<<16) / Sint32(dx);
759 bstep = Sint32((b2-b1)<<16) / Sint32(dx);
760
761 for (x = 0; x < dx; x++){
762 Callback(surface, px, py, SDL_MapRGB(surface->format, Uint8(R>>16), Uint8(G>>16), Uint8(B>>16)) );
763
764 y += dy;
765 if (y >= dx){
766 y -= dx;
767 py += sdy;
768 }
769 px += sdx;
770
771 R += rstep;
772 G += gstep;
773 B += bstep;
774 }
775 }
776 else{
777 rstep = Sint32((r2-r1)<<16) / Sint32(dy);
778 gstep = Sint32((g2-g1)<<16) / Sint32(dy);
779 bstep = Sint32((b2-b1)<<16) / Sint32(dy);
780
781 for (y = 0; y < dy; y++){
782 Callback(surface, px, py, SDL_MapRGB(surface->format, Uint8(R>>16), Uint8(G>>16), Uint8(B>>16)) );
783
784 x += dx;
785 if (x >= dy){
786 x -= dy;
787 px += sdx;
788 }
789 py += sdy;
790
791 R += rstep;
792 G += gstep;
793 B += bstep;
794 }
795 }
796 }
797
sge_mcLine(SDL_Surface * Surface,Sint16 x1,Sint16 y1,Sint16 x2,Sint16 y2,Uint8 r1,Uint8 g1,Uint8 b1,Uint8 r2,Uint8 g2,Uint8 b2)798 void sge_mcLine(SDL_Surface *Surface, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint8 r1, Uint8 g1, Uint8 b1, Uint8 r2, Uint8 g2, Uint8 b2)
799 {
800 if (SDL_MUSTLOCK(Surface) && _sge_lock) {
801 if (SDL_LockSurface(Surface) < 0)
802 return;
803 }
804
805 /* Draw the line */
806 sge_DomcLine(Surface, x1,y1, x2,y2, r1,g1,b1, r2,g2,b2, _PutPixel);
807
808 /* unlock the display */
809 if (SDL_MUSTLOCK(Surface) && _sge_lock) {
810 SDL_UnlockSurface(Surface);
811 }
812
813 sge_UpdateRect(Surface, (x1 < x2)? x1 : x2, (y1 < y2)? y1 : y2, ((x2-x1)<0)? (x1-x2+1) : (x2-x1+1), ((y2-y1)<0)? (y1-y2+1) : (y2-y1+1));
814 }
815
sge_mcLineAlpha(SDL_Surface * Surface,Sint16 x1,Sint16 y1,Sint16 x2,Sint16 y2,Uint8 r1,Uint8 g1,Uint8 b1,Uint8 r2,Uint8 g2,Uint8 b2,Uint8 alpha)816 void sge_mcLineAlpha(SDL_Surface *Surface, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint8 r1, Uint8 g1, Uint8 b1, Uint8 r2, Uint8 g2, Uint8 b2, Uint8 alpha)
817 {
818 if (SDL_MUSTLOCK(Surface) && _sge_lock)
819 if (SDL_LockSurface(Surface) < 0)
820 return;
821
822 _sge_alpha_hack = alpha;
823
824 /* Draw the line */
825 sge_DomcLine(Surface, x1,y1, x2,y2, r1,g1,b1, r2,g2,b2, callback_alpha_hack);
826
827 /* unlock the display */
828 if (SDL_MUSTLOCK(Surface) && _sge_lock) {
829 SDL_UnlockSurface(Surface);
830 }
831
832 sge_UpdateRect(Surface, (x1 < x2)? x1 : x2, (y1 < y2)? y1 : y2, ((x2-x1)<0)? (x1-x2+1) : (x2-x1+1), ((y2-y1)<0)? (y1-y2+1) : (y2-y1+1));
833 }
834
835
836 //==================================================================================
837 // Draws a anti-aliased multicolored line
838 //==================================================================================
_AAmcLineAlpha(SDL_Surface * dst,Sint16 x1,Sint16 y1,Sint16 x2,Sint16 y2,Uint8 r1,Uint8 g1,Uint8 b1,Uint8 r2,Uint8 g2,Uint8 b2,Uint8 alpha)839 void _AAmcLineAlpha(SDL_Surface *dst, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint8 r1, Uint8 g1, Uint8 b1, Uint8 r2, Uint8 g2, Uint8 b2, Uint8 alpha)
840 {
841 Uint32 erracc=0, erradj;
842 Uint32 erracctmp, wgt;
843 Sint16 tmp, y0p1, x0pxdir;
844 Uint8 a;
845
846 /* Keep on working with 32bit numbers */
847 Sint32 xx0=x1;
848 Sint32 yy0=y1;
849 Sint32 xx1=x2;
850 Sint32 yy1=y2;
851
852 /* Reorder points if required */
853 if (yy0 > yy1) {
854 SWAP(yy0, yy1, tmp);
855 SWAP(xx0, xx1, tmp);
856
857 SWAP(r1, r2, a);
858 SWAP(g1, g2, a);
859 SWAP(b1, b2, a);
860 }
861
862 /* Calculate distance */
863 Sint16 dx = xx1 - xx0;
864 Sint16 dy = yy1 - yy0;
865
866 /* Adjust for negative dx and set xdir */
867 Sint16 xdir=1;
868 if (dx < 0) {
869 xdir=-1;
870 dx=(-dx);
871 }
872
873 /* Check for special cases */
874 if (dx==0 || dy==0 || dx==dy) {
875 sge_mcLineAlpha(dst, x1, y1, x2, y2, r1, g1, b1, r2, g2, b2, alpha);
876 return;
877 }
878
879 /* We use fixedpoint math for the color fading */
880 Sint32 R = r1<<16;
881 Sint32 G = g1<<16;
882 Sint32 B = b1<<16;
883 Sint32 rstep;
884 Sint32 gstep;
885 Sint32 bstep;
886
887 float alpha_pp = float(alpha)/255; /* Used to calculate alpha level if alpha != 255 */
888 Uint32 intshift = 32 - AAbits; /* # of bits by which to shift erracc to get intensity level */
889
890 if(alpha==255)
891 _PutPixel(dst,x1,y1, SDL_MapRGB(dst->format, r1, g1, b1) ); /* Draw the initial pixel in the foreground color */
892 else
893 _PutPixelAlpha(dst,x1,y1, SDL_MapRGB(dst->format, r1, g1, b1), alpha);
894
895 /* x-major or y-major? */
896 if (dy > dx) {
897
898 /* y-major. Calculate 16-bit fixed point fractional part of a pixel that
899 X advances every time Y advances 1 pixel, truncating the result so that
900 we won't overrun the endpoint along the X axis */
901 erradj = ((dx << 16) / dy)<<16;
902
903 rstep = Sint32((r2-r1)<<16) / Sint32(dy);
904 gstep = Sint32((g2-g1)<<16) / Sint32(dy);
905 bstep = Sint32((b2-b1)<<16) / Sint32(dy);
906
907 /* draw all pixels other than the first and last */
908 x0pxdir=xx0+xdir;
909 while (--dy) {
910 R += rstep;
911 G += gstep;
912 B += bstep;
913
914 erracctmp = erracc;
915 erracc += erradj;
916 if (erracc <= erracctmp) {
917 /* rollover in error accumulator, x coord advances */
918 xx0=x0pxdir;
919 x0pxdir += xdir;
920 }
921 yy0++; /* y-major so always advance Y */
922
923 /* the AAbits most significant bits of erracc give us the intensity
924 weighting for this pixel, and the complement of the weighting for
925 the paired pixel. */
926 wgt = (erracc >> intshift) & 255;
927
928 a = Uint8(255-wgt);
929 if(alpha != 255)
930 a = Uint8(a*alpha_pp);
931
932 _PutPixelAlpha(dst,xx0,yy0,SDL_MapRGB(dst->format, Uint8(R>>16), Uint8(G>>16), Uint8(B>>16)),a);
933
934 a = Uint8(wgt);
935 if(alpha != 255)
936 a = Uint8(a*alpha_pp);
937
938 _PutPixelAlpha(dst,x0pxdir,yy0,SDL_MapRGB(dst->format, Uint8(R>>16), Uint8(G>>16), Uint8(B>>16)),a);
939 }
940 } else {
941
942 /* x-major line. Calculate 16-bit fixed-point fractional part of a pixel
943 that Y advances each time X advances 1 pixel, truncating the result so
944 that we won't overrun the endpoint along the X axis. */
945 erradj = ((dy << 16) / dx)<<16;
946
947 rstep = Sint32((r2-r1)<<16) / Sint32(dx);
948 gstep = Sint32((g2-g1)<<16) / Sint32(dx);
949 bstep = Sint32((b2-b1)<<16) / Sint32(dx);
950
951 /* draw all pixels other than the first and last */
952 y0p1=yy0+1;
953 while (--dx) {
954 R += rstep;
955 G += gstep;
956 B += bstep;
957
958 erracctmp = erracc;
959 erracc += erradj;
960 if (erracc <= erracctmp) {
961 /* Accumulator turned over, advance y */
962 yy0=y0p1;
963 y0p1++;
964 }
965 xx0 += xdir; /* x-major so always advance X */
966
967 /* the AAbits most significant bits of erracc give us the intensity
968 weighting for this pixel, and the complement of the weighting for
969 the paired pixel. */
970 wgt = (erracc >> intshift) & 255;
971
972 a = Uint8(255-wgt);
973 if(alpha != 255)
974 a = Uint8(a*alpha_pp);
975
976 _PutPixelAlpha(dst,xx0,yy0,SDL_MapRGB(dst->format, Uint8(R>>16), Uint8(G>>16), Uint8(B>>16)),a);
977
978 a = Uint8(wgt);
979 if(alpha != 255)
980 a = Uint8(a*alpha_pp);
981
982 _PutPixelAlpha(dst,xx0,y0p1,SDL_MapRGB(dst->format, Uint8(R>>16), Uint8(G>>16), Uint8(B>>16)),a);
983 }
984 }
985
986 /* Draw final pixel, always exactly intersected by the line and doesn't
987 need to be weighted. */
988 if(alpha==255)
989 _PutPixel(dst,x2,y2, SDL_MapRGB(dst->format,r2, g2, b2));
990 else
991 _PutPixelAlpha(dst,x2,y2, SDL_MapRGB(dst->format,r2, g2, b2), alpha);
992
993 }
994
sge_AAmcLineAlpha(SDL_Surface * dst,Sint16 x1,Sint16 y1,Sint16 x2,Sint16 y2,Uint8 r1,Uint8 g1,Uint8 b1,Uint8 r2,Uint8 g2,Uint8 b2,Uint8 alpha)995 void sge_AAmcLineAlpha(SDL_Surface *dst, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint8 r1, Uint8 g1, Uint8 b1, Uint8 r2, Uint8 g2, Uint8 b2, Uint8 alpha)
996 {
997 if ( SDL_MUSTLOCK(dst) && _sge_lock )
998 if ( SDL_LockSurface(dst) < 0 )
999 return;
1000
1001 _AAmcLineAlpha(dst, x1, y1, x2, y2, r1, g1, b1, r2, g2, b2, alpha);
1002
1003 if (SDL_MUSTLOCK(dst) && _sge_lock)
1004 SDL_UnlockSurface(dst);
1005
1006 sge_UpdateRect(dst, (x1 < x2)? x1 : x2, (y1 < y2)? y1 : y2, ((x2-x1)<0)? (x1-x2+1) : (x2-x1+1), ((y2-y1)<0)? (y1-y2+1) : (y2-y1+1));
1007 }
1008
sge_AAmcLine(SDL_Surface * Surface,Sint16 x1,Sint16 y1,Sint16 x2,Sint16 y2,Uint8 r1,Uint8 g1,Uint8 b1,Uint8 r2,Uint8 g2,Uint8 b2)1009 void sge_AAmcLine(SDL_Surface *Surface, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint8 r1, Uint8 g1, Uint8 b1, Uint8 r2, Uint8 g2, Uint8 b2)
1010 {
1011 sge_AAmcLineAlpha(Surface, x1,y1, x2,y2, r1,g1,b1, r2,g2,b2, SDL_ALPHA_OPAQUE);
1012 }
1013
1014
1015
1016 /**********************************************************************************/
1017 /** Figure functions **/
1018 /**********************************************************************************/
1019
1020 //==================================================================================
1021 // Draws a rectangle
1022 //==================================================================================
sge_Rect(SDL_Surface * Surface,Sint16 x1,Sint16 y1,Sint16 x2,Sint16 y2,Uint32 color)1023 void sge_Rect(SDL_Surface *Surface, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint32 color)
1024 {
1025 _HLine(Surface,x1,x2,y1,color);
1026 _HLine(Surface,x1,x2,y2,color);
1027 _VLine(Surface,x1,y1,y2,color);
1028 _VLine(Surface,x2,y1,y2,color);
1029
1030 sge_UpdateRect(Surface, x1, y1, x2-x1, 1);
1031 sge_UpdateRect(Surface, x1, y2, x2-x1+1, 1); /* Hmm? */
1032 sge_UpdateRect(Surface, x1, y1, 1, y2-y1);
1033 sge_UpdateRect(Surface, x2, y1, 1, y2-y1);
1034 }
1035
1036 //==================================================================================
1037 // Draws a rectangle (RGB)
1038 //==================================================================================
sge_Rect(SDL_Surface * Surface,Sint16 x1,Sint16 y1,Sint16 x2,Sint16 y2,Uint8 R,Uint8 G,Uint8 B)1039 void sge_Rect(SDL_Surface *Surface, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint8 R, Uint8 G, Uint8 B)
1040 {
1041 sge_Rect(Surface,x1,y1,x2,y2, SDL_MapRGB(Surface->format, R, G, B));
1042 }
1043
1044
1045 //==================================================================================
1046 // Draws a rectangle (alpha)
1047 //==================================================================================
sge_RectAlpha(SDL_Surface * Surface,Sint16 x1,Sint16 y1,Sint16 x2,Sint16 y2,Uint32 color,Uint8 alpha)1048 void sge_RectAlpha(SDL_Surface *Surface, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint32 color, Uint8 alpha)
1049 {
1050 if (SDL_MUSTLOCK(Surface) && _sge_lock)
1051 if (SDL_LockSurface(Surface) < 0)
1052 return;
1053
1054 _HLineAlpha(Surface,x1,x2,y1,color,alpha);
1055 _HLineAlpha(Surface,x1,x2,y2,color,alpha);
1056 _VLineAlpha(Surface,x1,y1,y2,color,alpha);
1057 _VLineAlpha(Surface,x2,y1,y2,color,alpha);
1058
1059 if (SDL_MUSTLOCK(Surface) && _sge_lock) {
1060 SDL_UnlockSurface(Surface);
1061 }
1062
1063 sge_UpdateRect(Surface, x1, y1, x2-x1, 1);
1064 sge_UpdateRect(Surface, x1, y2, x2-x1+1, 1); /* Hmm? */
1065 sge_UpdateRect(Surface, x1, y1, 1, y2-y1);
1066 sge_UpdateRect(Surface, x2, y1, 1, y2-y1);
1067 }
1068
1069 //==================================================================================
1070 // Draws a rectangle (RGB)
1071 //==================================================================================
sge_RectAlpha(SDL_Surface * Surface,Sint16 x1,Sint16 y1,Sint16 x2,Sint16 y2,Uint8 R,Uint8 G,Uint8 B,Uint8 alpha)1072 void sge_RectAlpha(SDL_Surface *Surface, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint8 R, Uint8 G, Uint8 B, Uint8 alpha)
1073 {
1074 sge_RectAlpha(Surface,x1,y1,x2,y2, SDL_MapRGB(Surface->format, R, G, B), alpha);
1075 }
1076
1077
1078 //==================================================================================
1079 // Draws a filled rectangle
1080 //==================================================================================
sge_FilledRect(SDL_Surface * Surface,Sint16 x1,Sint16 y1,Sint16 x2,Sint16 y2,Uint32 color)1081 void sge_FilledRect(SDL_Surface *Surface, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint32 color)
1082 {
1083 Sint16 tmp;
1084 if(x1>x2){
1085 tmp=x1; x1=x2; x2=tmp;
1086 }
1087 if(y1>y2){
1088 tmp=y1; y1=y2; y2=tmp;
1089 }
1090
1091 #if SDL_VERSIONNUM(SDL_MAJOR_VERSION, SDL_MINOR_VERSION, SDL_PATCHLEVEL) < \
1092 SDL_VERSIONNUM(1, 1, 5)
1093 if(x2<Surface->clip_minx || x1>Surface->clip_maxx || y2<Surface->clip_miny || y1>Surface->clip_maxy)
1094 return;
1095 if (x1 < Surface->clip_minx)
1096 x1=Surface->clip_minx;
1097 if (x2 > Surface->clip_maxx)
1098 x2=Surface->clip_maxx;
1099 if (y1 < Surface->clip_miny)
1100 y1=Surface->clip_miny;
1101 if (y2 > Surface->clip_maxy)
1102 y2=Surface->clip_maxy;
1103 #endif
1104
1105 SDL_Rect area;
1106 area.x=x1; area.y=y1;
1107 area.w=x2-x1+1; area.h=y2-y1+1;
1108
1109 SDL_FillRect(Surface,&area,color);
1110
1111 sge_UpdateRect(Surface, x1, y1, x2-x1+1, y2-y1+1);
1112 }
1113
1114 //==================================================================================
1115 // Draws a filled rectangle (RGB)
1116 //==================================================================================
sge_FilledRect(SDL_Surface * Surface,Sint16 x1,Sint16 y1,Sint16 x2,Sint16 y2,Uint8 R,Uint8 G,Uint8 B)1117 void sge_FilledRect(SDL_Surface *Surface, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint8 R, Uint8 G, Uint8 B)
1118 {
1119 sge_FilledRect(Surface,x1,y1,x2,y2, SDL_MapRGB(Surface->format, R, G, B));
1120 }
1121
1122
1123 //==================================================================================
1124 // Draws a filled rectangle (alpha)
1125 //==================================================================================
sge_FilledRectAlpha(SDL_Surface * surface,Sint16 x1,Sint16 y1,Sint16 x2,Sint16 y2,Uint32 color,Uint8 alpha)1126 void sge_FilledRectAlpha(SDL_Surface *surface, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint32 color, Uint8 alpha)
1127 {
1128 /*if( alpha == 255 ){
1129 sge_FilledRect(surface,x1,y1,x2,y2,color);
1130 return;
1131 }*/
1132
1133 /* Fix coords */
1134 Sint16 tmp;
1135 if(x1>x2){
1136 tmp=x1; x1=x2; x2=tmp;
1137 }
1138 if(y1>y2){
1139 tmp=y1; y1=y2; y2=tmp;
1140 }
1141
1142 /* Clipping */
1143 if(x2<sge_clip_xmin(surface) || x1>sge_clip_xmax(surface) || y2<sge_clip_ymin(surface) || y1>sge_clip_ymax(surface))
1144 return;
1145 if (x1 < sge_clip_xmin(surface))
1146 x1 = sge_clip_xmin(surface);
1147 if (x2 > sge_clip_xmax(surface))
1148 x2 = sge_clip_xmax(surface);
1149 if (y1 < sge_clip_ymin(surface))
1150 y1 = sge_clip_ymin(surface);
1151 if (y2 > sge_clip_ymax(surface))
1152 y2 = sge_clip_ymax(surface);
1153
1154 Uint32 Rmask = surface->format->Rmask, Gmask = surface->format->Gmask, Bmask = surface->format->Bmask, Amask = surface->format->Amask;
1155 Uint32 R,G,B,A=0;
1156 Sint16 x,y;
1157
1158 if (SDL_MUSTLOCK(surface) && _sge_lock)
1159 if (SDL_LockSurface(surface) < 0)
1160 return;
1161
1162 switch (surface->format->BytesPerPixel) {
1163 case 1: { /* Assuming 8-bpp */
1164 Uint8 *row, *pixel;
1165 Uint8 dR, dG, dB;
1166
1167 Uint8 sR = surface->format->palette->colors[color].r;
1168 Uint8 sG = surface->format->palette->colors[color].g;
1169 Uint8 sB = surface->format->palette->colors[color].b;
1170
1171 for(y = y1; y<=y2; y++){
1172 row = (Uint8 *)surface->pixels + y*surface->pitch;
1173 for(x = x1; x <= x2; x++){
1174 pixel = row + x;
1175
1176 dR = surface->format->palette->colors[*pixel].r;
1177 dG = surface->format->palette->colors[*pixel].g;
1178 dB = surface->format->palette->colors[*pixel].b;
1179
1180 dR = dR + ((sR-dR)*alpha >> 8);
1181 dG = dG + ((sG-dG)*alpha >> 8);
1182 dB = dB + ((sB-dB)*alpha >> 8);
1183
1184 *pixel = SDL_MapRGB(surface->format, dR, dG, dB);
1185 }
1186 }
1187 }
1188 break;
1189
1190 case 2: { /* Probably 15-bpp or 16-bpp */
1191 Uint16 *row, *pixel;
1192 Uint32 dR=(color & Rmask),dG=(color & Gmask),dB=(color & Bmask),dA=(color & Amask);
1193
1194 for(y = y1; y<=y2; y++){
1195 row = (Uint16 *)surface->pixels + y*surface->pitch/2;
1196 for(x = x1; x <= x2; x++){
1197 pixel = row + x;
1198
1199 R = ((*pixel & Rmask) + (( dR - (*pixel & Rmask) ) * alpha >> 8)) & Rmask;
1200 G = ((*pixel & Gmask) + (( dG - (*pixel & Gmask) ) * alpha >> 8)) & Gmask;
1201 B = ((*pixel & Bmask) + (( dB - (*pixel & Bmask) ) * alpha >> 8)) & Bmask;
1202 if( Amask )
1203 A = ((*pixel & Amask) + (( dA - (*pixel & Amask) ) * alpha >> 8)) & Amask;
1204
1205 *pixel= R | G | B | A;
1206 }
1207 }
1208 }
1209 break;
1210
1211 case 3: { /* Slow 24-bpp mode, usually not used */
1212 Uint8 *row,*pix;
1213 Uint8 dR, dG, dB, dA;
1214 Uint8 rshift8=surface->format->Rshift/8;
1215 Uint8 gshift8=surface->format->Gshift/8;
1216 Uint8 bshift8=surface->format->Bshift/8;
1217 Uint8 ashift8=surface->format->Ashift/8;
1218
1219 Uint8 sR = (color>>surface->format->Rshift)&0xff;
1220 Uint8 sG = (color>>surface->format->Gshift)&0xff;
1221 Uint8 sB = (color>>surface->format->Bshift)&0xff;
1222 Uint8 sA = (color>>surface->format->Ashift)&0xff;
1223
1224 for(y = y1; y<=y2; y++){
1225 row = (Uint8 *)surface->pixels + y * surface->pitch;
1226 for(x = x1; x <= x2; x++){
1227 pix = row + x*3;
1228
1229 dR = *((pix)+rshift8);
1230 dG = *((pix)+gshift8);
1231 dB = *((pix)+bshift8);
1232 dA = *((pix)+ashift8);
1233
1234 dR = dR + ((sR-dR)*alpha >> 8);
1235 dG = dG + ((sG-dG)*alpha >> 8);
1236 dB = dB + ((sB-dB)*alpha >> 8);
1237 dA = dA + ((sA-dA)*alpha >> 8);
1238
1239 *((pix)+rshift8) = dR;
1240 *((pix)+gshift8) = dG;
1241 *((pix)+bshift8) = dB;
1242 *((pix)+ashift8) = dA;
1243 }
1244 }
1245
1246 }
1247 break;
1248
1249 case 4: { /* Probably 32-bpp */
1250 Uint32 *row, *pixel;
1251 Uint32 dR=(color & Rmask),dG=(color & Gmask),dB=(color & Bmask),dA=(color & Amask);
1252
1253 for(y = y1; y<=y2; y++){
1254 row = (Uint32 *)surface->pixels + y*surface->pitch/4;
1255 for(x = x1; x <= x2; x++){
1256 pixel = row + x;
1257
1258 R = ((*pixel & Rmask) + (( dR - (*pixel & Rmask) ) * alpha >> 8)) & Rmask;
1259 G = ((*pixel & Gmask) + (( dG - (*pixel & Gmask) ) * alpha >> 8)) & Gmask;
1260 B = ((*pixel & Bmask) + (( dB - (*pixel & Bmask) ) * alpha >> 8)) & Bmask;
1261 if( Amask )
1262 A = ((*pixel & Amask) + (( dA - (*pixel & Amask) ) * alpha >> 8)) & Amask;
1263
1264 *pixel= R | G | B | A;
1265 }
1266 }
1267 }
1268 break;
1269 }
1270
1271 if (SDL_MUSTLOCK(surface) && _sge_lock) {
1272 SDL_UnlockSurface(surface);
1273 }
1274
1275 sge_UpdateRect(surface, x1, y1, x2-x1+1, y2-y1+1);
1276 }
1277
sge_FilledRectAlpha(SDL_Surface * Surface,Sint16 x1,Sint16 y1,Sint16 x2,Sint16 y2,Uint8 R,Uint8 G,Uint8 B,Uint8 alpha)1278 void sge_FilledRectAlpha(SDL_Surface *Surface, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint8 R, Uint8 G, Uint8 B, Uint8 alpha)
1279 {
1280 sge_FilledRectAlpha(Surface,x1,y1,x2,y2, SDL_MapRGB(Surface->format, R, G, B), alpha);
1281 }
1282
1283
1284 //==================================================================================
1285 // Performs Callback at each ellipse point.
1286 // (from Allegro)
1287 //==================================================================================
sge_DoEllipse(SDL_Surface * Surface,Sint16 x,Sint16 y,Sint16 rx,Sint16 ry,Uint32 color,void Callback (SDL_Surface * Surf,Sint16 X,Sint16 Y,Uint32 Color))1288 void sge_DoEllipse(SDL_Surface *Surface, Sint16 x, Sint16 y, Sint16 rx, Sint16 ry, Uint32 color, void Callback(SDL_Surface *Surf, Sint16 X, Sint16 Y, Uint32 Color) )
1289 {
1290 int ix, iy;
1291 int h, i, j, k;
1292 int oh, oi, oj, ok;
1293
1294 if (rx < 1)
1295 rx = 1;
1296
1297 if (ry < 1)
1298 ry = 1;
1299
1300 h = i = j = k = 0xFFFF;
1301
1302 if (rx > ry) {
1303 ix = 0;
1304 iy = rx * 64;
1305
1306 do {
1307 oh = h;
1308 oi = i;
1309 oj = j;
1310 ok = k;
1311
1312 h = (ix + 32) >> 6;
1313 i = (iy + 32) >> 6;
1314 j = (h * ry) / rx;
1315 k = (i * ry) / rx;
1316
1317 if (((h != oh) || (k != ok)) && (h < oi)) {
1318 Callback(Surface, x+h, y+k, color);
1319 if (h)
1320 Callback(Surface, x-h, y+k, color);
1321 if (k) {
1322 Callback(Surface, x+h, y-k, color);
1323 if (h)
1324 Callback(Surface, x-h, y-k, color);
1325 }
1326 }
1327
1328 if (((i != oi) || (j != oj)) && (h < i)) {
1329 Callback(Surface, x+i, y+j, color);
1330 if (i)
1331 Callback(Surface, x-i, y+j, color);
1332 if (j) {
1333 Callback(Surface, x+i, y-j, color);
1334 if (i)
1335 Callback(Surface, x-i, y-j, color);
1336 }
1337 }
1338
1339 ix = ix + iy / rx;
1340 iy = iy - ix / rx;
1341
1342 } while (i > h);
1343 }
1344 else {
1345 ix = 0;
1346 iy = ry * 64;
1347
1348 do {
1349 oh = h;
1350 oi = i;
1351 oj = j;
1352 ok = k;
1353
1354 h = (ix + 32) >> 6;
1355 i = (iy + 32) >> 6;
1356 j = (h * rx) / ry;
1357 k = (i * rx) / ry;
1358
1359 if (((j != oj) || (i != oi)) && (h < i)) {
1360 Callback(Surface, x+j, y+i, color);
1361 if (j)
1362 Callback(Surface, x-j, y+i, color);
1363 if (i) {
1364 Callback(Surface, x+j, y-i, color);
1365 if (j)
1366 Callback(Surface, x-j, y-i, color);
1367 }
1368 }
1369
1370 if (((k != ok) || (h != oh)) && (h < oi)) {
1371 Callback(Surface, x+k, y+h, color);
1372 if (k)
1373 Callback(Surface, x-k, y+h, color);
1374 if (h) {
1375 Callback(Surface, x+k, y-h, color);
1376 if (k)
1377 Callback(Surface, x-k, y-h, color);
1378 }
1379 }
1380
1381 ix = ix + iy / ry;
1382 iy = iy - ix / ry;
1383
1384 } while(i > h);
1385 }
1386 }
1387
1388
1389 //==================================================================================
1390 // Performs Callback at each ellipse point. (RGB)
1391 //==================================================================================
sge_DoEllipse(SDL_Surface * Surface,Sint16 x,Sint16 y,Sint16 rx,Sint16 ry,Uint8 R,Uint8 G,Uint8 B,void Callback (SDL_Surface * Surf,Sint16 X,Sint16 Y,Uint32 Color))1392 void sge_DoEllipse(SDL_Surface *Surface, Sint16 x, Sint16 y, Sint16 rx, Sint16 ry, Uint8 R, Uint8 G, Uint8 B, void Callback(SDL_Surface *Surf, Sint16 X, Sint16 Y, Uint32 Color) )
1393 {
1394 sge_DoEllipse(Surface,x,y,rx,ry,SDL_MapRGB(Surface->format, R, G, B),Callback);
1395 }
1396
1397
1398 //==================================================================================
1399 // Draws an ellipse
1400 //==================================================================================
sge_Ellipse(SDL_Surface * Surface,Sint16 x,Sint16 y,Sint16 rx,Sint16 ry,Uint32 color)1401 void sge_Ellipse(SDL_Surface *Surface, Sint16 x, Sint16 y, Sint16 rx, Sint16 ry, Uint32 color)
1402 {
1403 if (SDL_MUSTLOCK(Surface) && _sge_lock) {
1404 if (SDL_LockSurface(Surface) < 0)
1405 return;
1406 }
1407
1408 sge_DoEllipse(Surface, x, y, rx, ry, color, _PutPixel);
1409
1410 if (SDL_MUSTLOCK(Surface) && _sge_lock) {
1411 SDL_UnlockSurface(Surface);
1412 }
1413
1414 sge_UpdateRect(Surface, x-rx, y-ry, 2*rx+1, 2*ry+1);
1415
1416 }
1417
1418
1419 //==================================================================================
1420 // Draws an ellipse (RGB)
1421 //==================================================================================
sge_Ellipse(SDL_Surface * Surface,Sint16 x,Sint16 y,Sint16 rx,Sint16 ry,Uint8 R,Uint8 G,Uint8 B)1422 void sge_Ellipse(SDL_Surface *Surface, Sint16 x, Sint16 y, Sint16 rx, Sint16 ry, Uint8 R, Uint8 G, Uint8 B)
1423 {
1424 sge_Ellipse(Surface,x,y,rx,ry,SDL_MapRGB(Surface->format, R, G, B));
1425 }
1426
1427
1428 //==================================================================================
1429 // Draws an ellipse (alpha)
1430 //==================================================================================
sge_EllipseAlpha(SDL_Surface * Surface,Sint16 x,Sint16 y,Sint16 rx,Sint16 ry,Uint32 color,Uint8 alpha)1431 void sge_EllipseAlpha(SDL_Surface *Surface, Sint16 x, Sint16 y, Sint16 rx, Sint16 ry, Uint32 color, Uint8 alpha)
1432 {
1433 if (SDL_MUSTLOCK(Surface) && _sge_lock)
1434 if (SDL_LockSurface(Surface) < 0)
1435 return;
1436
1437 _sge_alpha_hack = alpha;
1438 sge_DoEllipse(Surface, x, y, rx, ry, color, callback_alpha_hack);
1439
1440 if (SDL_MUSTLOCK(Surface) && _sge_lock) {
1441 SDL_UnlockSurface(Surface);
1442 }
1443
1444 sge_UpdateRect(Surface, x-rx, y-ry, 2*rx+1, 2*ry+1);
1445 }
1446
1447
1448 //==================================================================================
1449 // Draws an ellipse (alpha - RGB)
1450 //==================================================================================
sge_EllipseAlpha(SDL_Surface * Surface,Sint16 x,Sint16 y,Sint16 rx,Sint16 ry,Uint8 R,Uint8 G,Uint8 B,Uint8 alpha)1451 void sge_EllipseAlpha(SDL_Surface *Surface, Sint16 x, Sint16 y, Sint16 rx, Sint16 ry, Uint8 R, Uint8 G, Uint8 B, Uint8 alpha)
1452 {
1453 sge_EllipseAlpha(Surface,x,y,rx,ry,SDL_MapRGB(Surface->format, R, G, B),alpha);
1454 }
1455
1456
1457 //==================================================================================
1458 // Draws a filled ellipse
1459 //==================================================================================
sge_FilledEllipse(SDL_Surface * Surface,Sint16 x,Sint16 y,Sint16 rx,Sint16 ry,Uint32 color)1460 void sge_FilledEllipse(SDL_Surface *Surface, Sint16 x, Sint16 y, Sint16 rx, Sint16 ry, Uint32 color)
1461 {
1462 int ix, iy;
1463 int h, i, j, k;
1464 int oh, oi, oj, ok;
1465
1466 if (rx < 1)
1467 rx = 1;
1468
1469 if (ry < 1)
1470 ry = 1;
1471
1472 oh = oi = oj = ok = 0xFFFF;
1473
1474 if (rx > ry) {
1475 ix = 0;
1476 iy = rx * 64;
1477
1478 do {
1479 h = (ix + 32) >> 6;
1480 i = (iy + 32) >> 6;
1481 j = (h * ry) / rx;
1482 k = (i * ry) / rx;
1483
1484 if ((k!=ok) && (k!=oj)) {
1485 if (k){
1486 _HLine(Surface,x-h,x+h,y-k,color);
1487 _HLine(Surface,x-h,x+h,y+k,color);
1488 }else
1489 _HLine(Surface,x-h,x+h,y,color);
1490 ok=k;
1491 }
1492
1493 if ((j!=oj) && (j!=ok) && (k!=j)) {
1494 if (j){
1495 _HLine(Surface,x-i,x+i,y-j,color);
1496 _HLine(Surface,x-i,x+i,y+j,color);
1497 }else
1498 _HLine(Surface,x-i,x+i,y,color);
1499 oj=j;
1500 }
1501
1502 ix = ix + iy / rx;
1503 iy = iy - ix / rx;
1504
1505 } while (i > h);
1506 }
1507 else {
1508 ix = 0;
1509 iy = ry * 64;
1510
1511 do {
1512 h = (ix + 32) >> 6;
1513 i = (iy + 32) >> 6;
1514 j = (h * rx) / ry;
1515 k = (i * rx) / ry;
1516
1517 if ((i!=oi) && (i!=oh)) {
1518 if (i){
1519 _HLine(Surface,x-j,x+j,y-i,color);
1520 _HLine(Surface,x-j,x+j,y+i,color);
1521 }else
1522 _HLine(Surface,x-j,x+j,y,color);
1523 oi=i;
1524 }
1525
1526 if ((h!=oh) && (h!=oi) && (i!=h)) {
1527 if (h){
1528 _HLine(Surface,x-k,x+k,y-h,color);
1529 _HLine(Surface,x-k,x+k,y+h,color);
1530 }else
1531 _HLine(Surface,x-k,x+k,y,color);
1532 oh=h;
1533 }
1534
1535 ix = ix + iy / ry;
1536 iy = iy - ix / ry;
1537
1538 } while(i > h);
1539 }
1540
1541 sge_UpdateRect(Surface, x-rx, y-ry, 2*rx+1, 2*ry+1);
1542 }
1543
1544
1545 //==================================================================================
1546 // Draws a filled ellipse (RGB)
1547 //==================================================================================
sge_FilledEllipse(SDL_Surface * Surface,Sint16 x,Sint16 y,Sint16 rx,Sint16 ry,Uint8 R,Uint8 G,Uint8 B)1548 void sge_FilledEllipse(SDL_Surface *Surface, Sint16 x, Sint16 y, Sint16 rx, Sint16 ry, Uint8 R, Uint8 G, Uint8 B)
1549 {
1550 sge_FilledEllipse(Surface,x,y,rx,ry,SDL_MapRGB(Surface->format, R, G, B));
1551 }
1552
1553
1554
1555 //==================================================================================
1556 // Draws a filled ellipse (alpha)
1557 //==================================================================================
sge_FilledEllipseAlpha(SDL_Surface * Surface,Sint16 x,Sint16 y,Sint16 rx,Sint16 ry,Uint32 color,Uint8 alpha)1558 void sge_FilledEllipseAlpha(SDL_Surface *Surface, Sint16 x, Sint16 y, Sint16 rx, Sint16 ry, Uint32 color, Uint8 alpha)
1559 {
1560 int ix, iy;
1561 int h, i, j, k;
1562 int oh, oi, oj, ok;
1563
1564 if (SDL_MUSTLOCK(Surface) && _sge_lock)
1565 if (SDL_LockSurface(Surface) < 0)
1566 return;
1567
1568 if (rx < 1)
1569 rx = 1;
1570
1571 if (ry < 1)
1572 ry = 1;
1573
1574 oh = oi = oj = ok = 0xFFFF;
1575
1576 if (rx > ry) {
1577 ix = 0;
1578 iy = rx * 64;
1579
1580 do {
1581 h = (ix + 32) >> 6;
1582 i = (iy + 32) >> 6;
1583 j = (h * ry) / rx;
1584 k = (i * ry) / rx;
1585
1586 if ((k!=ok) && (k!=oj)) {
1587 if (k){
1588 _HLineAlpha(Surface,x-h,x+h,y-k,color,alpha);
1589 _HLineAlpha(Surface,x-h,x+h,y+k,color,alpha);
1590 }else
1591 _HLineAlpha(Surface,x-h,x+h,y,color,alpha);
1592 ok=k;
1593 }
1594
1595 if ((j!=oj) && (j!=ok) && (k!=j)) {
1596 if (j){
1597 _HLineAlpha(Surface,x-i,x+i,y-j,color,alpha);
1598 _HLineAlpha(Surface,x-i,x+i,y+j,color,alpha);
1599 }else
1600 _HLineAlpha(Surface,x-i,x+i,y,color,alpha);
1601 oj=j;
1602 }
1603
1604 ix = ix + iy / rx;
1605 iy = iy - ix / rx;
1606
1607 } while (i > h);
1608 }
1609 else {
1610 ix = 0;
1611 iy = ry * 64;
1612
1613 do {
1614 h = (ix + 32) >> 6;
1615 i = (iy + 32) >> 6;
1616 j = (h * rx) / ry;
1617 k = (i * rx) / ry;
1618
1619 if ((i!=oi) && (i!=oh)) {
1620 if (i){
1621 _HLineAlpha(Surface,x-j,x+j,y-i,color,alpha);
1622 _HLineAlpha(Surface,x-j,x+j,y+i,color,alpha);
1623 }else
1624 _HLineAlpha(Surface,x-j,x+j,y,color,alpha);
1625 oi=i;
1626 }
1627
1628 if ((h!=oh) && (h!=oi) && (i!=h)) {
1629 if (h){
1630 _HLineAlpha(Surface,x-k,x+k,y-h,color,alpha);
1631 _HLineAlpha(Surface,x-k,x+k,y+h,color,alpha);
1632 }else
1633 _HLineAlpha(Surface,x-k,x+k,y,color,alpha);
1634 oh=h;
1635 }
1636
1637 ix = ix + iy / ry;
1638 iy = iy - ix / ry;
1639
1640 } while(i > h);
1641 }
1642
1643 if (SDL_MUSTLOCK(Surface) && _sge_lock) {
1644 SDL_UnlockSurface(Surface);
1645 }
1646
1647 sge_UpdateRect(Surface, x-rx, y-ry, 2*rx+1, 2*ry+1);
1648 }
1649
1650
1651 //==================================================================================
1652 // Draws a filled ellipse (alpha - RGB)
1653 //==================================================================================
sge_FilledEllipseAlpha(SDL_Surface * Surface,Sint16 x,Sint16 y,Sint16 rx,Sint16 ry,Uint8 R,Uint8 G,Uint8 B,Uint8 alpha)1654 void sge_FilledEllipseAlpha(SDL_Surface *Surface, Sint16 x, Sint16 y, Sint16 rx, Sint16 ry, Uint8 R, Uint8 G, Uint8 B, Uint8 alpha)
1655 {
1656 sge_FilledEllipseAlpha(Surface,x,y,rx,ry,SDL_MapRGB(Surface->format, R, G, B),alpha);
1657 }
1658
1659
1660 //==================================================================================
1661 // Draws an anti-aliased ellipse (alpha)
1662 // Some of this code is taken from "TwinLib" (http://www.twinlib.org) written by
1663 // Nicolas Roard (nicolas@roard.com)
1664 //==================================================================================
sge_AAEllipseAlpha(SDL_Surface * surface,Sint16 xc,Sint16 yc,Sint16 rx,Sint16 ry,Uint32 color,Uint8 alpha)1665 void sge_AAEllipseAlpha(SDL_Surface *surface, Sint16 xc, Sint16 yc, Sint16 rx, Sint16 ry, Uint32 color, Uint8 alpha)
1666 {
1667 /* Sanity check */
1668 if (rx < 1)
1669 rx = 1;
1670 if (ry < 1)
1671 ry = 1;
1672
1673 int a2 = rx * rx;
1674 int b2 = ry * ry;
1675
1676 int ds = 2 * a2;
1677 int dt = 2 * b2;
1678
1679 int dxt = int (a2 / sqrt(a2 + b2));
1680
1681 int t = 0;
1682 int s = -2 * a2 * ry;
1683 int d = 0;
1684
1685 Sint16 x = xc;
1686 Sint16 y = yc - ry;
1687
1688 Sint16 xs, ys, dyt;
1689 float cp, is, ip, imax = 1.0;
1690
1691 Uint8 s_alpha, p_alpha;
1692 float alpha_pp = float(alpha)/255;
1693
1694 /* Lock surface */
1695 if ( SDL_MUSTLOCK(surface) && _sge_lock )
1696 if ( SDL_LockSurface(surface) < 0 )
1697 return;
1698
1699 /* "End points" */
1700 _PutPixelAlpha(surface, x, y, color, alpha);
1701 _PutPixelAlpha(surface, 2*xc-x, y, color, alpha);
1702
1703 _PutPixelAlpha(surface, x, 2*yc-y, color, alpha);
1704 _PutPixelAlpha(surface, 2*xc-x, 2*yc-y, color, alpha);
1705
1706 int i;
1707
1708 for (i = 1; i <= dxt; i++)
1709 {
1710 x--;
1711 d += t - b2;
1712
1713 if (d >= 0)
1714 ys = y - 1;
1715 else if ((d - s - a2) > 0)
1716 {
1717 if ((2 * d - s - a2) >= 0)
1718 ys = y + 1;
1719 else
1720 {
1721 ys = y;
1722 y++;
1723 d -= s + a2;
1724 s += ds;
1725 }
1726 }
1727 else
1728 {
1729 y++;
1730 ys = y + 1;
1731 d -= s + a2;
1732 s += ds;
1733 }
1734
1735 t -= dt;
1736
1737 /* Calculate alpha */
1738 cp = float(abs(d)) / abs(s);
1739 is = float( cp * imax + 0.1 );
1740 ip = float( imax - is + 0.2 );
1741
1742 /* Overflow check */
1743 if( is > 1.0 )
1744 is = 1.0;
1745 if( ip > 1.0 )
1746 ip = 1.0;
1747
1748 /* Calculate alpha level */
1749 s_alpha = Uint8(is*255);
1750 p_alpha = Uint8(ip*255);
1751 if( alpha != 255 ){
1752 s_alpha = Uint8(s_alpha*alpha_pp);
1753 p_alpha = Uint8(p_alpha*alpha_pp);
1754 }
1755
1756
1757 /* Upper half */
1758 _PutPixelAlpha(surface, x, y, color, p_alpha);
1759 _PutPixelAlpha(surface, 2*xc-x, y, color, p_alpha);
1760
1761 _PutPixelAlpha(surface, x, ys, color, s_alpha);
1762 _PutPixelAlpha(surface, 2*xc-x, ys, color, s_alpha);
1763
1764
1765 /* Lower half */
1766 _PutPixelAlpha(surface, x, 2*yc-y, color, p_alpha);
1767 _PutPixelAlpha(surface, 2*xc-x, 2*yc-y, color, p_alpha);
1768
1769 _PutPixelAlpha(surface, x, 2*yc-ys, color, s_alpha);
1770 _PutPixelAlpha(surface, 2*xc-x, 2*yc-ys, color, s_alpha);
1771 }
1772
1773 dyt = abs(y - yc);
1774
1775 for (i = 1; i <= dyt; i++)
1776 {
1777 y++;
1778 d -= s + a2;
1779
1780 if (d <= 0)
1781 xs = x + 1;
1782 else if ((d + t - b2) < 0)
1783 {
1784 if ((2 * d + t - b2) <= 0)
1785 xs = x - 1;
1786 else
1787 {
1788 xs = x;
1789 x--;
1790 d += t - b2;
1791 t -= dt;
1792 }
1793 }
1794 else
1795 {
1796 x--;
1797 xs = x - 1;
1798 d += t - b2;
1799 t -= dt;
1800 }
1801
1802 s += ds;
1803
1804 /* Calculate alpha */
1805 cp = float(abs(d)) / abs(t);
1806 is = float( cp * imax + 0.1 );
1807 ip = float( imax - is + 0.2 );
1808
1809 /* Overflow check */
1810 if( is > 1.0 )
1811 is = 1.0;
1812 if( ip > 1.0 )
1813 ip = 1.0;
1814
1815 /* Calculate alpha level */
1816 s_alpha = Uint8(is*255);
1817 p_alpha = Uint8(ip*255);
1818 if( alpha != 255 ){
1819 s_alpha = Uint8(s_alpha*alpha_pp);
1820 p_alpha = Uint8(p_alpha*alpha_pp);
1821 }
1822
1823
1824 /* Upper half */
1825 _PutPixelAlpha(surface, x, y, color, p_alpha);
1826 _PutPixelAlpha(surface, 2*xc-x, y, color, p_alpha);
1827
1828 _PutPixelAlpha(surface, xs, y, color, s_alpha);
1829 _PutPixelAlpha(surface, 2*xc-xs, y, color, s_alpha);
1830
1831
1832 /* Lower half*/
1833 _PutPixelAlpha(surface, x, 2*yc-y, color, p_alpha);
1834 _PutPixelAlpha(surface, 2*xc-x, 2*yc-y, color, p_alpha);
1835
1836 _PutPixelAlpha(surface, xs, 2*yc-y, color, s_alpha);
1837 _PutPixelAlpha(surface, 2*xc-xs, 2*yc-y, color, s_alpha);
1838 }
1839
1840 /* unlock surface */
1841 if (SDL_MUSTLOCK(surface) && _sge_lock) {
1842 SDL_UnlockSurface(surface);
1843 }
1844
1845 /* Update surface if needed */
1846 sge_UpdateRect(surface, xc-rx, yc-ry, 2*rx+1, 2*ry+1);
1847 }
1848
1849
1850 //==================================================================================
1851 // Draws an anti-aliased ellipse (alpha - RGB)
1852 //==================================================================================
sge_AAEllipseAlpha(SDL_Surface * surface,Sint16 xc,Sint16 yc,Sint16 rx,Sint16 ry,Uint8 R,Uint8 G,Uint8 B,Uint8 alpha)1853 void sge_AAEllipseAlpha(SDL_Surface *surface, Sint16 xc, Sint16 yc, Sint16 rx, Sint16 ry, Uint8 R, Uint8 G, Uint8 B, Uint8 alpha)
1854 {
1855 sge_AAEllipseAlpha(surface,xc,yc,rx,ry,SDL_MapRGB(surface->format, R, G, B),alpha);
1856 }
1857
1858
1859 //==================================================================================
1860 // Draws an anti-aliased ellipse
1861 //==================================================================================
sge_AAEllipse(SDL_Surface * surface,Sint16 xc,Sint16 yc,Sint16 rx,Sint16 ry,Uint32 color)1862 void sge_AAEllipse(SDL_Surface *surface, Sint16 xc, Sint16 yc, Sint16 rx, Sint16 ry, Uint32 color)
1863 {
1864 sge_AAEllipseAlpha(surface,xc,yc,rx,ry,color,255);
1865 }
1866
1867 //==================================================================================
1868 // Draws an anti-aliased ellipse (RGB)
1869 //==================================================================================
sge_AAEllipse(SDL_Surface * surface,Sint16 xc,Sint16 yc,Sint16 rx,Sint16 ry,Uint8 R,Uint8 G,Uint8 B)1870 void sge_AAEllipse(SDL_Surface *surface, Sint16 xc, Sint16 yc, Sint16 rx, Sint16 ry, Uint8 R, Uint8 G, Uint8 B)
1871 {
1872 sge_AAEllipseAlpha(surface,xc,yc,rx,ry,SDL_MapRGB(surface->format, R, G, B),255);
1873 }
1874
1875
1876 //==================================================================================
1877 // Draws a filled anti-aliased ellipse
1878 // This is just a quick hack...
1879 //==================================================================================
sge_AAFilledEllipse(SDL_Surface * surface,Sint16 xc,Sint16 yc,Sint16 rx,Sint16 ry,Uint32 color)1880 void sge_AAFilledEllipse(SDL_Surface *surface, Sint16 xc, Sint16 yc, Sint16 rx, Sint16 ry, Uint32 color)
1881 {
1882 /* Sanity check */
1883 if (rx < 1)
1884 rx = 1;
1885 if (ry < 1)
1886 ry = 1;
1887
1888 int a2 = rx * rx;
1889 int b2 = ry * ry;
1890
1891 int ds = 2 * a2;
1892 int dt = 2 * b2;
1893
1894 int dxt = int (a2 / sqrt(a2 + b2));
1895
1896 int t = 0;
1897 int s = -2 * a2 * ry;
1898 int d = 0;
1899
1900 Sint16 x = xc;
1901 Sint16 y = yc - ry;
1902
1903 Sint16 xs, ys, dyt;
1904 float cp, is, ip, imax = 1.0;
1905
1906
1907 /* Lock surface */
1908 if ( SDL_MUSTLOCK(surface) && _sge_lock )
1909 if ( SDL_LockSurface(surface) < 0 )
1910 return;
1911
1912 /* "End points" */
1913 _PutPixel(surface, x, y, color);
1914 _PutPixel(surface, 2*xc-x, y, color);
1915
1916 _PutPixel(surface, x, 2*yc-y, color);
1917 _PutPixel(surface, 2*xc-x, 2*yc-y, color);
1918
1919 /* unlock surface */
1920 if (SDL_MUSTLOCK(surface) && _sge_lock)
1921 SDL_UnlockSurface(surface);
1922
1923 _VLine(surface, x, y+1, 2*yc-y-1, color);
1924
1925 int i;
1926
1927 for (i = 1; i <= dxt; i++)
1928 {
1929 x--;
1930 d += t - b2;
1931
1932 if (d >= 0)
1933 ys = y - 1;
1934 else if ((d - s - a2) > 0)
1935 {
1936 if ((2 * d - s - a2) >= 0)
1937 ys = y + 1;
1938 else
1939 {
1940 ys = y;
1941 y++;
1942 d -= s + a2;
1943 s += ds;
1944 }
1945 }
1946 else
1947 {
1948 y++;
1949 ys = y + 1;
1950 d -= s + a2;
1951 s += ds;
1952 }
1953
1954 t -= dt;
1955
1956 /* Calculate alpha */
1957 cp = (float) abs(d) / abs(s);
1958 is = cp * imax;
1959 ip = imax - is;
1960
1961
1962 /* Lock surface */
1963 if ( SDL_MUSTLOCK(surface) && _sge_lock )
1964 if ( SDL_LockSurface(surface) < 0 )
1965 return;
1966
1967 /* Upper half */
1968 _PutPixelAlpha(surface, x, y, color, Uint8(ip*255));
1969 _PutPixelAlpha(surface, 2*xc-x, y, color, Uint8(ip*255));
1970
1971 _PutPixelAlpha(surface, x, ys, color, Uint8(is*255));
1972 _PutPixelAlpha(surface, 2*xc-x, ys, color, Uint8(is*255));
1973
1974
1975 /* Lower half */
1976 _PutPixelAlpha(surface, x, 2*yc-y, color, Uint8(ip*255));
1977 _PutPixelAlpha(surface, 2*xc-x, 2*yc-y, color, Uint8(ip*255));
1978
1979 _PutPixelAlpha(surface, x, 2*yc-ys, color, Uint8(is*255));
1980 _PutPixelAlpha(surface, 2*xc-x, 2*yc-ys, color, Uint8(is*255));
1981
1982 /* unlock surface */
1983 if (SDL_MUSTLOCK(surface) && _sge_lock)
1984 SDL_UnlockSurface(surface);
1985
1986
1987 /* Fill */
1988 _VLine(surface, x, y+1, 2*yc-y-1, color);
1989 _VLine(surface, 2*xc-x, y+1, 2*yc-y-1, color);
1990 _VLine(surface, x, ys+1, 2*yc-ys-1, color);
1991 _VLine(surface, 2*xc-x, ys+1, 2*yc-ys-1, color);
1992 }
1993
1994 dyt = abs(y - yc);
1995
1996 for (i = 1; i <= dyt; i++)
1997 {
1998 y++;
1999 d -= s + a2;
2000
2001 if (d <= 0)
2002 xs = x + 1;
2003 else if ((d + t - b2) < 0)
2004 {
2005 if ((2 * d + t - b2) <= 0)
2006 xs = x - 1;
2007 else
2008 {
2009 xs = x;
2010 x--;
2011 d += t - b2;
2012 t -= dt;
2013 }
2014 }
2015 else
2016 {
2017 x--;
2018 xs = x - 1;
2019 d += t - b2;
2020 t -= dt;
2021 }
2022
2023 s += ds;
2024
2025 /* Calculate alpha */
2026 cp = (float) abs(d) / abs(t);
2027 is = cp * imax;
2028 ip = imax - is;
2029
2030
2031 /* Lock surface */
2032 if ( SDL_MUSTLOCK(surface) && _sge_lock )
2033 if ( SDL_LockSurface(surface) < 0 )
2034 return;
2035
2036 /* Upper half */
2037 _PutPixelAlpha(surface, x, y, color, Uint8(ip*255));
2038 _PutPixelAlpha(surface, 2*xc-x, y, color, Uint8(ip*255));
2039
2040 _PutPixelAlpha(surface, xs, y, color, Uint8(is*255));
2041 _PutPixelAlpha(surface, 2*xc-xs, y, color, Uint8(is*255));
2042
2043
2044 /* Lower half*/
2045 _PutPixelAlpha(surface, x, 2*yc-y, color, Uint8(ip*255));
2046 _PutPixelAlpha(surface, 2*xc-x, 2*yc-y, color, Uint8(ip*255));
2047
2048 _PutPixelAlpha(surface, xs, 2*yc-y, color, Uint8(is*255));
2049 _PutPixelAlpha(surface, 2*xc-xs, 2*yc-y, color, Uint8(is*255));
2050
2051 /* unlock surface */
2052 if (SDL_MUSTLOCK(surface) && _sge_lock)
2053 SDL_UnlockSurface(surface);
2054
2055 /* Fill */
2056 _HLine(surface, x+1, 2*xc-x-1, y, color);
2057 _HLine(surface, xs+1, 2*xc-xs-1, y, color);
2058 _HLine(surface, x+1, 2*xc-x-1, 2*yc-y, color);
2059 _HLine(surface, xs+1, 2*xc-xs-1, 2*yc-y, color);
2060 }
2061
2062 /* Update surface if needed */
2063 sge_UpdateRect(surface, xc-rx, yc-ry, 2*rx+1, 2*ry+1);
2064 }
2065
2066
2067 //==================================================================================
2068 // Draws a filled anti-aliased ellipse (RGB)
2069 //==================================================================================
sge_AAFilledEllipse(SDL_Surface * surface,Sint16 xc,Sint16 yc,Sint16 rx,Sint16 ry,Uint8 R,Uint8 G,Uint8 B)2070 void sge_AAFilledEllipse(SDL_Surface *surface, Sint16 xc, Sint16 yc, Sint16 rx, Sint16 ry, Uint8 R, Uint8 G, Uint8 B)
2071 {
2072 sge_AAFilledEllipse(surface,xc,yc,rx,ry,SDL_MapRGB(surface->format, R, G, B));
2073 }
2074
2075
2076
2077
2078
2079 //==================================================================================
2080 // Performs Callback at each circle point.
2081 //==================================================================================
sge_DoCircle(SDL_Surface * Surface,Sint16 x,Sint16 y,Sint16 r,Uint32 color,void Callback (SDL_Surface * Surf,Sint16 X,Sint16 Y,Uint32 Color))2082 void sge_DoCircle(SDL_Surface *Surface, Sint16 x, Sint16 y, Sint16 r, Uint32 color, void Callback(SDL_Surface *Surf, Sint16 X, Sint16 Y, Uint32 Color))
2083 {
2084 Sint16 cx = 0;
2085 Sint16 cy = r;
2086 Sint16 df = 1 - r;
2087 Sint16 d_e = 3;
2088 Sint16 d_se = -2 * r + 5;
2089
2090 do {
2091 Callback(Surface, x+cx, y+cy, color);
2092 Callback(Surface, x-cx, y+cy, color);
2093 Callback(Surface, x+cx, y-cy, color);
2094 Callback(Surface, x-cx, y-cy, color);
2095 Callback(Surface, x+cy, y+cx, color);
2096 Callback(Surface, x+cy, y-cx, color);
2097 Callback(Surface, x-cy, y+cx, color);
2098 Callback(Surface, x-cy, y-cx, color);
2099
2100 if (df < 0) {
2101 df += d_e;
2102 d_e += 2;
2103 d_se += 2;
2104 }
2105 else {
2106 df += d_se;
2107 d_e += 2;
2108 d_se += 4;
2109 cy--;
2110 }
2111
2112 cx++;
2113
2114 }while(cx <= cy);
2115
2116 }
2117
2118
2119 //==================================================================================
2120 // Performs Callback at each circle point. (RGB)
2121 //==================================================================================
sge_DoCircle(SDL_Surface * Surface,Sint16 x,Sint16 y,Sint16 r,Uint8 R,Uint8 G,Uint8 B,void Callback (SDL_Surface * Surf,Sint16 X,Sint16 Y,Uint32 Color))2122 void sge_DoCircle(SDL_Surface *Surface, Sint16 x, Sint16 y, Sint16 r, Uint8 R, Uint8 G, Uint8 B, void Callback(SDL_Surface *Surf, Sint16 X, Sint16 Y, Uint32 Color))
2123 {
2124 sge_DoCircle(Surface,x,y,r,SDL_MapRGB(Surface->format, R, G, B),Callback);
2125 }
2126
2127
2128 //==================================================================================
2129 // Draws a circle
2130 //==================================================================================
sge_Circle(SDL_Surface * Surface,Sint16 x,Sint16 y,Sint16 r,Uint32 color)2131 void sge_Circle(SDL_Surface *Surface, Sint16 x, Sint16 y, Sint16 r, Uint32 color)
2132 {
2133 if (SDL_MUSTLOCK(Surface) && _sge_lock) {
2134 if (SDL_LockSurface(Surface) < 0)
2135 return;
2136 }
2137
2138 sge_DoCircle(Surface, x, y, r, color, _PutPixel);
2139
2140 if (SDL_MUSTLOCK(Surface) && _sge_lock) {
2141 SDL_UnlockSurface(Surface);
2142 }
2143
2144 sge_UpdateRect(Surface, x-r, y-r, 2*r+1, 2*r+1);
2145 }
2146
2147 //==================================================================================
2148 // Draws a circle (RGB)
2149 //==================================================================================
sge_Circle(SDL_Surface * Surface,Sint16 x,Sint16 y,Sint16 r,Uint8 R,Uint8 G,Uint8 B)2150 void sge_Circle(SDL_Surface *Surface, Sint16 x, Sint16 y, Sint16 r, Uint8 R, Uint8 G, Uint8 B)
2151 {
2152 sge_Circle(Surface,x,y,r,SDL_MapRGB(Surface->format, R, G, B));
2153 }
2154
2155
2156 //==================================================================================
2157 // Draws a circle (alpha)
2158 //==================================================================================
sge_CircleAlpha(SDL_Surface * Surface,Sint16 x,Sint16 y,Sint16 r,Uint32 color,Uint8 alpha)2159 void sge_CircleAlpha(SDL_Surface *Surface, Sint16 x, Sint16 y, Sint16 r, Uint32 color, Uint8 alpha)
2160 {
2161 if (SDL_MUSTLOCK(Surface) && _sge_lock)
2162 if (SDL_LockSurface(Surface) < 0)
2163 return;
2164
2165 _sge_alpha_hack = alpha;
2166 sge_DoCircle(Surface, x, y, r, color, callback_alpha_hack);
2167
2168 if (SDL_MUSTLOCK(Surface) && _sge_lock) {
2169 SDL_UnlockSurface(Surface);
2170 }
2171
2172 sge_UpdateRect(Surface, x-r, y-r, 2*r+1, 2*r+1);
2173 }
2174
2175 //==================================================================================
2176 // Draws a circle (alpha - RGB)
2177 //==================================================================================
sge_CircleAlpha(SDL_Surface * Surface,Sint16 x,Sint16 y,Sint16 r,Uint8 R,Uint8 G,Uint8 B,Uint8 alpha)2178 void sge_CircleAlpha(SDL_Surface *Surface, Sint16 x, Sint16 y, Sint16 r, Uint8 R, Uint8 G, Uint8 B, Uint8 alpha)
2179 {
2180 sge_CircleAlpha(Surface,x,y,r,SDL_MapRGB(Surface->format, R, G, B),alpha);
2181 }
2182
2183
2184 //==================================================================================
2185 // Draws a filled circle
2186 //==================================================================================
sge_FilledCircle(SDL_Surface * Surface,Sint16 x,Sint16 y,Sint16 r,Uint32 color)2187 void sge_FilledCircle(SDL_Surface *Surface, Sint16 x, Sint16 y, Sint16 r, Uint32 color)
2188 {
2189 Sint16 cx = 0;
2190 Sint16 cy = r;
2191 bool draw=true;
2192 Sint16 df = 1 - r;
2193 Sint16 d_e = 3;
2194 Sint16 d_se = -2 * r + 5;
2195
2196 do {
2197 if(draw){
2198 _HLine(Surface,x-cx,x+cx,y+cy,color);
2199 _HLine(Surface,x-cx,x+cx,y-cy,color);
2200 draw=false;
2201 }
2202 if(cx!=cy){
2203 if(cx){
2204 _HLine(Surface,x-cy,x+cy,y-cx,color);
2205 _HLine(Surface,x-cy,x+cy,y+cx,color);
2206 }else
2207 _HLine(Surface,x-cy,x+cy,y,color);
2208 }
2209
2210 if (df < 0) {
2211 df += d_e;
2212 d_e += 2;
2213 d_se += 2;
2214 }
2215 else {
2216 df += d_se;
2217 d_e += 2;
2218 d_se += 4;
2219 cy--;
2220 draw=true;
2221 }
2222 cx++;
2223 }while(cx <= cy);
2224
2225 sge_UpdateRect(Surface, x-r, y-r, 2*r+1, 2*r+1);
2226 }
2227
2228 //==================================================================================
2229 // Draws a filled circle (RGB)
2230 //==================================================================================
sge_FilledCircle(SDL_Surface * Surface,Sint16 x,Sint16 y,Sint16 r,Uint8 R,Uint8 G,Uint8 B)2231 void sge_FilledCircle(SDL_Surface *Surface, Sint16 x, Sint16 y, Sint16 r, Uint8 R, Uint8 G, Uint8 B)
2232 {
2233 sge_FilledCircle(Surface,x,y,r,SDL_MapRGB(Surface->format, R, G, B));
2234 }
2235
2236
2237 //==================================================================================
2238 // Draws a filled circle (alpha)
2239 //==================================================================================
sge_FilledCircleAlpha(SDL_Surface * Surface,Sint16 x,Sint16 y,Sint16 r,Uint32 color,Uint8 alpha)2240 void sge_FilledCircleAlpha(SDL_Surface *Surface, Sint16 x, Sint16 y, Sint16 r, Uint32 color, Uint8 alpha)
2241 {
2242 Sint16 cx = 0;
2243 Sint16 cy = r;
2244 bool draw=true;
2245 Sint16 df = 1 - r;
2246 Sint16 d_e = 3;
2247 Sint16 d_se = -2 * r + 5;
2248
2249 if (SDL_MUSTLOCK(Surface) && _sge_lock)
2250 if (SDL_LockSurface(Surface) < 0)
2251 return;
2252
2253 do {
2254 if(draw){
2255 _HLineAlpha(Surface,x-cx,x+cx,y+cy,color,alpha);
2256 _HLineAlpha(Surface,x-cx,x+cx,y-cy,color,alpha);
2257 draw=false;
2258 }
2259 if(cx!=cy){
2260 if(cx){
2261 _HLineAlpha(Surface,x-cy,x+cy,y-cx,color,alpha);
2262 _HLineAlpha(Surface,x-cy,x+cy,y+cx,color,alpha);
2263 }else
2264 _HLineAlpha(Surface,x-cy,x+cy,y,color,alpha);
2265 }
2266
2267 if (df < 0) {
2268 df += d_e;
2269 d_e += 2;
2270 d_se += 2;
2271 }
2272 else {
2273 df += d_se;
2274 d_e += 2;
2275 d_se += 4;
2276 cy--;
2277 draw=true;
2278 }
2279 cx++;
2280 }while(cx <= cy);
2281
2282 if (SDL_MUSTLOCK(Surface) && _sge_lock) {
2283 SDL_UnlockSurface(Surface);
2284 }
2285
2286 sge_UpdateRect(Surface, x-r, y-r, 2*r+1, 2*r+1);
2287 }
2288
2289 //==================================================================================
2290 // Draws a filled circle (alpha - RGB)
2291 //==================================================================================
sge_FilledCircleAlpha(SDL_Surface * Surface,Sint16 x,Sint16 y,Sint16 r,Uint8 R,Uint8 G,Uint8 B,Uint8 alpha)2292 void sge_FilledCircleAlpha(SDL_Surface *Surface, Sint16 x, Sint16 y, Sint16 r, Uint8 R, Uint8 G, Uint8 B, Uint8 alpha)
2293 {
2294 sge_FilledCircleAlpha(Surface,x,y,r,SDL_MapRGB(Surface->format, R, G, B),alpha);
2295 }
2296
2297
2298 //==================================================================================
2299 // Draws an anti-aliased circle (alpha)
2300 //==================================================================================
sge_AACircleAlpha(SDL_Surface * surface,Sint16 xc,Sint16 yc,Sint16 r,Uint32 color,Uint8 alpha)2301 void sge_AACircleAlpha(SDL_Surface *surface, Sint16 xc, Sint16 yc, Sint16 r, Uint32 color, Uint8 alpha)
2302 {
2303 sge_AAEllipseAlpha(surface, xc, yc, r, r, color, alpha);
2304 }
2305
2306
2307 //==================================================================================
2308 // Draws an anti-aliased circle (alpha - RGB)
2309 //==================================================================================
sge_AACircleAlpha(SDL_Surface * surface,Sint16 xc,Sint16 yc,Sint16 r,Uint8 R,Uint8 G,Uint8 B,Uint8 alpha)2310 void sge_AACircleAlpha(SDL_Surface *surface, Sint16 xc, Sint16 yc, Sint16 r, Uint8 R, Uint8 G, Uint8 B, Uint8 alpha)
2311 {
2312 sge_AAEllipseAlpha(surface,xc,yc,r,r,SDL_MapRGB(surface->format, R, G, B),alpha);
2313 }
2314
2315
2316 //==================================================================================
2317 // Draws an anti-aliased circle
2318 //==================================================================================
sge_AACircle(SDL_Surface * surface,Sint16 xc,Sint16 yc,Sint16 r,Uint32 color)2319 void sge_AACircle(SDL_Surface *surface, Sint16 xc, Sint16 yc, Sint16 r, Uint32 color)
2320 {
2321 sge_AAEllipseAlpha(surface,xc,yc,r,r,color,255);
2322 }
2323
2324 //==================================================================================
2325 // Draws an anti-aliased circle (RGB)
2326 //==================================================================================
sge_AACircle(SDL_Surface * surface,Sint16 xc,Sint16 yc,Sint16 r,Uint8 R,Uint8 G,Uint8 B)2327 void sge_AACircle(SDL_Surface *surface, Sint16 xc, Sint16 yc, Sint16 r, Uint8 R, Uint8 G, Uint8 B)
2328 {
2329 sge_AAEllipseAlpha(surface,xc,yc,r,r,SDL_MapRGB(surface->format, R, G, B),255);
2330 }
2331
2332
2333 //==================================================================================
2334 // Draws a filled anti-aliased circle
2335 //==================================================================================
sge_AAFilledCircle(SDL_Surface * surface,Sint16 xc,Sint16 yc,Sint16 r,Uint32 color)2336 void sge_AAFilledCircle(SDL_Surface *surface, Sint16 xc, Sint16 yc, Sint16 r, Uint32 color)
2337 {
2338 sge_AAFilledEllipse(surface, xc, yc, r, r, color);
2339 }
2340
2341
2342 //==================================================================================
2343 // Draws a filled anti-aliased circle (RGB)
2344 //==================================================================================
sge_AAFilledCircle(SDL_Surface * surface,Sint16 xc,Sint16 yc,Sint16 r,Uint8 R,Uint8 G,Uint8 B)2345 void sge_AAFilledCircle(SDL_Surface *surface, Sint16 xc, Sint16 yc, Sint16 r, Uint8 R, Uint8 G, Uint8 B)
2346 {
2347 sge_AAFilledEllipse(surface,xc,yc,r,r,SDL_MapRGB(surface->format, R, G, B));
2348 }
2349
2350
2351
2352
2353
2354 //==================================================================================
2355 // Draws a bezier line
2356 //==================================================================================
2357 /* Macro to do the line... 'function' is the line drawing routine */
2358 #define DO_BEZIER(function)\
2359 /*
2360 * Note: I don't think there is any great performance win in translating this to fixed-point integer math,
2361 * most of the time is spent in the line drawing routine.
2362 */\
2363 float x = float(x1), y = float(y1);\
2364 float xp = x, yp = y;\
2365 float delta;\
2366 float dx, d2x, d3x;\
2367 float dy, d2y, d3y;\
2368 float a, b, c;\
2369 int i;\
2370 int n = 1;\
2371 Sint16 xmax=x1, ymax=y1, xmin=x1, ymin=y1;\
2372 \
2373 /* compute number of iterations */\
2374 if(level < 1)\
2375 level=1;\
2376 if(level >= 15)\
2377 level=15; \
2378 while (level-- > 0)\
2379 n*= 2;\
2380 delta = float( 1.0 / float(n) );\
2381 \
2382 /* compute finite differences */\
2383 /* a, b, c are the coefficient of the polynom in t defining the parametric curve */\
2384 /* The computation is done independently for x and y */\
2385 a = float(-x1 + 3*x2 - 3*x3 + x4);\
2386 b = float(3*x1 - 6*x2 + 3*x3);\
2387 c = float(-3*x1 + 3*x2);\
2388 \
2389 d3x = 6 * a * delta*delta*delta;\
2390 d2x = d3x + 2 * b * delta*delta;\
2391 dx = a * delta*delta*delta + b * delta*delta + c * delta;\
2392 \
2393 a = float(-y1 + 3*y2 - 3*y3 + y4);\
2394 b = float(3*y1 - 6*y2 + 3*y3);\
2395 c = float(-3*y1 + 3*y2);\
2396 \
2397 d3y = 6 * a * delta*delta*delta;\
2398 d2y = d3y + 2 * b * delta*delta;\
2399 dy = a * delta*delta*delta + b * delta*delta + c * delta;\
2400 \
2401 if (SDL_MUSTLOCK(surface) && _sge_lock) {\
2402 if (SDL_LockSurface(surface) < 0)\
2403 return;\
2404 }\
2405 \
2406 /* iterate */\
2407 for (i = 0; i < n; i++) {\
2408 x += dx; dx += d2x; d2x += d3x;\
2409 y += dy; dy += d2y; d2y += d3y;\
2410 if(Sint16(xp) != Sint16(x) || Sint16(yp) != Sint16(y)){\
2411 function;\
2412 if(_sge_update==1){\
2413 xmax= (xmax>Sint16(xp))? xmax : Sint16(xp); ymax= (ymax>Sint16(yp))? ymax : Sint16(yp);\
2414 xmin= (xmin<Sint16(xp))? xmin : Sint16(xp); ymin= (ymin<Sint16(yp))? ymin : Sint16(yp);\
2415 xmax= (xmax>Sint16(x))? xmax : Sint16(x); ymax= (ymax>Sint16(y))? ymax : Sint16(y);\
2416 xmin= (xmin<Sint16(x))? xmin : Sint16(x); ymin= (ymin<Sint16(y))? ymin : Sint16(y);\
2417 }\
2418 }\
2419 xp = x; yp = y;\
2420 }\
2421 \
2422 /* unlock the display */\
2423 if (SDL_MUSTLOCK(surface) && _sge_lock) {\
2424 SDL_UnlockSurface(surface);\
2425 }\
2426 \
2427 /* Update the area */\
2428 sge_UpdateRect(surface, xmin, ymin, xmax-xmin+1, ymax-ymin+1);
2429
2430 //==================================================================================
2431 // Draws a bezier line
2432 //==================================================================================
sge_Bezier(SDL_Surface * surface,Sint16 x1,Sint16 y1,Sint16 x2,Sint16 y2,Sint16 x3,Sint16 y3,Sint16 x4,Sint16 y4,int level,Uint32 color)2433 void sge_Bezier(SDL_Surface *surface, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2,Sint16 x3, Sint16 y3, Sint16 x4, Sint16 y4, int level, Uint32 color)
2434 {
2435 DO_BEZIER(_Line(surface, Sint16(xp),Sint16(yp), Sint16(x),Sint16(y), color));
2436 }
2437
2438 //==================================================================================
2439 // Draws a bezier line (RGB)
2440 //==================================================================================
sge_Bezier(SDL_Surface * surface,Sint16 x1,Sint16 y1,Sint16 x2,Sint16 y2,Sint16 x3,Sint16 y3,Sint16 x4,Sint16 y4,int level,Uint8 R,Uint8 G,Uint8 B)2441 void sge_Bezier(SDL_Surface *surface, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2,Sint16 x3, Sint16 y3, Sint16 x4, Sint16 y4, int level, Uint8 R, Uint8 G, Uint8 B)
2442 {
2443 sge_Bezier(surface,x1,y1,x2,y2,x3,y3,x4,y4,level, SDL_MapRGB(surface->format,R,G,B));
2444 }
2445
2446
2447 //==================================================================================
2448 // Draws a bezier line (alpha)
2449 //==================================================================================
sge_BezierAlpha(SDL_Surface * surface,Sint16 x1,Sint16 y1,Sint16 x2,Sint16 y2,Sint16 x3,Sint16 y3,Sint16 x4,Sint16 y4,int level,Uint32 color,Uint8 alpha)2450 void sge_BezierAlpha(SDL_Surface *surface, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2,Sint16 x3, Sint16 y3, Sint16 x4, Sint16 y4, int level, Uint32 color, Uint8 alpha)
2451 {
2452 _sge_alpha_hack = alpha;
2453
2454 DO_BEZIER(sge_DoLine(surface, Sint16(xp),Sint16(yp), Sint16(x),Sint16(y), color, callback_alpha_hack));
2455 }
2456
2457 //==================================================================================
2458 // Draws a bezier line (alpha - RGB)
2459 //==================================================================================
sge_BezierAlpha(SDL_Surface * surface,Sint16 x1,Sint16 y1,Sint16 x2,Sint16 y2,Sint16 x3,Sint16 y3,Sint16 x4,Sint16 y4,int level,Uint8 R,Uint8 G,Uint8 B,Uint8 alpha)2460 void sge_BezierAlpha(SDL_Surface *surface, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2,Sint16 x3, Sint16 y3, Sint16 x4, Sint16 y4, int level, Uint8 R, Uint8 G, Uint8 B, Uint8 alpha)
2461 {
2462 sge_BezierAlpha(surface,x1,y1,x2,y2,x3,y3,x4,y4,level, SDL_MapRGB(surface->format,R,G,B),alpha);
2463 }
2464
2465
2466 //==================================================================================
2467 // Draws an AA bezier line (alpha)
2468 //==================================================================================
sge_AABezierAlpha(SDL_Surface * surface,Sint16 x1,Sint16 y1,Sint16 x2,Sint16 y2,Sint16 x3,Sint16 y3,Sint16 x4,Sint16 y4,int level,Uint32 color,Uint8 alpha)2469 void sge_AABezierAlpha(SDL_Surface *surface, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2,Sint16 x3, Sint16 y3, Sint16 x4, Sint16 y4, int level, Uint32 color, Uint8 alpha)
2470 {
2471 Uint8 update = _sge_update;
2472 Uint8 lock = _sge_lock;
2473 _sge_update = 0;
2474 _sge_lock = 0;
2475
2476 if (SDL_MUSTLOCK(surface) && lock)
2477 if (SDL_LockSurface(surface) < 0)
2478 return;
2479
2480 DO_BEZIER(sge_AALineAlpha(surface, Sint16(xp),Sint16(yp), Sint16(x),Sint16(y), color, alpha));
2481
2482 if (SDL_MUSTLOCK(surface) && lock) {
2483 SDL_UnlockSurface(surface);
2484 }
2485
2486 _sge_update = update;
2487 _sge_lock = lock;
2488
2489 sge_UpdateRect(surface, xmin, ymin, xmax-xmin+1, ymax-ymin+1);
2490 }
2491
2492 //==================================================================================
2493 // Draws an AA bezier line (alpha - RGB)
2494 //==================================================================================
sge_AABezierAlpha(SDL_Surface * surface,Sint16 x1,Sint16 y1,Sint16 x2,Sint16 y2,Sint16 x3,Sint16 y3,Sint16 x4,Sint16 y4,int level,Uint8 R,Uint8 G,Uint8 B,Uint8 alpha)2495 void sge_AABezierAlpha(SDL_Surface *surface, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2,Sint16 x3, Sint16 y3, Sint16 x4, Sint16 y4, int level, Uint8 R, Uint8 G, Uint8 B, Uint8 alpha)
2496 {
2497 sge_AABezierAlpha(surface,x1,y1,x2,y2,x3,y3,x4,y4,level, SDL_MapRGB(surface->format,R,G,B),alpha);
2498 }
2499
2500
2501 //==================================================================================
2502 // Draws an AA bezier line
2503 //==================================================================================
sge_AABezier(SDL_Surface * surface,Sint16 x1,Sint16 y1,Sint16 x2,Sint16 y2,Sint16 x3,Sint16 y3,Sint16 x4,Sint16 y4,int level,Uint32 color)2504 void sge_AABezier(SDL_Surface *surface, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2,Sint16 x3, Sint16 y3, Sint16 x4, Sint16 y4, int level, Uint32 color)
2505 {
2506 sge_AABezierAlpha(surface, x1,y1, x2,y2, x3,y3, x4,y4, level, color, 255);
2507 }
2508
2509 //==================================================================================
2510 // Draws an AA bezier line (RGB)
2511 //==================================================================================
sge_AABezier(SDL_Surface * surface,Sint16 x1,Sint16 y1,Sint16 x2,Sint16 y2,Sint16 x3,Sint16 y3,Sint16 x4,Sint16 y4,int level,Uint8 R,Uint8 G,Uint8 B)2512 void sge_AABezier(SDL_Surface *surface, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2,Sint16 x3, Sint16 y3, Sint16 x4, Sint16 y4, int level, Uint8 R, Uint8 G, Uint8 B)
2513 {
2514 sge_AABezierAlpha(surface,x1,y1,x2,y2,x3,y3,x4,y4,level, SDL_MapRGB(surface->format,R,G,B),255);
2515 }
2516
2517