brewpanel/sdlgui.c

changeset 425
c51265b518ce
parent 422
13502d0dda65
child 427
e8e548922e31
equal deleted inserted replaced
424:d5e36ca9085f 425:c51265b518ce
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;
516 SDLGui_DrawTTF(dlg, i); 626 SDLGui_DrawTTF(dlg, i);
517 break; 627 break;
518 case SGBUTTON: 628 case SGBUTTON:
519 SDLGui_DrawButton(dlg, i); 629 SDLGui_DrawButton(dlg, i);
520 break; 630 break;
631 case SGLEDRED:
632 SDLGUI_DrawLEDRed(dlg, i);
633 break;
634 case SGLEDBLUE:
635 SDLGUI_DrawLEDBlue(dlg, i);
636 break;
637 case SGLEDGREEN:
638 SDLGUI_DrawLEDGreen(dlg, i);
639 break;
640 case SGLEDYELLOW:
641 SDLGUI_DrawLEDYellow(dlg, i);
642 break;
521 } 643 }
522 } 644 }
523 645
524 SDL_UpdateRect(pSdlGuiScrn, 0,0,0,0); 646 SDL_UpdateRect(pSdlGuiScrn, 0,0,0,0);
525 } 647 }

mercurial