home *** CD-ROM | disk | FTP | other *** search
- /* Morse Code Program for Macintosh */
- /* by James R. Logan Jr. */
-
- /* Part of the "send()" routine was */
- /* taken from a Morse Code program */
- /* writen by Keith J. McQueen (N7HMF) */
- /* and modified by Brian Minert. */
-
- #include <Quickdraw.h>
- #include <Windows.h>
- #include <Menus.h>
- #include <Errors.h>
- #include <Events.h>
- #include <TextEdit.h>
- #include <Dialogs.h>
- #include <Controls.h>
- #include <StandardFile.h>
- #include <sound.h>
- #include <stdio.h>
- #include <ToolUtils.h>
- #include <types.h>
-
- /* Factor for converting from words per minute to the
- duration of "di" in half milliseconds. It should be
- 2400, but adjusted downward because the actual
- performance was too slow. */
-
- /* Convert from the number of "di" in 1/60 of a second (a tick)
- to Morse Code words per minute */
- #define DPHMS_TO_WPM 66
-
- #define AMP 120
-
- #define REPEAT_EVENT_DELAY_TICKS 20
- #define REPEAT_AGAIN_DELAY_TICKS 4
-
- #define CODE_MODES 5
- #define WAIT_MODES 2
- #define PLAY_MODES 3
- #define PAUSE_MODES 2
- #define FILE_MODES 2
-
- #define PAUSE_STRING 0
- #define RESUME_STRING 1
-
- #define OPEN_STRING 0
- #define CLOSE_STRING 1
-
- #define HAND_CURSOR_ID 128
-
- #define CODE_STR_ID 128
- #define WAIT_STR_ID 129
- #define PLAY_STR_ID 130
- #define PAUSE_STR_ID 131
- #define FILE_STR_ID 132
-
- #define LINESIZE 8 /* Number of characters to display left of the code */
- /* This affects the code speed, higher numbers slow it down */
-
- #define TEXTHEIGHT 20
- #define TEXTINDENT 0
- #define TEXTMARGINS 0 /* Sum of left and right margin */
- #define TEXTWIDTH 226
- #define WINDOWWIDTH 256
-
- #define MAX_Menus 3
-
- #define BASE_MenuID 128
- #define MENUBAR_ID 128
-
- #define CODE_DIALOG 28243
- #define SettingsID 31324
-
- #define CNTL_OKAY_BTN 128
-
- #define QUEUE_SIZE 1024
-
- #define SOUND_COMPLETE 1
-
- enum {
- AppleN=128, /* APPLE/DA */
- fileMenuN, /* File */
- editMenuN, /* Edit */
- lastMenuN
- };
-
- enum { /* File */
- mFile_Open = 1,
- mSave_Settings,
- mFile_Quit,
- mFile_Last
- };
-
- enum { /* Dialog items */
- open_button = 1,
- quit_button,
- pause_button,
- volume_up,
- volume_down,
- frequency_up,
- frequency_down,
- duration_up,
- duration_down,
- whichcode_up,
- whichcode_down,
- wait_up,
- wait_down,
- play_up,
- play_down,
- volumeitem,
- freqitem,
- wordsitem,
- codeitem,
- waititem,
- playitem,
- code_pattern,
- code_character,
- volumelabelitem,
- frequencylabelitem,
- wordslabelitem,
- gray1item,
- gray2item,
- titleitem,
- wpmitem,
- dialog_item_last
- };
-
- short initsound(SndChannelPtr *soundptr);
-
- Boolean done;
- Boolean has_multifinder;
- Boolean key_correct;
- Boolean paused;
- Boolean playfile;
- Boolean random;
- Boolean ready;
- Boolean speedfor1character;
- short chasex;
- short codetimecharactercount;
- short codetimeunits;
- short cr_windowwidth;
- short duration;
- short playcontinuous;
- short frequency;
- short gp; /* Play file */
- short queuex;
- short repeat_event_item;
- short waitforkey;
- short whichcode; /* All, letters, numbers, symbols */
- short version;
- short volume;
- long codetimebegin;
- long codetimeend;
- long sharedTimeTicks;
- Point dialogPoint;
- Rect dragRect;
- Rect pattern_rect;
- ControlHandle OkayBtnHdl;
- DialogPtr myDialog;
- GrafPtr screenPort; /* For DragWindow() */
- SndChannelPtr soundptr;
- MenuHandle mymenus[MAX_Menus];
- WindowPtr noticeWindow; /* Window for copyright notice */
- WindowRecord nrecord;
-
- unsigned char display_code;
- unsigned char last_code;
-
- unsigned char queue[QUEUE_SIZE];
-
- static ResType crstyp = 'CURS';
- static ResType Setres = 'CNFG';
-
- static unsigned char *notice[] =
- {"\pMorseCode v1.0",
- "\p© 1993",
- "\pJames R. Logan Jr.",
- "\pE-mail: loganj@cs.byu.edu",
- "\p"}; /* The code stops when it sees a null string */
-
- char *code_line = { " " };
- unsigned char randomtable[] = {
- 'A','B','C','D','E','F','G','H','I','J',
- 'K','L','M','N','O','P','Q','R','S','T',
- 'U','V','W','X','Y','Z','0','1','2','3',
- '4','5','6','7','8','9','"','$','\'','/',
- '(',')','+',',','-','.','/',':',';','=',
- '?'};
-
- unsigned char *codetable[] = {
- "\pspace", /* ASCII 32 */
- "\p! ", // !
- "\p• – • • – •", // "
- "\p# ", // #
- "\p• • • – • • –", // $
- "\p% ", // %
- "\p& ", // &
- "\p• – – – – •", // '
-
- "\p– • – – •", /* ( ASCII 40 */
- "\p– • – – • –", // )
- "\p* ", // *
- "\p• – • – •", // +
- "\p– – • • – –", // ,
- "\p– • • • • –", // -
- "\p• – • – • –", // .
- "\p– • • – •", // /
- "\p– – – – –", // 0
- "\p• – – – –", // 1
-
- "\p• • – – –", /* 2 ASCII 50 */
- "\p• • • – –", // 3
- "\p• • • • –", // 4
- "\p• • • • •", // 5
- "\p– • • • •", // 6
- "\p– – • • •", // 7
- "\p– – – • •", // 8
- "\p– – – – •", // 9
- "\p– – – • • •", // :
- "\p– • – • – •", // ;
-
- "\p< ", /* < ASCII 60 */
- "\p– • • • –", // =
- "\p> ", // >
- "\p• • – – • •", // ?
- "\p@ ", // @
- "\p• –", // A
- "\p– • • •", // B
- "\p– • – •", // C
- "\p– • •", // D
- "\p•", // E
-
- "\p• • – •", /* F ASCII 70 */
- "\p– – •", // G
- "\p• • • •", // H
- "\p• •", // I
- "\p• – – –", // J
- "\p– • –", // K
- "\p• – • •", // L
- "\p– –", // M
- "\p– •", // N
- "\p– – –", // O
-
- "\p• – – •", /* P ASCII 80 */
- "\p– – • –", // Q
- "\p• – •", // R
- "\p• • •", // S
- "\p–", // T
- "\p• • –", // U
- "\p• • • –", // V
- "\p• – –", // W
- "\p– • • –", // X
- "\p– • – –", // Y
-
- "\p– – • •" /* Z ASCII 90 */
- };
-
-
- Str255 mcode[CODE_MODES];
- Str255 mwait[WAIT_MODES];
- Str255 mplay[PLAY_MODES];
- Str255 mpause[PAUSE_MODES];
- Str255 mfile[PAUSE_MODES];
-
-
-
- short BoundsLimitWithWrapAround(short *vPtr,short lo,short hi) {
- if( *vPtr < lo)
- *vPtr = hi;
- else if( *vPtr > hi)
- *vPtr = lo;
- return( *vPtr);
- }
-
-
-
- short BoundsLimit(short *vPtr, short lo, short hi) {
- if( *vPtr < lo)
- *vPtr = lo;
- else if( *vPtr > hi)
- *vPtr = hi;
- return( *vPtr);
- }
-
-
-
-
- #define THE_TYPE_H_RECT short theType; \
- Handle theHandle; \
- Rect theRect;
-
- /* GetDIHandle - return handle value of dialog item */
- Handle GetDIHandle(DialogPtr theDia, short i) {
- THE_TYPE_H_RECT
- GetDItem(theDia, i, &theType, &theHandle, &theRect);
- return theHandle;
- }
-
-
-
- void SetSettings(short *rp) {
- short i,*resptr;
- resptr = rp;
- version = *(resptr++);
- volume = *(resptr++);
- frequency = *(resptr++);
- duration = *(resptr++);
- whichcode = *(resptr++);
- waitforkey = *(resptr++);
- playcontinuous = *(resptr++);
-
- random = playcontinuous == 2;
-
- dialogPoint.h = *(resptr++);
- dialogPoint.v = *(resptr++);
- }
-
-
-
- void getSettings() {
- char **myResource; short i,*resptr;
- #define SettingsID 31324
- long mysize;
-
- myResource = GetResource(Setres, SettingsID);
- if (myResource == 0) SysBeep(4);
- else {
- resptr = (short*) *myResource;
- SetSettings(resptr);
- ReleaseResource(myResource);
- }
- }
-
-
- void saveSettings() {
- short i,*resptr;
- char **myResource;
- GrafPtr tempPort;
-
- GetPort(&tempPort);
- myResource = GetResource( Setres, SettingsID);
- resptr = (short*) *myResource;
- *(resptr++) = version;
- *(resptr++) = volume;
- *(resptr++) = frequency;
- *(resptr++) = duration;
- *(resptr++) = whichcode;
- *(resptr++) = waitforkey;
- *(resptr++) = playcontinuous;
-
- dialogPoint.h = myDialog->portRect.left; /* Save window position */
- dialogPoint.v = myDialog->portRect.top;
- SetPort(myDialog); LocalToGlobal(&dialogPoint);
- *(resptr++) = dialogPoint.h;
- *(resptr++) = dialogPoint.v;
-
- ChangedResource(myResource);
- WriteResource(myResource);
- ReleaseResource(myResource);
- SetPort(tempPort);
- }
-
-
-
- void GetStrings(Str255 buf[], short resource_id, short num_strings) {
- short i1;
- for (i1 = 0; i1 < num_strings; i1++)
- GetIndString(&buf[i1], resource_id, i1+1);
- }
-
-
-
- void OpenAppFile(short filenumber) {
- AppFile codefile;
- short status;
- GetAppFiles(filenumber,&codefile);
- status = FSOpen(codefile.fName, codefile.vRefNum, &gp);
- if (status != noErr) {
- SysBeep(4);
- gp = 0;
- } }
-
-
-
- void DrawCopyright() {
- short i1,linelength,linewidth,mycharwidth,wordwidth;
- char *linestart,*myptr;
- Rect box;
- PicHandle lrepict;
- GrafPtr tempPort;
-
- GetPort(&tempPort); /* Save the previous port */
- SetPort(noticeWindow);
-
- EraseRect(¬iceWindow->portRect);
-
- SetRect(&box, TEXTINDENT, -5, TEXTINDENT + TEXTWIDTH, TEXTHEIGHT); /* Dimensions of text box in window coordinates */
- TextSize(12); TextFace(0); TextFont(0); /* Font characteristics */
-
- i1 = 0;
- while (notice[i1][0]) {
- OffsetRect(&box, 0, 20); /* Move text box down */
- TextBox( ¬ice[i1][1], notice[i1][0], &box ,teJustCenter);
- i1++;
- }
-
- SetPort(tempPort);
- }
-
-
-
- void WaitForOperator() {
- Boolean gotEvent,waiting;
- short part;
- WindowPtr window;
- EventRecord myEvent;
-
- waiting = true;
- do {
- if (has_multifinder)
- gotEvent = WaitNextEvent(everyEvent, &myEvent, sharedTimeTicks, NULL); /* give time to other processes */
- else
- gotEvent = GetNextEvent(everyEvent, &myEvent); /* no other processes */
-
- if (gotEvent) {
- if (myEvent.what == mouseDown) {
- part = FindWindow(myEvent.where, &window); /* where did the click land */
- if ((FrontWindow() == noticeWindow) && (window == noticeWindow))
- waiting = false;
- } else if (myEvent.what == updateEvt) {
- if ((WindowPtr) myEvent.message == noticeWindow) {
- BeginUpdate(noticeWindow);
- DrawCopyright();
- DrawControls(noticeWindow);
- EndUpdate(noticeWindow);
- }
- #if 0
- } else if (myEvent.what == osEvt) {
- if (myEvent.message & 1)
- DrawCopyright(message,linecount);
- #endif
- } else if (myEvent.what == keyDown) {
- if (FrontWindow() == noticeWindow)
- waiting = false;
- }
- }
- } while (waiting);
- }
-
-
-
- /* The bounds of the copyright notice were hard coded here to discourage
- tampering, otherwise this stuff could be in resources. */
-
- void DoCopyright() {
- GrafPtr tempPort;
- Rect screenRect;
- Rect sRect;
-
- GetPort(&tempPort); /* Save the previous port */
-
- cr_windowwidth = TEXTWIDTH; /* Width of text portion of window (for drawing "Okay" button */
- SetRect(&screenRect,30,40,WINDOWWIDTH,180); /* Window bounds in screen coordinates */
- noticeWindow = NewWindow(&nrecord,&screenRect,"\p",false,3,(WindowPtr)-1L,0,(long)0L);
- OkayBtnHdl = GetNewControl(CNTL_OKAY_BTN,noticeWindow);
- MoveControl(OkayBtnHdl,(cr_windowwidth >> 1) - 20,noticeWindow->portRect.bottom - 30);
- ShowWindow(noticeWindow);
- SetPort(noticeWindow);
- SelectWindow(noticeWindow);
-
- /* DrawCopyright(); /* */
-
- WaitForOperator();
-
- DisposeWindow(noticeWindow);
-
- SetPort(tempPort);
- }
-
-
-
- ShowOptions() {
- short handshake,item_type,mSettings;
- Handle item_Handle;
- Rect item_box;
- Str255 item_text;
-
- GetSoundVol(&volume);
- NumToString(volume,item_text);
- SetIText( GetDIHandle( myDialog, volumeitem), item_text);
-
- NumToString(frequency,item_text);
- SetIText( GetDIHandle( myDialog, freqitem), item_text);
-
- NumToString(duration,item_text);
- SetIText( GetDIHandle( myDialog, wordsitem), item_text);
-
- SetIText( GetDIHandle( myDialog, codeitem), mcode[whichcode]);
-
- SetIText( GetDIHandle( myDialog, waititem), mwait[waitforkey]);
-
- SetIText( GetDIHandle( myDialog, playitem), mplay[playcontinuous]);
- }
-
-
-
- ShowCode(unsigned char c) {
- short i1,width;
- if ((c >= ' ') && (c <= 'Z')) {
- SetIText( GetDIHandle( myDialog, code_pattern), codetable[c - ' ']);
- }
- for (i1 = 1; i1 < LINESIZE; i1++)
- code_line[i1-1] = code_line[i1];
- code_line[LINESIZE-1] = c;
- SetPort(myDialog);
- #if 1
- EraseRect(&pattern_rect);
- width = TextWidth(code_line,0,LINESIZE);
- MoveTo(pattern_rect.right - width, pattern_rect.bottom - 4);
- DrawText(code_line,0,LINESIZE);
- #else
- TextBox(code_line,LINESIZE,&pattern_rect,teJustRight);
- #endif
- }
-
-
-
- ShowSpeed(void) {
- THE_TYPE_H_RECT
- long codespeed;
- Str255 mystring;
- if ((codetimeend > codetimebegin) &&
- ((codetimecharactercount > 1) || (speedfor1character))) {
- codespeed = (DPHMS_TO_WPM * codetimeunits)/(codetimeend - codetimebegin);
- NumToString(codespeed,mystring);
- SetIText( GetDIHandle( myDialog, wpmitem), mystring);
- codetimeend = -1;
- }
- }
-
-
-
- pascal void GrayItem(DialogPtr myDialog, short theItem) {
- THE_TYPE_H_RECT
- Handle myhandle;
- Rect myrect;
- short mytype;
- GrafPtr tempPort;
-
- GetPort(&tempPort);
- SetPort(myDialog);
- GetDItem(myDialog, theItem, &theType, &theHandle, &theRect);
- if ((playcontinuous < 2) && (whichcode > 0)) {
- PenPat(&qd.gray);
- PenMode(patBic);
- GetDItem(myDialog, codeitem, &mytype, &myhandle, &myrect);
- SetDItem(myDialog, theItem, theType, theHandle, &myrect);
- PaintRect(&myrect);
- PenNormal();
- } else {
- SetRect(&myrect, 20000, 20000, 20010, 20010);
- SetDItem(myDialog, theItem, theType, theHandle, &myrect);
- InvalRect(&theRect);
- }
- SetPort(tempPort);
- }
-
-
-
- pascal void PGrayItem(DialogPtr myDialog, short theItem) {
- THE_TYPE_H_RECT
- Handle myhandle;
- Rect myrect;
- short mytype;
- GrayItem(myDialog,theItem);
- }
-
-
-
- void AdjustControls(void) {
- THE_TYPE_H_RECT
- GetDItem(myDialog, waititem, &theType, &theHandle, &theRect);
- SetPort(myDialog);
- InvalRect(&theRect);
- }
-
-
-
- SetOptions(short the_item) {
- short handshake,item_type,mSettings;
- Handle item_handle;
- Rect item_box;
- Str255 item_text;
-
- #if 0
- NumToString(frequency,item_text);
- SetIText( GetDIHandle( myDialog, freqitem), item_text);
- #endif
-
- repeat_event_item = 0;
-
- if (the_item == open_button)
-
- if (playfile) {
- playfile = false;
- FSClose(gp);
- gp = 0;
- SetCTitle(GetDIHandle( myDialog, open_button), mfile[OPEN_STRING]);
- } else {
- FileCode();
- }
-
- else if (the_item == quit_button)
-
- done = true;
-
- else if (the_item == pause_button)
-
- if (paused) {
- paused = false;
- SetCTitle(GetDIHandle( myDialog, pause_button), mpause[PAUSE_STRING]);
- } else {
- paused = true;
- SetCTitle(GetDIHandle( myDialog, pause_button), mpause[RESUME_STRING]);
- }
-
- else if ((the_item == volume_up) ||
- (the_item == volume_down) ) { /* UP/DOWN volume*/
-
- GetSoundVol(&volume);
- volume += ((the_item == volume_up) ? 1 : -1);
- BoundsLimitWithWrapAround( &volume, 0, 7);
- SetSoundVol(volume);
- NumToString(volume,item_text);
- SetIText( GetDIHandle( myDialog, volumeitem), item_text);
- repeat_event_item = the_item;
-
- } else if ((the_item == frequency_up) ||
- (the_item == frequency_down)) { /* UP/DOWN frequency */
-
- frequency += ((the_item == frequency_up) ? 1 : -1);
- BoundsLimitWithWrapAround( &frequency, 70, 110);
- NumToString(frequency,item_text);
- SetIText( GetDIHandle( myDialog, freqitem), item_text);
- repeat_event_item = the_item;
-
- } else if ((the_item == duration_up) ||
- (the_item == duration_down)) { /* UP/DOWN words per minute */
-
- duration += ((the_item == duration_up) ? 1 : -1);
- BoundsLimitWithWrapAround( &duration, 40, 500);
- NumToString(duration,item_text);
- SetIText( GetDIHandle( myDialog, wordsitem), item_text);
- repeat_event_item = the_item;
- speedfor1character = true; /* Restart speed computation */
-
- } else if ((the_item == whichcode_up) ||
- (the_item == whichcode_down)) { /* UP/DOWN which codes */
-
- whichcode += ((the_item == whichcode_up) ? 1 : -1);
- BoundsLimitWithWrapAround( &whichcode, 0, 4);
- SetIText( GetDIHandle( myDialog, codeitem), mcode[ whichcode]);
- GrayItem(myDialog, gray1item);
- repeat_event_item = the_item;
-
- } else if ((the_item == wait_up) ||
- (the_item == wait_down)) { /* UP/DOWN wait for key */
-
- waitforkey += ((the_item == wait_up) ? 1 : -1);
- BoundsLimitWithWrapAround( &waitforkey, 0, 1);
- SetIText( GetDIHandle( myDialog, waititem), mwait[ waitforkey]);
- repeat_event_item = the_item;
-
- } else if ((the_item == play_up) ||
- (the_item == play_down)) { /* Play file continuously */
-
- playcontinuous += ((the_item == play_up) ? 1 : -1);
- BoundsLimitWithWrapAround( &playcontinuous, 0, 2);
- SetIText( GetDIHandle( myDialog, playitem), mplay[playcontinuous]);
- random = playcontinuous == 2;
- GrayItem(myDialog, gray1item);
- repeat_event_item = the_item;
-
- }
-
- AdjustControls(); /* */
- }
-
-
-
- di() {
- short myerr;
- SndCommand mysnd;
-
- codetimeunits += 2;
-
- mysnd.cmd = ampCmd;
- mysnd.param1 = AMP;
- mysnd.param2 = 0;
- myerr = SndDoCommand(soundptr, &mysnd, false);
-
- mysnd.cmd = freqDurationCmd;
- mysnd.param1 = duration; /* Duration in half-milliseconds. */
- mysnd.param2 = frequency; /* Frequency */
- myerr = SndDoCommand(soundptr, &mysnd, false);
-
- mysnd.cmd = restCmd;
- mysnd.param1 = duration; /* Duration in half-milliseconds. */
- mysnd.param2 = 0;
- myerr = SndDoCommand(soundptr, &mysnd, false);
- }
-
-
-
- dah() {
- short myerr;
- SndCommand mysnd;
-
- codetimeunits += 4;
-
- mysnd.cmd = ampCmd;
- mysnd.param1 = AMP;
- mysnd.param2 = 0;
- myerr = SndDoCommand(soundptr, &mysnd, false);
-
- mysnd.cmd = freqDurationCmd;
- mysnd.param1 = 3 * duration; /* Duration in half-milliseconds. */
- mysnd.param2 = frequency; /* Frequency */
- myerr = SndDoCommand(soundptr, &mysnd, false);
-
- mysnd.cmd = restCmd;
- mysnd.param1 = duration; /* Duration in half-milliseconds. */
- mysnd.param2 = 0;
- myerr = SndDoCommand(soundptr, &mysnd, false);
- }
-
-
-
- dit() {
- short myerr;
- SndCommand mysnd;
-
- codetimeunits += 4;
-
- mysnd.cmd = ampCmd;
- mysnd.param1 = AMP;
- mysnd.param2 = 0;
- myerr = SndDoCommand(soundptr, &mysnd, false);
-
- mysnd.cmd = freqDurationCmd;
- mysnd.param1 = duration; /* Duration in half-milliseconds. */
- mysnd.param2 = frequency; /* Frequency */
- myerr = SndDoCommand(soundptr, &mysnd, false);
-
- mysnd.cmd = restCmd;
- mysnd.param1 = 3 * duration; /* Duration in half-milliseconds. */
- mysnd.param2 = 0;
- myerr = SndDoCommand(soundptr, &mysnd, false);
-
- mysnd.cmd = callBackCmd;
- mysnd.param1 = SOUND_COMPLETE;
- mysnd.param2 = SetCurrentA5();
- myerr = SndDoCommand(soundptr, &mysnd, false);
- }
-
-
-
- daht() {
- short myerr;
- SndCommand mysnd;
-
- codetimeunits += 6;
-
- mysnd.cmd = ampCmd;
- mysnd.param1 = AMP;
- mysnd.param2 = 0;
- myerr = SndDoCommand(soundptr, &mysnd, false);
-
- mysnd.cmd = freqDurationCmd;
- mysnd.param1 = 3 * duration; /* Duration in half-milliseconds. */
- mysnd.param2 = frequency; /* Frequency */
- myerr = SndDoCommand(soundptr, &mysnd, false);
-
- mysnd.cmd = restCmd;
- mysnd.param1 = 3 * duration; /* Duration in half-milliseconds. */
- mysnd.param2 = 0;
- myerr = SndDoCommand(soundptr, &mysnd, false);
-
- mysnd.cmd = callBackCmd;
- mysnd.param1 = SOUND_COMPLETE;
- mysnd.param2 = SetCurrentA5();
- myerr = SndDoCommand(soundptr, &mysnd, false);
- }
-
-
-
- space() {
- short myerr;
- SndCommand mysnd;
-
- codetimeunits += 4;
-
- mysnd.cmd = restCmd;
- mysnd.param1 = 4 * duration; /* Duration in half-milliseconds. */
- mysnd.param2 = 0;
- myerr = SndDoCommand(soundptr, &mysnd, false);
-
- mysnd.cmd = callBackCmd;
- mysnd.param1 = SOUND_COMPLETE;
- mysnd.param2 = SetCurrentA5();
- myerr = SndDoCommand(soundptr, &mysnd, false);
- }
-
-
-
- /* Check to see if a character is a displayable character. */
-
- short iswhite(char c) {
- if ((c <= ' ') || (c > 126))
- return 1;
- else
- return 0;
- }
-
-
-
-
- /* This is the routine that translates a character into it's */
- /* corresponding DIs and DAHs, from Keith J. McQueen's */
- /* Morse Code program */
-
- void send(char c) { /* Input: the letter to be sent */
- char verify_c;
- Str255 code_text;
-
- /* Translate the character to uppercase and translate any tabs, */
- /* returns, linefeeds etc. to spaces */
-
- c = toupper(c);
- if (iswhite(c))
- c = ' ';
-
- if (!volume)
- return;
-
- if ((c < ' ') || (c > 'Z') || (c == '<') || (c == '>') || (c == '>') ||
- (c == '*') || (c == '&') || (c == '%') || (c == '#') || (c == '!') ||
- (c == '@')) {
- SysBeep(4); /* If not Morse Code */
- return;
- }
-
- if (ready) {
- ShowCode(c);
- ready = false;
- } else {
- queue[queuex++] = c;
- if (queuex >= QUEUE_SIZE)
- queuex = 0; /* Wrap around at end of queue */
- }
-
- last_code = c;
-
- if (speedfor1character || /* First time through, or */
- codetimecharactercount > 4) { /* after 5 characters... */
- speedfor1character = false;
- codetimebegin = TickCount();
- codetimeend = -1;
- codetimecharactercount = 0;
- codetimeunits = 0;
- }
-
-
- switch(c) {
- case 'A': di(); daht(); break;
- case 'B': dah(); di(); di(); dit(); break;
- case 'C': dah(); di(); dah(); dit(); break;
- case 'D': dah(); di(); dit(); break;
- case 'E': dit(); break;
- case 'F': di(); di(); dah(); dit(); break;
- case 'G': dah(); dah(); dit(); break;
- case 'H': di(); di(); di(); dit(); break;
- case 'I': di(); dit(); break;
- case 'J': di(); dah(); dah(); daht(); break;
-
- case 'K': dah(); di(); daht(); break;
- case 'L': di(); dah(); di(); dit(); break;
- case 'M': dah(); daht(); break;
- case 'N': dah(); dit(); break;
- case 'O': dah(); dah(); daht(); break;
- case 'P': di(); dah(); dah(); dit(); break;
- case 'Q': dah(); dah(); di(); daht(); break;
- case 'R': di(); dah(); dit(); break;
- case 'S': di(); di(); dit(); break;
- case 'T': daht(); break;
-
- case 'U': di(); di(); daht(); break;
- case 'V': di(); di(); di(); daht(); break;
- case 'W': di(); dah(); daht(); break;
- case 'X': dah(); di(); di(); daht(); break;
- case 'Y': dah(); di(); dah(); daht(); break;
- case 'Z': dah(); dah(); di(); dit(); break;
- case '0': dah(); dah(); dah(); dah(); daht(); break;
- case '1': di(); dah(); dah(); dah(); daht(); break;
- case '2': di(); di(); dah(); dah(); daht(); break;
- case '3': di(); di(); di(); dah(); daht(); break;
-
- case '4': di(); di(); di(); di(); daht(); break;
- case '5': di(); di(); di(); di(); dit(); break;
- case '6': dah(); di(); di(); di(); dit(); break;
- case '7': dah(); dah(); di(); di(); dit(); break;
- case '8': dah(); dah(); dah(); di(); dit(); break;
- case '9': dah(); dah(); dah(); dah(); dit(); break;
- case '"': di(); dah(); di(); di(); dah(); dit(); break;
- case '$': di(); di(); di(); dah(); di(); di(); daht(); break;
- case '\'': di(); dah(); dah(); dah(); dah(); dit(); break;
- case '(': dah(); di(); dah(); dah(); dit(); break;
-
- case ')': dah(); di(); dah(); dah(); di(); daht(); break;
- case '+': di(); dah(); di(); dah(); dit(); break;
- case ',': dah(); dah(); di(); di(); dah(); daht(); break;
- case '-': dah(); di(); di(); di(); di(); daht(); break;
- case '.': di(); dah(); di(); dah(); di(); daht(); break;
- case '/': dah(); di(); di(); dah(); dit(); break;
- case ':': dah(); dah(); dah(); di(); di(); dit(); break;
- case ';': dah(); di(); dah(); di(); dah(); dit(); break;
- case '=': dah(); di(); di(); di(); daht(); break;
- case '?': di(); di(); dah(); dah(); di(); dit(); break;
-
- case ' ': space(); break;
-
- default: break;
- }
- }
-
-
-
- pascal void CallBack(SndChannelPtr soundptr, SndCommand soundcmd) {
- long myA5;
- SndCommand mysnd;
-
- if (soundcmd.param1 == SOUND_COMPLETE) {
- myA5 = SetA5(soundcmd.param2);
- codetimeend = TickCount();
- codetimecharactercount++;
-
- if (chasex != queuex) {
- display_code = queue[chasex++];
- if (chasex >= QUEUE_SIZE)
- chasex = 0;
- }
-
- if (chasex == queuex)
- ready = true;
-
- myA5 = SetA5(myA5);
- }
- }
-
-
-
- #if 1
- short initsound(SndChannelPtr *soundptr) {
- short i1,myerr;
- SndCommand mysnd;
-
- *soundptr = NULL;
- myerr = SndNewChannel(soundptr,squareWaveSynth,initMono,&CallBack);
- if (!myerr) {
- mysnd.cmd = timbreCmd; /* freqCmd or timbreCmd? */
- mysnd.param1 = 0; /*timbre = 0 produces sine wave....127 produces a square wave*/
- mysnd.param2 = 0; /*ignored on input & output*/
- myerr = SndDoImmediate(*soundptr, &mysnd);
-
- mysnd.cmd = ampCmd;
- mysnd.param1 = AMP;
- mysnd.param2 = 0;
- myerr = SndDoImmediate(*soundptr, &mysnd);
- }
- return (myerr);
- }
-
-
- #else
- short initsound(SndChannelPtr *soundptr) {
- short i1,myerr;
- SndCommand mysnd;
- unsigned char mytable1[512];
-
- for (i1 = 0; i1 < 512; i1++)
- mytable1[i1] = (i1 >> 1) | 3;
-
- *soundptr = NULL;
- myerr = SndNewChannel(soundptr,waveTableSynth,initMono,(SndCallBackProcPtr) &CallBack);
-
- if (!myerr) {
- mysnd.cmd = waveTableCmd;
- mysnd.param1 = 512;
- mysnd.param2 = (long) &mytable1;
- myerr = SndDoCommand(*soundptr, &mysnd, false);
- }
- return (myerr);
- }
- #endif
-
-
-
- FileCode() {
- unsigned char mychar;
- long gcount;
- SFReply reply;
- Point pt;
- SFTypeList myTypes;
- short status;
- short howManyInTypeList=0; /* Try any file type */
-
- myTypes[0]='TEXT'; /* 'TYPE' of file to be played, not used */
-
- if (gp == 0) {
- SetPt(&pt, 148, 80);
- SFGetFile(pt, "\p", NULL, howManyInTypeList, myTypes, NULL, &reply);
- if (reply.good) {
- status = FSOpen(reply.fName,reply.vRefNum,&gp);
- if (status != noErr) {
- gp = 0;
- playfile = false;
- SetCTitle(GetDIHandle( myDialog, open_button), mfile[OPEN_STRING]);
- } else {
- playfile = true;
- SetCTitle(GetDIHandle( myDialog, open_button), mfile[CLOSE_STRING]);
- if (random) {
- playcontinuous = 1;
- random = false;
- ShowOptions();
- } } }
- } else if (ready) {
- gcount = 1;
- status = FSRead(gp,&gcount,&mychar);
- if (!status)
- send(mychar);
- else if (status == eofErr) {
- if (playcontinuous)
- SetFPos(gp,fsFromStart,0);
- else {
- FSClose(gp);
- gp = 0;
- playfile = false;
- SetCTitle(GetDIHandle( myDialog, open_button), mfile[OPEN_STRING]);
- }
- }
- }
- }
-
-
-
- RandomCode() {
- short r;
- switch (whichcode) {
- case 0:
- default:
- r = (Random() & 0x7fff) % 51; /* Choose any random code. */
- break;
- case 1:
- r = (Random() & 0x7fff) % 26; /* Choose letters random code. */
- break;
- case 2:
- r = 26 + ((Random() & 0x7fff) % 10); /* Choose numbers random code. */
- break;
- case 3:
- r = 36 + ((Random() & 0x7fff) % 15); /* Choose symbols random code. */
- break;
- case 4:
- r = (Random() & 0x7fff) % 36; /* Choose letters & numbers random code. */
- }
- send(randomtable[r]);
- }
-
-
-
- void FileMenu(short theitem) {
- switch (theitem) {
- case mFile_Open:
- if (playfile) {
- playfile = false;
- FSClose(gp);
- gp = 0;
- SetCTitle(GetDIHandle( myDialog, open_button), mfile[OPEN_STRING]);
- } else {
- FileCode();
- }
- break;
- case mSave_Settings:
- saveSettings();
- break;
- case mFile_Quit:
- done = true;
- break;
- default:
- break;
- }
- }
-
-
-
- /* Create menu bar and menus.
- * Inputs are:
- * menu bar resource id (barid)
- * resource id of first menu item (other menu id's must follow sequentially)
- */
- void Setupmenus(short barid, short baseid) {
- short i;
-
- for (i=0; i < MAX_Menus; i++) {
- mymenus[i] = GetMenu(baseid + i);
- InsertMenu( mymenus[i], 0);
- }
-
- DrawMenuBar();
-
- AddResMenu(mymenus[0], 'DRVR');
- }
-
-
-
- void docommand(short themenu, short theitem) {
- Str255 name;
- short refnum;
-
- switch (themenu) {
- case AppleN:
- if (theitem == 1)
- DoCopyright();
- else if (theitem > 2) {
- GetItem( mymenus[0], theitem, name);
- refnum = OpenDeskAcc(name);
- }
- break;
-
- case editMenuN:
- /*DoEditMenu(theitem);*/ break;
-
- case fileMenuN:
- FileMenu(theitem); break;
- }
- HiliteMenu(0); /* unHiliteMenu */
- }
-
-
-
- main() { /* ChkForAbort is called from time consuming abcontrol() */
- EventRecord myevent;
- Boolean event_repeated;
- short count;
- short i1;
- short message;
- short temp;
- short theItem;
- short theMenu;
- short Windowcode;
- long next_event_time;
- long theCommand;
- CursHandle handcursor;
- Point mypoint;
- THE_TYPE_H_RECT
- DialogPtr whichDialog;
- WindowPtr whichWindow;
- Str255 code_text;
-
- InitGraf( (Ptr) &qd.thePort);
- InitFonts();
- InitWindows();
- TEInit();
- InitDialogs( (ProcPtr) NULL); /* restart proc */
- InitCursor();
- InitMenus();
-
- MaxApplZone();
-
- for (i1 = 0; i1 < 32; i1++) MoreMasters();
-
- qd.randSeed = TickCount() & 0xffff; /* Initialize the random number sequence */
-
- getSettings();
- GetStrings(mcode, CODE_STR_ID, CODE_MODES);
- GetStrings(mwait, WAIT_STR_ID, WAIT_MODES);
- GetStrings(mplay, PLAY_STR_ID, PLAY_MODES);
- GetStrings(mpause, PAUSE_STR_ID, PAUSE_MODES);
- GetStrings(mfile, FILE_STR_ID, FILE_MODES);
-
- handcursor = (CursHandle) GetResource( crstyp,HAND_CURSOR_ID);
-
- Setupmenus(MENUBAR_ID,BASE_MenuID);
-
- FlushEvents( everyEvent, 0);
-
- sharedTimeTicks = 15;
- if (GetTrapAddress(0x60) != GetTrapAddress(0x9f) )
- has_multifinder = true;
- else
- has_multifinder = false;
-
- done = initsound(&soundptr);
- SetSoundVol(volume);
-
- paused = false;
- playfile = false;
- ready = true;
- key_correct = true;
-
- gp = 0;
- chasex = 0;
- queuex = 0;
- next_event_time = 0;
- repeat_event_item = 0;
- codetimebegin = 0;
- codetimeend = -1;
- speedfor1character = true;
-
- GetWMgrPort (&screenPort);
- dragRect = screenPort->portRect;
-
- CountAppFiles(&message,&count); /* message = 0 open, message = 1 print */
- if (count > 0) {
- OpenAppFile(count);
- if (gp) {
- ClrAppFiles(count--);
- random = false;
- playfile = true;
- } }
-
- myDialog = GetNewDialog(CODE_DIALOG,(DialogPeek) 0L, (WindowPtr)-1L);
-
- MoveWindow(myDialog,dialogPoint.h,dialogPoint.v,false);
-
- GetDItem(myDialog, gray1item, &theType, &theHandle, &theRect);
- theHandle = (Handle) &PGrayItem;
- SetDItem(myDialog, gray1item, theType, theHandle, &theRect);
-
- /* Save the rectangle of the code text for faster drawing */
- GetDItem(myDialog, code_character, &theType, &theHandle, &pattern_rect);
-
- if (gp)
- SetCTitle(GetDIHandle( myDialog, open_button), mfile[CLOSE_STRING]);
-
- DrawDialog(myDialog);
-
- ShowOptions();
-
- do {
-
- if (display_code) {
- ShowCode(display_code);
- display_code = 0;
- }
-
- ShowSpeed();
-
- if (!paused) {
- if (random || playfile) {
- if (ready) {
-
- if (!waitforkey || key_correct || (last_code == ' ')) {
- if (random)
- RandomCode();
- else if (playfile)
- FileCode();
-
- key_correct = false;
-
- } else
- send(last_code);
- }
- } else
- speedfor1character = true;
- } else
- speedfor1character = true;
-
- temp = WaitNextEvent(everyEvent, &myevent, sharedTimeTicks, NULL);
-
- if (((myevent.modifiers & optionKey) != 0) &&
- ((myevent.modifiers & shiftKey) == 0)) {
- SetCursor(*handcursor);
- } else {
- InitCursor();
-
- if (IsDialogEvent(&myevent)) {
- event_repeated = false;
- if (StillDown() &&
- repeat_event_item &&
- (TickCount() > (next_event_time))) {
- GetDItem(myDialog, repeat_event_item, &theType, &theHandle, &theRect);
- mypoint = myevent.where;
- GlobalToLocal(&mypoint);
- if (PtInRect(mypoint,&theRect)) {
- SetOptions(repeat_event_item);
- next_event_time = TickCount() + REPEAT_AGAIN_DELAY_TICKS;
- event_repeated = true;
- } }
-
- if (!event_repeated &&
- DialogSelect(&myevent,&whichDialog,&theItem)) {
- if (myDialog == whichDialog) {
- SetOptions(theItem);
- next_event_time = TickCount() + REPEAT_EVENT_DELAY_TICKS;
- } } } }
-
- switch (myevent.what) {
- char c;
-
- case mouseDown:
- Windowcode = FindWindow( myevent.where, &whichWindow);
-
- switch (Windowcode) {
- case inContent:
- if (((myevent.modifiers & optionKey) != 0) &&
- ((myevent.modifiers & shiftKey) == 0) ) {
- DragWindow( whichWindow, myevent.where, &dragRect);
- InitCursor();
- }
- break;
- case inMenuBar:
- { long theCommand = MenuSelect(myevent.where);
- short theMenu = HiWord( theCommand);
- short theItem = LoWord( theCommand);
- docommand(theMenu, theItem); break;
- }
- break;
- default:
- break;
- }
- break;
-
- case keyDown:
- case autoKey:
- c = (char) (255 & myevent.message);
-
- if (myevent.modifiers & cmdKey) { /* Try menu equivalent */
- theCommand = MenuKey (c);
- theMenu = HiWord(theCommand);
- theItem = LoWord(theCommand);
-
- if (HiWord(theCommand)) {
- docommand(theMenu, theItem);
- break;
- }
- } else if ((random || playfile) && waitforkey) {
- if (toupper(c) == last_code)
- key_correct = true;
- } else if ((!random && !playfile) || paused) {
- send(c);
- }
- break;
- default:
- break;
- }
- } while (!done);
- DisposDialog( myDialog);
- }
-