Annotation of previous/src/statusbar.c, revision 1.1.1.5

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.4   root       37: #include "dimension.h"
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.5 ! root       83: #define MAX_MESSAGE_LEN 69 /* changed for Previous, was 50 */
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.4   root      382:        char memsize[8];
                    383:        
                    384:        /* Message for NeXTdimension */
                    385:        if (ConfigureParams.Dimension.bEnabled &&
                    386:                ConfigureParams.Screen.nMonitorType==MONITOR_TYPE_DIMENSION) {
                    387:                end = Statusbar_AddString(end, "33MHz/i860XR/");
                    388:                sprintf(memsize, "%iMB/",Configuration_CheckDimensionMemory(ConfigureParams.Dimension.nMemoryBankSize));
                    389:                end = Statusbar_AddString(end, memsize);
                    390:                end = Statusbar_AddString(end, "NeXTdimension");
                    391:                *end = '\0';
                    392:                assert(end - DefaultMessage.msg < MAX_MESSAGE_LEN);
                    393:                DefaultMessage.shown = false;
                    394:                return;
                    395:        }
                    396:        
1.1       root      397:        /* CPU MHz */
1.1.1.5 ! root      398:     end = Statusbar_AddString(end, Main_SpeedMsg());
1.1       root      399: 
                    400:        /* CPU type */
                    401:        if(ConfigureParams.System.nCpuLevel > 0) {
1.1.1.3   root      402:         *end++ = '6';
                    403:         *end++ = '8';
1.1       root      404:                *end++ = '0';
1.1.1.3   root      405:         switch (ConfigureParams.System.nCpuLevel) {
                    406:             case 0: *end++ = '0'; break;
                    407:             case 1: *end++ = '1'; break;
                    408:             case 2: *end++ = '2'; break;
                    409:             case 3: *end++ = '3'; break;
                    410:             case 4: *end++ = '4'; break;
                    411:             case 5: *end++ = '6'; break;
                    412:             default: break;
                    413:         }
1.1       root      414:                *end++ = '0';
                    415:                *end++ = '/';
                    416:        }
                    417: 
                    418:        /* amount of memory */
1.1.1.3   root      419:     sprintf(memsize, "%iMB/", Configuration_CheckMemory(ConfigureParams.Memory.nMemoryBankSize));
                    420:     end = Statusbar_AddString(end, memsize);
1.1       root      421: 
                    422:        /* machine type */
1.1.1.3   root      423:     switch (ConfigureParams.System.nMachineType) {
                    424:         case NEXT_CUBE030:
                    425:             end = Statusbar_AddString(end, "NeXT Computer");
                    426:             break;
                    427:         case NEXT_CUBE040:
                    428:             end = Statusbar_AddString(end, "NeXTcube");
                    429:             break;
                    430:         case NEXT_STATION:
                    431:             end = Statusbar_AddString(end, "NeXTstation");
                    432:             break;
                    433:             
                    434:         default:
                    435:             break;
                    436:     }
                    437:     if (ConfigureParams.System.bTurbo)
1.1.1.4   root      438:         end = Statusbar_AddString(end, (ConfigureParams.System.nCpuFreq==40)?" Nitro":" Turbo");
                    439: 
1.1.1.3   root      440:     if (ConfigureParams.System.bColor)
                    441:         end = Statusbar_AddString(end, " Color");
1.1       root      442: 
                    443:        *end = '\0';
                    444: 
                    445:        assert(end - DefaultMessage.msg < MAX_MESSAGE_LEN);
                    446:        DEBUGPRINT(("Set default message: '%s'\n", DefaultMessage.msg));
1.1.1.2   root      447:     /* make sure default message gets (re-)drawn when next checked */
1.1       root      448:        DefaultMessage.shown = false;
                    449: }
                    450: 
                    451: /*-----------------------------------------------------------------------*/
                    452: /**
                    453:  * Draw 'msg' centered to the message area
                    454:  */
                    455: static void Statusbar_DrawMessage(SDL_Surface *surf, const char *msg)
                    456: {
                    457:        int fontw, fonth, offset;
                    458:        SDL_FillRect(surf, &MessageRect, GrayBg);
                    459:        if (*msg) {
                    460:                SDLGui_GetFontSize(&fontw, &fonth);
                    461:                offset = (MessageRect.w - strlen(msg) * fontw) / 2;
                    462:                SDLGui_Text(MessageRect.x + offset, MessageRect.y, msg);
                    463:        }
                    464:        SDL_UpdateRects(surf, 1, &MessageRect);
                    465:        DEBUGPRINT(("Draw message: '%s'\n", msg));
                    466: }
                    467: 
                    468: /*-----------------------------------------------------------------------*/
                    469: /**
                    470:  * If message's not shown, show it.  If message's timed out,
                    471:  * remove it and show next one.
                    472:  */
                    473: static void Statusbar_ShowMessage(SDL_Surface *surf, Uint32 ticks)
                    474: {
                    475:        msg_item_t *next;
                    476: 
                    477:        if (MessageList->shown) {
                    478:                if (!MessageList->expire) {
1.1.1.2   root      479:                        /* last/default message never expires */
1.1       root      480:                        return;
                    481:                }
                    482:                if (MessageList->expire > ticks) {
                    483:                        /* not timed out yet */
                    484:                        return;
                    485:                }
                    486:                assert(MessageList->next); /* last message shouldn't end here */
                    487:                next = MessageList->next;
                    488:                free(MessageList);
                    489:                MessageList = next;
                    490:                /* make sure next message gets shown */
                    491:                MessageList->shown = false;
                    492:        }
                    493:        if (!MessageList->shown) {
                    494:                /* not shown yet, show */
                    495:                Statusbar_DrawMessage(surf,  MessageList->msg);
                    496:                if (MessageList->timeout && !MessageList->expire) {
                    497:                        MessageList->expire = ticks + MessageList->timeout;
                    498:                }
                    499:                MessageList->shown = true;
                    500:        }
                    501: }
                    502: 
                    503: 
                    504: /*-----------------------------------------------------------------------*/
                    505: /**
                    506:  * Save the area that will be left under overlay led
                    507:  */
                    508: void Statusbar_OverlayBackup(SDL_Surface *surf)
                    509: {
                    510:        if ((StatusbarHeight && ConfigureParams.Screen.bShowStatusbar)
                    511:            || !ConfigureParams.Screen.bShowDriveLed) {
                    512:                /* overlay not used with statusbar */
                    513:                return;
                    514:        }
                    515:        assert(surf);
                    516:        if (!OverlayUnderside) {
                    517:                SDL_Surface *bak;
                    518:                SDL_PixelFormat *fmt = surf->format;
                    519:                bak = SDL_CreateRGBSurface(surf->flags,
                    520:                                           OverlayLedRect.w, OverlayLedRect.h,
                    521:                                           fmt->BitsPerPixel,
                    522:                                           fmt->Rmask, fmt->Gmask, fmt->Bmask,
                    523:                                           fmt->Amask);
                    524:                assert(bak);
                    525:                OverlayUnderside = bak;
                    526:        }
                    527:        SDL_BlitSurface(surf, &OverlayLedRect, OverlayUnderside, NULL);
                    528: }
                    529: 
                    530: /*-----------------------------------------------------------------------*/
                    531: /**
                    532:  * Restore the area left under overlay led
                    533:  */
                    534: void Statusbar_OverlayRestore(SDL_Surface *surf)
                    535: {
                    536:        if ((StatusbarHeight && ConfigureParams.Screen.bShowStatusbar)
                    537:            || !ConfigureParams.Screen.bShowDriveLed) {
                    538:                /* overlay not used with statusbar */
                    539:                return;
                    540:        }
                    541:        if (bOverlayState == OVERLAY_DRAWN && OverlayUnderside) {
                    542:                assert(surf);
                    543:                SDL_BlitSurface(OverlayUnderside, NULL, surf, &OverlayLedRect);
                    544:                /* this will make the draw function to update this the screen */
                    545:                bOverlayState = OVERLAY_RESTORED;
                    546:        }
                    547: }
                    548: 
                    549: /*-----------------------------------------------------------------------*/
                    550: /**
                    551:  * Draw overlay led
                    552:  */
                    553: static void Statusbar_OverlayDrawLed(SDL_Surface *surf, Uint32 color)
                    554: {
                    555:        SDL_Rect rect;
                    556:        if (bOverlayState == OVERLAY_DRAWN) {
                    557:                /* some led already drawn */
                    558:                return;
                    559:        }
                    560:        bOverlayState = OVERLAY_DRAWN;
                    561: 
                    562:        /* enabled led with border */
                    563:        rect = OverlayLedRect;
                    564:        rect.x += 1;
                    565:        rect.y += 1;
                    566:        rect.w -= 2;
                    567:        rect.h -= 2;
                    568:        SDL_FillRect(surf, &OverlayLedRect, LedColorBg);
                    569:        SDL_FillRect(surf, &rect, color);
                    570: }
                    571: 
                    572: /*-----------------------------------------------------------------------*/
                    573: /**
                    574:  * Draw overlay led onto screen surface if any drives are enabled.
                    575:  */
                    576: static void Statusbar_OverlayDraw(SDL_Surface *surf)
                    577: {
                    578:        Uint32 currentticks = SDL_GetTicks();
                    579:        int i;
                    580: 
                    581:        assert(surf);
1.1.1.4   root      582:        for (i = 0; i < NUM_DEVICE_LEDS; i++) {
1.1       root      583:                if (Led[i].state) {
                    584:                        if (Led[i].expire && Led[i].expire < currentticks) {
                    585:                                Led[i].state = false;
                    586:                                continue;
                    587:                        }
1.1.1.5 ! root      588:             Statusbar_OverlayDrawLed(surf, ConfigureParams.SCSI.nWriteProtection == WRITEPROT_ON && i == DEVICE_LED_SCSI ? LedColorOnWP : LedColorOn);
1.1       root      589:                        break;
                    590:                }
                    591:        }
                    592:        /* possible state transitions:
                    593:         *   NONE -> DRAWN -> RESTORED -> DRAWN -> RESTORED -> NONE
                    594:         * Other than NONE state needs to be updated on screen
                    595:         */
                    596:        switch (bOverlayState) {
                    597:        case OVERLAY_RESTORED:
                    598:                bOverlayState = OVERLAY_NONE;
                    599:        case OVERLAY_DRAWN:
                    600:                SDL_UpdateRects(surf, 1, &OverlayLedRect);
                    601:                DEBUGPRINT(("Overlay LED = %s\n", bOverlayState==OVERLAY_DRAWN?"ON":"OFF"));
                    602:                break;
                    603:        case OVERLAY_NONE:
                    604:                break;
                    605:        }
                    606: }
                    607: 
                    608: 
                    609: /*-----------------------------------------------------------------------*/
                    610: /**
                    611:  * Update statusbar information (leds etc) if/when needed.
                    612:  * 
                    613:  * May not be called when screen is locked (SDL limitation).
                    614:  */
1.1.1.5 ! root      615: void Statusbar_Update(SDL_Surface *surf) {
1.1       root      616:        Uint32 color, currentticks;
                    617:        SDL_Rect rect;
                    618:        int i;
                    619: 
                    620:        if (!(StatusbarHeight && ConfigureParams.Screen.bShowStatusbar)) {
                    621:                /* not enabled (anymore), show overlay led instead? */
                    622:                if (ConfigureParams.Screen.bShowDriveLed) {
                    623:                        Statusbar_OverlayDraw(surf);
                    624:                }
                    625:                return;
                    626:        }
                    627:        assert(surf);
                    628:        /* Statusbar_Init() not called before this? */
                    629:        assert(surf->h == ScreenHeight + StatusbarHeight);
                    630: 
                    631:        rect = LedRect;
                    632:        currentticks = SDL_GetTicks();
1.1.1.4   root      633:        for (i = 0; i < NUM_DEVICE_LEDS; i++) {
1.1       root      634:                if (Led[i].expire && Led[i].expire < currentticks) {
                    635:                        Led[i].state = false;
                    636:                }
                    637:                if (Led[i].state == Led[i].oldstate) {
                    638:                        continue;
                    639:                }
                    640:                Led[i].oldstate = Led[i].state;
                    641:                if (Led[i].state) {
1.1.1.5 ! root      642:             color = ConfigureParams.SCSI.nWriteProtection == WRITEPROT_ON  && i == DEVICE_LED_SCSI ? LedColorOnWP : LedColorOn;
1.1       root      643:                } else {
                    644:                        color = LedColorOff;
                    645:                }
                    646:                rect.x = Led[i].offset;
                    647:                SDL_FillRect(surf, &rect, color);
                    648:                SDL_UpdateRects(surf, 1, &rect);
                    649:        }
                    650: 
                    651:        Statusbar_ShowMessage(surf, currentticks);
                    652: 
1.1.1.4   root      653:        /* Draw dsp LED */
                    654:        if (bOldDspLed) {
                    655:                color = DspColorOn;
                    656:        } else {
                    657:                color = DspColorOff;
                    658:        }
                    659:        SDL_FillRect(surf, &DspLedRect, color);
                    660:        SDL_UpdateRects(surf, 1, &DspLedRect);
                    661: 
1.1.1.3   root      662:     /* Draw scr2 LED */
1.1.1.4   root      663:     if (bOldSystemLed) {
                    664:         color = SysColorOn;
1.1.1.3   root      665:     } else {
1.1.1.4   root      666:         color = SysColorOff;
1.1.1.3   root      667:     }
1.1.1.4   root      668:     SDL_FillRect(surf, &SystemLedRect, color);
                    669:     SDL_UpdateRects(surf, 1, &SystemLedRect);
                    670:     
                    671:     /* Draw NeXTdimension LED */
                    672:     switch(nOldNdLed) {
1.1.1.5 ! root      673:         case 0:  color = NdColorOff; break;
        !           674:         case 1:  color = NdColorCS8;  break;
        !           675:         case 2:  color = NdColorOn;  break;
1.1.1.4   root      676:                default: color = NdColorOff; break;
                    677:     }
                    678:     SDL_FillRect(surf, &NdLedRect, color);
                    679:     SDL_UpdateRects(surf, 1, &NdLedRect);
1.1       root      680: }

unix.superglobalmegacorp.com

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