home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Learn 3D Graphics Programming on the PC
/
Learn_3D_Graphics_Programming_on_the_PC_Ferraro.iso
/
rwwin
/
oswin.c_
/
oswin.bin
Wrap
Text File
|
1995-11-14
|
26KB
|
858 lines
/**********************************************************************
*
* File : oswin.c
*
* Abstract : The MS Windows specific part of this demo program.
* This file contains all of the OS specific components
* of the demo together with the main Windows application
* control loop.
*
**********************************************************************
*
* This file is a product of Criterion Software Ltd.
*
* This file is provided as is with no warranties of any kind and is
* provided without any obligation on Criterion Software Ltd. or
* Canon Inc. to assist in its use or modification.
*
* Criterion Software Ltd. will not, under any
* circumstances, be liable for any lost revenue or other damages arising
* from the use of this file.
*
* Copyright (c) 1995 Criterion Software Ltd.
* All Rights Reserved.
*
* RenderWare is a trademark of Canon Inc.
*
************************************************************************/
/*--- Include files ---*/
#define INCLUDE_SHELLAPI_H
#include <windows.h>
#include "global.h"
#include "common.h"
#include "rwwin.h"
#include "resource.h"
/*--- Macros and Magic Number definitions ---*/
/* Define the windows class name */
#define CYBER_CLASS_NAME "RwCyberClass"
/* Define the title that will appear on error dialogues */
#define ERROR_DIALOG_TITLE "RenderWare(tm) RwCyber Error"
/* The default size of the applications window */
#define DEFAULT_WINDOW_WIDTH 640
#define DEFAULT_WINDOW_HEIGHT 510
/* The maximum size of the camera that will be created */
#define MAX_CAMERA_WIDTH 640
#define MAX_CAMERA_HEIGHT 480
/*--- Global Variable Definitions ---*/
static HWND hGAppWindow; /* The current window handle */
static HINSTANCE hGAppInstance; /* The application instance handle */
static HDC PaintDC; /* The DC to use for calls to
RwShowCameraImage(). This variable
is defined in response to WM_PAINT
or WM_TIMER messages */
static RwInt32 UsingDIBs; /* If we are using DIB's then we
don't want to treat the Camera's image
buffer as an HDC */
/* The following variables are used to overlay the text on top of
* the rendered image.
*/
static HFONT fGFont; /* Font used at high detail */
static HFONT fGSFont; /* font used at low detail */
static HFONT fGOldFont; /* Old font to be restored at app clean up */
static int nGOldMode; /* Old background mode to be restored at clean up */
static COLORREF nGOldTColor; /* Old text color */
static HPEN pGOldPen; /* Old pen to be restored at clean up */
/* This flag indicates whether the 3D components of the application
* have been successfully initialized as yet. It is used to guard
* the message loop handler functions from being invoked before the
* 3D components of the application are successfully initialized.
*/
static BOOL nGThreeDInitialized = FALSE;
/* This flag is TRUE if the output image is being stretched (ie low detail)
* and FALSE if it is high detail */
static BOOL nGStretch = FALSE;
/************************************************************************
*
* Function: OsBeginCameraUpdate()
*
* Description: Os specific version of RwBeginCameraUpdate().
* For MS Windows RwBeginCameraUpdate() is passed
* the handle to the window. We use the global
* handle that is setup in the main window handler.
*
* Parameters: Camera - the Camera to pass to RwBeginCameraUpdate()
*
* Return Value: None
*
************************************************************************/
void OsBeginCameraUpdate(RwCamera *Camera)
{
RwBeginCameraUpdate(Camera, (void *)(DWORD)hGAppWindow);
}
/************************************************************************
*
* Function: OsShowCameraImage()
*
* Description: Os specific version of RwShowCameraImage().
* For MS Windows RwShowCameraUpdate() is passed
* a DC to display the image. We use the global PaintDC
* which is either the DC returned by BeginPaint()
* in response to a WM_PAINT message or the DC returned
* by a call to GetDC(hGAppWindow).
*
* Parameters: None
*
* Return Value: None
*
************************************************************************/
void OsShowCameraImage(void)
{
RwShowCameraImage(cpGCamera, (void *)(DWORD)PaintDC);
}
/************************************************************************
*
* Function: OsError()
*
* Description: Os specific error handler. For windows we just
* pop up a message box.
*
* Parameters: fmt - stdarg format string
*
* Return Value: None
*
************************************************************************/
void OsError(char *fmt, ...)
{
char buffer[256];
va_list args;
va_start(args, fmt);
vsprintf(buffer, fmt, args);
va_end(args);
MessageBox(hGAppWindow, buffer, ERROR_DIALOG_TITLE,
MB_OK | MB_ICONSTOP | MB_APPLMODAL);
}
/************************************************************************
*
* Function: OsOpen()
*
* Description: Os specific RwOpen(). This function opens
* RenderWare and sets the Shape Path
*
* Parameters: None
*
* Return Value: TRUE if successful else FALSE
*
************************************************************************/
int OsOpen(void)
{
int i;
char buffer[256];
#ifndef WIN32
RwOpenArgument args;
args.option = rwWINUSEWING;
if (!RwOpenExt("MSWindows", NULL, 1, &args))
#else
if (!RwOpen("MSWindows", NULL))
#endif
{
if (RwGetError() == E_RW_NOMEM)
{
OsError("Insufficient memory to open the RenderWare(tm) library");
}
else
{
OsError("Error opening the RenderWare(tm) library");
}
return FALSE;
}
GetModuleFileName(hGAppInstance, buffer, sizeof(buffer));
i = strlen(buffer);
while(buffer[i] != '\\')
i--;
/* set search path so we pick up our geometry & textures */
buffer[i+1] = 0;
strcat(buffer, "TEXTURES");
RwSetShapePath(buffer, rwREPLACE);
buffer[i+1] = 0;
strcat(buffer, "SCRIPTS");
RwSetShapePath(buffer, rwPRECONCAT);
buffer[i+1] = 0;
strcat(buffer, ".");
RwSetShapePath(buffer, rwPRECONCAT);
SetWindowText(hGAppWindow, "RenderWare CyberStreet");
RwGetDeviceInfo(rwWINIMAGEISDIB, &UsingDIBs, sizeof(UsingDIBs));
return TRUE;
}
/************************************************************************
*
* Function: OsResetCameraViewport()
*
* Description: Reset the camera viewport to have default behaviour.
* For MS Windows the viewport can be stretched so
* we disable this stretching.
*
* Parameters: None
*
* Return Value: None
*
************************************************************************/
void OsResetCameraViewport()
{
RwWinOutputSize winOutputSize;
winOutputSize.width = (RwInt32)-1;
winOutputSize.height = (RwInt32)-1;
winOutputSize.camera = cpGCamera;
RwDeviceControl(rwWINSETOUTPUTSIZE, 0L, &winOutputSize,
sizeof(winOutputSize));
}
/************************************************************************
*
* Function: OsSetCameraViewport()
*
* Description: Os specific RwSetCameraViewport(). For MS Windows
* the viewport can be stretched so we have to take
* account of this before calling RwSetCameraViewport
*
* Parameters: None
*
* Return Value: None
*
************************************************************************/
void OsSetCameraViewport()
{
RwWinOutputSize winOutputSize;
if (nGStretch)
{
RwSetCameraViewport(cpGCamera,
PANEL_HOLE_XOFFSET, PANEL_HOLE_YOFFSET,
PANEL_HOLE_WIDTH/2, PANEL_HOLE_HEIGHT/2);
winOutputSize.width = PANEL_HOLE_WIDTH;
winOutputSize.height = PANEL_HOLE_HEIGHT;
winOutputSize.camera = cpGCamera;
RwDeviceControl(rwWINSETOUTPUTSIZE, 0L, &winOutputSize,
sizeof(winOutputSize));
}
else
{
RwSetCameraViewport(cpGCamera,
PANEL_HOLE_XOFFSET, PANEL_HOLE_YOFFSET,
PANEL_HOLE_WIDTH, PANEL_HOLE_HEIGHT);
}
}
/************************************************************************
*
* Function: OsInit()
*
* Description: Os specific application initialisation. This function
* is called once the palette has been set up and
* performs all of the device specific initialisation
* and object loading
*
* Parameters: None
*
* Return Value: TRUE if successful else FALSE
*
************************************************************************/
int OsInit()
{
HDC devContext;
LOGFONT logFont;
/* Set up the camera viewport */
OsSetCameraViewport();
if (!UsingDIBs)
{
/*
* Select into the DC associated with the Camera the font we'll use
* for drawing the overlay graphics.
*/
devContext = (HDC)RwGetCameraImage(cpGCamera);
memset(&logFont, 0, sizeof(LOGFONT));
logFont.lfHeight = 18;
logFont.lfWeight = FW_BOLD;
logFont.lfItalic = 1;
strcpy(logFont.lfFaceName, "Arial");
fGFont = CreateFontIndirect(&logFont);
if (fGFont)
{
fGOldFont = SelectObject(devContext, fGFont);
}
logFont.lfHeight = 12;
logFont.lfWeight = FW_BOLD;
logFont.lfItalic = 1;
strcpy(logFont.lfFaceName, "Arial");
fGSFont = CreateFontIndirect(&logFont);
nGOldMode = SetBkMode(devContext, TRANSPARENT);
nGOldTColor = SetTextColor(devContext, RGB(255,255,255));
pGOldPen = SelectObject(devContext, CreatePen(PS_SOLID, 1, RGB(255,255,255)));
}
if (!(rpGPanel = RwReadRaster("panel", 0L)))
{
return FALSE;
}
return (TRUE);
}
/************************************************************************
*
* Function: OsMaxCameraWidth()
*
* Description: The maximum camera width is an OS specific
* feature. This function returns this information to
* the main body of the application
*
* Parameters: None
*
* Return Value: TRUE if successful else FALSE
*
************************************************************************/
RwInt32 OsMaxCameraWidth(void)
{
return((RwInt32)MAX_CAMERA_WIDTH);
}
/************************************************************************
*
* Function: OsMaxCameraHeight()
*
* Description: The maximum camera height is an OS specific
* feature. This function returns this information to
* the main body of the application
*
* Parameters: None
*
* Return Value: TRUE if successful else FALSE
*
************************************************************************/
RwInt32 OsMaxCameraHeight(void)
{
return((RwInt32)MAX_CAMERA_HEIGHT);
}
/************************************************************************
*
* Function: OsMaxScreenWidth()
*
* Description: The maximum screen width is an OS specific
* feature. This function returns this information to
* the main body of the application
*
* Parameters: None
*
* Return Value: TRUE if successful else FALSE
*
************************************************************************/
RwInt32 OsMaxScreenWidth(void)
{
return((RwInt32)DEFAULT_WINDOW_WIDTH);
}
/************************************************************************
*
* Function: OsMaxScreenHeight()
*
* Description: The maximum screen height is an OS specific
* feature. This function returns this information to
* the main body of the application
*
* Parameters: None
*
* Return Value: TRUE if successful else FALSE
*
************************************************************************/
RwInt32 OsMaxScreenHeight(void)
{
return((RwInt32)DEFAULT_WINDOW_HEIGHT);
}
/************************************************************************
*
* Function: OsTidy()
*
* Description: Clean up all of the stuff initialised in OsInit()
*
* Parameters: None
*
* Return Value: None
*
************************************************************************/
void OsTidy(void)
{
HDC hdc;
if (!UsingDIBs)
{
hdc = (HDC)RwGetCameraImage(cpGCamera);
DeleteObject(SelectObject(hdc, pGOldPen));
SetTextColor(hdc, nGOldTColor);
SetBkMode(hdc, nGOldMode);
if (fGFont)
{
SelectObject(hdc, fGOldFont);
DeleteObject(fGFont);
}
if (fGSFont)
{
SelectObject(hdc, fGOldFont);
DeleteObject(fGSFont);
}
}
}
/************************************************************************
*
* Function: OsDisplayScore()
*
* Description: Overlay the score on top of the rendered image
*
* Parameters: dead - number of dead rats
* left - number of rats remaining
*
* Return Value: None
*
************************************************************************/
void OsDisplayScore(int dead, int left)
{
HDC camDC;
char caScore[80];
if (!UsingDIBs)
{
camDC = (HDC)RwGetCameraImage(cpGCamera);
/* Draw up the score */
if (nGStretch)
{
sprintf(caScore,"Left: %d", left);
TextOut(camDC, 8>>1,8>>1, caScore, strlen(caScore));
sprintf(caScore,"Dead: %d", dead);
TextOut(camDC, 100>>1,8>>1, caScore, strlen(caScore));
}
else
{
sprintf(caScore,"Left: %d", left);
TextOut(camDC, 8,8, caScore, strlen(caScore));
sprintf(caScore,"Dead: %d", dead);
TextOut(camDC, 100,8, caScore, strlen(caScore));
}
}
}
/************************************************************************
*
* Function: HandleMenu()
*
* Description: Handle input from menus
*
* Parameters: window - the window that the message originated from
* menuItemID - the menu identifier
*
* Return Value: None
*
************************************************************************/
static void
HandleMenu(HWND window, WPARAM menuItemID)
{
HDC devContext;
switch (menuItemID)
{
case FILE_MENU_EXIT_ITEM_ID:
DestroyWindow(window);
break;
case OPTION_MENU_MAG_ITEM_ID: /* Detail menu - toggle stretching */
if (nGStretch)
{
/* Stretching currently on - turn it off */
CheckMenuItem(GetMenu(window),
OPTION_MENU_MAG_ITEM_ID,
MF_BYCOMMAND | MF_CHECKED);
nGStretch = FALSE;
OsSetCameraViewport();
/* No longer stretching so use a bigger font */
devContext = (HDC)RwGetCameraImage(cpGCamera);
SelectObject(devContext, fGFont);
}
else
{
/* Stretching currently off - turn it on */
CheckMenuItem(GetMenu(window),
OPTION_MENU_MAG_ITEM_ID,
MF_BYCOMMAND | MF_UNCHECKED);
nGStretch = TRUE;
OsSetCameraViewport();
devContext = (HDC)RwGetCameraImage(cpGCamera);
SelectObject(devContext, fGSFont);
}
break;
}
}
/************************************************************************
*
* Function: MainWndProc()
*
* Description: Main message handler for this window
*
* Parameters: window - the window that the message originated from
* menuItemID - the menu identifier
*
* Return Value: None
*
************************************************************************/
long far PASCAL
MainWndProc(HWND window, UINT message, WPARAM wParam, LPARAM lParam)
{
POINT point;
#ifdef WIN32
POINTS points = MAKEPOINTS(lParam);
point.x = points.x;
point.y = points.y;
#else
point = MAKEPOINT(lParam);
#endif
hGAppWindow = window;
switch (message)
{
case WM_CREATE:
/*
* In this application, 3D animation is driven by window's
* timer messages, so turn a timer on.
*/
SetTimer(window, 1, 20, NULL);
return 0L;
case WM_DESTROY:
/*
* Turn the timer off.
*/
KillTimer(window, 1);
/*
* Quit message handling.
*/
PostQuitMessage(0);
return 0L;
case WM_LBUTTONDOWN:
if (nGThreeDInitialized)
{
SetCapture(window);
ClientToScreen(window, &point);
HandleLeftButtonDown((RwInt32)point.x, (RwInt32)point.y,
wParam & MK_CONTROL, wParam & MK_SHIFT);
}
return 0L;
case WM_RBUTTONDOWN:
if (nGThreeDInitialized)
{
SetCapture(window);
ClientToScreen(window, &point);
HandleRightButtonDown((RwInt32)point.x, (RwInt32)point.y,
wParam & MK_CONTROL, wParam & MK_SHIFT);
}
return 0L;
case WM_MOUSEMOVE:
if (nGThreeDInitialized)
{
ClientToScreen(window, &point);
HandleMouseMove((RwInt32)point.x, (RwInt32)point.y);
}
return 0L;
case WM_LBUTTONUP:
if (nGThreeDInitialized)
{
ReleaseCapture();
HandleLeftButtonUp();
}
return 0L;
case WM_RBUTTONUP:
if (nGThreeDInitialized)
{
ReleaseCapture();
HandleRightButtonUp();
}
return 0L;
case WM_CHAR:
if (wParam == 'f')
{
ToggleFlyCamera();
}
else if (wParam == 'g')
{
GunToggle();
}
return 0L;
case WM_COMMAND:
if (nGThreeDInitialized)
{
if (LOWORD(lParam) == 0)
{
HandleMenu(window, wParam);
}
}
return 0L;
case WM_PAINT:
{
PAINTSTRUCT ps;
if (nGThreeDInitialized)
{
PaintDC = BeginPaint(hGAppWindow, &ps);
HandlePaint();
EndPaint(hGAppWindow, &ps);
}
return 0L;
}
case WM_TIMER:
if (nGThreeDInitialized)
{
PaintDC = GetDC(hGAppWindow);
HandleTimer();
ReleaseDC(hGAppWindow, PaintDC);
};
return 0L;
};
/*
* Let Windows handle all other messages.
*/
return DefWindowProc(window, message, wParam, lParam);
}
/************************************************************************
*
* Function: InitApplication()
*
* Description: Perform any necessary MS Windows application
* initialization. Basically, this means
* registering the window class for this
* application.
*
* Parameters: instance - the instance handle for this instance
*
* Return Value: the return value from RegisterClass
*
************************************************************************/
static BOOL
InitApplication(HANDLE instance)
{
WNDCLASS windowClass;
windowClass.style = CS_BYTEALIGNWINDOW;
windowClass.lpfnWndProc = (WNDPROC)MainWndProc;
windowClass.cbClsExtra = 0;
windowClass.cbWndExtra = 0;
windowClass.hInstance = instance;
windowClass.hIcon = LoadIcon(instance, "RW_ICON");
windowClass.hCursor = LoadCursor(NULL, IDC_ARROW);
windowClass.hbrBackground = NULL;
windowClass.lpszMenuName = "RWCYBER_MENU";
windowClass.lpszClassName = CYBER_CLASS_NAME;
return RegisterClass(&windowClass);
}
/************************************************************************
*
* Function: InitInstance()
*
* Description: Perform any necessary initialization for this
* instance of the application. This simply means
* creating the application's main window.
*
* Parameters: instance - the instance handle for this instance
*
* Return Value: the return value from CreateWindow
*
************************************************************************/
static HWND
InitInstance(HANDLE instance)
{
/*
* Create the MS Window's window instance for this application. The
* initial window size is given by DEFAULT_WINDOW_WIDTH and
* DEFAULT_WINDOW_HEIGHT. The window is not given a title as we
* set it during OsOpen() with information about the version of
* RenderWare being used.
*/
return CreateWindow(CYBER_CLASS_NAME, "",
WS_OVERLAPPED|WS_CAPTION|WS_SYSMENU|WS_MINIMIZEBOX,
CW_USEDEFAULT, CW_USEDEFAULT,
DEFAULT_WINDOW_WIDTH, DEFAULT_WINDOW_HEIGHT,
NULL, NULL, instance, NULL);
}
/************************************************************************
*
* Function: WinMain()
*
* Description: Ms Windows application entry point
*
* Parameters: instance - the instance handle for this instance
*
* Return Value: the return value from CreateWindow
*
************************************************************************/
int PASCAL
WinMain(HANDLE instance, HANDLE prevInstance, LPSTR cmdLine, int cmdShow)
{
MSG message;
HWND window;
/*
* Remember the instance handle in a global variable for later use.
*/
hGAppInstance = instance;
if (prevInstance)
{
/*
* Only allow one cyberstreet to run at any one time.
*/
MessageBox((HWND)0, "RwCyber is already running...",
ERROR_DIALOG_TITLE, MB_OK | MB_ICONSTOP | MB_APPLMODAL);
return FALSE;
}
/*
* Register the window class.
*/
if (!InitApplication(instance))
{
return FALSE;
}
/*
* Create the window.
*/
if (!(window = InitInstance(instance)))
{
return FALSE;
}
hGAppWindow = window;
/* Setup menus */
nGStretch = FALSE;
CheckMenuItem(GetMenu(window), OPTION_MENU_MAG_ITEM_ID, MF_BYCOMMAND | MF_CHECKED);
/*
* Initialize the 3D (RenderWare) components of the app.
*/
if (!Init3D())
{
DestroyWindow(window);
return FALSE;
}
nGThreeDInitialized = TRUE;
if (AllowStretching(window))
{
EnableMenuItem(GetMenu(window), OPTION_MENU_MAG_ITEM_ID, MF_ENABLED);
}
/* Load all of the sound effects */
#ifdef WITH_SOUND
AllSoundsAddSound("gun.wav",0);
AllSoundsAddSound("ricochet.wav",1);
AllSoundsAddSound("squish.wav",2);
AllSoundsAddSound("squeak.wav",2);
AllSoundsAddSound("boink.wav",3);
AllSoundsAddSound("ratty.wav",2);
AllSoundsAddSound("ratty2.wav",2);
AllSoundsAddSound("clang.wav",2);
#endif
/*
* Show the window, and refresh it.
*/
ShowWindow(window, cmdShow);
UpdateWindow(window);
/*
* Enter the message processing loop.
*/
while (GetMessage(&message, (HWND)0, 0, 0))
{
TranslateMessage(&message);
DispatchMessage(&message);
}
hGAppWindow = NULL;
/*
* Tidy up the 3D (RenderWare) components of the application.
*/
TidyUp3D();
UnregisterClass(CYBER_CLASS_NAME, instance);
return message.wParam;
}