home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Gold Fish 1
/
GoldFishApril1994_CD2.img
/
d4xx
/
d477
/
irmaster
/
irc.c
< prev
next >
Wrap
C/C++ Source or Header
|
1991-04-17
|
27KB
|
1,055 lines
/*------------------------------- i r c . c -------------------------------*/
/* Experimental interrupt handler. */
/* This routine sets up a level 2 interrupt server that is triggered by the */
/* ACK pin of the parallel port going low. The interrupt server then uses */
/* Timer B in CIA-B to time reading in data from the parallel port. */
/* The ACK and one data input pin on the parallel port are tied */
/* together by the hardware I built. Initially the ACK interrupt is */
/* enabled and the software sits and waits for something to happen. */
/* */
/* NEED TO CHECK RESOURCES ---- FREEMEM!!!!!!!!!!!!!!!!*/
/*--------------------------------------------------------------------------*/
/*--- Includes and Defines. */
#include "irc.h"
#include "IRMaster.h" /* Definitions of Screen, Window and gadgets. */
/* DBG = 1 --> Turn on debug printf's, DBG = 0 --> Turn off debug printf's. */
#define DBG 1
/* Set DEBUG to 0 to comment out code related to opening screen and window.*/
#define DEBUG 1
#define NOERROR 0
#define ERROR 1
/*--- NSAMPLES is the number of data samples to be read into buffer. */
#define NSAMPLES 3000
/*--- TOLERENCE is the number of samples difference that is tolerated in */
/*--- order to match two patterns. */
#define TOLERENCE 50
/*--- External system variables. */
extern struct Custom custom;
extern struct CIA ciab;
extern struct GfxBase *GfxBase;
extern struct IntuitionBase *IntuitionBase;
extern struct WBStartup *WBenchMsg; /* For Workbench startup. */
/**********************************************************/
/***************** Timer B Interrupt code *****************/
/**********************************************************/
/*
Update Timer every TIME_SLICE microseconds.
TIME_SLICE = 1.397 * (desired # of microseconds) [71 = 100us]
71, 50 work.
*/
#define TIME_SLICE ((unsigned short)35)
/* Defines to make the code more readable. */
#define ciatlo ciab.ciatblo
#define ciathi ciab.ciatbhi
#define ciacr ciab.ciacrb
#define ciaicr ciab.ciaicr
int TimerSigBit = -1; /* Allocated signal bit. */
ULONG TimerSigMask; /* TimerSigBit converted into a mask. */
static struct Library *CIAResource = NULL;
struct Task *thisTask;
int NSamples; /* Number of samples in buffer. */
int SetUpTimer()
{
char temp;
unsigned short micros;
/*--- Check to see if timer B in CIA-B is already in use. */
/*--- If START bit is set timer is probably being used. */
#if DBG
printf("\n Timer B control register = %X",ciab.ciacrb);
#endif
if(ciab.ciacrb & 0x01)
{
printf("\n Timer B is already allocated. Proceding anyway.");
}
/*--- Set latched value for timer to count down from. */
micros = TIME_SLICE;
#if DBG
printf("\n Sampling interval = %d * 1.397 microseconds", micros);
#endif
ciatlo = micros & 0xFF;
ciathi = micros >> 8;
/*--- Get ID for this task so can send it a signal. */
thisTask = NULL;
thisTask = FindTask(NULL);
if(thisTask == NULL)
{
printf("\n Error - Can't find this task ID.");
return(ERROR);
}
/*--- Get a signal bit. */
if((TimerSigBit = AllocSignal(-1L)) == -1)
{
printf("\n Timer: AllocSignal failed.");
StopTime(); /* Deallocate resources. */
return(ERROR);
}
TimerSigMask = 1L << TimerSigBit;
/*--- Open the CIA resource. */
if((CIAResource = OpenResource(CIABNAME)) == NULL)
{
printf("\n Timer: Couldn't open %s.", CIABNAME);
StopTime(); /* Deallocate resources. */
return(ERROR);
}
/*--- Interrupts have been enabled so may already */
/*--- have an interrupt. So do this... */
ciab.ciacrb &= ~CIACRBF_START; /* stop timer */
temp = ciaicr; /* Read IRC register to clear interrupt. */
SetSignal(0, TimerSigMask); /* clear signal */
#if DBG
printf("\n About to set RUNMODE");
#endif
ciacr &= ~CIACRBF_RUNMODE; /* Set it to reload upon underflow. */
ciacr &= ~CIACRBF_PBON; /* Output line PB7 is left alone. */
ciacr &= ~CIACRBF_INMODE0; /* Count clock pulses. */
ciacr &= ~CIACRBF_INMODE1; /* Count clock pulses. */
#if DBG
printf("\n About to strobe LOAD");
#endif
ciacr |= CIACRBF_LOAD; /* Strobe Load to latch in countdown value. */
#if DBG
printf("\n About to enable timer b interrupts");
#endif
ciaicr = 0x7D; /* Disable all other CIA-B interrupts. */
ciaicr = CIAICRF_SETCLR|CIAICRF_TB; /* Enable timer B interrupts. */
#if DBG
printf("\n Enabled timer b interrupts");
#endif
return(NOERROR);
}
int StopTime()
{
if(thisTask != NULL)
{
/*--- Disable timer B interrupts. */
#if DBG
printf("\n Stopping timer B.");
#endif
ciaicr = CIAICRF_TB;
/*--- Halt timer. */
ciacr &= ~CIACRBF_START;
/*--- Free resources. */
if(TimerSigBit != -1)
{
#if DBG
printf("\n Freeing signal bit.");
#endif
FreeSignal(TimerSigBit);
}
}
return(NOERROR);
}
/**********************************************************/
/***************** LEVEL 2 Interrupt code *****************/
/**********************************************************/
extern void ircserver();
struct Interrupt intrpt;
int AddINT2Server()
{
/*--- init NODE structure */
intrpt.is_Node.ln_Type = NT_INTERRUPT;
/* Was 0 but glasses flickered. 3 fixed it. */
intrpt.is_Node.ln_Pri = 127;
intrpt.is_Node.ln_Name = "WWB";
intrpt.is_Code = ircserver;
intrpt.is_Data = NULL;
#if DBG
printf("\n About to add interrupt server...");
#endif
AddIntServer(INTB_PORTS, &intrpt); /* Add server to chain */
#if DBG
printf("\n Added interrupt server.");
#endif
return(NOERROR);
}
int RemoveServer()
{
RemIntServer(INTB_PORTS, &intrpt);
return(NOERROR);
}
/**********************************************************/
/************************** MAIN **************************/
/**********************************************************/
unsigned char *buffer; /* Pointer to storage for data to be read in. */
unsigned char zuffer[NSAMPLES]; /* Storage for data to be read in. */
unsigned char pattern[20][NSAMPLES]; /* Stored signal patterns. */
char *address, mask;
struct Screen *Screen = NULL;
struct Window *Window = NULL;
struct RastPort *WRPort;
struct ViewPort *WVPort;
struct IntuiMessage *message;
ULONG class;
USHORT code;
struct Gadget *igad;
USHORT gadget_id;
extern int BackGround();
int helptxt();
int IRButtonOff(); /* Unhighlight button. */
int IRButtonOn(); /* Highlight button. */
int IRButtonLabel(); /* Relabel button. */
int GetPattern(); /* Get signal pattern. */
int DisplayPattern(); /* Draw the signal pattern. */
int DPattern(); /* Debug. */
/*--- Buffers for area fill and text. */
WORD chip areaArray[100]; /* Max of 20 vertices times 5 words per vertex. */
struct AreaInfo myAreaInfo;
PLANEPTR workspace;
struct TmpRas myTmpRas;
#define NOTHING 0
int active[21] = /* Used to remember which buttons have patterns. */
{
FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE,
FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE,
FALSE
};
main(argc, argv)
int argc;
char **argv;
{
int it, error, iz, is, try;
int diff[4], match, smallest;
BOOL exitflag;
int mode; /* Current mode of program (LEARN, NOTHING, etc. ) */
int IRButtonSelected = -1; /* Index of button currently selected. */
/*--- Ignore CTRL-C and CTRL-D. */
signal(SIGINT, SIG_IGN);
/*--- Open graphics and Intuition Libraries. */
GfxBase = NULL;
GfxBase = (struct GfxBase *)OpenLibrary("graphics.library", 33);
if(GfxBase == NULL)
{
printf("\n Error opening graphics library.");
goto ShutDown;
}
IntuitionBase = NULL;
IntuitionBase = (struct IntuitionBase *)OpenLibrary("intuition.library", 33);
if(IntuitionBase == NULL)
{
printf("\n Error opening Intuition library.");
goto ShutDown;
}
/*--- Open a new screen. */
Screen = (struct Screen *) OpenScreen(&NewScreenStructure);
if(Screen == 0L)
{
printf("\n Error opening a new screen.");
goto ShutDown;
}
#if DEBUG
/*--- Open window in screen. */
NewWindowStructure1.Screen = Screen;
Window = (struct Window *) OpenWindow(&NewWindowStructure1);
if(Window == 0L)
{
printf("\nError opening a new window");
goto ShutDown;
}
/*--- Get pointers to window structures. */
WRPort = Window->RPort; /* Get pointer to windows' RastPort. */
WVPort = (struct ViewPort *)ViewPortAddress(Window); /* Get pointer to window viewport. */
/*--- Set up area fill and text work buffers. */
InitArea(&myAreaInfo, &areaArray[0], 20);
WRPort->AreaInfo = &myAreaInfo;
workspace = AllocRaster(640, 200);
if(workspace == 0)
{
printf("\n Error - No space for temporary raster.");
goto ShutDown;
} else
{
InitTmpRas(&myTmpRas, workspace, RASSIZE(640,200));
WRPort->TmpRas = &myTmpRas;
}
/*--- Set color map. */
LoadRGB4(WVPort, Palette, (SHORT)16);
/*--- Draw raised background areas. */
BackGround();
/*--- Redraw the gadgets on top of the raised background. */
RefreshGadgets(&ARexx, Window, 0);
#endif /*DEBUG*/
/*--- Allocate the parallel port resource so that other tasks know it */
/*--- is taken. (This might not be a good idea. Online! allocates the */
/*--- the parallel port and this prevents me from doing */
/*--- "copy file to par:" in a seperate window. So leave it out for */
/*--- now. User will know if one program walks over another. */
/*****************
MR_ALLOCMISCRESOURCE(MR_PARALLELPORT, "IRMaster");
MR_ALLOCMISCRESOURCE(MR_PARALLELBITS, "IRMaster");
*****************/
/*--- Set up pointer to data buffer for SoftHandler(). */
/*--- Assembler doesn't seem to recognize zuffer but DOES buffer. */
buffer = &zuffer[0];
#if DBG
printf("\n buffer = %X", buffer);
#endif
/*--- Set up all the interrupt servers. */
AddINT2Server();
error = SetUpTimer();
if(error)goto Fini;
/*--- Explicitly enable level6 and level2 interrupts (even though */
/*--- they already seem to be enabled by default). */
/********* Causes sometimes guru.
Disable();
custom.intena |= INTF_SETCLR | INTF_EXTER;
custom.intena |= INTF_SETCLR | INTF_SOFTINT;
Enable();
*********/
#if DBG
/* This is slightly dangerous since it might clear any pending interrupts. */
/*printf("\n Enabled interrupts are: %X", custom.intenar);*/
#endif
/*--- Set address for IRC register (used in GetSample.) */
address = (char *)0xBFED01;/* Address of the Interrupt Control Register in 8520-A */
/*--- MAIN PROGRAM LOOP. */
/*--- Get messages from window until user presses CloseWindow gadget. */
#if DEBUG
exitflag = FALSE;
mode = NOTHING;
while(exitflag == FALSE)
{
/*--- If in DOIT mode wait for IR input. */
if(mode == DOIT)
{
/*--- Wait for user to press a button. */
GetSample();
/*--- Match input to stored samples. */
match = find_match();
}
/*--- Check for user action. */
message = (struct IntuiMessage *)GetMsg(Window->UserPort);
if(message != 0)
{
class = message->Class;
code = message->Code;
igad = (struct Gadget *)message->IAddress;/*get pointer to gadget */
ReplyMsg((struct Message *)message);
if(class == GADGETUP)
{
gadget_id = igad->GadgetID; /* get my gadget code */
switch(gadget_id)
{
case COMMANDSTR3:
#if DBG
printf("COMMANDSTR3\n");
#endif
break;
case COMMANDSTR1:
#if DBG
printf("COMMANDSTR1 = %s\n", commandstr1SIBuff);
#endif
/*--- Change the label on the button. */
IRButtonLabel(commandstr1SIBuff, IRButtonSelected);
/*--- Prompt user for next action. */
helptxt("Now press the button on your handheld IR remote control",
"that you want memorized.");
/*--- Get verified signal sample from the IR receiver. */
GetPattern(IRButtonSelected);
/*--- Remember which buttons have patterns stored. */
active[IRButtonSelected] = TRUE;
/*--- Unhighlight the control button. */
IRButtonOff(&IRButtonSelected);
mode = NOTHING;
break;
case COMMANDSTR2:
#if DBG
printf("COMMANDSTR2\n");
#endif
break;
default:
break;
} /* switch(gadget_id) */
} /* if(GADGETUP) */
if(class == GADGETDOWN)
{
gadget_id = igad->GadgetID; /* get my gadget code */
switch(gadget_id)
{
case EXIT:
#if DBG
printf("EXIT\n");
#endif
goto Fini;
break;
case AUTHOR:
#if DBG
printf("AUTHOR\n");
#endif
break;
case DOIT:
#if DBG
printf("DOIT\n");
#endif
mode = DOIT;
break;
case GETSET:
#if DBG
printf("GETSET\n");
#endif
break;
case SAVESET:
#if DBG
printf("SAVESET\n");
#endif
break;
case LEARN:
#if DBG
printf("LEARN\n");
#endif
helptxt("Press one of the twenty control buttons above.","");
mode = LEARN;
break;
case AREXX:
#if DBG
printf("AREXX\n");
#endif
break;
case IR20:
case IR19:
case IR18:
case IR17:
case IR16:
case IR15:
case IR14:
case IR13:
case IR12:
case IR11:
case IR10:
case IR9:
case IR8:
case IR7:
case IR6:
case IR5:
case IR4:
case IR3:
case IR2:
case IR1:
/*--- Unhighlight any currently selected button. */
IRButtonOff(&IRButtonSelected);
/*--- Set current button to highlight and highlight it. */
IRButtonSelected = (gadget_id - IR1) + 1;
IRButtonOn(IRButtonSelected);
#if DBG
printf("IR-%d\n", (gadget_id - IR1) + 1);
#endif
if(mode == LEARN)
{
/*--- Prompt user. */
helptxt("Enter the label name for the control button,",
"then press RETURN.");
} else
{
helptxt("Please choose a function button first.", "");
}
break;
default:
mode = NOTHING;
printf("Error - Got a hit on an unknown gadget\n");
printf(" Gadget id was: hex: %X decimal: %d\n", gadget_id,
gadget_id);
break;
} /* switch(gadget_id) */
} /* if(message) */
} /* if(class...) */
} /* while(GetMsg) */
#endif /*DEBUG*/
#if DBG
printf("\n Timer B control register = %X",ciab.ciacrb);
printf("\n buffer = %X", buffer);
#endif
/*--- Shut down timer B */
Fini:
StopTime();
/*--- Turn off the 8520's recognition of the ACK as an interrupt. */
mask = 0x10; /* Hex 10 = 00010000 Should disable the 8520 FLAG interrupt. */
*address = mask; /* Disable the interrupt. */
/*--- Remove the level2 interrupt server from server chain. */
RemoveServer();
/*--- Exit cleanly. */
ShutDown:
/*--- Deallocate parallel port resource. Commented out for reasons above. */
/*****************
MR_FREEMISCRESOURCE(MR_PARALLELPORT);
MR_FREEMISCRESOURCE(MR_PARALLELBITS);
*****************/
/*--- Close window and screen. */
#if DEBUG
if(Window)CloseWindow(Window);
if(Screen)CloseScreen(Screen);
#endif /*DEBUG*/
/*--- Close libraries. */
if(GfxBase)CloseLibrary((struct Library *)GfxBase);
if(IntuitionBase)CloseLibrary((struct Library *)IntuitionBase);
/*--- Free allocated memory. */
#if DEBUG
if(workspace != 0)FreeRaster(workspace, 640, 200);
#endif /*DEBUG*/
return(0); /* To keep compiler happy. */
} /* End of main(). */
int GetSample()
{
int idx;
/*--- Set up for taking another sample. */
#if DBG
printf("\n Setting up for next sample.");
#endif
for(idx=0; idx<NSAMPLES; idx++)zuffer[idx] = 0; /* Zero the buffer. */
NSamples = NSAMPLES; /* Reset sample counter. */
buffer = &zuffer[0]; /* Reset pointer to start of buffer. */
ciacr |= CIACRBF_LOAD; /* Strobe Load to latch in countdown value. */
ciaicr = CIAICRF_SETCLR|CIAICRF_TB; /* Enable timer B interrupts. */
mask = *address; /* Clear any pending interrupts. */
mask = 0x90; /* Hex 90 = 10010000 Should enable the 8520 FLAG interrupt. */
*address = mask; /* Enable the ACK interrupt. */
/*--- Interrupts are now all armed and dangerous. */
/*--- Wait until data is ready. */
#if DBG
printf("\n Waiting...press a button.");
#endif
Wait(TimerSigMask); /* Wait for full buffer. */
/*--- Stop timer B from counting. */
#if DBG
printf("\n Stopping timer B");
#endif
ciacr &= ~CIACRBF_START;
/*--- Wait until user lets go of button. */
LetGo();
return(0);
}
#if DEBUG
/*-------------------- h e l p t x t . c ------------------------*/
/* This routine clears the help message area and writes a new */
/* message into it. */
/*---------------------------------------------------------------*/
int helptxt(msg1, msg2)
char *msg1, *msg2;
{
/*--- Erase any old text that exists. */
SetAPen(WRPort, 0);
RectFill(WRPort, 24, 163, 617, 188);
/*--- Write new text. */
SetAPen(WRPort, 1);
Move(WRPort, 25, 173);
Text(WRPort, msg1, strlen(msg1));
Move(WRPort, 25, 185);
Text(WRPort, msg2, strlen(msg2));
return(0);
}
/*---------------------- I R B u t t o n s O f f . c ---------------------*/
/* This routine unhighlights any currently selected control button. */
/*------------------------------------------------------------------------*/
int IRButtonOff(button)
int *button; /* Button to turn off. */
{
USHORT position;
if((*button >= 1) && (*button <= 20))
{
/*--- Remove currently selected gadget from list. */
position = RemoveGList(Window, IR[*button-1], 1L);
/*--- Unselect the gadget. */
IR[*button-1]->Flags &= (~SELECTED);
/*--- Put the gadget back into the same place in the list. */
AddGList(Window, IR[*button-1], (LONG)position, 1L, NULL);
/*--- Refresh gadgets on display. */
RefreshGList(IR[*button-1], Window, NULL, 1L);
/*--- Set currently selected gadget to none. */
*button = -1;
}
return(TRUE);
}
/*---------------------- I R B u t t o n s O n . c -----------------------*/
/* This routine highlights the currently selected control button. */
/*------------------------------------------------------------------------*/
int IRButtonOn(button)
int button; /* Button number to highlight. */
{
USHORT position;
if((button >= 1) && (button <= 20))
{
/*--- Remove the selected gadget from list. */
position = RemoveGList(Window, IR[button-1], 1L);
/*--- Select the gadget. */
IR[button-1]->Flags |= SELECTED;
/*--- Put the gadget back into the same place in the list. */
AddGList(Window, IR[button-1], (LONG)position, 1L, NULL);
/*--- Refresh gadgets on display. */
RefreshGList(IR[button-1], Window, NULL, 1L);
}
return(TRUE);
}
/*------------------- I R B u t t o n L a b e l . c -------------------*/
/* This routine relabels the selected button. */
/*---------------------------------------------------------------------*/
int IRButtonLabel(buffer, button)
UBYTE *buffer;
int button;
{
USHORT position;
if((button >= 1) && (button <= 20))
{
/*--- Remove the selected gadget from list. */
position = RemoveGList(Window, IR[button-1], 1L);
/*--- Change the label. */
strncpy(IR[button-1]->GadgetText->IText , (char *)buffer, 7);
/*--- Put the gadget back into the same place in the list. */
AddGList(Window, IR[button-1], (LONG)position, 1L, NULL);
/*--- Refresh gadgets on display. */
RefreshGList(IR[button-1], Window, NULL, 1L);
}
return(TRUE);
}
/*------------------ G e t P a t t e r n . c ---------------------*/
/* This routine gets a signal sample from the IR receiver and */
/* then tries up to four times to verify it. */
/*----------------------------------------------------------------*/
GetPattern(button)
int button; /* Currently selected control button. */
{
int it, iz, is, try;
int diff[4], match, smallest;
#if DBG
printf("\n\n **** Storing pattern %d ****", button);
#endif
/*--- Get a sample. */
GetSample();
/*--- Plot data on screen. */
helptxt("Data received.", "");
/*DPattern(button, 1);*/
DisplayPattern(button, 0);
#if DBG
printf("\n NSamples=%d", NSamples);
#endif
/*--- Transfer data to storage. */
#if DBG
printf("\n Xferring to pattern memory.");
#endif
for(iz=0; iz<NSAMPLES; iz++)
{
pattern[button-1][iz] = zuffer[iz] & 0x01;
#if DBG
/*
if(pattern[button-1][iz] == 1)printf("|");
if(pattern[button-1][iz] == 0)printf("_");
*/
#endif
}
helptxt("Press the button again to verify the pattern.", "");
match = 0;
for(try=0; try<4; try++) /* Try four times to get a match. */
{
GetSample(); /* Read IR signal again. */
helptxt("Data received. Verifying match.", "");
/* DPattern(button, try+2);*/
DisplayPattern(button, 1);
/*--- Find number of cells that don't match. */
diff[try] = 0;
smallest = NSAMPLES+10;
for(iz=0; iz<NSAMPLES; iz++)
{
zuffer[iz] = zuffer[iz] & 0x01;
if(pattern[button-1][iz] != zuffer[iz])
{
diff[try]++;
}
#if DBG
/*
if(zuffer[iz] == 1)printf("|");
if(zuffer[iz] == 0)printf("_");
*/
#endif
}
if(diff[try] > TOLERENCE)
{
#if DBG
printf("\n Samples do not match:%d Please try again.",diff[try]);
#endif
helptxt("Samples do not match. Please press button again.", "");
if(diff[try] < smallest)
{
/*--- Store the best pattern so far. */
smallest = diff[try];
for(iz=0; iz<NSAMPLES; iz++)
{
pattern[button-1][iz] = zuffer[iz];
}
}
} else
{
match = 1;
break;
}
}
if(match == 0)
{
helptxt("Could not verify pattern. Will use the best match of four tries.", "");
#if DBG
printf("\n Could not verify pattern. Will use the best match.");
printf("\n Try the analyzer to verify compatability of your unit.");
#endif
} else
{
helptxt("Successful pattern match!", "");
DisplayPattern(button, 0);
}
return(TRUE);
}
/*-------------------- D i s p l a y P a t t e r n . c ------------------*/
/* This routine draws the acquired pattern on the screen in the help */
/* message area. */
/*-----------------------------------------------------------------------*/
int DisplayPattern(button, mode)
int button; /* Currently selected control button. */
int mode; /* 0 = draw pattern, 1 = draw difference. */
{
int it;
SHORT row;
/*--- Any old text or pattern that existed should have been erased with */
/*--- a help message. */
/*--- Draw pattern. X range = 24 to 617 */
SetAPen(WRPort, 1);
row = 0;
for(it=0; it<NSAMPLES; it++)
{
if(mode == 0)
{
if((zuffer[it] & 0x01) == 1)
{
Move(WRPort, 26 + (SHORT)(it%590), 175 + row);
Draw(WRPort, 26 + (SHORT)(it%590), 175 + row);
}
} else
{
if((zuffer[it] & 0x01) != pattern[button-1][it])
{
Move(WRPort, 26 + (SHORT)(it%590), 175 + row);
Draw(WRPort, 26 + (SHORT)(it%590), 175 + row);
}
}
/*--- Space the data in rows. */
if((it%590 == 0) &&(it != 0))row = row + 2;
}
#if DBG
printf("\n Drew the pattern.");
#endif
return(TRUE);
}
int DPattern(button, mode)
int button; /* Currently selected control button. */
int mode; /* 0 = draw pattern, 1 = draw difference. */
{
int it;
SHORT row;
/*--- Any old text or pattern that existed should have been erased with */
/*--- a help message. */
/*--- Draw pattern. X range = 24 to 617 */
SetAPen(WRPort, 1);
row = 0;
for(it=0; it<NSAMPLES; it++)
{
if((zuffer[it] & 0x01) == 1)
{
Move(WRPort, 26 + (SHORT)(it%590), 175 + row - mode*20);
Draw(WRPort, 26 + (SHORT)(it%590), 175 + row - mode*20);
}
/*--- Space the data in rows. */
if((it%590 == 0) &&(it != 0))row = row + 2;
}
return(TRUE);
}
#endif /*DEBUG*/
/*-------------------- f i n d _ m a t c h . c ----------------------*/
/* Find pattern which is the closest match to the one just read in. */
/*-------------------------------------------------------------------*/
int find_match()
{
int match, it, smallest;
int diff, pat;
#if DBG
printf("\n Matching patterns...");
#endif
/*--- Mask of bit of interest in zuffer. */
for(it=0; it<NSAMPLES; it++)zuffer[it] = zuffer[it] & 0x01;
/*--- Compare data to stored patterns. */
match = -1;
smallest = NSAMPLES+10;
for(pat=0; pat<20; pat++) /* Step through all stored patterns. */
{
if(active[pat+1]) /* Only examine active patterns to save time. */
{
diff = 0;
for(it=0; it<NSAMPLES; it++)
{
if(pattern[pat][it] != zuffer[it])diff++;
}
}
if(diff < smallest)
{
smallest = diff;
match = pat;
}
#if DBG
printf("\n diff(%d)=%d", pat, diff);
#endif
}
#if DBG
printf("\n Best match is pattern %d", match);
if(match == -1)
{
printf("\n No match for pattern!");
}
#endif
return(match);
}