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

unix.superglobalmegacorp.com

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