Annotation of previous_trunk/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: 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.