|
|
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: const char Statusbar_fileid[] = "Hatari statusbar.c : " __DATE__ " " __TIME__; ! 29: ! 30: #include <assert.h> ! 31: #include "main.h" ! 32: #include "configuration.h" ! 33: #include "sdlgui.h" ! 34: #include "statusbar.h" ! 35: #include "screen.h" ! 36: #include "video.h" ! 37: #include "dimension.hpp" ! 38: ! 39: #define DEBUG 0 ! 40: #if DEBUG ! 41: #define DEBUGPRINT(x) printf x ! 42: #else ! 43: #define DEBUGPRINT(x) ! 44: #endif ! 45: ! 46: /* whether drive leds should be ON and their previous shown state */ ! 47: static struct { ! 48: bool state; ! 49: bool oldstate; ! 50: Uint32 expire; /* when to disable led, valid only if >0 && state=TRUE */ ! 51: int offset; /* led x-pos on screen */ ! 52: } Led[NUM_DEVICE_LEDS]; ! 53: ! 54: /* drive leds size & y-pos */ ! 55: static SDL_Rect LedRect; ! 56: ! 57: /* overlay led size & pos */ ! 58: static SDL_Rect OverlayLedRect; ! 59: ! 60: /* screen contents left under overlay led */ ! 61: static SDL_Surface *OverlayUnderside; ! 62: ! 63: static enum { ! 64: OVERLAY_NONE, ! 65: OVERLAY_DRAWN, ! 66: OVERLAY_RESTORED ! 67: } bOverlayState; ! 68: ! 69: static SDL_Rect SystemLedRect; ! 70: static bool bOldSystemLed; ! 71: ! 72: static SDL_Rect DspLedRect; ! 73: static bool bOldDspLed; ! 74: ! 75: static SDL_Rect NdLedRect; ! 76: static int nOldNdLed; ! 77: ! 78: /* led colors */ ! 79: static Uint32 LedColorOn, LedColorOnWP, LedColorOff, SysColorOn, SysColorOff, DspColorOn, DspColorOff; ! 80: static Uint32 NdColorOn, NdColorCS8, NdColorOff; ! 81: static Uint32 GrayBg, LedColorBg; ! 82: ! 83: #define MAX_MESSAGE_LEN 69 ! 84: typedef struct msg_item { ! 85: struct msg_item *next; ! 86: char msg[MAX_MESSAGE_LEN+1]; ! 87: Uint32 timeout; /* msecs, zero=no timeout */ ! 88: Uint32 expire; /* when to expire message */ ! 89: bool shown; ! 90: } msg_item_t; ! 91: ! 92: static msg_item_t DefaultMessage; ! 93: static msg_item_t *MessageList = &DefaultMessage; ! 94: static SDL_Rect MessageRect; ! 95: ! 96: /* screen height above statusbar and height of statusbar below screen */ ! 97: static int ScreenHeight; ! 98: static int StatusbarHeight; ! 99: ! 100: ! 101: /*-----------------------------------------------------------------------*/ ! 102: /** ! 103: * Return statusbar height for given width and height ! 104: */ ! 105: int Statusbar_GetHeightForSize(int width, int height) ! 106: { ! 107: if (ConfigureParams.Screen.bShowStatusbar) { ! 108: /* Should check the same thing as SDLGui_SetScreen() ! 109: * does to decide the font size. ! 110: */ ! 111: if (width >= 640 && height >= (400-24)) { ! 112: return 24; ! 113: } else { ! 114: return 12; ! 115: } ! 116: } ! 117: return 0; ! 118: } ! 119: ! 120: /*-----------------------------------------------------------------------*/ ! 121: /** ! 122: * Set screen height used for statusbar height calculation. ! 123: * ! 124: * Return height of statusbar that should be added to the screen ! 125: * height when screen is (re-)created, or zero if statusbar will ! 126: * not be shown ! 127: */ ! 128: int Statusbar_SetHeight(int width, int height) ! 129: { ! 130: ScreenHeight = height; ! 131: StatusbarHeight = Statusbar_GetHeightForSize(width, height); ! 132: return StatusbarHeight; ! 133: } ! 134: ! 135: /*-----------------------------------------------------------------------*/ ! 136: /** ! 137: * Return height of statusbar set with Statusbar_SetHeight() ! 138: */ ! 139: int Statusbar_GetHeight(void) ! 140: { ! 141: return StatusbarHeight; ! 142: } ! 143: ! 144: ! 145: /*-----------------------------------------------------------------------*/ ! 146: /** ! 147: * Enable device led, it will be automatically disabled after a while. ! 148: */ ! 149: void Statusbar_BlinkLed(drive_index_t drive) ! 150: { ! 151: /* leds are shown for 1/2 sec after enabling */ ! 152: Led[drive].expire = SDL_GetTicks() + 1000/2; ! 153: Led[drive].state = true; ! 154: } ! 155: ! 156: ! 157: /*-----------------------------------------------------------------------*/ ! 158: /** ! 159: * Set system, DSP, CPU and NeXTdimension led state, anything enabling led with ! 160: * this needs also to take care of disabling it. ! 161: */ ! 162: void Statusbar_SetSystemLed(bool state) { ! 163: bOldSystemLed = state; ! 164: } ! 165: ! 166: void Statusbar_SetDspLed(bool state) { ! 167: bOldDspLed = state; ! 168: } ! 169: ! 170: void Statusbar_SetNdLed(int state) { ! 171: nOldNdLed = state; ! 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[NUM_DEVICE_LEDS] = { "EN:", "MO:", "SD:", "FD:" }; ! 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: LedColorOnWP = SDL_MapRGB(surf->format, 0xFF, 0xe0, 0x00); ! 218: LedColorBg = SDL_MapRGB(surf->format, 0x00, 0x00, 0x00); ! 219: SysColorOff = SDL_MapRGB(surf->format, 0x40, 0x00, 0x00); ! 220: SysColorOn = SDL_MapRGB(surf->format, 0xe0, 0x00, 0x00); ! 221: DspColorOff = SDL_MapRGB(surf->format, 0x00, 0x00, 0x40); ! 222: DspColorOn = SDL_MapRGB(surf->format, 0x00, 0x00, 0xe0); ! 223: NdColorOff = SDL_MapRGB(surf->format, 0x00, 0x00, 0x40); ! 224: NdColorCS8 = SDL_MapRGB(surf->format, 0xe0, 0x00, 0x00); ! 225: NdColorOn = SDL_MapRGB(surf->format, 0x00, 0x00, 0xe0); ! 226: GrayBg = SDL_MapRGB(surf->format, 0xb5, 0xb7, 0xaa); ! 227: ! 228: /* disable leds */ ! 229: for (i = 0; i < NUM_DEVICE_LEDS; i++) { ! 230: Led[i].state = Led[i].oldstate = false; ! 231: Led[i].expire = 0; ! 232: } ! 233: Statusbar_OverlayInit(surf); ! 234: ! 235: /* disable statusbar if it doesn't fit to video mode */ ! 236: if (surf->h < ScreenHeight + StatusbarHeight) { ! 237: StatusbarHeight = 0; ! 238: } ! 239: if (!StatusbarHeight) { ! 240: return; ! 241: } ! 242: ! 243: /* prepare fonts */ ! 244: SDLGui_Init(); ! 245: SDLGui_SetScreen(surf); ! 246: SDLGui_GetFontSize(&fontw, &fonth); ! 247: ! 248: /* video mode didn't match, need to recalculate sizes */ ! 249: if (surf->h > ScreenHeight + StatusbarHeight) { ! 250: StatusbarHeight = fonth + 2; ! 251: /* actually statusbar vertical offset */ ! 252: ScreenHeight = surf->h - StatusbarHeight; ! 253: } else { ! 254: assert(fonth+2 < StatusbarHeight); ! 255: } ! 256: ! 257: /* draw statusbar background gray so that text shows */ ! 258: sbarbox.x = 0; ! 259: sbarbox.y = surf->h - StatusbarHeight; ! 260: sbarbox.w = surf->w; ! 261: sbarbox.h = StatusbarHeight; ! 262: SDL_FillRect(surf, &sbarbox, GrayBg); ! 263: ! 264: /* led size */ ! 265: LedRect.w = fonth/2; ! 266: LedRect.h = fonth - 4; ! 267: LedRect.y = ScreenHeight + StatusbarHeight/2 - LedRect.h/2; ! 268: ! 269: /* black box for the leds */ ! 270: ledbox = LedRect; ! 271: ledbox.y -= 1; ! 272: ledbox.w += 2; ! 273: ledbox.h += 2; ! 274: ! 275: offset = fontw; ! 276: MessageRect.y = LedRect.y - 2; ! 277: /* draw led texts and boxes + calculate box offsets */ ! 278: for (i = 0; i < NUM_DEVICE_LEDS; i++) { ! 279: SDLGui_Text(offset, MessageRect.y, text[i]); ! 280: offset += strlen(text[i]) * fontw; ! 281: offset += fontw/2; ! 282: ! 283: ledbox.x = offset - 1; ! 284: SDL_FillRect(surf, &ledbox, LedColorBg); ! 285: ! 286: LedRect.x = offset; ! 287: SDL_FillRect(surf, &LedRect, LedColorOff); ! 288: ! 289: Led[i].offset = offset; ! 290: offset += LedRect.w + fontw; ! 291: } ! 292: MessageRect.x = offset + fontw; ! 293: MessageRect.w = MAX_MESSAGE_LEN * fontw; ! 294: MessageRect.h = fonth; ! 295: for (item = MessageList; item; item = item->next) { ! 296: item->shown = false; ! 297: } ! 298: ! 299: /* draw i860 led box */ ! 300: NdLedRect = LedRect; ! 301: NdLedRect.x = surf->w - 15*fontw - NdLedRect.w; ! 302: ledbox.x = NdLedRect.x - 1; ! 303: SDLGui_Text(ledbox.x - 3*fontw - fontw/2, MessageRect.y, "ND:"); ! 304: SDL_FillRect(surf, &ledbox, LedColorBg); ! 305: SDL_FillRect(surf, &NdLedRect, NdColorOff); ! 306: nOldNdLed = 0; ! 307: ! 308: /* draw dsp led box */ ! 309: DspLedRect = LedRect; ! 310: DspLedRect.x = surf->w - 8*fontw - DspLedRect.w; ! 311: ledbox.x = DspLedRect.x - 1; ! 312: SDLGui_Text(ledbox.x - 4*fontw - fontw/2, MessageRect.y, "DSP:"); ! 313: SDL_FillRect(surf, &ledbox, LedColorBg); ! 314: SDL_FillRect(surf, &DspLedRect, DspColorOff); ! 315: bOldDspLed = false; ! 316: ! 317: /* draw system led box */ ! 318: SystemLedRect = LedRect; ! 319: SystemLedRect.x = surf->w - fontw - SystemLedRect.w; ! 320: ledbox.x = SystemLedRect.x - 1; ! 321: SDLGui_Text(ledbox.x - 4*fontw - fontw/2, MessageRect.y, "LED:"); ! 322: SDL_FillRect(surf, &ledbox, LedColorBg); ! 323: SDL_FillRect(surf, &SystemLedRect, SysColorOff); ! 324: bOldSystemLed = false; ! 325: ! 326: /* and blit statusbar on screen */ ! 327: SDL_UpdateRects(surf, 1, &sbarbox); ! 328: DEBUGPRINT(("Draw statusbar\n")); ! 329: } ! 330: ! 331: ! 332: /*-----------------------------------------------------------------------*/ ! 333: /** ! 334: * Qeueue new statusbar message 'msg' to be shown for 'msecs' milliseconds ! 335: */ ! 336: void Statusbar_AddMessage(const char *msg, Uint32 msecs) ! 337: { ! 338: msg_item_t *item; ! 339: ! 340: if (!ConfigureParams.Screen.bShowStatusbar) { ! 341: /* no sense in queuing messages that aren't shown */ ! 342: return; ! 343: } ! 344: item = calloc(1, sizeof(msg_item_t)); ! 345: assert(item); ! 346: ! 347: item->next = MessageList; ! 348: MessageList = item; ! 349: ! 350: strncpy(item->msg, msg, MAX_MESSAGE_LEN); ! 351: item->msg[MAX_MESSAGE_LEN] = '\0'; ! 352: DEBUGPRINT(("Add message: '%s'\n", item->msg)); ! 353: ! 354: if (msecs) { ! 355: item->timeout = msecs; ! 356: } else { ! 357: /* show items by default for 2.5 secs */ ! 358: item->timeout = 2500; ! 359: } ! 360: item->shown = false; ! 361: } ! 362: ! 363: /*-----------------------------------------------------------------------*/ ! 364: /** ! 365: * Write given 'more' string to 'buffer' and return new end of 'buffer' ! 366: */ ! 367: static char *Statusbar_AddString(char *buffer, const char *more) ! 368: { ! 369: while(*more) { ! 370: *buffer++ = *more++; ! 371: } ! 372: return buffer; ! 373: } ! 374: ! 375: /*-----------------------------------------------------------------------*/ ! 376: /** ! 377: * Retrieve/update default statusbar information ! 378: */ ! 379: void Statusbar_UpdateInfo(void) ! 380: { ! 381: char *end = DefaultMessage.msg; ! 382: char memsize[16]; ! 383: char slot[16]; ! 384: ! 385: /* Message for NeXTdimension */ ! 386: if (ConfigureParams.Screen.nMonitorType==MONITOR_TYPE_DIMENSION) { ! 387: end = Statusbar_AddString(end, "33MHz/i860XR/"); ! 388: sprintf(memsize, "%iMB/",Configuration_CheckDimensionMemory(ConfigureParams.Dimension.board[ConfigureParams.Screen.nMonitorNum].nMemoryBankSize)); ! 389: end = Statusbar_AddString(end, memsize); ! 390: end = Statusbar_AddString(end, "NeXTdimension/"); ! 391: sprintf(slot, "Slot%i", ND_SLOT(ConfigureParams.Screen.nMonitorNum)); ! 392: end = Statusbar_AddString(end, slot); ! 393: *end = '\0'; ! 394: assert(end - DefaultMessage.msg < MAX_MESSAGE_LEN); ! 395: DefaultMessage.shown = false; ! 396: return; ! 397: } ! 398: ! 399: /* CPU MHz */ ! 400: end = Statusbar_AddString(end, Main_SpeedMsg()); ! 401: ! 402: /* CPU type */ ! 403: if(ConfigureParams.System.nCpuLevel > 0) { ! 404: *end++ = '6'; ! 405: *end++ = '8'; ! 406: *end++ = '0'; ! 407: switch (ConfigureParams.System.nCpuLevel) { ! 408: case 0: *end++ = '0'; break; ! 409: case 1: *end++ = '1'; break; ! 410: case 2: *end++ = '2'; break; ! 411: case 3: *end++ = '3'; break; ! 412: case 4: *end++ = '4'; break; ! 413: case 5: *end++ = '6'; break; ! 414: default: break; ! 415: } ! 416: *end++ = '0'; ! 417: *end++ = '/'; ! 418: } ! 419: ! 420: /* amount of memory */ ! 421: sprintf(memsize, "%iMB/", Configuration_CheckMemory(ConfigureParams.Memory.nMemoryBankSize)); ! 422: end = Statusbar_AddString(end, memsize); ! 423: ! 424: /* machine type */ ! 425: switch (ConfigureParams.System.nMachineType) { ! 426: case NEXT_CUBE030: ! 427: end = Statusbar_AddString(end, "NeXT Computer"); ! 428: break; ! 429: case NEXT_CUBE040: ! 430: end = Statusbar_AddString(end, "NeXTcube"); ! 431: break; ! 432: case NEXT_STATION: ! 433: end = Statusbar_AddString(end, "NeXTstation"); ! 434: break; ! 435: ! 436: default: ! 437: break; ! 438: } ! 439: if (ConfigureParams.System.bTurbo) { ! 440: end = Statusbar_AddString(end, (ConfigureParams.System.nCpuFreq==40)?" Nitro":" Turbo"); ! 441: } ! 442: ! 443: if (ConfigureParams.System.bColor) { ! 444: end = Statusbar_AddString(end, " Color"); ! 445: } ! 446: ! 447: *end = '\0'; ! 448: ! 449: assert(end - DefaultMessage.msg < MAX_MESSAGE_LEN); ! 450: DEBUGPRINT(("Set default message: '%s'\n", DefaultMessage.msg)); ! 451: /* make sure default message gets (re-)drawn when next checked */ ! 452: DefaultMessage.shown = false; ! 453: } ! 454: ! 455: /*-----------------------------------------------------------------------*/ ! 456: /** ! 457: * Draw 'msg' centered to the message area ! 458: */ ! 459: static void Statusbar_DrawMessage(SDL_Surface *surf, const char *msg) ! 460: { ! 461: int fontw, fonth, offset; ! 462: SDL_FillRect(surf, &MessageRect, GrayBg); ! 463: if (*msg) { ! 464: SDLGui_GetFontSize(&fontw, &fonth); ! 465: offset = (MessageRect.w - strlen(msg) * fontw) / 2; ! 466: SDLGui_Text(MessageRect.x + offset, MessageRect.y, msg); ! 467: } ! 468: SDL_UpdateRects(surf, 1, &MessageRect); ! 469: DEBUGPRINT(("Draw message: '%s'\n", msg)); ! 470: } ! 471: ! 472: /*-----------------------------------------------------------------------*/ ! 473: /** ! 474: * If message's not shown, show it. If message's timed out, ! 475: * remove it and show next one. ! 476: */ ! 477: static void Statusbar_ShowMessage(SDL_Surface *surf, Uint32 ticks) ! 478: { ! 479: msg_item_t *next; ! 480: ! 481: if (MessageList->shown) { ! 482: if (!MessageList->expire) { ! 483: /* last/default message never expires */ ! 484: return; ! 485: } ! 486: if (MessageList->expire > ticks) { ! 487: /* not timed out yet */ ! 488: return; ! 489: } ! 490: assert(MessageList->next); /* last message shouldn't end here */ ! 491: next = MessageList->next; ! 492: free(MessageList); ! 493: MessageList = next; ! 494: /* make sure next message gets shown */ ! 495: MessageList->shown = false; ! 496: } ! 497: if (!MessageList->shown) { ! 498: /* not shown yet, show */ ! 499: Statusbar_DrawMessage(surf, MessageList->msg); ! 500: if (MessageList->timeout && !MessageList->expire) { ! 501: MessageList->expire = ticks + MessageList->timeout; ! 502: } ! 503: MessageList->shown = true; ! 504: } ! 505: } ! 506: ! 507: ! 508: /*-----------------------------------------------------------------------*/ ! 509: /** ! 510: * Save the area that will be left under overlay led ! 511: */ ! 512: void Statusbar_OverlayBackup(SDL_Surface *surf) ! 513: { ! 514: if ((StatusbarHeight && ConfigureParams.Screen.bShowStatusbar) ! 515: || !ConfigureParams.Screen.bShowDriveLed) { ! 516: /* overlay not used with statusbar */ ! 517: return; ! 518: } ! 519: assert(surf); ! 520: if (!OverlayUnderside) { ! 521: SDL_Surface *bak; ! 522: SDL_PixelFormat *fmt = surf->format; ! 523: bak = SDL_CreateRGBSurface(surf->flags, ! 524: OverlayLedRect.w, OverlayLedRect.h, ! 525: fmt->BitsPerPixel, ! 526: fmt->Rmask, fmt->Gmask, fmt->Bmask, ! 527: fmt->Amask); ! 528: assert(bak); ! 529: OverlayUnderside = bak; ! 530: } ! 531: SDL_BlitSurface(surf, &OverlayLedRect, OverlayUnderside, NULL); ! 532: } ! 533: ! 534: /*-----------------------------------------------------------------------*/ ! 535: /** ! 536: * Restore the area left under overlay led ! 537: */ ! 538: void Statusbar_OverlayRestore(SDL_Surface *surf) ! 539: { ! 540: if ((StatusbarHeight && ConfigureParams.Screen.bShowStatusbar) ! 541: || !ConfigureParams.Screen.bShowDriveLed) { ! 542: /* overlay not used with statusbar */ ! 543: return; ! 544: } ! 545: if (bOverlayState == OVERLAY_DRAWN && OverlayUnderside) { ! 546: assert(surf); ! 547: SDL_BlitSurface(OverlayUnderside, NULL, surf, &OverlayLedRect); ! 548: /* this will make the draw function to update this the screen */ ! 549: bOverlayState = OVERLAY_RESTORED; ! 550: } ! 551: } ! 552: ! 553: /*-----------------------------------------------------------------------*/ ! 554: /** ! 555: * Draw overlay led ! 556: */ ! 557: static void Statusbar_OverlayDrawLed(SDL_Surface *surf, Uint32 color) ! 558: { ! 559: SDL_Rect rect; ! 560: if (bOverlayState == OVERLAY_DRAWN) { ! 561: /* some led already drawn */ ! 562: return; ! 563: } ! 564: bOverlayState = OVERLAY_DRAWN; ! 565: ! 566: /* enabled led with border */ ! 567: rect = OverlayLedRect; ! 568: rect.x += 1; ! 569: rect.y += 1; ! 570: rect.w -= 2; ! 571: rect.h -= 2; ! 572: SDL_FillRect(surf, &OverlayLedRect, LedColorBg); ! 573: SDL_FillRect(surf, &rect, color); ! 574: } ! 575: ! 576: /*-----------------------------------------------------------------------*/ ! 577: /** ! 578: * Draw overlay led onto screen surface if any drives are enabled. ! 579: */ ! 580: static void Statusbar_OverlayDraw(SDL_Surface *surf) ! 581: { ! 582: Uint32 currentticks = SDL_GetTicks(); ! 583: int i; ! 584: ! 585: assert(surf); ! 586: for (i = 0; i < NUM_DEVICE_LEDS; i++) { ! 587: if (Led[i].state) { ! 588: if (Led[i].expire && Led[i].expire < currentticks) { ! 589: Led[i].state = false; ! 590: continue; ! 591: } ! 592: Statusbar_OverlayDrawLed(surf, ConfigureParams.SCSI.nWriteProtection == WRITEPROT_ON && i == DEVICE_LED_SCSI ? LedColorOnWP : LedColorOn); ! 593: break; ! 594: } ! 595: } ! 596: /* possible state transitions: ! 597: * NONE -> DRAWN -> RESTORED -> DRAWN -> RESTORED -> NONE ! 598: * Other than NONE state needs to be updated on screen ! 599: */ ! 600: switch (bOverlayState) { ! 601: case OVERLAY_RESTORED: ! 602: bOverlayState = OVERLAY_NONE; ! 603: case OVERLAY_DRAWN: ! 604: SDL_UpdateRects(surf, 1, &OverlayLedRect); ! 605: DEBUGPRINT(("Overlay LED = %s\n", bOverlayState==OVERLAY_DRAWN?"ON":"OFF")); ! 606: break; ! 607: case OVERLAY_NONE: ! 608: break; ! 609: } ! 610: } ! 611: ! 612: ! 613: /*-----------------------------------------------------------------------*/ ! 614: /** ! 615: * Update statusbar information (leds etc) if/when needed. ! 616: * ! 617: * May not be called when screen is locked (SDL limitation). ! 618: */ ! 619: void Statusbar_Update(SDL_Surface *surf) { ! 620: Uint32 color, currentticks; ! 621: SDL_Rect rect; ! 622: int i; ! 623: ! 624: if (!(StatusbarHeight && ConfigureParams.Screen.bShowStatusbar)) { ! 625: /* not enabled (anymore), show overlay led instead? */ ! 626: if (ConfigureParams.Screen.bShowDriveLed) { ! 627: Statusbar_OverlayDraw(surf); ! 628: } ! 629: return; ! 630: } ! 631: assert(surf); ! 632: /* Statusbar_Init() not called before this? */ ! 633: assert(surf->h == ScreenHeight + StatusbarHeight); ! 634: ! 635: rect = LedRect; ! 636: currentticks = SDL_GetTicks(); ! 637: for (i = 0; i < NUM_DEVICE_LEDS; i++) { ! 638: if (Led[i].expire && Led[i].expire < currentticks) { ! 639: Led[i].state = false; ! 640: } ! 641: if (Led[i].state == Led[i].oldstate) { ! 642: continue; ! 643: } ! 644: Led[i].oldstate = Led[i].state; ! 645: if (Led[i].state) { ! 646: color = ConfigureParams.SCSI.nWriteProtection == WRITEPROT_ON && i == DEVICE_LED_SCSI ? LedColorOnWP : LedColorOn; ! 647: } else { ! 648: color = LedColorOff; ! 649: } ! 650: rect.x = Led[i].offset; ! 651: SDL_FillRect(surf, &rect, color); ! 652: SDL_UpdateRects(surf, 1, &rect); ! 653: } ! 654: ! 655: Statusbar_ShowMessage(surf, currentticks); ! 656: ! 657: /* Draw dsp LED */ ! 658: if (bOldDspLed) { ! 659: color = DspColorOn; ! 660: } else { ! 661: color = DspColorOff; ! 662: } ! 663: SDL_FillRect(surf, &DspLedRect, color); ! 664: SDL_UpdateRects(surf, 1, &DspLedRect); ! 665: ! 666: /* Draw scr2 LED */ ! 667: if (bOldSystemLed) { ! 668: color = SysColorOn; ! 669: } else { ! 670: color = SysColorOff; ! 671: } ! 672: SDL_FillRect(surf, &SystemLedRect, color); ! 673: SDL_UpdateRects(surf, 1, &SystemLedRect); ! 674: ! 675: /* Draw NeXTdimension LED */ ! 676: switch(nOldNdLed) { ! 677: case 0: color = NdColorOff; break; ! 678: case 1: color = NdColorCS8; break; ! 679: case 2: color = NdColorOn; break; ! 680: default: color = NdColorOff; break; ! 681: } ! 682: SDL_FillRect(surf, &NdLedRect, color); ! 683: SDL_UpdateRects(surf, 1, &NdLedRect); ! 684: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.