493 } |
493 } |
494 |
494 |
495 |
495 |
496 |
496 |
497 /* |
497 /* |
|
498 * SDL_Surface 32-bit circle-fill algorithm without using trig |
|
499 * |
|
500 * While I humbly call this "Celdecea's Method", odds are that the |
|
501 * procedure has already been documented somewhere long ago. All of |
|
502 * the circle-fill examples I came across utilized trig functions or |
|
503 * scanning neighbor pixels. This algorithm identifies the width of |
|
504 * a semi-circle at each pixel height and draws a scan-line covering |
|
505 * that width. |
|
506 * |
|
507 * The code is not optimized but very fast, owing to the fact that it |
|
508 * alters pixels in the provided surface directly rather than through |
|
509 * function calls. |
|
510 */ |
|
511 void SDLGui_fill_circle(SDL_Surface *surface, int cx, int cy, int radius, Uint32 pixel) |
|
512 { |
|
513 /* |
|
514 * Note that there is more to altering the bitrate of this |
|
515 * method than just changing this value. See how pixels are |
|
516 * altered at the following web page for tips: |
|
517 * http://www.libsdl.org/intro.en/usingvideo.html |
|
518 */ |
|
519 static const int BPP = 4; |
|
520 double r = (double)radius; |
|
521 double dy; |
|
522 |
|
523 for (dy = 1; dy <= r; dy += 1.0) { |
|
524 /* |
|
525 * This loop is unrolled a bit, only iterating through half of the |
|
526 * height of the circle. The result is used to draw a scan line and |
|
527 * its mirror image below it. |
|
528 * |
|
529 * The following formula has been simplified from our original. We |
|
530 * are using half of the width of the circle because we are provided |
|
531 * with a center and we need left/right coordinates. |
|
532 */ |
|
533 double dx = floor(sqrt((2.0 * r * dy) - (dy * dy))); |
|
534 int x = cx - dx; |
|
535 |
|
536 // Grab a pointer to the left-most pixel for each half of the circle |
|
537 Uint8 *target_pixel_a = (Uint8 *)surface->pixels + ((int)(cy + r - dy)) * surface->pitch + x * BPP; |
|
538 Uint8 *target_pixel_b = (Uint8 *)surface->pixels + ((int)(cy - r + dy)) * surface->pitch + x * BPP; |
|
539 |
|
540 for (; x <= cx + dx; x++) { |
|
541 *(Uint32 *)target_pixel_a = pixel; |
|
542 *(Uint32 *)target_pixel_b = pixel; |
|
543 target_pixel_a += BPP; |
|
544 target_pixel_b += BPP; |
|
545 } |
|
546 } |
|
547 } |
|
548 |
|
549 |
|
550 |
|
551 static void SDLGUI_DrawLEDRed(const SGOBJ *bdlg, int objnum) |
|
552 { |
|
553 Uint32 color; |
|
554 |
|
555 if (bdlg[objnum].state & SG_SELECTED) { |
|
556 color = SDL_MapRGB(pSdlGuiScrn->format, 255, 64, 0); |
|
557 } else { |
|
558 color = SDL_MapRGB(pSdlGuiScrn->format, 128, 16, 0); |
|
559 } |
|
560 SDLGui_fill_circle(pSdlGuiScrn, bdlg[objnum].x, bdlg[objnum].y, bdlg[objnum].w, color); |
|
561 } |
|
562 |
|
563 |
|
564 |
|
565 static void SDLGUI_DrawLEDBlue(const SGOBJ *bdlg, int objnum) |
|
566 { |
|
567 Uint32 color; |
|
568 |
|
569 if (bdlg[objnum].state & SG_SELECTED) { |
|
570 color = SDL_MapRGB(pSdlGuiScrn->format, 64, 160, 255); |
|
571 } else { |
|
572 color = SDL_MapRGB(pSdlGuiScrn->format, 16, 48, 112); |
|
573 } |
|
574 SDLGui_fill_circle(pSdlGuiScrn, bdlg[objnum].x, bdlg[objnum].y, bdlg[objnum].w, color); |
|
575 } |
|
576 |
|
577 |
|
578 |
|
579 static void SDLGUI_DrawLEDGreen(const SGOBJ *bdlg, int objnum) |
|
580 { |
|
581 Uint32 color; |
|
582 |
|
583 if (bdlg[objnum].state & SG_SELECTED) { |
|
584 color = SDL_MapRGB(pSdlGuiScrn->format, 80, 240, 0); |
|
585 } else { |
|
586 color = SDL_MapRGB(pSdlGuiScrn->format, 32, 112, 0); |
|
587 } |
|
588 SDLGui_fill_circle(pSdlGuiScrn, bdlg[objnum].x, bdlg[objnum].y, bdlg[objnum].w, color); |
|
589 } |
|
590 |
|
591 |
|
592 |
|
593 static void SDLGUI_DrawLEDYellow(const SGOBJ *bdlg, int objnum) |
|
594 { |
|
595 Uint32 color; |
|
596 |
|
597 if (bdlg[objnum].state & SG_SELECTED) { |
|
598 color = SDL_MapRGB(pSdlGuiScrn->format, 255, 255, 0); |
|
599 } else { |
|
600 color = SDL_MapRGB(pSdlGuiScrn->format, 160, 144, 0); |
|
601 } |
|
602 SDLGui_fill_circle(pSdlGuiScrn, bdlg[objnum].x, bdlg[objnum].y, bdlg[objnum].w, color); |
|
603 } |
|
604 |
|
605 |
|
606 |
|
607 /* |
498 * Draw a whole dialog. |
608 * Draw a whole dialog. |
499 */ |
609 */ |
500 void SDLGui_DrawDialog(const SGOBJ *dlg) |
610 void SDLGui_DrawDialog(const SGOBJ *dlg) |
501 { |
611 { |
502 int i; |
612 int i; |