/* This program is probably copyright Commodore-Amiga. It was mailed * to me directly by Bruce Barrett at Commodore-Amiga in response * to a question about a previous version's copyright status. I * therefore assume that it is Commodore-Amiga's intention that this * program be freely redistributable. Fred Fish, 3-Jan-86. */ /* !!! To those who haven't figured it out yet: * !!! set stack to 15000 before compiling. * !!! This is a generally good thing to do if * !!! the compiler blows up on a large source. * !!! if your program suddenly KILLS the compiler, * !!! increase stack by 5K and try again. jeeze you guys. */ /* This program was written to show the use of gadgets in a * window. Thus one menu, one auto requester, but lots of * gadget types. * For the sake of example, two mutual exclude gadgets * (female/male) are shown that perform a function that might * be better implemented as a toggle image, in a manner similar * to that shown in the inflection Mode gadget. * Again for the sake of example, the proportional gadgets * are generated dynamicly (that is, copied from a template and * filled in), whereas most gadgets are declared staticly in * the struct declaration, which saves the initialization code * space. * Lastly, for the sake of example, this program is extremely * verbose in the way of comments. Hope you don't mind. */ /* Written by David M Lucas. */ /* If you find somthing you don't like, fix it! Have fun! */ /* Send complaints to /dev/null. really. */ /* Thanks Amiga. */ #include "exec/types.h" #include "exec/exec.h" #include "intuition/intuition.h" #include "intuition/intuitionbase.h" #include "graphics/regions.h" #include "graphics/copper.h" #include "graphics/gels.h" #include "graphics/gfxbase.h" #include "devices/keymap.h" #include "hardware/blit.h" #include "devices/narrator.h" #include "libraries/translator.h" #ifndef LIBRARY_VERSION # define LIBRARY_VERSION (1) #endif /* #define DEBUG */ #define CONTWINDW 321 /* Overall Control Window Width/Height */ #define CONTWINDH 123 #define FACEWINDW 32 /* Overall Face Window Width / Height */ #define FACEWINDH 44 /* this includes borders, incedently */ /* Pen numbers to draw gadget borders/images/text with */ #define REDP 3 /* color in register 3 once was red */ #define BLKP 2 /* color in register 2 was black */ #define WHTP 1 /* color in register 1 was white */ #define BLUP 0 /* color in register 0 was blue */ /* the length of the English and phonetic buffers */ #define ESTRINGSIZE 512 #define PSTRINGSIZE 768 /* phonemes are longer than english */ #define NUMPROPS 4 /* number of proportional gadgets */ /* Ranges of proportional data */ #define RNGFREQ (MAXFREQ - MINFREQ) +1 #define RNGRATE (MAXRATE - MINRATE) +1 #define RNGPITCH (MAXPITCH - MINPITCH) +1 #define RNGVOL (MAXVOL - MINVOL) +1 struct TextAttr TestFont = /* Needed for opening screen */ { (STRPTR)"topaz.font", TOPAZ_EIGHTY, 0, 0 }; /* Which audio channels to use */ BYTE audio_chan[] = {3, 5, 10, 12}; /* Pointer to translator library vectors */ struct Library *TranslatorBase = 0; struct MsgPort talk_port; /* Message port for the say's I/O */ struct MsgPort read_port; /* Message port for the say's I/O */ struct mouth_rb mouth_io; /* IO Request block, mouth flavor */ /* IO Request block, narrator flavor */ struct narrator_rb voice_io; /* indicative of the Open return */ UBYTE NarratorOpenError = -1; /* not yet opened */ /* indicative of a Translations success */ UBYTE TranslatorError = 0; USHORT i; /* These are used to draw the eyes and mouth size relative */ USHORT MouthWMult; USHORT EyesLeft; USHORT MouthHMult; USHORT EyesTop; USHORT EyesBottom; USHORT YMouthCenter; /* Pixels from top edge */ USHORT XMouthCenter; /* Pixels from left edge */ USHORT yaw; USHORT LipWidth, LipHeight; /* String Gadgets ********************************************* * First the string gadgets. * 1) because the Phonetic string is refreshed programaticly * (that is, deleted and added again) quite often, and doing * this requires the use of RefreshGadgets(), and this causes * gadgets that are closer to the beginning of the list than * the gadget given to RefreshGadgets() to flicker. * 2) because they don't flicker when OTHER gadgets * (ie female/male, coming up) are deleted and added. */ /* These'll be used to put a nice double line border around * each of the two string gadgets. */ /* y,x pairs drawn as a connected line. Be sure to have an even * number of arguments (ie complete pairs). */ USHORT StrVectors[] = { 0, 0, 297, 0, 297, 14, 0, 14, 0, 1, 296, 1, 296, 13, 1, 13, 1, 1 }; struct Border StrBorder = { -4, -3, /* initial offsets, gadget relative */ WHTP, BLUP, JAM1, /* pens (fore, back) and drawmode */ 9, /* number of vectors */ StrVectors, /* pointer to the actual array of vectors */ NULL /* no next Border, can point to another border */ }; /* The same undo buffer is used for both string gadgets, * this is sized to largest so that largest fits. */ UBYTE UndoBuffer[PSTRINGSIZE]; /* English String Gadget is where the user types in English */ /* default text */ UBYTE EnglBuffer[ESTRINGSIZE] = "This is amiga speaking."; struct StringInfo EnglInfo = { EnglBuffer, /* pointer to I/O buffer */ UndoBuffer, /* pointer to undo buffer */ 0, /* buffer position */ ESTRINGSIZE, /* max number of chars, including NULL */ 0, 0, /* first char in display, undo positions */ 24, /* number of chars (currently) in the buffer */ 0, 0, 0, /* position variables calculated by Intuition */ NULL, /* no pointer to RastPort */ 0, /* not a LongInt string gadget */ NULL /* no pointer to alternate keymap */ }; struct IntuiText EnglText = { WHTP, BLUP, /* FrontPen, BackPen */ JAM1, /* DrawMode */ 0, -13, /* LeftEdge, TopEdge (relative to gadget) */ &TestFont, /* pointer to TextFont */ "English:", /* pointer to Text */ NULL /* no pointer to NextText */ }; struct Gadget EnglStrGadget = { NULL, /* pointer to Next Gadget */ 11, 63, 290, 10, /* (Left Top Width Height) Hit Box */ GADGHCOMP, /* Flags */ RELVERIFY, /* Activation flags */ STRGADGET, /* Type */ (APTR)&StrBorder, /* pointer to Border Image */ NULL, /* no pointer to SelectRender */ &EnglText, /* pointer to GadgetText */ 0, /* no MutualExclude */ (APTR)&EnglInfo, /* pointer to SpecialInfo */ 0, /* no ID */ NULL /* no pointer to special data */ }; /* Phonetic string gadget is where the program puts the * translated string, necessating a call to RefreshGadgets(), * and is where the user can type in Phonemes. */ UBYTE PhonBuffer[PSTRINGSIZE] = "DHIHS IHZ AHMIY3GAH SPIY4KIHNX."; struct StringInfo PhonInfo = { PhonBuffer, /* pointer to input buffer */ UndoBuffer, /* pointer to undo buffer */ 0, /* initial buffer position */ PSTRINGSIZE, /* max number of chars, including NULL */ 0, 0, /* display, undo positions */ 32, /* number of chars (currently) in the buffer */ 0, 0, 0, /* position variables calculated by Intuition */ NULL, /* no pointer to RastPort */ NULL, /* not a LongInt string gadget */ NULL /* no pointer to alternate keymap */ }; struct IntuiText PhonText = { WHTP, BLUP, /* FrontPen, BackPen */ JAM1, /* DrawMode */ 0, -13, /* LeftEdge, TopEdge (relative to gadget) */ &TestFont, /* pointer to TextFont */ "Phonetics:", /* pointer to Text */ NULL /* no pointer to NextText */ }; struct Gadget PhonStrGadget = { &EnglStrGadget, /* pointer to Next Gadget */ 11, 94, 290, 10, /* (Left Top Width Height) Hit Box */ GADGHCOMP, /* Flags */ RELVERIFY, /* Activation flags */ STRGADGET, /* Type */ (APTR)&StrBorder, /* pointer to Border Image */ NULL, /* no pointer to SelectRender */ &PhonText, /* pointer to GadgetText */ 0, /* no MutualExclude */ (APTR)&PhonInfo, /* pointer to SpecialInfo */ 0, /* no ID */ NULL /* no pointer to special data */ }; /* Now come the Boolean Gadgets. * The female/male pair shows the simplest implementation I * could think of to show how you can do mutual-exclude type * things yourself. They are two toggle gadgets that use * highlight image. The program starts with one selected, and * then if either of them are hit, both toggle. Gadgets must * be deleted and added whenever you want to change structure * member values that intuition expects to be coming from the * user, not a program (like the SELECTED bit in flags). Note * that certain structure values CAN be changed programaticly * without all this broohaha. Haha. Consult the intuition * manual. */ /* Female Toggle (Highlight Image) (Quasi mutual exclude with Male Toggle) */ struct Image FemaleImage = { 0, 0, /* LeftEdge, TopEdge (relative to gadget) */ 20, 10, 1, /* Width, Height, Depth */ NULL, /* pointer to ImageData */ 0x1, 0x0 /* PlanePick, PlaneOnOff */ }; struct Gadget FemaleGadget = { &PhonStrGadget, /* pointer to Next Gadget */ 134, 34, 20, 10, /* (Left Top Width Height) Hit Box */ GADGIMAGE | GADGHCOMP, /* Flags */ /* Activation flags */ RELVERIFY | GADGIMMEDIATE | TOGGLESELECT, BOOLGADGET, /* Type */ (APTR)&FemaleImage, /* pointer to GadgetRender */ NULL, /* no pointer to SelectRender */ NULL, /* no pointer to GadgetText */ 0, /* no MutualExclude */ NULL, /* no pointer to SpecialInfo */ 0, /* no ID */ NULL /* no pointer to special data */ }; /* Male Toggle (Highlight Image) (Quasi mutual Exclude with above) */ struct Image MaleImage = { 0, 0, /* LeftEdge, TopEdge (relative to gadget) */ 20, 10, 1, /* Width, Height, Depth */ NULL, /* pointer to ImageData */ 0x1, 0x0 /* PlanePick, PlaneOnOff */ }; struct Gadget MaleGadget = { &FemaleGadget, /* pointer to Next Gadget */ 154, 34, 20, 10, /* (Left Top Width Height) Hit Box */ GADGIMAGE | GADGHCOMP | SELECTED, /* Flags */ /* Activation flags */ RELVERIFY | GADGIMMEDIATE | TOGGLESELECT | ACTIVATE, BOOLGADGET, /* Type */ (APTR)&MaleImage, /* pointer to GadgetRender */ NULL, /* no pointer to SelectRender */ NULL, /* no pointer to GadgetText */ 0, /* no MutualExclude */ NULL, /* no pointer to SpecialInfo */ 0, /* no ID */ NULL /* no pointer to special data */ }; /* This boolean toggle gadget has an * alternate image that indicates * selection. The image stays flipped * until it gets another hit. (it toggles) */ /* Inflection Mode Toggle (AltImage) *************************/ struct Image HumanImage = { 0, 0, /* LeftEdge, TopEdge (relative to gadget) */ 40, 20, 1, /* Width, Height, Depth */ NULL, /* pointer to ImageData */ 0x1, 0x0 /* PlanePick, PlaneOnOff */ }; struct Image RobotImage = { 0, 0, /* LeftEdge, TopEdge (relative to gadget) */ 40, 20, 1, /* Width, Height, Depth */ NULL, /* pointer to ImageData */ 0x1, 0x0 /* PlanePick, PlaneOnOff */ }; struct Gadget ModeGadget = { &MaleGadget, /* pointer to Next Gadget */ 134, 2, 40, 20, /* (Left Top Width Height) Hit Box */ GADGIMAGE | GADGHIMAGE, /* Flags */ /* Activation flags */ RELVERIFY | GADGIMMEDIATE | TOGGLESELECT, BOOLGADGET, /* Type */ (APTR)&HumanImage, /* pointer to GadgetRender */ (APTR)&RobotImage, /* pointer to SelectRender */ NULL, /* no pointer to GadgetText */ 0, /* no MutualExclude */ NULL, /* no pointer to SpecialInfo */ 0, /* no ID */ NULL /* no pointer to special data */ }; /* Face Toggle (image and text) ******************************/ struct IntuiText FaceIText = { WHTP, BLUP, /* FrontPen, BackPen */ JAM2, /* DrawMode */ 4, 1, /* LeftEdge, TopEdge (relative to gadget) */ &TestFont, /* pointer to TextFont */ "Face",/* pointer to Text */ NULL /* no pointer to NextText */ }; struct Image FaceImage = { 0, 0, /* LeftEdge, TopEdge (relative to gadget) */ 40, 10, 1, /* Width, Height, Depth */ NULL, /* pointer to ImageData */ 0x1, 0x0 /* PlanePick, PlaneOnOff */ }; struct Gadget FaceGadget = { &ModeGadget, /* pointer to Next Gadget */ 134, 23, 40, 10, /* (Left Top Width Height) Hit Box */ GADGIMAGE | GADGHCOMP, /* Flags */ /* Activation flags */ RELVERIFY | GADGIMMEDIATE | TOGGLESELECT, BOOLGADGET, /* Type */ (APTR) &FaceImage, /* pointer to GadgetRender */ NULL, /* no pointer to SelectRender */ &FaceIText, /* pointer to GadgetText */ 0, /* no MutualExclude */ NULL, /* no pointer to SpecialInfo */ 0, /* no ID */ NULL /* no pointer to special data */ }; /* Stop Hit (image and text) ******************************/ struct IntuiText StopIText = { WHTP, BLUP, /* FrontPen, BackPen */ JAM2, /* DrawMode */ 4, 1, /* LeftEdge, TopEdge (relative to gadget) */ &TestFont, /* pointer to TextFont */ "Stop",/* pointer to Text */ NULL /* no pointer to NextText */ }; struct Image StopImage = { 0, 0, /* LeftEdge, TopEdge (relative to gadget) */ 40, 10, 1, /* Width, Height, Depth */ NULL, /* pointer to ImageData */ 0x1, 0x0 /* PlanePick, PlaneOnOff */ }; struct Gadget StopGadget = { &FaceGadget, /* pointer to Next Gadget */ 134, 45, 40, 10, /* Left Top Width Height Hit Box */ GADGIMAGE | GADGHCOMP, /* Flags */ RELVERIFY | GADGIMMEDIATE, /* Activation flags */ BOOLGADGET, /* Type */ (APTR) &StopImage, /* pointer to GadgetRender */ NULL, /* no pointer to SelectRender */ &StopIText, /* pointer to GadgetText */ 0, /* no MutualExclude */ NULL, /* no pointer to SpecialInfo */ 0, /* no ID */ NULL /* no pointer to special data */ }; /* This is a hit (as opposed to toggle) gadget that starts the translation.*/ /* Translate Hit (Highlight image) ***************************/ USHORT TransVectors[] = { 0, 0, 79, 0, 79, 13, 0, 13, 0, 1, 78, 1, 78, 12, 1, 12, 1, 1 }; struct Border TransBorder = { -4, -3, /* initial offsets, gadget relative */ WHTP, BLUP, JAM1, /* pens (fore, back) and drawmode */ 9, /* number of vectors */ TransVectors, /* pointer to the array of vectors */ NULL /* no next Border, can point to another */ }; struct IntuiText TranslateIText = { WHTP, BLUP, /* FrontPen, BackPen */ JAM2, /* DrawMode */ 0, 0, /* LeftEdge, TopEdge (relative to gadget) */ &TestFont, /* pointer to TextFont */ "Translate",/* pointer to Text */ NULL /* no pointer to NextText */ }; struct Gadget TranslateGadget = { &StopGadget, /* pointer to Next Gadget */ 229, 48, 71, 8, /* (Left Top Width Height) Hit Box */ GADGHCOMP, /* Flags */ RELVERIFY | GADGIMMEDIATE, /* Activation flags */ BOOLGADGET, /* Type */ (APTR)&TransBorder, /* no pointer to GadgetRender */ NULL, /* no pointer to SelectRender */ &TranslateIText, /* pointer to GadgetText */ 0, /* no MutualExclude */ NULL, /* no pointer to SpecialInfo */ 0, /* no ID */ NULL /* no pointer to special data */ }; /* This is a hit (as opposed to toggle) Starts the narration */ /* Speak Hit (Highlight Image) *******************************/ USHORT SpeakVectors[] = { 0, 0, 47, 0, 47, 13, 0, 13, 0, 1, 46, 1, 46, 12, 1, 12, 1, 1 }; struct Border SpeakBorder = { -4, -3, /* initial offsets, gadget relative */ WHTP, BLUP, JAM1, /* pens (fore, back) and drawmode */ 9, /* number of vectors */ SpeakVectors, /* pointer to the actual array of vectors */ NULL /* no next Border, can point to another border */ }; struct IntuiText SpeakIText = { WHTP, BLUP, /* FrontPen, BackPen */ JAM2, /* DrawMode */ 0, 0, /* LeftEdge, TopEdge (relative to gadget) */ &TestFont, /* pointer to TextFont */ "Speak", /* pointer to Text */ NULL /* no pointer to NextText */ }; struct Gadget SpeakGadget = { &TranslateGadget, /* pointer to Next Gadget */ 261, 79, 40, 8, /* (Left Top Width Height) Hit Box */ GADGHCOMP, /* Flags */ RELVERIFY | GADGIMMEDIATE, /* Activation flags */ BOOLGADGET, /* Type */ (APTR)&SpeakBorder, /* pointer to GadgetRender */ NULL, /* no pointer to SelectRender */ &SpeakIText, /* pointer to GadgetText */ 0, /* no MutualExclude */ NULL, /* no pointer to SpecialInfo */ 0, /* no ID */ NULL /* no pointer to special data */ }; /* Now the proportional gadgets. */ /* Proportional Gadgets **************************************/ /* The following variables are used to create proportional * Gadgets. These variables will be filled in with copies of * the generic Gadgetry below. */ SHORT PropCount = 0; /* index to next available Gadget */ struct IntuiText PTexts[NUMPROPS];/* get copies of TPropText */ /* dummy AUTOKNOB Images are required */ struct Image PImages[NUMPROPS]; /* These get copies of TPropInfo */ struct PropInfo PInfos[NUMPROPS]; /* These get copies of TPropGadget */ struct Gadget Props[NUMPROPS]; struct IntuiText TPropText = { WHTP, BLUP, /* FrontPen, BackPen */ JAM1, /* DrawMode */ 0, -10, /* LeftEdge, TopEdge (relative to gadget) */ &TestFont, /* pointer to TextFont */ NULL, /* pointer to Text is filled at runtime */ NULL /* no pointer to NextText */ }; struct PropInfo TPropInfo = { AUTOKNOB | FREEHORIZ, /* Flags */ 0, 0, /* Pots: Horiz, Vert: both start at 0 */ 0x1FFF, 0x1FFF, /* Bodies: Horiz is 1/8, Vert is 1/8 */ 0, 0, 0, 0, 0, 0 /* System usage stuff */ }; /* this is the template for the Gadget of a horizontal */ /* Proportional Gadget */ struct Gadget TPropGadget = { &SpeakGadget, /* pointer to NextGadget */ 7, 12, 115, 10, /* Select Box L T W H */ GADGHCOMP | GADGIMAGE, /* Flags */ GADGIMMEDIATE | RELVERIFY, /* Activation flags */ PROPGADGET, /* Type */ NULL, /* pointer to Image filled in later */ NULL, /* no pointer to SelectRender */ NULL, /* no pointer to GadgetText */ 0, /* no MutualExclude */ NULL, /* SpecialInfo proportional data filled later */ 0, /* no ID */ NULL /* no pointer to special data */ }; struct IntuitionBase *IntuitionBase = 0; struct GfxBase *GfxBase = 0; /* Only one menu. */ ULONG MenuNumber; ULONG TheMenu; ULONG TheItem; struct IntuiText MenuItemText = { BLUP, /* Front Pen */ WHTP, /* Back pen */ JAM2, /* Draw Mode */ 0, /* Left Edge */ 0, /* Top */ &TestFont, /* pointer to TextFont */ "About SpeechToy...", /* text */ NULL /* next */ }; struct MenuItem MyMenuItem = { NULL, /* pointer to next item */ 0, /* left */ 0, /* top */ 150, /* width */ 8, /* height */ ITEMTEXT | ITEMENABLED | HIGHCOMP, /* flags */ 0, /* no mutual exclude */ (APTR)&MenuItemText, /* Render */ NULL, /* pointer to alternate image */ NULL, /* Command "amiga" char */ NULL, /* Sub Item */ MENUNULL /* nextselect */ }; struct Menu MyMenu = { NULL, /* pointer to next menu */ 0,0,150,0, /* left,0,Width,0 */ MENUENABLED, /* flags */ "SpeachToy Menu", /* menu name */ &MyMenuItem /* First Item in list */ }; struct IntuiText ReqText1 = { BLUP, /* Front Pen */ WHTP, /* Back pen */ JAM2, /* Draw Mode */ 5, /* Left Edge */ 23, /* Top */ &TestFont, /* pointer to TextFont */ "Version 1.1 21 Dec, 1985", /* text */ NULL /* next */ }; struct IntuiText ReqText2 = { BLUP, /* Front Pen */ WHTP, /* Back pen */ JAM2, /* Draw Mode */ 5, /* Left Edge */ 13, /* Top */ &TestFont, /* pointer to TextFont */ "Freeware - Public Domain ", /* text */ &ReqText1 /* next */ }; struct IntuiText ReqText3 = { BLUP, /* Front Pen */ WHTP, /* Back pen */ JAM2, /* Draw Mode */ 5, /* Left Edge */ 3, /* Top */ &TestFont, /* pointer to TextFont */ "Written by David M Lucas ", /* text */ &ReqText2 /* next */ }; struct IntuiText OKIText = { BLUP, WHTP, /* FrontPen, BackPen */ JAM2, /* DrawMode */ 6, 3, /* LeftEdge, TopEdge (relative to gadget) */ &TestFont, /* pointer to TextFont */ "OK", /* pointer to Text */ NULL /* no pointer to NextText */ }; struct Requester *AboutRequester; USHORT autoret; struct Window *ControlWindow = NULL; struct Window *FaceWindow = NULL; struct IntuiMessage *MyIntuiMessage; struct NewWindow NewControlWindow = { 00, 11, /* start LeftEdge, TopEdge */ CONTWINDW, CONTWINDH, /* start Width, Height */ -1, -1, /* DetailPen, BlockPen */ GADGETUP | CLOSEWINDOW | MENUPICK, /* IDCMP FLAGS */ WINDOWDRAG | WINDOWDEPTH | WINDOWCLOSE | GIMMEZEROZERO | ACTIVATE,/* Flags (can be NULL) */ &Props[NUMPROPS-1], /* Pointer to FirstGadget */ NULL, /* no pointer to first CheckMark */ "SpeechToy", /* Title (can be NULL) */ NULL, /* no Pointer to Screen */ NULL, /* no Pointer to BitMap */ 20, 20, /* Min/max Sizable to (w/h) */ CONTWINDW, CONTWINDH, /* These aint used, can't size */ WBENCHSCREEN /* Type of screen window appears in */ }; struct NewWindow NewFaceWindow = { CONTWINDW, 11, /* start LeftEdge, TopEdge */ FACEWINDW * 2, FACEWINDH, /* start Width, Height */ -1, -1, /* DetailPen, BlockPen */ SIZEVERIFY | NEWSIZE | MENUPICK, /* IDCMP FLAGS */ /* Flags (can be NULL) */ WINDOWDRAG | WINDOWDEPTH | WINDOWSIZING | SIZEBBOTTOM | GIMMEZEROZERO | ACTIVATE, NULL, /* no Pointer to FirstGadget */ NULL, /* no Pointer to first CheckMark */ "Face", /* Title */ NULL, /* no Pointer to Screen */ NULL, /* no Pointer to BitMap */ FACEWINDW, FACEWINDH,/* Minimum sizeable to */ 640, 200, /* Maximum sizeable to */ WBENCHSCREEN /* Type of screen window appears in */ }; USHORT FemaleIData[] = { /* ---- - These nibbles matter to image. */ 0x0000, 0x0000, 0x00F0, 0x0000, 0x0198, 0x0000, 0x030C, 0x0000, 0x0198, 0x0000, 0x00F0, 0x0000, 0x0060, 0x0000, 0x01F8, 0x0000, 0x0060, 0x0000, 0x0000, 0x0000 }; USHORT MaleIData[] = { /* ---- - These nibbles matter to image. */ 0x0000, 0x0000, 0x003E, 0x0000, 0x000E, 0x0000, 0x0036, 0x0000, 0x01E0, 0x0000, 0x0330, 0x0000, 0x0618, 0x0000, 0x0330, 0x0000, 0x01E0, 0x0000, 0x0000, 0x0000 }; USHORT HumanIData[] = { /* ---- ---- -- These nibbles matter to image. */ 0x0000,0x0000,0x0000, 0x0000,0x0000,0x0000, 0x0000,0x0000,0x0000, 0x0000,0x0000,0x0000, 0x0007,0x9E00,0x0000, 0x0001,0x8600,0x0000, 0x0000,0x0000,0x0000, 0x0000,0x0000,0x0000, 0x0000,0x2000,0x0000, 0x0000,0x1000,0x0000, 0x0000,0x0800,0x0000, 0x0000,0x7C00,0x0000, 0x0000,0x0000,0x0000, 0x0000,0x0000,0x0000, 0x0000,0x0000,0x0000, 0x0000,0x7800,0x0000, 0x0000,0x0000,0x0000, 0x0000,0x0000,0x0000, 0x0000,0x0000,0x0000, 0x0000,0x0000,0x0000 }; USHORT RobotIData[] = { /* ---- ---- -- These nibbles matter to image. */ 0x0000,0x0000,0x0000, 0x0000,0x0000,0x0000, 0x0000,0x0000,0x0000, 0x0000,0x0000,0x0000, 0x0007,0x9E00,0x0000, 0x0004,0x9200,0x0000, 0x0007,0x9E00,0x0000, 0x0000,0x0000,0x0000, 0x0000,0x0000,0x0000, 0x0000,0x0000,0x0000, 0x0000,0x0000,0x0000, 0x0000,0x0000,0x0000, 0x0000,0x0000,0x0000, 0x0001,0xF800,0x0000, 0x0001,0x0800,0x0000, 0x0001,0xF800,0x0000, 0x0000,0x0000,0x0000, 0x0000,0x0000,0x0000, 0x0000,0x0000,0x0000, 0x0000,0x0000,0x0000 }; USHORT FaceIData[] = { /* ---- ---- -- These nibbles matter to image. */ 0x0000,0x0000,0x0000, 0x0000,0x0000,0x0000, 0x0000,0x0000,0x0000, 0x0000,0x0000,0x0000, 0x0000,0x0000,0x0000, 0x0000,0x0000,0x0000, 0x0000,0x0000,0x0000, 0x0000,0x0000,0x0000, 0x0000,0x0000,0x0000, 0x0000,0x0000,0x0000 }; USHORT StopIData[] = { /* ---- ---- -- These nibbles matter to image. */ 0x0000,0x0000,0x0000, 0x0000,0x0000,0x0000, 0x0000,0x0000,0x0000, 0x0000,0x0000,0x0000, 0x0000,0x0000,0x0000, 0x0000,0x0000,0x0000, 0x0000,0x0000,0x0000, 0x0000,0x0000,0x0000, 0x0000,0x0000,0x0000, 0x0000,0x0000,0x0000 }; USHORT *FemaleIData_chip = 0; USHORT *MaleIData_chip = 0; USHORT *HumanIData_chip = 0; USHORT *RobotIData_chip = 0; USHORT *FaceIData_chip = 0; USHORT *StopIData_chip = 0; /** start of code ***************************/ main() { ULONG Signals; /* Wait() tells me which to look at */ ULONG MIClass; /* Save quickly, ReplyMsg() asap */ USHORT MICode; /* These hold my needed information */ APTR MIAddress; /* let MyCleanup know these signals not allocated yet */ talk_port.mp_SigBit = -1; read_port.mp_SigBit = -1; /* Open those libraries that the program uses directly */ if ((IntuitionBase = (struct IntuitionBase *) OpenLibrary("intuition.library", LIBRARY_VERSION)) == 0) { #ifdef DEBUG printf("Can't open the intuition library\n"); #endif MyCleanup(); exit(FALSE); } if ((GfxBase = (struct GfxBase *) OpenLibrary("graphics.library", LIBRARY_VERSION)) == 0) { #ifdef DEBUG printf("Can't open the graphics library\n"); #endif MyCleanup(); exit(FALSE); } if ((TranslatorBase = (struct Library *) OpenLibrary("translator.library", LIBRARY_VERSION)) == 0) { #ifdef DEBUG printf("Can't open the translator library\n"); #endif MyCleanup(); exit(FALSE); } /* Open the device */ if ((NarratorOpenError = OpenDevice("narrator.device", 0, &voice_io, 0)) != 0) { #ifdef DEBUG printf("Can't open the narrator device\n"); #endif MyCleanup(); exit(FALSE); } /* This is where the proportional gadgets are set up, using * the templates that were declared staticly. */ for(PropCount = 0; PropCount < NUMPROPS; PropCount++) { PTexts[PropCount] = TPropText; Props[PropCount] = TPropGadget; PInfos[PropCount] = TPropInfo; Props[PropCount].GadgetText = (struct IntuiText *) &PTexts[PropCount]; Props[PropCount].GadgetRender = (APTR) &PImages[PropCount]; Props[PropCount].SpecialInfo = (APTR)&PInfos[PropCount]; switch (PropCount) { case 0: PTexts[PropCount].IText = "Sample Freq:"; if (DEFFREQ == MAXFREQ) PInfos[PropCount].HorizPot = 65535; else PInfos[PropCount].HorizPot = ((DEFFREQ - MINFREQ) << 16) / (MAXFREQ - MINFREQ); break; case 1: PTexts[PropCount].IText = "Rate:"; Props[PropCount].TopEdge += 22; Props[PropCount].NextGadget = &Props[PropCount-1]; if (DEFRATE == MAXRATE) PInfos[PropCount].HorizPot = 65535; else PInfos[PropCount].HorizPot = ((DEFRATE - MINRATE) << 16) / (MAXRATE - MINRATE); break; case 2: PTexts[PropCount].IText = "Pitch:"; Props[PropCount].LeftEdge += 183; Props[PropCount].NextGadget = &Props[PropCount-1]; if (DEFPITCH == MAXPITCH) PInfos[PropCount].HorizPot = 65535; else PInfos[PropCount].HorizPot = ((DEFPITCH-MINPITCH) << 16) / (MAXPITCH - MINPITCH); break; case 3: PTexts[PropCount].IText = "Volume:"; Props[PropCount].TopEdge += 22; Props[PropCount].LeftEdge += 183; Props[PropCount].NextGadget = &Props[PropCount-1]; if (DEFVOL == MAXVOL) PInfos[PropCount].HorizPot = 65535; else PInfos[PropCount].HorizPot = ((DEFVOL - MINVOL) << 16) / (MAXVOL - MINVOL); break; } } /* Now allocate memory accessable by the chips for images */ if (InitImages() != TRUE) { #ifdef DEBUG printf("Couldn't Allocate Images in chip memory.\n"); #endif MyCleanup(); exit(FALSE); } /* Set up the write port, allocate the signal, */ /* and the message */ talk_port.mp_Node.ln_Type = NT_MSGPORT; talk_port.mp_Flags = 0; if ((talk_port.mp_SigBit = AllocSignal(-1)) == -1) { #ifdef DEBUG printf("Couldn't Allocate talk Signal bit\n"); #endif MyCleanup(); exit(FALSE); } talk_port.mp_SigTask = (struct Task *) FindTask((char *) NULL); NewList(&talk_port.mp_MsgList); /* Set up the read port, allocate the signal, */ /* and the message */ read_port.mp_Node.ln_Type = NT_MSGPORT; read_port.mp_Flags = 0; if ((read_port.mp_SigBit = AllocSignal(-1)) == -1) { #ifdef DEBUG printf("Couldn't Allocate read Signal bit\n"); #endif MyCleanup(); exit(FALSE); } read_port.mp_SigTask = (struct Task *) FindTask((char *) NULL); NewList(&read_port.mp_MsgList); /* Set up the write channel information */ voice_io.ch_masks = (audio_chan); voice_io.nm_masks = sizeof(audio_chan); voice_io.mouths = 0; voice_io.message.io_Message.mn_ReplyPort = &talk_port; voice_io.message.io_Command = CMD_WRITE; voice_io.message.io_Offset = 0; voice_io.message.io_Data = (APTR)PhonBuffer; voice_io.message.io_Message.mn_Length = sizeof(voice_io); /* Set up the read channel information */ mouth_io.voice = voice_io; mouth_io.width = 0; mouth_io.height = 0; mouth_io.voice.message.io_Message.mn_ReplyPort = &read_port; mouth_io.voice.message.io_Command = CMD_READ; mouth_io.voice.message.io_Error = 0; if (FaceWindow == NULL) { if ((ControlWindow = (struct Window *)OpenWindow (&NewControlWindow)) == NULL) { #ifdef DEBUG printf("Couldn't open the control window.\n"); #endif MyCleanup(); exit(FALSE); } } /* fill background of window */ SetAPen(ControlWindow->RPort, BLKP); RectFill(ControlWindow->RPort,0,0, ControlWindow->GZZWidth, ControlWindow->GZZHeight); RefreshGadgets(&Props[NUMPROPS-1],ControlWindow,NULL); SetMenuStrip(ControlWindow, &MyMenu); /* !!! Ah, But what if FaceWindow's not been opened? */ for (;;) { /* ever wait for a signal and process it */ /* wait lets the rest of the system run, */ /* this program sleeps */ Signals = Wait((1 << ControlWindow->UserPort->mp_SigBit) | (1 << FaceWindow->UserPort->mp_SigBit) | (1 << voice_io.message.io_Message.mn_ReplyPort->mp_SigBit) | (1 << mouth_io.voice.message.io_Message.mn_ReplyPort->mp_SigBit)); /* now check to see to what we owe the intrusion */ if (Signals & (1<< ControlWindow->UserPort->mp_SigBit)) { /* Process the Intuition message */ while (MyIntuiMessage=(struct IntuiMessage *) GetMsg(ControlWindow->UserPort)) { /* Get all the needed info and give message back */ MIClass = MyIntuiMessage->Class; MICode = MyIntuiMessage->Code; MIAddress = MyIntuiMessage->IAddress; ReplyMsg(MyIntuiMessage); /* Now, what was it you wanted? */ switch (MIClass) { case MENUPICK: menumessage(MICode, ControlWindow); break; case GADGETUP: /* reply, then process */ gadgetmessage(MIAddress, ControlWindow); break; case CLOSEWINDOW: /* bye! */ while (MyIntuiMessage = (struct IntuiMessage *) GetMsg( ControlWindow->UserPort)) ReplyMsg(MyIntuiMessage); MyCleanup(); exit(TRUE); break; default: #ifdef DEBUG printf("Unhandled Message Received.\n"); #endif break; } /* switch */ } /* while */ } /* if */ /* Woken by intuition for FaceWindow*/ if (Signals & (1<< FaceWindow->UserPort->mp_SigBit)) { /* Process the Intuition message */ while (MyIntuiMessage=(struct IntuiMessage *) GetMsg(FaceWindow->UserPort)) { switch (MyIntuiMessage->Class) { case SIZEVERIFY: ReplyMsg(MyIntuiMessage); break; case MENUPICK: menumessage(MyIntuiMessage->Code,FaceWindow); ReplyMsg(MyIntuiMessage); break; case NEWSIZE: /* Don't reply until processed */ DrawFace(); ReplyMsg(MyIntuiMessage); break; default: #ifdef DEBUG printf("Unhandled Message Received.\n"); #endif ReplyMsg(MyIntuiMessage); break; } /* switch */ } /* while */ } /* if */ /* A voice SendIO (Write) has completed */ if (Signals & (1 << voice_io.message.io_Message.mn_ReplyPort->mp_SigBit)) { /* Was it Sucessful? filter out the abort error */ if (voice_io.message.io_Error == -2) voice_io.message.io_Error = 0; if (voice_io.message.io_Error != 0) { #ifdef DEBUG printf("Narrator won't. (%ld)\n", voice_io.message.io_Error); #endif /* flash this screen */ DisplayBeep(ControlWindow->WScreen); /* let user see where phoneme string was bad. */ i = RemoveGadget(ControlWindow, &PhonStrGadget); /* move the cursor to the error char */ PhonInfo.BufferPos = voice_io.message.io_Actual -1; /* assure cursor (error point) is shown in gad. */ /* within 29 (number of chars shown) of front */ if (voice_io.message.io_Actual < 29) PhonInfo.DispPos = 0; /* within 29 of end */ else if ((voice_io.message.io_Length - voice_io.message.io_Actual) < 29) PhonInfo.DispPos = voice_io.message.io_Length - 29; else PhonInfo.DispPos = voice_io.message.io_Actual - 15; AddGadget(ControlWindow, &PhonStrGadget, i); RefreshGadgets(&PhonStrGadget, ControlWindow, NULL); voice_io.message.io_Error = 0; } /* SpeakGadget.Flags ^= GADGDISABLED; FaceGadget.Flags ^= GADGDISABLED; */ OnGadget(&SpeakGadget, ControlWindow, NULL); OnGadget(&FaceGadget, ControlWindow, NULL); } /* A mouth DoIO (Read) has completed */ if (Signals & (1 << mouth_io.voice.message.io_Message.mn_ReplyPort->mp_SigBit)) { WaitBOVP(&FaceWindow->WScreen->ViewPort); SetAPen(FaceWindow->RPort, WHTP); RectFill(FaceWindow->RPort, 0, EyesBottom, FaceWindow->GZZWidth, FaceWindow->GZZHeight); if (MouthWMult == 0) LipWidth = mouth_io.width >> 1; else LipWidth = mouth_io.width * MouthWMult; if (MouthHMult == 0) LipHeight = mouth_io.height >> 1; else LipHeight = mouth_io.height * (MouthHMult); SetAPen(FaceWindow->RPort, REDP); Move(FaceWindow->RPort, XMouthCenter - LipWidth, YMouthCenter); Draw(FaceWindow->RPort, XMouthCenter, YMouthCenter - LipHeight); Draw(FaceWindow->RPort, XMouthCenter + LipWidth, YMouthCenter); Draw(FaceWindow->RPort, XMouthCenter, YMouthCenter + LipHeight); Draw(FaceWindow->RPort, XMouthCenter - LipWidth, YMouthCenter); /* the narrator will give an error when the */ /* write has completed and I've tried to read */ /* so I stop trying when that happens */ if (mouth_io.voice.message.io_Error == 0) SendIO(&mouth_io); } } /* for */ } /* main */ /* a MENUPICK has been received, this * routine takes the appropriate action */ menumessage(code, w) USHORT code; struct Window *w; { switch (MENUNUM(code)) { case 0: switch (ITEMNUM(code)) { case 0: AutoRequest(w, &ReqText3, NULL, &OKIText, 0, 0, 280, 47); break; } break; } } /* a GADGETUP has been received, this * routine takes the appropriate action */ gadgetmessage(address, w) APTR address; struct Window *w; { USHORT i; long PropRange; if (address == (APTR)&ModeGadget) { if (ModeGadget.Flags & SELECTED) voice_io.mode = ROBOTICF0; else voice_io.mode = NATURALF0; } else if (address == (APTR)&FaceGadget) { /* tell the write that reads will be forthcomming */ if (FaceGadget.Flags & SELECTED) { voice_io.mouths = 1; if ((FaceWindow = (struct Window *) OpenWindow(&NewFaceWindow)) == NULL) { #ifdef DEBUG printf("Couldn't open the face window.\n"); #endif MyCleanup(); exit(FALSE); } SetMenuStrip(FaceWindow, &MyMenu); DrawFace(); } else { /* FaceGadget de-SELECTed */ voice_io.mouths = 0; NewFaceWindow.LeftEdge = FaceWindow->LeftEdge; NewFaceWindow.TopEdge = FaceWindow->TopEdge; NewFaceWindow.Width = FaceWindow->Width; NewFaceWindow.Height = FaceWindow->Height; CloseWindow(FaceWindow); FaceWindow = NULL; } } else if (address == (APTR)&StopGadget) { AbortIO(&voice_io); voice_io.message.io_Error = 0; mouth_io.voice.message.io_Error = 0; } /* Since this program changes a flag that intuition expects * only the user to change (SELECTED bit), this program has * to remove, then change, then add this gadget. Then by * passing the address of this gadget to RefreshGadgets(), * only the gadgets from here to the start of the list will * be refreshed, which minimizes the visible flash that * RefreshGadgets() can introduce. * If one of the two gadgets (female/male) is hit, toggle * the selection of the other gadget (since the gadget hit * was toggled by intuition when it was hit). */ else if (address == (APTR)&FemaleGadget) { if (FemaleGadget.Flags & SELECTED) voice_io.sex = FEMALE; else voice_io.sex = MALE; i = RemoveGadget(ControlWindow, &MaleGadget); MaleGadget.Flags ^= SELECTED; AddGadget(ControlWindow, &MaleGadget, i); RefreshGadgets(&MaleGadget, ControlWindow, NULL); } else if (address == (APTR)&MaleGadget) { if (MaleGadget.Flags & SELECTED) voice_io.sex = MALE; else voice_io.sex = FEMALE; i = RemoveGadget(ControlWindow, &FemaleGadget); FemaleGadget.Flags ^= SELECTED; AddGadget(ControlWindow, &FemaleGadget, i); RefreshGadgets(&MaleGadget, ControlWindow, NULL); } /* Since the program changes the contents of the string * gadgets' buffer and it's size, which is something else * intuition doesn't expect a program (as opposed to the * user) to do. The program must remove, then change, then * add this gadget, and then by passing the address of this * gadget to RefreshGadgets(), only the gadgets from here * to the start of the list will be refreshed, which * minimizes the visible flash that RefreshGadgets() can * introduce. */ else if (address == (APTR)&TranslateGadget) { i = RemoveGadget(ControlWindow, &PhonStrGadget); if ((TranslatorError = Translate((APTR)EnglBuffer, EnglInfo.NumChars, (APTR)PhonBuffer, PhonInfo.MaxChars)) != 0) { #ifdef DEBUG printf("Translator won't. (%lx)\n",TranslatorError); #endif /* flash this screen */ DisplayBeep(ControlWindow->WScreen); } /* Hey! NumChars includes the terminating NULL. */ /* This must be done. */ PhonInfo.NumChars = voice_io.message.io_Length + 1; if (PhonInfo.DispPos > voice_io.message.io_Length) PhonInfo.DispPos = voice_io.message.io_Length; AddGadget(ControlWindow, &PhonStrGadget, i); RefreshGadgets(&PhonStrGadget, ControlWindow, NULL); } else if (address == (APTR)&SpeakGadget) { /* SpeakGadget.Flags ^= GADGDISABLED; FaceGadget.Flags ^= GADGDISABLED; */ OffGadget(&SpeakGadget, ControlWindow, NULL); OffGadget(&FaceGadget, ControlWindow, NULL); voice_io.message.io_Length = strlen(PhonBuffer); SendIO(&voice_io); if (voice_io.mouths == 1) { mouth_io.voice.message.io_Error = 0; SendIO(&mouth_io); } } else if (address == (APTR)&EnglStrGadget); /* do nothing */ else if (address == (APTR)&PhonStrGadget); /* do nothing */ else if (address == (APTR)&Props[0]) { PropRange = RNGFREQ; voice_io.sampfreq = (( (PInfos[0].HorizPot >> 1) * PropRange) >> 15) + MINFREQ; #ifdef DEBUG printf("Freq. = %ld\n", voice_io.sampfreq); #endif } else if (address == (APTR)&Props[1]) { PropRange = RNGRATE; voice_io.rate = (((PInfos[1].HorizPot >> 1) * PropRange) >> 15) + MINRATE; #ifdef DEBUG printf("Rate = %ld\n", voice_io.rate); #endif } else if (address == (APTR)&Props[2]) { PropRange = RNGPITCH; voice_io.pitch = (((PInfos[2].HorizPot >> 1) * PropRange) >> 15) + MINPITCH; #ifdef DEBUG printf("Pitch = %ld\n", voice_io.pitch); #endif } else if (address == (APTR)&Props[3]) { PropRange = RNGVOL; voice_io.volume = (((PInfos[3].HorizPot >> 1) * PropRange) >> 15) + MINVOL; #ifdef DEBUG printf("Vol. = %ld\n", voice_io.volume); #endif } #ifdef DEBUG else printf("Unhandled gadget up received!\n"); #endif } /* This calculates variables used to draw the mouth * and eyes, as well as redrawing the face. * Proportionality makes it very wierd, but it's * wierder if you don't use a GimmeZeroZero window * and GZZWidth/GZZHeight. */ DrawFace() { XMouthCenter = FaceWindow->GZZWidth >> 1; /* set left edge of left eye */ EyesLeft = FaceWindow->GZZWidth >> 2; /* multiplier for mouth width */ MouthWMult = FaceWindow->GZZWidth >> 6; EyesTop = (FaceWindow->GZZHeight >> 2) - (FaceWindow->GZZHeight >> 4); EyesBottom = EyesTop + (FaceWindow->GZZHeight >> 3) + 1; yaw = FaceWindow->GZZHeight - EyesBottom; YMouthCenter = ((yaw >> 1) + EyesBottom); MouthHMult = yaw >> 5; /* Set pen to White */ SetAPen(FaceWindow->RPort, WHTP); RectFill(FaceWindow->RPort, 0, 0, FaceWindow->GZZWidth, FaceWindow->GZZHeight); /* Set pen to Blue */ SetAPen(FaceWindow->RPort, BLUP); RectFill(FaceWindow->RPort, EyesLeft, EyesTop, EyesLeft + (FaceWindow->GZZWidth >> 3), EyesTop + (FaceWindow->GZZHeight >> 3)); RectFill(FaceWindow->RPort, (FaceWindow->GZZWidth >> 1) + (FaceWindow->GZZWidth >> 3), EyesTop, (FaceWindow->GZZWidth >> 1) + (FaceWindow->GZZWidth >> 3) /* two >> 3, not one >> 2 */ + (FaceWindow->GZZWidth >> 3),/* so eyes are same width */ EyesTop + (FaceWindow->GZZHeight >> 3)); SetAPen(FaceWindow->RPort, REDP); /* Set pen to Red */ Move(FaceWindow->RPort, XMouthCenter - (FaceWindow->GZZWidth >> 3), YMouthCenter); Draw(FaceWindow->RPort, XMouthCenter + (FaceWindow->GZZWidth >> 3), YMouthCenter); } /* Deallocate any memory, and close all of the * windows/screens/devices/libraries in reverse order to * make things work smoothly. And be sure to check * that the open/allocation was successful before * closing/deallocating. */ MyCleanup() { if (read_port.mp_SigBit != -1) FreeSignal(read_port.mp_SigBit); if (talk_port.mp_SigBit != -1) FreeSignal(talk_port.mp_SigBit); if (FaceWindow != NULL) CloseWindow(FaceWindow); if (ControlWindow != NULL) CloseWindow(ControlWindow); /* freeimages makes sure image allocation was successful */ freeimages(); if (NarratorOpenError == 0) CloseDevice(&voice_io); if (TranslatorBase != 0) CloseLibrary(TranslatorBase); if (GfxBase != 0) CloseLibrary(GfxBase); if (IntuitionBase != 0) CloseLibrary(IntuitionBase); return(0); } /* Allocate chip memory for gadget images, and set the * pointers in the corresponding image structures to point * to these images. This must be done because the program * could be loaded into expansion memory (off the side of * the box), which the custom chips cannot access. * And images must be in chip ram (that's memory that the * custom chips can access, the internal 512K). */ InitImages() { /* the images were staticly initialized above main */ extern USHORT *FemaleIData_chip; extern USHORT *MaleIData_chip; extern USHORT *HumanIData_chip; extern USHORT *RobotIData_chip; extern USHORT *FaceIData_chip; extern USHORT *StopIData_chip; int i; /* Allocate them all, stop and return false on failure */ if ((FemaleIData_chip = (USHORT *) AllocMem(sizeof(FemaleIData),MEMF_CHIP)) == 0) return(FALSE); if ((MaleIData_chip = (USHORT *) AllocMem(sizeof(MaleIData),MEMF_CHIP)) == 0) return(FALSE); if ((HumanIData_chip = (USHORT *) AllocMem(sizeof(HumanIData),MEMF_CHIP)) == 0) return(FALSE); if ((RobotIData_chip = (USHORT *) AllocMem(sizeof(RobotIData),MEMF_CHIP)) == 0) return(FALSE); if ((FaceIData_chip = (USHORT *) AllocMem(sizeof(FaceIData),MEMF_CHIP)) == 0) return(FALSE); if ((StopIData_chip = (USHORT *) AllocMem(sizeof(StopIData),MEMF_CHIP)) == 0) return(FALSE); for (i=0; i<20; i++) FemaleIData_chip[i] = FemaleIData[i]; for (i=0; i<20; i++) MaleIData_chip[i] = MaleIData[i]; for (i=0; i<60; i++) HumanIData_chip[i] = HumanIData[i]; for (i=0; i<60; i++) RobotIData_chip[i] = RobotIData[i]; for (i=0; i<30; i++) FaceIData_chip[i] = FaceIData[i]; for (i=0; i<30; i++) StopIData_chip[i] = StopIData[i]; FemaleImage.ImageData = FemaleIData_chip; MaleImage.ImageData = MaleIData_chip; HumanImage.ImageData = HumanIData_chip; RobotImage.ImageData = RobotIData_chip; FaceImage.ImageData = FaceIData_chip; StopImage.ImageData = StopIData_chip; return(TRUE); } /* Deallocate the memory that was used for images, * See initimages for more details. */ freeimages() { /* the images were staticly initialized above main */ extern USHORT *FemaleIData_chip; extern USHORT *MaleIData_chip; extern USHORT *HumanIData_chip; extern USHORT *RobotIData_chip; extern USHORT *FaceIData_chip; extern USHORT *StopIData_chip; /* Deallocate only if the pointer is really there. */ if (RobotIData_chip != 0) FreeMem(RobotIData_chip, sizeof(RobotIData)); if (HumanIData_chip != 0) FreeMem(HumanIData_chip, sizeof(HumanIData)); if (MaleIData_chip != 0) FreeMem(MaleIData_chip, sizeof(MaleIData)); if (FemaleIData_chip != 0) FreeMem(FemaleIData_chip, sizeof(FemaleIData)); if (FaceIData_chip != 0) FreeMem(FaceIData_chip, sizeof(FaceIData)); if (StopIData_chip != 0) FreeMem(StopIData_chip, sizeof(StopIData)); }