Annotation of hatari/src/statusbar.c, revision 1.1.1.1

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

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.