home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Learn 3D Graphics Programming on the PC
/
Learn_3D_Graphics_Programming_on_the_PC_Ferraro.iso
/
rwwin
/
rwshop.c_
/
rwshop.bin
Wrap
Text File
|
1995-11-14
|
44KB
|
1,435 lines
/**********************************************************************
*
* File : rwshop.c
*
* Abstract : RenderWare Shop demo. Main module
*
**********************************************************************
*
* 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.
*
************************************************************************/
/**********************************************************************
*
* Header files.
*
**********************************************************************/
#define INCLUDE_SHELLAPI_H
#include <windows.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "common.h"
#include "resource.h"
#include "gdi3d.h"
#include "rwlib.h"
#include "rwwin.h"
/**********************************************************************
*
* Application constants.
*
**********************************************************************/
#if !defined(__WINDOWS_386__)
#define MK_FP32(x) (x)
#endif
#define RWSHOP_CLASS_NAME "RwTeleShopClass"
#define RWWINDOW_CLASS_NAME "RwWindowClass"
#define RWMOVEBUTTON_CLASS_NAME "RwMoveButtonClass"
#define ERROR_DIALOG_TITLE "RenderWare TeleShopping Error"
#define DEFAULT_WINDOW_WIDTH 400
#define DEFAULT_WINDOW_HEIGHT 400
#define MAXIMUM_WINDOW_WIDTH 512
#define MAXIMUM_WINDOW_HEIGHT 512
#define DEFAULT_WORLD_MIN_X CREAL(-1.7)
#define DEFAULT_WORLD_MIN_Z CREAL(-1.7)
#define DEFAULT_WORLD_MAX_X CREAL(1.7)
#define DEFAULT_WORLD_MAX_Z CREAL(1.7)
#define DEFAULT_CAMERA_X CREAL(0.0)
#define DEFAULT_CAMERA_Y CREAL(0.75)
#define DEFAULT_CAMERA_Z DEFAULT_WORLD_MAX_Z
#define DEFAULT_CAMERA_FORWARD_DELTA CREAL(0.1)
#define DEFAULT_CAMERA_RIGHT_DELTA CREAL(0.1)
#define DEFAULT_CAMERA_TURN_DELTA CREAL(5.0)
#define MAX_OBJECT_NAME 30
#define DEFAULT_STATUS_MESSAGE "Right Button - Price an object"
/**********************************************************************
*
* Forward functions.
*
**********************************************************************/
extern long far PASCAL
WindowProc(HWND, WORD, WPARAM, LPARAM);
extern long far PASCAL
RenderWareWindowProc(HWND, WORD, WPARAM, LPARAM);
extern long far PASCAL
MoveButtonWindowProc(HWND, WORD, WPARAM, LPARAM);
/**********************************************************************
*
* Type definitions.
*
**********************************************************************/
typedef enum
{
SHOP_NONE,
SHOP_ART
} ShopType;
typedef enum
{
MMNoAction,
MMSpinClump,
} MMMode;
typedef enum
{
ANoAction,
ASpinClump
} AMode;
typedef enum
{
NoMove,
MoveForward,
MoveBackward,
MoveLeft,
MoveRight,
TurnLeft,
TurnRight
} MAction;
typedef struct
{
char i_name[MAX_OBJECT_NAME];
RwReal i_price;
int spin_flag;
RwReal spin_delta;
} ObjectInfo;
/**********************************************************************
*
* Application global variables.
*
**********************************************************************/
static RwInt32 UsingDib = FALSE;
static HANDLE AppInstance;
static RwScene *Scene = NULL;
static RwCamera *Camera = NULL;
static RwLight *Light = NULL;
static RwClump *ShopClump = NULL;
static RwClump *MallClump = NULL;
static RwClump *PickedClump = NULL;
static RwMatrix4d *SpinMatrix = NULL;
#if defined(USE_USERDRAW)
static RwUserDraw *UserDraw = NULL;
#endif
static MMMode MouseMoveMode = MMNoAction;
static ShopType Shop = SHOP_NONE;
static int LastX;
static int LastY;
static RwReal CameraTilt = CREAL(0.0);
static HFONT Font = (HFONT)0;
static MAction MoveAction = NoMove;
static BOOL RenderFlag = TRUE;
static RwReal CameraForwardDelta = DEFAULT_CAMERA_FORWARD_DELTA;
static RwReal CameraRightDelta = DEFAULT_CAMERA_RIGHT_DELTA;
static RwReal CameraTurnDelta = DEFAULT_CAMERA_TURN_DELTA;
static BOOL ThreeDInitialized = FALSE;
static HWND Window;
/**********************************************************************
*
* Functions.
*
**********************************************************************/
/**********************************************************************/
static void
SetStatusMessage(char *message)
{
if (Window)
SetDlgItemText(Window, STATUS_BAR_CONTROL_ID, message);
}
/**********************************************************************/
static ObjectInfo *
CreateObjectInfo(char *name, RwReal price, int spin)
{
ObjectInfo *objectInfo;
if (objectInfo = (ObjectInfo*)malloc(sizeof(ObjectInfo)))
{
strcpy(objectInfo->i_name, name);
objectInfo->i_price = price;
objectInfo->spin_flag = spin;
objectInfo->spin_delta = CREAL(0.0);
}
return objectInfo;
}
/**********************************************************************/
static RwClump *
DestroyObjectInfo(RwClump *clump)
{
if (RwGetClumpData(clump))
free(RwGetClumpData(clump));
return(clump);
}
/**********************************************************************/
static BOOL
InitApplication(HANDLE instance)
{
WNDCLASS windowClass;
windowClass.style = CS_HREDRAW | CS_VREDRAW;
windowClass.lpfnWndProc = (WNDPROC)WindowProc;
windowClass.cbClsExtra = 0;
windowClass.cbWndExtra = DLGWINDOWEXTRA;
windowClass.hInstance = instance;
windowClass.hIcon = LoadIcon(instance, MAKEINTRESOURCE(RW_ICON));
windowClass.hCursor = LoadCursor(NULL, IDC_ARROW);
windowClass.hbrBackground = NULL;
windowClass.lpszMenuName = "MAIN_MENU";
windowClass.lpszClassName = RWSHOP_CLASS_NAME;
if (!RegisterClass(&windowClass))
{
return FALSE;
}
windowClass.style = CS_HREDRAW | CS_VREDRAW;
windowClass.lpfnWndProc = (WNDPROC)MoveButtonWindowProc;
windowClass.cbClsExtra = 0;
windowClass.cbWndExtra = 0;
windowClass.hInstance = instance;
windowClass.hIcon = NULL;
windowClass.hCursor = LoadCursor(NULL, IDC_ARROW);
windowClass.hbrBackground = NULL;
windowClass.lpszMenuName = NULL;
windowClass.lpszClassName = RWMOVEBUTTON_CLASS_NAME;
if (!RegisterClass(&windowClass))
{
return FALSE;
}
windowClass.style = CS_HREDRAW | CS_VREDRAW;
windowClass.lpfnWndProc = (WNDPROC)RenderWareWindowProc;
windowClass.cbClsExtra = 0;
windowClass.cbWndExtra = 0;
windowClass.hInstance = instance;
windowClass.hIcon = NULL;
windowClass.hCursor = LoadCursor(NULL, IDC_ARROW);
windowClass.hbrBackground = NULL;
windowClass.lpszMenuName = NULL;
windowClass.lpszClassName = RWWINDOW_CLASS_NAME;
return RegisterClass(&windowClass);
}
/**********************************************************************/
static HWND
InitInstance(HANDLE instance)
{
return CreateDialog(instance, "TeleshoppingDialog", 0, NULL);
}
/**********************************************************************/
#if defined(USE_USERDRAW)
static RwUserDraw *
UserDrawCallBack(RwUserDraw *userDraw, void *camImage, RwRect *rect,
void *data)
{
HDC devContext;
HFONT oldFont;
int oldMode;
COLORREF oldColor;
SIZE extent;
ObjectInfo *objectInfo;
char buffer[30];
if (!data)
return(userDraw);
objectInfo = (ObjectInfo*)data;
sprintf(buffer, "%s $%0.2lf", objectInfo->i_name, REAL2FL(objectInfo->i_price));
if (!UsingDib)
{
devContext = (HDC)camImage;
if (Font)
oldFont = SelectObject(devContext, Font);
GetTextExtentPoint(devContext, buffer, strlen(buffer), &extent);
oldMode = SetBkMode(devContext, TRANSPARENT);
oldColor = SetTextColor(devContext, RGB(0, 0, 0));
TextOut(devContext, (int)(rect->x + ((rect->w / 2) - (extent.cx / 2))),
(int)(rect->y + ((rect->h / 2) - (extent.cy / 2))),
buffer, strlen(buffer));
SetTextColor(devContext, RGB(255, 255, 255));
TextOut(devContext, (int)(rect->x + ((rect->w / 2) - (extent.cx / 2)) - 2),
(int)(rect->y + ((rect->h / 2) - (extent.cy / 2)) - 2),
buffer, strlen(buffer));
SetBkMode(devContext, oldMode);
SetTextColor(devContext, oldColor);
if (Font)
SelectObject(devContext, oldFont);
}
else
{
SetStatusMessage(buffer);
}
return(userDraw);
}
#endif
/**********************************************************************/
static RwClump *
LoadClump(char *fileName)
{
RwClump *clump;
char buffer[128];
clump = RwReadShape(fileName);
if (!clump)
{
switch (RwGetError())
{
case E_RW_NOMEM:
sprintf(buffer, "Insufficient memory to load script %s",
fileName);
MessageBox(NULL, buffer, ERROR_DIALOG_TITLE,
MB_OK | MB_ICONSTOP | MB_APPLMODAL);
return NULL;
default:
sprintf(buffer,
"Error reading the script file %s",
fileName);
MessageBox(NULL, buffer, ERROR_DIALOG_TITLE,
MB_OK | MB_ICONSTOP | MB_APPLMODAL);
return NULL;
}
}
return clump;
}
/**********************************************************************/
static BOOL
Init3D(HANDLE instance)
{
char buffer[128];
LOGFONT logFont;
DWORD extent;
RwClump *clump;
ObjectInfo *objectInfo;
int i;
if (!RwOpen("MSWindows", NULL))
{
if (RwGetError() == E_RW_NOMEM)
{
MessageBox(NULL,
"Insufficient memory to open the RenderWare library",
ERROR_DIALOG_TITLE, MB_OK | MB_ICONSTOP | MB_APPLMODAL);
}
else
{
MessageBox(NULL, "Error opening the RenderWare library",
ERROR_DIALOG_TITLE, MB_OK | MB_ICONSTOP | MB_APPLMODAL);
}
return FALSE;
}
/*
* Determine if userdraw functinality is available and set the global flag
* accordingly
*/
RwGetDeviceInfo(rwWINIMAGEISDIB, &UsingDib, sizeof(RwInt32));
/*--- Set the shape path to enable texture loading ---*/
GetModuleFileName(instance, buffer, sizeof(buffer));
i = strlen(buffer);
while(buffer[i] != '\\')
i--;
buffer[i+1] = 0;
strcat(buffer, "TEXTURES");
RwSetShapePath(buffer, rwREPLACE);
buffer[i+1] = 0;
strcat(buffer, "SCRIPTS");
RwSetShapePath(buffer, rwPOSTCONCAT);
buffer[i+1] = 0;
strcat(buffer, ".");
RwSetShapePath(buffer, rwPOSTCONCAT);
Camera = RwCreateCamera(MAXIMUM_WINDOW_WIDTH, MAXIMUM_WINDOW_HEIGHT, NULL);
if (!Camera)
{
if (RwGetError() == E_RW_NOMEM)
{
MessageBox(NULL,
"Insufficient memory to create the RenderWare camera",
ERROR_DIALOG_TITLE, MB_OK | MB_ICONSTOP | MB_APPLMODAL);
}
else
{
MessageBox(NULL, "Error creating the RenderWare camera",
ERROR_DIALOG_TITLE, MB_OK | MB_ICONSTOP | MB_APPLMODAL);
}
RwClose();
return FALSE;
}
RwSetCameraBackColor(Camera, CREAL(0.5), CREAL(0.5), CREAL(1.0));
RwTiltCamera(Camera, CameraTilt);
RwSetCameraPosition(Camera, DEFAULT_CAMERA_X, DEFAULT_CAMERA_Y, DEFAULT_CAMERA_Z);
RwSetCameraViewwindow(Camera, CREAL(0.4), CREAL(0.4));
Scene = RwCreateScene();
if (!Scene)
{
RwDestroyCamera(Camera);
RwClose();
MessageBox(NULL, "Error creating the RenderWare scene",
ERROR_DIALOG_TITLE, MB_OK | MB_ICONSTOP | MB_APPLMODAL);
return FALSE;
}
Light = RwCreateLight(rwPOINT, CREAL(0.5), CREAL(1.2), CREAL(0.0),
CREAL(1.0));
if (!Light)
{
RwDestroyScene(Scene);
RwDestroyCamera(Camera);
RwClose();
MessageBox(NULL, "Error creating the RenderWare light",
ERROR_DIALOG_TITLE, MB_OK | MB_ICONSTOP | MB_APPLMODAL);
return FALSE;
}
RwAddLightToScene(Scene, Light);
SpinMatrix = RwCreateMatrix();
if (!SpinMatrix)
{
RwDestroyScene(Scene);
RwDestroyCamera(Camera);
RwClose();
MessageBox(NULL, "Error creating the RenderWare matrix",
ERROR_DIALOG_TITLE, MB_OK | MB_ICONSTOP | MB_APPLMODAL);
return FALSE;
}
MallClump = LoadClump("mall.rwx");
if (!MallClump)
{
RwDestroyScene(Scene);
RwDestroyCamera(Camera);
RwClose();
return FALSE;
}
RwAddHintToClump(MallClump, rwCONTAINER);
RwTranslateMatrix(RwScratchMatrix(), CREAL(0.0), CREAL(0.0), DEFAULT_WORLD_MIN_Z, rwREPLACE);
RwTransformClump(MallClump, RwScratchMatrix(), rwREPLACE);
RwAddClumpToScene(Scene, MallClump);
ShopClump = LoadClump("shop.rwx");
if (!ShopClump)
{
RwDestroyScene(Scene);
RwDestroyCamera(Camera);
RwClose();
return FALSE;
}
/* RwAddClumpToScene(Scene, ShopClump); */
if (clump = RwFindTaggedClump(ShopClump, 1))
{
objectInfo = CreateObjectInfo("Wooden Bowl", CREAL(75.95), TRUE);
if (objectInfo)
RwSetClumpData(clump, objectInfo);
}
if (clump = RwFindTaggedClump(ShopClump, 2))
{
objectInfo = CreateObjectInfo("Glass Vase", CREAL(299.99), TRUE);
if (objectInfo)
RwSetClumpData(clump, objectInfo);
}
if (clump = RwFindTaggedClump(ShopClump, 3))
{
objectInfo = CreateObjectInfo("Ornament", CREAL(1000.00), TRUE);
if (objectInfo)
RwSetClumpData(clump, objectInfo);
}
if (clump = RwFindTaggedClump(ShopClump, 4))
{
objectInfo = CreateObjectInfo("Le Printemps", CREAL(30000.00), FALSE);
if (objectInfo)
RwSetClumpData(clump, objectInfo);
}
if (clump = RwFindTaggedClump(ShopClump, 5))
{
objectInfo = CreateObjectInfo("Landscape", CREAL(9.50), FALSE);
if (objectInfo)
RwSetClumpData(clump, objectInfo);
}
memset(&logFont, 0, sizeof(LOGFONT));
logFont.lfHeight = 28;
strcpy(logFont.lfFaceName, "Arial Italic");
Font = CreateFontIndirect(&logFont);
extent = MAKELONG(400, 32);
#if defined(USE_USERDRAW)
UserDraw = RwCreateUserDraw(rwBBOXALIGN, rwALIGNBOTTOM, 0, 5,
LOWORD(extent) + 5, HIWORD(extent) + 5,
UserDrawCallBack);
if (!UserDraw)
{
RwDestroyScene(Scene);
RwDestroyCamera(Camera);
RwClose();
MessageBox(NULL, "Error creating the RenderWare user-draw",
ERROR_DIALOG_TITLE, MB_OK | MB_ICONSTOP | MB_APPLMODAL);
return FALSE;
}
RwSetUserDrawParentAlignment(UserDraw, rwALIGNBOTTOM);
#endif
ThreeDInitialized = TRUE;
return TRUE;
}
/**********************************************************************/
static void
TidyUp3D()
{
#if defined(USE_USERDRAW)
RwDestroyUserDraw(UserDraw);
#endif
if (Font)
DeleteObject(Font);
RwForAllClumpsInScene(Scene, DestroyObjectInfo);
RwDestroyMatrix(SpinMatrix);
RwDestroyScene(Scene);
RwDestroyCamera(Camera);
RwClose();
}
/**********************************************************************/
static void
HandleSizeRw(HWND window, int width, int height)
{
RwSetCameraViewport(Camera, 2, 2, width - 4, height - 4);
InvalidateRect(window, NULL, FALSE);
}
/**********************************************************************/
static void
HandleLeftButtonDownRw(HWND window, int x, int y)
{
RwPickRecord pick;
POINT pos;
ObjectInfo *info;
if (RwPickScene(Scene, x, y, Camera, &pick))
{
PickedClump = NULL;
switch (pick.type)
{
case rwNAPICKOBJECT:
MouseMoveMode = MMNoAction;
break;
case rwPICKCLUMP:
info = RwGetClumpData(pick.object.clump.clump);
if (info && info->spin_flag)
{
PickedClump = pick.object.clump.clump;
MouseMoveMode = MMSpinClump;
SetStatusMessage("Spin Object");
}
else
MouseMoveMode = MMNoAction;
break;
}
}
if (MouseMoveMode != MMNoAction)
{
SetCapture(window);
pos.x = x;
pos.y = y;
ClientToScreen(window, &pos);
LastX = pos.x;
LastY = pos.y;
RenderFlag = TRUE;
}
}
/**********************************************************************/
static void
HandleRightButtonDownRw(HWND window, int x, int y)
{
RwPickRecord pick;
if (RwPickScene(Scene, x, y, Camera, &pick) && (pick.type == rwPICKCLUMP))
{
if (RwGetClumpData(pick.object.clump.clump))
{
PickedClump = pick.object.clump.clump;
#if defined(USE_USERDRAW)
RwAddUserDrawToClump(PickedClump, UserDraw);
RwSetUserDrawData(UserDraw, RwGetClumpData(PickedClump));
#endif
RenderFlag = TRUE;
if (!UsingDib)
SetStatusMessage("Display Object Price");
}
else
PickedClump = NULL;
}
SetCapture(window);
}
/**********************************************************************/
static void
HandleMouseMoveRw(HWND window, int x, int y)
{
POINT pos;
RwReal xDelta;
ObjectInfo *info;
pos.x = x;
pos.y = y;
ClientToScreen(window, &pos);
switch (MouseMoveMode)
{
case MMNoAction:
break;
case MMSpinClump:
xDelta = INT2REAL(pos.x - LastX);
info = RwGetClumpData(PickedClump);
info->spin_delta = RAdd(info->spin_delta, xDelta);
if (info->spin_delta > CREAL(360.0))
info->spin_delta = RSub(info->spin_delta, CREAL(360.0));
if (info->spin_delta < CREAL(-360.0))
info->spin_delta = RAdd(info->spin_delta, CREAL(360.0));
RwRotateMatrix(SpinMatrix, CREAL(0.0), CREAL(1.0), CREAL(0.0), info->spin_delta, rwREPLACE);
RwTransformClumpJoint(PickedClump, SpinMatrix, rwREPLACE);
RenderFlag = TRUE;
break;
}
/* Remember the current X and Y for next time. */
LastX = pos.x;
LastY = pos.y;
}
/**********************************************************************/
static void
HandleLeftButtonUpRw()
{
if (MouseMoveMode != MMNoAction)
{
MouseMoveMode = MMNoAction;
ReleaseCapture();
SetStatusMessage(DEFAULT_STATUS_MESSAGE);
}
}
/**********************************************************************/
static void
HandleRightButtonUpRw()
{
#if defined(USE_USERDRAW)
if (RwGetUserDrawOwner(UserDraw))
{
RwRemoveUserDrawFromClump(UserDraw);
RenderFlag = TRUE;
SetStatusMessage(DEFAULT_STATUS_MESSAGE);
}
#endif
ReleaseCapture();
}
/**********************************************************************/
static void
HandlePaintRw(HWND window)
{
HDC devContext;
PAINTSTRUCT ps;
RECT rect;
devContext = BeginPaint(window, &ps);
GetClientRect(window, &rect);
FrameRect3D(devContext, rect.left, rect.top, rect.right, rect.bottom, FALSE);
FrameRect3D(devContext, rect.left + 1, rect.top + 1, rect.right - 1, rect.bottom - 1, FALSE);
RwInvalidateCameraViewport(Camera);
RwBeginCameraUpdate(Camera, (void *)(DWORD)window);
RwClearCameraViewport(Camera);
RwRenderScene(Scene);
RwEndCameraUpdate(Camera);
RenderFlag = FALSE;
RwShowCameraImage(Camera, (void*)(DWORD)devContext);
EndPaint(window, &ps);
}
/**********************************************************************/
RwClump *ScaleDoors(RwClump *clump)
{
RwInt32 tag;
tag = RwGetClumpTag(clump);
if ((tag == 7L) || (tag == 8L))
{
RwTransformClumpJoint(clump, RwScratchMatrix(), rwREPLACE);
}
return(clump);
}
/**********************************************************************/
static int ChangeShop(RwV3d *pos)
{
RwReal delta;
switch(Shop)
{
case SHOP_NONE:
if ((pos->x < CREAL(0.5)) &&
(pos->x > CREAL(-0.5)))
{
delta = RSub(pos->z, DEFAULT_WORLD_MIN_Z);
RwScaleMatrix(RwScratchMatrix(), RAdd(CREAL(0.5), RDiv(delta, CREAL(6.8))), CREAL(1.0), CREAL(1.0), rwREPLACE);
RwForAllClumpsInHierarchy(MallClump, ScaleDoors);
if (pos->z < (RAdd(DEFAULT_WORLD_MIN_Z, CREAL(0.3))))
{
RwSetCameraPosition(Camera, pos->x, pos->y, RSub(DEFAULT_WORLD_MAX_Z, CREAL(0.3)));
RwRemoveClumpFromScene(MallClump);
RwAddClumpToScene(Scene, ShopClump);
Shop = SHOP_ART;
return(1);
}
}
else
{
RwScaleMatrix(RwScratchMatrix(), CREAL(1.0), CREAL(1.0), CREAL(1.0), rwREPLACE);
RwForAllClumpsInHierarchy(MallClump, ScaleDoors);
}
break;
case SHOP_ART:
if ((pos->x < CREAL(0.5)) &&
(pos->x > CREAL(-0.5)))
{
delta = RSub(DEFAULT_WORLD_MAX_Z, pos->z);
RwScaleMatrix(RwScratchMatrix(), RAdd(CREAL(0.5), RDiv(delta, CREAL(6.8))), CREAL(1.0), CREAL(1.0), rwREPLACE);
RwForAllClumpsInHierarchy(ShopClump, ScaleDoors);
if (pos->z > RSub(DEFAULT_WORLD_MAX_Z, CREAL(0.3)))
{
RwSetCameraPosition(Camera, pos->x, pos->y, RAdd(DEFAULT_WORLD_MIN_Z, CREAL(0.3)));
RwRemoveClumpFromScene(ShopClump);
RwAddClumpToScene(Scene, MallClump);
Shop = SHOP_NONE;
return(1);
}
}
else
{
RwScaleMatrix(RwScratchMatrix(), CREAL(1.0), CREAL(1.0), CREAL(1.0), rwREPLACE);
RwForAllClumpsInHierarchy(ShopClump, ScaleDoors);
}
break;
}
return(0);
}
/**********************************************************************/
static void
HandleTimerRw(HWND window)
{
HDC devContext;
RwV3d pos, v, posdelta;
int moveflag = FALSE;
if (MoveAction != NoMove)
{
/* get flattened look at without moving camera */
RwGetCameraLookAt(Camera, &v);
v.y = CREAL(0.0);
RwNormalize(&v);
switch (MoveAction)
{
case MoveForward:
posdelta.x = RMul(CameraForwardDelta, v.x);
posdelta.z = RMul(CameraForwardDelta, v.z);
moveflag = TRUE;
break;
case MoveBackward:
posdelta.x = RMul(-CameraForwardDelta, v.x);
posdelta.z = RMul(-CameraForwardDelta, v.z);
moveflag = TRUE;
break;
case MoveLeft:
RwGetCameraLookRight(Camera, &v);
posdelta.x = RMul(-CameraRightDelta, v.x);
posdelta.z = RMul(-CameraRightDelta, v.z);
moveflag = TRUE;
break;
case MoveRight:
RwGetCameraLookRight(Camera, &v);
posdelta.x = RMul(CameraRightDelta, v.x);
posdelta.z = RMul(CameraRightDelta, v.z);
moveflag = TRUE;
break;
case TurnLeft:
RwTiltCamera(Camera, -CameraTilt);
RwPanCamera(Camera, CameraTurnDelta);
RwTiltCamera(Camera, CameraTilt);
break;
case TurnRight:
RwTiltCamera(Camera, -CameraTilt);
RwPanCamera(Camera, -CameraTurnDelta);
RwTiltCamera(Camera, CameraTilt);
break;
}
if (moveflag)
{
RwGetCameraPosition(Camera, &pos);
pos.x = RAdd(pos.x, posdelta.x);
pos.z = RAdd(pos.z, posdelta.z);
if (!ChangeShop(&pos))
{
if ((pos.x >= DEFAULT_WORLD_MIN_X) &&
(pos.z >= DEFAULT_WORLD_MIN_Z) &&
(pos.x <= DEFAULT_WORLD_MAX_X) &&
(pos.z <= DEFAULT_WORLD_MAX_Z))
{
RwSetCameraPosition(Camera, pos.x, pos.y, pos.z);
}
else
{
SetStatusMessage("Against the wall");
}
}
}
RenderFlag = TRUE;
}
if (RenderFlag)
{
RwBeginCameraUpdate(Camera, (void *)(DWORD)window);
RwClearCameraViewport(Camera);
RwRenderScene(Scene);
RwEndCameraUpdate(Camera);
devContext = GetDC(window);
RwShowCameraImage(Camera, (void*)(DWORD)devContext);
ReleaseDC(window, devContext);
RenderFlag = FALSE;
}
}
/**********************************************************************/
long far PASCAL
RenderWareWindowProc(HWND window, WORD message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_CREATE:
SetTimer(window, 1, 20, NULL);
return 0L;
case WM_SIZE:
if (ThreeDInitialized)
HandleSizeRw(window, LOWORD(lParam), HIWORD(lParam));
return 0L;
case WM_LBUTTONDOWN:
if (ThreeDInitialized)
HandleLeftButtonDownRw(window, LOWORD(lParam), HIWORD(lParam));
return 0L;
case WM_RBUTTONDOWN:
if (ThreeDInitialized)
HandleRightButtonDownRw(window, LOWORD(lParam), HIWORD(lParam));
return 0L;
case WM_MOUSEMOVE:
if (ThreeDInitialized)
{
if (MouseMoveMode != MMNoAction)
HandleMouseMoveRw(window, LOWORD(lParam), HIWORD(lParam));
}
return 0L;
case WM_LBUTTONUP:
if (ThreeDInitialized)
HandleLeftButtonUpRw();
return 0L;
case WM_RBUTTONUP:
if (ThreeDInitialized)
HandleRightButtonUpRw();
return 0L;
case WM_PAINT:
if (ThreeDInitialized)
HandlePaintRw(window);
return 0L;
case WM_TIMER:
if (ThreeDInitialized)
HandleTimerRw(window);
return 0L;
case WM_DESTROY:
KillTimer(window, 1);
return 0L;
}
return DefWindowProc(window, message, wParam, lParam);
}
/**********************************************************************/
long far PASCAL
MoveButtonWindowProc(HWND window, WORD message, WPARAM wParam, LPARAM lParam)
{
int x;
int y;
int width;
int height;
RECT rect;
BOOL selected;
HBITMAP bitmap;
HBITMAP oldBitmap;
BITMAP bitmapInfo;
HDC devContext;
HDC bitmapDevContext;
PAINTSTRUCT paintStruct;
switch (message)
{
case WM_CREATE:
return 0L;
case WM_LBUTTONDOWN:
#ifdef WIN32
switch (GetWindowLong(window, GWL_ID))
#else
switch (GetWindowWord(window, GWW_ID))
#endif
{
case FORWARD_BUTTON_ID:
MoveAction = MoveForward;
SetStatusMessage("Move forward");
break;
case BACKWARD_BUTTON_ID:
MoveAction = MoveBackward;
SetStatusMessage("Move backward");
break;
case LEFT_BUTTON_ID:
MoveAction = MoveLeft;
SetStatusMessage("Move left");
break;
case RIGHT_BUTTON_ID:
MoveAction = MoveRight;
SetStatusMessage("Move right");
break;
case TURN_LEFT_BUTTON_ID:
MoveAction = TurnLeft;
SetStatusMessage("Turn left");
break;
case TURN_RIGHT_BUTTON_ID:
MoveAction = TurnRight;
SetStatusMessage("Turn right");
break;
}
if (MoveAction != NoMove)
{
SetCapture(window);
InvalidateRect(window, NULL, FALSE);
}
return 0L;
case WM_MOUSEMOVE:
return 0L;
case WM_LBUTTONUP:
if (MoveAction != NoMove)
{
ReleaseCapture();
MoveAction = NoMove;
SetStatusMessage(DEFAULT_STATUS_MESSAGE);
InvalidateRect(window, NULL, FALSE);
}
return 0L;
case WM_PAINT:
devContext = BeginPaint(window, &paintStruct);
GetClientRect(window, &rect);
#ifdef WIN32
switch (GetWindowLong(window, GWL_ID))
#else
switch (GetWindowWord(window, GWW_ID))
#endif
{
case FORWARD_BUTTON_ID:
bitmap = LoadBitmap(AppInstance, MAKEINTRESOURCE(FORWARD_BITMAP_ID));
selected = (MoveAction == MoveForward);
break;
case BACKWARD_BUTTON_ID:
bitmap = LoadBitmap(AppInstance, MAKEINTRESOURCE(BACKWARD_BITMAP_ID));
selected = (MoveAction == MoveBackward);
break;
case LEFT_BUTTON_ID:
bitmap = LoadBitmap(AppInstance, MAKEINTRESOURCE(LEFT_BITMAP_ID));
selected = (MoveAction == MoveLeft);
break;
case RIGHT_BUTTON_ID:
bitmap = LoadBitmap(AppInstance, MAKEINTRESOURCE(RIGHT_BITMAP_ID));
selected = (MoveAction == MoveRight);
break;
case TURN_LEFT_BUTTON_ID:
bitmap = LoadBitmap(AppInstance, MAKEINTRESOURCE(TURN_LEFT_BITMAP_ID));
selected = (MoveAction == TurnLeft);
break;
case TURN_RIGHT_BUTTON_ID:
bitmap = LoadBitmap(AppInstance, MAKEINTRESOURCE(TURN_RIGHT_BITMAP_ID));
selected = (MoveAction == TurnRight);
break;
}
FrameRect(devContext, &rect, GetStockObject(BLACK_BRUSH));
FrameRect3D(devContext, rect.left + 1,
rect.top + 1,
rect.right - 1,
rect.bottom - 1,
!selected);
Rectangle3D(devContext, rect.left + 2,
rect.top + 2,
rect.right - 2,
rect.bottom - 2,
!selected);
if (bitmap)
{
GetObject(bitmap, sizeof(BITMAP), &bitmapInfo);
width = bitmapInfo.bmWidth;
height = bitmapInfo.bmHeight;
x = rect.left + (((rect.right - rect.left) - width) >> 1);
y = rect.top + (((rect.bottom - rect.top) - height) >> 1);
bitmapDevContext = CreateCompatibleDC(devContext);
oldBitmap = SelectObject(bitmapDevContext, bitmap);
BitBlt(devContext, x, y, width, height, bitmapDevContext, 0, 0, SRCCOPY);
SelectObject(bitmapDevContext, oldBitmap);
DeleteObject(bitmap);
DeleteDC(bitmapDevContext);
}
EndPaint(window, &paintStruct);
return 0L;
case WM_DESTROY:
return 0L;
}
return DefWindowProc(window, message, wParam, lParam);
}
/**********************************************************************/
static void
HandleDrawItem(UINT controlID, DRAWITEMSTRUCT FAR *drawItem)
{
HFONT oldFont;
char buffer[256];
int oldMode;
int x;
int y;
SIZE extent;
int width;
int height;
BOOL selected;
HBITMAP bitmap;
HBITMAP oldBitmap;
BITMAP bitmapInfo;
HDC bitmapDevContext;
RECT rect;
switch (controlID)
{
case STATUS_BAR_CONTROL_ID:
oldFont = SelectObject(drawItem->hDC, GetStockObject(ANSI_VAR_FONT));
GetWindowText(drawItem->hwndItem, buffer, sizeof(buffer));
GetTextExtentPoint(drawItem->hDC, buffer, strlen(buffer), &extent);
Rectangle3D(drawItem->hDC, drawItem->rcItem.left,
drawItem->rcItem.top,
drawItem->rcItem.right,
drawItem->rcItem.bottom,
FALSE);
x = drawItem->rcItem.left + 6;
y = drawItem->rcItem.top + (((drawItem->rcItem.bottom - drawItem->rcItem.top) - extent.cy) >> 1);
oldMode = SetBkMode(drawItem->hDC, TRANSPARENT);
TextOut(drawItem->hDC, x, y, buffer, strlen(buffer));
SetBkMode(drawItem->hDC, oldMode);
SelectObject(drawItem->hDC, oldFont);
break;
case LOOK_UP_BUTTON_ID:
case LOOK_AHEAD_BUTTON_ID:
case LOOK_DOWN_BUTTON_ID:
switch (controlID)
{
case LOOK_UP_BUTTON_ID:
bitmap = LoadBitmap(AppInstance, MAKEINTRESOURCE(LOOK_UP_BITMAP_ID));
break;
case LOOK_AHEAD_BUTTON_ID:
bitmap = LoadBitmap(AppInstance, MAKEINTRESOURCE(LOOK_AHEAD_BITMAP_ID));
break;
case LOOK_DOWN_BUTTON_ID:
bitmap = LoadBitmap(AppInstance, MAKEINTRESOURCE(LOOK_DOWN_BITMAP_ID));
break;
}
selected = ((drawItem->itemState & ODS_SELECTED) == ODS_SELECTED);
rect = drawItem->rcItem;
FrameRect(drawItem->hDC, &rect, GetStockObject(BLACK_BRUSH));
FrameRect3D(drawItem->hDC, drawItem->rcItem.left + 1,
drawItem->rcItem.top + 1,
drawItem->rcItem.right - 1,
drawItem->rcItem.bottom - 1,
!selected);
Rectangle3D(drawItem->hDC, drawItem->rcItem.left + 2,
drawItem->rcItem.top + 2,
drawItem->rcItem.right - 2,
drawItem->rcItem.bottom - 2,
!selected);
if (bitmap)
{
GetObject(bitmap, sizeof(BITMAP), &bitmapInfo);
width = bitmapInfo.bmWidth;
height = bitmapInfo.bmHeight;
x = drawItem->rcItem.left + (((drawItem->rcItem.right - drawItem->rcItem.left) - width) >> 1);
y = drawItem->rcItem.top + (((drawItem->rcItem.bottom - drawItem->rcItem.top) - height) >> 1);
bitmapDevContext = CreateCompatibleDC(drawItem->hDC);
oldBitmap = SelectObject(bitmapDevContext, bitmap);
BitBlt(drawItem->hDC, x, y, width, height, bitmapDevContext, 0, 0, SRCCOPY);
SelectObject(bitmapDevContext, oldBitmap);
DeleteObject(bitmap);
DeleteDC(bitmapDevContext);
}
break;
}
}
/**********************************************************************/
static void
HandlePaint(HWND window)
{
HDC devContext;
PAINTSTRUCT paintStruct;
RECT rect;
devContext = BeginPaint(window, &paintStruct);
GetClientRect(window, &rect);
FrameRect3D(devContext, rect.left, rect.top,
rect.right, rect.bottom, TRUE);
Rectangle3D(devContext, rect.left + 1, rect.top + 1,
rect.right - 1, rect.bottom - 1, TRUE);
EndPaint(window, &paintStruct);
}
/**************************************************************************
About Dialogue Box Stuff
**************************************************************************/
void DlgDrawItem(DRAWITEMSTRUCT FAR *dis)
{
HDC hdcMemory;
HBITMAP hbmplogo, hbmpOld;
BITMAP bm;
hbmplogo = LoadBitmap(AppInstance, MAKEINTRESOURCE(CRITERION_LOGO));
GetObject(hbmplogo, sizeof(BITMAP), &bm);
hdcMemory = CreateCompatibleDC(dis->hDC);
hbmpOld = SelectObject(hdcMemory, hbmplogo);
BitBlt(dis->hDC, dis->rcItem.left, dis->rcItem.top,
dis->rcItem.right - dis->rcItem.left,
dis->rcItem.bottom - dis->rcItem.top,
hdcMemory, 0, 0, SRCCOPY);
SelectObject(hdcMemory, hbmpOld);
DeleteDC(hdcMemory);
DeleteObject(hbmplogo);
}
BOOL FAR PASCAL AboutDlgProc(HWND hDlg, WORD message, WPARAM wParam, LPARAM lParam)
{
switch(message)
{
case WM_INITDIALOG:
return TRUE;
case WM_COMMAND:
switch(wParam)
{
case IDOK:
case IDCANCEL:
EndDialog(hDlg, 0);
return(TRUE);
}
break;
case WM_DRAWITEM:
DlgDrawItem((DRAWITEMSTRUCT FAR *)MK_FP32((void *)lParam));
return(TRUE);
}
return(FALSE);
}
/**********************************************************************/
static void
HandleMenu(HWND window, UINT menuID)
{
switch (menuID)
{
case EXIT_ITEM_ID:
DestroyWindow(window);
break;
case ABOUT_ITEM_ID:
DialogBox(AppInstance, "ABOUT", window, MakeProcInstance(AboutDlgProc, AppInstance));
break;
}
}
/**********************************************************************/
static void
HandleCommand(HWND window, UINT controlID)
{
static UINT oldcontrol = 0;
if (oldcontrol)
SendDlgItemMessage(window, oldcontrol, BM_SETSTATE, FALSE, 0);
switch (controlID)
{
case LOOK_UP_BUTTON_ID:
RwTiltCamera(Camera, -CameraTilt);
CameraTilt = CREAL(-20.0);
RwTiltCamera(Camera, CameraTilt);
SetStatusMessage("Look Up");
break;
case LOOK_AHEAD_BUTTON_ID:
RwTiltCamera(Camera, -CameraTilt);
CameraTilt = CREAL(0.0);
RwTiltCamera(Camera, CameraTilt);
SetStatusMessage("Look Ahead");
break;
case LOOK_DOWN_BUTTON_ID:
RwTiltCamera(Camera, -CameraTilt);
CameraTilt = CREAL(20.0);
RwTiltCamera(Camera, CameraTilt);
SetStatusMessage("Look Down");
break;
}
oldcontrol = controlID;
if (oldcontrol)
SendDlgItemMessage(window, oldcontrol, BM_SETSTATE, TRUE, 0);
RenderFlag = TRUE;
}
/**********************************************************************/
long far PASCAL
WindowProc(HWND window, WORD message, WPARAM wParam, LPARAM lParam)
{
static int init_flag = 0;
switch (message)
{
case WM_CREATE:
return 0L;
case WM_SIZE:
return 0L;
case WM_PAINT:
HandlePaint(window);
if (!init_flag)
{
HandleCommand(window, LOOK_AHEAD_BUTTON_ID); /* simulate press */
SetStatusMessage(DEFAULT_STATUS_MESSAGE);
init_flag = TRUE;
}
return 0L;
case WM_DRAWITEM:
HandleDrawItem(wParam, (DRAWITEMSTRUCT FAR*)MK_FP32((void*)lParam));
return 0L;
case WM_COMMAND:
if (LOWORD(lParam) == 0)
{
HandleMenu(window, wParam);
}
else
{
HandleCommand(window, wParam);
}
return 0L;
case WM_DESTROY:
PostQuitMessage(0);
return 0L;
}
return DefWindowProc(window, message, wParam, lParam);
}
/**********************************************************************/
/*
* MS Windows application entry point.
*/
int PASCAL
WinMain(HANDLE instance, HANDLE prevInstance, LPSTR cmdLine, int cmdShow)
{
MSG message;
AppInstance = instance;
if (prevInstance)
{
MessageBox((HWND)0, "RwShop is already running...",
ERROR_DIALOG_TITLE, MB_OK | MB_ICONSTOP | MB_APPLMODAL);
return FALSE;
}
if (!InitApplication(instance))
{
MessageBox((HWND)0, "Internal error\nPlease contact Criterion Software Ltd.",
ERROR_DIALOG_TITLE, MB_OK | MB_ICONSTOP | MB_APPLMODAL);
return FALSE;
}
if (!Init3D(instance))
{
return FALSE;
}
if (!(Window = InitInstance(instance)))
{
return FALSE;
}
CheckDisplayDepth(Window);
ShowWindow(Window, cmdShow);
UpdateWindow(Window);
while (GetMessage(&message, NULL, 0, 0))
{
TranslateMessage(&message);
DispatchMessage(&message);
}
TidyUp3D();
UnregisterClass(RWSHOP_CLASS_NAME, instance);
UnregisterClass(RWWINDOW_CLASS_NAME, instance);
UnregisterClass(RWMOVEBUTTON_CLASS_NAME, instance);
return message.wParam;
}
/**********************************************************************/