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