|
|
1.1 ! root 1: /* ! 2: Hatari - statusbar.c ! 3: ! 4: This file is distributed under the GNU Public License, version 2 or at ! 5: your option any later version. Read the file gpl.txt for details. ! 6: ! 7: Code to draw statusbar area, floppy leds etc. ! 8: ! 9: Use like this: ! 10: - Before screen surface is (re-)created Statusbar_SetHeight() ! 11: has to be called with the new screen height. Add the returned ! 12: value to screen height (zero means no statusbar). After this, ! 13: Statusbar_GetHeight() can be used to retrieve the statusbar size ! 14: - After screen surface is (re-)created, call Statusbar_Init() ! 15: to re-initialize / re-draw the statusbar ! 16: - Call Statusbar_SetFloppyLed() to set floppy drive led ON/OFF, ! 17: or call Statusbar_EnableHDLed() to enabled HD led for a while ! 18: - Whenever screen is redrawn, call Statusbar_Update() to draw the ! 19: updated information to the statusbar (outside of screen locking) ! 20: - If screen redraws may be partial, Statusbar_OverlayRestore() ! 21: needs to be called before locking the screen for drawing and ! 22: Statusbar_OverlayBackup() needs to be called after screen unlocking, ! 23: but before calling Statusbar_Update(). These are needed for ! 24: hiding the overlay drive led when drive leds are turned OFF. ! 25: - If other information shown by Statusbar (TOS version etc) changes, ! 26: call Statusbar_UpdateInfo() ! 27: ! 28: TODO: ! 29: - re-calculate colors on each update to make sure they're ! 30: correct in Falcon & TT 8-bit palette modes? ! 31: - call Statusbar_AddMessage() from log.c? ! 32: */ ! 33: const char Statusbar_fileid[] = "Hatari statusbar.c : " __DATE__ " " __TIME__; ! 34: ! 35: #include <assert.h> ! 36: #include "main.h" ! 37: #include "configuration.h" ! 38: #include "screenSnapShot.h" ! 39: #include "sdlgui.h" ! 40: #include "statusbar.h" ! 41: #include "video.h" ! 42: #include "avi_record.h" ! 43: ! 44: #define DEBUG 0 ! 45: #if DEBUG ! 46: #define DEBUGPRINT(x) printf x ! 47: #else ! 48: #define DEBUGPRINT(x) ! 49: #endif ! 50: ! 51: #define MAX_DRIVE_LEDS (DRIVE_LED_HD + 1) ! 52: ! 53: /* whether drive leds should be ON and their previous shown state */ ! 54: static struct { ! 55: bool state; ! 56: bool oldstate; ! 57: Uint32 expire; /* when to disable led, valid only if >0 && state=TRUE */ ! 58: int offset; /* led x-pos on screen */ ! 59: } Led[MAX_DRIVE_LEDS]; ! 60: ! 61: /* drive leds size & y-pos */ ! 62: static SDL_Rect LedRect; ! 63: ! 64: /* overlay led size & pos */ ! 65: static SDL_Rect OverlayLedRect; ! 66: ! 67: /* screen contents left under overlay led */ ! 68: static SDL_Surface *OverlayUnderside; ! 69: ! 70: static enum { ! 71: OVERLAY_NONE, ! 72: OVERLAY_DRAWN, ! 73: OVERLAY_RESTORED ! 74: } bOverlayState; ! 75: ! 76: static SDL_Rect RecLedRect; ! 77: static bool bOldRecording; ! 78: ! 79: /* led colors */ ! 80: static Uint32 LedColorOn, LedColorOff, RecColorOn, RecColorOff; ! 81: static Uint32 GrayBg, LedColorBg; ! 82: ! 83: ! 84: #define MAX_MESSAGE_LEN 33 ! 85: typedef struct msg_item { ! 86: struct msg_item *next; ! 87: char msg[MAX_MESSAGE_LEN+1]; ! 88: Uint32 timeout; /* msecs, zero=no timeout */ ! 89: Uint32 expire; /* when to expire message */ ! 90: bool shown; ! 91: } msg_item_t; ! 92: ! 93: static msg_item_t DefaultMessage; ! 94: static msg_item_t *MessageList = &DefaultMessage; ! 95: static SDL_Rect MessageRect; ! 96: ! 97: /* rect for both frame skip value and fast forward indicator */ ! 98: static SDL_Rect FrameSkipsRect; ! 99: static int nOldFrameSkips; ! 100: static int bOldFastForward; ! 101: ! 102: ! 103: /* screen height above statusbar and height of statusbar below screen */ ! 104: static int ScreenHeight; ! 105: static int StatusbarHeight; ! 106: ! 107: ! 108: /*-----------------------------------------------------------------------*/ ! 109: /** ! 110: * Return statusbar height for given width and height ! 111: */ ! 112: int Statusbar_GetHeightForSize(int width, int height) ! 113: { ! 114: if (ConfigureParams.Screen.bShowStatusbar) { ! 115: /* Should check the same thing as SDLGui_SetScreen() ! 116: * does to decide the font size. ! 117: */ ! 118: if (width >= 640 && height >= (400-24)) { ! 119: return 24; ! 120: } else { ! 121: return 12; ! 122: } ! 123: } ! 124: return 0; ! 125: } ! 126: ! 127: /*-----------------------------------------------------------------------*/ ! 128: /** ! 129: * Set screen height used for statusbar height calculation. ! 130: * ! 131: * Return height of statusbar that should be added to the screen ! 132: * height when screen is (re-)created, or zero if statusbar will ! 133: * not be shown ! 134: */ ! 135: int Statusbar_SetHeight(int width, int height) ! 136: { ! 137: ScreenHeight = height; ! 138: StatusbarHeight = Statusbar_GetHeightForSize(width, height); ! 139: return StatusbarHeight; ! 140: } ! 141: ! 142: /*-----------------------------------------------------------------------*/ ! 143: /** ! 144: * Return height of statusbar set with Statusbar_SetHeight() ! 145: */ ! 146: int Statusbar_GetHeight(void) ! 147: { ! 148: return StatusbarHeight; ! 149: } ! 150: ! 151: ! 152: /*-----------------------------------------------------------------------*/ ! 153: /** ! 154: * Enable HD drive led, it will be automatically disabled after a while. ! 155: */ ! 156: void Statusbar_EnableHDLed(void) ! 157: { ! 158: /* leds are shown for 1/2 sec after enabling */ ! 159: Led[DRIVE_LED_HD].expire = SDL_GetTicks() + 1000/2; ! 160: Led[DRIVE_LED_HD].state = true; ! 161: } ! 162: ! 163: /*-----------------------------------------------------------------------*/ ! 164: /** ! 165: * Set given floppy drive led state, anything enabling led with this ! 166: * needs also to take care of disabling it. ! 167: */ ! 168: void Statusbar_SetFloppyLed(drive_index_t drive, bool state) ! 169: { ! 170: assert(drive == DRIVE_LED_A || drive == DRIVE_LED_B); ! 171: Led[drive].state = state; ! 172: } ! 173: ! 174: ! 175: /*-----------------------------------------------------------------------*/ ! 176: /** ! 177: * Set overlay led size/pos on given screen to internal Rect ! 178: * and free previous resources. ! 179: */ ! 180: static void Statusbar_OverlayInit(const SDL_Surface *surf) ! 181: { ! 182: int h; ! 183: /* led size/pos needs to be re-calculated in case screen changed */ ! 184: h = surf->h / 50; ! 185: OverlayLedRect.w = 2*h; ! 186: OverlayLedRect.h = h; ! 187: OverlayLedRect.x = surf->w - 5*h/2; ! 188: OverlayLedRect.y = h/2; ! 189: /* free previous restore surface if it's incompatible */ ! 190: if (OverlayUnderside && ! 191: OverlayUnderside->w == OverlayLedRect.w && ! 192: OverlayUnderside->h == OverlayLedRect.h && ! 193: OverlayUnderside->format->BitsPerPixel == surf->format->BitsPerPixel) { ! 194: SDL_FreeSurface(OverlayUnderside); ! 195: OverlayUnderside = NULL; ! 196: } ! 197: bOverlayState = OVERLAY_NONE; ! 198: } ! 199: ! 200: /*-----------------------------------------------------------------------*/ ! 201: /** ! 202: * (re-)initialize statusbar internal variables for given screen surface ! 203: * (sizes&colors may need to be re-calculated for the new SDL surface) ! 204: * and draw the statusbar background. ! 205: */ ! 206: void Statusbar_Init(SDL_Surface *surf) ! 207: { ! 208: msg_item_t *item; ! 209: SDL_Rect ledbox, sbarbox; ! 210: int i, fontw, fonth, offset; ! 211: const char *text[MAX_DRIVE_LEDS] = { "A:", "B:", "HD:" }; ! 212: ! 213: assert(surf); ! 214: ! 215: /* dark green and light green for leds themselves */ ! 216: LedColorOff = SDL_MapRGB(surf->format, 0x00, 0x40, 0x00); ! 217: LedColorOn = SDL_MapRGB(surf->format, 0x00, 0xe0, 0x00); ! 218: LedColorBg = SDL_MapRGB(surf->format, 0x00, 0x00, 0x00); ! 219: RecColorOff = SDL_MapRGB(surf->format, 0x40, 0x00, 0x00); ! 220: RecColorOn = SDL_MapRGB(surf->format, 0xe0, 0x00, 0x00); ! 221: GrayBg = SDL_MapRGB(surf->format, 0xc0, 0xc0, 0xc0); ! 222: ! 223: /* disable leds */ ! 224: for (i = 0; i < MAX_DRIVE_LEDS; i++) { ! 225: Led[i].state = Led[i].oldstate = false; ! 226: Led[i].expire = 0; ! 227: } ! 228: Statusbar_OverlayInit(surf); ! 229: ! 230: /* disable statusbar if it doesn't fit to video mode */ ! 231: if (surf->h < ScreenHeight + StatusbarHeight) { ! 232: StatusbarHeight = 0; ! 233: } ! 234: if (!StatusbarHeight) { ! 235: return; ! 236: } ! 237: ! 238: /* prepare fonts */ ! 239: SDLGui_Init(); ! 240: SDLGui_SetScreen(surf); ! 241: SDLGui_GetFontSize(&fontw, &fonth); ! 242: ! 243: /* video mode didn't match, need to recalculate sizes */ ! 244: if (surf->h > ScreenHeight + StatusbarHeight) { ! 245: StatusbarHeight = fonth + 2; ! 246: /* actually statusbar vertical offset */ ! 247: ScreenHeight = surf->h - StatusbarHeight; ! 248: } else { ! 249: assert(fonth+2 < StatusbarHeight); ! 250: } ! 251: ! 252: /* draw statusbar background gray so that text shows */ ! 253: sbarbox.x = 0; ! 254: sbarbox.y = surf->h - StatusbarHeight; ! 255: sbarbox.w = surf->w; ! 256: sbarbox.h = StatusbarHeight; ! 257: SDL_FillRect(surf, &sbarbox, GrayBg); ! 258: ! 259: /* led size */ ! 260: LedRect.w = fonth/2; ! 261: LedRect.h = fonth - 4; ! 262: LedRect.y = ScreenHeight + StatusbarHeight/2 - LedRect.h/2; ! 263: ! 264: /* black box for the leds */ ! 265: ledbox = LedRect; ! 266: ledbox.y -= 1; ! 267: ledbox.w += 2; ! 268: ledbox.h += 2; ! 269: ! 270: offset = fontw; ! 271: MessageRect.y = LedRect.y - 2; ! 272: /* draw led texts and boxes + calculate box offsets */ ! 273: for (i = 0; i < MAX_DRIVE_LEDS; i++) { ! 274: SDLGui_Text(offset, MessageRect.y, text[i]); ! 275: offset += strlen(text[i]) * fontw; ! 276: offset += fontw/2; ! 277: ! 278: ledbox.x = offset - 1; ! 279: SDL_FillRect(surf, &ledbox, LedColorBg); ! 280: ! 281: LedRect.x = offset; ! 282: SDL_FillRect(surf, &LedRect, LedColorOff); ! 283: ! 284: Led[i].offset = offset; ! 285: offset += LedRect.w + fontw; ! 286: } ! 287: ! 288: /* draw frameskip */ ! 289: FrameSkipsRect.x = offset; ! 290: FrameSkipsRect.y = MessageRect.y; ! 291: SDLGui_Text(FrameSkipsRect.x, FrameSkipsRect.y, "FS:"); ! 292: FrameSkipsRect.x += 3 * fontw + fontw/2; ! 293: FrameSkipsRect.w = 4 * fontw; ! 294: FrameSkipsRect.h = fonth; ! 295: ! 296: if(ConfigureParams.System.bFastForward) { ! 297: SDLGui_Text(FrameSkipsRect.x, FrameSkipsRect.y, "0 >>"); ! 298: } else { ! 299: SDLGui_Text(FrameSkipsRect.x, FrameSkipsRect.y, "0"); ! 300: } ! 301: ! 302: nOldFrameSkips = 0; ! 303: ! 304: /* intialize messages */ ! 305: MessageRect.x = FrameSkipsRect.x + FrameSkipsRect.w + fontw; ! 306: MessageRect.w = MAX_MESSAGE_LEN * fontw; ! 307: MessageRect.h = fonth; ! 308: for (item = MessageList; item; item = item->next) { ! 309: item->shown = false; ! 310: } ! 311: ! 312: /* draw recording led box */ ! 313: RecLedRect = LedRect; ! 314: RecLedRect.x = surf->w - fontw - RecLedRect.w; ! 315: ledbox.x = RecLedRect.x - 1; ! 316: SDLGui_Text(ledbox.x - 4*fontw - fontw/2, MessageRect.y, "REC:"); ! 317: SDL_FillRect(surf, &ledbox, LedColorBg); ! 318: SDL_FillRect(surf, &RecLedRect, RecColorOff); ! 319: bOldRecording = false; ! 320: ! 321: /* and blit statusbar on screen */ ! 322: SDL_UpdateRects(surf, 1, &sbarbox); ! 323: DEBUGPRINT(("Draw statusbar\n")); ! 324: } ! 325: ! 326: ! 327: /*-----------------------------------------------------------------------*/ ! 328: /** ! 329: * Qeueue new statusbar message 'msg' to be shown for 'msecs' milliseconds ! 330: */ ! 331: void Statusbar_AddMessage(const char *msg, Uint32 msecs) ! 332: { ! 333: msg_item_t *item; ! 334: ! 335: if (!ConfigureParams.Screen.bShowStatusbar) { ! 336: /* no sense in queuing messages that aren't shown */ ! 337: return; ! 338: } ! 339: item = calloc(1, sizeof(msg_item_t)); ! 340: assert(item); ! 341: ! 342: item->next = MessageList; ! 343: MessageList = item; ! 344: ! 345: strncpy(item->msg, msg, MAX_MESSAGE_LEN); ! 346: item->msg[MAX_MESSAGE_LEN] = '\0'; ! 347: DEBUGPRINT(("Add message: '%s'\n", item->msg)); ! 348: ! 349: if (msecs) { ! 350: item->timeout = msecs; ! 351: } else { ! 352: /* show items by default for 2.5 secs */ ! 353: item->timeout = 2500; ! 354: } ! 355: item->shown = false; ! 356: } ! 357: ! 358: /*-----------------------------------------------------------------------*/ ! 359: /** ! 360: * Write given 'more' string to 'buffer' and return new end of 'buffer' ! 361: */ ! 362: static char *Statusbar_AddString(char *buffer, const char *more) ! 363: { ! 364: while(*more) { ! 365: *buffer++ = *more++; ! 366: } ! 367: return buffer; ! 368: } ! 369: ! 370: /*-----------------------------------------------------------------------*/ ! 371: /** ! 372: * Retrieve/update default statusbar information ! 373: */ ! 374: void Statusbar_UpdateInfo(void) ! 375: { ! 376: char *end = DefaultMessage.msg; ! 377: ! 378: /* CPU MHz */ ! 379: if (ConfigureParams.System.nCpuFreq > 9) { ! 380: *end++ = '0' + ConfigureParams.System.nCpuFreq / 10; ! 381: } ! 382: *end++ = '0' + ConfigureParams.System.nCpuFreq % 10; ! 383: end = Statusbar_AddString(end, "MHz/"); ! 384: ! 385: /* CPU type */ ! 386: if(ConfigureParams.System.nCpuLevel > 0) { ! 387: *end++ = '0'; ! 388: *end++ = '0' + ConfigureParams.System.nCpuLevel % 10; ! 389: *end++ = '0'; ! 390: *end++ = '/'; ! 391: } ! 392: ! 393: /* amount of memory */ ! 394: if (ConfigureParams.Memory.nMemorySize > 9) { ! 395: *end++ = '1'; ! 396: *end++ = '0' + ConfigureParams.Memory.nMemorySize % 10; ! 397: } else { ! 398: if (ConfigureParams.Memory.nMemorySize) { ! 399: *end++ = '0' + ConfigureParams.Memory.nMemorySize; ! 400: } else { ! 401: end = Statusbar_AddString(end, "1/2"); ! 402: } ! 403: } ! 404: end = Statusbar_AddString(end, "MB "); ! 405: ! 406: /* machine type */ ! 407: end = Statusbar_AddString(end, "NEXT"); ! 408: ! 409: *end = '\0'; ! 410: ! 411: assert(end - DefaultMessage.msg < MAX_MESSAGE_LEN); ! 412: DEBUGPRINT(("Set default message: '%s'\n", DefaultMessage.msg)); ! 413: DefaultMessage.shown = false; ! 414: } ! 415: ! 416: /*-----------------------------------------------------------------------*/ ! 417: /** ! 418: * Draw 'msg' centered to the message area ! 419: */ ! 420: static void Statusbar_DrawMessage(SDL_Surface *surf, const char *msg) ! 421: { ! 422: int fontw, fonth, offset; ! 423: SDL_FillRect(surf, &MessageRect, GrayBg); ! 424: if (*msg) { ! 425: SDLGui_GetFontSize(&fontw, &fonth); ! 426: offset = (MessageRect.w - strlen(msg) * fontw) / 2; ! 427: SDLGui_Text(MessageRect.x + offset, MessageRect.y, msg); ! 428: } ! 429: SDL_UpdateRects(surf, 1, &MessageRect); ! 430: DEBUGPRINT(("Draw message: '%s'\n", msg)); ! 431: } ! 432: ! 433: /*-----------------------------------------------------------------------*/ ! 434: /** ! 435: * If message's not shown, show it. If message's timed out, ! 436: * remove it and show next one. ! 437: */ ! 438: static void Statusbar_ShowMessage(SDL_Surface *surf, Uint32 ticks) ! 439: { ! 440: msg_item_t *next; ! 441: ! 442: if (MessageList->shown) { ! 443: if (!MessageList->expire) { ! 444: /* last/default message */ ! 445: return; ! 446: } ! 447: if (MessageList->expire > ticks) { ! 448: /* not timed out yet */ ! 449: return; ! 450: } ! 451: assert(MessageList->next); /* last message shouldn't end here */ ! 452: next = MessageList->next; ! 453: free(MessageList); ! 454: MessageList = next; ! 455: /* make sure next message gets shown */ ! 456: MessageList->shown = false; ! 457: } ! 458: if (!MessageList->shown) { ! 459: /* not shown yet, show */ ! 460: Statusbar_DrawMessage(surf, MessageList->msg); ! 461: if (MessageList->timeout && !MessageList->expire) { ! 462: MessageList->expire = ticks + MessageList->timeout; ! 463: } ! 464: MessageList->shown = true; ! 465: } ! 466: } ! 467: ! 468: ! 469: /*-----------------------------------------------------------------------*/ ! 470: /** ! 471: * Save the area that will be left under overlay led ! 472: */ ! 473: void Statusbar_OverlayBackup(SDL_Surface *surf) ! 474: { ! 475: if ((StatusbarHeight && ConfigureParams.Screen.bShowStatusbar) ! 476: || !ConfigureParams.Screen.bShowDriveLed) { ! 477: /* overlay not used with statusbar */ ! 478: return; ! 479: } ! 480: assert(surf); ! 481: if (!OverlayUnderside) { ! 482: SDL_Surface *bak; ! 483: SDL_PixelFormat *fmt = surf->format; ! 484: bak = SDL_CreateRGBSurface(surf->flags, ! 485: OverlayLedRect.w, OverlayLedRect.h, ! 486: fmt->BitsPerPixel, ! 487: fmt->Rmask, fmt->Gmask, fmt->Bmask, ! 488: fmt->Amask); ! 489: assert(bak); ! 490: OverlayUnderside = bak; ! 491: } ! 492: SDL_BlitSurface(surf, &OverlayLedRect, OverlayUnderside, NULL); ! 493: } ! 494: ! 495: /*-----------------------------------------------------------------------*/ ! 496: /** ! 497: * Restore the area left under overlay led ! 498: */ ! 499: void Statusbar_OverlayRestore(SDL_Surface *surf) ! 500: { ! 501: if ((StatusbarHeight && ConfigureParams.Screen.bShowStatusbar) ! 502: || !ConfigureParams.Screen.bShowDriveLed) { ! 503: /* overlay not used with statusbar */ ! 504: return; ! 505: } ! 506: if (bOverlayState == OVERLAY_DRAWN && OverlayUnderside) { ! 507: assert(surf); ! 508: SDL_BlitSurface(OverlayUnderside, NULL, surf, &OverlayLedRect); ! 509: /* this will make the draw function to update this the screen */ ! 510: bOverlayState = OVERLAY_RESTORED; ! 511: } ! 512: } ! 513: ! 514: /*-----------------------------------------------------------------------*/ ! 515: /** ! 516: * Draw overlay led ! 517: */ ! 518: static void Statusbar_OverlayDrawLed(SDL_Surface *surf, Uint32 color) ! 519: { ! 520: SDL_Rect rect; ! 521: if (bOverlayState == OVERLAY_DRAWN) { ! 522: /* some led already drawn */ ! 523: return; ! 524: } ! 525: bOverlayState = OVERLAY_DRAWN; ! 526: ! 527: /* enabled led with border */ ! 528: rect = OverlayLedRect; ! 529: rect.x += 1; ! 530: rect.y += 1; ! 531: rect.w -= 2; ! 532: rect.h -= 2; ! 533: SDL_FillRect(surf, &OverlayLedRect, LedColorBg); ! 534: SDL_FillRect(surf, &rect, color); ! 535: } ! 536: ! 537: /*-----------------------------------------------------------------------*/ ! 538: /** ! 539: * Draw overlay led onto screen surface if any drives are enabled. ! 540: */ ! 541: static void Statusbar_OverlayDraw(SDL_Surface *surf) ! 542: { ! 543: Uint32 currentticks = SDL_GetTicks(); ! 544: int i; ! 545: ! 546: assert(surf); ! 547: for (i = 0; i < MAX_DRIVE_LEDS; i++) { ! 548: if (Led[i].state) { ! 549: if (Led[i].expire && Led[i].expire < currentticks) { ! 550: Led[i].state = false; ! 551: continue; ! 552: } ! 553: Statusbar_OverlayDrawLed(surf, LedColorOn); ! 554: break; ! 555: } ! 556: } ! 557: /* possible state transitions: ! 558: * NONE -> DRAWN -> RESTORED -> DRAWN -> RESTORED -> NONE ! 559: * Other than NONE state needs to be updated on screen ! 560: */ ! 561: switch (bOverlayState) { ! 562: case OVERLAY_RESTORED: ! 563: bOverlayState = OVERLAY_NONE; ! 564: case OVERLAY_DRAWN: ! 565: SDL_UpdateRects(surf, 1, &OverlayLedRect); ! 566: DEBUGPRINT(("Overlay LED = %s\n", bOverlayState==OVERLAY_DRAWN?"ON":"OFF")); ! 567: break; ! 568: case OVERLAY_NONE: ! 569: break; ! 570: } ! 571: } ! 572: ! 573: ! 574: /*-----------------------------------------------------------------------*/ ! 575: /** ! 576: * Update statusbar information (leds etc) if/when needed. ! 577: * ! 578: * May not be called when screen is locked (SDL limitation). ! 579: */ ! 580: void Statusbar_Update(SDL_Surface *surf) ! 581: { ! 582: Uint32 color, currentticks; ! 583: SDL_Rect rect; ! 584: int i; ! 585: ! 586: if (!(StatusbarHeight && ConfigureParams.Screen.bShowStatusbar)) { ! 587: /* not enabled (anymore), show overlay led instead? */ ! 588: if (ConfigureParams.Screen.bShowDriveLed) { ! 589: Statusbar_OverlayDraw(surf); ! 590: } ! 591: return; ! 592: } ! 593: assert(surf); ! 594: /* Statusbar_Init() not called before this? */ ! 595: assert(surf->h == ScreenHeight + StatusbarHeight); ! 596: ! 597: rect = LedRect; ! 598: currentticks = SDL_GetTicks(); ! 599: for (i = 0; i < MAX_DRIVE_LEDS; i++) { ! 600: if (Led[i].expire && Led[i].expire < currentticks) { ! 601: Led[i].state = false; ! 602: } ! 603: if (Led[i].state == Led[i].oldstate) { ! 604: continue; ! 605: } ! 606: Led[i].oldstate = Led[i].state; ! 607: if (Led[i].state) { ! 608: color = LedColorOn; ! 609: } else { ! 610: color = LedColorOff; ! 611: } ! 612: rect.x = Led[i].offset; ! 613: SDL_FillRect(surf, &rect, color); ! 614: SDL_UpdateRects(surf, 1, &rect); ! 615: DEBUGPRINT(("LED[%d] = %s\n", i, Led[i].state?"ON":"OFF")); ! 616: } ! 617: ! 618: Statusbar_ShowMessage(surf, currentticks); ! 619: ! 620: ! 621: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.