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