objtab.c++ 4.78 KB
//====================================================================
// objtab.c++
//
// Synopsis:
//
// Author(s)
//  Steve Shepard
//
// Copyright 1993, Silicon Graphics, Inc.
// All Rights Reserved.
//
// This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
// the contents of this file may not be disclosed to third parties, copied or
// duplicated in any form, in whole or in part, without the prior written
// permission of Silicon Graphics, Inc.
//
// RESTRICTED RIGHTS LEGEND:
// Use, duplication or disclosure by the Government is subject to restrictions
// as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
// and Computer Software clause at DFARS 252.227-7013, and/or in similar or
// successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
// rights reserved under the Copyright Laws of the United States.
//====================================================================
#include <assert.h>
#include <stdlib.h>
#include "libbank.h"
#include <audiotools.h>


ICObjTab::ICObjTab()
{
    compact = FALSE; /* default value */
}

void ICObjTab::Append(ICObject *o)
{
    FailIf(!o, IC_INTERNAL_ERR);
    
    objList.Append(o);
}

void ICObjTab::Print()
{
    Node *obj;
    
    for (obj = objList.head; obj != 0; obj = obj->next) {
        ICObject *ptr = (ICObject *)obj->data;
        ptr->Print();
    }
}

void ICObjTab::Write(FILE *f)
{
    Node *obj;
    
    for (obj = objList.head; obj != 0; obj = obj->next) {
        ICObject *ptr = (ICObject *)obj->data;
        ptr->Write(f);        
    }
}

void ICObjTab::LayOutFile() 
{
    Node        *node = objList.head;
    Node        *prev = (Node*)&objList.head;
    int         objCl,curOffset = 0;
    ICObject    *obj;
    
    if(compact)
    {
        //  THIN SOUNDS FROM INSTRUMENTS
        while (node != 0)
        {
            obj =  (ICObject *)node->data;

            objCl = obj->GetObjectClass();
            if(objCl == ICINST)
                ((ICInst*)obj)->ThinSounds();
            else if(objCl == ICBANK)
                ((ICBank*)obj)->ThinPrograms();
            else if(objCl == ICBANKFILE)
                obj->MarkUsed();
            node = node->next;
        }

        node = objList.head;

        
        while (node != 0)
        {
            obj = (ICObject *)node->data;

            if (obj->GetUsedFlag())
            {
                curOffset = obj->LayOut(curOffset);
                prev = node;
                node = node->next;
            }
            else
            {
                delete obj;                         // delete object attached
                node = objList.Remove(node, prev);  // remove from list & delete
            }
        }
    }
    else
    {
        while (node != 0)
        {
            obj = (ICObject *)node->data;
            if (obj->GetRefCount())
            {
                curOffset = obj->LayOut(curOffset);
                prev = node;
                node = node->next;
            }
            else
            {
                delete obj;                         // delete object attached
                node = objList.Remove(node, prev);  // remove from list & delete
            }
        }
    }
}

void ICObjTab::AssembleFile()
{
    Node *obj;
    
    for (obj = objList.head; obj != 0; obj = obj->next) {
        ((ICObject *)obj->data)->Assemble();
    }
}

//----------------------------------------------------------------------

void ICObjTab::WriteSymFile(FILE *f)
{
    Node                *node;
    ALSymFile           symFile;
    ALSymFileObj        *symFileObj;
    int                 i = 0;
    
    symFile.revision = AL_SYM_FILE_VERSION;
    symFile.fileSize = 0;
    symFile.objectCount = objList.count;
    
    symFileObj = (ALSymFileObj *)calloc(symFile.objectCount,
                                        sizeof(ALSymFileObj));
    
    FailIf(!symFileObj, IC_INTERNAL_ERR);

    fwrite(&symFile, sizeof(ALSymFile), 1, f);
    fwrite(symFileObj, sizeof(ALSymFileObj), symFile.objectCount, f);
    
    for (node = objList.head; node != 0; node = node->next) {
        ICObject *obj                   = (ICObject *)node->data;

        symFileObj[i].objectId          = obj->GetObjectID();
        symFileObj[i].objectClass       = obj->GetObjectClass();
        symFileObj[i].bankFileOffset    = obj->GetObjectOffset();
        symFileObj[i].stringOffset      = ftell(f);
        symFileObj[i].refCount          = obj->GetRefCount();

        fprintf(f, "%s", obj->GetName());       // write the string
        putc(0, f);                             // null termination
        
        i++;
    }

    // rewrite the header info now that we have all the info
    symFile.fileSize = ftell(f);
    rewind(f);
    fwrite(&symFile, sizeof(ALSymFile), 1, f);
    fwrite(symFileObj, sizeof(ALSymFileObj), symFile.objectCount, f);
}