Empty Engine Code/TtTinselTown.c

/******************************************************************************
 **                                                                          **
 **     Module:     TtTinselTown.c                                           **
 **                                                                          **
 **     Purpose:    Sample empty drawing engine.                             **
 **                 This module contains registration methods.               **
 **                                                                          **
 **     Author:     Mike W. Kelley                                           **
 **                                                                          **
 **                 2/3/95  Revised for 0.9 SDK release                      **
 **                                                                          **
 **     Copyright (C) 1994-95 Apple Computer, Inc.  All rights reserved.     **
 **     Apple Computer Confidential                                          **
 **                                                                          **
 *****************************************************************************/
 
/* System */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
 
#include "RAVE.h"
#include "RAVE_system.h"
#include "TtTinselTown.h"
 
/************************************************************************************************
 * Globals.
 ***********************************************************************************************/
 
TTtStorePrivate     gTtStorePrivate = { NULL, NULL };
 
/************************************************************************************************
 * Error handling stuff.
 ***********************************************************************************************/
 
#ifdef kTtDebug
    void TtError (
        const char      *message)
    {
        char    ErrorStr[255];
        
        strcpy (&ErrorStr[1], message);
        ErrorStr[0] = strlen (message);
        DebugStr ( (ConstStr255Param) ErrorStr);
    }
#endif
 
/************************************************************************************************
 * Create the private draw context data.
 ***********************************************************************************************/
 
TQAError TtDrawPrivateNew (
    TQADrawContext      *newDrawContext,    /* Draw context to initialize */
    const TQADevice     *device,            /* Target device */
    const TQARect       *rect,              /* Target rectangle (device coordinates) */
    const TQAClip       *clip,              /* 2D clip region (or NULL) */
    unsigned long       flags)              /* Mask of kQAContext_xxx */
{
    TTtDrawPrivate      *newDrawPrivate;
    long                width, height;
    
    /*
     * Allocate the TTtDrawPrivate structure.
     */
    
    newDrawPrivate = TtMemoryNew (sizeof (TTtDrawPrivate));
    
    if (newDrawPrivate == NULL)
    {
        return (kQAParamErr);
    }
    
    newDrawPrivate->flags = flags;
    newDrawPrivate->device = *device;
    newDrawPrivate->deviceRect = *rect;
    
    /*
     * Initialize the fields that describe the front (visible) buffer.
     */
    
    newDrawPrivate->width = width = rect->right - rect->left;
    newDrawPrivate->height = height = rect->bottom - rect->top;
    
    switch (device->deviceType)
    {
        case kQADeviceMemory:
            newDrawPrivate->rowBytes = device->device.memoryDevice.rowBytes;
            switch (device->device.memoryDevice.pixelType)
            {
                case kQAPixel_ARGB16:
                    newDrawPrivate->depth = 16;
                    break;
                
                case kQAPixel_ARGB32:
                    newDrawPrivate->depth = 32;
                    break;
                
                default:
                    return (kQANotSupported);
                    break;
            }
            newDrawPrivate->baseAddr = ((char *) device->device.memoryDevice.baseAddr)
                    + rect->left * (newDrawPrivate->depth >> 3)
                    + rect->top * newDrawPrivate->rowBytes;
            break;
        
        case kQADeviceGDevice:
            {
                PixMap          *devicePixMap;
                
                devicePixMap = *(*device->device.gDevice)->gdPMap;
                
                newDrawPrivate->rowBytes = devicePixMap->rowBytes & 0x3fff;
                newDrawPrivate->depth = devicePixMap->pixelSize;
                newDrawPrivate->baseAddr = devicePixMap->baseAddr
                    + rect->left * (newDrawPrivate->depth >> 3)
                    + rect->top * newDrawPrivate->rowBytes;
            }
            break;
        
        #ifdef kTtDebug
            default:
                TtError ("Unknown TQADevice type");
                break;
        #endif
    }
    
    /*
     * If a clip region is assigned, copy it into the private data.
     */
    
    if (clip)
    {
        switch (clip->clipType)
        {
            case kQAClipRgn:
                {
                    /*
                     * Deal with the clip rgn. Probably the best solution is to
                     * draw it into a 1 bit/pixel bitmap and use that as a write
                     * mask.
                     */
                }
                break;
            
            #ifdef kTtDebug
                default:
                    TtError ("Unknown TQAClip type");
                    break;
            #endif
        }
    }
    
    /*
     * Set the default state variable values.
     */
    
    newDrawPrivate->state [kQATag_ZFunction].i =
            (flags & kQAContext_NoZBuffer) ? kQAZFunction_None : kQAZFunction_LT;
    newDrawPrivate->state [kQATag_ColorBG_a].f = 0.0;
    newDrawPrivate->state [kQATag_ColorBG_r].f = 0.0;
    newDrawPrivate->state [kQATag_ColorBG_g].f = 0.0;
    newDrawPrivate->state [kQATag_ColorBG_b].f = 0.0;
    newDrawPrivate->state [kQATag_Width].f = 1.0;
    newDrawPrivate->state [kQATag_ZMinOffset].f = 0.0;
    newDrawPrivate->state [kQATag_ZMinScale].f = 1.0 / 65535.0; /* Engine-specific */
    
    /*
     * Set the state variables used for texture mapping, etc. (and clear unused ones).
     */
    
    newDrawPrivate->state [kQATag_Antialias].i = kQAAntiAlias_Fast;
    newDrawPrivate->state [kQATag_Blend].i = kQABlend_PreMultiply;
    newDrawPrivate->state [kQATag_PerspectiveZ].i = kQAPerspectiveZ_Off;
    newDrawPrivate->state [kQATag_TextureFilter].i = kQATextureFilter_Fast;
    newDrawPrivate->state [kQATag_TextureOp].i = kQATextureOp_None;
    newDrawPrivate->state [kQATag_Texture].i = 0;
 
    /*
     * Initialize the TQADrawContext methods and draw private pointer, and return.
     * Note that we don't initialize the 
     */
    
    newDrawContext->drawPrivate = (TQADrawPrivate *) newDrawPrivate;
    newDrawContext->setFloat = TtSetFloat;
    newDrawContext->setInt = TtSetInt;
    newDrawContext->setPtr = TtSetPtr;
    newDrawContext->getFloat = TtGetFloat;
    newDrawContext->getInt = TtGetInt;
    newDrawContext->getPtr = TtGetPtr;
    newDrawContext->drawPoint = TtDrawPoint;
    newDrawContext->drawLine = TtDrawLine;
    newDrawContext->drawTriGouraud = TtDrawTriGouraud;
    newDrawContext->drawTriTexture = TtDrawTriTexture;
    newDrawContext->drawBitmap = TtDrawBitmap;
    newDrawContext->renderStart = TtRenderStart;
    newDrawContext->renderEnd = TtRenderEnd;
    newDrawContext->renderAbort = TtRenderAbort;
    newDrawContext->flush = TtFlush;
    newDrawContext->sync = TtSync;
    
    return (kQANoErr);
}
 
/************************************************************************************************
 * Delete private draw context data.
 ***********************************************************************************************/
 
void TtDrawPrivateDelete (
    TQADrawPrivate      *drawPrivate)       /* Private context data to delete */
{
    TTtDrawPrivate      *myPrivate;
 
    myPrivate = (TTtDrawPrivate *) drawPrivate;
    
    TtMemoryDelete (myPrivate);
}
 
/************************************************************************************************
 * Return kQANoErr if we can draw to 'device'. For example, this code causes
 * this drawing engine to be used for only 16 and 32 bit/pixel devices.
 ***********************************************************************************************/
 
TQAError TtEngineDeviceCheck (
    const TQADevice *device)                /* Target device */
{
    if (device->deviceType == kQADeviceMemory)
    {
        TQAImagePixelType       targetPixelType;
    
        targetPixelType = device->device.memoryDevice.pixelType;
        return (((targetPixelType == kQAPixel_ARGB16) || (targetPixelType == kQAPixel_ARGB32))
                ? kQANoErr : kQAError);
    }
    else if (device->deviceType == kQADeviceGDevice)
    {
        long                    targetDepth;
    
        targetDepth = (*(*device->device.gDevice)->gdPMap)->pixelSize;
        return (((targetDepth == 16) || (targetDepth == 32)) ? kQANoErr : kQAError);
    }
    
    return (kQAError);
}
 
/************************************************************************************************
 * This function returns gestalt information about this engine to the application.
 ***********************************************************************************************/
 
TQAError TtEngineGestalt (
    TQAGestaltSelector  selector,           /* Gestalt parameter being requested */
    void                *response)          /* Buffer that receives response */
{
    const char          *TtName = "Empty Drawing Engine";
    const char          *source;
    char                *target;
    long                length;
    
    switch (selector)
    {
        case kQAGestalt_OptionalFeatures:
            *((unsigned long *) response) = kQAOptional_None;
            break;
        
        case kQAGestalt_FastFeatures:
            *((unsigned long *) response) = kQAFast_None;
            break;
        
        case kQAGestalt_VendorID:
            *((long *) response) = kTtMyVendorID;
            break;
        
        case kQAGestalt_EngineID:
            *((long *) response) = kTtMyEngineID;
            break;
        
        case kQAGestalt_Revision:
            *((long *) response) = kTtMyRevisionID;
            break;
        
        case kQAGestalt_ASCIINameLength:
            for (source = TtName, length = 0; *source++; /* Nothing */)
            {
                ++length;
            }
            *((long *) response) = length;
            break;
        
        case kQAGestalt_ASCIIName:
            for (source = TtName, target = (char *) response; *source; /* Nothing */)
            {
                *target++ = *source++;
            }
            *target = '\0';
            break;
        
        default:
            return (kQAGestaltUnknown);
            break;
    }
    
    return (kQANoErr);
}
 
/************************************************************************************************
 * This function is called by the manager to get our engine methods.
 ***********************************************************************************************/
 
static TQAError TtEngineGetMethod (
    TQAEngineMethodTag      methodTag,              /* Method being requested */
    TQAEngineMethod         *method)                /* (Out) Method */
{
    switch (methodTag)
    {
        case kQADrawPrivateNew:
            method->drawPrivateNew = TtDrawPrivateNew;
            break;
        case kQADrawPrivateDelete:
            method->drawPrivateDelete = TtDrawPrivateDelete;
            break;
        case kQAEngineCheckDevice:
            method->engineCheckDevice = TtEngineDeviceCheck;
            break;
        case kQAEngineGestalt:
            method->engineGestalt = TtEngineGestalt;
            break;
        case kQATextureNew:
            method->textureNew = TtTextureNew;
            break;
        case kQATextureDetach:
            method->textureDetach = TtTextureDetach;
            break;
        case kQATextureDelete:
            method->textureDelete = TtTextureDelete;
            break;
        case kQABitmapNew:
            method->bitmapNew = TtBitmapNew;
            break;
        case kQABitmapDetach:
            method->bitmapDetach = TtBitmapDetach;
            break;
        case kQABitmapDelete:
            method->bitmapDelete = TtBitmapDelete;
            break;
        default:
            return (kQAParamErr);
            break;
    }
    return (kQANoErr);
}
 
/************************************************************************************************
 * Call this function to register this rasterizer with Tinsel Town. This is usually
 * called by the shared library initialization method. This function returns 0 on success,
 * non-zero on error.
 ***********************************************************************************************/
 
OSErr TtRegister (void)
{
    TQAError    status;
    
    status = QARegisterEngine (TtEngineGetMethod);
    
    return ((status == kQANoErr) ? noErr : paramErr);
}