home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OpenGL Superbible
/
OpenGL_Superbible_Waite_Group_Press_1996.iso
/
book
/
chapt10
/
tank
/
borland
/
tank.c
< prev
next >
Wrap
C/C++ Source or Header
|
1996-07-07
|
13KB
|
502 lines
// Tank.c
// This is the application shell for the tank simulator
// Include files
#include <windows.h> // Window defines
#include <math.h> // Include for sqrt()
#include <gl\gl.h> // OpenGL
#include <gl\glu.h> // GLU library
#include "resource.h" // About box and other resource identifiers.
#include "glutils.h" // OpenGL support functions
///////////////////////////////////////////////////////////////////////////
// Declaration of shared handles, etc. These are declared as externs in the
// header file externs.h
HWND hRadarWnd = NULL;
HWND hCenterWnd = NULL;
HWND hCompassWnd= NULL;
HWND hViewWnd = NULL;
HWND hMainWnd = NULL;
HPALETTE hPalette = NULL;
// Tank and robot position
struct _POSITION tankPos; // Tanks position
struct _POSITION robotPos; // Robots position
struct _POSITION *pObject; // Which one is current
// Real simple, if this is true, your the tank, if false, your the robot
BOOL bTank = TRUE;
BOOL bDrawShadows = FALSE;
// Display list identifiers
int nWorldList = 10000;
int nCompassList = 10001;
// This is going to come in handy more than once.
double PI = 3.14159265359;
// Class Names for all the window classes in this application
static LPCTSTR lpszMainWndClass = "MainClass";
static LPCTSTR lpszCenterWndClass = "CenterClass";
static LPCTSTR lpszCompassWndClass = "CompassClass";
static LPCTSTR lpszRadarWndClass = "RadarClass";
static LPCTSTR lpszViewWndClass = "ViewClass";
// Application name and instance storeage
static LPCTSTR lpszAppName = "GL Tank";
static HINSTANCE hInstance;
// Declaration for Window procedures
// Defined in this file (tank.c)
LRESULT CALLBACK WndProcMain(HWND hWnd,
UINT message,
WPARAM wParam,
LPARAM lParam);
// Declaration for Window procedures
// See CompassWnd.c
LRESULT CALLBACK WndProcCompass(HWND hWnd,
UINT message,
WPARAM wParam,
LPARAM lParam);
// Declaration for Window procedures
// See CenterWnd.c
LRESULT CALLBACK WndProcCenter(HWND hWnd,
UINT message,
WPARAM wParam,
LPARAM lParam);
// Declaration for Window procedures
// See RadarWnd.c
LRESULT CALLBACK WndProcRadar(HWND hWnd,
UINT message,
WPARAM wParam,
LPARAM lParam);
// Declaration for Window procedure
// See ViewWnd.c
LRESULT CALLBACK WndProcView(HWND hWnd,
UINT message,
WPARAM wParam,
LPARAM lParam);
// Dialog procedure for about box
BOOL APIENTRY AboutDlgProc (HWND hDlg, UINT message, UINT wParam, LONG lParam);
BOOL BuildClasses(void);
///////////////////////////////////////////////////////////////////////////////
// Create the window classes. Returns FALSE if any errors occur
BOOL BuildClasses(void)
{
WNDCLASS wc; // Windows class structure
// Register window style for the main window
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = (WNDPROC) WndProcMain;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance;
wc.hIcon = NULL;
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
// No need for background brush for this window
wc.hbrBackground = NULL;
wc.lpszMenuName = MAKEINTRESOURCE(IDR_MENU);
wc.lpszClassName = lpszMainWndClass;
// Register the window class
if(RegisterClass(&wc) == 0)
return FALSE;
// Register window style for the center window
// Most info is the same
wc.lpfnWndProc = (WNDPROC) WndProcCenter;
// May want to change later
wc.hbrBackground = GetStockObject(WHITE_BRUSH);
wc.lpszClassName = lpszCenterWndClass;
// Register the window class
if(RegisterClass(&wc) == 0)
return FALSE;
// Register window style for the control window
wc.lpfnWndProc = (WNDPROC) WndProcRadar;
wc.hbrBackground = GetStockObject(BLACK_BRUSH);
wc.lpszClassName = lpszRadarWndClass;
// Register the window class
if(RegisterClass(&wc) == 0)
return FALSE;
// Register window style for the main view window
// This is a window OpenGL will render in
wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
wc.lpfnWndProc = (WNDPROC) WndProcView;
// May want to change the cursor
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
// No need for background brush for this window
// Delete me later
wc.hbrBackground = NULL;
wc.lpszClassName = lpszViewWndClass;
// Register the window class
if(RegisterClass(&wc) == 0)
return FALSE;
// Register window style for the Map window, OpenGL will also render
// into this window.
// Most Info is the same
wc.lpfnWndProc = (WNDPROC) WndProcCompass;
wc.lpszClassName = lpszCompassWndClass;
// Register the window class
if(RegisterClass(&wc) == 0)
return FALSE;
return TRUE;
}
///////////////////////////////////////////////////////////////////////////////
// Entry point of all Windows programs
int APIENTRY WinMain( HINSTANCE hInst,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
MSG msg; // Windows message structure
// Variable is scoped to this file
hInstance = hInst;
// Create the window classes for the main window and the
// children
if(!BuildClasses())
return FALSE;
// Initializes the world geography
if(!InitWorld())
return FALSE;
// Create the main application window
hMainWnd = CreateWindow(
lpszMainWndClass,
lpszAppName,
WS_CAPTION | WS_BORDER | WS_SYSMENU,
0, 0, // Size and dimensions of window
640, 480,
NULL,
NULL,
hInstance,
NULL);
// Display the window
ShowWindow(hMainWnd,SW_SHOW);
UpdateWindow(hMainWnd);
// Process application messages until the application closes
while( GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}
///////////////////////////////////////////////////////////////////////////////
// Window procedure, handles all top messages for this program
LRESULT CALLBACK WndProcMain(HWND hWnd,
UINT message,
WPARAM wParam,
LPARAM lParam)
{
switch (message)
{
// Window creation, setup here
case WM_CREATE:
{
HANDLE hMenu = GetMenu(hWnd);
// Set initial menu check state
CheckMenuItem(hMenu,ID_VIEW_FROMTANK,MF_BYCOMMAND | MF_CHECKED);
// Create the child windows
// View Window
hViewWnd = CreateWindow(
lpszViewWndClass,
NULL,
WS_DLGFRAME | WS_CHILD | WS_CLIPCHILDREN | WS_CLIPSIBLINGS| WS_VISIBLE,
0, 0,
10, 10,
hWnd,
NULL,
hInstance,
NULL);
// Compass Window
hCompassWnd = CreateWindow(
lpszCompassWndClass,
NULL,
WS_DLGFRAME | WS_CHILD | WS_CLIPCHILDREN | WS_CLIPSIBLINGS| WS_VISIBLE,
1, 1,
10, 10,
hWnd,
NULL,
hInstance,
NULL);
// Center Window, just contains the instructions
hCenterWnd = CreateWindow(
lpszCenterWndClass,
NULL,
WS_DLGFRAME | WS_CHILD | WS_VISIBLE,
1, 1,
10, 10,
hWnd,
NULL,
hInstance,
NULL);
// Radar Window
hRadarWnd = CreateWindow(
lpszRadarWndClass,
NULL,
WS_DLGFRAME | WS_CHILD | WS_VISIBLE,
1, 1,
10, 10,
hWnd,
NULL,
hInstance,
NULL);
}
break;
// Window is being destroyed, cleanup
case WM_DESTROY:
// Tell the application to terminate after the window
// is gone.
PostQuitMessage(0);
break;
// Window is resized.
// This is really only going to be called once. Why resize here
// instead of just creating the windows where we want them? Because
// changes to the GUI may change the size of borders, etc. This
// code should continue to work regardless of any changes to the
// GUI.
case WM_SIZE:
{
RECT clientRect;
int width,height;
GetClientRect(hMainWnd,&clientRect);
// Position the viewing window
width = clientRect.right - clientRect.left;
height = (clientRect.bottom*2)/5;
MoveWindow(hViewWnd,0,height,
width,clientRect.bottom-height,TRUE);
// Position the Map Window
MoveWindow(hCompassWnd,0,0,175,height,TRUE);
// Position the Center Window
MoveWindow(hCenterWnd,175,0,
clientRect.right-350,height,TRUE);
// Position the Control Window
MoveWindow(hRadarWnd,width-175,0,
175,height,TRUE);
}
break;
// Windows is telling the application that it may modify
// the system palette. This message in essance asks the
// application for a new palette.
case WM_QUERYNEWPALETTE:
// Pass the message to the OpenGL Windows, none of the other
// Windows use anything outside the standard set of colors
PostMessage(hViewWnd,message,wParam,lParam);
PostMessage(hRadarWnd,message,wParam,lParam);
break;
// This window may set the palette, even though it is not the
// currently active window.
case WM_PALETTECHANGED:
// Pass the message to the OpenGL Windows, none of the other
// Windows use anything outside the standard 16 colors
PostMessage(hViewWnd,message,wParam,lParam);
PostMessage(hRadarWnd,message,wParam,lParam);
break;
// Catch and handle the arrow keys for movement
case WM_KEYDOWN:
{
switch(wParam)
{
case VK_UP: // Up arrow, move forward
{
MoveViewer(10.0);
// Invalidate the view window (compass doesn't change)
InvalidateRect(hViewWnd,NULL,FALSE);
break;
}
case VK_DOWN: // Down arrow, move backward
{
MoveViewer(-10.0);
// Invalidate the view window (compass doesn't change)
InvalidateRect(hViewWnd,NULL,FALSE);
break;
}
case VK_LEFT: // Left arrow, turn left
{
pObject->radsFromEast += PI/30.0f;
if(pObject->radsFromEast > (2.0*PI)) // Keep in bounds
pObject->radsFromEast = 0.0;
// Invalidate the compass window and view window
InvalidateRect(hCompassWnd,NULL,FALSE);
InvalidateRect(hViewWnd,NULL,FALSE);
break;
}
case VK_RIGHT: // Right Arrow, turn right
{
pObject->radsFromEast -= PI/30.0;
if(pObject->radsFromEast < 0.0)
pObject->radsFromEast = (2.0*PI); // Keep in bounds
// Invalidate the compass window and view window
InvalidateRect(hCompassWnd,NULL,FALSE);
InvalidateRect(hViewWnd,NULL,FALSE);
break;
}
}
}
break;
// A menu command
case WM_COMMAND:
{
HANDLE hMenu = GetMenu(hWnd);
switch(LOWORD(wParam))
{
// Exit the program
case ID_FILE_EXIT:
DestroyWindow(hWnd);
break;
// Display the about box
case ID_HELP_ABOUT:
DialogBox (hInstance,
MAKEINTRESOURCE(IDD_DIALOG_ABOUT),
hWnd,
AboutDlgProc);
break;
// View is from tank
case ID_VIEW_FROMTANK:
bTank = TRUE;
pObject = &tankPos;
CheckMenuItem(hMenu,ID_VIEW_FROMTANK,MF_BYCOMMAND | MF_CHECKED);
CheckMenuItem(hMenu,ID_VIEW_FROMROBOT,MF_BYCOMMAND | MF_UNCHECKED);
// Invalidate the compass window and view window
InvalidateRect(hCompassWnd,NULL,FALSE);
InvalidateRect(hViewWnd,NULL,FALSE);
break;
// View is from robot
case ID_VIEW_FROMROBOT:
bTank = FALSE;
pObject = &robotPos;
CheckMenuItem(hMenu,ID_VIEW_FROMTANK,MF_BYCOMMAND | MF_UNCHECKED);
CheckMenuItem(hMenu,ID_VIEW_FROMROBOT,MF_BYCOMMAND | MF_CHECKED);
// Invalidate the compass window and view window
InvalidateRect(hCompassWnd,NULL,FALSE);
InvalidateRect(hViewWnd,NULL,FALSE);
break;
}
}
break;
default: // Passes it on if unproccessed
return (DefWindowProc(hWnd, message, wParam, lParam));
}
return (0L);
}
///////////////////////////////////////////////////////////////////////////
// Dialog procedure
BOOL APIENTRY AboutDlgProc (HWND hDlg, UINT message, UINT wParam, LONG lParam)
{
switch (message)
{
// Process command messages
case WM_COMMAND:
{
// Validate and Make the changes
if(LOWORD(wParam) == IDOK)
EndDialog(hDlg,TRUE);
}
break;
// Closed from sysbox
case WM_CLOSE:
EndDialog(hDlg,TRUE);
break;
}
return FALSE;
}