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