home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Windows Shareware GOLD
/
NuclearComputingVol3No1.cdr
/
_bbs2
/
f1246.zip
/
TERMTOOL.C
< prev
Wrap
C/C++ Source or Header
|
1990-09-20
|
9KB
|
384 lines
//-------------------------------------------------------------------
//
// Program: Simple state machine simulation
// Filename: TERMTOOL.C
// Description:
//
// This program uses state machine theory to generate
// 'termites'. These termites move within the window
// using their individual state tables.
//
// Author: Hans D. Kellner
// Version: 1.0
// Notes: none
//
//-------------------------------------------------------------------
#include <stdio.h>
#include "windows.h"
#include "termite.h"
/* These are the values to add for each direction index. */
int xMove[4] = {0,0,1,-1};
int yMove[4] = {-1,1,0,0};
// The following tables store the state information read from
// the input file.
int stateTable[MAX_STATES][MAX_STATES],
colorTable[MAX_STATES][MAX_STATES],
motionTable[MAX_STATES][MAX_STATES];
// These tables hold the current termites state values and
// locations on the screen.
int miteX[MAX_MITES],
miteY[MAX_MITES],
direction[MAX_MITES],
state[MAX_MITES];
int noFile = TRUE, // True if no file has been loaded
pauseFlag = FALSE; // True if user has paused termites
int termiteCount; // Current number of termites
DWORD rgbColorTable[MAX_COLORS];
// Local prototypes
int RGB2Color(DWORD);
int moveMite(int *, int *, int *, int, int);
/*-----------------------------------------------------------------*/
/*
/* Name: RGB2Color
/* Description:
/*
/* Convert an RGB value back into an array index.
/*
/*-----------------------------------------------------------------*/
int RGB2Color(rgbColor)
DWORD rgbColor;
{
int color;
for ( color = 0; color < MAX_COLORS; color ++ )
{
if ( rgbColorTable[color] == rgbColor )
return color;
}
return 0;
}
/*-----------------------------------------------------------------*/
/*
/* Name: InitTermiteData
/* Description:
/*
/* Do like the name says... Initialize the termites data.
/*
/*-----------------------------------------------------------------*/
InitTermiteData()
{
int index;
short r,g,b;
noFile = TRUE;
pauseFlag = FALSE;
termiteCount = 1;
/* Initialize the data for each Termite */
for ( index = 0; index < termiteCount; index ++ )
{
state[index] = 0; /* Start in state 0 */
direction[index] = NORTH; /* heading north */
miteX[index] = (int)xClient / 2; /* and in the center of the window */
miteY[index] = (int)yClient / 2;
}
/* Create some default colors for color table */
rgbColorTable[0] = RGB( 0, 0, 128 );
rgbColorTable[1] = RGB( 0, 128, 0 );
rgbColorTable[2] = RGB( 128, 0, 0 );
rgbColorTable[3] = RGB( 0, 128, 128 );
rgbColorTable[4] = RGB( 128, 0, 128 );
rgbColorTable[5] = RGB( 128, 128, 0 );
rgbColorTable[6] = RGB( 128, 128, 128 );
rgbColorTable[7] = RGB( 0, 0, 255 );
rgbColorTable[8] = RGB( 0, 255, 0 );
rgbColorTable[9] = RGB( 255, 0, 0 );
rgbColorTable[10] = RGB( 0, 255, 255 );
rgbColorTable[11] = RGB( 255, 0, 255 );
rgbColorTable[12] = RGB( 255, 255, 0 );
rgbColorTable[13] = RGB( 255, 255, 255 );
return 0;
}
/*-----------------------------------------------------------------*/
/*
/* Name: ClipTermites
/* Description:
/*
/* When the window size has changed this routine is called.
/* It moves through the list of termites and adjusts their
/* position if they no longer are within the window limits.
/*
/*-----------------------------------------------------------------*/
ClipTermites()
{
int index;
for ( index = 0; index < termiteCount; index ++ )
{
if ( miteX[index] >= xClient )
miteX[index] = xClient / 2;
if ( miteY[index] >= yClient )
miteY[index] = yClient / 2;
}
return 0;
}
/*-----------------------------------------------------------------*/
/*
/* Name: LoadTermiteTables
/* Description:
/*
/* Using the filename given, load the termite data into
/* the program.
/*
/*-----------------------------------------------------------------*/
LoadTermiteTables( szFileName )
char *szFileName;
{
int row, col, rowCount, colCount;
FILE *fp;
InitTermiteData();
/* Open the data file, exit if unable to open */
fp = fopen( szFileName, "r" );
if ( fp == NULL ) return( -1 );
if ( fscanf( fp, "%d %d", &rowCount, &colCount ) != 2 )
goto loadError;
if ( ( rowCount < 1 || rowCount > MAX_STATES ) ||
( colCount < 1 || colCount > MAX_STATES ) )
goto loadError;
/* Read the state table */
for ( row = 0; row < rowCount; row ++ )
for ( col = 0; col < colCount; col ++ )
if ( fscanf( fp, "%d", &stateTable[row][col] ) != 1 )
goto loadError;
/* Read the color table */
for ( row = 0; row < rowCount; row ++ )
for ( col = 0; col < colCount; col ++ )
if ( fscanf( fp, "%d", &colorTable[row][col] ) != 1 )
goto loadError;
/* Read the motion table */
for ( row = 0; row < rowCount; row ++ )
for ( col = 0; col < colCount; col ++ )
if ( fscanf( fp, "%d", &motionTable[row][col] ) != 1 )
goto loadError;
fclose( fp );
noFile = FALSE;
return 0;
loadError:
fclose( fp );
return -1;
}
/*-----------------------------------------------------------------*/
/*
/* Name: InsertTermite
/* Description:
/*
/* Add a new termite to the list. Give it default values.
/*
/*-----------------------------------------------------------------*/
InsertTermite()
{
if ( termiteCount < MAX_MITES )
{
state[termiteCount] = 0; /* Start in state 0 */
direction[termiteCount] = NORTH; /* heading north */
miteX[termiteCount] = xClient / 2; /* and in the center */
miteY[termiteCount] = yClient / 2; /* of the window */
termiteCount ++;
}
return( termiteCount );
}
/*-----------------------------------------------------------------*/
/*
/* Name: DeleteTermite
/* Description:
/*
/* Just need to decrement the number of termites. This
/* will cause the last termite in the list to be lost.
/*
/*-----------------------------------------------------------------*/
DeleteTermite()
{
if ( termiteCount > 1 )
termiteCount --;
return termiteCount;
}
/*-----------------------------------------------------------------*/
/*
/* Name: moveMite
/* Description:
/*
/* Moves the Termite depending on the direction stored in
/* the motion table.
/*
/*-----------------------------------------------------------------*/
moveMite(x, y, direction, state, color)
int *x, *y, *direction, state, color;
{
/* Determine if the Termite is turning left or right. */
switch ( motionTable[state][color] )
{
case LEFT: /* Adjust 90' depending on current direction */
switch ( *direction )
{
case NORTH:
*direction = WEST; break;
case WEST:
*direction = SOUTH; break;
case SOUTH:
*direction = EAST; break;
default:
case EAST:
*direction = NORTH; break;
}
break;
case RIGHT: /* Adjust -90' depending on current direction */
switch ( *direction )
{
case NORTH:
*direction = EAST; break;
case SOUTH:
*direction = WEST; break;
case EAST:
*direction = SOUTH; break;
default:
case WEST:
*direction = NORTH; break;
}
break;
}
*x = *x + xMove[*direction]; /* Move to new location */
*y = *y + yMove[*direction];
/* Check for wrapping at window borders. Adjust if needed. */
if (*x < 0)
*x = (int)xClient-1;
else if (*x >= xClient)
*x = 0;
if (*y < 0)
*y = (int)yClient-1;
else if (*y >= yClient)
*y = 0;
return 0;
}
/*-----------------------------------------------------------------*/
/*
/* Name: HandleTermites
/* Description:
/*
/* This routine is called from the main message loop whenever
/* there was no message in the queue. It loops through the
/* each termite and updates it position.
/*
/*-----------------------------------------------------------------*/
void HandleTermites( hWnd )
HWND hWnd;
{
int index, color, newColor;
short xPos, yPos, r, g, b;
DWORD rgbColor;
HBRUSH hBrush;
HDC hDC;
if ( pauseFlag || noFile )
return;
hDC = GetDC( hWnd );
/* Move each Termite */
for ( index = 0; index < termiteCount; index ++ )
{
/* Get the current color at the current position */
rgbColor = GetPixel( hDC, miteX[index], miteY[index] );
color = RGB2Color( rgbColor );
/* Find new color from color table and set it at current position */
newColor = colorTable[state[index]][color];
SetPixel( hDC, miteX[index], miteY[index], rgbColorTable[newColor] );
/* Now, move the Termite */
moveMite( &miteX[index], &miteY[index], &direction[index], state[index], color );
/* Get next state */
state[index] = stateTable[state[index]][color];
}
ReleaseDC( hWnd, hDC );
}