MoofEncoder/main.cp

/*
    File:       main.cp
 
    Contains:   An extremely basic encoder utility to assist in building all of the various
                "compiled" resources used by MoofWars.  Many of the encoder utilities are 
                actually handled by things in the standard TGraphic class, so the main reason
                for pre-encoding the graphics is to improve the time to load the graphics in 
                the game.
 
    Written by: Timothy Carroll 
 
    Copyright:  Copyright © 1996-1999 by Apple Computer, Inc., All Rights Reserved.
 
                You may incorporate this Apple sample source code into your program(s) without
                restriction. This Apple sample source code has been provided "AS IS" and the
                responsibility for its operation is yours. You are not permitted to redistribute
                this Apple sample source code as "Apple sample source code" after having made
                changes. If you're going to re-distribute the source, we require that you make
                it clear in the source that the code was descended from Apple sample source
                code, but that you've made changes.
 
    Change History (most recent first):
                7/1/1999    Karl Groethe    Updated for Metrowerks Codewarror Pro 2.1
                2/23/98     Timothy Carroll Updated menu calls to latest Universal Headers
                2/27/97     Timothy Carroll Now explicitly include Main.h
                8/15/96     Timothy Carroll Initial Release
                
    
                
 
*/
 
#include <Fonts.h>
#include <Devices.h>
#include <Resources.h>
#include <StandardFile.h>
 
#include "Main.h"
#include "GridEncode.h"
#include "ICL8Encode.h"
#include "PictEncode.h"
#include "PICTMask.h"
 
/*********************************************************************************
    Globals 
*********************************************************************************/
 
CTabHandle          gAppColorTable = NULL;
static Boolean      gDone = false;
 
 
/*********************************************************************************
    Functions   
*********************************************************************************/
 
void main (void);
 
OSStatus InitApp (void);
OSStatus RunApp (void);
OSStatus QuitApp (void);
OSStatus HandleMenuCommand (SInt16 theMenu, SInt16 theItem);
OSStatus GetFiles (SInt16 *input, SInt16 *output);
 
 
 
 
 
void main (void)
{
    OSStatus theErr = noErr;
    int loop;
    
    // Standard Mac Init
    InitGraf(&qd.thePort);
    InitFonts();
    InitWindows();
    InitMenus();
    TEInit();
    InitDialogs(nil);
    InitCursor();
 
    MaxApplZone();
    
    for (loop = 0; loop < kNumberOfMasters; loop++)
        MoreMasters();
 
    // Initialize Application Specifics
    theErr = InitApp();
    FAIL_OSERR (theErr, "\pFailed to initialize the application")
 
    // Run the eventloop
    theErr = RunApp();
    
    error:
    // On an error, the application will just quit.  Probably would be nice in a real
    // app to put up a dialog box or something.
    
    theErr = QuitApp();
}
 
OSStatus InitApp (void)
{
    OSStatus    theErr      = noErr;
    Handle      menuBarH    = NULL;
    MenuRef     appleMenuH  = NULL;
    MenuRef     engineMenuH = NULL;
    
    // read and install the menu bar, adding DA names.
    menuBarH = GetNewMBar(rMenuBar);
    FAIL_NIL (menuBarH, "\pFailed to load the MenuBar")
 
    SetMenuBar(menuBarH);
    DisposeHandle(menuBarH);
    
    appleMenuH = GetMenuHandle(mAppleMenu);
    FAIL_NIL (appleMenuH, "\pFailed to find the Apple Menu")
    AppendResMenu(appleMenuH, 'DRVR');
    
    DrawMenuBar();
    
    goto cleanup;
    
    error:
    
    if (theErr == noErr)
        theErr = paramErr;
    
    cleanup:
    return theErr;
}
 
 
OSStatus RunApp (void)
{
 
    WindowRef   whichWindow = NULL;
    OSStatus    theErr = noErr;
    
    EventRecord theEvent;
    short       partCode;
    long        menuResult;
    short       theMenu, theItem;
 
    while (!gDone)
    {
        (void) WaitNextEvent(everyEvent,&theEvent,kSleepTime,NULL);
 
        switch (theEvent.what)
        {
            case    nullEvent:
                break;          
            case    mouseDown:
                partCode = FindWindow(theEvent.where,&whichWindow);
            
                switch(partCode)
                {
                    case    inMenuBar:
                        menuResult = MenuSelect(theEvent.where);
                        theMenu = (menuResult >> 16) & 0x0000FFFF;
                        theItem = (menuResult) & 0x0000FFFF;
                        
                        HandleMenuCommand (theMenu, theItem);
                        HiliteMenu(0);
 
                        break;
 
                    default:
                        break;
                    }
                break;
        
            case    keyDown:
                if (theEvent.modifiers & cmdKey)
                    {
                        menuResult = MenuKey((short) theEvent.message & charCodeMask);
                        theMenu = (menuResult >> 16) & 0x0000FFFF;
                        theItem = (menuResult) & 0x0000FFFF;
                    
                        HandleMenuCommand (theMenu, theItem);
                        
                        HiliteMenu(0);
                    }
                break;
            default:
                break;
        }
 
    }
 
    return noErr;
}
 
 
 
OSStatus QuitApp (void)
{
    return noErr;
}
 
OSStatus HandleMenuCommand (SInt16 theMenu, SInt16 theItem)
{
    OSStatus theErr = noErr;
 
    switch (theMenu)
    {
        case mAppleMenu:
            if (theItem == iAboutApp)
                (void) Alert (128, NULL); 
            else
                {
                MenuRef     appleMenuH  = NULL;
                Str255      deskAccName;
                
                appleMenuH = GetMenuHandle(mAppleMenu);
                FAIL_NIL (appleMenuH, "\pFailed to find the Apple Menu")
                
                GetMenuItemText(appleMenuH,theItem,deskAccName);
                (void) OpenDeskAcc(deskAccName);
                }
                
        break;
        
        case mFileMenu:
            switch (theItem)
            {
                case iEncodeIcons:
                {
                    SInt16 in, out;
                    theErr = GetFiles (&in, &out);
                    FAIL_OSERR (theErr, "\p Failed to open the files")
                    
                    ICL8Encode (in, out);
    
                    CloseResFile(in);
                    CloseResFile (out);
                }
                break;
                
                case iEncodePICTs:
                {
                    SInt16 in, out;
                    theErr = GetFiles (&in, &out);
                    FAIL_OSERR (theErr, "\p Failed to open the files")
                    
                    PICTEncode (in, out);
    
                    CloseResFile(in);
                    CloseResFile (out);
                }
                break;
                
                case iTriplePICTs:
                {
                    SInt16 in, out;
                    theErr = GetFiles (&in, &out);
                    FAIL_OSERR (theErr, "\p Failed to open the files")
                    
                    GeneratePICTMasks (in, out);
    
                    CloseResFile(in);
                    CloseResFile (out);
                }
                break;
                
                case iEncodeTiles:
                {
                    SInt16 in, out;
                    theErr = GetFiles (&in, &out);
                    FAIL_OSERR (theErr, "\p Failed to open the files")
                    
                    GridTileEncode (in, out);
    
                    CloseResFile(in);
                    CloseResFile (out);
                }
                break;
                
                case iQuit:
                    gDone = true;
                break;
            }
    }
    return noErr;
    
    error:
    if (theErr == noErr)
        theErr = paramErr;
    return theErr;
}
 
 
OSStatus GetFiles (SInt16 *input, SInt16 *output)
{
    // This routine displays the standard get and put file dialogs so that the user
    // can select a file to read from, and to create an output file.
    
    StandardFileReply       inputFile;
    StandardFileReply       outputFile;
    SFTypeList              typeList;
    Point                   p;
    short                   inResNum, outResNum;
 
    typeList[0] = 'RSRC';
    typeList[1] = 'rsrc';
    
    p.h = 100; p.v = 100;
    StandardGetFile (NULL, 2, typeList, &inputFile);
    
    if (!inputFile.sfGood)
        return paramErr;
        
    StandardPutFile ("\pSave file as...", "\pUntitled",&outputFile);
    
    if (!(outputFile.sfGood && !outputFile.sfReplacing))
        return paramErr;
    
    inResNum = FSpOpenResFile (&inputFile.sfFile, fsRdPerm);
    FSpCreateResFile(&outputFile.sfFile, 'Doug', 'RSRC', outputFile.sfScript);
    outResNum = FSpOpenResFile (&outputFile.sfFile, fsRdWrPerm);
    
    *input = inResNum;
    *output = outResNum;
    return noErr;
}
 
// This copies a particular resource from the source res file to the destination.
OSStatus CopyResource (SInt16 inRes, SInt16 outRes, OSType theType, SInt16 theID)
{
    OSStatus    theErr = noErr;
    
    Handle      temp = NULL;
    
    // temp can be either a resource or a handle, we use this to tell what the current status is, so
    // that if we need to cleanup, we can do this correctly.
    Boolean     tempIsResource = true; 
    
    // we pass these to GetResInfo so that we can get the actual resource ID.
    SInt16      resID;
    ResType     resType;
    Str255      resName;
 
    SInt16      saveResNum; // Used to save the resource chain info
    
    saveResNum = CurResFile();
 
    UseResFile (inRes);
 
    // attempt to grab the color table resource.  We grab it as a resource because we're going
    // to write it right back out into the output file.
 
    temp = Get1Resource (theType, theID);
    theErr = ResError();
    FAIL_NIL (temp, "\pFailed to load the resource")
    FAIL_OSERR (theErr, "\pFailed to load the resource")
    
    GetResInfo( temp, &resID, &resType, resName ); // we do this just to get the name
    theErr = ResError();
    FAIL_OSERR( theErr, "\pFailed to get info on the resource")
    
    DetachResource (temp);
    theErr = ResError();
    FAIL_OSERR( theErr, "\pFailed to detach the resource from the input chain")
    
    tempIsResource = false;
        
    UseResFile (outRes);
    
    AddResource( temp, theType, theID, resName );
    theErr = ResError();
    FAIL_OSERR (theErr, "\pFailed to add the resource to the file")
    
    tempIsResource = true;
    
    WriteResource( temp );
    theErr = ResError();
    FAIL_OSERR (theErr, "\pFailed to write the resource to the file")
 
    goto cleanup;
    
error:
    if (theErr == noErr)
        theErr = paramErr;
cleanup:
    if (temp != NULL)
        if (tempIsResource)
            ReleaseResource (temp);
        else
            DisposeHandle (temp);
    
    UseResFile (saveResNum);
    return theErr;
}