$treeview $search $mathjax
Stratagus
2.2.6
$projectbrief
|
$projectbrief
|
$searchbox |
_________ __ __ / _____// |_____________ _/ |______ ____ __ __ ______ \_____ \\ __\_ __ \__ \\ __\__ \ / ___\| | \/ ___/ / \| | | | \// __ \| | / __ \_/ /_/ > | /\___ \ /_______ /|__| |__| (____ /__| (____ /\___ /|____//____ > \/ \/ \//_____/ \/ ______________________ ______________________ T H E W A R B E G I N S Stratagus - A free fantasy real time strategy game engine
00001 #ifndef __RENDERER_H__ 00002 #define __RENDERER_H__ 00003 00004 #include <assert.h> 00005 00006 struct CPrimitives { 00007 virtual void DrawPixel(Uint32 color, int x, int y) = 0; 00008 virtual void DrawTransPixel(Uint32 color, int x, int y, 00009 unsigned char alpha) = 0; 00010 00011 virtual void DrawLine(Uint32 color, int sx, int sy, int dx, int dy) = 0; 00012 virtual void DrawTransLine(Uint32 color, int sx, int sy, 00013 int dx, int dy, unsigned char alpha) = 0; 00014 00015 virtual void DrawRectangle(Uint32 color, int x, int y, int w, int h) = 0; 00016 virtual void DrawTransRectangle(Uint32 color, int x, int y, 00017 int w, int h, unsigned char alpha) = 0; 00018 00019 virtual void FillTransRectangle(Uint32 color, int x, int y, 00020 int w, int h, unsigned char alpha) = 0; 00021 00022 virtual void DrawCircle(Uint32 color, int x, int y, int r) = 0; 00023 virtual void DrawTransCircle(Uint32 color, int x, int y, 00024 int r, unsigned char alpha) = 0; 00025 00026 virtual void FillCircle(Uint32 color, int x, int y, int r) = 0; 00027 virtual void FillTransCircle(Uint32 color, int x, int y, 00028 int r, unsigned char alpha) = 0; 00029 }; 00030 00031 namespace DRAW { 00032 template <const int BPP> 00033 static inline Uint32 GetPixel(const void *const pixels, unsigned int index) 00034 { 00035 if(BPP == 1) { 00036 return (((Uint8 *)pixels)[index]); 00037 } else if(BPP == 2) { 00038 return (((Uint16 *)pixels)[index]); 00039 } else if(BPP == 4) { 00040 return (((Uint32 *)pixels)[index]); 00041 } else { 00042 assert(0); 00043 } 00044 return 0; 00045 };// __attribute__ ((nothrow,nonnull (1))); 00046 00047 template <const int BPP> 00048 static inline void PutPixel(void *const pixels, 00049 unsigned int index, Uint32 color) 00050 { 00051 if(BPP == 1) { 00052 ((Uint8 *)pixels)[index] = color; 00053 } else if(BPP == 2) { 00054 ((Uint16 *)pixels)[index] = color; 00055 } else if(BPP == 4) { 00056 ((Uint32 *)pixels)[index] = color; 00057 } else { 00058 assert(0); 00059 } 00060 };// __attribute__ ((nothrow,nonnull (1))); 00061 00062 template <const int BPP> 00063 static inline void 00064 PutPixelDouble(void *pixels, const unsigned int index, Uint32 color) 00065 { 00066 if(BPP == 1) { 00067 color &= 0xFF; 00068 color |= color << 8; 00069 *((Uint16*)(((Uint8 *)pixels) + index)) = color; 00070 } else if(BPP == 2) { 00071 color &= 0xFFFF; 00072 color |= color << 16; 00073 *((Uint32*)(((Uint16 *)pixels) + index)) = color; 00074 } else if(BPP == 4) { 00075 Uint32 *ptr = ((Uint32 *)pixels) + index; 00076 #ifdef __x86_64__ 00077 Uint64 tmp = color; 00078 tmp <<= 32; 00079 //tmp |= color; 00080 *((Uint64*)ptr) = tmp | color; 00081 #else 00082 *ptr++ = color; 00083 *ptr = color; 00084 #endif 00085 } else { 00086 assert(0); 00087 } 00088 };// __attribute__ ((nothrow,nonnull (1))); 00089 00090 template <const int BPP> 00091 static inline void 00092 PutPixelQuatro(void *pixels, unsigned int index, Uint32 color) 00093 { 00094 if(BPP == 1) { 00095 color &= 0xFF; 00096 color |= color << 8; 00097 color |= color << 16; 00098 *((Uint32*)(((Uint8 *)pixels) + index)) = color; 00099 } else if(BPP == 2) { 00100 Uint32 *ptr = (Uint32*)(((Uint16 *)pixels) + index); 00101 color &= 0xFFFF; 00102 color |= color << 16; 00103 #ifdef __x86_64__ 00104 Uint64 tmp = color; 00105 tmp <<= 32; 00106 //tmp |= color; 00107 *((Uint64*)ptr) = tmp | color; 00108 #else 00109 *ptr++ = color; 00110 *ptr = color; 00111 #endif 00112 } else if(BPP == 4) { 00113 Uint32 *ptr = ((Uint32 *)pixels) + index; 00114 #ifdef __x86_64__ 00115 Uint64 tmp = color; 00116 tmp <<= 32; 00117 tmp |= color; 00118 *((Uint64*)ptr) = tmp; 00119 *((Uint64*)(ptr + 2)) = tmp; 00120 #else 00121 *ptr++ = color; 00122 *ptr++ = color; 00123 *ptr++ = color; 00124 *ptr = color; 00125 #endif 00126 } else { 00127 assert(0); 00128 } 00129 };// __attribute__ ((nothrow,nonnull (1))); 00130 00131 template <const int BPP> 00132 static inline void DrawHLine(void *pixels, unsigned int index, 00133 int width, Uint32 color) 00134 { 00135 #if 0 00136 //if(width < 1) return; 00137 do { 00138 PutPixel(pixels, index, color); 00139 index++; 00140 } while (--width); 00141 #else 00142 if(BPP == 1) { 00143 memset((void*)(((Uint8 *)pixels) + index), color, width ); 00144 } else if(BPP == 2) { 00145 #ifdef __x86_64__ 00146 switch(((uintptr_t)pixels) & 6 ) 00147 { 00148 case 6: 00149 PutPixel<BPP>(pixels, index, color); 00150 index++; 00151 --width; 00152 case 4: 00153 PutPixel<BPP>(pixels, index, color); 00154 index++; 00155 --width; 00156 case 2: 00157 PutPixel<BPP>(pixels, index, color); 00158 index++; 00159 --width; 00160 default: 00161 break; 00162 } 00163 #else 00164 if(((uintptr_t)pixels) & BPP ) { 00165 PutPixel<BPP>(pixels, index, color); 00166 index++; 00167 --width; 00168 } 00169 #endif 00170 } 00171 #ifdef __x86_64__ 00172 else if(BPP == 4 && ((uintptr_t)pixels) & BPP) { 00173 PutPixel<BPP>(pixels, index, color); 00174 index++; 00175 --width; 00176 } 00177 #endif 00178 while (width > 3) { 00179 PutPixelQuatro<BPP>(pixels, index, color); 00180 index+=4; 00181 width-=4; 00182 }; 00183 switch(width & 3) { 00184 case 3: 00185 PutPixel<BPP>(pixels, index, color); 00186 index++; 00187 //--width; 00188 case 2: 00189 PutPixel<BPP>(pixels, index, color); 00190 index++; 00191 //--width; 00192 case 1: 00193 PutPixel<BPP>(pixels, index, color); 00194 index++; 00195 //--width; 00196 default: 00197 break; 00198 } 00199 00200 #endif 00201 }; 00202 00203 }; 00204 00205 //RGB565 -> MASK = 0xf7de 00206 //RGB555 -> MASK = 0xfbde 00207 //RGB888 -> MASK = 0 00208 template <const int BPP, const int MASK> 00209 class CRenderer : public CPrimitives { 00210 00211 static inline void PutTransPixel(void *pixels, unsigned int index, 00212 Uint32 color, unsigned int alpha) 00213 { 00214 unsigned int dp; 00215 if(BPP == 2) { 00216 Uint16 *p = (((Uint16 *)pixels) + index); 00217 // Loses precision for speed 00218 alpha >>= 3; 00219 if(MASK == 0xf7de) { 00220 /* RGB565 */ 00221 color = (((color << 16) | color) & 0x07E0F81F); 00222 dp = *p; 00223 dp = ((dp << 16) | dp) & 0x07E0F81F; 00224 dp += (((color - dp) * alpha) >> 5); 00225 dp &= 0x07E0F81F; 00226 } else { 00227 if(MASK == 0xfbde) { 00228 /* RGB555 */ 00229 color = (((color << 16) | color) & 0x03e07c1f); 00230 dp = *p; 00231 dp = ((dp << 16) | dp) & 0x03e07c1f; 00232 dp += (((color - dp) * alpha) >> 5); 00233 dp &= 0x03e07c1f; 00234 } else { 00235 assert(0); 00236 } 00237 } 00238 *p = (dp >> 16) | dp; 00239 } else if(BPP == 4) { 00240 /* RGB888(8) */ 00241 Uint32 *p = (((Uint32 *)pixels) + index); 00242 unsigned int sp2 = (color & 0xFF00FF00) >> 8; 00243 unsigned int dp2; 00244 00245 color &= 0x00FF00FF; 00246 00247 dp = *p; 00248 dp2 = (dp & 0xFF00FF00) >> 8; 00249 dp &= 0x00FF00FF; 00250 00251 dp += (((color - dp) * alpha) >> 8); 00252 dp &= 0x00FF00FF; 00253 dp2 += (((sp2 - dp2) * alpha) >> 8); 00254 dp2 &= 0x00FF00FF; 00255 *p = (dp | (dp2 << 8)); 00256 } else { 00257 assert(0); 00258 } 00259 } // __attribute__ ((nothrow,nonnull (1))); 00260 00261 static inline void PutTransPixelDouble(void *pixels, unsigned int index, 00262 Uint32 color, unsigned int alpha) 00263 { 00264 00265 if(BPP == 2) { 00266 /* 00267 #ifdef __x86_64__ 00268 //FIXME 00269 unsigned int dp; 00270 Uint16 *p = (((Uint16 *)pixels) + index); 00271 00272 #else 00273 */ 00274 PutTransPixel(pixels, index, color, alpha); 00275 PutTransPixel(pixels, index + 1, color, alpha); 00276 //#endif 00277 } else if(BPP == 4) { 00278 #ifdef __x86_64__ 00279 Uint64 *const p = (Uint64*)(((Uint32 *)pixels) + index); 00280 const Uint64 A = alpha; 00281 Uint64 src0 = color; 00282 Uint64 src1 = (src0 | (src0 << 32)); 00283 Uint64 dst0 = *p; 00284 Uint64 dst1 = (dst0 >> 8); 00285 00286 src0 = src1; 00287 src1 >>= 8; 00288 00289 src0 &= 0x00FF00FF00FF00FF; 00290 src1 &= 0x00FF00FF00FF00FF; 00291 00292 dst0 &= 0x00FF00FF00FF00FF; 00293 dst1 &= 0x00FF00FF00FF00FF; 00294 00295 dst0 += ((src0 - dst0) * A >> 8); 00296 dst0 &= 0x00FF00FF00FF00FF; 00297 00298 dst1 += ((src1 - dst1) * A >> 8); 00299 dst1 &= 0x00FF00FF00FF00FF; 00300 00301 *p = dst0 | (dst1 << 8) 00302 #else 00303 Uint32 *p = (((Uint32 *)pixels) + index); 00304 /* 00305 * FIXME: 00306 * Two Pixels Blend for litle endian and 00307 * big endian may be broken. 00308 */ 00309 unsigned int d1, s1 = color & 0xff00ff; 00310 unsigned int dp = *p; 00311 d1 = dp & 0xff00ff; 00312 00313 color &= 0xff00; 00314 color = (color >> 8) | (color << 8); 00315 00316 d1 += (s1 - d1) * alpha >> 8; 00317 d1 &= 0xff00ff; 00318 00319 dp = ((dp & 0xff00) >> 8) | 00320 ((p[1] & 0xff00) << 8); 00321 00322 dp += (color - dp) * alpha >> 8; 00323 dp &= 0x00ff00ff; 00324 00325 *p++ = d1 | ((dp << 8) & 0xff00) | 0xff000000; 00326 00327 d1 = *p; 00328 d1 &= 0xff00ff; 00329 d1 += (s1 - d1) * alpha >> 8; 00330 d1 &= 0xff00ff; 00331 00332 *p = d1 | ((dp >> 8) & 0xff00) | 0xff000000; 00333 #endif 00334 } else { 00335 assert(0); 00336 } 00337 } // __attribute__ ((nothrow,nonnull (1))); 00338 00339 00340 static inline void PutTransPixel128(void *pixels, unsigned int index, 00341 Uint32 color) 00342 { 00343 if(BPP == 2) { 00344 /* blend a single 16 bit pixel at 50% */ 00345 #define BLEND16_50(d, s, mask) \ 00346 ((((s & mask) + (d & mask)) >> 1) + (s & d & (~mask & 0xffff))) 00347 00348 Uint16 *p = (((Uint16 *)pixels) + index); 00349 Uint16 d = *p; 00350 Uint16 s = color & 0xFFFF; // I hope that caler secure it; 00351 00352 *p = BLEND16_50(d, s, MASK); 00353 00354 #undef BLEND16_50 00355 } else if(BPP == 4) { 00356 Uint32 *p = (((Uint32 *)pixels) + index); 00357 unsigned int d = *p; 00358 00359 *p = ((((color & 0x00fefefe) + (d & 0x00fefefe)) >> 1) 00360 + (color & d & 0x00010101)) | 0xff000000; 00361 00362 } else { 00363 assert(0); 00364 } 00365 }; 00366 00367 static inline void PutTransPixel128Double(void *pixels, const unsigned int index, 00368 const Uint32 color) 00369 { 00370 if(BPP == 2) { 00371 /* blend two 16 bit pixels at 50% */ 00372 #define BLEND2x16_50(d, s, mask) \ 00373 (((s & (mask | mask << 16)) >> 1) + ((d & (mask | mask << 16)) >> 1) \ 00374 + (s & d & (~(mask | mask << 16)))) 00375 00376 Uint32 *p = (Uint32 *)(((Uint16 *)pixels) + index); 00377 Uint32 d = *p; 00378 const Uint32 s = (color & 0xFFFF) | color << 16; // I hope that caler secure it; 00379 00380 *p = BLEND2x16_50(d, s, MASK); 00381 00382 #undef BLEND2x16_50 00383 } else if(BPP == 4) { 00384 Uint32 *p = (((Uint32 *)pixels) + index); 00385 #ifdef __x86_64__ 00386 unsigned long long int d = *(unsigned long long int *)p; 00387 unsigned long long int s, c = color; 00388 00389 s = c | c << 32; 00390 c = s & 0x00fefefe00fefefe; 00391 00392 *(unsigned long long int *)p = 00393 (((c + (d & 0x00fefefe00fefefe)) >> 1) 00394 + (s & d & 0x0001010100010101)) | 00395 0xff000000ff000000; 00396 #else 00397 Uint32 d = *p; 00398 const Uint32 c = color & 0x00fefefe; 00399 *p++ = (((c + (d & 0x00fefefe)) >> 1) 00400 + (color & d & 0x00010101)) | 0xff000000; 00401 d = *p; 00402 *p = (((c + (d & 0x00fefefe)) >> 1) 00403 + (color & d & 0x00010101)) | 0xff000000; 00404 #endif 00405 } else { 00406 assert(0); 00407 } 00408 } // __attribute__ ((nothrow,nonnull (1))); 00409 00410 static void DrawVLine(void *pixels, const unsigned int pitch, 00411 unsigned int index, int height, Uint32 color) 00412 { 00413 if(height < 1) return; 00414 do { 00415 DRAW::PutPixel<BPP>(pixels, index, color); 00416 index += pitch; 00417 } while (--height); 00418 } // __attribute__ ((nothrow,nonnull (1))); 00419 00420 static void DrawTransVLine(void *pixels, const unsigned int pitch, 00421 unsigned int index, int height, Uint32 color, unsigned int alpha) 00422 { 00423 if(height < 1) return; 00424 if(alpha == 128) { 00425 do { 00426 PutTransPixel128(pixels, index, color); 00427 index += pitch; 00428 } while (--height); 00429 } else { 00430 do { 00431 PutTransPixel(pixels, index, color, alpha); 00432 index += pitch; 00433 } while (--height); 00434 } 00435 } // __attribute__ ((nothrow,nonnull (1))); 00436 00437 static inline void DrawTransHLine128(void *pixels, 00438 unsigned int index, int width, Uint32 color) 00439 { 00440 #ifdef __x86_64__ 00441 //FIXME: this may not work on 16 bpp 00442 if( ((uintptr_t)pixels) & BPP ) 00443 #else 00444 if(width & 1) 00445 #endif 00446 { 00447 PutTransPixel128(pixels, index, color); 00448 --width; 00449 index++; 00450 } 00451 while (width > 1) { 00452 PutTransPixel128Double(pixels, index, color); 00453 index+=2; 00454 width-=2; 00455 }; 00456 #ifdef __x86_64__ 00457 if(width) PutTransPixel128(pixels, index, color); 00458 #endif 00459 00460 } // __attribute__ ((nothrow,nonnull (1))); 00461 00462 00463 static inline void DrawTransHLineNon128(void *pixels, 00464 unsigned int index, int width, Uint32 color, unsigned int alpha) 00465 { 00466 #ifdef __x86_64__ 00467 if( ((uintptr_t)pixels) & BPP ) 00468 #else 00469 if(width & 1) 00470 #endif 00471 { 00472 PutTransPixel(pixels, index, color, alpha); 00473 --width; 00474 index++; 00475 } 00476 while (width > 1) { 00477 PutTransPixelDouble(pixels, index, color, alpha); 00478 index+=2; 00479 width-=2; 00480 }; 00481 #ifdef __x86_64__ 00482 if(width) PutTransPixel(pixels, index, color, alpha); 00483 #endif 00484 } // __attribute__ ((nothrow,nonnull (1))); 00485 00486 static inline void DrawTransHLine(void *pixels, 00487 unsigned int index, int width, Uint32 color, unsigned int alpha) 00488 { 00489 //if(width < 1) return; 00490 if(alpha == 128) { 00491 DrawTransHLine128(pixels, index, width, color); 00492 } else { 00493 DrawTransHLineNon128(pixels, index, width, color, alpha); 00494 } 00495 }; 00496 00497 void DrawPixel(Uint32 color, int x, int y) 00498 { 00499 unsigned int index = TheScreen->pitch / BPP; 00500 index *= y; 00501 index += x; 00502 DRAW::PutPixel<BPP>(TheScreen->pixels, index, color); 00503 }; 00504 00505 void DrawTransPixel(Uint32 color, int x, int y, unsigned char alpha) 00506 { 00507 unsigned int index = TheScreen->pitch / BPP; 00508 index *= y; 00509 index += x; 00510 if(alpha == 128) 00511 PutTransPixel128(TheScreen->pixels, index, color); 00512 else 00513 PutTransPixel(TheScreen->pixels, index, color, alpha); 00514 }; 00515 00516 void DrawLine(Uint32 color, int sx, int sy, int dx, int dy) 00517 { 00518 unsigned int index; 00519 const unsigned int pitch = TheScreen->pitch / BPP; 00520 00521 if (sx == dx) { 00522 unsigned int len = 1; 00523 if (sy < dy) { 00524 index = sx + sy * pitch; 00525 len += dy - sy; 00526 } else { 00527 index = dx + dy * pitch; 00528 len += sy - dy; 00529 } 00530 DrawVLine(TheScreen->pixels, pitch, index, len, color); 00531 return; 00532 } 00533 00534 if (sy == dy) { 00535 unsigned int len = 1; 00536 if (sx < dx) { 00537 index = sx + sy * pitch; 00538 len += dx - sx; 00539 } else { 00540 index = dx + dy * pitch; 00541 len += sx - dx; 00542 } 00543 DRAW::DrawHLine<BPP>(TheScreen->pixels, index, len, color); 00544 return; 00545 } 00546 00547 // exchange coordinates 00548 if (sy > dy) { 00549 int t; 00550 t = dx; 00551 dx = sx; 00552 sx = t; 00553 t = dy; 00554 dy = sy; 00555 sy = t; 00556 } 00557 00558 int ylen = dy - sy; 00559 int incr; 00560 int xlen; 00561 00562 if (sx > dx) { 00563 xlen = sx - dx; 00564 incr = -1; 00565 } else { 00566 xlen = dx - sx; 00567 incr = 1; 00568 } 00569 00570 int y = sy; 00571 int x = sx; 00572 00573 if (xlen > ylen) { 00574 int p; 00575 00576 if (sx > dx) { 00577 int t; 00578 t = sx; 00579 sx = dx; 00580 dx = t; 00581 y = dy; 00582 } 00583 00584 p = (ylen << 1) - xlen; 00585 00586 index = y * pitch; 00587 incr *= pitch; 00588 for (x = sx; x < dx; ++x) { 00589 DRAW::PutPixel<BPP>(TheScreen->pixels, x + index, color); 00590 if (p >= 0) { 00591 //y += incr; 00592 index += incr; 00593 p += (ylen - xlen) << 1; 00594 } else { 00595 p += (ylen << 1); 00596 } 00597 } 00598 return; 00599 } 00600 00601 if (ylen > xlen) { 00602 int p; 00603 00604 p = (xlen << 1) - ylen; 00605 index = sy * pitch; 00606 for (y = sy; y < dy; ++y) { 00607 DRAW::PutPixel<BPP>(TheScreen->pixels, x + index, color); 00608 if (p >= 0) { 00609 x += incr; 00610 p += (xlen - ylen) << 1; 00611 } else { 00612 p += (xlen << 1); 00613 } 00614 index += pitch; 00615 } 00616 00617 return; 00618 } 00619 00620 // Draw a diagonal line 00621 if (ylen == xlen) { 00622 index = y * pitch; 00623 while (y != dy) { 00624 DRAW::PutPixel<BPP>(TheScreen->pixels, x + index, color); 00625 x += incr; 00626 ++y; 00627 index += pitch; 00628 } 00629 } 00630 }; 00631 00632 void DrawTransLine(Uint32 color, int sx, int sy, 00633 int dx, int dy, unsigned char alpha) 00634 { 00635 DrawLine(color, sx, sy, dx, dy); 00636 } 00637 00638 00639 void DrawRectangle(Uint32 color, int x, int y, int w, int h) 00640 { 00641 const unsigned int pitch = TheScreen->pitch / BPP; 00642 unsigned int index = y * pitch; 00643 unsigned int y_offset = (h - 1) * pitch; 00644 PutTransPixel128(TheScreen->pixels, x + index, color); 00645 DRAW::DrawHLine<BPP>(TheScreen->pixels, x + index + 1, w - 2, color); 00646 PutTransPixel128(TheScreen->pixels, x + index + w - 1, color); 00647 00648 PutTransPixel128(TheScreen->pixels, x + index + y_offset, color); 00649 DRAW::DrawHLine<BPP>(TheScreen->pixels, x + index + y_offset + 1, w - 2, color); // (x, y + h - 1, w) 00650 PutTransPixel128(TheScreen->pixels, x + index + y_offset + w - 1, color); 00651 00652 DrawVLine(TheScreen->pixels, pitch, x + index + pitch, 00653 h - 2, color); //(x, y + 1, h - 2) 00654 DrawVLine(TheScreen->pixels, pitch, x + index + w - 1 + pitch, 00655 h - 2, color); //x + w - 1, y + 1, h - 2 00656 }; 00657 00658 void DrawTransRectangle(Uint32 color, int x, int y, 00659 int w, int h, unsigned char alpha) 00660 { 00661 const unsigned int pitch = TheScreen->pitch / BPP; 00662 unsigned int index = y * pitch; 00663 unsigned int y_offset = (h - 1) * pitch; 00664 //unsigned int a = 255 - alpha; 00665 00666 PutTransPixel(TheScreen->pixels, x + index, color, alpha / 2); 00667 DrawTransHLine(TheScreen->pixels, x + index + 1, w - 2, color, alpha); 00668 PutTransPixel(TheScreen->pixels, x + index + w - 1, color, alpha / 2); 00669 00670 PutTransPixel(TheScreen->pixels, x + index + y_offset, color, alpha / 2); 00671 DrawTransHLine(TheScreen->pixels, x + index + y_offset + 1, 00672 w - 2, color,alpha); // (x, y + h - 1, w) 00673 PutTransPixel(TheScreen->pixels, 00674 x + index + y_offset + w - 1, color, alpha / 2); 00675 00676 DrawTransVLine(TheScreen->pixels, pitch, x + index + pitch, 00677 h - 2, color, alpha); //(x, y + 1, h - 2) 00678 DrawTransVLine(TheScreen->pixels, pitch, x + index + w - 1 + pitch, 00679 h - 2, color, alpha); //x + w - 1, y + 1, h - 2 00680 }; 00681 00682 void FillTransRectangle(Uint32 color, int x, int y, 00683 int w, int h, unsigned char alpha) 00684 { 00685 const unsigned int pitch = TheScreen->pitch / BPP; 00686 unsigned int index = y * pitch; 00687 if(alpha == 128) { 00688 do { 00689 DrawTransHLine128(TheScreen->pixels, x + index, w, color); 00690 index += pitch; 00691 } while(--h); 00692 } else { 00693 do { 00694 DrawTransHLineNon128(TheScreen->pixels, x + index, w, color, alpha); 00695 index += pitch; 00696 } while(--h); 00697 } 00698 }; 00699 00700 void DrawCircle(Uint32 color, int x, int y, int r) 00701 { 00702 const unsigned int pitch = TheScreen->pitch / BPP; 00703 int p = 1 - r; 00704 int px = 0; 00705 int py = r; 00706 00707 for (; px <= py + 1; ++px) { 00708 unsigned int index_plus = (y + py) * pitch; 00709 unsigned int index_minus = (y - py) * pitch; 00710 00711 DRAW::PutPixel<BPP>(TheScreen->pixels, x + px + index_plus, color); 00712 DRAW::PutPixel<BPP>(TheScreen->pixels, x + px + index_minus, color); 00713 DRAW::PutPixel<BPP>(TheScreen->pixels, x - px + index_plus, color); 00714 DRAW::PutPixel<BPP>(TheScreen->pixels, x - px + index_minus, color); 00715 00716 index_plus = (y + px) * pitch; 00717 index_minus = (y - px) * pitch; 00718 00719 DRAW::PutPixel<BPP>(TheScreen->pixels, x + py + index_plus, color); 00720 DRAW::PutPixel<BPP>(TheScreen->pixels, x + py + index_minus, color); 00721 DRAW::PutPixel<BPP>(TheScreen->pixels, x - py + index_plus, color); 00722 DRAW::PutPixel<BPP>(TheScreen->pixels, x - py + index_minus, color); 00723 00724 if (p < 0) { 00725 p += 2 * px + 3; 00726 } else { 00727 p += 2 * (px - py) + 5; 00728 py -= 1; 00729 } 00730 } 00731 }; 00732 00733 void DrawTransCircle(Uint32 color, int x, int y, 00734 int r, unsigned char alpha) 00735 { 00736 const unsigned int pitch = TheScreen->pitch / BPP; 00737 int p = 1 - r; 00738 int px = 0; 00739 int py = r; 00740 00741 for (; px <= py + 1; ++px) { 00742 unsigned int index_plus = (y + py) * pitch; 00743 unsigned int index_minus = (y - py) * pitch; 00744 00745 PutTransPixel(TheScreen->pixels, x + px + index_plus, color,alpha); 00746 PutTransPixel(TheScreen->pixels, x + px + index_minus, color,alpha); 00747 PutTransPixel(TheScreen->pixels, x - px + index_plus, color,alpha); 00748 PutTransPixel(TheScreen->pixels, x - px + index_minus, color,alpha); 00749 00750 index_plus = (y + px) * pitch; 00751 index_minus = (y - px) * pitch; 00752 00753 PutTransPixel(TheScreen->pixels, x + py + index_plus, color,alpha); 00754 PutTransPixel(TheScreen->pixels, x + py + index_minus, color,alpha); 00755 PutTransPixel(TheScreen->pixels, x - py + index_plus, color,alpha); 00756 PutTransPixel(TheScreen->pixels, x - py + index_minus, color,alpha); 00757 00758 if (p < 0) { 00759 p += 2 * px + 3; 00760 } else { 00761 p += 2 * (px - py) + 5; 00762 py -= 1; 00763 } 00764 } 00765 }; 00766 00767 void FillCircle(Uint32 color, int x, int y, int r) 00768 { 00769 const unsigned int pitch = TheScreen->pitch / BPP; 00770 int p = 1 - r; 00771 int px = 0; 00772 int py = r; 00773 00774 for (; px <= py; ++px) { 00775 //FIXME: Change it to DrawHLine for speed. 00776 unsigned int y_index = y * pitch; 00777 unsigned int py_index = py * pitch; 00778 00779 // Fill up the middle half of the circle 00780 DrawVLine(TheScreen->pixels, pitch, 00781 x + px + y_index, 00782 py + 1, color); 00783 DrawVLine(TheScreen->pixels, pitch, 00784 x + px + (y_index - py_index), 00785 py, color); 00786 00787 if (px) { 00788 DrawVLine(TheScreen->pixels, pitch, 00789 x - px + y_index, 00790 py + 1, color); 00791 DrawVLine(TheScreen->pixels, pitch, 00792 x - px + (y_index - py_index), 00793 py, color); 00794 } 00795 00796 if (p < 0) { 00797 p += 2 * px + 3; 00798 } else { 00799 p += 2 * (px - py) + 5; 00800 py -= 1; 00801 // Fill up the left/right half of the circle 00802 if (py >= px) { 00803 unsigned int px_index = px * pitch; 00804 DrawVLine(TheScreen->pixels, pitch, 00805 x + py + 1 + y_index, 00806 px + 1, color); 00807 DrawVLine(TheScreen->pixels, pitch, 00808 x + py + 1 + (y_index - px_index), 00809 px, color); 00810 DrawVLine(TheScreen->pixels, pitch, 00811 x - py - 1 + y_index, 00812 px + 1, color); 00813 DrawVLine(TheScreen->pixels, pitch, 00814 x - py - 1 + (y_index - px_index), 00815 px, color); 00816 } 00817 } 00818 } 00819 }; 00820 00821 void FillTransCircle(Uint32 color, int x, int y, 00822 int r, unsigned char alpha) 00823 { 00824 const unsigned int pitch = TheScreen->pitch / BPP; 00825 int p = 1 - r; 00826 int px = 0; 00827 int py = r; 00828 00829 for (; px <= py; ++px) { 00830 //FIXME: Change it to DrawTransHLine for speed. 00831 unsigned int y_index = y * pitch; 00832 unsigned int py_index = py * pitch; 00833 00834 // Fill up the middle half of the circle 00835 DrawTransVLine(TheScreen->pixels, pitch, 00836 x + px + y_index, 00837 py + 1, color, alpha); 00838 DrawTransVLine(TheScreen->pixels, pitch, 00839 x + px + (y_index - py_index), 00840 py, color,alpha); 00841 00842 if (px) { 00843 DrawTransVLine(TheScreen->pixels, pitch, 00844 x - px + y_index, 00845 py + 1, color,alpha); 00846 DrawTransVLine(TheScreen->pixels, pitch, 00847 x - px + (y_index - py_index), 00848 py, color,alpha); 00849 } 00850 00851 if (p < 0) { 00852 p += 2 * px + 3; 00853 } else { 00854 p += 2 * (px - py) + 5; 00855 py -= 1; 00856 // Fill up the left/right half of the circle 00857 if (py >= px) { 00858 unsigned int px_index = px * pitch; 00859 DrawTransVLine(TheScreen->pixels, pitch, 00860 x + py + 1 + y_index, 00861 px + 1, color,alpha); 00862 DrawTransVLine(TheScreen->pixels, pitch, 00863 x + py + 1 + (y_index - px_index), 00864 px, color,alpha); 00865 DrawTransVLine(TheScreen->pixels, pitch, 00866 x - py - 1 + y_index, 00867 px + 1, color,alpha); 00868 DrawTransVLine(TheScreen->pixels, pitch, 00869 x - py - 1 + (y_index - px_index), 00870 px, color,alpha); 00871 } 00872 } 00873 } 00874 }; 00875 00876 }; 00877 00878 typedef CRenderer<2,0xfbde> Primitive16_555_t; 00879 typedef CRenderer<2,0xf7de> Primitive16_565_t; 00880 typedef CRenderer<4,0> Primitive32_t; 00881 00882 #endif 00883