123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394 |
- /*
- * SDL Graphics Extension
- * Drawing primitives
- *
- * Started 990815 (split from sge_draw 010611)
- *
- * License: LGPL v2+ (see the file LICENSE)
- * (c)1999-2003 Anders Lindström
- */
- /* MODIFIED: 02/27/2004 Janson
- *
- * MODIFIED: Prefix ++/-- instead of postfix (consistent with my other code)
- * Removed all 8/24 bit code
- *
- * REMOVED: _sge_update and all related functions
- * sge_CreateAlphaSurface
- * all palette functions
- *
- * MODIFIED: 03/05/2006 Janson
- *
- * ADDED: sge_FilledCircleDual
- */
- /*********************************************************************
- * 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
- */
- // (MODIFIED Janson - using std header)
- #include "all.h"
- /* Globals used for sge_Lock (defined in sge_surface) */
- 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(y<Surface->clip_miny || y>Surface->clip_maxy || x1>Surface->clip_maxx || x2<Surface->clip_minx)
- return;
- if(x1<Surface->clip_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(y<Surface->clip_miny || y>Surface->clip_maxy || x1>Surface->clip_maxx || x2<Surface->clip_minx)
- return;
- if(x1<Surface->clip_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 (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 lock = _sge_lock;
- _sge_lock = 0;
- sge_FilledRectAlpha(Surface, x1,y,x2,y, Color, alpha);
- _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(x<Surface->clip_minx || x>Surface->clip_maxx || y1>Surface->clip_maxy || y2<Surface->clip_miny)
- return;
- if(y1<Surface->clip_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(x<Surface->clip_minx || x>Surface->clip_maxx || y1>Surface->clip_maxy || y2<Surface->clip_miny)
- return;
- if(y1<Surface->clip_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 (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 lock = _sge_lock;
- _sge_lock = 0;
- sge_FilledRectAlpha(Surface, x,y1,x,y2, Color, alpha);
- _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 2: {
- for(x=0; x < dx; ++x) {
- *(Uint16*)pixel = color;
-
- 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);
- }
- }
- //==================================================================================
- // 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);
- }
- }
- //==================================================================================
- // 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);
- }
- }
- 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);
- }
- }
- 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);
- }
- }
- //==================================================================================
- // 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);
- }
- 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);
- }
- //==================================================================================
- // 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);
- }
- }
- //==================================================================================
- // 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(x2<Surface->clip_minx || x1>Surface->clip_maxx || y2<Surface->clip_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);
- }
- //==================================================================================
- // 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(x2<sge_clip_xmin(surface) || x1>sge_clip_xmax(surface) || y2<sge_clip_ymin(surface) || y1>sge_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 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 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);
- }
- }
- 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);
- }
- }
- //==================================================================================
- // 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);
- }
- }
- //==================================================================================
- // 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);
- }
- }
- //==================================================================================
- // 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);
- }
- }
- //==================================================================================
- // 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);
- }
- }
- //==================================================================================
- // 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);
- }
- }
- //==================================================================================
- // 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);
- }
- }
- //==================================================================================
- // 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);
- }
- }
- //==================================================================================
- // 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 dual-colored filled circle
- //==================================================================================
- void sge_FilledCircleDual(SDL_Surface *Surface, Sint16 x, Sint16 y, Sint16 r, Sint16 tweak, Uint32 color1, Uint32 color2)
- {
- if (SDL_MUSTLOCK(Surface) && _sge_lock) {
- if (SDL_LockSurface(Surface) < 0)
- return;
- }
- Sint16 cx = 0;
- Sint16 cy = r;
- Sint16 df = 1 - r;
- Sint16 d_e = 3;
- Sint16 d_se = -2 * r + 5;
- tweak = tweak ? 1 : 0;
- do {
- _HLine(Surface, x+tweak, x+tweak+cx, y+tweak+cy, color2);
- _HLine(Surface, x+tweak, x+tweak+cy, y+tweak+cx, color2);
- _HLine(Surface, x-cx, x, y+tweak+cy, color2);
- _HLine(Surface, x+tweak, x+tweak+cx, y-cy, color1);
- _HLine(Surface, x+tweak, x+tweak+cx, y-cx, color1);
- _HLine(Surface, x+tweak+cx, x+tweak+cy, y-cx, color2);
- _HLine(Surface, x-cx, x, y+tweak+cx, color2);
- _HLine(Surface, x-cy, x-cx, y+tweak+cx, color1);
- _HLine(Surface, x-cx, x, y-cy, color1);
- _HLine(Surface, x-cy, x, y-cx, color1);
- 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);
- if (SDL_MUSTLOCK(Surface) && _sge_lock) {
- SDL_UnlockSurface(Surface);
- }
- }
- //==================================================================================
- // 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);
- }
- //==================================================================================
- // 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);
- }
- }
- //==================================================================================
- // 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;\
- \
- /* 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;\
- }\
- xp = x; yp = y;\
- }\
- \
- /* unlock the display */\
- if (SDL_MUSTLOCK(surface) && _sge_lock) {\
- SDL_UnlockSurface(surface);\
- }\
- \
-
- //==================================================================================
- // Draws a bezier line
- //==================================================================================
- 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)
- {
- DO_BEZIER(_Line(surface, Sint16(xp),Sint16(yp), Sint16(x),Sint16(y), color));
- }
- //==================================================================================
- // Draws a bezier line (RGB)
- //==================================================================================
- 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)
- {
- sge_Bezier(surface,x1,y1,x2,y2,x3,y3,x4,y4,level, SDL_MapRGB(surface->format,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 lock = _sge_lock;
- _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_lock = lock;
- }
- //==================================================================================
- // 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);
- }
|