From: cklarson@taquito.engr.ucdavis.edu (Christopher Klaus Larson)
Newsgroups: comp.sys.mac.programmer
Subject: Re: INIT's/System Extension Questions
Keywords: INIT extensions
Date: 9 Nov 92 01:08:45 GMT
Organization: College of Engineering - University of California - Davis

In article <1992Nov5.184623.15326@asuvax.eas.asu.edu> system@asuvax.eas.asu.edu (Marc Lesure) writes:
 
>Also, are there any snippets showing the best way to show an INIT icon
>during the booting sequence?
 
I'm not sure if this is the _best_ way to show an icon during startup, but
it has always worked for me. :-)

Feel free to use this as you see fit. Optimizations and bug fixes welcome.

It is written in THINK C and requires the inclusion of the MacTraps library.
Hopefully the comments within the code are a sufficient explination of how
it works.

I have seen other examples that perform this operation but they were
written in assembly.

Sorry about the lines longer than 80 characters.

-- Chris
cklarson@engr.ucdavis.edu

Code Follows ...
----------------------

/******************************************************************************

    Draw_Init_Icon.c    1992 - Chris Larson

    This function will draw an Init's icon on the screen during startup.
    
    Include the line,
    
        extern void Draw_Init_Icon (short icon_id);
        
    in your INIT source with your function prototypes and pass in the
    resource ID of the icon you wish to be drawn. If color QD exists, the
    function will attempt to draw a 'cicn' resource. If there is no color QD,
    it will draw an 'icn#'. If an error occurs, SysBeep is called and nothing
    is drawn.
    
******************************************************************************/

#include <Quickdraw.h>
#include <Types.h>
#include <OSUtils.h>
#include <Resources.h>
#include <Memory.h>
#include <LoMem.h>

#define DI_INITIAL_OFFSET       8
#define DI_BOTTOM_OFFSET        8
#define DI_ICON_HEIGHT          32
#define DI_ICON_WIDTH           32
#define DI_ICON_OFFSET          8
#define DI_NO_COLOR_QD          0x4000
#define DI_BEEP_LENGTH          30
#define DI_ICNPOUND_ROWBYTES    4
#define DI_INCPOUND_MASK_OFFSET 128
#define DI_CHECKSUM_CONSTANT    0x1021
#define DI_PVT_GBL_SIZE         76

#define LEFT_OFFSET_POINTER ((short *)0x092C) /* Last 4 bytes of CurAppName */
#define CHECKSUM_POINTER    ((short *)0x092E) /* hold position & checksum   */

typedef struct
    {
    Byte        QD_Private_Global_Space[DI_PVT_GBL_SIZE];
    long        randseed;
    BitMap      screenBits;
    Cursor      arrow;
    Pattern     dkGray;
    Pattern     ltGray;
    Pattern     gray;
    Pattern     black;
    Pattern     white;
    GrafPtr     thePort;
    } QD_Variables;

void Draw_Init_Icon (short icon_id);

void Draw_Init_Icon (short icon_id)
{
    CIconHandle     icon_handle = NULL;
    Rect            destination_rect;
    Rect            source_rect;
    BitMap          icon_bitmap;
    BitMap          mask_bitmap;
    GrafPort        local_port;
    QD_Variables    my_vars;
    long            our_a5;
    long            old_a5;
    
    /* Prepare A5 for InitGraf call */
    
    asm 68000
        {
        move.l  a5,old_a5
        lea     our_a5,a5
        move.l  a5,CurrentA5
        }
    
    /* InitGraf and open our GrafPort */
    
    InitGraf (&(my_vars.thePort));
    OpenPort (&local_port);
    
    /* Determine if position is valid. If not, set to initial value.
       If so, do nothing. */
    
    if ((((*LEFT_OFFSET_POINTER)<<1)^DI_CHECKSUM_CONSTANT) != (*CHECKSUM_POINTER))
        *LEFT_OFFSET_POINTER = DI_INITIAL_OFFSET;
    
    /* Compute destination Rect. */
    
    destination_rect.bottom = local_port.portRect.bottom - DI_BOTTOM_OFFSET;
    destination_rect.left = local_port.portRect.left + *LEFT_OFFSET_POINTER;
    destination_rect.top = destination_rect.bottom - DI_ICON_HEIGHT;
    destination_rect.right = destination_rect.left + DI_ICON_WIDTH;
    
    /* If color QD exists, use 'cicn'. If not, use 'ICN#'.
       SysBeep and return if resource unavailable. */
    
    if (!(ROM85&DI_NO_COLOR_QD))
        {
        icon_handle = GetCIcon (icon_id);
        if (!icon_handle)
            {
            SysBeep (DI_BEEP_LENGTH);
            return;
            }
        PlotCIcon (&destination_rect,icon_handle);
        DisposCIcon (icon_handle);
        }
    else
        {
        icon_handle = (CIconHandle)GetResource ('ICN#',icon_id);
        if (!icon_handle)
            {
            SysBeep(DI_BEEP_LENGTH);
            return;
            }
        
        HLock (icon_handle);
        
        /* Set source Rect and intialize source BitMaps. */
        
        SetRect (&source_rect,0,0,DI_ICON_HEIGHT,DI_ICON_WIDTH);
        
        icon_bitmap.bounds  = mask_bitmap.bounds = source_rect;
        icon_bitmap.rowBytes = mask_bitmap.rowBytes = DI_ICNPOUND_ROWBYTES;
        icon_bitmap.baseAddr = (Ptr)(*icon_handle);
        mask_bitmap.baseAddr = (Ptr)(((Byte *)(*icon_handle))+DI_INCPOUND_MASK_OFFSET);
        
        /* Draw the 'ICN#' using its mask. */
        
        CopyMask (&icon_bitmap,&mask_bitmap,&(local_port.portBits),&source_rect,&source_rect,&destination_rect);
        
        HUnlock (icon_handle);
        ReleaseResource (icon_handle);
        }
    
    ClosePort (&local_port);
    
    /* Update drawing position and checksum. */
    
    *LEFT_OFFSET_POINTER += DI_ICON_WIDTH+DI_ICON_OFFSET;
    
    *CHECKSUM_POINTER = ((*LEFT_OFFSET_POINTER)<<1)^DI_CHECKSUM_CONSTANT;
    
    /* Reset A5 */
    
    asm 68000
        {
        movea.l old_a5,a5
        move.l  a5,CurrentA5
        }
    
    /* We're outa here. */
    
    return;
}
Newsgroups: comp.sys.mac.programmer