|
|
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"
1.1.1.2 root 35: #include "screen.h"
1.1 root 36: #include "video.h"
1.1.1.6 ! root 37: #include "dimension.hpp"
1.1 root 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 */
1.1.1.4 root 52: } Led[NUM_DEVICE_LEDS];
1.1 root 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:
1.1.1.4 root 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;
1.1 root 77:
78: /* led colors */
1.1.1.5 root 79: static Uint32 LedColorOn, LedColorOnWP, LedColorOff, SysColorOn, SysColorOff, DspColorOn, DspColorOff;
1.1.1.4 root 80: static Uint32 NdColorOn, NdColorCS8, NdColorOff;
1.1 root 81: static Uint32 GrayBg, LedColorBg;
82:
1.1.1.6 ! root 83: #define MAX_MESSAGE_LEN 69
1.1 root 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: /**
1.1.1.4 root 147: * Enable device led, it will be automatically disabled after a while.
1.1 root 148: */
1.1.1.4 root 149: void Statusbar_BlinkLed(drive_index_t drive)
1.1 root 150: {
151: /* leds are shown for 1/2 sec after enabling */
1.1.1.4 root 152: Led[drive].expire = SDL_GetTicks() + 1000/2;
153: Led[drive].state = true;
1.1 root 154: }
155:
1.1.1.4 root 156:
1.1 root 157: /*-----------------------------------------------------------------------*/
158: /**
1.1.1.5 root 159: * Set system, DSP, CPU and NeXTdimension led state, anything enabling led with
1.1.1.4 root 160: * this needs also to take care of disabling it.
1.1 root 161: */
1.1.1.5 root 162: void Statusbar_SetSystemLed(bool state) {
1.1.1.4 root 163: bOldSystemLed = state;
1.1 root 164: }
165:
1.1.1.5 root 166: void Statusbar_SetDspLed(bool state) {
1.1.1.4 root 167: bOldDspLed = state;
1.1.1.3 root 168: }
169:
1.1.1.5 root 170: void Statusbar_SetNdLed(int state) {
1.1.1.4 root 171: nOldNdLed = state;
172: }
1.1 root 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;
1.1.1.4 root 210: const char *text[NUM_DEVICE_LEDS] = { "EN:", "MO:", "SD:", "FD:" };
1.1 root 211:
212: assert(surf);
213:
214: /* dark green and light green for leds themselves */
1.1.1.5 root 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:
1.1 root 228: /* disable leds */
1.1.1.4 root 229: for (i = 0; i < NUM_DEVICE_LEDS; i++) {
1.1 root 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 */
1.1.1.4 root 278: for (i = 0; i < NUM_DEVICE_LEDS; i++) {
1.1 root 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: }
1.1.1.4 root 292: MessageRect.x = offset + fontw;
1.1 root 293: MessageRect.w = MAX_MESSAGE_LEN * fontw;
294: MessageRect.h = fonth;
295: for (item = MessageList; item; item = item->next) {
296: item->shown = false;
297: }
1.1.1.5 root 298:
1.1.1.4 root 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;
1.1.1.3 root 321: SDLGui_Text(ledbox.x - 4*fontw - fontw/2, MessageRect.y, "LED:");
1.1 root 322: SDL_FillRect(surf, &ledbox, LedColorBg);
1.1.1.4 root 323: SDL_FillRect(surf, &SystemLedRect, SysColorOff);
324: bOldSystemLed = false;
1.1 root 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;
1.1.1.6 ! root 382: char memsize[16];
! 383: char slot[16];
1.1.1.4 root 384:
385: /* Message for NeXTdimension */
1.1.1.6 ! root 386: if (ConfigureParams.Screen.nMonitorType==MONITOR_TYPE_DIMENSION) {
1.1.1.4 root 387: end = Statusbar_AddString(end, "33MHz/i860XR/");
1.1.1.6 ! root 388: sprintf(memsize, "%iMB/",Configuration_CheckDimensionMemory(ConfigureParams.Dimension.board[ConfigureParams.Screen.nMonitorNum].nMemoryBankSize));
1.1.1.4 root 389: end = Statusbar_AddString(end, memsize);
1.1.1.6 ! root 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';
1.1.1.4 root 394: assert(end - DefaultMessage.msg < MAX_MESSAGE_LEN);
395: DefaultMessage.shown = false;
396: return;
397: }
398:
1.1 root 399: /* CPU MHz */
1.1.1.5 root 400: end = Statusbar_AddString(end, Main_SpeedMsg());
1.1 root 401:
402: /* CPU type */
403: if(ConfigureParams.System.nCpuLevel > 0) {
1.1.1.3 root 404: *end++ = '6';
405: *end++ = '8';
1.1 root 406: *end++ = '0';
1.1.1.3 root 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: }
1.1 root 416: *end++ = '0';
417: *end++ = '/';
418: }
419:
420: /* amount of memory */
1.1.1.3 root 421: sprintf(memsize, "%iMB/", Configuration_CheckMemory(ConfigureParams.Memory.nMemoryBankSize));
422: end = Statusbar_AddString(end, memsize);
1.1 root 423:
424: /* machine type */
1.1.1.3 root 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: }
1.1.1.6 ! root 439: if (ConfigureParams.System.bTurbo) {
! 440: end = Statusbar_AddString(end, (ConfigureParams.System.nCpuFreq==40)?" Nitro":" Turbo");
! 441: }
1.1.1.4 root 442:
1.1.1.6 ! root 443: if (ConfigureParams.System.bColor) {
! 444: end = Statusbar_AddString(end, " Color");
! 445: }
1.1 root 446:
447: *end = '\0';
448:
449: assert(end - DefaultMessage.msg < MAX_MESSAGE_LEN);
450: DEBUGPRINT(("Set default message: '%s'\n", DefaultMessage.msg));
1.1.1.2 root 451: /* make sure default message gets (re-)drawn when next checked */
1.1 root 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) {
1.1.1.2 root 483: /* last/default message never expires */
1.1 root 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);
1.1.1.4 root 586: for (i = 0; i < NUM_DEVICE_LEDS; i++) {
1.1 root 587: if (Led[i].state) {
588: if (Led[i].expire && Led[i].expire < currentticks) {
589: Led[i].state = false;
590: continue;
591: }
1.1.1.5 root 592: Statusbar_OverlayDrawLed(surf, ConfigureParams.SCSI.nWriteProtection == WRITEPROT_ON && i == DEVICE_LED_SCSI ? LedColorOnWP : LedColorOn);
1.1 root 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: */
1.1.1.5 root 619: void Statusbar_Update(SDL_Surface *surf) {
1.1 root 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();
1.1.1.4 root 637: for (i = 0; i < NUM_DEVICE_LEDS; i++) {
1.1 root 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) {
1.1.1.5 root 646: color = ConfigureParams.SCSI.nWriteProtection == WRITEPROT_ON && i == DEVICE_LED_SCSI ? LedColorOnWP : LedColorOn;
1.1 root 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:
1.1.1.4 root 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:
1.1.1.3 root 666: /* Draw scr2 LED */
1.1.1.4 root 667: if (bOldSystemLed) {
668: color = SysColorOn;
1.1.1.3 root 669: } else {
1.1.1.4 root 670: color = SysColorOff;
1.1.1.3 root 671: }
1.1.1.4 root 672: SDL_FillRect(surf, &SystemLedRect, color);
673: SDL_UpdateRects(surf, 1, &SystemLedRect);
674:
675: /* Draw NeXTdimension LED */
676: switch(nOldNdLed) {
1.1.1.5 root 677: case 0: color = NdColorOff; break;
678: case 1: color = NdColorCS8; break;
679: case 2: color = NdColorOn; break;
1.1.1.4 root 680: default: color = NdColorOff; break;
681: }
682: SDL_FillRect(surf, &NdLedRect, color);
683: SDL_UpdateRects(surf, 1, &NdLedRect);
1.1 root 684: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.