Notes:Stickybear Reading

Source Code
Hello World! Can we get some syntax highlighting in here?

animation.c

 * 1) include 
 * 2) include 


 * 1) include "dbg.h"


 * 1) include "utility.h"
 * 2) include "animation.h"
 * 3) include "reading.h"

Direc      mfxDir[maxThings];  /* directory of all things in memory */ short      DirNum;     /* holds number of entries in directory */ EraTab     EraTab2;    /* screen 0 (really vidmem2) */ EraTab     EraTab3;    /* screen 1 (really vidmem3) */ EraTabPtr  EraPtr;     /* this always points at the erase table of the rear screen */ ScenePtr   SceneTab[maxScenes]; /* a table of scene ptrs */ int        IDstrips;   /* bkgd strip images */ TOCPtr     strips;     /* bkgd strip images */ TOCPtr     scrolls; Ptr        scrollchunk; Boolean    swapflag; short      daBkgd;     /* index for which bkgd table to draw from */ short      daScroll;   /* index for which scroll band tables to use */ RectListPtr theRectPtr; /* pointer to current rectangle list (hot spots) */

static Boolean     FrameFlag;  /* gets set if time for scene to do a frame */ static Boolean     ShowFlag;   /* gets set if items in scene should be displayed */

/* * ReinitScene - This Resets default values for a scene. */ void ReinitScene(theScene) ScenePtr theScene; { short          iCtr;       /* # of items counter */ ItemPtr        theItem;

currentT = clock; /* get current tick count */

theScene->Frame = 0;       /* main cycle counter for the scene */ theScene->NextTime = currentT + theScene->AniDelay; /* * Move initial values to current/working values for each item. */   if (theScene->NumItems != 0) { for (iCtr = 0; iCtr < theScene->NumItems; iCtr++) { /* loop for each item of scene */ theItem = (ItemPtr)((int)theScene + (int)theScene->ItemDir[iCtr].Where); switch(theItem->IType) { case ITypeShp: ReinitShp((ItemShpPtr)theItem); break; case ITypePix: ReinitPix((ItemPixPtr)theItem); break; case ITypeSeq: ReinitSeq((ItemSeqPtr)theItem); break; case ITypeGrp: ReinitGrp((ItemGrpPtr)theItem); break; case ITypeInt: break; case ITypeAud: break; }       }    } }

/* * ReinitShp - Resets shape table initial values. */ void ReinitShp(theShp) ItemShpPtr theShp; {   ReinitGen(&theShp->Gen); ReinitPos(&theShp->Pos);

theShp->Pos.ICurXOff = 0; theShp->Pos.ICurYOff = 0; theShp->Pos.ICurWide = theShp->Pos.IEraseWide = theShp->ShpIA->NumWide; theShp->Pos.ICurHigh = theShp->Pos.IEraseHigh = theShp->ShpIA->NumHigh; }

/* * ReinitSeq - Resets sequence table initial values. */ void ReinitSeq(theSeq) ItemSeqPtr theSeq; { SeqPtr     theSeqDF;   /* the sequence disk file */ ShapePtr   theShp;     /* shape disk file */

ReinitGen(&theSeq->Gen); ReinitPos(&theSeq->Pos); ReinitCyc(&theSeq->Cyc); /*    * Set the dimension values for the initial state. * If there are any states. */   if (theSeq->Cyc.ICycSize == 0) return; theSeqDF = theSeq->Cyc.ISeqPtr; theShp = theSeqDF->SeqTab[theSeq->Cyc.IIState].StateIA; theSeq->Pos.ICurXOff = theSeqDF->SeqTab[theSeq->Cyc.IIState].StateXOff; theSeq->Pos.ICurYOff = theSeqDF->SeqTab[theSeq->Cyc.IIState].StateYOff; theSeq->Pos.ICurWide = theSeq->Pos.IEraseWide = theShp->NumWide; theSeq->Pos.ICurHigh = theSeq->Pos.IEraseHigh = theShp->NumHigh; }

void ReinitPix(thePix) ItemPixPtr thePix; {   ReinitGen(&thePix->Gen); ReinitPos(&thePix->Pos); ReinitCyc(&thePix->Cyc); }

void ReinitGrp(theGrp) ItemGrpPtr theGrp; {   ReinitGen(&theGrp->Gen); ReinitPos(&theGrp->Pos); ReinitCyc(&theGrp->Cyc); }

/* * ReinitGen Resets the general item table values. */ void ReinitGen(theGen) ItemPtr theGen; {   theGen->IActive = theGen->IIActive; theGen->IDisplay = theGen->IIDisplay; theGen->IAofA = theGen->IIAofA; }

/* * ReinitPos resets the positional item table values. */ void ReinitPos(thePos) ItemPosPtr thePos; {   thePos->IBox = thePos->IIBox; thePos->IPlane = thePos->IIPlane; thePos->ICurX = thePos->IEraseX = thePos->IBaseX = thePos->IIBaseX; thePos->ICurY = thePos->IEraseY = thePos->IBaseY = thePos->IIBaseY; thePos->IVelEnable = thePos->IIVelEnable; thePos->IXVel = thePos->IIXVel; thePos->IXAcc = thePos->IIXAcc; thePos->IXVelCtr = thePos->IXVelDur = thePos->IIXVelDur; thePos->IXVelFin = thePos->IIXVelFin; thePos->IYVel = thePos->IIYVel; thePos->IYAcc = thePos->IIYAcc; thePos->IYVelCtr = thePos->IYVelDur = thePos->IIYVelDur; thePos->IYVelFin = thePos->IIYVelFin; }

/* * ReinitCyc resets the state cycling item table values. */ void ReinitCyc(theCyc) ItemCycPtr theCyc; {   theCyc->ICycEnable = theCyc->IICycEnable; theCyc->ICycCtr = theCyc->ICycle = theCyc->IICycle; theCyc->ICycCng = theCyc->IICycCng; theCyc->ICycDCtr = theCyc->ICycDur = theCyc->IICycDur; theCyc->ICycFin = theCyc->IICycFin; theCyc->IState = theCyc->IIState; }

/* * Resolve - * * First it links item tables with their disk file counterparts. * * Then it links memory resident disk file with others. For example, it links sequences * with their states and groups with there sequences. * */

Boolean Resolve { short      sCtr;       /* # of Scenes counter */ short      iCtr;       /* # of items counter */ short      DirInd; ScenePtr   theScene;   /* pointer to the "current" Scene */ ItemShpPtr theShp; ItemSeqPtr theSeq; Boolean    myBoo;

for (sCtr = 0; sCtr < maxScenes; sCtr++) { /* loop for each scene */ theScene = SceneTab[sCtr]; if (theScene != nil) { /* point at a scene */ if (theScene->NumItems) { for (iCtr = 0; iCtr < theScene->NumItems; iCtr++) { /* loop for each item of scene */ DirInd = getind(theScene->ItemDir[iCtr].Who); /* search mfxDir for this filename */ if (DirInd == -1) { /* try to load from current directory */ STATUS2("Resolve can't find %s\n", theScene->ItemDir[iCtr].Who); STATUS2("It has %d characters\n", strlen(theScene->ItemDir[iCtr].Who)); return(false); /* file not on directory - tell user somehow */ }                   mfxDir[DirInd].What = theScene->ItemDir[iCtr].What; switch(theScene->ItemDir[iCtr].What) { case ITypeShp: theShp = (ItemShpPtr)((int)theScene + (int)theScene->ItemDir[iCtr].Where); theShp->ShpIA = (ShapePtr) mfxDir[DirInd].Where; /* stuff address from mfxDir */ break; case ITypePix: break; case ITypeSeq: theSeq = (ItemSeqPtr)((int)theScene + (int)theScene->ItemDir[iCtr].Where); theSeq->Cyc.ISeqPtr = (SeqPtr)mfxDir[DirInd].Where; /* pointer to memory resident disk image file */ theSeq->Cyc.ICycSize = theSeq->Cyc.ISeqPtr->SeqNumSt; /* copy # of states from disk file to item table */ myBoo = RslvSeq((SeqPtr)mfxDir[DirInd].Where); if (myBoo == false) return(myBoo); /* exit at first sign of problems */ break; case ITypeGrp: break; case ITypeInt: break; case ITypeAud: break; }               }            }        }    }    return(true); }

/* * RslvSeq - Resolve the pointers to the state images of the sequence. * * Pass the scene and item number. */ Boolean RslvSeq(theSeq) SeqPtr theSeq; { short      DirInd; /* This is the index into 'mfxDir' (the directory of all things in memory) */ short      resctr;

if (theSeq->SeqNumSt != 0) { for (resctr = 0; resctr < theSeq->SeqNumSt; resctr++) { DirInd = getind(theSeq->SeqTab[resctr].StateName); /* search mfxDir for this filename */ if (DirInd == -1) { return(false); }           theSeq->SeqTab[resctr].StateIA = (ShapePtr)mfxDir[DirInd].Where; }   }    return(true); }

/* * Step - do one frame of animation (for all active scenes in memory). */ void Step { short          sCtr;       /* # of Scenes counter */ short          iCtr;       /* # of items counter */ ScenePtr       theScene;   /* pointer to the "current" Scene */ ItemPtr        theItem;

currentT = clock; /* get current tick count */

while (!swapflag);

/*    * Erase everything on the rear screen. */   if (EraPtr->EraCtr >= EraTab_Size) { STATUS2("*** EraTab has %d items ***\n", EraPtr->EraCtr); }   Erase(EraPtr); EraPtr->EraCtr = 0; /* start with empty erase list for this cycle */ /*    * Now we are ready to redraw all Scenes. * See how many there are and point at the first one. */   for (sCtr = 0; sCtr < maxScenes; sCtr++) {  /* loop for each scene */ theScene = SceneTab[sCtr]; if (theScene) { /* point at a scene */ if (theScene->Active) { if (currentT >= theScene->NextTime) { FrameFlag = true; theScene->NextTime = currentT + theScene->AniDelay; }               else FrameFlag = false; }           else FrameFlag = false;

if (theScene->Display) ShowFlag = true; else ShowFlag = false;

if (FrameFlag || ShowFlag) { if (theScene->NumItems != 0) { for (iCtr = 0; iCtr < theScene->NumItems; iCtr++) { /* loop for each item of scene */ theItem = (ItemPtr) ((int)theScene + (int)theScene->ItemDir[iCtr].Where); if (theItem->ITofA == theScene->Frame) { /* Time for an action? */                           if (theItem->ITofA != 0) {

}                       }                        switch(theItem->IType) { case ITypeShp: DriveShp(theItem); break; case ITypePix: DrivePix(theItem); break; case ITypeSeq: DriveSeq(theItem); break; case ITypeGrp: DriveGrp(theItem); break; case ITypeInt: break; case ITypeAud: break; }                   }                }                if (FrameFlag) theScene->Frame++; }       }    }    swap_clut7; }

void DriveShp(myItem) ItemPtr myItem; { ItemShpPtr theShp; short      ctr;

theShp = (ItemShpPtr)myItem;

if (ShowFlag && myItem->IDisplay) { Draw(theShp->ShpIA, theShp->Pos.ICurX, theShp->Pos.ICurY); /* draw the shape */

ctr = EraPtr->EraCtr; EraPtr->ETab[ctr].left = theShp->Pos.ICurX; EraPtr->ETab[ctr].top = theShp->Pos.ICurY; EraPtr->ETab[ctr].right = theShp->Pos.ICurX + theShp->Pos.ICurWide; EraPtr->ETab[ctr].bottom = theShp->Pos.ICurY + theShp->Pos.ICurHigh; EraPtr->EraCtr++; }

if (FrameFlag && myItem->IActive) { DrivePos(&theShp->Pos); /* now add velocity, accel, and update position for next cycle */ } }

void DrivePix(myItem) ItemPtr myItem; { ItemPixPtr thePix;

thePix = (ItemPixPtr)myItem;

if (FrameFlag) { DriveCyc(&thePix->Cyc, &thePix->Pos); } }

/* * DriveSeq - is used for sequences. * DriveCyc must be called before DrivePos as it sets the x,y offsets to use for * the current state of the sequence. The first time through, the offsets have been * set by the resolve code. */ void DriveSeq(myItem) ItemPtr myItem; { ItemSeqPtr theSeq; short      ctr;

theSeq = (ItemSeqPtr)myItem;

if (theSeq->Cyc.ICycSize != 0) { /* if empty sequence just exit */ if (ShowFlag && myItem->IDisplay) { Draw(theSeq->Cyc.ISeqPtr->SeqTab[theSeq->Cyc.IState].StateIA,               theSeq->Pos.ICurX, theSeq->Pos.ICurY);

ctr = EraPtr->EraCtr; EraPtr->ETab[ctr].left = theSeq->Pos.ICurX; EraPtr->ETab[ctr].top = theSeq->Pos.ICurY; EraPtr->ETab[ctr].right = theSeq->Pos.ICurX + theSeq->Pos.ICurWide; EraPtr->ETab[ctr].bottom = theSeq->Pos.ICurY + theSeq->Pos.ICurHigh; EraPtr->EraCtr++; }

if (FrameFlag && myItem->IActive) { DriveCyc(&theSeq->Cyc, &theSeq->Pos); DrivePos(&theSeq->Pos); }       /*         * Fix 01/26/92 - still call DriveCyc and DrivePos, * but disable velocity and cycling. * This should make the x,y offsets still figure in the position. */

} }

void DriveGrp(myItem) ItemPtr myItem; { ItemGrpPtr theGrp;

theGrp = (ItemGrpPtr)myItem;

if (FrameFlag) { DriveCyc(&theGrp->Cyc, &theGrp->Pos); DrivePos(&theGrp->Pos); } }

/* * DrivePos - do the velocity, acceleration, box limit stuff. * * When coming here, the image has already been drawn for this animation cycle (at ICurX, ICurY). * This code will set the parameters for the next animation cycle after setting * the update rectangle. */ void DrivePos(thePos) ItemPosPtr thePos; { short  locShort;

if (thePos->IVelEnable) { /* If velocity is "allowed" */ if (thePos->IXVel != thePos->IXVelFin) { /* If current X velocity is not final X vel */ if (thePos->IXVelCtr == thePos->IXVelDur) { /* is it time to add acceleration? */               thePos->IXVel += thePos->IXAcc; thePos->IXVelCtr = 0; }           else (thePos->IXVelCtr)++; }       thePos->IBaseX += thePos->IXVel; /* Add X velocity to current X position to set new X */

if (thePos->IYVel != thePos->IYVelFin) { /* If current Y velocity is not final Y vel */ if (thePos->IYVelCtr == thePos->IYVelDur) { /* is it time to add acceleration? */               thePos->IYVel += thePos->IYAcc; thePos->IYVelCtr = 0; }           else (thePos->IYVelCtr)++; }       thePos->IBaseY += thePos->IYVel; /* Add Y velocity to current Y position */ }   thePos->ICurX = thePos->IBaseX + thePos->ICurXOff; /* Adjust for sequences with offset states */ thePos->ICurY = thePos->IBaseY + thePos->ICurYOff; /* * Now check the box limits. */   if (thePos->ICurX + (thePos->ICurWide -1) > thePos->IBox.right) { thePos->IXVel = 0 - thePos->IXVel; /* negate the velocity */ /* * Get the amount of overshoot and make it the offset on the other side of the limit. */       locShort = thePos->ICurX + (thePos->ICurWide -1) - thePos->IBox.right; thePos->ICurX = thePos->IBox.right - (thePos->ICurWide -1) - locShort; thePos->IBaseX = thePos->ICurX - thePos->ICurXOff; }   if (thePos->ICurX < thePos->IBox.left) { thePos->IXVel = 0 - thePos->IXVel; /* negate the velocity */ thePos->ICurX = thePos->IBox.left + (thePos->IBox.left - thePos->ICurX); thePos->IBaseX = thePos->ICurX - thePos->ICurXOff; }

if (thePos->ICurY + (thePos->ICurHigh -1) > thePos->IBox.bottom) { thePos->IYVel = 0 - thePos->IYVel; /* negate the velocity */ /* * Get the amount of overshoot and make it the offset on the other side of the limit. */       locShort = thePos->ICurY + (thePos->ICurHigh -1) - thePos->IBox.bottom; thePos->ICurY = thePos->IBox.bottom - (thePos->ICurHigh -1) - locShort; thePos->IBaseY = thePos->ICurY - thePos->ICurYOff; }   if (thePos->ICurY < thePos->IBox.top) { thePos->IYVel = 0 - thePos->IYVel; /* negate the velocity */ thePos->ICurY = thePos->IBox.top + (thePos->IBox.top - thePos->ICurY); thePos->IBaseY = thePos->ICurY - thePos->ICurYOff; } }

/* * DriveCyc - This code changes the state to draw if the conditions are right. * If it does change the state, it also resets the counters and image dimension * variables in the item table. */ void DriveCyc(theCyc, thePos) ItemCycPtr theCyc; ItemPosPtr thePos; { SeqPtr theSeq;

if (theCyc->ICycEnable) { /* If cycling is "allowed" */ if (theCyc->ICycCtr == 0) { theCyc->ICycCtr = theCyc->ICycle;  /* reset counter */ theCyc->IState++; /*            * check against max # of states */           if (theCyc->IState == theCyc->ICycSize) theCyc->IState = 0; /*            * We have a new state to draw for next time, set it's new * dimension and offset values. */           theSeq = theCyc->ISeqPtr; thePos->ICurWide = (*theSeq->SeqTab[theCyc->IState].StateIA).NumWide; thePos->ICurHigh = (*theSeq->SeqTab[theCyc->IState].StateIA).NumHigh; thePos->ICurXOff = theSeq->SeqTab[theCyc->IState].StateXOff; thePos->ICurYOff = theSeq->SeqTab[theCyc->IState].StateYOff; }       else theCyc->ICycCtr--; } }

asm_itrfc.c

 * 1) include "utility.h"

/* * These are used in Assembly language routines. * Set these to reflect the bitmap dimensions when * using the Draw and Erase assembly routines. */ short          SceneWide16 = 384; int            SceneWide32 = 384; short          SceneHigh = 240; Ptr            EraSrc;     /* source screen to erase from */

bop.c

 * 1) include 
 * 2) include 
 * 3) include 
 * 4) include 
 * 5) include 
 * 6) include 


 * 1) include "dbg.h"


 * 1) include "my_types.h"
 * 2) include "animation.h"
 * 3) include "utility.h"
 * 4) include "reading.h"
 * 5) include "screen.h"
 * 6) include "rtf.h"
 * 7) include "bop.h"
 * 8) include "sound.h"
 * 9) include "file_mgr.h"

static unsigned    score; static char        sscore[10];

static Boolean     round_over; static Boolean     game_over;

static Ptr         BopData;

static short       DirSaveBop; static Rect        fullRect = {0,1,240,383}; static short       WhichBop = 0;   /* which bop package to do */ static ScenePtr    BopScene; static ScenePtr    StatScene; static ItemPtr     BopItem; static Boolean     FirstBop;       /* set if this is first package */

static short       bop_ctr;        /* down counter for bop image cycling */ static short       bop_item_index; /* which item was hit */

static Boolean     ball_active; static Boolean     cannon_active; static short       cannon_ctr;

static ItemSeqPtr  the_cannon; static ItemSeqPtr  the_wheel; static ItemSeqPtr  the_ball;

static ShapePtr    num_tab[10];    /* pointers to the 10 number shapes for the score */

/* * this is the table of the twenty Bop packages that get shuffled */ short  Boptab[NumBopPkgs] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9   };

static Bop_Pkg BopPkgs[NumBopPkgs] = { "Boppkg1.rtf", 4, 7, 8, "Boppkg2.rtf", 4, 6, 8, "Boppkg3.rtf", 4, 6, 7, "Boppkg4.rtf", 4, 6, 7, "Boppkg5.rtf", 6, 7, 9, "Boppkg6.rtf", 4, 6, 11, "Boppkg7.rtf", 4, 5, 7, "Boppkg8.rtf", 5, 6, 8, "Boppkg9.rtf", 4, 6, 8, "Boppkg10.rtf", 4, 6, 10 };

static Bop_Row BopRows[NumRows] = { 837, NumRowItems * 0, 0,2, TopRowSpace, -8, 50, TopRowYpos, 473, NumRowItems * 1, 0,2, MidRowSpace, -6,100, MidRowYpos, 225, NumRowItems * 2, 0,2, BotRowSpace, -4, 50, BotRowYpos };

static Bop_Item BopItems[NumBopItems];

static short num_gone;     /* when this reaches 6 we are finished for this level */

/* * These are the rectangles for the Bop buttons */ static RectList BopRect = { 5,   177, 33,218, 82,    /* help button */ 177, 88,218,149,   /* speech button */ 177,155,218,216,   /* text button */ 177,222,218,283,   /* play button */ 177,289,218,350    /* go back button */ };

static short   Balls;  /* start the game with this many balls */ static Rect    ball_rect;  /* this holds the current ball rectangle */ static Rect    collide_rect; /* this gets set to the previous and current ball rectangles */

/* * This is the main code for Bumper's Word Bop * */ void Bop { Boolean        done;

SceneTab[MScene] = nil; /* we are not using the 3rd scene (MScene) right now */ StatScene = SceneTab[BSScene] = (ScenePtr)stuffpkg(ScreenBuf); BopScene = SceneTab[BMScene] = (ScenePtr)mfxDir[getind("new.bop.scene")].Where;

FixScene(BSScene); FixScene(BMScene); BopScene->AniDelay = Bop_AniDelay; SetUpScene(BSScene);   /* status scene - contains score, balls, cannon */ SetUpScene(BMScene);   /* main scene - contains targets to shoot at */

StatScene->AniDelay = 0; /* this contains the cannon, wheel, ball, score, # balls */ StatScene->Active = true; StatScene->Display = true;

/*    * Set up pointers to the cannon, wheel, and ball item tables */   the_cannon = (ItemSeqPtr) ((unsigned)StatScene + (unsigned)StatScene->ItemDir[cannon_item].Where); the_wheel = (ItemSeqPtr) ((unsigned)StatScene + (unsigned)StatScene->ItemDir[wheel_item].Where); the_ball = (ItemSeqPtr) ((unsigned)StatScene + (unsigned)StatScene->ItemDir[ball_item].Where); init_cannon; /* get everything lined up */ /*    * Set up pointers to the number shapes */   num_tab[0] = (ShapePtr)mfxDir[getind("num0.shp")].Where; num_tab[1] = (ShapePtr)mfxDir[getind("num1.shp")].Where; num_tab[2] = (ShapePtr)mfxDir[getind("num2.shp")].Where; num_tab[3] = (ShapePtr)mfxDir[getind("num3.shp")].Where; num_tab[4] = (ShapePtr)mfxDir[getind("num4.shp")].Where; num_tab[5] = (ShapePtr)mfxDir[getind("num5.shp")].Where; num_tab[6] = (ShapePtr)mfxDir[getind("num6.shp")].Where; num_tab[7] = (ShapePtr)mfxDir[getind("num7.shp")].Where; num_tab[8] = (ShapePtr)mfxDir[getind("num8.shp")].Where; num_tab[9] = (ShapePtr)mfxDir[getind("num9.shp")].Where;

new_game;            /* initialize the game variables for a new game */

DirSaveBop = DirNum;   /* save for starting point when loading each new pkg */ theRectPtr = &BopRect; /* set list of hotspots */

mk_bop_scrn;         /* Make the screen for bop */ new_bop_pkg;         /* Play the curtain closing rtf, load data, open curtains */

Bop2;                /* start right in the game */ if (!game_over) { stop_all_audio; MkBopBut;            /* make the buttons for bop */ cursor_show; done = false; while (!done) {

chk_help(0, BEARfid, 0, 0); /* no restart audio to pass */ chk_dim; /* if it's time to dim, this won't return until undim */ CheckInput; if (theInpTab.ButPress) { switch (theInpTab.HotIndex) { case 0: /* Help button */ stop_all_audio; start_bkgd_audio(0, BEARfid, false); /* pass channel number */ CheckInput; while ((eor_ctr) && (theInpTab.HotIndex == 0) && (!theInpTab.ButPress)) CheckInput; stop_all_audio; reset_help; break; case 1: /* speech button */ Cursor_Freeze; stop_all_audio; new_bop_speech; start_bkgd_audio(0, BUTTONfid, false); /* pass channel number */ changeSpch; while (eor_ctr); stop_all_audio; set_bear_voice; set_button_voice; Cursor_Melt; break; case 2: /* text button */ Cursor_Freeze; stop_all_audio; new_bop_text; if (text == English) start_bkgd_audio(3, BUTTONfid, false); /* pass channel number */ if (text == Spanish) start_bkgd_audio(1, BUTTONfid, false); /* pass channel number */ changeText; while (eor_ctr); stop_all_audio; Cursor_Melt; break; case 3: /* play button */ Bop2;        /* play the game */ stop_all_audio; if (game_over) done = true; else if (!cannon_active) { MkBopBut;    /* make the buttons for bop */ cursor_show; }                       break; case 4: /* go back button */ stop_all_audio; done = true; break; }           }            last_xpos = inp_xpos;   /* xpos of input device */ last_ypos = inp_ypos;  /* ypos of input device */ }   }    stop_all_audio; NoBopBut; cursor_hide; Close_Curtains; SceneTab[BSScene] = nil; /* don't need these scenes anymore */ SceneTab[BMScene] = nil; }

/* * new_bop_pkg - Play the curtain closing rtf, load data, open curtains */ static void new_bop_pkg { int        fid; ItemSeqPtr theSeq;     /* the sequence item table */ SeqPtr     theSeqDF;   /* the sequence disk file */ ShapePtr   theShp;     /* shape disk file */ short      rowctr, itemctr, tocctr; short      i, initStat, relXOff, relYOff; Boolean    stat; SoundmapDesc   *sm_ptr; /* play_desc_ptr   play_tab; */

/*    * Clear the soundmap buffers */   for (i = 5; i <= 12; i++) { memset (snd_array[i].data, 0, BopNounGrpSize * 128); }   for (i = 13; i <= 15; i++) { memset (snd_array[i].data, 0, BopFXGrpSize * 128); }

if (!FirstBop) Close_Curtains; else FirstBop = false; STATUS2("loading %s\n", BopPkgs[Boptab[WhichBop]].PkgName);
 * 1) if 0
 * 1) endif

/*    * 'play' the new package */   fid = open_file(BopPkgs[Boptab[WhichBop]].PkgName, true); if (fid == -1) { WhichBop++; /* advance to next package */ if (WhichBop == NumBopPkgs) WhichBop = 0; fid = open_file(BopPkgs[Boptab[WhichBop]].PkgName, false); }

stat = play_recs(fid, reinit_rtf, 2, false, false, 0); /* curtain section */ stat = play_recs(fid, set_bop_pre_aud_pcls, 1, false, false, 0); /* bookmark to audio section */ stat = play_recs(fid, set_bop_pkg1_pcls, 8, false, false, 0); /* play 8 from the first 16 */ /*    * Adjust the soundmaps for the true size of the data just loaded */   sm_ptr = sm_info(audpath, snd_array[5].smap_id); sm_ptr->smd_nogrps = pcl_tab[0]->PCL_Cnt / 128; sm_ptr = sm_info(audpath, snd_array[6].smap_id); sm_ptr->smd_nogrps = pcl_tab[1]->PCL_Cnt / 128; sm_ptr = sm_info(audpath, snd_array[7].smap_id); sm_ptr->smd_nogrps = pcl_tab[2]->PCL_Cnt / 128; sm_ptr = sm_info(audpath, snd_array[8].smap_id); sm_ptr->smd_nogrps = pcl_tab[3]->PCL_Cnt / 128; sm_ptr = sm_info(audpath, snd_array[9].smap_id); sm_ptr->smd_nogrps = pcl_tab[4]->PCL_Cnt / 128; sm_ptr = sm_info(audpath, snd_array[10].smap_id); sm_ptr->smd_nogrps = pcl_tab[5]->PCL_Cnt / 128; sm_ptr = sm_info(audpath, snd_array[11].smap_id); sm_ptr->smd_nogrps = pcl_tab[6]->PCL_Cnt / 128; sm_ptr = sm_info(audpath, snd_array[12].smap_id); sm_ptr->smd_nogrps = pcl_tab[7]->PCL_Cnt / 128; /*    * Adjust the soundmaps for the true size of the data just loaded */   stat = play_recs(fid, set_bop_pkg2_pcls, 4, false, false, 0); /* play 4 from the next */ sm_ptr = sm_info(audpath, snd_array[13].smap_id); sm_ptr->smd_nogrps = pcl_tab[0]->PCL_Cnt / 128; sm_ptr = sm_info(audpath, snd_array[14].smap_id); sm_ptr->smd_nogrps = pcl_tab[1]->PCL_Cnt / 128; sm_ptr = sm_info(audpath, snd_array[15].smap_id); sm_ptr->smd_nogrps = pcl_tab[2]->PCL_Cnt / 128;

DirNum = DirSaveBop;   /* restore number of items in memory before last package */ BopData = stuffpkg(PkgBuf);    /* now add the package to the master directory */ /*    * Link the new sequences to the Bop Scene (the bottom two rows and the words) */   for (tocctr = 0; tocctr < NumRowItems*4; tocctr ++) { strcpy(BopScene->ItemDir[tocctr+NumRowItems].Who, pkgTOC->TE[tocctr].Who); }   /*     * temporarily shut off the status scene as setupscene eventually tries * to reinitialize everything in memory and we would like to keep * the score and cannon as they are */   SceneTab[BSScene] = 0; /* shut off scene with score, cannon, etc */ SetUpScene(BMScene); /* the bop main scene (the one with the targets) */ SceneTab[BSScene] = StatScene;

tocctr = 0; for (rowctr = 0; rowctr < NumRows; rowctr ++) { for (itemctr = 0; itemctr < NumRowItems; itemctr ++) {

theSeq = (ItemSeqPtr) ((unsigned)BopScene + (unsigned)BopScene->ItemDir[tocctr].Where); theSeq->Cyc.ICycle = Bop_Cycle; theSeqDF = theSeq->Cyc.ISeqPtr; theShp = theSeqDF->SeqTab[theSeq->Cyc.IIState].StateIA;

theSeq->Pos.IXVel = BopRows[rowctr].velocity; theSeq->Pos.IBaseY = theSeq->Pos.ICurY = BopRows[rowctr].inity - ((theShp->NumHigh)/2); theSeq->Pos.IBaseX = theSeq->Pos.ICurX = BopRows[rowctr].initx - ((theShp->NumWide)/2) + (BopRows[rowctr].row_space * itemctr); if (theSeq->Pos.IBaseX > RSide) { theSeq->Pos.IBaseX = theSeq->Pos.ICurX = RSide; theSeq->Gen.IDisplay = false; theSeq->Gen.IActive = false; }           else { theSeq->Gen.IDisplay = true; theSeq->Gen.IActive = true; BopRows[rowctr].last_id = itemctr; /* this is the last so far */ }           BopItems[rowctr*NumRowItems+itemctr].hit_ctr = 0; BopItems[rowctr*NumRowItems+itemctr].num_states = theSeqDF->SeqNumSt; BopItems[rowctr*NumRowItems+itemctr].org_seq_ptr = theSeqDF; /*            * Adjust the state offsets so that the first offset is 0,0 */           initStat= theSeq->Cyc.IIState; relXOff= theSeqDF->SeqTab[initStat].StateXOff; relYOff= theSeqDF->SeqTab[initStat].StateYOff; for (i = 0; i < theSeqDF->SeqNumSt; i++) { if (i == initStat){ theSeqDF->SeqTab[i].StateXOff= 0; theSeqDF->SeqTab[i].StateYOff= 0; }               else{ theSeqDF->SeqTab[i].StateXOff-= relXOff; theSeqDF->SeqTab[i].StateYOff-= relYOff; }           }            tocctr++; }   }

BopScene->AniDelay = Bop_AniDelay; BopScene->Active = true; BopScene->Display = true;

no_vel;  /* stop the x movement of the items */ Step;    /* draw the first frame of animation */

currentT = clock;        /* get current tick count */ reset_dim;               /* reset dim counter */ reset_help;
 * 1) if 0
 * 1) endif

stat = play_recs(fid, reinit_rtf, 2, false, false, 0); /* curtains opening */

stat = close_file(fid);

STATUS1("Loaded Bop Package\n"); }

/* * new_bop_speech - load just the 8 speech files for the 8 targets */ void new_bop_speech { int        fid; short      i; Boolean     stat; SoundmapDesc   *sm_ptr;

for (i = 5; i <= 12; i++) { /* Clear just the 8 word soundmap buffers */ memset (snd_array[i].data, 0, BopNounGrpSize * 128); }   /*     * 'play' the new package */   fid = open_file(BopPkgs[Boptab[WhichBop]].PkgName, false); stat = play_recs(fid, set_bop_pre_aud_pcls, 1, false, false, 0); /* bookmark to audio section */ stat = play_recs(fid, set_bop_aud_pcls, 8, false, false, 0); stat = close_file(fid); /*    * Adjust the soundmaps for the true size of the data just loaded */   sm_ptr = sm_info(audpath, snd_array[5].smap_id); sm_ptr->smd_nogrps = pcl_tab[0]->PCL_Cnt / 128; sm_ptr = sm_info(audpath, snd_array[6].smap_id); sm_ptr->smd_nogrps = pcl_tab[1]->PCL_Cnt / 128; sm_ptr = sm_info(audpath, snd_array[7].smap_id); sm_ptr->smd_nogrps = pcl_tab[2]->PCL_Cnt / 128; sm_ptr = sm_info(audpath, snd_array[8].smap_id); sm_ptr->smd_nogrps = pcl_tab[3]->PCL_Cnt / 128; sm_ptr = sm_info(audpath, snd_array[9].smap_id); sm_ptr->smd_nogrps = pcl_tab[4]->PCL_Cnt / 128; sm_ptr = sm_info(audpath, snd_array[10].smap_id); sm_ptr->smd_nogrps = pcl_tab[5]->PCL_Cnt / 128; sm_ptr = sm_info(audpath, snd_array[11].smap_id); sm_ptr->smd_nogrps = pcl_tab[6]->PCL_Cnt / 128; sm_ptr = sm_info(audpath, snd_array[12].smap_id); sm_ptr->smd_nogrps = pcl_tab[7]->PCL_Cnt / 128; }

/* * new_bop_text - set alls word on the screen to the other language */ void new_bop_text { short      i; ItemSeqPtr  theSeq;     /* the sequence item table */ SeqPtr     theSeqDF;   /* the sequence disk file */ ShapePtr   theShp;     /* shape disk file */

for (i = NumRowItems; i <= NumBopItems; i++) { /* start at the second row */ if (BopItems[i].hit_ctr == 1) { /* displaying the word */ theSeq = (ItemSeqPtr) ((unsigned)BopScene + (unsigned)BopScene->ItemDir[i].Where); theSeq->Cyc.IState ^= 1; theSeqDF = theSeq->Cyc.ISeqPtr; theShp = theSeqDF->SeqTab[theSeq->Cyc.IState].StateIA; theSeq->Pos.ICurWide = theShp->NumWide; theSeq->Pos.ICurHigh = theShp->NumHigh; }   } }

/* * mk_bop_scrn - Build the Bop screen. */ void mk_bop_scrn { Ptr        thePtr; Ptr        scnptrsav; int        fid; Boolean    stat;

/*    * Save original contents and then set scn_ptr to bkgd scrn * (most drawing happens at scn_ptr) */   scnptrsav = scn_ptr; scn_ptr = vidmem5;

FilCol = 96; Fill(fullRect, FilCol); /* fill entire bkgd screen */

thePtr = mfxDir[getind("boptop.shp")].Where; Draw((ShapePtr)thePtr, 0, 0); /* draw the shape */

thePtr = mfxDir[getind("bopbg.shp")].Where; Draw((ShapePtr)thePtr, 60, 36); /* draw the shape */

scn_ptr = scnptrsav; /* restore scn_ptr */ /*    * copy to rear screen, swap, and copy to new rear screen */   copy_bkgd_front; /*    * At this point, plane B is still invisible */   FadeDown(meddisolve); BopOn;   /* turn plane mixing off */

/*    * Play the first frame of the curtains opening rtf (display the open curtains) */   fid = open_file("CCurt.rtf", false); stat = play_recs(fid, reinit_rtf, 1, false, false, 0); stat = close_file(fid);

NoButs;              /* unlink old living room button strip */ PBFlag = true;         /* bring plane B up also */ BopScene->Display = false; Step; FadeUp(meddisolve, false); /* no cursor */ }

/* * Close curtains - */ static void Close_Curtains { int        fid; Boolean    stat;

fid = open_file("CCurt.rtf", false); stat = play_recs(fid, reinit_rtf, 2, false, false, 0); stat = close_file(fid); }

/* * Open curtains - */ static void Open_Curtains { int        fid; Boolean    stat;

fid = open_file("OCurt.rtf", false); stat = play_recs(fid, reinit_rtf, 2, false, false, 0); stat = close_file(fid); }

/* * no_vel - this disables the objects velocity */ void no_vel { ItemSeqPtr theSeq;     /* the sequence item table */ short      ctr;

for (ctr = 0; ctr < NumBopItems; ctr++) { theSeq = (ItemSeqPtr) ((unsigned)BopScene + (unsigned)BopScene->ItemDir[ctr].Where); theSeq->Pos.IIVelEnable = theSeq->Pos.IVelEnable = false; } }

/* * add_vel - this enables the objects velocity */ void add_vel { ItemSeqPtr theSeq;     /* the sequence item table */ short      ctr;

for (ctr = 0; ctr < NumBopItems; ctr++) { theSeq = (ItemSeqPtr) ((unsigned)BopScene + (unsigned)BopScene->ItemDir[ctr].Where); theSeq->Pos.IIVelEnable = theSeq->Pos.IVelEnable = true; } }

/* * init_cannon - setup the cannon, wheel, and ball */ static void init_cannon { SeqPtr     theSeqDF;   /* the sequence disk file */ ShapePtr   theShp;     /* shape disk file */ short      i, initStat, relXOff, relYOff;

/*    * Adjust the state offsets so that the first offset is 0,0 */   theSeqDF = the_cannon->Cyc.ISeqPtr; theShp = theSeqDF->SeqTab[the_cannon->Cyc.IIState].StateIA; initStat = the_cannon->Cyc.IIState; relXOff= theSeqDF->SeqTab[initStat].StateXOff; relYOff= theSeqDF->SeqTab[initStat].StateYOff; for (i = 0; i < theSeqDF->SeqNumSt; i++) { if (i == initStat){ theSeqDF->SeqTab[i].StateXOff= 0; theSeqDF->SeqTab[i].StateYOff= 0; }       else{ theSeqDF->SeqTab[i].StateXOff-= relXOff; theSeqDF->SeqTab[i].StateYOff-= relYOff; }   }

theSeqDF = the_wheel->Cyc.ISeqPtr; theShp = theSeqDF->SeqTab[the_wheel->Cyc.IIState].StateIA; initStat = the_wheel->Cyc.IIState; relXOff= theSeqDF->SeqTab[initStat].StateXOff; relYOff= theSeqDF->SeqTab[initStat].StateYOff; for (i = 0; i < theSeqDF->SeqNumSt; i++) { if (i == initStat){ theSeqDF->SeqTab[i].StateXOff= 0; theSeqDF->SeqTab[i].StateYOff= 0; }       else{ theSeqDF->SeqTab[i].StateXOff-= relXOff; theSeqDF->SeqTab[i].StateYOff-= relYOff; }   }

theSeqDF = the_ball->Cyc.ISeqPtr; theShp = theSeqDF->SeqTab[the_ball->Cyc.IIState].StateIA; initStat = the_ball->Cyc.IIState; relXOff= theSeqDF->SeqTab[initStat].StateXOff; relYOff= theSeqDF->SeqTab[initStat].StateYOff; for (i = 0; i < theSeqDF->SeqNumSt; i++) { if (i == initStat){ theSeqDF->SeqTab[i].StateXOff= 0; theSeqDF->SeqTab[i].StateYOff= 0; }       else{ theSeqDF->SeqTab[i].StateXOff-= relXOff; theSeqDF->SeqTab[i].StateYOff-= relYOff; }   }    show_cannon; }

/* * show_cannon - display the cannon */ static void show_cannon {

the_cannon->Pos.IBaseX = the_cannon->Pos.ICurX = cannon_init_xpos; the_cannon->Pos.IBaseY = the_cannon->Pos.ICurY = cannon_init_ypos; the_cannon->Pos.ICurXOff = 0; the_cannon->Pos.ICurYOff = 0;

the_cannon->Pos.IBox.bottom = 500; the_cannon->Pos.IIBox.bottom = 500;

the_cannon->Gen.IActive = true; the_cannon->Gen.IDisplay = true; the_cannon->Cyc.ICycEnable = false; the_cannon->Cyc.ICycle = 0; the_cannon->Cyc.IState = 0;

the_wheel->Pos.IBaseX = the_wheel->Pos.ICurX = cannon_init_xpos + wheel_xoff; the_wheel->Pos.IBaseY = the_wheel->Pos.ICurY = cannon_init_ypos + wheel_yoff; the_wheel->Pos.ICurXOff = 0; the_wheel->Pos.ICurYOff = 0; the_wheel->Gen.IDisplay = true; the_wheel->Gen.IActive = true; the_wheel->Cyc.ICycEnable = false;

ball_active = false; cannon_active = true; cannon_ctr = 0; pt_pos(vidpath, cannon_init_xpos * 2, cannon_init_ypos * 2);   /* reset to center */ }

/* * update_cannon - move the cannon *                 pass ( CANNON_LEFT or CANNON_RIGHT ) * */ void update_cannon(offset) short  offset; {

the_cannon->Pos.IBaseX += offset; the_wheel->Pos.IBaseX = the_cannon->Pos.IBaseX + wheel_xoff;

if (offset < 0) { the_wheel->Cyc.IState++; if (the_wheel->Cyc.IState == the_wheel->Cyc.ICycSize) the_wheel->Cyc.IState = 0; }   else { the_wheel->Cyc.IState--; if (the_wheel->Cyc.IState == -1) the_wheel->Cyc.IState = the_wheel->Cyc.ICycSize - 1; } }

/* * hide_cannon - */ void hide_cannon {

/*    * This gets called when the cannon is going behind the curtain. * This wont get called if there is a ball, bop, etc currently active. */   the_cannon->Gen.IActive = false; the_cannon->Gen.IDisplay = false; cannon_active = false; cannon_ctr = 0;

the_wheel->Gen.IActive = false; the_wheel->Gen.IDisplay = false;

if (ball_active) { the_ball->Gen.IDisplay = false; the_ball->Gen.IActive = false; ball_active = false; } }

/* * Bop2 - the game part of all this */ void Bop2 { int    stat;

while (theInpTab.ButPress) CheckInput; /* wait for button release */ cursor_hide; start_bkgd_audio(BopMusic, BEARfid, true); /* Start bkgd audio */ NoBopBut; show_cannon;         /* also sets pointer to center of screen */ last_xpos = inp_xpos;  /* xpos of input device */ last_ypos = inp_ypos;  /* ypos of input device */ add_vel;             /* let the targets bounce around */ while ((cannon_active) && (!game_over)) {

if (stat = chk_help(0, BEARfid, BopMusic, BEARfid)) add_vel;     /* the dimming code would have disabled the velocity */ if (stat = chk_dim)  /* if it's time to dim, this won't return until undim */ add_vel;     /* the dimming code would have disabled the velocity */

update_audio; if (round_over) { if ((!cannon_ctr) && (!ball_active) && (!bop_ctr)) { stop_all_audio; new_round; start_bkgd_audio(BopMusic, BEARfid, true); /* Start bkgd audio */ add_vel; }       }        if (ball_active) check_collision; update_rows; CheckInput; if (inp_xpos > cannon_init_xpos * 2) { update_cannon(CANNON_RIGHT); pt_pos(vidpath, cannon_init_xpos * 2, cannon_init_ypos * 2);   /* reset to center */ }       else if (inp_xpos < cannon_init_xpos * 2) { update_cannon(CANNON_LEFT); pt_pos(vidpath, cannon_init_xpos * 2, cannon_init_ypos * 2);   /* reset to center */ }       if ((the_cannon->Pos.IBaseX < cannon_left_limit) || (the_cannon->Pos.IBaseX > cannon_right_limit)) { if ((!cannon_ctr) && (!ball_active) && (!bop_ctr)) { hide_cannon; }       }        if ((cannon_ctr) || (ball_active)) update_shot; /* this could return with 'game_over' set */ else if ((theInpTab.ButPress) && (!bop_ctr) && (!smap_busy) && (!smap_list_ctr) &&           (!round_over) && (the_cannon->Pos.IBaseX >= cannon_left_limit) && (the_cannon->Pos.IBaseX <= cannon_right_limit)) init_shot; /* if there are no bops, no soundmaps being played or in the queue */

last_xpos = inp_xpos;  /* xpos of input device */ last_ypos = inp_ypos;  /* ypos of input device */ }   no_vel;               /* stop the x movement of the items */ }

/* * update_rows -   This sees if new items need to be introduced or *                  if old items need to be removed. */ static void update_rows { ItemSeqPtr theSeq;     /* the sequence item table */ ItemSeqPtr theSeq2;    /* another sequence item table */ SeqPtr     theSeqDF;   /* the sequence disk file */ ShapePtr   theShp;     /* shape disk file */ short      ctr, the_index;

/*    * See if there are any active bop sequences */   if (bop_ctr) { bop_ctr--; if (!bop_ctr) { /* time to change the image */ the_ball->Gen.IDisplay = false; the_ball->Gen.IActive = false; the_ball->Cyc.ICycEnable = false; the_ball->Pos.IXVel = 0; ball_active = false;

theSeq = (ItemSeqPtr) ((unsigned)BopScene +               (unsigned)BopScene->ItemDir[bop_item_index].Where);

if (bop_item_index >= NumRowItems) { /* less then NumRowItems means top row */ /*                * either restore the original image parameters * or substitute the word sequence */                switch (BopItems[bop_item_index].hit_ctr) {

case 1: /* switch to the word (if in bottom two rows) */

/*                        * word soundmaps start at snd #5 * images for bottom two rows start at item #4 * so add 1 to bop_item_index to get sound to play */                       start_soundmap(snd_array[bop_item_index + 1].smap_id); /*                        * theSeq2 is a ptr to the word sequence which * appears 8 items later than its image in the scene */                       theSeq2 = (ItemSeqPtr) ((unsigned)BopScene +                            (unsigned)BopScene->ItemDir[bop_item_index+8].Where); /*                        * transfer the word image sequence ptr to the item */                       theSeq->Cyc.ICycEnable = false; theSeq->Cyc.IState = text; /* text - 0=English, 1=Spanish */ if (theSeq->Gen.IActive) theSeq->Gen.IDisplay = true; theSeq->Cyc.ICycSize = 2;

theSeqDF = theSeq->Cyc.ISeqPtr = theSeq2->Cyc.ISeqPtr; theShp = theSeqDF->SeqTab[theSeq->Cyc.IState].StateIA; theSeq->Pos.ICurWide = theShp->NumWide; theSeq->Pos.ICurHigh = theShp->NumHigh;

theSeq->Pos.ICurXOff = 0;  /* these might be set from last sequence */ theSeq->Pos.ICurYOff = 0;  /* they would be added to the new position */

theSeq->Pos.IBaseY = theSeq->Pos.ICurY = BopRows[bop_item_index >> 2].inity - ((theShp->NumHigh) >> 1); break;

case 2: /* switch back to the original image */

/*                        * see if this is one with a sound effect and * play it if so                        */ if (bop_item_index == BopPkgs[Boptab[WhichBop]].item13) start_soundmap(snd_array[13].smap_id); else if (bop_item_index == BopPkgs[Boptab[WhichBop]].item14) start_soundmap(snd_array[14].smap_id); else if (bop_item_index == BopPkgs[Boptab[WhichBop]].item15) start_soundmap(snd_array[15].smap_id);

theSeq->Cyc.ICycEnable = true; theSeq->Cyc.IState = 0; /* might as well start at initial state */ if (theSeq->Gen.IActive) theSeq->Gen.IDisplay = true;

theSeqDF = theSeq->Cyc.ISeqPtr = BopItems[bop_item_index].org_seq_ptr; theSeq->Cyc.ICycSize = BopItems[bop_item_index].num_states; theShp = theSeqDF->SeqTab[theSeq->Cyc.IState].StateIA; theSeq->Pos.ICurWide = theShp->NumWide; theSeq->Pos.ICurHigh = theShp->NumHigh;

theSeq->Pos.IBaseY = theSeq->Pos.ICurY = BopRows[bop_item_index >> 2].inity - ((theShp->NumHigh) >> 1); break;

case 3: /* this item is finished */ theSeq->Gen.IDisplay = false; /* don't show item anymore */ num_gone++; if (num_gone == num_gone_needed) /* change back to 6 for final version */ round_over = true; break; }           }            else { /* it's something from the top row */ theSeq->Gen.IDisplay = false; /* don't show item anymore */ }       }    }    for (ctr=0; ctrItemDir[the_index].Where); if (theSeq->Pos.ICurX <= (LSide + 9)) { theSeq->Gen.IDisplay = false; theSeq->Gen.IActive = false; BopRows[ctr].first_id++; /* advance to the next item to be disabled */ if (BopRows[ctr].first_id == NumRowItems) BopRows[ctr].first_id = 0; }       /*         * See if the last item in the row has advanced far enough * for us to introduce a new item. */       the_index = BopRows[ctr].first_item + BopRows[ctr].last_id; theSeq = (ItemSeqPtr) ((unsigned)BopScene + (unsigned)BopScene->ItemDir[the_index].Where); if ((theSeq->Pos.IXVel < 0 ) && ((theSeq->Pos.ICurX + BopRows[ctr].row_space) <= RSide)) { BopRows[ctr].last_id++; if (BopRows[ctr].last_id == NumRowItems) BopRows[ctr].last_id = 0; the_index = BopRows[ctr].first_item + BopRows[ctr].last_id; theSeq = (ItemSeqPtr) ((unsigned)BopScene + (unsigned)BopScene->ItemDir[the_index].Where); if (theSeq->Gen.IActive) { STATUS2("The next item for row %d is not ready !!!\n", ctr); BopRows[ctr].last_id--; if (BopRows[ctr].last_id == 0) BopRows[ctr].last_id = NumRowItems - 1; }           else { theSeqDF = theSeq->Cyc.ISeqPtr; theShp = theSeqDF->SeqTab[theSeq->Cyc.IState].StateIA; theSeq->Pos.IBaseX = theSeq->Pos.ICurX = RSide - (theShp->NumWide / 2); theSeq->Gen.IActive = true;

/* if it still has a life */ if (BopItems[the_index].hit_ctr < 3)   /* 3 = hit thrice (gone) */ theSeq->Gen.IDisplay = true;

theSeq->Pos.IXVel = BopRows[ctr].velocity; }       }    } }

/* * init_shot - shoot the ball */ static void init_shot {

/*    *the first few cycles involve the cannon only, the ball appears later */   the_cannon->Cyc.ICycEnable = true; cannon_ctr = 12;       /* # of animation cycles for cannon to do (unless ball tops out first) */ }

/* * update_shot - check the cannon's state, move the ball, and check for top of screen */ static void update_shot { Boolean    stat;

stat = false; if (cannon_ctr == 10) { /*        * Start the ball - initial position relative to the cannon's         */ the_ball->Pos.IBaseX = the_ball->Pos.ICurX = the_cannon->Pos.IBaseX + ball_xoff; the_ball->Pos.IBaseY = the_ball->Pos.ICurY = the_cannon->Pos.IBaseY + ball_yoff; the_ball->Pos.IXVel = 0; the_ball->Pos.IYVel = ball_velocity; the_ball->Gen.IDisplay = true; the_ball->Gen.IActive = true; the_ball->Cyc.ICycEnable = false; the_ball->Cyc.IState = 0; ball_active = true; start_soundmap(snd_array[shot_snd].smap_id); }

if (cannon_ctr) { /* see if its time to stop the cannon from cycling */ cannon_ctr--; if (!cannon_ctr) { the_cannon->Cyc.ICycEnable = false; }   }

if ((ball_active) && (the_ball->Pos.IBaseY <= ball_min)) { /* is ball off top of screen ? */       the_ball->Gen.IDisplay = false; the_ball->Gen.IActive = false; ball_active = false; start_soundmap(snd_array[miss_snd].smap_id); /*        * If the cannon is still going, disable it         */ if (cannon_ctr) { the_cannon->Cyc.ICycEnable = false; the_cannon->Cyc.IState = 0; cannon_ctr = 0; }       game_over = loose_ball;   /* take a ball away */ } }

/* * check_collision - this checks for collisions and processes any hit items * * returns 'true' if all items have been removed */ static void check_collision { short      ctr; ItemSeqPtr theSeq;     /* the sequence item table */ SeqPtr     theSeqDF;   /* the sequence disk file */ ShapePtr   theShp;     /* shape disk file */

ball_rect.left = the_ball->Pos.ICurX; ball_rect.top = the_ball->Pos.ICurY; ball_rect.right = the_ball->Pos.ICurX + ball_width; ball_rect.bottom = the_ball->Pos.ICurY + ball_height;

for (ctr = 0; ctr < NumBopItems; ctr++) { theSeq = (ItemSeqPtr) ((unsigned)BopScene + (unsigned)BopScene->ItemDir[ctr].Where); if ((theSeq->Gen.IActive) && (theSeq->Gen.IDisplay)) { if (theSeq->Pos.ICurX <= ball_rect.right) { if (theSeq->Pos.ICurY <= ball_rect.bottom) { theSeqDF = theSeq->Cyc.ISeqPtr; theShp = theSeqDF->SeqTab[theSeq->Cyc.IState].StateIA; if (theSeq->Pos.ICurX + theShp->NumWide >= ball_rect.left) { if (theSeq->Pos.ICurY + theShp->NumHigh >= ball_rect.top) { if (ctr < 4) { if ((ctr == 0) || (ctr == 2)) { /* stars */ start_soundmap(snd_array[star_snd].smap_id); score += BopRows[ctr/NumRowItems].points; show_score; add_ball; /* add a ball */ }                               else { /* orbs */ start_soundmap(snd_array[sphere_snd].smap_id); if (score >= BopRows[ctr/NumRowItems].points) { score -= BopRows[ctr/NumRowItems].points; show_score; }                                   game_over = loose_ball;   /* take a ball away */ }                           }                            else { start_soundmap(snd_array[bop_snd].smap_id); score += BopRows[ctr/NumRowItems].points; show_score; }                           /*                             * Transfer the images velocity to the ball * also convert for different sized images */                           bop_item_index = ctr;   /* which item was hit */ theSeq->Gen.IDisplay = false; /* turn off the original object */ the_ball->Pos.IXVel = theSeq->Pos.IXVel; the_ball->Pos.IYVel = 0; the_ball->Cyc.ICycEnable = true;

theSeqDF = the_ball->Cyc.ISeqPtr; theShp = theSeqDF->SeqTab[the_ball->Cyc.IState].StateIA; the_ball->Pos.ICurWide = theShp->NumWide; the_ball->Pos.ICurHigh = theShp->NumHigh;

the_ball->Pos.IBaseY = the_ball->Pos.ICurY = BopRows[bop_item_index >> 2].inity - ((theShp->NumHigh) >> 1);

bop_ctr = 6;           /* down counter for bop image cycling */ BopItems[bop_item_index].hit_ctr++; break; /* don't check for multiple hits */ }                   }                }            }        }    } }

/* * new_game - reinit the number of balls and score and display both of these */ static void new_game { short      ctr; ItemShpPtr theShp;     /* shape item table */

FirstBop = true; Balls = ball_new_amount; for (ctr = 0; ctr < ball_box_max; ctr++) { theShp = (ItemShpPtr) ((unsigned)StatScene + (unsigned)StatScene->ItemDir[ctr].Where); theShp->Gen.IActive = true; theShp->Gen.IDisplay = true; }   for (ctr=0; ctr<NumBopItems; ctr++) { BopItems[ctr].hit_ctr = 0; }   for (ctr=0; ctr<NumRows; ctr++) { BopRows[ctr].first_id = 0; BopRows[ctr].last_id = 0; }   score = 0; bop_ctr = 0; num_gone = 0; round_over = false; game_over = false; show_score; }

/* * new_round - */ static void new_round { short  ctr;

for (ctr=0; ctr<NumBopItems; ctr++) { BopItems[ctr].hit_ctr = 0; }   for (ctr=0; ctr<NumRows; ctr++) { BopRows[ctr].first_id = 0; BopRows[ctr].last_id = 0; }   bop_ctr = 0; num_gone = 0; round_over = false; WhichBop++; /* advance to next package */ if (WhichBop == NumBopPkgs) WhichBop = 0; new_bop_pkg; }

/* * show_score - display the score */ static void show_score { short  ctr; ItemShpPtr theShp;     /* shape item table */

STATUS2("score = %d\n", score);

sprintf(sscore,"%7d",score); for (ctr=0; ctr<7; ctr++) { if (sscore[ctr] != 0x20) { /* space character */ theShp = (ItemShpPtr) ((unsigned)StatScene +               (unsigned)StatScene->ItemDir[ctr+5].Where); /* MSD of score is item #5 */ theShp->ShpIA = num_tab[sscore[ctr] - 0x30]; }       else { theShp = (ItemShpPtr) ((unsigned)StatScene +               (unsigned)StatScene->ItemDir[ctr+5].Where); /* MSD of score is item #5 */ theShp->ShpIA = num_tab[0]; }   } }

/* * loose_ball - remove one of the stockpile of balls * * The ball item numbers are 0,1,2,3,4 * The storage box in top can display up to 5 balls. * The cannon still holds one even when the ball box is empty. * * return 'true' if all balls are gone */ static Boolean loose_ball { ItemShpPtr theShp;     /* shape item table */

if ( (Balls > 1) && (Balls < 7) ) { /* balls=1 means the ball box is already empty */ theShp = (ItemShpPtr) ((unsigned)StatScene + (unsigned)StatScene->ItemDir[Balls-2].Where); theShp->Gen.IActive = false; theShp->Gen.IDisplay = false; }   Balls--; if (!Balls) return(true); else return(false); }

/* * add_ball - add to the stockpile of balls * */ static void add_ball { ItemShpPtr theShp;     /* shape item table */

if (Balls <= ball_box_max) { /* six balls or greater means the ball box is full */ theShp = (ItemShpPtr) ((unsigned)StatScene + (unsigned)StatScene->ItemDir[Balls-1].Where); theShp->Gen.IActive = true; theShp->Gen.IDisplay = true; }   Balls++; }

buttons.c

 * 1) include 
 * 2) include 
 * 3) include 


 * 1) include "dbg.h"


 * 1) include "utility.h"
 * 2) include "screen.h"
 * 3) include "buttons.h"
 * 4) include "animation.h"
 * 5) include "reading.h"
 * 6) include "sentbld.h"

int        butline = ButTop * 2;       /* current scan line that button bitmap is linked to */ Boolean    PlayFlag;                   /* true means the play button is active/usable */ TOCPtr     butTOC;     /* the table of contents of the button package */ Ptr        butData;    /* where the image data starts */

static Rect buttRect = {0,0,70,383};   /* enclosing rectangle for button strip */ static Rect buttRect2 = {1,1,69,382};  /* enclosing rectangle for button strip */

/* * DrawButShps - draw the rectangles that hold the words and icons */ void DrawButShps { Ptr    butPtr;

butPtr = (Ptr) ((unsigned)butData + (unsigned)butTOC->TE[but1_shp].Where); Draw((ShapePtr)butPtr, 33, 7); butPtr = (Ptr) ((unsigned)butData + (unsigned)butTOC->TE[but2_shp].Where); Draw((ShapePtr)butPtr, 88, 7); butPtr = (Ptr) ((unsigned)butData + (unsigned)butTOC->TE[but3_shp].Where); Draw((ShapePtr)butPtr, 155, 7);

if (ModMod == ModBook) butPtr = (Ptr) ((unsigned)butData + (unsigned)butTOC->TE[but6_shp].Where); else butPtr = (Ptr) ((unsigned)butData + (unsigned)butTOC->TE[but4_shp].Where); Draw((ShapePtr)butPtr, 222, 7);

if ((ModMod == ModSent2u) || (ModMod == ModSent2d)) butPtr = (Ptr) ((unsigned)butData + (unsigned)butTOC->TE[but7_shp].Where); else butPtr = (Ptr) ((unsigned)butData + (unsigned)butTOC->TE[but5_shp].Where); Draw((ShapePtr)butPtr, 289, 7); }

/* * DrawButIcns - draw the icons on the button rectangles */ void DrawButIcns { Ptr    butPtr;

butPtr = (Ptr) ((unsigned)butData + (unsigned)butTOC->TE[huh_shp].Where); Draw((ShapePtr)butPtr, 53, 13); butPtr = (Ptr) ((unsigned)butData + (unsigned)butTOC->TE[lips_shp].Where); Draw((ShapePtr)butPtr, 100, 14); butPtr = (Ptr) ((unsigned)butData + (unsigned)butTOC->TE[text_shp].Where); Draw((ShapePtr)butPtr, 178, 13);

if ((ModMod == ModSent1) || (ModMod == ModBook) || (ModMod == ModBop)) { butPtr = (Ptr) ((unsigned)butData + (unsigned)butTOC->TE[left_shp].Where); Draw((ShapePtr)butPtr, 301, 15); }

if (ModMod == ModMain) { butPtr = (Ptr) ((unsigned)butData + (unsigned)butTOC->TE[bye_shp].Where); Draw((ShapePtr)butPtr, 310, 12); }

if ( ((ModMod == ModSent1) || (ModMod == ModSent2u) || (ModMod == ModSent2d))       && (PlayFlag)) { butPtr = (Ptr) ((unsigned)butData + (unsigned)butTOC->TE[tv_shp].Where); Draw((ShapePtr)butPtr, 239, 13); }

if (ModMod == ModBop) { /* same as above check */ butPtr = (Ptr) ((unsigned)butData + (unsigned)butTOC->TE[tv_shp].Where); Draw((ShapePtr)butPtr, 239, 13); } }

/* * DrawButWrds - draw the words on the button rectangles */ void DrawButWrds { Ptr    butPtr;

if (text == English) { butPtr = (Ptr) ((unsigned)butData + (unsigned)butTOC->TE[help_e_shp].Where); Draw((ShapePtr)butPtr, 45, 33); /* draw the button shape */

if (speech == Spanish) { butPtr = (Ptr) ((unsigned)butData + (unsigned)butTOC->TE[lang_se_shp].Where); Draw((ShapePtr)butPtr, 95, 33); /* draw the button shape */ }       else { butPtr = (Ptr) ((unsigned)butData + (unsigned)butTOC->TE[lang_ee_shp].Where); Draw((ShapePtr)butPtr, 96, 33); /* draw the button shape */ }

butPtr = (Ptr) ((unsigned)butData + (unsigned)butTOC->TE[lang_ee_shp].Where); Draw((ShapePtr)butPtr, 163, 33); /* draw the button shape */

if ((ModMod == ModSent1) || (ModMod == ModBook) || (ModMod == ModBop)) { butPtr = (Ptr) ((unsigned)butData + (unsigned)butTOC->TE[back_e_shp].Where); Draw((ShapePtr)butPtr, 306, 33); /* draw the button shape */ }

if (ModMod == ModMain) { butPtr = (Ptr) ((unsigned)butData + (unsigned)butTOC->TE[bye_e_shp].Where); Draw((ShapePtr)butPtr, 309, 33); /* draw the button shape */ }

if (((ModMod == ModSent1) || (ModMod == ModSent2u) || (ModMod == ModSent2d)) && (PlayFlag)) { butPtr = (Ptr) ((unsigned)butData + (unsigned)butTOC->TE[play_e_shp].Where); Draw((ShapePtr)butPtr, 240, 33); }

if (ModMod == ModBop) { /* same results as for above check */ butPtr = (Ptr) ((unsigned)butData + (unsigned)butTOC->TE[play_e_shp].Where); Draw((ShapePtr)butPtr, 240, 33); }   }    if(text == Spanish) { butPtr = (Ptr) ((unsigned)butData + (unsigned)butTOC->TE[help_s_shp].Where); Draw((ShapePtr)butPtr, 39, 33); /* draw the button shape */

if (speech == English) { butPtr = (Ptr) ((unsigned)butData + (unsigned)butTOC->TE[lang_es_shp].Where); Draw((ShapePtr)butPtr, 100, 33); /* draw the button shape */ }       else { butPtr = (Ptr) ((unsigned)butData + (unsigned)butTOC->TE[lang_ss_shp].Where); Draw((ShapePtr)butPtr, 94, 33); /* draw the button shape */ }

butPtr = (Ptr) ((unsigned)butData + (unsigned)butTOC->TE[lang_ss_shp].Where); Draw((ShapePtr)butPtr, 161, 33); /* draw the button shape */

if ((ModMod == ModSent1) || (ModMod == ModBook) || (ModMod == ModBop)) { butPtr = (Ptr) ((unsigned)butData + (unsigned)butTOC->TE[back_s_shp].Where); /* Draw((ShapePtr)butPtr, 294, 33); */ /* draw the button shape */ Draw((ShapePtr)butPtr, 303, 33); /* draw the button shape */ }

if (ModMod == ModMain) { butPtr = (Ptr) ((unsigned)butData + (unsigned)butTOC->TE[bye_s_shp].Where); Draw((ShapePtr)butPtr, 303, 34); }

if (((ModMod == ModSent1) || (ModMod == ModSent2u) || (ModMod == ModSent2d)) && (PlayFlag)) { butPtr = (Ptr) ((unsigned)butData + (unsigned)butTOC->TE[play_s_shp].Where); Draw((ShapePtr)butPtr, 229, 33); }

if (ModMod == ModBop) { butPtr = (Ptr) ((unsigned)butData + (unsigned)butTOC->TE[play_s_shp].Where); Draw((ShapePtr)butPtr, 229, 33); }   } }

/* * NewBut - redraw the rectangles, icons, words, but don't redo the fill */ void NewBut { Ptr    scnptrsav;

scnptrsav = scn_ptr; scn_ptr = vidmem4; DrawButShps; /* draw the rectangles */ DrawButIcns; /* draw the icons */ DrawButWrds; /* draw the words */ scn_ptr = scnptrsav; }

/* * MkSentBut - Make Sentence Builder Buttons */ void MkSentBut { Ptr    butPtr; Ptr    scnptrsav;

scnptrsav = scn_ptr; scn_ptr = vidmem4;

Fill(buttRect, FilCol); /* wipeout whatever used to be here */

DrawButShps; /* draw the rectangles */ DrawButIcns; /* draw the icons */ DrawButWrds; /* draw the words */

/*    * Draw the bottom shadow shape onto the button strip sub-screen. * Also draw the contents of the play button if this is screen 2. */   if (ModMod == ModSent1) { butPtr = mfxDir[getind("shadow1.shp")].Where; Draw((ShapePtr)butPtr, 33, 0); /* draw the two smaller shadows */ }   else { butPtr = (Ptr) ((unsigned)butData + (unsigned)butTOC->TE[shadow2_shp].Where); Draw((ShapePtr)butPtr, 33, 0); /* draw the huge box shadow */ LetPlay; /* draw the play button contents */ }   scn_ptr = scnptrsav;

/* * Link the 70 scan line button strip to the plane B LCT. */   dc_wrli(vidpath,lctid2,butline,0,cp_dadr((int)vidmem4)); }

/* * MkBopBut - Make Word Bop Buttons */ void MkBopBut { Ptr    scnptrsav;

scnptrsav = scn_ptr; scn_ptr = vidmem4;

Fill(buttRect, 15); /* black */ Fill(buttRect2, FilCol);

DrawButShps; /* draw the rectangles */ DrawButIcns; /* draw the icons */ DrawButWrds; /* draw the words */

scn_ptr = scnptrsav; /*    * Link the 70 scan line button strip to the plane B LCT. */   dc_wrli(vidpath,lctid2,butline,0,cp_dadr((int)vidmem4)); /*    * turn on the matte in plane A to let the buttons show through */   bop_but_matte_on; }

void NoBopBut {   /*     * Unlink the 70 scan line button strip to the plane B LCT. */   dc_wrli(vidpath,lctid2,butline,0,cp_nop); /*    * turn off the matte in plane A     */ bop_but_matte_off; }

/* * MkMainBut - Make Main Menu Buttons *     When this is called, plane A is being shown so we can *     do whatever we want here. */ void MkMainBut { Ptr    butPtr; Ptr    scnptrsav;

scnptrsav = scn_ptr; scn_ptr = vidmem4; /*    * Draw the button strip background for the living room */   butPtr = mfxDir[getind("buttonblock.shp")].Where; Draw((ShapePtr)butPtr, 0, 0); /* draw the button shape */

DrawButShps; /* draw the rectangles */ DrawButIcns; /* draw the icons */ DrawButWrds; /* draw the words */

scn_ptr = scnptrsav; /*    * Link the 70 scan line button strip to the plane B LCT. */   dc_wrli(vidpath,lctid2,butline,0,cp_dadr((int)vidmem4)); }

/* * MkBookBut - Make Word Book Buttons *     When this is called, plane A is being shown so we can *     do whatever we want here. */ void MkBookBut { Ptr    butPtr; Ptr    scnptrsav;

scnptrsav = scn_ptr; scn_ptr = vidmem4;

Fill(buttRect, FilCol); /* wipeout whatever used to be here */

DrawButShps; /* draw the rectangles */ DrawButIcns; /* draw the icons */ DrawButWrds; /* draw the words */

butPtr = (Ptr) ((unsigned)butData + (unsigned)butTOC->TE[shadow2_shp].Where); Draw((ShapePtr)butPtr, 33, 0); /* draw the huge box shadow */

scn_ptr = scnptrsav; /* * Link the 70 scan line button strip to the plane B LCT. */   dc_wrli(vidpath,lctid2,butline,0,cp_dadr((int)vidmem4)); }

/* * LetPlay - draws the icon and text for the play button */ void LetPlay { Ptr        butPtr; Ptr        scnptrsav;

scnptrsav = scn_ptr; scn_ptr = vidmem4; butPtr = (Ptr) ((unsigned)butData + (unsigned)butTOC->TE[tv_shp].Where); Draw((ShapePtr)butPtr, 239, 13); if(text == English) { butPtr = (Ptr) ((unsigned)butData + (unsigned)butTOC->TE[play_e_shp].Where); Draw((ShapePtr)butPtr, 240, 33); }   if(text == Spanish) { butPtr = (Ptr) ((unsigned)butData + (unsigned)butTOC->TE[play_s_shp].Where); Draw((ShapePtr)butPtr, 229, 33); }   scn_ptr = scnptrsav; PlayFlag = true; }

/* * MoveBut - pass this 'false' to move the buttin strip up *          pass it 'true' to move the button strip down * * When this gets called we either have the scroll mask active * or we have a real time file frame present in plane A. * This code changes the values of either the matte or the transparent * area of the plane A rtf frame. */ void MoveBut(butdir) Boolean butdir; { Boolean    butflg = true; int        stat;

while (butflg) { swapflag = false;  /*  scan line interrupt will set to allow next frame */

if ((stat = dc_ssig(vidpath,SLI_SIGNAL,0)) == -1) { STATUS2("couldn't set SLI in MoveBut. error number %d\n", errno); }

/* STATUS1("Waiting\n"); */ while (!swapflag); /* STATUS1("Got\n"); */

if (butdir) {  /* true means going down */ if (butline == ButBot * 2) butflg = false; /* we're finished, reset butflg */ else { butline += 2; dc_wrli(vidpath,lctid2,butline,0,cp_dadr((int)vidmem4)); dc_wrli(vidpath,lctid2,butline-2,0,cp_nop); if (useRTF) { /* adjust the transparency line of plane A */ dc_wrli(vidpath,lctid0,butline,0,cp_matte(0,MO_RES,MF_MF0,ICF_MIN,0)); dc_wrli(vidpath,lctid0,butline-2,0,cp_nop); }               else { /* adjust the scrolling mask to the new button line */ dc_wrli(vidpath,lctid0,butline,0,cp_matte (0, MO_RES, MF_MF0, ICF_MIN, 0)); dc_wrli(vidpath,lctid0,butline,1,cp_matte (1, MO_END, MF_MF0, ICF_MIN, 0)); dc_wrli(vidpath,lctid0,butline-2,0,cp_nop); dc_wrli(vidpath,lctid0,butline-2,1,cp_nop); }           }        }        else {  /* button strip moving up */ if (butline == ButTop * 2) butflg = false; else { butline -= 2; dc_wrli(vidpath,lctid2,butline,0,cp_dadr((int)vidmem4)); dc_wrli(vidpath,lctid2,butline+2,0,cp_nop); if (useRTF) { /* adjust the transparency line of plane A */ dc_wrli(vidpath,lctid0,butline,0,cp_matte(0,MO_RES,MF_MF0,ICF_MIN,0*2)); dc_wrli(vidpath,lctid0,butline+2,0,cp_nop); }               else { /* adjust the scrolling mask to the new button line */ dc_wrli(vidpath,lctid0,butline,0,cp_matte (0, MO_RES, MF_MF0, ICF_MIN, 0)); dc_wrli(vidpath,lctid0,butline,1,cp_matte (1, MO_END, MF_MF0, ICF_MIN, 0)); dc_wrli(vidpath,lctid0,butline+2,0,cp_nop); dc_wrli(vidpath,lctid0,butline+2,1,cp_nop); }           }        }    } }

/* * NoButs - this unlinks the button bitmap from the main screen */ void NoButs {   dc_wrli(vidpath,lctid2,butline,0,cp_nop); }

cursor_mgr.c
/****************************************************************************
 * FILENAME:  cursor_mgr.c
 * PROJECT:   Sticky Bear Reading
 * PURPOSE:   Fully localize utility for managing the cursor through signals
 * FUNCTIONS: Update_Coord
 * Get_Coord
 * Get_Button
 * Set_Coord
 * cursor_mgr
 * AUTHOR:    Douglas Yoon
 * DATE:      June 29, 1992
 * LOCATION:  Philips Interactive Media of America, DC office
 * REVISED:   6/29/92 Version 1
 * REVISED:   6/30/92 Version 1.01 dgc Added call to pt_coord when
 * case is CM_BUTTON in cursor_mgr
 * REVISED:   9/22/92 Version 1.02 dcc/dgc Limit cursor to safe area
 * Handle PAL
 * REVISED:   10/2/92 Version 1.03 dcc/dgc Added cursor hold/release


 * 1) include "dbg.h"
 * 2) include "cursor_mgr.h"
 * 3) include "screen.h"
 * 4) include "utility.h"

static int gCurX; static int gCurY;

/**********************************/ /* This function should be only */ /* be called from a signal handler. */ /* It will call on the cursor */ /* manager to update its local */ /* variables */ /**********************************/ void Update_Coord {   int butn; int x_c; int y_c;

cursor_mgr (&x_c, &y_c, &butn, CM_UPDATE); }

/**********************************/ /* This function will return */ /* what is believes to be */ /* the current cursor position */ /**********************************/ void Get_Coord (x_c, y_c) int *x_c; int *y_c; {   int butn;

cursor_mgr (x_c, y_c, &butn, CM_COORD); if (PALflag) *y_c -= 40; }

/**********************************/ /* This function will return the */ /* button state as specified by the */ /* Green Book */ /**********************************/ void Get_Buttons (butn) int *butn; {   int x_c; int y_c;

cursor_mgr (&x_c, &y_c, butn, CM_BUTTON); }

/**********************************/ /* Will send a message to the cursor */ /* manager to move the cursor to */ /* a specific spot */ /**********************************/ void Set_Coord (x, y) int x;             /* these can not be passed directly since */ int y;             /* they are registers !!! */ {   int butn; int x_c; int y_c;

x_c = x;   y_c = y;

cursor_mgr (&x_c, &y_c, &butn, CM_MOVE); }

/**********************************/ /* Will send a message to the cursor */ /* manager to freeze the cursor */ /**********************************/ void Cursor_Freeze {   int butn; int x_c; int y_c;

cursor_mgr (&x_c, &y_c, &butn, CM_FREEZE); }

/**********************************/ /* Will send a message to the cursor */ /* manager to release the cursor */ /**********************************/ void Cursor_Melt {   int butn; int x_c; int y_c;

cursor_mgr (&x_c, &y_c, &butn, CM_MELT); }

/**********************************/ /* The cursor manager proper !!! */ /**********************************/ void cursor_mgr (x_c, y_c, butn, context) int *butn; int *x_c; int *y_c; int context; {   static int button = 0;              /* local "global" variables */ static int x_coord = 0;            /* to keep track of the cursor */ static int y_coord = 0;            /* and the button states */

switch (context) {       case CM_UPDATE:                 /* find out from the system, where the */ pt_coord (vidpath, &button, &x_coord, &y_coord); /* cursor currently */

{               short reset;

reset = 0;

if (x_coord > safe_rect.right) x_coord = reset = safe_rect.right; if (x_coord < safe_rect.left) x_coord = reset = safe_rect.left; if (y_coord > safe_rect.bottom) y_coord = reset = safe_rect.bottom; if (y_coord < safe_rect.top) y_coord = reset = safe_rect.top; if ( reset ) pt_pos (vidpath, x_coord, y_coord); }

gc_pos (vidpath, x_coord, y_coord);            /* exists */ break;

case CM_COORD:                 /* return the x,y coordinates */ *x_c = x_coord; *y_c = y_coord; break;

case CM_BUTTON:                /* return the buttons' states */ pt_coord (vidpath, &button, &x_coord, &y_coord); /* cursor currently */ *butn = button; break;

case CM_MOVE:                  /* move the cursor and graphic */ x_coord = *x_c; y_coord = *y_c; pt_pos (vidpath, x_coord, y_coord); /* REEEAL EXPENSIVE CALL!!! */           gc_pos (vidpath, x_coord, y_coord); break;

case CM_FREEZE:                /* freeze the cursor */ pt_rel (vidpath); pt_coord (vidpath, &button, &x_coord, &y_coord); /* cursor currently */ gCurX = x_coord; gCurY = y_coord; break;

case CM_MELT:                  /* start accepting cursor input again */ pt_pos (vidpath, gCurX, gCurY); /* start from where we froze */ pt_ssig (vidpath, PTR_SIGNAL); break;

} }

file_mgr.c

 * 1) include 
 * 2) include 
 * 3) include 
 * 4) include 
 * 5) include <csd.h>


 * 1) include "dbg.h"


 * 1) include "my_types.h"
 * 2) include "file_mgr.h"
 * 3) include "rtf.h"
 * 4) include "screen.h"
 * 5) include "sound.h"
 * 6) include "reading.h"

short              eor_ctr; short              trigger_ctr; Boolean            play_error; static short       gCurDataDir = 0;

/* * open_file - opens a file and returns the ID * * Pass    -   char *filename, Boolean just_say_no (true = return error, false = quit program) * * Returns -   int FID */ int open_file(name, just_say_no) char *name; Boolean just_say_no; { int    fid;

if ((fid = open(name,S_IREAD)) == -1) { STATUS3("Can't open %s. Error Number %d\n", name, errno); if ((fid = open(name,S_IREAD)) == -1) { STATUS3("Can't open %s on second try. Error Number %d\n", name, errno); if (just_say_no) return(-1); else DoDirtyDisc; }   }    return(fid); }

/* * play_recs - play record(s) of a real time file * * Pass    -   int         - file ID *              (*func)   - function pointer to setup routine (sets up PCB) *             short       - # records to play *             Boolean     - async - exit after starting play *             Boolean     - abortable *             short       - # triggers required before abort allowed * * Returns -   Boolean     - true if file was aborted before completion */ Boolean play_recs(fid, setup, recs, async, abortable, trigs) int    fid; void   (*setup) ; short  recs; Boolean async; Boolean abortable; short  trigs; { int        stat; Boolean    early = false; /* gets set if abort happens */ int        ctr; Boolean    retry;

if (setup) setup;       /* set up the PCB for this play */ trigger_ctr = trigs; /* if file is interruptable, we need this many triggers first */

play_error = false; /* the signal handler might set this */ thePCB->PCB_Rec = recs; eor_ctr = recs; ss_play(fid,thePCB);

if (async) return(false); /* return once the play has been started */

while (eor_ctr) { if (abortable) { Get_Buttons(&stat); /*            * trigger_ctr gets decremented for each trigger received during the RTF play. */           if ((stat & 0x03) && (!trigger_ctr) && (!early)) { ss_abort(fid); early = true; }       }    }    if (play_error) { STATUS2("Had trouble playing file. Error Number %d\n", errno); close_file(fid); DoDirtyDisc; }   if (!abortable) { /* if this was a data load without an av rtf, check the pcls for error */ retry = false; for (ctr=0; ctr<recs; ctr++) { if (pcl_tab[ctr]->PCL_Ctrl & 0x80) { STATUS2("pcl_tab[%d]->PCL_Ctrl is in trouble\n", ctr); retry = true; }       }        if (retry) { for (ctr=0; ctr<recs; ctr++) { pcl_tab[ctr]->PCL_Ctrl = 0; pcl_tab[ctr]->PCL_Cnt = 0; }           thePCB->PCB_Rec = recs; eor_ctr = recs; ss_play(fid,thePCB); while (eor_ctr);
 * 1) if 0

retry = false; for (ctr=0; ctr<recs; ctr++) { if (pcl_tab[ctr]->PCL_Ctrl & 0x80) { STATUS2("pcl_tab[%d]->PCL_Ctrl is in trouble on second try\n", ctr); retry = true; }           }            if (retry) close_file(fid); DoDirtyDisc; }   }    return(early); }
 * 1) endif

/* * close_file - closes a file * * Pass    -   int - file ID * * Returns -   true if error occured */ Boolean close_file(fid) int fid; { int    stat;

if ((stat = close(fid)) == -1) { STATUS2("Can't close file. Error Number %d\n", errno); return(true); }   return(false); }

/* * try_next_dir - if it can't, this goes to the dirty disc code and never comes back */ int try_next_dir {   if (gCurDataDir < 2) { STATUS1("Will try next data directory\n"); unset_files(ModMod);   /* close all open files related to current module */ SetDataDir(TRUE);      /* advance to next data dir */ set_files(ModMod);     /* open them all in the new data dir */ }   else { DoDirtyDisc; }   return(0); }
 * 1) if 0
 * 1) endif

/* * if n is TRUE then SetDataDir advances to the next data directory. * if n is FALSE it merely sets the current data dir. */ int SetDataDir(n) short n; { char   p[32]; char   *cd_dev; char   *dir1 = "DATA1"; char   *dir2 = "DATA2";
 * 1) if 0

STATUS1("SetDataDir: Enter\n");

play_error = false; /* reset this */

if ( n ) { gCurDataDir += 1; if ( gCurDataDir > 2 ) { DoDirtyDisc; /* we don't come back here */ }   }

if ( (cd_dev = csd_devname( DT_CDPLAY, 1 )) == NULL ) { STATUS1("can't get name of CD player\n"); return (1); }

strcpy(p, cd_dev); if (gCurDataDir == 1) strcpy(p, dir1); if (gCurDataDir == 2) strcpy(p, dir2);

if ( chdir(p) == -1 ) { STATUS1("***** Could not set data directory *****\n"); DoDirtyDisc; /* we don't come back here */ }

free( cd_dev );        /* Give back memory for csd stuff */

STATUS1("SetDataDir: Exit\n");

return(0); }
 * 1) endif

void DoDirtyDisc { int        dirty_fid; Boolean    stat; int        but_stat;

dirty_fid = open_file("dirty.rtf", true); if (dirty_fid == -1) { STATUS1("can't open dirty disc rtf\n"); exit(0); }   stat = play_recs(dirty_fid, reinit_rtf, 1, false, false, 0); /* play first frame/record */ *(short *)vidmem0 = 0x8F00; DslvBA(fastdisolve); /* show plane A */ stat = play_recs(dirty_fid, reinit_rtf, 1, false, true, 0); /* play rest of file */ stat = close_file(dirty_fid);

Get_Buttons(&but_stat); while (!(but_stat & 0x03)) { Get_Buttons(&but_stat); }   exit(0); }

reading.c

 * 1) include <stdio.h>
 * 2) include <errno.h>
 * 3) include <modes.h>
 * 4) include <rtr.h>
 * 5) include <aimdef.h>
 * 6) include <memory.h>
 * 7) include <time.h>
 * 8) include <module.h>
 * 9) include <ucm.h>
 * 10) include <csd.h>
 * 11) include <cdfm.h>
 * 12) include <bumper.h>


 * 1) include "dbg.h"


 * 1) include "utility.h"
 * 2) include "startup.h"
 * 3) include "screen.h"
 * 4) include "rtf.h"
 * 5) include "sound.h"
 * 6) include "buttons.h"
 * 7) include "wordbook.h"
 * 8) include "sentbld.h"
 * 9) include "bop.h"
 * 10) include "file_mgr.h"

/* * These are the rectangle tables for each section of SB Reading */ static RectList LVRect = { 7,   177, 33,218, 82,    /* help button */ 177, 88,218,149,   /* speech button */ 177,155,218,216,   /* text button */ 177,289,218,350,   /* go back button */ 17, 33,163,112,   /* bear #1 - Sara */ 19,117,154,187,   /* bear #2 - Bedford */ 72,235,170,321    /* bear #3 - Bumper */ };

short      ModMod; /* holds the index for the current program mode/module */ Ptr        PkgBuf;     /* This is the new buffer that holds the data for current module */ Ptr        ButtonBuf;  /* This holds the button images */ /* These are for Sentence Builder */ Ptr        ScreenBuf;  /* screen images */ Ptr        RezBuf;     /* resedit data */ Ptr        Seq1Buf;    /* seq 1 */ Ptr        Seq2Buf;    /* seq 2 */ Ptr        BkgdBuf;    /* background image */

TOCPtr     pkgTOC;     /* pointer to the table of contents for current package */ int        last_xpos; int        last_ypos; unsigned long  currentT;   /* current tick count */ unsigned long  HelpTime;   /* clk count for when to do help */ unsigned long  DimTime;    /* clk count for when to dim screen */

int        BUTTONfid;  /* file ID for button audio real time file */ int        BEARfid;    /* file ID for bear speech of current module */ int        TUNEfid;    /* file ID for bkgd music of current module */ int        Eng_bear_fid; int        Span_bear_fid; int        Eng_button_fid; int        Span_button_fid;

int        Tune1ID;    /* 1st file of bkgd tunes (all for word book) */ int        Tune2ID;    /* 2nd file of bkgd tunes (last 4 for word book) */ int        Tune3ID;    /* 1st file of sentence builder bkgd tunes */ int        Tune4ID;    /* 2nd file of sentence builder bkgd tunes */ int        Tune5ID;    /* 3rd file of sentence builder bkgd tunes */

short      speech = English; short      text = English;

static Boolean     BearFlag[3]; static short       BearTalk[3]; /* 0=bear hasn't spoken, 1=has, 2=currently is talking */ static ItemSeqPtr  MMSeq; static ScenePtr    MMScene; static short       DirSaveMM; static Boolean     SB_shuf = false; static Boolean     Sara_shuf = false; static Boolean     Bump_shuf = false;


 * 1) ifdef WANT_STATUS
 * 2) define BUMPER_MEMORY_COLOR SYSRAM
 * 3) define TITLE_MEMORY_COLOR SYSRAM
 * 4) else
 * 5) define BUMPER_MEMORY_COLOR VIDEO1
 * 6) define TITLE_MEMORY_COLOR VIDEO2
 * 7) endif
 * 8) define BUMP_ARGNUM    2       /* Max number of bumper cmd line args */
 * 9) define BUMPER_PATH_NUM 5      /* Number of open paths to pass */

char   *bumpargblk[BUMP_ARGNUM] = {"cdi_bumper", 0}; char   *bumpdata = "cdi_bumpdata";

extern int os9forkc; extern char **environ;

/* * This is the main code for Stickybear Reading */ void main(argc,argv) int argc; char *argv[]; { int        fid; int        stat; Boolean    playstat; STAT_BLK   seekstat; int        bumper_status; mod_exec   *datmod, *modlink, *modcload; BUMPER_DATA *bumpmod; char       *vid_dev,*csd_devname;

intercept(signal_handler); /* hook up our signal handler */ setup_audio;             /* open a path to the audio device */

/*    * get the bumper data module into memory */   if ( (int)(datmod = modcload( bumpargblk[0], 0, VIDEO1 )) == SYSERR ) exit( errno ); if ( (int)(datmod = modlink( bumpdata, MT_ANY )) == SYSERR ) exit( errno ); /*    * Point to the actual data section of the module */   bumpmod = (BUMPER_DATA *)((char *)datmod + ((DATA_MODULE *)datmod)->data_offset);

if ( (vid_dev = csd_devname( DT_VIDEO, 1 ) ) == NULL ) exit( SYSERR );

/*    * copy the video device name to the bumper data module */   strcpy( bumpmod->vid_name, vid_dev );

/*    * Open path to video device */   if ( (vidpath = open( vid_dev, (S_IREAD | S_IWRITE) )) == SYSERR ) exit( SYSERR ); free( vid_dev );           /* Release memory returned by func */ /*    * Set compat bit and PAL flag */   if ( set_comp_mode( vidpath, &PALflag ) == SYSERR ) exit( errno ); /*    * Create the DCP, shut down the planes, execute DCP */   fctid_RL7 = dc_crfct(vidpath,PA,150,RES_NORMAL);    /* our clut7 in plane A */ fctid_Clut7 = dc_crfct(vidpath,PB,140,RES_NORMAL); /* rl7 in plane B */ lctid0 = dc_crlct(vidpath,PA,240*2,RES_NORMAL); /* used for RL7 screens */ lctid2 = dc_crlct(vidpath,PB,240*2,RES_NORMAL); /* used for clut7 screens */ dc_flnk( vidpath, fctid_RL7, lctid0, 0 ); dc_flnk( vidpath, fctid_Clut7, lctid2, 0 ); dc_wrfi( vidpath, fctid_RL7, FCT_ICF, cp_icf(PA, ICF_MIN) ); dc_wrfi( vidpath, fctid_Clut7, FCT_ICF, cp_icf(PB, ICF_MIN) ); dc_exec( vidpath, fctid_RL7, fctid_Clut7 );

/*    * Init the rest of the data module */   bumpmod->dcp.fcta = fctid_RL7; bumpmod->dcp.fctb = fctid_Clut7; bumpmod->dcp.lcta = lctid0; bumpmod->dcp.lctb = lctid2; bumpmod->lct_height = MIN_BUMP_LCTHEIGHT; bumpmod->pal_flag = PALflag; bumpmod->pcb = NULL; bumpmod->data_sector = 0; bumpmod->app_pa_buf = NULL; bumpmod->app_pb_buf = NULL;

/*    * fixes for the new bumper */   dc_llnk( vidpath, lctid0, (240 * 2 ) -2, lctid0, (240 * 2 ) -2); dc_llnk( vidpath, lctid2, (240 * 2 ) -2, lctid2, (240 * 2 ) -2);

/*    * Fork the Bumper */   if ( os9exec( os9forkc, bumpargblk[0], bumpargblk, environ, 0, 0, BUMPER_PATH_NUM ) == SYSERR ) exit( errno );

wait( &bumper_status ); /*    * Check return status from bumper */   if ( bumpmod->return_status != BE_HUNKY ) { if ( bumpmod->return_status == BE_INTERRUPT ) { STATUS1("Bumper was interrupted by the user.\n"); }       else { STATUS2("loader:Bumper returns error 0x%x\n", bumpmod->return_status ); exit(errno); }   }    stat = munload( bumpdata, MT_ANY ); if (stat == -1) { STATUS2("****couldn't unload bumpdata. error numer 0x%x\n", errno); }

if (PALflag) { safe_rect.top += 40; safe_rect.bottom += 40; }

/* SetDataDir(TRUE); */

setup_CDI; setup_rtf;

dc_exec(vidpath,fctid_RL7,fctid_Clut7);

pt_ssig(vidpath,PTR_SIGNAL);

/*    * initialize cursor delay time */   cursorTime = currentT + cursor_delay;

set_module(ModMain); /*    * play the intro real time file */   fid = open_file("intro.rtf", false); playstat = play_recs(fid, reinit_rtf, 3, false, false, 0); /* play first frame and data */ dc_wrfi(vidpath,fctid_RL7,2,cp_icf(PA,ICF_MAX)); /* bring up plane A */ playstat = play_recs(fid, reinit_rtf, 1, false, true, 0); /* play rest of file */ playstat = close_file(fid); /*    * The opening rtf loaded the button package. * Set a pointer to the image data section of the package. */   butData = ButtonBuf + ((*(short *)ButtonBuf) * 40 + 4);

MainMenu; /*    * Quit the program - make the bears say goodbye */   MakeBearLook(Bedford); MakeBearLook(Bumper); MakeBearLook(Sara); Step; start_bkgd_audio(14, BEARfid, false); /* say goodbye */ while (eor_ctr) { Get_Buttons(&stat); if (stat & 0x03) { ss_abort(BEARfid); eor_ctr = 0; }   }    stop_all_audio; /*    * Play closing real time file and exit. *    * Read in the first frame of the real * time file and display it in plane A.    */ cursor_hide;

/*    * play the exit real time file */   fid = open_file("exit.rtf", false); stat = play_recs(fid, reinit_rtf, 1, false, false, 0); /* play first frame/record */ *(short *)vidmem0 = 0x8F00; DslvBA(fastdisolve); /* show plane A */ stat = play_recs(fid, reinit_rtf, 1, false, true, 0); /* play rest of file */ if (stat) { /* file was aborted */ seekstat.asy_sig = 0; seekstat.asy_stat = 0; /* book says not to mess with this ? */       ss_seek(fid, 4368 * FORM1_SECTOR, &seekstat); while (!(seekstat.asy_stat & 1)); /* wait for done bit */ if (seekstat.asy_stat & 0x8000) { STATUS2("Error %d occured during seek\n",seekstat.asy_sig); STATUS2("asy_sig = 0x%x\n",seekstat.asy_sig); STATUS2("asy_stat = 0x%x\n",seekstat.asy_stat); }       else { stat = play_recs(fid, reinit_rtf, 1, false, false, 0); }       close_file(fid); }   FadeDown(slowdisolve);

/*    * exit_program - give back memory and stuff. */   close_file(Eng_bear_fid); close_file(Span_bear_fid); close_file(Eng_button_fid); close_file(Span_button_fid);

dc_dlfct(vidpath,fctid_RL7); dc_dlfct(vidpath,fctid_Clut7); dc_dllct(vidpath,lctid0); dc_dllct(vidpath,lctid2); if (PALflag) { dc_dllct(vidpath,lct_pal_a); dc_dllct(vidpath,lct_pal_b); }   close(vidpath); DEALLOCATE(RL7Size * FORM2_SECTOR, vidmem0); DEALLOCATE(RL7Size * FORM2_SECTOR, vidmem1); DEALLOCATE(384 * 240, vidmem2); DEALLOCATE(384 * 240, vidmem3); DEALLOCATE(384 * 70, vidmem4); DEALLOCATE(384 * 240, vidmem5); DEALLOCATE(FORM1_SECTOR * MMPkgSecs, PkgBuf);

DEALLOCATE(FORM1_SECTOR * ButtonBufSize, ButtonBuf);

close_snd_stuff; close_rtf_stuff;

exit(0); }

/* * Main menu - This displays the livingroom and waits for a button press */ void   MainMenu { Boolean    done; int        fid; Boolean    stat;

setup_MM;            /* set up the main menu */

DslvAB(fastdisolve);

MakeBearLook(Bedford); Step; start_bkgd_audio(3, BEARfid, false); /* pass channel number */ while (eor_ctr) { CheckInput; if (theInpTab.ButPress) { stop_all_audio; eor_ctr = 0; }   }    MakeBearCycle(Bedford);

start_bkgd_audio(MMMusic, BEARfid, true); /* pass channel number */

Set_Coord (230,100); cursor_show;         /* display the cursor */ last_xpos = inp_xpos;  /* xpos of input device */ last_ypos = inp_ypos;  /* ypos of input device */ done = false; while (done == false) {

update_audio; chk_help(6, BEARfid, MMMusic, BEARfid); chk_dim; /* if it's time to dim, this won't return until undim */

CheckInput; /* This has to highlite places we are over as well */ switch (theInpTab.HotIndex) { case 0: /* HELP button */ if (theInpTab.ButPress) { stop_all_audio; start_bkgd_audio(7, BEARfid, false); /* pass channel number */ CheckInput; while ((eor_ctr) && (theInpTab.HotIndex == 0) && (!theInpTab.ButPress)) CheckInput; stop_all_audio; start_bkgd_audio(MMMusic, BEARfid, true); }               break; case 1: /* SPEECH button */ if (theInpTab.ButPress) { Cursor_Freeze; stop_all_audio; start_bkgd_audio(0, BUTTONfid, false); /* pass channel number */ changeSpch; while (eor_ctr); stop_all_audio; set_bear_voice; set_button_voice; start_bkgd_audio(MMMusic, BEARfid, true); Cursor_Melt; }               break; case 2: /* TEXT button */ if (theInpTab.ButPress) { Cursor_Freeze; stop_all_audio; if (text == English) start_bkgd_audio(3, BUTTONfid, false); /* pass channel number */ if (text == Spanish) start_bkgd_audio(1, BUTTONfid, false); /* pass channel number */ changeText; while (eor_ctr); stop_all_audio; start_bkgd_audio(MMMusic, BEARfid, true); Cursor_Melt; }               break; case 3: /* EXIT button */ if (theInpTab.ButPress) { Cursor_Freeze; stop_all_audio; start_bkgd_audio(2, BUTTONfid, false); /* pass channel number */ while (theInpTab.ButPress) CheckInput;  /* wait for button release */ while ((!theInpTab.ButPress) && (theInpTab.HotIndex == 3)) CheckInput; /* wait for button press or cursor move away */ stop_all_audio; if (theInpTab.ButPress) /* they chose to exit */ done = true; else   /* they moved the cursor off the exit button */ start_bkgd_audio(MMMusic, BEARfid, true); Cursor_Melt; }               break;

case 4: /* Sara */ if ((last_xpos == inp_xpos) && (last_ypos == inp_ypos)) { /* if cursor paused */ Cursor_Freeze; stop_all_audio; MakeBearLook(Sara); if (BearTalk[Sara] == 0) start_bkgd_audio(11, BEARfid, false); /* channel 11 = Sara's 1st words */ else start_bkgd_audio(12, BEARfid, false); /* channel 12 = Sara's 2nd words */ BearTalk[Sara] = 2; /* Sara is talking */ Cursor_Melt; while ((theInpTab.HotIndex == 4) && (!theInpTab.ButPress)) { CheckInput; last_xpos = inp_xpos;  /* xpos of input device */ last_ypos = inp_ypos;  /* ypos of input device */ chk_help(6, BEARfid, MMMusic, BEARfid); chk_dim; /* if it's time to dim, this won't return until undim */

if (BearTalk[Sara] == 1) update_audio;

if ((!eor_ctr) && (BearTalk[Sara] == 2)) { stop_all_audio; BearTalk[Sara] = 1; /* Sara has spoken, but is finished */ MakeBearCycle(Sara); start_bkgd_audio(MMMusic, BEARfid, true); }                   }

if (theInpTab.ButPress) { stop_all_audio; if (BearTalk[Sara] != 2) { MakeBearLook(Sara); /* if she wasn't looking */ Step; }                       start_bkgd_audio(13, BEARfid, false); /* channel 13 = Sara's OK */ while (eor_ctr); stop_all_audio; BearTalk[Sara] = 1; /* Sara has spoken, but is finished */ MakeBearCycle(Sara);

unset_module(ModMain); set_module(ModBook);

cursor_hide;

if (!Sara_shuf) { get_random_seed; shufshort(wbstab, NumPages);   /* shuffle the wordbook scenes */ Sara_shuf = true; }

/*                        * play the wordbook intro real time file */                       fid = open_file("wdbk.rtf", false); stat = play_recs(fid, reinit_rtf, 1, false, false, 0); *(short *)vidmem0 = 0x8F00; DslvBA(meddisolve); /* show plane A */ stat = play_recs(fid, reinit_rtf, 1, false, true, 0); /* play rest of file */ stat = close_file(fid);

DirNum = DirSaveMM; /* restore first */ WordBook; /* go to the game */ DirNum = DirSaveMM;

unset_module(ModBook); set_module(ModMain);

loadpkg("lv.com", PkgBuf);

FadeDown(fastdisolve); setup_MM; PAFlag = false; /* don't bring up plane A */ FadeUp(meddisolve, true); start_bkgd_audio(MMMusic, BEARfid, true); }                   else { Cursor_Freeze; if (BearTalk[Sara] == 2) { stop_all_audio; BearTalk[Sara] = 1; /* Sara has spoken */ MakeBearCycle(Sara); start_bkgd_audio(MMMusic, BEARfid, true); }                       Cursor_Melt; }               }                break;

case 5: /* Bedford */ if ((last_xpos == inp_xpos) && (last_ypos == inp_ypos)) { Cursor_Freeze; stop_all_audio; MakeBearLook(Bedford); start_bkgd_audio(4, BEARfid, false); /* channel 4 = Bedford's 1st and 2nd words */ BearTalk[Bedford] = 2; Cursor_Melt; while ((theInpTab.HotIndex == 5) && (!theInpTab.ButPress)) { CheckInput; last_xpos = inp_xpos;  /* xpos of input device */ last_ypos = inp_ypos;  /* ypos of input device */ chk_help(6, BEARfid, MMMusic, BEARfid); chk_dim; /* if it's time to dim, this won't return until undim */

if (BearTalk[Bedford] == 1) update_audio;

if ((!eor_ctr) && (BearTalk[Bedford] == 2)) { stop_all_audio; BearTalk[Bedford] = 1; /* Bedford has spoken, but is finished */ MakeBearCycle(Bedford); start_bkgd_audio(MMMusic, BEARfid, true); }                   }                    if (theInpTab.ButPress) { stop_all_audio; if (BearTalk[Bedford] != 2) { MakeBearLook(Bedford); Step; }                       start_bkgd_audio(5, BEARfid, false); /* channel 5 = Bedford's OK */ while (eor_ctr); stop_all_audio; BearTalk[Bedford] = 1; /* Bedford has spoken, but is finished */ MakeBearCycle(Bedford);

unset_module(ModMain); set_module(ModSent1);

cursor_hide; if (!SB_shuf) { get_random_seed; shufshort(sbptab, NumSBPkgs);  /* shuffle the sentence builder packages */ sbpctr = getran(NumSBPkgs -1); /* initial seed value for sentence builder packages */ SB_shuf = true; }                       /*                         * play the sentence builder intro real time file */                       fid = open_file("sent.rtf", false); stat = play_recs(fid, reinit_rtf, 2, false, false, 0); *(short *)vidmem0 = 0x8F00; DslvBA(meddisolve); /* show plane A */ stat = play_recs(fid, reinit_rtf, 1, false, true, 0); /* play rest of file */ stat = close_file(fid);
 * 1) ifndef WANT_SRCDBG
 * 1) endif

DirNum = DirSaveMM; /* restore first */ SentBld; /* go to the game */ DirNum = DirSaveMM;

unset_module(ModSent1); set_module(ModMain);

loadpkg("lv.com", PkgBuf);

FadeDown(fastdisolve); setup_MM; PAFlag = false; /* don't bring up plane A */ FadeUp(meddisolve, true); start_bkgd_audio(MMMusic, BEARfid, true); }                   else { Cursor_Freeze; if (BearTalk[Bedford] == 2) { stop_all_audio; BearTalk[Bedford] = 1; /* Bedford has spoken, and is finished */ MakeBearCycle(Bedford); start_bkgd_audio(MMMusic, BEARfid, true); }                       Cursor_Melt; }               }                break;

case 6: /* Bumper */ if ((last_xpos == inp_xpos) && (last_ypos == inp_ypos)) { Cursor_Freeze; stop_all_audio; MakeBearLook(Bumper); if (BearTalk[Bumper] == 0) start_bkgd_audio(8, BEARfid, false); /* channel 8 = Bumper's 1st words */ else start_bkgd_audio(9, BEARfid, false); /* channel 9 = Bumper's 2nd words */ BearTalk[Bumper] = 2; Cursor_Melt; while ((theInpTab.HotIndex == 6) && (!theInpTab.ButPress)) { CheckInput; last_xpos = inp_xpos;  /* xpos of input device */ last_ypos = inp_ypos;  /* ypos of input device */ chk_help(6, BEARfid, MMMusic, BEARfid); chk_dim; /* if it's time to dim, this won't return until undim */

if (BearTalk[Bumper] == 1) update_audio;

if ((!eor_ctr) && (BearTalk[Bumper] == 2)) { stop_all_audio; BearTalk[Bumper] = 1; /* Bumper has spoken, but is finished */ MakeBearCycle(Bumper); start_bkgd_audio(MMMusic, BEARfid, true); }                   }                    if (theInpTab.ButPress) { stop_all_audio; if (BearTalk[Bumper] != 2) { MakeBearLook(Bumper); Step; }                       start_bkgd_audio(10, BEARfid, false); /* channel 10 = Bumper's OK */ while (eor_ctr); stop_all_audio; BearTalk[Bumper] = 1; /* Bumper has spoken, but is finished */ MakeBearCycle(Bumper);

unset_module(ModMain); set_module(ModBop);

cursor_hide;

if (!Bump_shuf) { get_random_seed; shufshort(Boptab, NumBopPkgs); /* shuffle the bop packages */ Bump_shuf = true; }                       /*                         * play the bop intro real time file */                       fid = open_file("bop.rtf", false); stat = play_recs(fid, set_bop_intro_pcls, 2, false, false, 0); *(short *)vidmem0 = 0x8F00; DslvBA(meddisolve); /* show plane A */ stat = play_recs(fid, set_bop_intro_pcls, 1, false, true, 0); /* play rest of file */ stat = close_file(fid);

DirNum = DirSaveMM; /* restore first */ Bop; /* go to the game */ DirNum = DirSaveMM;

unset_module(ModBop); set_module(ModMain);

loadpkg("lv.com", PkgBuf);

FadeDown(fastdisolve); BopOff;  /* turn plane mixing back on */ setup_MM; PAFlag = false; /* don't bring up plane A */ FadeUp(meddisolve, true); start_bkgd_audio(MMMusic, BEARfid, true); }                   else { Cursor_Freeze; if (BearTalk[Bumper] == 2) { stop_all_audio; BearTalk[Bumper] = 1; /* Bumper has spoken, but is finished */ MakeBearCycle(Bumper); start_bkgd_audio(MMMusic, BEARfid, true); }                       Cursor_Melt; }               }                break; }       last_xpos = inp_xpos;   /* xpos of input device */ last_ypos = inp_ypos;  /* ypos of input device */ } }

/* * setup_MM */ void setup_MM { Ptr        thePtr; Ptr        scnptrsav;

DirSaveMM = DirNum; /* save for when leaving this module */

theRectPtr = &LVRect;      /* Set list of hotspots */

currentT = clock;        /* get current tick count */ reset_help;      /* reset help counter */ reset_dim;       /* reset dim counter */
 * 1) if 0
 * 1) endif

SceneTab[MScene] = (ScenePtr)stuffpkg(PkgBuf); FixScene(MScene); (*SceneTab[MScene]).Active = true; (*SceneTab[MScene]).Display = true; SetUpScene(MScene); /*    * Modify the scene now. First of all, let the scene run at full speed * and slow down the bear items if necessary. Also decrement the number * of states per bear so they don't look at you while cycling. */   MMScene = SceneTab[MScene]; MMScene->AniDelay = 4; MMSeq = (ItemSeqPtr)((int)MMScene + (int)MMScene->ItemDir[0].Where); MMSeq->Cyc.ICycle = 1; MMSeq->Cyc.ICycSize --; MMSeq = (ItemSeqPtr)((int)MMScene + (int)MMScene->ItemDir[1].Where); MMSeq->Cyc.ICycle = 1; MMSeq->Cyc.ICycSize --; MMSeq = (ItemSeqPtr)((int)MMScene + (int)MMScene->ItemDir[2].Where); MMSeq->Cyc.ICycle = 1; MMSeq->Cyc.ICycSize --;

NoButs; /* unlink old button strip */ /*    * draw the livingroom background picture */   scnptrsav = scn_ptr; scn_ptr = vidmem5; /* draw to bkgd screen */ thePtr = (Ptr) ((unsigned)MMScene + (unsigned)pkgTOC->TE[1].Where); /* bkgd shape is 2nd in package */ Draw((ShapePtr)thePtr, 0, 0); /* draw the shape */ scn_ptr = scnptrsav; /*    * copy to rear screen, swap, and copy to new rear screen */   copy_bkgd_front; /*    * Make the buttons for the main menu. */   MkMainBut;

}

/* * MakeBearLook - this increments the number of states in the sequence *                 and makes the bear look up at you. */ void MakeBearLook(theBear) short theBear; { SeqPtr     theSeqDF;   /* the sequence disk file */ ShapePtr   theShp;     /* shape disk file */

MMSeq = (ItemSeqPtr)((int)MMScene + (int)MMScene->ItemDir[theBear].Where); MMSeq->Cyc.ICycle = 1; MMSeq->Cyc.IState = MMSeq->Cyc.ICycSize; MMSeq->Cyc.ICycSize ++; MMSeq->Cyc.ICycEnable = false;

MMSeq->Pos.ICurXOff = MMSeq->Cyc.ISeqPtr->SeqTab[MMSeq->Cyc.IState].StateXOff; MMSeq->Pos.ICurYOff = MMSeq->Cyc.ISeqPtr->SeqTab[MMSeq->Cyc.IState].StateYOff; theSeqDF = MMSeq->Cyc.ISeqPtr; theShp = theSeqDF->SeqTab[MMSeq->Cyc.IState].StateIA; MMSeq->Pos.ICurWide = MMSeq->Pos.IEraseWide = theShp->NumWide; MMSeq->Pos.ICurHigh = MMSeq->Pos.IEraseHigh = theShp->NumHigh;

MMSeq->Pos.ICurX = MMSeq->Pos.IBaseX + MMSeq->Pos.ICurXOff; MMSeq->Pos.ICurY = MMSeq->Pos.IBaseY + MMSeq->Pos.ICurYOff;

}

/* * MakeBearCycle - this returns the bear to its cycling mode. */ void MakeBearCycle(theBear) short theBear; {   MMSeq = (ItemSeqPtr)((int)MMScene + (int)MMScene->ItemDir[theBear].Where); MMSeq->Cyc.ICycSize --; MMSeq->Cyc.IState = 0; MMSeq->Cyc.ICycEnable = true; BearFlag[theBear] = false; }

/* * changeSpch - */ void changeSpch {

if (speech == English) speech = Spanish; else speech = English;

NewBut; }

/* * changeText - */ void changeText {

if (text == English) text = Spanish; else text = English;

NewBut; }

/* * set_bear_voice - This opens either the English or Spanish bear rta file *                 It depends on the current module (setting of "ModMod"). */ void set_bear_voice {

if (speech == English) BEARfid = Eng_bear_fid; if (speech == Spanish) BEARfid = Span_bear_fid; }

/* * set_button_voice - This selects either the English or Spanish button rta file */ void set_button_voice {

if (speech == English) BUTTONfid = Eng_button_fid; if (speech == Spanish) BUTTONfid = Span_button_fid; }

/* * set_buffers - set PkgBuf to the proper size */ void set_buffers(mod) short mod; {   switch (mod) { case ModMain: /* Get enough memory to hold the livingroom package */ PkgBuf = (char *)ALLOCATE(FORM1_SECTOR * MMPkgSecs, VIDEO1); break; case ModBook: /* Get enough memory to hold largest WB package */ PkgBuf = (char *)ALLOCATE(FORM1_SECTOR * WBPkgSecs, VIDEO1); break; case ModBop: /* Get enough memory to hold largest Bop package */ PkgBuf = (char *)ALLOCATE(FORM1_SECTOR * BopPkgSecs, VIDEO1); break; case ModSent1: /* Get enough memory to hold largest Sentence Builder package */ PkgBuf = (char *)ALLOCATE(FORM1_SECTOR * SBPkgSecs, VIDEO1); break; }   if (PkgBuf == (char *)-1L) { STATUS2("Can't allocate PkgBuf. errno = %d\n", errno); }   pkgTOC = (TOCPtr)PkgBuf; /* packages always start with a table of contents */ }

/* * set_module  -   this allocates buffers, soundmaps, *                 opens files and sets pointers to the correct speech files */ void set_module(mod) short mod; { short      ctr;

ModMod = mod;  /* global module ID */ set_buffers(mod);

switch (mod) { case ModMain: set_files(mod); break; case ModBook: set_files(mod); break; case ModBop: ScreenBuf = (char *)ALLOCATE(FORM1_SECTOR * BopScrnSecs, VIDEO1); /* screen images */ if (ScreenBuf == (char *)-1L) { STATUS1("Can't allocate ScreenBuf\n"); }

snd_array[0].smap_id = SMAP_CREATE(audpath, D_CMONO, 36, &snd_array[0].data); /* bop sound */ if ( snd_array[0].smap_id == -1 ) { STATUS1("Can't get soundmap 0\n"); }

snd_array[1].smap_id = SMAP_CREATE(audpath, D_CMONO, 36, &snd_array[1].data); /* sphere sound */ if ( snd_array[1].smap_id == -1 ) { STATUS1("Can't get soundmap 1\n"); }

snd_array[2].smap_id = SMAP_CREATE(audpath, D_CMONO, 72, &snd_array[2].data); /* star sound */ if ( snd_array[2].smap_id == -1 ) { STATUS1("Can't get soundmap 2\n"); }

snd_array[3].smap_id = SMAP_CREATE(audpath, D_CMONO, 54, &snd_array[3].data); /* miss sound */ if ( snd_array[3].smap_id == -1 ) { STATUS1("Can't get soundmap 3\n"); }

snd_array[4].smap_id = SMAP_CREATE(audpath, D_CMONO, 54, &snd_array[4].data); /* shoot sound */ if ( snd_array[4].smap_id == -1 ) { STATUS1("Can't get soundmap 4\n"); }

for (ctr=5; ctr<=12; ctr++) { snd_array[ctr].smap_id = SMAP_CREATE(audpath, D_CMONO, BopNounGrpSize, &snd_array[ctr].data); if ( snd_array[ctr].smap_id == -1 ) { STATUS2("Can't get soundmap %d\n", ctr); }           }

for (ctr=13; ctr<=15; ctr++) { snd_array[ctr].smap_id = SMAP_CREATE(audpath, D_CMONO, BopFXGrpSize, &snd_array[ctr].data); if ( snd_array[ctr].smap_id == -1 ) { STATUS2("Can't get soundmap %d\n", ctr); }           }            set_files(mod); break; case ModSent1: case ModSent2u: case ModSent2d: ScreenBuf = (char *)ALLOCATE(FORM1_SECTOR * SBScrnSecs, VIDEO1); /* screen images */ if (ScreenBuf == (char *)-1L) { STATUS1("Can't allocate ScreenBuf\n"); }           RezBuf = (char *)ALLOCATE(FORM1_SECTOR * RezBufSecs, VIDEO1);   /* resedit data */ if (RezBuf == (char *)-1L) { STATUS1("Can't allocate RezBuf\n"); }           Seq1Buf = (char *)ALLOCATE(FORM1_SECTOR * SeqBufSecs, VIDEO1);  /* seq 1 */ if (Seq1Buf == (char *)-1L) { STATUS1("Can't allocate Seq1Buf\n"); }           Seq2Buf = (char *)ALLOCATE(FORM1_SECTOR * SeqBufSecs, VIDEO1);  /* seq 2 */ if (Seq2Buf == (char *)-1L) { STATUS1("Can't allocate Seq2Buf\n"); }           BkgdBuf = (char *)ALLOCATE(FORM1_SECTOR * BkgdBufSecs, VIDEO1);     /* background image */ if (BkgdBuf == (char *)-1L) { STATUS1("Can't allocate BkgdBuf\n"); }

snd_array[0].smap_id = SMAP_CREATE(audpath, D_CMONO, SBNounGrpSize, &snd_array[0].data); /* initial noun */ if ( snd_array[0].smap_id == -1 ) { STATUS1("Can't get soundmap for Eng noun #1\n"); }

snd_array[1].smap_id = SMAP_CREATE(audpath, D_CMONO, SBNounGrpSize, &snd_array[1].data); /* Verb */ if ( snd_array[1].smap_id == -1 ) { STATUS1("Can't get soundmap for Span noun #1\n"); }

snd_array[2].smap_id = SMAP_CREATE(audpath, D_CMONO, SBVerbGrpSize, &snd_array[2].data); /* final noun */ if ( snd_array[2].smap_id == -1 ) { STATUS1("Can't get soundmap for Eng verb\n"); }

snd_array[3].smap_id = SMAP_CREATE(audpath, D_CMONO, SBVerbGrpSize, &snd_array[3].data); /* sound effect */ if ( snd_array[3].smap_id == -1 ) { STATUS1("Can't get soundmap for Span verb\n"); }

snd_array[4].smap_id = SMAP_CREATE(audpath, D_CMONO, SBNounGrpSize, &snd_array[4].data); /* Verb */ if ( snd_array[4].smap_id == -1 ) { STATUS1("Can't get soundmap for Eng noun #2\n"); }

snd_array[5].smap_id = SMAP_CREATE(audpath, D_CMONO, SBNounGrpSize, &snd_array[5].data); /* final noun */ if ( snd_array[5].smap_id == -1 ) { STATUS1("Can't get soundmap for Span noun #2\n"); }

snd_array[6].smap_id = SMAP_CREATE(audpath, D_CMONO, SBFXGrpSize, &snd_array[6].data); /* sound effect */ if ( snd_array[6].smap_id == -1 ) { STATUS1("Can't get soundmap for sound effect\n"); }

set_files(mod); break; } }

/* * unset_module -  this givesback buffers and soundmaps */ void unset_module(mod) short mod; { short          ctr; SoundmapDesc   *sm_ptr;

switch (mod) { case ModMain: unset_files(mod); DEALLOCATE(FORM1_SECTOR * MMPkgSecs, PkgBuf); /* release main menu buffer */ break;

case ModBook: unset_files(mod); DEALLOCATE(FORM1_SECTOR * WBPkgSecs, PkgBuf); /* give back WB buffer */ break;

case ModBop: unset_files(mod); /*            * reset the original soundmap sizes before giving them back */           for (ctr=5; ctr<=12; ctr++) { sm_ptr = sm_info(audpath, snd_array[ctr].smap_id); sm_ptr->smd_nogrps = BopNounGrpSize; }           for (ctr=13; ctr<=15; ctr++) { sm_ptr = sm_info(audpath, snd_array[ctr].smap_id); sm_ptr->smd_nogrps = BopFXGrpSize; }           for (ctr=15; ctr>=0; ctr--) { SMAP_DESTROY(audpath, snd_array[ctr].smap_id); snd_array[ctr].smap_id = 0; }           DEALLOCATE(FORM1_SECTOR * BopScrnSecs, ScreenBuf); /* give back screen image buffer */ DEALLOCATE(FORM1_SECTOR * BopPkgSecs, PkgBuf); /* give back package buffer */ break;

case ModSent1: case ModSent2u: case ModSent2d: unset_files(mod); /*            * reset the original soundmap sizes before giving them back */           sm_ptr = sm_info(audpath, snd_array[0].smap_id); sm_ptr->smd_nogrps = SBNounGrpSize; sm_ptr = sm_info(audpath, snd_array[1].smap_id); sm_ptr->smd_nogrps = SBNounGrpSize; sm_ptr = sm_info(audpath, snd_array[2].smap_id); sm_ptr->smd_nogrps = SBVerbGrpSize; sm_ptr = sm_info(audpath, snd_array[3].smap_id); sm_ptr->smd_nogrps = SBVerbGrpSize; sm_ptr = sm_info(audpath, snd_array[4].smap_id); sm_ptr->smd_nogrps = SBNounGrpSize; sm_ptr = sm_info(audpath, snd_array[5].smap_id); sm_ptr->smd_nogrps = SBNounGrpSize; sm_ptr = sm_info(audpath, snd_array[6].smap_id); sm_ptr->smd_nogrps = SBFXGrpSize; for (ctr=6; ctr>=0; ctr--) { SMAP_DESTROY(audpath, snd_array[ctr].smap_id); snd_array[ctr].smap_id = 0; }           DEALLOCATE(FORM1_SECTOR * SBScrnSecs, ScreenBuf); DEALLOCATE(FORM1_SECTOR * RezBufSecs, RezBuf); DEALLOCATE(FORM1_SECTOR * SeqBufSecs, Seq1Buf); DEALLOCATE(FORM1_SECTOR * SeqBufSecs, Seq2Buf); DEALLOCATE(FORM1_SECTOR * BkgdBufSecs, BkgdBuf); DEALLOCATE(FORM1_SECTOR * SBPkgSecs, PkgBuf); /* give back SB buffer */ break; }   SNAPSHOT; }

/* * set_files   -   this opens files and sets pointers to the correct speech files */ void set_files(mod) short mod; {

switch (mod) { case ModMain: Eng_bear_fid = open_file("LV.Eng.rtf", false); Span_bear_fid = open_file("LV.Span.rtf", false); set_bear_voice; set_button_voice;        /* this really needs to be called just once */ break; case ModBook: Tune1ID = open_file("tunes1.rtf", false); Tune2ID = open_file("tunes2.rtf", false); Eng_bear_fid = open_file("BOP.BOOK.Eng.rtf", false); Span_bear_fid = open_file("BOP.BOOK.Span.rtf", false); set_bear_voice; break; case ModBop: Eng_bear_fid = open_file("BOP.BOOK.Eng.rtf", false); Span_bear_fid = open_file("BOP.BOOK.Span.rtf", false); set_bear_voice; break; case ModSent1: case ModSent2u: case ModSent2d: bkgdfid = open_file("bkgd.cmn", false); Tune3ID = open_file("tunes3.rtf", false); Tune4ID = open_file("tunes4.rtf", false); Tune5ID = open_file("tunes5.rtf", false); Eng_bear_fid = open_file("SENT.Eng.rtf", false); Span_bear_fid = open_file("SENT.Span.rtf", false); set_bear_voice; break; } }

/* * unset_files -   this closes the files for a module */ void unset_files(mod) short mod; {

close_file(Span_bear_fid); close_file(Eng_bear_fid);

switch (mod) { case ModMain: break; case ModBook: close_file(Tune2ID); close_file(Tune1ID); break; case ModBop: break; case ModSent1: case ModSent2u: case ModSent2d: close_file(Tune5ID); close_file(Tune4ID); close_file(Tune3ID); close_file(bkgdfid); break; } }

/****************************************************************************** void fork_bump int argc; char **argv; { int        vpath; int        apath; int        bumper_status; mod_exec   *datmod, *modlink, *modcload; BUMPER_DATA *bumpmod; char       argstring[5][8]; int        stat; int        stupid_fct_a, stupid_fct_b;
 * 1) if 0
 * fork_bump

STATUS1("fork_bump: ENTER\n");

errno = 0;

if ( (int)(datmod = modlink( bumpdata, MT_ANY )) == SYSERR ) { if ( (int)(datmod = modcload( bumpdata, 0, VIDEO1 )) == SYSERR ) exit( errno ); }   /*     * Link to the data module * Point to the actual data section of the module */   bumpmod = (BUMPER_DATA *)((char *)datmod + ((DATA_MODULE *)datmod)->data_offset);

/* Remember height of LCTs */ bumpmod->lct_height = BUMP_LCT_HEIGHT;

/* Get video environment setup */ if ( bump_init_vid( &vpath, &(bumpmod->dcp), BUMP_LCT_HEIGHT, bumpmod->vid_name ) == SYSERR ) exit( errno );

/* Set up audio so it plays */ if ( (int)((apath = init_audio)) == SYSERR ) exit(errno);

/* Set compat bit and PAL flag */ if ( set_comp_mode( vpath, &(bumpmod->pal_flag) ) == SYSERR ) exit( errno );

/* Null these out, assume we don't pass */ bumpmod->app_pa_buf = NULL; bumpmod->app_pb_buf = NULL; bumpmod->pcb = NULL; bumpmod->data_sector = 0;

/* Shut down the planes then execute DCP */ dc_wrfi( vpath, bumpmod->dcp.fcta, FCT_ICF, cp_icf(PA, ICF_MIN) ); dc_wrfi( vpath, bumpmod->dcp.fctb, FCT_ICF, cp_icf(PB, ICF_MIN) ); dc_exec( vpath, bumpmod->dcp.fcta, bumpmod->dcp.fctb );

/* Load the bumper executable and data module */ if ( (int)modcload( bumpargblk[0], 0, BUMPER_MEMORY_COLOR) == SYSERR ) exit( errno );

/* Fork the Bumper */ if ( os9exec( os9forkc, bumpargblk[0], bumpargblk, environ, 0, 0, BUMPER_PATH_NUM ) == SYSERR ) exit( errno );

wait( &bumper_status );

/* Check return status from bumper */ if ( bumpmod->return_status != BE_HUNKY ) {           if ( bumpmod->return_status == BE_INTERRUPT ) {                   STATUS1("Bumper was interrupted by the user.\n"); }           else {                   STATUS2("loader:Bumper returns error 0x%x\n", bumpmod->return_status ); exit(errno); }       }

/*    * Create new FCTs to keep the screen black */   stupid_fct_a = dc_crfct(vpath,PA,7,RES_NORMAL); stupid_fct_b = dc_crfct(vpath,PB,3,RES_NORMAL); /*    * Initialize the FCTs */   dc_wrfi(vpath,stupid_fct_a,0,cp_icm(ICM_CLUT7,ICM_CLUT7,NM_1,EV_OFF,CS_A)); dc_wrfi(vpath,stupid_fct_a,1,cp_dprm(RMS_NORMAL,PRF_X2,BP_NORMAL)); dc_wrfi(vpath,stupid_fct_a,2,cp_icf(PA,ICF_MIN)); dc_wrfi(vpath,stupid_fct_a,3,cp_po(PR_AB)); dc_wrfi(vpath,stupid_fct_a,4,cp_tci(MIX_ON,TR_CKEY_T,TR_OFF)); dc_wrfi(vpath,stupid_fct_a,5,cp_phld(PA,PH_OFF,0)); dc_wrfi(vpath,stupid_fct_a,6,cp_bkcol(BK_LOW, BK_BLACK));

dc_wrfi(vpath,stupid_fct_b,0,cp_dprm(RMS_NORMAL,PRF_X2,BP_NORMAL)); dc_wrfi(vpath,stupid_fct_b,1,cp_icf(PB,ICF_MIN)); dc_wrfi(vpath,stupid_fct_b,2,cp_phld(PB,PH_OFF,0));

dc_exec(vpath, stupid_fct_a, stupid_fct_b);

/*    * get rid of the old FCTs and LCTs */   dc_dllct( vpath, bumpmod->dcp.lcta ); dc_dllct( vpath, bumpmod->dcp.lctb ); dc_dlfct( vpath, bumpmod->dcp.fcta ); dc_dlfct( vpath, bumpmod->dcp.fctb );

sprintf(argstring[0],"%d",vpath); sprintf(argstring[1],"%d",apath); sprintf(argstring[2],"%d",(bumpmod->pal_flag==YES?1:0));

stat = munload( bumpdata, MT_ANY ); if (stat == -1) { STATUS2("****couldn't unload bumpdata. error numer 0x%x\n", errno); }

titleargblk[1] = argstring[0]; titleargblk[2] = argstring[1]; titleargblk[3] = argstring[2];

if ( (int)modcload( titleargblk[0], 0, TITLE_MEMORY_COLOR) == SYSERR ) exit( errno );

STATUS1("loader: EXIT\n");

if ( os9exec( chainc, titleargblk[0], titleargblk, environ, 0, 0, TITLE_PATH_NUM ) == SYSERR ) exit( errno ); }
 * 1) endif

rtf.c

 * 1) include <stdio.h>
 * 2) include <cdfm.h>
 * 3) include <errno.h>
 * 4) include <memory.h>
 * 5) include <rtr.h>


 * 1) include "dbg.h"


 * 1) include "utility.h"
 * 2) include "animation.h"
 * 3) include "rtf.h"
 * 4) include "screen.h"
 * 5) include "reading.h"
 * 6) include "sound.h"
 * 7) include "bop.h"
 * 8) include "sentbld.h"
 * 9) include "wordbook.h"
 * 10) include "file_mgr.h"

PCB    *thePCB;    /* play control block */ int    audpath;

PCL    *vid_pcl_0; PCL    *vid_pcl_1;

PCL    *pcl_tab[max_chans];

PCL    **vid_cils; PCL    **aud_cils; PCL    **dat_cils; PCL    *rear_vid_pcl;  /* points to the pcl that ponits to the rear RL7 buffer */

/* * Setup everything to play a real time audio and/or video file. */

Boolean setup_rtf { int    ctr;

/* * Create the PCB and PCLs we need */   thePCB = (PCB *)ALLOCATE(sizeof(PCB), VIDEO1); if (thePCB == (PCB *)-1L) return(false); memset (thePCB, 0, sizeof(PCB)); /* * Get arrays of PCL pointers ready */   vid_cils = (PCL **)ALLOCATE (32*4, VIDEO1); if (vid_cils == (PCL **)-1L) return(false); memset (vid_cils, 0, 32*4); /* * Only 16 channels for bkgd audio are possible. */   aud_cils = (PCL **)ALLOCATE (16*4, VIDEO1); if (aud_cils == (PCL **)-1L) return(false); memset (aud_cils, 0, 16*4); /* * Get 32 of 'em for data */   dat_cils = (PCL **)ALLOCATE (32*4, VIDEO1); if (dat_cils == (PCL **)-1L) return(false); memset (dat_cils, 0, 32*4);

vid_pcl_0 = (PCL *)ALLOCATE(sizeof(PCL), VIDEO1); if ( vid_pcl_0 == (PCL *)-1L ) { STATUS1("couldn't get vid_pcl_0\n"); }   memset (vid_pcl_0, 0, sizeof(PCL));

vid_pcl_1 = (PCL *)ALLOCATE(sizeof(PCL), VIDEO1); if ( vid_pcl_1 == (PCL *)-1L ) { STATUS1("couldn't get vid_pcl_1\n"); }   memset (vid_pcl_1, 0, sizeof(PCL));

for (ctr=0; ctr<max_chans; ctr++) { pcl_tab[ctr] = (PCL *)ALLOCATE(sizeof(PCL), VIDEO1); if ( pcl_tab[ctr] == (PCL *)-1L ) { STATUS2("couldn't get pcl %d\n", ctr); }       memset (pcl_tab[ctr], 0, sizeof(PCL)); }

rear_vid_pcl = vid_pcl_0;  /* since we start by showing vidmem0 for RL7 */ reinit_rtf; /* We'll be playing a regular (a/v) rtf first */ return(true); }

/* * reinit_rtf - call this before each real time file play. *             (The rtfs with RL7 data and also an rt audio track) */ void reinit_rtf {

if (cur_aud_fid) { STATUS1("cur_aud_fid is still set in reinit_rtf\n"); stop_all_audio; }

/*    * Reinit PCB for real time file play */   thePCB->PCB_Stat = 0;                   /* Current status of the play */ thePCB->PCB_Sig = PCB_SIGNAL;          /* Signal to be sent */ /* thePCB->PCB_Rec = 1; */             /* this gets set in 'play_recs' */ thePCB->PCB_Chan = (1 << AUDIO_CHAN) | (1 << VIDEO_CHAN) | (1 << 17) | (1 << 18); thePCB->PCB_AChan = (1 << AUDIO_CHAN); /* send default audio channel to processor */ thePCB->PCB_Video = vid_cils; thePCB->PCB_Audio = aud_cils; thePCB->PCB_Data = dat_cils; /*    * reinitialize CILs */   memset (aud_cils, 0, 16*4); memset (vid_cils, 0, 32*4); memset (dat_cils, 0, 32*4); vid_cils[VIDEO_CHAN] = rear_vid_pcl; dat_cils[17] = pcl_tab[0]; dat_cils[18] = pcl_tab[1]; /*    * Intialize PCLs for video */   vid_pcl_0->PCL_Ctrl = 0;            /* Control byte */ vid_pcl_0->PCL_Sig = BUFFER_SIGNAL0; /* Signal to be sent on buffer full */ vid_pcl_0->PCL_Nxt = vid_pcl_1;    /* Pointer to next PCL */ vid_pcl_0->PCL_Buf = vidmem0;      /* Pointer to buffer */ vid_pcl_0->PCL_BufSz = RL7Size;    /* Size of buffer */ vid_pcl_0->PCL_Cnt = 0;            /* Current offset in buffer */

vid_pcl_1->PCL_Ctrl = 0;               /* Control byte */ vid_pcl_1->PCL_Sig = BUFFER_SIGNAL1; /* Signal to be sent on buffer full */ vid_pcl_1->PCL_Nxt = vid_pcl_0;        /* Pointer to next PCL */ vid_pcl_1->PCL_Buf = vidmem1;      /* Pointer to buffer */ vid_pcl_1->PCL_BufSz = RL7Size;    /* Size of buffer */ vid_pcl_1->PCL_Cnt = 0;            /* Current offset in buffer */

pcl_tab[0]->PCL_Ctrl = 0;              /* Control byte */ pcl_tab[0]->PCL_Buf = PkgBuf;          /* Pointer to buffer */ pcl_tab[0]->PCL_BufSz = 58;        /* Size of buffer */ pcl_tab[0]->PCL_Cnt = 0;               /* Current offset in buffer */ /*    * Initialize PCL for image data that will be loaded from this rtf */   pcl_tab[1]->PCL_Ctrl = 0;               /* Control byte */ if (ModMod == ModMain) { pcl_tab[1]->PCL_Buf = ButtonBuf;           /* Pointer to buffer */ pcl_tab[1]->PCL_BufSz = ButtonBufSize; /* Size of buffer */ }   if (ModMod == ModSent1) { pcl_tab[1]->PCL_Buf = ScreenBuf;           /* Pointer to buffer */ pcl_tab[1]->PCL_BufSz = SBScrnSecs;    /* Size of buffer */ }   pcl_tab[1]->PCL_Cnt = 0;                /* Current offset in buffer */ }

/* * set_bop_intro_pcls - call this before each real time file play. *             (The rtfs with RL7 data and also an rt audio track) */ void set_bop_intro_pcls {

if (cur_aud_fid) { STATUS1("cur_aud_fid is still set in set_bop_intro_pcls\n"); stop_all_audio; }

/*    * Reinit PCB for real time file play */   thePCB->PCB_Stat = 0;                   /* Current status of the play */ thePCB->PCB_Sig = PCB_SIGNAL;          /* Signal to be sent */

/* thePCB->PCB_Rec = 1; */ /* gets set in 'play_data' */

thePCB->PCB_Chan = 0xFFFFFFFF;         /* Channel selection mask - select all */ thePCB->PCB_AChan = (1 << AUDIO_CHAN); /* send default audio channel to processor */ thePCB->PCB_Video = vid_cils; thePCB->PCB_Audio = aud_cils; thePCB->PCB_Data = dat_cils; /*    * reinitialize CILs */   memset (aud_cils, 0, 16*4); memset (vid_cils, 0, 32*4); memset (dat_cils, 0, 32*4); vid_cils[VIDEO_CHAN] = rear_vid_pcl; aud_cils[10] = pcl_tab[0]; aud_cils[11] = pcl_tab[1]; aud_cils[12] = pcl_tab[2]; aud_cils[13] = pcl_tab[3]; aud_cils[14] = pcl_tab[4]; dat_cils[15] = pcl_tab[5]; /* * Intialize PCLs for video */   vid_pcl_0->PCL_Ctrl = 0;                /* Control byte */ vid_pcl_0->PCL_Sig = BUFFER_SIGNAL0; /* Signal to be sent on buffer full */ vid_pcl_0->PCL_Nxt = vid_pcl_1;        /* Pointer to next PCL */ vid_pcl_0->PCL_Buf = vidmem0;      /* Pointer to buffer */ vid_pcl_0->PCL_BufSz = RL7Size;    /* Size of buffer */ vid_pcl_0->PCL_Cnt = 0;            /* Current offset in buffer */

vid_pcl_1->PCL_Ctrl = 0;               /* Control byte */ vid_pcl_1->PCL_Sig = BUFFER_SIGNAL1; /* Signal to be sent on buffer full */ vid_pcl_1->PCL_Nxt = vid_pcl_0;        /* Pointer to next PCL */ vid_pcl_1->PCL_Buf = vidmem1;      /* Pointer to buffer */ vid_pcl_1->PCL_BufSz = RL7Size;    /* Size of buffer */ vid_pcl_1->PCL_Cnt = 0;            /* Current offset in buffer */

pcl_tab[0]->PCL_Ctrl = 0;              /* Control byte */ pcl_tab[0]->PCL_Buf = snd_array[0].data;   /* Pointer to buffer */ pcl_tab[0]->PCL_BufSz = 3;         /* Size of buffer */ pcl_tab[0]->PCL_Cnt = 0;               /* Current offset in buffer */

pcl_tab[1]->PCL_Ctrl = 0;              /* Control byte */ pcl_tab[1]->PCL_Buf = snd_array[1].data;   /* Pointer to buffer */ pcl_tab[1]->PCL_BufSz = 3;         /* Size of buffer */ pcl_tab[1]->PCL_Cnt = 0;               /* Current offset in buffer */

pcl_tab[2]->PCL_Ctrl = 0;              /* Control byte */ pcl_tab[2]->PCL_Buf = snd_array[2].data;   /* Pointer to buffer */ pcl_tab[2]->PCL_BufSz = 5;         /* Size of buffer */ pcl_tab[2]->PCL_Cnt = 0;               /* Current offset in buffer */

pcl_tab[3]->PCL_Ctrl = 0;              /* Control byte */ pcl_tab[3]->PCL_Buf = snd_array[3].data;   /* Pointer to buffer */ pcl_tab[3]->PCL_BufSz = 4;         /* Size of buffer */ pcl_tab[3]->PCL_Cnt = 0;               /* Current offset in buffer */

pcl_tab[4]->PCL_Ctrl = 0;              /* Control byte */ pcl_tab[4]->PCL_Buf = snd_array[4].data;   /* Pointer to buffer */ pcl_tab[4]->PCL_BufSz = 4;         /* Size of buffer */ pcl_tab[4]->PCL_Cnt = 0;               /* Current offset in buffer */ /*    * Initialize PCL for image data that will be loaded from this rtf */   pcl_tab[5]->PCL_Ctrl = 0;           /* Control byte */ pcl_tab[5]->PCL_Buf = ScreenBuf;       /* Pointer to buffer */ pcl_tab[5]->PCL_BufSz = BopScrnSecs;   /* Size of buffer */ pcl_tab[5]->PCL_Cnt = 0;               /* Current offset in buffer */ }

/* * set_bop_pkg1_pcls - Call this before loading each bop package */ void set_bop_pkg1_pcls {

if (cur_aud_fid) { STATUS1("cur_aud_fid is still set in set_bop_pkg_pcls\n"); stop_all_audio; }

/*    * Reinit PCB for real time file play */   thePCB->PCB_Stat = 0;           /* Current status of the play */ thePCB->PCB_Sig = PCB_SIGNAL;  /* Signal to be sent */ /* thePCB->PCB_Rec = 8; */     /* this gets set in 'play_recs' */ thePCB->PCB_AChan = 0; thePCB->PCB_Video = 0; thePCB->PCB_Audio = aud_cils; thePCB->PCB_Data = 0;

memset (aud_cils, 0, 16*4); if (speech == English) {

thePCB->PCB_Chan = 0x000000FF; aud_cils[0] = pcl_tab[0]; aud_cils[1] = pcl_tab[1]; aud_cils[2] = pcl_tab[2]; aud_cils[3] = pcl_tab[3]; aud_cils[4] = pcl_tab[4]; aud_cils[5] = pcl_tab[5]; aud_cils[6] = pcl_tab[6]; aud_cils[7] = pcl_tab[7]; }   else { thePCB->PCB_Chan = 0x0000FF00; aud_cils[8] = pcl_tab[0]; aud_cils[9] = pcl_tab[1]; aud_cils[10] = pcl_tab[2]; aud_cils[11] = pcl_tab[3]; aud_cils[12] = pcl_tab[4]; aud_cils[13] = pcl_tab[5]; aud_cils[14] = pcl_tab[6]; aud_cils[15] = pcl_tab[7]; }   /*     * The eight words (speech) */   pcl_tab[0]->PCL_Ctrl = 0;               /* Control byte */ pcl_tab[0]->PCL_Buf = snd_array[5].data;   /* Pointer to buffer */ pcl_tab[0]->PCL_BufSz = BopNounSecs;   /* Size of buffer */ pcl_tab[0]->PCL_Cnt = 0;               /* Current offset in buffer */

pcl_tab[1]->PCL_Ctrl = 0;              /* Control byte */ pcl_tab[1]->PCL_Buf = snd_array[6].data;   /* Pointer to buffer */ pcl_tab[1]->PCL_BufSz = BopNounSecs;   /* Size of buffer */ pcl_tab[1]->PCL_Cnt = 0;               /* Current offset in buffer */

pcl_tab[2]->PCL_Ctrl = 0;              /* Control byte */ pcl_tab[2]->PCL_Buf = snd_array[7].data;   /* Pointer to buffer */ pcl_tab[2]->PCL_BufSz = BopNounSecs;   /* Size of buffer */ pcl_tab[2]->PCL_Cnt = 0;               /* Current offset in buffer */

pcl_tab[3]->PCL_Ctrl = 0;              /* Control byte */ pcl_tab[3]->PCL_Buf = snd_array[8].data;   /* Pointer to buffer */ pcl_tab[3]->PCL_BufSz = BopNounSecs;   /* Size of buffer */ pcl_tab[3]->PCL_Cnt = 0;               /* Current offset in buffer */

pcl_tab[4]->PCL_Ctrl = 0;              /* Control byte */ pcl_tab[4]->PCL_Buf = snd_array[9].data;   /* Pointer to buffer */ pcl_tab[4]->PCL_BufSz = BopNounSecs;   /* Size of buffer */ pcl_tab[4]->PCL_Cnt = 0;               /* Current offset in buffer */

pcl_tab[5]->PCL_Ctrl = 0;          /* Control byte */ pcl_tab[5]->PCL_Buf = snd_array[10].data;  /* Pointer to buffer */ pcl_tab[5]->PCL_BufSz = BopNounSecs;   /* Size of buffer */ pcl_tab[5]->PCL_Cnt = 0;               /* Current offset in buffer */

pcl_tab[6]->PCL_Ctrl = 0;          /* Control byte */ pcl_tab[6]->PCL_Buf = snd_array[11].data;  /* Pointer to buffer */ pcl_tab[6]->PCL_BufSz = BopNounSecs;   /* Size of buffer */ pcl_tab[6]->PCL_Cnt = 0;               /* Current offset in buffer */

pcl_tab[7]->PCL_Ctrl = 0;          /* Control byte */ pcl_tab[7]->PCL_Buf = snd_array[12].data;  /* Pointer to buffer */ pcl_tab[7]->PCL_BufSz = BopNounSecs;   /* Size of buffer */ pcl_tab[7]->PCL_Cnt = 0;               /* Current offset in buffer */ }

/* * set_bop_pkg2_pcls - */ void set_bop_pkg2_pcls {

/*    * Reinit PCB for real time file play */   thePCB->PCB_Stat = 0;           /* Current status of the play */ thePCB->PCB_Sig = PCB_SIGNAL;  /* Signal to be sent */ /* thePCB->PCB_Rec = 4; */     /* this gets set in 'play_recs' */ thePCB->PCB_AChan = 0; thePCB->PCB_Video = 0; thePCB->PCB_Audio = aud_cils; thePCB->PCB_Data = dat_cils;

memset (aud_cils, 0, 16*4); memset (dat_cils, 0, 32*4); thePCB->PCB_Chan = 0x00100007; aud_cils[0] = pcl_tab[0]; aud_cils[1] = pcl_tab[1]; aud_cils[2] = pcl_tab[2]; dat_cils[20] = pcl_tab[3]; /*    * These are for the 3 sound effects */   pcl_tab[0]->PCL_Ctrl = 0;           /* Control byte */ pcl_tab[0]->PCL_Buf = snd_array[13].data;  /* Pointer to buffer */ pcl_tab[0]->PCL_BufSz = BopFXSecs; /* Size of buffer */ pcl_tab[0]->PCL_Cnt = 0;               /* Current offset in buffer */

pcl_tab[1]->PCL_Ctrl = 0;          /* Control byte */ pcl_tab[1]->PCL_Buf = snd_array[14].data;  /* Pointer to buffer */ pcl_tab[1]->PCL_BufSz = BopFXSecs; /* Size of buffer */ pcl_tab[1]->PCL_Cnt = 0;               /* Current offset in buffer */

pcl_tab[2]->PCL_Ctrl = 0;          /* Control byte */ pcl_tab[2]->PCL_Buf = snd_array[15].data;  /* Pointer to buffer */ pcl_tab[2]->PCL_BufSz = BopFXSecs; /* Size of buffer */ pcl_tab[2]->PCL_Cnt = 0;               /* Current offset in buffer */ /*    * image data that will be loaded from this rtf */   pcl_tab[3]->PCL_Ctrl = 0;           /* Control byte */ pcl_tab[3]->PCL_Buf = PkgBuf;      /* Pointer to buffer */ pcl_tab[3]->PCL_BufSz = BopPkgSecs; /* Size of buffer */ pcl_tab[3]->PCL_Cnt = 0;               /* Current offset in buffer */ pcl_tab[3]->PCL_Err = 0; }

/* * set_bop_pre_aud_pcls - * */ void set_bop_pre_aud_pcls {

if (cur_aud_fid) { STATUS1("cur_aud_fid is still set in set_bop_pre_aud_pcls\n"); stop_all_audio; }   /*     * Reinit PCB for real time file play */   thePCB->PCB_Stat = 0;           /* Current status of the play */ thePCB->PCB_Sig = PCB_SIGNAL;  /* Signal to be sent */ /* thePCB->PCB_Rec = 1; */     /* this gets set in 'play_data' */ thePCB->PCB_Chan = CHAN_9; thePCB->PCB_AChan = 0; thePCB->PCB_Video = 0; thePCB->PCB_Audio = aud_cils; thePCB->PCB_Data = 0;

memset (aud_cils, 0, 16*4); aud_cils[9] = pcl_tab[0];

pcl_tab[0]->PCL_Ctrl = 0;              /* Control byte */ pcl_tab[0]->PCL_Buf = snd_array[5].data;   /* Pointer to buffer */ pcl_tab[0]->PCL_BufSz = BopNounSecs;   /* Size of buffer */ pcl_tab[0]->PCL_Cnt = 0;               /* Current offset in buffer */ }

/* * set_bop_aud_pcls - Call this before loading just the eight speech files * * IMPORTANT - When this is called the variable 'speech' hasn't *              been changed yet, so the channels are reversed *             from what you would think makes sense. */ void set_bop_aud_pcls {

if (cur_aud_fid) { STATUS1("cur_aud_fid is still set in set_bop_aud_pcls\n"); stop_all_audio; }

/*    * Reinit PCB for real time file play */   thePCB->PCB_Stat = 0;           /* Current status of the play */ thePCB->PCB_Sig = PCB_SIGNAL;  /* Signal to be sent */ /* thePCB->PCB_Rec = 8; */     /* this gets set in 'play_data' */ thePCB->PCB_AChan = 0; thePCB->PCB_Video = 0; thePCB->PCB_Audio = aud_cils; thePCB->PCB_Data = 0;

memset (aud_cils, 0, 16*4); if (speech == Spanish) {

thePCB->PCB_Chan = 0x000000FF; aud_cils[0] = pcl_tab[0]; aud_cils[1] = pcl_tab[1]; aud_cils[2] = pcl_tab[2]; aud_cils[3] = pcl_tab[3]; aud_cils[4] = pcl_tab[4]; aud_cils[5] = pcl_tab[5]; aud_cils[6] = pcl_tab[6]; aud_cils[7] = pcl_tab[7]; }   else { thePCB->PCB_Chan = 0x0000FF00; aud_cils[8] = pcl_tab[0]; aud_cils[9] = pcl_tab[1]; aud_cils[10] = pcl_tab[2]; aud_cils[11] = pcl_tab[3]; aud_cils[12] = pcl_tab[4]; aud_cils[13] = pcl_tab[5]; aud_cils[14] = pcl_tab[6]; aud_cils[15] = pcl_tab[7]; }   pcl_tab[0]->PCL_Ctrl = 0;               /* Control byte */ pcl_tab[0]->PCL_Buf = snd_array[5].data;   /* Pointer to buffer */ pcl_tab[0]->PCL_BufSz = BopNounSecs;   /* Size of buffer */ pcl_tab[0]->PCL_Cnt = 0;               /* Current offset in buffer */

pcl_tab[1]->PCL_Ctrl = 0;              /* Control byte */ pcl_tab[1]->PCL_Buf = snd_array[6].data;   /* Pointer to buffer */ pcl_tab[1]->PCL_BufSz = BopNounSecs;   /* Size of buffer */ pcl_tab[1]->PCL_Cnt = 0;               /* Current offset in buffer */

pcl_tab[2]->PCL_Ctrl = 0;              /* Control byte */ pcl_tab[2]->PCL_Buf = snd_array[7].data;   /* Pointer to buffer */ pcl_tab[2]->PCL_BufSz = BopNounSecs;   /* Size of buffer */ pcl_tab[2]->PCL_Cnt = 0;               /* Current offset in buffer */

pcl_tab[3]->PCL_Ctrl = 0;              /* Control byte */ pcl_tab[3]->PCL_Buf = snd_array[8].data;   /* Pointer to buffer */ pcl_tab[3]->PCL_BufSz = BopNounSecs;   /* Size of buffer */ pcl_tab[3]->PCL_Cnt = 0;               /* Current offset in buffer */

pcl_tab[4]->PCL_Ctrl = 0;              /* Control byte */ pcl_tab[4]->PCL_Buf = snd_array[9].data;   /* Pointer to buffer */ pcl_tab[4]->PCL_BufSz = BopNounSecs;   /* Size of buffer */ pcl_tab[4]->PCL_Cnt = 0;               /* Current offset in buffer */

pcl_tab[5]->PCL_Ctrl = 0;          /* Control byte */ pcl_tab[5]->PCL_Buf = snd_array[10].data;  /* Pointer to buffer */ pcl_tab[5]->PCL_BufSz = BopNounSecs;   /* Size of buffer */ pcl_tab[5]->PCL_Cnt = 0;               /* Current offset in buffer */

pcl_tab[6]->PCL_Ctrl = 0;          /* Control byte */ pcl_tab[6]->PCL_Buf = snd_array[11].data;  /* Pointer to buffer */ pcl_tab[6]->PCL_BufSz = BopNounSecs;   /* Size of buffer */ pcl_tab[6]->PCL_Cnt = 0;               /* Current offset in buffer */

pcl_tab[7]->PCL_Ctrl = 0;          /* Control byte */ pcl_tab[7]->PCL_Buf = snd_array[12].data;  /* Pointer to buffer */ pcl_tab[7]->PCL_BufSz = BopNounSecs;   /* Size of buffer */ pcl_tab[7]->PCL_Cnt = 0;               /* Current offset in buffer */ }

/* * set_sbpkg1_pcls - call this before playing first record * of sentence builder packages */ void set_sbpkg1_pcls {

if (cur_aud_fid) { STATUS1("cur_aud_fid is still set in set_sbpkg1_pcls\n"); stop_all_audio; }

thePCB->PCB_Stat = 0;                  /* Current status of the play */ thePCB->PCB_Sig = PCB_SIGNAL;          /* Signal to be sent */ /* thePCB->PCB_Rec = 1; */             /* this gets set in 'play_recs' */ thePCB->PCB_Chan = CHAN_17 | CHAN_18;  /* Channel selection mask 17 & 18 */ thePCB->PCB_AChan = 0;                 /* Audio to memory selection mask */ thePCB->PCB_Video = 0; thePCB->PCB_Audio = 0; thePCB->PCB_Data = dat_cils;

memset (dat_cils, 0, 32*4);    /* clear old ones first */ dat_cils[17] = pcl_tab[0];         /* screen 1 packages */ dat_cils[18] = pcl_tab[1];         /* resedit data */

pcl_tab[0]->PCL_Ctrl = 0;              /* Control byte */ pcl_tab[0]->PCL_Buf = PkgBuf;          /* Pointer to buffer */ pcl_tab[0]->PCL_BufSz = SBPkgSecs; /* Size of buffer */ pcl_tab[0]->PCL_Cnt = 0;               /* Current offset in buffer */

pcl_tab[1]->PCL_Ctrl = 0;              /* Control byte */ pcl_tab[1]->PCL_Buf = RezBuf;          /* Pointer to buffer */ pcl_tab[1]->PCL_BufSz = RezBufSecs; /* Size of buffer */ pcl_tab[1]->PCL_Cnt = 0;               /* Current offset in buffer */ }

/* * set_sbpkg2_pcls - call this before playing second record * of sentence builder packages. This loads 2 of the 18 sequences * of the second record. * Pass this the two channel numbers * * 7/3/92 FIX - This will always play channel 18 as well. This was added * to make sure the file pointer is always pointing past all the sequences * and at the first audio channel of the third record. * */ void set_sbpkg2_pcls(ch1, ch2) short  ch1; short  ch2; {

if (cur_aud_fid) { STATUS1("cur_aud_fid is still set in set_sbpkg2_pcls\n"); stop_all_audio; }

thePCB->PCB_Stat = 0;                  /* Current status of the play */ thePCB->PCB_Sig = PCB_SIGNAL;          /* Signal to be sent */ /* thePCB->PCB_Rec = 3; */                 /* this gets set in 'play_recs' */ thePCB->PCB_Chan = (1 << ch1) | (1 << ch2) | (1 << 18); thePCB->PCB_AChan = 0;                 /* Audio to memory selection mask */ thePCB->PCB_Video = 0; thePCB->PCB_Audio = 0; thePCB->PCB_Data = dat_cils;

memset (dat_cils, 0, 32*4);    /* clear old ones first */ dat_cils[ch1] = pcl_tab[0];        /* sequence #1 */ dat_cils[ch2] = pcl_tab[1];        /* sequence #2 */ dat_cils[18] = pcl_tab[2];         /* dummy - bookmark */

pcl_tab[0]->PCL_Ctrl = 0;              /* Control byte */ pcl_tab[0]->PCL_Buf = Seq1Buf;     /* Pointer to buffer */ pcl_tab[0]->PCL_BufSz = SeqBufSecs; /* Size of buffer */ pcl_tab[0]->PCL_Cnt = 0;               /* Current offset in buffer */

pcl_tab[1]->PCL_Ctrl = 0;              /* Control byte */ pcl_tab[1]->PCL_Buf = Seq2Buf;     /* Pointer to buffer */ pcl_tab[1]->PCL_BufSz = SeqBufSecs; /* Size of buffer */ pcl_tab[1]->PCL_Cnt = 0;               /* Current offset in buffer */

pcl_tab[2]->PCL_Ctrl = 0;              /* Control byte */ pcl_tab[2]->PCL_Buf = snd_array[3].data;   /* Pointer to buffer */ pcl_tab[2]->PCL_BufSz = SBFXSecs;      /* Size of buffer */ pcl_tab[2]->PCL_Cnt = 0;               /* Current offset in buffer */ }

/* * set_sbpkg3_pcls - call this before playing second record * of sentence builder packages. This loads 4 of the 16 soundmaps * of the second record. * Pass this the four channel numbers * This always plays channel 18 as well as a way to advance to the next set or records */ void set_sbpkg3_pcls(ch0, ch1, ch2, ch3) short  ch0; short  ch1; short  ch2; short  ch3; {

if (cur_aud_fid) { STATUS1("cur_aud_fid is still set in set_sbpkg3_pcls\n"); stop_all_audio; }

thePCB->PCB_Stat = 0;                  /* Current status of the play */ thePCB->PCB_Sig = PCB_SIGNAL;          /* Signal to be sent */ /* thePCB->PCB_Rec = 5; */                 /* this gets set in 'play_recs' */ thePCB->PCB_Chan = (1 << ch0) | (1 << ch1) | (1 << ch2) | (1 << ch3) | (1 << 18); thePCB->PCB_AChan = 0;                 /* Audio to memory selection mask */ thePCB->PCB_Video = 0; thePCB->PCB_Audio = aud_cils; thePCB->PCB_Data = dat_cils;

memset (aud_cils, 0, 16*4); memset (dat_cils, 0, 32*4); aud_cils[ch0] = pcl_tab[0];        /* English intiial noun smap */ aud_cils[ch1] = pcl_tab[1];        /* Spanish intiial noun smap */ aud_cils[ch2] = pcl_tab[2];        /* English verb smap */ aud_cils[ch3] = pcl_tab[3];        /* Spanish verb smap */ dat_cils[18] = pcl_tab[4];         /* dummy bookmark */

pcl_tab[0]->PCL_Ctrl = 0;              /* Control byte */ pcl_tab[0]->PCL_Buf = snd_array[0].data;   /* Pointer to buffer */ pcl_tab[0]->PCL_BufSz = SBNounSecs; /* Size of buffer */ pcl_tab[0]->PCL_Cnt = 0;               /* Current offset in buffer */

pcl_tab[1]->PCL_Ctrl = 0;              /* Control byte */ pcl_tab[1]->PCL_Buf = snd_array[1].data;   /* Pointer to buffer */ pcl_tab[1]->PCL_BufSz = SBNounSecs; /* Size of buffer */ pcl_tab[1]->PCL_Cnt = 0;               /* Current offset in buffer */

pcl_tab[2]->PCL_Ctrl = 0;              /* Control byte */ pcl_tab[2]->PCL_Buf = snd_array[2].data;   /* Pointer to buffer */ pcl_tab[2]->PCL_BufSz = SBVerbSecs; /* Size of buffer */ pcl_tab[2]->PCL_Cnt = 0;               /* Current offset in buffer */

pcl_tab[3]->PCL_Ctrl = 0;              /* Control byte */ pcl_tab[3]->PCL_Buf = snd_array[3].data;   /* Pointer to buffer */ pcl_tab[3]->PCL_BufSz = SBVerbSecs; /* Size of buffer */ pcl_tab[3]->PCL_Cnt = 0;               /* Current offset in buffer */

pcl_tab[4]->PCL_Ctrl = 0;              /* Control byte */ pcl_tab[4]->PCL_Buf = snd_array[4].data;   /* Pointer to buffer */ pcl_tab[4]->PCL_BufSz = SBFXSecs;      /* Size of buffer */ pcl_tab[4]->PCL_Cnt = 0;               /* Current offset in buffer */ }

/* * set_sbpkg4_pcls - */ void set_sbpkg4_pcls(ch0, ch1, ch2) short  ch0; short  ch1; short  ch2; {

thePCB->PCB_Stat = 0;                  /* Current status of the play */ thePCB->PCB_Sig = PCB_SIGNAL;          /* Signal to be sent */ /* thePCB->PCB_Rec = 3; */                 /* this gets set in 'play_recs' */ thePCB->PCB_Chan = (1 << ch0) | (1 << ch1) | (1 << ch2); thePCB->PCB_AChan = 0;                 /* Audio to memory selection mask */ thePCB->PCB_Video = 0; thePCB->PCB_Audio = aud_cils; thePCB->PCB_Data = 0;

memset (aud_cils, 0, 16*4); aud_cils[ch0] = pcl_tab[0];        /* English final noun smap */ aud_cils[ch1] = pcl_tab[1];        /* Spanish final noun smap */ aud_cils[ch2] = pcl_tab[2];        /* sound effect smap */

pcl_tab[0]->PCL_Ctrl = 0;              /* Control byte */ pcl_tab[0]->PCL_Buf = snd_array[4].data;   /* Pointer to buffer */ pcl_tab[0]->PCL_BufSz = SBNounSecs; /* Size of buffer */ pcl_tab[0]->PCL_Cnt = 0;               /* Current offset in buffer */

pcl_tab[1]->PCL_Ctrl = 0;              /* Control byte */ pcl_tab[1]->PCL_Buf = snd_array[5].data;   /* Pointer to buffer */ pcl_tab[1]->PCL_BufSz = SBNounSecs; /* Size of buffer */ pcl_tab[1]->PCL_Cnt = 0;               /* Current offset in buffer */

pcl_tab[2]->PCL_Ctrl = 0;              /* Control byte */ pcl_tab[2]->PCL_Buf = snd_array[6].data;   /* Pointer to buffer */ pcl_tab[2]->PCL_BufSz = SBFXSecs;      /* Size of buffer */ pcl_tab[2]->PCL_Cnt = 0;               /* Current offset in buffer */ }

/* * set_wbpkg_pcls - call this before loading wordbook packages. */ void set_wbpkg_pcls {

if (cur_aud_fid) { STATUS1("cur_aud_fid is still set in set_wbpkg_pcls\n"); stop_all_audio; }

thePCB->PCB_Stat = 0;                  /* Current status of the play */ thePCB->PCB_Sig = PCB_SIGNAL;          /* Signal to be sent */ /* thePCB->PCB_Rec = 1; */             /* this gets set in 'play_recs' */ thePCB->PCB_Chan = 0x00027FFF;         /* Channel selection mask */ thePCB->PCB_AChan = 0;                 /* Audio to memory selection mask */ thePCB->PCB_Video = 0; thePCB->PCB_Audio = aud_cils; thePCB->PCB_Data = dat_cils;

memset (dat_cils, 0, 32*4); memset (aud_cils, 0, 16*4); aud_cils[0] = vid_pcl_0; aud_cils[1] = vid_pcl_1; aud_cils[2] = pcl_tab[0]; aud_cils[3] = pcl_tab[1]; aud_cils[4] = pcl_tab[2]; aud_cils[5] = pcl_tab[3]; aud_cils[6] = pcl_tab[4]; aud_cils[7] = pcl_tab[5]; aud_cils[8] = pcl_tab[6]; aud_cils[9] = pcl_tab[7]; aud_cils[10] = pcl_tab[8]; aud_cils[11] = pcl_tab[9]; aud_cils[12] = pcl_tab[10]; aud_cils[13] = pcl_tab[11]; aud_cils[14] = pcl_tab[12]; dat_cils[17] = pcl_tab[13];

vid_pcl_0->PCL_Ctrl = 0;               /* Control byte */ vid_pcl_0->PCL_Buf = snd_array[0].data; /* Pointer to buffer */ vid_pcl_0->PCL_BufSz = 40;         /* Size of buffer */ vid_pcl_0->PCL_Cnt = 0;            /* Current offset in buffer */

vid_pcl_1->PCL_Ctrl = 0;               /* Control byte */ vid_pcl_1->PCL_Buf = snd_array[1].data; /* Pointer to buffer */ vid_pcl_1->PCL_BufSz = 40;         /* Size of buffer */ vid_pcl_1->PCL_Cnt = 0;            /* Current offset in buffer */

pcl_tab[0]->PCL_Ctrl = 0;              /* Control byte */ pcl_tab[0]->PCL_Buf = snd_array[2].data;   /* Pointer to buffer */ pcl_tab[0]->PCL_BufSz = 40;        /* Size of buffer */ pcl_tab[0]->PCL_Cnt = 0;               /* Current offset in buffer */

pcl_tab[1]->PCL_Ctrl = 0;              /* Control byte */ pcl_tab[1]->PCL_Buf = snd_array[3].data;   /* Pointer to buffer */ pcl_tab[1]->PCL_BufSz = 40;        /* Size of buffer */ pcl_tab[1]->PCL_Cnt = 0;               /* Current offset in buffer */

pcl_tab[2]->PCL_Ctrl = 0;              /* Control byte */ pcl_tab[2]->PCL_Buf = snd_array[4].data;   /* Pointer to buffer */ pcl_tab[2]->PCL_BufSz = 40;        /* Size of buffer */ pcl_tab[2]->PCL_Cnt = 0;               /* Current offset in buffer */

pcl_tab[3]->PCL_Ctrl = 0;              /* Control byte */ pcl_tab[3]->PCL_Buf = snd_array[5].data;   /* Pointer to buffer */ pcl_tab[3]->PCL_BufSz = 40;        /* Size of buffer */ pcl_tab[3]->PCL_Cnt = 0;               /* Current offset in buffer */

pcl_tab[4]->PCL_Ctrl = 0;              /* Control byte */ pcl_tab[4]->PCL_Buf = snd_array[6].data;   /* Pointer to buffer */ pcl_tab[4]->PCL_BufSz = 40;        /* Size of buffer */ pcl_tab[4]->PCL_Cnt = 0;               /* Current offset in buffer */

pcl_tab[5]->PCL_Ctrl = 0;          /* Control byte */ pcl_tab[5]->PCL_Buf = snd_array[7].data; /* Pointer to buffer */ pcl_tab[5]->PCL_BufSz = 40;        /* Size of buffer */ pcl_tab[5]->PCL_Cnt = 0;               /* Current offset in buffer */

pcl_tab[6]->PCL_Ctrl = 0;          /* Control byte */ pcl_tab[6]->PCL_Buf = snd_array[8].data;           /* Pointer to buffer */ pcl_tab[6]->PCL_BufSz = 40;        /* Size of buffer */ pcl_tab[6]->PCL_Cnt = 0;               /* Current offset in buffer */

pcl_tab[7]->PCL_Ctrl = 0;          /* Control byte */ pcl_tab[7]->PCL_Buf = snd_array[9].data;           /* Pointer to buffer */ pcl_tab[7]->PCL_BufSz = 40;        /* Size of buffer */ pcl_tab[7]->PCL_Cnt = 0;               /* Current offset in buffer */

pcl_tab[8]->PCL_Ctrl = 0;          /* Control byte */ pcl_tab[8]->PCL_Buf = snd_array[10].data;          /* Pointer to buffer */ pcl_tab[8]->PCL_BufSz = 40;        /* Size of buffer */ pcl_tab[8]->PCL_Cnt = 0;               /* Current offset in buffer */

pcl_tab[9]->PCL_Ctrl = 0;          /* Control byte */ pcl_tab[9]->PCL_Buf = snd_array[11].data;          /* Pointer to buffer */ pcl_tab[9]->PCL_BufSz = 40;        /* Size of buffer */ pcl_tab[9]->PCL_Cnt = 0;               /* Current offset in buffer */

pcl_tab[10]->PCL_Ctrl = 0;         /* Control byte */ pcl_tab[10]->PCL_Buf = snd_array[12].data;         /* Pointer to buffer */ pcl_tab[10]->PCL_BufSz = 40;           /* Size of buffer */ pcl_tab[10]->PCL_Cnt = 0;              /* Current offset in buffer */

pcl_tab[11]->PCL_Ctrl = 0;         /* Control byte */ pcl_tab[11]->PCL_Buf = snd_array[13].data; /* Pointer to buffer */ pcl_tab[11]->PCL_BufSz = 40;           /* Size of buffer */ pcl_tab[11]->PCL_Cnt = 0;              /* Current offset in buffer */

pcl_tab[12]->PCL_Ctrl = 0;         /* Control byte */ pcl_tab[12]->PCL_Buf = snd_array[14].data; /* Pointer to buffer */ pcl_tab[12]->PCL_BufSz = 40;           /* Size of buffer */ pcl_tab[12]->PCL_Cnt = 0;              /* Current offset in buffer */

pcl_tab[13]->PCL_Ctrl = 0;         /* Control byte */ pcl_tab[13]->PCL_Buf = PkgBuf;     /* Pointer to buffer */ pcl_tab[13]->PCL_BufSz = WBPkgSecs; /* Size of buffer */ pcl_tab[13]->PCL_Cnt = 0;              /* Current offset in buffer */ }

/* * setup_bkgd_audio_rtf - */ void setup_bkgd_audio_rtf(the_chan) int the_chan; {

if (cur_aud_fid) { STATUS1("cur_aud_fid is still set in setup_bkgd_audio_rtf\n"); ss_abort (cur_aud_fid); }   thePCB->PCB_Stat = 0;                   /* Current status of the play */ thePCB->PCB_Sig = PCB_SIGNAL;          /* Signal to be sent */ thePCB->PCB_Rec = 1; thePCB->PCB_Chan = (1 << the_chan); thePCB->PCB_AChan = (1 << the_chan);   /* send audio channel to processor */ thePCB->PCB_Video = 0; thePCB->PCB_Audio = aud_cils; thePCB->PCB_Data = 0;

memset (aud_cils, 0, 16*4); }

/* * close_rtf_stuff - */ void close_rtf_stuff { int    ctr;

DEALLOCATE(sizeof(PCB), thePCB); DEALLOCATE(32*4, vid_cils); DEALLOCATE(16*4, aud_cils); DEALLOCATE(32*4, dat_cils); DEALLOCATE(sizeof(PCL), vid_pcl_0); DEALLOCATE(sizeof(PCL), vid_pcl_1); for (ctr=0; ctr<max_chans; ctr++) DEALLOCATE(sizeof(PCL), pcl_tab[ctr]); }

screen.c

 * 1) include <stdio.h>
 * 2) include <ucm.h>
 * 3) include <modes.h>
 * 4) include <csd.h>
 * 5) include <aimdef.h>
 * 6) include <time.h>
 * 7) include <errno.h>


 * 1) include "dbg.h"


 * 1) include "animation.h"
 * 2) include "screen.h"
 * 3) include "buttons.h"
 * 4) include "sentbld.h"
 * 5) include "utility.h"
 * 6) include "reading.h"
 * 7) include "bop.h"       /* for the no_vel, add_vel routines */

Ptr    scn_ptr;        /* destination screen for draws and erases */ Ptr    vidmem0;        /* pointer to screen 0 (plane A) */ Ptr    vidmem1;        /* pointer to screen 1 (plane A) */ Ptr    vidmem2;        /* pointer to screen 0 (plane B) for clut7 */ Ptr    vidmem3;        /* pointer to screen 1 (plane B) for clut7 */ Ptr    vidmem4;        /* pointer to 70 scan line button strip (plane B) */ Ptr    vidmem5;        /* pointer to bkgd screen for our stuff (plane B) */ int    vidpath;        /* video path */ int    fctid_RL7;      /* field control table ID (RL7) */ int    fctid_Clut7;    /* field control table ID (Clut7) */ int    lctid0;         /* LCT for RL7 screens in plane A */ int    lctid2;         /* LCT for Clut7 screens in plane B */ int    lct_pal_a;      /* LCT for PAL in plane A */ int    lct_pal_b;      /* LCT for PAL in plane B */

short  FilCol; Boolean PAFlag;        /* plane A flag - true if plane A has ICF */ Boolean PBFlag;        /* plane B flag - true if plane B has ICF */

int    PALflag; Rect   safe_rect = { 24<<1, 33<<1, 207<<1, 342<<1 };

Boolean cursor_stat;

/************************************************************************ int set_comp_mode( vpath, pal_flag ) int vpath; int *pal_flag; { char *disp_dev, *disp_param; char *csd_devname, *csd_devparam; REG char *dp; int mode, org_diff;
 * set_comp_mode
 * **** This function was lifted almost entirely out of os9_util.c, the
 * **** only thing changed was the parameter for the pt_org offset
 * Purpose: Set the compatability mode on the CD-I system assuming
 * that the images used are 384 actual bytes wide
 * Passed:  the video device number,
 * a ptr to the var which will contain the PAL flag,
 * a ptr to the var which is to hold the pointer origin offset
 * which is returned from dc_setcmp
 * Output:  The compatability mode will be set according to the info
 * found in the CSD,
 * If we are displaying on a 625 line system, the pal_flag will
 * be set to YES, else it will be NO
 * Returned: OK or SYSERR
 * be set to YES, else it will be NO
 * Returned: OK or SYSERR


 * 1) define TV_TYPE_STR    "TV"    /* TV type ID string */
 * 2) define PAL_625_STR    "625"   /* Spec's 625 line system */

if ( (disp_dev = csd_devname( DT_VIDEO, 1 )) == NULL ) { STATUS1("Couldn't get disp_dev name\n"); exit(0); }   if ( (disp_param = csd_devparam( disp_dev )) == NULL ) { free( disp_dev ); STATUS1("Couldn't get disp_param\n"); exit(0); }   mode = 1;                   /* Mode 1 is for 384 width on Monitor */ dp = disp_param;           /* If "TV" is found then mode should be 0 */ while ( *dp != '\0' ) { if (strncmp( dp++, TV_TYPE_STR, strlen(TV_TYPE_STR) ) == 0) { mode = 0; break; }   }    *pal_flag = 0;              /* Assume NTSC */ dp = disp_param;           /* If 625 is found, then we are in PAL */ while ( *dp != '\0' ) { if (strncmp( dp++, PAL_625_STR, strlen(PAL_625_STR) ) == 0) { *pal_flag = 1; if ( mode == 1 )   /* Need mode to be 0 w/384x240 on 625 lines */ mode = 0; break; }   }    free( disp_dev );           /* Give back memory for csd stuff */ free( disp_param ); /* Set appropriate compatability mode */ /* and set return value to parameter */ Errchk( org_diff = dc_setcmp( vpath, mode ) );

/* Reset ptr to report from offset */ /* Also, if in PAL, move org down 40 lines */ pt_org( vpath, (org_diff >> 16), (org_diff & 0xff) );

return ( OK );


 * 1) undef TV_TYPE_STR
 * 2) undef PAL_625_STR

}

void InitMatte {   /*     * Copy the RL7 matte screen to the two RL7 buffers in plane A     */ memcpy(vidmem0, mattePtr, 4354); /* the image data starts 4354 bytes into the file */ memcpy(vidmem1, mattePtr, 4354); }

/* * Enable the scrolling matte in plane A. butline is the scan line * at which the button bitmap is linked to. */ void MatteOn {   dc_wrli(vidpath,lctid0,1*2,2,cp_matte (0, MO_SET, MF_MF0, ICF_MIN, 0*2)); dc_wrli(vidpath,lctid0,1*2,3,cp_matte (1, MO_RES, MF_MF0, ICF_MIN, 34*2)); dc_wrli(vidpath,lctid0,1*2,4,cp_matte (2, MO_SET, MF_MF0, ICF_MIN, 350*2)); dc_wrli(vidpath,lctid0,butline,0,cp_matte (0, MO_RES, MF_MF0, ICF_MIN, 0*2)); dc_wrli(vidpath,lctid0,butline,1,cp_matte (1, MO_END, MF_MF0, ICF_MIN, 0*2)); dc_wrfi(vidpath,fctid_RL7,4,cp_tci(MIX_OFF,TR_MAT0_F ,TR_OFF)); PAFlag = true; /* set plane A flag */ }

void MatteOff {   NoA; dc_wrfi(vidpath,fctid_RL7,4,cp_tci(MIX_ON,TR_CKEY_T,TR_OFF)); dc_wrli(vidpath,lctid0,1*2,2,cp_nop); dc_wrli(vidpath,lctid0,1*2,3,cp_nop); dc_wrli(vidpath,lctid0,1*2,4,cp_nop); dc_wrli(vidpath,lctid0,butline,0,cp_nop); dc_wrli(vidpath,lctid0,butline,1,cp_nop); }

/* * Enable to middle 120-140 scan lines that * the sentence builder RTFs play in */ void RTFMatteOn {   /*     * Modify the LCT for the RL7 screens in plane A.  Set the initial video buffer * address to a series of "draw transparent" instructions. At line 51, set the * actual RL7 video buffer. At line 190, point to the transparent buffer again. * This should allow the desired parts of plane B to show through. */   dc_wrli(vidpath,lctid0,theLine*2,1,cp_matte(0,MO_SET,MF_MF0,ICF_MIN,0*2)); dc_wrli(vidpath,lctid0,butline,0,cp_matte(0,MO_RES,MF_MF0,ICF_MIN,0*2)); dc_wrli(vidpath,lctid0,butline,1,cp_matte(1,MO_END,MF_MF0,ICF_MIN, 0*2)); dc_wrfi(vidpath,fctid_RL7,4,cp_tci(MIX_OFF,TR_MAT0_F,TR_OFF)); PAFlag = true; /* set plane A flag */ }

void RTFMatteOff {   /*     * Set plane A back to straight RL7 and turn it off */   PAFlag = false; dc_wrfi(vidpath,fctid_RL7,4,cp_tci(MIX_ON,TR_CKEY_T,TR_OFF)); dc_wrli(vidpath,lctid0,theLine*2,0,cp_nop); /* this was a link to the bitmap */ dc_wrli(vidpath,lctid0,theLine*2,1,cp_nop); dc_wrli(vidpath,lctid0,butline,0,cp_nop); dc_wrli(vidpath,lctid0,butline,1,cp_nop); }

void bop_but_matte_on {   dc_wrli(vidpath,lctid0,butline,0,cp_matte (0, MO_SET, MF_MF0, ICF_MIN, 0)); dc_wrli(vidpath,lctid0,butline,1,cp_tci(MIX_OFF,TR_M0CK_T,TR_OFF)); dc_wrli(vidpath,lctid0,239*2,1,cp_matte (1, MO_END, MF_MF0, ICF_MIN, 0)); }

void bop_but_matte_off {   dc_wrli(vidpath,lctid0,butline,0,cp_nop); dc_wrli(vidpath,lctid0,butline,1,cp_nop); dc_wrli(vidpath,lctid0,239*2,1,cp_nop); }

void BopOn {   dc_wrfi(vidpath,fctid_RL7,4,cp_tci(MIX_OFF,TR_CKEY_T,TR_OFF)); } void BopOff {   dc_wrfi(vidpath,fctid_RL7,4,cp_tci(MIX_ON,TR_CKEY_T,TR_OFF)); }

/* * swap_clut7 - switches the two screens in plane B. * scn_ptr should always be pointing at the rear screen in plane B. * * This is a two stage "process". A scan line interrupt is first set somewhere * below the line that holds the address pointer to the video buffer. When the interrupt * is enabled, and the signal is received, it's a safe time to change the address pointer. * After this, a scan line interrupt is set for the top line of the lct (the lct * varies for PAL of NTSC). * */ void swap_clut7 { int    stat;

/*    * clear old phase2 DCP instructions and write new phase1 */   if (PALflag) { dc_wrli(vidpath,lct_pal_b,PHASE2_SWAP_LINE*2,SWAP_COLUMN,cp_nop); dc_wrli(vidpath,lctid2,PHASE1_SWAP_LINE*2,SWAP_COLUMN,cp_sig); }   else { dc_wrli(vidpath,lctid2,PHASE2_SWAP_LINE*2,SWAP_COLUMN,cp_nop); dc_wrli(vidpath,lctid2,PHASE1_SWAP_LINE*2,SWAP_COLUMN,cp_sig); }   /*     * now wait for this line to be drawn */   swapflag = false;   /*  signal handler will set this */ if ((stat = dc_ssig(vidpath,SLI_SIGNAL,0)) == -1) { STATUS2("couldn't set phase 1 SLI in swap_clut7. error number %d\n", errno); }   while (!swapflag); /*    * Quickly write the new address instrcutions */   if (scn_ptr == vidmem2) { dc_wrli(vidpath,lctid2,0*2,0,cp_dadr((int)vidmem2)); scn_ptr = vidmem3; EraPtr = &EraTab3; }   else { dc_wrli(vidpath,lctid2,0*2,0,cp_dadr((int)vidmem3)); scn_ptr = vidmem2; EraPtr = &EraTab2; }   /*     * clear old phase1 DCP instructions and write new phase2 */   if (PALflag) { dc_wrli(vidpath,lctid2,PHASE1_SWAP_LINE*2,SWAP_COLUMN,cp_nop); dc_wrli(vidpath,lct_pal_b,PHASE2_SWAP_LINE*2,SWAP_COLUMN,cp_sig); }   else { dc_wrli(vidpath,lctid2,PHASE1_SWAP_LINE*2,SWAP_COLUMN,cp_nop); dc_wrli(vidpath,lctid2,PHASE2_SWAP_LINE*2,SWAP_COLUMN,cp_sig); }   /*     * set the new signal and exit */   swapflag = false;   /*  signal handler will set this */ if ((stat = dc_ssig(vidpath,SLI_SIGNAL,0)) == -1) { STATUS2("couldn't set phase 2 SLI in swap_clut7. error number %d\n", errno); } }

/* * These gradually change the image contibution factor of * planes A and B. * * Pass the delay value to either DslvAB of DslvBA */

void DslvAB(delay) short delay; { short A;

for (A=0; A<=ICF_MAX; A++) { tsleep(delay); dc_wrfi(vidpath,fctid_RL7,2,cp_icf(PA,ICF_MAX - A)); dc_wrfi(vidpath,fctid_Clut7,2,cp_icf(PB,A)); }   PAFlag = false; /* clear plane A flag */ PBFlag = true; /* plane B now has max ICF */ }

void DslvBA(delay) short delay; { short A;

for (A=0; A<=ICF_MAX; A++) { tsleep(delay); dc_wrfi(vidpath,fctid_RL7,2,cp_icf(PA,A)); dc_wrfi(vidpath,fctid_Clut7,2,cp_icf(PB,ICF_MAX - A)); }   PAFlag = true; /* set plane A flag */ PBFlag = false; }

void AddA {

short A;
 * 1) if 0

for (A=ICF_MIN; A<=ICF_MAX; A+=7) { tsleep(1); dc_wrfi(vidpath,fctid_RL7,2,cp_icf(PA,A)); }   dc_wrfi(vidpath,fctid_RL7,2,cp_icf(PA,ICF_MAX)); PAFlag = true; /* set plane A flag */ }
 * 1) endif

void AddB {

short A;
 * 1) if 0

for (A=ICF_MIN; A<=ICF_MAX; A+=7) { tsleep(1); dc_wrfi(vidpath,fctid_Clut7,2,cp_icf(PB,A)); }   dc_wrfi(vidpath,fctid_Clut7,2,cp_icf(PB,ICF_MAX)); PBFlag = true; }
 * 1) endif

void NoA {

short A;
 * 1) if 0

for (A=ICF_MAX; A>=ICF_MIN; A--) { tsleep(1); dc_wrfi(vidpath,fctid_RL7,2,cp_icf(PA,A)); }
 * 1) endif

dc_wrfi(vidpath,fctid_RL7,2,cp_icf(PA,ICF_MIN)); PAFlag = false; /* clear plane A flag */ }

/* * copy_bkgd_front -   This copies the bkgd bitmap to the rear screen in plane B. *                      it then swaps the screens in plane B and copies to the new rear screen. *                     It sets up all three screens to do our animation */ void copy_bkgd_front {   memcpy(scn_ptr, vidmem5, 384 * 240); /* copy it to the rear screen */ Step; /* this will draw the first frame of animation and call 'swap' */ while (!swapflag); memcpy(scn_ptr, vidmem5, 384 * 240); /* copy it to the new rear screen */ }

void cursor_show {   gc_show(vidpath); cursor_stat = true; }

void cursor_hide {   gc_hide(vidpath); cursor_stat = false; }

/* * FadeDown/FadeUp work with both planes simultaneously */ void FadeDown(delay) short  delay; { short  A;

cursor_hide; for (A=ICF_MAX; A>=ICF_MIN; A--) { tsleep(delay); if (PAFlag) dc_wrfi(vidpath,fctid_RL7,2,cp_icf(PA,A)); if (PBFlag) dc_wrfi(vidpath,fctid_Clut7,2,cp_icf(PB,A)); } }

void FadeUp(delay, cursor) short  delay; Boolean cursor; { short  A;

for (A=ICF_MIN; A<=ICF_MAX; A++) { tsleep(delay); if (PAFlag) dc_wrfi(vidpath,fctid_RL7,2,cp_icf(PA,A)); if (PBFlag) dc_wrfi(vidpath,fctid_Clut7,2,cp_icf(PB,A)); }   if (cursor) cursor_show; }

sentbld.c

 * 1) include <stdio.h>
 * 2) include <time.h>
 * 3) include <ucm.h>
 * 4) include <errno.h>
 * 5) include <modes.h>
 * 6) include <rtr.h>


 * 1) include "dbg.h"


 * 1) include "utility.h"
 * 2) include "animation.h"
 * 3) include "buttons.h"
 * 4) include "screen.h"
 * 5) include "sentbld.h"
 * 6) include "rtf.h"
 * 7) include "sound.h"
 * 8) include "reading.h"
 * 9) include "file_mgr.h"

short      sbpctr; static short       WhichSBPkg; /* which package to do */ static SBInfoPtr   RezPtr;     /* ptr to the resedit section of the package */ static Ptr         SBPkgData;  /* the data section of the package (past the TOC) */ static short       WhichBkgd = 0;  /* toggles between 0,1 for which bkgd version to use */ static short       WhichTune = 0;  /* cycles between 0,1, 2 for which tune to use */ static int         sbpkgfid;   /* file ID of current sb package file */ static short       SentNum;    /* which of the 27 sentences to use in the package */ int                bkgdfid;    /* file ID of the bkgd strip file */ static short       lastCell;   /* holds hotspot of last cell the star appeared over */ static int         RTFfid;     /* if one of the sentences has a RTF */ static SBSclBkPtr  ScrlRez;    /* points to one of the two scroll resource files */ static short       NxtFScrl;   /* index for next front scroll item to be introduced */ static short       NxtRScrl;   /* index for next rear scroll item to be introduced */ static short       ScrlID;

/* * This next group of pointers deal with things in the * sentence builder common file (sent.com) that gets * loaded during the sentence builder intro rtf. */ static ScenePtr    SBScene; static ScenePtr    ScrlScene0; /* the first scrolling scene */ static ScenePtr    ScrlScene1; /* the second scrolling scene */ static SBBkgdPtr   BGPtr0;     /* pointer to the bkgd rez data #1 */ static SBBkgdPtr   BGPtr1;     /* pointer to the bkgd rez data #2 */ static SBSclBkPtr  SCPtr0;     /* pointer to the scroll rez data #1 */ static TOCPtr      SCTOC;      /* table of contents (TOC) of the scroll data */ static Ptr         SCData;     /* data section of the combined scroll items */ static TOCPtr      BGTOC;      /* table of contents (TOC) of the bkgd strips file */ static Ptr         perPtr;     /* pointer to the period shape */ Ptr    mattePtr;               /* ptr to RL7 screen that resides in plane A */ Boolean useRTF;                /* true means the selected sentence has a RTF to use */ char   *RTFName; static short       RTFctr;     /* down counter used to count rtf plays */ static ItemSeqPtr  theiSeq;    /* initial item table pointer */ static ItemSeqPtr  thefSeq;    /* final item table pointer */

/* * this is the table of the 47 packages that gets shuffled * Sentence Builder Package Tab */ short  sbptab[NumSBPkgs] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,   10,11,12,13,14,15,16,17,18,19,    20,21,22,23,24,25,26,27,28,29,    30,31,32,33,34,35,36,37,38,39,    40,41,42,43,44,45,46    };

/* * This is kind of the main table for Sentence Builder * The first entry is the package filename * The second entry is the sentence number (0-26) that has an RTF (or -1 for none) * The third entry is the RT filename */ static PkgTab SBPkgTab[NumSBPkgs] = { "pkg73.rtf", 9, "BIRD.HOUSE.rtf", 25, "BEE.rtf", "pkg19.rtf", 12, "SPACE.rtf", -1, " ", "pkg67.rtf", 18, "TRUCK.TREE.rtf", -1, " ", "pkg68.rtf", 1, "CYCLE.HOUSE.rtf", -1, " ", "pkg30.rtf", 3, "KANG.rtf", -1, " ", "pkg58.rtf", -1, " ", -1, " ", "pkg110.rtf", -1, " ", -1, " ", "pkg99.rtf", 0, "TRAIN.rtf", -1, " ", "pkg1.rtf", 15, "TRUCK.ELE.rtf", -1, " ", "pkg2.rtf", 19, "CYCLE.GAS.rtf", -1, " ", "pkg3.rtf",  3, "BARN.TRACT.rtf", 12, "BARN.CYCLE.rtf", "pkg4.rtf",  5, "TRAIN.rtf", 21, "BARN.RACER.rtf", "pkg5.rtf", -1, " ", -1, " ", "pkg10.rtf", 11, "DIVER.FISH.rtf", -1, " ", "pkg11.rtf", 3, "ROW.ISLE.rtf", 5, "ROW.LIGHT.rtf", "pkg13.rtf", 16, "DIVER.SHARK.rtf", -1, " ", "pkg14.rtf", -1, " ", -1, " ", "pkg18.rtf", 0, "SAILBOAT.rtf", -1, " ", "pkg20.rtf", 0, "LIGHTHOUSE.rtf", 10, "BIRD.GIRAFFE.rtf", "pkg27.rtf", 10, "BIRD.TREE.rtf", -1, " ", "pkg29.rtf", 1, "PANTH.PIG.rtf", 10, "PANTH.CAT.rtf", "pkg31.rtf", 19, "TIGER.RABBIT.rtf", -1, " ", "pkg36.rtf", 0, "PIG.PANTH.rtf", -1, " ", "pkg37.rtf", -1, " ", -1, " ", "pkg38.rtf", -1, " ", -1, " ", "pkg39.rtf", -1, " ", -1, " ", "pkg40.rtf", -1, " ", -1, " ", "pkg43.rtf", -1, " ", -1, " ", "pkg44.rtf", -1, " ", -1, " ", "pkg46.rtf", -1, " ", -1, " ", "pkg53.rtf", -1, " ", -1, " ", "pkg60.rtf", -1, " ", -1, " ", "pkg70.rtf", 3, "TRUCK.KANG.rtf", -1, " ", "pkg76.rtf", 0, "BIRD.GIRAFFE.rtf", -1, " ", "pkg81.rtf", 14, "LIGHTHOUSE.rtf", -1, " ", "pkg83.rtf", 6, "HIPPO.rtf", -1, " ", "pkg85.rtf", 16, "PENGUIN.rtf", 18, "KANG.rtf", "pkg86.rtf", 18, "DOG.TURTLE.rtf", -1, " ", "pkg89.rtf", 3, "PANTH.CHICK.rtf", -1, " ", "pkg91.rtf", 12, "BARN.CYCLE.rtf", -1, " ", "pkg96.rtf", 3, "ROW.ISLE.rtf", -1, " ", "pkg100.rtf", -1, " ", -1, " ", "pkg109.rtf", -1, " ", -1, " ", "pkg111.rtf", 11, "DOG.BUCKET.rtf", -1, " ", "pkg113.rtf", 7, "LION.MOUSE.rtf", -1, " ", "pkg116.rtf", -1, " ", -1, " ", "pkg118.rtf", 21, "KANG.rtf", -1, " " };

/* * These two tables have their fixed ypos's set, the * first and third elements (word index) gets set by the code that chooses the words. */ S1Tab Snoun[6] = { 00, 22, 0000, 0000, 00, 00,   00, 37, 0000, 0000, 00, 00,    00, 52, 0000, 0000, 00, 00,    00,126, 0000, 0000, 00, 00,    00,141, 0000, 0000, 00, 00,    00,156, 0000, 0000, 00, 00 };

S1Tab Sverb[3] = { 00, 74, 0000, 0000, 00, 00,   00, 89, 0000, 0000, 00, 00,    00,104, 0000, 0000, 00, 00 };

/* * These hold the index of each group of three word/phrases. * Each can have the value of 1, 2, or 3 */ static short   TopNoun; static short   MidVerb; static short   BotNoun;

static short   DirSave1;   /* # of things that were in mfxDir before scrn1 images */ static short   DirSave2;   /* # of things that were in mfxDir before scrn2 images (verb seqs) */

static Boolean noun_smap;

/* * These are the rectangle tables for each section of SB Reading */ static RectList Sent1Rect = { 14,   177, 33,218, 82,    /* help button */ 177, 88,218,149,   /* speech button */ 177,155,218,216,   /* text button */ 177,222,218,283,   /* play button */ 177,289,218,350,   /* go back button */ 21, 33, 35,248,   /* initial noun #1 */ 36, 33, 50,248,   /* initial noun #2 */ 51, 33, 65,248,   /* initial noun #3 */ 73, 33, 87,248,   /* verb #1 */ 88, 33,102,248,   /* verb #2 */ 103, 33,117,248,   /* verb #3 */ 125, 33,139,248,   /* final noun #1 */ 140, 33,154,248,   /* final noun #2 */ 155, 33,169,248    /* final noun #3 */ };

static RectList Sent2bRect = { 6,   177, 33,218, 82,    /* help button */ 177, 88,218,149,   /* speech button */ 177,155,218,216,   /* text button */ 177,222,218,283,   /* play button */ 177,289,218,319,   /* go back arrow */ 177,320,218,350,   /* go next arrow */ };

static Rect    BkgdRect = { 52, 34, 190, 350 }; /* large animation window */ static Rect    fullRect = {  0,  1, 240, 383 }; /* entire CDI screen */ static Rect    sentRect = { 22, 34,  51, 350 }; /* sentence window */ static Rect    iNounRect = { 0, 0, 0, 0 };     /* initial noun */ static Rect    VerbRect = { 0, 0, 0, 0 };      /* verb phrase */ static Rect    fNounRect = { 0, 0, 0, 0 };     /* final noun */

static WITab   yTab[101] = { 2,1,2,1,2,2,2,2,2,2,   /* acrobat, airplane,anteater,astronaut, ball */ 2,2,2,2,2,2,2,4,2,2,   /* balloon, banana, barge, barn, barrel */ 2,4,2,2,2,1,2,2,2,2,   /* bed, bee, bird, book, box */ 2,2,2,2,2,2,2,2,2,2,   /* bridge, bucket, bulldozer, Bumper, buoy */ 2,1,2,2,4,4,4,1,2,2,   /* bus, camel, canoe, car, cat */ 2,2,2,2,2,2,2,0,2,2,   /* cementmixer, chair, chicken, clock, cloud */ 2,4,2,2,4,4,2,2,2,2,   /* clown, computer, cow, diver, dock */ 2,4,2,2,2,2,2,2,2,4,   /* dog, door, duck, elephant, fence */ 2,4,2,4,4,2,2,1,2,2,   /* fish, frog, garage, gasstation, giraffe */ 2,2,2,2,2,1,2,1,2,4,2,4,   /* goat, hanger, helicopter, hippo, horn, house */ 2,2,2,2,2,4,2,2,2,1,   /* iron, island, kangaroo, lighthouse, lion */ 2,4,4,2,2,2,2,2,2,1,   /* monkey, moon, motorboat, motorcycle, mountain */ 4,1,2,2,2,2,2,2,2,2,   /* mouse, ostrich, panther, parachutist, parrot */ 2,2,2,2,2,2,2,2,4,1,   /* penguin, pig, pumpkin, rabbit, racer */ 2,2,2,2,2,2,2,2,2,2,   /* rainbow, rocket, rowboat, sailboat, Sara */ 4,2,2,1,2,2,2,2,2,2,   /* saw, shark, sheep, shoe, skunk */ 2,1,2,2,2,2,2,2,4,2,   /* sock, star, Stickybear, submarine, swan */ 2,4,2,1,2,2,2,2,2,2,   /* table, tanker, taxi, tent, tiger */ 2,2,2,2,2,2,2,1,2,1,   /* tower, tractor, train, tree, truck */ 2,1,2,2,4,2,2,2,2,2    /* tunnel, turtle, wagon, window, zebra */ };

static WITab   VyTab[] = { 2,1,2,1,2,2,2,1,       /* bounces away, bounces behind, bounces by, bounces faster */ 2,2,2,2,2,2,2,2,       /* bounces infront, bounces to, bumps into, chases */ 2,2,2,2,2,2,2,1,       /* dances, drifts away, drifts past, drives behind */ 2,2,2,2,2,2,2,2,       /* drives infront, drives into, drives out, drives past */ 2,2,2,2,2,1,2,2,       /* drives up, flies around, flies behind, flies infront */ 2,2,2,2,2,1,2,2,       /* flies over, flies under, floats behind, floats infront */ 2,2,2,1,2,4,2,1,       /* follows, glides past, goes thru, hides behind */ 2,2,2,2,2,2,2,2,       /* honks at, jumps over, lands on, plays with */ 2,1,2,2,2,2,2,2,       /* races behind, races infront, races into, races out */ 2,2,2,1,2,2,2,1,       /* races past, rolls away, runs away, runs behind */ 2,1,2,2,2,2,2,2,       /* runs faster, runs infront, runs past, runs to */ 2,1,2,1,2,2,2,1,       /* skips away, skips behind, skips by, skips faster */ 2,2,2,2,2,1,2,1,       /* skips infront, skips to, slides away, slides behind */ 2,1,2,2,2,2,2,2,       /* slides faster, slides infront, slides past, slides to */ 2,1,2,2,2,2,2,2,       /* splashes behind, splashes infront, stands next, stands on */ 2,1,2,1,2,2,2,2,       /* swims away, swims behind, swims infront, swims over */ 2,2,2,1,2,1,2,2,       /* swims under, walks away, walks behind, walks infront */ 2,2,2,2,2,2,2,2,       /* walks past, walks to, waves at, whistles at */ 2,2,2,1,2,1,2,2,       /* zooms around, zooms away, zooms behind, zooms infront */ 2,2,2,2,2,2,2,2,       /* zooms into, zooms over, zooms past, zooms through  */ 2,2,2,2                /* zooms under, zooms to */ };

AITab artTab[9] = { 0, 0,0,    /* for compatibility with resedit data */ 2,23,0,    /* The */ 2,19,0,    /* the */ 2,11,0,    /* El */ 2,11,0,    /* el */ 2,14,0,    /* La */ 2,10,0,    /* la */ 2,19,0,    /* del */ 2,11,0     /* al */ };

static MCAud SBTunes[] = { 0, 0, 0, 1, 0, 2, 0, 3,   0, 4, 0, 5, 0, 6, 0, 7,    0, 8, 0, 9, 0,10, 0,11,    0,12, 0,13, 0,14, 0,15,

1, 0, 1, 1, 1, 2, 1, 3,   1, 4, 1, 5, 1, 6, 1, 7,    1, 8, 1, 9, 1,10, 1,11,    1,12, 1,13, 1,14, 1,15,

2, 0, 2, 1, 2, 2, 2, 3,   2, 4, 2, 5, 2, 6, 2, 7,    2, 8, 2, 9, 2,10, 2,11,    2,12, 2,13, 2,14, 2,15,    };

void SentBld { short      ctr; Boolean    done; Ptr        myPtr;

/*    * stuffpkg returns with a ptr to the first byte of the data * section of the package (which is where we always place a scene). * The rest of the stuff in the package can be found in mfxDir. */   SBScene = SceneTab[MScene] = (ScenePtr)stuffpkg(ScreenBuf); ScrlScene0 = SceneTab[ScScene0] = (ScenePtr)mfxDir[getind("scroll6a.scene")].Where; ScrlScene1 = SceneTab[ScScene1] = (ScenePtr)mfxDir[getind("scroll6b.scene")].Where;

FixScene(MScene); FixScene(ScScene0); FixScene(ScScene1);

ScrlScene0->AniDelay = ScrlScene1->AniDelay = SBScene->AniDelay = scrn1_AniDelay;

BGPtr0 = (SBBkgdPtr) mfxDir[getind("bkgdrez1")].Where; /* pointer to the bkgd rez data #1 */ BGPtr1 = (SBBkgdPtr) mfxDir[getind("bkgdrez2")].Where; /* pointer to the bkgd rez data #2 */ SCPtr0 = (SBSclBkPtr) mfxDir[getind("scrollrez1")].Where; /* pointer to the scroll rez data #1 */ SCTOC = (TOCPtr) mfxDir[getind("scroll.com")].Where;   /* table of contents (TOC) of the scroll data */ SCData = (Ptr) SCTOC + ((*(short *)SCTOC) * 40 + 4);   /* data section of the combined scroll items */ BGTOC = (TOCPtr) mfxDir[getind("bkgd.h")].Where;       /* table of contents (TOC) of the bkgd strips file */

RezPtr = (SBInfoPtr)RezBuf; /* pointer to resedit data */ mattePtr = mfxDir[getind("SBmatte.rl7")].Where + 468; perPtr = mfxDir[getind("period.shp")].Where; /* ptr to the period shape */ /*    * Setup the address pointers to the article shapes */   myPtr = mfxDir[getind("Cpthe.shp")].Where; artTab[1].BImage = myPtr; myPtr = mfxDir[getind("the.shp")].Where; artTab[2].BImage = myPtr; myPtr = mfxDir[getind("Cpel.shp")].Where; artTab[3].BImage = myPtr; myPtr = mfxDir[getind("el.shp")].Where; artTab[4].BImage = myPtr; myPtr = mfxDir[getind("Cpla.shp")].Where; artTab[5].BImage = myPtr; myPtr = mfxDir[getind("la.shp")].Where; artTab[6].BImage = myPtr; myPtr = mfxDir[getind("del.shp")].Where; artTab[7].BImage = myPtr; myPtr = mfxDir[getind("al.shp")].Where; artTab[8].BImage = myPtr;

DirSave1 = DirNum;

theRectPtr = &Sent1Rect;   /* set list of hotspots */

newsbpkg;                /* load new package */

MkScrn1(true);     /* Make scrn1 (also include buttons) */ Step;        /* This will draw the first frame of animation */

/* set_bkgd_music; */ /* This sets the bkgd audio rtf to the one containing the correct bkgd music */

FadeDown(meddisolve); PAFlag = false; PBFlag = true; FadeUp(meddisolve, true); /* Now just bring up plane B */

start_bkgd_audio(SBMusic, BEARfid, true); /* pass channel number */ InitMatte;   /* set up the mattes */

cursor_show;         /* display the cursor */ done = false; while (!done) {

update_audio;

chk_help(1, BEARfid, SBMusic, BEARfid); chk_dim; /* if it's time to dim, this won't return until undim */

CheckInput; CheckHighLite; if (theInpTab.ButPress) { switch (theInpTab.HotIndex) { case 0: /* Help button */ stop_all_audio; start_bkgd_audio(0, BEARfid, false); /* pass channel number */ CheckInput; CheckHighLite; while ((eor_ctr) && (theInpTab.HotIndex == 0) && (!theInpTab.ButPress)) { CheckInput; CheckHighLite; }                   stop_all_audio; start_bkgd_audio(SBMusic, BEARfid, true); reset_help; break; case 1: /* speech button */ Cursor_Freeze; stop_all_audio; start_bkgd_audio(0, BUTTONfid, false); /* pass channel number */ changeSpch; while (eor_ctr) { Step; CheckHighLite; }                   stop_all_audio; set_bear_voice; set_button_voice; start_bkgd_audio(SBMusic, BEARfid, true); Cursor_Melt; break; case 2: /* text button */ Cursor_Freeze; stop_all_audio; if (text == English) start_bkgd_audio(3, BUTTONfid, false); /* pass channel number */ if (text == Spanish) start_bkgd_audio(1, BUTTONfid, false); /* pass channel number */ changeText; MkScrn1(false); /* don't make new buttons */ for (ctr=0; ctr<6; ctr++) { if (Snoun[ctr].CelCol != clearcol) Snoun[ctr].CelUpdate = 2; }                   for (ctr=0; ctr<3; ctr++) { if (Sverb[ctr].CelCol != clearcol) Sverb[ctr].CelUpdate = 2; }                   while (eor_ctr) { Step; CheckHighLite; }                   stop_all_audio; start_bkgd_audio(SBMusic, BEARfid, true); Cursor_Melt; break; case 3: /* play button */ if (PlayFlag) { stop_all_audio; SBScene->AniDelay = scrn2_AniDelay; DoScrn2; /* this doesn't return until it's time to do screen 1 */ SBScene->AniDelay = scrn1_AniDelay; theRectPtr = &Sent1Rect;   /* set list of hotspots */ ModMod = ModSent1; /* we are on screen one */ InitScrn1; MkScrn1(true);     /* Draw screen1 with new buttons as well */ FadeUp(meddisolve, true); start_bkgd_audio(SBMusic, BEARfid, true); }                   break; case 4: /* go back button */ stop_all_audio; done = true; break; case 5: case 6: case 7: /*                    * Deselect any other from this group. It's ok if it turns * out to be the one we are selecting. */                   for (ctr=0; ctr<3; ctr++) { if (Snoun[ctr].CelCol == selcol) { Snoun[ctr].CelCol = 0; Snoun[ctr].CelUpdate = 2; }                   }                    Snoun[theInpTab.HotIndex-5].CelCol = selcol; Snoun[theInpTab.HotIndex-5].CelUpdate = 2; SetIcon(theInpTab.HotIndex-5); TopNoun = theInpTab.HotIndex-5; if ((MidVerb != MTPart) && (BotNoun != MTPart) && (PlayFlag == false)) LetPlay; break; case 8: case 9: case 10: for (ctr=0; ctr<3; ctr++) { if (Sverb[ctr].CelCol == selcol) { Sverb[ctr].CelCol = 0; Sverb[ctr].CelUpdate = 2; }                   }                    Sverb[theInpTab.HotIndex-8].CelCol = selcol; Sverb[theInpTab.HotIndex-8].CelUpdate = 2; MidVerb = theInpTab.HotIndex-8; if ((TopNoun != MTPart) && (BotNoun != MTPart) && (PlayFlag == false)) LetPlay; break; case 11: case 12: case 13: for (ctr=3; ctr<6; ctr++) { if (Snoun[ctr].CelCol == selcol) { Snoun[ctr].CelCol = 0; Snoun[ctr].CelUpdate = 2; }                   }                    Snoun[theInpTab.HotIndex-8].CelCol = selcol; Snoun[theInpTab.HotIndex-8].CelUpdate = 2; SetIcon(theInpTab.HotIndex-8); BotNoun = theInpTab.HotIndex-11; /* BotNoun is (0-2) */ if ((MidVerb != MTPart) && (TopNoun != MTPart) && (PlayFlag == false)) LetPlay; break; }       }        last_xpos = inp_xpos;   /* xpos of input device */ last_ypos = inp_ypos;  /* ypos of input device */ }   SceneTab[ScScene0] = 0; /* Remove these from the scene table */ SceneTab[ScScene1] = 0; /* so that resolve wont mess with them */ close_file(sbpkgfid); /* there should always be a package file open in scrn 1 */ }

/* * CheckHighLite - see if the cell colors of screen 1 need updating */ void CheckHighLite { short  ctr; Rect   highRect;

/*    * This (CheckHighLite) gets called after a call to "Step" * which causes swapflag to be cleared (to false) * The signal handler will set swapflag (to true) when the scan line interrupts occur * on scan line2. We probably want to wait for that to happen before we start * updating what we think is the rear screen. */

while (!swapflag); /*    * If we are in one of the nine noun/verb rectangles, set its * bkgd color to highcol (unless it's selected) */   if ((theInpTab.HotIndex>=5) && (theInpTab.HotIndex<=7)) { if (Snoun[theInpTab.HotIndex-5].CelCol != selcol) { Snoun[theInpTab.HotIndex-5].CelCol = highcol; Snoun[theInpTab.HotIndex-5].CelUpdate = 2; }   }    if ((theInpTab.HotIndex>=8) && (theInpTab.HotIndex<=10)) { if (Sverb[theInpTab.HotIndex-8].CelCol != selcol) { Sverb[theInpTab.HotIndex-8].CelCol = highcol; Sverb[theInpTab.HotIndex-8].CelUpdate = 2; }   }    if ((theInpTab.HotIndex>=11) && (theInpTab.HotIndex<=13)) { if (Snoun[theInpTab.HotIndex-8].CelCol != selcol) { Snoun[theInpTab.HotIndex-8].CelCol = highcol; Snoun[theInpTab.HotIndex-8].CelUpdate = 2; }   }    /*     * See if any cells need updating. If a cell is currently using * the highlite color, and its CelUpdate counter is zero, it means * that it's time to restore the original bkgd color (white). */   for (ctr=0; ctr<6; ctr++) { if (Snoun[ctr].CelUpdate) { /* if CelUpdate != 0 */ highRect.top = Snoun[ctr].WYpos; highRect.bottom = highRect.top + 14; highRect.left = 34; highRect.right = 248; Fill(highRect, Snoun[ctr].CelCol); Snoun[ctr].CelUpdate--; if ((Snoun[ctr].CelUpdate == 0) && (Snoun[ctr].CelCol == highcol)) { Snoun[ctr].CelCol = clearcol; Snoun[ctr].CelUpdate = 2; }       }    }

for (ctr=0; ctr<3; ctr++) { if (Sverb[ctr].CelUpdate) { /* if CelUpdate != 0 */ highRect.top = Sverb[ctr].WYpos; highRect.bottom = highRect.top + 14; highRect.left = 34; highRect.right = 248; Fill(highRect, Sverb[ctr].CelCol); Sverb[ctr].CelUpdate--; if ((Sverb[ctr].CelUpdate == 0) && (Sverb[ctr].CelCol == highcol)) { Sverb[ctr].CelCol = clearcol; Sverb[ctr].CelUpdate = 2; }       }    }    drawwords; }

/* * DoScrn2 - this is the main loop for screen2 of sentence builder. */ void DoScrn2 { Boolean        done; long           delayT;     /* tick count to delay until after each animation */ short          theChan;

SentNum = (TopNoun * 9) + (MidVerb * 3) + BotNoun; /* calculate the sentence index (0-26) */ ChkRTF;          /* this will set 'useRTF' if there is a RTF for this sentence */ AddVerbs;        /* Load the two sequences needed for screen2 */ AddSound;        /* Load the three soundmaps and one FX needed for screen2 */

ModMod = ModSent2d; /* scrn 2 - buttons down */ FadeDown(meddisolve);

if (useRTF) DoRTF;           /* start the rtf */ else { MkScrn2;         /* Draw screen2 */ MatteOn;         /* turn on the scrolling mattes */ FadeUp(meddisolve, false); /* don't display cursor */

/*        * Set the background audio file for this sentence */       switch (SBTunes[RezPtr->packData[SentNum].verbTune[WhichTune]].MCAFile) { case 0: TUNEfid = Tune3ID; break; case 1: TUNEfid = Tune4ID; break; case 2: TUNEfid = Tune5ID; break; default: STATUS1("Background tune file is OUT OF RANGE!!!!!\n"); break; }       theChan = SBTunes[RezPtr->packData[SentNum].verbTune[WhichTune]].MCAChan; if ((theChan > 15) || (theChan < 0)) { STATUS1("Background channel is OUT OF RANGE!!!!!\n"); }       WhichTune ++;   /* advance for next time */ if (WhichTune == 3) WhichTune = 0;

SaySent; SBScene->Active = true; MoveBut(true);                 /* move buttons down */

start_bkgd_audio(theChan, TUNEfid, false); /* start the bkgd tune */ if (noun_smap) { stop_fx_alarm;       /* shut off the old alarm */ start_soundmap(snd_array[6].smap_id); start_fx_alarm; }   }

currentT = clock;                            /* get current tick count */ reset_dim;       /* reset dim counter */ reset_help; done = false;
 * 1) if 0
 * 1) endif

while (!done) {

chk_help(7, BEARfid, 0, 0); /* no audio to restart */ chk_dim; /* if it's time to dim, this won't return until undim */

if (fx_time) { /* Check for time to do sound effect */ start_soundmap(snd_array[6].smap_id); fx_time = false; }

if ((!eor_ctr) && (ModMod == ModSent2d)) {  /* Bkgd tune (or RTF) has ended - bring up the buttons */ if (useRTF) { close_file(RTFfid); RTFctr--; if (!RTFctr) { BeamMeUp; }               else { ReDoRTF; }           }            else BeamMeUp; }

/*        * numOfClicks == 0 means continuous animation, not something that reaches end of screen */       if ((RezPtr->packData[SentNum].numOfClicks) && (!useRTF) && (ModMod == ModSent2d)) { if (SBScene->Frame > RezPtr->packData[SentNum].numOfClicks) { SBScene->Active = false; delayT = currentT + (CLK_TCK * 2); /* 2 seconds */ while ((currentT < delayT) && !theInpTab.ButPress) CheckInput;

theiSeq->Gen.IDisplay = false; /* stop displaying the first item */

delayT = currentT + (CLK_TCK * 1); /* 1 seconds */ while ((currentT < delayT) && !theInpTab.ButPress) CheckInput; ReinitScene(SBScene); /* this sets intial item to displayable */ SBScene->Active = true; if (noun_smap) start_soundmap(snd_array[6].smap_id); }       }
 * 1) if 0
 * 1) endif

if ((RezPtr->packData[SentNum].BkgdType) && (!useRTF) && (ModMod == ModSent2d)) /* BkgdType true = scrolling */ CheckScroll; /* see if time to intro/delete items */

CheckInput; /*        * If an action button is pressed, and the screen button strip is down, * bring the screen button strip up. */       if ((ModMod == ModSent2d) && theInpTab.ButPress) { if (useRTF) { ss_abort(RTFfid); while(eor_ctr); /* gets cleared by signal handler for abort */ close_file(RTFfid); }           BeamMeUp; }       else if (theInpTab.ButPress) { switch (theInpTab.HotIndex) { case 0: /* the Help button */ stop_all_audio; start_bkgd_audio(7, BEARfid, false); /* pass channel number */ while ((theInpTab.HotIndex == 0) && (eor_ctr)) CheckInput; stop_all_audio; currentT = clock;        /* get current tick count */ reset_help; break; case 1: /* the Speech button */ Cursor_Freeze; changeSpch; start_bkgd_audio(0, BUTTONfid, false); /* pass channel number */ while (eor_ctr); set_bear_voice; set_button_voice; Cursor_Melt; break; case 2: /* the Text button */ Cursor_Freeze; if (text == English) start_bkgd_audio(3, BUTTONfid, false); /* pass channel number */ if (text == Spanish) start_bkgd_audio(1, BUTTONfid, false); /* pass channel number */ changeText; NewSent(-1); /* no highlighting */ while (eor_ctr); Cursor_Melt; break; case 3: /* the Play button */ ModMod = ModSent2d; cursor_hide; if (useRTF) { RTFctr = 3;    /* play each real time file three times */ ReDoRTF;     /* restart the rtf */ }                   else { SaySent; MoveBut(true);     /* move buttons down */ start_bkgd_audio(theChan, TUNEfid, false); if (noun_smap) { stop_fx_alarm;       /* shut off the old alarm */ start_soundmap(snd_array[6].smap_id); start_fx_alarm; }                       SBScene->Active = true; if (RezPtr->packData[SentNum].BkgdType) { /* true means scrolling */ ScrlScene0->Active = true; ScrlScene1->Active = true; }                   }                    break; case 4: /* same old screen 1 */ ExitToOne; done = true; break; case 5: /* go to new package in screen 1 */ sbpctr++; /* increment for next package */ if (sbpctr == NumSBPkgs) sbpctr = 0; ExitToOne; done = true; break; }       }        last_xpos = inp_xpos;   /* xpos of input device */ last_ypos = inp_ypos;  /* ypos of input device */ } }

/* * SaySent - Say the sentence */ void SaySent {

NewSent(0); /* highlight initial noun */ if (speech == English) start_soundmap(snd_array[0].smap_id); else start_soundmap(snd_array[1].smap_id); while(smap_busy); NewSent(1); /* highlight verb */ if (speech == English) start_soundmap(snd_array[2].smap_id); else start_soundmap(snd_array[3].smap_id); while(smap_busy); NewSent(2); /* highlight final noun */ if (speech == English) start_soundmap(snd_array[4].smap_id); else start_soundmap(snd_array[5].smap_id); while(smap_busy); NewSent(-1); /* no highlight */ }

/* * BeamMeUp - End screen 2 animation, sound and bring button strip up */ void BeamMeUp {

if (!useRTF) { stop_fx_alarm;       /* shut off sound effect alarm */ fx_time = false; stop_all_audio; SBScene->Active = false; ScrlScene0->Active = false; ScrlScene1->Active = false; }   reset_dim; reset_help; theRectPtr = &Sent2bRect;  /* set list of hotspots */ MoveBut(false);            /* move buttons up */ ModMod = ModSent2u;        /* screen2 - part2 (the buttons in the up position) */ cursor_show;         /* display the cursor */ }
 * 1) if 0
 * 1) endif

/* * ExitToOne - return to screen1 */ void ExitToOne {   ScrlScene0->Display = false; ScrlScene1->Display = false; SBScene->Display = false; newsbpkg;        /* should open same old package */ /* set_bkgd_music; */ /* set bkgd file back to old one */

FadeDown(meddisolve); if (useRTF) { useRTF = false; RTFMatteOff;     /* remove RTF matte (window) */ theLine = 0;       /* link vidmem0 to scan line 0 from now on */ InitMatte;       /* copy scroll matte image to plane A */ }   else { MatteOff;        /* remove scrolling mattes */ } }

/* * newsbpkg - load one of the packages. Really open and play the first record. */ void newsbpkg { Boolean        stat;

DirNum = DirSave1; /* reset to # of things before a package was loaded */

WhichSBPkg = sbptab[sbpctr]; sbpkgfid = open_file(SBPkgTab[WhichSBPkg].PkgName, true); if (sbpkgfid == -1) { STATUS1("had trouble opening a package - will try next\n"); sbpctr++; /* increment for next package */ if (sbpctr == NumSBPkgs) sbpctr = 0; WhichSBPkg = sbptab[sbpctr]; sbpkgfid = open_file(SBPkgTab[WhichSBPkg].PkgName, false); }   stat = play_recs(sbpkgfid, set_sbpkg1_pcls, 1, false, false, 0);

STATUS2("Package %s\n", SBPkgTab[WhichSBPkg].PkgName);

InitScrn1; }

/* * InitScrn1 - setup/reset the icons for screen 1 */ void InitScrn1 { short      ctr; Ptr        thePtr; short      i, initStat, relXOff, relYOff; ItemSeqPtr theSeq;     /* the sequence item table */ SeqPtr     theSeqDF;   /* the sequence disk file */ ShapePtr   theShp;     /* shape disk file */ short      midx, midy; /* center of icon box */

SBPkgData = stuffpkg(PkgBuf); /* stuffpkg returns a ptr to data section (past header) */ SBScene->NumItems = 6; ScrlScene0->NumItems = 0; ScrlScene1->NumItems = 0; /*    * The first six entries in the package are really * sub packages of sequences and their states. * Each of these should probably be stuffed individually * Each sequence should probably be assigned to an    * item table in the scene as well. */   for (ctr = 0; ctr < SBScene->NumItems; ctr ++) { thePtr = (Ptr) ((unsigned)SBPkgData + (unsigned)pkgTOC->TE[ctr].Where); stuffpkg(thePtr); thePtr += 2; /* skip the "# of things in pkg" word */ strcpy(SBScene->ItemDir[ctr].Who, thePtr); /* first entry is always seq name */ }   /*     * This call to SetUpScene is needed here to link the shapes to their * sequences. Without it the icons wouldn't be centered in their boxes */   SetUpScene(MScene); /*    * Center the icons in their little boxes and initialize them */   for (ctr=0; ctr<6; ctr++) { theSeq = (ItemSeqPtr) ((unsigned)SBScene + (unsigned)SBScene->ItemDir[ctr].Where); theSeq->Gen.IIDisplay = theSeq->Gen.IDisplay = false; theSeq->Cyc.IICycEnable = theSeq->Cyc.ICycEnable = true; theSeq->Cyc.IICycle = theSeq->Cyc.ICycle = 0;  /* cycle rate delay value */ theSeq->Pos.IIVelEnable = theSeq->Pos.IVelEnable = false;

theSeqDF = theSeq->Cyc.ISeqPtr; theShp = theSeqDF->SeqTab[theSeq->Cyc.IIState].StateIA; if (ctr < 3) /* top icon box */ midy = 56; else midy = 136; midx = 305; theSeq->Pos.IBaseX = theSeq->Pos.IIBaseX = midx - (theShp->NumWide)/2; theSeq->Pos.IBaseY = theSeq->Pos.IIBaseY = midy - (theShp->NumHigh)/2; /*        * Adjust the state offsets so that the first offset is 0,0 */       initStat= theSeq->Cyc.IIState; relXOff= theSeqDF->SeqTab[initStat].StateXOff; relYOff= theSeqDF->SeqTab[initStat].StateYOff; for (i = 0; i < theSeqDF->SeqNumSt; i++) { if (i == initStat){ theSeqDF->SeqTab[i].StateXOff= 0; theSeqDF->SeqTab[i].StateYOff= 0; }           else{ theSeqDF->SeqTab[i].StateXOff-= relXOff; theSeqDF->SeqTab[i].StateYOff-= relYOff; }       }    }    SBScene->Active = SBScene->Display = true; ScrlScene0->Active = ScrlScene0->Display = false; ScrlScene1->Active = ScrlScene1->Display = false;

currentT = clock;        /* get current tick count */ reset_dim; reset_help; DirSave2 = DirNum; /* save # of things before screen 2 stuff is added */
 * 1) if 0
 * 1) endif

/*    * This reinits all word cell colors to white (unselected) */   for (ctr = 0; ctr < SBScene->NumItems; ctr ++) Snoun[ctr].CelCol = clearcol; /* Clear the cell color */ Sverb[0].CelCol = clearcol; /* clear the verb cell colors as well */ Sverb[1].CelCol = clearcol; Sverb[2].CelCol = clearcol; /*    * These three flags hold the indexes (or MTPart for "clear") * of each selected sentence part. */   TopNoun = MidVerb = BotNoun = MTPart; PlayFlag = false; /* disable the play button */ }

/* * SetIcon - Pass this the noun index number (0-5) to activate */ void SetIcon(index) short index; { ItemSeqPtr theSeq;

if (index <3) { /* disable the display flag of all three top items */ theSeq = (ItemSeqPtr)((unsigned)SBScene + (unsigned)SBScene->ItemDir[0].Where); theSeq->Gen.IDisplay = false; theSeq = (ItemSeqPtr)((unsigned)SBScene + (unsigned)SBScene->ItemDir[1].Where); theSeq->Gen.IDisplay = false; theSeq = (ItemSeqPtr)((unsigned)SBScene + (unsigned)SBScene->ItemDir[2].Where); theSeq->Gen.IDisplay = false; }   else { /* disable the display flag of all three bottom items */ theSeq = (ItemSeqPtr)((unsigned)SBScene + (unsigned)SBScene->ItemDir[3].Where); theSeq->Gen.IDisplay = false; theSeq = (ItemSeqPtr)((unsigned)SBScene + (unsigned)SBScene->ItemDir[4].Where); theSeq->Gen.IDisplay = false; theSeq = (ItemSeqPtr)((unsigned)SBScene + (unsigned)SBScene->ItemDir[5].Where); theSeq->Gen.IDisplay = false; }   theSeq = (ItemSeqPtr)((unsigned)SBScene + (unsigned)SBScene->ItemDir[index].Where); theSeq->Gen.IDisplay = true; }

/* * Play the second record of the rtf. First set the channel selection * mask and the PCLs for the two sequence channels that we need. * This is also going to play channel 20 so as to position * the file pointer past all sequence channels. */ void AddVerbs { TOCPtr     theSeqTOC; SeqPtr     theSeqDF;   /* the sequence disk file */ ShapePtr   theShp;     /* shape disk file */ short      i, initStat, relXOff, relYOff; Boolean        stat;

DirNum = DirSave2; /* reset to # of things before a screen 2 package was loaded */ SBScene->NumItems = 2; /* just the first two items are needed for screen 2 */

set_sbpkg2_pcls(TopNoun * 3 + MidVerb, BotNoun * 3 + 9 + MidVerb); stat = play_recs(sbpkgfid, 0, 3, false, false, 0);

if (useRTF) { SBScene->Active = SBScene->Display = false; /* InitScrn1 will turn this back on */ return; }   /*     * Now link the verbs to the scene. */   stuffpkg(Seq1Buf); /* Add contents of sequence packages to mfxDir */ stuffpkg(Seq2Buf);

if (RezPtr->packData[SentNum].revFlg) { theSeqTOC = (TOCPtr)Seq1Buf; /* point at table of contents of first sequence 'package' */ strcpy(SBScene->ItemDir[1].Who, theSeqTOC->TE[0].Who); /* first entry is always seq name */ theSeqTOC = (TOCPtr)Seq2Buf; /* point at table of contents of second sequence 'package' */ strcpy(SBScene->ItemDir[0].Who, theSeqTOC->TE[0].Who); /* first entry is always seq name */ theiSeq = (ItemSeqPtr) ((unsigned)SBScene + (unsigned)SBScene->ItemDir[1].Where); thefSeq = (ItemSeqPtr) ((unsigned)SBScene + (unsigned)SBScene->ItemDir[0].Where); }   else { theSeqTOC = (TOCPtr)Seq1Buf; /* point at table of contents of first sequence 'package' */ strcpy(SBScene->ItemDir[0].Who, theSeqTOC->TE[0].Who); /* first entry is always seq name */ theSeqTOC = (TOCPtr)Seq2Buf; /* point at table of contents of second sequence 'package' */ strcpy(SBScene->ItemDir[1].Who, theSeqTOC->TE[0].Who); /* first entry is always seq name */ theiSeq = (ItemSeqPtr) ((unsigned)SBScene + (unsigned)SBScene->ItemDir[0].Where); thefSeq = (ItemSeqPtr) ((unsigned)SBScene + (unsigned)SBScene->ItemDir[1].Where); }   SetUpScene(MScene); /* call this to get the shapes linked to their sequences */

theSeqDF = theiSeq->Cyc.ISeqPtr; theShp = theSeqDF->SeqTab[theiSeq->Cyc.IIState].StateIA; theiSeq->Pos.IIBaseX = BkgdRect.left + RezPtr->packData[SentNum].iNounXPos -1; theiSeq->Pos.IIBaseY = BkgdRect.top + RezPtr->packData[SentNum].iNounYPos - (theShp->NumHigh); theiSeq->Pos.IIXVel = RezPtr->packData[SentNum].iNounXVel; theiSeq->Pos.IIYVel = RezPtr->packData[SentNum].iNounYVel; theiSeq->Pos.IIXAcc = RezPtr->packData[SentNum].iNounXAcc; theiSeq->Pos.IIYAcc = RezPtr->packData[SentNum].iNounYAcc; theiSeq->Pos.IIXVelFin = RezPtr->packData[SentNum].iNounXFinalVel; theiSeq->Pos.IIYVelFin = RezPtr->packData[SentNum].iNounYFinalVel; theiSeq->Cyc.IICycEnable = RezPtr->packData[SentNum].iNounCycEnable; theiSeq->Cyc.IICycle = RezPtr->packData[SentNum].iNounCycRate + 1; theiSeq->Pos.IIVelEnable = true; theiSeq->Gen.IIDisplay = true; theiSeq->Gen.IIActive = true;

initStat= theiSeq->Cyc.IIState; relXOff= theSeqDF->SeqTab[initStat].StateXOff; relYOff= theSeqDF->SeqTab[initStat].StateYOff; for (i = 0; i < theSeqDF->SeqNumSt; i++) { if (i == initStat){ theSeqDF->SeqTab[i].StateXOff= 0; theSeqDF->SeqTab[i].StateYOff= 0; }       else{ theSeqDF->SeqTab[i].StateXOff-= relXOff; theSeqDF->SeqTab[i].StateYOff-= relYOff; }   }

theSeqDF = thefSeq->Cyc.ISeqPtr; theShp = theSeqDF->SeqTab[thefSeq->Cyc.IIState].StateIA; thefSeq->Pos.IIBaseX = BkgdRect.left + RezPtr->packData[SentNum].fNounXPos -1; thefSeq->Pos.IIBaseY = BkgdRect.top + RezPtr->packData[SentNum].fNounYPos - (theShp->NumHigh); thefSeq->Pos.IIXVel = RezPtr->packData[SentNum].fNounXVel; thefSeq->Pos.IIYVel = RezPtr->packData[SentNum].fNounYVel; thefSeq->Pos.IIXAcc = RezPtr->packData[SentNum].fNounXAcc; thefSeq->Pos.IIYAcc = RezPtr->packData[SentNum].fNounYAcc; thefSeq->Pos.IIXVelFin = RezPtr->packData[SentNum].fNounXFinalVel; thefSeq->Pos.IIYVelFin = RezPtr->packData[SentNum].fNounYFinalVel; thefSeq->Cyc.IICycEnable = RezPtr->packData[SentNum].fNounCycEnable; thefSeq->Cyc.IICycle = RezPtr->packData[SentNum].fNounCycRate + 1; thefSeq->Pos.IIVelEnable = true; thefSeq->Gen.IIDisplay = true; thefSeq->Gen.IIActive = true;

initStat= thefSeq->Cyc.IIState; relXOff= theSeqDF->SeqTab[initStat].StateXOff; relYOff= theSeqDF->SeqTab[initStat].StateYOff; for (i = 0; i < theSeqDF->SeqNumSt; i++) { if (i == initStat){ theSeqDF->SeqTab[i].StateXOff= 0; theSeqDF->SeqTab[i].StateYOff= 0; }       else{ theSeqDF->SeqTab[i].StateXOff-= relXOff; theSeqDF->SeqTab[i].StateYOff-= relYOff; }   }

ReinitScene(SBScene); /* move initial values to current values */ SBScene->Active = false; /* turn this off until after sentence is read */ }

/* * Play the third record of the rtf. First set the channel selection * mask and the PCLs for the 4 smap channels that we need. */ void AddSound { short  ch0; short  ch1; short  ch2; short  ch3; short  ch4; short  ch5; short  ch6; Boolean combine = false; Boolean        stat; SoundmapDesc   *sm_ptr;

/*    * Clear the soundmap buffers */   memset (snd_array[0].data, 0, SBNounGrpSize * 128); memset (snd_array[1].data, 0, SBNounGrpSize * 128); memset (snd_array[2].data, 0, SBVerbGrpSize * 128); memset (snd_array[3].data, 0, SBVerbGrpSize * 128); memset (snd_array[4].data, 0, SBNounGrpSize * 128); memset (snd_array[5].data, 0, SBNounGrpSize * 128); memset (snd_array[6].data, 0, SBFXGrpSize * 128); /*    * See if the Spanish verb and final noun are combined. */   if (RezPtr->fNoun[BotNoun].SPrep == 4) { /* 4 = "el" */ if ((RezPtr->verb[MidVerb].Suffix == 7) || (RezPtr->verb[MidVerb].Suffix == 8)) combine = true; }   ch0 = TopNoun;          /* English initial noun */ ch1 = TopNoun + 3;     /* Spanish initial noun */ ch2 = MidVerb + 6;     /* English verb */ ch3 = MidVerb + 9;     /* Spanish verb */ if (combine) ch3 += 3;

ch4 = BotNoun;         /* English final noun */ ch5 = BotNoun + 3;     /* Spanish final noun */ if (combine) ch5 += 3; ch6 = TopNoun + 9;     /* sound effect */

set_sbpkg3_pcls(ch0, ch1, ch2, ch3); stat = play_recs(sbpkgfid, 0, 5, false, false, 0); /* inlude the extra eor for the bookmark */ /*    * Adjust the soundmaps for the true size of the data just loaded */   sm_ptr = sm_info(audpath, snd_array[0].smap_id); sm_ptr->smd_nogrps = pcl_tab[0]->PCL_Cnt / 128; sm_ptr = sm_info(audpath, snd_array[1].smap_id); sm_ptr->smd_nogrps = pcl_tab[1]->PCL_Cnt / 128; sm_ptr = sm_info(audpath, snd_array[2].smap_id); sm_ptr->smd_nogrps = pcl_tab[2]->PCL_Cnt / 128; sm_ptr = sm_info(audpath, snd_array[3].smap_id); sm_ptr->smd_nogrps = pcl_tab[3]->PCL_Cnt / 128;

set_sbpkg4_pcls(ch4, ch5, ch6); stat = play_recs(sbpkgfid, 0, 3, false, false, 0); stat = close_file(sbpkgfid); /*    * Adjust the soundmaps for the true size of the data just loaded */   sm_ptr = sm_info(audpath, snd_array[4].smap_id); sm_ptr->smd_nogrps = pcl_tab[0]->PCL_Cnt / 128; sm_ptr = sm_info(audpath, snd_array[5].smap_id); sm_ptr->smd_nogrps = pcl_tab[1]->PCL_Cnt / 128; sm_ptr = sm_info(audpath, snd_array[6].smap_id); sm_ptr->smd_nogrps = pcl_tab[2]->PCL_Cnt / 128; if (sm_ptr->smd_nogrps == 18) /* silence */ noun_smap = false; else noun_smap = true; }

/* * MkScrn1 - Build sentence builder screen 1. This code gets called either when *         the user is viewing screen2 or the last frame of the real time intro file. * * When coming here, the 6 nouns and 3 verbs should already be selected. * * pass 'buts' wether or not to do new buttons as well */ void MkScrn1(buts) Boolean buts; { Ptr        thePtr; Ptr        scnptrsav;

/* * Save original contents and then set scn_ptr to bkgd scrn * (most drawing happens at scn_ptr) */   scnptrsav = scn_ptr; scn_ptr = vidmem5; /* * First, draw the five boxes on the background screen */   FilCol = 96; Fill(fullRect, FilCol); /* fill entire bkgd screen */ thePtr = mfxDir[getind("slots.shp")].Where; Draw((ShapePtr)thePtr, 33, 21); /* draw the shape */ Draw((ShapePtr)thePtr, 33, 73); /* draw the shape */ Draw((ShapePtr)thePtr, 33, 125); /* draw the shape */ thePtr = mfxDir[getind("topbox.shp")].Where; Draw((ShapePtr)thePtr, 256, 21); /* draw the shape */ thePtr = mfxDir[getind("botbox.shp")].Where; Draw((ShapePtr)thePtr, 256, 101); /* draw the shape */ /*    * This draws the nine words/phrases in the * proper language (still at scn_ptr = bkgd) */   drawwords;

scn_ptr = scnptrsav; /* restore scn_ptr */ if (buts) NoButs; /* unlink old button strip */ /*    * copy to rear screen, swap, and copy to new rear screen */   copy_bkgd_front;

if (buts) MkSentBut;   /* make the buttons for screen 1 */ }

/* * drawwords - this draws the 9 words/phrases */ void drawwords {   DrawWord0; DrawWord1; DrawWord2; DrawWord3; DrawWord4; DrawWord5; DrawWord6; DrawWord7; DrawWord8; }

/* * DrawWord0 - draw initial noun 0 */ void DrawWord0 { short  nounX; Ptr    thePtr;

if (text == English) { nounX = strtNX; if (RezPtr->iNoun[0].EPrep) { Draw((ShapePtr)artTab[RezPtr->iNoun[0].EPrep].BImage,nounX,Snoun[0].WYpos               + artTab[RezPtr->iNoun[0].EPrep].Byoff); nounX += (artTab[RezPtr->iNoun[0].EPrep].Bwdth + spcNX); }       thePtr = (Ptr) ((unsigned)SBPkgData + (unsigned)pkgTOC->TE[6].Where); Draw((ShapePtr)thePtr,nounX,Snoun[0].WYpos + yTab[RezPtr->iNoun[0].idx].Eyoff); }   if (text == Spanish) { nounX = strtNX; if (RezPtr->iNoun[0].SPrep) { Draw((ShapePtr)artTab[RezPtr->iNoun[0].SPrep].BImage,nounX,Snoun[0].WYpos               + artTab[RezPtr->iNoun[0].SPrep].Byoff); nounX += (artTab[RezPtr->iNoun[0].SPrep].Bwdth + spcNX); }       thePtr = (Ptr) ((unsigned)SBPkgData + (unsigned)pkgTOC->TE[15].Where); Draw((ShapePtr)thePtr,nounX,Snoun[0].WYpos + yTab[RezPtr->iNoun[0].idx].Syoff); } }

/* * DrawWord1 - draw initial noun 1 */ void DrawWord1 { short  nounX; Ptr    thePtr;

if (text == English) { nounX = strtNX; if (RezPtr->iNoun[1].EPrep) { Draw((ShapePtr)artTab[RezPtr->iNoun[1].EPrep].BImage,nounX,Snoun[1].WYpos               + artTab[RezPtr->iNoun[1].EPrep].Byoff); nounX += (artTab[RezPtr->iNoun[1].EPrep].Bwdth + spcNX); }       thePtr = (Ptr) ((unsigned)SBPkgData + (unsigned)pkgTOC->TE[7].Where); Draw((ShapePtr)thePtr,nounX,Snoun[1].WYpos + yTab[RezPtr->iNoun[1].idx].Eyoff); }   if (text == Spanish) { nounX = strtNX; if (RezPtr->iNoun[1].SPrep) { Draw((ShapePtr)artTab[RezPtr->iNoun[1].SPrep].BImage,nounX,Snoun[1].WYpos               + artTab[RezPtr->iNoun[1].SPrep].Byoff); nounX += (artTab[RezPtr->iNoun[1].SPrep].Bwdth + spcNX); }       thePtr = (Ptr) ((unsigned)SBPkgData + (unsigned)pkgTOC->TE[16].Where); Draw((ShapePtr)thePtr,nounX,Snoun[1].WYpos + yTab[RezPtr->iNoun[1].idx].Syoff); } }

/* * DrawWord2 - draw initial noun 2 */ void DrawWord2 { short  nounX; Ptr    thePtr;

if (text == English) { nounX = strtNX; if (RezPtr->iNoun[2].EPrep) { Draw((ShapePtr)artTab[RezPtr->iNoun[2].EPrep].BImage,nounX,Snoun[2].WYpos               + artTab[RezPtr->iNoun[2].EPrep].Byoff); nounX += (artTab[RezPtr->iNoun[2].EPrep].Bwdth + spcNX); }       thePtr = (Ptr) ((unsigned)SBPkgData + (unsigned)pkgTOC->TE[8].Where); Draw((ShapePtr)thePtr,nounX,Snoun[2].WYpos + yTab[RezPtr->iNoun[2].idx].Eyoff); }   if (text == Spanish) { nounX = strtNX; if (RezPtr->iNoun[2].SPrep) { Draw((ShapePtr)artTab[RezPtr->iNoun[2].SPrep].BImage,nounX,Snoun[2].WYpos               + artTab[RezPtr->iNoun[2].SPrep].Byoff); nounX += (artTab[RezPtr->iNoun[2].SPrep].Bwdth + spcNX); }       thePtr = (Ptr) ((unsigned)SBPkgData + (unsigned)pkgTOC->TE[17].Where); Draw((ShapePtr)thePtr,nounX,Snoun[2].WYpos + yTab[RezPtr->iNoun[2].idx].Syoff); } }

/* * DrawWord3 - draw verb 0 */ void DrawWord3 { Ptr    thePtr;

if (text == English) { thePtr = (Ptr) ((unsigned)SBPkgData + (unsigned)pkgTOC->TE[9].Where); Draw((ShapePtr)thePtr,strtNX,Sverb[0].WYpos + VyTab[RezPtr->verb[0].idx].Eyoff); }   if (text == Spanish) { thePtr = (Ptr) ((unsigned)SBPkgData + (unsigned)pkgTOC->TE[18].Where); Draw((ShapePtr)thePtr,strtNX,Sverb[0].WYpos + VyTab[RezPtr->verb[0].idx].Syoff); } }

/* * DrawWord4 - draw verb 1 */ void DrawWord4 { Ptr    thePtr;

if (text == English) { thePtr = (Ptr) ((unsigned)SBPkgData + (unsigned)pkgTOC->TE[10].Where); Draw((ShapePtr)thePtr,strtNX,Sverb[1].WYpos + VyTab[RezPtr->verb[1].idx].Eyoff); }   if (text == Spanish) { thePtr = (Ptr) ((unsigned)SBPkgData + (unsigned)pkgTOC->TE[19].Where); Draw((ShapePtr)thePtr,strtNX,Sverb[1].WYpos + VyTab[RezPtr->verb[1].idx].Syoff); } }

/* * DrawWord5 - draw verb 2 */ void DrawWord5 { Ptr    thePtr;

if (text == English) { thePtr = (Ptr) ((unsigned)SBPkgData + (unsigned)pkgTOC->TE[11].Where); Draw((ShapePtr)thePtr,strtNX,Sverb[2].WYpos + VyTab[RezPtr->verb[2].idx].Eyoff); }   if (text == Spanish) { thePtr = (Ptr) ((unsigned)SBPkgData + (unsigned)pkgTOC->TE[20].Where); Draw((ShapePtr)thePtr,strtNX,Sverb[2].WYpos + VyTab[RezPtr->verb[2].idx].Syoff); } }

/* * DrawWord6 - draw final noun 0 */ void DrawWord6 { short  nounX; Ptr    thePtr;

if (text == English) { nounX = strtNX; if (RezPtr->fNoun[0].EPrep == 2) { /* the */ Draw((ShapePtr)artTab[2].BImage,nounX,Snoun[3].WYpos + artTab[2].Byoff); nounX += (artTab[2].Bwdth + spcNX); }       thePtr = (Ptr) ((unsigned)SBPkgData + (unsigned)pkgTOC->TE[12].Where); Draw((ShapePtr)thePtr,nounX,Snoun[3].WYpos + yTab[RezPtr->fNoun[0].idx].Eyoff); }   if (text == Spanish) { nounX = strtNX; if (RezPtr->fNoun[0].SPrep) { Draw((ShapePtr)artTab[RezPtr->fNoun[0].SPrep].BImage,nounX,Snoun[3].WYpos               + artTab[RezPtr->fNoun[0].SPrep].Byoff); nounX += (artTab[RezPtr->fNoun[0].SPrep].Bwdth + spcNX); }       thePtr = (Ptr) ((unsigned)SBPkgData + (unsigned)pkgTOC->TE[21].Where); Draw((ShapePtr)thePtr,nounX,Snoun[3].WYpos + yTab[RezPtr->fNoun[0].idx].Syoff); } }

/* * DrawWord7 - draw final noun 1 */ void DrawWord7 { short  nounX; Ptr    thePtr;

if (text == English) { nounX = strtNX; if (RezPtr->fNoun[1].EPrep == 2) { /* the */ Draw((ShapePtr)artTab[2].BImage,nounX,Snoun[4].WYpos + artTab[2].Byoff); nounX += (artTab[2].Bwdth + spcNX); }       thePtr = (Ptr) ((unsigned)SBPkgData + (unsigned)pkgTOC->TE[13].Where); Draw((ShapePtr)thePtr,nounX,Snoun[4].WYpos + yTab[RezPtr->fNoun[1].idx].Eyoff); }   if (text == Spanish) { nounX = strtNX; if (RezPtr->fNoun[1].SPrep) { Draw((ShapePtr)artTab[RezPtr->fNoun[1].SPrep].BImage,nounX,Snoun[4].WYpos               + artTab[RezPtr->fNoun[1].SPrep].Byoff); nounX += (artTab[RezPtr->fNoun[1].SPrep].Bwdth + spcNX); }       thePtr = (Ptr) ((unsigned)SBPkgData + (unsigned)pkgTOC->TE[22].Where); Draw((ShapePtr)thePtr,nounX,Snoun[4].WYpos + yTab[RezPtr->fNoun[1].idx].Syoff); } }

/* * DrawWord8 - draw final noun 2 */ void DrawWord8 { short  nounX; Ptr    thePtr;

if (text == English) { nounX = strtNX; if (RezPtr->fNoun[2].EPrep == 2) { /* the */ Draw((ShapePtr)artTab[2].BImage,nounX,Snoun[5].WYpos + artTab[2].Byoff); nounX += (artTab[2].Bwdth + spcNX); }       thePtr = (Ptr) ((unsigned)SBPkgData + (unsigned)pkgTOC->TE[14].Where); Draw((ShapePtr)thePtr,nounX,Snoun[5].WYpos + yTab[RezPtr->fNoun[2].idx].Eyoff); }   if (text == Spanish) { nounX = strtNX; if (RezPtr->fNoun[2].SPrep) { Draw((ShapePtr)artTab[RezPtr->fNoun[2].SPrep].BImage,nounX,Snoun[5].WYpos               + artTab[RezPtr->fNoun[2].SPrep].Byoff); nounX += (artTab[RezPtr->fNoun[2].SPrep].Bwdth + spcNX); }       thePtr = (Ptr) ((unsigned)SBPkgData + (unsigned)pkgTOC->TE[23].Where); Draw((ShapePtr)thePtr,nounX,Snoun[5].WYpos + yTab[RezPtr->fNoun[2].idx].Syoff); } }

/* * MkScrn2 - Build sentence builder screen2. This code gets called only when *         the user is viewing screen1. * */ void MkScrn2 { Ptr        thePtr; Ptr        scnptrsav;

/*    * fill the bkgd screen then draw the huge box */   scnptrsav = scn_ptr; scn_ptr = vidmem5; FilCol = 96; Fill(fullRect, FilCol); /* erase bkgd with same color as already there */ thePtr = mfxDir[getind("hugebox.shp")].Where; Draw((ShapePtr)thePtr, 33, 21); /* draw the huge box shape */

if (!useRTF) DrawBkgd;        /* generate the bkgd image in the huge box */

drawsent; /* Print the sentence in the upper box */

scn_ptr = scnptrsav; /* restore scn_ptr */ NoButs; /* unlink old button strip */ /*    * copy to rear screen, swap, and copy to new rear screen */   copy_bkgd_front;

MkSentBut; /* make buttons for screen 2 */ }

/* * NewSent - call this to redraw just the sentence window of screen 2 */ void NewSent(highword) short highword; { Ptr        scnptrsav;

/*    * fill the sentence window */   scnptrsav = scn_ptr; scn_ptr = vidmem5; Fill(sentRect, 0); /* fill sentence rectangle with white */ switch(highword) { case 0: Fill(iNounRect, selcol); break; case 1: Fill(VerbRect, selcol); break; case 2: Fill(fNounRect, selcol); break; default: break; }   drawsent; /* Print the sentence in the upper box */ scn_ptr = scnptrsav; /* restore scn_ptr */ /*    * copy to rear screen, swap, and copy to new rear screen */   copy_bkgd_front; }

/* * drawsent - this draws the sentence on screen 2 (in the upper box) */ void drawsent { short      sentX; short      sentY; ShapePtr   theShape; Boolean    skipLast;   /* if the Spanish verb phrase "sucks up" the final "el" */ Ptr        thePtr;

sentX = strtNX; sentY = 23;

iNounRect.left = sentX -2; iNounRect.top = sentY; if (text == English) { if (RezPtr->iNoun[TopNoun].EPrep) { Draw((ShapePtr)artTab[RezPtr->iNoun[TopNoun].EPrep].BImage, sentX,                sentY + artTab[RezPtr->iNoun[TopNoun].EPrep].Byoff); sentX += (artTab[RezPtr->iNoun[TopNoun].EPrep].Bwdth + spcNX); }       thePtr = (Ptr) ((unsigned)SBPkgData + (unsigned)pkgTOC->TE[TopNoun+6].Where); Draw((ShapePtr)thePtr,sentX,sentY + yTab[RezPtr->iNoun[TopNoun].idx].Eyoff); /*        * Add the width of the noun shape, plus the standard between word space (spcNX). */       theShape = (ShapePtr)thePtr; sentX += (*theShape).NumWide + spcNX; iNounRect.right = sentX +2 - spcNX; iNounRect.bottom = sentY +15; /*        * Let's see if the verb phrase fits on this line. */       thePtr = (Ptr) ((unsigned)SBPkgData + (unsigned)pkgTOC->TE[MidVerb+9].Where); theShape = (ShapePtr)thePtr; if ((sentX + (*theShape).NumWide) > maxsentX) { sentX = strtNX; sentY = sentY + spcNY; }       /*         * We are now in position to draw verb phrase. */       VerbRect.left = sentX -2; VerbRect.top = sentY; Draw((ShapePtr)thePtr,sentX,sentY + VyTab[RezPtr->verb[MidVerb].idx].Eyoff); sentX += (*theShape).NumWide + spcNX;  /* Width of verb phrase added */ VerbRect.right = sentX +2 - spcNX; VerbRect.bottom = sentY +15;

/*        * We might as well see if we can fit the final noun on the same line. */       thePtr = (Ptr) ((unsigned)SBPkgData + (unsigned)pkgTOC->TE[BotNoun+12].Where); theShape = (ShapePtr)thePtr; if ((sentX + (*theShape).NumWide) > maxsentX) { sentX = strtNX; sentY = sentY + spcNY; }       /*         * We are now in position to draw the final noun. * First we have to draw the "the" (usually) */       fNounRect.left = sentX -2; fNounRect.top = sentY; if (RezPtr->fNoun[BotNoun].EPrep) { Draw((ShapePtr)artTab[RezPtr->fNoun[BotNoun].EPrep].BImage, sentX,                sentY + artTab[RezPtr->fNoun[BotNoun].EPrep].Byoff); sentX += (artTab[RezPtr->fNoun[BotNoun].EPrep].Bwdth + spcNX); }

thePtr = (Ptr) ((unsigned)SBPkgData + (unsigned)pkgTOC->TE[BotNoun+12].Where); theShape = (ShapePtr)thePtr; Draw((ShapePtr)thePtr,sentX,sentY + yTab[RezPtr->fNoun[BotNoun].idx].Eyoff); sentX += (*theShape).NumWide + spcNX; fNounRect.right = sentX +2 - spcNX; fNounRect.bottom = sentY +15; }

if (text == Spanish) { skipLast = false;  /* As of now we will include the el/la for final noun */ /*        * The initial noun is preceeded by an El,La, or nothing */       if (RezPtr->iNoun[TopNoun].SPrep) { Draw((ShapePtr)artTab[RezPtr->iNoun[TopNoun].SPrep].BImage, sentX,               sentY + artTab[RezPtr->iNoun[TopNoun].SPrep].Byoff); sentX += (artTab[RezPtr->iNoun[TopNoun].SPrep].Bwdth + spcNX); }       thePtr = (Ptr) ((unsigned)SBPkgData + (unsigned)pkgTOC->TE[TopNoun+15].Where); Draw((ShapePtr)thePtr,sentX,sentY + yTab[RezPtr->iNoun[TopNoun].idx].Syoff); /*        * Add the width of the noun shape, plus the standard between word space (spcNX). */       theShape = (ShapePtr)thePtr; sentX += (*theShape).NumWide + spcNX; iNounRect.right = sentX +2 - spcNX; iNounRect.bottom = sentY +15; /*        * Let's see if the verb phrase fits on this line. */       thePtr = (Ptr) ((unsigned)SBPkgData + (unsigned)pkgTOC->TE[MidVerb+18].Where); theShape = (ShapePtr)thePtr; if ((sentX + (*theShape).NumWide) > maxsentX) { sentX = strtNX; sentY = sentY + spcNY; }       /*         * We are now in position to draw verb phrase. */       VerbRect.left = sentX -2; VerbRect.top = sentY; Draw((ShapePtr)thePtr,sentX,sentY + VyTab[RezPtr->verb[MidVerb].idx].Syoff); sentX += (*theShape).NumWide + spcNX;  /* Width of verb phrase added (for now) */ /*        * Here's the semi-tricky part. If the verb ends with "de", and the * final noun begins with "el", an "el" shape must be positioned so that * the "e"s from the "de" and "el" "are one". The final noun would then * be drawn after the "del", or even on the next line if necessary. *        * The same bit of trickery applies to verbs ending in "a" combined * with "el" starting final nouns. The "a" becomes "al". *        * I guess the first thing to check is if the final noun starts with "el" */       if (RezPtr->fNoun[BotNoun].SPrep == 4) { /* 4 = "el" */ switch (RezPtr->verb[MidVerb].Suffix) { case 7: /* ends in "de", backspace and draw the "el" shape */ sentX -= (7 + spcNX); Draw((ShapePtr)artTab[4].BImage,sentX,sentY + artTab[4].Byoff); sentX += (artTab[4].Bwdth + spcNX); skipLast = true; break; case 8: /* ends in "a", backspace and draw the "al" shape */ sentX -= (7 + spcNX); Draw((ShapePtr)artTab[8].BImage,sentX,sentY + artTab[8].Byoff); sentX += (artTab[8].Bwdth + spcNX); skipLast = true; break; default: break; }       }        VerbRect.right = sentX +2 - spcNX; VerbRect.bottom = sentY +15; /*        * We might as well see if we can fit the final noun on the same line. */       thePtr = (Ptr) ((unsigned)SBPkgData + (unsigned)pkgTOC->TE[BotNoun+21].Where); theShape = (ShapePtr)thePtr; if ((sentX + (*theShape).NumWide) > maxsentX) { sentX = strtNX; sentY = sentY + spcNY; }       /*         * We are now in position to draw the final noun. * See if we need an "el" or "la". */       fNounRect.left = sentX -2; fNounRect.top = sentY; if (!skipLast) {

if (RezPtr->fNoun[BotNoun].SPrep) { Draw((ShapePtr)artTab[RezPtr->fNoun[BotNoun].SPrep].BImage, sentX,                   sentY + artTab[RezPtr->fNoun[BotNoun].SPrep].Byoff); sentX += (artTab[RezPtr->fNoun[BotNoun].SPrep].Bwdth + spcNX); }       }        thePtr = (Ptr) ((unsigned)SBPkgData + (unsigned)pkgTOC->TE[BotNoun+21].Where); theShape = (ShapePtr)thePtr; Draw((ShapePtr)thePtr,sentX,sentY + yTab[RezPtr->fNoun[BotNoun].idx].Syoff); sentX += (*theShape).NumWide + spcNX; fNounRect.right = sentX +2 - spcNX; fNounRect.bottom = sentY +15; }   Draw((ShapePtr)perPtr,sentX -3,sentY + 8); /* don't forget the period */ }

/* * DoRTF - Play one of the little rtf's in the middle of the screens in Plane A *        Let the sentence window and button strip show through from Plane B */ void DoRTF { int    stat;

theLine = rtfline; RTFctr = 3;    /* play each real time file three times */

RTFfid = open_file(RTFName, false);

stat = play_recs(RTFfid, reinit_rtf, 1, false, false, 0); /* play first frame and return */

MkScrn2;         /* Draw screen2 */ RTFMatteOn;      /* turn on the middle 140 scan lines of plane A */ /*    * make sure the matte instructions are in effect before fading up the screen */   swapflag = false;   /*  scan line interrupt will set to allow next frame */ dc_ssig(vidpath,SLI_SIGNAL,0); /* set for next scan line interrupt */ while (!swapflag);

FadeUp(meddisolve, false);

SaySent;         /* say the sentence */ MoveBut(true);     /* move buttons down */

stat = play_recs(RTFfid, reinit_rtf, 1, true, false, 0); /* start play rest of file */

/*    * This continues in the main loop of screen 2 code */ }

/* * ReDoRTF - Play one of the little rtf's in the middle of the screens in Plane A *        Let the sentence window and button strip show through from Plane B */ void ReDoRTF { int    stat;

RTFfid = open_file(RTFName, false); stat = play_recs(RTFfid, reinit_rtf, 1, false, false, 0); /* play first frame and return */

if (RTFctr == 3) { SaySent;         /* say the sentence */ MoveBut(true);     /* move buttons down */ }

stat = play_recs(RTFfid, reinit_rtf, 1, true, false, 0); /* start play rest of file */ /*    * This continues in the main loop of screen 2 code */ }

/* * ChkRTF - this checks to see if an rtf exists for the sentence to display */ void ChkRTF {

useRTF = false;

if (SentNum == SBPkgTab[WhichSBPkg].RTFNum0) { RTFName = (char *)SBPkgTab[WhichSBPkg].RTFName0; useRTF = true; }   if (SentNum == SBPkgTab[WhichSBPkg].RTFNum1) { RTFName = (char *)SBPkgTab[WhichSBPkg].RTFName1; useRTF = true; } }

/* * DrawBkgd - This is the code that generates the backgrounds *         used for Sentence Builder. */

void DrawBkgd { Rect       theRect; SBBkgdPtr  BkgdRez; short      BkgdStripID; short      BkgdID;

BkgdID = (RezPtr->packData[SentNum].BkgdVer[WhichBkgd]) - 1; STATUS2("BkgdID = %d\n", BkgdID); WhichBkgd ^= 1; /* toggle for next time */ /*    * Get the bkgd type (scroll, static) */   if (RezPtr->packData[SentNum].BkgdType) { /* true means scrolling */ initScroll; }   else { /* non-scrolling background */ /*        * Point at the resource for this background */       if (BkgdID <= 139) BkgdRez = BGPtr0; else { BkgdRez = BGPtr1; BkgdID -= 140; }       if (BkgdRez->stripID[BkgdID].dividingYPos == 0) { theRect = BkgdRect; /* first set the rectangle to the entire window */ Fill(theRect, BkgdRez->stripID[BkgdID].topColor); }       else { if (BkgdRez->stripID[BkgdID].dividingYPos != -1) { theRect = BkgdRect; /* first set the rectangle to the entire window */ theRect.bottom = theRect.top + BkgdRez->stripID[BkgdID].dividingYPos; Fill(theRect, BkgdRez->stripID[BkgdID].topColor); /*                * Do the bottom color */               theRect = BkgdRect; /* reset the rectangle to the entire window */ theRect.top = theRect.top + BkgdRez->stripID[BkgdID].dividingYPos; Fill(theRect, BkgdRez->stripID[BkgdID].bottomColor); /*                * draw a horizon line */               theRect = BkgdRect; /* reset the rectangle to the entire window */ theRect.top = theRect.top + BkgdRez->stripID[BkgdID].dividingYPos; theRect.bottom = theRect.top +1; Fill(theRect, 127); }       }        /*         * Load the background strip (maybe) * Draw it if there is one. * Otherwise draw a horizon line. */       BkgdStripID = BkgdRez->stripID[BkgdID].stripIdx; if (BkgdStripID) { BkgdStripID--; /* to make index start at 0 */ loadOne(bkgdfid, BGTOC, BkgdStripID, BkgdBuf); Draw((ShapePtr)BkgdBuf, BkgdRect.left -1, BkgdRect.top -1 + BkgdRez->stripID[BkgdID].stripYpos); }   } }

/* * initScroll - This sets up the scrollband(s) for the background * whose index is stored in the global variable "daBkgd" * * This really needs to be called **AFTER EACH RESOLVE** as these * shapes aren't included in mfxDir and stuffing there indivdual * names into the scene's ItemDir would be useless. */ void initScroll { ItemShpPtr theShp; short      ctr; Rect       theRect;

ScrlID = (RezPtr->packData[SentNum].BkgdVer[WhichBkgd]) - 1; /* STATUS2("ScrollID is %d\n",ScrlID); */

/*    * Point at the resource for this scrolling thing */   ScrlRez = SCPtr0;

/*    * If the dividing ypos is 0 or -1, don't fill */   if ((ScrlRez->scrollID[ScrlID].dividingYPos != 0) &&     (ScrlRez->scrollID[ScrlID].dividingYPos != -1)) { theRect = BkgdRect; /* first set the rectangle to the entire window */ theRect.bottom = theRect.top + ScrlRez->scrollID[ScrlID].dividingYPos; Fill(theRect, ScrlRez->scrollID[ScrlID].topColor); /*        * Do the bottom color */       theRect = BkgdRect; /* reset the rectangle to the entire window */ theRect.top = theRect.top + ScrlRez->scrollID[ScrlID].dividingYPos; Fill(theRect, ScrlRez->scrollID[ScrlID].bottomColor); /*        * draw a horizon line */       theRect = BkgdRect; /* reset the rectangle to the entire window */ theRect.top = theRect.top + ScrlRez->scrollID[ScrlID].dividingYPos; theRect.bottom = theRect.top +1; Fill(theRect, 127); }   /*     * Set up the twelve scrolling shapes * The image addresses are being stuffed directly without inserting their names * into the Item Directory of the scene. Make sure resolve doesn't get called anywhere!!! */   for (ctr=0; ctr<6; ctr++) { theShp = (ItemShpPtr)((unsigned) ScrlScene0 + (unsigned) ScrlScene0->ItemDir[ctr].Where); theShp->ShpIA = (ShapePtr) ((unsigned)SCData +        (unsigned)SCTOC->TE[ScrlRez->scrollID[ScrlID].rItmIdx[ctr].itemIdx -1].Where); theShp->Gen.IIActive = theShp->Gen.IIDisplay = false; theShp->Pos.IIBaseX = BkgdRect.right; theShp->Pos.IIBaseY = ScrlRez->scrollID[ScrlID].rYPos - theShp->ShpIA->NumHigh + BkgdRect.top; theShp->Pos.IIXVel = ScrlRez->scrollID[ScrlID].rXVel; /* now do front scroll band */ theShp = (ItemShpPtr)((unsigned) ScrlScene1 + (unsigned) ScrlScene1->ItemDir[ctr].Where); theShp->ShpIA = (ShapePtr) ((unsigned)SCData +        (unsigned)SCTOC->TE[ScrlRez->scrollID[ScrlID].fItmIdx[ctr].itemIdx -1].Where); theShp->Gen.IIActive = theShp->Gen.IIDisplay = false; theShp->Pos.IIBaseX = BkgdRect.right; theShp->Pos.IIBaseY = ScrlRez->scrollID[ScrlID].fYPos - theShp->ShpIA->NumHigh + BkgdRect.top; theShp->Pos.IIXVel = ScrlRez->scrollID[ScrlID].fXVel; }   NxtRScrl = 0;   /* introduce item #0 next for rear band at next code line number of ticks */ ScrlRez->scrollID[ScrlID].rCtr = ScrlRez->scrollID[ScrlID].rItmIdx[NxtRScrl].ticksToNext; NxtFScrl = 0;  /* introduce item #0 next for front band */ ScrlRez->scrollID[ScrlID].fCtr = ScrlRez->scrollID[ScrlID].fItmIdx[NxtFScrl].ticksToNext; ScrlScene0->Active = ScrlScene0->Display = true; ScrlScene1->Active = ScrlScene1->Display = true; ScrlScene0->NumItems = ScrlScene1->NumItems = 6; ReinitScene(ScrlScene0); ReinitScene(ScrlScene1); }

/* * CheckScroll - This sees if any items need to be removed or added to the scroll bands */ void CheckScroll { short      ctr; ItemShpPtr theShp;

/*    * I'm assuming there will always be two scroll bands active or none */   if (!ScrlScene0->Active) return; /* scrolling is not active? */

for (ctr=0; ctr<6; ctr++) { theShp = (ItemShpPtr)((unsigned) ScrlScene0 + (unsigned) ScrlScene0->ItemDir[ctr].Where); if ((theShp->Pos.IBaseX == 0) || (theShp->Pos.IBaseX + theShp->Pos.IXVel < 0)) { /* STATUS2("IBaseX = %d\n",theShp->Pos.IBaseX); */ ReinitShp(theShp); }       theShp = (ItemShpPtr)((unsigned) ScrlScene1 + (unsigned) ScrlScene1->ItemDir[ctr].Where); if ((theShp->Pos.IBaseX == 0) || (theShp->Pos.IBaseX + theShp->Pos.IXVel < 0)) { /* STATUS2("IBaseX = %d\n",theShp->Pos.IBaseX); */ ReinitShp(theShp); }   }

if (ScrlScene0->Frame >= ScrlRez->scrollID[ScrlID].rCtr) { /* STATUS1("Trying to intro new rear item\n"); */ theShp = (ItemShpPtr)((unsigned) ScrlScene0 + (unsigned) ScrlScene0->ItemDir[NxtRScrl].Where); if (!theShp->Gen.IActive) { /* only if it's not being used */ theShp->Gen.IActive = theShp->Gen.IDisplay = true; NxtRScrl++; if (NxtRScrl == ScrlScene0->NumItems) NxtRScrl = 0; ScrlRez->scrollID[ScrlID].rCtr = ScrlRez->scrollID[ScrlID].rItmIdx[NxtRScrl].ticksToNext + ScrlScene0->Frame; }   }

if (ScrlScene1->Frame >= ScrlRez->scrollID[ScrlID].fCtr) { /* STATUS1("Trying to intro new front item\n"); */ theShp = (ItemShpPtr)((unsigned) ScrlScene1 + (unsigned) ScrlScene1->ItemDir[NxtFScrl].Where); if (!theShp->Gen.IActive) { /* only if it's not being used */ theShp->Gen.IActive = theShp->Gen.IDisplay = true; NxtFScrl++; if (NxtFScrl == ScrlScene1->NumItems) NxtFScrl = 0; ScrlRez->scrollID[ScrlID].fCtr = ScrlRez->scrollID[ScrlID].fItmIdx[NxtFScrl].ticksToNext + ScrlScene1->Frame; }   } }

snapshot.c
/******************************************************************************* file: snapshot.c                                              Richard Pferdner Douglas Corarito

capture memory map and print it out

SCCS: @(#)snapshot.c  1.1 4/9/91

7/2/92 DCC Added fflush,sleep and added error functionality to asm call

(C) Copyright 1990 American Interactive Media, All Rights Reserved


 * 1) include <stdio.h>
 * 2) include <modes.h>


 * 1) ifdef WANT_SNAPSHOT

void snapshot {   unsigned int blockmap[128];         /* map of free fragments */ unsigned int blockinfo[4]; unsigned int *blockptr; char mem_type;

blockptr = blockmap; if ( getblkmap( blockptr, blockinfo ) == -1 ) {           printf("Error while getting block map\n");fflush(stdout); return; }

printf( "Minimum alloc size   = 0x%8X (%8d)\n",             blockinfo[0], blockinfo[0] );

printf( "# fragments in system = 0x%8X (%8d)\n",             blockinfo[1], blockinfo[1] );

printf( "Total RAM at startup  = 0x%8X (%8d)\n",             blockinfo[2], blockinfo[2] );

printf( "Current free RAM      = 0x%8X (%8d)\n",             blockinfo[3], blockinfo[3] );

printf( "Dump of memory fragment info: \n" );

while ( (*blockptr != 0) && ((int)(blockptr-blockmap) < 128 ) ) {       if ( *blockptr < 0x080000 )     /* plane A */ mem_type = 'A';

else if ( *blockptr < 0x0FFFFF )   /* plane B */ mem_type = 'B';

/*       note: as of 10/90 the address of FMV is not specified. This is a guess. NOT USED *** DCC

else if ( *blockptr < 0x180000 ) mem_type = 'C';

else mem_type = 'S';

printf( "address = [%c]0x%06X, size = 0x%8X (%8d) \n",                 mem_type, *blockptr, *(blockptr + 1), *(blockptr + 1) );

blockptr += 2; }

fflush(stdout); sleep(5); return; }

/* getblkmap: loads memory map - d0 = *blockmap, d1 = *blockinfo */

getblkmap: movem.l d0-d3/a0-a1,-(sp)  ; save regs movea.l d0,a0              ; set ptr = blockmap movea.l d1,a1              ; set a1 = info area move.l #0,d0               ; mem to start at    move.l  #(128*8),d1         ; length of map OS9    F$GBlkMp            ; get map info bcs.s  gbm_error           ; check for error move.l d0,(a1)+            ; save min alloc size move.l d1,(a1)+            ; # frags move.l d2,(a1)+            ; total RAM at startup move.l d3,(a1)             ; total free RAM now move.l #0,d0               ; set no error gbm_done movem.l (sp)+,d0-d3/a0-a1  ; restore regs rts                        ; and return gbm_error move.l #-1,d0              ;set error bra.s  gbm_done            ;leave
 * asm
 * 1) endasm


 * 1) endif


 * 1) ifdef WANT_TRACKMEM

long gNumPtrs = 0; long gNumAPtrs = 0; long gNumBPtrs = 0;

char * TrackAllocate(size, type) int size; int type; {   char * ptr; unsigned long p;

ptr = (char *)srqcmem(size,type); if ( (int)(ptr) == -1 ) {           printf("Error requesting %d bytes.\n", size);fflush(stdout);sleep(1); return(-1); }

gNumPtrs += 1;

printf("ALLOCATED %d bytes in ",size); p = (unsigned long)ptr; if ( (p>0x00000000)&&(p<0x00080000) ) {           printf("A at 0x%X.",p); gNumAPtrs += 1; }   else if ( (p>0x00080000)&&(p<0x00100000) ) {           printf("B at 0x%X.",p); gNumBPtrs += 1; }   else {           printf("S at 0x%X.",p); }

printf(" [PA=%d,PB=%d,All=%d]\n",gNumAPtrs,gNumBPtrs,gNumPtrs); fflush(stdout);sleep(1);

return(ptr); }

int TrackDeallocate(size,address) int size; char *address; {   unsigned long p;

if ( _srtmem(size,address) == -1 ) {           printf("Error deallocating %d bytes at 0x%X\n",size,address); return(-1); }

printf("DEALLOCATED %d bytes at 0x%X",size,address); p = (unsigned long)address; if ( (p>0x00000000)&&(p<0x00080000) ) gNumAPtrs -= 1; if ( (p>0x00080000)&&(p<0x00100000) ) gNumBPtrs -= 1; gNumPtrs -= 1;

printf(" [PA=%d,PB=%d,All=%d]\n",gNumAPtrs,gNumBPtrs,gNumPtrs); fflush(stdout);sleep(1);

return(0); }


 * 1) endif


 * 1) ifdef WANT_TRACKSND

long gNumSMaps = 0;

int TrackSnd(snd_path, snd_type, snd_grps, snd_buf) int snd_path; int snd_type; short snd_grps; char **snd_buf; {   int smap_id;

smap_id = sm_creat(snd_path, snd_type, snd_grps, snd_buf); if ( smap_id == -1 ) {       printf("Can't get smap_id\n"); }

gNumSMaps += 1;

printf("SND CREATED: %d bytes at 0x%X id = %d\n",snd_grps * 128, *snd_buf, smap_id );

printf("gNumSMaps = %d\n", gNumSMaps); fflush(stdout);sleep(1);

return(smap_id); }

int UntrackSnd(snd_path, smap_id) int snd_path; int smap_id; {

if ( sm_close(snd_path, smap_id) == -1 ) {           printf("Error deallocating sound map\n"); return(-1); }   gNumSMaps -= 1; printf("SND DESTROYED: id = %d \n", smap_id);

printf("gNumSMaps = %d\n", gNumSMaps); fflush(stdout);sleep(1);

return(0); }


 * 1) endif

sound.c

 * 1) include <stdio.h>
 * 2) include <errno.h>
 * 3) include <cdfm.h>
 * 4) include <modes.h>
 * 5) include <csd.h>
 * 6) include <aimdef.h>
 * 7) include <procid.h>
 * 8) include <iff.h>
 * 9) include <memory.h>


 * 1) include "dbg.h"


 * 1) include "utility.h"
 * 2) include "sound.h"
 * 3) include "rtf.h"
 * 4) include "file_mgr.h"  /* for 'eor_ctr' */

snd_pair       snd_array[max_smaps];

Boolean        smap_busy; int            cur_aud_fid; int            cur_aud_channel; static int     pause_aud_fid;  /* holds cur_aud_fid during an ss_pause so we can clear cur_aud_fid */ static int     last_aud_fid; static int     last_aud_channel; static int     bkgd_audio_stat; static int     smap_list[smap_list_size]; static int     smap_list_next; /* index to next soundmap to start */ static int     smap_list_last; /* always pointing at next free space in list */ int            smap_list_ctr;  /* number of soundmaps in list */ Boolean        bkgd_audio_loop;

static STAT_BLK    s_b_a_stat;     /* background audio status block */ STAT_BLK       smap_stat;      /* soundmap status block */

static int     alarm_stat; /* return status from alarm calls */ int            fx_alarm_id; Boolean        fx_alarm_stat;  /* wether alarm is on or not */

/* * setup_audio - */ void setup_audio { short      ctr; char       *aud_dev;

if ((aud_dev = csd_devname( DT_AUDIO, 1 )) == NULL ) { STATUS1("Couldn't get aud_dev name\n"); exit(0); }   if ( (int)((audpath = open( aud_dev, (S_IREAD | S_IWRITE)))) == SYSERR ) { STATUS1("Couldn't open audpath\n"); exit(0); }   free( aud_dev );

if ( sc_atten( audpath, 0x00000000 ) == SYSERR ) { STATUS1("Couldn't set attenuation\n"); exit(0); }   cur_aud_fid = 0; smap_busy = false; stop_all_audio;  /* reset most other sound variables */

fx_alarm_stat = false; for (ctr = 0; ctr < max_smaps; ctr ++) { snd_array[ctr].smap_id = 0; } }

int start_fx_alarm {   if (!fx_alarm_stat) { fx_alarm_id = alm_cycle(FX_ALARM_SIGNAL, 0x80000A00); /* every 10 seconds */ if (fx_alarm_id == -1) { STATUS2("Couldn't set fx_alarm_id. Error #%d\n", errno); return(-1); }       fx_alarm_stat = true; }   return(0); }

int stop_fx_alarm {   if (fx_alarm_stat) { alarm_stat = alm_delete(fx_alarm_id); if (alarm_stat == -1) { STATUS2("Couldn't clear fx_alarm_id. Error #%d\n", errno); return(-1); }       fx_alarm_stat = false; }   return(0); }

int start_bkgd_audio(BGChan, theFID, loop) short BGChan; int theFID; Boolean loop; {

if (cur_aud_fid) { STATUS1("cur_aud_fid is still set in start_bkgd_audio\n"); ss_abort (cur_aud_fid); while(cur_aud_fid);    /* wait for the abort signal */ }   s_b_a_stat.asy_sig = 0; s_b_a_stat.asy_stat = 0; ss_seek(theFID,0,&s_b_a_stat); while (!(s_b_a_stat.asy_stat & 0x8001));   /* wait for done bit or error bit */ if (s_b_a_stat.asy_stat & 0x8000) { STATUS2("Error %d occured during seek\n",s_b_a_stat.asy_sig); STATUS2("asy_sig = 0x%x\n",s_b_a_stat.asy_sig); STATUS2("asy_stat = 0x%x\n",s_b_a_stat.asy_stat); /* tsleep(100); */ /* about one second */ s_b_a_stat.asy_sig = 0; s_b_a_stat.asy_stat = 0; ss_seek(theFID,0,&s_b_a_stat); while (!(s_b_a_stat.asy_stat & 0x8001));   /* wait for done bit or error bit */ if (s_b_a_stat.asy_stat & 0x8000) DoDirtyDisc; /* we don't come back here */ }   setup_bkgd_audio_rtf(BGChan); eor_ctr = 1; ss_play(theFID,thePCB); cur_aud_fid = theFID; cur_aud_channel = BGChan; bkgd_audio_loop = loop; if (bkgd_audio_loop) { last_aud_fid = cur_aud_fid; last_aud_channel = cur_aud_channel; }   return(0); }

int start_soundmap(smap_id) int smap_id; {

if (smap_busy) { /* there is still a soundmap playing - queue this one */ smap_list[smap_list_last] = smap_id; smap_list_last++; if (smap_list_last == smap_list_size) smap_list_last = 0; smap_list_ctr++; }   else { /* just play the soundmap */ smap_busy = true; smap_stat.asy_sig = SM_OUT_SIGNAL; smap_stat.asy_stat = 0; if (sm_out(audpath, smap_id, &smap_stat) == -1) { STATUS2("error 0x%x in start_soundmap\n", errno); smap_busy = false; return(-1); }   }    return(0); }

/* * update_audio - this needs to be in the main loop of the application * * 1 - check if there are soundmaps waiting to be played. * 2 - see if bkgd audio is stopped and 'bkgd_audio_loop' is set. * 3 - */ void update_audio {

if (smap_list_ctr) { /* any sounds in the queue ? */       if (!smap_busy) { /* if one is not currently playing */ /* STATUS1("playing from the soundmap queue\n"); */ start_soundmap(smap_list[smap_list_next]); smap_list_next++; if (smap_list_next == smap_list_size) smap_list_next = 0; smap_list_ctr--; }   }    else if ((!eor_ctr) && (bkgd_audio_loop)) { STATUS1("restarting the background audio\n"); start_bkgd_audio(last_aud_channel, last_aud_fid, true); } }

/* * stop_all_audio */ void stop_all_audio {   if (cur_aud_fid) ss_abort(cur_aud_fid); if (smap_busy) sm_off(audpath); smap_list_next = 0; /* index to next soundmap to start */ smap_list_last = 0; /* index to last soundmap in list */ smap_list_ctr = 0; /* number of soundmaps in list */ bkgd_audio_loop = false; smap_busy = false; /* should be cleared by signal handler */ cur_aud_fid = 0;   /* should be cleared by signal handler */ cur_aud_channel = 0; }

/* * close_snd_stuff - */ void close_snd_stuff {

close(audpath);

}

startup.c

 * 1) include <stdio.h>
 * 2) include <modes.h>
 * 3) include <csd.h>
 * 4) include <errno.h>
 * 5) include <cdfm.h>
 * 6) include <aimdef.h>
 * 7) include <ucm.h>
 * 8) include <memory.h>
 * 9) include <rtr.h>


 * 1) include "dbg.h"


 * 1) include "utility.h"
 * 2) include "rtf.h"
 * 3) include "screen.h"
 * 4) include "sentbld.h"
 * 5) include "startup.h"
 * 6) include "asm_itrfc.h"
 * 7) include "reading.h"
 * 8) include "buttons.h"

/* * This is the star cursor */ static short StarCur[16] = { 0x0080,0x0180,0x01C0,0x03E0, 0x03F1,0x47FF,0xFFFF,0x7FFE, 0x3FFC,0x1FF8,0x0FF8,0x0FF8, 0x0FFC,0x1F7C,0x3E1C,0x780E };

/* * Init the player for our stuff */

void setup_CDI { short  ctr, index; char   *ptr1, *ptr2;

dc_intl(vidpath,0);

if (PALflag) { lct_pal_a = dc_crlct(vidpath,PA,20*2,RES_NORMAL); lct_pal_b = dc_crlct(vidpath,PB,20*2,RES_NORMAL); dc_flnk(vidpath,fctid_RL7,lct_pal_a,0*2); dc_flnk(vidpath,fctid_Clut7,lct_pal_b,0*2); dc_llnk(vidpath,lct_pal_a,19*2,lctid0,0*2); dc_llnk(vidpath,lct_pal_b,19*2,lctid2,0*2); dc_llnk(vidpath,lctid0,239*2,lct_pal_a,0*2); dc_llnk(vidpath,lctid2,239*2,lct_pal_b,0*2); }   else { dc_flnk(vidpath,fctid_RL7,lctid0,0*2); dc_flnk(vidpath,fctid_Clut7,lctid2,0*2); }   /*     * Initialize the FCTs */   dc_wrfi(vidpath,fctid_RL7,0,cp_icm(ICM_CLUT7,ICM_CLUT7,NM_1,EV_OFF,CS_A)); dc_wrfi(vidpath,fctid_RL7,1,cp_dprm(RMS_RL,PRF_X2,BP_NORMAL)); dc_wrfi(vidpath,fctid_RL7,2,cp_icf(PA,ICF_MIN)); dc_wrfi(vidpath,fctid_RL7,3,cp_po(PR_AB)); dc_wrfi(vidpath,fctid_RL7,4,cp_tci(MIX_ON,TR_CKEY_T,TR_OFF)); dc_wrfi(vidpath,fctid_RL7,5,cp_phld(PA,PH_OFF,0)); dc_wrfi(vidpath,fctid_RL7,6,cp_tcol(PA,16,235,16)); dc_wrfi(vidpath,fctid_RL7,7,cp_mcol(PA,0,0,0)); dc_wrfi(vidpath,fctid_RL7,8,cp_bkcol(BK_LOW, BK_BLACK)); dc_wrfi(vidpath,fctid_RL7,10,cp_cbnk(0)); dc_wrfi(vidpath,fctid_RL7,75,cp_cbnk(1)); for (ctr=138; ctr<150; ctr++) { dc_wrfi(vidpath,fctid_RL7,ctr,cp_nop); /* clear the clut instr. left from the bumper */ }

dc_wrfi(vidpath,fctid_Clut7,1,cp_dprm(RMS_NORMAL,PRF_X2,BP_NORMAL)); dc_wrfi(vidpath,fctid_Clut7,2,cp_icf(PB,ICF_MIN)); dc_wrfi(vidpath,fctid_Clut7,3,cp_nop); dc_wrfi(vidpath,fctid_Clut7,4,cp_nop); dc_wrfi(vidpath,fctid_Clut7,5,cp_phld(PB,PH_OFF,0)); dc_wrfi(vidpath,fctid_Clut7,7,cp_nop); dc_wrfi(vidpath,fctid_Clut7,9,cp_nop); dc_wrfi(vidpath,fctid_Clut7,10,cp_cbnk(2)); dc_wrfi(vidpath,fctid_Clut7,75,cp_cbnk(3));

/*    * load and install the Stickybear palette. */   DirNum = 0;                 /* mfxdir starts with no items */ index = loadthing("sbclut"); if (index != -1) { ptr1 = (char *)(mfxDir[index].Where + 12); StorePalette(ptr1); }   else { STATUS1("can't find sbclut\n"); }   /*     * Change cursor to star */   pt_org(vidpath,0,0); gc_org(vidpath,0,0); gc_ptn(vidpath,8,8,16,16,0,StarCur); inp_col = 0x80808000; /* yellow - intensity bit (bit 31) on */ gc_col(vidpath,inp_col); gc_blnk(vidpath,0x00000070);

/*    * Allocate screen memory (40 sectors for Clut7, 7 sectors for RL7) */   vidmem0 = (Ptr)ALLOCATE(RL7Size * FORM2_SECTOR,VIDEO1); if (vidmem0 == (Ptr)-1L) { STATUS1("FAILURE MEMORY => vidmem0"); }

vidmem1 = (Ptr)ALLOCATE(RL7Size * FORM2_SECTOR,VIDEO1); if (vidmem1 == (Ptr)-1L) { STATUS1("FAILURE MEMORY => vidmem1"); }

/*    * clear both RL7 buffers */   ptr1 = (char *)vidmem0; ptr2 = (char *)vidmem1; for (ctr = 0; ctr < 240; ctr ++) { *ptr1++ = 0x8F00; *ptr2++ = 0x8F00; }

vidmem2 = (Ptr)ALLOCATE(384 * 240,VIDEO2); /* screen 0 for our stuff (plane B) */ if (vidmem2 == (Ptr)-1L) { STATUS1("FAILURE MEMORY => vidmem2"); }

vidmem3 = (Ptr)ALLOCATE(384 * 240,VIDEO2); /* screen 1 for our stuff (plane B) */ if (vidmem3 == (Ptr)-1L) { STATUS1("FAILURE MEMORY => vidmem3"); }

vidmem4 = (Ptr)ALLOCATE(384 * 70,VIDEO2); /* button strip (plane B) */ if (vidmem4 == (Ptr)-1L) { STATUS1("FAILURE MEMORY => vidmem4"); }

vidmem5 = (Ptr)ALLOCATE(384 * 240,VIDEO2); /* bkgd screen for our stuff (plane B) */ if (vidmem5 == (Ptr)-1L) { STATUS1("FAILURE MEMORY => vidmem5"); }

/*    * Initialize LCT */   dc_wrli(vidpath,lctid0,0*2,0,cp_dadr((int)vidmem0)); dc_wrli(vidpath,lctid2,0*2,0,cp_dadr((int)vidmem2)); if (PALflag) { for (ctr = 0; ctr < 20; ctr++) { dc_wrli(vidpath,lct_pal_a,ctr*2,0,cp_dadr((int)vidmem0)); dc_wrli(vidpath,lct_pal_b,ctr*2,0,cp_dadr((int)vidmem2)); }   }

/*    * these are for our animation system */   scn_ptr = vidmem3;      /* since we start by showing vidmem2 for clut7 */ EraPtr = &EraTab3;     /* the erase table for vivmem3 */ EraTab2.EraCtr = 0;    /* no erase rectangles for screen 0 (vidmem2) */ EraTab3.EraCtr = 0;    /* no erase rectangles for screen 1 (vidmem3) */ EraSrc = vidmem5;      /* set the erase source screen to be our Bkgd screen */ swapflag = true;       /* we are not waiting for a swap to occur */ DirNum = 0;            /* we don't need the sbclut entry in mfxdir anymore */ for (ctr=0; ctr < maxScenes; ctr++) /* Initialize the scene table */ SceneTab[ctr] = 0; /*    * The components that are used to make all buttons in the program */   ButtonBuf = (char *)ALLOCATE(FORM1_SECTOR * ButtonBufSize, VIDEO1); if (ButtonBuf == (char *)-1L) { STATUS1("Can't allocate ButtonBuf\n"); }   butTOC = (TOCPtr)ButtonBuf; /* table of contents is first at buttonbuf */ /*    * open the button speech files */   Eng_button_fid = open_file("BUTTON.Eng.rtf", false); Span_button_fid = open_file("BUTTON.Span.rtf", false);

}

/* * This function installs the 128 color palette whose pointer is passed. */ Boolean StorePalette(rgbdata) char *rgbdata; {   char *b; char red,green,blue; short i;

b = rgbdata;

for (i=0;i<64;i++) { red = *b++; green = *b++; blue = *b++; dc_wrfi(vidpath,fctid_RL7,11+i,cp_clut(i,red,green,blue)); dc_wrfi(vidpath,fctid_Clut7,11+i,cp_clut(i,red,green,blue)); }   for (i=0;i<64;i++) { red = *b++; green = *b++; blue = *b++; dc_wrfi(vidpath,fctid_RL7,76+i,cp_clut(i,red,green,blue)); dc_wrfi(vidpath,fctid_Clut7,76+i,cp_clut(i,red,green,blue)); }   return(true); }

utility.c

 * 1) include <stdio.h>
 * 2) include <errno.h>
 * 3) include <modes.h>
 * 4) include <aimdef.h>
 * 5) include <cdfm.h>
 * 6) include <rtr.h>
 * 7) include <ucm.h>
 * 8) include <memory.h>
 * 9) include <time.h>


 * 1) include "dbg.h"


 * 1) include "animation.h"
 * 2) include "utility.h"
 * 3) include "screen.h"
 * 4) include "sentbld.h"
 * 5) include "rtf.h"
 * 6) include "reading.h"
 * 7) include "cursor_mgr.h"
 * 8) include "sound.h"
 * 9) include "file_mgr.h"

unsigned short ranctr;  /* index to random number table */ static short   rantab[ransize] = {

99,126, 13, 28, 51, 40,246,141, 14, 55, 88,255, 11,201,208, 66,   136, 73 ,75,144,214,192,122,150,102,190,182,139,225,167,153,  8,     36, 13, 62,171, 46, 72,115,240, 31,166,251,  0,174,124,225,178,    199,230, 70, 31,  7, 79,184, 32,165,249,146, 10, 16, 52,200,166,     32,110,142,157,180,230,112, 74, 75,116,179, 22,102,  6, 13, 60,    195,132, 66, 78,147,194,184,194,164,199,190,148, 12,142,196, 48,     76, 21, 70,179, 19,112,156,212, 71,206,191,  8,182,164,198,107,    182,239, 79, 47, 92,233,136, 42,174,100,203,255, 32,157, 49,116,     89,167,122,226,249,180,137,100,212,185,130,115,195, 22, 50,165,    146,  8, 10, 72, 88,134,131,170,141,161,199,156, 28,119,173, 78,     53, 37, 79,188, 49, 89,132,189,176, 55, 94,207,126, 47, 47, 67,     74,250, 90,246 ,84,225, 59, 52,117,230,127,179,212, 69,217,216,    237,127,219,234,  1,182,131, 94,152,194,131, 42,122,151, 91,205,     79, 16, 18, 58,128,107,133,142,113,148,207,165,217,159,213, 68,     28,226, 19,128, 38, 64,176,232, 20,155,143,148, 66,113,215,167,    191, 34,130,119, 95,235,177, 93, 58, 52,138,  1,229,  9,158,158,     24,244,131,146,  2,189,139, 34, 64,106,139, 49, 62, 94,101,216,    187,124,126,137,207,185,140,150,102,190,182,139,225,167,103,  8,     29, 13, 62,117, 46, 72,145, 13, 31,145,251,  0,135,124,225,124,    199,230, 63, 31,  7, 26,184, 32, 67,249,146, 51, 16, 52, 99,166,    109,187,142,157, 42,230,112,151, 75,235,179, 22,179,  6, 13,214,    195,132, 59,121,191,187,184,194,122,211,202,141, 12,142,223,128,     38, 21, 70,237, 98,192,235,242, 71, 39, 78,150,175,164,198,119,    194,225, 71, 39,203, 21,179,102,234,250,147,199, 83,119, 11, 78,     33,111, 15,218,241,231,180,143, 16,245,190, 59,139,222,143,  1,    196, 65, 67,129,148,195,191,194,165,132,191,149, 49,179,233,117,    145,129,139,248,109,149,193,249, 72,207,192,  9,183,104,107,127,    175, 18,114,169,145, 29,197,113,177, 34,187,239, 93,129, 22,139,      5,151,115,130,153,239,189,152,213,254,192,102,129,212,151,  9,    172,108, 57,119,189,128,125,135, 84,172,231,218, 22,220,220,126,     79, 62,111,221, 99,124,236,251, 13,129,236,240,185,174, 19,227,    184, 27,181, 81, 57,146,237,153, 50, 45,130,100, 66,102,151,218    };

long       cursorTime; int        inp_col;    /* color of cursor */ int        inp_but;    /* button of input device */ int        inp_xpos;   /* xpos of input device */ int        inp_ypos;   /* ypos of input device */ InpTab     theInpTab;  /* holds hotspot index and button press */

short      theLine = 0;    /* scan line to link vidmem0 (RL7 buffer) to */

Boolean    fx_time;

/* * FindRect - The application must take care of setting a Ptr to the * proper table of rectangles for the current mode. This code compares * the passed x,y coordinates against each rectangle in the list until * the rectangle (if any) is found that contains the passed coordinates. * It returns the rectangle's index (or -1 if none). */ short FindRect(xpos, ypos) short xpos; short ypos; { short ctr;

for (ctr = 0; ctr <= theRectPtr->RectNum; ctr++) { if (xpos >= theRectPtr->theRects[ctr].left) { if (xpos <= theRectPtr->theRects[ctr].right) { if (ypos >= theRectPtr->theRects[ctr].top) { if (ypos <= theRectPtr->theRects[ctr].bottom) { return(ctr); }               }            }        }    }    return (-1); }

/* * stuffbunch places the "who and where", into mfxDir, of each * individual thing that got loaded as part of a larger file. */ Boolean stuffbunch(theDirPtr, theDataPtr) Ptr theDirPtr; Ptr theDataPtr; { TOCPtr theTOC; int    ctr;

theTOC = (TOCPtr)theDirPtr; /* STATUS2("mfxDir has %d items when entering stuffbunch\n", DirNum); */ /* STATUS2("stuffbunch is adding %d items to mfxDir\n", theTOC->TOCNum); */ for (ctr=0; ctr < theTOC->TOCNum; ctr++) { mfxDir[DirNum].Where = theDataPtr + theTOC->TE[ctr].Where; strcpy(mfxDir[DirNum].Who, theTOC->TE[ctr].Who); /* STATUS3("stuffbunch is adding %s at 0x%x\n", mfxDir[DirNum].Who, mfxDir[DirNum].Where); */ DirNum++;      /* increment # of "things" in memory */ if (DirNum >= maxThings) { STATUS1("mfxdir is maxed out ********\n"); }   }    /* STATUS2("mfxDir has %d items when exiting stuffbunch\n", DirNum); */ return(true); }

/* * loadpkg - Pass this the name of a "package" (a .com file). *          This returns a pointer to the .cmn portion (this is handy *           when the first thing is a "scene". */

Ptr loadpkg(theName, theBuf) Str31  theName; Ptr    theBuf; { int    fid; Size   theSize; Size   theSize2;

fid = open_file(theName, false);

theSize = _gs_size(fid);

theSize2 = read(fid, theBuf, theSize); if (theSize2 == -1) { STATUS1("loadpkg couldn't load the package ***\n"); close_file(fid); return((Ptr)-1); }   close_file(fid); /* return(stuffpkg(theBuf)); */ /* we don't need this here */ return(0); }

/* * stuffpkg - this "resolves" the package at pkgbuf */ Ptr stuffpkg(theBuf) Ptr    theBuf; { Ptr    theDataPtr;

/*    * Call the code "stuffbunch" that places everything just loaded into mfxDir */   theDataPtr = theBuf + ((*(short *)theBuf) * 40 + 4); stuffbunch(theBuf, theDataPtr); return(theDataPtr); }

/* * loadthing loads the thing whose name is passed in 'theName'. * It returns the index into mfxDir of its directory record (or -1 if an error occured). */ short loadthing(theName) Str31 theName; {

int    fid; Size   theSize; Size   theSize2;

fid = open(theName, S_IREAD); if (fid == -1) { STATUS2("loadthing can't find %s\n", theName); return(fid); }

theSize = _gs_size(fid); mfxDir[DirNum].Where = (char *)ALLOCATE(theSize, VIDEO1); if (mfxDir[DirNum].Where == (char *)-1L) {       STATUS1("LoadThing FAIL MEMORY\n"); }   strcpy(mfxDir[DirNum].Who, theName);

theSize2 = read(fid, mfxDir[DirNum].Where, theSize); if (theSize2 == -1) { close_file(fid); return(-1); }   /* STATUS4("loadthing loaded 0x%x bytes of %s at 0x%x\n", theSize2, theName, mfxDir[DirNum].Where); */ close_file(fid); DirNum++;      /* increment # of "things" in memory */ return(DirNum - 1); }

/* * loadOne - This loads one thing from a combined file. * * Pass it: findex - file index number (of large data file on disk) *          theTOC - Ptr to table of contents (TOC) for large disk file. *          tindex - index into TOC *          theBuf - Ptr to the buffer * * Returns: # bytes read (or -1 for error) */ short loadOne(findex, theTOC, tindex, theBuf) int    findex; TOCPtr theTOC; short  tindex; Ptr    theBuf; {

STAT_BLK   seekstat; Size   theSize;

seekstat.asy_sig = 0; seekstat.asy_stat = 0; ss_seek(findex,theTOC->TE[tindex].Where,&seekstat); while (!(seekstat.asy_stat & 1)); /* wait for done bit */ if (seekstat.asy_stat & 0x8000) { STATUS2("Error %d occured during seek\n",seekstat.asy_sig); STATUS2("asy_sig = 0x%x\n",seekstat.asy_sig); STATUS2("asy_stat = 0x%x\n",seekstat.asy_stat); return(-1); }   theSize = read(findex, theBuf, theTOC->TE[tindex].How); if (theSize == -1) { return(-1); }   return(theSize); }

/* * FixScene - Pass this the scene index number. It will resolve the item table *             addresses. */ Boolean FixScene(theIndex) short theIndex; { Size       ITabSize; /* size of an item table is defined in "defines.h" */ ScenePtr   theScene;   /* handle to the "current" Scene */ int        CurOff; short      ctr;

/* * Convert the itemdir "where" entries from (lengths of each item table) * to (offsets from start of scene to each item table). */   theScene = SceneTab[theIndex]; CurOff = sizeof(Scene) - (sizeof(Direc) * maxItems) + (sizeof(Direc) * (*theScene).NumItems); for (ctr = 0; ctr < (*theScene).NumItems; ctr++) { ITabSize = (int)(*theScene).ItemDir[ctr].Where; /* save size of current table */ (*theScene).ItemDir[ctr].Where = (Ptr)CurOff; CurOff += ITabSize; }   return(true); }

/* * SetupScene - these lines of code have been chopped of the end of LoadScene * so that I can alter the item tables filenames before calling resolve/reinit. */ Boolean SetUpScene(theIndex) short theIndex; { Boolean    myBoo;

/* * Call the code that makes sure all image/sound data is in memory and resolves * all necessary pointers for each item table. */   myBoo = Resolve; /* link all item tables to their disk file images and disk file images to theirs */ if (myBoo == false) { STATUS1("Resolve returned FALSE!!!\n"); /* ShowMFX; */ }   ReinitScene(SceneTab[theIndex]); return(true); }

/* * ShowMFX - prints the contents of mfxDir */ void ShowMFX { short  ctr;
 * 1) if 0

return; for (ctr=0; ctr<DirNum; ctr++) { STATUS3("Item #%d in mfxDir is %s\n", ctr, mfxDir[ctr].Who); } }
 * 1) endif

/* * Pass this the filename to search for. * This returns the index # or (-1) if name not in directory (mfxDir). */ short getind(theText) char *theText; { short  ctr; short  index = -1;

for (ctr=0; ctr<DirNum; ctr++) { if (strcmp(mfxDir[ctr].Who, theText) == 0) { index = ctr; break; }   }    if (index == -1) { STATUS2("getind coundn't find %s\n",theText); }   return(index); }

/* * * CheckInput - This reads the controller and positions the cursor. *             It stuffs values into the table whose address is passed. * * Pass this structure: *     short   HotIndex;  stuffs index number of hotspot (or -1) *     Boolean ButPress;  set if controller button is pressed, cleared otherwise */ void CheckInput {

Step;

Get_Coord(&inp_xpos,&inp_ypos); Get_Buttons(&inp_but);

theInpTab.HotIndex = FindRect(inp_xpos/2,inp_ypos/2); if (theInpTab.HotIndex == -1) inp_col = 0x80808000; /* yellow - intensity bit (bit 31) on */ else if (currentT >= cursorTime) { inp_col = (inp_col ^ 0x00008000); /* toggle between yellow and red */ cursorTime = currentT + cursor_delay; }   gc_col(vidpath,inp_col);

if (inp_but & 0x03) theInpTab.ButPress = true; else theInpTab.ButPress = false; }

/* * This is the signal handler */ int signal_handler(signal) int signal; {   short   theStat;

theStat = thePCB->PCB_Stat; switch (signal) {

case SLI_SIGNAL:   /* tell main that scan line interrupt "has happened" */ swapflag = true; break;

case SM_OUT_SIGNAL: /* sound map has been sent to audio processor */ smap_busy = false; if (!(smap_stat.asy_stat & 1)) { STATUS1("have smap signal but done bit is clear\n"); }           if (smap_stat.asy_stat & 0x8000) { STATUS2("smap error 0x%x\n", smap_stat.asy_sig); }           break;

case PCB_SIGNAL: if ( theStat & SBM_Er ) { /* Error or Abort has occurred */ if ( thePCB->PCB_Sig == E_ABORT ) { eor_ctr = 0; cur_aud_fid = 0; }               else { STATUS3("Play Error 0x%x, PCB_Stat %x\n\n",thePCB->PCB_Sig, theStat); play_error = true; eor_ctr = 0; cur_aud_fid = 0; }           }            if ( theStat & SBM_Dn ) { /* Play is finished */ cur_aud_fid = 0; /* STATUS1("Play Finished\n"); */ }           if ( theStat & SBM_Eof ) { /* End of File */ cur_aud_fid = 0; /* STATUS1("EOF\n"); */ }           if ( theStat & SBM_Trg ) { /* Trigger */ trigger_ctr --; /* STATUS1("Trigger\n"); */ }           if ( theStat & SBM_Eor ) { /* End of record */ eor_ctr --; /*STATUS1("EOR\n");*/ }           break;

case PTR_SIGNAL: reset_dim;                   /* reset the dim timer */ reset_help;                  /* reset the help timer */ Update_Coord;                /* update the cursor manager */ pt_ssig(vidpath,PTR_SIGNAL);   /* re-arm the signal */ /* STATUS1("ptr\n"); */ break;

case BUFFER_SIGNAL0: vid_pcl_0->PCL_BufSz = RL7Size; vid_pcl_0->PCL_Ctrl = 0;               /* Control byte */ vid_pcl_0->PCL_Cnt = 0;            /* Current offset in buffer */ dc_wrli (vidpath,lctid0,theLine*2,0,cp_dadr((int)vidmem0)); rear_vid_pcl = vid_pcl_1; break;

case BUFFER_SIGNAL1: vid_pcl_1->PCL_BufSz = RL7Size; vid_pcl_1->PCL_Ctrl = 0;               /* Control byte */ vid_pcl_1->PCL_Cnt = 0;            /* Current offset in buffer */ dc_wrli (vidpath,lctid0,theLine*2,0,cp_dadr((int)vidmem1)); rear_vid_pcl = vid_pcl_0; break;

case FX_ALARM_SIGNAL: fx_time = true; break;

default: break; }   return(0); }

short getran(limit) short limit; { short ranval; short ranval2;

ranval = rantab[ranctr]; ranctr++; if (ranctr >= ransize) ranctr = 0; if (ranval > limit) { ranval2 = ranval / limit; ranval2 *= limit; ranval -= ranval2; }   return(ranval); }

/* * get_random_seed */ void get_random_seed { short      ctr;

currentT = clock; /* get current tick count */ ranctr = (short) currentT; if (ranctr > ransize) { ctr = ranctr / ransize; ctr *= ransize; ranctr -= ctr; } }

/* * shufshort - pass this the address and size of a table of short values to shuffle */ void shufshort(table, size) short  *table; short  size; { short  ctr; short  ranval1; short  ranval2; short  tempval;

for (ctr=0; ctr<100; ctr++) { ranval1 = getran(size -1); ranval2 = getran(size -1); tempval = table[ranval1]; table[ranval1] = table[ranval2]; table[ranval2] = tempval; } }

/* * reset_dim - set a new click count as the target for dimming */ void reset_dim {   DimTime = currentT + (CLK_TCK * DimSecs); }

/* * chk_dim */ int chk_dim { int    did_dim; extern Boolean cursor_stat;

if (currentT >= DimTime) {

if (ModMod == ModBop) no_vel;              /* stop the x movement of the items */ if (PAFlag) dc_wrfi(vidpath,fctid_RL7,2,cp_icf(PA,ICF_MAX/3)); if (PBFlag) dc_wrfi(vidpath,fctid_Clut7,2,cp_icf(PB,ICF_MAX/3)); if (cursor_stat) gc_hide(vidpath); /* we can't call 'cursor_hide' as it clears 'cursor_stat' */ while ((last_xpos == inp_xpos) && (last_ypos == inp_ypos) && (!theInpTab.ButPress)) CheckInput; if (PAFlag) dc_wrfi(vidpath,fctid_RL7,2,cp_icf(PA,ICF_MAX)); if (PBFlag) dc_wrfi(vidpath,fctid_Clut7,2,cp_icf(PB,ICF_MAX)); if (cursor_stat) cursor_show;         /* display the cursor */ reset_dim;               /* reset dim counter */

did_dim = 1; }   else did_dim = 0; return(did_dim); }

/* * reset_help - set a new click count as the target for playing *             the automatic help message */ void reset_help {   HelpTime = currentT + (CLK_TCK * HelpSecs); }

/* * chk_help -  if it's time to play the help message, do it, *             and then restart the backgound audio */ int chk_help(hlp_chn, hlp_fid, bkd_chn, bkd_fid) short  hlp_chn, bkd_chn; int    hlp_fid, bkd_fid; { int    did_help;

if (currentT >= HelpTime) {

if (ModMod == ModBop) no_vel;              /* stop the x movement of the items */

stop_all_audio; start_bkgd_audio(hlp_chn, hlp_fid, false); while ((last_xpos == inp_xpos) && (last_ypos == inp_ypos) &&           (!theInpTab.ButPress) && (eor_ctr)) { CheckInput; }

stop_all_audio; if (bkd_fid) start_bkgd_audio(bkd_chn, bkd_fid, true); reset_help; did_help = 1; }   else did_help = 0; return(did_help); }

wordbook.c

 * 1) include <stdio.h>
 * 2) include <errno.h>
 * 3) include <modes.h>
 * 4) include <aimdef.h>
 * 5) include <memory.h>
 * 6) include <rtr.h>
 * 7) include <time.h>


 * 1) include "dbg.h"


 * 1) include "wordbook.h"
 * 2) include "animation.h"
 * 3) include "reading.h"
 * 4) include "screen.h"
 * 5) include "rtf.h"
 * 6) include "sound.h"
 * 7) include "file_mgr.h"
 * 8) include "utility.h"

/* * this is the table of the twenty scenes that gets shuffled */ short  wbstab[NumPages] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,   10,11,12,13,14,15,16,17,18,19    };

/* * These are the hotspots for each wordbook "page" * The first 6 are the buttons. */

static RectList farm1Rect = { 11,   177, 33,218, 82,    /* help button */ 177, 88,218,149,   /* speech button */ 177,155,218,216,   /* text button */ 177,222,218,252,   /* prev button */ 177,253,218,283,   /* next button */ 177,289,218,350,   /* go back button */ 60, 55,116,117,   /* cow */ 90,137,126,187,   /* chicken */ 114,221,160,295,   /* pig */ 60,291,100,345,   /* tractor */ 36,168, 74,228    /* barn */ };

static RectList spaceRect = { 10,   177, 33,218, 82,    /* help button */ 177, 88,218,149,   /* speech button */ 177,155,218,216,   /* text button */ 177,222,218,252,   /* prev button */ 177,253,218,283,   /* next button */ 177,289,218,350,   /* go back button */ 41, 53,104,118,   /* astronaut */ 30,247, 74,288,   /* moon */ 100,127,143,183,   /* satellite */ 107,226,167,346    /* rocket */ };

static RectList AfricaRect = { 11,   177, 33,218, 82,    /* help button */ 177, 88,218,149,   /* speech button */ 177,155,218,216,   /* text button */ 177,222,218,252,   /* prev button */ 177,253,218,283,   /* next button */ 177,289,218,350,   /* go back button */ 49, 77,100,150,   /* elephant */ 58,217,100,267,   /* lion */ 100,290,170,341,   /* giraffe */ 100,138,144,200,   /* zebra */ 117, 46,169, 95    /* hippo */ };

static RectList farm2Rect = { 11,   177, 33,218, 82,    /* help button */ 177, 88,218,149,   /* speech button */ 177,155,218,216,   /* text button */ 177,222,218,252,   /* prev button */ 177,253,218,283,   /* next button */ 177,289,218,350,   /* go back button */ 53,177,100,248,   /* goat */ 60,284,121,341,   /* pumpkin */ 128,292,150,344,   /* duck */ 115,113,160,178,   /* sheep */ 30, 50,110,113    /* scarecrow */ };

static RectList AustraliaRect = { 11,   177, 33,218, 82,    /* help button */ 177, 88,218,149,   /* speech button */ 177,155,218,216,   /* text button */ 177,222,218,252,   /* prev button */ 177,253,218,283,   /* next button */ 177,289,218,350,   /* go back button */ 28,117, 85,167,   /* monkey */ 140,141,160,206,   /* anteater */ 98,295,158,343,   /* ostrich */ 33,218, 70,255,   /* parrot */ 93, 38,150,121    /* kangaroo */ };

static RectList oceanRect = { 10,   177, 33,218, 82,    /* help button */ 177, 88,218,149,   /* speech button */ 177,155,218,216,   /* text button */ 177,222,218,252,   /* prev button */ 177,253,218,283,   /* next button */ 177,289,218,350,   /* go back button */ 55, 51,110,150,   /* submarine */ 30,171, 54,278,   /* motorboat */ 53,284, 94,332,   /* fish */ 106,157,147,283    /* shark */ };

static RectList beachRect = { 11,   177, 33,218, 82,    /* help button */ 177, 88,218,149,   /* speech button */ 177,155,218,216,   /* text button */ 177,222,218,252,   /* prev button */ 177,253,218,283,   /* next button */ 177,289,218,350,   /* go back button */ 113, 51,150,141,   /* Sara */ 32,112, 65,171,   /* island */ 40,284, 87,340,   /* sailboat */ 84,156,111,216,   /* rowboat */ 113,241,157,317    /* ball */ };

static RectList houseRect = { 11,   177, 33,218, 82,    /* help button */ 177, 88,218,149,   /* speech button */ 177,155,218,216,   /* text button */ 177,222,218,252,   /* prev button */ 177,253,218,283,   /* next button */ 177,289,218,350,   /* go back button */ 44, 64,133,122,   /* door */ 43,144,100,193,   /* window */ 120,135,160,205,   /* dog */ 114,284,150,337,   /* cat */ 32,250, 80,305    /* tree */ };

static RectList vehiclesRect = { 11,   177, 33,218, 82,    /* help button */ 177, 88,218,149,   /* speech button */ 177,155,218,216,   /* text button */ 177,222,218,252,   /* prev button */ 177,253,218,283,   /* next button */ 177,289,218,350,   /* go back button */ 93, 66,144,154,   /* cement mixer */ 116,265,202,331,   /* motorcycle */ 80,188,120,274,   /* truck */ 35,266, 69,351,   /* train */ 35, 90, 83,176    /* gas station */ };

static RectList skyRect = { 11,   177, 33,218, 82,    /* help button */ 177, 88,218,149,   /* speech button */ 177,155,218,216,   /* text button */ 177,222,218,252,   /* prev button */ 177,253,218,283,   /* next button */ 177,289,218,350,   /* go back button */ 73, 38,100,156,   /* airplane */ 46,190, 77,265,   /* helicopter */ 92,182,127,232,   /* cloud */ 107,258,140,302,   /* bird */ 114, 80,168,118    /* balloon */ };

static RectList porchRect = { 11,   177, 33,218, 82,    /* help button */ 177, 88,218,149,   /* speech button */ 177,155,218,216,   /* text button */ 177,222,218,252,   /* prev button */ 177,253,218,283,   /* next button */ 177,289,218,350,   /* go back button */ 67,115,117,170,   /* barrel */ 126, 90,165,183,   /* mouse */ 124,200,153,238,   /* bucket */ 105,274,147,345,   /* wagon */ 40,298,140,334    /* balloon */ };

static RectList interiorRect = { 10,   177, 33,218, 82,    /* help button */ 177, 88,218,149,   /* speech button */ 177,155,218,216,   /* text button */ 177,222,218,252,   /* prev button */ 177,253,218,283,   /* next button */ 177,289,218,350,   /* go back button */ 59, 43,166,135,   /* bed */ 49,156,123,231,   /* chair */ 129,208,160,249,   /* banana */ 54,264,151,348    /* telephone */ };

static RectList pondRect = { 11,   177, 33,218, 82,    /* help button */ 177, 88,218,149,   /* speech button */ 177,155,218,216,   /* text button */ 177,222,218,252,   /* prev button */ 177,253,218,283,   /* next button */ 177,289,218,350,   /* go back button */ 84,122,116,199,   /* swan */ 90,275,120,348,   /* frog */ 113,204,164,245,   /* rabbit */ 35,167, 66,235,   /* rainbow */ 115, 60,148,124    /* turtle */ };

static RectList windowRect = { 11,   177, 33,218, 82,    /* help button */ 177, 88,218,149,   /* speech button */ 177,155,218,216,   /* text button */ 177,222,218,252,   /* prev button */ 177,253,218,283,   /* next button */ 177,289,218,350,   /* go back button */ 100,298,160,340,   /* brush */ 64,180, 89,239,   /* tent */ 36, 57,106,157,   /* house */ 134, 51,160,100,   /* box */ 100,165,160,240    /* shoe */ };

static RectList musicRect = { 10,   177, 33,218, 82,    /* help button */ 177, 88,218,149,   /* speech button */ 177,155,218,216,   /* text button */ 177,222,218,252,   /* prev button */ 177,253,218,283,   /* next button */ 177,289,218,350,   /* go back button */ 65, 41,158,141,   /* piano */ 45,223,146,291,   /* trombone */ 65,150,163,222,   /* drum */ 81,295,166,344    /* guitar */ };

static RectList classroomRect = { 11,   177, 33,218, 82,    /* help button */ 177, 88,218,149,   /* speech button */ 177,155,218,216,   /* text button */ 177,222,218,252,   /* prev button */ 177,253,218,283,   /* next button */ 177,289,218,350,   /* go back button */ 104, 60,153,100,   /* globe */ 41, 45, 88,114,   /* blackboard */ 45,149, 89,225,   /* map */ 35,293, 63,325,   /* bell */ 106,255,152,302    /* computer */ };

static RectList kitchenRect = { 11,   177, 33,218, 82,    /* help button */ 177, 88,218,149,   /* speech button */ 177,155,218,216,   /* text button */ 177,222,218,252,   /* prev button */ 177,253,218,283,   /* next button */ 177,289,218,350,   /* go back button */ 42, 96,135,169,   /* Stickybear */ 54,214, 82,263,   /* tea kettle */ 30,272,136,332,   /* refrigerator */ 100,195,150,243,   /* toaster */ 103, 41,143, 83    /* mixer */ };

static RectList parkRect = { 11,   177, 33,218, 82,    /* help button */ 177, 88,218,149,   /* speech button */ 177,155,218,216,   /* text button */ 177,222,218,252,   /* prev button */ 177,253,218,283,   /* next button */ 177,289,218,350,   /* go back button */ 27, 50,160,121,   /* lamp post */ 55,113,118,196,   /* fountain */ 45,225, 88,328,   /* bridge */ 100,305,160,347,   /* bench */ 82,191,160,241    /* clown */ };

static RectList sinkRect = { 11,   177, 33,218, 82,    /* help button */ 177, 88,218,149,   /* speech button */ 177,155,218,216,   /* text button */ 177,222,218,252,   /* prev button */ 177,253,218,283,   /* next button */ 177,289,218,350,   /* go back button */ 108,160,140,329,   /* sink */ 35,168,100,237,   /* faucet */ 36,270,105,347,   /* pan */ 100, 69,160,137,   /* pot */ 30, 40, 78,125    /* cans */ };

static RectList supermarketRect = { 10,   177, 33,218, 82,    /* help button */ 177, 88,218,149,   /* speech button */ 177,155,218,216,   /* text button */ 177,222,218,252,   /* prev button */ 177,253,218,283,   /* next button */ 177,289,218,350,   /* go back button */ 52,253,118,348,   /* cash register */ 126,191,145,261,   /* pie */ 41, 42,137, 87,   /* Bumper */ 75,119,136,177    /* shopping cart */ };

static Str31 WBNames[NumPages] = { "Africa.rtf", "Australia.rtf", "beach.rtf", "classroom.rtf", "farm1.rtf", "farm2.rtf", "house.rtf", "interior.rtf", "kitchen.rtf", "music.rtf", "ocean.rtf", "park.rtf", "pond.rtf", "porch.rtf", "sink.rtf", "sky.rtf", "space.rtf", "supermarket.rtf", "vehicles.rtf", "window.rtf" };

static MCAud WBTunes[NumPages] = { 0, 0,   0, 1,    0, 2,    0, 3,    0, 4,    0, 5,    0, 6,    0, 7,    0, 8,    0, 9,    0, 10,    0, 11,    0, 12,    0, 13,    0, 14,    0, 15,    1, 0,    1, 1,    1, 2,    1, 3    };

static Ptr WBSpots[NumPages] = { &AfricaRect, &AustraliaRect, &beachRect, &classroomRect, &farm1Rect, &farm2Rect, &houseRect, &interiorRect, &kitchenRect, &musicRect, &oceanRect, &parkRect, &pondRect, &porchRect, &sinkRect, &skyRect, &spaceRect, &supermarketRect, &vehiclesRect, &windowRect };

static WBSMap Africasmap = { 15,    90, 90, 72,    /* elephant */ 72, 72,108,   /* lion */ 90, 90, 18,   /* giraffe */ 90, 72, 72,   /* zebra */ 72,108, 18    /* hippo */ };

static WBSMap Australiasmap = { 15,    72, 72, 72,    /* monkey */ 90,126,108,   /* anteater */ 90,108, 18,   /* ostrich */ 72, 72, 72,   /* parrot */ 90, 90, 72    /* kangaroo */ };

static WBSMap beachsmap = { 15,    72, 72,108,    /* Sara */ 72, 72, 18,   /* island */ 108,126,162,   /* sailboat */ 108,144,144,   /* rowboat */ 72, 90, 72    /* ball */ };

static WBSMap classroomsmap = { 15,    90,108, 72,    /* globe */ 90, 90, 18,   /* blackboard */ 72, 72, 54,   /* map */ 72, 90,126,   /* bell */ 90,108, 90    /* computer */ };

static WBSMap farm1smap = { 15,    72, 90,108,    /* cow */ 72, 90,108,   /* chicken */ 72, 72, 72,   /* pig */ 90, 90,162,   /* tractor */ 72, 90,180    /* barn */ };

static WBSMap farm2smap = { 15,    90, 72, 90,    /* goat */ 90,108, 72,   /* pumpkin */ 90, 72, 72,   /* duck */ 72, 72,108,   /* sheep */ 90,126, 90    /* scarecrow */ };

static WBSMap housesmap = { 15,    72, 90, 90,    /* door */ 90, 90,108,   /* window */ 72, 72, 72,   /* dog */ 72, 90, 90,   /* cat */ 72, 72, 18    /* tree */ };

static WBSMap interiorsmap = { 15,    72, 72,162,    /* bed */ 72, 72, 36,   /* chair */ 72, 90, 54,   /* banana */ 90, 90,108,   /* telephone */ 18, 18, 18    /* filler */ };

static WBSMap kitchensmap = { 15,    90, 90,126,    /* Stickybear */ 72, 90,144,   /* teakettle */ 108, 90, 72,   /* refrigerator */ 90,108, 72,   /* toaster */ 90,108,162    /* mixer */ };

static WBSMap musicsmap = { 15,    72, 72,162,    /* piano */ 108, 90,108,   /* trombone */ 72, 90,108,   /* drum */ 90, 90,144,   /* guitar */ 18, 18, 18    /* filler */ };

static WBSMap oceansmap = { 15,   108,108,162,    /* submarine */ 108, 90,108,   /* motorboat */ 72, 72, 54,   /* fish */ 90, 90,126,   /* shark */ 18, 18, 18    /* filler */ };

static WBSMap parksmap = { 15,   108,126, 90,    /* lamppost */ 72, 90,180,   /* fountain */ 90, 90,126,   /* bridge */ 72, 90, 72,   /* bench */ 90, 72, 90    /* clown */ };

static WBSMap pondsmap = { 15,   108, 72,144,    /* swan */ 72, 72, 54,   /* frog */ 90, 72, 18,   /* rabbit */ 108,108,108,   /* rainbow */ 72, 90, 54    /* turtle */ };

static WBSMap porchsmap = { 15,    72, 90, 90,    /* barrel */ 90, 90, 36,   /* mouse */ 90, 90, 72,   /* bucket */ 90, 90,126,   /* wagon */ 108, 72, 54    /* balloon */ };

static WBSMap sinksmap = { 15,    72, 90, 90,    /* sink */ 72,108,162,   /* faucet */ 72, 90, 72,   /* pan */ 72, 72, 54,   /* pot */ 90, 90, 72    /* cans */ };

static WBSMap skysmap = { 15,    90, 72,180,    /* airplane */ 90,108,108,   /* helicopter */ 90, 72, 18,   /* cloud */ 72, 72, 72,   /* bird */ 108, 72, 54    /* balloon */ };

static WBSMap spacesmap = { 15,    90,108, 18,    /* astronaut */ 90, 72,162,   /* moon */ 90,108,108,   /* satellite */ 90, 72,108,   /* rocket */ 18, 18, 18    /* filler */ };

static WBSMap supermarketsmap = { 15,   126,126,126,    /* cash register */ 72, 90, 18,   /* pie */ 90, 72,126,   /* Bumper */ 108, 90,126,   /* shopping cart */ 18, 18, 18    /* filler */ };

static WBSMap vehiclessmap = { 15,   126,162,126,    /* cement mixer */ 108, 72,108,   /* motorcycle */ 72, 90, 90,   /* truck */ 90, 72,144,   /* train */ 108,162,108    /* gas station */ };

static WBSMap windowsmap = { 15,    72, 90, 54,    /* brush */ 72, 72, 54,   /* tent */ 90, 72,126,   /* house */ 90, 72, 18,   /* box */ 72, 90, 90    /* shoe */ };

static WBSMapPtr WBSMaplists[NumPages] = { &Africasmap, &Australiasmap, &beachsmap, &classroomsmap, &farm1smap, &farm2smap, &housesmap, &interiorsmap, &kitchensmap, &musicsmap, &oceansmap, &parksmap, &pondsmap, &porchsmap, &sinksmap, &skysmap, &spacesmap, &supermarketsmap, &vehiclessmap, &windowsmap };

static short       DirSaveWB; static Rect        fullRect = {0,1,240,383}; static short       wbsctr = 5; static short       WhichPage;  /* which word book page to do */ static ScenePtr    WBScene; static ItemPtr     WBItem; static short       LastFXID;       /* ID of last sound effect to play */ static int         LastFXCtr;      /* ctr for when to do sound effect */

static Boolean     mute_fx[15];    /* array entry set means don't play sound effect */

/* * Sara's wordbook */ void WordBook { Boolean    done; short      ctr;

WhichPage = wbstab[wbsctr]; DirSaveWB = DirNum;    /* save for starting point when loading each new 'page' */ set_bear_voice;      /* set the bear file ID to the appropriate file */

newWBpkg(1);           /* Load the initial wordbook package */ MkBookBut;           /* Make the buttons for word book. */   Step;                 /* This will draw the first frame of animation */

start_bkgd_audio(WBTunes[WhichPage].MCAChan, TUNEfid, true); /* Start bkgd audio */

DslvAB(fastdisolve);       /* disolve from plane A to plane B */

Set_Coord (230,100); cursor_show;         /* display the cursor */ done = false; while (!done) {

update_audio;

chk_help(8, BEARfid, WBTunes[WhichPage].MCAChan, TUNEfid); chk_dim; /* if it's time to dim, this won't return until undim */

if ((LastFXID != -1) && (fx_time)) { /* Check for time to do sound effect */ start_soundmap(snd_array[LastFXID].smap_id); fx_time = false; }

CheckInput; /* This checks the input device and calls 'Step' */ switch (theInpTab.HotIndex) { case 0: /* HELP button */ if (theInpTab.ButPress) { stop_all_audio; start_bkgd_audio(7, BEARfid, false); /* pass channel number */ CheckInput; while ((eor_ctr) && (theInpTab.HotIndex == 0) && (!theInpTab.ButPress)) CheckInput; stop_all_audio; reset_help; start_bkgd_audio(WBTunes[WhichPage].MCAChan, TUNEfid, true); }               break; case 1: /* SPEECH button */ if (theInpTab.ButPress) { Cursor_Freeze; stop_all_audio; start_bkgd_audio(0, BUTTONfid, false); /* pass channel number */ changeSpch; while (eor_ctr); set_bear_voice; set_button_voice; start_bkgd_audio(WBTunes[WhichPage].MCAChan, TUNEfid, true); Cursor_Melt; }               break; case 2: /* TEXT button */ if (theInpTab.ButPress) { Cursor_Freeze; stop_all_audio; stop_all_audio; if (text == English) start_bkgd_audio(3, BUTTONfid, false); /* pass channel number */ if (text == Spanish) start_bkgd_audio(1, BUTTONfid, false); /* pass channel number */ changeText; if (text == Spanish) { WBItem = (ItemPtr)((int)WBScene + (int)WBScene->ItemDir[1].Where); if (WBItem->IDisplay == true) { WBItem->IDisplay = false; WBItem = (ItemPtr)((int)WBScene + (int)WBScene->ItemDir[2].Where); WBItem->IDisplay = true; }                       WBItem = (ItemPtr)((int)WBScene + (int)WBScene->ItemDir[4].Where); if (WBItem->IDisplay == true) { WBItem->IDisplay = false; WBItem = (ItemPtr)((int)WBScene + (int)WBScene->ItemDir[5].Where); WBItem->IDisplay = true; }                       WBItem = (ItemPtr)((int)WBScene + (int)WBScene->ItemDir[7].Where); if (WBItem->IDisplay == true) { WBItem->IDisplay = false; WBItem = (ItemPtr)((int)WBScene + (int)WBScene->ItemDir[8].Where); WBItem->IDisplay = true; }                       WBItem = (ItemPtr)((int)WBScene + (int)WBScene->ItemDir[10].Where); if (WBItem->IDisplay == true) { WBItem->IDisplay = false; WBItem = (ItemPtr)((int)WBScene + (int)WBScene->ItemDir[11].Where); WBItem->IDisplay = true; }                       if (WBScene->NumItems == 15) { WBItem = (ItemPtr)((int)WBScene + (int)WBScene->ItemDir[13].Where); if (WBItem->IDisplay == true) { WBItem->IDisplay = false; WBItem = (ItemPtr)((int)WBScene + (int)WBScene->ItemDir[14].Where); WBItem->IDisplay = true; }                       }                    }                    if (text == English) { WBItem = (ItemPtr)((int)WBScene + (int)WBScene->ItemDir[2].Where); if (WBItem->IDisplay == true) { WBItem->IDisplay = false; WBItem = (ItemPtr)((int)WBScene + (int)WBScene->ItemDir[1].Where); WBItem->IDisplay = true; }                       WBItem = (ItemPtr)((int)WBScene + (int)WBScene->ItemDir[5].Where); if (WBItem->IDisplay == true) { WBItem->IDisplay = false; WBItem = (ItemPtr)((int)WBScene + (int)WBScene->ItemDir[4].Where); WBItem->IDisplay = true; }                       WBItem = (ItemPtr)((int)WBScene + (int)WBScene->ItemDir[8].Where); if (WBItem->IDisplay == true) { WBItem->IDisplay = false; WBItem = (ItemPtr)((int)WBScene + (int)WBScene->ItemDir[7].Where); WBItem->IDisplay = true; }                       WBItem = (ItemPtr)((int)WBScene + (int)WBScene->ItemDir[11].Where); if (WBItem->IDisplay == true) { WBItem->IDisplay = false; WBItem = (ItemPtr)((int)WBScene + (int)WBScene->ItemDir[10].Where); WBItem->IDisplay = true; }                       if (WBScene->NumItems == 15) { WBItem = (ItemPtr)((int)WBScene + (int)WBScene->ItemDir[14].Where); if (WBItem->IDisplay == true) { WBItem->IDisplay = false; WBItem = (ItemPtr)((int)WBScene + (int)WBScene->ItemDir[13].Where); WBItem->IDisplay = true; }                       }                    }                    while (eor_ctr); stop_all_audio; start_bkgd_audio(WBTunes[WhichPage].MCAChan, TUNEfid, true); Cursor_Melt; }               break; case 3: /* PREVIOUS button */ if (theInpTab.ButPress) { stop_all_audio; wbsctr --; if (wbsctr == -1) wbsctr = NumPages -1; WhichPage = wbstab[wbsctr]; newWBpkg(0);   /* Load a wordbook package */ start_bkgd_audio(WBTunes[WhichPage].MCAChan, TUNEfid, true); }               break; case 4: /* NEXT button */ if (theInpTab.ButPress) { stop_all_audio; wbsctr ++; if (wbsctr == NumPages) wbsctr = 0; WhichPage = wbstab[wbsctr]; newWBpkg(1);   /* Load a wordbook package */ start_bkgd_audio(WBTunes[WhichPage].MCAChan, TUNEfid, true); }               break; case 5: /* GOBACK button */ if (theInpTab.ButPress) { stop_all_audio; start_bkgd_audio(10, BEARfid, false); /* Sara says "bye" */ while (eor_ctr); /* DirNum = DirSaveWB; */  /* restore old value */ done = true; }               break;

case 6: /* Item #0 */ if ((theInpTab.ButPress) && (!smap_busy) && (!smap_list_ctr)) { WBItem = (ItemPtr)((int)WBScene + (int)WBScene->ItemDir[0].Where); if (WBItem->IActive == true) { /* already active - disable it */ WBItem->IActive = false; WBItem = (ItemPtr)((int)WBScene + (int)WBScene->ItemDir[1].Where); WBItem->IDisplay = false; WBItem = (ItemPtr)((int)WBScene + (int)WBScene->ItemDir[2].Where); WBItem->IDisplay = false; if (LastFXID == 2) LastFXID = -1; /* turn off this sound effect */ }                   else { /* activate the item and proper word shape */ WBItem->IActive = true; if (text == English) { WBItem = (ItemPtr)((int)WBScene + (int)WBScene->ItemDir[1].Where); WBItem->IDisplay = true; if (speech == English) start_soundmap(snd_array[0].smap_id); else start_soundmap(snd_array[1].smap_id); }                       else { WBItem = (ItemPtr)((int)WBScene + (int)WBScene->ItemDir[2].Where); WBItem->IDisplay = true; if (speech == English) start_soundmap(snd_array[0].smap_id); else start_soundmap(snd_array[1].smap_id); }                       stop_fx_alarm;        /* shut off the old alarm */ LastFXID = 2;          /* set sound effect ID */ if (!mute_fx[LastFXID]) { start_soundmap(snd_array[LastFXID].smap_id); start_fx_alarm; }                   }                    while (theInpTab.ButPress) CheckInput; /* wait for button release */ }               break;

case 7: /* Item #1 */ if ((theInpTab.ButPress) && (!smap_busy) && (!smap_list_ctr)) { WBItem = (ItemPtr)((int)WBScene + (int)WBScene->ItemDir[3].Where); if (WBItem->IActive == true) { WBItem->IActive = false; WBItem = (ItemPtr)((int)WBScene + (int)WBScene->ItemDir[4].Where); WBItem->IDisplay = false; WBItem = (ItemPtr)((int)WBScene + (int)WBScene->ItemDir[5].Where); WBItem->IDisplay = false; if (LastFXID == 5) LastFXID = -1; /* turn off this sound effect */ }                   else { WBItem->IActive = true; if (text == English) { WBItem = (ItemPtr)((int)WBScene + (int)WBScene->ItemDir[4].Where); WBItem->IDisplay = true; if (speech == English) start_soundmap(snd_array[3].smap_id); else start_soundmap(snd_array[4].smap_id); }                       else { WBItem = (ItemPtr)((int)WBScene + (int)WBScene->ItemDir[5].Where); WBItem->IDisplay = true; if (speech == English) start_soundmap(snd_array[3].smap_id); else start_soundmap(snd_array[4].smap_id); }                       stop_fx_alarm;        /* shut off the old alarm */ LastFXID = 5;          /* set sound effect ID */ if (!mute_fx[LastFXID]) { start_soundmap(snd_array[LastFXID].smap_id); start_fx_alarm; }                   }                    while (theInpTab.ButPress) CheckInput; }               break;

case 8: /* Item #2 */ if ((theInpTab.ButPress) && (!smap_busy) && (!smap_list_ctr)) { WBItem = (ItemPtr)((int)WBScene + (int)WBScene->ItemDir[6].Where); if (WBItem->IActive == true) { WBItem->IActive = false; WBItem = (ItemPtr)((int)WBScene + (int)WBScene->ItemDir[7].Where); WBItem->IDisplay = false; WBItem = (ItemPtr)((int)WBScene + (int)WBScene->ItemDir[8].Where); WBItem->IDisplay = false; if (LastFXID == 8) LastFXID = -1; /* turn off this sound effect */ }                   else { WBItem->IActive = true; if (text == English) { WBItem = (ItemPtr)((int)WBScene + (int)WBScene->ItemDir[7].Where); WBItem->IDisplay = true; if (speech == English) start_soundmap(snd_array[6].smap_id); else start_soundmap(snd_array[7].smap_id); }                       else { WBItem = (ItemPtr)((int)WBScene + (int)WBScene->ItemDir[8].Where); WBItem->IDisplay = true; if (speech == English) start_soundmap(snd_array[6].smap_id); else start_soundmap(snd_array[7].smap_id); }                       stop_fx_alarm;        /* shut off the old alarm */ LastFXID = 8;          /* set sound effect ID */ if (!mute_fx[LastFXID]) { start_soundmap(snd_array[LastFXID].smap_id); start_fx_alarm; }                   }                    while (theInpTab.ButPress) CheckInput; }               break;

case 9: /* Item #3 */ if ((theInpTab.ButPress) && (!smap_busy) && (!smap_list_ctr)) { WBItem = (ItemPtr)((int)WBScene + (int)WBScene->ItemDir[9].Where); if (WBItem->IActive == true) { WBItem->IActive = false; WBItem = (ItemPtr)((int)WBScene + (int)WBScene->ItemDir[10].Where); WBItem->IDisplay = false; WBItem = (ItemPtr)((int)WBScene + (int)WBScene->ItemDir[11].Where); WBItem->IDisplay = false; if (LastFXID == 11) LastFXID = -1; /* turn off this sound effect */ }                   else { WBItem->IActive = true; if (text == English) { WBItem = (ItemPtr)((int)WBScene + (int)WBScene->ItemDir[10].Where); WBItem->IDisplay = true; if (speech == English) start_soundmap(snd_array[9].smap_id); else start_soundmap(snd_array[10].smap_id); }                       else { WBItem = (ItemPtr)((int)WBScene + (int)WBScene->ItemDir[11].Where); WBItem->IDisplay = true; if (speech == English) start_soundmap(snd_array[9].smap_id); else start_soundmap(snd_array[10].smap_id); }                       stop_fx_alarm;        /* shut off the old alarm */ LastFXID = 11;         /* set sound effect ID */ if (!mute_fx[LastFXID]) { start_soundmap(snd_array[LastFXID].smap_id); start_fx_alarm; }                   }                    while (theInpTab.ButPress) CheckInput; }               break;

case 10: /* Item #4 */ if ((theInpTab.ButPress) && (!smap_busy) && (!smap_list_ctr)) { WBItem = (ItemPtr)((int)WBScene + (int)WBScene->ItemDir[12].Where); if (WBItem->IActive == true) { WBItem->IActive = false; WBItem = (ItemPtr)((int)WBScene + (int)WBScene->ItemDir[13].Where); WBItem->IDisplay = false; WBItem = (ItemPtr)((int)WBScene + (int)WBScene->ItemDir[14].Where); WBItem->IDisplay = false; if (LastFXID == 14) LastFXID = -1; /* turn off this sound effect */ }                   else { WBItem->IActive = true; if (text == English) { WBItem = (ItemPtr)((int)WBScene + (int)WBScene->ItemDir[13].Where); WBItem->IDisplay = true; if (speech == English) start_soundmap(snd_array[12].smap_id); else start_soundmap(snd_array[13].smap_id); }                       else { WBItem = (ItemPtr)((int)WBScene + (int)WBScene->ItemDir[14].Where); WBItem->IDisplay = true; if (speech == English) start_soundmap(snd_array[12].smap_id); else start_soundmap(snd_array[13].smap_id); }                       stop_fx_alarm;        /* shut off the old alarm */ LastFXID = 14;         /* set sound effect ID */ if (!mute_fx[LastFXID]) { start_soundmap(snd_array[LastFXID].smap_id); start_fx_alarm; }                   }                    while (theInpTab.ButPress) CheckInput; }               break; }       last_xpos = inp_xpos;   /* xpos of input device */ last_ypos = inp_ypos;  /* ypos of input device */ }   stop_fx_alarm; stop_all_audio; /*    * Give back sound map buffers */   for (ctr = 15; ctr >= 0; ctr --) { if (snd_array[ctr].smap_id) { SMAP_DESTROY(audpath, snd_array[ctr].smap_id); snd_array[ctr].smap_id = 0; }   } }

/* * newWBpkg - This loads one of the twenty wordbook packages *           The soundmaps are loaded to their buffers *           The image data gets loaded at PkgBuf */ void newWBpkg(direction) short direction; { Ptr        thePtr; Ptr        scnptrsav; int        fid; WBSMapPtr  theSMPtr; short      NumMaps; int        NumGrps; short      ctr; Boolean    stat;

/*    * Release old soundmaps */   for (ctr = 15; ctr >= 0; ctr --) { if (snd_array[ctr].smap_id) { SMAP_DESTROY(audpath, snd_array[ctr].smap_id); snd_array[ctr].smap_id = 0; }   }

/*    * try opening the new file first, before allocating the new soundmaps */   fid = open_file(WBNames[WhichPage], true); if (fid == -1) { STATUS1("had trouble opening package - will try another\n"); if (direction) { wbsctr ++; if (wbsctr == NumPages) wbsctr = 0; }       else { wbsctr --; if (wbsctr == -1) wbsctr = NumPages -1; }       WhichPage = wbstab[wbsctr]; fid = open_file(WBNames[WhichPage], false); }   /*     * Create the new soundmaps for this page */   theSMPtr = WBSMaplists[WhichPage]; NumMaps = theSMPtr->NumSMaps; for (ctr=0; ctr<NumMaps; ctr++) { NumGrps = (theSMPtr->SMapSize[ctr] +17); /*        * This little 'if/else' became necessary when we switched from AMP * to playing soundmaps at the last minute. It used to be okay to        * mix silence (the 18 soundgroups) with the background audio. Now * it creates a gap in the background audio for no apparent reason * for the user. If 'NumGrps' equals 18 we have to set a flag to        * not play the sound effect. We also must not set the fx_alarm. */       if  (NumGrps == 18 + 17) mute_fx[ctr] = true; else mute_fx[ctr] = false; /* let this audio play */

snd_array[ctr].smap_id = SMAP_CREATE(audpath, D_CMONO, NumGrps, &snd_array[ctr].data); if ( snd_array[ctr].smap_id == -1 ) { STATUS1("SMAP_CREATE returned -1\n"); }   }

stat = play_recs(fid, set_wbpkg_pcls, 1, false, false, 0); stat = close_file(fid);

DirNum = DirSaveWB; /* restore old value */

SceneTab[MScene] = (ScenePtr)stuffpkg(PkgBuf); FixScene(MScene); WBScene = SceneTab[MScene]; WBScene->AniDelay = WordBook_AniDelay; WBScene->Active = true; WBScene->Display = true; SetUpScene(MScene);

/*    * Set list of hotspots */   theRectPtr = (RectListPtr)WBSpots[WhichPage];

FilCol = 96; /* should probably be a little more random than this */ /*    * Save original contents and then set scn_ptr to bkgd scrn * (most drawing happens at scn_ptr) */   scnptrsav = scn_ptr; scn_ptr = vidmem5; Fill(fullRect, FilCol); /* fill entire bkgd screen */

thePtr = (Ptr) ((unsigned)WBScene + (unsigned)pkgTOC->TE[1].Where); Draw((ShapePtr)thePtr, 32, 25); /* draw the shape */ scn_ptr = scnptrsav; /* restore scn_ptr */

copy_bkgd_front;

/*    * Set the background audio file for this page */   if (WBTunes[WhichPage].MCAFile) TUNEfid = Tune2ID; else TUNEfid = Tune1ID;

/*    * Disable the sound effect stuff for now */   LastFXID = -1; fx_time = false; currentT = clock;        /* get current tick count */ reset_dim; reset_help; }
 * 1) if 0
 * 1) endif