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