home *** CD-ROM | disk | FTP | other *** search
- /*=========================================================================\
- * *
- * FILE: wrmthrd.c *
- * *
- * DESCRIPTION: *
- * *
- * *
- * Created 1991 IBM Corp. *
- * *
- * DISCLAIMER OF WARRANTIES. The following [enclosed] code is *
- * sample code created by IBM Corporation. This sample code is not *
- * part of any standard or IBM product and is provided to you solely *
- * for the purpose of assisting you in the development of your * *
- * applications. The code is provided "AS IS", without *
- * warranty of any kind. IBM shall not be liable for any damages *
- * arising out of your use of the sample code, even if they have been *
- * advised of the possibility of such damages. * *
- * *
- *-------------------------------------------------------------------------*
- *--------------------------------------------------------------
- *
- * This source file contains the following functions:
- *
- *
- * move_worm_up
- * move_worm_down
- * move_worm_right
- * move_worm_left
- * move_worm_zigup
- *
- *
- *
- \*==============================================================*/
-
- /*--------------------------------------------------------------*\
- * Include files, macros, defined constants, and externs
- \*--------------------------------------------------------------*/
-
- #define INCL_DOS
- #define INCL_VIO
- #define INCL_KBD
- #define INCL_MOU
- #define INCL_DOSPROCESS
- #define INCL_DOSSEMAPHORES
-
- #include <os2.h>
- #include <stdio.h>
- #include <string.h>
- #include <stddef.h>
- #include <string.h>
- #include <stdlib.h>
- #include "worms.h"
- #include "wrmthrd.h"
- /*--------------------------------------------------------------*\
- * Global variables and definitions for this file
- \*--------------------------------------------------------------*/
- CHAR *pszLeftWorm = "<<<------->";
- CHAR *pszRightWorm = "<------->>>";
- CHAR *pszBlank = " ";
- CHAR achUpWorm[10] = {'^','^','|','|','|','v'};
- CHAR achDownWorm[10]= {'^','^','|','|','|','v'};
- SHORT asWidths [] = {2,4,8,16};
- SHORT asHorizWidths [] = {HOR_WIDTH / 2, HOR_WIDTH /8,HOR_WIDTH,HOR_WIDTH / 3};
- SHORT asVertHeights [] = {HEIGHT / 4,HEIGHT / 8, HEIGHT / 2, HEIGHT };
- SHORT sDirection = 0;
- SHORT sVertHeight = 0;
- SHORT sRefresh = 1;
- #define DEBUG 0
- #define MAX_LEN_WORM 48
- #define FILE_NAME "TEST.???"
-
- /*--------------------------------------------------------------*\
- * Entry point declarations
- \*--------------------------------------------------------------*/
-
- VOID move_worm_up( USHORT *pusCurrentRow,USHORT *pusCurrentCol,
- PBYTE pbAttribute,
- SHORT *psCurrentDirection,
- LONG tidWorm);
- VOID move_worm_down( USHORT *pusCurrentRow,USHORT *pusCurrentCol,
- PBYTE pbAttribute,
- SHORT *psCurrentDirection,
- LONG tidWorm);
- VOID move_worm_right( USHORT *pusCurrentRow,USHORT *pusCurrentCol,
- PBYTE pbAttribute,
- SHORT *psCurrentDirection,
- LONG tidWorm);
- VOID move_worm_left( USHORT *pusCurrentRow,USHORT *pusCurrentCol,
- PBYTE pbAttribute,
- SHORT *psCurrentDirection,
- LONG tidWorm);
- VOID move_worm_zigup(USHORT *pusCurrentRow,USHORT *pusCurrentCol,
- PBYTE pbAttribute,
- SHORT *psCurrentDirection,
- LONG tidWorm);
- /****************************************************************\
- * Routine Name:wrmthrd()
- *--------------------------------------------------------------
- *
- * Name:
- *
- * Purpose: This routine allows each thread to draw to the screen.
- * Each thread will stay in this loop, until the thread
- * dies, or is terminated. Each thread may draw to the
- * unless the semaphore is set by thread one or indicating
- * that one of the parent threads wants control of the
- * screeen.
- *
- * Returns: There is no return value. The thread terminates.
- *
- \****************************************************************/
- VOID
- WormThread(PVOID pvMessage)
- {
-
- PTHREAD_DATA pThreadData;
- SHORT sDummy;
- SHORT asDirection [] = { UP,RIGHT,LEFT,DOWN};
-
-
-
- srand(sDummy);
- pThreadData = (PTHREAD_DATA) pvMessage;
- /*
- *start the worm off
- */
- if(sDirection == ( sizeof(asDirection) / sizeof(SHORT) ) )
- {
- sDirection = 0;
- }
- pThreadData->sCurrentDirection = asDirection[sDirection++];
- do
- {
- switch(pThreadData->sCurrentDirection)
- {
- case UP:
- move_worm_up( &pThreadData->usCurrentRow,&pThreadData->usCurrentCol,
- &pThreadData->bAttribute,
- &pThreadData->sCurrentDirection,
- pThreadData->tidWorm);
- break;
- case DOWN:
- move_worm_down( &pThreadData->usCurrentRow,&pThreadData->usCurrentCol,
- &pThreadData->bAttribute,
- &pThreadData->sCurrentDirection,
- pThreadData->tidWorm);
- break;
-
- case LEFT:
- move_worm_left( &pThreadData->usCurrentRow,&pThreadData->usCurrentCol,
- &pThreadData->bAttribute,
- &pThreadData->sCurrentDirection,
- pThreadData->tidWorm );
- break;
- case RIGHT:
- move_worm_right( &pThreadData->usCurrentRow,&pThreadData->usCurrentCol,
- &pThreadData->bAttribute,
- &pThreadData->sCurrentDirection,
- pThreadData->tidWorm );
- break;
- case ZIG_UP:
- move_worm_zigup( &pThreadData->usCurrentRow,&pThreadData->usCurrentCol,
- &pThreadData->bAttribute,
- &pThreadData->sCurrentDirection,
- pThreadData->tidWorm );
- break;
- default:
- pThreadData->usCurrentRow = ( LAST_ROW - FIRST_ROW ) /2;
- pThreadData->usCurrentCol = ( LAST_COL - FIRST_COL ) /2;
- if(sDirection == ( sizeof(asDirection) / sizeof(SHORT) ) )
- {
- sDirection = 0;
- }
- pThreadData->sCurrentDirection = asDirection[sDirection++];
- break;
- }
- DosSleep(PAUSE_TIME);
- /*
- *if set,then the thread that services the console,or the
- *thread that services the mouse queue wants control of
- *the screen
- */
- DosPostEventSem(hevDrawOk);
- DosWaitEventSem(hevDrawSem,SEM_INDEFINITE_WAIT);
-
- }while(pThreadData->fActive);
-
- pThreadData->tidWorm = 0;
- /*
- *if the process is to exit
- *post the semaphore on the way out
- */
- if(fQuit)
- {
- DosPostEventSem(hevDrawOk);
- }
-
- /*
- *should alway be called
- *to free any runtime resources this thread
- *might be using
- */
- _endthread();
-
- }/*WormThread*/
- /****************************************************************\
- *
- *--------------------------------------------------------------
- *
- * Name:move_worm_down()
- *
- * Purpose: Draw the worm down the screen vertically and set up to go to
- * another direction.
- * Returns: VOID
- *
- \****************************************************************/
- VOID move_worm_down(USHORT *pusCurrentRow,USHORT *pusCurrentCol,PBYTE pbAttribute,
- SHORT *psCurrentDirection,
- LONG tidWorm )
-
- {
-
- USHORT sRow;
- SHORT sPos = 0;
- SHORT sStartRow;
- CHAR achCell[2];
- BYTE bAttribute;
- USHORT usCount;
- BOOL fOnce = TRUE;
- BYTE bBackGround = WM_BACKGROUND;
-
- if(sVertHeight == (sizeof(asVertHeights) / sizeof(SHORT ) ) )
- {
- sVertHeight = 0;
- }
- if(*pusCurrentRow <= FIRST_ROW || *pusCurrentRow >= LAST_ROW )
- {
- *pusCurrentRow = ( LAST_ROW - asVertHeights[sVertHeight++]) ;
- }
-
- if(*pusCurrentRow < FIRST_ROW || *pusCurrentRow > LAST_ROW )
- {
- *pusCurrentRow = (FIRST_ROW + 1);
- }
- sStartRow = *pusCurrentRow;
- usCount = sizeof(achCell);
- bAttribute = *pbAttribute;
- for(sRow = (*pusCurrentRow + WIDTH); *pusCurrentRow < LAST_ROW && fDraw; (*pusCurrentRow)++ )
- {
- /*
- *read the current attribute
- *on the screen
- *if another worm
- */
- VioReadCellStr(achCell,&usCount,*pusCurrentRow,*pusCurrentCol,hvio);
- if(!fSilent)
- {
- if(achCell[0] != ' ' && fOnce )
- {
- DosBeep(600,175);
- DosBeep(1200,175);
- bAttribute = 0x4F;
- fOnce = FALSE;
- }
- }
- VioWrtCharStrAtt( &achDownWorm[sPos],1,
- *pusCurrentRow,*pusCurrentCol,&bAttribute,
- hvio );
- DosSleep(PAUSE_TIME);
- if(!achUpWorm[sPos++] )
- {
- for(; sStartRow <= (*pusCurrentRow ) && fDraw;sStartRow++)
- {
- VioWrtCharStrAtt( &pszBlank[0],1,
- sStartRow,*pusCurrentCol,&bBackGround,
- hvio );
- }
- sPos = 0;
- }
-
- }
- /*
- *clean off any tail we
- *left behind
- */
- if(sPos)
- {
- for(; sStartRow <= (*pusCurrentRow ) ;sStartRow++)
- {
- VioWrtCharStrAtt( &pszBlank[sPos],1,
- sStartRow,*pusCurrentCol,&bBackGround,
- hvio );
- }
- }
-
- /*
- *if we stopped drawing
- *come back to the same spot
- */
- if(fDraw)
- {
- *psCurrentDirection = (rand() % MAX_DIRECTIONS);
- *pusCurrentRow = (rand() % HEIGHT);
- *pusCurrentCol = ( (rand() % HOR_WIDTH) / asWidths[rand() % 4] + 1);
- }
-
- }
- /****************************************************************\
- *
- *--------------------------------------------------------------
- *
- * Name:move_worm_up()
- *
- * Purpose:Redraw the worm moving vertically up the screen.
- * Draw until the bottom of the screen or fDraw flag has
- * been reset.
- *
- * Returns: VOID
- *
- \****************************************************************/
- VOID move_worm_up(USHORT *pusCurrentRow,USHORT *pusCurrentCol,PBYTE pbAttribute,
- SHORT *psCurrentDirection,
- LONG tidWorm )
-
- {
-
- USHORT sRow;
- SHORT sPos;
- SHORT sStartRow;
- BYTE bBackGround = WM_BACKGROUND;
- static SHORT sVertHeight = 0;
-
- if(sVertHeight == (sizeof(asVertHeights) / sizeof(SHORT ) ) )
- {
- sVertHeight = 0;
- }
- if(*pusCurrentRow <= FIRST_ROW || *pusCurrentRow >= LAST_ROW )
- {
- *pusCurrentRow = ( LAST_ROW - asVertHeights[sVertHeight]) ;
- }
- sStartRow = *pusCurrentRow;
- for(sRow = (*pusCurrentRow - WIDTH),sPos = 0;
- (*pusCurrentRow > FIRST_ROW )&& fDraw;
- (*pusCurrentRow)--)
- {
- /*
- *read the current attribute
- *on the screen
- *if another worm beep
- */
- VioWrtCharStrAtt( &achUpWorm[sPos],1,
- *pusCurrentRow,*pusCurrentCol,pbAttribute,
- hvio );
- DosSleep(PAUSE_TIME);
- if(!achUpWorm[sPos++] )
- {
- for(; sStartRow >= (*pusCurrentRow ) && fDraw;sStartRow--)
- {
- VioWrtCharStrAtt( &pszBlank[0],1,
- sStartRow,*pusCurrentCol,&bBackGround,
- hvio );
- }
- sPos = 0;
- }
-
-
- }
- /*
- *clean up any head on the screen
- */
- if(sPos)
- {
- for(; sStartRow >= (*pusCurrentRow ) ;sStartRow--)
- {
- VioWrtCharStrAtt( &pszBlank[0],1,
- sStartRow,*pusCurrentCol,&bBackGround,
- hvio );
- }
- }
-
- /*
- *if we stopped drawing
- *come back to the same spot
- */
- if(fDraw)
- {
- *psCurrentDirection = ( rand() % MAX_DIRECTIONS);
- *pusCurrentRow = ( (rand() % HEIGHT) );
- *pusCurrentCol = ( (rand() % HOR_WIDTH)/ asWidths[rand() % 4] + 1) ;
- }
- }
-
-
- /****************************************************************\
- *
- *--------------------------------------------------------------
- *
- * Name:move_worm_right()
- *
- * Purpose:Move the worm to the right side of the screen and wrap
- * around.
- *
- * Returns: VOID
- *
- \****************************************************************/
- VOID move_worm_right(USHORT *pusCurrentRow,USHORT *pusCurrentCol,PBYTE pbAttribute,
- SHORT *psCurrentDirection,
- LONG tidWorm )
-
- {
- SHORT sCol;
- USHORT usSize;
- BYTE bAttribute;
- BOOL fOnce = TRUE;
- static SHORT sHorizWidth = 0;
- BYTE bBackGround = WM_BACKGROUND;
- USHORT usOldRow,usOldCol;
- CHAR achCell[ MAX_LEN_WORM ];
- USHORT usCount;
-
-
- if(*pusCurrentRow < FIRST_ROW || *pusCurrentRow > LAST_ROW )
- {
- *pusCurrentRow = (FIRST_ROW + 1);
- }
- if(sHorizWidth == (sizeof(asHorizWidths) / sizeof(SHORT ) ) )
- {
- sHorizWidth = 0;
- }
-
- usSize = sizeof(achCell);
- bAttribute = *pbAttribute;
-
- usOldRow = *pusCurrentRow;
- usOldCol = *pusCurrentCol;
- usCount = strlen(pszRightWorm);
- VioReadCellStr(achCell,&usCount,usOldRow,usOldCol,hvio);
- for(sCol = (*pusCurrentCol + asHorizWidths[sHorizWidth++]);
- (*pusCurrentCol) <= sCol && fDraw;
- (*pusCurrentCol)++ )
- {
- /*
- *read the current attribute
- *on the screen
- *if another worm
- */
- VioReadCellStr(achCell,&usSize,*pusCurrentRow,*pusCurrentCol,hvio);
- if(!fSilent)
- {
- if(achCell[0] != ' ' && fOnce )
- {
- DosBeep(600,175);
- DosBeep(1200,175);
- bAttribute = 0x4F;
- fOnce = FALSE;
- }
- }
-
- VioWrtCharStrAtt( pszRightWorm,strlen(pszRightWorm),
- *pusCurrentRow,*pusCurrentCol,&bAttribute,
- hvio );
- /*
- *erase the last one
- *by setting the background
- *color
- */
- DosSleep(PAUSE_TIME);
- VioWrtCharStrAtt( pszBlank,strlen(pszRightWorm),
- *pusCurrentRow,(*pusCurrentCol),&bBackGround,
- hvio );
-
-
- }
-
- /*
- *if we stopped drawing
- *come back to the same spot
- */
- if(fDraw)
- {
- VioWrtCellStr(achCell,usCount,usOldRow,usOldCol,hvio);
- *psCurrentDirection = (rand() % MAX_DIRECTIONS);
- *pusCurrentCol = ( (rand() % HOR_WIDTH) + 1/ asWidths[rand() % 4] + 1);
- *pusCurrentRow = ( (rand() % HEIGHT) );
- }
-
- }
-
-
- /****************************************************************\
- *
- *--------------------------------------------------------------
- *
- * Name:move_worm_zigup
- *
- * Purpose:Draw the worm in a diagonal direction moving upwards.
- *
- * Returns:
- * VOID
- \****************************************************************/
- VOID move_worm_zigup(USHORT *pusCurrentRow,USHORT *pusCurrentCol,
- PBYTE pbAttribute,
- SHORT *psCurrentDirection,
- LONG tidWorm )
- {
-
- USHORT sRow;
- SHORT sPos;
- SHORT sStartRow,sStartCol;
- BYTE bBackGround = WM_BACKGROUND;
-
- sStartRow = *pusCurrentRow;
- sStartCol = *pusCurrentCol;
- for(sRow = (*pusCurrentRow - WIDTH),sPos = 0;
- (*pusCurrentRow > FIRST_ROW + 1) && fDraw;
- (*pusCurrentRow) -=2,(*pusCurrentCol)++ )
- {
- VioWrtCharStrAtt( &achUpWorm[sPos],1,
- *pusCurrentRow,*pusCurrentCol,pbAttribute,
- hvio );
- DosSleep(PAUSE_TIME);
- if(!achUpWorm[sPos++] )
- {
- for(; sStartRow >= (*pusCurrentRow )&& fDraw;sStartRow -=2 ,sStartCol++ )
- {
- VioWrtCharStrAtt( &pszBlank[0],1,
- sStartRow,sStartCol,&bBackGround,
- hvio );
- }
- sPos = 0;
- }
-
-
- }
- /*
- *clean up any head on the screen
- */
- if(sPos)
- {
- for(; sStartRow >= (*pusCurrentRow );sStartRow -=2 )
- {
- VioWrtCharStrAtt( &pszBlank[0],1,
- sStartRow,sStartCol++,&bBackGround,
- hvio );
- }
- }
-
- /*
- *if we stopped drawing
- *come back to the same spot
- */
- if(fDraw)
- {
- *psCurrentDirection = ( rand() % MAX_DIRECTIONS);
- *pusCurrentCol = ( (rand() % HOR_WIDTH)/ asWidths[rand() % 4] + 1);
- *pusCurrentRow = ( (rand() % HEIGHT) );
- }
-
- }
-
-
- /****************************************************************\
- *
- *--------------------------------------------------------------
- *
- * Name:move_worm_left()
- *
- * Purpose:Move the worm to the left side of the screen.
- *
- * Returns: VOID
- *
- \****************************************************************/
- VOID move_worm_left(USHORT *pusCurrentRow,USHORT *pusCurrentCol,
- PBYTE pbAttribute,
- SHORT *psCurrentDirection,
- LONG tidWorm )
-
- {
-
- USHORT sCol;
- static SHORT sHorizWidth = 0;
- BYTE bBackGround = WM_BACKGROUND;
-
-
- if(sHorizWidth == (sizeof(asHorizWidths) / sizeof(SHORT ) ) )
- {
- sHorizWidth = 0;
- }
-
- if(*pusCurrentRow < FIRST_ROW || *pusCurrentRow > LAST_ROW )
- {
- *pusCurrentRow = (LAST_ROW - 1);
- }
- sCol = rand() % WIDTH;
- if( sCol > *pusCurrentCol)
- {
- sCol = sCol - *pusCurrentCol;
- }
- for( ;((*pusCurrentCol) > sCol) && fDraw; (*pusCurrentCol)--)
- {
- /*
- *read the current attribute
- *on the screen
- *if another worm
- */
-
- VioWrtCharStrAtt( pszLeftWorm,strlen(pszLeftWorm),
- *pusCurrentRow,*pusCurrentCol,pbAttribute,
- hvio );
-
- DosSleep(PAUSE_TIME);
- if(!fDraw)
- {
- break;
- }
- VioWrtCharStrAtt( pszBlank,strlen(pszLeftWorm),
- *pusCurrentRow,(*pusCurrentCol),&bBackGround,
- hvio );
-
- }
- /*
- *if we stopped drawing
- *come back to the same spot
- */
- if(fDraw)
- {
- *psCurrentDirection = (rand() % MAX_DIRECTIONS);
- *pusCurrentRow = ( (rand() % HEIGHT) );
- *pusCurrentCol = ( (rand() % HOR_WIDTH)/ asWidths[rand() % 4] + 1);
- }
- }
-
- /*--------------------------------------------------------------*\
- * End of file : wrmthrd.c
- \*--------------------------------------------------------------*/
-