sge_primitives.cpp 66 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394
  1. /*
  2. * SDL Graphics Extension
  3. * Drawing primitives
  4. *
  5. * Started 990815 (split from sge_draw 010611)
  6. *
  7. * License: LGPL v2+ (see the file LICENSE)
  8. * (c)1999-2003 Anders Lindström
  9. */
  10. /* MODIFIED: 02/27/2004 Janson
  11. *
  12. * MODIFIED: Prefix ++/-- instead of postfix (consistent with my other code)
  13. * Removed all 8/24 bit code
  14. *
  15. * REMOVED: _sge_update and all related functions
  16. * sge_CreateAlphaSurface
  17. * all palette functions
  18. *
  19. * MODIFIED: 03/05/2006 Janson
  20. *
  21. * ADDED: sge_FilledCircleDual
  22. */
  23. /*********************************************************************
  24. * This library is free software; you can redistribute it and/or *
  25. * modify it under the terms of the GNU Library General Public *
  26. * License as published by the Free Software Foundation; either *
  27. * version 2 of the License, or (at your option) any later version. *
  28. *********************************************************************/
  29. /*
  30. * Some of this code is taken from the "Introduction to SDL" and
  31. * John Garrison's PowerPak
  32. */
  33. // (MODIFIED Janson - using std header)
  34. #include "all.h"
  35. /* Globals used for sge_Lock (defined in sge_surface) */
  36. extern Uint8 _sge_lock;
  37. #define SWAP(x,y,temp) temp=x;x=y;y=temp
  38. /**********************************************************************************/
  39. /** Line functions **/
  40. /**********************************************************************************/
  41. //==================================================================================
  42. // Internal draw horizontal line
  43. //==================================================================================
  44. void _HLine(SDL_Surface *Surface, Sint16 x1, Sint16 x2, Sint16 y, Uint32 Color)
  45. {
  46. if(x1>x2){Sint16 tmp=x1; x1=x2; x2=tmp;}
  47. //Do the clipping
  48. #if SDL_VERSIONNUM(SDL_MAJOR_VERSION, SDL_MINOR_VERSION, SDL_PATCHLEVEL) < \
  49. SDL_VERSIONNUM(1, 1, 5)
  50. if(y<Surface->clip_miny || y>Surface->clip_maxy || x1>Surface->clip_maxx || x2<Surface->clip_minx)
  51. return;
  52. if(x1<Surface->clip_minx)
  53. x1=Surface->clip_minx;
  54. if(x2>Surface->clip_maxx)
  55. x2=Surface->clip_maxx;
  56. #endif
  57. SDL_Rect l;
  58. l.x=x1; l.y=y; l.w=x2-x1+1; l.h=1;
  59. SDL_FillRect(Surface, &l, Color);
  60. }
  61. //==================================================================================
  62. // Draw horizontal line
  63. //==================================================================================
  64. void sge_HLine(SDL_Surface *Surface, Sint16 x1, Sint16 x2, Sint16 y, Uint32 Color)
  65. {
  66. if(x1>x2){Sint16 tmp=x1; x1=x2; x2=tmp;}
  67. //Do the clipping
  68. #if SDL_VERSIONNUM(SDL_MAJOR_VERSION, SDL_MINOR_VERSION, SDL_PATCHLEVEL) < \
  69. SDL_VERSIONNUM(1, 1, 5)
  70. if(y<Surface->clip_miny || y>Surface->clip_maxy || x1>Surface->clip_maxx || x2<Surface->clip_minx)
  71. return;
  72. if(x1<Surface->clip_minx)
  73. x1=Surface->clip_minx;
  74. if(x2>Surface->clip_maxx)
  75. x2=Surface->clip_maxx;
  76. #endif
  77. SDL_Rect l;
  78. l.x=x1; l.y=y; l.w=x2-x1+1; l.h=1;
  79. SDL_FillRect(Surface, &l, Color);
  80. }
  81. //==================================================================================
  82. // Draw horizontal line (RGB)
  83. //==================================================================================
  84. void sge_HLine(SDL_Surface *Surface, Sint16 x1, Sint16 x2, Sint16 y, Uint8 R, Uint8 G, Uint8 B)
  85. {
  86. sge_HLine(Surface,x1,x2,y, SDL_MapRGB(Surface->format, R, G, B));
  87. }
  88. //==================================================================================
  89. // Internal draw horizontal line (alpha)
  90. //==================================================================================
  91. void _HLineAlpha(SDL_Surface *Surface, Sint16 x1, Sint16 x2, Sint16 y, Uint32 Color, Uint8 alpha)
  92. {
  93. Uint8 lock = _sge_lock;
  94. _sge_lock = 0;
  95. sge_FilledRectAlpha(Surface, x1,y,x2,y, Color, alpha);
  96. _sge_lock = lock;
  97. }
  98. //==================================================================================
  99. // Draw horizontal line (alpha)
  100. //==================================================================================
  101. void sge_HLineAlpha(SDL_Surface *Surface, Sint16 x1, Sint16 x2, Sint16 y, Uint32 Color, Uint8 alpha)
  102. {
  103. sge_FilledRectAlpha(Surface, x1,y,x2,y, Color, alpha);
  104. }
  105. //==================================================================================
  106. // Draw horizontal line (alpha RGB)
  107. //==================================================================================
  108. void sge_HLineAlpha(SDL_Surface *Surface, Sint16 x1, Sint16 x2, Sint16 y, Uint8 R, Uint8 G, Uint8 B, Uint8 alpha)
  109. {
  110. sge_HLineAlpha(Surface,x1,x2,y, SDL_MapRGB(Surface->format, R, G, B), alpha);
  111. }
  112. //==================================================================================
  113. // Internal draw vertical line
  114. //==================================================================================
  115. void _VLine(SDL_Surface *Surface, Sint16 x, Sint16 y1, Sint16 y2, Uint32 Color)
  116. {
  117. if(y1>y2){Sint16 tmp=y1; y1=y2; y2=tmp;}
  118. //Do the clipping
  119. #if SDL_VERSIONNUM(SDL_MAJOR_VERSION, SDL_MINOR_VERSION, SDL_PATCHLEVEL) < \
  120. SDL_VERSIONNUM(1, 1, 5)
  121. if(x<Surface->clip_minx || x>Surface->clip_maxx || y1>Surface->clip_maxy || y2<Surface->clip_miny)
  122. return;
  123. if(y1<Surface->clip_miny)
  124. y1=Surface->clip_miny;
  125. if(y2>Surface->clip_maxy)
  126. y2=Surface->clip_maxy;
  127. #endif
  128. SDL_Rect l;
  129. l.x=x; l.y=y1; l.w=1; l.h=y2-y1+1;
  130. SDL_FillRect(Surface, &l, Color);
  131. }
  132. //==================================================================================
  133. // Draw vertical line
  134. //==================================================================================
  135. void sge_VLine(SDL_Surface *Surface, Sint16 x, Sint16 y1, Sint16 y2, Uint32 Color)
  136. {
  137. if(y1>y2){Sint16 tmp=y1; y1=y2; y2=tmp;}
  138. //Do the clipping
  139. #if SDL_VERSIONNUM(SDL_MAJOR_VERSION, SDL_MINOR_VERSION, SDL_PATCHLEVEL) < \
  140. SDL_VERSIONNUM(1, 1, 5)
  141. if(x<Surface->clip_minx || x>Surface->clip_maxx || y1>Surface->clip_maxy || y2<Surface->clip_miny)
  142. return;
  143. if(y1<Surface->clip_miny)
  144. y1=Surface->clip_miny;
  145. if(y2>Surface->clip_maxy)
  146. y2=Surface->clip_maxy;
  147. #endif
  148. SDL_Rect l;
  149. l.x=x; l.y=y1; l.w=1; l.h=y2-y1+1;
  150. SDL_FillRect(Surface, &l, Color);
  151. }
  152. //==================================================================================
  153. // Draw vertical line (RGB)
  154. //==================================================================================
  155. void sge_VLine(SDL_Surface *Surface, Sint16 x, Sint16 y1, Sint16 y2, Uint8 R, Uint8 G, Uint8 B)
  156. {
  157. sge_VLine(Surface,x,y1,y2, SDL_MapRGB(Surface->format, R, G, B));
  158. }
  159. //==================================================================================
  160. // Internal draw vertical line (alpha - no update)
  161. //==================================================================================
  162. void _VLineAlpha(SDL_Surface *Surface, Sint16 x, Sint16 y1, Sint16 y2, Uint32 Color, Uint8 alpha)
  163. {
  164. Uint8 lock = _sge_lock;
  165. _sge_lock = 0;
  166. sge_FilledRectAlpha(Surface, x,y1,x,y2, Color, alpha);
  167. _sge_lock = lock;
  168. }
  169. //==================================================================================
  170. // Draw vertical line (alpha)
  171. //==================================================================================
  172. void sge_VLineAlpha(SDL_Surface *Surface, Sint16 x, Sint16 y1, Sint16 y2, Uint32 Color, Uint8 alpha)
  173. {
  174. sge_FilledRectAlpha(Surface, x,y1,x,y2, Color, alpha);
  175. }
  176. //==================================================================================
  177. // Draw vertical line (alpha RGB)
  178. //==================================================================================
  179. void sge_VLineAlpha(SDL_Surface *Surface, Sint16 x, Sint16 y1, Sint16 y2, Uint8 R, Uint8 G, Uint8 B, Uint8 alpha)
  180. {
  181. sge_VLineAlpha(Surface,x,y1,y2, SDL_MapRGB(Surface->format, R, G, B), alpha);
  182. }
  183. //==================================================================================
  184. // Performs Callback at each line point. (From PowerPak)
  185. //==================================================================================
  186. 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))
  187. {
  188. Sint16 dx, dy, sdx, sdy, x, y, px, py;
  189. dx = x2 - x1;
  190. dy = y2 - y1;
  191. sdx = (dx < 0) ? -1 : 1;
  192. sdy = (dy < 0) ? -1 : 1;
  193. dx = sdx * dx + 1;
  194. dy = sdy * dy + 1;
  195. x = y = 0;
  196. px = x1;
  197. py = y1;
  198. if (dx >= dy){
  199. for (x = 0; x < dx; ++x){
  200. Callback(Surface, px, py, Color);
  201. y += dy;
  202. if (y >= dx){
  203. y -= dx;
  204. py += sdy;
  205. }
  206. px += sdx;
  207. }
  208. }
  209. else{
  210. for (y = 0; y < dy; ++y){
  211. Callback(Surface, px, py, Color);
  212. x += dx;
  213. if (x >= dy){
  214. x -= dy;
  215. px += sdx;
  216. }
  217. py += sdy;
  218. }
  219. }
  220. }
  221. //==================================================================================
  222. // Performs Callback at each line point. (RGB)
  223. //==================================================================================
  224. 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))
  225. {
  226. sge_DoLine(Surface,X1,Y1,X2,Y2, SDL_MapRGB(Surface->format, R, G, B),Callback);
  227. }
  228. //==================================================================================
  229. // Line clipping
  230. // Standard Cohen-Sutherland algorithm (from gfxPrimitives)
  231. //==================================================================================
  232. #define CLIP_LEFT_EDGE 0x1
  233. #define CLIP_RIGHT_EDGE 0x2
  234. #define CLIP_BOTTOM_EDGE 0x4
  235. #define CLIP_TOP_EDGE 0x8
  236. #define CLIP_INSIDE(a) (!a)
  237. #define CLIP_REJECT(a,b) (a&b)
  238. #define CLIP_ACCEPT(a,b) (!(a|b))
  239. int clipEncode(Sint16 x, Sint16 y, Sint16 left, Sint16 top, Sint16 right, Sint16 bottom)
  240. {
  241. int code = 0;
  242. if (x < left)
  243. code |= CLIP_LEFT_EDGE;
  244. else if (x > right)
  245. code |= CLIP_RIGHT_EDGE;
  246. if (y < top)
  247. code |= CLIP_TOP_EDGE;
  248. else if (y > bottom)
  249. code |= CLIP_BOTTOM_EDGE;
  250. return code;
  251. }
  252. int clipLine(SDL_Surface *dst, Sint16 *x1, Sint16 *y1, Sint16 *x2, Sint16 *y2)
  253. {
  254. int code1, code2;
  255. bool draw = false;
  256. Sint16 tmp;
  257. float m;
  258. /* Get clipping boundary */
  259. Sint16 left, right, top, bottom;
  260. left = sge_clip_xmin(dst);
  261. right = sge_clip_xmax(dst);
  262. top = sge_clip_ymin(dst);
  263. bottom = sge_clip_ymax(dst);
  264. while (true){
  265. code1 = clipEncode(*x1, *y1, left, top, right, bottom);
  266. code2 = clipEncode(*x2, *y2, left, top, right, bottom);
  267. if(CLIP_ACCEPT(code1, code2)){
  268. draw = true;
  269. break;
  270. }else if(CLIP_REJECT(code1, code2))
  271. break;
  272. else{
  273. if(CLIP_INSIDE(code1)){
  274. tmp = *x2;
  275. *x2 = *x1;
  276. *x1 = tmp;
  277. tmp = *y2;
  278. *y2 = *y1;
  279. *y1 = tmp;
  280. tmp = code2;
  281. code2 = code1;
  282. code1 = tmp;
  283. }
  284. if(*x2 != *x1)
  285. m = (*y2 - *y1) / float(*x2 - *x1);
  286. else
  287. m = 1.0;
  288. if(code1 & CLIP_LEFT_EDGE){
  289. *y1 += Sint16( (left - *x1) * m );
  290. *x1 = left;
  291. }else if(code1 & CLIP_RIGHT_EDGE){
  292. *y1 += Sint16( (right - *x1) * m );
  293. *x1 = right;
  294. }else if(code1 & CLIP_BOTTOM_EDGE){
  295. if (*x2 != *x1) {
  296. *x1 += Sint16( (bottom - *y1) / m );
  297. }
  298. *y1 = bottom;
  299. }else if(code1 & CLIP_TOP_EDGE){
  300. if (*x2 != *x1) {
  301. *x1 += Sint16( (top - *y1) / m );
  302. }
  303. *y1 = top;
  304. }
  305. }
  306. }
  307. return draw;
  308. }
  309. //==================================================================================
  310. // Draws a line
  311. //==================================================================================
  312. void _Line(SDL_Surface *surface, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint32 color)
  313. {
  314. if( !clipLine(surface, &x1, &y1, &x2, &y2) )
  315. return;
  316. Sint16 dx, dy, sdx, sdy, x, y;
  317. dx = x2 - x1;
  318. dy = y2 - y1;
  319. sdx = (dx < 0) ? -1 : 1;
  320. sdy = (dy < 0) ? -1 : 1;
  321. dx = sdx * dx + 1;
  322. dy = sdy * dy + 1;
  323. x = y = 0;
  324. Sint16 pixx = surface->format->BytesPerPixel;
  325. Sint16 pixy = surface->pitch;
  326. Uint8 *pixel = (Uint8*)surface->pixels + y1*pixy + x1*pixx;
  327. pixx *= sdx;
  328. pixy *= sdy;
  329. if (dx < dy) {
  330. Sint32 tmp = dx; dx = dy; dy = Sint16(tmp);
  331. tmp = pixx; pixx = pixy; pixy = tmp;
  332. }
  333. switch(surface->format->BytesPerPixel) {
  334. case 2: {
  335. for(x=0; x < dx; ++x) {
  336. *(Uint16*)pixel = color;
  337. y += dy;
  338. if (y >= dx) {
  339. y -= dx;
  340. pixel += pixy;
  341. }
  342. pixel += pixx;
  343. }
  344. }
  345. break;
  346. case 4: {
  347. for(x=0; x < dx; ++x) {
  348. *(Uint32*)pixel = color;
  349. y += dy;
  350. if (y >= dx) {
  351. y -= dx;
  352. pixel += pixy;
  353. }
  354. pixel += pixx;
  355. }
  356. }
  357. break;
  358. }
  359. }
  360. void sge_Line(SDL_Surface *Surface, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint32 Color)
  361. {
  362. if (SDL_MUSTLOCK(Surface) && _sge_lock) {
  363. if (SDL_LockSurface(Surface) < 0)
  364. return;
  365. }
  366. /* Draw the line */
  367. _Line(Surface, x1,y1, x2,y2, Color);
  368. /* unlock the display */
  369. if (SDL_MUSTLOCK(Surface) && _sge_lock) {
  370. SDL_UnlockSurface(Surface);
  371. }
  372. }
  373. //==================================================================================
  374. // Draws a line (RGB)
  375. //==================================================================================
  376. void sge_Line(SDL_Surface *Surface, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint8 R, Uint8 G, Uint8 B)
  377. {
  378. sge_Line(Surface,x1,y1,x2,y2, SDL_MapRGB(Surface->format, R, G, B));
  379. }
  380. //==================================================================================
  381. // A quick hack to get alpha working with callbacks
  382. //==================================================================================
  383. Uint8 _sge_alpha_hack = 0;
  384. void callback_alpha_hack(SDL_Surface *surf, Sint16 x, Sint16 y, Uint32 color)
  385. {
  386. _PutPixelAlpha(surf,x,y,color,_sge_alpha_hack);
  387. }
  388. //==================================================================================
  389. // Draws a line (alpha)
  390. //==================================================================================
  391. void _LineAlpha(SDL_Surface *Surface, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint32 Color, Uint8 alpha)
  392. {
  393. _sge_alpha_hack = alpha;
  394. /* Draw the line */
  395. sge_DoLine(Surface, x1, y1, x2, y2, Color, callback_alpha_hack);
  396. }
  397. void sge_LineAlpha(SDL_Surface *Surface, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint32 Color, Uint8 alpha)
  398. {
  399. if (SDL_MUSTLOCK(Surface) && _sge_lock)
  400. if (SDL_LockSurface(Surface) < 0)
  401. return;
  402. _LineAlpha(Surface, x1, y1, x2, y2, Color, alpha);
  403. /* unlock the display */
  404. if (SDL_MUSTLOCK(Surface) && _sge_lock) {
  405. SDL_UnlockSurface(Surface);
  406. }
  407. }
  408. //==================================================================================
  409. // Draws a line (alpha - RGB)
  410. //==================================================================================
  411. void sge_LineAlpha(SDL_Surface *Surface, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint8 R, Uint8 G, Uint8 B, Uint8 alpha)
  412. {
  413. sge_LineAlpha(Surface,x1,y1,x2,y2, SDL_MapRGB(Surface->format, R, G, B), alpha);
  414. }
  415. //==================================================================================
  416. // Anti-aliased line
  417. // From SDL_gfxPrimitives written by A. Schiffler (aschiffler@home.com)
  418. //==================================================================================
  419. #define AAbits 8
  420. #define AAlevels 256 /* 2^AAbits */
  421. void _AALineAlpha(SDL_Surface *dst, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint32 color, Uint8 alpha)
  422. {
  423. Uint32 erracc=0, erradj;
  424. Uint32 erracctmp, wgt;
  425. Sint16 tmp, y0p1, x0pxdir;
  426. Uint8 a;
  427. /* Keep on working with 32bit numbers */
  428. Sint32 xx0=x1;
  429. Sint32 yy0=y1;
  430. Sint32 xx1=x2;
  431. Sint32 yy1=y2;
  432. /* Reorder points if required */
  433. if (yy0 > yy1) {
  434. SWAP(yy0, yy1, tmp);
  435. SWAP(xx0, xx1, tmp);
  436. }
  437. /* Calculate distance */
  438. Sint16 dx = xx1 - xx0;
  439. Sint16 dy = yy1 - yy0;
  440. /* Adjust for negative dx and set xdir */
  441. Sint16 xdir = 1;
  442. if (dx < 0) {
  443. xdir=-1;
  444. dx=(-dx);
  445. }
  446. /* Check for special cases */
  447. if (dx==0 || dy==0 || dx==dy) {
  448. if(alpha==SDL_ALPHA_OPAQUE)
  449. _Line(dst,x1,y1,x2,y2,color);
  450. else
  451. _LineAlpha(dst,x1,y1,x2,y2,color,alpha);
  452. return;
  453. }
  454. float alpha_pp = float(alpha)/255; /* Used to calculate alpha level if alpha != 255 */
  455. Uint32 intshift = 32 - AAbits; /* # of bits by which to shift erracc to get intensity level */
  456. /* Draw the initial pixel in the foreground color */
  457. if(alpha==SDL_ALPHA_OPAQUE)
  458. _PutPixel(dst,x1,y1, color);
  459. else
  460. _PutPixelAlpha(dst,x1,y1, color, alpha);
  461. /* x-major or y-major? */
  462. if (dy > dx) {
  463. /* y-major. Calculate 16-bit fixed point fractional part of a pixel that
  464. X advances every time Y advances 1 pixel, truncating the result so that
  465. we won't overrun the endpoint along the X axis */
  466. erradj = ((dx << 16) / dy)<<16;
  467. /* draw all pixels other than the first and last */
  468. x0pxdir=xx0+xdir;
  469. while (--dy) {
  470. erracctmp = erracc;
  471. erracc += erradj;
  472. if (erracc <= erracctmp) {
  473. /* rollover in error accumulator, x coord advances */
  474. xx0=x0pxdir;
  475. x0pxdir += xdir;
  476. }
  477. ++yy0; /* y-major so always advance Y */
  478. /* the AAbits most significant bits of erracc give us the intensity
  479. weighting for this pixel, and the complement of the weighting for
  480. the paired pixel. */
  481. wgt = (erracc >> intshift) & 255;
  482. a = Uint8(255-wgt);
  483. if(alpha != SDL_ALPHA_OPAQUE)
  484. a = Uint8(a*alpha_pp);
  485. _PutPixelAlpha(dst,xx0,yy0,color,a);
  486. a = Uint8(wgt);
  487. if(alpha != SDL_ALPHA_OPAQUE)
  488. a = Uint8(a*alpha_pp);
  489. _PutPixelAlpha(dst,x0pxdir,yy0,color,a);
  490. }
  491. } else {
  492. /* x-major line. Calculate 16-bit fixed-point fractional part of a pixel
  493. that Y advances each time X advances 1 pixel, truncating the result so
  494. that we won't overrun the endpoint along the X axis. */
  495. erradj = ((dy << 16) / dx)<<16;
  496. /* draw all pixels other than the first and last */
  497. y0p1=yy0+1;
  498. while (--dx) {
  499. erracctmp = erracc;
  500. erracc += erradj;
  501. if (erracc <= erracctmp) {
  502. /* Accumulator turned over, advance y */
  503. yy0=y0p1;
  504. ++y0p1;
  505. }
  506. xx0 += xdir; /* x-major so always advance X */
  507. /* the AAbits most significant bits of erracc give us the intensity
  508. weighting for this pixel, and the complement of the weighting for
  509. the paired pixel. */
  510. wgt = (erracc >> intshift) & 255;
  511. a = Uint8(255-wgt);
  512. if(alpha != SDL_ALPHA_OPAQUE)
  513. a = Uint8(a*alpha_pp);
  514. _PutPixelAlpha(dst,xx0,yy0,color,a);
  515. a = Uint8(wgt);
  516. if(alpha != SDL_ALPHA_OPAQUE)
  517. a = Uint8(a*alpha_pp);
  518. _PutPixelAlpha(dst,xx0,y0p1,color,a);
  519. }
  520. }
  521. /* Draw final pixel, always exactly intersected by the line and doesn't
  522. need to be weighted. */
  523. if(alpha==SDL_ALPHA_OPAQUE)
  524. _PutPixel(dst,x2,y2, color);
  525. else
  526. _PutPixelAlpha(dst,x2,y2, color, alpha);
  527. }
  528. void sge_AALineAlpha(SDL_Surface *dst, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint32 color, Uint8 alpha)
  529. {
  530. /* Lock surface */
  531. if ( SDL_MUSTLOCK(dst) && _sge_lock )
  532. if ( SDL_LockSurface(dst) < 0 )
  533. return;
  534. _AALineAlpha(dst,x1,y1,x2,y2,color,alpha);
  535. /* unlock the display */
  536. if (SDL_MUSTLOCK(dst) && _sge_lock) {
  537. SDL_UnlockSurface(dst);
  538. }
  539. }
  540. void sge_AALineAlpha(SDL_Surface *dst, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint8 r, Uint8 g, Uint8 b, Uint8 alpha)
  541. {
  542. sge_AALineAlpha(dst,x1,y1,x2,y2,SDL_MapRGB(dst->format, r, g, b),alpha);
  543. }
  544. void sge_AALine(SDL_Surface *dst, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint32 color)
  545. {
  546. sge_AALineAlpha(dst, x1,y1, x2,y2, color, SDL_ALPHA_OPAQUE);
  547. }
  548. void sge_AALine(SDL_Surface *dst, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint8 r, Uint8 g, Uint8 b)
  549. {
  550. sge_AALineAlpha(dst,x1,y1,x2,y2,SDL_MapRGB(dst->format, r, g, b),SDL_ALPHA_OPAQUE);
  551. }
  552. //==================================================================================
  553. // Draws a multicolored line
  554. //==================================================================================
  555. 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))
  556. {
  557. Sint16 dx, dy, sdx, sdy, x, y, px, py;
  558. dx = x2 - x1;
  559. dy = y2 - y1;
  560. sdx = (dx < 0) ? -1 : 1;
  561. sdy = (dy < 0) ? -1 : 1;
  562. dx = sdx * dx + 1;
  563. dy = sdy * dy + 1;
  564. x = y = 0;
  565. px = x1;
  566. py = y1;
  567. /* We use fixedpoint math for the color fading */
  568. Sint32 R = r1<<16;
  569. Sint32 G = g1<<16;
  570. Sint32 B = b1<<16;
  571. Sint32 rstep;
  572. Sint32 gstep;
  573. Sint32 bstep;
  574. if (dx >= dy){
  575. rstep = Sint32((r2-r1)<<16) / Sint32(dx);
  576. gstep = Sint32((g2-g1)<<16) / Sint32(dx);
  577. bstep = Sint32((b2-b1)<<16) / Sint32(dx);
  578. for (x = 0; x < dx; ++x){
  579. Callback(surface, px, py, SDL_MapRGB(surface->format, Uint8(R>>16), Uint8(G>>16), Uint8(B>>16)) );
  580. y += dy;
  581. if (y >= dx){
  582. y -= dx;
  583. py += sdy;
  584. }
  585. px += sdx;
  586. R += rstep;
  587. G += gstep;
  588. B += bstep;
  589. }
  590. }
  591. else{
  592. rstep = Sint32((r2-r1)<<16) / Sint32(dy);
  593. gstep = Sint32((g2-g1)<<16) / Sint32(dy);
  594. bstep = Sint32((b2-b1)<<16) / Sint32(dy);
  595. for (y = 0; y < dy; ++y){
  596. Callback(surface, px, py, SDL_MapRGB(surface->format, Uint8(R>>16), Uint8(G>>16), Uint8(B>>16)) );
  597. x += dx;
  598. if (x >= dy){
  599. x -= dy;
  600. px += sdx;
  601. }
  602. py += sdy;
  603. R += rstep;
  604. G += gstep;
  605. B += bstep;
  606. }
  607. }
  608. }
  609. 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)
  610. {
  611. if (SDL_MUSTLOCK(Surface) && _sge_lock) {
  612. if (SDL_LockSurface(Surface) < 0)
  613. return;
  614. }
  615. /* Draw the line */
  616. sge_DomcLine(Surface, x1,y1, x2,y2, r1,g1,b1, r2,g2,b2, _PutPixel);
  617. /* unlock the display */
  618. if (SDL_MUSTLOCK(Surface) && _sge_lock) {
  619. SDL_UnlockSurface(Surface);
  620. }
  621. }
  622. 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)
  623. {
  624. if (SDL_MUSTLOCK(Surface) && _sge_lock)
  625. if (SDL_LockSurface(Surface) < 0)
  626. return;
  627. _sge_alpha_hack = alpha;
  628. /* Draw the line */
  629. sge_DomcLine(Surface, x1,y1, x2,y2, r1,g1,b1, r2,g2,b2, callback_alpha_hack);
  630. /* unlock the display */
  631. if (SDL_MUSTLOCK(Surface) && _sge_lock) {
  632. SDL_UnlockSurface(Surface);
  633. }
  634. }
  635. //==================================================================================
  636. // Draws a anti-aliased multicolored line
  637. //==================================================================================
  638. 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)
  639. {
  640. Uint32 erracc=0, erradj;
  641. Uint32 erracctmp, wgt;
  642. Sint16 tmp, y0p1, x0pxdir;
  643. Uint8 a;
  644. /* Keep on working with 32bit numbers */
  645. Sint32 xx0=x1;
  646. Sint32 yy0=y1;
  647. Sint32 xx1=x2;
  648. Sint32 yy1=y2;
  649. /* Reorder points if required */
  650. if (yy0 > yy1) {
  651. SWAP(yy0, yy1, tmp);
  652. SWAP(xx0, xx1, tmp);
  653. SWAP(r1, r2, a);
  654. SWAP(g1, g2, a);
  655. SWAP(b1, b2, a);
  656. }
  657. /* Calculate distance */
  658. Sint16 dx = xx1 - xx0;
  659. Sint16 dy = yy1 - yy0;
  660. /* Adjust for negative dx and set xdir */
  661. Sint16 xdir=1;
  662. if (dx < 0) {
  663. xdir=-1;
  664. dx=(-dx);
  665. }
  666. /* Check for special cases */
  667. if (dx==0 || dy==0 || dx==dy) {
  668. sge_mcLineAlpha(dst, x1, y1, x2, y2, r1, g1, b1, r2, g2, b2, alpha);
  669. return;
  670. }
  671. /* We use fixedpoint math for the color fading */
  672. Sint32 R = r1<<16;
  673. Sint32 G = g1<<16;
  674. Sint32 B = b1<<16;
  675. Sint32 rstep;
  676. Sint32 gstep;
  677. Sint32 bstep;
  678. float alpha_pp = float(alpha)/255; /* Used to calculate alpha level if alpha != 255 */
  679. Uint32 intshift = 32 - AAbits; /* # of bits by which to shift erracc to get intensity level */
  680. if(alpha==255)
  681. _PutPixel(dst,x1,y1, SDL_MapRGB(dst->format, r1, g1, b1) ); /* Draw the initial pixel in the foreground color */
  682. else
  683. _PutPixelAlpha(dst,x1,y1, SDL_MapRGB(dst->format, r1, g1, b1), alpha);
  684. /* x-major or y-major? */
  685. if (dy > dx) {
  686. /* y-major. Calculate 16-bit fixed point fractional part of a pixel that
  687. X advances every time Y advances 1 pixel, truncating the result so that
  688. we won't overrun the endpoint along the X axis */
  689. erradj = ((dx << 16) / dy)<<16;
  690. rstep = Sint32((r2-r1)<<16) / Sint32(dy);
  691. gstep = Sint32((g2-g1)<<16) / Sint32(dy);
  692. bstep = Sint32((b2-b1)<<16) / Sint32(dy);
  693. /* draw all pixels other than the first and last */
  694. x0pxdir=xx0+xdir;
  695. while (--dy) {
  696. R += rstep;
  697. G += gstep;
  698. B += bstep;
  699. erracctmp = erracc;
  700. erracc += erradj;
  701. if (erracc <= erracctmp) {
  702. /* rollover in error accumulator, x coord advances */
  703. xx0=x0pxdir;
  704. x0pxdir += xdir;
  705. }
  706. ++yy0; /* y-major so always advance Y */
  707. /* the AAbits most significant bits of erracc give us the intensity
  708. weighting for this pixel, and the complement of the weighting for
  709. the paired pixel. */
  710. wgt = (erracc >> intshift) & 255;
  711. a = Uint8(255-wgt);
  712. if(alpha != 255)
  713. a = Uint8(a*alpha_pp);
  714. _PutPixelAlpha(dst,xx0,yy0,SDL_MapRGB(dst->format, Uint8(R>>16), Uint8(G>>16), Uint8(B>>16)),a);
  715. a = Uint8(wgt);
  716. if(alpha != 255)
  717. a = Uint8(a*alpha_pp);
  718. _PutPixelAlpha(dst,x0pxdir,yy0,SDL_MapRGB(dst->format, Uint8(R>>16), Uint8(G>>16), Uint8(B>>16)),a);
  719. }
  720. } else {
  721. /* x-major line. Calculate 16-bit fixed-point fractional part of a pixel
  722. that Y advances each time X advances 1 pixel, truncating the result so
  723. that we won't overrun the endpoint along the X axis. */
  724. erradj = ((dy << 16) / dx)<<16;
  725. rstep = Sint32((r2-r1)<<16) / Sint32(dx);
  726. gstep = Sint32((g2-g1)<<16) / Sint32(dx);
  727. bstep = Sint32((b2-b1)<<16) / Sint32(dx);
  728. /* draw all pixels other than the first and last */
  729. y0p1=yy0+1;
  730. while (--dx) {
  731. R += rstep;
  732. G += gstep;
  733. B += bstep;
  734. erracctmp = erracc;
  735. erracc += erradj;
  736. if (erracc <= erracctmp) {
  737. /* Accumulator turned over, advance y */
  738. yy0=y0p1;
  739. ++y0p1;
  740. }
  741. xx0 += xdir; /* x-major so always advance X */
  742. /* the AAbits most significant bits of erracc give us the intensity
  743. weighting for this pixel, and the complement of the weighting for
  744. the paired pixel. */
  745. wgt = (erracc >> intshift) & 255;
  746. a = Uint8(255-wgt);
  747. if(alpha != 255)
  748. a = Uint8(a*alpha_pp);
  749. _PutPixelAlpha(dst,xx0,yy0,SDL_MapRGB(dst->format, Uint8(R>>16), Uint8(G>>16), Uint8(B>>16)),a);
  750. a = Uint8(wgt);
  751. if(alpha != 255)
  752. a = Uint8(a*alpha_pp);
  753. _PutPixelAlpha(dst,xx0,y0p1,SDL_MapRGB(dst->format, Uint8(R>>16), Uint8(G>>16), Uint8(B>>16)),a);
  754. }
  755. }
  756. /* Draw final pixel, always exactly intersected by the line and doesn't
  757. need to be weighted. */
  758. if(alpha==255)
  759. _PutPixel(dst,x2,y2, SDL_MapRGB(dst->format,r2, g2, b2));
  760. else
  761. _PutPixelAlpha(dst,x2,y2, SDL_MapRGB(dst->format,r2, g2, b2), alpha);
  762. }
  763. 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)
  764. {
  765. if ( SDL_MUSTLOCK(dst) && _sge_lock )
  766. if ( SDL_LockSurface(dst) < 0 )
  767. return;
  768. _AAmcLineAlpha(dst, x1, y1, x2, y2, r1, g1, b1, r2, g2, b2, alpha);
  769. if (SDL_MUSTLOCK(dst) && _sge_lock)
  770. SDL_UnlockSurface(dst);
  771. }
  772. 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)
  773. {
  774. sge_AAmcLineAlpha(Surface, x1,y1, x2,y2, r1,g1,b1, r2,g2,b2, SDL_ALPHA_OPAQUE);
  775. }
  776. /**********************************************************************************/
  777. /** Figure functions **/
  778. /**********************************************************************************/
  779. //==================================================================================
  780. // Draws a rectangle
  781. //==================================================================================
  782. void sge_Rect(SDL_Surface *Surface, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint32 color)
  783. {
  784. _HLine(Surface,x1,x2,y1,color);
  785. _HLine(Surface,x1,x2,y2,color);
  786. _VLine(Surface,x1,y1,y2,color);
  787. _VLine(Surface,x2,y1,y2,color);
  788. }
  789. //==================================================================================
  790. // Draws a rectangle (RGB)
  791. //==================================================================================
  792. void sge_Rect(SDL_Surface *Surface, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint8 R, Uint8 G, Uint8 B)
  793. {
  794. sge_Rect(Surface,x1,y1,x2,y2, SDL_MapRGB(Surface->format, R, G, B));
  795. }
  796. //==================================================================================
  797. // Draws a rectangle (alpha)
  798. //==================================================================================
  799. void sge_RectAlpha(SDL_Surface *Surface, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint32 color, Uint8 alpha)
  800. {
  801. if (SDL_MUSTLOCK(Surface) && _sge_lock)
  802. if (SDL_LockSurface(Surface) < 0)
  803. return;
  804. _HLineAlpha(Surface,x1,x2,y1,color,alpha);
  805. _HLineAlpha(Surface,x1,x2,y2,color,alpha);
  806. _VLineAlpha(Surface,x1,y1,y2,color,alpha);
  807. _VLineAlpha(Surface,x2,y1,y2,color,alpha);
  808. if (SDL_MUSTLOCK(Surface) && _sge_lock) {
  809. SDL_UnlockSurface(Surface);
  810. }
  811. }
  812. //==================================================================================
  813. // Draws a rectangle (RGB)
  814. //==================================================================================
  815. void sge_RectAlpha(SDL_Surface *Surface, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint8 R, Uint8 G, Uint8 B, Uint8 alpha)
  816. {
  817. sge_RectAlpha(Surface,x1,y1,x2,y2, SDL_MapRGB(Surface->format, R, G, B), alpha);
  818. }
  819. //==================================================================================
  820. // Draws a filled rectangle
  821. //==================================================================================
  822. void sge_FilledRect(SDL_Surface *Surface, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint32 color)
  823. {
  824. Sint16 tmp;
  825. if(x1>x2){
  826. tmp=x1; x1=x2; x2=tmp;
  827. }
  828. if(y1>y2){
  829. tmp=y1; y1=y2; y2=tmp;
  830. }
  831. #if SDL_VERSIONNUM(SDL_MAJOR_VERSION, SDL_MINOR_VERSION, SDL_PATCHLEVEL) < \
  832. SDL_VERSIONNUM(1, 1, 5)
  833. if(x2<Surface->clip_minx || x1>Surface->clip_maxx || y2<Surface->clip_miny || y1>Surface->clip_maxy)
  834. return;
  835. if (x1 < Surface->clip_minx)
  836. x1=Surface->clip_minx;
  837. if (x2 > Surface->clip_maxx)
  838. x2=Surface->clip_maxx;
  839. if (y1 < Surface->clip_miny)
  840. y1=Surface->clip_miny;
  841. if (y2 > Surface->clip_maxy)
  842. y2=Surface->clip_maxy;
  843. #endif
  844. SDL_Rect area;
  845. area.x=x1; area.y=y1;
  846. area.w=x2-x1+1; area.h=y2-y1+1;
  847. SDL_FillRect(Surface,&area,color);
  848. }
  849. //==================================================================================
  850. // Draws a filled rectangle (RGB)
  851. //==================================================================================
  852. void sge_FilledRect(SDL_Surface *Surface, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint8 R, Uint8 G, Uint8 B)
  853. {
  854. sge_FilledRect(Surface,x1,y1,x2,y2, SDL_MapRGB(Surface->format, R, G, B));
  855. }
  856. //==================================================================================
  857. // Draws a filled rectangle (alpha)
  858. //==================================================================================
  859. void sge_FilledRectAlpha(SDL_Surface *surface, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint32 color, Uint8 alpha)
  860. {
  861. /*if( alpha == 255 ){
  862. sge_FilledRect(surface,x1,y1,x2,y2,color);
  863. return;
  864. }*/
  865. /* Fix coords */
  866. Sint16 tmp;
  867. if(x1>x2){
  868. tmp=x1; x1=x2; x2=tmp;
  869. }
  870. if(y1>y2){
  871. tmp=y1; y1=y2; y2=tmp;
  872. }
  873. /* Clipping */
  874. if(x2<sge_clip_xmin(surface) || x1>sge_clip_xmax(surface) || y2<sge_clip_ymin(surface) || y1>sge_clip_ymax(surface))
  875. return;
  876. if (x1 < sge_clip_xmin(surface))
  877. x1 = sge_clip_xmin(surface);
  878. if (x2 > sge_clip_xmax(surface))
  879. x2 = sge_clip_xmax(surface);
  880. if (y1 < sge_clip_ymin(surface))
  881. y1 = sge_clip_ymin(surface);
  882. if (y2 > sge_clip_ymax(surface))
  883. y2 = sge_clip_ymax(surface);
  884. Uint32 Rmask = surface->format->Rmask, Gmask = surface->format->Gmask, Bmask = surface->format->Bmask, Amask = surface->format->Amask;
  885. Uint32 R,G,B,A=0;
  886. Sint16 x,y;
  887. if (SDL_MUSTLOCK(surface) && _sge_lock)
  888. if (SDL_LockSurface(surface) < 0)
  889. return;
  890. switch (surface->format->BytesPerPixel) {
  891. case 2: { /* Probably 15-bpp or 16-bpp */
  892. Uint16 *row, *pixel;
  893. Uint32 dR=(color & Rmask),dG=(color & Gmask),dB=(color & Bmask),dA=(color & Amask);
  894. for(y = y1; y<=y2; ++y){
  895. row = (Uint16 *)surface->pixels + y*surface->pitch/2;
  896. for(x = x1; x <= x2; ++x){
  897. pixel = row + x;
  898. R = ((*pixel & Rmask) + (( dR - (*pixel & Rmask) ) * alpha >> 8)) & Rmask;
  899. G = ((*pixel & Gmask) + (( dG - (*pixel & Gmask) ) * alpha >> 8)) & Gmask;
  900. B = ((*pixel & Bmask) + (( dB - (*pixel & Bmask) ) * alpha >> 8)) & Bmask;
  901. if( Amask )
  902. A = ((*pixel & Amask) + (( dA - (*pixel & Amask) ) * alpha >> 8)) & Amask;
  903. *pixel= R | G | B | A;
  904. }
  905. }
  906. }
  907. break;
  908. case 4: { /* Probably 32-bpp */
  909. Uint32 *row, *pixel;
  910. Uint32 dR=(color & Rmask),dG=(color & Gmask),dB=(color & Bmask),dA=(color & Amask);
  911. for(y = y1; y<=y2; ++y){
  912. row = (Uint32 *)surface->pixels + y*surface->pitch/4;
  913. for(x = x1; x <= x2; ++x){
  914. pixel = row + x;
  915. R = ((*pixel & Rmask) + (( dR - (*pixel & Rmask) ) * alpha >> 8)) & Rmask;
  916. G = ((*pixel & Gmask) + (( dG - (*pixel & Gmask) ) * alpha >> 8)) & Gmask;
  917. B = ((*pixel & Bmask) + (( dB - (*pixel & Bmask) ) * alpha >> 8)) & Bmask;
  918. if( Amask )
  919. A = ((*pixel & Amask) + (( dA - (*pixel & Amask) ) * alpha >> 8)) & Amask;
  920. *pixel= R | G | B | A;
  921. }
  922. }
  923. }
  924. break;
  925. }
  926. if (SDL_MUSTLOCK(surface) && _sge_lock) {
  927. SDL_UnlockSurface(surface);
  928. }
  929. }
  930. void sge_FilledRectAlpha(SDL_Surface *Surface, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint8 R, Uint8 G, Uint8 B, Uint8 alpha)
  931. {
  932. sge_FilledRectAlpha(Surface,x1,y1,x2,y2, SDL_MapRGB(Surface->format, R, G, B), alpha);
  933. }
  934. //==================================================================================
  935. // Performs Callback at each ellipse point.
  936. // (from Allegro)
  937. //==================================================================================
  938. 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) )
  939. {
  940. int ix, iy;
  941. int h, i, j, k;
  942. int oh, oi, oj, ok;
  943. if (rx < 1)
  944. rx = 1;
  945. if (ry < 1)
  946. ry = 1;
  947. h = i = j = k = 0xFFFF;
  948. if (rx > ry) {
  949. ix = 0;
  950. iy = rx * 64;
  951. do {
  952. oh = h;
  953. oi = i;
  954. oj = j;
  955. ok = k;
  956. h = (ix + 32) >> 6;
  957. i = (iy + 32) >> 6;
  958. j = (h * ry) / rx;
  959. k = (i * ry) / rx;
  960. if (((h != oh) || (k != ok)) && (h < oi)) {
  961. Callback(Surface, x+h, y+k, color);
  962. if (h)
  963. Callback(Surface, x-h, y+k, color);
  964. if (k) {
  965. Callback(Surface, x+h, y-k, color);
  966. if (h)
  967. Callback(Surface, x-h, y-k, color);
  968. }
  969. }
  970. if (((i != oi) || (j != oj)) && (h < i)) {
  971. Callback(Surface, x+i, y+j, color);
  972. if (i)
  973. Callback(Surface, x-i, y+j, color);
  974. if (j) {
  975. Callback(Surface, x+i, y-j, color);
  976. if (i)
  977. Callback(Surface, x-i, y-j, color);
  978. }
  979. }
  980. ix = ix + iy / rx;
  981. iy = iy - ix / rx;
  982. } while (i > h);
  983. }
  984. else {
  985. ix = 0;
  986. iy = ry * 64;
  987. do {
  988. oh = h;
  989. oi = i;
  990. oj = j;
  991. ok = k;
  992. h = (ix + 32) >> 6;
  993. i = (iy + 32) >> 6;
  994. j = (h * rx) / ry;
  995. k = (i * rx) / ry;
  996. if (((j != oj) || (i != oi)) && (h < i)) {
  997. Callback(Surface, x+j, y+i, color);
  998. if (j)
  999. Callback(Surface, x-j, y+i, color);
  1000. if (i) {
  1001. Callback(Surface, x+j, y-i, color);
  1002. if (j)
  1003. Callback(Surface, x-j, y-i, color);
  1004. }
  1005. }
  1006. if (((k != ok) || (h != oh)) && (h < oi)) {
  1007. Callback(Surface, x+k, y+h, color);
  1008. if (k)
  1009. Callback(Surface, x-k, y+h, color);
  1010. if (h) {
  1011. Callback(Surface, x+k, y-h, color);
  1012. if (k)
  1013. Callback(Surface, x-k, y-h, color);
  1014. }
  1015. }
  1016. ix = ix + iy / ry;
  1017. iy = iy - ix / ry;
  1018. } while(i > h);
  1019. }
  1020. }
  1021. //==================================================================================
  1022. // Performs Callback at each ellipse point. (RGB)
  1023. //==================================================================================
  1024. 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) )
  1025. {
  1026. sge_DoEllipse(Surface,x,y,rx,ry,SDL_MapRGB(Surface->format, R, G, B),Callback);
  1027. }
  1028. //==================================================================================
  1029. // Draws an ellipse
  1030. //==================================================================================
  1031. void sge_Ellipse(SDL_Surface *Surface, Sint16 x, Sint16 y, Sint16 rx, Sint16 ry, Uint32 color)
  1032. {
  1033. if (SDL_MUSTLOCK(Surface) && _sge_lock) {
  1034. if (SDL_LockSurface(Surface) < 0)
  1035. return;
  1036. }
  1037. sge_DoEllipse(Surface, x, y, rx, ry, color, _PutPixel);
  1038. if (SDL_MUSTLOCK(Surface) && _sge_lock) {
  1039. SDL_UnlockSurface(Surface);
  1040. }
  1041. }
  1042. //==================================================================================
  1043. // Draws an ellipse (RGB)
  1044. //==================================================================================
  1045. void sge_Ellipse(SDL_Surface *Surface, Sint16 x, Sint16 y, Sint16 rx, Sint16 ry, Uint8 R, Uint8 G, Uint8 B)
  1046. {
  1047. sge_Ellipse(Surface,x,y,rx,ry,SDL_MapRGB(Surface->format, R, G, B));
  1048. }
  1049. //==================================================================================
  1050. // Draws an ellipse (alpha)
  1051. //==================================================================================
  1052. void sge_EllipseAlpha(SDL_Surface *Surface, Sint16 x, Sint16 y, Sint16 rx, Sint16 ry, Uint32 color, Uint8 alpha)
  1053. {
  1054. if (SDL_MUSTLOCK(Surface) && _sge_lock)
  1055. if (SDL_LockSurface(Surface) < 0)
  1056. return;
  1057. _sge_alpha_hack = alpha;
  1058. sge_DoEllipse(Surface, x, y, rx, ry, color, callback_alpha_hack);
  1059. if (SDL_MUSTLOCK(Surface) && _sge_lock) {
  1060. SDL_UnlockSurface(Surface);
  1061. }
  1062. }
  1063. //==================================================================================
  1064. // Draws an ellipse (alpha - RGB)
  1065. //==================================================================================
  1066. void sge_EllipseAlpha(SDL_Surface *Surface, Sint16 x, Sint16 y, Sint16 rx, Sint16 ry, Uint8 R, Uint8 G, Uint8 B, Uint8 alpha)
  1067. {
  1068. sge_EllipseAlpha(Surface,x,y,rx,ry,SDL_MapRGB(Surface->format, R, G, B),alpha);
  1069. }
  1070. //==================================================================================
  1071. // Draws a filled ellipse
  1072. //==================================================================================
  1073. void sge_FilledEllipse(SDL_Surface *Surface, Sint16 x, Sint16 y, Sint16 rx, Sint16 ry, Uint32 color)
  1074. {
  1075. int ix, iy;
  1076. int h, i, j, k;
  1077. int oh, oi, oj, ok;
  1078. if (rx < 1)
  1079. rx = 1;
  1080. if (ry < 1)
  1081. ry = 1;
  1082. oh = oi = oj = ok = 0xFFFF;
  1083. if (rx > ry) {
  1084. ix = 0;
  1085. iy = rx * 64;
  1086. do {
  1087. h = (ix + 32) >> 6;
  1088. i = (iy + 32) >> 6;
  1089. j = (h * ry) / rx;
  1090. k = (i * ry) / rx;
  1091. if ((k!=ok) && (k!=oj)) {
  1092. if (k){
  1093. _HLine(Surface,x-h,x+h,y-k,color);
  1094. _HLine(Surface,x-h,x+h,y+k,color);
  1095. }else
  1096. _HLine(Surface,x-h,x+h,y,color);
  1097. ok=k;
  1098. }
  1099. if ((j!=oj) && (j!=ok) && (k!=j)) {
  1100. if (j){
  1101. _HLine(Surface,x-i,x+i,y-j,color);
  1102. _HLine(Surface,x-i,x+i,y+j,color);
  1103. }else
  1104. _HLine(Surface,x-i,x+i,y,color);
  1105. oj=j;
  1106. }
  1107. ix = ix + iy / rx;
  1108. iy = iy - ix / rx;
  1109. } while (i > h);
  1110. }
  1111. else {
  1112. ix = 0;
  1113. iy = ry * 64;
  1114. do {
  1115. h = (ix + 32) >> 6;
  1116. i = (iy + 32) >> 6;
  1117. j = (h * rx) / ry;
  1118. k = (i * rx) / ry;
  1119. if ((i!=oi) && (i!=oh)) {
  1120. if (i){
  1121. _HLine(Surface,x-j,x+j,y-i,color);
  1122. _HLine(Surface,x-j,x+j,y+i,color);
  1123. }else
  1124. _HLine(Surface,x-j,x+j,y,color);
  1125. oi=i;
  1126. }
  1127. if ((h!=oh) && (h!=oi) && (i!=h)) {
  1128. if (h){
  1129. _HLine(Surface,x-k,x+k,y-h,color);
  1130. _HLine(Surface,x-k,x+k,y+h,color);
  1131. }else
  1132. _HLine(Surface,x-k,x+k,y,color);
  1133. oh=h;
  1134. }
  1135. ix = ix + iy / ry;
  1136. iy = iy - ix / ry;
  1137. } while(i > h);
  1138. }
  1139. }
  1140. //==================================================================================
  1141. // Draws a filled ellipse (RGB)
  1142. //==================================================================================
  1143. void sge_FilledEllipse(SDL_Surface *Surface, Sint16 x, Sint16 y, Sint16 rx, Sint16 ry, Uint8 R, Uint8 G, Uint8 B)
  1144. {
  1145. sge_FilledEllipse(Surface,x,y,rx,ry,SDL_MapRGB(Surface->format, R, G, B));
  1146. }
  1147. //==================================================================================
  1148. // Draws a filled ellipse (alpha)
  1149. //==================================================================================
  1150. void sge_FilledEllipseAlpha(SDL_Surface *Surface, Sint16 x, Sint16 y, Sint16 rx, Sint16 ry, Uint32 color, Uint8 alpha)
  1151. {
  1152. int ix, iy;
  1153. int h, i, j, k;
  1154. int oh, oi, oj, ok;
  1155. if (SDL_MUSTLOCK(Surface) && _sge_lock)
  1156. if (SDL_LockSurface(Surface) < 0)
  1157. return;
  1158. if (rx < 1)
  1159. rx = 1;
  1160. if (ry < 1)
  1161. ry = 1;
  1162. oh = oi = oj = ok = 0xFFFF;
  1163. if (rx > ry) {
  1164. ix = 0;
  1165. iy = rx * 64;
  1166. do {
  1167. h = (ix + 32) >> 6;
  1168. i = (iy + 32) >> 6;
  1169. j = (h * ry) / rx;
  1170. k = (i * ry) / rx;
  1171. if ((k!=ok) && (k!=oj)) {
  1172. if (k){
  1173. _HLineAlpha(Surface,x-h,x+h,y-k,color,alpha);
  1174. _HLineAlpha(Surface,x-h,x+h,y+k,color,alpha);
  1175. }else
  1176. _HLineAlpha(Surface,x-h,x+h,y,color,alpha);
  1177. ok=k;
  1178. }
  1179. if ((j!=oj) && (j!=ok) && (k!=j)) {
  1180. if (j){
  1181. _HLineAlpha(Surface,x-i,x+i,y-j,color,alpha);
  1182. _HLineAlpha(Surface,x-i,x+i,y+j,color,alpha);
  1183. }else
  1184. _HLineAlpha(Surface,x-i,x+i,y,color,alpha);
  1185. oj=j;
  1186. }
  1187. ix = ix + iy / rx;
  1188. iy = iy - ix / rx;
  1189. } while (i > h);
  1190. }
  1191. else {
  1192. ix = 0;
  1193. iy = ry * 64;
  1194. do {
  1195. h = (ix + 32) >> 6;
  1196. i = (iy + 32) >> 6;
  1197. j = (h * rx) / ry;
  1198. k = (i * rx) / ry;
  1199. if ((i!=oi) && (i!=oh)) {
  1200. if (i){
  1201. _HLineAlpha(Surface,x-j,x+j,y-i,color,alpha);
  1202. _HLineAlpha(Surface,x-j,x+j,y+i,color,alpha);
  1203. }else
  1204. _HLineAlpha(Surface,x-j,x+j,y,color,alpha);
  1205. oi=i;
  1206. }
  1207. if ((h!=oh) && (h!=oi) && (i!=h)) {
  1208. if (h){
  1209. _HLineAlpha(Surface,x-k,x+k,y-h,color,alpha);
  1210. _HLineAlpha(Surface,x-k,x+k,y+h,color,alpha);
  1211. }else
  1212. _HLineAlpha(Surface,x-k,x+k,y,color,alpha);
  1213. oh=h;
  1214. }
  1215. ix = ix + iy / ry;
  1216. iy = iy - ix / ry;
  1217. } while(i > h);
  1218. }
  1219. if (SDL_MUSTLOCK(Surface) && _sge_lock) {
  1220. SDL_UnlockSurface(Surface);
  1221. }
  1222. }
  1223. //==================================================================================
  1224. // Draws a filled ellipse (alpha - RGB)
  1225. //==================================================================================
  1226. void sge_FilledEllipseAlpha(SDL_Surface *Surface, Sint16 x, Sint16 y, Sint16 rx, Sint16 ry, Uint8 R, Uint8 G, Uint8 B, Uint8 alpha)
  1227. {
  1228. sge_FilledEllipseAlpha(Surface,x,y,rx,ry,SDL_MapRGB(Surface->format, R, G, B),alpha);
  1229. }
  1230. //==================================================================================
  1231. // Draws an anti-aliased ellipse (alpha)
  1232. // Some of this code is taken from "TwinLib" (http://www.twinlib.org) written by
  1233. // Nicolas Roard (nicolas@roard.com)
  1234. //==================================================================================
  1235. void sge_AAEllipseAlpha(SDL_Surface *surface, Sint16 xc, Sint16 yc, Sint16 rx, Sint16 ry, Uint32 color, Uint8 alpha)
  1236. {
  1237. /* Sanity check */
  1238. if (rx < 1)
  1239. rx = 1;
  1240. if (ry < 1)
  1241. ry = 1;
  1242. int a2 = rx * rx;
  1243. int b2 = ry * ry;
  1244. int ds = 2 * a2;
  1245. int dt = 2 * b2;
  1246. int dxt = int (a2 / sqrt(a2 + b2));
  1247. int t = 0;
  1248. int s = -2 * a2 * ry;
  1249. int d = 0;
  1250. Sint16 x = xc;
  1251. Sint16 y = yc - ry;
  1252. Sint16 xs, ys, dyt;
  1253. float cp, is, ip, imax = 1.0;
  1254. Uint8 s_alpha, p_alpha;
  1255. float alpha_pp = float(alpha)/255;
  1256. /* Lock surface */
  1257. if ( SDL_MUSTLOCK(surface) && _sge_lock )
  1258. if ( SDL_LockSurface(surface) < 0 )
  1259. return;
  1260. /* "End points" */
  1261. _PutPixelAlpha(surface, x, y, color, alpha);
  1262. _PutPixelAlpha(surface, 2*xc-x, y, color, alpha);
  1263. _PutPixelAlpha(surface, x, 2*yc-y, color, alpha);
  1264. _PutPixelAlpha(surface, 2*xc-x, 2*yc-y, color, alpha);
  1265. int i;
  1266. for (i = 1; i <= dxt; ++i)
  1267. {
  1268. --x;
  1269. d += t - b2;
  1270. if (d >= 0)
  1271. ys = y - 1;
  1272. else if ((d - s - a2) > 0)
  1273. {
  1274. if ((2 * d - s - a2) >= 0)
  1275. ys = y + 1;
  1276. else
  1277. {
  1278. ys = y;
  1279. ++y;
  1280. d -= s + a2;
  1281. s += ds;
  1282. }
  1283. }
  1284. else
  1285. {
  1286. ++y;
  1287. ys = y + 1;
  1288. d -= s + a2;
  1289. s += ds;
  1290. }
  1291. t -= dt;
  1292. /* Calculate alpha */
  1293. cp = float(abs(d)) / abs(s);
  1294. is = float( cp * imax + 0.1 );
  1295. ip = float( imax - is + 0.2 );
  1296. /* Overflow check */
  1297. if( is > 1.0 )
  1298. is = 1.0;
  1299. if( ip > 1.0 )
  1300. ip = 1.0;
  1301. /* Calculate alpha level */
  1302. s_alpha = Uint8(is*255);
  1303. p_alpha = Uint8(ip*255);
  1304. if( alpha != 255 ){
  1305. s_alpha = Uint8(s_alpha*alpha_pp);
  1306. p_alpha = Uint8(p_alpha*alpha_pp);
  1307. }
  1308. /* Upper half */
  1309. _PutPixelAlpha(surface, x, y, color, p_alpha);
  1310. _PutPixelAlpha(surface, 2*xc-x, y, color, p_alpha);
  1311. _PutPixelAlpha(surface, x, ys, color, s_alpha);
  1312. _PutPixelAlpha(surface, 2*xc-x, ys, color, s_alpha);
  1313. /* Lower half */
  1314. _PutPixelAlpha(surface, x, 2*yc-y, color, p_alpha);
  1315. _PutPixelAlpha(surface, 2*xc-x, 2*yc-y, color, p_alpha);
  1316. _PutPixelAlpha(surface, x, 2*yc-ys, color, s_alpha);
  1317. _PutPixelAlpha(surface, 2*xc-x, 2*yc-ys, color, s_alpha);
  1318. }
  1319. dyt = abs(y - yc);
  1320. for (i = 1; i <= dyt; ++i)
  1321. {
  1322. ++y;
  1323. d -= s + a2;
  1324. if (d <= 0)
  1325. xs = x + 1;
  1326. else if ((d + t - b2) < 0)
  1327. {
  1328. if ((2 * d + t - b2) <= 0)
  1329. xs = x - 1;
  1330. else
  1331. {
  1332. xs = x;
  1333. --x;
  1334. d += t - b2;
  1335. t -= dt;
  1336. }
  1337. }
  1338. else
  1339. {
  1340. --x;
  1341. xs = x - 1;
  1342. d += t - b2;
  1343. t -= dt;
  1344. }
  1345. s += ds;
  1346. /* Calculate alpha */
  1347. cp = float(abs(d)) / abs(t);
  1348. is = float( cp * imax + 0.1 );
  1349. ip = float( imax - is + 0.2 );
  1350. /* Overflow check */
  1351. if( is > 1.0 )
  1352. is = 1.0;
  1353. if( ip > 1.0 )
  1354. ip = 1.0;
  1355. /* Calculate alpha level */
  1356. s_alpha = Uint8(is*255);
  1357. p_alpha = Uint8(ip*255);
  1358. if( alpha != 255 ){
  1359. s_alpha = Uint8(s_alpha*alpha_pp);
  1360. p_alpha = Uint8(p_alpha*alpha_pp);
  1361. }
  1362. /* Upper half */
  1363. _PutPixelAlpha(surface, x, y, color, p_alpha);
  1364. _PutPixelAlpha(surface, 2*xc-x, y, color, p_alpha);
  1365. _PutPixelAlpha(surface, xs, y, color, s_alpha);
  1366. _PutPixelAlpha(surface, 2*xc-xs, y, color, s_alpha);
  1367. /* Lower half*/
  1368. _PutPixelAlpha(surface, x, 2*yc-y, color, p_alpha);
  1369. _PutPixelAlpha(surface, 2*xc-x, 2*yc-y, color, p_alpha);
  1370. _PutPixelAlpha(surface, xs, 2*yc-y, color, s_alpha);
  1371. _PutPixelAlpha(surface, 2*xc-xs, 2*yc-y, color, s_alpha);
  1372. }
  1373. /* unlock surface */
  1374. if (SDL_MUSTLOCK(surface) && _sge_lock) {
  1375. SDL_UnlockSurface(surface);
  1376. }
  1377. }
  1378. //==================================================================================
  1379. // Draws an anti-aliased ellipse (alpha - RGB)
  1380. //==================================================================================
  1381. void sge_AAEllipseAlpha(SDL_Surface *surface, Sint16 xc, Sint16 yc, Sint16 rx, Sint16 ry, Uint8 R, Uint8 G, Uint8 B, Uint8 alpha)
  1382. {
  1383. sge_AAEllipseAlpha(surface,xc,yc,rx,ry,SDL_MapRGB(surface->format, R, G, B),alpha);
  1384. }
  1385. //==================================================================================
  1386. // Draws an anti-aliased ellipse
  1387. //==================================================================================
  1388. void sge_AAEllipse(SDL_Surface *surface, Sint16 xc, Sint16 yc, Sint16 rx, Sint16 ry, Uint32 color)
  1389. {
  1390. sge_AAEllipseAlpha(surface,xc,yc,rx,ry,color,255);
  1391. }
  1392. //==================================================================================
  1393. // Draws an anti-aliased ellipse (RGB)
  1394. //==================================================================================
  1395. void sge_AAEllipse(SDL_Surface *surface, Sint16 xc, Sint16 yc, Sint16 rx, Sint16 ry, Uint8 R, Uint8 G, Uint8 B)
  1396. {
  1397. sge_AAEllipseAlpha(surface,xc,yc,rx,ry,SDL_MapRGB(surface->format, R, G, B),255);
  1398. }
  1399. //==================================================================================
  1400. // Draws a filled anti-aliased ellipse
  1401. // This is just a quick hack...
  1402. //==================================================================================
  1403. void sge_AAFilledEllipse(SDL_Surface *surface, Sint16 xc, Sint16 yc, Sint16 rx, Sint16 ry, Uint32 color)
  1404. {
  1405. /* Sanity check */
  1406. if (rx < 1)
  1407. rx = 1;
  1408. if (ry < 1)
  1409. ry = 1;
  1410. int a2 = rx * rx;
  1411. int b2 = ry * ry;
  1412. int ds = 2 * a2;
  1413. int dt = 2 * b2;
  1414. int dxt = int (a2 / sqrt(a2 + b2));
  1415. int t = 0;
  1416. int s = -2 * a2 * ry;
  1417. int d = 0;
  1418. Sint16 x = xc;
  1419. Sint16 y = yc - ry;
  1420. Sint16 xs, ys, dyt;
  1421. float cp, is, ip, imax = 1.0;
  1422. /* Lock surface */
  1423. if ( SDL_MUSTLOCK(surface) && _sge_lock )
  1424. if ( SDL_LockSurface(surface) < 0 )
  1425. return;
  1426. /* "End points" */
  1427. _PutPixel(surface, x, y, color);
  1428. _PutPixel(surface, 2*xc-x, y, color);
  1429. _PutPixel(surface, x, 2*yc-y, color);
  1430. _PutPixel(surface, 2*xc-x, 2*yc-y, color);
  1431. /* unlock surface */
  1432. if (SDL_MUSTLOCK(surface) && _sge_lock)
  1433. SDL_UnlockSurface(surface);
  1434. _VLine(surface, x, y+1, 2*yc-y-1, color);
  1435. int i;
  1436. for (i = 1; i <= dxt; ++i)
  1437. {
  1438. --x;
  1439. d += t - b2;
  1440. if (d >= 0)
  1441. ys = y - 1;
  1442. else if ((d - s - a2) > 0)
  1443. {
  1444. if ((2 * d - s - a2) >= 0)
  1445. ys = y + 1;
  1446. else
  1447. {
  1448. ys = y;
  1449. ++y;
  1450. d -= s + a2;
  1451. s += ds;
  1452. }
  1453. }
  1454. else
  1455. {
  1456. ++y;
  1457. ys = y + 1;
  1458. d -= s + a2;
  1459. s += ds;
  1460. }
  1461. t -= dt;
  1462. /* Calculate alpha */
  1463. cp = (float) abs(d) / abs(s);
  1464. is = cp * imax;
  1465. ip = imax - is;
  1466. /* Lock surface */
  1467. if ( SDL_MUSTLOCK(surface) && _sge_lock )
  1468. if ( SDL_LockSurface(surface) < 0 )
  1469. return;
  1470. /* Upper half */
  1471. _PutPixelAlpha(surface, x, y, color, Uint8(ip*255));
  1472. _PutPixelAlpha(surface, 2*xc-x, y, color, Uint8(ip*255));
  1473. _PutPixelAlpha(surface, x, ys, color, Uint8(is*255));
  1474. _PutPixelAlpha(surface, 2*xc-x, ys, color, Uint8(is*255));
  1475. /* Lower half */
  1476. _PutPixelAlpha(surface, x, 2*yc-y, color, Uint8(ip*255));
  1477. _PutPixelAlpha(surface, 2*xc-x, 2*yc-y, color, Uint8(ip*255));
  1478. _PutPixelAlpha(surface, x, 2*yc-ys, color, Uint8(is*255));
  1479. _PutPixelAlpha(surface, 2*xc-x, 2*yc-ys, color, Uint8(is*255));
  1480. /* unlock surface */
  1481. if (SDL_MUSTLOCK(surface) && _sge_lock)
  1482. SDL_UnlockSurface(surface);
  1483. /* Fill */
  1484. _VLine(surface, x, y+1, 2*yc-y-1, color);
  1485. _VLine(surface, 2*xc-x, y+1, 2*yc-y-1, color);
  1486. _VLine(surface, x, ys+1, 2*yc-ys-1, color);
  1487. _VLine(surface, 2*xc-x, ys+1, 2*yc-ys-1, color);
  1488. }
  1489. dyt = abs(y - yc);
  1490. for (i = 1; i <= dyt; ++i)
  1491. {
  1492. ++y;
  1493. d -= s + a2;
  1494. if (d <= 0)
  1495. xs = x + 1;
  1496. else if ((d + t - b2) < 0)
  1497. {
  1498. if ((2 * d + t - b2) <= 0)
  1499. xs = x - 1;
  1500. else
  1501. {
  1502. xs = x;
  1503. --x;
  1504. d += t - b2;
  1505. t -= dt;
  1506. }
  1507. }
  1508. else
  1509. {
  1510. --x;
  1511. xs = x - 1;
  1512. d += t - b2;
  1513. t -= dt;
  1514. }
  1515. s += ds;
  1516. /* Calculate alpha */
  1517. cp = (float) abs(d) / abs(t);
  1518. is = cp * imax;
  1519. ip = imax - is;
  1520. /* Lock surface */
  1521. if ( SDL_MUSTLOCK(surface) && _sge_lock )
  1522. if ( SDL_LockSurface(surface) < 0 )
  1523. return;
  1524. /* Upper half */
  1525. _PutPixelAlpha(surface, x, y, color, Uint8(ip*255));
  1526. _PutPixelAlpha(surface, 2*xc-x, y, color, Uint8(ip*255));
  1527. _PutPixelAlpha(surface, xs, y, color, Uint8(is*255));
  1528. _PutPixelAlpha(surface, 2*xc-xs, y, color, Uint8(is*255));
  1529. /* Lower half*/
  1530. _PutPixelAlpha(surface, x, 2*yc-y, color, Uint8(ip*255));
  1531. _PutPixelAlpha(surface, 2*xc-x, 2*yc-y, color, Uint8(ip*255));
  1532. _PutPixelAlpha(surface, xs, 2*yc-y, color, Uint8(is*255));
  1533. _PutPixelAlpha(surface, 2*xc-xs, 2*yc-y, color, Uint8(is*255));
  1534. /* unlock surface */
  1535. if (SDL_MUSTLOCK(surface) && _sge_lock)
  1536. SDL_UnlockSurface(surface);
  1537. /* Fill */
  1538. _HLine(surface, x+1, 2*xc-x-1, y, color);
  1539. _HLine(surface, xs+1, 2*xc-xs-1, y, color);
  1540. _HLine(surface, x+1, 2*xc-x-1, 2*yc-y, color);
  1541. _HLine(surface, xs+1, 2*xc-xs-1, 2*yc-y, color);
  1542. }
  1543. }
  1544. //==================================================================================
  1545. // Draws a filled anti-aliased ellipse (RGB)
  1546. //==================================================================================
  1547. void sge_AAFilledEllipse(SDL_Surface *surface, Sint16 xc, Sint16 yc, Sint16 rx, Sint16 ry, Uint8 R, Uint8 G, Uint8 B)
  1548. {
  1549. sge_AAFilledEllipse(surface,xc,yc,rx,ry,SDL_MapRGB(surface->format, R, G, B));
  1550. }
  1551. //==================================================================================
  1552. // Performs Callback at each circle point.
  1553. //==================================================================================
  1554. 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))
  1555. {
  1556. Sint16 cx = 0;
  1557. Sint16 cy = r;
  1558. Sint16 df = 1 - r;
  1559. Sint16 d_e = 3;
  1560. Sint16 d_se = -2 * r + 5;
  1561. do {
  1562. Callback(Surface, x+cx, y+cy, color);
  1563. Callback(Surface, x-cx, y+cy, color);
  1564. Callback(Surface, x+cx, y-cy, color);
  1565. Callback(Surface, x-cx, y-cy, color);
  1566. Callback(Surface, x+cy, y+cx, color);
  1567. Callback(Surface, x+cy, y-cx, color);
  1568. Callback(Surface, x-cy, y+cx, color);
  1569. Callback(Surface, x-cy, y-cx, color);
  1570. if (df < 0) {
  1571. df += d_e;
  1572. d_e += 2;
  1573. d_se += 2;
  1574. }
  1575. else {
  1576. df += d_se;
  1577. d_e += 2;
  1578. d_se += 4;
  1579. --cy;
  1580. }
  1581. ++cx;
  1582. }while(cx <= cy);
  1583. }
  1584. //==================================================================================
  1585. // Performs Callback at each circle point. (RGB)
  1586. //==================================================================================
  1587. 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))
  1588. {
  1589. sge_DoCircle(Surface,x,y,r,SDL_MapRGB(Surface->format, R, G, B),Callback);
  1590. }
  1591. //==================================================================================
  1592. // Draws a circle
  1593. //==================================================================================
  1594. void sge_Circle(SDL_Surface *Surface, Sint16 x, Sint16 y, Sint16 r, Uint32 color)
  1595. {
  1596. if (SDL_MUSTLOCK(Surface) && _sge_lock) {
  1597. if (SDL_LockSurface(Surface) < 0)
  1598. return;
  1599. }
  1600. sge_DoCircle(Surface, x, y, r, color, _PutPixel);
  1601. if (SDL_MUSTLOCK(Surface) && _sge_lock) {
  1602. SDL_UnlockSurface(Surface);
  1603. }
  1604. }
  1605. //==================================================================================
  1606. // Draws a circle (RGB)
  1607. //==================================================================================
  1608. void sge_Circle(SDL_Surface *Surface, Sint16 x, Sint16 y, Sint16 r, Uint8 R, Uint8 G, Uint8 B)
  1609. {
  1610. sge_Circle(Surface,x,y,r,SDL_MapRGB(Surface->format, R, G, B));
  1611. }
  1612. //==================================================================================
  1613. // Draws a circle (alpha)
  1614. //==================================================================================
  1615. void sge_CircleAlpha(SDL_Surface *Surface, Sint16 x, Sint16 y, Sint16 r, Uint32 color, Uint8 alpha)
  1616. {
  1617. if (SDL_MUSTLOCK(Surface) && _sge_lock)
  1618. if (SDL_LockSurface(Surface) < 0)
  1619. return;
  1620. _sge_alpha_hack = alpha;
  1621. sge_DoCircle(Surface, x, y, r, color, callback_alpha_hack);
  1622. if (SDL_MUSTLOCK(Surface) && _sge_lock) {
  1623. SDL_UnlockSurface(Surface);
  1624. }
  1625. }
  1626. //==================================================================================
  1627. // Draws a circle (alpha - RGB)
  1628. //==================================================================================
  1629. void sge_CircleAlpha(SDL_Surface *Surface, Sint16 x, Sint16 y, Sint16 r, Uint8 R, Uint8 G, Uint8 B, Uint8 alpha)
  1630. {
  1631. sge_CircleAlpha(Surface,x,y,r,SDL_MapRGB(Surface->format, R, G, B),alpha);
  1632. }
  1633. //==================================================================================
  1634. // Draws a dual-colored filled circle
  1635. //==================================================================================
  1636. void sge_FilledCircleDual(SDL_Surface *Surface, Sint16 x, Sint16 y, Sint16 r, Sint16 tweak, Uint32 color1, Uint32 color2)
  1637. {
  1638. if (SDL_MUSTLOCK(Surface) && _sge_lock) {
  1639. if (SDL_LockSurface(Surface) < 0)
  1640. return;
  1641. }
  1642. Sint16 cx = 0;
  1643. Sint16 cy = r;
  1644. Sint16 df = 1 - r;
  1645. Sint16 d_e = 3;
  1646. Sint16 d_se = -2 * r + 5;
  1647. tweak = tweak ? 1 : 0;
  1648. do {
  1649. _HLine(Surface, x+tweak, x+tweak+cx, y+tweak+cy, color2);
  1650. _HLine(Surface, x+tweak, x+tweak+cy, y+tweak+cx, color2);
  1651. _HLine(Surface, x-cx, x, y+tweak+cy, color2);
  1652. _HLine(Surface, x+tweak, x+tweak+cx, y-cy, color1);
  1653. _HLine(Surface, x+tweak, x+tweak+cx, y-cx, color1);
  1654. _HLine(Surface, x+tweak+cx, x+tweak+cy, y-cx, color2);
  1655. _HLine(Surface, x-cx, x, y+tweak+cx, color2);
  1656. _HLine(Surface, x-cy, x-cx, y+tweak+cx, color1);
  1657. _HLine(Surface, x-cx, x, y-cy, color1);
  1658. _HLine(Surface, x-cy, x, y-cx, color1);
  1659. if (df < 0) {
  1660. df += d_e;
  1661. d_e += 2;
  1662. d_se += 2;
  1663. }
  1664. else {
  1665. df += d_se;
  1666. d_e += 2;
  1667. d_se += 4;
  1668. --cy;
  1669. }
  1670. ++cx;
  1671. }while(cx <= cy);
  1672. if (SDL_MUSTLOCK(Surface) && _sge_lock) {
  1673. SDL_UnlockSurface(Surface);
  1674. }
  1675. }
  1676. //==================================================================================
  1677. // Draws a filled circle
  1678. //==================================================================================
  1679. void sge_FilledCircle(SDL_Surface *Surface, Sint16 x, Sint16 y, Sint16 r, Uint32 color)
  1680. {
  1681. Sint16 cx = 0;
  1682. Sint16 cy = r;
  1683. bool draw=true;
  1684. Sint16 df = 1 - r;
  1685. Sint16 d_e = 3;
  1686. Sint16 d_se = -2 * r + 5;
  1687. do {
  1688. if(draw){
  1689. _HLine(Surface,x-cx,x+cx,y+cy,color);
  1690. _HLine(Surface,x-cx,x+cx,y-cy,color);
  1691. draw=false;
  1692. }
  1693. if(cx!=cy){
  1694. if(cx){
  1695. _HLine(Surface,x-cy,x+cy,y-cx,color);
  1696. _HLine(Surface,x-cy,x+cy,y+cx,color);
  1697. }else
  1698. _HLine(Surface,x-cy,x+cy,y,color);
  1699. }
  1700. if (df < 0) {
  1701. df += d_e;
  1702. d_e += 2;
  1703. d_se += 2;
  1704. }
  1705. else {
  1706. df += d_se;
  1707. d_e += 2;
  1708. d_se += 4;
  1709. --cy;
  1710. draw=true;
  1711. }
  1712. ++cx;
  1713. }while(cx <= cy);
  1714. }
  1715. //==================================================================================
  1716. // Draws a filled circle (RGB)
  1717. //==================================================================================
  1718. void sge_FilledCircle(SDL_Surface *Surface, Sint16 x, Sint16 y, Sint16 r, Uint8 R, Uint8 G, Uint8 B)
  1719. {
  1720. sge_FilledCircle(Surface,x,y,r,SDL_MapRGB(Surface->format, R, G, B));
  1721. }
  1722. //==================================================================================
  1723. // Draws a filled circle (alpha)
  1724. //==================================================================================
  1725. void sge_FilledCircleAlpha(SDL_Surface *Surface, Sint16 x, Sint16 y, Sint16 r, Uint32 color, Uint8 alpha)
  1726. {
  1727. Sint16 cx = 0;
  1728. Sint16 cy = r;
  1729. bool draw=true;
  1730. Sint16 df = 1 - r;
  1731. Sint16 d_e = 3;
  1732. Sint16 d_se = -2 * r + 5;
  1733. if (SDL_MUSTLOCK(Surface) && _sge_lock)
  1734. if (SDL_LockSurface(Surface) < 0)
  1735. return;
  1736. do {
  1737. if(draw){
  1738. _HLineAlpha(Surface,x-cx,x+cx,y+cy,color,alpha);
  1739. _HLineAlpha(Surface,x-cx,x+cx,y-cy,color,alpha);
  1740. draw=false;
  1741. }
  1742. if(cx!=cy){
  1743. if(cx){
  1744. _HLineAlpha(Surface,x-cy,x+cy,y-cx,color,alpha);
  1745. _HLineAlpha(Surface,x-cy,x+cy,y+cx,color,alpha);
  1746. }else
  1747. _HLineAlpha(Surface,x-cy,x+cy,y,color,alpha);
  1748. }
  1749. if (df < 0) {
  1750. df += d_e;
  1751. d_e += 2;
  1752. d_se += 2;
  1753. }
  1754. else {
  1755. df += d_se;
  1756. d_e += 2;
  1757. d_se += 4;
  1758. --cy;
  1759. draw=true;
  1760. }
  1761. ++cx;
  1762. }while(cx <= cy);
  1763. if (SDL_MUSTLOCK(Surface) && _sge_lock) {
  1764. SDL_UnlockSurface(Surface);
  1765. }
  1766. }
  1767. //==================================================================================
  1768. // Draws a filled circle (alpha - RGB)
  1769. //==================================================================================
  1770. void sge_FilledCircleAlpha(SDL_Surface *Surface, Sint16 x, Sint16 y, Sint16 r, Uint8 R, Uint8 G, Uint8 B, Uint8 alpha)
  1771. {
  1772. sge_FilledCircleAlpha(Surface,x,y,r,SDL_MapRGB(Surface->format, R, G, B),alpha);
  1773. }
  1774. //==================================================================================
  1775. // Draws an anti-aliased circle (alpha)
  1776. //==================================================================================
  1777. void sge_AACircleAlpha(SDL_Surface *surface, Sint16 xc, Sint16 yc, Sint16 r, Uint32 color, Uint8 alpha)
  1778. {
  1779. sge_AAEllipseAlpha(surface, xc, yc, r, r, color, alpha);
  1780. }
  1781. //==================================================================================
  1782. // Draws an anti-aliased circle (alpha - RGB)
  1783. //==================================================================================
  1784. void sge_AACircleAlpha(SDL_Surface *surface, Sint16 xc, Sint16 yc, Sint16 r, Uint8 R, Uint8 G, Uint8 B, Uint8 alpha)
  1785. {
  1786. sge_AAEllipseAlpha(surface,xc,yc,r,r,SDL_MapRGB(surface->format, R, G, B),alpha);
  1787. }
  1788. //==================================================================================
  1789. // Draws an anti-aliased circle
  1790. //==================================================================================
  1791. void sge_AACircle(SDL_Surface *surface, Sint16 xc, Sint16 yc, Sint16 r, Uint32 color)
  1792. {
  1793. sge_AAEllipseAlpha(surface,xc,yc,r,r,color,255);
  1794. }
  1795. //==================================================================================
  1796. // Draws an anti-aliased circle (RGB)
  1797. //==================================================================================
  1798. void sge_AACircle(SDL_Surface *surface, Sint16 xc, Sint16 yc, Sint16 r, Uint8 R, Uint8 G, Uint8 B)
  1799. {
  1800. sge_AAEllipseAlpha(surface,xc,yc,r,r,SDL_MapRGB(surface->format, R, G, B),255);
  1801. }
  1802. //==================================================================================
  1803. // Draws a filled anti-aliased circle
  1804. //==================================================================================
  1805. void sge_AAFilledCircle(SDL_Surface *surface, Sint16 xc, Sint16 yc, Sint16 r, Uint32 color)
  1806. {
  1807. sge_AAFilledEllipse(surface, xc, yc, r, r, color);
  1808. }
  1809. //==================================================================================
  1810. // Draws a filled anti-aliased circle (RGB)
  1811. //==================================================================================
  1812. void sge_AAFilledCircle(SDL_Surface *surface, Sint16 xc, Sint16 yc, Sint16 r, Uint8 R, Uint8 G, Uint8 B)
  1813. {
  1814. sge_AAFilledEllipse(surface,xc,yc,r,r,SDL_MapRGB(surface->format, R, G, B));
  1815. }
  1816. //==================================================================================
  1817. // Draws a bezier line
  1818. //==================================================================================
  1819. /* Macro to do the line... 'function' is the line drawing routine */
  1820. #define DO_BEZIER(function)\
  1821. /*
  1822. * Note: I don't think there is any great performance win in translating this to fixed-point integer math,
  1823. * most of the time is spent in the line drawing routine.
  1824. */\
  1825. float x = float(x1), y = float(y1);\
  1826. float xp = x, yp = y;\
  1827. float delta;\
  1828. float dx, d2x, d3x;\
  1829. float dy, d2y, d3y;\
  1830. float a, b, c;\
  1831. int i;\
  1832. int n = 1;\
  1833. \
  1834. /* compute number of iterations */\
  1835. if(level < 1)\
  1836. level=1;\
  1837. if(level >= 15)\
  1838. level=15; \
  1839. while (--level >= 0)\
  1840. n*= 2;\
  1841. delta = float( 1.0 / float(n) );\
  1842. \
  1843. /* compute finite differences */\
  1844. /* a, b, c are the coefficient of the polynom in t defining the parametric curve */\
  1845. /* The computation is done independently for x and y */\
  1846. a = float(-x1 + 3*x2 - 3*x3 + x4);\
  1847. b = float(3*x1 - 6*x2 + 3*x3);\
  1848. c = float(-3*x1 + 3*x2);\
  1849. \
  1850. d3x = 6 * a * delta*delta*delta;\
  1851. d2x = d3x + 2 * b * delta*delta;\
  1852. dx = a * delta*delta*delta + b * delta*delta + c * delta;\
  1853. \
  1854. a = float(-y1 + 3*y2 - 3*y3 + y4);\
  1855. b = float(3*y1 - 6*y2 + 3*y3);\
  1856. c = float(-3*y1 + 3*y2);\
  1857. \
  1858. d3y = 6 * a * delta*delta*delta;\
  1859. d2y = d3y + 2 * b * delta*delta;\
  1860. dy = a * delta*delta*delta + b * delta*delta + c * delta;\
  1861. \
  1862. if (SDL_MUSTLOCK(surface) && _sge_lock) {\
  1863. if (SDL_LockSurface(surface) < 0)\
  1864. return;\
  1865. }\
  1866. \
  1867. /* iterate */\
  1868. for (i = 0; i < n; ++i) {\
  1869. x += dx; dx += d2x; d2x += d3x;\
  1870. y += dy; dy += d2y; d2y += d3y;\
  1871. if(Sint16(xp) != Sint16(x) || Sint16(yp) != Sint16(y)){\
  1872. function;\
  1873. }\
  1874. xp = x; yp = y;\
  1875. }\
  1876. \
  1877. /* unlock the display */\
  1878. if (SDL_MUSTLOCK(surface) && _sge_lock) {\
  1879. SDL_UnlockSurface(surface);\
  1880. }\
  1881. \
  1882. //==================================================================================
  1883. // Draws a bezier line
  1884. //==================================================================================
  1885. 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)
  1886. {
  1887. DO_BEZIER(_Line(surface, Sint16(xp),Sint16(yp), Sint16(x),Sint16(y), color));
  1888. }
  1889. //==================================================================================
  1890. // Draws a bezier line (RGB)
  1891. //==================================================================================
  1892. 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)
  1893. {
  1894. sge_Bezier(surface,x1,y1,x2,y2,x3,y3,x4,y4,level, SDL_MapRGB(surface->format,R,G,B));
  1895. }
  1896. //==================================================================================
  1897. // Draws a bezier line (alpha)
  1898. //==================================================================================
  1899. 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)
  1900. {
  1901. _sge_alpha_hack = alpha;
  1902. DO_BEZIER(sge_DoLine(surface, Sint16(xp),Sint16(yp), Sint16(x),Sint16(y), color, callback_alpha_hack));
  1903. }
  1904. //==================================================================================
  1905. // Draws a bezier line (alpha - RGB)
  1906. //==================================================================================
  1907. 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)
  1908. {
  1909. sge_BezierAlpha(surface,x1,y1,x2,y2,x3,y3,x4,y4,level, SDL_MapRGB(surface->format,R,G,B),alpha);
  1910. }
  1911. //==================================================================================
  1912. // Draws an AA bezier line (alpha)
  1913. //==================================================================================
  1914. 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)
  1915. {
  1916. Uint8 lock = _sge_lock;
  1917. _sge_lock = 0;
  1918. if (SDL_MUSTLOCK(surface) && lock)
  1919. if (SDL_LockSurface(surface) < 0)
  1920. return;
  1921. DO_BEZIER(sge_AALineAlpha(surface, Sint16(xp),Sint16(yp), Sint16(x),Sint16(y), color, alpha));
  1922. if (SDL_MUSTLOCK(surface) && lock) {
  1923. SDL_UnlockSurface(surface);
  1924. }
  1925. _sge_lock = lock;
  1926. }
  1927. //==================================================================================
  1928. // Draws an AA bezier line (alpha - RGB)
  1929. //==================================================================================
  1930. 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)
  1931. {
  1932. sge_AABezierAlpha(surface,x1,y1,x2,y2,x3,y3,x4,y4,level, SDL_MapRGB(surface->format,R,G,B),alpha);
  1933. }
  1934. //==================================================================================
  1935. // Draws an AA bezier line
  1936. //==================================================================================
  1937. 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)
  1938. {
  1939. sge_AABezierAlpha(surface, x1,y1, x2,y2, x3,y3, x4,y4, level, color, 255);
  1940. }
  1941. //==================================================================================
  1942. // Draws an AA bezier line (RGB)
  1943. //==================================================================================
  1944. 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)
  1945. {
  1946. sge_AABezierAlpha(surface,x1,y1,x2,y2,x3,y3,x4,y4,level, SDL_MapRGB(surface->format,R,G,B),255);
  1947. }