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