Index: branches/rewrite/i386/boot2/graphics.c =================================================================== --- branches/rewrite/i386/boot2/graphics.c (revision 1066) +++ branches/rewrite/i386/boot2/graphics.c (revision 1067) @@ -1,1224 +0,0 @@ -/* - * Copyright (c) 1999-2003 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * Portions Copyright (c) 1999-2003 Apple Computer, Inc. All Rights - * Reserved. This file contains Original Code and/or Modifications of - * Original Code as defined in and that are subject to the Apple Public - * Source License Version 2.0 (the "License"). You may not use this file - * except in compliance with the License. Please obtain a copy of the - * License at http://www.apple.com/publicsource and read it before using - * this file. - * - * The Original Code and all software distributed under the License are - * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT. Please see the - * License for the specific language governing rights and limitations - * under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ -/* - * Copyright 1993 NeXT, Inc. - * All rights reserved. - */ - -#include "boot.h" -#include "vbe.h" -#include "appleClut8.h" -#include "gui.h" -#include "IOHibernatePrivate.h" - -/* - * for spinning disk - */ -static int currentIndicator = 0; - -int previewTotalSectors = 0; -int previewLoadedSectors = 0; -uint8_t *previewSaveunder = 0; - -#define VIDEO(x) (bootArgs->Video.v_ ## x) - -//========================================================================== -// getVBEInfoString - -char *getVBEInfoString() -{ - VBEInfoBlock vbeInfo; - int err, small; - char *buff = malloc(sizeof(char)*256); - if(!buff) return 0; - - bzero( &vbeInfo, sizeof(vbeInfo) ); - strcpy( (char*)&vbeInfo, "VBE2" ); - err = getVBEInfo( &vbeInfo ); - if (err != errSuccess) - return 0; - - if ( strncmp( (char *)vbeInfo.VESASignature, "VESA", 4 ) ) - return 0; - - small = (vbeInfo.TotalMemory < 16); - - sprintf(buff, "VESA v%d.%d %d%s (%s)\n", - vbeInfo.VESAVersion >> 8, - vbeInfo.VESAVersion & 0xf, - small ? (vbeInfo.TotalMemory * 64) : (vbeInfo.TotalMemory / 16), - small ? "KB" : "MB", - VBEDecodeFP(const char *, vbeInfo.OEMStringPtr) ); - - return buff; -} - -//========================================================================== -// - -void -printVBEModeInfo() -{ - VBEInfoBlock vbeInfo; - unsigned short * modePtr; - VBEModeInfoBlock modeInfo; - int err; - int line; - - bzero( &vbeInfo, sizeof(vbeInfo) ); - strcpy( (char*)&vbeInfo, "VBE2" ); - err = getVBEInfo( &vbeInfo ); - if ( err != errSuccess ) - return; - - line = 0; - - // Activate and clear page 1 - setActiveDisplayPage(1); - clearScreenRows(0, 24); - setCursorPosition( 0, 0, 1 ); - - printf( getVBEInfoString() ); - printf("Video modes supported:\n", VBEDecodeFP(const char *, vbeInfo.OEMStringPtr)); - - // Loop through the mode list, and find the matching mode. - - for ( modePtr = VBEDecodeFP( unsigned short *, vbeInfo.VideoModePtr ); - *modePtr != modeEndOfList; modePtr++ ) - { - // Get mode information. - - bzero( &modeInfo, sizeof(modeInfo) ); - err = getVBEModeInfo( *modePtr, &modeInfo ); - if ( err != errSuccess ) - { - continue; - } - - printf("Mode %x: %dx%dx%d mm:%d attr:%x\n", - *modePtr, modeInfo.XResolution, modeInfo.YResolution, - modeInfo.BitsPerPixel, modeInfo.MemoryModel, - modeInfo.ModeAttributes); - - if (line++ >= 20) { - pause(); - line = 0; - clearScreenRows(0, 24); - setCursorPosition( 0, 0, 1 ); - } - } - if (line != 0) { - pause(); - } - setActiveDisplayPage(0); -} - -char *getVBEModeInfoString() -{ - VBEInfoBlock vbeInfo; - unsigned short * modePtr; - VBEModeInfoBlock modeInfo; - int err; - - bzero( &vbeInfo, sizeof(vbeInfo) ); - strcpy( (char*)&vbeInfo, "VBE2" ); - err = getVBEInfo( &vbeInfo ); - if ( err != errSuccess ) - return 0; - - char *buff=malloc(sizeof(char)*3072); - if(!buff) return 0; - - // Loop through the mode list, and find the matching mode. - for ( modePtr = VBEDecodeFP( unsigned short *, vbeInfo.VideoModePtr ); - *modePtr != modeEndOfList; modePtr++ ) - { - // Get mode information. - - bzero( &modeInfo, sizeof(modeInfo) ); - err = getVBEModeInfo( *modePtr, &modeInfo ); - if ( err != errSuccess ) - { - continue; - } - - sprintf(buff+strlen(buff), "Mode %x: %dx%dx%d mm:%d attr:%x\n", - *modePtr, modeInfo.XResolution, modeInfo.YResolution, - modeInfo.BitsPerPixel, modeInfo.MemoryModel, - modeInfo.ModeAttributes); - - } - return buff; -} - -//========================================================================== -// getVESAModeWithProperties -// -// Return the VESA mode that matches the properties specified. -// If a mode is not found, then return the "best" available mode. - -static unsigned short -getVESAModeWithProperties( unsigned short width, - unsigned short height, - unsigned char bitsPerPixel, - unsigned short attributesSet, - unsigned short attributesClear, - VBEModeInfoBlock * outModeInfo, - unsigned short * vesaVersion ) -{ - VBEInfoBlock vbeInfo; - unsigned short * modePtr; - VBEModeInfoBlock modeInfo; - unsigned char modeBitsPerPixel; - unsigned short matchedMode = modeEndOfList; - int err; - - // Clear output mode info. - - bzero( outModeInfo, sizeof(*outModeInfo) ); - - // Get VBE controller info containing the list of supported modes. - - bzero( &vbeInfo, sizeof(vbeInfo) ); - strcpy( (char*)&vbeInfo, "VBE2" ); - err = getVBEInfo( &vbeInfo ); - if ( err != errSuccess ) - { - return modeEndOfList; - } - - // Report the VESA major/minor version number. - - if (vesaVersion) *vesaVersion = vbeInfo.VESAVersion; - - // Loop through the mode list, and find the matching mode. - - for ( modePtr = VBEDecodeFP( unsigned short *, vbeInfo.VideoModePtr ); - *modePtr != modeEndOfList; modePtr++ ) - { - // Get mode information. - - bzero( &modeInfo, sizeof(modeInfo) ); - err = getVBEModeInfo( *modePtr, &modeInfo ); - if ( err != errSuccess ) - { - continue; - } - -#if DEBUG - printf("Mode %x: %dx%dx%d mm:%d attr:%x\n", - *modePtr, modeInfo.XResolution, modeInfo.YResolution, - modeInfo.BitsPerPixel, modeInfo.MemoryModel, - modeInfo.ModeAttributes); -#endif - - // Filter out unwanted modes based on mode attributes. - - if ( ( ( modeInfo.ModeAttributes & attributesSet ) != attributesSet ) - || ( ( modeInfo.ModeAttributes & attributesClear ) != 0 ) ) - { - continue; - } - - // Pixel depth in bits. - - modeBitsPerPixel = modeInfo.BitsPerPixel; - - if ( ( modeBitsPerPixel == 4 ) && ( modeInfo.MemoryModel == 0 ) ) - { - // Text mode, 16 colors. - } - else if ( ( modeBitsPerPixel == 8 ) && ( modeInfo.MemoryModel == 4 ) ) - { - // Packed pixel, 256 colors. - } - else if ( ( ( modeBitsPerPixel == 16 ) || ( modeBitsPerPixel == 15 ) ) - && ( modeInfo.MemoryModel == 6 ) - && ( modeInfo.RedMaskSize == 5 ) - && ( modeInfo.GreenMaskSize == 5 ) - && ( modeInfo.BlueMaskSize == 5 ) ) - { - // Direct color, 16 bpp (1:5:5:5). - modeInfo.BitsPerPixel = modeBitsPerPixel = 16; - } - else if ( ( modeBitsPerPixel == 32 ) - && ( modeInfo.MemoryModel == 6 ) - && ( modeInfo.RedMaskSize == 8 ) - && ( modeInfo.GreenMaskSize == 8 ) - && ( modeInfo.BlueMaskSize == 8 ) ) - { - // Direct color, 32 bpp (8:8:8:8). - } - else - { - continue; // Not a supported mode. - } - - // Modes larger than the specified dimensions are skipped. - - if ( ( modeInfo.XResolution > width ) || - ( modeInfo.YResolution > height ) ) - { - continue; - } - - // Perfect match, we're done looking. - - if ( ( modeInfo.XResolution == width ) && - ( modeInfo.YResolution == height ) && - ( modeBitsPerPixel == bitsPerPixel ) ) - { - matchedMode = *modePtr; - bcopy( &modeInfo, outModeInfo, sizeof(modeInfo) ); - break; - } - - // Save the next "best" mode in case a perfect match is not found. - - if ( modeInfo.XResolution == outModeInfo->XResolution && - modeInfo.YResolution == outModeInfo->YResolution && - modeBitsPerPixel <= outModeInfo->BitsPerPixel ) - { - continue; // Saved mode has more depth. - } - if ( modeInfo.XResolution < outModeInfo->XResolution || - modeInfo.YResolution < outModeInfo->YResolution || - modeBitsPerPixel < outModeInfo->BitsPerPixel ) - { - continue; // Saved mode has more resolution. - } - - matchedMode = *modePtr; - bcopy( &modeInfo, outModeInfo, sizeof(modeInfo) ); - } - - return matchedMode; -} - -//========================================================================== -// setupPalette - -static void setupPalette( VBEPalette * p, const unsigned char * g ) -{ - int i; - unsigned char * source = (unsigned char *) g; - - for (i = 0; i < 256; i++) - { - (*p)[i] = 0; - (*p)[i] |= ((unsigned long)((*source++) >> 2)) << 16; // Red - (*p)[i] |= ((unsigned long)((*source++) >> 2)) << 8; // Green - (*p)[i] |= ((unsigned long)((*source++) >> 2)); // Blue - } -} - -//========================================================================== -// Simple decompressor for boot images encoded in RLE format. - -char * decodeRLE( const void * rleData, int rleBlocks, int outBytes ) -{ - char *out, *cp; - - struct RLEBlock { - unsigned char count; - unsigned char value; - } * bp = (struct RLEBlock *) rleData; - - out = cp = malloc( outBytes ); - if ( out == NULL ) return NULL; - - while ( rleBlocks-- ) - { - memset( cp, bp->value, bp->count ); - cp += bp->count; - bp++; - } - - return out; -} - -//========================================================================== -// setVESAGraphicsMode - -static int -setVESAGraphicsMode( unsigned short width, - unsigned short height, - unsigned char bitsPerPixel, - unsigned short refreshRate ) -{ - VBEModeInfoBlock minfo; - unsigned short mode; - unsigned short vesaVersion; - int err = errFuncNotSupported; - - do { - mode = getVESAModeWithProperties( width, height, bitsPerPixel, - maColorModeBit | - maModeIsSupportedBit | - maGraphicsModeBit | - maLinearFrameBufferAvailBit, - 0, - &minfo, &vesaVersion ); - if ( mode == modeEndOfList ) - { - break; - } - -// -// FIXME : generateCRTCTiming() causes crash. -// - -// if ( (vesaVersion >> 8) >= 3 && refreshRate >= 60 && -// (gBootMode & kBootModeSafe) == 0 ) -// { -// VBECRTCInfoBlock timing; -// -// // Generate CRTC timing for given refresh rate. -// -// generateCRTCTiming( minfo.XResolution, minfo.YResolution, -// refreshRate, kCRTCParamRefreshRate, -// &timing ); -// -// // Find the actual pixel clock supported by the hardware. -// -// getVBEPixelClock( mode, &timing.PixelClock ); -// -// // Re-compute CRTC timing based on actual pixel clock. -// -// generateCRTCTiming( minfo.XResolution, minfo.YResolution, -// timing.PixelClock, kCRTCParamPixelClock, -// &timing ); -// -// // Set the video mode and use specified CRTC timing. -// -// err = setVBEMode( mode | kLinearFrameBufferBit | -// kCustomRefreshRateBit, &timing ); -// } -// else -// { -// // Set the mode with default refresh rate. -// -// err = setVBEMode( mode | kLinearFrameBufferBit, NULL ); -// } - - // Set the mode with default refresh rate. - - err = setVBEMode( mode | kLinearFrameBufferBit, NULL ); - - if ( err != errSuccess ) - { - break; - } - - // Set 8-bit color palette. - - if ( minfo.BitsPerPixel == 8 ) - { - VBEPalette palette; - setupPalette( &palette, appleClut8 ); - if ((err = setVBEPalette(palette)) != errSuccess) - { - break; - } - } - - // Is this required for buggy Video BIOS implementations? - // On which adapter? - - if ( minfo.BytesPerScanline == 0 ) - minfo.BytesPerScanline = ( minfo.XResolution * - minfo.BitsPerPixel ) >> 3; - - // Update KernBootStruct using info provided by the selected - // VESA mode. - - bootArgs->Video.v_display = GRAPHICS_MODE; - bootArgs->Video.v_width = minfo.XResolution; - bootArgs->Video.v_height = minfo.YResolution; - bootArgs->Video.v_depth = minfo.BitsPerPixel; - bootArgs->Video.v_rowBytes = minfo.BytesPerScanline; - bootArgs->Video.v_baseAddr = VBEMakeUInt32(minfo.PhysBasePtr); - - } - while ( 0 ); - - return err; -} - -int -convertImage( unsigned short width, - unsigned short height, - const unsigned char *imageData, - unsigned char **newImageData ) -{ - int cnt; - unsigned char *img = 0; - unsigned short *img16; - unsigned long *img32; - - switch ( VIDEO(depth) ) { - case 16 : - img16 = malloc(width * height * 2); - if ( !img16 ) break; - for (cnt = 0; cnt < (width * height); cnt++) - img16[cnt] = lookUpCLUTIndex(imageData[cnt], 16); - img = (unsigned char *)img16; - break; - - case 32 : - img32 = malloc(width * height * 4); - if ( !img32 ) break; - for (cnt = 0; cnt < (width * height); cnt++) - img32[cnt] = lookUpCLUTIndex(imageData[cnt], 32); - img = (unsigned char *)img32; - break; - - default : - img = malloc(width * height); - bcopy(imageData, img, width * height); - break; - } - *newImageData = img; - return 0; -} - -int loadPngImage(const char *filename, uint16_t *width, uint16_t *height, - uint8_t **imageData) -{ - uint8_t *pngData = NULL; - int pngFile = 0, pngSize; - PNG_info_t *info; - int error = 0; - - pngFile = open_bvdev("bt(0,0)", filename, 0); - if (pngFile == -1) { - error = -1; - goto failed; - } - pngSize = file_size(pngFile); - if (!pngSize) { - error = -1; - goto failed; - } - pngData = malloc(pngSize); - if (read(pngFile, (char *) pngData, pngSize) != pngSize) { - error = -1; - goto failed; - } - - PNG_error = -1; - info = PNG_decode(pngData, pngSize); - if (PNG_error != 0) { - error = PNG_error; - goto failed; - } else if ((info->width > 0xffff) || (info->height > 0xffff)) { - error = -1; - goto failed; - } else if ((info->width * info->height * 4) != info->image->size) { - error = -1; - goto failed; - } - uint8_t *result = malloc(info->width*4*info->height); - *width = info->width; - *height = info->height; - memcpy(result, info->image->data, info->width*4*info->height); - *imageData = result; - -failed: - png_alloc_free_all(); - if (pngData) - free(pngData); - if (pngFile != -1) - close(pngFile); - - return error; -} - -int loadEmbeddedPngImage(uint8_t *pngData, int pngSize, uint16_t *width, uint16_t *height, uint8_t **imageData) { - PNG_info_t *info; - int error = 0; - - PNG_error = -1; - info = PNG_decode(pngData, pngSize); - if (PNG_error != 0) { - error = PNG_error; - goto failed; - } else if ((info->width > 0xffff) || (info->height > 0xffff)) { - error = -1; - goto failed; - } else if ((info->width * info->height * 4) != info->image->size) { - error = -1; - goto failed; - } - uint8_t *result = malloc(info->width*4*info->height); - *width = info->width; - *height = info->height; - memcpy(result, info->image->data, info->width*4*info->height); - *imageData = result; - -failed: - png_alloc_free_all(); - - return error; -} - -void blendImage(uint16_t x, uint16_t y, uint16_t width, uint16_t height, - uint8_t *data) -{ - uint16_t drawWidth; - uint8_t *vram = (uint8_t *) VIDEO(baseAddr) + VIDEO(rowBytes) * y + 4 * x; - - drawWidth = MIN(width, VIDEO(width) - x); - height = MIN(height, VIDEO(height) - y); - while (height--) { - switch (VIDEO (depth)) - { - case 32: /* Optimized version*/ - { - uint32_t s; uint32_t* d; // Source (img) and destination (bkgd) pixels - uint32_t a; // Alpha - uint32_t dstrb, dstg, srcrb, srcg, drb, dg, rb, g, tempB; // Intermediate variables - uint16_t pos; - - for (pos = 0; pos < drawWidth * 4; pos += 4) { - // Fast pseudo-vector alpha blending, adapted from: http://www.stereopsis.com/doubleblend.html - s = *((uint32_t*) (data + pos)); - d = (uint32_t*) (vram + pos); - - // Flip B and R in source - // TODO: use XCHG and inline assembly to do this in a faster, saner way - tempB = (s & 0xFF0000); // save B - s = (s & 0xFF00FFFF) | ((s & 0xFF) << 16); // put R in B - s = (s & 0xFFFFFF00) | (tempB >> 16); // put B in R - - a = (s >> 24) + 1; - - dstrb = *d & 0xFF00FF; dstg = *d & 0xFF00; - srcrb = s & 0xFF00FF; srcg = s & 0xFF00; - - drb = srcrb - dstrb; - dg = srcg - dstg; - drb *= a; dg *= a; - drb >>= 8; dg >>= 8; - - rb = (drb + dstrb) & 0xFF00FF; - g = (dg + dstg) & 0xFF00; - - *d = rb | g; - } - } - break; - - default: /*Universal version*/ - { - uint32_t s; - uint32_t a; // Alpha - uint32_t dr, dg, db, sr, sg, sb; // Intermediate variables - uint16_t pos; - int bpp = (VIDEO (depth) + 7)/8; - - for (pos = 0; pos < drawWidth; pos ++) { - // Fast pseudo-vector alpha blending, adapted from: http://www.stereopsis.com/doubleblend.html - s = *((uint32_t*) (data + 4*pos)); - - sb = (s & 0xFF0000) >> 16; - sg = (s & 0xFF00) >> 8; - sr = (s & 0xFF); - - a = (s >> 24) + 1; - - switch (VIDEO (depth)) - { - case 24: - db = ((*(uint32_t *)(vram + bpp*pos))&0xff); - dg = ((*(uint32_t *)(vram + bpp*pos))&0xff00)>>8; - dr = ((*(uint32_t *)(vram + bpp*pos))&0xff0000)>>16; - break; - case 16://16-bit seems to be 15-bit -/* db = ((*(uint16_t *)(vram + bpp*pos))&0x1f)<<3; - dg = ((*(uint16_t *)(vram + bpp*pos))&0x07e0)>>3; - dr = ((*(uint16_t *)(vram + bpp*pos))&0xf800)>>8; - break; */ - case 15: - db = ((*(uint16_t *)(vram + bpp*pos))&0x1f)<<3; - dg = ((*(uint16_t *)(vram + bpp*pos))&0x03e0)>>2; - dr = ((*(uint16_t *)(vram + bpp*pos))&0x7c00)>>7; - break; - default: - return; - } - - dr = (((sr - dr) * a) >> 8) + dr; - dg = (((sg - dg) * a) >> 8) + dg; - db = (((sb - db) * a) >> 8) + db; - switch (VIDEO (depth)) - { - case 24: - *(uint32_t *)(vram + bpp*pos) = (*(uint32_t *)(vram + bpp*pos) &0xff000000) - | (db&0xff) | ((dg&0xff)<<8) | ((dr&0xff)<<16); - break; - case 16: -// *(uint16_t *)(vram + bpp*pos) = ((db&0xf8)>>3) | ((dg&0xfc)<<3) | ((dr&0xf8)<<8); -// break; - case 15: - *(uint16_t *)(vram + bpp*pos) = ((db&0xf8)>>3) | ((dg&0xf8)<<2) | ((dr&0xf8)<<7); - break; - } - - } - } - break; - } - vram += VIDEO(rowBytes); - data += width * 4; - } -} - -void drawCheckerBoard() -{ - uint32_t *vram = (uint32_t *) VIDEO(baseAddr); - uint16_t x, y; - uint8_t color; - - for (y = 0; y < VIDEO(height); y++, vram += VIDEO(width)) { - for (x = 0; x < VIDEO(width); x++) { - color = 204 + 51 * (((x / 8) % 2) == ((y / 8) % 2)); - vram[x] = (color << 16) | (color << 8) | color; - } - } -} - -//========================================================================== -// LookUpCLUTIndex - -unsigned long lookUpCLUTIndex( unsigned char index, - unsigned char depth ) -{ - long result, red, green, blue; - - red = appleClut8[index * 3 + 0]; - green = appleClut8[index * 3 + 1]; - blue = appleClut8[index * 3 + 2]; - - switch (depth) { - case 16 : - result = ((red & 0xF8) << 7) | - ((green & 0xF8) << 2) | - ((blue & 0xF8) >> 3); - result |= (result << 16); - break; - - case 32 : - result = (red << 16) | (green << 8) | blue; - break; - - default : - result = index | (index << 8); - result |= (result << 16); - break; - } - - return result; -} - -//========================================================================== -// drawColorRectangle - -void * stosl(void * dst, long val, long len) -{ - asm volatile ( "rep; stosl" - : "=c" (len), "=D" (dst) - : "0" (len), "1" (dst), "a" (val) - : "memory" ); - - return dst; -} - -void drawColorRectangle( unsigned short x, - unsigned short y, - unsigned short width, - unsigned short height, - unsigned char colorIndex ) -{ - long pixelBytes; - long color = lookUpCLUTIndex( colorIndex, VIDEO(depth) ); - char * vram; - - pixelBytes = VIDEO(depth) / 8; - vram = (char *) VIDEO(baseAddr) + - VIDEO(rowBytes) * y + pixelBytes * x; - - width = MIN(width, VIDEO(width) - x); - height = MIN(height, VIDEO(height) - y); - - while ( height-- ) - { - int rem = ( pixelBytes * width ) % 4; - if ( rem ) bcopy( &color, vram, rem ); - stosl( vram + rem, color, pixelBytes * width / 4 ); - vram += VIDEO(rowBytes); - } -} - -//========================================================================== -// drawDataRectangle - -void drawDataRectangle( unsigned short x, - unsigned short y, - unsigned short width, - unsigned short height, - unsigned char * data ) -{ - unsigned short drawWidth; - long pixelBytes = VIDEO(depth) / 8; - unsigned char * vram = (unsigned char *) VIDEO(baseAddr) + - VIDEO(rowBytes) * y + pixelBytes * x; - - drawWidth = MIN(width, VIDEO(width) - x); - height = MIN(height, VIDEO(height) - y); - while ( height-- ) { - bcopy( data, vram, drawWidth * pixelBytes ); - vram += VIDEO(rowBytes); - data += width * pixelBytes; - } -} - -void -loadImageScale (void *input, int iw, int ih, int ip, void *output, int ow, int oh, int op, int or) -{ - int x,y, off; - int red=0x7f, green=0x7f, blue=0x7f; - for (x=0;x>7)&0xf8; - green=(val>>2)&0xf8; - blue=(val<<3)&0xf8; - break; - } - case 32: - { - uint32_t val; - val=((uint32_t *)input)[off]; - red=(val>>16)&0xff; - green=(val>>8)&0xff; - blue=(val)&0xff; - break; - } - } - char *ptr=(char *)output+x*(op/8)+y*or; - switch (op) - { - case 16: - *((uint16_t *)ptr) = ((red & 0xF8) << 7) | - ((green & 0xF8) << 2) | - ((blue & 0xF8) >> 3); - break; - case 32 : - *((uint32_t *)ptr) = (red << 16) | (green << 8) | blue; - break; - } - } -} - -DECLARE_IOHIBERNATEPROGRESSALPHA - -void drawPreview(void *src, uint8_t * saveunder) -{ - uint8_t * screen; - uint32_t rowBytes, pixelShift; - uint32_t x, y; - int32_t blob; - uint32_t alpha, in, color, result; - uint8_t * out; - void *uncomp; - int origwidth, origheight, origbpx; - uint32_t saveindex[kIOHibernateProgressCount] = { 0 }; - - if (src && (uncomp=DecompressData(src, &origwidth, &origheight, &origbpx))) - { - if (!setVESAGraphicsMode(origwidth, origheight, origbpx, 0)) - if (initGraphicsMode () != errSuccess) - return; - screen = (uint8_t *) VIDEO (baseAddr); - rowBytes = VIDEO (rowBytes); - loadImageScale (uncomp, origwidth, origheight, origbpx, screen, VIDEO(width), VIDEO(height), VIDEO(depth), VIDEO (rowBytes)); - } - else - { - if (initGraphicsMode () != errSuccess) - return; - screen = (uint8_t *) VIDEO (baseAddr); - rowBytes = VIDEO (rowBytes); - // Set the screen to 75% grey. - drawColorRectangle(0, 0, VIDEO(width), VIDEO(height), 0x01 /* color index */); - } - - - pixelShift = VIDEO (depth) >> 4; - if (pixelShift < 1) return; - - screen += ((VIDEO (width) - - kIOHibernateProgressCount * (kIOHibernateProgressWidth + kIOHibernateProgressSpacing)) << (pixelShift - 1)) - + (VIDEO (height) - kIOHibernateProgressOriginY - kIOHibernateProgressHeight) * rowBytes; - - for (y = 0; y < kIOHibernateProgressHeight; y++) - { - out = screen + y * rowBytes; - for (blob = 0; blob < kIOHibernateProgressCount; blob++) - { - color = blob ? kIOHibernateProgressDarkGray : kIOHibernateProgressMidGray; - for (x = 0; x < kIOHibernateProgressWidth; x++) - { - alpha = gIOHibernateProgressAlpha[y][x]; - result = color; - if (alpha) - { - if (0xff != alpha) - { - if (1 == pixelShift) - { - in = *((uint16_t *)out) & 0x1f; // 16 - in = (in << 3) | (in >> 2); - } - else - in = *((uint32_t *)out) & 0xff; // 32 - saveunder[blob * kIOHibernateProgressSaveUnderSize + saveindex[blob]++] = in; - result = ((255 - alpha) * in + alpha * result + 0xff) >> 8; - } - if (1 == pixelShift) - { - result >>= 3; - *((uint16_t *)out) = (result << 10) | (result << 5) | result; // 16 - } - else - *((uint32_t *)out) = (result << 16) | (result << 8) | result; // 32 - } - out += (1 << pixelShift); - } - out += (kIOHibernateProgressSpacing << pixelShift); - } - } -} - -void updateProgressBar(uint8_t * saveunder, int32_t firstBlob, int32_t select) -{ - uint8_t * screen; - uint32_t rowBytes, pixelShift; - uint32_t x, y; - int32_t blob, lastBlob; - uint32_t alpha, in, color, result; - uint8_t * out; - uint32_t saveindex[kIOHibernateProgressCount] = { 0 }; - - pixelShift = VIDEO(depth) >> 4; - if (pixelShift < 1) return; - screen = (uint8_t *) VIDEO (baseAddr); - rowBytes = VIDEO (rowBytes); - - screen += ((VIDEO (width) - - kIOHibernateProgressCount * (kIOHibernateProgressWidth + kIOHibernateProgressSpacing)) << (pixelShift - 1)) - + (VIDEO (height) - kIOHibernateProgressOriginY - kIOHibernateProgressHeight) * rowBytes; - - lastBlob = (select < kIOHibernateProgressCount) ? select : (kIOHibernateProgressCount - 1); - - screen += (firstBlob * (kIOHibernateProgressWidth + kIOHibernateProgressSpacing)) << pixelShift; - - for (y = 0; y < kIOHibernateProgressHeight; y++) - { - out = screen + y * rowBytes; - for (blob = firstBlob; blob <= lastBlob; blob++) - { - color = (blob < select) ? kIOHibernateProgressLightGray : kIOHibernateProgressMidGray; - for (x = 0; x < kIOHibernateProgressWidth; x++) - { - alpha = gIOHibernateProgressAlpha[y][x]; - result = color; - if (alpha) - { - if (0xff != alpha) - { - in = saveunder[blob * kIOHibernateProgressSaveUnderSize + saveindex[blob]++]; - result = ((255 - alpha) * in + alpha * result + 0xff) / 255; - } - if (1 == pixelShift) - { - result >>= 3; - *((uint16_t *)out) = (result << 10) | (result << 5) | result; // 16 - } - else - *((uint32_t *)out) = (result << 16) | (result << 8) | result; // 32 - } - out += (1 << pixelShift); - } - out += (kIOHibernateProgressSpacing << pixelShift); - } - } -} - - -//========================================================================== -// setVESATextMode - -static int -setVESATextMode( unsigned short cols, - unsigned short rows, - unsigned char bitsPerPixel ) -{ - VBEModeInfoBlock minfo; - unsigned short mode = modeEndOfList; - - if ( (cols != 80) || (rows != 25) ) // not 80x25 mode - { - mode = getVESAModeWithProperties( cols, rows, bitsPerPixel, - maColorModeBit | - maModeIsSupportedBit, - maGraphicsModeBit, - &minfo, NULL ); - } - - if ( ( mode == modeEndOfList ) || ( setVBEMode(mode, NULL) != errSuccess ) ) - { - video_mode( 2 ); // VGA BIOS, 80x25 text mode. - minfo.XResolution = 80; - minfo.YResolution = 25; - } - - // Update KernBootStruct using info provided by the selected - // VESA mode. - - bootArgs->Video.v_display = VGA_TEXT_MODE; - bootArgs->Video.v_baseAddr = 0xb8000; - bootArgs->Video.v_width = minfo.XResolution; - bootArgs->Video.v_height = minfo.YResolution; - bootArgs->Video.v_depth = 8; - bootArgs->Video.v_rowBytes = 0x8000; - - return errSuccess; // always return success -} - -//========================================================================== -// getNumberArrayFromProperty - -static int -getNumberArrayFromProperty( const char * propKey, - unsigned long numbers[], - unsigned long maxArrayCount ) -{ - char * propStr; - unsigned long count = 0; - - propStr = newStringForKey( (char *) propKey , &bootInfo->bootConfig ); - if ( propStr ) - { - char * delimiter = propStr; - char * p = propStr; - - while ( count < maxArrayCount && *p != '\0' ) - { - unsigned long val = strtoul( p, &delimiter, 10 ); - if ( p != delimiter ) - { - numbers[count++] = val; - p = delimiter; - } - while ( ( *p != '\0' ) && !isdigit(*p) ) - p++; - } - - free( propStr ); - } - - return count; -} - -int initGraphicsMode () -{ - unsigned long params[4]; - int count; - - params[3] = 0; - count = getNumberArrayFromProperty( kGraphicsModeKey, params, 4 ); - - // Try to find a resolution if "Graphics Mode" setting is not available. - if ( count < 3 ) - { - // Use the default resolution if we don't have an initialized GUI. - if (gui.screen.width == 0 || gui.screen.height == 0) - { - gui.screen.width = DEFAULT_SCREEN_WIDTH; - gui.screen.height = DEFAULT_SCREEN_HEIGHT; - } - - params[0] = gui.screen.width; - params[1] = gui.screen.height; - params[2] = 32; - } - - // Map from pixel format to bits per pixel. - - if ( params[2] == 256 ) params[2] = 8; - if ( params[2] == 555 ) params[2] = 16; - if ( params[2] == 888 ) params[2] = 32; - - return setVESAGraphicsMode( params[0], params[1], params[2], params[3] ); -} - -//========================================================================== -// setVideoMode -// -// Set the video mode to VGA_TEXT_MODE or GRAPHICS_MODE. - -void -setVideoMode( int mode, int drawgraphics) -{ - unsigned long params[4]; - int count; - int err = errSuccess; - - if ( mode == GRAPHICS_MODE ) - { - if ( (err=initGraphicsMode ()) == errSuccess ) { - if (gVerboseMode) { - // Tell the kernel to use text mode on a linear frame buffer display - bootArgs->Video.v_display = FB_TEXT_MODE; - } else { - bootArgs->Video.v_display = GRAPHICS_MODE; - } - } - } - - if ( (mode == VGA_TEXT_MODE) || (err != errSuccess) ) - { - count = getNumberArrayFromProperty( kTextModeKey, params, 2 ); - if ( count < 2 ) - { - params[0] = 80; // Default text mode is 80x25. - params[1] = 25; - } - - setVESATextMode( params[0], params[1], 4 ); - bootArgs->Video.v_display = VGA_TEXT_MODE; - } - - currentIndicator = 0; -} - -void getGraphicModeParams(unsigned long params[]) { - - params[3] = 0; - - VBEModeInfoBlock minfo; - - unsigned short vesaVersion; - unsigned short mode = modeEndOfList; - - getNumberArrayFromProperty( kGraphicsModeKey, params, 4); - - mode = getVESAModeWithProperties( params[0], params[1], params[2], - maColorModeBit | - maModeIsSupportedBit | - maGraphicsModeBit | - maLinearFrameBufferAvailBit, - 0, - &minfo, &vesaVersion ); - - params[0] = minfo.XResolution; - params[1] = minfo.YResolution; - params[2] = 32; -} - -//========================================================================== -// Return the current video mode, VGA_TEXT_MODE or GRAPHICS_MODE. - -int getVideoMode(void) -{ - return bootArgs->Video.v_display; -} - -//========================================================================== -// Display and clear the activity indicator. - -static char indicator[] = {'-', '\\', '|', '/', '-', '\\', '|', '/', '\0'}; - -// To prevent a ridiculously fast-spinning indicator, -// ensure a minimum of 1/9 sec between animation frames. -#define MIN_TICKS 2 - -void -spinActivityIndicator(int sectors) -{ - static unsigned long lastTickTime = 0, currentTickTime; - - if (previewTotalSectors && previewSaveunder) - { - int blob, lastBlob; - - lastBlob = (previewLoadedSectors * kIOHibernateProgressCount) / previewTotalSectors; - previewLoadedSectors+=sectors; - blob = (previewLoadedSectors * kIOHibernateProgressCount) / previewTotalSectors; - - if (blob!=lastBlob) - updateProgressBar (previewSaveunder, lastBlob, blob); - return; - } - - currentTickTime = time18(); // late binding - if (currentTickTime < lastTickTime + MIN_TICKS) - { - return; - } - else - { - lastTickTime = currentTickTime; - } - - if (getVideoMode() == VGA_TEXT_MODE) - { - if (currentIndicator >= sizeof(indicator)) - { - currentIndicator = 0; - } - putchar(indicator[currentIndicator++]); - putchar('\b'); - } -} - -void -clearActivityIndicator( void ) -{ - if ( getVideoMode() == VGA_TEXT_MODE ) - { - putchar(' '); - putchar('\b'); - } -} -