home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Windows Shareware GOLD
/
NuclearComputingVol3No1.cdr
/
other
/
f1261
/
sub.c
< prev
next >
Wrap
C/C++ Source or Header
|
1990-09-12
|
9KB
|
359 lines
/* **********************************************************
sub.c - Controls a sub in FISH to shoot fish using DDE
Placed in public domain by Horizon Technologies Inc. 1990
***revision history***
1 SUB.C 24-Jan-90,15:11:52,`JMH' Initial version
2 SUB.C 29-Jan-90,9:13:06,`JMH' Semi-stable version
3 SUB.C 19-Feb-90,14:43:14,`JMH' Version as of 3/5/90
4 SUB.C 19-Jun-90,10:51:24,`JMH' Version as of 6/25/90
5 SUB.C 25-Jun-90,14:48:12,`JMH' Version as of 6/25/90
6 SUB.C 2-Jul-90,14:15:54,`PRS' Version as of 6/25/90
7 SUB.C 19-Jul-90,9:22:42,`PRS' Version with win.ini regerstered settings
8 SUB.C 12-Sep-90,15:59:04,`JMH' Version 1.3
***revision history***
********************************************************** */
#define MAIN
#define NOCOMM
#include "windows.h"
#include "stdio.h"
#include "stdlib.h"
#include "string.h"
#include "dde.h"
#include "ddelib.h"
#include "sub.h"
/* Undocumented windows functions */
int FAR PASCAL lstrlen (LPSTR);
LPSTR FAR PASCAL lstrcpy (LPSTR, LPSTR);
LPSTR FAR PASCAL lstrcat (LPSTR, LPSTR);
int FAR PASCAL lstrcmp (LPSTR, LPSTR);
/* Globals */
static HANDLE ghInstance;
static char *gszAppName = "Sub";
static int gxFish, gyFish;
static int gxSub, gySub;
static int gxPrevFish;
static DWORD gdwSampleRate;
static DWORD gdwSampleCounter;
static HANDLE ghFish;
static HANDLE ghSub;
static DDECALLBACK glpfnFish;
static DDECALLBACK glpfnSub;
static FARPROC glpfnAbout;
/* Functions */
int PASCAL WinMain (HANDLE, HANDLE, LPSTR, int);
long FAR PASCAL SubProc (HWND, unsigned, WORD, LONG);
WORD FAR PASCAL Fish (HWND, unsigned, LPSTR, HANDLE);
WORD FAR PASCAL Sub (HWND, unsigned, LPSTR, HANDLE);
void MoveSub (void);
BOOL FAR PASCAL About (HWND, unsigned, WORD, LONG);
int PASCAL WinMain (hInstance, hPrevInstance, lpCmdLine, nCmdShow)
HANDLE hInstance;
HANDLE hPrevInstance;
LPSTR lpCmdLine;
int nCmdShow;
{
WNDCLASS wndclass;
MSG msg;
HWND hWnd;
ghInstance = hInstance;
if ( !hPrevInstance )
{
wndclass.style = CS_HREDRAW | CS_VREDRAW;
wndclass.lpfnWndProc = SubProc;
wndclass.cbClsExtra = 0;
wndclass.cbWndExtra = 0;
wndclass.hInstance = hInstance;
wndclass.hIcon = LoadIcon ( hInstance, gszAppName );
wndclass.hCursor = LoadCursor ( NULL, IDC_ARROW );
wndclass.hbrBackground = (HBRUSH) GetStockObject ( WHITE_BRUSH );
wndclass.lpszMenuName = gszAppName;
wndclass.lpszClassName = gszAppName;
if ( !RegisterClass ( &wndclass ) )
return FALSE;
} /* if ! hPrevInstance */
hWnd = CreateWindow ( gszAppName, gszAppName, WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL,
hInstance, NULL );
if ( !hWnd )
return ( NULL );
ShowWindow ( hWnd, SW_SHOWMINIMIZED );
UpdateWindow ( hWnd );
while ( GetMessage ( &msg, NULL, NULL, NULL ) )
{
TranslateMessage ( &msg );
DispatchMessage ( &msg );
} /* while GetMessage */
return ( msg.wParam );
} /* function WinMain */
long FAR PASCAL SubProc (hWnd, iMessage, wParam, lParam)
HWND hWnd;
unsigned iMessage;
WORD wParam;
LONG lParam;
{
DDEADVISE ddeAdvise;
PAINTSTRUCT ps;
char szText[40];
switch ( iMessage )
{
case WM_CREATE:
/* Provide callback addresses for DDE callback functions */
glpfnFish = (DDECALLBACK) MakeProcInstance ( (FARPROC) Fish,
ghInstance );
glpfnSub = (DDECALLBACK) MakeProcInstance ( (FARPROC) Sub,
ghInstance );
/* Inititate DDE Sessions with FISH */
if ( !( ghFish = DDEInitiate ( hWnd, "Fish", "Position" ) ) )
break;
if ( !( ghSub = DDEInitiate ( hWnd, "Fish", "Sub" ) ) )
break;
/* Ask to be advised everytime fish number zero makes a move */
ddeAdvise.fDeferUpd = FALSE;
ddeAdvise.fAckReq = TRUE;
ddeAdvise.cfFormat = CF_TEXT;
DDEAdvise ( ghFish, "0", &ddeAdvise, glpfnFish );
/* Set up a timer to determine the sampling rate */
SetTimer ( hWnd, NULL, 5000, NULL );
break;
case WM_COMMAND:
switch ( wParam )
{
case IDM_EXIT:
SendMessage ( hWnd, WM_CLOSE, 0, 0L );
break;
case IDM_ABOUT:
glpfnAbout = MakeProcInstance ( About, ghInstance );
DialogBox ( ghInstance, "About", hWnd, glpfnAbout );
FreeProcInstance ( glpfnAbout );
break;
} /* switch wParam */
break;
case WM_PAINT:
BeginPaint ( hWnd, &ps );
/* Print the sampling rate */
sprintf ( szText, "Sample rate: %ld/minute, %ld/second",
gdwSampleRate, gdwSampleRate / 60 );
TextOut ( ps.hdc, 0, 0, szText, strlen ( szText ) );
sprintf ( szText, "Message rate: %ld/minute, %ld/second",
gdwSampleRate * 7, gdwSampleRate * 7 / 60 );
TextOut ( ps.hdc, 0, 20, szText, strlen ( szText ) );
EndPaint ( hWnd, &ps );
break;
case WM_TIMER:
/* Reset the sample rate counter */
gdwSampleRate = gdwSampleCounter * 12;
gdwSampleCounter = 0;
/* Cause a repainting of the client area */
InvalidateRect ( hWnd, NULL, TRUE );
UpdateWindow ( hWnd );
break;
case WM_DESTROY:
/* Cancel the advise circuit for fish zero */
// DDEUnadvise (ghFish, "0"); - BUG: FISH does not ack the unadvise
/* End the sessions with FISH */
DDETerminate ( ghFish );
DDETerminate ( ghSub );
PostQuitMessage ( 0 );
break;
default:
return DefWindowProc ( hWnd, iMessage, wParam, lParam );
} /* switch iMessage */
return 0L;
} /* function SubProc */
/* Callback routine to notify us when the fish moves */
WORD FAR PASCAL Fish (hFish, iMessage, lpszItem, hData)
HWND hFish;
unsigned iMessage;
LPSTR lpszItem;
HANDLE hData;
{
LPDDEDATA lpData;
char szData[20];
/* If this is good data */
if ( iMessage == DDE_DATA )
{
/* Move data to a local string */
lpData = (LPDDEDATA) GlobalLock ( hData );
lstrcpy ( szData, lpData->Value );
GlobalUnlock ( hData );
/* Save the previous x-position of Fish zero */
gxPrevFish = gxFish;
/* Fish out new fish position */
sscanf ( szData, "%d %d", &gxFish, &gyFish );
/* Request the current position of the sub */
DDERequest ( ghSub, "Position", CF_TEXT, glpfnSub );
/* Go get the fish that moved */
MoveSub ();
/* Show a sample hit */
gdwSampleCounter++;
} /* if iMessage */
return NULL;
} /* function Fish */
/* Callback routine to notify us of the current sub position */
WORD FAR PASCAL Sub (hSub, iMessage, lpszItem, hData)
HWND hSub;
unsigned iMessage;
LPSTR lpszItem;
HANDLE hData;
{
LPDDEDATA lpData;
char szData[20];
/* If this is good data */
if ( iMessage == DDE_DATA )
{
/* Move data to a local string */
lpData = (LPDDEDATA) GlobalLock ( hData );
lstrcpy ( szData, lpData->Value );
GlobalUnlock ( hData );
/* Fish out sub position */
sscanf ( szData, "%d %d", &gxSub, &gySub );
} /* if iMessage */
return NULL;
} /* function Sub */
/* Function to compute execute command and do it */
void MoveSub ()
{
HANDLE hCommand;
LPSTR lpszCommand;
BOOL bFire = TRUE;
/* Allocate room for the command */
hCommand = GlobalAlloc ( GHND | GMEM_DDESHARE, (DWORD) 10 );
lpszCommand = GlobalLock ( hCommand );
/* Fish is moving right... */
if ( gxFish > gxPrevFish )
{
/* We are behind the fish, go get it! */
if ( gxFish > gxSub + 100 )
lstrcpy ( lpszCommand, "[r]" );
/* Can't fire... too close... back away */
else
{
lstrcpy ( lpszCommand, "[l]" );
bFire = FALSE;
} /* else */
} /* if gxFish */
/* Fish is moving left... */
else
{
/* We are behind the fish, go get it! */
if ( gxFish < gxSub - 100 )
lstrcpy ( lpszCommand, "[l]" );
/* Can't fire... too close... back away */
else
{
lstrcpy ( lpszCommand, "[r]" );
bFire = FALSE;
} /* else */
} /* else */
/* Compute simple up/down command */
lstrcat ( lpszCommand, ( gyFish < gySub ) ? "[u]" : "[d]" );
/* Check for vertical accuracy, cancel fire if too high or low */
if ( abs ( gyFish - gySub ) > 10 )
bFire = FALSE;
/* Add the command to Fire! */
if ( bFire )
lstrcat ( lpszCommand, "[f]" );
/* Clean up */
GlobalUnlock ( hCommand );
/* Execute the command */
DDEExecute ( ghSub, hCommand );
} /* function MoveSub */
/* About box */
BOOL FAR PASCAL About (hDlg, iMessage, wParam, lParam)
HWND hDlg;
unsigned iMessage;
WORD wParam;
LONG lParam;
{
switch ( iMessage )
{
case WM_INITDIALOG:
break;
case WM_COMMAND:
EndDialog ( hDlg, FALSE );
break;
default:
return FALSE;
} /* switch iMessage */
return TRUE;
} /* function About */