sge030809/0000755000175000001440000000000007716016413011024 5ustar samuserssge030809/sge_primitives.h0000644000175000001440000002402307713723353014234 0ustar samusers/* * SDL Graphics Extension * Drawing primitives (header) * * Started 990815 (split from sge_draw 010611) * * License: LGPL v2+ (see the file LICENSE) * (c)1999-2003 Anders Lindstrm */ /********************************************************************* * This library is free software; you can redistribute it and/or * * modify it under the terms of the GNU Library General Public * * License as published by the Free Software Foundation; either * * version 2 of the License, or (at your option) any later version. * *********************************************************************/ #ifndef sge_primitives_H #define sge_primitives_H #include "SDL.h" #include "sge_internal.h" #ifdef _SGE_C extern "C" { #endif DECLSPEC void sge_HLine(SDL_Surface *Surface, Sint16 x1, Sint16 x2, Sint16 y, Uint32 Color); DECLSPEC void sge_HLineAlpha(SDL_Surface *Surface, Sint16 x1, Sint16 x2, Sint16 y, Uint32 Color, Uint8 alpha); DECLSPEC void sge_VLine(SDL_Surface *Surface, Sint16 x, Sint16 y1, Sint16 y2, Uint32 Color); DECLSPEC void sge_VLineAlpha(SDL_Surface *Surface, Sint16 x, Sint16 y1, Sint16 y2, Uint32 Color, Uint8 alpha); DECLSPEC 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)); DECLSPEC void sge_Line(SDL_Surface *Surface, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint32 Color); DECLSPEC void sge_LineAlpha(SDL_Surface *Surface, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint32 Color, Uint8 alpha); DECLSPEC void sge_AALine(SDL_Surface *dst, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint32 color); DECLSPEC void sge_AALineAlpha(SDL_Surface *dst, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint32 color, Uint8 alpha); DECLSPEC 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)); DECLSPEC 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); DECLSPEC 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); DECLSPEC 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); DECLSPEC 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); DECLSPEC void sge_Rect(SDL_Surface *Surface, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint32 color); DECLSPEC void sge_RectAlpha(SDL_Surface *Surface, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint32 color, Uint8 alpha); DECLSPEC void sge_FilledRect(SDL_Surface *Surface, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint32 color); DECLSPEC void sge_FilledRectAlpha(SDL_Surface *surface, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint32 color, Uint8 alpha); DECLSPEC 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)); DECLSPEC void sge_Ellipse(SDL_Surface *Surface, Sint16 x, Sint16 y, Sint16 rx, Sint16 ry, Uint32 color); DECLSPEC void sge_EllipseAlpha(SDL_Surface *Surface, Sint16 x, Sint16 y, Sint16 rx, Sint16 ry, Uint32 color, Uint8 Alpha); DECLSPEC void sge_FilledEllipse(SDL_Surface *Surface, Sint16 x, Sint16 y, Sint16 rx, Sint16 ry, Uint32 color); DECLSPEC void sge_FilledEllipseAlpha(SDL_Surface *Surface, Sint16 x, Sint16 y, Sint16 rx, Sint16 ry, Uint32 color, Uint8 alpha); DECLSPEC void sge_AAEllipseAlpha(SDL_Surface *surface, Sint16 xc, Sint16 yc, Sint16 rx, Sint16 ry, Uint32 color, Uint8 alpha); DECLSPEC void sge_AAEllipse(SDL_Surface *surface, Sint16 xc, Sint16 yc, Sint16 rx, Sint16 ry, Uint32 color); DECLSPEC void sge_AAFilledEllipse(SDL_Surface *surface, Sint16 xc, Sint16 yc, Sint16 rx, Sint16 ry, Uint32 color); DECLSPEC 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)); DECLSPEC void sge_Circle(SDL_Surface *Surface, Sint16 x, Sint16 y, Sint16 r, Uint32 color); DECLSPEC void sge_CircleAlpha(SDL_Surface *Surface, Sint16 x, Sint16 y, Sint16 r, Uint32 color, Uint8 alpha); DECLSPEC void sge_FilledCircle(SDL_Surface *Surface, Sint16 x, Sint16 y, Sint16 r, Uint32 color); DECLSPEC void sge_FilledCircleAlpha(SDL_Surface *Surface, Sint16 x, Sint16 y, Sint16 r, Uint32 color, Uint8 alpha); DECLSPEC void sge_AACircleAlpha(SDL_Surface *surface, Sint16 xc, Sint16 yc, Sint16 r, Uint32 color, Uint8 alpha); DECLSPEC void sge_AACircle(SDL_Surface *surface, Sint16 xc, Sint16 yc, Sint16 r, Uint32 color); DECLSPEC void sge_AAFilledCircle(SDL_Surface *surface, Sint16 xc, Sint16 yc, Sint16 r, Uint32 color); DECLSPEC 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); DECLSPEC 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); DECLSPEC 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); DECLSPEC 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); #ifdef _SGE_C } #endif #ifndef sge_C_ONLY DECLSPEC void sge_HLine(SDL_Surface *Surface, Sint16 x1, Sint16 x2, Sint16 y, Uint8 R, Uint8 G, Uint8 B); DECLSPEC void sge_HLineAlpha(SDL_Surface *Surface, Sint16 x1, Sint16 x2, Sint16 y, Uint8 R, Uint8 G, Uint8 B, Uint8 alpha); DECLSPEC void sge_VLine(SDL_Surface *Surface, Sint16 x, Sint16 y1, Sint16 y2, Uint8 R, Uint8 G, Uint8 B); DECLSPEC void sge_VLineAlpha(SDL_Surface *Surface, Sint16 x, Sint16 y1, Sint16 y2, Uint8 R, Uint8 G, Uint8 B, Uint8 alpha); DECLSPEC 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)); DECLSPEC void sge_Line(SDL_Surface *Surface, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint8 R, Uint8 G, Uint8 B); DECLSPEC void sge_LineAlpha(SDL_Surface *Surface, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint8 R, Uint8 G, Uint8 B, Uint8 alpha); DECLSPEC void sge_AALine(SDL_Surface *dst, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint8 r, Uint8 g, Uint8 b); DECLSPEC void sge_AALineAlpha(SDL_Surface *dst, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint8 r, Uint8 g, Uint8 b, Uint8 alpha); DECLSPEC void sge_Rect(SDL_Surface *Surface, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint8 R, Uint8 G, Uint8 B); DECLSPEC void sge_RectAlpha(SDL_Surface *Surface, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint8 R, Uint8 G, Uint8 B, Uint8 alpha); DECLSPEC void sge_FilledRect(SDL_Surface *Surface, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint8 R, Uint8 G, Uint8 B); DECLSPEC void sge_FilledRectAlpha(SDL_Surface *Surface, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint8 R, Uint8 G, Uint8 B, Uint8 alpha); DECLSPEC 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)); DECLSPEC void sge_Ellipse(SDL_Surface *Surface, Sint16 x, Sint16 y, Sint16 rx, Sint16 ry, Uint8 R, Uint8 G, Uint8 B); DECLSPEC void sge_EllipseAlpha(SDL_Surface *Surface, Sint16 x, Sint16 y, Sint16 rx, Sint16 ry, Uint8 R, Uint8 G, Uint8 B, Uint8 alpha); DECLSPEC void sge_FilledEllipse(SDL_Surface *Surface, Sint16 x, Sint16 y, Sint16 rx, Sint16 ry, Uint8 R, Uint8 G, Uint8 B); DECLSPEC void sge_FilledEllipseAlpha(SDL_Surface *Surface, Sint16 x, Sint16 y, Sint16 rx, Sint16 ry, Uint8 R, Uint8 G, Uint8 B, Uint8 alpha); DECLSPEC void sge_AAEllipseAlpha(SDL_Surface *surface, Sint16 xc, Sint16 yc, Sint16 rx, Sint16 ry, Uint8 R, Uint8 G, Uint8 B, Uint8 alpha); DECLSPEC void sge_AAEllipse(SDL_Surface *surface, Sint16 xc, Sint16 yc, Sint16 rx, Sint16 ry, Uint8 R, Uint8 G, Uint8 B); DECLSPEC void sge_AAFilledEllipse(SDL_Surface *surface, Sint16 xc, Sint16 yc, Sint16 rx, Sint16 ry, Uint8 R, Uint8 G, Uint8 B); DECLSPEC 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)); DECLSPEC void sge_Circle(SDL_Surface *Surface, Sint16 x, Sint16 y, Sint16 r, Uint8 R, Uint8 G, Uint8 B); DECLSPEC void sge_CircleAlpha(SDL_Surface *Surface, Sint16 x, Sint16 y, Sint16 r, Uint8 R, Uint8 G, Uint8 B, Uint8 alpha); DECLSPEC void sge_FilledCircle(SDL_Surface *Surface, Sint16 x, Sint16 y, Sint16 r, Uint8 R, Uint8 G, Uint8 B); DECLSPEC void sge_FilledCircleAlpha(SDL_Surface *Surface, Sint16 x, Sint16 y, Sint16 r, Uint8 R, Uint8 G, Uint8 B, Uint8 alpha); DECLSPEC void sge_AACircleAlpha(SDL_Surface *surface, Sint16 xc, Sint16 yc, Sint16 r, Uint8 R, Uint8 G, Uint8 B, Uint8 alpha); DECLSPEC void sge_AACircle(SDL_Surface *surface, Sint16 xc, Sint16 yc, Sint16 r, Uint8 R, Uint8 G, Uint8 B); DECLSPEC void sge_AAFilledCircle(SDL_Surface *surface, Sint16 xc, Sint16 yc, Sint16 r, Uint8 R, Uint8 G, Uint8 B); DECLSPEC 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); DECLSPEC 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); DECLSPEC 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); DECLSPEC 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); #endif /* sge_C_ONLY */ #endif /* sge_primitives_H */ sge030809/sge_tt_text.h0000644000175000001440000001214207714437763013543 0ustar samusers/* * SDL Graphics Extension * Text/TrueType functions (header) * * Started 990815 * * License: LGPL v2+ (see the file LICENSE) * (c)1999-2003 Anders Lindstrm * * Uses the excellent FreeType 2 library, available at: * http://www.freetype.org/ */ /********************************************************************* * This library is free software; you can redistribute it and/or * * modify it under the terms of the GNU Library General Public * * License as published by the Free Software Foundation; either * * version 2 of the License, or (at your option) any later version. * *********************************************************************/ #ifndef sge_tt_text_H #define sge_tt_text_H #include "SDL.h" #include "sge_internal.h" /* Text input flags */ #define SGE_IBG SGE_FLAG1 #define SGE_IDEL SGE_FLAG2 #define SGE_INOKR SGE_FLAG3 #ifndef _SGE_NOTTF /* the truetype font structure */ typedef struct _sge_TTFont sge_TTFont; /* Font style */ #define SGE_TTF_NORMAL SGE_FLAG0 #define SGE_TTF_BOLD SGE_FLAG1 #define SGE_TTF_ITALIC SGE_FLAG2 #define SGE_TTF_UNDERLINE SGE_FLAG3 /* ZERO WIDTH NO-BREAKSPACE (Unicode byte order mark) */ #define UNICODE_BOM_NATIVE 0xFEFF #define UNICODE_BOM_SWAPPED 0xFFFE #endif /* _SGE_NOTTF */ #ifdef _SGE_C extern "C" { #endif #ifndef _SGE_NOTTF DECLSPEC void sge_TTF_AAOff(void); DECLSPEC void sge_TTF_AAOn(void); DECLSPEC void sge_TTF_AA_Alpha(void); DECLSPEC void sge_TTF_ByteSwappedUNICODE(int swapped); DECLSPEC int sge_TTF_Init(void); DECLSPEC sge_TTFont *sge_TTF_OpenFont(const char *file, int ptsize); DECLSPEC sge_TTFont *sge_TTF_OpenFontRW( SDL_RWops *src, int freesrc, int ptsize, int xdpi, int ydpi); DECLSPEC sge_TTFont *sge_TTF_OpenFontIndex(const char *file, int ptsize, long index, int xdpi, int ydpi); DECLSPEC sge_TTFont *sge_TTF_OpenFontIndexRW(SDL_RWops *src, int freesrc, int ptsize, long index, int xdpi, int ydpi); DECLSPEC int sge_TTF_SetFontSize(sge_TTFont *font, int ptsize); DECLSPEC int sge_TTF_SetFontSizeDPI(sge_TTFont *font, int ptsize, int xdpi, int ydpi); DECLSPEC int sge_TTF_FontHeight(sge_TTFont *font); DECLSPEC int sge_TTF_FontAscent(sge_TTFont *font); DECLSPEC int sge_TTF_FontDescent(sge_TTFont *font); DECLSPEC int sge_TTF_FontLineSkip(sge_TTFont *font); DECLSPEC long sge_TTF_FontFaces(sge_TTFont *font); DECLSPEC int sge_TTF_FontFaceIsFixedWidth(sge_TTFont *font); DECLSPEC char *sge_TTF_FontFaceFamilyName(sge_TTFont *font); DECLSPEC char *sge_TTF_FontFaceStyleName(sge_TTFont *font); DECLSPEC void sge_TTF_SetFontStyle(sge_TTFont *font, Uint8 style); DECLSPEC Uint8 sge_TTF_GetFontStyle(sge_TTFont *font); DECLSPEC void sge_TTF_CloseFont(sge_TTFont *font); DECLSPEC SDL_Rect sge_TTF_TextSizeUNI(sge_TTFont *font, const Uint16 *text); DECLSPEC SDL_Rect sge_TTF_TextSize(sge_TTFont *Font, char *Text); DECLSPEC SDL_Rect sge_tt_textout(SDL_Surface *Surface, sge_TTFont *font, const char *string, Sint16 x, Sint16 y, Uint32 fcolor, Uint32 bcolor, int Alpha); DECLSPEC SDL_Rect sge_tt_textout_UTF8(SDL_Surface *Surface, sge_TTFont *font, const char *string, Sint16 x, Sint16 y, Uint32 fcolor, Uint32 bcolor, int Alpha); DECLSPEC SDL_Rect sge_tt_textout_UNI(SDL_Surface *Surface, sge_TTFont *font, const Uint16 *uni, Sint16 x, Sint16 y, Uint32 fcolor, Uint32 bcolor, int Alpha); DECLSPEC SDL_Rect sge_tt_textoutf(SDL_Surface *Surface, sge_TTFont *font, Sint16 x, Sint16 y, Uint8 fR, Uint8 fG, Uint8 fB, Uint8 bR, Uint8 bG, Uint8 bB, int Alpha ,char *format,...); DECLSPEC int sge_tt_input_UNI(SDL_Surface *screen,sge_TTFont *font,Uint16 *string,Uint8 flags, int pos,int len,Sint16 x,Sint16 y, Uint32 fcol, Uint32 bcol, int Alpha); DECLSPEC int sge_tt_input(SDL_Surface *screen,sge_TTFont *font,char *string,Uint8 flags, int pos,int len,Sint16 x,Sint16 y, Uint32 fcol, Uint32 bcol, int Alpha); DECLSPEC SDL_Surface *sge_TTF_Render(sge_TTFont *font,const Uint16 *text, SDL_Color fg, SDL_Color bg, int alpha_level); DECLSPEC SDL_Surface *sge_TTF_RenderUNICODE(sge_TTFont *font,const Uint16 *text, SDL_Color fg, SDL_Color bg); #endif /* _SGE_NOTTF */ DECLSPEC Uint16 *sge_Latin1_Uni(const char *text); #ifdef _SGE_C } #endif #ifndef sge_C_ONLY #ifndef _SGE_NOTTF DECLSPEC SDL_Rect sge_tt_textout(SDL_Surface *Surface, sge_TTFont *font, const char *string, Sint16 x, Sint16 y, Uint8 fR, Uint8 fG, Uint8 fB, Uint8 bR, Uint8 bG, Uint8 bB, int Alpha); DECLSPEC SDL_Rect sge_tt_textout_UTF8(SDL_Surface *Surface, sge_TTFont *font, const char *string, Sint16 x, Sint16 y, Uint8 fR, Uint8 fG, Uint8 fB, Uint8 bR, Uint8 bG, Uint8 bB, int Alpha); DECLSPEC SDL_Rect sge_tt_textout_UNI(SDL_Surface *Surface, sge_TTFont *font, const Uint16 *uni, Sint16 x, Sint16 y, Uint8 fR, Uint8 fG, Uint8 fB, Uint8 bR, Uint8 bG, Uint8 bB, int Alpha); DECLSPEC int sge_tt_input_UNI(SDL_Surface *screen,sge_TTFont *font,Uint16 *string,Uint8 flags, int pos,int len,Sint16 x,Sint16 y, Uint8 fR, Uint8 fG, Uint8 fB, Uint8 bR,Uint8 bG,Uint8 bB, int Alpha); DECLSPEC int sge_tt_input(SDL_Surface *screen,sge_TTFont *font,char *string,Uint8 flags, int pos,int len,Sint16 x,Sint16 y, Uint8 fR, Uint8 fG, Uint8 fB, Uint8 bR,Uint8 bG,Uint8 bB, int Alpha); #endif /* _SGE_NOTTF */ #endif /* sge_C_ONLY */ #endif /* sge_tt_text_H */ sge030809/Todo0000644000175000001440000000023607715153424011660 0ustar samusers-Improve error handling... urk. -Improve/finish sge_screen. -Run the spell checker more often :-) -Alpha blended AA filled circles and AA filled ellipses. sge030809/docs/0000755000175000001440000000000007715147603011761 5ustar samuserssge030809/docs/blib.html0000644000175000001440000001760107714201543013555 0ustar samusers SGE Documentation - Blib

SGE Blib


Important!


void sge_FadedLine(SDL_Surface *dest, Sint16 x1, Sint16 x2, Sint16 y, Uint8 r1, Uint8 g1, Uint8 b1, Uint8 r2, Uint8 g2, Uint8 b2)
Draws a horizontal line from (x1,y) to (x2,y) with its color faded from (r1,g1,b1) to (r2,g2,b2).


void sge_TexturedLine(SDL_Surface *dest, Sint16 x1, Sint16 x2, Sint16 y, SDL_Surface *source, Sint16 sx1, Sint16 sy1, Sint16 sx2, Sint16 sy2)
Draws a horizontal line from (x1,y) to (x2,y) on dest with the texture from the line (sx1,sy1) to (sx2,sy2) in src.


sge_Trigon
Draws a triangle.



sge_FilledTrigon
Draws a filled triangle. Note that if using sge_FilledTrigon() on a HW surface then the surface must be unlocked.



void sge_FadedTrigon(SDL_Surface *dest, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Sint16 x3, Sint16 y3, Uint32 c1, Uint32 c2, Uint32 c3)
Draws a gourand shaded triangle where c1, c2 and c3 are the colors of the three vertices.


void sge_TexturedTrigon(SDL_Surface *dest, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Sint16 x3, Sint16 y3, SDL_Surface *source, Sint16 sx1, Sint16 sy1, Sint16 sx2, Sint16 sy2, Sint16 sx3, Sint16 sy3)
Draws a texture mapped triangle (p1,p2,p3) on dest with the texture from the triangle (sp1,sp2,sp3) on src.


void sge_TexturedRect(SDL_Surface *dest, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Sint16 x3, Sint16 y3, Sint16 x4, Sint16 y4, SDL_Surface *source, Sint16 sx1, Sint16 sy1, Sint16 sx2, Sint16 sy2, Sint16 sx3, Sint16 sy3, Sint16 sx4, Sint16 sy4)
Draws a texture mapped rectangle (p1,p2,p3,p4) on dest with the texture from the rectangle (sp1,sp2,sp3,sp4) on src.


sge_FilledPolygon
Draws a filled polygon. Takes the arrays x[] and y[] with n elements as an argument where (x[i], y[i]) is the i:th vertex in the polygon. The last vertex, (x[n-1], y[n-1]), is automatically connected to the first, (x[0], y[0]), to close the polygon. Manages to fill most nonconvex, convex and complex polygons correctly but might be confused by extremly complex polygons, so don't push your luck. Note that sge_FilledPolygon() and sge_AAFilledPolygon() (and sge_FilledPolygonAlpha() if using opaque alpha value) must be able to control surface locking.

Returns int:
Zero - Operation finished OK.
-1 - Polygon rejected because n<3 or negative coords in arrays (the polygon might be halfdrawn).
-2 - Unable to lock surface.



sge_FadedPolygon
As sge_FilledPolygon() but draws a gourand shaded polygon where (R[i], G[i], B[i]) is the color of the i:th vertex. Note that the shading is done on each y-line so some care is needed with the RGB values when working with complex polygons.





Copyright © 1999-2003 Anders Lindstrm
Last updated 030806

sge030809/docs/thanks.html0000644000175000001440000000266107713155607014145 0ustar samusers SGE Documentation - Thanks

Thanks

Thanks goes to...





Copyright © 1999-2003 Anders Lindstrm
Last updated 030803

sge030809/docs/shape.html0000644000175000001440000002216607715147632013760 0ustar samusers SGE Documentation - Shape classes

Shape classes


sge_shape
This is an abstract base class. Shapes are something that can be drawn and cleared on surfaces. All classes derived from this class MUST provide the methods below.

Constructor:
No constructor.
Methods:
virtual void draw(void)
Draws the shape.

virtual void clear(Uint32 color)
Removes the shape by clearing it to a color.

virtual void clear(SDL_Surface *src, Sint16 srcX, Sint16 srcY)
Removes the shape by blitting a part of src over it.

virtual void UpdateRects(void)
Updates (SDL/sge_UpdateRect) areas that have been cleared or drawn.

SDL_Rect get_pos(void)
Returns the current (maybe undrawn) position.

SDL_Rect get_last_pos(void)
Returns the last drawn position.

Sint16 get_xpos(void)
Sint16 get_ypos(void)

Returns the upper left corner of shape.

Sint16 get_w(void)
Sint16 get_h(void)

Returns the width and height of the shape.

SDL_Surface* get_dest(void)
Returns the surface on which this class operates on.

Usefull coords in shape
These methods returns some useful (current) coords in shape.
	NW N NE
	W  C  E
	SW S SE
	
Sint16 c_x(void)
Sint16 c_y(void)

Sint16 nw_x(void)
Sint16 nw_y(void)

Sint16 n_x(void)
Sint16 n_y(void)

Sint16 ne_x(void)
Sint16 ne_y(void)

Sint16 e_x(void)
Sint16 e_y(void)

Sint16 se_x(void)
Sint16 se_y(void)

Sint16 s_x(void)
Sint16 s_y(void)

Sint16 sw_x(void)
Sint16 sw_y(void)

Sint16 w_x(void)
Sint16 w_y(void)





sge_surface
Derived (public) from sge_shape.
This is the most basic blitting class. You can draw & clear the image and move it around.

Constructor:
sge_surface(SDL_Surface *dest, SDL_Surface *src, Sint16 x=0, Sint16 y=0)
Dest is the surface you want to blit to, src is the image.

Methods:
virtual void move_to(Sint16 x, Sint16 y)
Moves the image to a new coord.

virtual void move(Sint16 x_step, Sint16 y_step)
Moves the image x/y steps to the left/down (or right/up if negative step size).

SDL_Surface* get_img(void)
Returns a pointer to the image.




sge_ssprite
Derived (public) from sge_surface.
The next step is to introduce speeds and multiple frames.

Constructor:
sge_ssprite(SDL_Surface *screen, SDL_Surface *img, Sint16 x=0, Sint16 y=0)
Img is the first frame to show.

sge_ssprite(SDL_Surface *screen, SDL_Surface *img, sge_cdata *cdata, Sint16 x=0, Sint16 y=0)
As above but with collision data [sge_collision].

Methods:
void set_vel(Sint16 x, Sint16 y)
void set_xvel(Sint16 x)
void set_yvel(Sint16 y)

Sets the speed (pixels/update).

Sint16 get_xvel(void)
Sint16 get_yvel(void)

Returns the current speed.

virtual bool update(void)
Move the sprite according to the speeds. Returns true if the position changed.

void add_frame(SDL_Surface *img)
void add_frame(SDL_Surface *img, sge_cdata *cdata)

Adds a new frame to the sprite, with or without collision data [sge_collision]. This resets the playing sequence.

void skip_frame(int skips)
void next_frame(void)
void prev_frame(void)
void first_frame(void)
void last_frame(void)

Change the current frame. Calling next_frame()/prev_frame() is the same thing as calling skip_frame(1)/skip_frame(-1). First_frame()/last_frame() sets the first/last frame in the sequence as the current frame (but does not change the sequence).

void set_seq(int start, int stop, playing_mode mode=loop)
void reset_seq(void)
sge_ssprite::playing_mode get_PlayingMode(void)

Changes the frame playing sequence. The default is to loop over all frames (next_frame() returns to the first frame when the last frame has been shown). Use set_seq() to set the start and stop frame (frame 0 is the first frame) and playing mode. You can set the following playing modes:
Use reset_seq() to reset to the default sequence.
Get_PlayingMode() returns the current mode or sge_ssprite::stop if all frames in the sequence has been shown (only possible if sge_ssprite::play_once was used).

void set_border(SDL_Rect box)
void border_bounce(bool mode)
void border_warp(bool mode)

The sprite will bounce at the border of the screen as default. You can change the allowed rectangle with set_border() or turn this off completely with border_bounce(false). You can also make the sprite warp (pixel for pixel) at the border with border_warp(true).

sge_cdata* get_cdata(void)
Returns the collision map for the current frame (or NULL if no one exist).

sge_frame* get_frame(void)
Returns the frame data for the current frame:
struct sge_frame{
  //The image
  SDL_Surface *img;
	
  //Collision data
  sge_cdata *cdata;
};
std::list<sge_frame*>* get_list(void)
The linked list with frames is stored in a STL list<> container. This method returns a pointer to this list. If you change anything in the list you *MUST* call reset_seq()!




sge_sprite
Derived (public) from sge_ssprite.
Finally we add timed operations to the sprite. All speeds are now in pixels/second.

Constructor:
sge_sprite(SDL_Surface *screen, SDL_Surface *img, Sint16 x=0, Sint16 y=0)
sge_sprite(SDL_Surface *screen, SDL_Surface *img, sge_cdata *cdata, Sint16 x=0, Sint16 y=0)
Methods:
void set_pps(Sint16 x, Sint16 y)
void set_xpps(Sint16 x)
void set_ypps(Sint16 y)
void set_fps(Sint16 f)

Sets the speed (pixels/second). Set_fps() sets how fast (frames/second) the frames should be changed.

Sint16 get_xpps(void)
Sint16 get_ypps(void)
Sint16 get_fps(void)

Returns the current speeds.

bool update(Uint32 ticks)
bool update(void)

Updates the internal status (calculates the new position and changes the current frame if needed). You can let update() call SDL_GetTicks() itself or provide the information. Returns true if the sprite changed position or frame.

void pause(void)
Halt the sprite until next call to update().




sge_screen
This class is not finished and might eat your homework.
This class can be used to draw shapes (sge_shape) on screen. This class will detect if doublebuffering or a hardware screen surface is used and act accordingly.

Constructor:
sge_screen(SDL_Surface *screen)
Methods:
void add_rect(SDL_Rect rect)
void add_rect(Sint16 x, Sint16 y, Uint32 w, Uint32 h)

Adds an rectangle to be updated (with SDL_UpdateRects()) on update() if needed.

void add_shape(sge_shape *shape)
void add_shape_p(sge_shape *shape)

Adds an sge_shape to be drawn and updated (if needed) on update().

void remove_shape_p(sge_shape *shape)
Removes an sge_shape from the permanent list.

void clear_all(void)
Clears all shapes (even those added with add_shape_p()) and rectangles.

void update(void)
Draws all shapes and updates all rectangles and shapes. All shapes and rectangales are then cleared (beside those added with add_shape_p()) from the class.





Copyright © 1999-2003 Anders Lindstrm
Last updated 030809

sge030809/docs/figures.html0000644000175000001440000003577107714257626014336 0ustar samusers SGE Documentation - Figures

Figures


Important!



sge_H/VLine Draws a horizontal or vertical line. The surface must be unlocked if using a HW surface with the non-alpha functions.



sge_DoLine Calculates all the points along a line from (x1, y1) to (x2, y2), calling the supplied function for each point. The callback function should look like Callback(SDL_Surface *Surf, Sint16 x, Sint16 y, Uint32 Color). For example, to draw a line without lock or update: sge_DoLine(Surface, x1, y1, x2, y2, Color, _PutPixel).



sge_Line Draws a line from (x1, y1) to (x2, y2).



sge_DomcLine Calculates all the points along a line from (x1, y1) to (x2, y2), calling the supplied function for each point. The color is faded from (r1, g1, b1) to (r2, g2, b2).



sge_mcLine Draws a multicolored line from (x1, y1) to (x2, y2), fading the color from (r1, g1, b1) to (r2, g2, b2). Also see sge_FadedLine().



sge_Rect Draws a rectangle. The surface must be unlocked if using a HW surface with the non-alpha functions.



sge_FilledRect Draws a filled rectangle. You can also use SDL_FillRect() directly. The surface must be unlocked if using a HW surface with the non-alpha functions.



sge_DoCircle Calculates all the points in a circle around point (x,y) with radius r, calling the supplied function for each one. The callback function should look like Callback(SDL_Surface *Surf, Sint16 x, Sint16 y, Uint32 Color).



sge_Circle Draws a circle with the specified centre and radius.



sge_FilledCircle Draws a filled circle with the specified centre and radius. The surface must be unlocked if using a HW surface with sge_FilledCircle(). Note that sge_AAFilledCircle() must be able to control surface locking.



sge_DoEllipse Calculates all the points in an ellipse around point (x,y) with x-radius rx and y-radius ry, calling the supplied function for each one. The callback function should look like Callback(SDL_Surface *Surf, Sint16 X, Sint16 Y, Uint32 Color).



sge_Ellipse Draws an ellipse with the specified centre and radius.



sge_FilledEllipse Draws a filled ellipse with the specified centre and radius. The surface must be unlocked if using a HW surface with sge_FilledEllipse(). Note that sge_AAFilledEllipse() must be able to control surface locking.



sge_Bezier Draws a bezier curve from (x1, y1) to (x4, y4) with the control points (x2, y2) and (x3, y3). The variable 'level' indicates how good precision the function should use, 4-7 is normal.







Copyright © 1999-2003 Anders Lindstrm
Last updated 030806

sge030809/docs/surface.html0000644000175000001440000001406507714763102014302 0ustar samusers SGE Documentation - Surface

Surface operations



Tip when you initialize the video in SDL (SDL_SetVideoMode()):

If you request SDL_SWSURFACE, then you get a video buffer allocated in system memory, and you must call SDL_UpdateRects() or SDL_Flip() to update the screen. SDL_Flip() calls SDL_UpdateRects(the-whole-screen) in this case. All allocated surfaces will be in system memory for blit speed.

If you request SDL_HWSURFACE, then if possible SDL will give you access to the actual video memory being displayed to the screen. If this is successful, the returned surface will have the SDL_HWSURFACE flag set, and you will be able to allocate other surfaces in video memory, which presumably can be blitted very fast. The disadvantage is that video memory tends to be much slower than system memory, so you don't want to write directly to it in most cases. In this case, SDL_UpdateRects() and SDL_Flip() are inexpensive noops, as you are writing to memory automatically being displayed.

If you request SDL_HWSURFACE, you may also request double-buffering by adding the SDL_DOUBLEBUF flag. If possible, SDL will set up two buffers in video memory for double-buffered page flipping. If this is successfully set up, then you will be writing to the non-visible back-buffer, and when you call SDL_Flip(), SDL will queue up a page flip for the next vertical retrace, so that the current video surface will then be displayed, and the front and back video buffers will be swapped. The next display surface lock will block until the flip has completed.

Sam Lantinga


void sge_UpdateRect(SDL_Surface *screen, Sint16 x, Sint16 y, Uint16 w, Uint16 h)
Makes sure the given rectangle is updated on the given screen. Unlike SDL_UpdateRect() this function does work even if some part of the given rectangle is outside the surface. Use SDL_UpdateRect(surface,0,0,0,0) to update the entire surface. Does not respect clipping.

void sge_Update_ON(void)
void sge_Update_OFF(void)

Most of SGE:s functions will call sge_UpdateRect() to update the destination screen when finished. But if you don't want the result to be visible directly after the call (to avoid tearing) you can turn off this automatic update feature with sge_Update_OFF(), turn it on again with sge_Update_ON(). Default is ON. You can get the current mode with 'Uint8 sge_getUpdate(void)', returns 1 if updating is on or else 0.

void sge_Lock_ON(void)
void sge_Lock_OFF(void)

Most of SGE:s functions will lock the surface if necessary, but with these functions you can control that behavior. Keep in mind that it's unwise to turn of locking and keep update on for surfaces that requires locking! Default is ON. You can get the current mode with 'Uint8 sge_getLock(void)', returns 1 if locking is on or else 0.

SDL_Surface *sge_CreateAlphaSurface(Uint32 flags, int width, int height)
Creates a 32bit alpha surface (RGBA - 8/8/8/8). The alpha channel is blended on blitting.

void sge_ClearSurface(SDL_Surface *Surface, Uint32 color)
void sge_ClearSurface(SDL_Surface *Surface, Uint8 R, Uint8 G, Uint8 B)

Clear surface to color. Does lock and update the surface.

SDL_Surface *sge_copy_surface(SDL_Surface *src)
Copies a surface to a new.

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)
This performs a blit from the source surface to the destination surface. Clear is the color key (transparent pixel) in the source surface. Alpha sets the transparency of the source surface (0-255). Note that the original alpha and color key is lost on the source surface. Only use this function if the surface will be blitted once, in other cases set the alpha and color key and use sge_Blit(). Does respect clipping on destination surface. Returns 0 on success.

int sge_Blit(SDL_Surface *Src, SDL_Surface *Dest, Sint16 SrcX, Sint16 SrcY, Sint16 DestX, Sint16 DestY, Sint16 W, Sint16 H)
This performs a blit from the source surface to the destination surface, without touching color key or alpha. Does respect clipping on destination surface. Returns 0 on success.

void sge_FloodFill(SDL_Surface *dst, Sint16 x, Sint16 y, Uint32 color)
void sge_FloodFill(SDL_Surface *dst, Sint16 x, Sint16 y, Uint8 R, Uint8 G, Uint8 B)

Flood fills (with the specified color) all areas that connects to and has the same color as the point (x,y). Use with care! Does respect clipping but doesn't update the surface.





Copyright © 1999-2003 Anders Lindstrm
Last updated 030808

sge030809/docs/ttf.html0000644000175000001440000001463507713246460013454 0ustar samusers SGE Documentation - TTF

TrueType font rendering

To the sge_tt_textout() functions>>


The TT font structure
typedef struct{
  ...
} sge_TTFont;
When working with TTF functions you must give a pointer to the font structure. To open a new font (structure) use sge_TTF_OpenFont() and when finished use sge_TTF_CloseFont().


int sge_TTF_Init(void)
Starts the FreeType engine, must be called before any of the other TTF functions. Returns 0 on success.

sge_TTFont *sge_TTF_OpenFont(char *file, int ptsize)
Opens the given ttf file and sets the font size to ptsize. Returns a pointer to the new font.

sge_TTFont *sge_TTF_OpenFontIndex(char *file, int ptsize, long index, int xdpi, int ydpi)
Same as sge_TTF_OpenFont() but you can also set the font face index and the dpi used. Font face #0 and 96x96dpi is used with sge_TTF_OpenFont().

sge_TTFont *sge_TTF_OpenFontRW(SDL_RWops *src, int freesrc, int ptsize, int xdpi, int ydpi)
Same as sge_TTF_OpenFont() but reads from a SDL_RWops stream. The stream is closed at sge_TTF_CloseFont() if freesrc > 0.

sge_TTFont *sge_TTF_OpenFontIndexRW(SDL_RWops *src, int freesrc, int ptsize, long index, int xdpi, int ydpi)
Same as sge_TTF_OpenFontRW() but you can also set the font face index.

void sge_TTF_CloseFont(sge_TTFont *font)
Removes font from memory.

void sge_TTF_ByteSwappedUNICODE(int swapped)
This function tells the library whether UNICODE text is generally byteswapped. A UNICODE BOM character (UNICODE_BOM_NATIVE or UNICODE_BOM_SWAPPED) at the beginning of a string will override this setting for that string.

int sge_TTF_SetFontSize(sge_TTFont *font, int ptsize)
Change the size of the given font. Returns 0 on success.

int sge_TTF_SetFontSizeDPI(sge_TTFont *font, int ptsize, int xdpi, int ydpi)
Same as sge_TTF_SetFontSize() but you can also set the dpi used.

SDL_Rect sge_TTF_TextSize(sge_TTFont *Font, char *Text)
Returns the width (.w) and height (.h) of the text with the given font.

int sge_TTF_FontHeight(sge_TTFont *font)
Returns the distance between the fonts baseline and the top of the highest character.

int sge_TTF_FontAscent(sge_TTFont *font)
Returns the ascent of the font.

int sge_TTF_FontDescent(sge_TTFont *font)
Returns the descent of the font.

int sge_TTF_FontLineSkip(sge_TTFont *font)
Returns the recommended line skip for this font.

long sge_TTF_FontFaces(sge_TTFont *font)
Returns the number of font faces available for this font.

int sge_TTF_FontFaceIsFixedWidth(sge_TTFont *font)
Returns true if the used font face is fixed width.

char *sge_TTF_FontFaceFamilyName(sge_TTFont *font)
Returns the family name of the selected font face.

char *sge_TTF_FontFaceStyleName(sge_TTFont *font)
Returns the style name of this font face.

void sge_TTF_AAOn(void)
void sge_TTF_AAOff(void)
void sge_TTF_AA_Alpha(void)

Turns anti-aliasing for truetype output on/off. Defaults to ON. You can also enable alpha blending support (very nice but slow).

void sge_TTF_SetFontStyle(sge_TTFont *font, Uint8 style)
Sets the font style.
Flags: (may be ORed, eg. SGE_TTF_BOLD|SGE_TTF_ITALIC)
SGE_TTF_NORMAL - The default style.
SGE_TTF_BOLD - Bold.
SGE_TTF_ITALIC - Italic.
SGE_TTF_UNDERLINE - Underlined.

Uint8 sge_TTF_GetFontStyle(sge_TTFont *font)
Returns the current font style.

To the sge_tt_textout() functions>>





Copyright © 1999-2003 Anders Lindstrm
Last updated 030803

sge030809/docs/pixels.html0000644000175000001440000001125207714761456014163 0ustar samusers SGE Documentation - Pixels

Pixel operations



_PutPixel
Writes a pixel to the specified position. Does NOT lock or update the surface, but respects clipping. The 'Uint32 color' version is faster. _PutPixelAlpha() will blend the pixel with the background. For the speed maniac the [8/16/24/32] functions are also available, which only work on the correct bpp (8/16/24/32). They do not respect clipping. _PutPixelX() works like _PutPixel() but ignores clipping.



sge_PutPixel
Unlike _PutPixel these functions does lock and update the surface.



Sint32 sge_CalcYPitch(SDL_Surface *surface, Sint16 y)
Returns the y pitch offset, use it with sge_pPutPixel. Note that the return type is *Sint32*.

void sge_pPutPixel(SDL_Surface *surface, Sint16 x, Sint32 ypitch, Uint32 color)
Writes a pixel to the specified position using the precalculated ypitch. This saves one mul and one div when writing more than one time to the same y coord.
Does not lock or update the surface, but respects clipping.


Uint32 sge_GetPixel(SDL_Surface *surface, Sint16 x, Sint16 y)
Gets the color of the specified pixel.


void sge_write_block8(SDL_Surface *Surface, Uint8 *block, Sint16 y)
void sge_write_block16(SDL_Surface *Surface, Uint16 *block, Sint16 y)
void sge_write_block32(SDL_Surface *Surface, Uint32 *block, Sint16 y)
These functions writes the given block (of color values) to the surface. A block consist of Surface->w (the width of the surface) numbers of color values. Write your data to the block and then call sge_write_block() to update the y:th line on the surface with new color values. Note the difference in byte size for the block elements for different bpp. This is much faster then using the put pixel functions to update a line. 24-bpp version not included (OK! I admit that I don't like 24bpp - it's slow!). Does not lock or update the surface, nor does it respect clipping - but it's fast!.


void sge_read_block8(SDL_Surface *Surface, Uint8 *block, Sint16 y)
void sge_read_block16(SDL_Surface *Surface, Uint16 *block, Sint16 y)
void sge_read_block32(SDL_Surface *Surface, Uint32 *block, Sint16 y)
Reads the y:th line to block. See above for more information.






Copyright © 1999-2003 Anders Lindstrm
Last updated 030808

sge030809/docs/text_classes.html0000644000175000001440000002434107714761122015351 0ustar samusers SGE Documentation - Text Classes

Text classes

sge_TextEditor
Edits text from SDL_Events. This class just stores a text string in memory and lets you perfrom some basic editing on it. You can only change (or insert) the character left or right of the "cursor".

Constructor:
sge_TextEditor(void)
Methods:
bool insert(Uint16 c)
Adds an (unicode) char before the cursor.

bool remove_left(void)
Removes the char left of cursor.

bool remove_right(void)
Removes the char right of cursor.

inline bool move_left(void)
Move the cursor to the left.

inline bool move_right(void)
Move the cursor to the right.

bool move_start(void)
Move the cursor to the start.

bool move_end(void)
Move the cursor to the end.

std::string get_string(bool wCursor=true)
Returns the text as latin1 with or without the cursor char.

Uint16* get_ucstring(bool wCursor=true)
Returns a unicode c-style string (allocated with new).

virtual bool check(SDL_Event* event)
Process an SDL_Event. The text can be edited with [Backspace], [Delete], [Left arrow] and [Right arrow]. Returns true if the text changed.

void change_cursor(Uint16 c)
Change the cursor char. Default is the '|' character.

void clear_text(void)
Clears the text string.

void change_text(const std::string s)
Changes the text.

void change_uctext(Uint16 *text)
Changes the text (c-style unicode).

void change_textf(const char *text, ...)
Changes the text (printf c-style).

void max_chars(unsigned int c)
Set max chars (default: limited only by memory).

unsigned int get_chars(void)
Returns the number of characters in the current string.




sge_text
Derived (public) from sge_TextEditor.
A class for rendering text. Can render both truetype and bitmap fonts. Change/Edit the text with the methods in sge_TextEditor.

Constructor:
sge_text(void)
Methods:
SDL_Surface* get_textSurface(bool copy=false)
Get a pointer to the text surface or (if copy=true) returns a copy (don't forget to free it later). This will not work with SFonts with an alpha channel.

bool update_textSurface(bool force=false)
Updates the textsurface if the text has changed (or if force=true) and returns true if the surface was updated.

void set_ttFont(sge_TTFont *font, Uint8 r, Uint8 g, Uint8 b, Uint8 br=0, Uint8 bg=0, Uint8 bb=0)
Sets the truetype font and color. If you use antialiasing, the background color must be set to the background color of the area where you will render the text. If the background has more than one color it might be better to use sge_TTF_AA_Alpha().

void set_bmFont(sge_bmpFont *bm_font)
Sets the bitmap font.

void show_cursor(bool mode)
Should the cursor be drawn when rendering text?

SDL_Rect render_text(SDL_Surface *surface, Sint16 x, Sint16 y)
Renders the text directly to the given surface (instead of rendering to the text surface with update_textSurface()). Return the size and position of the rendered text.

void use_TTrender(void)
Render text using truetype fonts. The default is to use the last set font.

void use_BMrender(void)
Render text using bitmap fonts. The default is to use the last set font.

void set_alpha(Uint8 alpha)
Sets the alpha value for the text (doesn't work with alpha channel SFonts).

bool get_color(SDL_Color *fg)
Fills fg with the RGB color of the truetype font if set. Returns false if the color is not set.

bool get_bg(SDL_Color *bg)
Fills bg with the background RGB color of the truetype font if set. Returns false if the color is not set.



sge_TextSurface
Derived public from sge_text and sge_surface.
This class works exactly as sge_surface, but uses the current text surface. Note that get_img() will not work with SFonts with an alpha channel. See also the example.

Constructor:
sge_TextSurface(SDL_Surface *screen, Sint16 x=0, Sint16 y=0)
sge_TextSurface(SDL_Surface *screen, const std::string text, Sint16 x=0, Sint16 y=0)
You can set a default text if you want.
Methods:
See sge_text and sge_surface.




sge_TextSsprite
Derived public from sge_text and sge_ssprite.
This class works exactly as sge_ssprite, but uses the current text surface. The text surface is always the first frame (so you can display other frames). Will probably not work as normal with SFonts with an alpha channel.

Constructor:
sge_TextSsprite(SDL_Surface *screen, Sint16 x=0, Sint16 y=0)
sge_TextSsprite(SDL_Surface *screen, const std::string text, Sint16 x=0, Sint16 y=0)
You can set a default text if you want.
Methods:
See sge_text and sge_ssprite.




sge_TextSprite
Derived public from sge_text and sge_sprite.
This class works exactly as sge_sprite, but uses the current text surface. The text surface is always the first frame (so you can display other frames). Will probably not work as normal with SFonts with an alpha channel.

Constructor:
sge_TextSprite(SDL_Surface *screen, Sint16 x=0, Sint16 y=0)
sge_TextSprite(SDL_Surface *screen, const std::string text, Sint16 x=0, Sint16 y=0)
You can set a default text if you want.
Methods:
See sge_text and sge_sprite.




int sge_text_input(sge_TextSurface *tc, Uint8 flags)
A helper function for lazy users: blocking text input for sge_TextSurface objects. Does the same thing as the example below. The argument "flags" is the same as for BM and TTF input (which uses this function). Make sure "tc" is setup with the correct font etc. before calling this function.




Example

This is a simple example of the sge_TextSurface class; draws TT text on the screen and lets the user edit it.

#include <stdio.h>
#include "SDL.h"
#include "sge.h"

...

/* Init font engine and exit on error */
if( sge_TTF_Init() != 0 ){
fprintf(stderr,"TT error: %s\n", SDL_GetError());
exit(1);
}

/* Open the TT font and exit on error */
sge_TTFont *font = sge_TTF_OpenFont("font.ttf", 25);
if( !font ){
fprintf(stderr,"TT error: %s\n", SDL_GetError());
exit(1);
}

/* The buffer for the background (only if you want to keep the background) */
SDL_Surface *buffer;
buffer = SDL_DisplayFormat(screen);

/* Enable keyrepeat */
SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL+50);

SDL_EnableUNICODE(1); //This is VERY important!!

/* Init our text class */
sge_TextSurface text(screen,"Edit Me!",8,50);
text.set_ttFont(font,0,255,0); //Use the TT font
text.show_cursor(true); //Show a cursor

/* Draw the text for the first time */
text.draw();
text.UpdateRects();

sge_Update_OFF();

/* Main loop */
SDL_Event event;
do{
SDL_Delay(10);

/* Check events */
if( SDL_PollEvent(&event) == 1 ){
if( event.type == SDL_KEYDOWN && event.key.keysym.sym == SDLK_ESCAPE ) break;
if( event.type == SDL_QUIT ) break;

/* Let the text class handle the event*/
if( text.check(&event) ){
/* The text has changed */
text.clear(buffer, 8,50); //Remove the text
text.draw(); //Draw the new text
sge_Update_ON();
text.UpdateRects(); //Update screen
sge_Update_OFF();
}
}
}while(true);


/* Clean up */
SDL_FreeSurface(buffer);
sge_TTF_CloseFont(font);





Copyright © 1999-2003 Anders Lindstrm
Last updated 030808

sge030809/docs/index.html0000644000175000001440000000405607714201660013754 0ustar samusers SGE Documentation

SGE Documentation

This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details.

Index

SGE Introduction
Beginners guide to SGE
Surface operations
Color manipulation
Pixel operations
Figures
Text management
TrueType font rendering
Bitmap font rendering
Text classes
Surface and sprite classes
Basic collision detection
Surface rotation/scaling routines
Polygons and some texture mapping
Misc. functions
Macros
Thanks


SGE:s Homepage





Copyright © 1999-2003 Anders Lindstrm
Last updated 030806

sge030809/docs/bmf.html0000644000175000001440000001261707714723610013417 0ustar samusers SGE Documentation - BMF

Bitmap font rendering

The bitmap font structure
typedef struct{
   ...					
} sge_bmpFont;
When working with BF functions you must give a pointer to the font structure. To open a new font (structure) use sge_BF_OpenFont() and when finished use sge_BF_CloseFont().


sge_bmpFont* sge_BF_OpenFont(char *file, Uint8 flags)
Opens the given font file. Returns a pointer to the new font.
Flags: (may be ORed, eg. SGE_BFTRANSP|SGE_BFSFONT)
SGE_BFTRANSP - Transparent (should usually be set).
SGE_BFNOCONVERT - Don't convert font surface to display format for faster blits.
SGE_BFSFONT - If you enabled support for SDL_img when compiling SGE you can also set the SGE_BFSFONT flag, this enables you to load Karl Bartel's SFont files.
SGE_BFPALETTE - Converts the font surface to a palette surface (8bit). Don't do this on color fonts or SFonts! Blits from the font surface will be a bit slower but sge_BF_SetColor() will be faster (O(1) instead of O(n^2)).

sge_bmpFont* sge_BF_CreateFont(SDL_Surface *surface, Uint8 flags)
Same as sge_BF_OpenFont() but reads the font data directly from a surface.

void sge_BF_CloseFont(sge_bmpFont *font)
Removes font from memory.

void sge_BF_SetColor(sge_bmpFont *font, Uint8 R, Uint8 G, Uint8 B)
Changes the color of the font to (R,G,B). Doesn't work on 'color fonts' or SFonts. Use SGE_BFPALETTE when opening the font if you're going to use this function often.

void sge_BF_SetAlpha(sge_bmpFont *font, Uint8 alpha)
Sets the alpha level of the font. Doesn't work on SFonts with alpha channels.

Sint16 sge_BF_GetHeight(sge_bmpFont *font)
Returns the height of the font.

Sint16 sge_BF_GetWidth(sge_bmpFont *font)
Returns the width of one character in the specified font. Doesn't work on SFonts.

SDL_Rect sge_BF_TextSize(sge_bmpFont *font, char *string)
Returns the width (.w) and height (.h) of the string with the given font.

SDL_Rect sge_BF_textout(SDL_Surface *surface, sge_bmpFont *font, char *string, Sint16 x, Sint16 y)
Renders the given string on surface with the given font. (x,y) is the position of the left top corner. Does lock and update the surface. Returns the postion and size of the rendered string. Does lock and update the surface. Does respect clipping.

SDL_Rect sge_BF_textoutf(SDL_Surface *surface, sge_bmpFont *font, Sint16 x, Sint16 y , char *format, ...)
Just as sge_BF_textout() but with the same syntax as printf().


sge_BF_input
These function handle keyboard input and shows the result on screen. Works in the same way as sge_tt_input() but always preserves the background and (x,y) is the top left corner of the rendered text string.
Flags: (may be ORed, eg. SGE_IDEL|SGE_INOKR)
0 - Default
SGE_IDEL - Delete text on exit.
SGE_INOKR - No keyrepeat (you can then use SDL_EnableKeyRepeat() yourself).
Note: This function will block your program! Use the text classes if you want more control (see the example).





Copyright © 1999-2003 Anders Lindstrm
Last updated 030808

sge030809/docs/toc.html0000644000175000001440000002337407714763166013454 0ustar samusers SGE Documentation

SGE Documentation

Table of Contents

SGE Introduction
1. Intro
2. Requirements
3. Compiling
4. Library usage
5. Makefile options
5.1 Using pure C with SGE(C_COMP)
5.2 FreeType (USE_FT)
5.3 The SDL_Image library (USE_IMG)
5.4 The QUIET option (QUIET)
6. Cross compiling SGE to W32
7. Compiling SGE under W32 with MS VisC/C++
8. Misc.
Beginners guide to SGE
1. Intro
2. Compiling SGE
3. Using SGE
4. How to distribute your project
Surface operations
sge_UpdateRect
sge_Update_ON/OFF
sge_Lock_ON/OFF
sge_CreateAlphaSurface
sge_ClearSurface
sge_copy_surface
sge_BlitTransparent
sge_Blit
sge_FloodFill
Color manipulation
sge_MapAlpha
sge_FillPaletteEntry
sge_GetRGB
sge_Fader
sge_AlphaFader
sge_SetupRainbowPalette
sge_SetupBWPalette
Pixel operations
_PutPixel
sge_PutPixel
sge_CalcYPitch
sge_pPutPixel
sge_GetPixel
sge_write_block
sge_read_block
Figures
sge_H/VLine
sge_DoLine
sge_Line
sge_DomcLine
sge_mcLine
sge_Rect
sge_FilledRect
sge_DoCircle
sge_Circle
sge_FilledCircle
sge_DoEllipse
sge_Ellipse
sge_FilledEllipse
sge_Bezier
Text management
TrueType font rendering
The TT font structure
sge_TTF_Init
sge_TTF_OpenFont
sge_TTF_OpenFontIndex
sge_TTF_OpenFontRW
sge_TTF_OpenFontIndexRW
sge_TTF_CloseFont
sge_TTF_ByteSwappedUNICODE
sge_TTF_SetFontSize
sge_TTF_SetFontSizeDPI
sge_TTF_TextSize
sge_TTF_FontHeight
sge_TTF_FontAscent
sge_TTF_FontDescent
sge_TTF_FontLineSkip
sge_TTF_FontFaces
sge_TTF_FontFaceIsFixedWidth
sge_TTF_FontFaceFamilyName
sge_TTF_FontFaceStyleName
sge_TTF_AAOn/Off/_Alpha
sge_TTF_SetFontStyle
sge_TTF_GetFontStyle
sge_tt_textout
sge_tt_textoutf
sge_tt_input
Bitmap font rendering
The bitmap font structure
sge_BF_OpenFont
sge_BF_CreateFont
sge_BF_CloseFont
sge_BF_SetColor
sge_BF_SetAlpha
sge_BF_GetHeight
sge_BF_GetWidth
sge_BF_TextSize
sge_BF_textout
sge_BF_textoutf
sge_BF_input
Text classes
sge_TextEditor
sge_text
sge_TextSurface
sge_TextSsprite
sge_TextSprite
sge_text_input
Surface and sprite classes
sge_shape
sge_surface
sge_ssprite
sge_sprite
sge_screen
Basic collision detection
sge_make_cmap
sge_bbcheck
sge_bbcheck_shape
sge_cmcheck
sge_get_cx/y
sge_unset_cdata
sge_set_cdata
sge_destroy_cmap
Surface rotation/scaling routines
sge_transform
sge_transform_surface
Polygons and some texture mapping
sge_FadedLine
sge_TexturedLine
sge_Trigon
sge_FilledTrigon
sge_FadedTrigon
sge_TexturedTrigon
sge_TexturedRect
sge_FilledPolygon
sge_FadedPolygon
Misc. functions
sge_Random
sge_Randomize
sge_CalibrateDelay
sge_DelayRes
sge_Delay
Macros
sge_clip
sge_RectUnion
Thanks


SGE:s Homepage





Copyright © 1999-2003 Anders Lindstrm
Last updated 030808

sge030809/docs/macros.html0000644000175000001440000000257407714761363014147 0ustar samusers SGE Documentation - Macros

SGE Macros


Important!

sge_clip
Returns clipping boundaries for the surface.



void sge_RectUnion(SDL_Rect dst_rect, SDL_Rect rect1, SDL_Rect rect2)
Put the smallest bounding rectangle that encloses both rect1 and rect2 in dst_rect. Note that dst_rect can't be the same structure as rect1 or rect2!





Copyright © 1999-2003 Anders Lindstrm
Last updated 030808

sge030809/docs/guide.html0000644000175000001440000002167607712730735013761 0ustar samusers SGE Documentation - Guide

Beginners guide to SGE

1. Intro
2. Compiling SGE
3. Using SGE
4. How to distribute your project

1. Intro

This is a small guide about how to compile and use SGE in your own project. It's mostly aimed at Unix/Linux developers but others can probably find some information in here too. This guide also assumes that you have a working version of SDL (and FreeType if you want to use TT fonts in SGE) installed on your system (see the "README" file for more information about this).

2. Compiling SGE

First we need to download the latest release. It's available under "Download" at the SGE homepage:
http://www.etek.chalmers.se/~e8cal1/sge/index.html or
http://home.swipnet.se/cal_home/sge/index.html.
Save the sgeXXXXXX.tar.gz file somewhere and open a terminal and go to the directory where you saved it. Unpack the file ('tar zxfv sgeXXXXXX.tar.gz') and you will have a new directory with the SGE source code inside.

Now you're ready to compile SGE! Make sure that you're standing in the root SGE directory (sgeXXXXXX/). If you just want to test SGE and its examples you should now run 'make' (or whatever GNU make is called on your system), but if you want to install SGE on your system then you should run 'make install'. If something goes wrong under the compilation there's probably something wrong with your SDL or FreeType installations.

You should test the examples when you have finished compiling SGE. Enter the directory "examples/" and run "make", this will build all examples. Read the "README" file in this directory for more information about the examples.

3. Using SGE

In this part of the guide I'll assume that you have installed SGE with "make install".

First create a directory for your new project (e.g. 'mkdir myproject'), in this directory we'll create the file "myproject.cpp". Start your favorite text editor and put some C/C++ code into the "myproject.cpp" file, e.g. this very simple program:

/* A very simple SDL/SGE program */

#include "SDL.h"
#include "sge.h"

int main(int argc, char** argv)
{
	/* Init SDL */
	SDL_Init(SDL_INIT_TIMER|SDL_INIT_VIDEO);

	/* Set window title */
	SDL_WM_SetCaption("Testing", "testing");

	/* Initialize the display */
	SDL_Surface *screen;
	screen = SDL_SetVideoMode(640, 480, 16, SDL_SWSURFACE);

	sge_FilledRect(screen, 20,20, 620,460, 255,0,0);

	SDL_Event event;
	do{
		/* Wait for user input */
		SDL_WaitEvent(&event);
		if(event.type == SDL_KEYDOWN && event.key.keysym.sym == SDLK_ESCAPE)
			break;
		if(event.type == SDL_QUIT)
			break;
	}while(true);

	SDL_Quit();
	return 0;
}

This is a very simple program without any error checking. Don't try this at home, always check for errors!

You can now compile and link this code with:
g++ -Wall -O3 `sdl-config --cflags` -c myproject.cpp
g++ -o myproject myproject.o -lSGE `sdl-config --libs` -lstdc++

Run ./myproject and a window with a red rectangle should show.

It can become a bit tedious to enter the command lines above every time you want to compile your code, therefor we will now write a makefile for our project. Create a file namned "Makefile" and enter the following:

# Makefile for myproject

CXX=g++
CFLAGS =-Wall -O3 $(shell sdl-config --cflags)
LIBS = -lSGE  $(shell sdl-config --libs) -lstdc++

TARGETS = myproject 	#change this to your project name

OBJECTS = $(addsuffix .o, $(TARGETS))

all:	$(TARGETS)

$(TARGETS):	%:%.o
	$(CXX) -o $@ $< $(LIBS)

$(OBJECTS):	%.o:%.cpp
	$(CXX) $(CFLAGS) -c $<

clean:
	@rm -f *.o $(TARGETS)


Run 'make clean' to remove the data from the previous compile and then run 'make', the result should be the same as when you entered the commands manually.

If your project grows and spilts into multiple .cpp files that each have a corresponding .h file then your makefile should look something like:

# Makefile for mycomplexproject

CXX=g++
CFLAGS =-Wall -O3 $(shell sdl-config --cflags)
LIBS = -lSGE  $(shell sdl-config --libs) -lstdc++

OBJECTS = foo.o bar.o baz.o  #every .cpp file in your project but replace .cpp with .o

all:	$(OBJECTS)
	$(CXX) -o mycomplexproject $(OBJECTS) $(LIBS)

$(OBJECTS):	%.o:%.cpp %.h
	$(CXX) $(CFLAGS) -c $<

clean:
	@rm -f *.o mycomplexproject


Well, it's all a bit of black magic but for now I assume that you used the first Makefile example (for more information about GNU make black magic please read its manual).

4. How to distribute your project

It's important to remember that SGE is licensed under the GNU Lesser General Public License, which means that you can't link any non-GPL or non-LGPL code directly to it. In that case you MUST link to a shared library version (under Unix libSGE.so and under Win32 SGE.dll). You must also include a notice in your distribution that you're using SGE (and SDL!) and where the source code for SGE can be found. Also note that you might be using other libraries too that SGE and SDL depend on (e.g. libpthread and libfreetype).

But if your project is licensed under the GPL or LGPL then you're free to use SGE (and SDL) in almost any way you want (e.g. copy&paste code directly from SGE).

Below are some hints about how to include SGE in a source distribution of your project.


The do-it-yourself method
The easiest way to use SGE in your source distribution is to tell the user to download and install SGE him/her-self. This is the most common way.


The include-it method
It might be a bit frustrating for the user to download every library him/her-self, especially smaller libraries like SGE. One way to solve this is to include the SGE source code directly. Place the sge*.cpp, sge*.h, Makefile* and License files in a new directory (i.e. sge/) at the root of your project. Please also include a short notice like:

This project uses the SGE library from http://www.etek.chalmers.se/~e8cal1/sge/index.html. SGE is distributed under the GNU Lesser General Public License (LGPL - see the License file for more information).

Now either tell the user to go to this directory and compile and install SGE him/her-self or do it from your build system. Make sure that you modify the "Makefile.conf" to suite your project, this way you can use it directly in your build system (if you use a pure make system like the examples above). Then you can use a Makefile like this for your project:
# Makefile for foobar

include sge/Makefile.conf

CFLAGS =-Wall -O2 $(SGE_CFLAGS) -Isge/
LIBS =-Lsge/ -lSGE $(SGE_LIBS)

... (the rest of the Makefile goes here).

Also add this rule in the Makefile:
...
sgelib:
	@(cd sge; $(MAKE))
...
and then add that rule like a dependency somewhere, something like:
...
all:	sgelib $(TARGETS)
	...
or if you used the more complex makefile example above:
...
all:	sgelib $(OBJECTS)
	...
well, you get the idea. It might also be a good idea to modify the clean rule:
...
clean:
	...
	@(cd sge; $(MAKE) clean)
...
Done! If you don't want "Makefile.conf" to output any SGE messages while building then you should uncomment the "QUIET" option.

This will link your code statically to SGE so your project must be GPL/LGPL licensed for this to work. If you want to link dynamically to SGE it might be better to ask the user to compile and install SGE before building your project, but you might also automatically build a shared version of SGE with "@(cd sge; $(MAKE) shared)" from your Makefile, however you should no longer use the SGE_CFLAGS and SGE_LIBS in your makefile (just do something like the first simple makefile example above). Also, in this case, don't forget to install SGE ("@(cd sge; $(MAKE) install)" if you want the default SGE installation) with your project or else your executables won't run. Some Unix systems (like Linux) also require that you run "ldconfig" when you have installed new libraries.


Anders Lindstrm





Copyright © 1999-2003 Anders Lindstrm
Last updated 030802

sge030809/docs/collision.html0000644000175000001440000000565407714761304014653 0ustar samusers SGE Documentation - Collision detection

Basic collision detection


sge_cdata *sge_make_cmap(SDL_Surface *img)
Creates a new collision map. Use SDL_SetColorKey() before calling this function. Every non-transparent pixel is set to solid in the collision map. The collision map is bit encoded in a Uint8 array. Returns the collision map or NULL on error.

int sge_bbcheck(sge_cdata *cd1,Sint16 x1,Sint16 y1, sge_cdata *cd2,Sint16 x2,Sint16 y2)
int _sge_bbcheck(Sint16 x1,Sint16 y1,Sint16 w1,Sint16 h1, Sint16 x2,Sint16 y2,Sint16 w2,Sint16 h2)

Checks if two rectangles (the bounding boxes) overlap. Returns 1 if so or else 0.

int sge_bbcheck_shape(sge_shape *shape1, sge_shape *shape2)
Checks if two shapes (the bounding boxes) overlap. Returns 1 if so or else 0.

int sge_cmcheck(sge_cdata *cd1,Sint16 x1,Sint16 y1, sge_cdata *cd2,Sint16 x2,Sint16 y2)
int _sge_cmcheck(sge_cdata *cd1,Sint16 x1,Sint16 y1, sge_cdata *cd2,Sint16 x2,Sint16 y2);

Does pixel perfect collision detection. The (x1,y1) and (x2,y2) coords are the positions of the upper left corners of the images. You MUST call sge_bbcheck() before using _sge_cmcheck(), sge_cmcheck() does this automatically. Returns 1 if any solid pixels of the two images overlap or else 0.

Sint16 sge_get_cx(void)
Sint16 sge_get_cy(void)

Returns the position of the last collision found by sge_cmcheck().

void sge_unset_cdata(sge_cdata *cd, Sint16 x, Sint16 y, Sint16 w, Sint16 h)
Clears an area in the collision map from anything solid.

void sge_set_cdata(sge_cdata *cd, Sint16 x, Sint16 y, Sint16 w, Sint16 h)
Makes an area in the collision map solid.

void sge_destroy_cmap(sge_cdata *cd)
Removes collision map from memory.





Copyright © 1999-2003 Anders Lindstrm
Last updated 030808

sge030809/docs/color.html0000644000175000001440000000475207714761333013776 0ustar samusers SGE Documentation - Color

Color manipulation

Uint32 sge_MapAlpha(Uint8 R, Uint8 G, Uint8 B, Uint8 A)
Use this function to map Uint32 color values (RGBA) for *32bit* alpha surfaces. The color value can then be used with any of SGEs functions.

SDL_Color sge_FillPaletteEntry(Uint8 R, Uint8 G, Uint8 B)
Fills a palette entry (SDL_Color) with R, G, B components.

SDL_Color sge_GetRGB(SDL_Surface *Surface, Uint32 Color)
Get the RGB of a color value.

void sge_Fader(SDL_Surface *Surface, Uint8 sR,Uint8 sG,Uint8 sB, Uint8 dR,Uint8 dG,Uint8 dB,Uint32 *ctab,int start, int stop)
Fades from (sR,sG,sB) to (dR,dG,dB), puts result (32-bit pixel format) in ctab[start] to ctab[stop].

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)
Fades from (sR,sG,sB,sA) to (dR,dG,dB,dA), puts result (32-bit alpha pixel format) in ctab[start] to ctab[stop].

void sge_SetupRainbowPalette(SDL_Surface *Surface,Uint32 *ctab,int intensity, int start, int stop)
Copies a nice rainbow palette to the color table (ctab[start] to ctab[stop]). You must also set the intensity of the palette (0-bright 255-dark)

void sge_SetupBWPalette(SDL_Surface *Surface,Uint32 *ctab,int start, int stop)
Copies a B&W palette to the color table (ctab[start] to ctab[stop]).





Copyright © 1999-2003 Anders Lindstrm
Last updated 030808

sge030809/docs/rotate.html0000644000175000001440000000705007714762751014155 0ustar samusers SGE Documentation - Surface rotation and scaling

Surface rotation and scaling


SDL_Rect sge_transform(SDL_Surface *src, SDL_Surface *dst, float angle, float xscale, float yscale, Uint16 px, Uint16 py, Uint16 qx, Uint16 qy, Uint8 flags)
Draws a rotated and scaled version of src on dest. Flags: (may be ORed, eg. SGE_TAA|SGE_TSAFE) To get optimal performance PLEASE make sure that the two surfaces has the same pixel format (color depth) and doesn't use 24-bpp.

Note:
  • You can set source and destination clipping rectangles with SDL_SetClipRect().
  • If you use the interpolated renderer the image will be clipped 1 pixel in hight and width (to optimize the performance).
  • If you want to transform a 32-bpp RGBA (alpha) surface with the interpolated renderer, please use the SGE_TSAFE flag.
  • This function will not do any alpha blending, but it will try to preserve the alpha channel. If you want to rotate and alpha blend the result, please use sge_transform_surface() and then blit that surface to its destination.
Does lock the surfaces.

Returns SDL_Rect: The size and position (bounding box) of the rendered image on dst surface.




SDL_Surface *sge_transform_surface(SDL_Surface *src, Uint32 bcol, float angle, float xscale, float yscale, Uint8 flags)
Returns a rotated and scaled version of src. See sge_transform() for more information.
  • Uint32 bcol - What background color should the new surface have? This pixel value should be mapped with SDL_MapRGB/SDL_MapRGBA on the src surface.
The new surface will have the same depth and pixel format as the src surface.

Returns SDL_Surface*: A pointer to the new surface or NULL on failure. Don't forget to free this surface later with SDL_FreeSurface().






Copyright © 1999-2003 Anders Lindstrm
Last updated 030808

sge030809/docs/ttf-output.html0000644000175000001440000001034507713247144015004 0ustar samusers SGE Documentation - TTF

TrueType font output

To the TTF setup functions>>

sge_tt_textout

  • SDL_Rect sge_tt_textout(SDL_Surface *Surface, sge_TTFont *font, const char *string, Sint16 x, Sint16 y, Uint32 fcolor, Uint32 bcolor, int Alpha)
  • SDL_Rect sge_tt_textout(SDL_Surface *Surface, sge_TTFont *font, const char *string, Sint16 x, Sint16 y, Uint8 fR, Uint8 fG, Uint8 fB, Uint8 bR, Uint8 bG, Uint8 bB, int Alpha)
  • SDL_Rect sge_tt_textout_UNI(SDL_Surface *Surface, sge_TTFont *font, const Uint16 *uni, Sint16 x, Sint16 y, Uint32 fcolor, Uint32 bcolor, int Alpha)
  • SDL_Rect sge_tt_textout_UNI(SDL_Surface *Surface, sge_TTFont *font, const Uint16 *uni, Sint16 x, Sint16 y, Uint8 fR, Uint8 fG, Uint8 fB, Uint8 bR, Uint8 bG, Uint8 bB, int Alpha)
  • SDL_Rect sge_tt_textout_UTF8(SDL_Surface *Surface, sge_TTFont *font, const char *string, Sint16 x, Sint16 y, Uint32 fcolor, Uint32 bcolor, int Alpha)
  • SDL_Rect sge_tt_textout_UTF8(SDL_Surface *Surface, sge_TTFont *font, const char *string, Sint16 x, Sint16 y, Uint8 fR, Uint8 fG, Uint8 fB, Uint8 bR, Uint8 bG, Uint8 bB, int Alpha)
Renders the given Latin-1/Unicode/UTF-8 string on surface with the given font.

SDL_Surface *Surface - The surface to render text to.
sge_TTFont *font - The font to render the text with.
const char *string or const Uint16 *uni - The Latin-1/Unicode/UTF-8 text string.
Sint16 x, Sint16 y - The leftmost point of the baseline for the text.
Uint32 fcolor or Uint8 fR, Uint8 fG, Uint8 fB - The color of the font.
Uint32 bcolor or Uint8 bR, Uint8 bG, Uint8 bB - The background color (see below).
int Alpha - Sets the transparency of the text (0-255).

You can use sge_TTF_AAOn(), sge_TTF_AAOff() and sge_TTF_AA_Alpha() to control how the text is rendered. If you use antialiasing, the background color must be set to the background color of the area where you will render the text. If the background has more than one color it might be better to use sge_TTF_AA_Alpha().
Does lock and update the surface. Does respect clipping.

Returns SDL_Rect: The size and position of the rendered text.


sge_tt_textoutf

  • SDL_Rect sge_tt_textoutf(SDL_Surface *Surface, sge_TTFont *font, Sint16 x, Sint16 y, Uint8 fR, Uint8 fG, Uint8 fB, Uint8 bR, Uint8 bG, Uint8 bB, int Alpha, char *format,...)
Just as sge_tt_textout() but with the same syntax as printf().

Example

#include <iostream>
#include <string>
#include "SDL.h"
#include "sge.h"

using namespace std;

...

//Init font engine and exit on error
if(sge_TTF_Init()!=0){
cerr << "TT error: " << SDL_GetError() << endl;
exit(1);
}
//Open font and exit on error
sge_TTFont *font=sge_TTF_OpenFont("font.ttf", 25);
if(!font){
cerr << "TT error: " << SDL_GetError() << endl;
exit(1);
}
string text("Hello World!");

sge_tt_textoutf( screen, font, 10,100, 0,200,100, 0,0,0, SDL_ALPHA_OPAQUE, "Testing: %s", text.c_str() );

sge_TTF_CloseFont(font);


To the TTF input functions>>





Copyright © 1999-2003 Anders Lindstrm
Last updated 030803

sge030809/docs/intro.html0000644000175000001440000002106207714732037014003 0ustar samusers SGE Documentation - Intro

SDL Graphics Extension (SGE)

1. Intro
2. Requirements
3. Compiling
4. Library usage
5. Makefile options
5.1 Using pure C with SGE (C_COMP)
5.2 FreeType (USE_FT)
5.3 The SDL_Image library (USE_IMG)
5.4 The QUIET option (QUIET)
6. Cross compiling SGE to W32
7. Compiling SGE under W32 with MS VisC/C++
8. Misc.

1. Intro

SGE is an add-on graphics library for the Simple Direct Media Layer. SGE provides pixel operations, graphics primitives, FreeType rendering, rotation/scaling and much more.

This is free software (LGPL), read LICENSE for details.

SGE has the following parts:

[sge_surface] - Pixel operations, blitting and some pallete stuff.
[sge_primitives] - Drawing primitives such as lines and circles.
[sge_tt_text] - FreeType font support.
[sge_bm_text] - Bitmapfont and SFont support.
[sge_textpp] - Classes for handling and rendering text.
[sge_shape] - Classes for blitting and sprites.
[sge_collision] - Basic collision detection.
[sge_rotation] - Rotation and scaling of surfaces.
[sge_blib] - Filled, gourand shaded and texture mapped polygons.
[sge_misc] - Random number and delay functions.


Read docs/index.html for API documentation.

Always check WhatsNew for important (API) changes!

There is a "Beginners guide to SGE" in this documentation about how to compile and use SGE in your own project, please read it if you're new to Unix/Linux development.

Read INSTALL for quick compile and install instructions.

2. Requirements

  • GNU Make.
  • SDL 1.2+.
  • An ANSI/ISO C++ compiler. SGE should conform to ANSI/ISO C++.
  • Optional:
  • Some SDL knowledge.
First you need SDL and the FreeType (2.x) library (you only need the FreeType library if you want to use SGE's truetype font routines, see section 5.2). The FreeType library is included in most Linux distributions (RPM users: install the freetype dev rpm package from the install cd).

After installing SDL and FreeType, don't forget to check that the dynamic linker can find them (check /etc/ld.so.conf and run ldconfig).
You must also have a good C++ compiler (should be able to handle templates). Recent versions of GNU c++ works fine. SGE will use gcc/g++ as default, this can be changed in Makefile.conf.


3. Compiling

Before compiling you might want to change some Makefile.conf options, see section 5.

Just do 'make install' to compile and install SGE. This will install SGE to the same place as SDL. You can change the install location by editing the PREFIX and PREFIX_H lines in the file "Makefile.conf".

If you just want to test the examples (and not install anything) you can just do 'make'. This will build a static version of SGE (libSGE.a).

If you want a dynamic version of SGE (libSGE.so) but don't want the makefile to install SGE, do 'make shared'.

To build the examples, goto the directory examples/ and do 'make'.

See the file INSTALL for more information. You can also read the "Beginners guide to SGE".


4. Library usage

Do #include "sge.h" in your code after the normal #include "SDL.h" line.

The normal way to compile code that uses SGE is with the flag `sdl-config --cflags`, but also add the flag -I/path/to/SGE/headers if the SGE headers are installed at any other place than the SDL headers.

The normal way to link code that uses SGE is with the flags -lSGE `sdl-config --libs` -lstdc++, but also add the flag -L/path/to/SGE/library if SGE is installed at any other place than SDL. If you're using static linking then the flags `freetype-config --libs` and/or -lSDL_image also needs to be added if FreeType and/or SDL_Image support is enabled.

Example:
g++ -Wall -O3 `sdl-config --cflags` -c my_sge_app.cxx
g++ -o my_sge_app my_sge_app.o -lSGE `sdl-config --libs` -lstdc++

See the "Beginners guide to SGE" and the code in examples/ for more information.


5. Makefile options

Edit Makefile.conf to turn on/off (y/n) these options.

5.1 Using pure C with SGE (C_COMP)

Setting 'C_COMP = y' should allow both C and C++ projects to use SGE. However, you will not be able to use any of the overloaded functions (only the Uint32 color version of the overloaded functions will be available) or C++ classes from a C project. C++ projects should not be affected. Default is 'y'.

5.2 FreeType (USE_FT)

If you don't need the TT font routines or just don't want do depend on FreeType, uncomment 'USE_FT = n' in Makefile.conf. Default behavior is to autodetect FreeType.

5.3 The SDL_Image library (USE_IMG)

The SDL_Image library SDL_Image will be autodetected with the default setting. SDL_Image support enables SGE to load png images and thus use Karl Bartel's very nice SFont bitmapfonts. The use of SDL_Image can also be controlled by setting 'USE_IMG = y/n' manually.

5.4 The QUIET option (QUIET)

Set QUIET = y if you don't want the makefile to output any SGE specific messages.


6. Cross compiling SGE to W32

SGE can be compiled by a win32 crosscompiler. You need a crosscompiled version of SDL (and FreeType or SDL_Image if used). Check SDL's documentation (README.Win32) on how to get and setup a cross-compiler.

A crosscompiler can be found at SDL's Mingw32 side. This crosscompiler uses the new MS C-Run-time library "msvcrt.dll", you can get it from Microsoft (do a keyword search for "libraries update") if you don't already have it.

If you want to build a dll ('cross-make dll' or 'dll-strip') then you might want to do 'ln -s ../../bin/i386-mingw32msvc-dllwrap dllwrap' in /usr/local/cross-tools/i386-mingw32msvc/bin.

7. Compiling SGE under W32 with MS VisC/C++

Should work. Check the download page on SGEs homepage for project files (these are untested by me and are often outdated but may be of some help).

Note that if you don't use the makefile system to build SGE (as with VisC/C++) then you must edit sge_config.h manually to change build options. The options in section 5 corresponds to defining the following symbols in sge_config.h:
_SGE_C_AND_CPP  - C_COMP=y
_SGE_NOTTF      - USE_FT=n
_SGE_HAVE_IMG   - USE_IMG=y
For example:
/* SGE Config header */
#define SGE_VER 030810
#define _SGE_C_AND_CPP
#define _SGE_HAVE_IMG


8. Misc.

Read the html documentation and study the examples.



Anders Lindstrm





Copyright © 1999-2003 Anders Lindstrm
Last updated 030803

sge030809/docs/ttf-input.html0000644000175000001440000001205007714722074014577 0ustar samusers SGE Documentation - TTF

TrueType font input

sge_tt_input

  • int sge_tt_input(SDL_Surface *screen, sge_TTFont *font, char *string, Uint8 flags, int pos, int len, Sint16 x, Sint16 y, Uint32 fcol, Uint32 bcol, int Alpha)
  • int sge_tt_input(SDL_Surface *screen, sge_TTFont *font, char *string, Uint8 flags, int pos,int len,Sint16 x,Sint16 y, Uint8 fR, Uint8 fG, Uint8 fB, Uint8 bR, Uint8 bG, Uint8 bB, int Alpha)
  • int sge_tt_input_UNI(SDL_Surface *screen, sge_TTFont *font, Uint16 *string, Uint8 flags, int pos, int len, Sint16 x, Sint16 y, Uint32 fcol, Uint32 bcol, int Alpha)
  • int sge_tt_input_UNI(SDL_Surface *screen, sge_TTFont *font, Uint16 *string, Uint8 flags, int pos, int len, Sint16 x, Sint16 y, Uint8 fR, Uint8 fG, Uint8 fB, Uint8 bR, Uint8 bG, Uint8 bB, int Alpha)
These functions handle keyboard input and shows the result on screen.

SDL_Surface *screen - The screen pointer.
sge_TTFont *font - The font to render the text with.
char *string or Uint16 *string - The Latin-1/Unicode text string to put the result into.
Uint8 flags - Flags (may be ORed, eg. SGE_IBG|SGE_IDEL).
0 - Default
SGE_IBG - Keeps the background, use this if the background has more colors than the background color.
SGE_IDEL - Delete text on screen on exit.
SGE_INOKR - No keyrepeat (you can then use SDL_EnableKeyRepeat() yourself).
int pos - Set this to zero if you don't want a default text (see below).
int len - The max numbers of chars editable, "string" should have at least len+1 elements allocated.
Sint16 x, Sint16 y - The leftmost point of the baseline for the text.
Uint32 fcolor or Uint8 fR, Uint8 fG, Uint8 fB - The color of the font.
Uint32 bcolor or Uint8 bR, Uint8 bG, Uint8 bB - The background color (see below).
int Alpha - Sets the transparency of the text (0-255).

The text can be edited with [Backspace], [Delete], [Left arrow] and [Right arrow]. Text input is terminated when [Return], [Enter] or [Escape] is pressed, or if a quit event is received. Puts the result in "string" (null terminated).

If you want a 'default' text then copy a null (\0) terminated string into the argument "string" before calling this function. Set "pos" to any other value than zero to indicate this.

You can use sge_TTF_AAOn(), sge_TTF_AAOff() and sge_TTF_AA_Alpha() to control how the text is rendered. If you use antialiasing, the background color must be set to the background color of the area where you will render the text. If the background has more than one color it might be better to use sge_TTF_AA_Alpha().
Does lock and update the surface. Does respect clipping.

Note: This function will block your program! Use the text classes if you want more control (see the example).

Returns int:
Zero or above - the length of the string (i.e. [Return] or [Enter] was pressed).
-1 - received a quit event, but everything else was handled as normal.
-2 - [Escape] was pressed, but everything else was handled as normal.
-3 - out of memory.

Example

#include <iostream>
#include <string.h>
#include "SDL.h"
#include "sge.h"

using namespace std;

...

//Init font engine and exit on error
if(sge_TTF_Init()!=0){
cerr << "TT error: " << SDL_GetError() << endl;
exit(1);
}
//Open font and exit on error
sge_TTFont *font=sge_TTF_OpenFont("font.ttf", 25);
if(!font){
cerr << "TT error: " << SDL_GetError() << endl;
exit(1);
}
sge_TTF_AA_Alpha(); //Nice alpha rendering

char string[52];
strcpy(string,"Edit Me!"); //The default text
int ret;

//Let the user edit the text
ret=sge_tt_input( screen, font, string, SGE_IBG, 1, 50, 10,100, 0,0,255, 0,0,0, SDL_ALPHA_OPAQUE );
if(ret>0)
cout << string << endl; //print the text
sge_TTF_CloseFont(font);


To the TTF setup functions>>





Copyright © 1999-2003 Anders Lindstrm
Last updated 030808

sge030809/docs/misc.html0000644000175000001440000000430207714764467013615 0ustar samusers SGE Documentation - Misc. functions

Misc. functions


int sge_Random(int min, int max)
Returns a random integer between (and including) min and max.

void sge_Randomize(void)
Seed the random number generator with a number from the system clock. Should be called once before the first use of sge_Random.

Uint32 sge_CalibrateDelay(void)
Tests and returns the current resolution (the smallest delay possible) of SDL_Delay(). This test will take 10-50ms to complete.

Uint32 sge_DelayRes(void)
Returns the latest result of sge_CalibrateDelay() or 10ms as default.

Uint32 sge_Delay(Uint32 ticks)
The SGE version of SDL_Delay(). SDL_Delay() burns time by giving it to the system, which gives other tasks more CPU time. BUT (if you're not running a realtime OS) the delay will not take the exact time you specified and will not be the same on a different machine or OS. sge_Delay() uses sge_DelayRes() to get the safe amount of time to burn with SDL_Delay() and burns the rest in a loop. This should give the same delay on all machines & OSes but still give more CPU time to other tasks if possible. Note that if the user starts something CPU intensive after you called sge_CalibrateDelay() the result will be less reliable.
Returns the exact time delayed.





Copyright © 1999-2003 Anders Lindstrm
Last updated 030808

sge030809/sge_primitives.cpp0000644000175000001440000021303107714662501014564 0ustar samusers/* * SDL Graphics Extension * Drawing primitives * * Started 990815 (split from sge_draw 010611) * * License: LGPL v2+ (see the file LICENSE) * (c)1999-2003 Anders Lindstrm */ /********************************************************************* * This library is free software; you can redistribute it and/or * * modify it under the terms of the GNU Library General Public * * License as published by the Free Software Foundation; either * * version 2 of the License, or (at your option) any later version. * *********************************************************************/ /* * Some of this code is taken from the "Introduction to SDL" and * John Garrison's PowerPak */ #include "SDL.h" #include #include #include #include #include "sge_primitives.h" #include "sge_surface.h" /* Globals used for sge_Update/sge_Lock (defined in sge_surface) */ extern Uint8 _sge_update; extern Uint8 _sge_lock; #define SWAP(x,y,temp) temp=x;x=y;y=temp /**********************************************************************************/ /** Line functions **/ /**********************************************************************************/ //================================================================================== // Internal draw horizontal line //================================================================================== void _HLine(SDL_Surface *Surface, Sint16 x1, Sint16 x2, Sint16 y, Uint32 Color) { if(x1>x2){Sint16 tmp=x1; x1=x2; x2=tmp;} //Do the clipping #if SDL_VERSIONNUM(SDL_MAJOR_VERSION, SDL_MINOR_VERSION, SDL_PATCHLEVEL) < \ SDL_VERSIONNUM(1, 1, 5) if(yclip_miny || y>Surface->clip_maxy || x1>Surface->clip_maxx || x2clip_minx) return; if(x1clip_minx) x1=Surface->clip_minx; if(x2>Surface->clip_maxx) x2=Surface->clip_maxx; #endif SDL_Rect l; l.x=x1; l.y=y; l.w=x2-x1+1; l.h=1; SDL_FillRect(Surface, &l, Color); } //================================================================================== // Draw horizontal line //================================================================================== void sge_HLine(SDL_Surface *Surface, Sint16 x1, Sint16 x2, Sint16 y, Uint32 Color) { if(x1>x2){Sint16 tmp=x1; x1=x2; x2=tmp;} //Do the clipping #if SDL_VERSIONNUM(SDL_MAJOR_VERSION, SDL_MINOR_VERSION, SDL_PATCHLEVEL) < \ SDL_VERSIONNUM(1, 1, 5) if(yclip_miny || y>Surface->clip_maxy || x1>Surface->clip_maxx || x2clip_minx) return; if(x1clip_minx) x1=Surface->clip_minx; if(x2>Surface->clip_maxx) x2=Surface->clip_maxx; #endif SDL_Rect l; l.x=x1; l.y=y; l.w=x2-x1+1; l.h=1; SDL_FillRect(Surface, &l, Color); sge_UpdateRect(Surface, x1, y, x2-x1+1, 1); } //================================================================================== // Draw horizontal line (RGB) //================================================================================== void sge_HLine(SDL_Surface *Surface, Sint16 x1, Sint16 x2, Sint16 y, Uint8 R, Uint8 G, Uint8 B) { sge_HLine(Surface,x1,x2,y, SDL_MapRGB(Surface->format, R, G, B)); } //================================================================================== // Internal draw horizontal line (alpha) //================================================================================== void _HLineAlpha(SDL_Surface *Surface, Sint16 x1, Sint16 x2, Sint16 y, Uint32 Color, Uint8 alpha) { Uint8 update = _sge_update; Uint8 lock = _sge_lock; _sge_update = 0; _sge_lock = 0; sge_FilledRectAlpha(Surface, x1,y,x2,y, Color, alpha); _sge_update = update; _sge_lock = lock; } //================================================================================== // Draw horizontal line (alpha) //================================================================================== void sge_HLineAlpha(SDL_Surface *Surface, Sint16 x1, Sint16 x2, Sint16 y, Uint32 Color, Uint8 alpha) { sge_FilledRectAlpha(Surface, x1,y,x2,y, Color, alpha); } //================================================================================== // Draw horizontal line (alpha RGB) //================================================================================== void sge_HLineAlpha(SDL_Surface *Surface, Sint16 x1, Sint16 x2, Sint16 y, Uint8 R, Uint8 G, Uint8 B, Uint8 alpha) { sge_HLineAlpha(Surface,x1,x2,y, SDL_MapRGB(Surface->format, R, G, B), alpha); } //================================================================================== // Internal draw vertical line //================================================================================== void _VLine(SDL_Surface *Surface, Sint16 x, Sint16 y1, Sint16 y2, Uint32 Color) { if(y1>y2){Sint16 tmp=y1; y1=y2; y2=tmp;} //Do the clipping #if SDL_VERSIONNUM(SDL_MAJOR_VERSION, SDL_MINOR_VERSION, SDL_PATCHLEVEL) < \ SDL_VERSIONNUM(1, 1, 5) if(xclip_minx || x>Surface->clip_maxx || y1>Surface->clip_maxy || y2clip_miny) return; if(y1clip_miny) y1=Surface->clip_miny; if(y2>Surface->clip_maxy) y2=Surface->clip_maxy; #endif SDL_Rect l; l.x=x; l.y=y1; l.w=1; l.h=y2-y1+1; SDL_FillRect(Surface, &l, Color); } //================================================================================== // Draw vertical line //================================================================================== void sge_VLine(SDL_Surface *Surface, Sint16 x, Sint16 y1, Sint16 y2, Uint32 Color) { if(y1>y2){Sint16 tmp=y1; y1=y2; y2=tmp;} //Do the clipping #if SDL_VERSIONNUM(SDL_MAJOR_VERSION, SDL_MINOR_VERSION, SDL_PATCHLEVEL) < \ SDL_VERSIONNUM(1, 1, 5) if(xclip_minx || x>Surface->clip_maxx || y1>Surface->clip_maxy || y2clip_miny) return; if(y1clip_miny) y1=Surface->clip_miny; if(y2>Surface->clip_maxy) y2=Surface->clip_maxy; #endif SDL_Rect l; l.x=x; l.y=y1; l.w=1; l.h=y2-y1+1; SDL_FillRect(Surface, &l, Color); sge_UpdateRect(Surface, x, y1, 1, y2-y1+1); } //================================================================================== // Draw vertical line (RGB) //================================================================================== void sge_VLine(SDL_Surface *Surface, Sint16 x, Sint16 y1, Sint16 y2, Uint8 R, Uint8 G, Uint8 B) { sge_VLine(Surface,x,y1,y2, SDL_MapRGB(Surface->format, R, G, B)); } //================================================================================== // Internal draw vertical line (alpha - no update) //================================================================================== void _VLineAlpha(SDL_Surface *Surface, Sint16 x, Sint16 y1, Sint16 y2, Uint32 Color, Uint8 alpha) { Uint8 update = _sge_update; Uint8 lock = _sge_lock; _sge_update = 0; _sge_lock = 0; sge_FilledRectAlpha(Surface, x,y1,x,y2, Color, alpha); _sge_update = update; _sge_lock = lock; } //================================================================================== // Draw vertical line (alpha) //================================================================================== void sge_VLineAlpha(SDL_Surface *Surface, Sint16 x, Sint16 y1, Sint16 y2, Uint32 Color, Uint8 alpha) { sge_FilledRectAlpha(Surface, x,y1,x,y2, Color, alpha); } //================================================================================== // Draw vertical line (alpha RGB) //================================================================================== void sge_VLineAlpha(SDL_Surface *Surface, Sint16 x, Sint16 y1, Sint16 y2, Uint8 R, Uint8 G, Uint8 B, Uint8 alpha) { sge_VLineAlpha(Surface,x,y1,y2, SDL_MapRGB(Surface->format, R, G, B), alpha); } //================================================================================== // Performs Callback at each line point. (From PowerPak) //================================================================================== 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)) { Sint16 dx, dy, sdx, sdy, x, y, px, py; dx = x2 - x1; dy = y2 - y1; sdx = (dx < 0) ? -1 : 1; sdy = (dy < 0) ? -1 : 1; dx = sdx * dx + 1; dy = sdy * dy + 1; x = y = 0; px = x1; py = y1; if (dx >= dy){ for (x = 0; x < dx; x++){ Callback(Surface, px, py, Color); y += dy; if (y >= dx){ y -= dx; py += sdy; } px += sdx; } } else{ for (y = 0; y < dy; y++){ Callback(Surface, px, py, Color); x += dx; if (x >= dy){ x -= dy; px += sdx; } py += sdy; } } } //================================================================================== // Performs Callback at each line point. (RGB) //================================================================================== 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)) { sge_DoLine(Surface,X1,Y1,X2,Y2, SDL_MapRGB(Surface->format, R, G, B),Callback); } //================================================================================== // Line clipping // Standard Cohen-Sutherland algorithm (from gfxPrimitives) //================================================================================== #define CLIP_LEFT_EDGE 0x1 #define CLIP_RIGHT_EDGE 0x2 #define CLIP_BOTTOM_EDGE 0x4 #define CLIP_TOP_EDGE 0x8 #define CLIP_INSIDE(a) (!a) #define CLIP_REJECT(a,b) (a&b) #define CLIP_ACCEPT(a,b) (!(a|b)) int clipEncode(Sint16 x, Sint16 y, Sint16 left, Sint16 top, Sint16 right, Sint16 bottom) { int code = 0; if (x < left) code |= CLIP_LEFT_EDGE; else if (x > right) code |= CLIP_RIGHT_EDGE; if (y < top) code |= CLIP_TOP_EDGE; else if (y > bottom) code |= CLIP_BOTTOM_EDGE; return code; } int clipLine(SDL_Surface *dst, Sint16 *x1, Sint16 *y1, Sint16 *x2, Sint16 *y2) { int code1, code2; bool draw = false; Sint16 tmp; float m; /* Get clipping boundary */ Sint16 left, right, top, bottom; left = sge_clip_xmin(dst); right = sge_clip_xmax(dst); top = sge_clip_ymin(dst); bottom = sge_clip_ymax(dst); while (true){ code1 = clipEncode(*x1, *y1, left, top, right, bottom); code2 = clipEncode(*x2, *y2, left, top, right, bottom); if(CLIP_ACCEPT(code1, code2)){ draw = true; break; }else if(CLIP_REJECT(code1, code2)) break; else{ if(CLIP_INSIDE(code1)){ tmp = *x2; *x2 = *x1; *x1 = tmp; tmp = *y2; *y2 = *y1; *y1 = tmp; tmp = code2; code2 = code1; code1 = tmp; } if(*x2 != *x1) m = (*y2 - *y1) / float(*x2 - *x1); else m = 1.0; if(code1 & CLIP_LEFT_EDGE){ *y1 += Sint16( (left - *x1) * m ); *x1 = left; }else if(code1 & CLIP_RIGHT_EDGE){ *y1 += Sint16( (right - *x1) * m ); *x1 = right; }else if(code1 & CLIP_BOTTOM_EDGE){ if (*x2 != *x1) { *x1 += Sint16( (bottom - *y1) / m ); } *y1 = bottom; }else if(code1 & CLIP_TOP_EDGE){ if (*x2 != *x1) { *x1 += Sint16( (top - *y1) / m ); } *y1 = top; } } } return draw; } //================================================================================== // Draws a line //================================================================================== void _Line(SDL_Surface *surface, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint32 color) { if( !clipLine(surface, &x1, &y1, &x2, &y2) ) return; Sint16 dx, dy, sdx, sdy, x, y; dx = x2 - x1; dy = y2 - y1; sdx = (dx < 0) ? -1 : 1; sdy = (dy < 0) ? -1 : 1; dx = sdx * dx + 1; dy = sdy * dy + 1; x = y = 0; Sint16 pixx = surface->format->BytesPerPixel; Sint16 pixy = surface->pitch; Uint8 *pixel = (Uint8*)surface->pixels + y1*pixy + x1*pixx; pixx *= sdx; pixy *= sdy; if (dx < dy) { Sint32 tmp = dx; dx = dy; dy = Sint16(tmp); tmp = pixx; pixx = pixy; pixy = tmp; } switch(surface->format->BytesPerPixel) { case 1: { for(x=0; x < dx; x++) { *pixel = color; y += dy; if (y >= dx) { y -= dx; pixel += pixy; } pixel += pixx; } } break; case 2: { for(x=0; x < dx; x++) { *(Uint16*)pixel = color; y += dy; if (y >= dx) { y -= dx; pixel += pixy; } pixel += pixx; } } break; case 3: { Uint8 rshift8 = surface->format->Rshift/8; Uint8 gshift8 = surface->format->Gshift/8; Uint8 bshift8 = surface->format->Bshift/8; Uint8 ashift8 = surface->format->Ashift/8; Uint8 R = (color>>surface->format->Rshift)&0xff; Uint8 G = (color>>surface->format->Gshift)&0xff; Uint8 B = (color>>surface->format->Bshift)&0xff; Uint8 A = (color>>surface->format->Ashift)&0xff; for(x=0; x < dx; x++) { *(pixel+rshift8) = R; *(pixel+gshift8) = G; *(pixel+bshift8) = B; *(pixel+ashift8) = A; y += dy; if (y >= dx) { y -= dx; pixel += pixy; } pixel += pixx; } } break; case 4: { for(x=0; x < dx; x++) { *(Uint32*)pixel = color; y += dy; if (y >= dx) { y -= dx; pixel += pixy; } pixel += pixx; } } break; } } void sge_Line(SDL_Surface *Surface, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint32 Color) { if (SDL_MUSTLOCK(Surface) && _sge_lock) { if (SDL_LockSurface(Surface) < 0) return; } /* Draw the line */ _Line(Surface, x1,y1, x2,y2, Color); /* unlock the display */ if (SDL_MUSTLOCK(Surface) && _sge_lock) { SDL_UnlockSurface(Surface); } 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)); } //================================================================================== // Draws a line (RGB) //================================================================================== void sge_Line(SDL_Surface *Surface, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint8 R, Uint8 G, Uint8 B) { sge_Line(Surface,x1,y1,x2,y2, SDL_MapRGB(Surface->format, R, G, B)); } //================================================================================== // A quick hack to get alpha working with callbacks //================================================================================== Uint8 _sge_alpha_hack = 0; void callback_alpha_hack(SDL_Surface *surf, Sint16 x, Sint16 y, Uint32 color) { _PutPixelAlpha(surf,x,y,color,_sge_alpha_hack); } //================================================================================== // Draws a line (alpha) //================================================================================== void _LineAlpha(SDL_Surface *Surface, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint32 Color, Uint8 alpha) { _sge_alpha_hack = alpha; /* Draw the line */ sge_DoLine(Surface, x1, y1, x2, y2, Color, callback_alpha_hack); } void sge_LineAlpha(SDL_Surface *Surface, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint32 Color, Uint8 alpha) { if (SDL_MUSTLOCK(Surface) && _sge_lock) if (SDL_LockSurface(Surface) < 0) return; _LineAlpha(Surface, x1, y1, x2, y2, Color, alpha); /* unlock the display */ if (SDL_MUSTLOCK(Surface) && _sge_lock) { SDL_UnlockSurface(Surface); } 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)); } //================================================================================== // Draws a line (alpha - RGB) //================================================================================== void sge_LineAlpha(SDL_Surface *Surface, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint8 R, Uint8 G, Uint8 B, Uint8 alpha) { sge_LineAlpha(Surface,x1,y1,x2,y2, SDL_MapRGB(Surface->format, R, G, B), alpha); } //================================================================================== // Anti-aliased line // From SDL_gfxPrimitives written by A. Schiffler (aschiffler@home.com) //================================================================================== #define AAbits 8 #define AAlevels 256 /* 2^AAbits */ void _AALineAlpha(SDL_Surface *dst, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint32 color, Uint8 alpha) { Uint32 erracc=0, erradj; Uint32 erracctmp, wgt; Sint16 tmp, y0p1, x0pxdir; Uint8 a; /* Keep on working with 32bit numbers */ Sint32 xx0=x1; Sint32 yy0=y1; Sint32 xx1=x2; Sint32 yy1=y2; /* Reorder points if required */ if (yy0 > yy1) { SWAP(yy0, yy1, tmp); SWAP(xx0, xx1, tmp); } /* Calculate distance */ Sint16 dx = xx1 - xx0; Sint16 dy = yy1 - yy0; /* Adjust for negative dx and set xdir */ Sint16 xdir = 1; if (dx < 0) { xdir=-1; dx=(-dx); } /* Check for special cases */ if (dx==0 || dy==0 || dx==dy) { if(alpha==SDL_ALPHA_OPAQUE) _Line(dst,x1,y1,x2,y2,color); else _LineAlpha(dst,x1,y1,x2,y2,color,alpha); return; } float alpha_pp = float(alpha)/255; /* Used to calculate alpha level if alpha != 255 */ Uint32 intshift = 32 - AAbits; /* # of bits by which to shift erracc to get intensity level */ /* Draw the initial pixel in the foreground color */ if(alpha==SDL_ALPHA_OPAQUE) _PutPixel(dst,x1,y1, color); else _PutPixelAlpha(dst,x1,y1, color, alpha); /* x-major or y-major? */ if (dy > dx) { /* y-major. Calculate 16-bit fixed point fractional part of a pixel that X advances every time Y advances 1 pixel, truncating the result so that we won't overrun the endpoint along the X axis */ erradj = ((dx << 16) / dy)<<16; /* draw all pixels other than the first and last */ x0pxdir=xx0+xdir; while (--dy) { erracctmp = erracc; erracc += erradj; if (erracc <= erracctmp) { /* rollover in error accumulator, x coord advances */ xx0=x0pxdir; x0pxdir += xdir; } yy0++; /* y-major so always advance Y */ /* the AAbits most significant bits of erracc give us the intensity weighting for this pixel, and the complement of the weighting for the paired pixel. */ wgt = (erracc >> intshift) & 255; a = Uint8(255-wgt); if(alpha != SDL_ALPHA_OPAQUE) a = Uint8(a*alpha_pp); _PutPixelAlpha(dst,xx0,yy0,color,a); a = Uint8(wgt); if(alpha != SDL_ALPHA_OPAQUE) a = Uint8(a*alpha_pp); _PutPixelAlpha(dst,x0pxdir,yy0,color,a); } } else { /* x-major line. Calculate 16-bit fixed-point fractional part of a pixel that Y advances each time X advances 1 pixel, truncating the result so that we won't overrun the endpoint along the X axis. */ erradj = ((dy << 16) / dx)<<16; /* draw all pixels other than the first and last */ y0p1=yy0+1; while (--dx) { erracctmp = erracc; erracc += erradj; if (erracc <= erracctmp) { /* Accumulator turned over, advance y */ yy0=y0p1; y0p1++; } xx0 += xdir; /* x-major so always advance X */ /* the AAbits most significant bits of erracc give us the intensity weighting for this pixel, and the complement of the weighting for the paired pixel. */ wgt = (erracc >> intshift) & 255; a = Uint8(255-wgt); if(alpha != SDL_ALPHA_OPAQUE) a = Uint8(a*alpha_pp); _PutPixelAlpha(dst,xx0,yy0,color,a); a = Uint8(wgt); if(alpha != SDL_ALPHA_OPAQUE) a = Uint8(a*alpha_pp); _PutPixelAlpha(dst,xx0,y0p1,color,a); } } /* Draw final pixel, always exactly intersected by the line and doesn't need to be weighted. */ if(alpha==SDL_ALPHA_OPAQUE) _PutPixel(dst,x2,y2, color); else _PutPixelAlpha(dst,x2,y2, color, alpha); } void sge_AALineAlpha(SDL_Surface *dst, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint32 color, Uint8 alpha) { /* Lock surface */ if ( SDL_MUSTLOCK(dst) && _sge_lock ) if ( SDL_LockSurface(dst) < 0 ) return; _AALineAlpha(dst,x1,y1,x2,y2,color,alpha); /* unlock the display */ if (SDL_MUSTLOCK(dst) && _sge_lock) { SDL_UnlockSurface(dst); } 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)); } void sge_AALineAlpha(SDL_Surface *dst, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint8 r, Uint8 g, Uint8 b, Uint8 alpha) { sge_AALineAlpha(dst,x1,y1,x2,y2,SDL_MapRGB(dst->format, r, g, b),alpha); } void sge_AALine(SDL_Surface *dst, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint32 color) { sge_AALineAlpha(dst, x1,y1, x2,y2, color, SDL_ALPHA_OPAQUE); } void sge_AALine(SDL_Surface *dst, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint8 r, Uint8 g, Uint8 b) { sge_AALineAlpha(dst,x1,y1,x2,y2,SDL_MapRGB(dst->format, r, g, b),SDL_ALPHA_OPAQUE); } //================================================================================== // Draws a multicolored line //================================================================================== 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)) { Sint16 dx, dy, sdx, sdy, x, y, px, py; dx = x2 - x1; dy = y2 - y1; sdx = (dx < 0) ? -1 : 1; sdy = (dy < 0) ? -1 : 1; dx = sdx * dx + 1; dy = sdy * dy + 1; x = y = 0; px = x1; py = y1; /* We use fixedpoint math for the color fading */ Sint32 R = r1<<16; Sint32 G = g1<<16; Sint32 B = b1<<16; Sint32 rstep; Sint32 gstep; Sint32 bstep; if (dx >= dy){ rstep = Sint32((r2-r1)<<16) / Sint32(dx); gstep = Sint32((g2-g1)<<16) / Sint32(dx); bstep = Sint32((b2-b1)<<16) / Sint32(dx); for (x = 0; x < dx; x++){ Callback(surface, px, py, SDL_MapRGB(surface->format, Uint8(R>>16), Uint8(G>>16), Uint8(B>>16)) ); y += dy; if (y >= dx){ y -= dx; py += sdy; } px += sdx; R += rstep; G += gstep; B += bstep; } } else{ rstep = Sint32((r2-r1)<<16) / Sint32(dy); gstep = Sint32((g2-g1)<<16) / Sint32(dy); bstep = Sint32((b2-b1)<<16) / Sint32(dy); for (y = 0; y < dy; y++){ Callback(surface, px, py, SDL_MapRGB(surface->format, Uint8(R>>16), Uint8(G>>16), Uint8(B>>16)) ); x += dx; if (x >= dy){ x -= dy; px += sdx; } py += sdy; R += rstep; G += gstep; B += bstep; } } } 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) { if (SDL_MUSTLOCK(Surface) && _sge_lock) { if (SDL_LockSurface(Surface) < 0) return; } /* Draw the line */ sge_DomcLine(Surface, x1,y1, x2,y2, r1,g1,b1, r2,g2,b2, _PutPixel); /* unlock the display */ if (SDL_MUSTLOCK(Surface) && _sge_lock) { SDL_UnlockSurface(Surface); } 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)); } 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) { if (SDL_MUSTLOCK(Surface) && _sge_lock) if (SDL_LockSurface(Surface) < 0) return; _sge_alpha_hack = alpha; /* Draw the line */ sge_DomcLine(Surface, x1,y1, x2,y2, r1,g1,b1, r2,g2,b2, callback_alpha_hack); /* unlock the display */ if (SDL_MUSTLOCK(Surface) && _sge_lock) { SDL_UnlockSurface(Surface); } 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)); } //================================================================================== // Draws a anti-aliased multicolored line //================================================================================== 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) { Uint32 erracc=0, erradj; Uint32 erracctmp, wgt; Sint16 tmp, y0p1, x0pxdir; Uint8 a; /* Keep on working with 32bit numbers */ Sint32 xx0=x1; Sint32 yy0=y1; Sint32 xx1=x2; Sint32 yy1=y2; /* Reorder points if required */ if (yy0 > yy1) { SWAP(yy0, yy1, tmp); SWAP(xx0, xx1, tmp); SWAP(r1, r2, a); SWAP(g1, g2, a); SWAP(b1, b2, a); } /* Calculate distance */ Sint16 dx = xx1 - xx0; Sint16 dy = yy1 - yy0; /* Adjust for negative dx and set xdir */ Sint16 xdir=1; if (dx < 0) { xdir=-1; dx=(-dx); } /* Check for special cases */ if (dx==0 || dy==0 || dx==dy) { sge_mcLineAlpha(dst, x1, y1, x2, y2, r1, g1, b1, r2, g2, b2, alpha); return; } /* We use fixedpoint math for the color fading */ Sint32 R = r1<<16; Sint32 G = g1<<16; Sint32 B = b1<<16; Sint32 rstep; Sint32 gstep; Sint32 bstep; float alpha_pp = float(alpha)/255; /* Used to calculate alpha level if alpha != 255 */ Uint32 intshift = 32 - AAbits; /* # of bits by which to shift erracc to get intensity level */ if(alpha==255) _PutPixel(dst,x1,y1, SDL_MapRGB(dst->format, r1, g1, b1) ); /* Draw the initial pixel in the foreground color */ else _PutPixelAlpha(dst,x1,y1, SDL_MapRGB(dst->format, r1, g1, b1), alpha); /* x-major or y-major? */ if (dy > dx) { /* y-major. Calculate 16-bit fixed point fractional part of a pixel that X advances every time Y advances 1 pixel, truncating the result so that we won't overrun the endpoint along the X axis */ erradj = ((dx << 16) / dy)<<16; rstep = Sint32((r2-r1)<<16) / Sint32(dy); gstep = Sint32((g2-g1)<<16) / Sint32(dy); bstep = Sint32((b2-b1)<<16) / Sint32(dy); /* draw all pixels other than the first and last */ x0pxdir=xx0+xdir; while (--dy) { R += rstep; G += gstep; B += bstep; erracctmp = erracc; erracc += erradj; if (erracc <= erracctmp) { /* rollover in error accumulator, x coord advances */ xx0=x0pxdir; x0pxdir += xdir; } yy0++; /* y-major so always advance Y */ /* the AAbits most significant bits of erracc give us the intensity weighting for this pixel, and the complement of the weighting for the paired pixel. */ wgt = (erracc >> intshift) & 255; a = Uint8(255-wgt); if(alpha != 255) a = Uint8(a*alpha_pp); _PutPixelAlpha(dst,xx0,yy0,SDL_MapRGB(dst->format, Uint8(R>>16), Uint8(G>>16), Uint8(B>>16)),a); a = Uint8(wgt); if(alpha != 255) a = Uint8(a*alpha_pp); _PutPixelAlpha(dst,x0pxdir,yy0,SDL_MapRGB(dst->format, Uint8(R>>16), Uint8(G>>16), Uint8(B>>16)),a); } } else { /* x-major line. Calculate 16-bit fixed-point fractional part of a pixel that Y advances each time X advances 1 pixel, truncating the result so that we won't overrun the endpoint along the X axis. */ erradj = ((dy << 16) / dx)<<16; rstep = Sint32((r2-r1)<<16) / Sint32(dx); gstep = Sint32((g2-g1)<<16) / Sint32(dx); bstep = Sint32((b2-b1)<<16) / Sint32(dx); /* draw all pixels other than the first and last */ y0p1=yy0+1; while (--dx) { R += rstep; G += gstep; B += bstep; erracctmp = erracc; erracc += erradj; if (erracc <= erracctmp) { /* Accumulator turned over, advance y */ yy0=y0p1; y0p1++; } xx0 += xdir; /* x-major so always advance X */ /* the AAbits most significant bits of erracc give us the intensity weighting for this pixel, and the complement of the weighting for the paired pixel. */ wgt = (erracc >> intshift) & 255; a = Uint8(255-wgt); if(alpha != 255) a = Uint8(a*alpha_pp); _PutPixelAlpha(dst,xx0,yy0,SDL_MapRGB(dst->format, Uint8(R>>16), Uint8(G>>16), Uint8(B>>16)),a); a = Uint8(wgt); if(alpha != 255) a = Uint8(a*alpha_pp); _PutPixelAlpha(dst,xx0,y0p1,SDL_MapRGB(dst->format, Uint8(R>>16), Uint8(G>>16), Uint8(B>>16)),a); } } /* Draw final pixel, always exactly intersected by the line and doesn't need to be weighted. */ if(alpha==255) _PutPixel(dst,x2,y2, SDL_MapRGB(dst->format,r2, g2, b2)); else _PutPixelAlpha(dst,x2,y2, SDL_MapRGB(dst->format,r2, g2, b2), alpha); } 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) { if ( SDL_MUSTLOCK(dst) && _sge_lock ) if ( SDL_LockSurface(dst) < 0 ) return; _AAmcLineAlpha(dst, x1, y1, x2, y2, r1, g1, b1, r2, g2, b2, alpha); if (SDL_MUSTLOCK(dst) && _sge_lock) SDL_UnlockSurface(dst); 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)); } 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) { sge_AAmcLineAlpha(Surface, x1,y1, x2,y2, r1,g1,b1, r2,g2,b2, SDL_ALPHA_OPAQUE); } /**********************************************************************************/ /** Figure functions **/ /**********************************************************************************/ //================================================================================== // Draws a rectangle //================================================================================== void sge_Rect(SDL_Surface *Surface, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint32 color) { _HLine(Surface,x1,x2,y1,color); _HLine(Surface,x1,x2,y2,color); _VLine(Surface,x1,y1,y2,color); _VLine(Surface,x2,y1,y2,color); sge_UpdateRect(Surface, x1, y1, x2-x1, 1); sge_UpdateRect(Surface, x1, y2, x2-x1+1, 1); /* Hmm? */ sge_UpdateRect(Surface, x1, y1, 1, y2-y1); sge_UpdateRect(Surface, x2, y1, 1, y2-y1); } //================================================================================== // Draws a rectangle (RGB) //================================================================================== void sge_Rect(SDL_Surface *Surface, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint8 R, Uint8 G, Uint8 B) { sge_Rect(Surface,x1,y1,x2,y2, SDL_MapRGB(Surface->format, R, G, B)); } //================================================================================== // Draws a rectangle (alpha) //================================================================================== void sge_RectAlpha(SDL_Surface *Surface, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint32 color, Uint8 alpha) { if (SDL_MUSTLOCK(Surface) && _sge_lock) if (SDL_LockSurface(Surface) < 0) return; _HLineAlpha(Surface,x1,x2,y1,color,alpha); _HLineAlpha(Surface,x1,x2,y2,color,alpha); _VLineAlpha(Surface,x1,y1,y2,color,alpha); _VLineAlpha(Surface,x2,y1,y2,color,alpha); if (SDL_MUSTLOCK(Surface) && _sge_lock) { SDL_UnlockSurface(Surface); } sge_UpdateRect(Surface, x1, y1, x2-x1, 1); sge_UpdateRect(Surface, x1, y2, x2-x1+1, 1); /* Hmm? */ sge_UpdateRect(Surface, x1, y1, 1, y2-y1); sge_UpdateRect(Surface, x2, y1, 1, y2-y1); } //================================================================================== // Draws a rectangle (RGB) //================================================================================== void sge_RectAlpha(SDL_Surface *Surface, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint8 R, Uint8 G, Uint8 B, Uint8 alpha) { sge_RectAlpha(Surface,x1,y1,x2,y2, SDL_MapRGB(Surface->format, R, G, B), alpha); } //================================================================================== // Draws a filled rectangle //================================================================================== void sge_FilledRect(SDL_Surface *Surface, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint32 color) { Sint16 tmp; if(x1>x2){ tmp=x1; x1=x2; x2=tmp; } if(y1>y2){ tmp=y1; y1=y2; y2=tmp; } #if SDL_VERSIONNUM(SDL_MAJOR_VERSION, SDL_MINOR_VERSION, SDL_PATCHLEVEL) < \ SDL_VERSIONNUM(1, 1, 5) if(x2clip_minx || x1>Surface->clip_maxx || y2clip_miny || y1>Surface->clip_maxy) return; if (x1 < Surface->clip_minx) x1=Surface->clip_minx; if (x2 > Surface->clip_maxx) x2=Surface->clip_maxx; if (y1 < Surface->clip_miny) y1=Surface->clip_miny; if (y2 > Surface->clip_maxy) y2=Surface->clip_maxy; #endif SDL_Rect area; area.x=x1; area.y=y1; area.w=x2-x1+1; area.h=y2-y1+1; SDL_FillRect(Surface,&area,color); sge_UpdateRect(Surface, x1, y1, x2-x1+1, y2-y1+1); } //================================================================================== // Draws a filled rectangle (RGB) //================================================================================== void sge_FilledRect(SDL_Surface *Surface, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint8 R, Uint8 G, Uint8 B) { sge_FilledRect(Surface,x1,y1,x2,y2, SDL_MapRGB(Surface->format, R, G, B)); } //================================================================================== // Draws a filled rectangle (alpha) //================================================================================== void sge_FilledRectAlpha(SDL_Surface *surface, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint32 color, Uint8 alpha) { /*if( alpha == 255 ){ sge_FilledRect(surface,x1,y1,x2,y2,color); return; }*/ /* Fix coords */ Sint16 tmp; if(x1>x2){ tmp=x1; x1=x2; x2=tmp; } if(y1>y2){ tmp=y1; y1=y2; y2=tmp; } /* Clipping */ if(x2sge_clip_xmax(surface) || y2sge_clip_ymax(surface)) return; if (x1 < sge_clip_xmin(surface)) x1 = sge_clip_xmin(surface); if (x2 > sge_clip_xmax(surface)) x2 = sge_clip_xmax(surface); if (y1 < sge_clip_ymin(surface)) y1 = sge_clip_ymin(surface); if (y2 > sge_clip_ymax(surface)) y2 = sge_clip_ymax(surface); Uint32 Rmask = surface->format->Rmask, Gmask = surface->format->Gmask, Bmask = surface->format->Bmask, Amask = surface->format->Amask; Uint32 R,G,B,A=0; Sint16 x,y; if (SDL_MUSTLOCK(surface) && _sge_lock) if (SDL_LockSurface(surface) < 0) return; switch (surface->format->BytesPerPixel) { case 1: { /* Assuming 8-bpp */ Uint8 *row, *pixel; Uint8 dR, dG, dB; Uint8 sR = surface->format->palette->colors[color].r; Uint8 sG = surface->format->palette->colors[color].g; Uint8 sB = surface->format->palette->colors[color].b; for(y = y1; y<=y2; y++){ row = (Uint8 *)surface->pixels + y*surface->pitch; for(x = x1; x <= x2; x++){ pixel = row + x; dR = surface->format->palette->colors[*pixel].r; dG = surface->format->palette->colors[*pixel].g; dB = surface->format->palette->colors[*pixel].b; dR = dR + ((sR-dR)*alpha >> 8); dG = dG + ((sG-dG)*alpha >> 8); dB = dB + ((sB-dB)*alpha >> 8); *pixel = SDL_MapRGB(surface->format, dR, dG, dB); } } } break; case 2: { /* Probably 15-bpp or 16-bpp */ Uint16 *row, *pixel; Uint32 dR=(color & Rmask),dG=(color & Gmask),dB=(color & Bmask),dA=(color & Amask); for(y = y1; y<=y2; y++){ row = (Uint16 *)surface->pixels + y*surface->pitch/2; for(x = x1; x <= x2; x++){ pixel = row + x; R = ((*pixel & Rmask) + (( dR - (*pixel & Rmask) ) * alpha >> 8)) & Rmask; G = ((*pixel & Gmask) + (( dG - (*pixel & Gmask) ) * alpha >> 8)) & Gmask; B = ((*pixel & Bmask) + (( dB - (*pixel & Bmask) ) * alpha >> 8)) & Bmask; if( Amask ) A = ((*pixel & Amask) + (( dA - (*pixel & Amask) ) * alpha >> 8)) & Amask; *pixel= R | G | B | A; } } } break; case 3: { /* Slow 24-bpp mode, usually not used */ Uint8 *row,*pix; Uint8 dR, dG, dB, dA; Uint8 rshift8=surface->format->Rshift/8; Uint8 gshift8=surface->format->Gshift/8; Uint8 bshift8=surface->format->Bshift/8; Uint8 ashift8=surface->format->Ashift/8; Uint8 sR = (color>>surface->format->Rshift)&0xff; Uint8 sG = (color>>surface->format->Gshift)&0xff; Uint8 sB = (color>>surface->format->Bshift)&0xff; Uint8 sA = (color>>surface->format->Ashift)&0xff; for(y = y1; y<=y2; y++){ row = (Uint8 *)surface->pixels + y * surface->pitch; for(x = x1; x <= x2; x++){ pix = row + x*3; dR = *((pix)+rshift8); dG = *((pix)+gshift8); dB = *((pix)+bshift8); dA = *((pix)+ashift8); dR = dR + ((sR-dR)*alpha >> 8); dG = dG + ((sG-dG)*alpha >> 8); dB = dB + ((sB-dB)*alpha >> 8); dA = dA + ((sA-dA)*alpha >> 8); *((pix)+rshift8) = dR; *((pix)+gshift8) = dG; *((pix)+bshift8) = dB; *((pix)+ashift8) = dA; } } } break; case 4: { /* Probably 32-bpp */ Uint32 *row, *pixel; Uint32 dR=(color & Rmask),dG=(color & Gmask),dB=(color & Bmask),dA=(color & Amask); for(y = y1; y<=y2; y++){ row = (Uint32 *)surface->pixels + y*surface->pitch/4; for(x = x1; x <= x2; x++){ pixel = row + x; R = ((*pixel & Rmask) + (( dR - (*pixel & Rmask) ) * alpha >> 8)) & Rmask; G = ((*pixel & Gmask) + (( dG - (*pixel & Gmask) ) * alpha >> 8)) & Gmask; B = ((*pixel & Bmask) + (( dB - (*pixel & Bmask) ) * alpha >> 8)) & Bmask; if( Amask ) A = ((*pixel & Amask) + (( dA - (*pixel & Amask) ) * alpha >> 8)) & Amask; *pixel= R | G | B | A; } } } break; } if (SDL_MUSTLOCK(surface) && _sge_lock) { SDL_UnlockSurface(surface); } sge_UpdateRect(surface, x1, y1, x2-x1+1, y2-y1+1); } void sge_FilledRectAlpha(SDL_Surface *Surface, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint8 R, Uint8 G, Uint8 B, Uint8 alpha) { sge_FilledRectAlpha(Surface,x1,y1,x2,y2, SDL_MapRGB(Surface->format, R, G, B), alpha); } //================================================================================== // Performs Callback at each ellipse point. // (from Allegro) //================================================================================== 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) ) { int ix, iy; int h, i, j, k; int oh, oi, oj, ok; if (rx < 1) rx = 1; if (ry < 1) ry = 1; h = i = j = k = 0xFFFF; if (rx > ry) { ix = 0; iy = rx * 64; do { oh = h; oi = i; oj = j; ok = k; h = (ix + 32) >> 6; i = (iy + 32) >> 6; j = (h * ry) / rx; k = (i * ry) / rx; if (((h != oh) || (k != ok)) && (h < oi)) { Callback(Surface, x+h, y+k, color); if (h) Callback(Surface, x-h, y+k, color); if (k) { Callback(Surface, x+h, y-k, color); if (h) Callback(Surface, x-h, y-k, color); } } if (((i != oi) || (j != oj)) && (h < i)) { Callback(Surface, x+i, y+j, color); if (i) Callback(Surface, x-i, y+j, color); if (j) { Callback(Surface, x+i, y-j, color); if (i) Callback(Surface, x-i, y-j, color); } } ix = ix + iy / rx; iy = iy - ix / rx; } while (i > h); } else { ix = 0; iy = ry * 64; do { oh = h; oi = i; oj = j; ok = k; h = (ix + 32) >> 6; i = (iy + 32) >> 6; j = (h * rx) / ry; k = (i * rx) / ry; if (((j != oj) || (i != oi)) && (h < i)) { Callback(Surface, x+j, y+i, color); if (j) Callback(Surface, x-j, y+i, color); if (i) { Callback(Surface, x+j, y-i, color); if (j) Callback(Surface, x-j, y-i, color); } } if (((k != ok) || (h != oh)) && (h < oi)) { Callback(Surface, x+k, y+h, color); if (k) Callback(Surface, x-k, y+h, color); if (h) { Callback(Surface, x+k, y-h, color); if (k) Callback(Surface, x-k, y-h, color); } } ix = ix + iy / ry; iy = iy - ix / ry; } while(i > h); } } //================================================================================== // Performs Callback at each ellipse point. (RGB) //================================================================================== 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) ) { sge_DoEllipse(Surface,x,y,rx,ry,SDL_MapRGB(Surface->format, R, G, B),Callback); } //================================================================================== // Draws an ellipse //================================================================================== void sge_Ellipse(SDL_Surface *Surface, Sint16 x, Sint16 y, Sint16 rx, Sint16 ry, Uint32 color) { if (SDL_MUSTLOCK(Surface) && _sge_lock) { if (SDL_LockSurface(Surface) < 0) return; } sge_DoEllipse(Surface, x, y, rx, ry, color, _PutPixel); if (SDL_MUSTLOCK(Surface) && _sge_lock) { SDL_UnlockSurface(Surface); } sge_UpdateRect(Surface, x-rx, y-ry, 2*rx+1, 2*ry+1); } //================================================================================== // Draws an ellipse (RGB) //================================================================================== void sge_Ellipse(SDL_Surface *Surface, Sint16 x, Sint16 y, Sint16 rx, Sint16 ry, Uint8 R, Uint8 G, Uint8 B) { sge_Ellipse(Surface,x,y,rx,ry,SDL_MapRGB(Surface->format, R, G, B)); } //================================================================================== // Draws an ellipse (alpha) //================================================================================== void sge_EllipseAlpha(SDL_Surface *Surface, Sint16 x, Sint16 y, Sint16 rx, Sint16 ry, Uint32 color, Uint8 alpha) { if (SDL_MUSTLOCK(Surface) && _sge_lock) if (SDL_LockSurface(Surface) < 0) return; _sge_alpha_hack = alpha; sge_DoEllipse(Surface, x, y, rx, ry, color, callback_alpha_hack); if (SDL_MUSTLOCK(Surface) && _sge_lock) { SDL_UnlockSurface(Surface); } sge_UpdateRect(Surface, x-rx, y-ry, 2*rx+1, 2*ry+1); } //================================================================================== // Draws an ellipse (alpha - RGB) //================================================================================== void sge_EllipseAlpha(SDL_Surface *Surface, Sint16 x, Sint16 y, Sint16 rx, Sint16 ry, Uint8 R, Uint8 G, Uint8 B, Uint8 alpha) { sge_EllipseAlpha(Surface,x,y,rx,ry,SDL_MapRGB(Surface->format, R, G, B),alpha); } //================================================================================== // Draws a filled ellipse //================================================================================== void sge_FilledEllipse(SDL_Surface *Surface, Sint16 x, Sint16 y, Sint16 rx, Sint16 ry, Uint32 color) { int ix, iy; int h, i, j, k; int oh, oi, oj, ok; if (rx < 1) rx = 1; if (ry < 1) ry = 1; oh = oi = oj = ok = 0xFFFF; if (rx > ry) { ix = 0; iy = rx * 64; do { h = (ix + 32) >> 6; i = (iy + 32) >> 6; j = (h * ry) / rx; k = (i * ry) / rx; if ((k!=ok) && (k!=oj)) { if (k){ _HLine(Surface,x-h,x+h,y-k,color); _HLine(Surface,x-h,x+h,y+k,color); }else _HLine(Surface,x-h,x+h,y,color); ok=k; } if ((j!=oj) && (j!=ok) && (k!=j)) { if (j){ _HLine(Surface,x-i,x+i,y-j,color); _HLine(Surface,x-i,x+i,y+j,color); }else _HLine(Surface,x-i,x+i,y,color); oj=j; } ix = ix + iy / rx; iy = iy - ix / rx; } while (i > h); } else { ix = 0; iy = ry * 64; do { h = (ix + 32) >> 6; i = (iy + 32) >> 6; j = (h * rx) / ry; k = (i * rx) / ry; if ((i!=oi) && (i!=oh)) { if (i){ _HLine(Surface,x-j,x+j,y-i,color); _HLine(Surface,x-j,x+j,y+i,color); }else _HLine(Surface,x-j,x+j,y,color); oi=i; } if ((h!=oh) && (h!=oi) && (i!=h)) { if (h){ _HLine(Surface,x-k,x+k,y-h,color); _HLine(Surface,x-k,x+k,y+h,color); }else _HLine(Surface,x-k,x+k,y,color); oh=h; } ix = ix + iy / ry; iy = iy - ix / ry; } while(i > h); } sge_UpdateRect(Surface, x-rx, y-ry, 2*rx+1, 2*ry+1); } //================================================================================== // Draws a filled ellipse (RGB) //================================================================================== void sge_FilledEllipse(SDL_Surface *Surface, Sint16 x, Sint16 y, Sint16 rx, Sint16 ry, Uint8 R, Uint8 G, Uint8 B) { sge_FilledEllipse(Surface,x,y,rx,ry,SDL_MapRGB(Surface->format, R, G, B)); } //================================================================================== // Draws a filled ellipse (alpha) //================================================================================== void sge_FilledEllipseAlpha(SDL_Surface *Surface, Sint16 x, Sint16 y, Sint16 rx, Sint16 ry, Uint32 color, Uint8 alpha) { int ix, iy; int h, i, j, k; int oh, oi, oj, ok; if (SDL_MUSTLOCK(Surface) && _sge_lock) if (SDL_LockSurface(Surface) < 0) return; if (rx < 1) rx = 1; if (ry < 1) ry = 1; oh = oi = oj = ok = 0xFFFF; if (rx > ry) { ix = 0; iy = rx * 64; do { h = (ix + 32) >> 6; i = (iy + 32) >> 6; j = (h * ry) / rx; k = (i * ry) / rx; if ((k!=ok) && (k!=oj)) { if (k){ _HLineAlpha(Surface,x-h,x+h,y-k,color,alpha); _HLineAlpha(Surface,x-h,x+h,y+k,color,alpha); }else _HLineAlpha(Surface,x-h,x+h,y,color,alpha); ok=k; } if ((j!=oj) && (j!=ok) && (k!=j)) { if (j){ _HLineAlpha(Surface,x-i,x+i,y-j,color,alpha); _HLineAlpha(Surface,x-i,x+i,y+j,color,alpha); }else _HLineAlpha(Surface,x-i,x+i,y,color,alpha); oj=j; } ix = ix + iy / rx; iy = iy - ix / rx; } while (i > h); } else { ix = 0; iy = ry * 64; do { h = (ix + 32) >> 6; i = (iy + 32) >> 6; j = (h * rx) / ry; k = (i * rx) / ry; if ((i!=oi) && (i!=oh)) { if (i){ _HLineAlpha(Surface,x-j,x+j,y-i,color,alpha); _HLineAlpha(Surface,x-j,x+j,y+i,color,alpha); }else _HLineAlpha(Surface,x-j,x+j,y,color,alpha); oi=i; } if ((h!=oh) && (h!=oi) && (i!=h)) { if (h){ _HLineAlpha(Surface,x-k,x+k,y-h,color,alpha); _HLineAlpha(Surface,x-k,x+k,y+h,color,alpha); }else _HLineAlpha(Surface,x-k,x+k,y,color,alpha); oh=h; } ix = ix + iy / ry; iy = iy - ix / ry; } while(i > h); } if (SDL_MUSTLOCK(Surface) && _sge_lock) { SDL_UnlockSurface(Surface); } sge_UpdateRect(Surface, x-rx, y-ry, 2*rx+1, 2*ry+1); } //================================================================================== // Draws a filled ellipse (alpha - RGB) //================================================================================== void sge_FilledEllipseAlpha(SDL_Surface *Surface, Sint16 x, Sint16 y, Sint16 rx, Sint16 ry, Uint8 R, Uint8 G, Uint8 B, Uint8 alpha) { sge_FilledEllipseAlpha(Surface,x,y,rx,ry,SDL_MapRGB(Surface->format, R, G, B),alpha); } //================================================================================== // Draws an anti-aliased ellipse (alpha) // Some of this code is taken from "TwinLib" (http://www.twinlib.org) written by // Nicolas Roard (nicolas@roard.com) //================================================================================== void sge_AAEllipseAlpha(SDL_Surface *surface, Sint16 xc, Sint16 yc, Sint16 rx, Sint16 ry, Uint32 color, Uint8 alpha) { /* Sanity check */ if (rx < 1) rx = 1; if (ry < 1) ry = 1; int a2 = rx * rx; int b2 = ry * ry; int ds = 2 * a2; int dt = 2 * b2; int dxt = int (a2 / sqrt(a2 + b2)); int t = 0; int s = -2 * a2 * ry; int d = 0; Sint16 x = xc; Sint16 y = yc - ry; Sint16 xs, ys, dyt; float cp, is, ip, imax = 1.0; Uint8 s_alpha, p_alpha; float alpha_pp = float(alpha)/255; /* Lock surface */ if ( SDL_MUSTLOCK(surface) && _sge_lock ) if ( SDL_LockSurface(surface) < 0 ) return; /* "End points" */ _PutPixelAlpha(surface, x, y, color, alpha); _PutPixelAlpha(surface, 2*xc-x, y, color, alpha); _PutPixelAlpha(surface, x, 2*yc-y, color, alpha); _PutPixelAlpha(surface, 2*xc-x, 2*yc-y, color, alpha); int i; for (i = 1; i <= dxt; i++) { x--; d += t - b2; if (d >= 0) ys = y - 1; else if ((d - s - a2) > 0) { if ((2 * d - s - a2) >= 0) ys = y + 1; else { ys = y; y++; d -= s + a2; s += ds; } } else { y++; ys = y + 1; d -= s + a2; s += ds; } t -= dt; /* Calculate alpha */ cp = float(abs(d)) / abs(s); is = float( cp * imax + 0.1 ); ip = float( imax - is + 0.2 ); /* Overflow check */ if( is > 1.0 ) is = 1.0; if( ip > 1.0 ) ip = 1.0; /* Calculate alpha level */ s_alpha = Uint8(is*255); p_alpha = Uint8(ip*255); if( alpha != 255 ){ s_alpha = Uint8(s_alpha*alpha_pp); p_alpha = Uint8(p_alpha*alpha_pp); } /* Upper half */ _PutPixelAlpha(surface, x, y, color, p_alpha); _PutPixelAlpha(surface, 2*xc-x, y, color, p_alpha); _PutPixelAlpha(surface, x, ys, color, s_alpha); _PutPixelAlpha(surface, 2*xc-x, ys, color, s_alpha); /* Lower half */ _PutPixelAlpha(surface, x, 2*yc-y, color, p_alpha); _PutPixelAlpha(surface, 2*xc-x, 2*yc-y, color, p_alpha); _PutPixelAlpha(surface, x, 2*yc-ys, color, s_alpha); _PutPixelAlpha(surface, 2*xc-x, 2*yc-ys, color, s_alpha); } dyt = abs(y - yc); for (i = 1; i <= dyt; i++) { y++; d -= s + a2; if (d <= 0) xs = x + 1; else if ((d + t - b2) < 0) { if ((2 * d + t - b2) <= 0) xs = x - 1; else { xs = x; x--; d += t - b2; t -= dt; } } else { x--; xs = x - 1; d += t - b2; t -= dt; } s += ds; /* Calculate alpha */ cp = float(abs(d)) / abs(t); is = float( cp * imax + 0.1 ); ip = float( imax - is + 0.2 ); /* Overflow check */ if( is > 1.0 ) is = 1.0; if( ip > 1.0 ) ip = 1.0; /* Calculate alpha level */ s_alpha = Uint8(is*255); p_alpha = Uint8(ip*255); if( alpha != 255 ){ s_alpha = Uint8(s_alpha*alpha_pp); p_alpha = Uint8(p_alpha*alpha_pp); } /* Upper half */ _PutPixelAlpha(surface, x, y, color, p_alpha); _PutPixelAlpha(surface, 2*xc-x, y, color, p_alpha); _PutPixelAlpha(surface, xs, y, color, s_alpha); _PutPixelAlpha(surface, 2*xc-xs, y, color, s_alpha); /* Lower half*/ _PutPixelAlpha(surface, x, 2*yc-y, color, p_alpha); _PutPixelAlpha(surface, 2*xc-x, 2*yc-y, color, p_alpha); _PutPixelAlpha(surface, xs, 2*yc-y, color, s_alpha); _PutPixelAlpha(surface, 2*xc-xs, 2*yc-y, color, s_alpha); } /* unlock surface */ if (SDL_MUSTLOCK(surface) && _sge_lock) { SDL_UnlockSurface(surface); } /* Update surface if needed */ sge_UpdateRect(surface, xc-rx, yc-ry, 2*rx+1, 2*ry+1); } //================================================================================== // Draws an anti-aliased ellipse (alpha - RGB) //================================================================================== void sge_AAEllipseAlpha(SDL_Surface *surface, Sint16 xc, Sint16 yc, Sint16 rx, Sint16 ry, Uint8 R, Uint8 G, Uint8 B, Uint8 alpha) { sge_AAEllipseAlpha(surface,xc,yc,rx,ry,SDL_MapRGB(surface->format, R, G, B),alpha); } //================================================================================== // Draws an anti-aliased ellipse //================================================================================== void sge_AAEllipse(SDL_Surface *surface, Sint16 xc, Sint16 yc, Sint16 rx, Sint16 ry, Uint32 color) { sge_AAEllipseAlpha(surface,xc,yc,rx,ry,color,255); } //================================================================================== // Draws an anti-aliased ellipse (RGB) //================================================================================== void sge_AAEllipse(SDL_Surface *surface, Sint16 xc, Sint16 yc, Sint16 rx, Sint16 ry, Uint8 R, Uint8 G, Uint8 B) { sge_AAEllipseAlpha(surface,xc,yc,rx,ry,SDL_MapRGB(surface->format, R, G, B),255); } //================================================================================== // Draws a filled anti-aliased ellipse // This is just a quick hack... //================================================================================== void sge_AAFilledEllipse(SDL_Surface *surface, Sint16 xc, Sint16 yc, Sint16 rx, Sint16 ry, Uint32 color) { /* Sanity check */ if (rx < 1) rx = 1; if (ry < 1) ry = 1; int a2 = rx * rx; int b2 = ry * ry; int ds = 2 * a2; int dt = 2 * b2; int dxt = int (a2 / sqrt(a2 + b2)); int t = 0; int s = -2 * a2 * ry; int d = 0; Sint16 x = xc; Sint16 y = yc - ry; Sint16 xs, ys, dyt; float cp, is, ip, imax = 1.0; /* Lock surface */ if ( SDL_MUSTLOCK(surface) && _sge_lock ) if ( SDL_LockSurface(surface) < 0 ) return; /* "End points" */ _PutPixel(surface, x, y, color); _PutPixel(surface, 2*xc-x, y, color); _PutPixel(surface, x, 2*yc-y, color); _PutPixel(surface, 2*xc-x, 2*yc-y, color); /* unlock surface */ if (SDL_MUSTLOCK(surface) && _sge_lock) SDL_UnlockSurface(surface); _VLine(surface, x, y+1, 2*yc-y-1, color); int i; for (i = 1; i <= dxt; i++) { x--; d += t - b2; if (d >= 0) ys = y - 1; else if ((d - s - a2) > 0) { if ((2 * d - s - a2) >= 0) ys = y + 1; else { ys = y; y++; d -= s + a2; s += ds; } } else { y++; ys = y + 1; d -= s + a2; s += ds; } t -= dt; /* Calculate alpha */ cp = (float) abs(d) / abs(s); is = cp * imax; ip = imax - is; /* Lock surface */ if ( SDL_MUSTLOCK(surface) && _sge_lock ) if ( SDL_LockSurface(surface) < 0 ) return; /* Upper half */ _PutPixelAlpha(surface, x, y, color, Uint8(ip*255)); _PutPixelAlpha(surface, 2*xc-x, y, color, Uint8(ip*255)); _PutPixelAlpha(surface, x, ys, color, Uint8(is*255)); _PutPixelAlpha(surface, 2*xc-x, ys, color, Uint8(is*255)); /* Lower half */ _PutPixelAlpha(surface, x, 2*yc-y, color, Uint8(ip*255)); _PutPixelAlpha(surface, 2*xc-x, 2*yc-y, color, Uint8(ip*255)); _PutPixelAlpha(surface, x, 2*yc-ys, color, Uint8(is*255)); _PutPixelAlpha(surface, 2*xc-x, 2*yc-ys, color, Uint8(is*255)); /* unlock surface */ if (SDL_MUSTLOCK(surface) && _sge_lock) SDL_UnlockSurface(surface); /* Fill */ _VLine(surface, x, y+1, 2*yc-y-1, color); _VLine(surface, 2*xc-x, y+1, 2*yc-y-1, color); _VLine(surface, x, ys+1, 2*yc-ys-1, color); _VLine(surface, 2*xc-x, ys+1, 2*yc-ys-1, color); } dyt = abs(y - yc); for (i = 1; i <= dyt; i++) { y++; d -= s + a2; if (d <= 0) xs = x + 1; else if ((d + t - b2) < 0) { if ((2 * d + t - b2) <= 0) xs = x - 1; else { xs = x; x--; d += t - b2; t -= dt; } } else { x--; xs = x - 1; d += t - b2; t -= dt; } s += ds; /* Calculate alpha */ cp = (float) abs(d) / abs(t); is = cp * imax; ip = imax - is; /* Lock surface */ if ( SDL_MUSTLOCK(surface) && _sge_lock ) if ( SDL_LockSurface(surface) < 0 ) return; /* Upper half */ _PutPixelAlpha(surface, x, y, color, Uint8(ip*255)); _PutPixelAlpha(surface, 2*xc-x, y, color, Uint8(ip*255)); _PutPixelAlpha(surface, xs, y, color, Uint8(is*255)); _PutPixelAlpha(surface, 2*xc-xs, y, color, Uint8(is*255)); /* Lower half*/ _PutPixelAlpha(surface, x, 2*yc-y, color, Uint8(ip*255)); _PutPixelAlpha(surface, 2*xc-x, 2*yc-y, color, Uint8(ip*255)); _PutPixelAlpha(surface, xs, 2*yc-y, color, Uint8(is*255)); _PutPixelAlpha(surface, 2*xc-xs, 2*yc-y, color, Uint8(is*255)); /* unlock surface */ if (SDL_MUSTLOCK(surface) && _sge_lock) SDL_UnlockSurface(surface); /* Fill */ _HLine(surface, x+1, 2*xc-x-1, y, color); _HLine(surface, xs+1, 2*xc-xs-1, y, color); _HLine(surface, x+1, 2*xc-x-1, 2*yc-y, color); _HLine(surface, xs+1, 2*xc-xs-1, 2*yc-y, color); } /* Update surface if needed */ sge_UpdateRect(surface, xc-rx, yc-ry, 2*rx+1, 2*ry+1); } //================================================================================== // Draws a filled anti-aliased ellipse (RGB) //================================================================================== void sge_AAFilledEllipse(SDL_Surface *surface, Sint16 xc, Sint16 yc, Sint16 rx, Sint16 ry, Uint8 R, Uint8 G, Uint8 B) { sge_AAFilledEllipse(surface,xc,yc,rx,ry,SDL_MapRGB(surface->format, R, G, B)); } //================================================================================== // Performs Callback at each circle point. //================================================================================== 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)) { Sint16 cx = 0; Sint16 cy = r; Sint16 df = 1 - r; Sint16 d_e = 3; Sint16 d_se = -2 * r + 5; do { Callback(Surface, x+cx, y+cy, color); Callback(Surface, x-cx, y+cy, color); Callback(Surface, x+cx, y-cy, color); Callback(Surface, x-cx, y-cy, color); Callback(Surface, x+cy, y+cx, color); Callback(Surface, x+cy, y-cx, color); Callback(Surface, x-cy, y+cx, color); Callback(Surface, x-cy, y-cx, color); if (df < 0) { df += d_e; d_e += 2; d_se += 2; } else { df += d_se; d_e += 2; d_se += 4; cy--; } cx++; }while(cx <= cy); } //================================================================================== // Performs Callback at each circle point. (RGB) //================================================================================== 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)) { sge_DoCircle(Surface,x,y,r,SDL_MapRGB(Surface->format, R, G, B),Callback); } //================================================================================== // Draws a circle //================================================================================== void sge_Circle(SDL_Surface *Surface, Sint16 x, Sint16 y, Sint16 r, Uint32 color) { if (SDL_MUSTLOCK(Surface) && _sge_lock) { if (SDL_LockSurface(Surface) < 0) return; } sge_DoCircle(Surface, x, y, r, color, _PutPixel); if (SDL_MUSTLOCK(Surface) && _sge_lock) { SDL_UnlockSurface(Surface); } sge_UpdateRect(Surface, x-r, y-r, 2*r+1, 2*r+1); } //================================================================================== // Draws a circle (RGB) //================================================================================== void sge_Circle(SDL_Surface *Surface, Sint16 x, Sint16 y, Sint16 r, Uint8 R, Uint8 G, Uint8 B) { sge_Circle(Surface,x,y,r,SDL_MapRGB(Surface->format, R, G, B)); } //================================================================================== // Draws a circle (alpha) //================================================================================== void sge_CircleAlpha(SDL_Surface *Surface, Sint16 x, Sint16 y, Sint16 r, Uint32 color, Uint8 alpha) { if (SDL_MUSTLOCK(Surface) && _sge_lock) if (SDL_LockSurface(Surface) < 0) return; _sge_alpha_hack = alpha; sge_DoCircle(Surface, x, y, r, color, callback_alpha_hack); if (SDL_MUSTLOCK(Surface) && _sge_lock) { SDL_UnlockSurface(Surface); } sge_UpdateRect(Surface, x-r, y-r, 2*r+1, 2*r+1); } //================================================================================== // Draws a circle (alpha - RGB) //================================================================================== void sge_CircleAlpha(SDL_Surface *Surface, Sint16 x, Sint16 y, Sint16 r, Uint8 R, Uint8 G, Uint8 B, Uint8 alpha) { sge_CircleAlpha(Surface,x,y,r,SDL_MapRGB(Surface->format, R, G, B),alpha); } //================================================================================== // Draws a filled circle //================================================================================== void sge_FilledCircle(SDL_Surface *Surface, Sint16 x, Sint16 y, Sint16 r, Uint32 color) { Sint16 cx = 0; Sint16 cy = r; bool draw=true; Sint16 df = 1 - r; Sint16 d_e = 3; Sint16 d_se = -2 * r + 5; do { if(draw){ _HLine(Surface,x-cx,x+cx,y+cy,color); _HLine(Surface,x-cx,x+cx,y-cy,color); draw=false; } if(cx!=cy){ if(cx){ _HLine(Surface,x-cy,x+cy,y-cx,color); _HLine(Surface,x-cy,x+cy,y+cx,color); }else _HLine(Surface,x-cy,x+cy,y,color); } if (df < 0) { df += d_e; d_e += 2; d_se += 2; } else { df += d_se; d_e += 2; d_se += 4; cy--; draw=true; } cx++; }while(cx <= cy); sge_UpdateRect(Surface, x-r, y-r, 2*r+1, 2*r+1); } //================================================================================== // Draws a filled circle (RGB) //================================================================================== void sge_FilledCircle(SDL_Surface *Surface, Sint16 x, Sint16 y, Sint16 r, Uint8 R, Uint8 G, Uint8 B) { sge_FilledCircle(Surface,x,y,r,SDL_MapRGB(Surface->format, R, G, B)); } //================================================================================== // Draws a filled circle (alpha) //================================================================================== void sge_FilledCircleAlpha(SDL_Surface *Surface, Sint16 x, Sint16 y, Sint16 r, Uint32 color, Uint8 alpha) { Sint16 cx = 0; Sint16 cy = r; bool draw=true; Sint16 df = 1 - r; Sint16 d_e = 3; Sint16 d_se = -2 * r + 5; if (SDL_MUSTLOCK(Surface) && _sge_lock) if (SDL_LockSurface(Surface) < 0) return; do { if(draw){ _HLineAlpha(Surface,x-cx,x+cx,y+cy,color,alpha); _HLineAlpha(Surface,x-cx,x+cx,y-cy,color,alpha); draw=false; } if(cx!=cy){ if(cx){ _HLineAlpha(Surface,x-cy,x+cy,y-cx,color,alpha); _HLineAlpha(Surface,x-cy,x+cy,y+cx,color,alpha); }else _HLineAlpha(Surface,x-cy,x+cy,y,color,alpha); } if (df < 0) { df += d_e; d_e += 2; d_se += 2; } else { df += d_se; d_e += 2; d_se += 4; cy--; draw=true; } cx++; }while(cx <= cy); if (SDL_MUSTLOCK(Surface) && _sge_lock) { SDL_UnlockSurface(Surface); } sge_UpdateRect(Surface, x-r, y-r, 2*r+1, 2*r+1); } //================================================================================== // Draws a filled circle (alpha - RGB) //================================================================================== void sge_FilledCircleAlpha(SDL_Surface *Surface, Sint16 x, Sint16 y, Sint16 r, Uint8 R, Uint8 G, Uint8 B, Uint8 alpha) { sge_FilledCircleAlpha(Surface,x,y,r,SDL_MapRGB(Surface->format, R, G, B),alpha); } //================================================================================== // Draws an anti-aliased circle (alpha) //================================================================================== void sge_AACircleAlpha(SDL_Surface *surface, Sint16 xc, Sint16 yc, Sint16 r, Uint32 color, Uint8 alpha) { sge_AAEllipseAlpha(surface, xc, yc, r, r, color, alpha); } //================================================================================== // Draws an anti-aliased circle (alpha - RGB) //================================================================================== void sge_AACircleAlpha(SDL_Surface *surface, Sint16 xc, Sint16 yc, Sint16 r, Uint8 R, Uint8 G, Uint8 B, Uint8 alpha) { sge_AAEllipseAlpha(surface,xc,yc,r,r,SDL_MapRGB(surface->format, R, G, B),alpha); } //================================================================================== // Draws an anti-aliased circle //================================================================================== void sge_AACircle(SDL_Surface *surface, Sint16 xc, Sint16 yc, Sint16 r, Uint32 color) { sge_AAEllipseAlpha(surface,xc,yc,r,r,color,255); } //================================================================================== // Draws an anti-aliased circle (RGB) //================================================================================== void sge_AACircle(SDL_Surface *surface, Sint16 xc, Sint16 yc, Sint16 r, Uint8 R, Uint8 G, Uint8 B) { sge_AAEllipseAlpha(surface,xc,yc,r,r,SDL_MapRGB(surface->format, R, G, B),255); } //================================================================================== // Draws a filled anti-aliased circle //================================================================================== void sge_AAFilledCircle(SDL_Surface *surface, Sint16 xc, Sint16 yc, Sint16 r, Uint32 color) { sge_AAFilledEllipse(surface, xc, yc, r, r, color); } //================================================================================== // Draws a filled anti-aliased circle (RGB) //================================================================================== void sge_AAFilledCircle(SDL_Surface *surface, Sint16 xc, Sint16 yc, Sint16 r, Uint8 R, Uint8 G, Uint8 B) { sge_AAFilledEllipse(surface,xc,yc,r,r,SDL_MapRGB(surface->format, R, G, B)); } //================================================================================== // Draws a bezier line //================================================================================== /* Macro to do the line... 'function' is the line drawing routine */ #define DO_BEZIER(function)\ /* * Note: I don't think there is any great performance win in translating this to fixed-point integer math, * most of the time is spent in the line drawing routine. */\ float x = float(x1), y = float(y1);\ float xp = x, yp = y;\ float delta;\ float dx, d2x, d3x;\ float dy, d2y, d3y;\ float a, b, c;\ int i;\ int n = 1;\ Sint16 xmax=x1, ymax=y1, xmin=x1, ymin=y1;\ \ /* compute number of iterations */\ if(level < 1)\ level=1;\ if(level >= 15)\ level=15; \ while (level-- > 0)\ n*= 2;\ delta = float( 1.0 / float(n) );\ \ /* compute finite differences */\ /* a, b, c are the coefficient of the polynom in t defining the parametric curve */\ /* The computation is done independently for x and y */\ a = float(-x1 + 3*x2 - 3*x3 + x4);\ b = float(3*x1 - 6*x2 + 3*x3);\ c = float(-3*x1 + 3*x2);\ \ d3x = 6 * a * delta*delta*delta;\ d2x = d3x + 2 * b * delta*delta;\ dx = a * delta*delta*delta + b * delta*delta + c * delta;\ \ a = float(-y1 + 3*y2 - 3*y3 + y4);\ b = float(3*y1 - 6*y2 + 3*y3);\ c = float(-3*y1 + 3*y2);\ \ d3y = 6 * a * delta*delta*delta;\ d2y = d3y + 2 * b * delta*delta;\ dy = a * delta*delta*delta + b * delta*delta + c * delta;\ \ if (SDL_MUSTLOCK(surface) && _sge_lock) {\ if (SDL_LockSurface(surface) < 0)\ return;\ }\ \ /* iterate */\ for (i = 0; i < n; i++) {\ x += dx; dx += d2x; d2x += d3x;\ y += dy; dy += d2y; d2y += d3y;\ if(Sint16(xp) != Sint16(x) || Sint16(yp) != Sint16(y)){\ function;\ if(_sge_update==1){\ xmax= (xmax>Sint16(xp))? xmax : Sint16(xp); ymax= (ymax>Sint16(yp))? ymax : Sint16(yp);\ xmin= (xminSint16(x))? xmax : Sint16(x); ymax= (ymax>Sint16(y))? ymax : Sint16(y);\ xmin= (xminformat,R,G,B)); } //================================================================================== // Draws a bezier line (alpha) //================================================================================== 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) { _sge_alpha_hack = alpha; DO_BEZIER(sge_DoLine(surface, Sint16(xp),Sint16(yp), Sint16(x),Sint16(y), color, callback_alpha_hack)); } //================================================================================== // Draws a bezier line (alpha - RGB) //================================================================================== 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) { sge_BezierAlpha(surface,x1,y1,x2,y2,x3,y3,x4,y4,level, SDL_MapRGB(surface->format,R,G,B),alpha); } //================================================================================== // Draws an AA bezier line (alpha) //================================================================================== 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) { Uint8 update = _sge_update; Uint8 lock = _sge_lock; _sge_update = 0; _sge_lock = 0; if (SDL_MUSTLOCK(surface) && lock) if (SDL_LockSurface(surface) < 0) return; DO_BEZIER(sge_AALineAlpha(surface, Sint16(xp),Sint16(yp), Sint16(x),Sint16(y), color, alpha)); if (SDL_MUSTLOCK(surface) && lock) { SDL_UnlockSurface(surface); } _sge_update = update; _sge_lock = lock; sge_UpdateRect(surface, xmin, ymin, xmax-xmin+1, ymax-ymin+1); } //================================================================================== // Draws an AA bezier line (alpha - RGB) //================================================================================== 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) { sge_AABezierAlpha(surface,x1,y1,x2,y2,x3,y3,x4,y4,level, SDL_MapRGB(surface->format,R,G,B),alpha); } //================================================================================== // Draws an AA bezier line //================================================================================== 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) { sge_AABezierAlpha(surface, x1,y1, x2,y2, x3,y3, x4,y4, level, color, 255); } //================================================================================== // Draws an AA bezier line (RGB) //================================================================================== 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) { sge_AABezierAlpha(surface,x1,y1,x2,y2,x3,y3,x4,y4,level, SDL_MapRGB(surface->format,R,G,B),255); } sge030809/WhatsNew0000644000175000001440000002162007715001414012502 0ustar samusersThis is a list of important changes in SGE's version history. 030809: -Better Makefiles (autodetects SDL, Freetype & SDL_Image). -Better library numbering (thanks Sam!). -Fixed a problem with newer version of g++ and c-linkage. -Better C support (thanks Ippei!). SGE is now configured to support C and C++ with the same library file (set C_COMP=n in Makefile.conf to disable). -Resynced the TTF code with SDL_ttf 2.0.6 (.fon and stream support). -Added filled and gourand shaded polygons. -Removed some harmless warning with MS Visual C++. -Added multicolored lines. -Cleaned up the text input functions (the return value has changed a bit). -Fixed some bitmap rendering bugs in sge_Text. -Some minor updates and bugfixes. 020904: -Corrected some errors in the documentation. -Fixed problems with Visual C++. -Fixed line clipping. -Resynced the TTF code with SDL_ttf 2.0.5, some functions added. -Fixed alpha levels with the TTF renderer (thanks Marco!). -Fixed small error in rotate clipping logic. 020104: -Added sge_FloodFill(), a fast non-recursive flood fill function. -Fixed a problem with the example 'speedtest' with gcc v3. -Some portability fixes. -Some small changes to the makefiles. -Added a "Beginners guide to SGE" to the documentation. -Added anti-aliased ellipses and circles. -Better alpha blending in AA lines. -Fixed a problem when AA rotating 32bit surfaces. 010629: -Many, many optimizations. -Split sge_draw into sge_surface and sge_primitives. -Fixed some bugs with hardware surfaces. -Fixed bugs with 24 bpp. -Added sge_PutPixelAlpha() - put pixel with blending. -Most drawing primitives now have an 'Alpha' version too. -Added anti-aliased lines (from SDL_gfxPrimitives). -Added anti-aliased bezier curves. -Added anti-aliased triangles. -Texture mapped rotation/scaling is back! It's a bit faster than normal rotation but not as nice and it can't do interpolation. Use the flag 'SGE_TTMAP' to select this renderer with sge_transform(). -A new example is included: 'speedtest', benchmarks most of SGEs primitives. Inspired by the example from SDL_gfxPrimitives. -Synced the TTF code with SDL_ttf 2.0.3; SGE now uses FreeType 2! Changed the makefile to use the new freetype-config tool. Note that FreeType2 can load more font formats than just truetype. 010606: -Small fix in sge_draw.h. -Fixed sge_Lock_ON(). Added sge_getUpdate() & sge_getLock() to get the current mode. -Fixed a signed-cast in sge_tt_text.cpp. -New rotation/scaling engine! Much faster and can do interpolated rendering. Use sge_transform()/sge_transform_surface() to access the new features. See documentation for more info. 010224: -Fixed errors with SDL_VERSIONNUM for older versions of SDL. -Synced the TTF code with SDL_ttf 1.2.2. New functions: sge_TTF_FontAscent() returns ascent sge_TTF_FontDescent() returns descent sge_TTF_FontLineSkip() returns recommended line skip sge_TTF_SetFontStyle() sets font style (SGE_TTF_NORMAL|SGE_TTF_BOLD| SGE_TTF_ITALIC|SGE_TTF_UNDERLINE) sge_TTF_GetFontStyle() returns the current style. Thanks to Idigoras Inaki (IIdigoras@ikerlan.es) for betatesting this! -Fixed more problems with MSVC. Should work now. -Added sge_BF_TextSize(). -Exorcised the old and horrible sge_tt_input_object class! New classes for text handling and rendering: sge_TextEditor - edits textstrings sge_text - render and buffers text sge_TextSurface - same as sge_surface (but with text) sge_TextSsprite - same as sge_ssprite ( " ) sge_TextSprite - same as sge_sprite ( " ). -Minor changes to the sge_shape classes (mostly bugfixes). -Added border_warp() in sge_ssprite. -New flag for sge_BF_OpenFont(): SGE_BFPALETTE. sge_BF_OpenFont() will use an 8bit surface for the font if this flag is set, this makes sge_BF_SetColor() much faster (~O(1)), but makes bliting a bit slower. -Replaced font.bmp with a new font from Garrett Banuk's SDL Console (http://www.wpi.edu/~mongoose/SDL_Console). -Better Makefile ('install' is possible now). -Added sge_Bezier(), draws a bezier curve. -Updated documentation. 010101: -Clipping now also works in newer versions of SDL, but stay away from SDL 1.1.5! -Fix for MDK7.2 include error. -Some fixes for RedHat7 (the infamous gcc 2.96) from Chuck (clc@alum.mit.edu). -Cleaned up the makefiles, everything is now configured in Makefile.conf. -Some fixes for MS VisC/C++ from Seung Chan Lim (limsc@maya.com or slim@djslim.com). -Updated SFont support. 000930: -This is a hack to get SGE working with SDL 1.1.5. When using the new version of SDL SGE will not perform pixel clipping (for now). The "Big Alpha Flip" in SDL also changes how SGE handles alpha!!! SDL_ALPHA_OPAQUE and SDL_ALPHA_TRANSPARENT is always set to the correct values (even under old versions of SDL). * THIS VERSION OF SGE IS NOT WELL TESTED! * Use SGE000714 if you don't have SDL 1.1.5 and don't feel lucky (this version of SGE should work with older versions of SDL - I think...). The documentation is not yet updated. I think you need a new version of SDL_img if you want SFont support. 000714: -Improved performance in sge_HLine(). -Changed all Sint32 coords to Sint16 (SDL uses Sint16). -Added delay functions: sge_CalibrateDelay() and sge_Delay() [sge_misc]. -Johan E. Thlin has contributed a new part to SGE: [sge_blib] (Tadaa!). -Nuked the old sge_sprite class and did it better this time [sge_shape]. -A new class: sge_screen, a tool class when working with shapes [sge_shape]. -sge_CalcYPitch() and sge_pPutPixel() added. Used for precalculating the y pitch offset [sge_draw]. -Some new routines for rotating and scaling bitmaps [sge_rotation]. -Updated and added some examples. -Updated documentation. 000418: -Improved the makefiles. * Always link your code against libSGE.a or libSGE.so * -Fixed freetype.h include problem. -Added sge.h - use it instead of the sge_*.h files. -Separated the TT and bitmap code. -Added some alpha component support: -sge_CreateAlphaSurface() Creates a 32bit alpha surface (RGBA - 8/8/8/8). The alpha channel is blended on blitting. *SGE only supports 32bit alpha surfaces* -sge_MapAlpha() Use this function to map Uint32 color values (RGBA) for alpha surfaces. The color value can then be used with any of SGEs functions. -The TTF functions now support alpha blending. Use sge_TTF_AA_Alpha() to turn this feature on. -sge_AlphaFader() Fades from (sR,sG,sB,sA) to (dR,dG,dB,dA). -Added SFont (Karl Bartel's font format) support to the bitmapfont routines. Open the sfont with sge_BF_OpenFont("filename",SGE_BFSFONT). Note that most sfonts need a alpha channel to look good which means it can't be loaded as a .bmp file (they do not support alpha). To enable SGE to load .png files uncomment 'USE_IMG = y' in the makefile (requires the SDL_img library!), this will enable SGE to load any image format SDL_img supports. If you do this, remember to link your code with SDL_img (not necessary if you use libSGE.so). 000312: -Fixed a bug in sge_Line(). -Added (still testing, no documentation) collision routines. -More work on the sprite class. 000115: -Added this text file. -The TTF routines can now draw non anti-aliased text also. Control this with sge_TTF_AAOff() - Turns anti-aliasing OFF sge_TTF_AAOn() - Turns anti-aliasing ON -DEFAULT- -A new flagsystem (finally). The following routines are effected: sge_tt_input... - 'int type' replaced by 'Uint8 flags' sge_BF_OpenFont - 'int flags' replaced by 'Uint8 flags' (no API change) sge_BF_input - 'Uint8 flags' added *PLEASE UPDATE YOUR SOURCE* The following flags can be used: SGE_FLAG1 - SGE_FLAG8 (defined in sge_draw.h), but routine specific flags are also provided. The flags can be ORed, eg. SGE_FLAG1|SGE_FLAG2|... The input functions has the following flags: SGE_IBG - Preserve background (only in tt, BF always preserves the background) SGE_IDEL - Delete text when finished SGE_INOKR - No keyrepeat NOTE! sge_tt_input: The old ('type') and the new ('flags') flags are not the same! If you do not update your source code, this will happend: type=0 => flags=0 - OK, same type=1 => flags=SGE_IBG - OK, same type=2 => flags=SGE_IDEL - NOT THE SAME! (should be SGE_IBG|SGE_IDEL) -TrueType font support optional, check the README. 000102: SGE now supports win32 crosscompiling. Support for bitmap fonts added. Some printf() like functions added. 991222: Fixed a small bug in sge_UpdateRect, more work on the circle routines. SGE can now be linked to both C and C++ code, check the README file for more information. 991219: Fixes some problems with lines and adds some ellipse routines. Update: Oops, the sge_FilledEllipse function was missing - fixed. 991208: SGE now has a sprite class *VERY BETA* and a nice surface rotation function. This version is tested with SDL 0.10 and 1.0. 990905: New version, with a completed text edit class. 990827: Released a new version, now with documentation. 990826: First public release of SGE (r990826). Have fun! /Anders Lindstrm sge030809/Makefile0000644000175000001440000000431507716015551012471 0ustar samusers# Makefile for the SGE library include Makefile.conf CFLAGS += $(SGE_CFLAGS) -fPIC $(FT_CFLAGS) LIBS =$(SGE_LIBS) SGE_VER = 030809 API_VER = 0 OBJECTS=sge_surface.o sge_primitives.o sge_tt_text.o sge_bm_text.o sge_misc.o sge_textpp.o sge_blib.o sge_rotation.o sge_collision.o sge_shape.o all: config $(OBJECTS) @ar rsc libSGE.a $(OBJECTS) $(OBJECTS): %.o:%.cpp %.h #Each object depends on thier .cpp and .h file $(CXX) $(CFLAGS) -c $< shared: all $(CXX) $(CFLAGS) -Wl,-soname,libSGE.so.$(API_VER) -fpic -fPIC -shared -o libSGE.so $(OBJECTS) $(LIBS) shared-strip: shared @strip libSGE.so # Building a dll... I have no idea how to do this, but it should be something like below. dll: config $(OBJECTS) dlltool --output-def SGE.def $(OBJECTS) dllwrap --driver-name $(CXX) -o SGE.dll --def SGE.def --output-lib libSGE.a --dllname SGE.dll $(OBJECTS) $(LIBS) dll-strip: dll @strip SGE.dll clean: @rm -f *.o *.so *.a *.dll *.def config: @echo "/* SGE Config header (generated automatically) */" >sge_config.h @echo "#define SGE_VER $(SGE_VER)" >>sge_config.h ifeq ($(C_COMP),y) @echo "#define _SGE_C_AND_CPP" >>sge_config.h endif ifeq ($(USE_FT),n) @echo "#define _SGE_NOTTF" >>sge_config.h endif ifeq ($(USE_IMG),y) @echo "#define _SGE_HAVE_IMG" >>sge_config.h endif ifeq ($(NO_CLASSES),y) @echo "#define _SGE_NO_CLASSES" >>sge_config.h endif ifneq ($(QUIET),y) @echo "== SGE r$(SGE_VER)" ifeq ($(C_COMP),y) @echo "== Note: Trying to be C friendly." endif ifeq ($(USE_FT),n) @echo "== FreeType2 support disabled." else @echo "== FreeType2 support enabled." endif ifeq ($(USE_IMG),y) @echo "== SDL_Image (SFont) support enabled." else @echo "== SDL_Image (SFont) support disabled." endif ifeq ($(NO_CLASSES),y) @echo "== Warning: No C++ classes will be build!" endif @echo "" endif install: shared @mkdir -p $(PREFIX_H) install -c -m 644 sge*.h $(PREFIX_H) @mkdir -p $(PREFIX)/lib install -c -m 644 libSGE.a $(PREFIX)/lib install -c libSGE.so $(PREFIX)/lib/libSGE.so.$(API_VER).$(SGE_VER) @cd $(PREFIX)/lib;\ ln -sf libSGE.so.$(API_VER).$(SGE_VER) libSGE.so.$(API_VER);\ ln -sf libSGE.so.$(API_VER) libSGE.so @echo "** Headerfiles installed in $(PREFIX_H)" @echo "** Library files installed in $(PREFIX)/lib" sge030809/Makefile.conf0000644000175000001440000000302607716016027013412 0ustar samusers# Configure Makefile for the SGE library # Comment/uncomment the following line to disable/enable build options # (See README for more info) C_COMP = y #USE_FT = n #USE_IMG = n #QUIET = y # Compilers (C and C++) CC=gcc CXX=g++ # Make sure sdl-config is available HAVE_SDL =$(shell if (sdl-config --version) < /dev/null > /dev/null 2>&1; then echo "y"; else echo "n"; fi;) ifeq ($(HAVE_SDL),n) $(error ERROR: Can't find SDL! Make sure that you have SDL (http://www.libsdl.org/) and its development files installed) endif # Where should SGE be installed? PREFIX =$(shell sdl-config --prefix) # Where should the headerfiles be installed? PREFIX_H =$(shell sdl-config --prefix)/include/SDL # Flags passed to the compiler CFLAGS =-Wall -O3 -ffast-math SGE_CFLAGS =$(shell sdl-config --cflags) # Uncomment to make some more optimizations #CFLAGS =-Wall -O9 -ffast-math -march=i686 # Libs config SGE_LIBS =$(shell sdl-config --libs) -lstdc++ # Is freetype-config available? HAVE_FT =$(shell if (freetype-config --version) < /dev/null > /dev/null 2>&1; then echo "y"; else echo "n"; fi;) ifeq ($(HAVE_FT),n) USE_FT = n endif ifneq ($(USE_FT),n) USE_FT = y SGE_LIBS +=$(shell freetype-config --libs) FT_CFLAGS =$(shell freetype-config --cflags) endif # Is SDL_image available? HAVE_IMG =$(shell if test -e "`sdl-config --prefix`/include/SDL/SDL_image.h" >/dev/null 2>&1; then echo "y"; else echo "n"; fi;) ifneq ($(USE_IMG),y) ifneq ($(USE_IMG),n) USE_IMG =$(HAVE_IMG) endif endif ifeq ($(USE_IMG),y) SGE_LIBS +=-lSDL_image endif sge030809/LICENSE0000644000175000001440000006347607374502341012051 0ustar samusers GNU LESSER GENERAL PUBLIC LICENSE Version 2.1, February 1999 Copyright (C) 1991, 1999 Free Software Foundation, Inc. 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. [This is the first released version of the Lesser GPL. It also counts as the successor of the GNU Library Public License, version 2, hence the version number 2.1.] Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public Licenses are intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This license, the Lesser General Public License, applies to some specially designated software packages--typically libraries--of the Free Software Foundation and other authors who decide to use it. You can use it too, but we suggest you first think carefully about whether this license or the ordinary General Public License is the better strategy to use in any particular case, based on the explanations below. When we speak of free software, we are referring to freedom of use, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish); that you receive source code or can get it if you want it; that you can change the software and use pieces of it in new free programs; and that you are informed that you can do these things. To protect your rights, we need to make restrictions that forbid distributors to deny you these rights or to ask you to surrender these rights. These restrictions translate to certain responsibilities for you if you distribute copies of the library or if you modify it. For example, if you distribute copies of the library, whether gratis or for a fee, you must give the recipients all the rights that we gave you. You must make sure that they, too, receive or can get the source code. If you link other code with the library, you must provide complete object files to the recipients, so that they can relink them with the library after making changes to the library and recompiling it. And you must show them these terms so they know their rights. We protect your rights with a two-step method: (1) we copyright the library, and (2) we offer you this license, which gives you legal permission to copy, distribute and/or modify the library. To protect each distributor, we want to make it very clear that there is no warranty for the free library. Also, if the library is modified by someone else and passed on, the recipients should know that what they have is not the original version, so that the original author's reputation will not be affected by problems that might be introduced by others. Finally, software patents pose a constant threat to the existence of any free program. We wish to make sure that a company cannot effectively restrict the users of a free program by obtaining a restrictive license from a patent holder. Therefore, we insist that any patent license obtained for a version of the library must be consistent with the full freedom of use specified in this license. Most GNU software, including some libraries, is covered by the ordinary GNU General Public License. This license, the GNU Lesser General Public License, applies to certain designated libraries, and is quite different from the ordinary General Public License. We use this license for certain libraries in order to permit linking those libraries into non-free programs. When a program is linked with a library, whether statically or using a shared library, the combination of the two is legally speaking a combined work, a derivative of the original library. The ordinary General Public License therefore permits such linking only if the entire combination fits its criteria of freedom. The Lesser General Public License permits more lax criteria for linking other code with the library. We call this license the "Lesser" General Public License because it does Less to protect the user's freedom than the ordinary General Public License. It also provides other free software developers Less of an advantage over competing non-free programs. These disadvantages are the reason we use the ordinary General Public License for many libraries. However, the Lesser license provides advantages in certain special circumstances. For example, on rare occasions, there may be a special need to encourage the widest possible use of a certain library, so that it becomes a de-facto standard. To achieve this, non-free programs must be allowed to use the library. A more frequent case is that a free library does the same job as widely used non-free libraries. In this case, there is little to gain by limiting the free library to free software only, so we use the Lesser General Public License. In other cases, permission to use a particular library in non-free programs enables a greater number of people to use a large body of free software. For example, permission to use the GNU C Library in non-free programs enables many more people to use the whole GNU operating system, as well as its variant, the GNU/Linux operating system. Although the Lesser General Public License is Less protective of the users' freedom, it does ensure that the user of a program that is linked with the Library has the freedom and the wherewithal to run that program using a modified version of the Library. The precise terms and conditions for copying, distribution and modification follow. Pay close attention to the difference between a "work based on the library" and a "work that uses the library". The former contains code derived from the library, whereas the latter must be combined with the library in order to run. GNU LESSER GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License Agreement applies to any software library or other program which contains a notice placed by the copyright holder or other authorized party saying it may be distributed under the terms of this Lesser General Public License (also called "this License"). Each licensee is addressed as "you". A "library" means a collection of software functions and/or data prepared so as to be conveniently linked with application programs (which use some of those functions and data) to form executables. The "Library", below, refers to any such software library or work which has been distributed under these terms. A "work based on the Library" means either the Library or any derivative work under copyright law: that is to say, a work containing the Library or a portion of it, either verbatim or with modifications and/or translated straightforwardly into another language. (Hereinafter, translation is included without limitation in the term "modification".) "Source code" for a work means the preferred form of the work for making modifications to it. For a library, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the library. Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running a program using the Library is not restricted, and output from such a program is covered only if its contents constitute a work based on the Library (independent of the use of the Library in a tool for writing it). Whether that is true depends on what the Library does and what the program that uses the Library does. 1. You may copy and distribute verbatim copies of the Library's complete source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and distribute a copy of this License along with the Library. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Library or any portion of it, thus forming a work based on the Library, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) The modified work must itself be a software library. b) You must cause the files modified to carry prominent notices stating that you changed the files and the date of any change. c) You must cause the whole of the work to be licensed at no charge to all third parties under the terms of this License. d) If a facility in the modified Library refers to a function or a table of data to be supplied by an application program that uses the facility, other than as an argument passed when the facility is invoked, then you must make a good faith effort to ensure that, in the event an application does not supply such function or table, the facility still operates, and performs whatever part of its purpose remains meaningful. (For example, a function in a library to compute square roots has a purpose that is entirely well-defined independent of the application. Therefore, Subsection 2d requires that any application-supplied function or table used by this function must be optional: if the application does not supply it, the square root function must still compute square roots.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Library, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Library, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Library. In addition, mere aggregation of another work not based on the Library with the Library (or with a work based on the Library) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may opt to apply the terms of the ordinary GNU General Public License instead of this License to a given copy of the Library. To do this, you must alter all the notices that refer to this License, so that they refer to the ordinary GNU General Public License, version 2, instead of to this License. (If a newer version than version 2 of the ordinary GNU General Public License has appeared, then you can specify that version instead if you wish.) Do not make any other change in these notices. Once this change is made in a given copy, it is irreversible for that copy, so the ordinary GNU General Public License applies to all subsequent copies and derivative works made from that copy. This option is useful when you wish to copy part of the code of the Library into a program that is not a library. 4. You may copy and distribute the Library (or a portion or derivative of it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange. If distribution of object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place satisfies the requirement to distribute the source code, even though third parties are not compelled to copy the source along with the object code. 5. A program that contains no derivative of any portion of the Library, but is designed to work with the Library by being compiled or linked with it, is called a "work that uses the Library". Such a work, in isolation, is not a derivative work of the Library, and therefore falls outside the scope of this License. However, linking a "work that uses the Library" with the Library creates an executable that is a derivative of the Library (because it contains portions of the Library), rather than a "work that uses the library". The executable is therefore covered by this License. Section 6 states terms for distribution of such executables. When a "work that uses the Library" uses material from a header file that is part of the Library, the object code for the work may be a derivative work of the Library even though the source code is not. Whether this is true is especially significant if the work can be linked without the Library, or if the work is itself a library. The threshold for this to be true is not precisely defined by law. If such an object file uses only numerical parameters, data structure layouts and accessors, and small macros and small inline functions (ten lines or less in length), then the use of the object file is unrestricted, regardless of whether it is legally a derivative work. (Executables containing this object code plus portions of the Library will still fall under Section 6.) Otherwise, if the work is a derivative of the Library, you may distribute the object code for the work under the terms of Section 6. Any executables containing that work also fall under Section 6, whether or not they are linked directly with the Library itself. 6. As an exception to the Sections above, you may also combine or link a "work that uses the Library" with the Library to produce a work containing portions of the Library, and distribute that work under terms of your choice, provided that the terms permit modification of the work for the customer's own use and reverse engineering for debugging such modifications. You must give prominent notice with each copy of the work that the Library is used in it and that the Library and its use are covered by this License. You must supply a copy of this License. If the work during execution displays copyright notices, you must include the copyright notice for the Library among them, as well as a reference directing the user to the copy of this License. Also, you must do one of these things: a) Accompany the work with the complete corresponding machine-readable source code for the Library including whatever changes were used in the work (which must be distributed under Sections 1 and 2 above); and, if the work is an executable linked with the Library, with the complete machine-readable "work that uses the Library", as object code and/or source code, so that the user can modify the Library and then relink to produce a modified executable containing the modified Library. (It is understood that the user who changes the contents of definitions files in the Library will not necessarily be able to recompile the application to use the modified definitions.) b) Use a suitable shared library mechanism for linking with the Library. A suitable mechanism is one that (1) uses at run time a copy of the library already present on the user's computer system, rather than copying library functions into the executable, and (2) will operate properly with a modified version of the library, if the user installs one, as long as the modified version is interface-compatible with the version that the work was made with. c) Accompany the work with a written offer, valid for at least three years, to give the same user the materials specified in Subsection 6a, above, for a charge no more than the cost of performing this distribution. d) If distribution of the work is made by offering access to copy from a designated place, offer equivalent access to copy the above specified materials from the same place. e) Verify that the user has already received a copy of these materials or that you have already sent this user a copy. For an executable, the required form of the "work that uses the Library" must include any data and utility programs needed for reproducing the executable from it. However, as a special exception, the materials to be distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. It may happen that this requirement contradicts the license restrictions of other proprietary libraries that do not normally accompany the operating system. Such a contradiction means you cannot use both them and the Library together in an executable that you distribute. 7. You may place library facilities that are a work based on the Library side-by-side in a single library together with other library facilities not covered by this License, and distribute such a combined library, provided that the separate distribution of the work based on the Library and of the other library facilities is otherwise permitted, and provided that you do these two things: a) Accompany the combined library with a copy of the same work based on the Library, uncombined with any other library facilities. This must be distributed under the terms of the Sections above. b) Give prominent notice with the combined library of the fact that part of it is a work based on the Library, and explaining where to find the accompanying uncombined form of the same work. 8. You may not copy, modify, sublicense, link with, or distribute the Library except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense, link with, or distribute the Library is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 9. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Library or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Library (or any work based on the Library), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Library or works based on it. 10. Each time you redistribute the Library (or any work based on the Library), the recipient automatically receives a license from the original licensor to copy, distribute, link with or modify the Library subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties with this License. 11. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Library at all. For example, if a patent license would not permit royalty-free redistribution of the Library by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Library. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply, and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 12. If the distribution and/or use of the Library is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Library under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 13. The Free Software Foundation may publish revised and/or new versions of the Lesser General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Library specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Library does not specify a license version number, you may choose any version ever published by the Free Software Foundation. 14. If you wish to incorporate parts of the Library into other free programs whose distribution conditions are incompatible with these, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Libraries If you develop a new library, and you want it to be of the greatest possible use to the public, we recommend making it free software that everyone can redistribute and change. You can do so by permitting redistribution under these terms (or, alternatively, under the terms of the ordinary General Public License). To apply these terms, attach the following notices to the library. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Also add information on how to contact you by electronic and paper mail. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the library, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the library `Frob' (a library for tweaking knobs) written by James Random Hacker. , 1 April 1990 Ty Coon, President of Vice That's all there is to it! sge030809/sge.h0000644000175000001440000000152407713172642011761 0ustar samusers/* * SDL Graphics Extension * * Started 990815 * * License: LGPL v2+ (see the file LICENSE) * (c)1999-2003 Anders Lindstrm */ /********************************************************************* * This library is free software; you can redistribute it and/or * * modify it under the terms of the GNU Library General Public * * License as published by the Free Software Foundation; either * * version 2 of the License, or (at your option) any later version. * *********************************************************************/ #ifndef sge_H #define sge_H #include "sge_surface.h" #include "sge_primitives.h" #include "sge_misc.h" #include "sge_tt_text.h" #include "sge_bm_text.h" #include "sge_textpp.h" #include "sge_blib.h" #include "sge_shape.h" #include "sge_collision.h" #include "sge_rotation.h" #endif /* sge_H */ sge030809/README0000644000175000001440000001754007715143162011714 0ustar samusersSDL Graphics Extension (SGE) ==================================================================================== http://freshmeat.net/projects/sge/ http://www.etek.chalmers.se/~e8cal1/sge/index.html http://www.digitalfanatics.org/cal/sge/index.html Author: Anders Lindstrm - email: cal@swipnet.se 1. Intro 2. Requirements 3. Compiling 4. Library usage 5. Makefile options 5.1 Using pure C with SGE (C_COMP) 5.2 FreeType (USE_FT) 5.3 The SDL_Image library (USE_IMG) 5.4 The QUIET option (QUIET) 6. Cross compiling SGE to W32 7. Compiling SGE under W32 with MS VisC/C++ 8. Thanks 9. Misc. ==================================================================================== 1. Intro SGE is an add-on graphics library for the Simple Direct Media Layer. SGE provides pixel operations, graphics primitives, FreeType rendering, rotation/scaling and much more. This is free software (LGPL), read LICENSE for details. SGE has the following parts: [sge_surface] Pixel operations, blitting and some pallete stuff. [sge_primitives] Drawing primitives. [sge_tt_text] FreeType font support. [sge_bm_text] Bitmapfont and SFont support. [sge_textpp] Classes for handling and rendering text. [sge_shape] Classes for blitting and sprites. [sge_collision] Basic collision detection. [sge_rotation] Rotation and scaling of surfaces. [sge_blib] Normal, filled, gourand shaded and texture mapped polygons. [sge_misc] Random number and delay functions. Read docs/index.html for API documentation. Always check WhatsNew for important (API) changes! There is a "Beginners guide to SGE" in the html documentation about how to compile and use SGE in your own project, please read it if you're new to Unix/Linux development. Read INSTALL for quick compile and install instructions. ==================================================================================== 2. Requirements -GNU Make. -SDL 1.2+. -An ANSI/ISO C++ compiler. SGE should conform to ANSI/ISO C++. -Optional: -FreeType 2+ -SDL_Image (see section 5.3) -Some SDL knowledge. First you need SDL (http://www.libsdl.org/) and the FreeType (2.x) library at http://www.freetype.org/ (you only need the FreeType library if you want to use SGE's truetype font routines, see section 5.2). The FreeType library is included in most Linux distributions (RPM users: install the freetype dev rpm package from the install cd). After installing SDL and FreeType, don't forget to check that the dynamic linker can find them (check /etc/ld.so.conf and run ldconfig). You must also have a good C++ compiler (should be able to handle templates). Recent versions of GNU c++ works fine. SGE will use gcc/g++ as default, but this can be changed in the file "Makefile.conf". ==================================================================================== 3. Compiling Before compiling you might want to change some Makefile.conf options, see section 5. Just do 'make install' to compile and install SGE. This will install SGE to the same place as SDL. You can change the install location by editing the PREFIX and PREFIX_H lines in the file "Makefile.conf". If you just want to test the examples (and not install anything) you can just do 'make'. This will build a static version of SGE (libSGE.a). If you want a dynamic version of SGE (libSGE.so) but don't want the makefile to install SGE, do 'make shared'. To build the examples, goto the directory examples/ and do 'make'. See the file INSTALL for more information. You can also read the file "docs/guide.html" ==================================================================================== 4. Library usage Do "#include "sge.h"" in your code after the normal "#include "SDL.h"" line. The normal way to compile code that uses SGE is with the flag "`sdl-config --cflags`", but also add the flag "-I/path/to/SGE/headers" if the SGE headers are installed at any other place than the SDL headers. The normal way to link code that uses SGE is with the flags "-lSGE `sdl-config --libs` -lstdc++", but also add the flag "-L/path/to/SGE/library" if SGE is installed at any other place than SDL. If you're using static linking then the flags "`freetype-config --libs`" and/or "-lSDL_image" also needs to be added if FreeType and/or SDL_Image support is enabled. Example: g++ -Wall -O3 `sdl-config --cflags` -c my_sge_app.cxx g++ -o my_sge_app my_sge_app.o -lSGE `sdl-config --libs` -lstdc++ See "docs/guide.html" and the code in examples/ for more information. ==================================================================================== 5. Makefile options Edit Makefile.conf to turn on/off (y/n) these options. 5.1 Using pure C with SGE (C_COMP) Setting 'C_COMP = y' should allow both C and C++ projects to use SGE. However, you will not be able to use any of the overloaded functions (only the Uint32 color version of the overloaded functions will be available) or C++ classes from a C project. C++ projects should not be affected. Default is 'y'. 5.2 FreeType (USE_FT) If you don't need the TT font routines or just don't want do depend on FreeType, uncomment 'USE_FT = n' in Makefile.conf. Default behavior is to autodetect FreeType. 5.3 The SDL_Image library (USE_IMG) The SDL_Image library (http://www.libsdl.org/projects/SDL_image/index.html) will be autodetected with the default setting. SDL_Image support enables SGE to load png images and thus use Karl Bartel's very nice SFont bitmapfonts (http://www.linux-games.com/sfont/). The use of SDL_Image can also be controlled by setting 'USE_IMG = y/n' manually. 5.4 The QUIET option (QUIT) Set 'QUIET = y' if you don't want the makefile to output any SGE specific messages. ==================================================================================== 6. Cross compiling SGE to W32 SGE can be compiled by a win32 crosscompiler. You need a crosscompiled version of SDL (and FreeType or SDL_Image if used). Check SDL's documentation (README.Win32) on how to get and setup a cross-compiler. A crosscompiler can be found at http://www.libsdl.org/Xmingw32/index.html. This crosscompiler uses the new MS C-Run-time library "msvcrt.dll", you can get it from www.microsoft.com/downloads (do a keyword search for "libraries update") if you don't already have it. If you want to build a dll ('cross-make dll' or 'dll-strip') then you might want to do 'ln -s ../../bin/i386-mingw32msvc-dllwrap dllwrap' in /usr/local/cross-tools/i386-mingw32msvc/bin. ==================================================================================== 7. Compiling SGE under W32 with MS VisC/C++ Should work. Check the download page on SGEs homepage for project files (these are untested by me and are often outdated but may be of some help). Note that if you don't use the makefile system to build SGE (as with VisC/C++) then you must edit sge_config.h manually to change build options. The options in section 5 corresponds to defining the following symbols in sge_config.h: _SGE_C_AND_CPP - C_COMP=y _SGE_NOTTF - USE_FT=n _SGE_HAVE_IMG - USE_IMG=y For example: /* SGE Config header */ #define SGE_VER 030809 #define _SGE_C_AND_CPP #define _SGE_HAVE_IMG ==================================================================================== 8. Thanks. Thanks goes to... -Sam Lantinga for the excellent SDL library. -The FreeType library developers. -John Garrison for the PowerPak library. -Karl Bartel for the SFont library (http://www.linux-games.com/). -Garrett Banuk for his bitmap font routines (http://www.mongeese.org/SDL_Console/). -Seung Chan Lim (limsc@maya.com or slim@djslim.com). -Idigoras Inaki (IIdigoras@ikerlan.es). -Andreas Schiffler (http://www.ferzkopp.net/Software/SDL_gfx-2.0/index.html). -Nicolas Roard (http://www.twinlib.org). and many more... ==================================================================================== 9. Misc. Read the html documentation and study the examples. /Anders Lindstrm - email: cal@swipnet.se sge030809/sge_tt_text.cpp0000644000175000001440000012123707714716010014065 0ustar samusers/* * SDL Graphics Extension * Text/TrueType font functions * * Started 990815 * * License: LGPL v2+ (see the file LICENSE) * (c)1999-2003 Anders Lindstrm * * Uses the excellent FreeType 2 library, available at: * http://www.freetype.org/ */ /********************************************************************* * This library is free software; you can redistribute it and/or * * modify it under the terms of the GNU Library General Public * * License as published by the Free Software Foundation; either * * version 2 of the License, or (at your option) any later version. * *********************************************************************/ /* * Most of this code is taken from the SDL ttf lib by Sam Lantinga * */ #include "SDL.h" #include "SDL_endian.h" #include #include #include #include #include "sge_surface.h" #include "sge_primitives.h" #include "sge_tt_text.h" #include "sge_textpp.h" #ifndef _SGE_NOTTF #include #include #include #include /* The structure used to hold glyph information (cached) */ struct glyph { int stored; FT_UInt index; //FT_Bitmap bitmap; FT_Bitmap pixmap; int minx; int maxx; int miny; int maxy; int yoffset; int advance; Uint16 cached; }; /* the truetype font structure */ struct _sge_TTFont{ FT_Face face; /* Font metrics */ int height; int ascent; int descent; int lineskip; /* The font style */ Uint8 style; /* Extra width in glyph bounds for text styles */ int glyph_overhang; float glyph_italics; /* Information in the font for underlining */ int underline_offset; int underline_height; /* For now, support Latin-1 character set caching */ glyph *current; glyph cache[256]; glyph scratch; /* We are responsible for closing the font stream */ SDL_RWops *src; int freesrc; FT_Open_Args args; /* For non-scalable formats, we must remember which font index size */ int font_size_family; }; /* FIXME: Right now we assume the gray-scale renderer Freetype is using supports 256 shades of gray, but we should instead key off of num_grays in the result FT_Bitmap after the FT_Render_Glyph() call. */ #define NUM_GRAYS 256 /* Handy routines for converting from fixed point */ #define FT_FLOOR(X) ((X & -64) / 64) #define FT_CEIL(X) (((X + 63) & -64) / 64) #define CACHED_METRICS 0x10 #define CACHED_BITMAP 0x01 #define CACHED_PIXMAP 0x02 /* Fix a problem with older version of Freetype */ #ifndef FT_OPEN_STREAM #define FT_OPEN_STREAM ft_open_stream #endif /* The FreeType font engine/library */ static FT_Library _sge_library; static int _sge_TTF_initialized = 0; static int _sge_TTF_byteswapped = 0; Uint8 _sge_TTF_AA=1; //Rendering mode: 0-OFF, 1-AA, 2-Alpha /**********************************************************************************/ /** Open/misc font functions **/ /**********************************************************************************/ //================================================================================== // Turns TTF AntiAliasing On/Off or alpha (nice but slow) (Default: On) //================================================================================== void sge_TTF_AAOff(void) { _sge_TTF_AA=0; } void sge_TTF_AAOn(void) { _sge_TTF_AA=1; } void sge_TTF_AA_Alpha(void) { _sge_TTF_AA=2; } //================================================================================== // Control UNICODE byteswapping (default: no => swapped=0) //================================================================================== /* This function tells the library whether UNICODE text is generally byteswapped. A UNICODE BOM character at the beginning of a string will override this setting for that string. */ void sge_TTF_ByteSwappedUNICODE(int swapped) { _sge_TTF_byteswapped = swapped; } //================================================================================== // Closes the ttf engine, done by exit //================================================================================== void sge_TTF_Quit(void) { if ( _sge_TTF_initialized ) { FT_Done_FreeType( _sge_library ); } _sge_TTF_initialized = 0; } //================================================================================== // Starts the ttf engine, must be called first //================================================================================== int sge_TTF_Init(void) { FT_Error error; if( _sge_TTF_initialized ) return 0; error = FT_Init_FreeType( &_sge_library ); if ( error ) { SDL_SetError("SGE - Couldn't init FreeType engine"); return(-1); } else { _sge_TTF_initialized = 1; } atexit(sge_TTF_Quit); //dont't trust the user... return 0; } //================================================================================== // Some helper functions //================================================================================== void Flush_Glyph(glyph *glyph) { glyph->stored = 0; glyph->index = 0; //if( glyph->bitmap.buffer ) { // free( glyph->bitmap.buffer ); // glyph->bitmap.buffer = 0; //} if( glyph->pixmap.buffer ) { free( glyph->pixmap.buffer ); glyph->pixmap.buffer = 0; } glyph->cached = 0; } void Flush_Cache(sge_TTFont *font) { int i; int size = sizeof( font->cache ) / sizeof( font->cache[0] ); for( i = 0; i < size; ++i ) { if( font->cache[i].cached ) { Flush_Glyph( &font->cache[i] ); } } if( font->scratch.cached ) { Flush_Glyph( &font->scratch ); } } //================================================================================== // Remove font from memory //================================================================================== void sge_TTF_CloseFont(sge_TTFont *font) { Flush_Cache( font ); if ( font->face ) FT_Done_Face( font->face ); if ( font->args.stream ) free( font->args.stream ); if ( font->freesrc ) SDL_RWclose( font->src ); free( font ); } //================================================================================== // Seek and read stream (internal) //================================================================================== unsigned long RWread(FT_Stream stream, unsigned long offset, unsigned char* buffer, unsigned long count) { SDL_RWops *src; src = (SDL_RWops *)stream->descriptor.pointer; SDL_RWseek( src, (int)offset, SEEK_SET ); return SDL_RWread( src, buffer, 1, (int)count ); } //================================================================================== // Open the TT font sream and returns the font //================================================================================== sge_TTFont *sge_TTF_OpenFontIndexRW(SDL_RWops *src, int freesrc, int ptsize, long index, int xdpi, int ydpi) { sge_TTFont *font; FT_Error error; FT_Face face; FT_Fixed scale; FT_Stream stream; int position; if( !_sge_TTF_initialized){ SDL_SetError("SGE - Freetype not initialized"); return NULL; } /* Check to make sure we can seek in this stream */ position = SDL_RWtell(src); if ( position < 0 ) { SDL_SetError("SGE - Can't seek in font stream"); return NULL; } font = (sge_TTFont *)malloc(sizeof(*font)); if ( font == NULL ) { SDL_SetError("SGE - Out of memory"); return(NULL); } memset(font, 0, sizeof(*font)); font->src = src; font->freesrc = freesrc; stream = (FT_Stream)malloc(sizeof(*stream)); if ( stream == NULL ) { SDL_SetError("SGE - Out of memory"); sge_TTF_CloseFont( font ); return NULL; } memset(stream, 0, sizeof(*stream)); stream->memory = _sge_library->memory; stream->read = RWread; stream->descriptor.pointer = src; stream->pos = (unsigned long)position; SDL_RWseek(src, 0, SEEK_END); stream->size = (unsigned long)(SDL_RWtell(src) - position); SDL_RWseek(src, position, SEEK_SET); font->args.flags = FT_OPEN_STREAM; font->args.stream = stream; /* Open the font stream and create ancillary data */ error = FT_Open_Face( _sge_library, &font->args, index, &font->face ); if ( error ) { SDL_SetError("SGE - Couldn't open font face"); sge_TTF_CloseFont( font ); return NULL; } face = font->face; /* Handle scalable font face (global metrics) */ if ( FT_IS_SCALABLE(face) ) { /* Set the character size and use DPI in arguments */ error = FT_Set_Char_Size( font->face, 0, ptsize * 64, xdpi, ydpi ); if( error ) { SDL_SetError("SGE - Couldn't set font size"); sge_TTF_CloseFont( font ); return NULL; } /* Get the scalable font metrics for this font */ scale = face->size->metrics.y_scale; font->ascent = FT_CEIL(FT_MulFix(face->bbox.yMax, scale)); font->descent = FT_CEIL(FT_MulFix(face->bbox.yMin, scale)); font->height = font->ascent - font->descent + /* baseline */ 1; font->lineskip = FT_CEIL(FT_MulFix(face->height, scale)); font->underline_offset = FT_FLOOR(FT_MulFix(face->underline_position, scale)); font->underline_height = FT_FLOOR(FT_MulFix(face->underline_thickness, scale)); } else { /* Non-scalable font face. ptsize determines which family * or series of fonts to grab from the non-scalable format. * It is not the point size of the font. * */ if ( ptsize >= font->face->num_fixed_sizes ) ptsize = font->face->num_fixed_sizes - 1; font->font_size_family = ptsize; error = FT_Set_Pixel_Sizes( face, face->available_sizes[ptsize].height, face->available_sizes[ptsize].width ); /* With non-scalale fonts, Freetype2 likes to fill many of the * font metrics with the value of 0. The size of the * non-scalable fonts must be determined differently * or sometimes cannot be determined. * */ font->ascent = face->available_sizes[ptsize].height; font->descent = 0; font->height = face->available_sizes[ptsize].height; font->lineskip = FT_CEIL(font->ascent); font->underline_offset = FT_FLOOR(face->underline_position); font->underline_height = FT_FLOOR(face->underline_thickness); } if ( font->underline_height < 1 ) font->underline_height = 1; /* Set the default font style */ font->style = SGE_TTF_NORMAL; font->glyph_overhang = face->size->metrics.y_ppem / 10; /* x offset = cos(((90.0-12)/360)*2*M_PI), or 12 degree angle */ font->glyph_italics = 0.207f; font->glyph_italics *= font->height; return font; } sge_TTFont *sge_TTF_OpenFontRW( SDL_RWops *src, int freesrc, int ptsize, int xdpi, int ydpi) { return sge_TTF_OpenFontIndexRW(src, freesrc, ptsize, 0, xdpi, ydpi); } sge_TTFont *sge_TTF_OpenFontIndex( const char *file, int ptsize, long index, int xdpi, int ydpi) { return sge_TTF_OpenFontIndexRW(SDL_RWFromFile(file, "rb"), 1, ptsize, index, xdpi, ydpi); } sge_TTFont *sge_TTF_OpenFont(const char *file, int ptsize) { return sge_TTF_OpenFontIndex(file, ptsize, 0, 96, 96); } //================================================================================== // Load a glyph //================================================================================== FT_Error Load_Glyph(sge_TTFont *font, Uint16 ch, glyph *cached, int want ) { FT_Face face; FT_Error error; FT_GlyphSlot glyph; FT_Glyph_Metrics* metrics; FT_Outline* outline; if ( !font || !font->face ) { return FT_Err_Invalid_Handle; } face = font->face; /* Load the glyph */ if ( ! cached->index ) { cached->index = FT_Get_Char_Index( face, ch ); } error = FT_Load_Glyph( face, cached->index, FT_LOAD_DEFAULT ); if( error ) { return error; } /* Get our glyph shortcuts */ glyph = face->glyph; metrics = &glyph->metrics; outline = &glyph->outline; /* Get the glyph metrics if desired */ if ( (want & CACHED_METRICS) && !(cached->stored & CACHED_METRICS) ) { if ( FT_IS_SCALABLE( face ) ) { /* Get the bounding box */ cached->minx = FT_FLOOR(metrics->horiBearingX); cached->maxx = cached->minx + FT_CEIL(metrics->width); cached->maxy = FT_FLOOR(metrics->horiBearingY); cached->miny = cached->maxy - FT_CEIL(metrics->height); cached->yoffset = font->ascent - cached->maxy; cached->advance = FT_CEIL(metrics->horiAdvance); } else { /* Get the bounding box for non-scalable format. * Again, freetype2 fills in many of the font metrics * with the value of 0, so some of the values we * need must be calculated differently with certain * assumptions about non-scalable formats. * */ cached->minx = FT_FLOOR(metrics->horiBearingX); cached->maxx = cached->minx + FT_CEIL(metrics->horiAdvance); cached->maxy = FT_FLOOR(metrics->horiBearingY); cached->miny = cached->maxy - FT_CEIL(face->available_sizes[font->font_size_family].height); cached->yoffset = 0; cached->advance = FT_CEIL(metrics->horiAdvance); } /* Adjust for bold and italic text */ if ( font->style & SGE_TTF_BOLD ) { cached->maxx += font->glyph_overhang; } if ( font->style & SGE_TTF_ITALIC ) { cached->maxx += (int)ceil(font->glyph_italics); } cached->stored |= CACHED_METRICS; } if ( ((want & CACHED_BITMAP) && !(cached->stored & CACHED_BITMAP)) || ((want & CACHED_PIXMAP) && !(cached->stored & CACHED_PIXMAP)) ) { //int mono = (want & CACHED_BITMAP); int i; FT_Bitmap* src; FT_Bitmap* dst; /* Handle the italic style */ if( font->style & SGE_TTF_ITALIC ) { FT_Matrix shear; shear.xx = 1 << 16; shear.xy = (int) ( font->glyph_italics * ( 1 << 16 ) ) / font->height; shear.yx = 0; shear.yy = 1 << 16; FT_Outline_Transform( outline, &shear ); } /* Render the glyph */ //if ( mono ) { // error = FT_Render_Glyph( glyph, ft_render_mode_mono ); //} else { error = FT_Render_Glyph( glyph, ft_render_mode_normal ); //} if( error ) { return error; } /* Copy over information to cache */ src = &glyph->bitmap; //if ( mono ) { // dst = &cached->bitmap; //} else { dst = &cached->pixmap; //} memcpy( dst, src, sizeof( *dst ) ); /* FT_Render_Glyph() and .fon fonts always generate a * two-color (black and white) glyphslot surface, even * when rendered in ft_render_mode_normal. This is probably * a freetype2 bug because it is inconsistent with the * freetype2 documentation under FT_Render_Mode section. * */ if ( !FT_IS_SCALABLE(face) ) { dst->pitch *= 8; } /* Adjust for bold and italic text */ if( font->style & SGE_TTF_BOLD ) { int bump = font->glyph_overhang; dst->pitch += bump; dst->width += bump; } if( font->style & SGE_TTF_ITALIC ) { int bump = (int)ceil(font->glyph_italics); dst->pitch += bump; dst->width += bump; } if( dst->rows != 0 ) { dst->buffer = (unsigned char *)malloc( dst->pitch * dst->rows ); if( !dst->buffer ) { return FT_Err_Out_Of_Memory; } memset( dst->buffer, 0, dst->pitch * dst->rows ); for( i = 0; i < src->rows; i++ ) { int soffset = i * src->pitch; int doffset = i * dst->pitch; /*if ( mono ) { unsigned char *srcp = src->buffer + soffset; unsigned char *dstp = dst->buffer + doffset; int j; for ( j = 0; j < src->width; j += 8 ) { unsigned char ch = *srcp++; *dstp++ = (ch&0x80) >> 7; ch <<= 1; *dstp++ = (ch&0x80) >> 7; ch <<= 1; *dstp++ = (ch&0x80) >> 7; ch <<= 1; *dstp++ = (ch&0x80) >> 7; ch <<= 1; *dstp++ = (ch&0x80) >> 7; ch <<= 1; *dstp++ = (ch&0x80) >> 7; ch <<= 1; *dstp++ = (ch&0x80) >> 7; ch <<= 1; *dstp++ = (ch&0x80) >> 7; } } else */if ( !FT_IS_SCALABLE(face) ) { /* This special case wouldn't * be here if the FT_Render_Glyph() * function wasn't buggy when it tried * to render a .fon font with 256 * shades of gray. Instead, it * returns a black and white surface * and we have to translate it back * to a 256 gray shaded surface. * */ unsigned char *srcp = src->buffer + soffset; unsigned char *dstp = dst->buffer + doffset; unsigned char ch; int j, k; for ( j = 0; j < src->width; j += 8) { ch = *srcp++; for (k = 0; k < 8; ++k) { if ((ch&0x80) >> 7) { *dstp++ = NUM_GRAYS - 1; } else { *dstp++ = 0x00; } ch <<= 1; } } } else { memcpy(dst->buffer+doffset, src->buffer+soffset, src->pitch); } } } /* Handle the bold style */ if ( font->style & SGE_TTF_BOLD ) { int row; int col; int offset; int pixel; Uint8* pixmap; /* The pixmap is a little hard, we have to add and clamp */ for( row = dst->rows - 1; row >= 0; --row ) { pixmap = (Uint8*) dst->buffer + row * dst->pitch; for( offset=1; offset <= font->glyph_overhang; ++offset ) { for( col = dst->width - 1; col > 0; --col ) { pixel = (pixmap[col] + pixmap[col-1]); if( pixel > NUM_GRAYS - 1 ) { pixel = NUM_GRAYS - 1; } pixmap[col] = (Uint8) pixel; } } } } /* Mark that we rendered this format */ //if ( mono ) { // cached->stored |= CACHED_BITMAP; //} else { cached->stored |= CACHED_PIXMAP; //} } /* We're done, mark this glyph cached */ cached->cached = ch; return 0; } //================================================================================== // Find glyph //================================================================================== FT_Error Find_Glyph(sge_TTFont *font, Uint16 ch, int want) { int retval = 0; if( ch < 256 ) { font->current = &font->cache[ch]; } else { if ( font->scratch.cached != ch ) { Flush_Glyph( &font->scratch ); } font->current = &font->scratch; } if ( (font->current->stored & want) != want ) { retval = Load_Glyph( font, ch, font->current, want ); } return retval; } //================================================================================== // Change the size of font //================================================================================== int sge_TTF_SetFontSizeDPI(sge_TTFont *font, int ptsize, int xdpi, int ydpi) { FT_Error error; FT_Fixed scale; FT_Face face; face = font->face; Flush_Cache(font); if ( FT_IS_SCALABLE(face) ) { /* Set the character size */ error = FT_Set_Char_Size( font->face, 0, ptsize * 64, xdpi, ydpi ); if( error ) { sge_SetError("SGE - Couldn't set font size"); sge_TTF_CloseFont( font ); return -1; } /* Get the scalable font metrics for this font */ scale = face->size->metrics.y_scale; font->ascent = FT_CEIL(FT_MulFix(face->bbox.yMax, scale)); font->descent = FT_CEIL(FT_MulFix(face->bbox.yMin, scale)); font->height = font->ascent - font->descent + /* baseline */ 1; font->lineskip = FT_CEIL(FT_MulFix(face->height, scale)); font->underline_offset = FT_FLOOR(FT_MulFix(face->underline_position, scale)); font->underline_height = FT_FLOOR(FT_MulFix(face->underline_thickness, scale)); } else { /* Non-scalable font case. ptsize determines which family * or series of fonts to grab from the non-scalable format. * It is not the point size of the font. * */ if ( ptsize >= font->face->num_fixed_sizes ) ptsize = font->face->num_fixed_sizes - 1; font->font_size_family = ptsize; error = FT_Set_Pixel_Sizes( face, face->available_sizes[ptsize].height, face->available_sizes[ptsize].width ); /* With non-scalale fonts, Freetype2 likes to fill many of the * font metrics with the value of 0. The size of the * non-scalable fonts must be determined differently * or sometimes cannot be determined. * */ font->ascent = face->available_sizes[ptsize].height; font->descent = 0; font->height = face->available_sizes[ptsize].height; font->lineskip = FT_CEIL(font->ascent); font->underline_offset = FT_FLOOR(face->underline_position); font->underline_height = FT_FLOOR(face->underline_thickness); } if ( font->underline_height < 1 ) { font->underline_height = 1; } /* Set the default font style */ //font->style = SGE_TTF_NORMAL; font->glyph_overhang = face->size->metrics.y_ppem / 10; /* x offset = cos(((90.0-12)/360)*2*M_PI), or 12 degree angle */ font->glyph_italics = 0.207f; font->glyph_italics *= font->height; return 0; } int sge_TTF_SetFontSize(sge_TTFont *font, int ptsize) { return sge_TTF_SetFontSizeDPI(font, ptsize, 96 ,96); } //================================================================================== // Get font geometrics //================================================================================== int sge_TTF_FontHeight(sge_TTFont *font) { return(font->height); } int sge_TTF_FontAscent(sge_TTFont *font) { return(font->ascent); } int sge_TTF_FontDescent(sge_TTFont *font) { return(font->descent); } int sge_TTF_FontLineSkip(sge_TTFont *font) { return(font->lineskip); } long sge_TTF_FontFaces(sge_TTFont *font) { return(font->face->num_faces); } int sge_TTF_FontFaceIsFixedWidth(sge_TTFont *font) { return(FT_IS_FIXED_WIDTH(font->face)); } char *sge_TTF_FontFaceFamilyName(sge_TTFont *font) { return(font->face->family_name); } char *sge_TTF_FontFaceStyleName(sge_TTFont *font) { return(font->face->style_name); } int sge_TTF_GlyphMetrics(sge_TTFont *font, Uint16 ch, int* minx, int* maxx, int* miny, int* maxy, int* advance) { FT_Error error; error = Find_Glyph(font, ch, CACHED_METRICS); if ( error ) { return -1; } if ( minx ) { *minx = font->current->minx; } if ( maxx ) { *maxx = font->current->maxx; } if ( miny ) { *miny = font->current->miny; } if ( maxy ) { *maxy = font->current->maxy; } if ( advance ) { *advance = font->current->advance; } return 0; } //================================================================================== // Set font style //================================================================================== void sge_TTF_SetFontStyle(sge_TTFont *font, Uint8 style) { font->style = style; Flush_Cache(font); } //================================================================================== // Get font style //================================================================================== Uint8 sge_TTF_GetFontStyle(sge_TTFont *font) { return(font->style); } #endif /* _SGE_NOTTF */ //================================================================================== // Convert the Latin-1 text to UNICODE //================================================================================== Uint16 *ASCII_to_UNICODE(Uint16 *unicode, const char *text, int len) { int i; for ( i=0; i < len; ++i ) { unicode[i] = ((const unsigned char *)text)[i]; } unicode[i] = 0; return unicode; } Uint16 *sge_Latin1_Uni(const char *text) { Uint16 *unicode_text; int i, unicode_len; /* Copy the Latin-1 text to a UNICODE text buffer */ unicode_len = strlen(text); unicode_text = (Uint16 *)malloc((unicode_len+1)*(sizeof *unicode_text)); if ( unicode_text == NULL ) { SDL_SetError("SGE - Out of memory"); return(NULL); } for ( i=0; i < unicode_len; ++i ) { unicode_text[i] = ((const unsigned char *)text)[i]; } unicode_text[i] = 0; return(unicode_text); } //================================================================================== // Convert the UTF-8 text to UNICODE //================================================================================== Uint16 *UTF8_to_UNICODE(Uint16 *unicode, const char *utf8, int len) { int i, j; Uint16 ch; for ( i=0, j=0; i < len; ++i, ++j ) { ch = ((const unsigned char *)utf8)[i]; if ( ch >= 0xF0 ) { ch = (Uint16)(utf8[i]&0x07) << 18; ch |= (Uint16)(utf8[++i]&0x3F) << 12; ch |= (Uint16)(utf8[++i]&0x3F) << 6; ch |= (Uint16)(utf8[++i]&0x3F); } else if ( ch >= 0xE0 ) { ch = (Uint16)(utf8[i]&0x3F) << 12; ch |= (Uint16)(utf8[++i]&0x3F) << 6; ch |= (Uint16)(utf8[++i]&0x3F); } else if ( ch >= 0xC0 ) { ch = (Uint16)(utf8[i]&0x3F) << 6; ch |= (Uint16)(utf8[++i]&0x3F); } unicode[j] = ch; } unicode[j] = 0; return unicode; } Uint16 *sge_UTF8_Uni(const char *text) { Uint16 *unicode_text; int unicode_len; /* Copy the UTF-8 text to a UNICODE text buffer */ unicode_len = strlen(text); unicode_text = (Uint16 *)malloc((unicode_len+1)*(sizeof *unicode_text)); if ( unicode_text == NULL ) { SDL_SetError("SGE - Out of memory"); return(NULL); } return UTF8_to_UNICODE(unicode_text, text, unicode_len); } #ifndef _SGE_NOTTF //================================================================================== // Get the width of the text with the given font //================================================================================== SDL_Rect sge_TTF_TextSizeUNI(sge_TTFont *font, const Uint16 *text) { SDL_Rect ret; ret.x=0; ret.y=0, ret.w=0, ret.h=0; const Uint16 *ch; int swapped; int x, z; int minx, maxx; int miny, maxy; glyph *glyph; FT_Error error; /* Initialize everything to 0 */ if ( ! _sge_TTF_initialized ) { return ret; } minx = miny = 0; maxx = maxy = 0; swapped = _sge_TTF_byteswapped; /* Load each character and sum it's bounding box */ x= 0; for ( ch=text; *ch; ++ch ) { Uint16 c = *ch; if ( c == UNICODE_BOM_NATIVE ) { swapped = 0; if ( text == ch ) { ++text; } continue; } if ( c == UNICODE_BOM_SWAPPED ) { swapped = 1; if ( text == ch ) { ++text; } continue; } if ( swapped ) { c = SDL_Swap16(c); } error = Find_Glyph(font, c, CACHED_METRICS); if ( error ) { return ret; } glyph = font->current; if ( (ch == text) && (glyph->minx < 0) ) { /* Fixes the texture wrapping bug when the first letter * has a negative minx value or horibearing value. The entire * bounding box must be adjusted to be bigger so the entire * letter can fit without any texture corruption or wrapping. * * Effects: First enlarges bounding box. * Second, xstart has to start ahead of its normal spot in the * negative direction of the negative minx value. * (pushes everything to the right). * * This will make the memory copy of the glyph bitmap data * work out correctly. * */ z -= glyph->minx; } z = x + glyph->minx; if ( minx > z ) { minx = z; } if ( font->style & SGE_TTF_BOLD ) { x += font->glyph_overhang; } if ( glyph->advance > glyph->maxx ) { z = x + glyph->advance; } else { z = x + glyph->maxx; } if ( maxx < z ) { maxx = z; } x += glyph->advance; if ( glyph->miny < miny ) { miny = glyph->miny; } if ( glyph->maxy > maxy ) { maxy = glyph->maxy; } } /* Fill the bounds rectangle */ ret.w = (maxx - minx); //ret.h = (maxy - miny); /* This is correct, but breaks many applications */ ret.h = font->height; return ret; } SDL_Rect sge_TTF_TextSize(sge_TTFont *font, char *text) { SDL_Rect ret; ret.x=ret.y=ret.w=ret.y=0; Uint16 *unicode_text; int unicode_len; /* Copy the Latin-1 text to a UNICODE text buffer */ unicode_len = strlen(text); unicode_text = (Uint16 *)malloc((unicode_len+1)*(sizeof *unicode_text)); if ( unicode_text == NULL ) { SDL_SetError("SGE - Out of memory"); return ret; } ASCII_to_UNICODE(unicode_text, text, unicode_len); /* Render the new text */ ret = sge_TTF_TextSizeUNI(font, unicode_text); /* Free the text buffer and return */ free(unicode_text); return ret; } /**********************************************************************************/ /** TTF output functions **/ /**********************************************************************************/ //================================================================================== // TT Render (unicode) // Returns an 8bit or 32bit(8/8/8/8-alpha) surface with TT text //================================================================================== SDL_Surface *sge_TTF_Render(sge_TTFont *font,const Uint16 *text, SDL_Color fg, SDL_Color bg, int alpha_level) { int xstart, width; int w, h; SDL_Surface *textbuf; SDL_Palette *palette; int index; int rdiff, gdiff, bdiff; int swapped; const Uint16 *ch; Uint8 *src, *dst; Uint32 *dst32; Uint32 alpha=0; Uint32 pixel=0; Uint32 Rmask=0, Gmask=0, Bmask=0, Amask=0; int row, col; FT_Error error; /* Get the dimensions of the text surface */ SDL_Rect ret=sge_TTF_TextSizeUNI(font, text); w=ret.w; h=ret.h; if ( !w ) { SDL_SetError("SGE - Text has zero width"); return(NULL); } /* Create the target surface */ width = w; if(_sge_TTF_AA!=2) /* Allocate an 8-bit pixmap */ textbuf = SDL_AllocSurface(SDL_SWSURFACE, w, h, 8, 0, 0, 0, 0); else{ /* Allocate an 32-bit alpha pixmap */ if ( SDL_BYTEORDER == SDL_LIL_ENDIAN ) { Rmask = 0x000000FF; Gmask = 0x0000FF00; Bmask = 0x00FF0000; Amask = 0xFF000000; } else { Rmask = 0xFF000000; Gmask = 0x00FF0000; Bmask = 0x0000FF00; Amask = 0x000000FF; } textbuf = SDL_AllocSurface(SDL_SWSURFACE, w, h, 32, Rmask, Gmask, Bmask, Amask); } if ( textbuf == NULL ) { SDL_SetError("SGE - Out of memory"); return(NULL); } /* Setup our colors */ switch(_sge_TTF_AA){ case 0:{ /* No fancy antialiasing or alpha component */ palette = textbuf->format->palette; palette->colors[0].r = bg.r; palette->colors[0].g = bg.g; palette->colors[0].b = bg.b; palette->colors[1].r = fg.r; palette->colors[1].g = fg.g; palette->colors[1].b = fg.b; } break; case 1:{ /* Fill the palette with NUM_GRAYS levels of shading from bg to fg */ palette = textbuf->format->palette; rdiff = fg.r - bg.r; gdiff = fg.g - bg.g; bdiff = fg.b - bg.b; for ( index=0; index< NUM_GRAYS; ++index ) { palette->colors[index].r = bg.r + (index*rdiff)/(NUM_GRAYS-1); palette->colors[index].g = bg.g + (index*gdiff)/(NUM_GRAYS-1); palette->colors[index].b = bg.b + (index*bdiff)/(NUM_GRAYS-1); } } break; case 2:{ /* Alpha component magic */ sge_ClearSurface(textbuf, SDL_MapRGBA(textbuf->format, bg.r,bg.g,bg.b,SDL_ALPHA_TRANSPARENT)); //pixel = (fg.r<<16)|(fg.g<<8)|fg.b; pixel = (fg.b<<16)|(fg.g<<8)|fg.r; } break; } /* Load and render each character */ xstart = 0; swapped = _sge_TTF_byteswapped; for ( ch=text; *ch; ++ch ) { Uint16 c = *ch; if ( c == UNICODE_BOM_NATIVE ) { swapped = 0; if ( text == ch ) { ++text; } continue; } if ( c == UNICODE_BOM_SWAPPED ) { swapped = 1; if ( text == ch ) { ++text; } continue; } if ( swapped ) { c = SDL_Swap16(c); } error = Find_Glyph(font, c, CACHED_METRICS|CACHED_PIXMAP); if ( ! error ) { /* Compensate for wrap around bug with negative minx's */ if ( (ch == text) && (font->current->minx < 0) ) { xstart -= font->current->minx; } w = font->current->pixmap.width; for ( row = 0; row < font->current->pixmap.rows; ++row ) { /* Make sure we don't go over the limit */ if ( row+font->current->yoffset >= textbuf->h ) continue; dst = (Uint8 *)textbuf->pixels + (row + font->current->yoffset)* textbuf->pitch + xstart + font->current->minx; switch(_sge_TTF_AA){ case 0:{ /* Normal */ src = font->current->pixmap.buffer + row * font->current->pixmap.pitch; for ( col=w; col>0; --col ) { *dst++ |= (*src++current->pixmap.buffer + row * font->current->pixmap.pitch; for ( col=w; col>0; --col ) { *dst++ |= *src++; } } break; case 2:{ /* Alpha */ src = (Uint8*) (font->current->pixmap.buffer + font->current->pixmap.pitch * row); dst32 = (Uint32 *)textbuf->pixels + (row + font->current->yoffset)* textbuf->pitch/4 + xstart + font->current->minx; if( alpha_level == SDL_ALPHA_OPAQUE ){ for ( col=w; col>0; --col ) { alpha = *src++; *dst32++ |= pixel | (alpha << 24); } }else{ //We need to scale the alpha value //Thanks mabi! for ( col=w; col>0; --col ) { alpha = (*src++) * alpha_level/255; *dst32++ |= pixel | (alpha << 24); } } } break; } } xstart += font->current->advance; if ( font->style & SGE_TTF_BOLD ) { xstart += font->glyph_overhang; } } } /* Handle the underline style */ if ( font->style & SGE_TTF_UNDERLINE ) { int row_offset; row_offset = font->ascent - font->underline_offset - 1; if ( row_offset > textbuf->h ) { row_offset = (textbuf->h-1) - font->underline_height; } if(_sge_TTF_AA==0){ dst = (Uint8 *)textbuf->pixels + row_offset * textbuf->pitch; for ( row=font->underline_height; row>0; --row ) { memset(dst, 1, textbuf->w ); dst += textbuf->pitch; } }else if(_sge_TTF_AA==1){ dst = (Uint8 *)textbuf->pixels + row_offset * textbuf->pitch; for ( row=font->underline_height; row>0; --row ) { memset(dst, NUM_GRAYS - 1, textbuf->w ); dst += textbuf->pitch; } }else{ //pixel |= Amask; pixel |= (alpha_level << 24); dst32 = (Uint32 *)textbuf->pixels+row_offset*textbuf->pitch/4; for ( row=font->underline_height; row>0; --row ) { for ( col=0; col < textbuf->w; ++col ) { dst32[col] = pixel; } dst32 += textbuf->pitch/4; } } } return(textbuf); } SDL_Surface *sge_TTF_RenderUNICODE(sge_TTFont *font,const Uint16 *text, SDL_Color fg, SDL_Color bg) { return sge_TTF_Render(font, text, fg, bg, SDL_ALPHA_OPAQUE); } //================================================================================== // Renders the Unicode string to TrueType on surface, with the color fcolor. // bcolor is the target color for the antialiasing. // Alpha sets the transparency of the text (255-solid, 0-max). //================================================================================== SDL_Rect sge_tt_textout_UNI(SDL_Surface *Surface, sge_TTFont *font, const Uint16 *uni, Sint16 x, Sint16 y, Uint32 fcolor, Uint32 bcolor, int Alpha) { SDL_Rect ret; ret.x=0; ret.y=0; ret.w=0; ret.h=0; SDL_Color temp; SDL_Surface *text; text=sge_TTF_Render(font,uni,sge_GetRGB(Surface,fcolor),sge_GetRGB(Surface,bcolor), Alpha); if(text==NULL){return ret;} /* Align the surface text to the baseline */ Uint16 ascent=font->ascent; temp=sge_GetRGB(Surface,bcolor); sge_BlitTransparent(text,Surface,0,0,x,y-ascent,text->w,text->h,SDL_MapRGB(text->format,temp.r,temp.g,temp.b),Alpha); sge_UpdateRect(Surface,x,y-ascent,text->w,text->h); ret.x=x; ret.y=y-ascent; ret.w=text->w; ret.h=text->h; SDL_FreeSurface(text); return ret; } //================================================================================== // Renders the Unicode string to TrueType on surface, with the color fcolor. // bcolor is the target color for the antialiasing. // Alpha sets the transparency of the text (0-solid, 255-max). (RGB) //================================================================================== SDL_Rect sge_tt_textout_UNI(SDL_Surface *Surface, sge_TTFont *font, const Uint16 *uni, Sint16 x, Sint16 y, Uint8 fR, Uint8 fG, Uint8 fB, Uint8 bR, Uint8 bG, Uint8 bB, int Alpha) { SDL_Rect ret; ret.x=0; ret.y=0; ret.w=0; ret.h=0; SDL_Surface *text; text=sge_TTF_Render(font,uni,sge_FillPaletteEntry(fR,fG,fB),sge_FillPaletteEntry(bR,bG,bB), Alpha); if(text==NULL){return ret;} /* Align the surface text to the baseline */ Uint16 ascent=font->ascent; sge_BlitTransparent(text,Surface,0,0,x,y-ascent,text->w,text->h,SDL_MapRGB(text->format,bR,bG,bB),Alpha); sge_UpdateRect(Surface,x,y-ascent,text->w,text->h); ret.x=x; ret.y=y-ascent; ret.w=text->w; ret.h=text->h; SDL_FreeSurface(text); return ret; } //================================================================================== // Renders the Latin-1 string to TrueType on surface, with the color fcolor. // bcolor is the target color for the antialiasing. // Alpha sets the transparency of the text (0-solid, 255-max). //================================================================================== SDL_Rect sge_tt_textout(SDL_Surface *Surface, sge_TTFont *font, const char *string, Sint16 x, Sint16 y, Uint32 fcolor, Uint32 bcolor, int Alpha) { SDL_Rect ret; Uint16 *uni; uni=sge_Latin1_Uni(string); ret=sge_tt_textout_UNI(Surface,font,uni,x,y,fcolor,bcolor,Alpha); free(uni); return ret; } //================================================================================== // Renders the Latin-1 string to TrueType on surface, with the color fcolor. // bcolor is the target color for the antialiasing. // Alpha sets the transparency of the text (0-solid, 255-max). (RGB) //================================================================================== SDL_Rect sge_tt_textout(SDL_Surface *Surface, sge_TTFont *font, const char *string, Sint16 x, Sint16 y, Uint8 fR, Uint8 fG, Uint8 fB, Uint8 bR, Uint8 bG, Uint8 bB, int Alpha) { SDL_Rect ret; Uint16 *uni; uni=sge_Latin1_Uni(string); ret=sge_tt_textout_UNI(Surface,font,uni,x,y, fR,fG,fB, bR,bG,bB, Alpha); free(uni); return ret; } //================================================================================== // Renders the UTF-8 string to TrueType on surface, with the color fcolor. // bcolor is the target color for the antialiasing. // Alpha sets the transparency of the text (0-solid, 255-max). //================================================================================== SDL_Rect sge_tt_textout_UTF8(SDL_Surface *Surface, sge_TTFont *font, const char *string, Sint16 x, Sint16 y, Uint32 fcolor, Uint32 bcolor, int Alpha) { SDL_Rect ret; Uint16 *uni; uni=sge_UTF8_Uni(string); ret=sge_tt_textout_UNI(Surface,font,uni,x,y,fcolor,bcolor,Alpha); free(uni); return ret; } //================================================================================== // Renders the UTF-8 string to TrueType on surface, with the color fcolor. // bcolor is the target color for the antialiasing. // Alpha sets the transparency of the text (0-solid, 255-max). (RGB) //================================================================================== SDL_Rect sge_tt_textout_UTF8(SDL_Surface *Surface, sge_TTFont *font, const char *string, Sint16 x, Sint16 y, Uint8 fR, Uint8 fG, Uint8 fB, Uint8 bR, Uint8 bG, Uint8 bB, int Alpha) { SDL_Rect ret; Uint16 *uni; uni=sge_UTF8_Uni(string); ret=sge_tt_textout_UNI(Surface,font,uni,x,y, fR,fG,fB, bR,bG,bB, Alpha); free(uni); return ret; } //================================================================================== // Renders the formatet Latin-1 string to TrueType on surface, with the color fcolor. // bcolor is the target color for the antialiasing. // Alpha sets the transparency of the text (0-solid, 255-max). (RGB ONLY) // * just like printf(char *format,...) * //================================================================================== SDL_Rect sge_tt_textoutf(SDL_Surface *Surface, sge_TTFont *font, Sint16 x, Sint16 y, Uint8 fR, Uint8 fG, Uint8 fB, Uint8 bR, Uint8 bG, Uint8 bB, int Alpha ,char *format,...) { char buf[256]; va_list ap; #ifdef __WIN32__ va_start((va_list*)ap, format); //Stupid win32 crosscompiler #else va_start(ap, format); #endif vsprintf(buf, format, ap); va_end(ap); return sge_tt_textout(Surface, font, buf, x,y, fR,fG,fB, bR,bG,bB, Alpha); } /**********************************************************************************/ /** TTF 'input' functions **/ /**********************************************************************************/ // The old code that once lurked here has been replaced by shiny new code that uses // the text classes. int sge_tt_input(SDL_Surface *screen, sge_TTFont *font, char *string, Uint8 flags,int pos, int len, Sint16 x,Sint16 y, Uint8 fR,Uint8 fG,Uint8 fB, Uint8 bR,Uint8 bG,Uint8 bB, int Alpha) { if( pos==0 && len>0 ) string[0] = '\0'; sge_TextSurface text(screen, string, x, y-sge_TTF_FontAscent(font)); text.set_ttFont(font, fR,fG,fB, bR, bG, bB); text.show_cursor(true); text.set_alpha(Alpha); text.max_chars(len-1); int ret = sge_text_input(&text, flags); strncpy( string, text.get_string(false).c_str(), sizeof(char)*len ); return ret; } int sge_tt_input_UNI(SDL_Surface *screen, sge_TTFont *font, Uint16 *string, Uint8 flags, int pos, int len, Sint16 x,Sint16 y, Uint8 fR,Uint8 fG,Uint8 fB, Uint8 bR,Uint8 bG,Uint8 bB, int Alpha) { sge_TextSurface text(screen, "", x, y-sge_TTF_FontAscent(font)); if( pos!=0 ) text.change_uctext(string); text.set_ttFont(font, fR,fG,fB, bR, bG, bB); text.show_cursor(true); text.set_alpha(Alpha); text.max_chars(len-1); int ret = sge_text_input(&text, flags); Uint16 *tmp = text.get_ucstring(false); strncpy( (char*)string, (char*)tmp, sizeof(Uint16)*len ); delete[] tmp; return ret; } int sge_tt_input_UNI(SDL_Surface *screen, sge_TTFont *font, Uint16 *string, Uint8 flags, int pos,int len, Sint16 x,Sint16 y, Uint32 fcol,Uint32 bcol, int Alpha) { Uint8 fr,fg,fb, br,bg,bb; SDL_GetRGB(fcol, screen->format, &fr, &fg, &fb); SDL_GetRGB(bcol, screen->format, &br, &bg, &bb); return sge_tt_input_UNI(screen, font, string, flags, pos,len, x,y, fr,fg,fb, br,bg,bb, Alpha); } int sge_tt_input(SDL_Surface *screen, sge_TTFont *font, char *string, Uint8 flags, int pos,int len, Sint16 x,Sint16 y, Uint32 fcol,Uint32 bcol, int Alpha) { Uint8 fr,fg,fb, br,bg,bb; SDL_GetRGB(fcol, screen->format, &fr, &fg, &fb); SDL_GetRGB(bcol, screen->format, &br, &bg, &bb); return sge_tt_input(screen, font, string, flags, pos,len, x,y, fr,fg,fb, br,bg,bb, Alpha); } #endif /* _SGE_NOTTF */ sge030809/sge_rotation.cpp0000644000175000001440000005164007713172503014233 0ustar samusers/* * SDL Graphics Extension * Rotation routines * * Started 000625 * * License: LGPL v2+ (see the file LICENSE) * (c)1999-2003 Anders Lindstrm */ /********************************************************************* * This library is free software; you can redistribute it and/or * * modify it under the terms of the GNU Library General Public * * License as published by the Free Software Foundation; either * * version 2 of the License, or (at your option) any later version. * *********************************************************************/ #include "SDL.h" #include #include #include "sge_rotation.h" #include "sge_surface.h" #include "sge_blib.h" #define SWAP(x,y,temp) temp=x;x=y;y=temp extern Uint8 _sge_update; //Declared in sge_draw.cpp extern Uint8 _sge_lock; SDL_Rect sge_transform_tmap(SDL_Surface *src, SDL_Surface *dst, float angle, float xscale, float yscale, Uint16 qx, Uint16 qy); //================================================================================== // Helper function to sge_transform() // Returns the bounding box //================================================================================== void _calcRect(SDL_Surface *src, SDL_Surface *dst, float theta, float xscale, float yscale, Uint16 px, Uint16 py, Uint16 qx, Uint16 qy, Sint16 *xmin, Sint16 *ymin, Sint16 *xmax, Sint16 *ymax) { Sint16 x, y, rx, ry; // Clip to src surface Sint16 sxmin = sge_clip_xmin(src); Sint16 sxmax = sge_clip_xmax(src); Sint16 symin = sge_clip_ymin(src); Sint16 symax = sge_clip_ymax(src); Sint16 sx[]={sxmin, sxmax, sxmin, sxmax}; Sint16 sy[]={symin, symax, symax, symin}; // We don't really need fixed-point here // but why not? Sint32 const istx = Sint32((sin(theta)*xscale) * 8192.0); /* Inverse transform */ Sint32 const ictx = Sint32((cos(theta)*xscale) * 8192.2); Sint32 const isty = Sint32((sin(theta)*yscale) * 8192.0); Sint32 const icty = Sint32((cos(theta)*yscale) * 8192.2); //Calculate the four corner points for(int i=0; i<4; i++){ rx = sx[i] - px; ry = sy[i] - py; x = Sint16(((ictx*rx - isty*ry) >> 13) + qx); y = Sint16(((icty*ry + istx*rx) >> 13) + qy); if(i==0){ *xmax = *xmin = x; *ymax = *ymin = y; }else{ if(x>*xmax) *xmax=x; else if(x<*xmin) *xmin=x; if(y>*ymax) *ymax=y; else if(y<*ymin) *ymin=y; } } //Better safe than sorry... *xmin -= 1; *ymin -= 1; *xmax += 1; *ymax += 1; //Clip to dst surface if( !dst ) return; if( *xmin < sge_clip_xmin(dst) ) *xmin = sge_clip_xmin(dst); if( *xmax > sge_clip_xmax(dst) ) *xmax = sge_clip_xmax(dst); if( *ymin < sge_clip_ymin(dst) ) *ymin = sge_clip_ymin(dst); if( *ymax > sge_clip_ymax(dst) ) *ymax = sge_clip_ymax(dst); } /*================================================================================== ** Rotate by angle about pivot (px,py) scale by scale and place at ** position (qx,qy). ** ** Transformation matrix application (rotated coords "R"): ** ** / rx \ / cos(theta) sin(theta) \ / dx \ ** | | = | | | | ** \ ry / \ -sin(theta) cos(theta) / \ dy / ** ** => rx = cos(theta) dx + sin(theta) dy ** ry = cos(theta) dy - sin(theta) dx ** but represented as a fixed-point float using integer math ** ** Developed with the help from Terry Hancock (hancock@earthlink.net) ** **==================================================================================*/ // First we need some macros to handle different bpp // I'm sorry about this... #define TRANSFORM(UintXX, DIV) \ Sint32 const src_pitch=src->pitch/DIV; \ Sint32 const dst_pitch=dst->pitch/DIV; \ UintXX const *src_row = (UintXX *)src->pixels; \ UintXX *dst_row; \ \ for (y=ymin; ypixels + y*dst_pitch; \ \ for (x=xmin; x> 13); /* Convert from fixed-point */ \ ry=Sint16(sy >> 13); \ \ /* Make sure the source pixel is actually in the source image. */ \ if( (rx>=sxmin) && (rx<=sxmax) && (ry>=symin) && (ry<=symax) ) \ *(dst_row + x) = *(src_row + ry*src_pitch + rx); \ \ sx += ctx; /* Incremental transformations */ \ sy -= sty; \ } \ } #define TRANSFORM_GENERIC \ Uint8 R, G, B, A; \ \ for (y=ymin; y> 13); /* Convert from fixed-point */ \ ry=Sint16(sy >> 13); \ \ /* Make sure the source pixel is actually in the source image. */ \ if( (rx>=sxmin) && (rx<=sxmax) && (ry>=symin) && (ry<=symax) ){ \ sge_GetRGBA(sge_GetPixel(src,rx,ry), src->format, &R, &G, &B, &A);\ _PutPixelX(dst,x,y,sge_MapRGBA(dst->format, R, G, B, A)); \ \ } \ sx += ctx; /* Incremental transformations */ \ sy -= sty; \ } \ } // Interpolated transform #define TRANSFORM_AA(UintXX, DIV) \ Sint32 const src_pitch=src->pitch/DIV; \ Sint32 const dst_pitch=dst->pitch/DIV; \ UintXX const *src_row = (UintXX *)src->pixels; \ UintXX *dst_row; \ UintXX c1, c2, c3, c4;\ Uint32 R, G, B, A=0; \ UintXX Rmask = src->format->Rmask, Gmask = src->format->Gmask, Bmask = src->format->Bmask, Amask = src->format->Amask;\ Uint32 wx, wy;\ Uint32 p1, p2, p3, p4;\ \ /* * Interpolation: * We calculate the distances from our point to the four nearest pixels, d1..d4. * d(a,b) = sqrt(a+b) ~= 0.707(a+b) (Pythagoras (Taylor) expanded around (0.5;0.5)) * * 1 wx 2 * *-|-* (+ = our point at (x,y)) * | | | (* = the four nearest pixels) * wy --+ | wx = float(x) - int(x) * | | wy = float(y) - int(y) * *---* * 3 4 * d1 = d(wx,wy) d2 = d(1-wx,wy) d3 = d(wx,1-wy) d4 = d(1-wx,1-wy) * We now want to weight each pixels importance - it's vicinity to our point: * w1=d4 w2=d3 w3=d2 w4=d1 (Yes it works... just think a bit about it) * * If the pixels have the colors c1..c4 then our point should have the color * c = (w1*c1 + w2*c2 + w3*c3 + w4*c4)/(w1+w2+w3+w4) (the weighted average) * but w1+w2+w3+w4 = 4*0.707 so we might as well write it as * c = p1*c1 + p2*c2 + p3*c3 + p4*c4 where p1..p4 = (w1..w4)/(4*0.707) * * But p1..p4 are fixed point so we can just divide the fixed point constant! * 8192/(4*0.71) = 2897 and we can skip 0.71 too (the division will cancel it everywhere) * 8192/4 = 2048 * * 020102: I changed the fixed-point representation for the variables in the weighted average * to 24.7 to avoid problems with 32bit colors. Everything else is still 18.13. This * does however not solve the problem with 32bit RGBA colors... */\ \ Sint32 const one = 2048>>6; /* 1 in Fixed-point */ \ Sint32 const two = 2*2048>>6; /* 2 in Fixed-point */ \ \ for (y=ymin; ypixels + y*dst_pitch; \ \ for (x=xmin; x> 13); /* Convert from fixed-point */ \ ry=Sint16(sy >> 13); \ \ /* Make sure the source pixel is actually in the source image. */ \ if( (rx>=sxmin) && (rx+1<=sxmax) && (ry>=symin) && (ry+1<=symax) ){ \ wx = (sx & 0x00001FFF) >>8; /* (float(x) - int(x)) / 4 */ \ wy = (sy & 0x00001FFF) >>8;\ \ p4 = wx+wy;\ p3 = one-wx+wy;\ p2 = wx+one-wy;\ p1 = two-wx-wy;\ \ c1 = *(src_row + ry*src_pitch + rx);\ c2 = *(src_row + ry*src_pitch + rx+1);\ c3 = *(src_row + (ry+1)*src_pitch + rx);\ c4 = *(src_row + (ry+1)*src_pitch + rx+1);\ \ /* Calculate the average */\ R = ((p1*(c1 & Rmask) + p2*(c2 & Rmask) + p3*(c3 & Rmask) + p4*(c4 & Rmask))>>7) & Rmask;\ G = ((p1*(c1 & Gmask) + p2*(c2 & Gmask) + p3*(c3 & Gmask) + p4*(c4 & Gmask))>>7) & Gmask;\ B = ((p1*(c1 & Bmask) + p2*(c2 & Bmask) + p3*(c3 & Bmask) + p4*(c4 & Bmask))>>7) & Bmask;\ if(Amask)\ A = ((p1*(c1 & Amask) + p2*(c2 & Amask) + p3*(c3 & Amask) + p4*(c4 & Amask))>>7) & Amask;\ \ *(dst_row + x) = R | G | B | A;\ } \ sx += ctx; /* Incremental transformations */ \ sy -= sty; \ } \ } #define TRANSFORM_GENERIC_AA \ Uint8 R, G, B, A, R1, G1, B1, A1=0, R2, G2, B2, A2=0, R3, G3, B3, A3=0, R4, G4, B4, A4=0; \ Sint32 wx, wy, p1, p2, p3, p4;\ \ Sint32 const one = 2048; /* 1 in Fixed-point */ \ Sint32 const two = 2*2048; /* 2 in Fixed-point */ \ \ for (y=ymin; y> 13); /* Convert from fixed-point */ \ ry=Sint16(sy >> 13); \ \ /* Make sure the source pixel is actually in the source image. */ \ if( (rx>=sxmin) && (rx+1<=sxmax) && (ry>=symin) && (ry+1<=symax) ){ \ wx = (sx & 0x00001FFF) >> 2; /* (float(x) - int(x)) / 4 */ \ wy = (sy & 0x00001FFF) >> 2;\ \ p4 = wx+wy;\ p3 = one-wx+wy;\ p2 = wx+one-wy;\ p1 = two-wx-wy;\ \ sge_GetRGBA(sge_GetPixel(src,rx, ry), src->format, &R1, &G1, &B1, &A1);\ sge_GetRGBA(sge_GetPixel(src,rx+1,ry), src->format, &R2, &G2, &B2, &A2);\ sge_GetRGBA(sge_GetPixel(src,rx, ry+1), src->format, &R3, &G3, &B3, &A3);\ sge_GetRGBA(sge_GetPixel(src,rx+1,ry+1), src->format, &R4, &G4, &B4, &A4);\ \ /* Calculate the average */\ R = (p1*R1 + p2*R2 + p3*R3 + p4*R4)>>13;\ G = (p1*G1 + p2*G2 + p3*G3 + p4*G4)>>13;\ B = (p1*B1 + p2*B2 + p3*B3 + p4*B4)>>13;\ A = (p1*A1 + p2*A2 + p3*A3 + p4*A4)>>13;\ \ _PutPixelX(dst,x,y,sge_MapRGBA(dst->format, R, G, B, A)); \ \ } \ sx += ctx; /* Incremental transformations */ \ sy -= sty; \ } \ } // We get better performance if AA and normal rendering is seperated into two functions (better optimization). // sge_transform() is used as a wrapper. SDL_Rect sge_transformNorm(SDL_Surface *src, SDL_Surface *dst, float angle, float xscale, float yscale ,Uint16 px, Uint16 py, Uint16 qx, Uint16 qy, Uint8 flags) { Sint32 dy, sx, sy; Sint16 x, y, rx, ry; SDL_Rect r; r.x = r.y = r.w = r.h = 0; float theta = float(angle*PI/180.0); /* Convert to radians. */ // Here we use 18.13 fixed point integer math // Sint32 should have 31 usable bits and one for sign // 2^13 = 8192 // Check scales Sint32 maxint = Sint32(pow(2, sizeof(Sint32)*8 - 1 - 13)); // 2^(31-13) if( xscale == 0 || yscale == 0) return r; if( 8192.0/xscale > maxint ) xscale = float(8192.0/maxint); else if( 8192.0/xscale < -maxint ) xscale = float(-8192.0/maxint); if( 8192.0/yscale > maxint ) yscale = float(8192.0/maxint); else if( 8192.0/yscale < -maxint ) yscale = float(-8192.0/maxint); // Fixed-point equivalents Sint32 const stx = Sint32((sin(theta)/xscale) * 8192.0); Sint32 const ctx = Sint32((cos(theta)/xscale) * 8192.0); Sint32 const sty = Sint32((sin(theta)/yscale) * 8192.0); Sint32 const cty = Sint32((cos(theta)/yscale) * 8192.0); Sint32 const mx = Sint32(px*8192.0); Sint32 const my = Sint32(py*8192.0); // Compute a bounding rectangle Sint16 xmin=0, xmax=dst->w, ymin=0, ymax=dst->h; _calcRect(src, dst, theta, xscale, yscale, px, py, qx, qy, &xmin,&ymin, &xmax,&ymax); // Clip to src surface Sint16 sxmin = sge_clip_xmin(src); Sint16 sxmax = sge_clip_xmax(src); Sint16 symin = sge_clip_ymin(src); Sint16 symax = sge_clip_ymax(src); // Some terms in the transform are constant Sint32 const dx = xmin - qx; Sint32 const ctdx = ctx*dx; Sint32 const stdx = sty*dx; // Lock surfaces... hopfully less than two needs locking! if ( SDL_MUSTLOCK(src) && _sge_lock ) if ( SDL_LockSurface(src) < 0 ) return r; if ( SDL_MUSTLOCK(dst) && _sge_lock ){ if ( SDL_LockSurface(dst) < 0 ){ if ( SDL_MUSTLOCK(src) && _sge_lock ) SDL_UnlockSurface(src); return r; } } // Use the correct bpp if( src->format->BytesPerPixel == dst->format->BytesPerPixel && src->format->BytesPerPixel != 3 && !(flags&SGE_TSAFE) ){ switch( src->format->BytesPerPixel ){ case 1: { /* Assuming 8-bpp */ TRANSFORM(Uint8, 1) } break; case 2: { /* Probably 15-bpp or 16-bpp */ TRANSFORM(Uint16, 2) } break; case 4: { /* Probably 32-bpp */ TRANSFORM(Uint32, 4) } break; } }else{ TRANSFORM_GENERIC } // Unlock surfaces if ( SDL_MUSTLOCK(src) && _sge_lock ) SDL_UnlockSurface(src); if ( SDL_MUSTLOCK(dst) && _sge_lock ) SDL_UnlockSurface(dst); //Return the bounding rectangle r.x=xmin; r.y=ymin; r.w=xmax-xmin; r.h=ymax-ymin; return r; } SDL_Rect sge_transformAA(SDL_Surface *src, SDL_Surface *dst, float angle, float xscale, float yscale ,Uint16 px, Uint16 py, Uint16 qx, Uint16 qy, Uint8 flags) { Sint32 dy, sx, sy; Sint16 x, y, rx, ry; SDL_Rect r; r.x = r.y = r.w = r.h = 0; float theta = float(angle*PI/180.0); /* Convert to radians. */ // Here we use 18.13 fixed point integer math // Sint32 should have 31 usable bits and one for sign // 2^13 = 8192 // Check scales Sint32 maxint = Sint32(pow(2, sizeof(Sint32)*8 - 1 - 13)); // 2^(31-13) if( xscale == 0 || yscale == 0) return r; if( 8192.0/xscale > maxint ) xscale = float(8192.0/maxint); else if( 8192.0/xscale < -maxint ) xscale = float(-8192.0/maxint); if( 8192.0/yscale > maxint ) yscale = float(8192.0/maxint); else if( 8192.0/yscale < -maxint ) yscale = float(-8192.0/maxint); // Fixed-point equivalents Sint32 const stx = Sint32((sin(theta)/xscale) * 8192.0); Sint32 const ctx = Sint32((cos(theta)/xscale) * 8192.0); Sint32 const sty = Sint32((sin(theta)/yscale) * 8192.0); Sint32 const cty = Sint32((cos(theta)/yscale) * 8192.0); Sint32 const mx = Sint32(px*8192.0); Sint32 const my = Sint32(py*8192.0); // Compute a bounding rectangle Sint16 xmin=0, xmax=dst->w, ymin=0, ymax=dst->h; _calcRect(src, dst, theta, xscale, yscale, px, py, qx, qy, &xmin,&ymin, &xmax,&ymax); // Clip to src surface Sint16 sxmin = sge_clip_xmin(src); Sint16 sxmax = sge_clip_xmax(src); Sint16 symin = sge_clip_ymin(src); Sint16 symax = sge_clip_ymax(src); // Some terms in the transform are constant Sint32 const dx = xmin - qx; Sint32 const ctdx = ctx*dx; Sint32 const stdx = sty*dx; // Lock surfaces... hopfully less than two needs locking! if ( SDL_MUSTLOCK(src) && _sge_lock ) if ( SDL_LockSurface(src) < 0 ) return r; if ( SDL_MUSTLOCK(dst) && _sge_lock ){ if ( SDL_LockSurface(dst) < 0 ){ if ( SDL_MUSTLOCK(src) && _sge_lock ) SDL_UnlockSurface(src); return r; } } // Use the correct bpp if( src->format->BytesPerPixel == dst->format->BytesPerPixel && src->format->BytesPerPixel != 3 && !(flags&SGE_TSAFE) ){ switch( src->format->BytesPerPixel ){ case 1: { /* Assuming 8-bpp */ //TRANSFORM_AA(Uint8, 1) TRANSFORM_GENERIC_AA } break; case 2: { /* Probably 15-bpp or 16-bpp */ TRANSFORM_AA(Uint16, 2) } break; case 4: { /* Probably 32-bpp */ TRANSFORM_AA(Uint32, 4) } break; } }else{ TRANSFORM_GENERIC_AA } // Unlock surfaces if ( SDL_MUSTLOCK(src) && _sge_lock ) SDL_UnlockSurface(src); if ( SDL_MUSTLOCK(dst) && _sge_lock ) SDL_UnlockSurface(dst); //Return the bounding rectangle r.x=xmin; r.y=ymin; r.w=xmax-xmin; r.h=ymax-ymin; return r; } SDL_Rect sge_transform(SDL_Surface *src, SDL_Surface *dst, float angle, float xscale, float yscale, Uint16 px, Uint16 py, Uint16 qx, Uint16 qy, Uint8 flags) { if(flags&SGE_TTMAP) return sge_transform_tmap(src, dst, angle, xscale, yscale, qx, qy); else{ if(flags&SGE_TAA) return sge_transformAA(src, dst, angle, xscale, yscale, px, py, qx, qy, flags); else return sge_transformNorm(src, dst, angle, xscale, yscale, px, py, qx, qy, flags); } } //================================================================================== // Same as sge_transform() but returns an surface with the result //================================================================================== SDL_Surface *sge_transform_surface(SDL_Surface *src, Uint32 bcol, float angle, float xscale, float yscale, Uint8 flags) { float theta = float(angle*PI/180.0); /* Convert to radians. */ // Compute a bounding rectangle Sint16 xmin=0, xmax=0, ymin=0, ymax=0; _calcRect(src, NULL, theta, xscale, yscale, 0, 0, 0, 0, &xmin,&ymin, &xmax,&ymax); Sint16 w = xmax-xmin+1; Sint16 h = ymax-ymin+1; Sint16 qx = -xmin; Sint16 qy = -ymin; SDL_Surface *dest; dest = SDL_CreateRGBSurface(SDL_SWSURFACE, w, h, src->format->BitsPerPixel, src->format->Rmask, src->format->Gmask, src->format->Bmask, src->format->Amask); if(!dest) return NULL; sge_ClearSurface(dest,bcol); //Set background color sge_transform(src, dest, angle, xscale, yscale, 0, 0, qx, qy, flags); return dest; } //================================================================================== // Rotate using texture mapping //================================================================================== SDL_Rect sge_transform_tmap(SDL_Surface *src, SDL_Surface *dst, float angle, float xscale, float yscale, Uint16 qx, Uint16 qy) { double rad; double a=(sge_clip_xmax(src) - sge_clip_xmin(src))/2.0; double b=(sge_clip_ymax(src) - sge_clip_ymin(src))/2.0; double cosv, sinv; //Get an exact value if possible if(angle==0.0 || angle==360.0){ cosv=1; sinv=0; } else if(angle==90.0){ cosv=0; sinv=1; } else if(angle==180.0){ cosv=-1; sinv=0; } else if(angle==270.0){ cosv=0; sinv=-1; } else{ //Oh well rad=angle*(PI/180.0); //Deg => rad cosv=cos(rad); sinv=sin(rad); } //Precalculate as much as possible double acosv=a*cosv*xscale, bcosv=b*cosv*yscale; double asinv=a*sinv*xscale, bsinv=b*sinv*yscale; /* Do the maths */ Sint16 xt[4],yt[4]; xt[0] = Sint16((-acosv+bsinv)+qx); yt[0] = Sint16((-asinv-bcosv)+qy); xt[1] = Sint16((acosv+bsinv)+qx); yt[1] = Sint16((asinv-bcosv)+qy); xt[2] = Sint16((-acosv-bsinv)+qx); yt[2] = Sint16((-asinv+bcosv)+qy); xt[3] = Sint16((acosv-bsinv)+qx); yt[3] = Sint16((asinv+bcosv)+qy); //Use a texture mapped rectangle sge_TexturedRect(dst,xt[0],yt[0],xt[1],yt[1],xt[2],yt[2],xt[3],yt[3],src, sge_clip_xmin(src),sge_clip_ymin(src), sge_clip_xmax(src),sge_clip_ymin(src), sge_clip_xmin(src),sge_clip_ymax(src), sge_clip_xmax(src),sge_clip_ymax(src)); //Or maybe two trigons... //sge_TexturedTrigon(dest,xt[0],yt[0],xt[1],yt[1],xt[2],yt[2],src, sge_clip_xmin(src),sge_clip_ymin(src), sge_clip_xmax(src),sge_clip_ymin(src), sge_clip_xmin(src),sge_clip_ymax(src)); //sge_TexturedTrigon(dest,xt[3],yt[3],xt[1],yt[1],xt[2],yt[2],src, sge_clip_xmax(src),sge_clip_ymax(src), sge_clip_xmax(src),sge_clip_ymin(src), sge_clip_xmin(src),sge_clip_ymax(src)); //For debug //sge_Trigon(dest,xt[0],yt[0],xt[1],yt[1],xt[2],yt[2],SDL_MapRGB(dest->format,255,0,0)); //sge_Trigon(dest,xt[3],yt[3],xt[1],yt[1],xt[2],yt[2],SDL_MapRGB(dest->format,0,255,0)); Sint16 xmax=xt[0], xmin=xt[0]; xmax= (xmax>xt[1])? xmax : xt[1]; xmin= (xminxt[2])? xmax : xt[2]; xmin= (xminxt[3])? xmax : xt[3]; xmin= (xminyt[1])? ymax : yt[1]; ymin= (yminyt[2])? ymax : yt[2]; ymin= (yminyt[3])? ymax : yt[3]; ymin= (yminh*src->h/2 + src->w*src->w/2) *scale + 1 ) ); dest=SDL_AllocSurface(SDL_SWSURFACE, max, max, src->format->BitsPerPixel, src->format->Rmask, src->format->Gmask, src->format->Bmask, src->format->Amask ); if(!dest){SDL_SetError("SGE - Out of memory");return NULL;} sge_ClearSurface(dest,bcol); sge_transform(src, dest, float(angle), float(scale), float(scale), src->w/2,src->h/2, dest->w/2,dest->h/2,0); return(dest); } SDL_Surface *sge_rotate_surface(SDL_Surface *src, int angle, Uint32 bcol) { return sge_rotate_scaled_surface(src, angle, 1.0, bcol); } SDL_Rect sge_rotate_xyscaled(SDL_Surface *dest, SDL_Surface *src, Sint16 x, Sint16 y, int angle, double xscale, double yscale) { SDL_Rect ret; ret=sge_transform(src, dest, float(angle), float(xscale), float(yscale), src->w/2,src->h/2, x,y,0); if(_sge_update) sge_UpdateRect(dest,ret.x,ret.y,ret.w+1,ret.h+1); return ret; } SDL_Rect sge_rotate_scaled(SDL_Surface *dest, SDL_Surface *src, Sint16 x, Sint16 y, int angle, double scale) { return sge_rotate_xyscaled(dest,src,x,y,angle,scale,scale); } SDL_Rect sge_rotate(SDL_Surface *dest, SDL_Surface *src, Sint16 x, Sint16 y, int angle) { return sge_rotate_xyscaled(dest,src,x,y,angle,1.0,1.0); } sge030809/sge_bm_text.cpp0000644000175000001440000003164207714717476014055 0ustar samusers/* * SDL Graphics Extension * Text/Bitmap font functions * * Started 990815 * * License: LGPL v2+ (see the file LICENSE) * (c)1999-2003 Anders Lindstrm */ /********************************************************************* * This library is free software; you can redistribute it and/or * * modify it under the terms of the GNU Library General Public * * License as published by the Free Software Foundation; either * * version 2 of the License, or (at your option) any later version. * *********************************************************************/ /* * Some of this is taken from SDL_DrawText by Garrett Banuk (mongoose@wpi.edu) * http://www.wpi.edu/~mongoose/SDL_Console * Thanks to Karl Bartel for the SFont format! */ #include "SDL.h" #include #include #include #include #include "sge_surface.h" #include "sge_bm_text.h" #include "sge_tt_text.h" #include "sge_textpp.h" #ifdef _SGE_HAVE_IMG #include #endif using namespace std; /* Globals used for sge_Update/sge_Lock (defined in sge_surface) */ extern Uint8 _sge_update; extern Uint8 _sge_lock; //================================================================================== // Creates a new font from a surface //================================================================================== sge_bmpFont* sge_BF_CreateFont(SDL_Surface *surface, Uint8 flags) { sge_bmpFont *font; font = new(nothrow) sge_bmpFont; if(font==NULL){SDL_SetError("SGE - Out of memory");return NULL;} if(!(flags&SGE_BFNOCONVERT) && !(flags&SGE_BFSFONT)){ /* Get a converted copy */ font->FontSurface = SDL_DisplayFormat(surface); if(font->FontSurface==NULL){SDL_SetError("SGE - Out of memory");return NULL;} if(flags&SGE_BFPALETTE){ //We want an 8bit surface SDL_Surface *tmp; tmp = SDL_AllocSurface(SDL_SWSURFACE, surface->w, surface->h, 8, 0, 0, 0, 0); if(tmp==NULL){SDL_SetError("SGE - Out of memory");SDL_FreeSurface(font->FontSurface);return NULL;} //Set the palette SDL_Color c[2]; c[0].r=0; c[1].r=255; c[0].g=0; c[1].g=255; c[0].b=0; c[1].b=255; SDL_SetColors(tmp, c, 0, 2); if (SDL_MUSTLOCK(font->FontSurface) && _sge_lock) if (SDL_LockSurface(font->FontSurface) < 0){ SDL_SetError("SGE - Locking error"); SDL_FreeSurface(font->FontSurface); return NULL; } //Copy the font to the 8bit surface Sint16 x,y; Uint32 bc=sge_GetPixel(font->FontSurface,0,surface->h-1); for(y=0; yFontSurface->h; y++){ for(x=0; xFontSurface->w; x++){ if(sge_GetPixel(font->FontSurface,x,y)==bc) *((Uint8 *)tmp->pixels + y * tmp->pitch + x)=0; else *((Uint8 *)tmp->pixels + y * tmp->pitch + x)=1; } } if (SDL_MUSTLOCK(font->FontSurface) && _sge_lock) { SDL_UnlockSurface(font->FontSurface); } //sge_Blit(surface, tmp, 0,0,0,0,surface->w, surface->h); SDL_FreeSurface(font->FontSurface); font->FontSurface=tmp; } if((flags&SGE_FLAG8)) SDL_FreeSurface(surface); } else if(flags&SGE_FLAG8) /* Use the source */ font->FontSurface = surface; else /* Get a copy */ font->FontSurface = sge_copy_surface(surface); if(font->FontSurface==NULL){SDL_SetError("SGE - Out of memory");return NULL;} SDL_Surface *fnt = font->FontSurface; //Shorthand font->Chars=0; if(!(flags&SGE_BFSFONT)){ /* Fixed width font */ font->CharWidth = font->FontSurface->w/256; font->CharHeight = font->FontSurface->h; font->CharPos = NULL; font->yoffs = 0; font->Chars=256; } else{ /* Karl Bartel's sfont */ Sint16 x=0; int i=0; font->CharPos = new(nothrow) Sint16[256]; if(!font->CharPos){SDL_SetError("SGE - Out of memory");sge_BF_CloseFont(font);return NULL;} Uint32 color = sge_GetPixel(fnt,0,0); //get data color while ( x < fnt->w && font->Chars < 256 ){ if (sge_GetPixel(fnt,x,0)==color) { font->CharPos[i++]=x; while ( x < fnt->w-1 && sge_GetPixel(fnt,x,0) == color ) x++; font->CharPos[i++]=x; font->Chars++; } x++; } font->CharHeight = font->FontSurface->h-1; font->CharWidth = 0; font->yoffs = 1; } /* Set font as transparent if the flag is set */ if (SDL_MUSTLOCK(font->FontSurface) && _sge_lock) if (SDL_LockSurface(font->FontSurface) < 0){ return font; } font->bcolor=sge_GetPixel(font->FontSurface,0,font->FontSurface->h-1); if (SDL_MUSTLOCK(font->FontSurface) && _sge_lock) { SDL_UnlockSurface(font->FontSurface); } if(flags&SGE_BFTRANSP || flags&SGE_BFSFONT) #if SDL_VERSIONNUM(SDL_MAJOR_VERSION, SDL_MINOR_VERSION, SDL_PATCHLEVEL) >= \ SDL_VERSIONNUM(1, 1, 4) SDL_SetColorKey(font->FontSurface,SDL_SRCCOLORKEY, font->bcolor); //Some versions of SDL have a bug with SDL_RLEACCEL #else SDL_SetColorKey(font->FontSurface,SDL_SRCCOLORKEY|SDL_RLEACCEL, font->bcolor); #endif return font; } //================================================================================== // Loads the font into a new struct //================================================================================== sge_bmpFont* sge_BF_OpenFont(char *file, Uint8 flags) { sge_bmpFont *font; SDL_Surface *Temp; /* load the font bitmap */ #ifdef _SGE_HAVE_IMG if(NULL == (Temp = IMG_Load(file))) //We have SDL_Img lib! #else if(NULL == (Temp = SDL_LoadBMP(file))) //We can only load bmp files... #endif { sge_SetError("SGE - Couldn't load font file: %s",file); return NULL; } font = sge_BF_CreateFont(Temp,flags|SGE_FLAG8); //SGE_FLAG8 - no need to make a copy of the surface return font; } //================================================================================== // Draws string to surface with the selected font // Returns pos. and size of the drawn text //================================================================================== SDL_Rect sge_BF_textout(SDL_Surface *surface, sge_bmpFont *font, char *string, Sint16 x, Sint16 y) { SDL_Rect ret; ret.x=0;ret.y=0;ret.w=0;ret.h=0; if(font==NULL){return ret;} int characters; Sint16 xsrc,xdest,ofs,adv=font->CharWidth; float diff=0; /* Valid coords ? */ if(surface) if(x>surface->w || y>surface->h) return ret; characters = strlen(string); xdest=x; /* Now draw it */ for(int i=0; iCharPos) /* Fixed width */ xsrc = string[i] * font->CharWidth; else{ /* Variable width */ if(string[i]==' ' || (string[i]-33)>font->Chars || string[i]<33){ xdest += font->CharPos[2]-font->CharPos[1]; continue; } ofs = (string[i]-33)*2+1; xsrc = (font->CharPos[ofs]+font->CharPos[ofs-1])/2; //font->CharWidth = (font->CharPos[ofs+2]+font->CharPos[ofs+1])/2-(font->CharPos[ofs]+font->CharPos[ofs-1])/2-1; font->CharWidth = (font->CharPos[ofs+2]+font->CharPos[ofs+1])/2-(font->CharPos[ofs]+font->CharPos[ofs-1])/2; adv = font->CharPos[ofs+1]-font->CharPos[ofs]; diff =float( (font->CharPos[ofs]-font->CharPos[ofs-1])/2.0 ); } if(surface) sge_Blit(font->FontSurface, surface, xsrc,font->yoffs, int(xdest-diff),y, font->CharWidth,font->CharHeight); xdest += adv; } ret.x=x; ret.y=y; ret.w=xdest-x+font->CharWidth; ret.h=font->CharHeight; if(surface) sge_UpdateRect(surface, x, y, ret.w, ret.h); return ret; } //================================================================================== // Returns the size (w and h) of the string (if rendered with font) //================================================================================== SDL_Rect sge_BF_TextSize(sge_bmpFont *font, char *string) { return sge_BF_textout(NULL, font, string, 0,0); } //================================================================================== // Draws formated text to surface with the selected font // Returns pos. and size of the drawn text // * just like printf(char *format, ...) * //================================================================================== SDL_Rect sge_BF_textoutf(SDL_Surface *surface, sge_bmpFont *font, Sint16 x, Sint16 y , char *format, ...) { char buf[256]; va_list ap; #ifdef __WIN32__ va_start((va_list*)ap, format); //Stupid w32 crosscompiler #else va_start(ap, format); #endif vsprintf(buf, format, ap); va_end(ap); return sge_BF_textout(surface, font, buf, x, y); } //================================================================================== // Returns the height of the font // Returns 0 if the struct was invalid //================================================================================== Sint16 sge_BF_GetHeight(sge_bmpFont *font) { if(font) return font->CharHeight; else return 0; } //================================================================================== // Returns the width of the font (only fixed width fonts) // Returns 0 if the struct was invalid //================================================================================== Sint16 sge_BF_GetWidth(sge_bmpFont *font) { if(font) return font->CharWidth; else return 0; } //================================================================================== // Removes font from memory //================================================================================== void sge_BF_CloseFont(sge_bmpFont *font) { if(font){ SDL_FreeSurface(font->FontSurface); if(font->CharPos) delete[] font->CharPos; delete font; font=NULL; } } //================================================================================== // Change the font color // Will not work on 'color' fonts! // Doesn't like 24bpp //================================================================================== void sge_BF_SetColor(sge_bmpFont *font, Uint8 R, Uint8 G, Uint8 B) { if(font==NULL){return;} if(!font->FontSurface->format->palette){ //Slow truecolor version Sint16 x,y; Sint16 ypnt; SDL_Surface *surface=font->FontSurface; Uint32 c_keep=font->bcolor; Uint32 color=SDL_MapRGB(font->FontSurface->format, R, G, B); switch(surface->format->BytesPerPixel){ case 1: { /* Assuming 8-bpp */ Uint8 *pnt; for(y=0; yh; y++){ ypnt=y*surface->pitch; for(x=0; xw; x++){ pnt=((Uint8 *)surface->pixels + x + ypnt); if(*pnt!=c_keep){*pnt=(Uint8)color;} } } } break; case 2: { /* Probably 15-bpp or 16-bpp */ Uint16 *pnt; for(y=0; yh; y++){ ypnt=y*surface->pitch/2; for(x=0; xw; x++){ pnt=((Uint16 *)surface->pixels + x + ypnt); if(*pnt!=c_keep){*pnt=(Uint16)color;} } } } break; case 3: { /* Slow 24-bpp mode, usually not used */ } break; case 4: { /* Probably 32-bpp */ Uint32 *pnt; for(y=0; yh; y++){ ypnt=y*surface->pitch/4; for(x=0; xw; x++){ pnt=((Uint32 *)surface->pixels + x + ypnt); if(*pnt!=c_keep){*pnt=(Uint32)color;} } } } break; } }else{ //Fast palette version SDL_Color c[2]; c[0].r=0; c[1].r=R; c[0].g=0; c[1].g=G; c[0].b=0; c[1].b=B; SDL_SetColors(font->FontSurface, c, 0, 2); } } //================================================================================== // Sets an alpha value for the font (don't work with sfonts with an alpha channel) //================================================================================== void sge_BF_SetAlpha(sge_bmpFont *font, Uint8 alpha) { SDL_SetAlpha(font->FontSurface,SDL_SRCALPHA|SDL_RLEACCEL, alpha); } //================================================================================== // BitmapText input //================================================================================== int sge_BF_inputAlpha(SDL_Surface *screen, sge_bmpFont *font, char *string, Uint8 flags, int pos,int len, Sint16 x, Sint16 y, int Alpha) { if( pos==0 && len>0 ) string[0] = '\0'; sge_TextSurface text(screen, string, x, y); text.set_bmFont(font); text.show_cursor(true); text.set_alpha(Alpha); text.max_chars(len-1); int ret = sge_text_input(&text, flags); strncpy( string, text.get_string(false).c_str(), sizeof(char)*len ); return ret; } int sge_BF_inputAlpha_UNI(SDL_Surface *screen, sge_bmpFont *font, Uint16 *string, Uint8 flags, int pos,int len, Sint16 x,Sint16 y, int Alpha) { sge_TextSurface text(screen, "", x, y); if( pos!=0 ) text.change_uctext(string); text.set_bmFont(font); text.show_cursor(true); text.set_alpha(Alpha); text.max_chars(len-1); int ret = sge_text_input(&text, flags); Uint16 *tmp = text.get_ucstring(false); strncpy( (char*)string, (char*)tmp, sizeof(Uint16)*len ); delete[] tmp; return ret; } int sge_BF_input(SDL_Surface *screen,sge_bmpFont *font,char *string, Uint8 flags, int pos,int len,Sint16 x,Sint16 y) { return sge_BF_inputAlpha(screen, font, string, flags, pos, len, x,y, SDL_ALPHA_OPAQUE); } int sge_BF_input_UNI(SDL_Surface *screen, sge_bmpFont *font, Uint16 *string, Uint8 flags, int pos,int len, Sint16 x,Sint16 y) { return sge_BF_inputAlpha_UNI(screen, font, string, flags, pos, len, x,y, SDL_ALPHA_OPAQUE); } sge030809/sge_collision.cpp0000644000175000001440000002030007713172523014356 0ustar samusers/* * SDL Graphics Extension * Collision routines * * Started 000625 * * License: LGPL v2+ (see the file LICENSE) * (c)1999-2003 Anders Lindstrm */ /********************************************************************* * This library is free software; you can redistribute it and/or * * modify it under the terms of the GNU Library General Public * * License as published by the Free Software Foundation; either * * version 2 of the License, or (at your option) any later version. * *********************************************************************/ #include "SDL.h" #include #include #include #include "sge_collision.h" #include "sge_surface.h" #include "sge_shape.h" using namespace std; Uint8 sge_mask[8]={SGE_FLAG1,SGE_FLAG2,SGE_FLAG3,SGE_FLAG4,SGE_FLAG5,SGE_FLAG6,SGE_FLAG7,SGE_FLAG8}; SDL_Rect _ua; Sint16 _cx=0,_cy=0; int memand(Uint8 *s1, Uint8 *s2, int shift1, int shift2, int N); //================================================================================== // Makes a new collision map from img. Set colorkey first! //================================================================================== sge_cdata *sge_make_cmap(SDL_Surface *img) { sge_cdata *cdata; Uint8 *map; Sint16 x,y; Sint32 offs; int i; cdata=new(nothrow) sge_cdata; if(!cdata){SDL_SetError("SGE - Out of memory");return NULL;} cdata->w=img->w; cdata->h=img->h; offs=(img->w*img->h)/8; cdata->map=new(nothrow) Uint8[offs+2]; if(!cdata->map){SDL_SetError("SGE - Out of memory");return NULL;} memset(cdata->map,0x00,offs+2); map=cdata->map; i=0; for(y=0; y < img->h; y++){ for(x=0; x < img->w; x++){ if(i>7){i=0;map++;} if(sge_GetPixel(img, Sint16(x),Sint16(y))!=img->format->colorkey){ *map=*map|sge_mask[i]; } i++; } } return cdata; } //================================================================================== // Checks bounding boxes for collision: 0-no collision 1-collision //================================================================================== int sge_bbcheck(sge_cdata *cd1,Sint16 x1,Sint16 y1, sge_cdata *cd2,Sint16 x2,Sint16 y2) { Sint16 w1=cd1->w; Sint16 h1=cd1->h; Sint16 w2=cd2->w; Sint16 h2=cd2->h; if(x1 < x2){ if(x1+w1 > x2){ if(y1 < y2){ if(y1+h1 > y2){ _ua.x=x2; _ua.y=y2; return 1; } } else{ if(y2+h2 > y1){ _ua.x=x2; _ua.y=y1; return 1; } } } } else{ if(x2+w2 > x1){ if(y2 < y1){ if(y2+h2 > y1){ _ua.x=x1; _ua.y=y1; return 1; } } else{ if(y1+h1 > y2){ _ua.x=x1; _ua.y=y2; return 1; } } } } return 0; } //================================================================================== // Checks bounding boxes for collision: 0-no collision 1-collision //================================================================================== int _sge_bbcheck(Sint16 x1,Sint16 y1,Sint16 w1,Sint16 h1, Sint16 x2,Sint16 y2,Sint16 w2,Sint16 h2) { if(x1 < x2){ if(x1+w1 > x2){ if(y1 < y2){ if(y1+h1 > y2){ _ua.x=x2; _ua.y=y2; return 1; } } else{ if(y2+h2 > y1){ _ua.x=x2; _ua.y=y1; return 1; } } } } else{ if(x2+w2 > x1){ if(y2 < y1){ if(y2+h2 > y1){ _ua.x=x1; _ua.y=y1; return 1; } } else{ if(y1+h1 > y2){ _ua.x=x1; _ua.y=y2; return 1; } } } } return 0; } //================================================================================== // AND N bits of s1 and s2 // Returns the number of the bit (or zero) //================================================================================== int memand(Uint8 *s1, Uint8 *s2, int shift1, int shift2, int N) { int b,i1=shift1,i2=shift2; for(b=0; b7){i1=0;s1++;} if(i2>7){i2=0;s2++;} if( (*s1&sge_mask[i1]) && (*s2&sge_mask[i2]) ) return b+1; i1++; i2++; } return 0; } //================================================================================== // Checks for pixel perfect collision: 0-no collision 1-collision // sge_bbcheck MUST be called first!!! //================================================================================== int _sge_cmcheck(sge_cdata *cd1,Sint16 x1,Sint16 y1, sge_cdata *cd2,Sint16 x2,Sint16 y2) { if(cd1->map==NULL || cd2->map==NULL) return 0; Sint16 w1=cd1->w; Sint16 h1=cd1->h; Sint16 w2=cd2->w; Sint16 h2=cd2->h; //masks Sint32 x1o=0,x2o=0,y1o=0,y2o=0,offs; //offsets int i1=0,i2=0; Uint8 *map1=cd1->map; Uint8 *map2=cd2->map; //Calculate correct starting point if(_ua.x==x2 && _ua.y==y2){ x1o=x2-x1; y1o=y2-y1; offs=w1*y1o+x1o; map1+=offs/8; i1=offs%8; } else if(_ua.x==x2 && _ua.y==y1){ x1o=x2-x1; y2o=y1-y2; map1+=x1o/8; i1=x1o%8; offs=w2*y2o; map2+=offs/8; i2=offs%8; } else if(_ua.x==x1 && _ua.y==y1){ x2o=x1-x2; y2o=y1-y2; offs=w2*y2o+x2o; map2+=offs/8; i2=offs%8; } else if(_ua.x==x1 && _ua.y==y2){ x2o=x1-x2; y1o=y2-y1; offs=w1*y1o; map1+=offs/8; i1=offs%8; map2+=x2o/8; i2=x2o%8; } else return 0; Sint16 y; Sint16 lenght; if(x1+w1 < x2+w2) lenght=w1-x1o; else lenght=w2-x2o; //AND(map1,map2) for(y=_ua.y; y<=y1+h1 && y<=y2+h2; y++){ offs=memand(map1,map2,i1,i2,lenght); if(offs){ _cx=_ua.x+offs-1; _cy=y; return 1; } //goto the new line offs=(y-y1)*w1+x1o; map1=cd1->map; //reset pointer map1+=offs/8; i1=offs%8; offs=(y-y2)*w2+x2o; map2=cd2->map; //reset pointer map2+=offs/8; i2=offs%8; } return 0; } //================================================================================== // Checks pixel perfect collision: 0-no collision 1-collision // calls sge_bbcheck automaticly //================================================================================== int sge_cmcheck(sge_cdata *cd1,Sint16 x1,Sint16 y1, sge_cdata *cd2,Sint16 x2,Sint16 y2) { if(!sge_bbcheck(cd1,x1,y1, cd2,x2,y2)) return 0; if(cd1->map==NULL || cd2->map==NULL) return 1; return _sge_cmcheck(cd1,x1,y1, cd2,x2,y2); } //================================================================================== // Get the position of the last collision //================================================================================== Sint16 sge_get_cx(void) { return _cx; } Sint16 sge_get_cy(void) { return _cy; } //================================================================================== // Removes collision map from memory //================================================================================== void sge_destroy_cmap(sge_cdata *cd) { if(cd->map!=NULL) delete [] cd->map; delete cd; } //================================================================================== // Checks bounding boxes for collision: 0-no collision 1-collision // (sprites) //================================================================================== #ifndef _SGE_NO_CLASSES int sge_bbcheck_shape(sge_shape *shape1, sge_shape *shape2) { return _sge_bbcheck(shape1->get_xpos(), shape1->get_ypos(), shape1->get_w(), shape1->get_h(), shape2->get_xpos(), shape2->get_ypos(), shape2->get_w(), shape2->get_h()); } #endif //================================================================================== // Clears an area in a cmap //================================================================================== void sge_unset_cdata(sge_cdata *cd, Sint16 x, Sint16 y, Sint16 w, Sint16 h) { Uint8 *map=cd->map; Sint16 offs,len; int i,n=0; offs=y*cd->w + x; map+=offs/8; i=offs%8; while(h--){ len=w; while(len--){ if(i>7){i=0;map++;} *map&=~sge_mask[i]; i++; } n++; map=cd->map; offs=(y+n)*cd->w + x; map+=offs/8; i=offs%8; } } //================================================================================== // Fills an area in a cmap //================================================================================== void sge_set_cdata(sge_cdata *cd, Sint16 x, Sint16 y, Sint16 w, Sint16 h) { Uint8 *map=cd->map; Sint16 offs,len; int i,n=0; offs=y*cd->w + x; map+=offs/8; i=offs%8; while(h--){ len=w; while(len--){ if(i>7){i=0;map++;} *map|=sge_mask[i]; i++; } n++; map=cd->map; offs=(y+n)*cd->w + x; map+=offs/8; i=offs%8; } } sge030809/sge_shape.h0000644000175000001440000002707207715147353013152 0ustar samusers/* * SDL Graphics Extension * SGE shape (header) * * Started 000430 * * License: LGPL v2+ (see the file LICENSE) * (c)2000-2003 Anders Lindstrm */ /********************************************************************* * This library is free software; you can redistribute it and/or * * modify it under the terms of the GNU Library General Public * * License as published by the Free Software Foundation; either * * version 2 of the License, or (at your option) any later version. * *********************************************************************/ #ifndef sge_shape_H #define sge_shape_H #include "SDL.h" #include "sge_internal.h" #ifndef _SGE_NO_CLASSES // Remove "class 'std::list<>' needs to have dll-interface to be used" warnings // from MS VisualC++ #ifdef _MSC_VER #pragma warning(push) #pragma warning(disable: 4251) #endif #include #include "sge_surface.h" #include "sge_collision.h" class DECLSPEC sge_shape; //================================================================================== // The screen class //================================================================================== class DECLSPEC sge_screen { protected: SDL_Surface *screen; //The SDL screen surface std::list rects; //The list of rectangles to be updated std::list shapes; //The list of shapes to draw on screen std::list shapes_p; //The list of permanent shapes to draw on screen typedef std::list::const_iterator RI; //List iterator (for rects) typedef std::list::const_iterator SI; //List iterator (for shapes) bool HW, DB, FS; //video memory, double-buffered or/and fullscreen? public: sge_screen(SDL_Surface *screen); ~sge_screen(void){rects.clear();shapes.clear();shapes_p.clear();} void add_rect(SDL_Rect rect); void add_rect(Sint16 x, Sint16 y, Uint32 w, Uint32 h); void add_shape(sge_shape *shape); void add_shape_p(sge_shape *shape); //Adds an shape permanently void remove_shape_p(sge_shape *shape); void clear_all(void); void update(void); }; //================================================================================== // sge_shape // Abstract base class for different shapes (surfaces, sprites, ...) //================================================================================== class sge_shape { protected: SDL_Rect current_pos; //The *current* (maybe undrawn) position of the shape SDL_Rect last_pos; //The *last* drawn position of shape SDL_Rect prev_pos; //The previous drawn position of shape (used to update a cleared area) SDL_Surface *dest; //The surface to perform operations on public: virtual ~sge_shape(void){} //Destructor virtual void draw(void)=0; //Draws the shape - prev_pos = last_pos; last_pos = the new position of shape //Updates the screen (last_pos+prev_pos) //If sge_screen is used this member will use it (the_screen) instead of doing it directly! virtual void UpdateRects(void)=0; //Some functions to clear (remove) shape virtual void clear(Uint32 color)=0; //Clears to color virtual void clear(SDL_Surface *src, Sint16 srcX, Sint16 srcY)=0; //Clears by blitting src inline SDL_Rect get_pos(void) const{return current_pos;} //Returns the current position inline SDL_Rect get_last_pos(void) const{return last_pos;} //Returns the last updated position inline SDL_Surface* get_dest(void) const{return dest;} /* //NW N NE // \|/ // W-C-E // /|\ //SW S SE // //Returns some usefull coords in shape (current) */ inline Sint16 c_x(void) const{return current_pos.x+current_pos.w/2;} inline Sint16 c_y(void) const{return current_pos.y+current_pos.h/2;} inline Sint16 nw_x(void) const{return current_pos.x;} inline Sint16 nw_y(void) const{return current_pos.y;} inline Sint16 n_x(void) const{return current_pos.x+current_pos.w/2;} inline Sint16 n_y(void) const{return current_pos.y;} inline Sint16 ne_x(void) const{return current_pos.x+current_pos.w-1;} inline Sint16 ne_y(void) const{return current_pos.y;} inline Sint16 e_x(void) const{return current_pos.x+current_pos.w-1;} inline Sint16 e_y(void) const{return current_pos.y+current_pos.h/2;} inline Sint16 se_x(void) const{return current_pos.x+current_pos.w-1;} inline Sint16 se_y(void) const{return current_pos.y+current_pos.h-1;} inline Sint16 s_x(void) const{return current_pos.x+current_pos.w/2;} inline Sint16 s_y(void) const{return current_pos.y+current_pos.h-1;} inline Sint16 sw_x(void) const{return current_pos.x;} inline Sint16 sw_y(void) const{return current_pos.y+current_pos.h-1;} inline Sint16 w_x(void) const{return current_pos.x;} inline Sint16 w_y(void) const{return current_pos.y+current_pos.h/2;} inline Sint16 get_xpos(void) const{return current_pos.x;} inline Sint16 get_ypos(void) const{return current_pos.y;} inline Sint16 get_w(void) const{return current_pos.w;} inline Sint16 get_h(void) const{return current_pos.h;} }; //================================================================================== // sge_surface (derived from sge_shape) // A class for moving/blitting surfaces //================================================================================== class DECLSPEC sge_surface: public sge_shape { protected: SDL_Surface *surface; //The source surface *NOT COPIED* //Do warp logic bool check_warp(void); //Handles outside screen problems (But not in this class) virtual bool check_border(void){return check_warp();} //The border box (default: the screen size) SDL_Rect border; //Should we warp around the border box? (not in this class //but some methods here must know) bool warp_border; //Decode a warp pos rectangle int get_warp(SDL_Rect rec, SDL_Rect &r1, SDL_Rect &r2, SDL_Rect &r3, SDL_Rect &r4); //Helper functions void warp_draw(void); void warp_update(SDL_Rect rec); void warp_clear(Uint32 color); void warp_clear(SDL_Surface *src, Sint16 srcX, Sint16 srcY); public: sge_surface(SDL_Surface *dest, SDL_Surface *src, Sint16 x=0, Sint16 y=0); ~sge_surface(void); //Draws the surface virtual void draw(void); virtual inline void clear(Uint32 color); virtual inline void clear(SDL_Surface *src, Sint16 srcX, Sint16 srcY); //virtual inline void clear(SDL_Surface *src){clear(src,last_pos.x,last_pos.y);} virtual void UpdateRects(void); //Move the surface virtual inline void move_to(Sint16 x, Sint16 y){current_pos.x=x; current_pos.y=y;check_border();} virtual inline void move(Sint16 x_step, Sint16 y_step){current_pos.x+=x_step; current_pos.y+=y_step; check_border();} //Get pointer to surface SDL_Surface* get_img(void) const{return surface;} //Sets the border box void set_border(SDL_Rect box){border=box;} }; //================================================================================== // The frame struct (for sge_ssprite) //================================================================================== struct sge_frame { //The image SDL_Surface *img; //Collision data sge_cdata *cdata; }; //================================================================================== // sge_ssprite (derived from sge_surface) // A simple sprite class //================================================================================== class DECLSPEC sge_ssprite: public sge_surface { public:enum playing_mode{loop, play_once, stop}; //This must be public protected: //Linked list with the frames //Obs! 'surface' always points to the current frame image std::list frames; typedef std::list::const_iterator FI; //List iterator (for frames) FI current_fi; FI fi_start; //first frame in the playing sequence loop FI fi_stop; //last frame + 1 //The pointer to the current frame sge_frame *current_frame; //Should at all times be *current_fi //The speed of the sprite (pixels/update) Sint16 xvel, yvel; bool bounce_border; //Do we want the sprite to bounce at the border? virtual bool check_border(void); //Playing sequence mode playing_mode seq_mode; public: //Constructor and destructor sge_ssprite(SDL_Surface *screen, SDL_Surface *img, Sint16 x=0, Sint16 y=0); sge_ssprite(SDL_Surface *screen, SDL_Surface *img, sge_cdata *cdata, Sint16 x=0, Sint16 y=0); ~sge_ssprite(void); //Updates the internal status //Returns true if the sprite moved virtual inline bool update(void); //Sets the speed void set_vel(Sint16 x, Sint16 y){xvel=x;yvel=y;} void set_xvel(Sint16 x){xvel=x;} void set_yvel(Sint16 y){yvel=y;} //Gets the speed Sint16 get_xvel(void) const{return xvel;} Sint16 get_yvel(void) const{return yvel;} //Add a frame //Obs! Resets playing sequence void add_frame(SDL_Surface *img); void add_frame(SDL_Surface *img, sge_cdata *cdata); //Change frame void skip_frame(int skips); //A negative 'skips' indicates backwards void next_frame(void){skip_frame(1);} void prev_frame(void){skip_frame(-1);} void first_frame(void); //Does NOT change the sequence void last_frame(void); // " //Changes playing sequence (0- first frame) //playing_mode: // sge_ssprite::loop - loops forever // sge_ssprite::play_once - just once then stops // sge_ssprite::stop - is returned by get_PlayingMode() if stoped void set_seq(int start, int stop, playing_mode mode=loop); void reset_seq(void); playing_mode get_PlayingMode(void){return seq_mode;} //Get cdata for current frame sge_cdata* get_cdata(void){return current_frame->cdata;} //Get the current frame sge_frame* get_frame(void){return current_frame;} //Get the frame list //DO NOT ADD OR REMOVE ELEMENTS without using //reset_seq() when done!! std::list* get_list(void){return &frames;} //Set border mode: //Bounce - sprite bounces (default) //Warp - sprite warps at border void border_bounce(bool mode){bounce_border=mode; if(warp_border){warp_border=false;}} void border_warp(bool mode){warp_border=mode; if(bounce_border){bounce_border=false;}} }; //================================================================================== // sge_sprite (derived from sge_ssprite) // A timed sprite class //================================================================================== class DECLSPEC sge_sprite: public sge_ssprite { protected: //Pixels/ms double xppms, yppms; //Frames/ms double fpms; //The float pos double xpos, ypos, fpos; //Ticks since last pos update Uint32 tlast; virtual bool check_border(void); public: //Constructor sge_sprite(SDL_Surface *screen, SDL_Surface *img, Sint16 x=0, Sint16 y=0): sge_ssprite(screen,img,x,y){xppms=yppms=fpms=0;tlast=0;xpos=x;ypos=y;fpos=0;} sge_sprite(SDL_Surface *screen, SDL_Surface *img, sge_cdata *cdata, Sint16 x=0, Sint16 y=0): sge_ssprite(screen,img,cdata,x,y){xppms=yppms=fpms=0;tlast=0;xpos=x;ypos=y;fpos=0;} //Change the speeds void set_pps(Sint16 x, Sint16 y){xppms=x/1000.0; yppms=y/1000.0;} void set_xpps(Sint16 x){xppms=x/1000.0;} void set_ypps(Sint16 y){yppms=y/1000.0;} void set_fps(Sint16 f){fpms=f/1000.0;} //Get the speeds Sint16 get_xpps(void) const{return Sint16(xppms*1000);} Sint16 get_ypps(void) const{return Sint16(yppms*1000);} Sint16 get_fps(void) const{return Sint16(fpms*1000);} //Update position and frame //Returns true if something changed bool update(Uint32 ticks); bool update(void){return update(SDL_GetTicks());} //Correct move members for this class void move_to(Sint16 x, Sint16 y){sge_surface::move_to(x,y); xpos=current_pos.x; ypos=current_pos.y;} void move(Sint16 x_step, Sint16 y_step){sge_surface::move(x_step,y_step); xpos=current_pos.x; ypos=current_pos.y;} //Freeze time until next update void pause(void){tlast=0;} }; #ifdef _MSC_VER #pragma warning(pop) #endif #endif /* _SGE_NO_CLASSES */ #endif /* sge_shape_H */ sge030809/sge_bm_text.h0000644000175000001440000000476007714717570013516 0ustar samusers/* * SDL Graphics Extension * Text/Bitmap font functions (header) * * Started 990815 * * License: LGPL v2+ (see the file LICENSE) * (c)1999-2003 Anders Lindstrm */ /********************************************************************* * This library is free software; you can redistribute it and/or * * modify it under the terms of the GNU Library General Public * * License as published by the Free Software Foundation; either * * version 2 of the License, or (at your option) any later version. * *********************************************************************/ #ifndef sge_bm_text_H #define sge_bm_text_H #include "SDL.h" #include "sge_internal.h" /* BF open flags */ #define SGE_BFTRANSP SGE_FLAG1 #define SGE_BFSFONT SGE_FLAG2 #define SGE_BFNOCONVERT SGE_FLAG3 #define SGE_BFPALETTE SGE_FLAG4 /* Text input flags */ #define SGE_IBG SGE_FLAG1 #define SGE_IDEL SGE_FLAG2 #define SGE_INOKR SGE_FLAG3 /* the bitmap font structure */ typedef struct{ SDL_Surface *FontSurface; Sint16 CharWidth; Sint16 CharHeight; Sint16 *CharPos; Sint16 yoffs; Uint32 bcolor; Sint16 Chars; } sge_bmpFont; #ifdef _SGE_C extern "C" { #endif DECLSPEC sge_bmpFont* sge_BF_CreateFont(SDL_Surface *surface, Uint8 flags); DECLSPEC sge_bmpFont* sge_BF_OpenFont(char *file, Uint8 flags); DECLSPEC void sge_BF_CloseFont(sge_bmpFont *font); DECLSPEC void sge_BF_SetColor(sge_bmpFont *font, Uint8 R, Uint8 G, Uint8 B); DECLSPEC void sge_BF_SetAlpha(sge_bmpFont *font, Uint8 alpha); DECLSPEC Sint16 sge_BF_GetHeight(sge_bmpFont *font); DECLSPEC Sint16 sge_BF_GetWidth(sge_bmpFont *font); DECLSPEC SDL_Rect sge_BF_TextSize(sge_bmpFont *font, char *string); DECLSPEC SDL_Rect sge_BF_textout(SDL_Surface *surface, sge_bmpFont *font, char *string, Sint16 x, Sint16 y); DECLSPEC SDL_Rect sge_BF_textoutf(SDL_Surface *surface, sge_bmpFont *font, Sint16 x, Sint16 y , char *format, ...); DECLSPEC int sge_BF_input(SDL_Surface *screen,sge_bmpFont *font,char *string, Uint8 flags,int pos,int len,Sint16 x,Sint16 y); DECLSPEC int sge_BF_inputAlpha(SDL_Surface *screen, sge_bmpFont *font, char *string, Uint8 flags, int pos,int len, Sint16 x, Sint16 y, int Alpha); DECLSPEC int sge_BF_input_UNI(SDL_Surface *screen, sge_bmpFont *font, Uint16 *string, Uint8 flags, int pos,int len, Sint16 x,Sint16 y); DECLSPEC int sge_BF_inputAlpha_UNI(SDL_Surface *screen, sge_bmpFont *font, Uint16 *string, Uint8 flags, int pos,int len, Sint16 x,Sint16 y, int Alpha); #ifdef _SGE_C } #endif #endif /* sge_bm_text_H */ sge030809/sge_shape.cpp0000644000175000001440000004133407715151745013502 0ustar samusers/* * SDL Graphics Extension * SGE shape * * Started 000430 * * License: LGPL v2+ (see the file LICENSE) * (c)2000-2003 Anders Lindstrm */ /********************************************************************* * This library is free software; you can redistribute it and/or * * modify it under the terms of the GNU Library General Public * * License as published by the Free Software Foundation; either * * version 2 of the License, or (at your option) any later version. * *********************************************************************/ #include "SDL.h" #include #include #include "sge_surface.h" #include "sge_primitives.h" #include "sge_shape.h" #include "sge_misc.h" #ifndef _SGE_NO_CLASSES using namespace std; sge_screen *the_screen=NULL; //The pointer to the active screen class (or NULL) //================================================================================== // sge_screen //================================================================================== sge_screen::sge_screen(SDL_Surface *screen) { sge_screen::screen=screen; //Our screen pointer /* Test some flags */ HW=(((screen->flags) & SDL_HWSURFACE) != 0); DB=(((screen->flags) & SDL_DOUBLEBUF) != 0); FS=(((screen->flags) & SDL_FULLSCREEN) != 0); /* Test the resolution of SDL_Delay() */ //sge_CalibrateDelay(); /* Register us as the screen class */ the_screen=this; #ifdef sge_debug if(HW) printf("Screen surface is in video memory ("); else printf("Screen surface is in system memory ("); if(DB) printf("double-buffered "); else printf("single-buffered "); if(FS) printf("fullscreen mode).\n"); else printf("window mode).\n"); //printf("The resolution of SDL_Delay() is %d ms.\n",sge_DelayRes()); #endif } void sge_screen::add_rect(SDL_Rect rect) { if(!(HW||DB)){ /* Corrects the coords */ if(rect.x>=screen->w || rect.y>=screen->h){return;} Sint16 a=rect.w,b=rect.h; if(rect.x < 0){rect.x=0;} if(rect.y < 0){rect.y=0;} if(a+rect.x > screen->w) a=screen->w-rect.x; if(b+rect.y > screen->h) b=screen->h-rect.y; rect.w=a; rect.h=b; /* Put the rectangle last in the list */ rects.push_back(rect); } } void sge_screen::add_rect(Sint16 x, Sint16 y, Uint32 w, Uint32 h) { if(!(HW||DB)){ SDL_Rect rect; rect.x=x; rect.y=y; rect.w=w; rect.h=h; add_rect(rect); } } void sge_screen::add_shape(sge_shape *shape) { shapes.push_back(shape); } void sge_screen::add_shape_p(sge_shape *shape) { shapes_p.push_back(shape); } void sge_screen::remove_shape_p(sge_shape *shape) { shapes_p.remove(shape); } void sge_screen::clear_all(void) { shapes.clear(); shapes_p.clear(); rects.clear(); } void sge_screen::update(void) { SI i; //Draw shapes in list for(i=shapes.begin(); i != shapes.end(); i++){ (*i)->draw(); (*i)->UpdateRects(); //Adds rectangles with add_rect() automaticly } shapes.clear(); //Draw permanent shapes in list for(i=shapes_p.begin(); i != shapes_p.end(); i++){ (*i)->draw(); (*i)->UpdateRects(); //Adds rectangles with add_rect() automaticly } //Updates the list of rectangles on screen if(!(HW||DB)){ int j=0; SDL_Rect *r=new SDL_Rect[rects.size()]; //ANSI C++ /* Copy every element in the linked list to the array */ for(RI i=rects.begin(); i != rects.end(); i++){ r[j++]=*i; } SDL_UpdateRects(screen,rects.size(), r); //Let SDL update the rectangles delete[] r; rects.clear(); //Empty the list } else if(DB) //double-buffered SDL_Flip(screen); } //================================================================================== // sge_surface (derived from sge_shape) // A class for moving/blitting surfaces //================================================================================== sge_surface::sge_surface(SDL_Surface *dest, SDL_Surface *src, Sint16 x, Sint16 y) { surface=src; sge_surface::dest=dest; current_pos.x=x;current_pos.y=y;current_pos.w=src->w;current_pos.h=src->h; last_pos.x=last_pos.y=last_pos.w=last_pos.h=0; prev_pos=last_pos; border.x=border.y=0;border.w=dest->w;border.h=dest->h; warp_border=false; } sge_surface::~sge_surface(void) { //Nothing for now... } bool sge_surface::check_warp(void) { bool flag=false; if(warp_border){ if(current_pos.x+current_pos.wborder.x+border.w){ current_pos.x=border.x; flag=true; }if(current_pos.y+current_pos.hborder.y+border.h){ current_pos.y=border.y; flag=true; } } return flag; } int sge_surface::get_warp(SDL_Rect rec, SDL_Rect &r1, SDL_Rect &r2, SDL_Rect &r3, SDL_Rect &r4) { //We want to decode the pos rectangle into two or four rectangles. r1.x = r2.x = r3.x = r4.x = rec.x, r1.y = r2.y = r3.y = r4.y = rec.y; r1.w = r2.w = r3.w = r4.w = rec.w, r1.h = r2.h = r3.h = r4.h = rec.h; int rects=0; if(warp_border){ if(rec.x border.x + border.w){ r1.x = rec.x; r1.w = border.x + border.w - rec.x; r2.x = border.x; r2.w = abs(rec.w - r1.w); rects=2; } r3.x = r1.x; r3.w = r1.w; r4.x = r2.x; r4.w = r2.w; if(rec.y border.y + border.h){ if(rects==0){ r1.y = rec.y; r1.h = border.y + border.h - rec.y; r2.y = border.y; r2.h = abs(rec.h - r1.h); rects=2; }else{ r2.y = r1.y = rec.y; r2.h = r1.h = border.y + border.h - rec.y; r4.y = r3.y = border.y; r4.h = r3.h = abs(rec.h - r1.h); rects=4; } } } return rects; } void sge_surface::warp_draw(void) { SDL_Rect r1,r2,r3,r4; int rects=get_warp(current_pos,r1,r2,r3,r4); if(rects==2){ sge_Blit(surface, dest, 0,0, r1.x, r1.y, r1.w, r1.h); sge_Blit(surface, dest, surface->w-r2.w,surface->h-r2.h, r2.x, r2.y, r2.w, r2.h); } else if(rects==4){ sge_Blit(surface, dest, 0,0, r1.x, r1.y, r1.w, r1.h); sge_Blit(surface, dest, surface->w-r2.w,0, r2.x, r2.y, r2.w, r2.h); sge_Blit(surface, dest, 0,surface->h-r3.h, r3.x, r3.y, r3.w, r3.h); sge_Blit(surface, dest, surface->w-r4.w,surface->h-r4.h, r4.x, r4.y, r4.w, r4.h); } else sge_Blit(surface, dest, 0,0, current_pos.x, current_pos.y, surface->w, surface->h); } void sge_surface::warp_update(SDL_Rect rec) { SDL_Rect r1,r2,r3,r4; int rects=get_warp(rec,r1,r2,r3,r4); if(rects>0){ if(the_screen){ //Use the screen class? the_screen->add_rect(r1.x, r1.y, r1.w, r1.h); the_screen->add_rect(r2.x, r2.y, r2.w, r2.h); if(rects>2){ the_screen->add_rect(r3.x, r3.y, r3.w, r3.h); the_screen->add_rect(r4.x, r4.y, r4.w, r4.h); } }else{ sge_UpdateRect(dest, r1.x, r1.y, r1.w, r1.h); sge_UpdateRect(dest, r2.x, r2.y, r2.w, r2.h); if(rects>2){ sge_UpdateRect(dest, r3.x, r3.y, r3.w, r3.h); sge_UpdateRect(dest, r4.x, r4.y, r4.w, r4.h); } } } else{ if(the_screen) the_screen->add_rect(rec.x, rec.y, rec.w, rec.h); else sge_UpdateRect(dest, rec.x, rec.y, rec.w, rec.h); } } void sge_surface::warp_clear(Uint32 color) { SDL_Rect r1,r2,r3,r4; int rects=get_warp(last_pos,r1,r2,r3,r4); if(rects>0){ sge_FilledRect(dest, r1.x, r1.y, r1.x+r1.w-1, r1.y+r1.h-1, color); sge_FilledRect(dest, r2.x, r2.y, r2.x+r2.w-1, r2.y+r2.h-1, color); if(rects>2){ sge_FilledRect(dest, r3.x, r3.y, r3.x+r3.w-1, r3.y+r3.h-1, color); sge_FilledRect(dest, r4.x, r4.y, r4.x+r4.w-1, r4.y+r4.h-1, color); } } else sge_FilledRect(dest, last_pos.x, last_pos.y, last_pos.x+last_pos.w-1, last_pos.y+last_pos.h-1,color); } void sge_surface::warp_clear(SDL_Surface *src, Sint16 srcX, Sint16 srcY) { SDL_Rect r1,r2,r3,r4; int rects=get_warp(current_pos,r1,r2,r3,r4); if(rects>0){ sge_Blit(src, dest, r1.x,r1.y, r1.x, r1.y, r1.w, r1.h); sge_Blit(src, dest, r2.x,r2.y, r2.x, r2.y, r2.w, r2.h); if(rects>2){ sge_Blit(src, dest, r3.x,r3.y, r3.x, r3.y, r3.w, r3.h); sge_Blit(src, dest, r4.x,r4.y, r4.x, r4.y, r4.w, r4.h); } } else sge_Blit(src,dest, srcX, srcY, last_pos.x, last_pos.y, last_pos.w, last_pos.h); } //Draws the surface void sge_surface::draw(void) { if(!surface) return; current_pos.w=surface->w; current_pos.h=surface->h; if(warp_border) warp_draw(); else sge_Blit(surface, dest, 0,0, current_pos.x, current_pos.y, surface->w, surface->h); prev_pos=last_pos; last_pos=current_pos; } void sge_surface::UpdateRects(void) { Sint16 xoffs=last_pos.x-prev_pos.x, yoffs=last_pos.y-prev_pos.y; //if the prev and last area to update is very near //it's better to update both with one sge_UpdateRect call if(xoffs<0) xoffs=~xoffs+1; //abs(xoffs) if(yoffs<0) yoffs=~yoffs+1; if(xoffs <= prev_pos.w/2 && yoffs <= prev_pos.h/2){ Sint16 minx, miny, maxx, maxy, w=prev_pos.w+xoffs, h=prev_pos.h+yoffs; minx= (prev_pos.x last_pos.x+last_pos.w)? prev_pos.x+prev_pos.w : last_pos.x+last_pos.w; w=maxx-minx; } if(prev_pos.h!=last_pos.h){ maxy= (prev_pos.y+prev_pos.h > last_pos.y+last_pos.h)? prev_pos.y+prev_pos.h : last_pos.y+last_pos.h; h=maxy-miny; } if(warp_border){ SDL_Rect r; r.x=minx; r.y=miny; r.w=w; r.h=h; warp_update(r); } else if(the_screen) //Use the screen class? the_screen->add_rect(minx, miny, w, h); else sge_UpdateRect(dest, minx, miny, w, h); } else{ if(warp_border){ warp_update(prev_pos); warp_update(last_pos); } else if(the_screen){ the_screen->add_rect(prev_pos.x, prev_pos.y, prev_pos.w, prev_pos.h); the_screen->add_rect(last_pos.x, last_pos.y, last_pos.w, last_pos.h); } else{ sge_UpdateRect(dest, prev_pos.x, prev_pos.y, prev_pos.w, prev_pos.h); sge_UpdateRect(dest, last_pos.x, last_pos.y, last_pos.w, last_pos.h); } } } void sge_surface::clear(Uint32 color) { if(warp_border) warp_clear(color); else sge_FilledRect(dest, last_pos.x, last_pos.y, last_pos.x+last_pos.w-1, last_pos.y+last_pos.h-1,color); } void sge_surface::clear(SDL_Surface *src, Sint16 srcX, Sint16 srcY) { if(warp_border) warp_clear(src,srcX,srcY); else sge_Blit(src,dest, srcX, srcY, last_pos.x, last_pos.y, last_pos.w, last_pos.h); } //================================================================================== // sge_ssprite (derived from sge_surface) // A simple sprite class //================================================================================== sge_ssprite::sge_ssprite(SDL_Surface *screen, SDL_Surface *img, Sint16 x, Sint16 y): sge_surface(screen,img,x,y) { //Create the first frame current_frame= new sge_frame; //User has to catch bad_alloc himself current_frame->img = img; current_frame->cdata=NULL; frames.push_back(current_frame); current_fi=frames.begin(); fi_start = current_fi; fi_stop = frames.end(); //Default xvel=yvel=0; seq_mode=stop; bounce_border=true; } sge_ssprite::sge_ssprite(SDL_Surface *screen, SDL_Surface *img, sge_cdata *cdata, Sint16 x, Sint16 y): sge_surface(screen,img,x,y) { //Create the first frame current_frame= new sge_frame; //User has to catch bad_alloc himself current_frame->img = img; current_frame->cdata=cdata; frames.push_back(current_frame); current_fi=frames.begin(); fi_start = current_fi; fi_stop = frames.end(); //Default xvel=yvel=0; seq_mode=stop; bounce_border=true; } sge_ssprite::~sge_ssprite(void) { //Empty the list for(FI i=frames.begin(); i != frames.end(); i++) delete *i; frames.clear(); } bool sge_ssprite::check_border(void) { if(!bounce_border) return sge_surface::check_border(); bool flag=false; if(current_pos.x border.x+border.w){ current_pos.x=border.x+border.w-current_pos.w; xvel=-xvel; flag=true; } if(current_pos.y border.y+border.h){ current_pos.y=border.y+border.h-current_pos.h; yvel=-yvel; flag=true; } return flag; } void sge_ssprite::add_frame(SDL_Surface *img) { add_frame(img, NULL); } void sge_ssprite::add_frame(SDL_Surface *img, sge_cdata *cdata) { //Create a new frame sge_frame *frame = new sge_frame; //User has to catch bad_alloc himself frame->img = img; frame->cdata = cdata; frames.push_back(frame); fi_start = frames.begin(); fi_stop = frames.end(); seq_mode=loop; } void sge_ssprite::skip_frame(int skips) { if(skips > 0){ for(int i=0; iimg; current_pos.w = surface->w; current_pos.h = surface->h; } bool sge_ssprite::update(void) { move(xvel,yvel); return !((xvel==0)&&(yvel==0)); } void sge_ssprite::set_seq(int start, int stop, playing_mode mode) { //Handle stupid user errors if(start < 0 || start > int(frames.size())-1) return; if(stop < start || stop > int(frames.size())-1) return; seq_mode=loop; if(mode==play_once) seq_mode=play_once; if(start==stop) seq_mode=sge_ssprite::stop; fi_start=fi_stop=frames.begin(); for(int i=0; i<=stop; i++){ if(iimg; current_pos.w = surface->w; current_pos.h = surface->h; } void sge_ssprite::reset_seq(void) { fi_start=frames.begin(); fi_stop=frames.end(); current_fi = fi_start; current_frame = *current_fi; surface = current_frame->img; current_pos.w = surface->w; current_pos.h = surface->h; if(frames.size() > 1) seq_mode=loop; else seq_mode=stop; } void sge_ssprite::first_frame(void) { current_fi = fi_start; current_frame = *current_fi; surface = current_frame->img; current_pos.w = surface->w; current_pos.h = surface->h; } void sge_ssprite::last_frame(void) { current_fi = fi_stop; current_fi--; current_frame = *current_fi; surface = current_frame->img; current_pos.w = surface->w; current_pos.h = surface->h; } //================================================================================== // sge_sprite (derived from sge_ssprite) // A timed sprite class //================================================================================== bool sge_sprite::update(Uint32 ticks) { if(tlast==0){ tlast=ticks; return false; } Sint16 tmp; Uint32 time=ticks-tlast; tlast=ticks; //Reset time bool ret=false; //Calculate new pos if(xppms!=0){ xpos+=time*xppms; tmp=int(xpos); if(current_pos.x!=tmp){ current_pos.x=tmp; ret=true; } } if(yppms!=0){ ypos+=time*yppms; tmp=int(ypos); if(current_pos.y!=tmp){ current_pos.y=tmp; ret=true; } } if(ret) //Are we off-screen? check_border(); //Calculate new frame if(fpms!=0){ fpos+=time*fpms; tmp=int(fpos); if(tmp!=0){ skip_frame(tmp); fpos-=tmp; ret=true; } } return ret; } bool sge_sprite::check_border(void) { if(warp_border){ if(sge_surface::check_warp()){ xpos=current_pos.x; ypos=current_pos.y; return true; } return false; } if(!bounce_border) return false; bool flag=false; if(current_pos.x border.x+border.w){ current_pos.x=border.x+border.w-current_pos.w; xpos=current_pos.x; xppms=-xppms; flag=true; } if(current_pos.y border.y+border.h){ current_pos.y=border.y+border.h-current_pos.h; ypos=current_pos.y; yppms=-yppms; flag=true; } return flag; } #endif /* _SGE_NO_CLASSES */ sge030809/sge_surface.cpp0000644000175000001440000010104707713172470014024 0ustar samusers/* * SDL Graphics Extension * Pixel, surface and color functions * * Started 990815 (split from sge_draw 010611) * * License: LGPL v2+ (see the file LICENSE) * (c)1999-2003 Anders Lindstrm */ /********************************************************************* * This library is free software; you can redistribute it and/or * * modify it under the terms of the GNU Library General Public * * License as published by the Free Software Foundation; either * * version 2 of the License, or (at your option) any later version. * *********************************************************************/ /* * Some of this code is taken from the "Introduction to SDL" and * John Garrison's PowerPak */ #include "SDL.h" #include #include #include #include "sge_surface.h" /* Globals used for sge_Update/sge_Lock */ Uint8 _sge_update=1; Uint8 _sge_lock=1; /**********************************************************************************/ /** Misc. functions **/ /**********************************************************************************/ //================================================================================== // Turns off automatic update (to avoid tearing). //================================================================================== void sge_Update_OFF(void) { _sge_update=0; } //================================================================================== // Turns on automatic update (default) //================================================================================== void sge_Update_ON(void) { _sge_update=1; } //================================================================================== // Turns off automatic locking of surfaces //================================================================================== void sge_Lock_OFF(void) { _sge_lock=0; } //================================================================================== // Turns on automatic locking (default) //================================================================================== void sge_Lock_ON(void) { _sge_lock=1; } //================================================================================== // Returns update&locking mode (1-on and 0-off) //================================================================================== Uint8 sge_getUpdate(void) { return _sge_update; } Uint8 sge_getLock(void) { return _sge_lock; } //================================================================================== // SDL_UpdateRect does nothing if any part of the rectangle is outside the surface // --- This version always work //================================================================================== void sge_UpdateRect(SDL_Surface *screen, Sint16 x, Sint16 y, Uint16 w, Uint16 h) { if(_sge_update!=1 || screen != SDL_GetVideoSurface()){return;} if(x>=screen->w || y>=screen->h){return;} Sint16 a,b; a=w; b=h; if(x < 0){x=0;} if(y < 0){y=0;} if(a+x > screen->w){a=screen->w-x;} if(b+y > screen->h){b=screen->h-y;} SDL_UpdateRect(screen,x,y,a,b); } //================================================================================== // Creates a 32bit (8/8/8/8) alpha surface // Map colors with sge_MapAlpha() and then use the Uint32 color versions of // SGEs routines //================================================================================== SDL_Surface *sge_CreateAlphaSurface(Uint32 flags, int width, int height) { return SDL_CreateRGBSurface(flags,width,height,32, 0xFF000000, 0x00FF0000, 0x0000FF00, 0x000000FF); } //================================================================================== // Returns the Uint32 color value for a 32bit (8/8/8/8) alpha surface //================================================================================== Uint32 sge_MapAlpha(Uint8 R, Uint8 G, Uint8 B, Uint8 A) { Uint32 color=0; color|=R<<24; color|=G<<16; color|=B<<8; color|=A; return color; } //================================================================================== // Sets an SDL error string // Accepts formated argument - like printf() // SDL_SetError() also does this, but it does not use standard syntax (why?) //================================================================================== void sge_SetError(const char *format, ...) { char buf[256]; va_list ap; #ifdef __WIN32__ va_start((va_list*)ap, format); //Stupid w32 crosscompiler #else va_start(ap, format); #endif vsprintf(buf, format, ap); va_end(ap); SDL_SetError(buf); } /**********************************************************************************/ /** Pixel functions **/ /**********************************************************************************/ //================================================================================== // Fast put pixel //================================================================================== void _PutPixel(SDL_Surface *surface, Sint16 x, Sint16 y, Uint32 color) { if(x>=sge_clip_xmin(surface) && x<=sge_clip_xmax(surface) && y>=sge_clip_ymin(surface) && y<=sge_clip_ymax(surface)){ switch (surface->format->BytesPerPixel) { case 1: { /* Assuming 8-bpp */ *((Uint8 *)surface->pixels + y*surface->pitch + x) = color; } break; case 2: { /* Probably 15-bpp or 16-bpp */ *((Uint16 *)surface->pixels + y*surface->pitch/2 + x) = color; } break; case 3: { /* Slow 24-bpp mode, usually not used */ Uint8 *pix = (Uint8 *)surface->pixels + y * surface->pitch + x*3; /* Gack - slow, but endian correct */ *(pix+surface->format->Rshift/8) = color>>surface->format->Rshift; *(pix+surface->format->Gshift/8) = color>>surface->format->Gshift; *(pix+surface->format->Bshift/8) = color>>surface->format->Bshift; *(pix+surface->format->Ashift/8) = color>>surface->format->Ashift; } break; case 4: { /* Probably 32-bpp */ *((Uint32 *)surface->pixels + y*surface->pitch/4 + x) = color; } break; } } } //================================================================================== // Fast put pixel (RGB) //================================================================================== void _PutPixel(SDL_Surface *surface, Sint16 x, Sint16 y, Uint8 R, Uint8 G, Uint8 B) { _PutPixel(surface,x,y, SDL_MapRGB(surface->format, R, G, B)); } //================================================================================== // Fastest put pixel functions (don't mess up indata, thank you) //================================================================================== void _PutPixel8(SDL_Surface *surface, Sint16 x, Sint16 y, Uint32 color) { *((Uint8 *)surface->pixels + y*surface->pitch + x) = color; } void _PutPixel16(SDL_Surface *surface, Sint16 x, Sint16 y, Uint32 color) { *((Uint16 *)surface->pixels + y*surface->pitch/2 + x) = color; } void _PutPixel24(SDL_Surface *surface, Sint16 x, Sint16 y, Uint32 color) { Uint8 *pix = (Uint8 *)surface->pixels + y * surface->pitch + x*3; /* Gack - slow, but endian correct */ *(pix+surface->format->Rshift/8) = color>>surface->format->Rshift; *(pix+surface->format->Gshift/8) = color>>surface->format->Gshift; *(pix+surface->format->Bshift/8) = color>>surface->format->Bshift; *(pix+surface->format->Ashift/8) = color>>surface->format->Ashift; } void _PutPixel32(SDL_Surface *surface, Sint16 x, Sint16 y, Uint32 color) { *((Uint32 *)surface->pixels + y*surface->pitch/4 + x) = color; } void _PutPixelX(SDL_Surface *dest,Sint16 x,Sint16 y,Uint32 color) { switch ( dest->format->BytesPerPixel ) { case 1: *((Uint8 *)dest->pixels + y*dest->pitch + x) = color; break; case 2: *((Uint16 *)dest->pixels + y*dest->pitch/2 + x) = color; break; case 3: _PutPixel24(dest,x,y,color); break; case 4: *((Uint32 *)dest->pixels + y*dest->pitch/4 + x) = color; break; } } //================================================================================== // Safe put pixel //================================================================================== void sge_PutPixel(SDL_Surface *surface, Sint16 x, Sint16 y, Uint32 color) { if ( SDL_MUSTLOCK(surface) && _sge_lock ) { if ( SDL_LockSurface(surface) < 0 ) { return; } } _PutPixel(surface, x, y, color); if ( SDL_MUSTLOCK(surface) && _sge_lock ) { SDL_UnlockSurface(surface); } if(_sge_update!=1){return;} sge_UpdateRect(surface, x, y, 1, 1); } //================================================================================== // Safe put pixel (RGB) //================================================================================== void sge_PutPixel(SDL_Surface *surface, Sint16 x, Sint16 y, Uint8 R, Uint8 G, Uint8 B) { sge_PutPixel(surface,x,y, SDL_MapRGB(surface->format, R, G, B)); } //================================================================================== // Calculate y pitch offset // (the y pitch offset is constant for the same y coord and surface) //================================================================================== Sint32 sge_CalcYPitch(SDL_Surface *dest,Sint16 y) { if(y>=sge_clip_ymin(dest) && y<=sge_clip_ymax(dest)){ switch ( dest->format->BytesPerPixel ) { case 1: return y*dest->pitch; break; case 2: return y*dest->pitch/2; break; case 3: return y*dest->pitch; break; case 4: return y*dest->pitch/4; break; } } return -1; } //================================================================================== // Put pixel with precalculated y pitch offset //================================================================================== void sge_pPutPixel(SDL_Surface *surface, Sint16 x, Sint32 ypitch, Uint32 color) { if(x>=sge_clip_xmin(surface) && x<=sge_clip_xmax(surface) && ypitch>=0){ switch (surface->format->BytesPerPixel) { case 1: { /* Assuming 8-bpp */ *((Uint8 *)surface->pixels + ypitch + x) = color; } break; case 2: { /* Probably 15-bpp or 16-bpp */ *((Uint16 *)surface->pixels + ypitch + x) = color; } break; case 3: { /* Slow 24-bpp mode, usually not used */ /* Gack - slow, but endian correct */ Uint8 *pix = (Uint8 *)surface->pixels + ypitch + x*3; *(pix+surface->format->Rshift/8) = color>>surface->format->Rshift; *(pix+surface->format->Gshift/8) = color>>surface->format->Gshift; *(pix+surface->format->Bshift/8) = color>>surface->format->Bshift; *(pix+surface->format->Ashift/8) = color>>surface->format->Ashift; } break; case 4: { /* Probably 32-bpp */ *((Uint32 *)surface->pixels + ypitch + x) = color; } break; } } } //================================================================================== // Get pixel //================================================================================== Uint32 sge_GetPixel(SDL_Surface *surface, Sint16 x, Sint16 y) { if(x<0 || x>=surface->w || y<0 || y>=surface->h) return 0; switch (surface->format->BytesPerPixel) { case 1: { /* Assuming 8-bpp */ return *((Uint8 *)surface->pixels + y*surface->pitch + x); } break; case 2: { /* Probably 15-bpp or 16-bpp */ return *((Uint16 *)surface->pixels + y*surface->pitch/2 + x); } break; case 3: { /* Slow 24-bpp mode, usually not used */ Uint8 *pix; int shift; Uint32 color=0; pix = (Uint8 *)surface->pixels + y * surface->pitch + x*3; shift = surface->format->Rshift; color = *(pix+shift/8)<format->Gshift; color|= *(pix+shift/8)<format->Bshift; color|= *(pix+shift/8)<format->Ashift; color|= *(pix+shift/8)<pixels + y*surface->pitch/4 + x); } break; } return 0; } //================================================================================== // Put pixel with alpha blending //================================================================================== void _PutPixelAlpha(SDL_Surface *surface, Sint16 x, Sint16 y, Uint32 color, Uint8 alpha) { if(x>=sge_clip_xmin(surface) && x<=sge_clip_xmax(surface) && y>=sge_clip_ymin(surface) && y<=sge_clip_ymax(surface)){ Uint32 Rmask = surface->format->Rmask, Gmask = surface->format->Gmask, Bmask = surface->format->Bmask, Amask = surface->format->Amask; Uint32 R,G,B,A=0; switch (surface->format->BytesPerPixel) { case 1: { /* Assuming 8-bpp */ if( alpha == 255 ){ *((Uint8 *)surface->pixels + y*surface->pitch + x) = color; }else{ Uint8 *pixel = (Uint8 *)surface->pixels + y*surface->pitch + x; Uint8 dR = surface->format->palette->colors[*pixel].r; Uint8 dG = surface->format->palette->colors[*pixel].g; Uint8 dB = surface->format->palette->colors[*pixel].b; Uint8 sR = surface->format->palette->colors[color].r; Uint8 sG = surface->format->palette->colors[color].g; Uint8 sB = surface->format->palette->colors[color].b; dR = dR + ((sR-dR)*alpha >> 8); dG = dG + ((sG-dG)*alpha >> 8); dB = dB + ((sB-dB)*alpha >> 8); *pixel = SDL_MapRGB(surface->format, dR, dG, dB); } } break; case 2: { /* Probably 15-bpp or 16-bpp */ if( alpha == 255 ){ *((Uint16 *)surface->pixels + y*surface->pitch/2 + x) = color; }else{ Uint16 *pixel = (Uint16 *)surface->pixels + y*surface->pitch/2 + x; Uint32 dc = *pixel; R = ((dc & Rmask) + (( (color & Rmask) - (dc & Rmask) ) * alpha >> 8)) & Rmask; G = ((dc & Gmask) + (( (color & Gmask) - (dc & Gmask) ) * alpha >> 8)) & Gmask; B = ((dc & Bmask) + (( (color & Bmask) - (dc & Bmask) ) * alpha >> 8)) & Bmask; if( Amask ) A = ((dc & Amask) + (( (color & Amask) - (dc & Amask) ) * alpha >> 8)) & Amask; *pixel= R | G | B | A; } } break; case 3: { /* Slow 24-bpp mode, usually not used */ Uint8 *pix = (Uint8 *)surface->pixels + y * surface->pitch + x*3; Uint8 rshift8=surface->format->Rshift/8; Uint8 gshift8=surface->format->Gshift/8; Uint8 bshift8=surface->format->Bshift/8; Uint8 ashift8=surface->format->Ashift/8; if( alpha == 255 ){ *(pix+rshift8) = color>>surface->format->Rshift; *(pix+gshift8) = color>>surface->format->Gshift; *(pix+bshift8) = color>>surface->format->Bshift; *(pix+ashift8) = color>>surface->format->Ashift; }else{ Uint8 dR, dG, dB, dA=0; Uint8 sR, sG, sB, sA=0; pix = (Uint8 *)surface->pixels + y * surface->pitch + x*3; dR = *((pix)+rshift8); dG = *((pix)+gshift8); dB = *((pix)+bshift8); dA = *((pix)+ashift8); sR = (color>>surface->format->Rshift)&0xff; sG = (color>>surface->format->Gshift)&0xff; sB = (color>>surface->format->Bshift)&0xff; sA = (color>>surface->format->Ashift)&0xff; dR = dR + ((sR-dR)*alpha >> 8); dG = dG + ((sG-dG)*alpha >> 8); dB = dB + ((sB-dB)*alpha >> 8); dA = dA + ((sA-dA)*alpha >> 8); *((pix)+rshift8) = dR; *((pix)+gshift8) = dG; *((pix)+bshift8) = dB; *((pix)+ashift8) = dA; } } break; case 4: { /* Probably 32-bpp */ if( alpha == 255 ){ *((Uint32 *)surface->pixels + y*surface->pitch/4 + x) = color; }else{ Uint32 *pixel = (Uint32 *)surface->pixels + y*surface->pitch/4 + x; Uint32 dc = *pixel; R = ((dc & Rmask) + (( (color & Rmask) - (dc & Rmask) ) * alpha >> 8)) & Rmask; G = ((dc & Gmask) + (( (color & Gmask) - (dc & Gmask) ) * alpha >> 8)) & Gmask; B = ((dc & Bmask) + (( (color & Bmask) - (dc & Bmask) ) * alpha >> 8)) & Bmask; if( Amask ) A = ((dc & Amask) + (( (color & Amask) - (dc & Amask) ) * alpha >> 8)) & Amask; *pixel = R | G | B | A; } } break; } } } void sge_PutPixelAlpha(SDL_Surface *surface, Sint16 x, Sint16 y, Uint32 color, Uint8 alpha) { if ( SDL_MUSTLOCK(surface) && _sge_lock ) if ( SDL_LockSurface(surface) < 0 ) return; _PutPixelAlpha(surface,x,y,color,alpha); /* unlock the display */ if (SDL_MUSTLOCK(surface) && _sge_lock) { SDL_UnlockSurface(surface); } if(_sge_update!=1){return;} sge_UpdateRect(surface, x, y, 1, 1); } void _PutPixelAlpha(SDL_Surface *surface, Sint16 x, Sint16 y, Uint8 R, Uint8 G, Uint8 B, Uint8 alpha) { _PutPixelAlpha(surface,x,y, SDL_MapRGB(surface->format, R, G, B),alpha); } void sge_PutPixelAlpha(SDL_Surface *surface, Sint16 x, Sint16 y, Uint8 R, Uint8 G, Uint8 B, Uint8 alpha) { sge_PutPixelAlpha(surface,x,y, SDL_MapRGB(surface->format, R, G, B), alpha); } /**********************************************************************************/ /** Block functions **/ /**********************************************************************************/ //================================================================================== // The sge_write_block* functions copies the given block (a surface line) directly // to the surface. This is *much* faster then using the put pixel functions to // update a line. The block consist of Surface->w (the width of the surface) numbers // of color values. Note the difference in byte size for the block elements for // different color dephts. 24 bpp is slow and not included! //================================================================================== void sge_write_block8(SDL_Surface *Surface, Uint8 *block, Sint16 y) { memcpy( (Uint8 *)Surface->pixels + y*Surface->pitch, block, sizeof(Uint8)*Surface->w ); } void sge_write_block16(SDL_Surface *Surface, Uint16 *block, Sint16 y) { memcpy( (Uint16 *)Surface->pixels + y*Surface->pitch/2, block, sizeof(Uint16)*Surface->w ); } void sge_write_block32(SDL_Surface *Surface, Uint32 *block, Sint16 y) { memcpy( (Uint32 *)Surface->pixels + y*Surface->pitch/4, block, sizeof(Uint32)*Surface->w ); } //================================================================================== // ...and get //================================================================================== void sge_read_block8(SDL_Surface *Surface, Uint8 *block, Sint16 y) { memcpy( block,(Uint8 *)Surface->pixels + y*Surface->pitch, sizeof(Uint8)*Surface->w ); } void sge_read_block16(SDL_Surface *Surface, Uint16 *block, Sint16 y) { memcpy( block,(Uint16 *)Surface->pixels + y*Surface->pitch/2, sizeof(Uint16)*Surface->w ); } void sge_read_block32(SDL_Surface *Surface, Uint32 *block, Sint16 y) { memcpy( block,(Uint32 *)Surface->pixels + y*Surface->pitch/4, sizeof(Uint32)*Surface->w ); } /**********************************************************************************/ /** Blitting/surface functions **/ /**********************************************************************************/ //================================================================================== // Clear surface to color //================================================================================== void sge_ClearSurface(SDL_Surface *Surface, Uint32 color) { SDL_FillRect(Surface,NULL, color); if(_sge_update!=1){return;} SDL_UpdateRect(Surface, 0,0,0,0); } //================================================================================== // Clear surface to color (RGB) //================================================================================== void sge_ClearSurface(SDL_Surface *Surface, Uint8 R, Uint8 G, Uint8 B) { sge_ClearSurface(Surface,SDL_MapRGB(Surface->format, R, G, B)); } //================================================================================== // Blit from one surface to another // Warning! Alpha and color key is lost (=0) on Src surface //================================================================================== 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) { SDL_Rect src, dest; int ret; /* Dest clipping */ #if SDL_VERSIONNUM(SDL_MAJOR_VERSION, SDL_MINOR_VERSION, SDL_PATCHLEVEL) < \ SDL_VERSIONNUM(1, 1, 5) int flag=0; if (DestX < Dest->clip_minx){ SrcX += Dest->clip_minx-DestX; W -= Dest->clip_minx-DestX-1; DestX=Dest->clip_minx; } if (DestY < Dest->clip_miny){ SrcY +=Dest->clip_miny-DestY; H -= Dest->clip_miny-DestY-1; DestY=Dest->clip_miny; } if ((DestX + W) > Dest->clip_maxx){ W = W - ((DestX + W) - Dest->clip_maxx)+1; if(W<=0){SDL_SetError("SGE - Blit error");return -1;} } if ((DestY + H) > Dest->clip_maxy){ H = H - ((DestY + H) - Dest->clip_maxy)+1; if(H<=0){SDL_SetError("SGE - Blit error");return -1;} } #endif /* Initialize our rectangles */ src.x = SrcX; src.y = SrcY; src.w = W; src.h = H; dest.x = DestX; dest.y = DestY; dest.w = W; dest.h = H; /* We don't care about src clipping, only dest! */ #if SDL_VERSIONNUM(SDL_MAJOR_VERSION, SDL_MINOR_VERSION, SDL_PATCHLEVEL) < \ SDL_VERSIONNUM(1, 1, 5) if ( (Src->flags & SDL_SRCCLIPPING) == SDL_SRCCLIPPING){ Src->flags &= ~SDL_SRCCLIPPING; flag=1; } #endif /* Set the color to be transparent */ SDL_SetColorKey(Src, SDL_SRCCOLORKEY, Clear); /* Set the alpha value */ SDL_SetAlpha(Src, SDL_SRCALPHA, Alpha); /* Blit */ ret=SDL_BlitSurface(Src, &src, Dest, &dest); /* Set the correct flag */ #if SDL_VERSIONNUM(SDL_MAJOR_VERSION, SDL_MINOR_VERSION, SDL_PATCHLEVEL) < \ SDL_VERSIONNUM(1, 1, 5) if (flag==1){ Src->flags |= SDL_SRCCLIPPING; } #endif /* Set normal levels */ SDL_SetAlpha(Src,0,0); SDL_SetColorKey(Src,0,0); return ret; } //================================================================================== // Blit from one surface to another (not touching alpha or color key - // use SDL_SetColorKey and SDL_SetAlpha) //================================================================================== int sge_Blit(SDL_Surface *Src, SDL_Surface *Dest, Sint16 SrcX, Sint16 SrcY, Sint16 DestX, Sint16 DestY, Sint16 W, Sint16 H) { SDL_Rect src, dest; int ret; /* Dest clipping */ #if SDL_VERSIONNUM(SDL_MAJOR_VERSION, SDL_MINOR_VERSION, SDL_PATCHLEVEL) < \ SDL_VERSIONNUM(1, 1, 5) int flag=0; if (DestX < Dest->clip_minx){ SrcX += Dest->clip_minx-DestX; W -= Dest->clip_minx-DestX -1; DestX=Dest->clip_minx; } if (DestY < Dest->clip_miny){ SrcY +=Dest->clip_miny-DestY; H -= Dest->clip_miny-DestY -1; DestY=Dest->clip_miny; } if ((DestX + W) > Dest->clip_maxx){ W = W - ((DestX + W) - Dest->clip_maxx)+1; if(W<=0){SDL_SetError("SGE - Blit error");return -1;} } if ((DestY + H) > Dest->clip_maxy){ H = H - ((DestY + H) - Dest->clip_maxy)+1; if(H<=0){SDL_SetError("SGE - Blit error");return -1;} } #endif /* Initialize our rectangles */ src.x = SrcX; src.y = SrcY; src.w = W; src.h = H; dest.x = DestX; dest.y = DestY; dest.w = W; dest.h = H; /* We don't care about src clipping, only dest! */ #if SDL_VERSIONNUM(SDL_MAJOR_VERSION, SDL_MINOR_VERSION, SDL_PATCHLEVEL) < \ SDL_VERSIONNUM(1, 1, 5) if ( (Src->flags & SDL_SRCCLIPPING) == SDL_SRCCLIPPING){ Src->flags &= ~SDL_SRCCLIPPING; flag=1; } #endif /* Blit */ ret=SDL_BlitSurface(Src, &src, Dest, &dest); /* Set the correct flag */ #if SDL_VERSIONNUM(SDL_MAJOR_VERSION, SDL_MINOR_VERSION, SDL_PATCHLEVEL) < \ SDL_VERSIONNUM(1, 1, 5) if (flag==1){ Src->flags |= SDL_SRCCLIPPING; } #endif return ret; } //================================================================================== // Copies a surface to a new... //================================================================================== SDL_Surface *sge_copy_surface(SDL_Surface *src) { return SDL_ConvertSurface(src, src->format,SDL_SWSURFACE); } /**********************************************************************************/ /** Palette functions **/ /**********************************************************************************/ //================================================================================== // Fill in a palette entry with R, G, B componenets //================================================================================== SDL_Color sge_FillPaletteEntry(Uint8 R, Uint8 G, Uint8 B) { SDL_Color color; color.r = R; color.g = G; color.b = B; return color; } //================================================================================== // Get the RGB of a color value // Needed in those dark days before SDL 1.0 //================================================================================== SDL_Color sge_GetRGB(SDL_Surface *Surface, Uint32 Color) { SDL_Color rgb; SDL_GetRGB(Color, Surface->format, &(rgb.r), &(rgb.g), &(rgb.b)); return(rgb); } //================================================================================== // Fades from (sR,sG,sB) to (dR,dG,dB), puts result in ctab[start] to ctab[stop] //================================================================================== void sge_Fader(SDL_Surface *Surface, Uint8 sR,Uint8 sG,Uint8 sB, Uint8 dR,Uint8 dG,Uint8 dB,Uint32 *ctab,int start, int stop) { // (sR,sG,sB) and (dR,dG,dB) are two points in space (the RGB cube). /* The vector for the straight line */ int v[3]; v[0]=dR-sR; v[1]=dG-sG; v[2]=dB-sB; /* Ref. point */ int x0=sR, y0=sG, z0=sB; // The line's equation is: // x= x0 + v[0] * t // y= y0 + v[1] * t // z= z0 + v[2] * t // // (x,y,z) will travel between the two points when t goes from 0 to 1. int i=start; double step=1.0/((stop+1)-start); for(double t=0.0; t<=1.0 && i<=stop ; t+=step){ ctab[i++]=SDL_MapRGB(Surface->format, (Uint8)(x0+v[0]*t), (Uint8)(y0+v[1]*t), (Uint8)(z0+v[2]*t) ); } } //================================================================================== // Fades from (sR,sG,sB,sA) to (dR,dG,dB,dA), puts result in ctab[start] to ctab[stop] //================================================================================== 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) { // (sR,sG,sB,sA) and (dR,dG,dB,dA) are two points in hyperspace (the RGBA hypercube). /* The vector for the straight line */ int v[4]; v[0]=dR-sR; v[1]=dG-sG; v[2]=dB-sB; v[3]=dA-sA; /* Ref. point */ int x0=sR, y0=sG, z0=sB, w0=sA; // The line's equation is: // x= x0 + v[0] * t // y= y0 + v[1] * t // z= z0 + v[2] * t // w= w0 + v[3] * t // // (x,y,z,w) will travel between the two points when t goes from 0 to 1. int i=start; double step=1.0/((stop+1)-start); for(double t=0.0; t<=1.0 && i<=stop ; t+=step) ctab[i++]=sge_MapAlpha((Uint8)(x0+v[0]*t), (Uint8)(y0+v[1]*t), (Uint8)(z0+v[2]*t), (Uint8)(w0+v[3]*t)); } //================================================================================== // Copies a nice rainbow palette to the color table (ctab[start] to ctab[stop]). // You must also set the intensity of the palette (0-bright 255-dark) //================================================================================== void sge_SetupRainbowPalette(SDL_Surface *Surface,Uint32 *ctab,int intensity, int start, int stop) { int slice=(int)((stop-start)/6); /* Red-Yellow */ sge_Fader(Surface, 255,intensity,intensity, 255,255,intensity, ctab, start,slice); /* Yellow-Green */ sge_Fader(Surface, 255,255,intensity, intensity,255,intensity, ctab, slice+1, 2*slice); /* Green-Turquoise blue */ sge_Fader(Surface, intensity,255,intensity, intensity,255,255, ctab, 2*slice+1, 3*slice); /* Turquoise blue-Blue */ sge_Fader(Surface, intensity,255,255, intensity,intensity,255, ctab, 3*slice+1, 4*slice); /* Blue-Purple */ sge_Fader(Surface, intensity,intensity,255, 255,intensity,255, ctab, 4*slice+1, 5*slice); /* Purple-Red */ sge_Fader(Surface, 255,intensity,255, 255,intensity,intensity, ctab, 5*slice+1, stop); } //================================================================================== // Copies a B&W palette to the color table (ctab[start] to ctab[stop]). //================================================================================== void sge_SetupBWPalette(SDL_Surface *Surface,Uint32 *ctab,int start, int stop) { sge_Fader(Surface, 0,0,0, 255,255,255, ctab,start,stop); } /**********************************************************************************/ /** Color filling functions **/ /**********************************************************************************/ //================================================================================== // sge_FloodFill: Fast non-recursive flood fill // // Algorithm originally written by // Paul Heckbert, 13 Sept 1982, 28 Jan 1987 //================================================================================== /* horizontal segment of scan line y */ struct seg{ Sint16 y, xl, xr, dy; }; #define MAX 1000 /* max depth of stack */ #define PUSH(Y, XL, XR, DY){\ if (sp=sge_clip_ymin(dst) && Y+(DY)<=sge_clip_ymax(dst)){\ sp->y = Y;\ sp->xl = XL;\ sp->xr = XR;\ sp->dy = DY;\ sp++;\ }\ } #define POP(Y, XL, XR, DY){\ sp--;\ DY = sp->dy;\ Y = sp->y + sp->dy;\ XL = sp->xl;\ XR = sp->xr;\ } /* * set the pixel at (x,y) and all of its 4-connected neighbors * with the same pixel value to the new pixel color. * A 4-connected neighbor is a pixel above, below, left, or right of a pixel. */ // First a generic (slow) version and then 8/16/32 bpp versions void _FloodFillX(SDL_Surface *dst, Sint16 x, Sint16 y, Uint32 color) { Sint16 l, x1, x2, dy; Uint32 oc; /* old pixel color */ seg stack[MAX], *sp = stack; /* stack of filled segments */ if (xsge_clip_xmax(dst) || ysge_clip_ymax(dst)) return; oc = sge_GetPixel(dst, x,y); /* read color at seed point */ if (oc == color) return; PUSH(y, x, x, 1); /* needed in some cases */ PUSH(y+1, x, x, -1); /* seed segment (popped 1st) */ while (sp>stack) { /* pop segment off stack and fill a neighboring scan line */ POP(y, x1, x2, dy); /* * segment of scan line y-dy for x1<=x<=x2 was previously filled, * now explore adjacent pixels in scan line y */ for (x=x1; x>=sge_clip_xmin(dst); x--){ if( sge_GetPixel(dst, x,y) != oc ) break; _PutPixel(dst, x, y, color); } if (x>=x1) goto skip; l = x+1; if (lx2+1) PUSH(y, x2+1, x-1, -dy); /* leak on right? */ skip: for (x++; x<=x2; x++) if( sge_GetPixel(dst, x,y) == oc ) break; l = x; } while (x<=x2); } } /* Macro for 8/16/32 bpp */ #define DO_FILL(UintXX, label)\ {\ Sint16 l, x1, x2, dy;\ Uint32 oc; /* old pixel color */\ seg stack[MAX], *sp = stack; /* stack of filled segments */\ Uint16 pitch = dst->pitch/dst->format->BytesPerPixel;\ UintXX *row = (UintXX*)dst->pixels + y*pitch;\ UintXX *pixel = row + x;\ \ if (xsge_clip_xmax(dst) || ysge_clip_ymax(dst))\ return;\ \ oc = *pixel; /* read color at seed point */\ \ if (oc == color)\ return;\ \ PUSH(y, x, x, 1); /* needed in some cases */\ PUSH(y+1, x, x, -1); /* seed segment (popped 1st) */\ \ while (sp>stack) {\ /* pop segment off stack and fill a neighboring scan line */\ POP(y, x1, x2, dy);\ row = (UintXX*)dst->pixels + y*pitch;\ pixel = row + x1;\ \ /*\ * segment of scan line y-dy for x1<=x<=x2 was previously filled, * now explore adjacent pixels in scan line y */\ for (x=x1; x>=sge_clip_xmin(dst) && *pixel == oc; x--, pixel--)\ *pixel = color;\ \ if (x>=x1)\ goto label;\ \ l = x+1;\ if (lx2+1)\ PUSH(y, x2+1, x-1, -dy); /* leak on right? */\ label:\ pixel++;\ \ for (x++; x<=x2 && *pixel != oc; x++, pixel++);\ \ l = x;\ } while (x<=x2);\ }\ } // Wrapper function void sge_FloodFill(SDL_Surface *dst, Sint16 x, Sint16 y, Uint32 color) { if ( SDL_MUSTLOCK(dst) && _sge_lock ) if ( SDL_LockSurface(dst) < 0 ) return; switch (dst->format->BytesPerPixel) { case 1: /* Assuming 8-bpp */ DO_FILL(Uint8, skip8) break; case 2: /* Probably 15-bpp or 16-bpp */ DO_FILL(Uint16, skip16) break; case 3: /* Slow 24-bpp mode, usually not used */ _FloodFillX(dst, x,y, color); break; case 4: /* Probably 32-bpp */ DO_FILL(Uint32, skip32) break; } if ( SDL_MUSTLOCK(dst) && _sge_lock ){ SDL_UnlockSurface(dst); } } void sge_FloodFill(SDL_Surface *dst, Sint16 x, Sint16 y, Uint8 R, Uint8 G, Uint8 B) { sge_FloodFill(dst, x, y, SDL_MapRGB(dst->format, R,G,B)); } sge030809/sge_internal.h0000644000175000001440000000725007713172623013656 0ustar samusers/* * SDL Graphics Extension * SGE internal header * * Started 000627 * * License: LGPL v2+ (see the file LICENSE) * (c)2000-2003 Anders Lindstrm */ /********************************************************************* * This library is free software; you can redistribute it and/or * * modify it under the terms of the GNU Library General Public * * License as published by the Free Software Foundation; either * * version 2 of the License, or (at your option) any later version. * *********************************************************************/ #ifndef sge_internal_H #define sge_internal_H /* This header is included in all sge_*.h files */ #include "sge_config.h" /* * C compatibility * Thanks to Ohbayashi Ippei (ohai@kmc.gr.jp) for this clever hack! */ #ifdef _SGE_C_AND_CPP #ifdef __cplusplus #define _SGE_C /* use extern "C" on base functions */ #else #define sge_C_ONLY /* remove overloaded functions */ #define _SGE_NO_CLASSES /* no C++ classes */ #endif #endif /* * This is traditional */ #ifndef PI #define PI 3.1414926535 #endif /* * Bit flags */ #define SGE_FLAG0 0x00 #define SGE_FLAG1 0x01 #define SGE_FLAG2 0x02 #define SGE_FLAG3 0x04 #define SGE_FLAG4 0x08 #define SGE_FLAG5 0x10 #define SGE_FLAG6 0x20 #define SGE_FLAG7 0x40 #define SGE_FLAG8 0x80 /* * Define the right alpha values * (they were fliped in SDL 1.1.5+) */ #ifndef SDL_ALPHA_OPAQUE #define SDL_ALPHA_OPAQUE 0 #endif #ifndef SDL_ALPHA_TRANSPARENT #define SDL_ALPHA_TRANSPARENT 255 #endif /* * Older versions of SDL doesn't have SDL_VERSIONNUM */ #ifndef SDL_VERSIONNUM #define SDL_VERSIONNUM(X, Y, Z) \ (X)*1000 + (Y)*100 + (Z) #endif /* * Older versions of SDL doesn't have SDL_CreateRGBSurface */ #ifndef SDL_AllocSurface #define SDL_CreateRGBSurface SDL_AllocSurface #endif /* * Macro to get clipping */ #if SDL_VERSIONNUM(SDL_MAJOR_VERSION, SDL_MINOR_VERSION, SDL_PATCHLEVEL) >= \ SDL_VERSIONNUM(1, 1, 5) #define sge_clip_xmin(pnt) pnt->clip_rect.x #define sge_clip_xmax(pnt) pnt->clip_rect.x + pnt->clip_rect.w-1 #define sge_clip_ymin(pnt) pnt->clip_rect.y #define sge_clip_ymax(pnt) pnt->clip_rect.y + pnt->clip_rect.h-1 #else #define sge_clip_xmin(pnt) pnt->clip_minx #define sge_clip_xmax(pnt) pnt->clip_maxx #define sge_clip_ymin(pnt) pnt->clip_miny #define sge_clip_ymax(pnt) pnt->clip_maxy #endif /* * Macro to get the smallest bounding box from two (SDL_Rect) rectangles */ #define sge_RectUnion(dst_rect, rect1, rect2)\ dst_rect.x = (rect1.x < rect2.x)? rect1.x:rect2.x;\ dst_rect.y = (rect1.y < rect2.y)? rect1.y:rect2.y;\ dst_rect.w = (rect1.x + rect1.w > rect2.x + rect2.w)? rect1.x + rect1.w - dst_rect.x : rect2.x + rect2.w - dst_rect.x;\ dst_rect.h = (rect1.y + rect1.h > rect2.y + rect2.h)? rect1.y + rect1.h - dst_rect.y : rect2.y + rect2.h - dst_rect.y; /* * We need to use alpha sometimes but older versions of SDL doesn't have * alpha support. */ #if SDL_VERSIONNUM(SDL_MAJOR_VERSION, SDL_MINOR_VERSION, SDL_PATCHLEVEL) >= \ SDL_VERSIONNUM(1, 1, 5) #define sge_MapRGBA SDL_MapRGBA #define sge_GetRGBA SDL_GetRGBA #else #define sge_MapRGBA(fmt, r, g, b, a) SDL_MapRGB(fmt, r, g, b) #define sge_GetRGBA(pixel, fmt, r, g, b, a) SDL_GetRGBA(pixel, fmt, r, g, b) #endif /* * Some compilers use a special export keyword * Thanks to Seung Chan Lim (limsc@maya.com or slim@djslim.com) to pointing this out * (From SDL) */ #ifndef DECLSPEC #ifdef __BEOS__ #if defined(__GNUC__) #define DECLSPEC __declspec(dllexport) #else #define DECLSPEC __declspec(export) #endif #else #ifdef WIN32 #define DECLSPEC __declspec(dllexport) #else #define DECLSPEC #endif #endif #endif #endif /* sge_internal_H */ sge030809/sge_blib.h0000644000175000001440000001035107713761317012752 0ustar samusers/* * SDL Graphics Extension * Johan E. Thelin's BLib (header) * * Started 000428 * * License: LGPL v2+ (see the file LICENSE) * (c)2000-2003 Anders Lindstrm & Johan E. Thelin */ /********************************************************************* * This library is free software; you can redistribute it and/or * * modify it under the terms of the GNU Library General Public * * License as published by the Free Software Foundation; either * * version 2 of the License, or (at your option) any later version. * *********************************************************************/ #ifndef sge_blib_H #define sge_blib_H #include "SDL.h" #include "sge_internal.h" #ifdef _SGE_C extern "C" { #endif DECLSPEC void sge_FadedLine(SDL_Surface *dest,Sint16 x1,Sint16 x2,Sint16 y,Uint8 r1,Uint8 g1,Uint8 b1,Uint8 r2,Uint8 g2,Uint8 b2); DECLSPEC void sge_TexturedLine(SDL_Surface *dest,Sint16 x1,Sint16 x2,Sint16 y,SDL_Surface *source,Sint16 sx1,Sint16 sy1,Sint16 sx2,Sint16 sy2); DECLSPEC void sge_Trigon(SDL_Surface *dest,Sint16 x1,Sint16 y1,Sint16 x2,Sint16 y2,Sint16 x3,Sint16 y3,Uint32 color); DECLSPEC void sge_TrigonAlpha(SDL_Surface *dest,Sint16 x1,Sint16 y1,Sint16 x2,Sint16 y2,Sint16 x3,Sint16 y3,Uint32 color, Uint8 alpha); DECLSPEC void sge_AATrigon(SDL_Surface *dest,Sint16 x1,Sint16 y1,Sint16 x2,Sint16 y2,Sint16 x3,Sint16 y3,Uint32 color); DECLSPEC void sge_AATrigonAlpha(SDL_Surface *dest,Sint16 x1,Sint16 y1,Sint16 x2,Sint16 y2,Sint16 x3,Sint16 y3,Uint32 color, Uint8 alpha); DECLSPEC void sge_FilledTrigon(SDL_Surface *dest,Sint16 x1,Sint16 y1,Sint16 x2,Sint16 y2,Sint16 x3,Sint16 y3,Uint32 color); DECLSPEC void sge_FilledTrigonAlpha(SDL_Surface *dest,Sint16 x1,Sint16 y1,Sint16 x2,Sint16 y2,Sint16 x3,Sint16 y3,Uint32 color, Uint8 alpha); DECLSPEC void sge_FadedTrigon(SDL_Surface *dest,Sint16 x1,Sint16 y1,Sint16 x2,Sint16 y2,Sint16 x3,Sint16 y3,Uint32 c1,Uint32 c2,Uint32 c3); DECLSPEC void sge_TexturedTrigon(SDL_Surface *dest,Sint16 x1,Sint16 y1,Sint16 x2,Sint16 y2,Sint16 x3,Sint16 y3,SDL_Surface *source,Sint16 sx1,Sint16 sy1,Sint16 sx2,Sint16 sy2,Sint16 sx3,Sint16 sy3); DECLSPEC void sge_TexturedRect(SDL_Surface *dest,Sint16 x1,Sint16 y1,Sint16 x2,Sint16 y2,Sint16 x3,Sint16 y3,Sint16 x4,Sint16 y4,SDL_Surface *source,Sint16 sx1,Sint16 sy1,Sint16 sx2,Sint16 sy2,Sint16 sx3,Sint16 sy3,Sint16 sx4,Sint16 sy4); DECLSPEC int sge_FilledPolygon(SDL_Surface *dest, Uint16 n, Sint16 *x, Sint16 *y, Uint32 color); DECLSPEC int sge_FilledPolygonAlpha(SDL_Surface *dest, Uint16 n, Sint16 *x, Sint16 *y, Uint32 color, Uint8 alpha); DECLSPEC int sge_AAFilledPolygon(SDL_Surface *dest, Uint16 n, Sint16 *x, Sint16 *y, Uint32 color); DECLSPEC int sge_FadedPolygon(SDL_Surface *dest, Uint16 n, Sint16 *x, Sint16 *y, Uint8 *R, Uint8 *G, Uint8 *B); DECLSPEC int sge_FadedPolygonAlpha(SDL_Surface *dest, Uint16 n, Sint16 *x, Sint16 *y, Uint8 *R, Uint8 *G, Uint8 *B, Uint8 alpha); DECLSPEC int sge_AAFadedPolygon(SDL_Surface *dest, Uint16 n, Sint16 *x, Sint16 *y, Uint8 *R, Uint8 *G, Uint8 *B); #ifdef _SGE_C } #endif #ifndef sge_C_ONLY DECLSPEC void sge_Trigon(SDL_Surface *dest,Sint16 x1,Sint16 y1,Sint16 x2,Sint16 y2,Sint16 x3,Sint16 y3,Uint8 R, Uint8 G, Uint8 B); DECLSPEC void sge_TrigonAlpha(SDL_Surface *dest,Sint16 x1,Sint16 y1,Sint16 x2,Sint16 y2,Sint16 x3,Sint16 y3,Uint8 R, Uint8 G, Uint8 B, Uint8 alpha); DECLSPEC void sge_AATrigon(SDL_Surface *dest,Sint16 x1,Sint16 y1,Sint16 x2,Sint16 y2,Sint16 x3,Sint16 y3,Uint8 R, Uint8 G, Uint8 B); DECLSPEC void sge_AATrigonAlpha(SDL_Surface *dest,Sint16 x1,Sint16 y1,Sint16 x2,Sint16 y2,Sint16 x3,Sint16 y3,Uint8 R, Uint8 G, Uint8 B, Uint8 alpha); DECLSPEC void sge_FilledTrigon(SDL_Surface *dest,Sint16 x1,Sint16 y1,Sint16 x2,Sint16 y2,Sint16 x3,Sint16 y3,Uint8 R, Uint8 G, Uint8 B); DECLSPEC void sge_FilledTrigonAlpha(SDL_Surface *dest,Sint16 x1,Sint16 y1,Sint16 x2,Sint16 y2,Sint16 x3,Sint16 y3,Uint8 R, Uint8 G, Uint8 B, Uint8 alpha); DECLSPEC int sge_FilledPolygon(SDL_Surface *dest, Uint16 n, Sint16 *x, Sint16 *y, Uint8 r, Uint8 g, Uint8 b); DECLSPEC int sge_FilledPolygonAlpha(SDL_Surface *dest, Uint16 n, Sint16 *x, Sint16 *y, Uint8 r, Uint8 g, Uint8 b, Uint8 alpha); DECLSPEC int sge_AAFilledPolygon(SDL_Surface *dest, Uint16 n, Sint16 *x, Sint16 *y, Uint8 r, Uint8 g, Uint8 b); #endif /* sge_C_ONLY */ #endif /* sge_blib_H */ sge030809/sge_misc.h0000644000175000001440000000166107713172615012776 0ustar samusers/* * SDL Graphics Extension * Misc functions (header) * * Started 990819 * * License: LGPL v2+ (see the file LICENSE) * (c)1999-2003 Anders Lindstrm */ /********************************************************************* * This library is free software; you can redistribute it and/or * * modify it under the terms of the GNU Library General Public * * License as published by the Free Software Foundation; either * * version 2 of the License, or (at your option) any later version. * *********************************************************************/ #ifndef sge_misc_H #define sge_misc_H #include "SDL.h" #include "sge_internal.h" #ifdef _SGE_C extern "C" { #endif DECLSPEC int sge_Random(int min, int max); DECLSPEC void sge_Randomize(void); DECLSPEC Uint32 sge_CalibrateDelay(void); DECLSPEC Uint32 sge_DelayRes(void); DECLSPEC Uint32 sge_Delay(Uint32 ticks); #ifdef _SGE_C } #endif #endif /* sge_misc_H */ sge030809/sge_surface.h0000644000175000001440000001133507713172562013473 0ustar samusers/* * SDL Graphics Extension * Pixel, surface and color functions (header) * * Started 990815 (split from sge_draw 010611) * * License: LGPL v2+ (see the file LICENSE) * (c)1999-2003 Anders Lindstrm */ /********************************************************************* * This library is free software; you can redistribute it and/or * * modify it under the terms of the GNU Library General Public * * License as published by the Free Software Foundation; either * * version 2 of the License, or (at your option) any later version. * *********************************************************************/ #ifndef sge_surface_H #define sge_surface_H #include "SDL.h" #include "sge_internal.h" /* * Obsolete function names */ #define sge_copy_sblock8 sge_write_block8 #define sge_copy_sblock16 sge_write_block16 #define sge_copy_sblock32 sge_write_block32 #define sge_get_sblock8 sge_read_block8 #define sge_get_sblock16 sge_read_block16 #define sge_get_sblock32 sge_read_block32 #ifdef _SGE_C extern "C" { #endif DECLSPEC void sge_Update_OFF(void); DECLSPEC void sge_Update_ON(void); DECLSPEC void sge_Lock_OFF(void); DECLSPEC void sge_Lock_ON(void); DECLSPEC Uint8 sge_getUpdate(void); DECLSPEC Uint8 sge_getLock(void); DECLSPEC void sge_UpdateRect(SDL_Surface *screen, Sint16 x, Sint16 y, Uint16 w, Uint16 h); DECLSPEC SDL_Surface *sge_CreateAlphaSurface(Uint32 flags, int width, int height); DECLSPEC Uint32 sge_MapAlpha(Uint8 R, Uint8 G, Uint8 B, Uint8 A); DECLSPEC void sge_SetError(const char *format, ...); DECLSPEC void _PutPixel(SDL_Surface *surface, Sint16 x, Sint16 y, Uint32 color); DECLSPEC void _PutPixel8(SDL_Surface *surface, Sint16 x, Sint16 y, Uint32 color); DECLSPEC void _PutPixel16(SDL_Surface *surface, Sint16 x, Sint16 y, Uint32 color); DECLSPEC void _PutPixel24(SDL_Surface *surface, Sint16 x, Sint16 y, Uint32 color); DECLSPEC void _PutPixel32(SDL_Surface *surface, Sint16 x, Sint16 y, Uint32 color); DECLSPEC void _PutPixelX(SDL_Surface *dest,Sint16 x,Sint16 y,Uint32 color); DECLSPEC Sint32 sge_CalcYPitch(SDL_Surface *dest,Sint16 y); DECLSPEC void sge_pPutPixel(SDL_Surface *surface, Sint16 x, Sint32 ypitch, Uint32 color); DECLSPEC void sge_PutPixel(SDL_Surface *surface, Sint16 x, Sint16 y, Uint32 color); DECLSPEC Uint32 sge_GetPixel(SDL_Surface *surface, Sint16 x, Sint16 y); DECLSPEC void _PutPixelAlpha(SDL_Surface *surface, Sint16 x, Sint16 y, Uint32 color, Uint8 alpha); DECLSPEC void sge_PutPixelAlpha(SDL_Surface *surface, Sint16 x, Sint16 y, Uint32 color, Uint8 alpha); DECLSPEC void sge_write_block8(SDL_Surface *Surface, Uint8 *block, Sint16 y); DECLSPEC void sge_write_block16(SDL_Surface *Surface, Uint16 *block, Sint16 y); DECLSPEC void sge_write_block32(SDL_Surface *Surface, Uint32 *block, Sint16 y); DECLSPEC void sge_read_block8(SDL_Surface *Surface, Uint8 *block, Sint16 y); DECLSPEC void sge_read_block16(SDL_Surface *Surface, Uint16 *block, Sint16 y); DECLSPEC void sge_read_block32(SDL_Surface *Surface, Uint32 *block, Sint16 y); DECLSPEC void sge_ClearSurface(SDL_Surface *Surface, Uint32 color); DECLSPEC 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); DECLSPEC int sge_Blit(SDL_Surface *Src, SDL_Surface *Dest, Sint16 SrcX, Sint16 SrcY, Sint16 DestX, Sint16 DestY, Sint16 W, Sint16 H); DECLSPEC SDL_Surface *sge_copy_surface(SDL_Surface *src); DECLSPEC SDL_Color sge_GetRGB(SDL_Surface *Surface, Uint32 Color); DECLSPEC SDL_Color sge_FillPaletteEntry (Uint8 R, Uint8 G, Uint8 B); DECLSPEC void sge_Fader(SDL_Surface *Surface, Uint8 sR,Uint8 sG,Uint8 sB, Uint8 dR,Uint8 dG,Uint8 dB,Uint32 *ctab,int start, int stop); DECLSPEC 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); DECLSPEC void sge_SetupRainbowPalette(SDL_Surface *Surface,Uint32 *ctab,int intensity, int start, int stop); DECLSPEC void sge_SetupBWPalette(SDL_Surface *Surface,Uint32 *ctab,int start, int stop); DECLSPEC void sge_FloodFill(SDL_Surface *dst, Sint16 x, Sint16 y, Uint32 color); #ifdef _SGE_C } #endif #ifndef sge_C_ONLY DECLSPEC void _PutPixel(SDL_Surface *screen, Sint16 x, Sint16 y, Uint8 R, Uint8 G, Uint8 B); DECLSPEC void sge_PutPixel(SDL_Surface *screen, Sint16 x, Sint16 y, Uint8 R, Uint8 G, Uint8 B); DECLSPEC void _PutPixelAlpha(SDL_Surface *surface, Sint16 x, Sint16 y, Uint8 R, Uint8 G, Uint8 B, Uint8 alpha); DECLSPEC void sge_PutPixelAlpha(SDL_Surface *surface, Sint16 x, Sint16 y, Uint8 R, Uint8 G, Uint8 B, Uint8 alpha); DECLSPEC void sge_ClearSurface(SDL_Surface *Surface, Uint8 R, Uint8 G, Uint8 B); DECLSPEC void sge_FloodFill(SDL_Surface *dst, Sint16 x, Sint16 y, Uint8 R, Uint8 G, Uint8 B); #endif /* sge_C_ONLY */ #endif /* sge_surface_H */ sge030809/sge_collision.h0000644000175000001440000000331707713172666014044 0ustar samusers/* * SDL Graphics Extension * Collision routines (header) * * Started 000625 * * License: LGPL v2+ (see the file LICENSE) * (c)1999-2003 Anders Lindstrm */ /********************************************************************* * This library is free software; you can redistribute it and/or * * modify it under the terms of the GNU Library General Public * * License as published by the Free Software Foundation; either * * version 2 of the License, or (at your option) any later version. * *********************************************************************/ #ifndef sge_collision_H #define sge_collision_H #include "SDL.h" #include "sge_internal.h" /* The collision struct */ typedef struct { Uint8 *map; Uint16 w,h; } sge_cdata; #ifdef _SGE_C extern "C" { #endif DECLSPEC sge_cdata *sge_make_cmap(SDL_Surface *img); DECLSPEC int sge_bbcheck(sge_cdata *cd1,Sint16 x1,Sint16 y1, sge_cdata *cd2,Sint16 x2,Sint16 y2); DECLSPEC int _sge_bbcheck(Sint16 x1,Sint16 y1,Sint16 w1,Sint16 h1, Sint16 x2,Sint16 y2,Sint16 w2,Sint16 h2); DECLSPEC int _sge_cmcheck(sge_cdata *cd1,Sint16 x1,Sint16 y1, sge_cdata *cd2,Sint16 x2,Sint16 y2); DECLSPEC int sge_cmcheck(sge_cdata *cd1,Sint16 x1,Sint16 y1, sge_cdata *cd2,Sint16 x2,Sint16 y2); DECLSPEC Sint16 sge_get_cx(void); DECLSPEC Sint16 sge_get_cy(void); DECLSPEC void sge_destroy_cmap(sge_cdata *cd); DECLSPEC void sge_unset_cdata(sge_cdata *cd, Sint16 x, Sint16 y, Sint16 w, Sint16 h); DECLSPEC void sge_set_cdata(sge_cdata *cd, Sint16 x, Sint16 y, Sint16 w, Sint16 h); #ifdef _SGE_C } #endif #ifndef _SGE_NO_CLASSES class DECLSPEC sge_shape; DECLSPEC int sge_bbcheck_shape(sge_shape *shape1, sge_shape *shape2); #endif /* _SGE_NO_CLASSES */ #endif /* sge_collision_H */ sge030809/sge_textpp.cpp0000644000175000001440000003737107715152147013731 0ustar samusers/* * SDL Graphics Extension * Text/TrueType classes * * Started 990826 / 010207 (new version) * * License: LGPL v2+ (see the file LICENSE) * (c)1999-2003 Anders Lindstrm * * Uses the excellent FreeType 2 library, available at: * http://www.freetype.org/ */ /********************************************************************* * This library is free software; you can redistribute it and/or * * modify it under the terms of the GNU Library General Public * * License as published by the Free Software Foundation; either * * version 2 of the License, or (at your option) any later version. * *********************************************************************/ #include "SDL.h" #include #include #include "sge_surface.h" #include "sge_textpp.h" #ifndef _SGE_NO_CLASSES using namespace std; //================================================================================== // sge_TextEditor //================================================================================== sge_TextEditor::node* sge_TextEditor::new_node(node* p, node* n, Uint16 c) { node* tmp = new node; tmp->prev=p; tmp->next=n; tmp->c=c; text_changed=true; return tmp; } bool sge_TextEditor::nswap(node* one, node* two) { if(!one || !two || one==two) return false; //Check if the two nodes are connected if(one->prev==two){ one->prev=two->prev; two->next=one->next; one->next=two; two->prev=one; }else if(one->next==two){ one->next=two->next; two->prev=one->prev; one->prev=two; two->next=one; }else{ node* p= one->prev; node* n= one->next; one->prev= two->prev; one->next= two->next; two->prev= p; two->next= n; } //Update connected nodes and list metadata if(!one->prev) start=one; else one->prev->next=one; if(!one->next) end=one; else one->next->prev=one; if(!two->prev) start=two; else two->prev->next=two; if(!two->next) end=two; else two->next->prev=two; text_changed=true; return true; } sge_TextEditor::sge_TextEditor(void) { chars=0; mChars=0; cursor_char=124; //The charactar for the cursor - '|' cursor=end=start=new_node(NULL,NULL,cursor_char); text_changed=false; } sge_TextEditor::~sge_TextEditor(void) { node *tmp; for(node* i=start; i;){ tmp=i->next; delete i; i=tmp; } } bool sge_TextEditor::insert(Uint16 c) { if(mChars && chars>=mChars) return false; if(cursor->prev){ cursor->prev->next=new_node(cursor->prev,cursor,c); cursor->prev=cursor->prev->next; } else{ //New first node - update list metadata cursor->prev=start=new_node(NULL,cursor,c); } chars++; return true; } bool sge_TextEditor::remove_left(void) { if(cursor->prev){ node* tmp=cursor->prev->prev; delete cursor->prev; cursor->prev=tmp; if(!cursor->prev) start=cursor; else tmp->next=cursor; chars--; text_changed=true; return true; } return false; } bool sge_TextEditor::remove_right(void) { if(cursor->next){ node* tmp=cursor->next->next; delete cursor->next; cursor->next=tmp; if(!cursor->next) end=cursor; else tmp->prev=cursor; chars--; text_changed=true; return true; } return false; } bool sge_TextEditor::move_left(void) { return nswap(cursor,cursor->prev); } bool sge_TextEditor::move_right(void) { return nswap(cursor,cursor->next); } bool sge_TextEditor::move_start(void) { if(cursor->prev){ cursor->prev->next= cursor->next; if(cursor->next) cursor->next->prev= cursor->prev; else end=cursor->prev; cursor->prev= NULL; cursor->next= start; start->prev= cursor; start= cursor; text_changed=true; return true; } return false; } bool sge_TextEditor::move_end(void) { if(cursor->next){ cursor->next->prev= cursor->prev; if(cursor->prev) cursor->prev->next= cursor->next; else start=cursor->next; cursor->next= NULL; cursor->prev= end; end->next= cursor; end= cursor; text_changed=true; return true; } return false; } string sge_TextEditor::get_string(bool wCursor) { string ret; for(node* i=start; i; i=i->next){ if(!wCursor && i==cursor) continue; ret += char(i->c); } return ret; } /* basic_string sge_TextEditor::get_ustring(bool wCursor) { basic_string ret; for(node* i=start; i; i=i->next){ if(!wCursor && i==cursor) continue; ret += i->c; } return ret; } */ Uint16* sge_TextEditor::get_ucstring(bool wCursor) { Uint16* str=NULL; if(wCursor) str= new Uint16[chars+2]; else str= new Uint16[chars+1]; int k=0; for(node* i=start; i; i=i->next){ if(!wCursor && i==cursor) continue; str[k++] = i->c; } str[k]=0; return str; } bool sge_TextEditor::check(SDL_Event* event) { if(event->type!=SDL_KEYDOWN) return false; if(event->key.keysym.sym==SDLK_BACKSPACE) return remove_left(); else if(event->key.keysym.sym==SDLK_DELETE) return remove_right(); else if(event->key.keysym.sym==SDLK_LEFT) return move_left(); else if(event->key.keysym.sym==SDLK_RIGHT) return move_right(); else if(event->key.keysym.sym==SDLK_RETURN || event->key.keysym.sym==SDLK_KP_ENTER) return false; else if(event->key.keysym.sym==SDLK_HOME) return move_start(); else if(event->key.keysym.sym==SDLK_END) return move_end(); else if(event->key.keysym.unicode!=0) return insert(event->key.keysym.unicode); return false; } void sge_TextEditor::clear_text(void) { if(!chars) return; node *tmp; for(node* i=start; i;){ tmp=i->next; delete i; i=tmp; } cursor=end=start=new_node(NULL,NULL,cursor_char); chars=0; text_changed=true; } void sge_TextEditor::change_text(const string s) { clear_text(); for(unsigned int i=0; i s) { clear_text(); for(unsigned int i=0; iformat,background.r,background.g,background.b)); if( alpha_level != SDL_ALPHA_OPAQUE ) SDL_SetAlpha(text_surface, SDL_SRCALPHA, alpha_level); set_textSurface(text_surface); }else #endif if(bm_font){ if(bm_font->CharPos && bm_font->FontSurface->format->Amask){ set_textSurface(NULL); return true; /* These fonts can't be buffered (SFonts) */ } if(text_surface) SDL_FreeSurface(text_surface); string text=get_string(sCursor); SDL_Rect size = sge_BF_TextSize(bm_font, (char*)(text.c_str())); text_surface = SDL_CreateRGBSurface(SDL_SWSURFACE, size.w, size.h, bm_font->FontSurface->format->BitsPerPixel, bm_font->FontSurface->format->Rmask, bm_font->FontSurface->format->Gmask, bm_font->FontSurface->format->Bmask, 0); if(!text_surface) return false; Uint32 bcol; if(bm_font->FontSurface->format->palette){ //Set the palette SDL_Color c[2]; c[0].r=bm_font->FontSurface->format->palette->colors[1].r+100; /* Whatever */ c[0].g=bm_font->FontSurface->format->palette->colors[1].g+100; c[0].b=bm_font->FontSurface->format->palette->colors[1].b+100; c[1].r=bm_font->FontSurface->format->palette->colors[1].r; c[1].g=bm_font->FontSurface->format->palette->colors[1].g; c[1].b=bm_font->FontSurface->format->palette->colors[1].b; SDL_SetColors(text_surface, c, 0, 2); bcol = 0; }else{ //Use the same background color as the font surface Uint8 r,g,b; SDL_GetRGB(bm_font->bcolor, bm_font->FontSurface->format, &r, &g, &b); bcol = SDL_MapRGB(text_surface->format, r,g,b); sge_ClearSurface(text_surface, bcol); } sge_BF_textout(text_surface, bm_font, (char*)(text.c_str()), 0, 0); SDL_SetColorKey(text_surface,SDL_SRCCOLORKEY, bcol); if( alpha_level != SDL_ALPHA_OPAQUE ) SDL_SetAlpha(text_surface, SDL_SRCALPHA, alpha_level); set_textSurface(text_surface); }else return false; text_changed=false; return true; } return false; } #ifndef _SGE_NOTTF void sge_text::set_ttFont(sge_TTFont *font, Uint8 r, Uint8 g, Uint8 b, Uint8 br, Uint8 bg, Uint8 bb) { color.r=r; color.g=g; color.b=b; background.r=br; background.g=bg; background.b=bb; tt_font=font; use_tt=true; update_textSurface(true); } #endif void sge_text::set_bmFont(sge_bmpFont *font) { bm_font=font; use_tt=false; update_textSurface(true); } SDL_Rect sge_text::render_text(SDL_Surface *surface, Sint16 x, Sint16 y) { #ifndef _SGE_NOTTF if(use_tt && tt_font){ SDL_Rect ret; ret.x=ret.y=ret.w=ret.h=0; SDL_Surface *tmp; Uint16* text=get_ucstring(sCursor); tmp=sge_TTF_Render(tt_font, text, color, background, alpha_level); delete[] text; if(!tmp) return ret; SDL_SetColorKey(tmp,SDL_SRCCOLORKEY,SDL_MapRGB(tmp->format,background.r,background.g,background.b)); if( alpha_level != SDL_ALPHA_OPAQUE ) SDL_SetAlpha(tmp, SDL_SRCALPHA, alpha_level); sge_Blit(tmp, surface, 0, 0, x, y, tmp->w, tmp->h); ret.x=x; ret.y=y; ret.w=tmp->w; ret.h=tmp->h; SDL_FreeSurface(tmp); return ret; }else #endif if(bm_font){ string text=get_string(sCursor); if( alpha_level != SDL_ALPHA_OPAQUE && !bm_font->FontSurface->format->Amask) SDL_SetAlpha(bm_font->FontSurface,SDL_SRCALPHA, alpha_level); return sge_BF_textout(surface, bm_font, (char*)(text.c_str()), x, y); }else{ SDL_Rect ret; ret.x=ret.y=ret.w=ret.h=0; return ret; } } //================================================================================== // sge_TextSurface //================================================================================== void sge_TextSurface::set_textSurface(SDL_Surface *new_surf) { if(bm_font){ if(bm_font->CharPos && bm_font->FontSurface->format->Amask){ SDL_Rect size = sge_BF_TextSize(bm_font, (char*)(get_string(sCursor).c_str())); current_pos.w = size.w; current_pos.h = size.h; return; } } surface=new_surf; current_pos.w=surface->w; current_pos.h=surface->h; } void sge_TextSurface::draw(void) { if(bm_font){ if(bm_font->CharPos && bm_font->FontSurface->format->Amask){ /* These fonts can't be buffered and must be rendered */ SDL_Rect size = render_text(dest, current_pos.x, current_pos.y); current_pos.w = size.w; current_pos.h = size.h; prev_pos=last_pos; last_pos=current_pos; return; } } update_textSurface(); if(text_surface) sge_surface::draw(); } //================================================================================== // sge_TextSsprite //================================================================================== void sge_TextSsprite::set_textSurface(SDL_Surface *new_surf) { if(bm_font){ if(bm_font->CharPos && bm_font->FontSurface->format->Amask){ SDL_Rect size = sge_BF_TextSize(bm_font, (char*)(get_string(sCursor).c_str())); current_pos.w = size.w; current_pos.h = size.h; return; } } //Update the first frame sge_frame *tmp=frames.front(); if(tmp->img==surface){ surface=new_surf; current_pos.w=surface->w; current_pos.h=surface->h; } tmp->img=new_surf; } void sge_TextSsprite::draw(void) { if(bm_font){ if(bm_font->CharPos && bm_font->FontSurface->format->Amask){ /* These fonts can't be buffered and must be rendered */ SDL_Rect size = render_text(dest, current_pos.x, current_pos.y); current_pos.w = size.w; current_pos.h = size.h; prev_pos=last_pos; last_pos=current_pos; return; } } update_textSurface(); if(text_surface){ sge_surface::draw(); } } //================================================================================== // sge_TextSprite //================================================================================== void sge_TextSprite::set_textSurface(SDL_Surface *new_surf) { if(bm_font){ if(bm_font->CharPos && bm_font->FontSurface->format->Amask){ SDL_Rect size = sge_BF_TextSize(bm_font, (char*)(get_string(sCursor).c_str())); current_pos.w = size.w; current_pos.h = size.h; return; } } //Update the first frame sge_frame *tmp=frames.front(); if(tmp->img==surface){ surface=new_surf; current_pos.w=surface->w; current_pos.h=surface->h; } tmp->img=new_surf; } void sge_TextSprite::draw(void) { if(bm_font){ if(bm_font->CharPos && bm_font->FontSurface->format->Amask){ /* These fonts can't be buffered and must be rendered */ SDL_Rect size = render_text(dest, current_pos.x, current_pos.y); current_pos.w = size.w; current_pos.h = size.h; prev_pos=last_pos; last_pos=current_pos; return; } } update_textSurface(); if(text_surface){ sge_surface::draw(); } } //================================================================================== // A helper function for lazy users: blocking text input for sge_TextSurface // objects. // Flags is the same as for BM and TTF input (which now uses this function) //================================================================================== extern Uint8 _sge_update; int sge_text_input(sge_TextSurface *tc, Uint8 flags) { if( !tc ) return -4; Uint8 update = _sge_update; SDL_Surface *screen = tc->get_dest(); SDL_Surface *buffer = NULL; SDL_Color bg; bool is_ttf = tc->get_bg(&bg); /* No bc color indicates bitmap font */ if( flags&SGE_FLAG1 || !is_ttf ){ /* Keep background? */ buffer = SDL_DisplayFormat(screen); if(buffer==NULL){ SDL_SetError("SGE - Out of memory");return -3; } } /* Enable keyrepeat */ if(!(flags&SGE_FLAG3)) SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL+50); int uflag = SDL_EnableUNICODE(1); Sint16 x = tc->get_xpos(); Sint16 y = tc->get_ypos(); /* Draw the text for the first time */ tc->draw(); tc->UpdateRects(); /* Main loop */ SDL_Event event; int quit = 0; do{ SDL_WaitEvent(&event); if( event.type == SDL_QUIT ){ quit=-1; break; } else if( event.type == SDL_KEYDOWN && event.key.keysym.sym == SDLK_ESCAPE ){ quit=-2; break; } else if(event.type==SDL_KEYDOWN && (event.key.keysym.sym==SDLK_RETURN || event.key.keysym.sym==SDLK_KP_ENTER)){ quit=0; break; } /* Let the text class handle the event*/ if( tc->check(&event) ){ /* The text has changed */ if(buffer) tc->clear(buffer, x,y); //Remove the text else tc->clear(SDL_MapRGB(screen->format, bg.r, bg.g, bg.b)); tc->draw(); //Draw the new text sge_Update_ON(); tc->UpdateRects(); //Update screen sge_Update_OFF(); } }while(true); if(buffer){ tc->clear(buffer, x,y); //Remove the text SDL_FreeSurface(buffer); } if( !(flags&SGE_FLAG2) ){ //Draw text without cursor tc->show_cursor(false); tc->draw(); } sge_Update_ON(); tc->UpdateRects(); //Update screen _sge_update = update; SDL_EnableUNICODE(uflag); //Restore unicode setting if( quit < 0 ) return quit; else return tc->get_chars(); } #endif /* _SGE_NO_CLASSES */ sge030809/sge_blib.cpp0000644000175000001440000013152007714177170013306 0ustar samusers/* * SDL Graphics Extension * Triangles of every sort * * Started 000428 * * License: LGPL v2+ (see the file LICENSE) * (c)2000-2003 Anders Lindstrm & Johan E. Thelin */ /********************************************************************* * This library is free software; you can redistribute it and/or * * modify it under the terms of the GNU Library General Public * * License as published by the Free Software Foundation; either * * version 2 of the License, or (at your option) any later version. * *********************************************************************/ /* * Written with some help from Johan E. Thelin. */ #include "SDL.h" #include "sge_surface.h" #include "sge_primitives.h" #include "sge_blib.h" #define SWAP(x,y,temp) temp=x;x=y;y=temp /* Globals used for sge_Update/sge_Lock (defined in sge_surface) */ extern Uint8 _sge_update; extern Uint8 _sge_lock; extern Uint8 _sge_alpha_hack; /* We need some internal functions */ extern void _Line(SDL_Surface *surface, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint32 color); extern void _LineAlpha(SDL_Surface *Surface, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint32 Color, Uint8 alpha); extern void _HLine(SDL_Surface *Surface, Sint16 x1, Sint16 x2, Sint16 y, Uint32 Color); extern void _HLineAlpha(SDL_Surface *Surface, Sint16 x1, Sint16 x2, Sint16 y, Uint32 Color, Uint8 alpha); extern void callback_alpha_hack(SDL_Surface *surf, Sint16 x, Sint16 y, Uint32 color); extern void _AALineAlpha(SDL_Surface *dst, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint32 color, Uint8 alpha); extern 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); /* Macro to inline RGB mapping */ #define MapRGB(format, r, g, b)\ (r >> format->Rloss) << format->Rshift\ | (g >> format->Gloss) << format->Gshift\ | (b >> format->Bloss) << format->Bshift //================================================================================== // Draws a horisontal line, fading the colors //================================================================================== void _FadedLine(SDL_Surface *dest,Sint16 x1,Sint16 x2,Sint16 y,Uint8 r1,Uint8 g1,Uint8 b1,Uint8 r2,Uint8 g2,Uint8 b2) { Sint16 x; Uint8 t; /* Fix coords */ if ( x1 > x2 ) { SWAP(x1,x2,x); SWAP(r1,r2,t); SWAP(g1,g2,t); SWAP(b1,b2,t); } /* We use fixedpoint math */ Sint32 R = r1<<16; Sint32 G = g1<<16; Sint32 B = b1<<16; /* Color step value */ Sint32 rstep = Sint32((r2-r1)<<16) / Sint32(x2-x1+1); Sint32 gstep = Sint32((g2-g1)<<16) / Sint32(x2-x1+1); Sint32 bstep = Sint32((b2-b1)<<16) / Sint32(x2-x1+1); /* Clipping */ if(x2sge_clip_xmax(dest) || ysge_clip_ymax(dest)) return; if (x1 < sge_clip_xmin(dest)){ /* Update start colors */ R += (sge_clip_xmin(dest)-x1)*rstep; G += (sge_clip_xmin(dest)-x1)*gstep; B += (sge_clip_xmin(dest)-x1)*bstep; x1 = sge_clip_xmin(dest); } if (x2 > sge_clip_xmax(dest)) x2 = sge_clip_xmax(dest); switch (dest->format->BytesPerPixel) { case 1: { /* Assuming 8-bpp */ Uint8 *pixel; Uint8 *row = (Uint8 *)dest->pixels + y*dest->pitch; for (x = x1; x <= x2; x++){ pixel = row + x; *pixel = SDL_MapRGB( dest->format, R>>16, G>>16, B>>16 ); R += rstep; G += gstep; B += bstep; } } break; case 2: { /* Probably 15-bpp or 16-bpp */ Uint16 *pixel; Uint16 *row = (Uint16 *)dest->pixels + y*dest->pitch/2; for (x = x1; x <= x2; x++){ pixel = row + x; *pixel = MapRGB( dest->format, R>>16, G>>16, B>>16 ); R += rstep; G += gstep; B += bstep; } } break; case 3: { /* Slow 24-bpp mode, usually not used */ Uint8 *pixel; Uint8 *row = (Uint8 *)dest->pixels + y*dest->pitch; Uint8 rshift8=dest->format->Rshift/8; Uint8 gshift8=dest->format->Gshift/8; Uint8 bshift8=dest->format->Bshift/8; for (x = x1; x <= x2; x++){ pixel = row + x*3; *(pixel+rshift8) = R>>16; *(pixel+gshift8) = G>>16; *(pixel+bshift8) = B>>16; R += rstep; G += gstep; B += bstep; } } break; case 4: { /* Probably 32-bpp */ Uint32 *pixel; Uint32 *row = (Uint32 *)dest->pixels + y*dest->pitch/4; for (x = x1; x <= x2; x++){ pixel = row + x; *pixel = MapRGB( dest->format, R>>16, G>>16, B>>16 ); R += rstep; G += gstep; B += bstep; } } break; } } void sge_FadedLine(SDL_Surface *dest,Sint16 x1,Sint16 x2,Sint16 y,Uint8 r1,Uint8 g1,Uint8 b1,Uint8 r2,Uint8 g2,Uint8 b2) { if ( SDL_MUSTLOCK(dest) && _sge_lock ) if ( SDL_LockSurface(dest) < 0 ) return; _FadedLine(dest,x1,x2,y,r1,g1,b1,r2,g2,b2); if ( SDL_MUSTLOCK(dest) && _sge_lock ) SDL_UnlockSurface(dest); if(_sge_update!=1){return;} if ( x1 > x2 ) sge_UpdateRect(dest, x1, y, x1-x2+1, 1); else sge_UpdateRect(dest, x1, y, x2-x1+1, 1); } //================================================================================== // Draws a horisontal, textured line //================================================================================== void _TexturedLine(SDL_Surface *dest,Sint16 x1,Sint16 x2,Sint16 y,SDL_Surface *source,Sint16 sx1,Sint16 sy1,Sint16 sx2,Sint16 sy2) { Sint16 x; /* Fix coords */ if ( x1 > x2 ) { SWAP(x1,x2,x); SWAP(sx1,sx2,x); SWAP(sy1,sy2,x); } /* Fixed point texture starting coords */ Sint32 srcx = sx1<<16; Sint32 srcy = sy1<<16; /* Texture coords stepping value */ Sint32 xstep = Sint32((sx2-sx1)<<16) / Sint32(x2-x1+1); Sint32 ystep = Sint32((sy2-sy1)<<16) / Sint32(x2-x1+1); /* Clipping */ if(x2sge_clip_xmax(dest) || ysge_clip_ymax(dest)) return; if (x1 < sge_clip_xmin(dest)){ /* Fix texture starting coord */ srcx += (sge_clip_xmin(dest)-x1)*xstep; srcy += (sge_clip_xmin(dest)-x1)*ystep; x1 = sge_clip_xmin(dest); } if (x2 > sge_clip_xmax(dest)) x2 = sge_clip_xmax(dest); if(dest->format->BytesPerPixel == source->format->BytesPerPixel){ /* Fast mode. Just copy the pixel */ switch (dest->format->BytesPerPixel) { case 1: { /* Assuming 8-bpp */ Uint8 *pixel; Uint8 *row = (Uint8 *)dest->pixels + y*dest->pitch; for (x = x1; x <= x2; x++){ pixel = row + x; *pixel = *((Uint8 *)source->pixels + (srcy>>16)*source->pitch + (srcx>>16)); srcx += xstep; srcy += ystep; } } break; case 2: { /* Probably 15-bpp or 16-bpp */ Uint16 *pixel; Uint16 *row = (Uint16 *)dest->pixels + y*dest->pitch/2; Uint16 pitch = source->pitch/2; for (x = x1; x <= x2; x++){ pixel = row + x; *pixel = *((Uint16 *)source->pixels + (srcy>>16)*pitch + (srcx>>16)); srcx += xstep; srcy += ystep; } } break; case 3: { /* Slow 24-bpp mode, usually not used */ Uint8 *pixel, *srcpixel; Uint8 *row = (Uint8 *)dest->pixels + y*dest->pitch; Uint8 rshift8=dest->format->Rshift/8; Uint8 gshift8=dest->format->Gshift/8; Uint8 bshift8=dest->format->Bshift/8; for (x = x1; x <= x2; x++){ pixel = row + x*3; srcpixel = (Uint8 *)source->pixels + (srcy>>16)*source->pitch + (srcx>>16)*3; *(pixel+rshift8) = *(srcpixel+rshift8); *(pixel+gshift8) = *(srcpixel+gshift8); *(pixel+bshift8) = *(srcpixel+bshift8); srcx += xstep; srcy += ystep; } } break; case 4: { /* Probably 32-bpp */ Uint32 *pixel; Uint32 *row = (Uint32 *)dest->pixels + y*dest->pitch/4; Uint16 pitch = source->pitch/4; for (x = x1; x <= x2; x++){ pixel = row + x; *pixel = *((Uint32 *)source->pixels + (srcy>>16)*pitch + (srcx>>16)); srcx += xstep; srcy += ystep; } } break; } }else{ /* Slow mode. We must translate every pixel color! */ Uint8 r=0,g=0,b=0; switch (dest->format->BytesPerPixel) { case 1: { /* Assuming 8-bpp */ Uint8 *pixel; Uint8 *row = (Uint8 *)dest->pixels + y*dest->pitch; for (x = x1; x <= x2; x++){ pixel = row + x; SDL_GetRGB(sge_GetPixel(source, srcx>>16, srcy>>16), source->format, &r, &g, &b); *pixel = SDL_MapRGB( dest->format, r, g, b ); srcx += xstep; srcy += ystep; } } break; case 2: { /* Probably 15-bpp or 16-bpp */ Uint16 *pixel; Uint16 *row = (Uint16 *)dest->pixels + y*dest->pitch/2; for (x = x1; x <= x2; x++){ pixel = row + x; SDL_GetRGB(sge_GetPixel(source, srcx>>16, srcy>>16), source->format, &r, &g, &b); *pixel = MapRGB( dest->format, r, g, b ); srcx += xstep; srcy += ystep; } } break; case 3: { /* Slow 24-bpp mode, usually not used */ Uint8 *pixel, *srcpixel; Uint8 *row = (Uint8 *)dest->pixels + y*dest->pitch; Uint8 rshift8=dest->format->Rshift/8; Uint8 gshift8=dest->format->Gshift/8; Uint8 bshift8=dest->format->Bshift/8; for (x = x1; x <= x2; x++){ pixel = row + x*3; srcpixel = (Uint8 *)source->pixels + (srcy>>16)*source->pitch + (srcx>>16)*3; SDL_GetRGB(sge_GetPixel(source, srcx>>16, srcy>>16), source->format, &r, &g, &b); *(pixel+rshift8) = r; *(pixel+gshift8) = g; *(pixel+bshift8) = b; srcx += xstep; srcy += ystep; } } break; case 4: { /* Probably 32-bpp */ Uint32 *pixel; Uint32 *row = (Uint32 *)dest->pixels + y*dest->pitch/4; for (x = x1; x <= x2; x++){ pixel = row + x; SDL_GetRGB(sge_GetPixel(source, srcx>>16, srcy>>16), source->format, &r, &g, &b); *pixel = MapRGB( dest->format, r, g, b ); srcx += xstep; srcy += ystep; } } break; } } } void sge_TexturedLine(SDL_Surface *dest,Sint16 x1,Sint16 x2,Sint16 y,SDL_Surface *source,Sint16 sx1,Sint16 sy1,Sint16 sx2,Sint16 sy2) { if ( SDL_MUSTLOCK(dest) && _sge_lock ) if ( SDL_LockSurface(dest) < 0 ) return; if ( SDL_MUSTLOCK(source) && _sge_lock ) if ( SDL_LockSurface(source) < 0 ) return; _TexturedLine(dest,x1,x2,y,source,sx1,sy1,sx2,sy2); if ( SDL_MUSTLOCK(dest) && _sge_lock ) SDL_UnlockSurface(dest); if ( SDL_MUSTLOCK(source) && _sge_lock ) SDL_UnlockSurface(source); if(_sge_update!=1){return;} if ( x1 > x2 ) sge_UpdateRect(dest, x1, y, x1-x2+1, 1); else sge_UpdateRect(dest, x1, y, x2-x1+1, 1); } //================================================================================== // Draws a trigon //================================================================================== void sge_Trigon(SDL_Surface *dest,Sint16 x1,Sint16 y1,Sint16 x2,Sint16 y2,Sint16 x3,Sint16 y3,Uint32 color) { if ( SDL_MUSTLOCK(dest) && _sge_lock ) if ( SDL_LockSurface(dest) < 0 ) return; _Line(dest,x1,y1,x2,y2,color); _Line(dest,x1,y1,x3,y3,color); _Line(dest,x3,y3,x2,y2,color); if ( SDL_MUSTLOCK(dest) && _sge_lock ) SDL_UnlockSurface(dest); if(_sge_update!=1){return;} Sint16 xmax=x1, ymax=y1, xmin=x1, ymin=y1; xmax= (xmax>x2)? xmax : x2; ymax= (ymax>y2)? ymax : y2; xmin= (xminx3)? xmax : x3; ymax= (ymax>y3)? ymax : y3; xmin= (xminformat, R,G,B)); } //================================================================================== // Draws a trigon (alpha) //================================================================================== void sge_TrigonAlpha(SDL_Surface *dest,Sint16 x1,Sint16 y1,Sint16 x2,Sint16 y2,Sint16 x3,Sint16 y3,Uint32 color, Uint8 alpha) { if ( SDL_MUSTLOCK(dest) && _sge_lock ) if ( SDL_LockSurface(dest) < 0 ) return; _LineAlpha(dest,x1,y1,x2,y2,color,alpha); _LineAlpha(dest,x1,y1,x3,y3,color,alpha); _LineAlpha(dest,x3,y3,x2,y2,color,alpha); if ( SDL_MUSTLOCK(dest) && _sge_lock ) SDL_UnlockSurface(dest); if(_sge_update!=1){return;} Sint16 xmax=x1, ymax=y1, xmin=x1, ymin=y1; xmax= (xmax>x2)? xmax : x2; ymax= (ymax>y2)? ymax : y2; xmin= (xminx3)? xmax : x3; ymax= (ymax>y3)? ymax : y3; xmin= (xminformat, R,G,B), alpha); } //================================================================================== // Draws an AA trigon (alpha) //================================================================================== void sge_AATrigonAlpha(SDL_Surface *dest,Sint16 x1,Sint16 y1,Sint16 x2,Sint16 y2,Sint16 x3,Sint16 y3,Uint32 color, Uint8 alpha) { if ( SDL_MUSTLOCK(dest) && _sge_lock ) if ( SDL_LockSurface(dest) < 0 ) return; _AALineAlpha(dest,x1,y1,x2,y2,color,alpha); _AALineAlpha(dest,x1,y1,x3,y3,color,alpha); _AALineAlpha(dest,x3,y3,x2,y2,color,alpha); if ( SDL_MUSTLOCK(dest) && _sge_lock ) SDL_UnlockSurface(dest); if(_sge_update!=1){return;} Sint16 xmax=x1, ymax=y1, xmin=x1, ymin=y1; xmax= (xmax>x2)? xmax : x2; ymax= (ymax>y2)? ymax : y2; xmin= (xminx3)? xmax : x3; ymax= (ymax>y3)? ymax : y3; xmin= (xminformat, R,G,B), alpha); } void sge_AATrigon(SDL_Surface *dest,Sint16 x1,Sint16 y1,Sint16 x2,Sint16 y2,Sint16 x3,Sint16 y3,Uint32 color) { sge_AATrigonAlpha(dest,x1,y1,x2,y2,x3,y3, color, 255); } void sge_AATrigon(SDL_Surface *dest,Sint16 x1,Sint16 y1,Sint16 x2,Sint16 y2,Sint16 x3,Sint16 y3,Uint8 R, Uint8 G, Uint8 B) { sge_AATrigonAlpha(dest,x1,y1,x2,y2,x3,y3, SDL_MapRGB(dest->format, R,G,B), 255); } //================================================================================== // Draws a filled trigon //================================================================================== void sge_FilledTrigon(SDL_Surface *dest,Sint16 x1,Sint16 y1,Sint16 x2,Sint16 y2,Sint16 x3,Sint16 y3,Uint32 color) { Sint16 y; if( y1==y3 ) return; /* Sort coords */ if ( y1 > y2 ) { SWAP(y1,y2,y); SWAP(x1,x2,y); } if ( y2 > y3 ) { SWAP(y2,y3,y); SWAP(x2,x3,y); } if ( y1 > y2 ) { SWAP(y1,y2,y); SWAP(x1,x2,y); } /* * How do we calculate the starting and ending x coordinate of the horizontal line * on each y coordinate? We can do this by using a standard line algorithm but * instead of plotting pixels, use the x coordinates as start and stop * coordinates for the horizontal line. * So we will simply trace the outlining of the triangle; this will require 3 lines. * Line 1 is the line between (x1,y1) and (x2,y2) * Line 2 is the line between (x1,y1) and (x3,y3) * Line 3 is the line between (x2,y2) and (x3,y3) * * We can divide the triangle into 2 halfs. The upper half will be outlined by line * 1 and 2. The lower half will be outlined by line line 2 and 3. */ /* Starting coords for the three lines */ Sint32 xa = Sint32(x1<<16); Sint32 xb = xa; Sint32 xc = Sint32(x2<<16); /* Lines step values */ Sint32 m1 = 0; Sint32 m2 = Sint32((x3 - x1)<<16)/Sint32(y3 - y1); Sint32 m3 = 0; /* Upper half of the triangle */ if( y1==y2 ) _HLine(dest, x1, x2, y1, color); else{ m1 = Sint32((x2 - x1)<<16)/Sint32(y2 - y1); for ( y = y1; y <= y2; y++) { _HLine(dest, xa>>16, xb>>16, y, color); xa += m1; xb += m2; } } /* Lower half of the triangle */ if( y2==y3 ) _HLine(dest, x2, x3, y2, color); else{ m3 = Sint32((x3 - x2)<<16)/Sint32(y3 - y2); for ( y = y2+1; y <= y3; y++) { _HLine(dest, xb>>16, xc>>16, y, color); xb += m2; xc += m3; } } if(_sge_update!=1){return;} Sint16 xmax=x1, xmin=x1; xmax= (xmax>x2)? xmax : x2; xmin= (xminx3)? xmax : x3; xmin= (xminformat, R,G,B)); } //================================================================================== // Draws a filled trigon (alpha) //================================================================================== void sge_FilledTrigonAlpha(SDL_Surface *dest,Sint16 x1,Sint16 y1,Sint16 x2,Sint16 y2,Sint16 x3,Sint16 y3,Uint32 color, Uint8 alpha) { Sint16 y; if( y1==y3 ) return; /* Sort coords */ if ( y1 > y2 ) { SWAP(y1,y2,y); SWAP(x1,x2,y); } if ( y2 > y3 ) { SWAP(y2,y3,y); SWAP(x2,x3,y); } if ( y1 > y2 ) { SWAP(y1,y2,y); SWAP(x1,x2,y); } Sint32 xa = Sint32(x1<<16); Sint32 xb = xa; Sint32 xc = Sint32(x2<<16); Sint32 m1 = 0; Sint32 m2 = Sint32((x3 - x1)<<16)/Sint32(y3 - y1); Sint32 m3 = 0; if ( SDL_MUSTLOCK(dest) && _sge_lock ) if ( SDL_LockSurface(dest) < 0 ) return; /* Upper half of the triangle */ if( y1==y2 ) _HLineAlpha(dest, x1, x2, y1, color, alpha); else{ m1 = Sint32((x2 - x1)<<16)/Sint32(y2 - y1); for ( y = y1; y <= y2; y++) { _HLineAlpha(dest, xa>>16, xb>>16, y, color, alpha); xa += m1; xb += m2; } } /* Lower half of the triangle */ if( y2==y3 ) _HLineAlpha(dest, x2, x3, y2, color, alpha); else{ m3 = Sint32((x3 - x2)<<16)/Sint32(y3 - y2); for ( y = y2+1; y <= y3; y++) { _HLineAlpha(dest, xb>>16, xc>>16, y, color, alpha); xb += m2; xc += m3; } } if ( SDL_MUSTLOCK(dest) && _sge_lock ) SDL_UnlockSurface(dest); if(_sge_update!=1){return;} Sint16 xmax=x1, xmin=x1; xmax= (xmax>x2)? xmax : x2; xmin= (xminx3)? xmax : x3; xmin= (xminformat, R,G,B),alpha); } //================================================================================== // Draws a gourand shaded trigon //================================================================================== void sge_FadedTrigon(SDL_Surface *dest,Sint16 x1,Sint16 y1,Sint16 x2,Sint16 y2,Sint16 x3,Sint16 y3,Uint32 c1,Uint32 c2,Uint32 c3) { Sint16 y; if( y1==y3 ) return; Uint8 c=0; SDL_Color col1; SDL_Color col2; SDL_Color col3; col1 = sge_GetRGB(dest,c1); col2 = sge_GetRGB(dest,c2); col3 = sge_GetRGB(dest,c3); /* Sort coords */ if ( y1 > y2 ) { SWAP(y1,y2,y); SWAP(x1,x2,y); SWAP(col1.r,col2.r,c); SWAP(col1.g,col2.g,c); SWAP(col1.b,col2.b,c); } if ( y2 > y3 ) { SWAP(y2,y3,y); SWAP(x2,x3,y); SWAP(col2.r,col3.r,c); SWAP(col2.g,col3.g,c); SWAP(col2.b,col3.b,c); } if ( y1 > y2 ) { SWAP(y1,y2,y); SWAP(x1,x2,y); SWAP(col1.r,col2.r,c); SWAP(col1.g,col2.g,c); SWAP(col1.b,col2.b,c); } /* * We trace three lines exactly like in sge_FilledTrigon(), but here we * must also keep track of the colors. We simply calculate how the color * will change along the three lines. */ /* Starting coords for the three lines */ Sint32 xa = Sint32(x1<<16); Sint32 xb = xa; Sint32 xc = Sint32(x2<<16); /* Starting colors (rgb) for the three lines */ Sint32 r1 = Sint32(col1.r<<16); Sint32 r2 = r1; Sint32 r3 = Sint32(col2.r<<16); Sint32 g1 = Sint32(col1.g<<16); Sint32 g2 = g1; Sint32 g3 = Sint32(col2.g<<16); Sint32 b1 = Sint32(col1.b<<16); Sint32 b2 = b1; Sint32 b3 = Sint32(col2.b<<16); /* Lines step values */ Sint32 m1 = 0; Sint32 m2 = Sint32((x3 - x1)<<16)/Sint32(y3 - y1); Sint32 m3 = 0; /* Colors step values */ Sint32 rstep1 = 0; Sint32 rstep2 = Sint32((col3.r - col1.r) << 16) / Sint32(y3 - y1); Sint32 rstep3 = 0; Sint32 gstep1 = 0; Sint32 gstep2 = Sint32((col3.g - col1.g) << 16) / Sint32(y3 - y1); Sint32 gstep3 = 0; Sint32 bstep1 = 0; Sint32 bstep2 = Sint32((col3.b - col1.b) << 16) / Sint32(y3 - y1); Sint32 bstep3 = 0; if ( SDL_MUSTLOCK(dest) && _sge_lock ) if ( SDL_LockSurface(dest) < 0 ) return; /* Upper half of the triangle */ if( y1==y2 ) _FadedLine(dest, x1, x2, y1, col1.r, col1.g, col1.b, col2.r, col2.g, col2.b); else{ m1 = Sint32((x2 - x1)<<16)/Sint32(y2 - y1); rstep1 = Sint32((col2.r - col1.r) << 16) / Sint32(y2 - y1); gstep1 = Sint32((col2.g - col1.g) << 16) / Sint32(y2 - y1); bstep1 = Sint32((col2.b - col1.b) << 16) / Sint32(y2 - y1); for ( y = y1; y <= y2; y++) { _FadedLine(dest, xa>>16, xb>>16, y, r1>>16, g1>>16, b1>>16, r2>>16, g2>>16, b2>>16); xa += m1; xb += m2; r1 += rstep1; g1 += gstep1; b1 += bstep1; r2 += rstep2; g2 += gstep2; b2 += bstep2; } } /* Lower half of the triangle */ if( y2==y3 ) _FadedLine(dest, x2, x3, y2, col2.r, col2.g, col2.b, col3.r, col3.g, col3.b); else{ m3 = Sint32((x3 - x2)<<16)/Sint32(y3 - y2); rstep3 = Sint32((col3.r - col2.r) << 16) / Sint32(y3 - y2); gstep3 = Sint32((col3.g - col2.g) << 16) / Sint32(y3 - y2); bstep3 = Sint32((col3.b - col2.b) << 16) / Sint32(y3 - y2); for ( y = y2+1; y <= y3; y++) { _FadedLine(dest, xb>>16, xc>>16, y, r2>>16, g2>>16, b2>>16, r3>>16, g3>>16, b3>>16); xb += m2; xc += m3; r2 += rstep2; g2 += gstep2; b2 += bstep2; r3 += rstep3; g3 += gstep3; b3 += bstep3; } } if ( SDL_MUSTLOCK(dest) && _sge_lock ) SDL_UnlockSurface(dest); if(_sge_update!=1){return;} Sint16 xmax=x1, xmin=x1; xmax= (xmax>x2)? xmax : x2; xmin= (xminx3)? xmax : x3; xmin= (xmin y2 ) { SWAP(y1,y2,y); SWAP(x1,x2,y); SWAP(sx1,sx2,y); SWAP(sy1,sy2,y); } if ( y2 > y3 ) { SWAP(y2,y3,y); SWAP(x2,x3,y); SWAP(sx2,sx3,y); SWAP(sy2,sy3,y); } if ( y1 > y2 ) { SWAP(y1,y2,y); SWAP(x1,x2,y); SWAP(sx1,sx2,y); SWAP(sy1,sy2,y); } /* * Again we do the same thing as in sge_FilledTrigon(). But here we must keep track of how the * texture coords change along the lines. */ /* Starting coords for the three lines */ Sint32 xa = Sint32(x1<<16); Sint32 xb = xa; Sint32 xc = Sint32(x2<<16); /* Lines step values */ Sint32 m1 = 0; Sint32 m2 = Sint32((x3 - x1)<<16)/Sint32(y3 - y1); Sint32 m3 = 0; /* Starting texture coords for the three lines */ Sint32 srcx1 = Sint32(sx1<<16); Sint32 srcx2 = srcx1; Sint32 srcx3 = Sint32(sx2<<16); Sint32 srcy1 = Sint32(sy1<<16); Sint32 srcy2 = srcy1; Sint32 srcy3 = Sint32(sy2<<16); /* Texture coords stepping value */ Sint32 xstep1 = 0; Sint32 xstep2 = Sint32((sx3 - sx1) << 16) / Sint32(y3 - y1); Sint32 xstep3 = 0; Sint32 ystep1 = 0; Sint32 ystep2 = Sint32((sy3 - sy1) << 16) / Sint32(y3 - y1); Sint32 ystep3 = 0; if ( SDL_MUSTLOCK(dest) && _sge_lock ) if ( SDL_LockSurface(dest) < 0 ) return; if ( SDL_MUSTLOCK(source) && _sge_lock ) if ( SDL_LockSurface(source) < 0 ) return; /* Upper half of the triangle */ if( y1==y2 ) _TexturedLine(dest,x1,x2,y1,source,sx1,sy1,sx2,sy2); else{ m1 = Sint32((x2 - x1)<<16)/Sint32(y2 - y1); xstep1 = Sint32((sx2 - sx1) << 16) / Sint32(y2 - y1); ystep1 = Sint32((sy2 - sy1) << 16) / Sint32(y2 - y1); for ( y = y1; y <= y2; y++) { _TexturedLine(dest, xa>>16, xb>>16, y, source, srcx1>>16, srcy1>>16, srcx2>>16, srcy2>>16); xa += m1; xb += m2; srcx1 += xstep1; srcx2 += xstep2; srcy1 += ystep1; srcy2 += ystep2; } } /* Lower half of the triangle */ if( y2==y3 ) _TexturedLine(dest,x2,x3,y2,source,sx2,sy2,sx3,sy3); else{ m3 = Sint32((x3 - x2)<<16)/Sint32(y3 - y2); xstep3 = Sint32((sx3 - sx2) << 16) / Sint32(y3 - y2); ystep3 = Sint32((sy3 - sy2) << 16) / Sint32(y3 - y2); for ( y = y2+1; y <= y3; y++) { _TexturedLine(dest, xb>>16, xc>>16, y, source, srcx2>>16, srcy2>>16, srcx3>>16, srcy3>>16); xb += m2; xc += m3; srcx2 += xstep2; srcx3 += xstep3; srcy2 += ystep2; srcy3 += ystep3; } } if ( SDL_MUSTLOCK(dest) && _sge_lock ) SDL_UnlockSurface(dest); if ( SDL_MUSTLOCK(source) && _sge_lock ) SDL_UnlockSurface(source); if(_sge_update!=1){return;} Sint16 xmax=x1, xmin=x1; xmax= (xmax>x2)? xmax : x2; xmin= (xminx3)? xmax : x3; xmin= (xmin y2 ) { SWAP(x1,x2,y); SWAP(y1,y2,y); SWAP(sx1,sx2,y); SWAP(sy1,sy2,y); } if ( y2 > y3 ) { SWAP(x3,x2,y); SWAP(y3,y2,y); SWAP(sx3,sx2,y); SWAP(sy3,sy2,y); } if ( y1 > y2 ) { SWAP(x1,x2,y); SWAP(y1,y2,y); SWAP(sx1,sx2,y); SWAP(sy1,sy2,y); } if ( y3 > y4 ) { SWAP(x3,x4,y); SWAP(y3,y4,y); SWAP(sx3,sx4,y); SWAP(sy3,sy4,y); } if ( y2 > y3 ) { SWAP(x3,x2,y); SWAP(y3,y2,y); SWAP(sx3,sx2,y); SWAP(sy3,sy2,y); } if ( y1 > y2 ) { SWAP(x1,x2,y); SWAP(y1,y2,y); SWAP(sx1,sx2,y); SWAP(sy1,sy2,y); } /* * We do this exactly like sge_TexturedTrigon(), but here we must trace four lines. */ Sint32 xa = Sint32(x1<<16); Sint32 xb = xa; Sint32 xc = Sint32(x2<<16); Sint32 xd = Sint32(x3<<16); Sint32 m1 = 0; Sint32 m2 = Sint32((x3 - x1)<<16)/Sint32(y3 - y1); Sint32 m3 = Sint32((x4 - x2)<<16)/Sint32(y4 - y2); Sint32 m4 = 0; Sint32 srcx1 = Sint32(sx1<<16); Sint32 srcx2 = srcx1; Sint32 srcx3 = Sint32(sx2<<16); Sint32 srcx4 = Sint32(sx3<<16); Sint32 srcy1 = Sint32(sy1<<16); Sint32 srcy2 = srcy1; Sint32 srcy3 = Sint32(sy2<<16); Sint32 srcy4 = Sint32(sy3<<16); Sint32 xstep1 = 0; Sint32 xstep2 = Sint32((sx3 - sx1) << 16) / Sint32(y3 - y1); Sint32 xstep3 = Sint32((sx4 - sx2) << 16) / Sint32(y4 - y2); Sint32 xstep4 = 0; Sint32 ystep1 = 0; Sint32 ystep2 = Sint32((sy3 - sy1) << 16) / Sint32(y3 - y1); Sint32 ystep3 = Sint32((sy4 - sy2) << 16) / Sint32(y4 - y2); Sint32 ystep4 = 0; if ( SDL_MUSTLOCK(dest) && _sge_lock ) if ( SDL_LockSurface(dest) < 0 ) return; /* Upper bit of the rectangle */ if( y1==y2 ) _TexturedLine(dest,x1,x2,y1,source,sx1,sy1,sx2,sy2); else{ m1 = Sint32((x2 - x1)<<16)/Sint32(y2 - y1); xstep1 = Sint32((sx2 - sx1) << 16) / Sint32(y2 - y1); ystep1 = Sint32((sy2 - sy1) << 16) / Sint32(y2 - y1); for ( y = y1; y <= y2; y++) { _TexturedLine(dest, xa>>16, xb>>16, y, source, srcx1>>16, srcy1>>16, srcx2>>16, srcy2>>16); xa += m1; xb += m2; srcx1 += xstep1; srcx2 += xstep2; srcy1 += ystep1; srcy2 += ystep2; } } /* Middle bit of the rectangle */ for ( y = y2+1; y <= y3; y++) { _TexturedLine(dest, xb>>16, xc>>16, y, source, srcx2>>16, srcy2>>16, srcx3>>16, srcy3>>16); xb += m2; xc += m3; srcx2 += xstep2; srcx3 += xstep3; srcy2 += ystep2; srcy3 += ystep3; } /* Lower bit of the rectangle */ if( y3==y4 ) _TexturedLine(dest,x3,x4,y3,source,sx3,sy3,sx4,sy4); else{ m4 = Sint32((x4 - x3)<<16)/Sint32(y4 - y3); xstep4 = Sint32((sx4 - sx3) << 16) / Sint32(y4 - y3); ystep4 = Sint32((sy4 - sy3) << 16) / Sint32(y4 - y3); for ( y = y3+1; y <= y4; y++) { _TexturedLine(dest, xc>>16, xd>>16, y, source, srcx3>>16, srcy3>>16, srcx4>>16, srcy4>>16); xc += m3; xd += m4; srcx3 += xstep3; srcx4 += xstep4; srcy3 += ystep3; srcy4 += ystep4; } } if ( SDL_MUSTLOCK(dest) && _sge_lock ) SDL_UnlockSurface(dest); if(_sge_update!=1){return;} Sint16 xmax=x1, xmin=x1; xmax= (xmax>x2)? xmax : x2; xmin= (xminx3)? xmax : x3; xmin= (xminx4)? xmax : x4; xmin= (xmin>16); fx += fm; } }; /* Pointer storage (to preserve polymorphism) */ struct pline_p{ pline *p; }; /* Radix sort */ pline* rsort(pline *inlist) { if(!inlist) return NULL; // 16 radix-buckets pline* bucket[16] = {NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL}; pline* bi[16]; // bucket itterator (points to last element in bucket) pline *plist = inlist; int i,k; pline *j; Uint8 nr; // Radix sort in 4 steps (16-bit numbers) for( i = 0; i < 4; i++ ){ for( j = plist; j; j = j->next ){ nr = Uint8( ( j->x >> (4*i) ) & 0x000F); // Get bucket number if( !bucket[nr] ) bucket[nr] = j; // First in bucket else bi[nr]->next = j; // Put last in bucket bi[nr] = j; // Update bucket itterator } // Empty buckets (recombine list) j = NULL; for( k = 0; k < 16; k++ ){ if( bucket[k] ){ if( j ) j->next = bucket[k]; // Connect elements in buckets else plist = bucket[k]; // First element j = bi[k]; } bucket[k] = NULL; // Empty } j->next = NULL; // Terminate list } return plist; } /* Calculate the scanline for y */ pline* get_scanline(pline_p *plist, Uint16 n, Sint32 y) { pline* p = NULL; pline* list = NULL; pline* li = NULL; for( int i = 0; i < n; i++ ){ // Is polyline on this scanline? p = plist[i].p; if( p->y1 <= y && p->y2 >= y && (p->y1 != p->y2) ){ if( list ) li->next = p; // Add last in list else list = p; // Add first in list li = p; // Update itterator // Calculate x p->update(); } } if( li ) li->next = NULL; // terminate // Sort list return rsort(list); } /* Removes duplicates if needed */ inline void remove_dup(pline *li, Sint16 y) { if( li->next ) if( (y==li->y1 || y==li->y2) && (y==li->next->y1 || y==li->next->y2) ) if( ((y == li->y1)? -1:1) != ((y == li->next->y1)? -1:1) ) li->next = li->next->next; } //================================================================================== // Draws a n-points filled polygon //================================================================================== int sge_FilledPolygonAlpha(SDL_Surface *dest, Uint16 n, Sint16 *x, Sint16 *y, Uint32 color, Uint8 alpha) { if(n<3) return -1; if (SDL_MUSTLOCK(dest) && _sge_lock) if (SDL_LockSurface(dest) < 0) return -2; pline *line = new pline[n]; pline_p *plist = new pline_p[n]; Sint16 y1,y2, x1, x2, tmp, sy; Sint16 ymin = y[1], ymax=y[1]; Sint16 xmin = x[1], xmax=x[1]; Uint16 i; /* Decompose polygon into straight lines */ for( i = 0; i < n; i++ ){ y1 = y[i]; x1 = x[i]; if( i == n-1 ){ // Last point == First point y2 = y[0]; x2 = x[0]; }else{ y2 = y[i+1]; x2 = x[i+1]; } // Make sure y1 <= y2 if( y1 > y2 ) { SWAP(y1,y2,tmp); SWAP(x1,x2,tmp); } // Reject polygons with negative coords if( y1 < 0 || x1 < 0 || x2 < 0 ){ if (SDL_MUSTLOCK(dest) && _sge_lock) SDL_UnlockSurface(dest); delete[] line; delete[] plist; return -1; } if( y1 < ymin ) ymin = y1; if( y2 > ymax ) ymax = y2; if( x1 < xmin ) xmin = x1; else if( x1 > xmax ) xmax = x1; if( x2 < xmin ) xmin = x2; else if( x2 > xmax ) xmax = x2; //Fill structure line[i].y1 = y1; line[i].y2 = y2; line[i].x1 = x1; line[i].x2 = x2; // Start x-value (fixed point) line[i].fx = Sint32(x1<<16); // Lines step value (fixed point) if( y1 != y2) line[i].fm = Sint32((x2 - x1)<<16)/Sint32(y2 - y1); else line[i].fm = 0; line[i].next = NULL; // Add to list plist[i].p = &line[i]; // Draw the polygon outline (looks nicer) if( alpha == SDL_ALPHA_OPAQUE ) _Line(dest,x1,y1,x2,y2,color); // Can't do this with alpha, might overlap with the filling } /* Remove surface lock if _HLine() is to be used */ if (SDL_MUSTLOCK(dest) && _sge_lock && alpha == SDL_ALPHA_OPAQUE) SDL_UnlockSurface(dest); pline* list = NULL; pline* li = NULL; // list itterator // Scan y-lines for( sy = ymin; sy <= ymax; sy++){ list = get_scanline(plist, n, sy); if( !list ) continue; // nothing in list... hmmmm x1 = x2 = -1; // Draw horizontal lines between pairs for( li = list; li; li = li->next ){ remove_dup(li, sy); if( x1 < 0 ) x1 = li->x+1; else if( x2 < 0 ) x2 = li->x; if( x1 >= 0 && x2 >= 0 ){ if( x2-x1 < 0 && alpha == SDL_ALPHA_OPAQUE ){ // Already drawn by the outline x1 = x2 = -1; continue; } if( alpha == SDL_ALPHA_OPAQUE ) _HLine(dest, x1, x2, sy, color); else _HLineAlpha(dest, x1-1, x2, sy, color, alpha); x1 = x2 = -1; } } } if (SDL_MUSTLOCK(dest) && _sge_lock && alpha != SDL_ALPHA_OPAQUE) SDL_UnlockSurface(dest); delete[] line; delete[] plist; if(_sge_update!=1){return 0;} sge_UpdateRect(dest, xmin, ymin, xmax-xmin+1, ymax-ymin+1); return 0; } int sge_FilledPolygonAlpha(SDL_Surface *dest, Uint16 n, Sint16 *x, Sint16 *y, Uint8 r, Uint8 g, Uint8 b, Uint8 alpha) { return sge_FilledPolygonAlpha(dest, n, x, y, SDL_MapRGB(dest->format,r,g,b), alpha); } int sge_FilledPolygon(SDL_Surface *dest, Uint16 n, Sint16 *x, Sint16 *y, Uint32 color) { return sge_FilledPolygonAlpha(dest, n, x, y, color, SDL_ALPHA_OPAQUE); } int sge_FilledPolygon(SDL_Surface *dest, Uint16 n, Sint16 *x, Sint16 *y, Uint8 r, Uint8 g, Uint8 b) { return sge_FilledPolygonAlpha(dest, n, x, y, SDL_MapRGB(dest->format,r,g,b), SDL_ALPHA_OPAQUE); } //================================================================================== // Draws a n-points (AA) filled polygon //================================================================================== int sge_AAFilledPolygon(SDL_Surface *dest, Uint16 n, Sint16 *x, Sint16 *y, Uint32 color) { if(n<3) return -1; if (SDL_MUSTLOCK(dest) && _sge_lock) if (SDL_LockSurface(dest) < 0) return -2; pline *line = new pline[n]; pline_p *plist = new pline_p[n]; Sint16 y1,y2, x1, x2, tmp, sy; Sint16 ymin = y[1], ymax=y[1]; Sint16 xmin = x[1], xmax=x[1]; Uint16 i; /* Decompose polygon into straight lines */ for( i = 0; i < n; i++ ){ y1 = y[i]; x1 = x[i]; if( i == n-1 ){ // Last point == First point y2 = y[0]; x2 = x[0]; }else{ y2 = y[i+1]; x2 = x[i+1]; } // Make sure y1 <= y2 if( y1 > y2 ) { SWAP(y1,y2,tmp); SWAP(x1,x2,tmp); } // Reject polygons with negative coords if( y1 < 0 || x1 < 0 || x2 < 0 ){ if (SDL_MUSTLOCK(dest) && _sge_lock) SDL_UnlockSurface(dest); delete[] line; delete[] plist; return -1; } if( y1 < ymin ) ymin = y1; if( y2 > ymax ) ymax = y2; if( x1 < xmin ) xmin = x1; else if( x1 > xmax ) xmax = x1; if( x2 < xmin ) xmin = x2; else if( x2 > xmax ) xmax = x2; //Fill structure line[i].y1 = y1; line[i].y2 = y2; line[i].x1 = x1; line[i].x2 = x2; // Start x-value (fixed point) line[i].fx = Sint32(x1<<16); // Lines step value (fixed point) if( y1 != y2) line[i].fm = Sint32((x2 - x1)<<16)/Sint32(y2 - y1); else line[i].fm = 0; line[i].next = NULL; // Add to list plist[i].p = &line[i]; // Draw AA Line _AALineAlpha(dest,x1,y1,x2,y2,color,SDL_ALPHA_OPAQUE); } if (SDL_MUSTLOCK(dest) && _sge_lock) SDL_UnlockSurface(dest); pline* list = NULL; pline* li = NULL; // list itterator // Scan y-lines for( sy = ymin; sy <= ymax; sy++){ list = get_scanline(plist, n, sy); if( !list ) continue; // nothing in list... hmmmm x1 = x2 = -1; // Draw horizontal lines between pairs for( li = list; li; li = li->next ){ remove_dup(li, sy); if( x1 < 0 ) x1 = li->x+1; else if( x2 < 0 ) x2 = li->x; if( x1 >= 0 && x2 >= 0 ){ if( x2-x1 < 0 ){ x1 = x2 = -1; continue; } _HLine(dest, x1, x2, sy, color); x1 = x2 = -1; } } } delete[] line; delete[] plist; if(_sge_update!=1){return 0;} sge_UpdateRect(dest, xmin, ymin, xmax-xmin+1, ymax-ymin+1); return 0; } int sge_AAFilledPolygon(SDL_Surface *dest, Uint16 n, Sint16 *x, Sint16 *y, Uint8 r, Uint8 g, Uint8 b) { return sge_AAFilledPolygon(dest, n, x, y, SDL_MapRGB(dest->format,r,g,b)); } //================================================================================== // Draws a n-points gourand shaded polygon //================================================================================== /* faded polygon structure */ class fpline : public pline{ public: Uint8 r1, r2; Uint8 g1, g2; Uint8 b1, b2; Uint32 fr, fg, fb; Sint32 fmr, fmg, fmb; Uint8 r,g,b; virtual void update(void) { x = Sint16(fx>>16); fx += fm; r = Uint8(fr>>16); g = Uint8(fg>>16); b = Uint8(fb>>16); fr += fmr; fg += fmg; fb += fmb; } }; int sge_FadedPolygonAlpha(SDL_Surface *dest, Uint16 n, Sint16 *x, Sint16 *y, Uint8 *R, Uint8 *G, Uint8 *B, Uint8 alpha) { if(n<3) return -1; if (SDL_MUSTLOCK(dest) && _sge_lock) if (SDL_LockSurface(dest) < 0) return -2; fpline *line = new fpline[n]; pline_p *plist = new pline_p[n]; Sint16 y1,y2, x1, x2, tmp, sy; Sint16 ymin = y[1], ymax=y[1]; Sint16 xmin = x[1], xmax=x[1]; Uint16 i; Uint8 r1=0, g1=0, b1=0, r2=0, g2=0, b2=0, t; // Decompose polygon into straight lines for( i = 0; i < n; i++ ){ y1 = y[i]; x1 = x[i]; r1 = R[i]; g1 = G[i]; b1 = B[i]; if( i == n-1 ){ // Last point == First point y2 = y[0]; x2 = x[0]; r2 = R[0]; g2 = G[0]; b2 = B[0]; }else{ y2 = y[i+1]; x2 = x[i+1]; r2 = R[i+1]; g2 = G[i+1]; b2 = B[i+1]; } // Make sure y1 <= y2 if( y1 > y2 ) { SWAP(y1,y2,tmp); SWAP(x1,x2,tmp); SWAP(r1,r2,t); SWAP(g1,g2,t); SWAP(b1,b2,t); } // Reject polygons with negative coords if( y1 < 0 || x1 < 0 || x2 < 0 ){ if ( SDL_MUSTLOCK(dest) && _sge_lock ) SDL_UnlockSurface(dest); delete[] line; delete[] plist; return -1; } if( y1 < ymin ) ymin = y1; if( y2 > ymax ) ymax = y2; if( x1 < xmin ) xmin = x1; else if( x1 > xmax ) xmax = x1; if( x2 < xmin ) xmin = x2; else if( x2 > xmax ) xmax = x2; //Fill structure line[i].y1 = y1; line[i].y2 = y2; line[i].x1 = x1; line[i].x2 = x2; line[i].r1 = r1; line[i].g1 = g1; line[i].b1 = b1; line[i].r2 = r2; line[i].g2 = g2; line[i].b2 = b2; // Start x-value (fixed point) line[i].fx = Sint32(x1<<16); line[i].fr = Uint32(r1<<16); line[i].fg = Uint32(g1<<16); line[i].fb = Uint32(b1<<16); // Lines step value (fixed point) if( y1 != y2){ line[i].fm = Sint32((x2 - x1)<<16)/Sint32(y2 - y1); line[i].fmr = Sint32((r2 - r1)<<16)/Sint32(y2 - y1); line[i].fmg = Sint32((g2 - g1)<<16)/Sint32(y2 - y1); line[i].fmb = Sint32((b2 - b1)<<16)/Sint32(y2 - y1); }else{ line[i].fm = 0; line[i].fmr = 0; line[i].fmg = 0; line[i].fmb = 0; } line[i].next = NULL; // Add to list plist[i].p = &line[i]; // Draw the polygon outline (looks nicer) if( alpha == SDL_ALPHA_OPAQUE ) sge_DomcLine(dest,x1,y1,x2,y2,r1,g1,b1,r2,g2,b2, _PutPixel); // Can't do this with alpha, might overlap with the filling } fpline* list = NULL; fpline* li = NULL; // list itterator // Scan y-lines for( sy = ymin; sy <= ymax; sy++){ list = (fpline *)get_scanline(plist, n, sy); if( !list ) continue; // nothing in list... hmmmm x1 = x2 = -1; // Draw horizontal lines between pairs for( li = list; li; li = (fpline *)li->next ){ remove_dup(li, sy); if( x1 < 0 ){ x1 = li->x+1; r1 = li->r; g1 = li->g; b1 = li->b; }else if( x2 < 0 ){ x2 = li->x; r2 = li->r; g2 = li->g; b2 = li->b; } if( x1 >= 0 && x2 >= 0 ){ if( x2-x1 < 0 && alpha == SDL_ALPHA_OPAQUE){ x1 = x2 = -1; continue; } if( alpha == SDL_ALPHA_OPAQUE ) _FadedLine(dest, x1, x2, sy, r1, g1, b1, r2, g2, b2); else{ _sge_alpha_hack = alpha; sge_DomcLine(dest, x1-1, sy, x2, sy, r1, g1, b1, r2, g2, b2, callback_alpha_hack); } x1 = x2 = -1; } } } if ( SDL_MUSTLOCK(dest) && _sge_lock ) SDL_UnlockSurface(dest); delete[] line; delete[] plist; if(_sge_update!=1){return 0;} sge_UpdateRect(dest, xmin, ymin, xmax-xmin+1, ymax-ymin+1); return 0; } int sge_FadedPolygon(SDL_Surface *dest, Uint16 n, Sint16 *x, Sint16 *y, Uint8 *R, Uint8 *G, Uint8 *B) { return sge_FadedPolygonAlpha(dest, n, x, y, R, G, B, SDL_ALPHA_OPAQUE); } //================================================================================== // Draws a n-points (AA) gourand shaded polygon //================================================================================== int sge_AAFadedPolygon(SDL_Surface *dest, Uint16 n, Sint16 *x, Sint16 *y, Uint8 *R, Uint8 *G, Uint8 *B) { if(n<3) return -1; if (SDL_MUSTLOCK(dest) && _sge_lock) if (SDL_LockSurface(dest) < 0) return -2; fpline *line = new fpline[n]; pline_p *plist = new pline_p[n]; Sint16 y1,y2, x1, x2, tmp, sy; Sint16 ymin = y[1], ymax=y[1]; Sint16 xmin = x[1], xmax=x[1]; Uint16 i; Uint8 r1=0, g1=0, b1=0, r2=0, g2=0, b2=0, t; // Decompose polygon into straight lines for( i = 0; i < n; i++ ){ y1 = y[i]; x1 = x[i]; r1 = R[i]; g1 = G[i]; b1 = B[i]; if( i == n-1 ){ // Last point == First point y2 = y[0]; x2 = x[0]; r2 = R[0]; g2 = G[0]; b2 = B[0]; }else{ y2 = y[i+1]; x2 = x[i+1]; r2 = R[i+1]; g2 = G[i+1]; b2 = B[i+1]; } // Make sure y1 <= y2 if( y1 > y2 ) { SWAP(y1,y2,tmp); SWAP(x1,x2,tmp); SWAP(r1,r2,t); SWAP(g1,g2,t); SWAP(b1,b2,t); } // Reject polygons with negative coords if( y1 < 0 || x1 < 0 || x2 < 0 ){ if ( SDL_MUSTLOCK(dest) && _sge_lock ) SDL_UnlockSurface(dest); delete[] line; delete[] plist; return -1; } if( y1 < ymin ) ymin = y1; if( y2 > ymax ) ymax = y2; if( x1 < xmin ) xmin = x1; else if( x1 > xmax ) xmax = x1; if( x2 < xmin ) xmin = x2; else if( x2 > xmax ) xmax = x2; //Fill structure line[i].y1 = y1; line[i].y2 = y2; line[i].x1 = x1; line[i].x2 = x2; line[i].r1 = r1; line[i].g1 = g1; line[i].b1 = b1; line[i].r2 = r2; line[i].g2 = g2; line[i].b2 = b2; // Start x-value (fixed point) line[i].fx = Sint32(x1<<16); line[i].fr = Uint32(r1<<16); line[i].fg = Uint32(g1<<16); line[i].fb = Uint32(b1<<16); // Lines step value (fixed point) if( y1 != y2){ line[i].fm = Sint32((x2 - x1)<<16)/Sint32(y2 - y1); line[i].fmr = Sint32((r2 - r1)<<16)/Sint32(y2 - y1); line[i].fmg = Sint32((g2 - g1)<<16)/Sint32(y2 - y1); line[i].fmb = Sint32((b2 - b1)<<16)/Sint32(y2 - y1); }else{ line[i].fm = 0; line[i].fmr = 0; line[i].fmg = 0; line[i].fmb = 0; } line[i].next = NULL; // Add to list plist[i].p = &line[i]; // Draw the polygon outline (AA) _AAmcLineAlpha(dest,x1,y1,x2,y2,r1,g1,b1,r2,g2,b2,SDL_ALPHA_OPAQUE); } fpline* list = NULL; fpline* li = NULL; // list itterator // Scan y-lines for( sy = ymin; sy <= ymax; sy++){ list = (fpline *)get_scanline(plist, n, sy); if( !list ) continue; // nothing in list... hmmmm x1 = x2 = -1; // Draw horizontal lines between pairs for( li = list; li; li = (fpline *)li->next ){ remove_dup(li, sy); if( x1 < 0 ){ x1 = li->x+1; r1 = li->r; g1 = li->g; b1 = li->b; }else if( x2 < 0 ){ x2 = li->x; r2 = li->r; g2 = li->g; b2 = li->b; } if( x1 >= 0 && x2 >= 0 ){ if( x2-x1 < 0 ){ x1 = x2 = -1; continue; } _FadedLine(dest, x1, x2, sy, r1, g1, b1, r2, g2, b2); x1 = x2 = -1; } } } if ( SDL_MUSTLOCK(dest) && _sge_lock ) SDL_UnlockSurface(dest); delete[] line; delete[] plist; if(_sge_update!=1){return 0;} sge_UpdateRect(dest, xmin, ymin, xmax-xmin+1, ymax-ymin+1); return 0; } sge030809/sge_rotation.h0000644000175000001440000000336007713172602013674 0ustar samusers/* * SDL Graphics Extension * Rotation routines (header) * * Started 000625 * * License: LGPL v2+ (see the file LICENSE) * (c)1999-2003 Anders Lindstrm */ /********************************************************************* * This library is free software; you can redistribute it and/or * * modify it under the terms of the GNU Library General Public * * License as published by the Free Software Foundation; either * * version 2 of the License, or (at your option) any later version. * *********************************************************************/ #ifndef sge_rotation_H #define sge_rotation_H #include "SDL.h" #include "sge_internal.h" /* Transformation flags */ #define SGE_TAA SGE_FLAG1 #define SGE_TSAFE SGE_FLAG2 #define SGE_TTMAP SGE_FLAG3 #ifdef _SGE_C extern "C" { #endif DECLSPEC SDL_Rect sge_transform(SDL_Surface *src, SDL_Surface *dst, float angle, float xscale, float yscale ,Uint16 px, Uint16 py, Uint16 qx, Uint16 qy, Uint8 flags); DECLSPEC SDL_Surface *sge_transform_surface(SDL_Surface *src, Uint32 bcol, float angle, float xscale, float yscale, Uint8 flags); /* Old obolete functions - now uses sge_transform() anyway */ DECLSPEC SDL_Surface *sge_rotate_scaled_surface(SDL_Surface *src, int angle, double scale, Uint32 bcol); DECLSPEC SDL_Surface *sge_rotate_surface(SDL_Surface *src, int angle, Uint32 bcol); DECLSPEC SDL_Rect sge_rotate_xyscaled(SDL_Surface *dest, SDL_Surface *src, Sint16 x, Sint16 y, int angle, double xscale, double yscale); DECLSPEC SDL_Rect sge_rotate_scaled(SDL_Surface *dest, SDL_Surface *src, Sint16 x, Sint16 y, int angle, double scale); DECLSPEC SDL_Rect sge_rotate(SDL_Surface *dest, SDL_Surface *src, Sint16 x, Sint16 y, int angle); #ifdef _SGE_C } #endif #endif /* sge_rotation_H */ sge030809/INSTALL0000644000175000001440000000332707715153217012065 0ustar samusersThe file "README" has more detailed information. You should also read the file "docs/guide.html". Requirements ============= -GNU Make. -SDL 1.2+ (http://www.libsdl.org/). -An ANSI/ISO C++ compiler. SGE should conform to ANSI/ISO C++. -Optional: -FreeType 2+ (http://www.freetype.org/). -SDL_Image (http://www.libsdl.org/projects/SDL_image/index.html). -Some SDL knowledge. Compile & install ================== 'make install' Configure ========== You can edit the file "Makefile.conf" to configure SGE. At the top of this file you will see: C_COMP = y #USE_FT = n #USE_IMG = n #QUIET = y Remove the comment (#) symbol to activate the control (y/n) of the following options: C_COMP Makes it possible to link C code to SGE. See the README file for more information. Default: y. USE_FT Controls the use of the FreeType library. Default: autodetected. USE_IMG Controls the use of the SDL_Image library. Default: autodetected. QUIET Don't show build status before compiling. Make options ============= 'make' Builds a static SGE library (libSGE.a). 'make shared' Builds a dynamic SGE library (libSGE.so). 'make shared-strip' Same as 'make shared' but strips symbols from the libSGE.so file. 'make dll' Builds a win32 dll file (SGE.dll). You must use a win32 cross compiler to do this. You must also remove the # symbol on the "SGE_LIBS =...#-lstdc++" line in Makefile.conf. 'make dll-strip' Same as 'make dll' but strips symbols from the SGE.dll file. 'make clean' Removes compiled files. 'make install' Builds a dynamic SGE library and installs it with the headers to the same install location as SDL. You can change this location by editing the PREFIX and PREFIX_H lines in Makefile.conf. You must probably be root to install. sge030809/sge_textpp.h0000644000175000001440000001710707715152123013363 0ustar samusers/* * SDL Graphics Extension * Text/TrueType classes (header) * * Started 990826 / 010207 (new version) * * License: LGPL v2+ (see the file LICENSE) * (c)1999-2003 Anders Lindstrm * * Uses the excellent FreeType 2 library, available at: * http://www.freetype.org/ */ /********************************************************************* * This library is free software; you can redistribute it and/or * * modify it under the terms of the GNU Library General Public * * License as published by the Free Software Foundation; either * * version 2 of the License, or (at your option) any later version. * *********************************************************************/ #ifndef sge_textpp_H #define sge_textpp_H #include "SDL.h" #include "sge_internal.h" #ifndef _SGE_NO_CLASSES #include #include #include "sge_tt_text.h" #include "sge_bm_text.h" #include "sge_shape.h" //================================================================================== // Edits text from SDL_Event //================================================================================== class DECLSPEC sge_TextEditor { protected: //The text is stored in a double linked list //The elements in the linked list struct node{ Uint16 c; //Unicode char node* next; node* prev; }; //List metadata node* start; node* end; node* cursor; //The current node (the cursor) Uint16 cursor_char; //The charactar for the cursor unsigned int chars; //Size of the string (without the cursor) unsigned int mChars; //Max chars, 0 is default (unlimited) //Create and fill a new node node* new_node(node* p, node* n, Uint16 c); //Swap two nodes bool nswap(node* one, node* two); //This indicates that the text has changed since last //set to false (used for derived classes) bool text_changed; public: //Creator sge_TextEditor(void); //Destructor virtual ~sge_TextEditor(void); //Adds an char before the cursor bool insert(Uint16 c); //Removes the char left of cursor bool remove_left(void); //Removes the char right of cursor bool remove_right(void); //Move cursor left inline bool move_left(void); //Move cursor right inline bool move_right(void); //Move cursor to the start bool move_start(void); //Move cursor to the end bool move_end(void); //Returns text as latin1 or unicode with or without the cursor char std::string get_string(bool wCursor=true); //std::basic_string get_ustring(bool wCursor=true); //Returns a unicode c-style string (allocated with new) Uint16* get_ucstring(bool wCursor=true); //Process a SDL_Event //Returns true if the text changed virtual bool check(SDL_Event* event); //Change the cursor char void change_cursor(Uint16 c){cursor_char=c; cursor->c=c;} //Change the text void clear_text(void); void change_text(const std::string s); //void change_utext(const std::basic_string s); void change_uctext(Uint16 *text); void change_textf(const char *text, ...); //printf c-style... urk //Set max chars (default: limited only by memory) void max_chars(unsigned int c){mChars=c;} //Returns the number of characters in the current string unsigned int get_chars(void){return chars;} }; //================================================================================== // A class for rendering text //================================================================================== class DECLSPEC sge_text: public sge_TextEditor { protected: #ifndef _SGE_NOTTF sge_TTFont *tt_font; //The truetype font #else Uint8 *tt_font; #endif //TT Font color SDL_Color color; SDL_Color background; sge_bmpFont *bm_font; //The bitmap font Uint8 alpha_level; //Alpha level (default: opaque) SDL_Surface* text_surface; virtual void set_textSurface(SDL_Surface *new_surf){;} //Use what render? bool use_tt; //Show cursor when rendering text? bool sCursor; public: //Constructor sge_text(void){tt_font=NULL; bm_font=NULL; text_surface=NULL; use_tt=true; text_surface=NULL; sCursor=false; alpha_level=SDL_ALPHA_OPAQUE;} virtual ~sge_text(void){if(text_surface){SDL_FreeSurface(text_surface);}} //Get a pointer to the text surface or (if copy=true) returns //a copy (don't forget to free it later) SDL_Surface* get_textSurface(bool copy=false); //Updates the textsurface if the text has changed (or if force=true) //and returns true if the surface was updated bool update_textSurface(bool force=false); #ifndef _SGE_NOTTF void set_ttFont(sge_TTFont *font, Uint8 r, Uint8 g, Uint8 b, Uint8 br=0, Uint8 bg=0, Uint8 bb=0); #endif bool get_color(SDL_Color *fg){if( tt_font ) {fg->r = color.r; fg->g = color.g; fg->b = color.b; return true;} else return false;} bool get_bg(SDL_Color *bg) {if( tt_font ) {bg->r = background.r; bg->g = background.g; bg->b = background.b; return true;} else return false;} void set_bmFont(sge_bmpFont *bm_font); //Should a cursor be drawn? void show_cursor(bool mode){if(mode!=sCursor){text_changed=true;} sCursor=mode;} //Render text to a surface SDL_Rect render_text(SDL_Surface *surface, Sint16 x, Sint16 y); void use_TTrender(void){if(tt_font){use_tt=true;}} void use_BMrender(void){if(bm_font){use_tt=false;}} //set alpha level (default: opaque) void set_alpha(Uint8 alpha){alpha_level = alpha;} }; //================================================================================== //sge_TextSurface (derived public from sge_text and sge_surface) //sge_TextSsprite (derived public from sge_text and sge_ssprite) //sge_TextSprite (derived public from sge_text and sge_sprite) //================================================================================== class DECLSPEC sge_TextSurface: public sge_text, public sge_surface { protected: virtual void set_textSurface(SDL_Surface *new_surf); public: sge_TextSurface(SDL_Surface *screen, Sint16 x=0, Sint16 y=0): sge_surface(screen,screen,x,y) {\ surface=NULL; current_pos.w=0; current_pos.h=0; } sge_TextSurface(SDL_Surface *screen, const std::string text, Sint16 x=0, Sint16 y=0): sge_surface(screen,screen,x,y) { change_text(text); current_pos.w=0; current_pos.h=0; } virtual void draw(void); }; class DECLSPEC sge_TextSsprite: public sge_text, public sge_ssprite { protected: virtual void set_textSurface(SDL_Surface *new_surf); public: sge_TextSsprite(SDL_Surface *screen, Sint16 x=0, Sint16 y=0): sge_ssprite(screen,screen,x,y) {\ surface=NULL; current_pos.w=0; current_pos.h=0; } sge_TextSsprite(SDL_Surface *screen, const std::string text, Sint16 x=0, Sint16 y=0): sge_ssprite(screen,screen,x,y) { change_text(text); current_pos.w=0; current_pos.h=0; } virtual void draw(void); }; class DECLSPEC sge_TextSprite: public sge_text, public sge_sprite { protected: virtual void set_textSurface(SDL_Surface *new_surf); public: sge_TextSprite(SDL_Surface *screen, Sint16 x=0, Sint16 y=0): sge_sprite(screen,screen,x,y) {\ surface=NULL; current_pos.w=0; current_pos.h=0; } sge_TextSprite(SDL_Surface *screen, const std::string text, Sint16 x=0, Sint16 y=0): sge_sprite(screen,screen,x,y) { change_text(text); current_pos.w=0; current_pos.h=0; } virtual void draw(void); }; //================================================================================== // A helper function for lazy users: blocking text input for sge_TextSurface // objects. // Flags is the same as for BM and TTF input (which now uses this function) //================================================================================== DECLSPEC int sge_text_input(sge_TextSurface *tc, Uint8 flags); #endif /* _SGE_NO_CLASSES */ #endif /* sge_textpp_H */ sge030809/examples/0000755000175000001440000000000010517151152012633 5ustar samuserssge030809/examples/bitmapfont.cpp0000644000175000001440000000344007714716134015517 0ustar samusers#include #include #include #include "SDL.h" #include "sge.h" int main(int argc, char** argv) { /* Init SDL */ if ( SDL_Init(SDL_INIT_TIMER|SDL_INIT_VIDEO) < 0 ) { fprintf(stderr, "Couldn't load SDL: %s\n", SDL_GetError()); exit(1); } /* Clean up on exit */ atexit(SDL_Quit); /* Set window title */ SDL_WM_SetCaption("Input", "input"); /* Initialize the display */ SDL_Surface *screen; screen = SDL_SetVideoMode(300, 100, 16, SDL_SWSURFACE); if ( screen == NULL ) { fprintf(stderr, "Couldn't set video mode: %s\n", SDL_GetError()); exit(1); } sge_bmpFont *font; font=sge_BF_OpenFont("font.bmp",SGE_BFTRANSP|SGE_BFPALETTE); if(font==NULL){fprintf(stderr,"Error: %s\n", SDL_GetError());exit(1);} /* Make a nice background */ Uint32 color[301]; sge_SetupRainbowPalette(screen,color,0, 0, 300); for(int i=0; i<300; i++){ sge_VLine(screen, i, 0, 100, color[i]); } int a=21; float b=5.31; char c='q'; char d[]="Hello World!"; sge_BF_textoutf(screen, font, 10, 10, "Testing - Integer:%d, Float:%.3f",a,b); sge_BF_textoutf(screen, font, 10, 25, "Char:%c, String:%s",c,d); sge_BF_SetColor(font, 0,0,0); //Change the color of the font sge_BF_textout(screen, font, "Edit:", 10, 50); //Keyrepeat SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL+50); int quit=0; char string[40]; if(sge_BF_input(screen,font,string,SGE_INOKR, 0,39 ,10,65)<0){ quit=1; }; if(quit==0){ printf("%s\n",string); //print the text } /* Clean up */ sge_BF_CloseFont(font); /* Main loop */ SDL_Event event; do{ SDL_Delay(10); /* Check events */ if(SDL_PollEvent(&event)==1){ if(event.type==SDL_KEYDOWN && event.key.keysym.sym==SDLK_ESCAPE){quit=1;} if(event.type==SDL_QUIT){quit=1;} } }while(quit==0); return 0; } sge030809/examples/Makefile0000644000175000001440000000157507715153144014314 0ustar samusers# Makefile for the SGE library examples include ../Makefile.conf CFLAGS += $(SGE_CFLAGS) -I./../ LIBS =-L./../ -lSGE $(SGE_LIBS) TARGETS = fire bitmapfont collision blib rotate speedtest sprite sprite2 poly C_TARGETS = ifneq ($(USE_FT),n) TARGETS += basics blitting input alpha inputdeluxe ifeq ($(C_COMP),y) C_TARGETS = basics_c endif endif ifeq ($(USE_IMG),y) TARGETS += sfont endif OBJECTS = $(addsuffix .o, $(TARGETS)) C_OBJECTS = $(addsuffix .o, $(C_TARGETS)) all: $(TARGETS) $(C_TARGETS) $(TARGETS): %:%.o $(CXX) -o $@ $< $(LIBS) $(OBJECTS): %.o:%.cpp $(CXX) $(CFLAGS) -c $< strip: all @strip $(TARGETS) # The c example $(C_TARGETS): %:%.o $(CC) -o $@ $< $(LIBS) $(C_OBJECTS): %.o:%.c $(CC) $(CFLAGS) -c $< clean: @rm -f *.o fire bitmapfont collision blib rotate basics blitting input alpha sfont sprite sprite2 inputdeluxe basics_c speedtest poly sge030809/examples/README0000644000175000001440000000453607715153701013533 0ustar samusersSGE Examples ================================================================================== Do 'make' to compile the examples (requires the libSGE.a and header files in ../ - if you're using libSGE.so, make sure ld can find it). Read ttf_readme for license details about the truetype font. The file sfont.png is copyrighted by Karl Bartel (http://www.linux-games.com/), please ask him before including it into any non-GPL/LGPL project! Press [ESC] or close the window to quit. Basics ======= Shows the basic drawing and text functions. Basics_c is the C version of this program and tests SGE's C compatibility. Blitting ========= Shows simple buffering and blitting with alpha value. Reports fps - should be slightly under 100 fps. Fire ===== Shows the block copy function and some palette functions. Input ====== Demonstrates the use of sge_tt_input functions. Feel free to edit the text. If you press [Return],[Enter] or [ESC] the text will be printed out on the console. InputDeluxe ============ sge_TextSprite is *much* more powerful than sge_tt_input... You can even make the text bounce around on the screen. Also shows border warping. Sprite ======= Demonstrates the sprite class with timed movement and frames. Sprite2 ======== The sge_ssprite version of SDLs testsprite... Uses the sge_screen class. Bitmapfont =========== Some bitmapfont routines. Collision ========== A simple test of the pixel collision routines. Alpha ====== Demonstrates alpha surfaces and text. Very nice. Rotate ======= Rotates and scales an image. Press |SPACE] to switch between texture mapped, normal and interpolated rendering. Press [s] to slow down or to speed up the rendering. Sfont ====== Same as 'bitmapfont' but with Karl Bartel's SFonts. You must have the SDL_image library and compile SGE with the 'USE_IMG' build option to get this to work. Blib ===== Fun with triangles. Speedtest ========== Benchmarks some of SGEs routines. You can specify some options if you want: Usage: ./speedtest [-bpp N] [-hw] [-fullscreen] -bpp N - The colordepth you want to run the program in (8/16/24/32). -hw - Use hardware surfaces if possible, often used with '-fullscreen'. -fullscreen - Run the program in fullscreen. Poly ===== Draws some random filled polygons (press any key for a new one). The first polygon is precalculated (a gourand shaded filled pentagram). /Anders Lindstrm sge030809/examples/smiley.bmp0000644000175000001440000000110207301070043014623 0ustar samusersBMBB( m m """""!"!!""!""""!""""""""!""""""""""""""!""""""""!""""""""""""""""""""""""""""""""""""""""!""""""""!""""""""""""""!""""""""""sge030809/examples/sprite.cpp0000644000175000001440000000616507415070535014665 0ustar samusers#include #include #include "SDL.h" #include "sge.h" int main(int argc, char** argv) { /* Init SDL */ if ( SDL_Init(SDL_INIT_TIMER|SDL_INIT_VIDEO) < 0 ) { fprintf(stderr, "Couldn't load SDL: %s\n", SDL_GetError()); exit(1); } /* Clean up on exit */ atexit(SDL_Quit); /* Set window title */ SDL_WM_SetCaption("Sprite", "sprite"); /* Initialize the display */ SDL_Surface *screen; screen = SDL_SetVideoMode(640, 400, 16, SDL_SWSURFACE); if ( screen == NULL ) { fprintf(stderr, "Couldn't set video mode: %s\n", SDL_GetError()); exit(1); } //Allocate some buffers for the sprites SDL_Surface *img1,*img2, *img3, *img4; img1=SDL_AllocSurface(SDL_SWSURFACE|SDL_SRCCOLORKEY,80,80,16, 0,0,0,0); img2=SDL_AllocSurface(SDL_SWSURFACE|SDL_SRCCOLORKEY,80,80,16, 0,0,0,0); img3=SDL_AllocSurface(SDL_SWSURFACE|SDL_SRCCOLORKEY,80,80,16, 0,0,0,0); img4=SDL_AllocSurface(SDL_SWSURFACE|SDL_SRCCOLORKEY,80,80,16, 0,0,0,0); //Sprite 1 - frame 1 sge_ClearSurface(img1,0); sge_FilledCircle(img1,40,40,39, 150,200,50); SDL_SetColorKey(img1,SDL_SRCCOLORKEY|SDL_RLEACCEL,0); //Sprite 2 - frame 1 sge_ClearSurface(img2,0); sge_FilledCircle(img2,40,40,39, 50,90,210); SDL_SetColorKey(img2,SDL_SRCCOLORKEY|SDL_RLEACCEL,0); //Sprite 1 - frame 2 sge_ClearSurface(img3,0); sge_FilledRect(img3,0,0,80,80, 150,200,50); //Sprite 1 - frame 3 sge_ClearSurface(img4,0); sge_FilledRect(img4,0,0,80,80, 50,90,210); //Init sprite 1 sge_sprite sprite1(screen,img1,100,100); sprite1.add_frame(img3); //Add frame 2 sprite1.add_frame(img4); //Add frame 3 //sprite1.set_seq(1,3); //Set the playing sequence sprite1.set_pps(-140, 0); //Set speed sprite1.set_fps(2); //Set fps //Init sprite 2 sge_sprite sprite2(screen,img2,100,200); sprite2.set_pps(350,350); // If the delay between two PollEvent is greater than 100 and all events are added to the // event queue, the queue will grow *fast*. You're program will have no change to catch // up. You *must* try to avoid adding events unnecessarily - mousemotions for example. SDL_EventState(SDL_MOUSEMOTION,SDL_IGNORE); sge_Update_OFF(); /* Sets start time */ Uint32 start=SDL_GetTicks(); Uint32 time=start; int lps=0; /* Main loop */ SDL_Event event; int quit=0; bool upd1,upd2; do{ //SDL_Delay(1); //Uncomment to see how the sprite class handles delays time=SDL_GetTicks(); //Calculate sprite data upd1=sprite1.update(time); upd2=sprite2.update(time); if(upd1 || upd2){ //Redraw needed? sprite1.clear(0); //Clear the prev. drawed sprite2.clear(0); sprite1.draw(); //Draw the new sprite2.draw(); sge_Update_ON(); sprite1.UpdateRects(); //Update the correct area on screen sprite2.UpdateRects(); sge_Update_OFF(); } lps++; /* Check events */ if(SDL_PollEvent(&event)==1){ if(event.type==SDL_KEYDOWN && event.key.keysym.sym==SDLK_ESCAPE){quit=1;} if(event.type==SDL_QUIT){quit=1;} } }while(quit==0); printf("%d LPS.\n",int((lps*1000.0)/(SDL_GetTicks()-start))); //Clean upp SDL_FreeSurface(img1); SDL_FreeSurface(img2); SDL_FreeSurface(img3); SDL_FreeSurface(img4); return 0; } sge030809/examples/font.bmp0000644000175000001440000016506607301070043014313 0ustar samusersBM66( sge030809/examples/sfont.cpp0000644000175000001440000000335707714716160014513 0ustar samusers#include #include #include #include "SDL.h" #include "sge.h" int main(int argc, char** argv) { /* Init SDL */ if ( SDL_Init(SDL_INIT_TIMER|SDL_INIT_VIDEO) < 0 ) { fprintf(stderr, "Couldn't load SDL: %s\n", SDL_GetError()); exit(1); } /* Clean up on exit */ atexit(SDL_Quit); /* Set window title */ SDL_WM_SetCaption("Sfont", "sfont"); /* Initialize the display */ SDL_Surface *screen; screen = SDL_SetVideoMode(600, 200, 16, SDL_SWSURFACE); if ( screen == NULL ) { fprintf(stderr, "Couldn't set video mode: %s\n", SDL_GetError()); exit(1); } /* Open the SFont */ sge_bmpFont *font; font=sge_BF_OpenFont("sfont.png",SGE_BFSFONT); if(font==NULL){fprintf(stderr,"Error: %s\n", SDL_GetError());exit(1);} /* Make a nice background */ Uint32 color[201]; sge_Fader(screen, 0,0,255, 255,0,0, color, 0, 200); for(int i=0; i<200; i++){ sge_HLine(screen, 0,600,i, color[i]); } int a=21; float b=5.31; char c='q'; char d[]="Hello World!"; sge_BF_textoutf(screen, font, 10, 10, "Testing - Integer:%d, Float:%.3f",a,b); sge_BF_textoutf(screen, font, 10, 40, "Char:%c, String:%s",c,d); sge_BF_textout(screen, font, "Edit:", 10, 110); //Keyrepeat SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL+50); int quit=0; char string[21]; if(sge_BF_input(screen,font,string,SGE_INOKR, 0,20 ,10,150)<0){ quit=1; }; if(quit==0){ printf("%s\n",string); //print the text } /* Clean up */ sge_BF_CloseFont(font); /* Main loop */ SDL_Event event; do{ SDL_Delay(10); /* Check events */ if(SDL_PollEvent(&event)==1){ if(event.type==SDL_KEYDOWN && event.key.keysym.sym==SDLK_ESCAPE){quit=1;} if(event.type==SDL_QUIT){quit=1;} } }while(quit==0); return 0; } sge030809/examples/sfont.png0000644000175000001440000031107607301070043014476 0ustar samusersPNG  IHDR \( gAMA a IDATx}w|\ŵ}WZV,;<!BiF~)/ /$!KʖmYlow~;]iW ~GΙ3s̙3'Hw'.Fgt ՇTi(ޓtlDYg:F'C>ӡ1:3lqmv*t5O>TӕSl>t5n(8H['nNt?j??}8tOm.M?3lvT4ftp2`:O~=dũSWMEpN*sq<kd&q2pHٗUt=Ǵ,-J||'w:q:ӧDtI_(U'zLOg["O<||?'[|ZT#|}Q@ (P@ (P@ (P@ S (P@ (P@ (P@ (P@ (P@ (P@ (P0PJ\*P@ (P@ (P@ (P@pՓy\ϕ&ksR@  ^O`5('g "9)3E)P@ L (P@ (P@9NGФ@v@>q y|xղ|sx*Ɲ#6Ni&ϴ =! ۷Ӎ (P0瘙CzBf(X6t 2Di 2l:p T*j'QH"3t8'9~e,dDTF"6f&3 ˓~e)Nd81(1D'T7POYa$`iNDzt[ R C&N4'CB9gӁpB< |ϛ +T1]D' R5H,?NHtb[@6u*c5fU?.g@Ѥ{XeV #! +QPuJc2E:w`ri~6ΐN:mSMF/YGʴRtdh3YPlٳfݾޞ=* ޟO~LwS,=bZ{4Oɾ7;AgK?ME7͸oLR&l- ML q Sx2߳ }Q "L|gh.A?>|f$rC/Q_qSكLN5[RZ9V@Hi.@t^dFe~!~gXi*c~$zBy10i  8Aн#"A OW2uwu@ N6du:6f=1MzNG93b&p캄c´ ndj!V4B"uQC1(̄Rzzȏ"f,P/AƎZ}[_Y3js/k(~ V\,z;(?f't^il\&26b>`: D|M=CA3'z"2b֖2Hw8ft` DG$.dB6:,SY|  r9m{P4NWVOQ4aCtY5ئe0~11N`;߁xg6QLe)m~-j'ՁnIx_&d\$]6JNKd|8St֕;Hb/fЗ{k/uCubHDJv3=^d/'^ jkd6^S}tRRw3܋h1L& a鞃Y;M2-__t^SkdAQsM H0`|yZJ79&79LlP;왆]O6t}s dI)-mJ]VҒ}J3b2kt_mvf+!m26 {<|R|]$ߏ;ڡgf9RSԙ |7]~RETįQJyܤgTWҡ$mJ痶!Ha'PvA*{+M%r9KZ^3r_f Hts:zג$HW܉h(v0 qZĂDYz:>C^LEYs >HcD,3#MҾāe_=ԭ~nJ,,}h@9'*Ǔ%sPX(_`H&TFzW=١h~QDg;`Xv䩃cu8D]d-5 ^Zâ3 gˋ*[ưxuD9A҂̩C;a sKخLJ7C4?h 'fѹI}`3s 'Ա PIB=$ ⡆0]Xb^ aXLB?Q-U@4( Nc`` *0h5Yƕ#CC!w[s'm˚>+Ѭm| qe5-09LRX_9?61,[Q!ljܟb8deM)2-e&Ĝ*a7t7~?/A10ՊҤY`b H_R"34 A3vL#VzZq,}1s!H&ơŔߴ .gpRg-Q*މEnAv.k#ҖfNdb1N Gd3e #Fh:YemOC]I P =fꟀDVUJlV;UqEE7^W&g0t:%z `$;`/3['|Bzn d`i?Fe )kq#YӤSYgB\ž'Ȏܦ^]4RҡAM'C)XsFedJsU6gu+Pp_}'Q;'E6]9VSg@Gܿ!=>C1lKIPhˏCSO'i*# c;6f\v.AяAWSZ}TL.6"6&c8#0_r>@ڰbռܛjוVDPy=o*PWl2U7zts:"SrFȪKI }\nf:g#++[AJ,# 9+Tn2C3?eF-WW*GtvGhJ]G!!t/5 o g k*ԫs U*^wC [v޲8i `5yZ{_39іȶo?wWW~=h|w%'ĄmlZ0(9p"N0'^+gL0Wio" @A{_8wޒB VK_%|K0ܵ]*㩏,Z4օWZK-OOC[nݴaݕŵXss~wB\lG?sEglڒ3U*X9(*x[u.0gYP`iW/9xs7=hR $:YSV\U<$oB,cHg }W tQ ]={MU\n_ cW*]~-@e7M]'$/`0a˺_}rœ%U89@qndR9oә:0vQ N olݳ>^y}!iBr3ٹ /\n/4WBy60oTj}q*5@J{:M>0h\Ch6 9mEm=s}wPЖɡO C_SY݂+\JF\{ƹ4dszI^pZp#=q_aZE& cB$m$p8W-3h4@`Y4xݞ;CHY/|K\a(hT2KB<7 i};8a}R"Sl l a|КKSWR8Ŏe/{5=`.Glf/8oɏtZsGC;#6?i 25Ѥ*&mReٲ;s+9݄^U]]Ă9"Ͼշ?i9Vues{yusrXh*Έ$b2e”ށ9:*Hft)@ cY,kh&ŖquM٠@1󳭱rk)b8zByp=D|Et/gɕaӜ8c,?F4<fOš(@noĉr(%D_yz__ܙS2{m_zAV-)[++|B $##xXU1]fLm0t4nos✟ULgT0x}cj]nU*X_yC!ѡj[aQv$tW9hLvCMc0NL @VQ+rW֨x8.aDTkޡsXdtWYPp9kK4H c$ |pڲ}n$yʼn,ή>omI]A"k6AY֭:>b* @a2xE)= i 5CB8gْ,ϱWU<C!kBj:S?:(jQzI+@0BDha/ȑ_󑦞/"v6MǞ` )?|hMIsKu0 `"R8 -1ڿM(}`_:ߩ}07tsXhd6!0z !+8r3|pqEc$q|:qXQաP4Ch op`_h#!;Sd:13˻b4 Oƥ*-s:Cou9>{Yyl<FiCh%@w(Cch͗cu㰡DE!h9)QI}_D,eq}~lk:͑|=nO({Ϯǖԕ]j07  ` ё14\?Hpy\+erJ`OCۖ%[h:f|6G? Ш O9n0Hp/ya뽺 KƎMZm96ku(Z|:#ؽTubUi:y,ϵW[j.6^-b[y3odؐա@0-(kx*PKrߏOmׄz5^gZ[Zƈ38AusUHwuP u8O JDGZmҧf$&4jLJ+$q0ry?9Oon|OWI3:n <:b}Fr"7_ڄAAZוZ\E5">i`2 mKG]5u}إɒ rV[a,h!U70qz x~wug^҄:ZCO=: p,Fۃ^vn槤=wYiلj5tpTSXM\"uWׇ^mݪ^qϵJV(_^}_(}河.YHلyj5̒1Ɓq/qzwk91 F ȅBՑ .Q}D 8bHbWSM%E;kFcBK7O6UKMH( C@h')g uWEW=`0i3]?/;4qgs}DtBCuvU!gJ@I}]h_Lĝ,0hU9}4%Ul. 'U$;4Z0kookVNL{'yP Ƣώ]eZN{z74Mҧ3\OT0)<:#BXf)̟W,*Xb7`=RyS(R]7B_%_ G:C>Z^o$ Y tK r.uP LJG|*5Zzc?N mKx7r"x?r=76/\hS`ve"z\4D *JxG&.whV y~6ֽ+dI-A_x5 N`>?v`W~< C/ړ0e4΀*qj-q2t@rz<Vox.Ӫ _3.}h+v#':{/@,RtxQ >aMqe/d/X v<+Ol0^p3xdHp`K;}B{Akٵkd PQ=ƈ6a՜c< L@allփחTfѽ10DZ.ɯ}Mï#?5uOE/^{»7Eg{g4zFgNeޮ-Ʀ)|3ϼ z!eO' $m~`]W pgK;37_`fp u~c/nڧ3Pۑ/{ee d-bΏv\0HȂ>r5L'GCϴ?0TW _Lsl~kHr]͝*&N36g7!_"_>je5ʞ*Ҹ6#^~ٕ΋=‰ T3i!Qu+J~)ug8Rb5eeEDMm٤6 F[G \X8N Tʚ0ߤqK嘖~ޱYU ĒtJHK8ZozU5Tb5&O}c>hL7o-B`WUxiJ ~`з[4. ds<R][P`Y=o~\(Iot;)As4z @6G=tڍkZ6iQ@4EA%[d=l1izTόI]w{F܇ XEVj'jA+x=,)1t1(x ȍ|8k]Z56J54ڭ=[l9DI{wLءהW-Q}*AC 5z"!>}=MfqK,)*^]5{w'U)O7e- !FGw `B!'\߱~~C< aX x|,Aqen?YWum_7U}@ fd,Vv8?' Mc!QP|UqqD@-۟x`c_GEZe Gdž<3"a2?qݲZCؾX*Ѕ#Qhǥ} {Uϔ~B[~@C+6[Pu +˖ 쪊}ڲ6r(ޮ 8aҜHFT[p_vcWg! s~=!@gZ+w/T}ř+)U_oxsoP옸Dj:?aUWs#:vOs$7+– aG*VWek^ ̽ I"ҋX.~WwkyyvU9 oBA~څ'X-OLI6LVgkoJq}@b}* 33dxL4՟9KP $?*o?ڲMWXrtIY%;^*5%oG'-'`Ӣ5Lc9iL~qaMTRS;Q7Ϧ*'`t@*ހ]yIs6h?4,ܯ1%U/ gS~ŔE6}s2wc]f)IA7smp7ŠΙBXMk2uaHU.Ӆ<m  !?@tS_BM(iсaf2n4xM7nDAZddD8s?2*WdX5k8 _ b)/^8sT݇7?vAP}77ٷ6 ϑz>7n 8!Yp`G~eyu.nݳ#` mM 3/ 9i*X)q A\p<}kM#gimpucOtW +_ ueKXM7uȠ=BpAu~ڲ,0,:jr%*~9zL)'Ӟ;gj/:懺?;"d]\0J>; )yamsu|pт=ߏJtTOMJ×Xn u/?!|j Z]h W[2۹I_ob޷]_F^ܻA0cʿ:Jh/cyR<1l7@G,ak\I8w_5ܻ>%rB}k8A";z>~*KLZ( x|yEUEV" J>q 7n5DOC{靪B׆ C}k(\Լe_wʙ_[:F>Fȍ?ߕ[v-z ⚤&?G^ųj* HCs^uLY|@/x>0~w=\|p~-oNRF`˜y.tDNF'> Oo_ҿ.Ϲ/<ٿiCzsB.ɪQeڎ]8 E^^@Co_qx~C[U;?l;_SZA,"ye+$ʟVHfhi3soFU|_ EZ^ <M>v u 14&*{||G!fg]dbϢJ @<*Y*WF泝E3|C8_~\V9Oj+C\AE̮FQ"Jڣ/ ʑ*kGׇu klY7u"vɖHY/jǷZ|/Lwfxpvl u&5CuA\%kZWZ"[kon ʤr^{#g/D`+ @װ)ie7l gܳVO x^RL-W;4,ξZڊcH5 ?5?ylW1xiTEfB }` ve6e^mxXxB;P?'dm%%L2Btۀkaݬy͊Q!ӣ ! y¼<.~F}[#_ڀg-OKGఱE' k47??qu-'~9*=gW$iUY`q Vu.mtܴy"y\ U;Д66cNJvm|˼tS[֑p DxEK%{M$&'&W8;':"tp*5^ќXCBUlXܑB'Uu΃}T>{zSWsmc1ޫ: [_&Fs~%|S GzMX׎I-Ie\paMRtWݶOAGpTώ; IDATGk\\[X&uIUM3{LU=3졟9fsoW/j>Fm1et\]?TKD; y.t6r_uǮǃo#zn?PkZ!kmQ20^ fpy[m/aˬFD+ ګ~TCL a{쟬iU~|{۽ '`2> d9w&H0:F욲J u?4d=SX2o<"ro0oC]|}F.Rνr5A 63z(lZUGaOw?--*:[+aiowb-l֌AR^lk* o+4g<>cs"fr8Rsh V5@{8yk zvf׾9xnt=V^`N巰i`3 (}!˶_2J"gׇ@eNm~k&Rنt\}|('8t5FYf?T[Pa!q\lb .~ݡQ٘GvbA^d:N6!+?nzjGgy-/\ sW^Cpxpxw,А1y޾DY{vOBv6Uyt|/^3vKo~BH`r,/Yk(ʩ|w Еbוn9pt_X5 L K@Z1B QPWN`;`d8/,/2G9 AЭ_7/2Ǹ8=C"ղT0ciM12;Rvi??e̿Sya6=L'n^O#@JΣ< ~n(mV$LywyMNK,r'>W?%I8+4Ǝ+<@VqޕkkoȨus)DL=I_a)]R[-:6 vRk(:d2wʻ9>K@#N3i92>zR~"+0pҹ%DBvM7<ۃ!>XC\!LSK-L!j]{Kg]y^CUw - ._]NfN|rJx`CaQ(hQ?}Ѷ &TnC.f_*5q8^XABdzS? u0qzaJw/2 ?fP 9"^o]jV0bUggWfl0rC /?-y#͵w( 9}c~9jrDשLO`</7r| H;uV8JW\buǏ ͽw  A8H" ̓O䇺rYyi#!xaOǟ5ŕ-$o"{?vNsjr ZƶI}0 gAG 3C20 u}]Q+lp "Di'E8V9n.,Hظz![Ȕk#с4.8wh8SO8˨G/Fo4]Ns"WXnhݡW]}^KM F 1q7siqՆj6@ /iH2J/1l#=/+MEF|\2"5졶õ/). E>SGX˪M?!,9˻Qu.rM^@`盻{톯=zL۴_{4rg]AcAgS+Yf!X_yҢ}6-o'*g^ܣr}6yZsx #RBac=dsJWW:7/Ө ٿΕ}cJ@v3B~EDovpf+ۣZ r5/V#G7DuFEQ O3zU=` |'xoO==W{ wڊ&T@|ş FnkX wј~0ċtG5^&H'Wԙ?,|<+_QsbbSh7;GwijF|qɮ}{`C\.:xeReP!ǡ(^#O "s~-FǏ¯qGmN~oK@pU&~|Eن i4`Re3 έCbTf<*iR63?Y`b:\w`I8v@ .P "ټ 55HO&r5Ai~G3qvS2:|JC A\:ӥ+Esu M~t^^7<:f.x@7C뭄\|>cTC Sk'fȩ{оb ~jPA3z'ty7mG5>ֳu z>;n|͘)A iv%9q Y \nCYwGGdz1g?e~_UBQs.rrqsP)Xh޹uvD[@ 6:'݄O^j2~S{uVyU3I#iF]%ے{KuN!.me ca_`߾.K tRIB:Neɖd2{1\)*&>=clA?"SNL)d54h&cf7RFt`~ޚ>489ܾTIfBŜDKPB64V)E3$C[NW(z%х+$kW<|_|p(-GuVS?Gr)cG9ShR)TamMd86eY)Nc8$),X2uQqupWv`>֨h_yoDy6d_3ݵդg߬R2>Y-,t 2B`~ViCZN>I)^La3BUAXZ}*+I:;u]х>WZۛyEn޴Ѥ2!FR`標S:^89cRʜ+SR1XJ 4s$(,^ tD-ijhx+y5<'ANP,Q%w_FPuio$ň2g>YVw<5yEq4+iG(gP7oJ,'_KFcj.ylƄ #Ό(0.9^)u.Ӈ-=4 vspمlOdƺWk-JJǎg3GNŤZWsOT?W{%q׿6MťɽՎ]@bRD5LXP;wO/ױG/L7+7"gZCc?`MQ:P£IS N)&ǰ\,%r%0D~pu]v$#atE.>3NPLq$"b@*g>A⩐$aAx9VT^J3Us^-k; /feѤ4CsQ3#mf,)S$XyQKԞioV= 32ET(aJ'2 Zk#g/(@@m.$(ߌD][/k)}Ty\wOR~-zRbG]( lDgk&RTң'ڣb#of 2It^ P[5̓ĹI}$-FId/\Pq`TRDg~~2'3 ѹiSgpM"4wQ\d@iw^SK5K)}t~L`V~7rwF;]hg^eL2gn,Ali\o`ǺqG"dy*ORor#}eMV>@nLOr'˸~<ؽF˒L(ļAϲO)rhu|KZ ֖ZOf3j[GJ{j[ߨK<&/CίRiIXyWd߶4h8bXzw.?Mme\L]r}'60VSһusWۈӑNPfGGNvĤXV|}BhQV@X掠۲2s+Ayt)0'{ljX2oy*kz9o @y_ *>t:HP`Xc ==j3RgdG ,5d|e[2c//\r@V*(ўR,=l`G>}#mST~OnHG2?Zy^RRK>_i ?X'`hXJ5uuCV)kTԵTe\mۭ㪕h4i6AnTTC]5}0\x9?qIpxFPJw[ծer\s2ԠkWЮUF'閵-umbukűa3GQkgSdWnPM}gN^2vO9^-u-VlkYZvڵb5W+-ת1l2R]UX? :Z}8̌+Ap?rvrv};`g;y>.dz\5[&ywuHsc'gcFu}2<)SD@p¥v[agd肳;ؠmYR !&9yu_r%86柏&:a6$1҄(2ś ~k'q/ ^[in$&~JOr T=a $jiIx];ޖQ8ek'/ꫝj Ey4Pe5ؑAd~2(@ @_#+fP\]`]%l4&ʋaX /ik{YCd =xI@21ij#DL\g% "MWb]w ؝z= ٰ%f /ݒ$ep >37hvEJߧg!2:ݱ6`S?*s iW gP0Lr˝-zo&Gosr#2QR:Qޫ'YGXlqkOR,Jb ZAS^wiiMRme|rz{ͣk;j\[E !W7rf4] Rl> DY<~H_tȝcu Hëc S蛋s\vKڱԣ,q_od\r9tلeT0)lMf/ǿV) mS92)Ɨ,*sq~dsgGO /x;[?r& m cM=|Ι-a_,CLH|N;n*=ƭX9^ǐaoKW$|ux"()Ox }^ Jqf[r,c9p y!+G@$"p,&+"&K:\e #Bi]^Nb}$U8y 2Bٗ9fdΐog!Yr`/2L ^u-6 /&5 `&#;Y G3BZMFw K+,P a+ciµ IDATFq%Pc)K ׷nddGxժ=;L/cKgJQ.Le1ߑ,<૙S7QM 4=B%bx:8WCX hQLeGhynpibvEr83^qK!XubǙҺǑGh ̇i04+n:Pm9~QF.br\?zc\u9bη4QbR;~zqrV ld9F [nm|&_CJ \O,FF+u! ŠN]"ѲXd*O8S]3jW ޅ<6E΅LP2V%C@4'};z>]^ S͔5!|Ez`J=_Z%;&q*ϗ6_ݛ*`EnMJy`:cZx)_Ւr,1ZMTRZYQeHP8PWD[DN״9QԞ%2.%W:%Jw^ڢxi"&NB=Zݿ4N]׍π+_Py/Qƒt{D :i]mO=zhlBJ&`Q~?Bbu{vl˓THj5HWS1D@4((? @bYliь]W ĬiKgHjZa~WUHkksP+S(EN,ײ8IS, Idjҡʦ))?)Z|,ܻ8bU9#f녷OI=I(%Q` PезIS @<}czGtg_BӶy( WY3:x{iBilt I΍:@nh}JK@]TBv0,\TgLd:D&GEnX afůgk<=Dq@p-%ل<CUblG -NL\LO-SBb ,U8! \u2݀1 RO9Y\]ʖ8Q[pt]*bV[yb:jm7TG@DT8(if;+?YNMF;3Q B(zhN0䬫LZ|x\:qګL cO]naxvPVzLZFb|}>H=6TP`S&-Ne7ن\äLLDӀUU,%=<''46x}t$q 3+NKJé)-뵑KkUX_[xh>;p*Jg:tuM^\}+>~2<ڽL%<ΒgȗFqC5UeN3{=A>+1bUG· vhNk#xO!w޲J[IɪTYsrQ3?/a)v o>h1ny&O+V; Q._Rn, Melb|e&۹TLQ( %9e)%L:dbռYUShnI+dл?~aBݦnK.k?:c4L,#MtAݯ9Fּ8;=i`Itvļ[bnbbj$$&JaiLiCNc=>nS}iagBU]OV:2~I 2,P0vY}x~Q⡋Q`._`U7 8͍YYF먮X2P&vƽ}҅1ٲ/Hb?*\3(ēg񱱾Ov,8a@Wׄ,Mdt"̤!XDsi15\U)8Vi?3$PXl 1YM5x]T 9PpՒT;ױJ_ ˭ۏGvPXєePpc㗞e0aWM&.rK.Ts":]Ӗt<5 2 :'$@,XT ºI:(cc*zBD ( ǥWhYdG !)+fGv|9(ʏuF T]v=!x|QAjbp:rnVl e&zv93d&Hzf&CF^{p;oUG3oT&1#,+Ix8ZwEĐbV)BS;}Ʈ w2ò0xG^ 78HSѹH?<3VKtQvb-Em4"WSKaQ;U\LqʗɎ^i4:KL)+1AfTT)TJݪm`M‘3dYTx 2w',C;) =scUC^ x[l|وd?" % @) t:%ָ<,P'0,CςTvG>!Mo& aq2Gߔy8 "/G:E1J]a)8G;lj}")` y=-&JQc*X's!Rfy1!Wj{ `Kq:P.7MS OrK+ k06`Rp^ ,ډDs.%\8Uo23Khxd?Fo1tQm WCmf4_eԘsp\Zo+ 8,4vZ?I}(-W |,-Iu.=ݺkgfׯ)Ƕ=-OrO0DU6e%M/J,ƧˍBtw oC Wd?>GoR|ԏאiJ´f @E^tW t~G.o+BpDz7x_鬦b>Z78RnbJf)EB>^'eRȝW~у5_,anwIV8hbĔ̃"[Ņϟ^&6l6ǪD1 [ϴػGɍH@n]UCV<ЫgF;JT3͟TΎ 4V{5z~3W+S R`2Kvu@20SNV v-vЦ h ,x²uWyKӒVhhk]2+igg[}ͭ%ƚMze _7ns-,M@p[R7s5Rt$,{gN7q=*Spu[ΣH&ek 3{ƽήy #(Ⱦ20Iy}WÑcs:/m1ٖGt2] ۮ| P̲2#}%PMigЮ|`0}ȝo𱨎kd6V!CQq 9='G][*۝:L8;Cyk_ki"WL\86L%;K`6gN^|,YXJ^|{ M8h5WUvJ 8vAq_sM6sivA18>RP`K3g'w7Xa]L j{vIl,xcB8.c73s]c63'f>4J7mZ8GR¥sQeណқ@n{Wy9r[d#*fK˵x +i)ɮ(őŧGF~ki?;[cN-.lwZ+k* ;Kt!0`6-/$ggkZU5O}f{+/w4זf&"酿+k 6Oe`rԅdP8sY[dn%:֑eHk!sv1 -DrT69ԉU {1oX٫;L\p8f^la 13Zuedfɡ{iQ`[*wsmƝ%,'_Wʜ7NMG+pɂ!xUIeYɕ#_&T-eOr̀$<{͂'W[]{=[y<ԓQᚪ'$ $%FBp:GNn]uPIsXF-&<V9};+flgH=qi;5e&TӞKLo2r 0^XTgHiza*Ћe̯agܼ{Ggbn?f>|ًIMd b%4sM͌0Տ Cct9xßUIG(%RKsK8?tӱ3`gXe9A eA`RNeqBhyps$K,$o>3d&0885rVm 4TX: xjQIj&(pil KncK6u\8GNkTt8n5.d^JfIQBw#\X&Uˈ _ K;sgg.nzK+q3u_U79^8o+Srs(Nu.Y@˄󚶲ߝNuJLOc>6t}+j+'2Sc^@.^o?26m`LO-2אDP`N^yPjIQ;g nh8E+3RH1#QY2;~zjgou|]_'}sL!ӻcm6խBZeZ~Ǹ@8odb!DfַAD$e2F#u|t`O`ձj`^r)q}ࣛ*nl$Ļoҩy0Yff䱋ۚϞݻ{J _8J\dLq[3-ry@P==1:x2` .RmvbBM( vLK lU-{LCx*98X,8=cg" ́--Uψ$8t"i1#< c `˷9oxm&@)[ %_)n+%ht\`\ 䶎O'#)lŶ^nK d{9NB:4,WE9+ѱfwN>GGc, -S夣_(@n%z6 EH(:slXz4Έ[󢄨wx+%@SϚ糽N r2Sf- IDATr3S D41˕(tʰ,MBV{m /7rxn(rz#v)QBS*H@vcB:n u*;Ft_4 AW7;Im3pJKGo)Ό߄ɮT_RXs<3-mw7bSP-qdq/g5XTVG>3 } Z\cg\ΔB8UIۮxy<L~H7;>XfBZ-| IWgL?`LKh\ˤ<1l3B @gҗJ҂i\m&2}ʭht6}H7䙮bT) 6|!̱/Wd*'iEXb74Nt"@.N?ljƺI/q!X}3Ӊ#?r>!zMm&-Re͞׻mTeLLaL/04sUSIW?ɸjBl׋G#XS4M%GzBU9ڦ[ NL}b%z̲X]`H2~bdNL7+L[8};VrD.;2!:vdpjkSCzplHKqz;A!6'^;Z7.>zo|۟ߏ/{Х/HM8{U<}2h+r 8Pu~`Rx%diԃZ1$d< ( Q,Ub6#:t;9b\]]!12yqFhh̓%- y?xu5HH,Ν[=mX_ w)g>Pun0I)^ gGYDh;/Lx^*(c/xV݇v\2!8d9lr_r'OPߪW٩ t՛3 URG'왱)lfqpZ+ÑE<_s (g&{o~gShv@-|mƭ2m!1Ll=:cePwgYrw6Ug[ 0\!;{ncd@R7^>nSR̗=!{ܼ;[Jz>1F`J_nV_3. |=ŞB27XH`~)L\L;K~xOǷs, v6:.@W2ǃt6OQ@~wo(-q$"2m2S}x] K)s ݌`S]QW[G2R6_?|}ZY2_AL?l;0)M5|(k>b5*y"ǎ*HO.>UIʎ*k';Dqkx`btWM]X \M6e aANz<0Bb-TJ#7o;YC%! <{NƖk>Rjb_wu3.gJk̂׹-jZm ~/ A]cܸxXY'i2wf[󇬥 !9Pq\>SO]m4scOJe 6| a9 YSV┲,S@ *ShQqYY-Q恥 .K|bXʬ (xK C1uޞg)| c/ݟe#c$G ^qʆ7y0V=cx}_qWp.=d` 2ӧ4ŌͤC,%ݠy'D"8m;L*> f'8g rFaU"FM9 K4NBE5KXq -,!Rg/:U292xuYV\cmT4џM#3Z"+I0F8Z{NtVk7Vzػ\Z}9eVM-/-)qY\Nko O\qXkkq RఝT/R`|"&+c.1;>Z7}hG9 `H;m~`Iq,srxLB.vᐋo䔁t&Kr[PS)iKVS]UUՎG''3Lqz 2:Ǯzk=p_ߡaal :65;x,9;66{&ӝ)<9{CY9JV,rW{Z*fzCC]<e 1WKCNfPe J/5~YMMS q4\چmP|,+ Ų兮$NõyOg?dW9W?za>, hTK5h]`YTi  Ўb|Fx^?#fqk'\C=L\sRљS7f'ߵ+cRۅc!s+rp/"r2gQ -4^~1t͢VAm562CSt< nju*7L|XLZAݷEEV)\ xn!{D\!jlTtjNm*඙]!)9̕F9؊,.z75X?@2Z̙W$\ X =Et$A~͎! @3OsMݺ8锨X9oE+ԲNưd6Xdrf^eP͛-3zuFB0I)ail1:~m{FQލ fR &6KM6 %R6ɦ}M!TB1`6lhz{3#aK2XxS9O^ƨ=ʷH5 .7h0%0Z(x[1jԤ#@SUw(Ѣ96K,'\_!ꚽ*c暷a״#dF[NZE~ @,Q @% JUƮZ7 .u ;u;@V~)vPT:8B0v#m9{'RUpJ3-Q*ӊqSe܌by$9p  <i1ɕc|䲅/Ń?>=ȩ P@WsIO* $¤eH <{'{RMo m9T4 RaVxN)ƣl0`QtNJqqx'e_g#sT*&j!<$Bzt}+>Wzۜfb0kIΜ)/?s5>QQKPJwǫ +ηsύK;Y`Ú*g&89b~Ud6|\ߋB⦒T0^RreE/-7ڱe*ܑ{̔;kiaɫ]Eϣ<g%[0',82H2nO79`OP3E *R {)XE$Qǁuq@Py^PG\KiWsQ-\k,w)bT, c߽esSC yl=M|;.UΈ4؛S^}^̔ g= KȓrsG;٣*#WBÙͽ\  =?й]ktXԢρ(zΚU|bCK,W=zM+׳?'dӞC԰!o(޻ԄkEL=b->Gw)s ӌ^RDIL> hor^~E:'GPN`dF}jȪ :u/6K)2Z[*XfaԛFeEYT洸t~햍^8&3z ZPܗ#%[>:Ut__kJ0 BIJ%|^+Wr#f'qYoi`h|oB >ղ}hy^kE0%$H=?/Ɋr*SIiki5:iPTW.O;,4JkvEpa+"6hn4u*V.g!{C#œcyA#}q.5)m*vmNc.g~A՝~'4t,ns8ؠKlw]WOv=[él}PT1ʾ۠׭h(nQwߜK4[>k\)~F~Ub3C;]{ηNT*:5>Am11;zo0|g=sݚ*fq_R1oR/ߛ3Rp$ ꛋE, R?hx6w&g鈕`(`JN"_T?SCR桡nocsS^^/t,"4r}PwO-؇2d#cV2aJV yJɔAhOH65q gza*rMm<ګr|hh--fSaV @#P;Ø;Cd& u ;q^#)㓻Aw u##><>ȾιujGd@|>Ie{;b?FlO+Wt0LydovL/<Tiյ]^rph D𡻚۾Ro`#Y9e}|P=gd226{KǸDK9oH:1CL!(0U.9Qo}?p{ijJ٤xnd.әS K IDATߝ\R>[ꌛTHSLH_;,z\Rڙ-!7?\$pGRD5l*Be0UB/7{PqmY5vaXA- Ф,,!8#l2oӈqHh-9 tDwi"0bG|=ݞ W|P)(5kzw$yP&YžD:$.N7Wao4T8"}aܣqW&W0 #@z6DnWF?~+;o2v  \)|00? ^Wm^ /ȚG󮆣xn>ᩞ'?$EPR0r&#zr}=JuR(J;v:RL8[ $qe(E SfbݥBkԹ&&c](}c=byťRܧ&V>-ý7r˱,1Ɵ`8cE9fe~`VZtRKC_vtyyR>h41qU@yyH6!QݤUaIHƭ Ob_P^C{6׾BV['9^E9FpF[iH vl| wb6_&mՙV,á (W0jU՝9>ҥˎ]/0l}wjU7OY 'a@?_թƣ$儸*_}7`t3raU.O:ǮZ**fR0O$;eri0*⿥2(c?LkxheMC1x*pҌ\Rc[Hu4y0oICa9wF3[{_]o2IqPcB0S26Y͚;S.>{_uGꠑd?rɣ% R 3SPTx.3rbk{.k뽯^ T]<цe:'^v ‣#lH~i3?yԽٟ}o{‡'BT%8c ؿ^k]1kl聤ϬM}n2}ChX%;l&# OS":U+7{ϙq; \[%l|~2Ĺ5~Mro{Ѵ @Pݴ(GDӧΩZ  >ܸ3-$I3Cc($IZd-@8W٦a 5,'3]iG֝6%gD&ya{h4nPE6ըqMYIS3å<|A4Y쩯~˯d5Ji#v(gUn̰[ԥl3\)B.XU73 $ʢ7Tz|+?w_Z}ľ(vAﵙPuEҞEy{*.V uT6tasɤ BdžoS]hdn(C? ϻat 1GkMlOÚ긫GF2tZFEGB̠l}w4K.-V6JIjׅ?ȠiTuYa5w"Mkm:ȩ_~w IG/Q}\d|??라u\lB>r.oҚ"xbt35 @>O!h=km+_ο}j1_?P+Y$;EZb" 8|_ˑöwh?z}~EGr/v޸VX{n%JDKlǒRa_?reeL4*WRvɷ&Ь#c_&̹ *HNݲKZ (NI[=>R8FC;O:RޥOgK4k S=C0G:G)^TJG=ԦHAVw8D#d/yMٟpWD&¶ 6OӁX5\]N7NF˹1Dhp")Mn_@X v~V=3ץ{QTt$CR2]N?M%Hmsn-K>H؛k%|gmۆz8ee<4vp :7޴y6I~'izѯ9֣XB:]3#C( 2NPGFM[j Gz6Sw[47h o }lF'IqE5yU2 ˒ w,k^6f5{&#'ָ4z_@YvG)qytا(X6r}4Y=01{,_c'ew5R;>\D4152zTeNϗȡ _ 5ֹLH$7Zԁ4G;(el0T`D{Skex/iR&Te1'w"QKN`<͡x e6,9Ko櫗lwp++ͧ)ϭ̠GНIݡŜ _A^cS-HMd vN)11Tv?񫘁#YPa'7+Ye&@3VlsLν(v^.8 ##~= W'K״\SR@%[kgcLȓp0]9B~KWn8,# Y!Kf'ڏ=!s: M*ciV_ֺ|]5#MiSB`\0ў1mBƔτL> n.|Ntn+#9 . ,J$&U(*MoUר'ld]O4˹7ou8'<y}e J8[U8^3?qSh 6U  @c ]2AFGyƭO2cm~23  mR`WLTQٿz+؟q)}Fbt`4z8I&ę߇~ 61Ȣ-+?e>*k3HBW\{( >B?wRUVakJߣ:Mimz#t u,Ҡʸ)7pnwZHj`o\T;/GcHȔn-f6-q7D9S{L@ԚKҮϣ_E4 MWoElϹ9~uچ}=:5ٽwcXsZdJ pb6c6k%5c(ʄCE/WvΦ"@ #%ظ$pg uLY;ZPƪxr" V>!IFow5u4YONw`ϊh}"򀤅S8X?Qke[s`3V<ӗe '[n^_s_Bck7YfU+nJk =17p5%u%G^>Ȋ':s]?o珤gmjVǑ lk9)^0.߰~u4,<&װ lWP8ks=C>:M`,`yC5N%EhSTT1 NYe4%zh%VQpWk@Й_M?am8w2^?{%%|7P)Y*B |PMAY^SιhI`8BsJT`Vke7k{xG*19W8A5Lp@V-m2I9[ JLT:NPYGV@!},ώdĐR1#S`K dCa367Cx(*D_n0ʾo|'DhCDh1>t͖mGC=ǂ78O]Q"n$:5 zM7g?Fz~'8QƢtvpĿ0pgW^tP΄ qQkN|y+ 5t!ZkK niGFln0]k^U1ws(hO %^80P9p6CUUL%^Vabہ[+W%XuL&x ==89~|G^B&ґ Fqk 8M ,_ZˉLuNU8>Q IDATu"땭\p ~qS/OE>?C)~9ٿ/{9 #\ 2{&e` lX#4&053-k Mˮn^ˤ덗8v!͋W}1e#4{kZƯFKj]Iq\8@ gsG .mDqʸn,T"χ\T *B2p=km20Z 2 ?"O`* @7ptv*%lCUת x0(2[4daѱ$=FvJ+Pjwg-hB),`0w 6ٚjhE ongw(U:7<8kF.l%_>l Rg8xO|ߟrtC'Xr2R%&nm3]L0wlBD*KLe abcLxWRz">0Vy kT}Ktpf(p0s3ΰM ER?bXNJV . LOpg9-@v[tDscpxG#{Y) :v,Z~~no<{1{0c Of5$ = J1HtdsQAv:RbʐuDf`ٌ8J$3uͶs5 g8p*A@ bzGb{r) D'U^B@tsa@C1ु莕 źaҳ70ٻ1? w7;S@z|>We5k@0Ɍ JA떾3c9W`@Y٠BX9Ch m.Z{MeӼS$^VT9T^5'y8Uo{C@ t؟oD9qMB(8>ksH/z0K#Fћ=cF *C?}QY]EJD Bp4E>S.9*0W]7Ѻ<3=N[c &IǒX>R3I$*?*ٔ]9QeKeW'K.G{/25 @Cۗ߄M@ B0M#o-vT5Dz3Rd ŘSxbz. 60`xWTۍn5ߡM4H v[zƪ#_IkY~IVQ-H n?;׻壔ΉW6Q@ǩTTSxXR#mRdS\~ & p$yf/lg ]mOßMG&3 ri֬< , + ­4pe zwdoɢ4g60'+) QX-;$ؑEU峾EԦjR٣1C(7H9aF`s_wW)S?Q+q,!-blu2e@ީYx1Bf)%t[v6{u M4>m Sbuvu!̈vB>Ja1ee xl3<hҬie9I3D@~4 hcjt e pOkfkl`\:JW٣p\H&@e߈ǻ<&IrY{~v|~ {,{ (oY1*΄\\ɱnj8|5yM'X ^e21RIgP#fTǩM0jV EQVpaK4 +U0 PVza|w<{7bRwroųVi:bM %}% z R&ne.LX&w2`Z<1_ wB+9JDg #Ǜ5Ys۽Mo%̾7~14,{%#n~g$IDqϤU!N^'tab)Ze3/-OTeHҀ%4 *E}j3l}yefd [*YRI<y PCE ~+ 3 n͢$x0+iME? Au, `LҠxH75ϯRqFaFFvT1kum]2kQ) ť'emTLG3L 5s󫷼7@ 0d%h =|6, X X&jys>RT$_}LQ:,%,t#G(aIqMutXv`/Ҳ k߹"obb,5al{ck#\RyỈ$5wCN+yx!p4W<{  ϲ*қ[j+{,@Z͆UKb.I%'zbѦ_`v©CX)PAwsmz KKsD:<F:'bv#}KE,mU.r'%mWtjVF6Je0;|l nBY~"s| WZɉHZFn V'AUP}%35=;3ؾst "үwLGAɇGūZ憆oaRߟeC&7G5 J1h+|-P-jMH1s>6qnJ)T8c@όPm;e% LE ,t,FL?)x=$L0 \ sR@G0!y3d2Gig-zlKn<;~* e:9mzٙ%,[q;bi oɛPRI_c 7mYV/VZI{N{?Μ)oz:yݿWjKOݢ .Q'O{`Kݬ&NgRDxbѺHARcyD6j~&9& bᲠE5gmv m(PKolgfn f[~+"Ud',<ʡCwe)N4ܕ#!(F8l iߚynyTo ɿb}As? pK\ox/9eZ=ϕI76GY+Cva h/f|_J&`C{} t`|>9+MaNC;;XHo@utEDԙd+9D}Zxᵟ|# ?zbL}JjrV[41u&_tfe55(ΧǤnsᚋф#S+\{ߺ{5`KݱQ:6z7?7I $o5Y&-{ӠQÙBi:ȱ9#1-n S!E]nɫ -b%MvC~8-ղ|\ry5 .ҲKymSBw$;W]Y},_wgD5WBWϥu72y%Ss\K1xlz AzWRx7 &όfveHJIV,jS@LUg匬V9T+(n{wcv6@]ӊeYǗ%'$4>;Q=ۜuz%x+{&j? @<ѕkHJ I7{yזhC֯D/sw2!E*+B)A+\A?Ӂ7:<0PR 9/ `0 0JrTfCAчXn0 ]հm{3:xMygaD[Y $cYu=V9w ?-=n{C]Ӏ&WfʅKwg8Bt/eP@i~#1滧{ ֐U=ӷpzt(nATCI/-6B@ךw/l? O!l.{h2^FgPrNRek@HhbL vkIH%pl/{(t=+fG*^QTpav94zf @*dB 枇b|\Qg]m>36L6|]i";-n\<i@0+lLM@* Q<礼T{+;;L RdY΃vj!;bLJ ̌ѹ6_cڧ(kcIB[y Q:q?6M)2|+3y {sT8<$ ȁ-kou3-ߚHۮNo0jHS!X,l‰Js,y9QMхyʊ ۳d<{-N큑gRo צ!^6{ ls2c*œLbZGI/|u`0UmeTꗯٷӭ>}pIV!,`,fou2 !J<_ ,lƿ`yv bEy୭ ׭qibf:mbi< MfQ(ɛ-m' PbuՂ@c;d ^Z$qq BE@XF4*ŭ6Ȣ־ b#wɍ"qֺhHްf 1n Th ݧqs]dl߲a_wdJ͎bEx^n:J E׶+G2x; Mg,ҒXήok@Z31`` B.coeh?n@^u0j.i%x">9qjB)>k9)PR:d$3U-u= -l͟ Km1Sa->ޓt4>pX +0_G1NZrbx*v jZяX[52s+%U=`kAquۍ`Z7:AL}>׿ w´{L x&Jp3D41K^%aH$ q XMmQO3q8gTl3(QH),ޟ|-Y|[c R3MOwR;Z2*Z~_j:Y?euk[Rbq_ۏjwk(ݵ<H-7IZ_ԊvXw p} <cN@#I ވb]J@.{#9֯FG?ݳvHm~\*'ê0Rj% Ȅ!sxI{n j0rN#D5}iPLn9aOT#īPOyrcclbaX:aC3`vݢ-R<Ig(EWY)er#0f 7sy8Hڽ79X4?"۟G l ]·SWf 5 IDAT4i}wls;f##|-PF*bHv+amuu=pcyyS>mwϞտd/= f+|ms rjX t* f3~%g&U)5<[<{Wkـiju |{趲;<|Z#ts `H=me}}B,=;ܻ-[@k:=~>!\c`8 6,ڛWA%:6='y)-MYxd[L]9mdR.&,(f)dJ%s*5ugaP`v޸ᾍ*?9ys>ϻ^թ w'2o;zl[0XNc/$Jf+eU虒:"RI'o flbӠPoH*kuSgsN)qm SKQ,z .Պ^<OC?|?rrrJ\۝l璿౩G8<;4O #_CgKIg/-2U=\g/eˀ5} &ac>I'ՑIulR;TG&j!ſ_FJU ت<wy̜S_!lC)cR_K "{q~m^s ienоxJJjKі;ir$%> (l,|4:}kgZtz]IUrdioQ*!3.{7.PSxXӖ(G@é) ?wc ~( ?!ػT-wb k~{5k7[SeIVK,ZBョcC>Sl!?~z {vgHgwCЀ'R$Z:! .J@ag@vcS20Je;/7VKkH9pYԿ}&iׇWhxo_/E^X;q.r޸NKC / :{p1U2/74ok#F}6Yغ;`g:'Tլtr &0P-kBCggՂyMK>CRnY(e.v "džoHj͌=^-ow>f[@ͺ\0@ Lrkq@@/Nh m: Zp\U+z@RnBoU@S3߸ؙ,ߛ?wzX%C FN(0Jƨ~{P[ lYa J33senmY./vo*qftA 7N H(4vT8F7 @<ˀISQSC9%/' ?! T:σ @U|'|-m߭h{ MU8b QI2|vĹƒ$'ֵUřAtKQKkq&d&c$6@:*8gY6t^\I/θQ(qfAJTrbt,oƞ̋xRqad5&TiN#RTk@Pٞ{>69ɶ0lGʹ_a\4KK} >6a}L̫kZ7JΦ +t_݆f@\ۢr]NGὗ,.0C)u}(JIP0]ȩ ib3;hΤO3o>/ @f׶o$c;m59,:Ĺ'bv+NMٻZއ!1Vq> L`}oo`mRJA坹^lsZ,S [0(&(yoy:`Z׿vӫI1oHl(o1"o<B{f_;<9=$b_og<oO쭳oG?Je:x0gQu'O=/D3Cw>F6"F1'V׭<GˁًVƟ0NcXosW8Tfh:nVA1T~}D䅽 x:/*_2`Lɂʩ޾ML'iTCkdE(&%-?Cet[H,< K}F3A뻠z߫.Kyv4kͮ&}+][ap$Κ<(G(U6 gctl2T(U Wҍ,->*>0)gf<1aySzׅ,|J&f[r$(tA;)h0J _J.9YybTo()IdȔp\GgvuA3b?kd+qrUns$pڗ5嵯w '&o<k=6벲)\s|8Ffܞ:G[pn*u9XG}Xjb~.9diŽn>N٣+͂}]v#XT@l6Bp$EC;&E)fC΋~ָ-m&jN 渖:RP0t&GXpm51 IX2Ɓ<J[kW@)ٳD_f{5`Y@$t0Y.u( A[J0v dqRy5IWRgO%sODڣlx wΥ֏rݼй6AlsҌc =+[랛w| t? "`6PʂGgvjLm$@A5IK T)|W2׷@B^.A_9h,ž*10&*e4Js0'y.6t&LUi\tVXD6U5N S0uV߰(O=XxŮXM@yrJso1S};|{?bfw wo ֟;22}mEeB5rRcoY[`딹y é4ތlD AK:^x@ϵoc8 z׉`0WF]6zKӭϖ.41 iϏy溮K.3ulHCd& ]^c(|g ]*~U?gLSt,1͹ʁX/%vZiVJL/!Py6i>v[Z\M(9Yg+/ituw&Tx cY Mw ) d6e.}؀Ƕ9IE NHOfWPgȱg$z]Lk,w!iY41Thǂ@\c0/7֚6jrdlv=t>V*g`g(_F^81 SR?u{LRƒqAwڶ{<d60bV,km!*QM##y6?Qvh[Y'WUTZ 0p6h$&ċ+$^d< W7Zwds W9LE/_^'xd59oͲb VC~qVmOje[2m&RHMce(%L*l"Z /$ m TmV㞀k6Θ$rf:d6]\\ cف`_K/.'T̯b*b^ S RiIYU>[n]T#쯹 0br @@~OR,L'Bq/~`WCG382,W -8y*3k$"9XdU`ץkn ~6-؁OAgu; o'){ŭ&3rRv.|zût~ɥ(>Ȑ)Łpw|[27=r&sV5;8kX.(mX .f%SS i0<\7}N3qi#R@Vd]eAZޔU4JNgV+[H"PCYĝMx5" L1lTh^30 ~Br4 @J>^\ _+rkm aRH+qװ@82b*].դ4x́\Cr6O=s:t<{%uΦNKFR** ryIi3ML]&?qӔ| OE2-֚N#g%ҍ%2ѧ Vh]weeJTc0x30(2/~ah4K`,?X.LNC@DҹҝE W"e1GkE2PÛ:<dzrwE(Gk?$sh$)8 ]\4DIOf ϲG܏qYa@X;=aj4d ,(tZ^;y(xWBD @6KZgQL^on+QylP+ųpVRb+,Jw_Z.kRN'Xw{ R NsNP޹]"Nʁ|i0f ,,"DUWU8<8_NRqX!LXrHէQ"().s]2mMW8.k\dmAVz {.ˀrص0*"Q+Z/oEaq 5* q d[S^*<@(ʑˁ,uʠ@Kݾ!,Guqwߗ'DQ|c컽Nx?NkJE@` @Fܾ\*p^} }rK5(0Xۤ@v zHSc8.UU(Z2JQelh~{Sn"ӸV'[ {TIzrG uZۆɼ/Ϭ7VOm嚵W³2jd |.z%*> 4|q~ 3gϫ鯷|o<;knK06%R8oGFdXX'GFgc}-([7x[[fYeoRoN IDAT%laY,sp[ϧP1RSևLZ4sʉ'Sؿћu~O~nm4_},b.o [{mܸ & mSS\84Y7p"Aɱ`( Qhq$o'!r|lM}3w{5\a&iQjJL˨CcX=BYi;ָTgfDRe![˿Iv!>ayiAaB^M\mJTEeb5@CyL{5 DzF{/8ƱzZKCWhÕ&\LC奫/,%hF"ZMhpsc(eT_6h $ z qradRs3džn*y33~f&/L&NՏe-3p}bm/Iw~ufY(e ߢ S+ahgg.^|``l"!iUg:pR "-IJ1<?FN~؅]8} l+Sc}Zڰ2AۦW>}?7qG }!x; TʳVs\L΃s EŀbJ2׷kȝu.n͠Jb.'¸~Vvh~ևz]ן~dߦ5䆾~ׁ<3^!,)̕~mFQ-zJ~M"9P4 #˰rLLuBЗV線 Qx?ɛ >yflݟoGİ߃`(s,5kk "ACЌ$4#! )ִO\ @-u7L&hO>x̿dӕ8^UsW!6 5ֈJ%b\ϵϰW&M ?y{MUW;(1-p`l1gS$EJst}t1շ MFUy~YE7xnmj/̫FU !v[3(͐^")ά{*JGbZRbc- M{AXF)ٜTv`H~St_(_?Ee MM_wߦ?W$!8RC3(7y|Y10rRZr(4;&rp`yJ)Z=+kZ7ɓ(pVU. LFvLJHiT7|7}7J>hϮR3JGrmU+P힉# 'L,(t[JF} ADT~NIb-w9Wع&/QbCˉ񋊊7fs.6G6tշCt_b9PsX} fcL4s4e ϦtЊ,/%2~/ʉOq;~8˷6XJħNN>~0b)|v_Ь 㟢˸)^]WO)e.$R&y %u)Wh rRv'J]qnX^ʣē0I : ?wU+D!6qqXLJZ ?M4`Z߽(UqPwyt!8ft'OJce}.ƏP!jQs@`Vi4|k^mZdA<Ũ2_x85hN^+ytwǓdQrCK>۔Zx,U%e6,kE hfLT'Z Dy DW~فkW# M'uVv"[:7q$}a5E-0O]IjxEmo,z7ŽZ(6t@YS-똊/^k[8šNf:fGZ੐/ud{d'~_ftD/g$aGw::I)0Jw~/^6a ,tRKJ(XxU`t4('P_Jޖb J"`A(-x^0p8ׁф!p\]@&ƢLvfFUU/0h#avl]5wIg,|*q71Xx\wtM*Ŗ~+%ͼS9*ZtJnh*~4V'ix:"\rj,d  fcTKUno5܇·SO~E2=E FB'eAuUNh ٿMQ8 2+/_nżu+[oꈏ'$Im3X;_zmce;^xC%K8yr*M7lGpf; P᳎<|X~ 0OAஊ+V^H}8v^n~p"ak9 $HlF|p@H-jAH3s]"/5mB[/ݪenR`4GS( S]j$fx(EZ"gA(" @V?yW,J`"nn^ ~CӿV}ZArWN;jŋRPRDPvZ}m`wYO+wuO 52k%S&EuED *ŋ<;Q {FWe)"<{k](_pB?i/E(tw'E&˕fZf>~562'O8'%́5H[14We.eҕ\4 S`u`X^P4%)W菷ſ!8s#ojBܡV 2W `+׮dXTR_QQ)((w ,Y<{x57oڽ$q!νwl nac`CûxuAȈ]a㵑0XQW˩gçRK(v@@mXygB1)+@4~]quVq4MAIn[VvO-!xtAj'MT Ѣc-bfb:}72Ifl5KA-t7ֹvxLϮ?.Սط?ֲ ҄ڿ; aAm./%\Syy%ErQʷ덅TCbdmY2ǡ%:yoP]>D3_ȱg'fOru-c ^(~zCBvJ]q]O,Y^R b%$rɥ \%N/޻49g93#E^=o?<ǞZ{w]kʋoLL;س i~{&@4:-^Gcлo4B:'kr_毺ͮ_ਰE` ̼ij1zGA]m5-2dAg;} O—|? .2HEzu Pg\/M 6 fYs0WZ[^_R8yI)8C=* et+5Ԃ=Y@># ᡩߢ5EghV?7﻾X2`({99ʌ!;gV:8+9ʋ0f H00 #}K.nu" Z2]XnpȻ[,ix 0|j&i!`* ^m5\V#@)^s0dJYi ";CID V/df>9H.34rvQƃ?~E5,U^wž`pƠxx &j iYYgS.U L$dJeYcfZ}5@BL)]@4r6H6 p$B<0S9yg;;NNGv:8`TYn|d[]W,+1\Xp(ܣ%k(.oϸz=aiZ IPLE2KB֪ Go)Ry}j>ۚ7@wac7QN?´mx/Dg F0&UebP|es<erqȸ ɞ*/)?lj^{|`239Ɲ(k bR$W7]TND,+*̒FA0ٹj88!`;lɹyvxhi.s5^Xu!֊J~UXLPN K8&%A`jPϕ4yEILEIFwX&3۲gsCtYOʹ ^ҲI ?(JuL1ku#}fBɥjDvg\I.=I ?$QrSG8Wi?"<͗Kg>[ 4+"ks.#Q{dLiVJHo~ecѾ?HrΒoQi>Vy?UPfW^aTD\8]+ˋ0#41 J8/~+ZZmZo)6ΛzPBz0 e$B'"efR;-Q[˥ OE7_M_siZn|cSZlyZv,^Wqy1|I)r zC{-O4X<Yɚr= AR9Q`&5d29ߟVO ֤cD \>teC'wYFnB'I2'پ@%8Dg&'VdY)G嫙G}g{O?|g17 %X2QrjT͠8F8bRqud{M׺3>gosЙt";o3͗ ɑPԴڃ´, -S`06XYJJa`?=oBHv*(׀'5Z Ii @x6:+'?+dÐ(aGأ(6ʊG4-k Q?Y:a|]dBAl. N̲* 0fe|N%p˖V<7e凍 0P( #w^&I,vHT #eElj)NbgK v9eMaHIKhjzv1 D# 7{fyz?ĝͬٙ ^^6h[5 }>r_O"Qa׾ɝ="Ix_2 RŅFhX>b2 }r%H 22oP1pB=_YUa63U 5㻾Tر|QǹKK,g]ȿ/`NJPxtRXyh~:"%z,V"IZ7ml̲GT?wxo =6 IDATXj2W'e-qv_[gd} 40~aSyUd-ߠg)IpNh?{D05*|&f}k4d_:crQ.alL7rY{{3oǶ-˪1cIY0u E@g}?,^, +GmU//u ؠ:(u|y٭ζ}$a2AV {h81~sGZeO,e⪛ ':1#Ј!Nddhg]xJ 3O%8L{,Z/rts:*GcK">PO:/+؏ݟ8TR]-gi7ц :}M-! 1(fE 62 F>iHR@D qI'\laAXoXp3$p8ۙi8` P@0tRҙ%DfN8ZaQtDKR7"pm5DLNvّP70z˚-ʖn?2sU^#֕[fjn-XJ PMsD'N ,lHY~O %OJ,qhROصcC .0%Jv0M"ڏiQfXΫZ2HOxd}jfen0c"Yj_ eriet% i0gMfFNBZGL }0euLr_rQj8T[ܻ7-c߭AH!wzL7Qq11Q~k~?&?&-yL*oz] Jg"cUy7r`%xpG&4[GXO⊽HI#geLtYs򊭗f_G czǐ[bؾ@O`IeyfTTSTal;ZMߩ6)KK~x]z@]_EnʮYmЏ$O ]d|oMEח0i]ǧ_DZ2/ rEA;J%2n!,,YA[zKyXcB9Y"ct5,]C4]1 ubJxO]Ω<6_0cNIۗ:F"ʹZ4l1"DZ!P/Ն}*9 :֣G^vn U x*'c5kFn/kg]o De ;C 800$aCUZa?=X! J1> K{b$- mE*˦#]@06ظ}UAtc(fy+؋fXky^ X<%dF,)*(ʶvC'w06&" )/W{/ͽVI/*-*þr:  HF;*r[TH=;{}AV~]a+4B֍6d~&sl<>%m01,b/0o.rK0UI B 9U;`_kp杠$b[S @z3$`G ab@ ̫V'c|O8-}r_IzR 5`aig OxwpEN+¸>W TJRa*ct|Mwe=ȱc$=49XdqDYeq<XmW(8H~tZ^6rh f4))|Qe0/3L'c8ۏYgNɉՄxN[(R/,w%Sޛ'Œ:GfFj75e/͋S1=pn=@I0 hU{ȁEji8!LHDNG+AM֛1mNL S CF)`fH,1(XN|˗sЉ)iT`+}w2QkP)C WUJ?PM@T@9 O9s|sϳ*\IB !hG/xjQݛm6AĎC#B?Q%+ 14گTPi:^Afc)ٮh#4925gR7'ؒ$pU6M0 eU]lZm'/:8F10]mS0cC)JD>+nQt9c1(bPL#swAfw8b ϟ 9C?Qd$\uKDQeQp*S;d|폴ypoϿ]bh>(&RQhtR<#Wo5F/lbHCөgQm&NTRDGB)ۓHlѲxV R YL-*Irб_4;#tLòP&gs^zE?SZ{GURZ_)yZy^@콲Фդ(a0jƒYK9jp(V~N%{U]bz5g~;K`a@衘D!X"qi']f I)OqϰPkEp̻Ʀ'qgT>KY|mw_y F]`_A=;'T*kٿ!to@!U*вx$1 hUaYyd٩A6K]+7)ʺ" vRH10}@;[~w P@@Rf;2`S)o>\l`2F?J`Cy-rYOp2}2$!p>?$g2bi9*Z4\Z2cR$@U,fY( {\Th>7{}.QBTϣ_!N6|i |BgC?<|32)0S!hI!P cra(quuv]E5*<%,TIT[U}'nUݪ;ʪ Jz" bΙE/q! q B1|f^K#M߸դ(]^B=u'?->wJ#HG"N572^$KH($#?7y JE<< Hk rqo嫭C)~V]ӞLfj85疻nonjwPIQ rqz-p-SbOZ{eS"%D {k9u:LgĹeZ K*}!M_g ]SKTa<)j_q5˛BX T1w闗;ߥ^*Rh]pK&ΗVdS֑VoV@f#ҡZej-ϾȮޮP`HrRϷj (/7ms 82( ^b#;>Ao(E9m:oyMvD>HA f{FDEm9:UEI_ 7_ww\0ҥ:{xd- IR4;sBD^n}wO'~I /&+CU1%#̋~E4\yBXefe!R1dYG^!-C@!V@MˠKѷsk|{]Z (*f)(BΈjԬZ5)}b\Q~]03xAߞ=sh\}5K4&3@:8U"m$(0L$kYR-fbEĐaXb:/oqf*uV3ni9 h1ߘ; hɤ(33a% Fka^.%7FDAછONOAfK !)lҰZC r(rqex*U`_=Fg .[_CS)ylxY<~i)Cԙzb t ^̙&7 $3ͭ @Di3,l1cgt]a!aGY! gY[HO0 _v̈́ гvRj0r '!Y'93xd>x^lRŝYvn+C[BXEM72C %IWALPZp4RZC~:O,/SYtŚmŜ9*ͬV_j&$/r2%+k Bi2u>Y40o5ej@E8g|+WMH&S)R.Q.H&#-ǤL \J3CБ UcY$6lu: <^-9"S2j]o7X@B1I08`طw_}_1AqθLbf*TScwھgEܙBQKfΗȉ=COfnL?5JFc'k™ҩ*/{#=k_iD85zMgp s"B'J L[>?,"77fsFnhX!e9>%Q,霬}k"ubdM\: 8A5J:9۰@96vOX/:ϳ-)6}qj @m!Jld|N,;M*kz?i2s6ѷK(v5dbCcܨ/(쌊#q㫑Λ.ЅЪ ~џxj?MDb"Rqz )3Wpu8,K=`@&[:{UΏۙuCRYy;sfbBotM$XSY+lY<~u/ {OYZKo)6i퉤4fqz * XccWcy<_|&x%_\ۡۃŤk$R2dW{U?Gm9esOUZ NۢĀVuߤ s.Orƞ&O2&ujf "Z3eie%$;jۙ&~J:WqvÕ RC= N,4;k:DU0<B!X 7,M P2U0$:]t 5X3H3`c%3sꃗ *,0gTJU@%v%(*yNVNnYVZʣ'S?L:p S nu$u=WjʛT"Ct~: @ R%H $Rbl5kf&JRre?e}!茓K,\yR̳ $]gd H$rr\ 5QkIJ;V >V|둷kzqN*c+fH 2\S6rQB}8l s(ڦ'{PKp뭊W1Wn+0T??xBژ[*_3{Yvhɣ/7iٓ< P$j 4A/af;{G55)  :I(ㅞ2!pp{Ǧė׶@4ӷT?X?X?J0~4!/,4e8(QAsş޻2Ur6?`eE% Agzxri+C_U\_]WbO߈G/JT%(-%O8T9=g[@v*&/8u͞bIf@?Td@ ; x6hwZk4Fϳ*]D12?u SJћ@:Ђ2 jA%)#}Ӌɷxy瑞b]yIKuӸcY˺/_Ա:罜p:`Ǭ.E"qop+AK `Dz.dƻYٵ HV(K܃Ӂ%麳kx@+nb= ,KDuDH`{q6cDu/~ϐ>YqT}U]ss*[\Ndӭ͛Vqcs})˂:r!(,ˣc+|g OhU]7kUH )㯲z$o?HeKCZ*;0~\7[@G=;/-6У+7;fmDZ(alx宓=)U,KwEe7JeSB@M'0G}G,-y9e!/ޑOnܸz95o \LA3Mz }Q T%@PʶB7y܊V5o^ 熳9xX9/mi@TQ AZ"EO䪥Wmmu9J;e$>][PEKs Fpڊ/Q~1 jYe?N"}K8f[ݼyWT:7ԲxB\H n3}R}4}D$̽84g睍ܳ*ٴkp9r;ãcښ3 (1Jqծ|IewZ w-Z'*5@:{k퓃-vՋuQQQ^z%A|T9DىѴIh`ֲǚ7$ ,&e8D14l7"-!Sո'aqy|w?&Q<1sTY_fCϵ~\p/2`jmk=vl77qZ;F'﹤u LSո/;aa_nmP R;J'L*8?XV2\bl{rҍ6[EZnoS9Sm';zBы.skW"[cǻb//{&>]]pȝcClSIZ@zJ0dS.kbPI탓ᾷ/ɷ MkO^qg*me2=-LUWd|tl$2al3GOxwMMh]2SR/e,I"W(k)Ii"-c8 1 0MF0*_fD&qHb䡑嵝8$ DeReQ#|iurv HNE30)*iP}< Q<"'|~_5XWbSA,GS'5kpK\njHIזeڳ~2PD'L w "_{bmƕ[6+v %oIO=?2{o+ {V5%;6ixs%FBRq>~f&/AP RBP(@x%4ZvVfXy %oG4ӯ=vK'/̩F$'hJlj# @_*Lk- ST.ҥuKvE?3Ɯ, n)(Ňԑ˕;}aƠdc;C:m+qlrHx ɳ,w`zDX^%{4Rk75>X,h@gdjw"{!^ܣgٶcڊw^Q=$31L0|ΡlP!bW$}oŲ8- tRT5v񧫗|ykݾT-37ٔKߒ$NޝBʳ|PD͡h(bwUoa&I>Q=Z$A_}_(NP̫{~T- $@(r |žpz׽XYe[ľ-)SMGQĴ>2I|-]丬].5ڸ>Jdm '\@â/0"Hz@\L%(n1`"7Uk ѵ"WwDqr=OcC: )/vP, &:g<旐G0`4 YfIp2zPɾ!o}"1b_ ї|IUΞ׮u\p-ru FCR]7_{"Qq-0' ?<1]bW\xD1~.7,@9-_Bb @,ױe;+A_OFdf+6؊.IB]%1|=cX&BQ>[*r~э||6k(Rzq%)SC|w ("2[K!KI/|D3ٷYhNrN}g/orZXccOu c/5l% xu k8殾B1 9Xoj6 o8sᄢf{<-c<=z0)*Hn=&)A({u(viVKuRDíxSSk\qEkSShd*7R/{|/VkYׇ uж:*~]đ-jtqB(Izs7cpWYhyM3m0Urs[~V- M5q ZK2"(D *~S!"HJ%!J3sAcr2v̖o?*(I! m[Ҹ9N ݪ1pݢ AQ܍.&^_v\ Fʹs9SG;wc)4d-kk.xwڻ*ՔY7XUJvQC]~ x_)+HN%ka۶e=X Xv 媚λGqOj[@) |;?K#}f׿90^gU~'{tPlF*iûM} ˋ}wx$WﯪsnFR+=Iq.%c Xc.-Ai ^ Gw8=jr6tk}6?o1l(2[0X}#ұaubcoõfZuL„ѳZ G^V.o@YkUn7 ˳C/v=n)&)$s NwO<[}k$n;Ydd}vsCϓ.W ]W'e@{\AI $Q5~9 yU]!߱*U7b̄(S%l)E7=ޕcZ!@D?)TvԵ1CC+Js"Fڦkyvm/t֭@p;0O1 fEveR*Z?15{ Jr+ڼa1[Ă"}sK<^4D1'uYjfg2~~yİKb(g f-y`gP2 .h9uwt_P郬 m˓N>Wݷ+{&!9~ߺ1x2ޮPhgҷSG'Hg#PwhlkxbAd3CSAI%b/!! .# e2մC{{`|e)d |-É8 fqR%ʀFD <*p Qi8Q :,y +ZΏ4;eW]4`ހgerѸIJL.y~#pn3H K8`@$m g?甆qew%$?tL.i?[|_7Ԓf)\[s UmCYpe$є.AG6`;8ekjB #C @c>~둽G3'in?}lAIh*MK9ĐR.:I fA@_4cG>bYOq"ɧV8Mf'ܵyAfXs" 8 p/uumnȈR 6/$*fA o\)H 1\,6sa V^$ǵ8=gz>L61bA1 U %FDnVBS ^籖Jb1鏜l< "00 .]χCكw54-ZI+ZZZ}]8 Dq섆Q z]y7-.;&[W= @9Կ-5pprlrPZ]ԍq8qշ<ȎCco(g}IpH K}p,=1ڹ?ZxI^tSeyﻩwRBɱ'$HЙ=!([EFקx> # xڒZcpˮ+5;Z}ND!x!!xцΗ&+_R􅥢OfdK#+bu Kbha wkyR /Vi%,NΖ8q IDAT` c,|[Xv+(^9@[G>uu7 E^Xor[~rhLW8>q[j 4:?e\q1'i܂Q&2ybR^JN|%eK؞p|xߙÃ=9?1H:B. mZͩ“Gw6̭CPlq >t 4 7{Π +;Y~8lO_7nDwWK]"\I сSt}SЦZONqS.+oxLSЉvu?f?&H"{"fE(Aҙ=i_FQm`g"n/N&#/js竽e^¦>\{LWLo˺޹ O NT @ch O@C{(ەn, 85՟> {uȱqӡO4:s׍ ߴaɳa߲bmvz<>c๞ǔD2UoY`Yzb4'XC(!KapK@h%kPoƂ(?pU[p󲂷y͵EpWC?F(X@(NE3ENйhݝælb{{[7nx%wxe߈uaa^S6/`@?̹ݎ)\7?k͚G*>= <2bkӖ8rP%|KH82|mhw[SZ\ 0h 4Oh=r+ZEUhۿhG>SnXd(W(T"S {K˱Zo?r^{sեE rk=֠Gp`$zaovt'!+YA00[ք 4ӟ)>ᠨBx.b帺!)%u>_$ɍ^hjkb|M<-ylPqFƛ{ywŪJqCo=Lbg9 K7R4_ilj| > :.չZ9f$@}o Dh& }72//V`a-` EIkE]2GkFeu8p gAZ,gb!"lֆ]" G$!KF0b_Nﴢ$o?Z7Mܒ_Anك'd-@a}xY_Ep C- .(3%Me4 d9 1p7g.99~T"C7?TzG?>}푰^QL.~7r럲mg`,ZP8}PMssZxc ڜ`*j\Em3 he[+2>Z[ɛ9:cO`(6h 0%Zez (h졖By"n{L&Kܻt@~~y8h՛+$)r I Y;wx>.';5X3MtU%t^({.1R۔4U|wz^{K4^k^,Ó`xisR`rK};}4|#)%\ FE+G9e5 ɖ(m +ksz=%[AW y|S:󇦂]k?SbcMb ."t/2X/,dNImlLKiuo(_uChL}6cyX[s +`6DLKYy{=wi.t|<{ڢUl\@M( UM}hڳ:̃84Nj?d{8/|tfɇ(E VU(/cPp>VΐL)ړgQ9,Fb?CǓ,exSڐKψ}z|hįx2+k q%­ͭn)syR,v\򮕹WVyt^yW~E1Ud iHBۯ,VA EF A֜qx~P 9_|O~'~Z'dkU?}n[Xrj *Z]w?BܦuB'ˢ v!&IJDvCSbt W7Yn[Ģ>s'5{&쟌4ͺIO1%h)U.y?Q/o\SMb X4W+4гQeT}8+ y2 TN.~eVk_FB=L@' {AzA%2 K6ƜH7d{8~ʳJjPm@AyG!;r(㒿oGZgmԼc-j|UsWj|;R[M+u8:Do!H ~һq@~?tN F_k񱳱_7}x͐c/6TL@4/zdM QqCsNn3XB0IK 2Ash8_@$JP:-GxGnsl1*Ƣs֗cl>x Ĉ8m vphVnFeC3ZΠbQI㇐G6S@PcfeMbWûRN nSsG|Cͧ#;~Jf8Đ^xO,r󛃞k1qY $־yM#5?5E(c䒔CHnBe#uv+fs4y7I;# rE*:VCN<uբu4%CwfkGNS"O|Xy]Pcr3Up_*0.cQ+?zrg1K$%E&aeOxZ ;Qqux &夼P58N|SDLI4)nn|)g-ji}?e=n{rJ$1)KvnL򥦋ev /뼱sM6!H A[0d&َJyE>{*oxw PmP,I~ϑILD"ڋ7 &)jr5[ʪG$/Zgⵯ-cp}<_/ gX2*eӜf/\.DǯBv&ϭDOL+{9G#}ݥND-W0DT_2GQ#p4h7'`LbRTy<ǹP#5G:A +j='%)A(C1VmJ=(0uU/Cv*E:eJٻQWtF(-pd}_4/< ͭK tsFqj{ Z'@ ƾpZП=wA M-V*F/lEۋ9p*F"%5 @U&=>>|TƧ[),PC4A+qD/7OF[+#ЛIG$Pe#QPVFsnjhU@ )y1t:}AWPy(YA [Yc< '4.f`DIL sN0h_\#cdewhؾg***K=^2Ct~ꬑ%Գ͙@luU6۶!~dhqRDQ-mA53s+5ْޯT:c%4bk*=7=_6ʒtAJHrgmJ~HޢLuxo|GV*$J[&7uIx]d]14X/ǣ[*Y]x[MAKv#.a^ē?I6«sŲt T<9qrb ZK>̂\̔[!Bv?ٔ| o祕=Ǔ1]cq?˄|M/՝;KmZ}f'c3#HhsZ[88ygRǚkxvu[Ύ'mBzkbp-t<)'X9_XyP5oytHnKQU:ާN #ᮜ78Y6NL3.o#}ljI`bR ty@f(Ly=\;~:oԟ8zߴ ~f(2B."A~v+/Cz=?ok`PǤ{OGBgsZZ9CŋH-_s.3:c~!s:ʹC N-5ƀ^S{ Ctvɕ٩d/S'[És^St"x2n?v"7>lM~J+?MLQ9HŲq$Zɥz߼@:uW471OFH ZQK&AR'ߟi.XA[MĹB$":48AkE7X%_O{HMj)X5XV$P,8 1<|g楹=V3kS|=!aeq=\ݨaMh=urFdġ' gtnyAl[jOKL!LJ/]}\h>ٔxA,4"1d @N\V}Ab5Zm%Mm) lBiDyf8(RǑw}u.ɽrS=^kn]yREϜwX++| r,+Kᓃ/?-`No$x?wـ#zw0Ԥ%zIi;ZY;Sz~[O#ޞes9{F0Uk8k$5^J>n!jtv PI )'=ޙa,Qd'!B'F.Y> -?M+3#nxokP{^5g)gix~x%\F={| _oc[՟R|{pۉxS$L}V%/uk0]LΟn.mbC-OYw7& xʼćyRAO2uPY7(A˥(y@$9_ q4N̅(qۡ8t?7a1{LefA@|VXBB_4ΟAV 97C+;_@[_L&Km(w94Q# ȃ]V9ECK#0 I:w.\vW2Ssl5up&S3K^g-Qi1߼- go6Uc/Gz*͂_=W=9WQ.|pl_>䔜@!џz<3:{i%=EO28LsLJ7Z~}?=#^ ;Sd? r: @ŕcwA@A qV%9ղkY`r-IrE @|b% 3[tԓٳ=4r\/'hMcH`tc@SSb7t iܬYCf8#?nyW)ގӕa:s `;|b廯zm6 :'0.[m^{`8:tyg@"C0VR^7@+2iZݛkE6A7˜RlvzFW#1|7cg.i`߾ \^ KA /.EKS(ADl{HeIDATp:HsK/WD5yWMh"IӬC 97z6EN6'9%]H0úkYnKM_겷h"6utU[xhuLj糐+*vCL- `i twuɭNyiMC\z|z04_z&bll1v$>xpAݽ++cO+֑)~mͬM|D@}CO~[Ubar>ۆ b&9ѱt}ݙ·>K)k|U'J#\cS.][!\BX>_(r5g-Ýh\ݺJ6jCk|о3gcQe#1|i+!Cj|:~ܔVW0L勬b~itVNhG,I3jn|4Y+uX uUG,|/ĨEQ.ԑ-Je򬅠 1ŒG}VE/, vOMGGٹcl~SV# ԭ2λڊݓxju~Ppo?C/ptŇYh^(@~`OşqKE)1hE<OzxAc'I5j8偊-A'^$i)n#O][> 2=5jKq\d @ja0Tes\2+pn8h+.ڹ4=qԠpƔ j>0ŷeBq5MPtw1 h !O 2ȠE='CmrFp6>YP"â =vis(6+R[P C: 4 2Ƞ˔uȅ<@:wr`:T[ 2ȠK4>#5^ISɧyj.'6T/;VK^rI\?dUjQ-0b #_A5A\j\Z5hISu0^ߴ{Zp >l%B)iA~YUhP;׸WUT 114Hb"( 1[;UZi HT!)J;г' ghG;PڹBw^*6 . p|:$LFCk? ޼9xNlqIUb%$l/OǺmA { qnX=bp`KVk | 3O _e(yv?V}7o'JW> >̫fj|M}.ʁQa1}]V>y/<(r -5L[w+]48RiӽkY13.HK*dQsu?6x t)ERgTpfdfM @[&+@ML҇l͸򳋲AdA4?٭1(U (0M1>8mزdbQ2 UVQI;tQ<9Iy3>ͨ-$yJx(}.'?,>L*8 mjD^v.+s2]غ}IckQ8ywoh bp䪖P*LB]@CύK N(; TBv|@J)*|.KˬZg œ/+\ VYwo!Lm#cAd딦i7_0tA F{x>DēiAdA3R* P%9zQ/F Z47?h (2 ʌr?~Ԋ}HA(KBAqy @vb ?9ǡ-UJS\ WuC+ycʇ:] 4HN|d]7̋ Bc$;:d|lL A>ta?i|ZSJɞQ~L21YtUAt&E+. ppiA-U 2 #NO33Ƞ$^)YK 2 z}b3tf0 2(+Ӷ"}T z C]HZlZ!R}vZyR{LrB .CUa/$#ƒeE";.3@A?qi /KmT-Z.hDͼʇuY 2h>H;'-qv =Uli9W\ 2dAdAdAdAdAdAO?3R+(..!|B#j'28~yv^pg䫑. t҂،]0>N 粘הY2 8;)vqff&{ HCϒ?[#IENDB`sge030809/examples/sprite2.cpp0000644000175000001440000000431207715012702014732 0ustar samusers#include #include #include "SDL.h" #include "sge.h" #define NSPRITES 100 int main(int argc, char** argv) { /* Init SDL */ if ( SDL_Init(SDL_INIT_TIMER|SDL_INIT_VIDEO) < 0 ) { fprintf(stderr, "Couldn't load SDL: %s\n", SDL_GetError()); exit(1); } /* Clean up on exit */ atexit(SDL_Quit); /* Set window title */ SDL_WM_SetCaption("SGE testsprite", "testsprite"); /* Initialize the display */ SDL_Surface *screen; screen = SDL_SetVideoMode(640, 480, 0, SDL_SWSURFACE); if ( screen == NULL ) { fprintf(stderr, "Couldn't set video mode: %s\n", SDL_GetError()); exit(1); } /* Setup the screen class */ sge_screen screenc(screen); //Load the smiley SDL_Surface *temp,*bitmap; temp = SDL_LoadBMP("smiley.bmp"); if(!temp){ fprintf(stderr, "Error: %s\n", SDL_GetError()); exit(1); } bitmap = SDL_DisplayFormat(temp); SDL_FreeSurface(temp); SDL_SetColorKey(bitmap, SDL_SRCCOLORKEY|SDL_RLEACCEL, sge_GetPixel(bitmap,0,0)); sge_Randomize(); /* Setup the sprites */ sge_ssprite *sprite[NSPRITES]; int i; for(i=0; iget_xvel() && ! sprite[i]->get_yvel() ) { sprite[i]->set_xvel( sge_Random(-1,1) ); sprite[i]->set_yvel( sge_Random(-1,1) ); } //Random starting pos sprite[i]->move_to(sge_Random(0, screen->w-bitmap->w), sge_Random(0, screen->h-bitmap->h)); } sge_Update_OFF(); /* Main loop */ SDL_Event event; int quit=0; int loops=0; Uint32 start=SDL_GetTicks(); do{ for(i=0; iclear(0); //Remove sprite from screen sprite[i]->update(); //Move the sprite } //Let the screen class redraw and update rects for all sprites screenc.update(); loops++; /* Check events */ if(SDL_PollEvent(&event)==1){ if(event.type==SDL_KEYDOWN && event.key.keysym.sym==SDLK_ESCAPE){quit=1;} if(event.type==SDL_QUIT){quit=1;} } }while(!quit); //Show FPS printf("%.2f FPS.\n",((double)loops*1000)/(SDL_GetTicks()-start)); //Clean up for(i=0; i #include #include "SDL.h" #include "sge.h" void do_poly(SDL_Surface *dest) { Sint16 x[30]; Sint16 y[30]; Uint8 R,G,B; int points = sge_Random(3,30); //Number of points in polygon int i; // Generate random coords for( i=0; iw-1); y[i] = sge_Random(0, dest->h-1); } // Pick a color R = sge_Random(0, 255); G = sge_Random(0, 255); B = sge_Random(0, 255); if( R<40 && G<40 && B<40 ){ // Too dark R=G=B=255; } sge_AAFilledPolygon(dest, points, x, y, R,G,B); } int main(int argc, char** argv) { /* Init SDL */ if ( SDL_Init(SDL_INIT_TIMER|SDL_INIT_VIDEO) < 0 ) { fprintf(stderr, "Couldn't load SDL: %s\n", SDL_GetError()); exit(1); } /* Clean up on exit */ atexit(SDL_Quit); /* Set window title */ SDL_WM_SetCaption("Polygons (Press any key)", "poly"); /* Initialize the display */ SDL_Surface *screen; screen = SDL_SetVideoMode(640, 480, 0, SDL_SWSURFACE); if ( screen == NULL ) { fprintf(stderr, "Couldn't set video mode: %s\n", SDL_GetError()); exit(1); } /* First draw a very nice gourand shaded pentagram */ Sint16 x[]={111, 529, 190, 320, 450, 111, 320, 529, 450, 190}; Sint16 y[]={193, 193, 439, 41, 439, 193, 41, 193, 439, 439}; Uint8 R[]={ 95, 95, 255, 0, 255, 95, 0, 95, 255, 255}; Uint8 G[]={ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; Uint8 B[]={160, 160, 0, 255, 0, 160, 255, 160, 0, 0}; sge_AAFadedPolygon(screen, 10, x, y, R, G, B); sge_Randomize(); /* Main loop */ SDL_Event event; do{ /* Wait for user input */ SDL_WaitEvent(&event); if(event.type==SDL_KEYDOWN && event.key.keysym.sym==SDLK_ESCAPE){break;} else if(event.type==SDL_KEYDOWN){ sge_ClearSurface(screen, 0,0,0); do_poly(screen); } if(event.type==SDL_QUIT){break;} }while(true); return 0; } sge030809/examples/rotate.cpp0000644000175000001440000000612007415146777014660 0ustar samusers#include #include #include #include "SDL.h" #include "sge.h" int main(int argc, char** argv) { /* Init SDL */ if ( SDL_Init(SDL_INIT_TIMER|SDL_INIT_VIDEO) < 0 ) { fprintf(stderr, "Couldn't load SDL: %s\n", SDL_GetError()); exit(1); } /* Clean up on exit */ atexit(SDL_Quit); /* Set window title */ SDL_WM_SetCaption("Rotating Tux. Press [Space]/[s]!", "tux"); /* Initialize the display */ SDL_Surface *screen; screen = SDL_SetVideoMode(300, 300, 0, SDL_SWSURFACE); if ( screen == NULL ) { fprintf(stderr, "Couldn't set video mode: %s\n", SDL_GetError()); exit(1); } /* Load the texture */ SDL_Surface *temp,*texture; temp = SDL_LoadBMP("tux.bmp"); if ( temp == NULL ) { fprintf(stderr, "Error: %s\n", SDL_GetError()); exit(1); } texture = SDL_DisplayFormat(temp); //Convert it to the screen format for speed SDL_FreeSurface(temp); //SDL_Rect r; //r.x=40; r.y=40; r.w=40; r.h=40; //SDL_SetClipRect(texture, &r); Uint32 black = SDL_MapRGB(screen->format,0,0,0); sge_Update_OFF(); SDL_Event event; int loops=0; Uint32 start=SDL_GetTicks(); /* Starting values*/ int angle=1; Uint8 flag=SGE_TTMAP; float xscale=3.0,yscale=3.0,xstep=-0.02, ystep=-0.01; SDL_Rect new_rect, old_rect, tmp_rect; old_rect.x=0; old_rect.y=0; old_rect.w=screen->w; old_rect.h=screen->h; bool delay=false; /* Main loop */ do{ if(delay) SDL_Delay(20); sge_FilledRect(screen, old_rect.x, old_rect.y, old_rect.x + old_rect.w-1, old_rect.y + old_rect.h-1, black); new_rect = sge_transform(texture, screen, angle, xscale, yscale, texture->w/2,texture->h/2, 150,150, flag); sge_RectUnion(tmp_rect, old_rect, new_rect); sge_Update_ON(); sge_UpdateRect(screen,tmp_rect.x, tmp_rect.y, tmp_rect.w, tmp_rect.h); sge_Update_OFF(); old_rect = new_rect; /* Change degree and scale for next loop */ angle+=2; yscale+=ystep; xscale+=xstep; if(angle>=360) angle=1; if(yscale>3.5 || yscale<-3.5) ystep=-ystep; if(xscale>3.5 || xscale<0) xstep=-xstep; loops++; /* Check events */ if(SDL_PollEvent(&event)==1){ if(event.type==SDL_KEYDOWN && event.key.keysym.sym==SDLK_SPACE){ /* Change rendering method and report FPS for previous */ if(flag&SGE_TTMAP){ flag = 0; printf("Texture mapping: %.2f FPS.\n",((double)loops*1000)/(SDL_GetTicks()-start)); }else if(flag==0){ flag = SGE_TAA; printf("Normal rendering: %.2f FPS.\n",((double)loops*1000)/(SDL_GetTicks()-start)); }else{ flag=SGE_TTMAP; printf("AA rendering: %.2f FPS.\n",((double)loops*1000)/(SDL_GetTicks()-start)); } loops=0; start=SDL_GetTicks(); } if(event.type==SDL_KEYDOWN && event.key.keysym.sym==SDLK_s){ if(delay) delay=false; else delay=true; /* reset FPS */ loops=0; start=SDL_GetTicks(); } if(event.type==SDL_KEYDOWN && event.key.keysym.sym==SDLK_ESCAPE){break;} if(event.type==SDL_QUIT){break;} } }while(true); //Clean up SDL_FreeSurface(texture); //Show FPS printf("%.2f FPS.\n",((double)loops*1000)/(SDL_GetTicks()-start)); return 0; } sge030809/examples/blib.cpp0000644000175000001440000000474307374477760014306 0ustar samusers#include #include #include #include "SDL.h" #include "sge.h" int main(int argc, char** argv) { /* Init SDL */ if ( SDL_Init(SDL_INIT_TIMER|SDL_INIT_VIDEO) < 0 ) { fprintf(stderr, "Couldn't load SDL: %s\n", SDL_GetError()); exit(1); } /* Clean up on exit */ atexit(SDL_Quit); /* Set window title */ SDL_WM_SetCaption("Blib test", "blib"); /* Initialize the display */ SDL_Surface *screen; screen = SDL_SetVideoMode(700, 450, 16, SDL_SWSURFACE); if ( screen == NULL ) { fprintf(stderr, "Couldn't set video mode: %s\n", SDL_GetError()); exit(1); } /* Load the texture */ SDL_Surface *temp,*texture; temp = SDL_LoadBMP("tux.bmp"); if ( temp == NULL ) { fprintf(stderr, "Error: %s\n", SDL_GetError()); exit(1); } texture = SDL_DisplayFormat(temp); SDL_FreeSurface(temp); sge_Update_OFF(); sge_ClearSurface(screen,100,100,100); /* Draw some triangles*/ Uint32 colour; int i; for ( i = 0; i < 11; i++ ) { colour = SDL_MapRGB(screen->format,0,0,25 * i); sge_Trigon(screen, 30+60*i, 50, (Sint16)(30+60*i + 40*cos(3.14/180*i*36)), (Sint16)( 50-sin(3.14/180*i*36)*40), (Sint16)(30+60*i+sin(3.14/180*i*36)*40), (Sint16)( 50 + 40*cos(3.14/180*i*36)), colour); sge_FilledTrigon(screen, 30+60*i, 150, (Sint16)(30+60*i + 40*cos(3.14/180*i*36)), (Sint16)(150-sin(3.14/180*i*36)*40), (Sint16)(30+60*i+sin(3.14/180*i*36)*40), (Sint16)(150 + 40*cos(3.14/180*i*36)), colour); sge_FadedTrigon(screen, 30+60*i, 250, (Sint16)(30+60*i + 40*cos(3.14/180*i*36)), (Sint16)(250-sin(3.14/180*i*36)*40), (Sint16)(30+60*i+sin(3.14/180*i*36)*40), (Sint16)(250 + 40*cos(3.14/180*i*36)), SDL_MapRGB(screen->format,255,0,0),SDL_MapRGB(screen->format,0,255,0),SDL_MapRGB(screen->format,0,0,255)); sge_TexturedTrigon(screen,30+60*i, 350, (Sint16)(30+60*i + 40*cos(3.14/180*i*36)), (Sint16)(350-sin(3.14/180*i*36)*40), (Sint16)(30+60*i+sin(3.14/180*i*36)*40), (Sint16)(350 + 40*cos(3.14/180*i*36)), texture,0,0,0,texture->h-1,texture->w-1,0); } /* And some lines */ for ( i = 0; i < 10; i++) sge_FadedLine(screen,300,400,400+i,255,0,255,0,255,127); for ( i = 0; i < 10; i++) sge_TexturedLine(screen,100,200,400+i,texture,0,i,texture->w-1,texture->h/2+i); SDL_UpdateRect(screen,0,0,0,0); /* Main loop */ SDL_Event event; do{ /* Check events */ SDL_WaitEvent(&event); if(event.type==SDL_KEYDOWN && event.key.keysym.sym==SDLK_ESCAPE){break;} if(event.type==SDL_QUIT){break;} }while(true); //Clean up SDL_FreeSurface(texture); return 0; } sge030809/examples/fire.cpp0000644000175000001440000000661707374477731014323 0ustar samusers#include #include #include #include "SDL.h" #include "sge.h" #define NCOLORS 1200 #define XRES 300 #define YRES 100 void setup_palette(SDL_Surface *Surface, Uint32 *ctab, int start,int stop); void fade(SDL_Surface *surface, int speed); /* Globals */ int cb[YRES][XRES]; //The color buffer Uint32 ctab[NCOLORS]; //The color table int main(int argc, char** argv) { /* Init SDL */ if ( SDL_Init(SDL_INIT_TIMER|SDL_INIT_VIDEO) < 0 ) { fprintf(stderr, "Couldn't load SDL: %s\n", SDL_GetError()); exit(1); } /* Clean up on exit */ atexit(SDL_Quit); /* Set window title */ SDL_WM_SetCaption("Fire!", "fire"); /* Initialize the display */ SDL_Surface *screen; screen = SDL_SetVideoMode(XRES, YRES, 16, SDL_SWSURFACE); if ( screen == NULL ) { fprintf(stderr, "Couldn't set video mode: %s\n", SDL_GetError()); exit(1); } /* Clear the color buffer */ for(int y=0; y60) // Lower the flame speed=1; } fade(screen,speed); // Do the fading /* Update screen */ SDL_UpdateRect(screen,0,0,0,0); loops++; /* Check events */ if(SDL_PollEvent(&event)==1){ if(event.type==SDL_KEYDOWN && event.key.keysym.sym==SDLK_ESCAPE){break;} if(event.type==SDL_QUIT){break;} } }while(true); //Show FPS printf("%.2f FPS.\n",((double)loops*1000)/(SDL_GetTicks()-start)); return 0; } //==================================================================== // This function creates a "flame" palette (using sge_Fader) //==================================================================== void setup_palette(SDL_Surface *Surface, Uint32 *ctab, int start, int stop) { int slice=(int)((stop-start)/5); sge_Fader(Surface, 0,0,0, 0,0,40, ctab, start,slice); /* black - dark blue */ sge_Fader(Surface, 0,0,40, 255,0,0, ctab, slice+1,2*slice); /* - red */ sge_Fader(Surface, 255,0,0, 255,255,0, ctab, 2*slice+1, 3*slice); /* -yellow */ sge_Fader(Surface, 255,255,0, 255,255,255, ctab, 3*slice+1,stop); /* -white */ } //==================================================================== // Do the fading magic //==================================================================== void fade(SDL_Surface *surface, int speed) { int color,x,y; Uint16 block[XRES]; if(SDL_MUSTLOCK(surface)) SDL_LockSurface(surface); for(y=0; y0){ color+=cb[y][x-1]; //pixel to the left } if(x>2)-speed; //average (well, often) and fade if(color>NCOLORS-1) color=NCOLORS-1; if(color<0) color=0; block[x]=(Uint16)ctab[color]; cb[y][x]=color; } sge_write_block16(surface, block, y); //Copy the new block to screen } if(SDL_MUSTLOCK(surface)) SDL_UnlockSurface(surface); } sge030809/examples/input.cpp0000644000175000001440000000407207714716077014523 0ustar samusers#include #include #include #include "SDL.h" #include "sge.h" int main(int argc, char** argv) { /* Init SDL */ if ( SDL_Init(SDL_INIT_TIMER|SDL_INIT_VIDEO) < 0 ) { fprintf(stderr, "Couldn't load SDL: %s\n", SDL_GetError()); exit(1); } /* Clean up on exit */ atexit(SDL_Quit); /* Set window title */ SDL_WM_SetCaption("Input", "input"); /* Initialize the display */ SDL_Surface *screen; screen = SDL_SetVideoMode(640, 200, 16, SDL_SWSURFACE); if ( screen == NULL ) { fprintf(stderr, "Couldn't set video mode: %s\n", SDL_GetError()); exit(1); } /* Init TTF */ if(sge_TTF_Init()!=0){fprintf(stderr,"TT error: %s\n", SDL_GetError());exit(1);} sge_TTFont *font; font=sge_TTF_OpenFont("font.ttf", 25); if(font==NULL){fprintf(stderr,"TT error: %s\n", SDL_GetError());exit(1);} //sge_TTF_SetFontStyle(font, SGE_TTF_ITALIC); /* Make a nice background */ int max = int(1.5*sge_TTF_FontHeight(font)+5); Uint32 *col=new Uint32[max]; sge_Fader(screen, 100,255,100, 0,0,0, col,0, (int)(1.5*sge_TTF_FontHeight(font)+4)); sge_HLine(screen,0, 640, 100-sge_TTF_FontHeight(font), 255,0,0); sge_HLine(screen,0, 640, 100+(int)(sge_TTF_FontHeight(font)/2), 255,0,0); int i=0; for(int y=101-sge_TTF_FontHeight(font); y<100+(int)(sge_TTF_FontHeight(font)/2); y++){ if(i #include #include "SDL.h" #include "sge.h" //Main int main(int argc, char** argv) { /* Init SDL */ if ( SDL_Init(SDL_INIT_TIMER|SDL_INIT_VIDEO) < 0 ) { fprintf(stderr, "Couldn't load SDL: %s\n", SDL_GetError()); exit(1); } /* Clean up on exit */ atexit(SDL_Quit); /* Set window title */ SDL_WM_SetCaption("Alpha magic", "alpha"); /* Initialize the display */ SDL_Surface *screen; screen = SDL_SetVideoMode(600, 300, 16, SDL_SWSURFACE); if ( screen == NULL ) { fprintf(stderr, "Couldn't set video mode: %s\n", SDL_GetError()); exit(1); } sge_FilledRect(screen,0,0, screen->w,screen->h/2, 255,255,255); /* Open TT font file */ if(sge_TTF_Init()!=0){fprintf(stderr,"TT error: %s\n",SDL_GetError());exit(1);} sge_TTFont *font; font=sge_TTF_OpenFont("font.ttf", 55); if(font==NULL){fprintf(stderr,"TT error: %s\n",SDL_GetError());exit(1);} /* Ugly font rendering */ sge_TTF_AAOff(); sge_tt_textout(screen,font,"Linux", 10,167, 0,0,255, 255,255,255, SDL_ALPHA_OPAQUE); /* AA rendering */ sge_TTF_AAOn(); sge_tt_textout(screen,font,"Linux", 210,167, 0,0,255, 255,255,255, SDL_ALPHA_OPAQUE); /* AA with alpha rendering */ sge_TTF_AA_Alpha(); sge_tt_textout(screen,font,"Linux", 410,167, 0,0,255, 1,2,3, SDL_ALPHA_OPAQUE); sge_TTF_SetFontSize(font, 25); sge_tt_textout(screen,font,"Normal", 50,200, 0,255,0, 0,0,0, SDL_ALPHA_OPAQUE); sge_tt_textout(screen,font,"Anti aliasing", 210,200, 0,255,0, 0,0,0, SDL_ALPHA_OPAQUE); sge_tt_textout(screen,font,"Alpha", 460,200, 0,255,0, 0,0,0, SDL_ALPHA_OPAQUE); sge_TTF_CloseFont(font); /* Some alpha component magic */ SDL_Surface *img=sge_CreateAlphaSurface(SDL_SWSURFACE, 100, 100); //Alocate buffer Uint32 ctab[101]; sge_AlphaFader(255,0,255,0, 0,0,255,230, ctab,0,100); //Make a nice alpha blended pallete /* Paint the buffer */ for(int yy=0; yy<=100; yy++) sge_HLine(img,0,100,yy,ctab[yy]); SDL_UpdateRect(screen,0,0,0,0); /* The buffer for the background */ SDL_Surface *buffer; buffer=SDL_DisplayFormat(screen); // If the delay between two PollEvent is greater than 100 and all events are added to the // event queue, the queue will grow *fast*. You're program will have no change to catch // up. You *must* try to avoid adding events unnecessarily - mousemotions for example. SDL_EventState(SDL_MOUSEMOTION,SDL_IGNORE); Sint32 x=50,y=190; Sint32 oldx = 50, oldy = 190; bool right=true, down=false; sge_Update_OFF(); // Sets start time Uint32 tstart=SDL_GetTicks(); int loops=0; // Main loop SDL_Event event; do{ SDL_Delay(10); //Check borders if( (x+img->w) >= screen->w ) right = false; else if( x <= 0 ) right = true; if( (y+img->h) >= screen->h ) down = false; else if( y <= 0) down = true; //Update pos if(right) x++; else x--; if(down) y++; else y--; //Update last pos from buffer sge_Blit(buffer,screen,oldx, oldy, oldx,oldy, img->w,img->h); //Draw the alpha surface sge_Blit(img,screen,0,0, x,y, img->w,img->h); //Update screen sge_Update_ON(); sge_UpdateRect(screen, x-1, y-1, img->w+2, img->h+2); sge_Update_OFF(); oldx=x; oldy=y; loops++; // Check events if(SDL_PollEvent(&event)==1){ if(event.type==SDL_KEYDOWN && event.key.keysym.sym==SDLK_ESCAPE){break;} if(event.type==SDL_QUIT){break;} } }while(true); /* Print FPS */ printf("%.2f FPS (target: 100).\n",((double)loops*1000)/(SDL_GetTicks()-tstart)); /* Clean up */ SDL_FreeSurface(img); SDL_FreeSurface(buffer); return 0; } sge030809/examples/tux.bmp0000644000175000001440000003006607301070044014155 0ustar samusersBM606(@@0 A()սͽŽ ͽͽRPR ŽͽͽͽŽͬŽŴ Ŭsy999s洲ʹ101ͬŤsaiaaiaai}sͽŽiiaqyyyqiiqsŽRPRŽqaiyy9ŽŽA@AA@A989ŽaqiyYqiqy9A()$ uaY8Rayyu@b0J8J8Zisʹ)()1aa0Ji99 Hj(Aiy 0AY(A)999   9Hsy jab0J8Z DRuibYZPsi 9   1$)y 99  (9yy 999 (9}y 9999 YsLb(9y} 99    9Hj  99  9y  9 999 9 9 uyy1 Ys1PjZYZHjuu Ys)()ei(9ZYZ{qssqs989{y{sqs A@AZYZ101A@AA@AJHJsqs jijRPR)()sqsjabjijJHJJHJ RPRjijJHJ101洪101JHJ޽jijʹŤ sqs{y{)()ŬjabZabjijZYZ {qs{qs{y{)()ZYZ)() A() sqsbab A()A() )())() A@AJHJA@A101  A@AjijjijZYZA@A989)() A@AsqssqsZYZA@A989)()A()jijjijAHJ)()989bab{y{jabRPR101101RPRZYZRPR989 A()101  sge030809/examples/blitting.cpp0000644000175000001440000000546007414657671015203 0ustar samusers#include #include #include "SDL.h" #include "sge.h" int main(int argc, char** argv) { /* Init SDL */ if ( SDL_Init(SDL_INIT_TIMER|SDL_INIT_VIDEO) < 0 ) { fprintf(stderr, "Couldn't load SDL: %s\n", SDL_GetError()); exit(1); } /* Clean up on exit */ atexit(SDL_Quit); /* Set window title */ SDL_WM_SetCaption("Bouncing ball!", "bounce"); /* Initialize the display */ SDL_Surface *screen; screen = SDL_SetVideoMode(640, 480, 16, SDL_SWSURFACE); if ( screen == NULL ) { fprintf(stderr, "Couldn't set video mode: %s\n", SDL_GetError()); exit(1); } /* Open TT font file */ if(sge_TTF_Init()!=0){fprintf(stderr,"TT error: %s\n", SDL_GetError());exit(1);} sge_TTFont *font; font=sge_TTF_OpenFont("font.ttf", 50); if(font==NULL){fprintf(stderr,"TT error: %s\n", SDL_GetError());exit(1);} /* Make a nice background */ sge_tt_textout(screen,font,"Super Fun", 160,180, 0,255,0, 0,0,0, SDL_ALPHA_OPAQUE); sge_tt_textout(screen,font,"Bouncing Ball!!", 100,260, 0,255,0,0,0,0, SDL_ALPHA_OPAQUE); sge_TTF_CloseFont(font); /* Allocate buffers */ SDL_Surface *buffer,*circle; circle=SDL_AllocSurface(SDL_SWSURFACE,100,100,16, 0,0,0,0); buffer=SDL_AllocSurface(SDL_SWSURFACE,640,480,16, 0,0,0,0); /* Draws a filled circle on the circle buffer */ sge_ClearSurface(circle,0); sge_AAFilledCircle(circle,50,50,49, 255,0,0); /* Set the transparity on the circle */ SDL_SetColorKey(circle, SDL_SRCCOLORKEY, 0); //Set the transparent color SDL_SetAlpha(circle, SDL_SRCALPHA|SDL_RLEACCEL, 128); //Set the alpha blending value /* Turns off automatic update */ sge_Update_OFF(); /* Buffers the background */ sge_Blit(screen,buffer,0,0, 0,0 ,640,480); Sint32 x=250,y=200,oldx=250,oldy=200; bool left=false, down=false; int loops=0; /* Sets start time */ Uint32 start = SDL_GetTicks(); /* Main loop */ SDL_Event event; do{ SDL_Delay(10); /* Bounce at screen borders */ if(x>540) left = true; else if(x<0) left = false; if(y>380) down = false; else if(y<0) down = true; /* Updates coords */ if(left) x-=2; else x+=2; if(down) y+=2; else y-=2; /* Updates the last area */ sge_Blit(buffer,screen,oldx-5,oldy-5, oldx-5,oldy-5, 120,120); oldx=x;oldy=y; /* Draws the circel */ sge_Blit(circle,screen,0,0, x,y, 100,100); /* Updates the screen */ sge_Update_ON(); sge_UpdateRect(screen,x-5,y-5,120,120); sge_Update_OFF(); /* Calculate fps */ loops++; /* Check events */ if(SDL_PollEvent(&event)==1){ if(event.type==SDL_KEYDOWN && event.key.keysym.sym==SDLK_ESCAPE){break;} if(event.type==SDL_QUIT){break;} } }while(true); /* Print FPS */ printf("%.2f FPS (target: 100).\n",((double)loops*1000)/(SDL_GetTicks()-start)); /* Clean up */ SDL_FreeSurface(buffer); SDL_FreeSurface(circle); return 0; } sge030809/examples/basics.cpp0000644000175000001440000000351107530741725014617 0ustar samusers#include #include #include "SDL.h" #include "sge.h" int main(int argc, char** argv) { /* Init SDL */ if ( SDL_Init(SDL_INIT_TIMER|SDL_INIT_VIDEO) < 0 ) { fprintf(stderr, "Couldn't load SDL: %s\n", SDL_GetError()); exit(1); } /* Clean up on exit */ atexit(SDL_Quit); /* Set window title */ SDL_WM_SetCaption("SGE Basics", "basics"); /* Initialize the display */ SDL_Surface *screen; screen = SDL_SetVideoMode(640, 480, 16, SDL_SWSURFACE); if ( screen == NULL ) { fprintf(stderr, "Couldn't set video mode: %s\n", SDL_GetError()); exit(1); } /* Draws some primitives on screen */ sge_HLine(screen,0,640,100,255,0,0); sge_VLine(screen,100,0,480,255,255,0); sge_Line(screen,0,0,640,480,0,0,255); sge_Rect(screen,150,150,250,250,255,255,255); sge_Rect(screen,260,260,360,360,255,255,255); sge_FilledRect(screen,260,150,360,250,255,0,255); sge_AACircle(screen,200,200,150,0,255,0); sge_AAFilledCircle(screen,500,150,50,255,255,0); sge_AAFilledEllipse(screen,500,280, 80,50, 100,150,200); /* Open TT font file */ if(sge_TTF_Init()!=0){fprintf(stderr,"TT error: %s\n",SDL_GetError());exit(1);} sge_TTFont *font; font=sge_TTF_OpenFont("font.ttf", 50); if(font==NULL){fprintf(stderr,"TT error: %s\n",SDL_GetError());exit(1);} /* Draws TT text on screen */ sge_tt_textout(screen,font,"SGE", 30,100, 0,0,255, 0,0,0, 120); /* Change font style and size */ sge_TTF_SetFontSize(font, 30); sge_TTF_SetFontStyle(font, SGE_TTF_ITALIC|SGE_TTF_UNDERLINE); sge_tt_textout(screen,font,"Hello World!", 400,470, 155,200,100, 0,0,0, SDL_ALPHA_OPAQUE); sge_TTF_CloseFont(font); /* Main loop */ SDL_Event event; do{ /* Wait for user input */ SDL_WaitEvent(&event); if(event.type==SDL_KEYDOWN && event.key.keysym.sym==SDLK_ESCAPE){break;} if(event.type==SDL_QUIT){break;} }while(true); return 0; } sge030809/examples/basics_c.c0000644000175000001440000000425407415067054014564 0ustar samusers#include #include #include "SDL.h" #include "sge.h" int main(int argc, char** argv) { SDL_Surface *screen; SDL_Event event; sge_TTFont *font; /* Init SDL */ if ( SDL_Init(SDL_INIT_TIMER|SDL_INIT_VIDEO) < 0 ) { fprintf(stderr, "Couldn't load SDL: %s\n", SDL_GetError()); exit(1); } /* Clean up on exit */ atexit(SDL_Quit); /* Set window title */ SDL_WM_SetCaption("SGE Basics", "basics"); /* Initialize the display */ screen = SDL_SetVideoMode(640, 480, 16, SDL_SWSURFACE); if ( screen == NULL ) { fprintf(stderr, "Couldn't set video mode: %s\n", SDL_GetError()); exit(1); } /* Draws some primitives on screen */ sge_HLine(screen,0,640,100, SDL_MapRGB(screen->format,255,0,0)); sge_VLine(screen,100,0,480, SDL_MapRGB(screen->format,255,255,0)); sge_Line(screen,0,0,640,480, SDL_MapRGB(screen->format,0,0,255)); sge_Rect(screen,150,150,250,250, SDL_MapRGB(screen->format,255,255,255)); sge_Rect(screen,260,260,360,360, SDL_MapRGB(screen->format,255,255,255)); sge_FilledRect(screen,260,150,360,250, SDL_MapRGB(screen->format,255,0,255)); sge_AACircle(screen,200,200,150, SDL_MapRGB(screen->format,0,255,0)); sge_AAFilledCircle(screen,500,150,50, SDL_MapRGB(screen->format,255,255,0)); sge_AAFilledEllipse(screen,500,280, 80,50, SDL_MapRGB(screen->format, 100,150,200)); /* Draws TT text on screen */ if(sge_TTF_Init()!=0){fprintf(stderr,"TT error: %s\n",SDL_GetError());exit(1);} font=sge_TTF_OpenFont("font.ttf", 50); if(font==NULL){fprintf(stderr,"TT error: %s\n",SDL_GetError());exit(1);} /* Draws TT text on screen */ sge_tt_textout(screen,font,"SGE", 30,100, SDL_MapRGB(screen->format,0,0,255), SDL_MapRGB(screen->format,0,0,0), 120); /* Change font style and size */ sge_TTF_SetFontSize(font, 30); sge_TTF_SetFontStyle(font, SGE_TTF_ITALIC|SGE_TTF_UNDERLINE); sge_tt_textout(screen,font,"Hello World!",400,470, SDL_MapRGB(screen->format,155,200,100), SDL_MapRGB(screen->format,0,0,0), 255); sge_TTF_CloseFont(font); /* Main loop */ do{ /* Wait for user input */ SDL_WaitEvent(&event); if(event.type==SDL_KEYDOWN && event.key.keysym.sym==SDLK_ESCAPE){break;} if(event.type==SDL_QUIT){break;} }while(1); return 0; } sge030809/examples/speedtest.cpp0000644000175000001440000003533207714763461015366 0ustar samusers#include #include #include #include #include "SDL.h" #include "sge.h" #define NUM_RANDOM 1000 using namespace std; /* Bitmap fonts */ sge_bmpFont *font; sge_bmpFont *cfont; /* The texture */ SDL_Surface *texture; /* Coordinates */ Sint16 xl1[NUM_RANDOM], xl2[NUM_RANDOM], y1[NUM_RANDOM], y2[NUM_RANDOM]; Sint16 xl3[NUM_RANDOM], xl4[NUM_RANDOM], y3[NUM_RANDOM], y4[NUM_RANDOM]; Sint16 xr1[NUM_RANDOM], xr2[NUM_RANDOM]; //xl - left, xr -right coord Sint16 xr3[NUM_RANDOM], xr4[NUM_RANDOM]; /* Radii and offsets */ Sint16 r1[NUM_RANDOM], r2[NUM_RANDOM]; /* Colors and alpha */ Uint32 col1[NUM_RANDOM], col2[NUM_RANDOM], col3[NUM_RANDOM]; Uint8 r[NUM_RANDOM], g[NUM_RANDOM], b[NUM_RANDOM]; Uint8 a[NUM_RANDOM]; /* Clear and redraw left */ void init_screen_left(SDL_Surface *screen) { SDL_Rect r; r.x=0; r.y=0; r.w=screen->w; r.h=screen->h; SDL_SetClipRect(screen, &r); sge_ClearSurface(screen,SDL_MapRGB(screen->format,0,0,0)); sge_BF_textoutf(screen, font, 5, 2, "%s","SGE drawing primitives performance test - LMB for next test, RMB for previous."); sge_HLine(screen,0, screen->w, 16, 255,255,255); sge_HLine(screen,0, screen->w, 35, 255,255,255); sge_VLine(screen, screen->w/2, 16,screen->h, 255,255,255); if (SDL_MUSTLOCK(screen)) if (SDL_LockSurface(screen) < 0) return; /* Draw the colored area */ Sint16 x,y; float stepx, stepy, fx, fy, fxy; stepx=1.0/(screen->w/2-screen->w/8); stepy=1.0/(screen->h-36 - (screen->h-36)/4); fx=0.0; for (x=0; xw/2; x++) { fy=0.0; for (y=36; yw; y++) { fxy=1.0-fx*fy; _PutPixel(screen,x,y,(int)(128.0*fx*fx),(int)(128.0*fxy*fxy),(int)(128.0*fy*fy)); fy += stepy; } fx += stepx; } if (SDL_MUSTLOCK(screen)) { SDL_UnlockSurface(screen); } SDL_UpdateRect(screen,0,0,0,0); r.x=0; r.y=37; r.w=screen->w/2; r.h=screen->h-37; SDL_SetClipRect(screen, &r); } /* Clear and redraw right */ void init_screen_right(SDL_Surface *screen) { SDL_Rect r; r.x=0; r.y=0; r.w=screen->w; r.h=screen->h; SDL_SetClipRect(screen, &r); if (SDL_MUSTLOCK(screen)) if (SDL_LockSurface(screen) < 0) return; /* Draw the colored area */ Sint16 x,y; float stepx, stepy, fx, fy, fxy; stepx=1.0/(screen->w/2-screen->w/8); stepy=1.0/(screen->h-36 - (screen->h-36)/4); fx=0.0; for (x=screen->w/2+1; xw; x++) { fy=0.0; for (y=36; yw; y++) { fxy=1.0-fx*fy; _PutPixel(screen,x,y,(int)(128.0*fx*fx),(int)(128.0*fxy*fxy),(int)(128.0*fy*fy)); fy += stepy; } fx += stepx; } if (SDL_MUSTLOCK(screen)) { SDL_UnlockSurface(screen); } SDL_UpdateRect(screen,0,0,0,0); r.x=screen->w/2+1; r.y=37; r.w=screen->w/2; r.h=screen->h-37; SDL_SetClipRect(screen, &r); } /* Macro to test 'function' in the left part of the screen */ #define RUN_TEST_LEFT(screen,title,testloops,showloops,lock,function)\ {\ SDL_Rect rect;\ rect.x=0; rect.y=37; rect.w=screen->w/2; rect.h=screen->h-37;\ SDL_SetClipRect(screen, &rect);\ \ if (SDL_MUSTLOCK(screen) && lock){\ sge_Lock_OFF();\ if (SDL_LockSurface(screen) < 0)\ exit(-1);\ }else\ sge_Lock_ON();\ \ int i=0;\ Uint32 start = SDL_GetTicks();\ for (int j=0; jw; rect.h=screen->h;\ SDL_SetClipRect(screen, &rect);\ sge_BF_textoutf(screen, font, 5, 20, "%s - %.0f/s.",title,((double)testloops*1000)/(stop-start));\ printf("%s - %.0f/s.\n",title,((double)testloops*1000)/(stop-start));\ SDL_UpdateRect(screen,0,0,0,0);\ } /* Macro to test 'function' in the right part of the screen */ #define RUN_TEST_RIGHT(screen,title,testloops,showloops,lock,function)\ {\ SDL_Rect rect;\ rect.x=screen->w/2+1; rect.y=37; rect.w=screen->w/2; rect.h=screen->h-37;\ SDL_SetClipRect(screen, &rect);\ \ if (SDL_MUSTLOCK(screen) && lock){\ sge_Lock_OFF();\ if (SDL_LockSurface(screen) < 0)\ exit(-1);\ }else\ sge_Lock_ON();\ \ int i=0;\ Uint32 start = SDL_GetTicks();\ for (int j=0; jw; rect.h=screen->h;\ SDL_SetClipRect(screen, &rect);\ sge_BF_textoutf(screen, font, screen->w/2+6, 20, "%s - %.0f/s.",title,((double)testloops*1000)/(stop-start));\ printf("%s - %.0f/s.\n",title,((double)testloops*1000)/(stop-start));\ SDL_UpdateRect(screen,0,0,0,0);\ } /* Setup random data */ void rand_data(SDL_Surface *screen) { Uint8 R,G,B; for (int i=0; iw/2-1); xl2[i]=sge_Random(0,screen->w/2-1); xl3[i]=sge_Random(0,screen->w/2-1); xl4[i]=sge_Random(0,screen->w/2-1); y1[i]=sge_Random(37,screen->h); y2[i]=sge_Random(37,screen->h); y3[i]=sge_Random(37,screen->h); y4[i]=sge_Random(37,screen->h); xr1[i]=screen->w/2 + 1 + xl1[i]; xr2[i]=screen->w/2 + 1 + xl2[i]; xr3[i]=screen->w/2 + 1 + xl3[i]; xr4[i]=screen->w/2 + 1 + xl4[i]; r1[i]=sge_Random(5,60); r2[i]=sge_Random(5,60); R=sge_Random(0,255); G=sge_Random(0,255); B=sge_Random(0,255); col1[i]=SDL_MapRGB(screen->format,R,G,B); R=sge_Random(0,255); G=sge_Random(0,255); B=sge_Random(0,255); col2[i]=SDL_MapRGB(screen->format,R,G,B); R=sge_Random(0,255); G=sge_Random(0,255); B=sge_Random(0,255); col3[i]=SDL_MapRGB(screen->format,R,G,B); r[i]=R; g[i]=G; b[i]=B; a[i]=sge_Random(40,240); } } int main(int argc, char** argv) { /* Init SDL */ if ( SDL_Init(SDL_INIT_TIMER|SDL_INIT_VIDEO) < 0 ) { fprintf(stderr, "Couldn't load SDL: %s\n", SDL_GetError()); exit(1); } /* Clean up on exit */ atexit(SDL_Quit); /* Set window title */ SDL_WM_SetCaption("SpeedTest", "speedtest"); /* Handle arguments */ int video_bpp = 0; Uint32 videoflags = SDL_SWSURFACE; while ( argc > 1 ) { --argc; if ( string(argv[argc-1]) == "-bpp" ) { video_bpp = atoi(argv[argc]); --argc; } else if ( string(argv[argc]) == "-hw" ) videoflags |= SDL_HWSURFACE; else if ( string(argv[argc]) == "-fullscreen" ) videoflags |= SDL_FULLSCREEN; else { fprintf(stderr,"Usage: %s [-bpp N] [-hw] [-fullscreen]\n",argv[0]); exit(1); } } /* Initialize the display */ SDL_Surface *screen; screen = SDL_SetVideoMode(640, 480, video_bpp, videoflags); if ( screen == NULL ) { fprintf(stderr, "Couldn't set video mode: %s\n", SDL_GetError()); exit(1); } /* Open bitmap fonts, optimized for blits or color change */ font=sge_BF_OpenFont("font.bmp",SGE_BFTRANSP); if(font==NULL){fprintf(stderr,"Error: %s\n", SDL_GetError());exit(1);} cfont=sge_BF_OpenFont("font.bmp",SGE_BFTRANSP|SGE_BFPALETTE); if(cfont==NULL){fprintf(stderr,"Error: %s\n", SDL_GetError());exit(1);} /* Load the texture */ SDL_Surface *temp; temp = SDL_LoadBMP("tux.bmp"); if ( temp == NULL ) { fprintf(stderr, "Error: %s\n", SDL_GetError()); exit(1); } texture = SDL_DisplayFormat(temp); SDL_FreeSurface(temp); sge_Update_OFF(); sge_Lock_OFF(); sge_Randomize(); rand_data(screen); SDL_Delay(100); /* Time for the system to calm down */ /* Main loop */ SDL_Event event; int op = 1; int next_op = 1; do{ switch ( op ) { case 1: RUN_TEST_LEFT(screen,"Pixels",500000,1000,true,_PutPixel(screen,xl1[i],y1[i],col1[i])); RUN_TEST_RIGHT(screen,"Pixels (alpha)",300000,1000,true,_PutPixelAlpha(screen,xr1[i],y1[i],col1[i],a[i])); op = 0; break; case 2: RUN_TEST_LEFT(screen,"Horizontal lines",150000,200,false,sge_HLine(screen,xl1[i],xl2[i],y1[i],col1[i])); RUN_TEST_RIGHT(screen,"Horizontal lines (alpha)",15000,200,true,sge_HLineAlpha(screen,xr1[i],xr2[i],y1[i],col1[i],a[i])); op = 0; break; case 3: RUN_TEST_LEFT(screen,"Vertical lines",7000,200,false,sge_VLine(screen,xl1[i],y1[i],y2[i],col1[i])); RUN_TEST_RIGHT(screen,"Vertical lines (alpha)",6000,200,true,sge_VLineAlpha(screen,xr1[i],y1[i],y2[i],col1[i],a[i])); op = 0; break; case 4: RUN_TEST_LEFT(screen,"Normal lines",7000,200,true,sge_Line(screen,xl1[i],y1[i],xl2[i],y2[i],col1[i])); RUN_TEST_RIGHT(screen,"Normal lines (alpha)",4000,200,true,sge_LineAlpha(screen,xr1[i],y1[i],xr2[i],y2[i],col1[i],a[i])); op = 0; break; case 5: RUN_TEST_LEFT(screen,"Anti-aliased lines",1000,200,true,sge_AALine(screen,xl1[i],y1[i],xl2[i],y2[i],col1[i])); RUN_TEST_RIGHT(screen,"Anti-aliased lines (alpha)",1000,200,true,sge_AALineAlpha(screen,xr1[i],y1[i],xr2[i],y2[i],col1[i],a[i])); op = 0; break; case 6: RUN_TEST_LEFT(screen,"Rectangles",6000,100,false,sge_Rect(screen,xl1[i],y1[i],xl2[i],y2[i],col1[i])); RUN_TEST_RIGHT(screen,"Rectangles (alpha)",2000,100,true,sge_RectAlpha(screen,xr1[i],y1[i],xr2[i],y2[i],col1[i],a[i])); op = 0; break; case 7: RUN_TEST_LEFT(screen,"Filled rectangles",2000,100,false,sge_FilledRect(screen,xl1[i],y1[i],xl2[i],y2[i],col1[i])); RUN_TEST_RIGHT(screen,"Filled rectangles (alpha)",100,100,true,sge_FilledRectAlpha(screen,xr1[i],y1[i],xr2[i],y2[i],col1[i],a[i])); op = 0; break; case 8: RUN_TEST_LEFT(screen,"Circles",7000,100,true,sge_Circle(screen,xl1[i],y1[i],r1[i],col1[i])); RUN_TEST_RIGHT(screen,"Circles (alpha)",4000,100,true,sge_CircleAlpha(screen,xr1[i],y1[i],r1[i],col1[i],a[i])); op = 0; break; case 9: RUN_TEST_LEFT(screen,"AA circles",3000,100,true,sge_AACircle(screen,xl1[i],y1[i],r1[i],col1[i])); RUN_TEST_RIGHT(screen,"AA circles (alpha)",1000,100,true,sge_AACircleAlpha(screen,xr1[i],y1[i],r1[i],col1[i],a[i])); op = 0; break; case 10: RUN_TEST_LEFT(screen,"Filled circles",1000,100,false,sge_FilledCircle(screen,xl1[i],y1[i],r1[i],col1[i])); RUN_TEST_RIGHT(screen,"Filled circles (alpha)",500,100,true,sge_FilledCircleAlpha(screen,xr1[i],y1[i],r1[i],col1[i],a[i])); op = 0; break; case 11: RUN_TEST_LEFT(screen,"Ellipses",4000,100,true,sge_Ellipse(screen,xl1[i],y1[i],r1[i],r2[i],col1[i])); RUN_TEST_RIGHT(screen,"Ellipses (alpha)",3000,100,true,sge_EllipseAlpha(screen,xr1[i],y1[i],r1[i],r2[i],col1[i],a[i])); op = 0; break; case 12: RUN_TEST_LEFT(screen,"AA ellipses",1000,100,true,sge_AAEllipse(screen,xl1[i],y1[i],r1[i],r2[i],col1[i])); RUN_TEST_RIGHT(screen,"AA ellipses (alpha)",1000,100,true,sge_AAEllipseAlpha(screen,xr1[i],y1[i],r1[i],r2[i],col1[i],a[i])); op = 0; break; case 13: RUN_TEST_LEFT(screen,"Filled ellipses",1000,100,false,sge_FilledEllipse(screen,xl1[i],y1[i],r1[i],r2[i],col1[i])); RUN_TEST_RIGHT(screen,"Filled ellipses (alpha)",500,100,true,sge_FilledEllipseAlpha(screen,xr1[i],y1[i],r1[i],r2[i],col1[i],a[i])); op = 0; break; case 14: RUN_TEST_LEFT(screen,"AA filled circles",500,100,false,sge_AAFilledCircle(screen,xl1[i],y1[i],r1[i],col1[i])); RUN_TEST_RIGHT(screen,"AA filled ellipses",500,100,false,sge_AAFilledEllipse(screen,xr1[i],y1[i],r1[i],r2[i],col1[i])); op = 0; break; case 15: RUN_TEST_LEFT(screen,"Bezier curves",1500,50,true,sge_Bezier(screen, xl1[i],y1[i],xl2[i],y2[i],xl3[i],y3[i],xl4[i],y4[i], 6, col1[i])); RUN_TEST_RIGHT(screen,"Bezier curves (alpha)",800,50,true,sge_BezierAlpha(screen, xr1[i],y1[i],xr2[i],y2[i],xr3[i],y3[i],xr4[i],y4[i], 6, col1[i], a[i])); op = 0; break; case 16: RUN_TEST_LEFT(screen,"AA bezier curves",800,50,true,sge_AABezier(screen, xl1[i],y1[i],xl2[i],y2[i],xl3[i],y3[i],xl4[i],y4[i], 6, col1[i])); RUN_TEST_RIGHT(screen,"AA bezier curves (alpha)",800,50,true,sge_AABezierAlpha(screen, xr1[i],y1[i],xr2[i],y2[i],xr3[i],y3[i],xr4[i],y4[i], 6, col1[i], a[i])); op = 0; break; case 17: RUN_TEST_LEFT(screen,"Triangles",1500,30,true,sge_Trigon(screen, xl1[i],y1[i],xl2[i],y2[i],xl3[i],y3[i], col1[i])); RUN_TEST_RIGHT(screen,"Triangles (alpha)",1000,30,true,sge_TrigonAlpha(screen, xr1[i],y1[i],xr2[i],y2[i],xr3[i],y3[i], col1[i], a[i])); op = 0; break; case 18: RUN_TEST_LEFT(screen,"AA triangles",500,30,true,sge_AATrigon(screen, xl1[i],y1[i],xl2[i],y2[i],xl3[i],y3[i], col1[i])); RUN_TEST_RIGHT(screen,"AA triangles (alpha)",500,30,true,sge_AATrigonAlpha(screen, xr1[i],y1[i],xr2[i],y2[i],xr3[i],y3[i], col1[i], a[i])); op = 0; break; case 19: RUN_TEST_LEFT(screen,"Filled triangles",800,30,false,sge_FilledTrigon(screen, xl1[i],y1[i],xl2[i],y2[i],xl3[i],y3[i], col1[i])); RUN_TEST_RIGHT(screen,"Filled triangles (alpha)",100,30,true,sge_FilledTrigonAlpha(screen, xr1[i],y1[i],xr2[i],y2[i],xr3[i],y3[i], col1[i], a[i])); op = 0; break; case 20: RUN_TEST_LEFT(screen,"Gourand shaded triangles",400,20,true,sge_FadedTrigon(screen, xl1[i],y1[i],xl2[i],y2[i],xl3[i],y3[i], col1[i],col2[i],col3[i])); if (SDL_MUSTLOCK(texture)) if (SDL_LockSurface(texture) < 0) break; RUN_TEST_RIGHT(screen,"Texture mapped triangles",500,20,true,sge_TexturedTrigon(screen, xr1[i],y1[i],xr2[i],y2[i],xr3[i],y3[i], texture,0,0,0,texture->h-1,texture->w-1,0)); if (SDL_MUSTLOCK(texture)) SDL_UnlockSurface(texture); op = 0; break; case 21: RUN_TEST_LEFT(screen,"Bitmap text",4000,100,false,sge_BF_textout(screen, font, "Hello World!", xl1[i], y1[i])); RUN_TEST_RIGHT(screen,"Colored bitmap text",4000,100,false,sge_BF_SetColor(cfont,r[i],g[i],b[i]);sge_BF_textout(screen, cfont, "Hello World!", xr1[i], y1[i])); op = 0; break; } /* Wait for user input */ SDL_WaitEvent(&event); if(event.type==SDL_MOUSEBUTTONDOWN && event.button.button == SDL_BUTTON_LEFT){ /* Goto next test */ op = ++next_op; if(op > 21){ op=1; next_op=1; rand_data(screen); } } if(event.type==SDL_MOUSEBUTTONDOWN && event.button.button == SDL_BUTTON_RIGHT){ /* Goto previous test */ op = --next_op; if(op < 1){ op=21; next_op=21; rand_data(screen); } } if(event.type==SDL_KEYDOWN && event.key.keysym.sym==SDLK_ESCAPE){break;} if(event.type==SDL_QUIT){break;} }while(true); /* Clean up */ sge_BF_CloseFont(font); sge_BF_CloseFont(cfont); SDL_FreeSurface(texture); return 0; } sge030809/examples/collision.cpp0000644000175000001440000000673707414660226015360 0ustar samusers#include #include #include #include #include "SDL.h" #include "sge.h" int main(int argc, char** argv) { /* Init SDL */ if ( SDL_Init(SDL_INIT_TIMER|SDL_INIT_VIDEO) < 0 ) { fprintf(stderr, "Couldn't load SDL: %s\n", SDL_GetError()); exit(1); } /* Clean up on exit */ atexit(SDL_Quit); /* Set window title */ SDL_WM_SetCaption("Collision", "collision"); /* Initialize the display */ SDL_Surface *screen; screen = SDL_SetVideoMode(640, 480, 16, SDL_SWSURFACE); if ( screen == NULL ) { fprintf(stderr, "Couldn't set video mode: %s\n", SDL_GetError()); exit(1); } sge_ClearSurface(screen,0); //Allocate some buffers SDL_Surface *img1,*buffer; //The buffer for the ball img1=SDL_AllocSurface(SDL_SWSURFACE|SDL_SRCCOLORKEY,30,30,16, 0,0,0,0); sge_ClearSurface(img1,0); sge_AAFilledCircle(img1,15,15, 14, 150,200,50); SDL_SetColorKey(img1, SDL_SRCCOLORKEY|SDL_RLEACCEL, 0); //Set transparent color //Draw a background (add more filled rectangles if you want) sge_FilledRect(screen, 300,80, 340,400, 0,0,255); sge_FilledRect(screen, 0,360, 200,400, 0,0,255); sge_FilledRect(screen, 340,260, 550,300, 0,0,255); sge_FilledRect(screen, 100,80, 140,360, 0,0,255); sge_FilledRect(screen, 500,80, 550,130, 0,0,255); buffer=SDL_DisplayFormat(screen); //The buffer for the background //Make the collision maps sge_cdata *cimg1, *cbg; cimg1=sge_make_cmap(img1); SDL_SetColorKey(buffer, SDL_SRCCOLORKEY, 0); //Must set transparent color on background cbg=sge_make_cmap(buffer); SDL_SetColorKey(buffer, 0, 0); //No transparency // If the delay between two PollEvent is greater than 100 and all events are added to the // event queue, the queue will grow *fast*. You're program will have no change to catch // up. You *must* try to avoid adding events unnecessarily - mousemotions for example. SDL_EventState(SDL_MOUSEMOTION,SDL_IGNORE); Sint16 x=50,y=190; Sint16 oldx=x,oldy=y; bool right=true, down=false; sge_Update_OFF(); // Sets start time Uint32 tstart=SDL_GetTicks(); int loops=0; // Main loop SDL_Event event; do{ SDL_Delay(10); //Check borders if( (x+img1->w)>=screen->w ) right=false; else if(x<=0) right=true; if( (y+img1->h)>=screen->h ) down=false; else if(y<=0) down=true; //Check for collision if( sge_cmcheck(cbg,0,0, cimg1,x,y) ){ //SDL_Delay(200); //Bounce the ball if( abs(sge_get_cx()-(x+img1->w/2)) < abs(sge_get_cy()-(y+img1->h/2)) ){ if( sge_get_cy()-(y+img1->h/2) < 0 ) down=true; else down=false; } else{ if( sge_get_cx()-(x+img1->w/2) < 0 ) right=true; else right=false; } } //Update pos if(right) x++; else x--; if(down) y++; else y--; //Update last pos from buffer sge_Blit(buffer,screen,oldx,oldy, oldx,oldy, img1->w,img1->h); //Draw the circle sge_Blit(img1,screen,0,0, x,y, img1->w,img1->h); oldx=x;oldy=y; //Update screen sge_Update_ON(); sge_UpdateRect(screen,x-1,y-1,img1->w+2,img1->h+2); sge_Update_OFF(); loops++; // Check events if(SDL_PollEvent(&event)==1){ if(event.type==SDL_KEYDOWN && event.key.keysym.sym==SDLK_ESCAPE){break;} if(event.type==SDL_QUIT){break;} } }while(true); /* Print FPS */ printf("%.2f FPS (target: 100).\n",((double)loops*1000)/(SDL_GetTicks()-tstart)); //Clean upp SDL_FreeSurface(img1); SDL_FreeSurface(buffer); sge_destroy_cmap(cimg1); sge_destroy_cmap(cbg); return 0; } sge030809/examples/inputdeluxe.cpp0000644000175000001440000000463007415070315015714 0ustar samusers#include "SDL.h" #include "sge.h" #include #include int main(int argc, char** argv) { /* Init SDL */ if ( SDL_Init(SDL_INIT_TIMER|SDL_INIT_VIDEO) < 0 ) { fprintf(stderr, "Couldn't load SDL: %s\n", SDL_GetError()); exit(1); } /* Clean up on exit */ atexit(SDL_Quit); /* Set window title */ SDL_WM_SetCaption("Input Deluxe", "input deluxe"); /* Initialize the display */ SDL_Surface *screen; screen = SDL_SetVideoMode(600, 400, 0, SDL_SWSURFACE); if ( screen == NULL ) { fprintf(stderr, "Couldn't set video mode: %s\n", SDL_GetError()); exit(1); } sge_Update_OFF(); SDL_EnableUNICODE(1); //This is VERY important!! //Init our text sprites sge_TextSprite text(screen,"Edit Me!",20,90); text.show_cursor(true); sge_TextSprite text2(screen,"Hello World!",100,25); text.show_cursor(true); //Set and draw the border box SDL_Rect r; r.x=1; r.y=81; r.w=598; r.h=318; text.set_border(r); sge_Rect(screen,0,80, 599,399, 255,0,0); //Open a TT font if(sge_TTF_Init()!=0){fprintf(stderr,"TT error: %s\n",SDL_GetError());exit(1);} sge_TTFont *font; font=sge_TTF_OpenFont("font.ttf", 25); if(font==NULL){fprintf(stderr,"TT error: %s\n",SDL_GetError());exit(1);} text.set_ttFont(font,0,255,0); //Use our font text2.set_ttFont(font,50,50,200); text.set_pps(60,60); //set speed (pixels/second) text2.set_pps(-170,0); text.border_warp(true); //WARP! text2.border_warp(true); SDL_UpdateRect(screen, 0,0,0,0); //Update whole screen //Keyrepeat SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL+50); SDL_Event event; do{ //SDL_Delay(1); /* Check events */ if(SDL_PollEvent(&event)==1){ if(event.type==SDL_QUIT){break;} if(event.type==SDL_KEYDOWN && event.key.keysym.sym==SDLK_ESCAPE){break;} text.check(&event); //Let our text sprite handle the event (editing the text) } if(text.update()){ //update() calculates the new pos and returns true if we need to redraw text.clear(0); //clear text area text.draw(); //draw text at new pos sge_Update_ON(); text.UpdateRects(); //Update screen (old pos + new pos) sge_Update_OFF(); } if(text2.update()){ //Same thing for the other sprite text2.clear(0); text2.draw(); sge_Update_ON(); text2.UpdateRects(); sge_Update_OFF(); } }while(true); sge_TTF_CloseFont(font); return 0; } sge030809/sge_config.h0000644000175000001440000000016607716016112013277 0ustar samusers/* SGE Config header (generated automatically) */ #define SGE_VER 030809 #define _SGE_C_AND_CPP #define _SGE_HAVE_IMG sge030809/sge_misc.cpp0000644000175000001440000000512207713172514013323 0ustar samusers/* * SDL Graphics Extension * Misc functions * * Started 990819 * * License: LGPL v2+ (see the file LICENSE) * (c)1999-2003 Anders Lindstrm */ /********************************************************************* * This library is free software; you can redistribute it and/or * * modify it under the terms of the GNU Library General Public * * License as published by the Free Software Foundation; either * * version 2 of the License, or (at your option) any later version. * *********************************************************************/ #include "SDL.h" #include #include #include #include #include "sge_misc.h" Uint32 delay_res=10; //================================================================================== // Returns a random integer between min and max //================================================================================== int sge_Random(int min, int max) { return min+(rand()%(max-min+1)); } //================================================================================== // Seed the random number generator with a number from the system clock. // Should be called once before the first use of sge_Random. //================================================================================== void sge_Randomize(void) { srand(time(NULL)); } //================================================================================== // Test the resolution of SDL_Delay() //================================================================================== Uint32 sge_CalibrateDelay(void) { SDL_Delay(10); delay_res=SDL_GetTicks(); SDL_Delay(1); delay_res=SDL_GetTicks()-delay_res; return delay_res; } //================================================================================== // Get the resolution of SDL_Delay() //================================================================================== Uint32 sge_DelayRes(void) { return delay_res; } //================================================================================== // Delay 'ticks' ms. // Tries to burn time in SDL_Delay() if possible // Returns the exact delay time //================================================================================== Uint32 sge_Delay(Uint32 ticks) { Uint32 start = SDL_GetTicks(); Sint32 time_left = (Sint32)ticks; Uint32 tmp; if(ticks >= delay_res){ tmp=ticks-(ticks%delay_res); SDL_Delay(tmp); time_left=(Sint32)(ticks-(SDL_GetTicks()-start)); //Possible error for large ticks... nah } while(time_left>0){ time_left=ticks-(SDL_GetTicks()-start); } return SDL_GetTicks()-start; }