home *** CD-ROM | disk | FTP | other *** search
- //-------------------------------------------------------------------
- //
- // 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 );
- }
-
-