Amiga-Request@cs.odu.edu (Amiga Sources/Binaries Moderator) (01/17/90)
Submitted-by: karl@sugar.hackercorp.com (Karl Lehenbauer)
Posting-number: Volume 90, Issue 019
Archive-name: audio/chatterbox/part02
#!/bin/sh
# This is a shell archive. Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file". To overwrite existing
# files, type "sh file -c". You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g.. If this archive is complete, you
# will see the following message at the end:
# "End of archive 2 (of 2)."
# Contents: 8svx.c player.c tracker.c windows.c
# Wrapped by tadguy@xanth on Tue Jan 16 21:23:14 1990
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f '8svx.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'8svx.c'\"
else
echo shar: Extracting \"'8svx.c'\" \(8137 characters\)
sed "s/^X//" >'8svx.c' <<'END_OF_FILE'
X/* quasi-minimal IFF 8SVX sample file loader for Karl's Audio Stuff
X * by Karl Lehenbauer, based originally on public domain IFF code from
X * Electronic Arts
X * rewritten 2/25/88 KEL to support chaining of samples through a
X * central sample store and to support music (it's now carrying
X * around octave and one-shot info)
X
X *
X * this version for the sound effect player has had the octave stuff
X * hacked back out but the central sample store is still there
X *
X */
X
X#include <exec/types.h>
X#include <functions.h>
X#include <exec/memory.h>
X#include <exec/nodes.h>
X#include <exec/lists.h>
X#include <stdio.h>
X#include <fcntl.h>
X#include "assert.h"
X
X#include "iff.h"
X#include "8svx.h"
X
X#include "sample.h"
X
Xstruct List SampleStore;
Xstruct List *SampleList = &SampleStore;
X
X/* this is a global variable that is set by Load8SVX to indicate whether
X * it found the sample in memory already or not. When we're playing
X * sounds for the timer and noload is selected, it's a good thing to know
X * and we already return a value (bleah, C is a bit restrictive in this
X * case)
X */
Xint sample_was_in_cache;
X
Xchar *SamplePath = "ChatterBox:";
X
Xvoid UnloadAllSamples()
X{
X#ifdef DEBUG
X fprintf(stderr,"UnloadAllSamples cleanup routine executing\n");
X#endif
X while (SampleList->lh_TailPred != SampleList)
X {
X UnloadSampleAt(SampleList->lh_Head);
X }
X#ifdef DEBUG
X fprintf(stderr,"UnloadAllSamples cleanup routine complete\n");
X#endif
X}
X
X
XInit8SVX()
X{
X NewList(SampleList);
X add_cleanup(UnloadAllSamples);
X}
X
XSample *Load8SVX(fname)
Xchar *fname;
X{
X int iffile;
X ChunkHeader chunkhead;
X Voice8Header voicehead;
X LONG samplebytes, fibbytes;
X LONG formtype;
X char *sampbufp, *fibbufp;
X register Sample *samptr;
X LONG headsize;
X short flags = 0;
X char fnamebuf[256];
X
X assert(sizeof(chunkhead) == 8);
X
X#ifndef NOAUDIT
X if (SampleList->lh_Head == (struct Node *)NULL)
X panic("called Load8SVX without calling Init8SVX\n");
X#endif
X
X#ifdef DEBUG
X printf("checking sample store for %s - ",fname);
X#endif
X if ((samptr = (Sample *)FindName(SampleList, fname)) != NULL)
X {
X#ifdef DEBUG
X printf("request for %s satisfied from sample store\n",fname);
X#endif
X sample_was_in_cache = YES;
X return(samptr);
X }
X
X sample_was_in_cache = NO;
X
X#ifdef DEBUG
X printf("didn't find it\n");
X#endif
X
X sprintf(fnamebuf,"%s%s",SamplePath,fname);
X#ifdef DEBUG
X printf("looking for IFF file, name of %s\n",fnamebuf);
X fflush(stdout);
X#endif
X if ((iffile = OpenIFF(fnamebuf, ID_8SVX)) < 0)
X {
X fprintf(stderr,"Load8SVX: can't open IFF sample file %s\n",fnamebuf);
X return((Sample *)NULL);
X }
X
X if ((headsize = chunkuntil(iffile,ID_VHDR)) == -1)
X {
X fputs("Load8SVX: IFF 8SVX VHDR chunk search failed\n",stderr);
X return((Sample *)NULL);
X }
X
X if (!readchunk(iffile,&voicehead,headsize))
X {
X fputs("Load8SVX: read of IFF VHDR chunk failed\n",stderr);
X return((Sample *)NULL);
X }
X#ifdef DEBUG
X DumpVoiceHead(&voicehead);
X#endif
X
X if ((samplebytes = chunkuntil(iffile,ID_BODY)) < 0)
X {
X fputs("Load8SVX: IFF 8SVX BODY chunk search failed\n",stderr);
X return((Sample *)NULL);
X }
X
X if (voicehead.sCompression == sCmpFibDelta)
X {
X#ifdef DEBUG
X fprintf(stderr,"Load8SVX: sample uses Fibonacci Delta Encoding\n");
X#endif
X fibbytes = samplebytes;
X samplebytes = (fibbytes - 2) * 2;
X }
X
X if ((sampbufp = (char *)AllocMem(samplebytes,MEMF_FAST)) == (char *)NULL)
X {
X if ((sampbufp = (char *)AllocMem(samplebytes,MEMF_CHIP)) == (char *)NULL)
X {
X fputs("Load8SVX: unable to allocate memory for waveform\n",stderr);
X return((Sample *)NULL);
X }
X else
X flags = SAMPLE_ALLOCATED_IN_CHIP_RAM;
X
X }
X else
X flags = SAMPLE_ALLOCATED_IN_FAST_RAM;
X
X if (voicehead.sCompression == sCmpFibDelta)
X {
X
X /* load the delta compressed data into the back half of the sample
X * buffer just allocated. We will decompress the data into the
X * same sample memory, without overwriting the compressed data.
X * It'll work. Trust me, I know what I'm doing.
X */
X
X fibbufp = &sampbufp[samplebytes / 2];
X
X if (!readchunk(iffile,fibbufp,fibbytes))
X {
X fputs("Read of fib sample data failed!\n",stderr);
X FreeMem(sampbufp,samplebytes);
X return((Sample *)NULL);
X }
X FibUnpack(fibbufp+2,fibbytes-2,sampbufp,fibbufp[1]);
X }
X else if (!readchunk(iffile,sampbufp,samplebytes))
X {
X fputs("Read of sample data failed!\n",stderr);
X FreeMem(sampbufp,samplebytes);
X return((Sample *)NULL);
X }
X
X close(iffile);
X
X if ((samptr = (Sample *)AllocMem(sizeof(Sample),0L)) == (Sample *)NULL)
X {
X fputs("Load8SVX: unable to allocate memory for Sample structure\n",stderr);
X FreeMem(sampbufp,samplebytes);
X return((Sample *)NULL);
X }
X
X /* allocate memory for sample name */
X if ((samptr->node.ln_Name = (char *)AllocMem(strlen(fname) + 1,0)) == (char *)NULL)
X {
X fputs("Load8SVX: unable to allocate memory for Sample name\n",stderr);
X FreeMem(sampbufp,samplebytes);
X FreeMem(samptr,sizeof(Sample));
X return((Sample *)NULL);
X }
X
X /* structure copy in Voice8Header info */
X samptr->sampleheader = voicehead;
X
X /* set up pointer to sample data and store length */
X if (flags & SAMPLE_ALLOCATED_IN_FAST_RAM)
X {
X samptr->fastsampledata = sampbufp;
X samptr->sampledata = NULL;
X }
X else if (flags & SAMPLE_ALLOCATED_IN_CHIP_RAM)
X {
X samptr->fastsampledata = NULL;
X samptr->sampledata = sampbufp;
X }
X samptr->samplebytes = samplebytes;
X
X /* copy in the voice name */
X strcpy(samptr->node.ln_Name,fname);
X
X /* ...and set up the flags */
X samptr->sample_flags = flags;
X
X /* set the number of current "users" of the sample in chip RAM to zero */
X samptr->chip_use_count = 0;
X
X /* initialize the rest of the node fields */
X samptr->node.ln_Type = samptr->node.ln_Pri = 0;
X
X /* stick this new sample onto the end of the sample list */
X AddTail(SampleList,&samptr->node);
X
X#ifndef NOAUDIT
X samptr->magic = SAMPLE_MAGIC;
X#endif
X
X#ifdef DEBUG
X fprintf(stderr,"Load8SVX: waveform bytes %ld, samples/second %d\n",samplebytes,voicehead.samplesPerSec);
X fprintf(stderr,"Load8SVX: samptr %lx, sampledata %lx\n",samptr,sampbufp);
X#endif
X return(samptr);
X}
X
X/* FibUnpack - unpack Fibonacci Delta Compressed audio sample
X * see IFF file formats in the ROM Kernel Exec manual
X * or on one of the Fred Fish disks
X */
X
Xchar FibToDelta[16] = {-34,-21,-13,-8,-5,-3,-2,-1,0,1,2,3,5,8,13,21};
X
XFibUnpack(inp,n,outp,val)
Xchar *inp, *outp;
Xlong n;
Xchar val;
X{
X register char pair;
X#ifdef DEBUG
X fprintf(stderr,"FibUnpack: inp %lx, n %ld, outp %lx, val %d\n",inp,n,outp,val);
X#endif
X while (n--)
X {
X pair = *inp++; /* get a pair of compressed samples */
X val += FibToDelta[(pair >> 4) & 0xf]; /* uncompress first sample */
X *outp++ = val;
X val += FibToDelta[pair & 0xf]; /* uncompress second sample */
X *outp++ = val;
X }
X}
X
X/* unload sample at address */
XUnloadSampleAt(samptr)
XSample *samptr;
X{
X ASSERT_SAMPLE_MAGIC(samptr);
X
X#ifdef DEBUG
X printf("UnloadSampleAt: Unloading Sample %s\n",samptr->node.ln_Name);
X#endif
X
X /* remove the sample from the sample list */
X Remove(&samptr->node);
X
X /* free the space allocated for the sample's name */
X FreeMem(samptr->node.ln_Name,strlen(samptr->node.ln_Name)+1);
X
X /* free the sample data itself */
X if (samptr->sample_flags & SAMPLE_ALLOCATED_IN_CHIP_RAM)
X {
X FreeMem(samptr->sampledata,samptr->samplebytes);
X }
X else
X {
X assert(samptr->sample_flags & SAMPLE_ALLOCATED_IN_FAST_RAM);
X FreeMem(samptr->fastsampledata,samptr->samplebytes);
X }
X#ifndef NOAUDIT
X samptr->magic = 0;
X#endif
X samptr->sample_flags = 0;
X
X /* free the sample structure */
X FreeMem(samptr,sizeof(Sample));
X}
X
XUnloadSample(name)
Xchar *name;
X{
X Sample *samptr;
X
X#ifdef DEBUG
X printf("UnloadSample(%s)\n",name);
X#endif
X
X if ((samptr = (Sample *)FindName(SampleList,name)) != NULL)
X UnloadSampleAt(samptr);
X else
X fprintf(stderr,"couldn't find sample %s to unload it\n",name);
X}
X
X#ifdef DEBUG
XDumpVoiceHead(vptr)
XVoice8Header *vptr;
X{
X printf("oneShotHiSamples %d, repeatHiSamples %d\n",
X vptr->oneShotHiSamples, vptr->repeatHiSamples);
X printf("samplesPerHiCycle %ld, samplesPerSec %d\n",
X vptr->samplesPerHiCycle, vptr->samplesPerSec);
X printf("ctOctave %d, sCompression %d, volume %d\n",
X vptr->ctOctave, vptr->sCompression, vptr->volume);
X}
X#endif
X
X/* end of 8svx.c */
END_OF_FILE
if test 8137 -ne `wc -c <'8svx.c'`; then
echo shar: \"'8svx.c'\" unpacked with wrong size!
fi
# end of '8svx.c'
fi
if test -f 'player.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'player.c'\"
else
echo shar: Extracting \"'player.c'\" \(12352 characters\)
sed "s/^X//" >'player.c' <<'END_OF_FILE'
X/* player - sound playing portion of karl's smus player */
X/* hacked to be an effects player */
X
X
X/* note - "channels", throughout the code below, are a structure I have
X * invented, a logical channel sort of thing that is useful for what
X * I'm trying to do. There is not a 1-1 correspondence between these
X * channels and the hardware channels, which hardware channel is used
X * for a given channel is determined by audio.device when we make a
X * request to allocate a channel.
X */
X
X#include <exec/types.h>
X#include <functions.h>
X#include <exec/memory.h>
X#include <devices/audio.h>
X#include <stdio.h>
X
X#include "assert.h"
X#include "8svx.h"
X
X#include "sample.h"
X#include "channels.h"
X
X#define YES 1
X#define NO 0
X
Xshort audio_up = NO, audio_down = NO;
X
Xextern int debug;
X
X#ifdef DEBUG
X#define WHERE fprintf(stderr,"%s %s %d\n",__FILE__,__FUNC__,__LINE__); fflush(stderr);
X#define WHAT(x) fprintf(stderr,"%s %s %d %s\n",__FILE__,__FUNC__,__LINE__,x->name);
X#else
X#define WHERE
X#define WHAT(x)
X#endif
X
X#define CLOCKFREQ 3579545
X
X/* define the channel array - this is the top level of data for an audio
X channel */
XChannel Channels[MAX_CHANNELS];
X
Xstruct Device *AudioDevice;
Xstruct MsgPort *sfx_port;
Xstruct SMUS_IOAudio *openIOB;
X
Xshort MasterVolume = 127;
X
X/* allocation maps for requesting channel assignments from audio.device:
X * I use LeftMap and RightMap to insist on a stereo side - if it can't
X * allocate (at play time) that side it will blow off the note.
X * I use TryLeftMap and TryRightMap to indicate a preference for a
X * stereo side, but if I can't have a channel on that side, it'll
X * give me one from the other side if one is available there
X */
Xstatic UBYTE LeftMap[] = {LEFT0, LEFT1};
Xstatic UBYTE RightMap[] = {RIGHT0, RIGHT1};
Xstatic UBYTE TryLeftMap[] = {LEFT1, LEFT0, RIGHT1, RIGHT0};
Xstatic UBYTE TryRightMap[] = {RIGHT1, RIGHT0, LEFT1, LEFT0};
X
X/* SMUS_IOBallocate - allocates a SMUS player IOB
X * It shouldn't panic when the allocate fails, and will be eventually
X * made to back out properly.
X * Not much to the routine at all...
X */
Xstruct SMUS_IOAudio *SMUS_IOBallocate()
X{
X struct SMUS_IOAudio *IOB;
X extern UBYTE *MyAllocMem();
X
X if ((IOB = (struct SMUS_IOAudio *)MyAllocMem(sizeof(struct SMUS_IOAudio), (long)MEMF_PUBLIC | MEMF_CLEAR)) == (struct SMUS_IOAudio *) NULL)
X panic("SMUS_IOBallocate failed");
X
X return(IOB);
X}
X
X/* free an IOB created by SMUS_IOBallocate */
XSMUS_IOBfree(IOBp)
Xstruct SMUS_IOAudio *IOBp;
X{
X if (IOBp != NULL)
X FreeMem(IOBp, sizeof(struct SMUS_IOAudio));
X}
X
X/* Init the IOB for the oneshot portion of the sound */
XSMUS_InitShotIOB(channel)
Xint channel;
X{
X struct SMUS_IOAudio *IOB = Channels[channel].IOBs[ONESHOT_IOB];
X
X IOB->smusIOB.ioa_Request.io_Command = CMD_WRITE;
X IOB->smusIOB.ioa_Request.io_Flags = ADIOF_PERVOL;
X
X /* NEEDS WORK - needs to dynamically set volume based on volume
X * commands we receive from the track, and the overall volume
X * from the song structure */
X IOB->smusIOB.ioa_Volume = 127;
X
X /* cycles to repeat is 1, this is a oneshot sound */
X IOB->smusIOB.ioa_Cycles = 1;
X}
X
X/* Init an IOB that will stop the playing sound */
XSMUS_InitStopIOB(channel)
Xint channel;
X{
X struct SMUS_IOAudio *IOB = Channels[channel].IOBs[STOP_IOB];
X
X /* I switched from ADCMD_FINISH to CMD_FLUSH because I
X * can have up to three things queued on a channel
X * and I want to kill them all - ADCMD_FINISH would only
X * kill the one in progress
X * IOB->smusIOB.ioa_Request.io_Command = ADCMD_FINISH;
X */
X IOB->smusIOB.ioa_Request.io_Command = CMD_FLUSH;
X IOB->smusIOB.ioa_Request.io_Flags = IOF_QUICK;
X}
X
X
X/* Init an IOB that will allocate a channel */
XSMUS_InitAllocIOB(channel)
Xint channel;
X{
X struct SMUS_IOAudio *allocIOB = Channels[channel].IOBs[ALLOC_IOB];
X
X static BYTE attack_precedences[] = {50, 40, 30, 20};
X
X allocIOB->smusIOB.ioa_Request.io_Command = ADCMD_ALLOCATE;
X
X allocIOB->smusIOB.ioa_Request.io_Message.mn_Node.ln_Pri = attack_precedences[channel];
X
X /* The IFF SMUS spec says priority is to be highest for track 1
X * and descending with progressively higher tracks.
X *
X * The audio.device doc in the ROM Kernel Manual says that
X * higher priorities should be given for the attack portions
X * of each note and that priorities for notes in a music
X * program range from -50 (lowest) to 50 (highest)
X *
X * Consequently, since I'm orienting it toward four tracks on the
X * Amiga, and this code is totally Amiga dependent anyway, I
X * am assigning attack priorities of 50 for the first track, and
X * each successive track minus 10, with the sustain portion of
X * the note having its precedence lowered effectively by 50
X *
X */
X
X /* for now, channel 1 and 3 prefer the left channel, while 2 and 4
X * prefer the right
X */
X allocIOB->smusIOB.ioa_Data = (channel) ? TryLeftMap : TryRightMap;
X allocIOB->smusIOB.ioa_Length = 4;
X
X allocIOB->smusIOB.ioa_Request.io_Flags = (ADIOF_NOWAIT | IOF_QUICK);
X}
X
X/* Init an IOB that will deallocate the channel */
XSMUS_InitDeallocIOB(channel)
Xint channel;
X{
X struct SMUS_IOAudio *IOB = Channels[channel].IOBs[FREE_IOB];
X
X IOB->smusIOB.ioa_Request.io_Command = ADCMD_FREE;
X IOB->smusIOB.ioa_Request.io_Flags = IOF_QUICK;
X}
X
X/* init a channel
X *
X * this guy takes care of allocating and initting all the different IOBs
X */
XInitChannel(channelindex)
Xint channelindex;
X{
X int i;
X struct SMUS_IOAudio *IOB;
X Channel *channelp = &Channels[channelindex];
X
X /* for all the IOBs,
X * allocate the IOB and set the channel's IOB pointer to it
X * set the channel pointer field that I tack onto the end
X * of IOBs to point back to the channel (so that we can
X * tell to what channel an IOB we receive on a message
X * port belongs, if we need to)
X */
X for (i = 0; i < MAX_CHANNEL_IOBS; i++)
X {
X IOB = channelp->IOBs[i] = SMUS_IOBallocate();
X
X IOB->channelp = channelp; /* set pointer to IOB's Channel parent */
X
X /* set replyport and device */
X /* see someday if having the reply port is really neccessary */
X IOB->smusIOB.ioa_Request.io_Message.mn_ReplyPort = sfx_port;
X
X /* set the device in the request to the audio device */
X IOB->smusIOB.ioa_Request.io_Device = AudioDevice;
X
X /* let audio.device assign the alloc keys first time through */
X IOB->smusIOB.ioa_AllocKey = 0;
X }
X
X /* initialize the different kinds of IOBs we use */
X SMUS_InitShotIOB(channelindex);
X SMUS_InitStopIOB(channelindex);
X SMUS_InitAllocIOB(channelindex);
X SMUS_InitDeallocIOB(channelindex);
X
X channelp->samptr = NULL;
X}
X
XInitAudio()
X{
X int EndAudio();
X int i;
X
X openIOB = NULL;
X AudioDevice = NULL;
X
X add_cleanup(EndAudio);
X
X openIOB = SMUS_IOBallocate();
X
X if (OpenDevice(AUDIONAME, 0, &openIOB->smusIOB, 0) != 0)
X panic("can't open audio device");
X
X AudioDevice = openIOB->smusIOB.ioa_Request.io_Device;
X
X if ((sfx_port = CreatePort((char *)NULL, 0)) == (struct MsgPort *)NULL)
X panic("can't create sfx_port");
X
X for (i = 0; i < MAX_CHANNELS; i++)
X InitChannel(i);
X
X audio_up = YES;
X}
X
XEndAudio()
X{
X int i, j;
X Channel *channelp;
X
X#ifdef DEBUG
X fprintf(stderr,"endaudio cleanup routine executing\n");
X#endif
X if(audio_down)
X return;
X audio_down = YES;
X
X if (audio_up)
X {
X for (i = 0; i < MAX_CHANNELS; i++)
X StopChannelNote(&Channels[i]);
X }
X audio_up = NO;
X
X if (sfx_port)
X DeletePort(sfx_port,sizeof(struct MsgPort));
X
X for (i = 0; i < MAX_CHANNELS; i++)
X {
X channelp = &Channels[i];
X for (j = 0; j < MAX_CHANNEL_IOBS; j++)
X {
X SMUS_IOBfree(channelp->IOBs[j]);
X channelp->IOBs[j] = NULL;
X }
X }
X if(openIOB)
X {
X if(AudioDevice)
X {
X CloseDevice(openIOB);
X AudioDevice = NULL;
X }
X SMUS_IOBfree(openIOB);
X openIOB = NULL;
X }
X#ifdef DEBUG
X fprintf(stderr,"endaudio cleanup routine complete\n");
X#endif
X}
X
X/* the guts of note playing, right here */
X
XPlayChannelSample(samptr,velocity,stereo_side)
XSample *samptr;
Xint velocity;
Xint stereo_side;
X{
X int i;
X struct SMUS_IOAudio *iobptr;
X Channel *channelp;
X struct OctaveStruct *octave_ptr;
X int octave, noctaves;
X short shift_up_n_octaves = 0;
X short shift_down_n_octaves = 0;
X short period;
X short volume;
X int channel = -1;
X struct SMUS_IOAudio *allocIOB;
X struct SMUS_IOAudio *shotIOB;
X
X /* make relatively certain samptr points to a good sample */
X ASSERT_SAMPLE_MAGIC(samptr);
X
X /* gimme one of my logical channels */
X for (channel = 0; channel < 4; channel++)
X {
X channelp = &Channels[channel];
X if (!(channelp->flags & (LOOP_PLAYING | SHOT_PLAYING)))
X goto got_channel;
X }
X
X#ifdef DEBUG
X printf("failed to get a channel, they're all in use\n");
X#endif
X return;
X
X got_channel:
X /* cons up some convenient pointers */
X /* these assignments could be moved to where they're needed to prevent
X * their being assigned but unused because of alloc failure,
X * no need for oneshot, etc. */
X allocIOB = channelp->IOBs[ALLOC_IOB];
X shotIOB = channelp->IOBs[ONESHOT_IOB];
X
X
X /* zero the alloc key so we'll get a fresh one - it's the only way
X * to be sure we won't conflict with someone else */
X /* allocIOB->smusIOB.ioa_AllocKey = 0; */
X /* I think we're OK if we alloc it once */
X allocIOB->smusIOB.ioa_Data = (stereo_side) ? TryLeftMap : TryRightMap;
X BeginIO(&allocIOB->smusIOB);
X
X /* the only possible error return is ADIOERR_NOALLOCATION */
X if (allocIOB->smusIOB.ioa_Request.io_Error)
X {
X fprintf(stderr,"alloc failed on channel %d\n",channel);
X return;
X }
X#ifdef DEBUG
X fprintf(stderr,"channel %d allockey %d\n",channel,allocIOB->smusIOB.ioa_AllocKey);
X#endif
X
X channelp->samptr = samptr;
X
X /* copy the Unit and AllocKey into the other IOBs
X * This is not the coolest way to go.
X * It doesn't need to copy it to all of them.
X * Perhaps it should only copy it into the channel and
X * the other routines would get it out of the channel and
X * shove it into the IOB - I don't know, maybe later
X * also, AllocKey need only be propogated once
X */
X for (i = 0; i < MAX_CHANNEL_IOBS; i++)
X {
X iobptr = Channels[channel].IOBs[i];
X iobptr->smusIOB.ioa_Request.io_Unit = allocIOB->smusIOB.ioa_Request.io_Unit;
X iobptr->smusIOB.ioa_AllocKey = allocIOB->smusIOB.ioa_AllocKey;
X }
X
X
X assert(samptr->sampleheader.samplesPerSec != 0);
X shotIOB->smusIOB.ioa_Period = (CLOCKFREQ / samptr->sampleheader.samplesPerSec);
X
X if (make_sample_chip(samptr))
X {
X shotIOB->smusIOB.ioa_Data = (UBYTE *)samptr->sampledata;
X shotIOB->smusIOB.ioa_Length = (ULONG)samptr->samplebytes;
X shotIOB->smusIOB.ioa_Volume = 64;
X shotIOB->smusIOB.ioa_Cycles = 1;
X
X BeginIO(&shotIOB->smusIOB);
X /* possible errors are IOERR_ABORTED and ADIOERR_NOALLOCATION */
X if (shotIOB->smusIOB.ioa_Request.io_Error)
X return;
X channelp->flags |= SHOT_PLAYING;
X#ifdef DEBUG
X fprintf(stderr,"queued shot on channel %d\n",channel);
X#endif
X }
X else
X {
X fprintf(stderr,"chatterbox: chip RAM allocation failed\n");
X }
X}
X
X/* stop playing the channel if it's playing (we may not have been able to
X * allocate a channel you know) and deallocate it
X */
X/* memo to self: you should always stop all notes that stop in a
X * certain time interval prior to starting any new ones
X */
XStopChannelNote(channelp)
XChannel *channelp;
X{
X
X struct SMUS_IOAudio *stopIOB = channelp->IOBs[STOP_IOB];
X struct SMUS_IOAudio *freeIOB= channelp->IOBs[FREE_IOB];
X
X if (channelp->flags & (LOOP_PLAYING | SHOT_PLAYING))
X {
X BeginIO(&stopIOB->smusIOB);
X /* only error return is ADIOERR_NOALLOCATION */
X
X if (channelp->flags & SHOT_PLAYING)
X {
X#ifdef DEBUG
X fprintf(stderr,"SHOT playing\n");
X#endif
X WaitIO(&channelp->IOBs[ONESHOT_IOB]->smusIOB);
X }
X if (channelp->flags & LOOP_PLAYING)
X {
X#ifdef DEBUG
X fprintf(stderr,"LOOP wait\n");
X#endif
X WaitIO(&channelp->IOBs[LOOP_IOB]->smusIOB);
X /* error returns can be IOERR_ABORTED and ADIOERR_NOALLOCATION */
X }
X
X /* there's no point in waiting on precedence, it's synchronous */
X channelp->flags &= ~(SHOT_PLAYING | LOOP_PLAYING);
X
X#ifdef DEBUG
X fprintf(stderr,"free channel %d, alloc key %d\n",channel,freeIOB->smusIOB.ioa_AllocKey);
X#endif
X BeginIO(&freeIOB->smusIOB);
X /* only possible error return is ADIOERR_NOALLOCATION */
X#ifndef NOAUDIT
X if (freeIOB->smusIOB.ioa_Request.io_Error)
X fprintf(stderr,"dealloc i/o error\n");
X#endif
X
X free_sample_chip(channelp->samptr);
X }
X}
X/* I have forgone magic numbers on channel structures because of the static
X * nature of the channels and their small number (4)
X */
Xstruct SMUS_IOAudio *SMUS_GetMsg()
X{
X return((struct SMUS_IOAudio *)GetMsg(sfx_port));
X}
X
X/* end of player.c */
END_OF_FILE
if test 12352 -ne `wc -c <'player.c'`; then
echo shar: \"'player.c'\" unpacked with wrong size!
fi
# end of 'player.c'
fi
if test -f 'tracker.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'tracker.c'\"
else
echo shar: Extracting \"'tracker.c'\" \(9277 characters\)
sed "s/^X//" >'tracker.c' <<'END_OF_FILE'
X/* tracking memory allocator */
X
X#ifdef TRACKER
X
X#include <exec/types.h>
X#include <exec/memory.h>
X#include <functions.h>
X#include <stdio.h>
X
X/* comment out the following line if you want locks freed twice reported
X * at the cost of getting spurious resource error messages when
X * reusing the lock */
X/* #define FORGET_LOCKS_WHEN_UNLOCKED */
X
X/* comment out the following line if you want memory freed twice reported
X * at the cost of getting spurious resource error messages when
X * freeing and reallocating memory */
X/* #define FORGET_MEMORY_WHEN_FREED */
X
X/* make sure our invocations of the real routines on behalf of the user
X don't cause us to recurse */
X
X#ifdef AllocMem
X#undef AllocMem
X#undef FreeMem
X#undef AllocSignal
X#undef FreeSignal
X#undef Lock
X#undef UnLock
X#undef DupLock
X#endif
X
X/* my flags */
X#define FREED_IT 1
X
Xstruct TrackingAllocMemData
X{
X UBYTE *where; /* address returned by allocator */
X long amount; /* number of bytes allocated */
X long alloc_flags; /* flags passed to allocator */
X char *file; /* filename of caller from the macro */
X int line; /* line number of caller from macro */
X long my_flags; /* flags internal to tracker */
X struct TrackingAllocMemData *next; /* pointer to next entry */
X};
X
Xstruct TrackingAllocMemData *TrackingAllocMemList = NULL;
Xlong MemAllocCount = 0, MemFreeCount = 0;
X
Xvoid *TrackingAllocMem(amount,flags,file,line)
Xlong amount;
Xlong flags;
Xchar *file;
Xint line;
X{
X register struct TrackingAllocMemData *rp;
X UBYTE *users_memory;
X
X /* perform the actual alloc */
X users_memory = AllocMem(amount,flags);
X
X /* if it succeeded, record tracking info */
X if (users_memory)
X {
X MemAllocCount++;
X
X if ((rp = AllocMem((long)sizeof(struct TrackingAllocMemData),0L)) == NULL)
X panic("tracker: can't alloc memory to record AllocMem data");
X
X /* add new alloc data entry to linked list */
X rp->next = TrackingAllocMemList;
X TrackingAllocMemList = rp;
X
X /* shove in save values */
X rp->amount = amount;
X rp->alloc_flags = flags;
X rp->where = users_memory;
X rp->file = file;
X rp->line = line;
X rp->my_flags = 0;
X }
X /* return pointer to the space allocated */
X return(users_memory);
X}
X
Xvoid TrackingFreeMem(where,amount,file,line)
XUBYTE *where;
Xlong amount;
Xchar *file;
Xint line;
X{
X register struct TrackingAllocMemData *rp, *op, *freep;
X
X MemFreeCount++;
X /* scan the memory tracking list for a match */
X for (rp = TrackingAllocMemList, op = NULL; rp != NULL; op = rp, rp = rp->next)
X {
X /* if we matched the address */
X if (rp->where == where)
X {
X /* if they got the amount wrong, tell them */
X if (rp->amount != amount)
X {
X fprintf(stderr,"freed addr %lx OK but length differs, talloc'ed %ld, freed %ld,\n\tallocated at file %s line %d, freed at file %s line %d\n",
X where,rp->amount,amount,rp->file,rp->line,file,line);
X }
X#ifndef FORGET_MEMORY_WHEN_FREED
X /* if it's already free, tell them they freed twice */
X if (rp->my_flags & FREED_IT)
X {
X fprintf(stderr,"freed memory twice at %lx, amount %ld,\n\tallocated in file %s at line %d, freed in file %s at line %d\n",where,amount,rp->file,rp->line,file,line);
X return;
X }
X else
X {
X /* mark this entry as free */
X rp->my_flags |= FREED_IT;
X }
X#else
X /* remove entry from linked list and free it */
X if (op != NULL) op->next = rp->next;
X else
X TrackingAllocMemList = rp->next;
X freep = rp;
X rp = rp->next;
X FreeMem(freep,(long)sizeof(struct TrackingAllocMemData));
X#endif
X FreeMem(where,amount);
X
X return;
X }
X }
X fprintf(stderr,"Freed memory at %lx of amount %ld that wasn't allocated,\n\tfreed at file %s line %d\n",where,amount,file,line);
X FreeMem(where,amount);
X}
X
Xvoid ReportUnfreedMemory()
X{
X struct TrackingAllocMemData *rp = TrackingAllocMemList, *freep;
X
X while (rp != NULL)
X {
X if (!(rp->my_flags & FREED_IT))
X {
X fprintf(stderr,"FreeMem was never called for memory at %lx, amount %ld,\n\tthe alloc was performed at file %s line %d\n",rp->where,rp->amount,rp->file,rp->line);
X }
X freep = rp;
X rp = rp->next;
X FreeMem(freep,(long)sizeof(struct TrackingAllocMemData));
X }
X printf("Total tracked AllocMem calls %ld, FreeMem calls %ld\n",MemAllocCount,MemFreeCount);
X}
X
X
X/* track signals */
X/* tracking AllocSignal doesn't currently track where it was called from */
X
Xlong TrackingSignalMask = 0;
Xlong SignalAllocCount = 0, SignalFreeCount = 0;
X
Xlong TrackingAllocSignal(signal_num,file,line)
Xlong signal_num;
Xchar *file;
Xint line;
X{
X SignalAllocCount++;
X
X signal_num = AllocSignal(signal_num);
X
X if (signal_num != -1)
X TrackingSignalMask |= (1 << signal_num);
X
X return(signal_num);
X}
X
Xvoid TrackingFreeSignal(signal_num,file,line)
Xlong signal_num;
Xchar *file;
Xint line;
X{
X SignalFreeCount++;
X
X if (!(TrackingSignalMask & (1 << signal_num)))
X {
X fprintf("freed a signal (%ld) that was never allocated, at file %s line %d\n",
X signal_num,file,line);
X TrackingSignalMask &= ~(1 << signal_num);
X }
X}
X
Xvoid ReportUnfreedSignals()
X{
X if (TrackingSignalMask)
X fprintf("failed to free signals indicated by this mask: %8lx\n",
X TrackingSignalMask);
X printf("Total tracked AllocSignal calls %ld, FreeSignal calls %ld\n",SignalAllocCount,SignalFreeCount);
X}
X
X/* tracking lock and unlock */
X
Xstruct TrackingLockData
X{
X struct FileLock *lock; /* lock returned by Lock */
X char *name; /* name of file that was locked */
X long accessMode; /* access mode of the file that was locked */
X char *file; /* ptr to file name of line of caller */
X int line; /* ptr to line number text of locker */
X long my_flags; /* flags internal to tracker */
X struct TrackingLockData *next; /* pointer to next entry */
X};
X
X/* flags */
X#define CREATED_BY_DUPLOCK 1
X
Xstruct TrackingLockData *TrackingLockList = NULL;
Xlong TrackerLockCount = 0, TrackerUnLockCount = 0;
X
Xstruct FileLock *TrackingLock(name, accessMode, file, line)
Xchar *name;
Xlong accessMode;
Xchar *file;
Xint line;
X{
X register struct TrackingLockData *lp;
X struct FileLock *users_lock;
X
X users_lock = Lock(name, (long)accessMode);
X
X if (users_lock)
X {
X TrackerLockCount++;
X
X if ((lp = AllocMem((long)sizeof(struct TrackingLockData),0L)) == NULL)
X panic("tracker: can't alloc memory to record lock data");
X
X /* add new alloc data entry to linked list */
X lp->next = TrackingLockList;
X TrackingLockList = lp;
X
X /* shove in save values */
X lp->accessMode = accessMode;
X lp->file = file;
X lp->line = line;
X lp->my_flags = 0;
X lp->lock = users_lock;
X
X /* alloc space for filename and save */
X if ((lp->name = AllocMem((long)(strlen(name)+1),0L)) == NULL)
X panic("tracker: can't alloc memory to record lock filename");
X strcpy(lp->name,name);
X }
X return(users_lock);
X}
X
Xstruct FileLock *TrackingDupLock(lock, file, line)
Xstruct FileLock *lock;
Xchar *file;
Xint line;
X{
X register struct TrackingLockData *lp;
X struct FileLock *users_lock;
X
X users_lock = DupLock(lock);
X
X if (users_lock)
X {
X TrackerLockCount++;
X
X if ((lp = AllocMem((long)sizeof(struct TrackingLockData),0L)) == NULL)
X panic("tracker: can't alloc memory to record lock data");
X
X /* add new alloc data entry to linked list */
X lp->next = TrackingLockList;
X TrackingLockList = lp;
X
X lp->file = file;
X lp->line = line;
X lp->name = NULL;
X lp->lock = users_lock;
X lp->my_flags = CREATED_BY_DUPLOCK;
X }
X return(users_lock);
X}
X
Xvoid TrackingUnLock(lock,file,line)
Xstruct FileLock *lock;
Xchar *file;
Xint line;
X{
X register struct TrackingLockData *lp, *op, *freep;
X
X TrackerUnLockCount++;
X
X /* scan the lock tracking list for a match */
X for (lp = TrackingLockList, op = NULL; lp != NULL; op = lp, lp = lp->next)
X {
X /* if we matched the lock */
X if (lp->lock == lock)
X {
X#ifndef FORGET_LOCKS_WHEN_UNLOCKED
X /* if it's already free, tell them they freed twice */
X if (lp->my_flags & FREED_IT)
X {
X fprintf(stderr,"freed lock twice, lock %lx, filename %s\n\tlocked at file %s line %d, freed at file %s line %d\n",lock,lp->name,lp->file,lp->line,file,line);
X return;
X }
X else
X {
X /* mark this entry as free */
X lp->my_flags |= FREED_IT;
X }
X#else
X if (op != NULL) op->next = lp->next;
X else TrackingLockList = lp->next;
X freep = lp;
X lp = lp->next;
X if (lp->name != NULL)
X FreeMem(lp->name,(long)(strlen(lp->name)+1));
X FreeMem(freep,(long)(sizeof(struct TrackingLockData)));
X#endif
X UnLock(lock);
X return;
X }
X }
X fprintf(stderr,"Freed lock %lx that hadn't been allocated at file %s line %d\n",lock,file,line);
X}
X
XReportUnfreedLocks()
X{
X struct TrackingLockData *lp = TrackingLockList, *freep;
X
X while (lp != NULL)
X {
X if (!(lp->my_flags & FREED_IT))
X {
X if (lp->my_flags & CREATED_BY_DUPLOCK)
X {
X fprintf(stderr,"UnLock was never called for lock %lx,\n\It was created by DupLock at file %s line %d\n",lp->lock,lp->file,lp->line);
X }
X else
X {
X fprintf(stderr,"UnLock was never called for lock %lx,\n\It was created by a Lock of %s\nat file %s line %d\n",lp->lock,lp->name,lp->file,lp->line);
X }
X }
X if (lp->name != NULL)
X FreeMem(lp->name,(long)(strlen(lp->name)+1));
X freep = lp;
X lp = lp->next;
X FreeMem(freep,(long)sizeof(struct TrackingLockData));
X }
X printf("Total tracked Lock and DupLock calls %ld, UnLock calls %ld\n",TrackerLockCount,TrackerUnLockCount);
X}
X
XTrackerExitReport()
X{
X ReportUnfreedMemory();
X ReportUnfreedLocks();
X ReportUnfreedSignals();
X}
X
X#endif
END_OF_FILE
if test 9277 -ne `wc -c <'tracker.c'`; then
echo shar: \"'tracker.c'\" unpacked with wrong size!
fi
# end of 'tracker.c'
fi
if test -f 'windows.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'windows.c'\"
else
echo shar: Extracting \"'windows.c'\" \(12546 characters\)
sed "s/^X//" >'windows.c' <<'END_OF_FILE'
X
Xstruct IntuiText XIText1 = {
X 3,1,COMPLEMENT, /* front and back text pens, drawmode and fill byte */
X 0,0, /* XY origin relative to container TopLeft */
X NULL, /* font pointer or NULL for default */
X (UBYTE *)"Quit", /* pointer to text */
X NULL /* next IntuiText structure */
X};
X
Xstruct MenuItem XMenuItem3 = {
X NULL, /* next MenuItem structure */
X 0,18, /* XY of Item hitbox relative to TopLeft of parent hitbox */
X 112,8, /* hit box width and height */
X ITEMTEXT+ITEMENABLED+HIGHCOMP, /* Item flags */
X 0, /* each bit mutually-excludes a same-level Item */
X (APTR)&XIText1, /* Item render (IntuiText or Image or NULL) */
X NULL, /* Select render */
X NULL, /* alternate command-key */
X NULL, /* SubItem list */
X MENUNULL /* filled in by Intuition for drag selections */
X};
X
Xstruct IntuiText XIText2 = {
X 3,1,COMPLEMENT, /* front and back text pens, drawmode and fill byte */
X 0,0, /* XY origin relative to container TopLeft */
X NULL, /* font pointer or NULL for default */
X (UBYTE *)"arranging services, and pro sampling.", /* pointer to text */
X NULL /* next IntuiText structure */
X};
X
Xstruct MenuItem XSubItem5 = {
X NULL, /* next SubItem structure */
X 97,24, /* XY of Item hitbox relative to TopLeft of parent hitbox */
X 416,8, /* hit box width and height */
X ITEMTEXT+ITEMENABLED+HIGHCOMP, /* Item flags */
X 0, /* each bit mutually-excludes a same-level Item */
X (APTR)&XIText2, /* Item render (IntuiText or Image or NULL) */
X NULL, /* Select render */
X NULL, /* alternate command-key */
X NULL, /* no SubItem list for SubItems */
X MENUNULL /* filled in by Intuition for drag selections */
X};
X
Xstruct IntuiText XIText3 = {
X 3,1,COMPLEMENT, /* front and back text pens, drawmode and fill byte */
X 0,0, /* XY origin relative to container TopLeft */
X NULL, /* font pointer or NULL for default */
X (UBYTE *)"(including SMUS and MIDI players), composition and", /* pointer to text */
X NULL /* next IntuiText structure */
X};
X
Xstruct MenuItem XSubItem4 = {
X &XSubItem5, /* next SubItem structure */
X 97,16, /* XY of Item hitbox relative to TopLeft of parent hitbox */
X 416,8, /* hit box width and height */
X ITEMTEXT+ITEMENABLED+HIGHCOMP, /* Item flags */
X 0, /* each bit mutually-excludes a same-level Item */
X (APTR)&XIText3, /* Item render (IntuiText or Image or NULL) */
X NULL, /* Select render */
X NULL, /* alternate command-key */
X NULL, /* no SubItem list for SubItems */
X MENUNULL /* filled in by Intuition for drag selections */
X};
X
Xstruct IntuiText XIText4 = {
X 3,1,COMPLEMENT, /* front and back text pens, drawmode and fill byte */
X 0,0, /* XY origin relative to container TopLeft */
X NULL, /* font pointer or NULL for default */
X (UBYTE *)"Contact me for innovative, licensable audio software", /* pointer to text */
X NULL /* next IntuiText structure */
X};
X
Xstruct MenuItem XSubItem3 = {
X &XSubItem4, /* next SubItem structure */
X 97,8, /* XY of Item hitbox relative to TopLeft of parent hitbox */
X 416,8, /* hit box width and height */
X ITEMTEXT+ITEMENABLED+HIGHCOMP, /* Item flags */
X 0, /* each bit mutually-excludes a same-level Item */
X (APTR)&XIText4, /* Item render (IntuiText or Image or NULL) */
X NULL, /* Select render */
X NULL, /* alternate command-key */
X NULL, /* no SubItem list for SubItems */
X MENUNULL /* filled in by Intuition for drag selections */
X};
X
Xstruct IntuiText XIText5 = {
X 3,1,COMPLEMENT, /* front and back text pens, drawmode and fill byte */
X 0,0, /* XY origin relative to container TopLeft */
X NULL, /* font pointer or NULL for default */
X (UBYTE *)"", /* pointer to text */
X NULL /* next IntuiText structure */
X};
X
Xstruct MenuItem XSubItem2 = {
X &XSubItem3, /* next SubItem structure */
X 97,0, /* XY of Item hitbox relative to TopLeft of parent hitbox */
X 416,8, /* hit box width and height */
X ITEMTEXT+ITEMENABLED+HIGHCOMP, /* Item flags */
X 0, /* each bit mutually-excludes a same-level Item */
X (APTR)&XIText5, /* Item render (IntuiText or Image or NULL) */
X NULL, /* Select render */
X NULL, /* alternate command-key */
X NULL, /* no SubItem list for SubItems */
X MENUNULL /* filled in by Intuition for drag selections */
X};
X
Xstruct IntuiText XIText6 = {
X 3,1,COMPLEMENT, /* front and back text pens, drawmode and fill byte */
X 0,0, /* XY origin relative to container TopLeft */
X NULL, /* font pointer or NULL for default */
X (UBYTE *)"Freely redistributable for noncommercial purposes.", /* pointer to text */
X NULL /* next IntuiText structure */
X};
X
Xstruct MenuItem XSubItem1 = {
X &XSubItem2, /* next SubItem structure */
X 97,-8, /* XY of Item hitbox relative to TopLeft of parent hitbox */
X 416,8, /* hit box width and height */
X ITEMTEXT+ITEMENABLED+HIGHCOMP, /* Item flags */
X 0, /* each bit mutually-excludes a same-level Item */
X (APTR)&XIText6, /* Item render (IntuiText or Image or NULL) */
X NULL, /* Select render */
X NULL, /* alternate command-key */
X NULL, /* no SubItem list for SubItems */
X MENUNULL /* filled in by Intuition for drag selections */
X};
X
Xstruct IntuiText XIText7 = {
X 3,1,COMPLEMENT, /* front and back text pens, drawmode and fill byte */
X 0,0, /* XY origin relative to container TopLeft */
X NULL, /* font pointer or NULL for default */
X (UBYTE *)"Redistribution", /* pointer to text */
X NULL /* next IntuiText structure */
X};
X
Xstruct MenuItem XMenuItem2 = {
X &XMenuItem3, /* next MenuItem structure */
X 0,9, /* XY of Item hitbox relative to TopLeft of parent hitbox */
X 112,8, /* hit box width and height */
X ITEMTEXT+ITEMENABLED+HIGHCOMP, /* Item flags */
X 0, /* each bit mutually-excludes a same-level Item */
X (APTR)&XIText7, /* Item render (IntuiText or Image or NULL) */
X NULL, /* Select render */
X NULL, /* alternate command-key */
X &XSubItem1, /* SubItem list */
X MENUNULL /* filled in by Intuition for drag selections */
X};
X
Xstruct IntuiText XIText8 = {
X 3,1,COMPLEMENT, /* front and back text pens, drawmode and fill byte */
X 0,0, /* XY origin relative to container TopLeft */
X NULL, /* font pointer or NULL for default */
X (UBYTE *)"Internet: karl@sugar.hackercorp.com", /* pointer to text */
X NULL /* next IntuiText structure */
X};
X
Xstruct MenuItem XSubItem11 = {
X NULL, /* next SubItem structure */
X 97,32, /* XY of Item hitbox relative to TopLeft of parent hitbox */
X 280,8, /* hit box width and height */
X ITEMTEXT+ITEMENABLED+HIGHCOMP, /* Item flags */
X 0, /* each bit mutually-excludes a same-level Item */
X (APTR)&XIText8, /* Item render (IntuiText or Image or NULL) */
X NULL, /* Select render */
X NULL, /* alternate command-key */
X NULL, /* no SubItem list for SubItems */
X MENUNULL /* filled in by Intuition for drag selections */
X};
X
Xstruct IntuiText XIText9 = {
X 3,1,COMPLEMENT, /* front and back text pens, drawmode and fill byte */
X 0,0, /* XY origin relative to container TopLeft */
X NULL, /* font pointer or NULL for default */
X (UBYTE *)"Usenet: uunet!sugar!karl", /* pointer to text */
X NULL /* next IntuiText structure */
X};
X
Xstruct MenuItem XSubItem10 = {
X &XSubItem11, /* next SubItem structure */
X 97,24, /* XY of Item hitbox relative to TopLeft of parent hitbox */
X 280,8, /* hit box width and height */
X ITEMTEXT+ITEMENABLED+HIGHCOMP, /* Item flags */
X 0, /* each bit mutually-excludes a same-level Item */
X (APTR)&XIText9, /* Item render (IntuiText or Image or NULL) */
X NULL, /* Select render */
X NULL, /* alternate command-key */
X NULL, /* no SubItem list for SubItems */
X MENUNULL /* filled in by Intuition for drag selections */
X};
X
Xstruct IntuiText XIText10 = {
X 3,1,COMPLEMENT, /* front and back text pens, drawmode and fill byte */
X 0,0, /* XY origin relative to container TopLeft */
X NULL, /* font pointer or NULL for default */
X (UBYTE *)"Missouri City, TX 77459", /* pointer to text */
X NULL /* next IntuiText structure */
X};
X
Xstruct MenuItem XSubItem9 = {
X &XSubItem10, /* next SubItem structure */
X 97,16, /* XY of Item hitbox relative to TopLeft of parent hitbox */
X 280,8, /* hit box width and height */
X ITEMTEXT+ITEMENABLED+HIGHCOMP, /* Item flags */
X 0, /* each bit mutually-excludes a same-level Item */
X (APTR)&XIText10, /* Item render (IntuiText or Image or NULL) */
X NULL, /* Select render */
X NULL, /* alternate command-key */
X NULL, /* no SubItem list for SubItems */
X MENUNULL /* filled in by Intuition for drag selections */
X};
X
Xstruct IntuiText XIText11 = {
X 3,1,COMPLEMENT, /* front and back text pens, drawmode and fill byte */
X 0,0, /* XY origin relative to container TopLeft */
X NULL, /* font pointer or NULL for default */
X (UBYTE *)"3918 Panorama", /* pointer to text */
X NULL /* next IntuiText structure */
X};
X
Xstruct MenuItem XSubItem8 = {
X &XSubItem9, /* next SubItem structure */
X 97,8, /* XY of Item hitbox relative to TopLeft of parent hitbox */
X 280,8, /* hit box width and height */
X ITEMTEXT+ITEMENABLED+HIGHCOMP, /* Item flags */
X 0, /* each bit mutually-excludes a same-level Item */
X (APTR)&XIText11, /* Item render (IntuiText or Image or NULL) */
X NULL, /* Select render */
X NULL, /* alternate command-key */
X NULL, /* no SubItem list for SubItems */
X MENUNULL /* filled in by Intuition for drag selections */
X};
X
Xstruct IntuiText XIText12 = {
X 3,1,COMPLEMENT, /* front and back text pens, drawmode and fill byte */
X 0,0, /* XY origin relative to container TopLeft */
X NULL, /* font pointer or NULL for default */
X (UBYTE *)"by Karl Lehenbauer, Hackercorp", /* pointer to text */
X NULL /* next IntuiText structure */
X};
X
Xstruct MenuItem XSubItem7 = {
X &XSubItem8, /* next SubItem structure */
X 97,0, /* XY of Item hitbox relative to TopLeft of parent hitbox */
X 280,8, /* hit box width and height */
X ITEMTEXT+ITEMENABLED+HIGHCOMP, /* Item flags */
X 0, /* each bit mutually-excludes a same-level Item */
X (APTR)&XIText12, /* Item render (IntuiText or Image or NULL) */
X NULL, /* Select render */
X NULL, /* alternate command-key */
X NULL, /* no SubItem list for SubItems */
X MENUNULL /* filled in by Intuition for drag selections */
X};
X
Xstruct IntuiText XIText13 = {
X 3,1,COMPLEMENT, /* front and back text pens, drawmode and fill byte */
X 0,0, /* XY origin relative to container TopLeft */
X NULL, /* font pointer or NULL for default */
X (UBYTE *)"Chatterbox - v0.1", /* pointer to text */
X NULL /* next IntuiText structure */
X};
X
Xstruct MenuItem XSubItem6 = {
X &XSubItem7, /* next SubItem structure */
X 97,-8, /* XY of Item hitbox relative to TopLeft of parent hitbox */
X 280,8, /* hit box width and height */
X ITEMTEXT+ITEMENABLED+HIGHCOMP, /* Item flags */
X 0, /* each bit mutually-excludes a same-level Item */
X (APTR)&XIText13, /* Item render (IntuiText or Image or NULL) */
X NULL, /* Select render */
X NULL, /* alternate command-key */
X NULL, /* no SubItem list for SubItems */
X MENUNULL /* filled in by Intuition for drag selections */
X};
X
Xstruct IntuiText XIText14 = {
X 3,1,COMPLEMENT, /* front and back text pens, drawmode and fill byte */
X 0,0, /* XY origin relative to container TopLeft */
X NULL, /* font pointer or NULL for default */
X (UBYTE *)"About", /* pointer to text */
X NULL /* next IntuiText structure */
X};
X
Xstruct MenuItem XMenuItem1 = {
X &XMenuItem2, /* next MenuItem structure */
X 0,0, /* XY of Item hitbox relative to TopLeft of parent hitbox */
X 112,8, /* hit box width and height */
X ITEMTEXT+ITEMENABLED+HIGHCOMP, /* Item flags */
X 0, /* each bit mutually-excludes a same-level Item */
X (APTR)&XIText14, /* Item render (IntuiText or Image or NULL) */
X NULL, /* Select render */
X NULL, /* alternate command-key */
X &XSubItem6, /* SubItem list */
X MENUNULL /* filled in by Intuition for drag selections */
X};
X
Xstruct Menu XMenu1 = {
X NULL, /* next Menu structure */
X 0,0, /* XY origin of Menu hit box relative to screen TopLeft */
X 75,0, /* Menu hit box width and height */
X MENUENABLED, /* Menu flags */
X "Project", /* text of Menu name */
X &XMenuItem1 /* MenuItem linked list pointer */
X};
X
X#define XMenuList1 XMenu1
X
Xstruct NewWindow XNewWindowStructure1 = {
X 355,22, /* window XY origin relative to TopLeft of screen */
X 165,10, /* window width and height */
X 0,1, /* detail and block pens */
X MENUPICK+CLOSEWINDOW+NEWPREFS+DISKINSERTED+DISKREMOVED+ACTIVEWINDOW+INACTIVEWINDOW, /* IDCMP flags */
X WINDOWDRAG+WINDOWDEPTH+WINDOWCLOSE, /* other window flags */
X NULL, /* first gadget in gadget list */
X NULL, /* custom CHECKMARK imagery */
X (UBYTE *)"Chatterbox", /* window title */
X NULL, /* custom screen pointer */
X NULL, /* custom bitmap */
X 5,5, /* minimum width and height */
X 640,200, /* maximum width and height */
X WBENCHSCREEN /* destination screen type */
X};
X
X
Xvoid HandleEvent(object)
XAPTR object;
X{
X if (object == (APTR)&XMenuItem3) { Quit(object); return; }
X}
X#define HANDLEEVENT HandleEvent
X
X/* end of PowerWindows source generation */
END_OF_FILE
if test 12546 -ne `wc -c <'windows.c'`; then
echo shar: \"'windows.c'\" unpacked with wrong size!
fi
# end of 'windows.c'
fi
echo shar: End of archive 2 \(of 2\).
cp /dev/null ark2isdone
MISSING=""
for I in 1 2 ; do
if test ! -f ark${I}isdone ; then
MISSING="${MISSING} ${I}"
fi
done
if test "${MISSING}" = "" ; then
echo You have unpacked both archives.
rm -f ark[1-9]isdone
else
echo You still need to unpack the following archives:
echo " " ${MISSING}
fi
## End of shell archive.
exit 0
--
Submissions to comp.sources.amiga and comp.binaries.amiga should be sent to:
amiga@cs.odu.edu
or amiga@xanth.cs.odu.edu ( obsolescent mailers may need this address )
or ...!uunet!xanth!amiga ( very obsolescent mailers need this address )
Comments, questions, and suggestions s should be addressed to ``amiga-request''
(only use ``amiga'' for submissions) at the above addresses.