home *** CD-ROM | disk | FTP | other *** search
Text File | 1995-11-14 | 77.4 KB | 2,433 lines |
- /**********************************************************************
- *
- * File : rwroller.c
- *
- * Abstract : A virtual Rollercoaster for RenderWare and Microsoft
- * Windows.
- *
- * This application had been written to be compatible with
- * both the fixed and floating-point versions of the
- * RenderWare library, i.e., it uses the macros CREAL,
- * INT2REAL, RAdd, RDiv, RSub etc. If your application is
- * intended for the floating-point version of the library
- * only these macros are not necessary.
- *
- * Please note that this application is intended for
- * demonstration purposes only. No support will be
- * provided for this code and it comes with no warranty.
- *
- **********************************************************************
- *
- * Building RWROLLER.EXE...
- *
- **********************************************************************
- *
- * Watcom C/C++ 9.5 and 10.0 and RenderWare V1.4 static library
- *
- * This application can be built using the Watcom compiler and the
- * fixed-point RenderWare V1.4 library as follows:
- * wcc386p /I=\rwwin\include /zW /4r /zp4 /mf /fpc /s /j /ei /oneatx
- * /DRWFIXED /fo=rwroller.obj rwroller.c
- * wcc386p /I=\rwwin\include /zW /4r /zp4 /mf /fpc /s /j /ei /oneatx
- * /DRWFIXED /fo=rolltype.obj rolltype.c
- * wcc386p /I=\rwwin\include /zW /4r /zp4 /mf /fpc /s /j /ei /oneatx
- * /DRWFIXED /fo=rwpal.obj rwpal.c
- * wlink option caseexact option stack=32768 name rwroller system win386
- * file rwroller.obj rolltype.obj rwpal.obj library
- * \rwwin\lib\rwwrxp.lib
- * wbind rwroller -R rwroller,rc
- *
- * (Note for Watcom 10.0 substitue the command wcc386p with wcc386).
- *
- * This application can be built using the Watcom compiler and the
- * floating-point RenderWare V1.4 library as follows:
- * wcc386p /I=\rwwin\include /zW /4r /zp4 /mf /7 /s /j /ei /oneatx
- * /DRWFLOAT /fo=rwroller.obj rwroller.c
- * wcc386p /I=\rwwin\include /zW /4r /zp4 /mf /7 /s /j /ei /oneatx
- * /DRWFLOAT /fo=rolltype.obj rolltype.c
- * wcc386p /I=\rwwin\include /zW /4r /zp4 /mf /7 /s /j /ei /oneatx
- * /DRWFLOAT /fo=rwpal.obj rwpal.c
- * wlink option caseexact option stack=32768 name rwroller system win386
- * file rwroller.obj rolltype.obj rwpal.obj library
- * \rwwin\lib\rwwrlp.lib
- * wbind rwroller -R rwroller.rc
- *
- * (Note for Watcom 10.0 substitue the command wcc386p with wcc386).
- *
- **********************************************************************
- *
- * Microsoft Visual C++ 1.5 and RenderWare V1.4 DLL
- *
- * The fixed-point rwview.exe project for Visual C++ 1.5 must have
- * the following options set:
- *
- * The project should contain the following files:
- * rwroller.c
- * rwroller.def
- * rwroller.rc
- * rolltype.c
- * rwpal.c
- *
- * Compiler Options:
- * Memory Model
- * Model: Large
- * Preprocessos
- * Symbols: RWFIXED
- * Include path: \rwwin\include
- *
- * Linker Options:
- * Input
- * Libraries: ..., \rwwin\lib\rwxv.lib
- * Windows libraries
- * COMMDLG
- * SHELL
- *
- * (In addition the fixed point RenderWare V1.4 DLL rwx.dll must be
- * in your search path).
- *
- * The floating-point rwview.exe project for Visual C++ 1.5 must have
- * the following options set:
- *
- * The project should contain the following files:
- * rwroller.c
- * rwroller.def
- * rwroller.rc
- * rolltype.c
- * rwpal.c
- *
- * Compiler Options:
- * Memory Model
- * Model: Large
- * Preprocessos
- * Symbols: RWFLOAT
- * Include path: \rwwin\include
- *
- * Linker Options:
- * Input
- * Libraries: ..., \rwwin\lib\rwlv.lib
- * Windows libraries
- * COMMDLG
- * SHELL
- *
- * (In addition the fixed point RenderWare V1.4 DLL rwl.dll must be
- * in your search path).
- *
- **********************************************************************
- *
- * Borland C++ 4.0 and RenderWare V1.4 DLL
- *
- * The fixed-point rwroller.exe project for Borland C++ 4.0 must have
- * the following options set:
- *
- * New Project:
- * Target Type Application (.EXE)
- * Platform Windows 3.x (16)
- * Target Model Large
- * Standard Libraries
- * OWL Unchecked
- * Class Library Unchecked
- * Runtime Checked
- * BWCC Unchecked
- * Dynamic Checked
- * Static Unchecked
- * Advanced
- * .cpp Node Unchecked
- * .c Node Checked
- * No Source Node Unchecked
- * .rc node Unchecked
- * .def node Unchecked
- *
- * Project Options:
- * Directories
- * Include ...; \rwwin\include
- * Compiler
- * Defines ...; RWFIXED
- * 16-Bit Compiler
- * Calling Conventions C
- * Memory Model Large
- *
- * You must add the nodes rolltype.c, rwpal.c and \rwwin\lib\rwxb.lib
- * to your project.
- *
- * (In addition the fixed point RenderWare V1.4 DLL rwx.dll must be
- * in your search path).
- *
- * The floating-point rwroller.exe project for Borland C++ 4.0 must have
- * the following options set:
- *
- * New Project:
- * Target Type Application (.EXE)
- * Platform Windows 3.x (16)
- * Target Model Large
- * Standard Libraries
- * OWL Unchecked
- * Class Library Unchecked
- * Runtime Checked
- * BWCC Unchecked
- * Dynamic Checked
- * Static Unchecked
- * Advanced
- * .cpp Node Unchecked
- * .c Node Checked
- * No Source Node Unchecked
- * .rc node Unchecked
- * .def node Unchecked
- *
- * Project Options:
- * Directories
- * Include ...; \rwwin\include
- * Compiler
- * Defines ...; RWFLOAT
- * 16-Bit Compiler
- * Calling Conventions C
- * Memory Model Large
- *
- * You must add the nodes rolltype.c, rwpal.c and \rwwin\lib\rwxb.lib
- * to your project.
- *
- * (In addition the fixed point RenderWare V1.4 DLL rwx.dll must be
- * in your search path).
- *
- **********************************************************************
- *
- * 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) 1994, 1995 Criterion Software Ltd.
- * All Rights Reserved.
- *
- * RenderWare is a trademark of Canon Inc.
- *
- **********************************************************************/
-
- /**********************************************************************
- *
- * Header files.
- *
- **********************************************************************/
-
- #if defined(__WINDOWS_386__)
-
- /*
- * Watcom specific...
- */
- #define INCLUDE_SHELLAPI_H
- #define INCLUDE_COMMDLG_H
- #include <windows.h>
-
- #else
-
- #include <windows.h>
- #include <shellapi.h>
- #include <commdlg.h>
-
- #endif
-
- #include <stdlib.h>
- #include <stdio.h>
- #include <math.h>
- #include <string.h>
- #if !defined(__WINDOWS_386__)
- #include <memory.h>
- #endif
-
- #include <rwlib.h>
- #include <rwwin.h>
-
- #include "resource.h"
- #include "rolltype.h"
- #include "pick.h"
- #include "common.h"
- #include "palette.h"
-
- /**********************************************************************
- *
- * Application constants.
- *
- **********************************************************************/
-
- /*
- * Class name for the MS Window's window class.
- */
- #define RWROLLERCLASSNAME "RwRollerClass"
-
- /*
- * The default window title (and the title for error dialogs).
- */
- #define WINDOWTITLE "RenderWare Rollercoaster"
-
- /*
- * Name of the palette and backdrop files to load.
- */
- #define PALETTEFILENAME "rwroller.pal"
- #define BACKDROPFILENAME "mount64.bmp"
-
- /*
- * Default size of the viewer's window.
- */
- #define DEFAULT_WINDOW_WIDTH 320
- #define DEFAULT_WINDOW_HEIGHT 220
-
- /*
- * Maximum size of the viewer's window.
- */
- #define MAXIMUM_WINDOW_WIDTH 640
- #define MAXIMUM_WINDOW_HEIGHT 480
-
- /*
- * Default distance of the camera from the origin.
- */
- #define DEFAULT_CAMERA_DISTANCE CREAL(-7.0)
-
- /**********************************************************************
- *
- * Forward functions.
- *
- **********************************************************************/
-
- #ifndef __WINDOWS_386__
- /*
- * Stealth API function to allow the app to connect to the DLL even if
- * it is already in use. This should only be used when the DLL thinks
- * it is in use (but isn't) because a previous client has crashed.
- */
- extern void
- _rwResetReferenceCount(void);
- #endif
-
- LRESULT CALLBACK
- MainWndProc(HWND window, UINT mesage, WPARAM wParam, LPARAM lParam);
-
- /**********************************************************************
- *
- * Type definitions.
- *
- **********************************************************************/
-
- /*
- * The camera's motion mode.
- */
- typedef enum
- {
- cmNONE, /* No camera motion. */
- cmRIDE, /* Camera "rides" the rollercoaster. */
- cmSPOTTER, /* "Spotter" camera rotates around the rollercoaster car. */
- cmTRAIL, /* Camera trails the car on the rollercoaster. */
- cmLEAD, /* Camera "leads" the car on the rollercoaster. */
- cmELEVATION, /* Camera pans around and zooms into the rollercoaster elevation. */
- cmPLAN /* Camera pans around and zooms into the rollercoaster plan. */
- } CMMode;
-
- /*
- * This enumerated type tells us what kind of action should be taken
- * on mouse events.
- */
- typedef enum
- {
- mmNONE, /* No mouse move action. */
- mmMOVECAMERA, /* Move the camera on mouse move. */
- mmALTMOVECAMERA, /* Alternative camera motion on mouse move. */
- mmMOVECONTROL, /* Move a spline control point on mouse move. */
- mmMOVELIGHT /* Move the light. */
- } MMMode;
-
- /*
- * The direction of motion of the viewer on the track.
- */
- typedef enum
- {
- vmLEVEL,
- vmCLIMBING,
- vmFALLING
- } VMMode;
-
- /**********************************************************************
- *
- * Application global variables.
- *
- **********************************************************************/
-
- /*
- * Instance handle for this application.
- */
- static HANDLE AppInstance;
-
- /*
- * Drive from which the application was launched.
- */
- static char AppPath[_MAX_PATH];
-
- /*
- * The global, single camera instance.
- */
- static RwCamera *Camera = NULL;
-
- static CMMode CameraMode = cmRIDE;
-
- static RwReal CameraAngle = CREAL(0.0);
-
- /*
- * This variable tells us what kind of action to take on a mouse move.
- * The action depends on the object that was picked when the mouse button
- * went down, and on the selection of virtual keys that were depressed at
- * that time. By default no action is taken on mouse move.
- */
- static MMMode MouseMoveMode = mmNONE;
-
- /*
- * Global variables used to remember the last mouse X and Y coordinates
- * when involved in a pan, zoom, drag or spin.
- */
- static int LastX;
- static int LastY;
-
- /*
- * Current distance the camera is from the origin. This is stored to
- * help us pan and zoom the camera.
- */
- static RwReal CameraDistance = DEFAULT_CAMERA_DISTANCE;
-
- /*
- * Current angle of tilt applied to the camera.
- */
- static RwReal CameraTilt = CREAL(0.0);
-
- /*
- * 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 ThreeDInitialized = FALSE;
-
- /*
- * The current rollercoaster.
- */
- static RollerCoasterType *CurrentCoaster = NULL;
-
- /*
- * Default coaster filename table.
- */
- static char DefaultCoasterFilenames[4][_MAX_PATH] =
- {
- "track1.rrc",
- "track2.rrc",
- "track3.rrc",
- "track4.rrc"
- };
-
- /*
- * Filename used for communication with the Choose dialog.
- */
- static char CoasterFilename[_MAX_PATH];
-
- /*
- * The current control point picked (if any).
- */
- static int ControlPoint = 0;
-
- /*
- * Whether to use WinG or not. By default we do (unless we are running
- * under Windows95 or Windows NT 3.5 where we ignore WinG and use
- * DIB Sections which are much nicer).
- */
- static BOOL UseWinG = TRUE;
-
- /*
- * Can we stretch bitmaps efficiently.
- */
- static BOOL CanStretch = FALSE;
-
- /*
- * If we can stretch, are we stretching.
- */
- static BOOL DoStretch = FALSE;
-
- /*
- * Whether to show the coaster's car or not.
- */
- static BOOL ShowCar = TRUE;
-
- /**********************************************************************
- *
- * Functions.
- *
- **********************************************************************/
-
- /**********************************************************************/
-
- static BOOL
- TrackBackdropToCamera(RwCamera *camera)
- {
- RwRaster *backdrop;
- RwInt32 backdropWidth;
- RwInt32 backdropHeight;
- RwV3d at;
- RwReal angle;
- RwInt32 xOffset;
- RwInt32 yOffset;
- RwInt32 windowWidth;
- RwInt32 windowHeight;
-
- backdrop = RwGetCameraBackdrop(camera);
-
- /*
- * No-op if the camera has no backdrop.
- */
- if (backdrop != NULL)
- {
- /*
- * Get the window and backdrop dimensions.
- */
- RwGetCameraViewport(camera, NULL, NULL, &windowWidth, &windowHeight);
-
- backdropWidth = RwGetRasterWidth(backdrop);
- backdropHeight = RwGetRasterHeight(backdrop);
-
- /*
- * We use the look at vector for determining both
- * horizontal and vertical positioning.
- */
- RwGetCameraLookAt(camera, &at);
-
- /*
- * Compute the horizontal position. This is done
- * by compute the camera's angle of rotate about
- * the Z axis. The angle is then directly converted
- * into a horizontal backdrop offset.
- */
-
- /*
- * Compute the angle in the range 0 => PI.
- */
- at.y = CREAL(0.0);
- RwNormalize(&at);
- if (at.z > CREAL(1.0))
- at.z = CREAL(1.0);
- else if (at.z < CREAL(-1.0))
- at.z = CREAL(-1.0);
- angle = FL2REAL(acos(REAL2FL(at.z)));
-
- /*
- * Get the angle in the range 0 => 2 PI
- */
- if (at.x < CREAL(0.0))
- angle = RSub(CREAL(M_2PI), angle);
-
- /*
- * The backdrop X offset is derived simply from
- * the angle computed above.
- */
- xOffset = -REAL2INT(RDiv(RMul(angle, INT2REAL(backdropWidth)), CREAL(M_2PI)));
-
- /*
- * Compute the vertical position. This is done by getting
- * the angle between the look at vector and the Y axis. We
- * simply use the dot product (cosine of the angle) multiplied
- * by a scale factor to compute the vertical offset.
- */
- RwGetCameraLookAt(Camera, &at);
- yOffset = REAL2INT(RAdd(INT2REAL(windowHeight / 2), RMul(RMul(at.y, CREAL(1.5)), INT2REAL(windowHeight / 2)))) - (backdropHeight / 2);
-
- RwSetCameraBackdropOffset(Camera, xOffset, 0);
- RwSetCameraBackdropViewportRect(Camera, 0, yOffset, windowWidth, backdropHeight);
- }
- return TRUE;
- }
-
- /**********************************************************************/
-
- /*
- * Update the application menu to reflect the current application
- * state.
- */
- static void
- UpdateMenu(HWND window)
- {
- HMENU menu;
-
- menu = GetMenu(window);
-
- CheckMenuItem(menu, IDM_VIEWPOINT_RIDE,
- MF_BYCOMMAND | (CameraMode == cmRIDE ? MF_CHECKED : MF_UNCHECKED));
- CheckMenuItem(menu, IDM_VIEWPOINT_SPOTTER,
- MF_BYCOMMAND | (CameraMode == cmSPOTTER ? MF_CHECKED : MF_UNCHECKED));
- CheckMenuItem(menu, IDM_VIEWPOINT_TRAIL,
- MF_BYCOMMAND | (CameraMode == cmTRAIL ? MF_CHECKED : MF_UNCHECKED));
- CheckMenuItem(menu, IDM_VIEWPOINT_LEAD,
- MF_BYCOMMAND | (CameraMode == cmLEAD ? MF_CHECKED : MF_UNCHECKED));
- CheckMenuItem(menu, IDM_EDIT_SIDEVIEW,
- MF_BYCOMMAND | (CameraMode == cmELEVATION ? MF_CHECKED : MF_UNCHECKED));
- CheckMenuItem(menu, IDM_EDIT_TOPVIEW,
- MF_BYCOMMAND | (CameraMode == cmPLAN ? MF_CHECKED : MF_UNCHECKED));
-
- /*
- * Can we stretch output (are we using WinG or DIB Sections)?
- */
- EnableMenuItem(menu, IDM_OPTION_STRETCH,
- MF_BYCOMMAND | (CanStretch ? MF_ENABLED : MF_GRAYED));
-
- /*
- * Are we stretching?
- */
- CheckMenuItem(menu, IDM_OPTION_STRETCH,
- MF_BYCOMMAND | (DoStretch ? MF_CHECKED : MF_UNCHECKED));
-
- CheckMenuItem(menu, IDM_OPTION_SHOWCAR,
- MF_BYCOMMAND | (ShowCar ? MF_CHECKED : MF_UNCHECKED));
- }
-
- /**********************************************************************/
-
- /*
- * Put camera into ride mode.
- */
- static void
- SwitchToRideView(HWND window)
- {
- CameraMode = cmRIDE;
- SwitchToCoasterRideMode(CurrentCoaster);
- UpdateMenu(window);
- }
-
- /**********************************************************************/
-
- /*
- * Put camera into ride mode.
- */
- static void
- SwitchToSpotterView(HWND window)
- {
- CameraMode = cmSPOTTER;
- SwitchToCoasterRideMode(CurrentCoaster);
- UpdateMenu(window);
- }
-
- /**********************************************************************/
-
- /*
- * Put camera into trail mode.
- */
- static void
- SwitchToTrailView(HWND window)
- {
- CameraMode = cmTRAIL;
- SwitchToCoasterRideMode(CurrentCoaster);
- UpdateMenu(window);
- }
-
- /**********************************************************************/
-
- /*
- * Put camera into lead mode.
- */
- static void
- SwitchToLeadView(HWND window)
- {
- CameraMode = cmLEAD;
- SwitchToCoasterRideMode(CurrentCoaster);
- UpdateMenu(window);
- }
-
- /**********************************************************************/
-
- /*
- * Put camera into elevation mode.
- */
- static void
- SwitchToElevationView(HWND window)
- {
- CameraMode = cmELEVATION;
- SwitchToCoasterEditMode(CurrentCoaster);
-
- RwSetCameraPosition(Camera,
- CurrentCoaster->elevationPosition.x,
- CurrentCoaster->elevationPosition.y,
- CurrentCoaster->elevationPosition.z);
- RwPointCamera(Camera,
- CREAL(0.0),
- CurrentCoaster->elevationPosition.y,
- CREAL(0.0));
- RwSetCameraLookUp(Camera,
- CREAL(0.0),
- CREAL(1.0),
- CREAL(0.0));
- TrackBackdropToCamera(Camera);
- UpdateMenu(window);
- }
-
- /**********************************************************************/
-
- /*
- * Put the camera into plan mode.
- */
- static void
- SwitchToPlanView(HWND window)
- {
- CameraMode = cmPLAN;
- SwitchToCoasterEditMode(CurrentCoaster);
-
- RwSetCameraPosition(Camera,
- CurrentCoaster->planPosition.x,
- CurrentCoaster->planPosition.y,
- CurrentCoaster->planPosition.z);
-
- /*
- * Unsatisfactory hack to get the camera aligned in the
- * way we wish. This itself will fail if the camera's is
- * looking down the X-axis already - sigh!
- */
- RwSetCameraLookUp(Camera,
- CREAL(1.0),
- CREAL(0.0),
- CREAL(0.0));
- RwPointCamera(Camera,
- CurrentCoaster->planPosition.x,
- CREAL(0.0),
- CurrentCoaster->planPosition.z);
- RwSetCameraLookUp(Camera,
- CREAL(0.0),
- CREAL(0.0),
- CREAL(1.0));
-
- UpdateMenu(window);
- }
-
- /**********************************************************************/
-
- static void
- SwitchCoaster(HWND window, RollerCoasterType *coaster)
- {
- DestroyRollerCoaster(CurrentCoaster);
- CurrentCoaster = coaster;
- switch (CameraMode)
- {
- case cmRIDE:
- SwitchToRideView(window);
- break;
- case cmSPOTTER:
- SwitchToSpotterView(window);
- break;
- case cmTRAIL:
- SwitchToTrailView(window);
- break;
- case cmLEAD:
- SwitchToLeadView(window);
- break;
- case cmELEVATION:
- SwitchToElevationView(window);
- break;
- case cmPLAN:
- SwitchToPlanView(window);
- break;
- }
- if (ShowCar)
- EnableCoasterCar(CurrentCoaster);
- else
- DisableCoasterCar(CurrentCoaster);
- SetWindowText(window, CurrentCoaster->description);
- }
-
- /**********************************************************************/
-
- /*
- * Dialog procedure for the rollercoaster about dialog.
- */
- BOOL CALLBACK
- CoasterAboutDialogProc(HWND dialog, UINT message, WPARAM wParam, LPARAM lParam)
- {
- DRAWITEMSTRUCT FAR *drawItemStruct;
- RECT FAR *rect;
- HDC dc;
- HDC bitmapDC;
- HBITMAP oldBitmap;
- BITMAP bitmapInfo;
- int x;
- int y;
- int width;
- int height;
-
- static HBITMAP renderWareLogo = NULL;
-
- switch (message)
- {
- case WM_INITDIALOG:
- renderWareLogo = LoadBitmap(AppInstance, MAKEINTRESOURCE(IDB_RWLOGO));
- return TRUE;
-
- case WM_DRAWITEM:
- #if defined(__WINDOWS_386__)
- drawItemStruct = (DRAWITEMSTRUCT FAR *)MK_FP32((void*)lParam);
- #else
- drawItemStruct = (DRAWITEMSTRUCT *)lParam;
- #endif
- rect = &drawItemStruct->rcItem;
- dc = drawItemStruct->hDC;
-
- switch (drawItemStruct->CtlID)
- {
- case IDC_RENDERWARELOGO:
- GetObject(renderWareLogo, sizeof(BITMAP), &bitmapInfo);
- width = bitmapInfo.bmWidth;
- height = bitmapInfo.bmHeight;
- x = rect->left + (((rect->right - rect->left) - width) / 2);
- y = rect->top + (((rect->bottom - rect->top) - height) / 2);
- bitmapDC = CreateCompatibleDC(dc);
- oldBitmap = SelectObject(bitmapDC, renderWareLogo);
- BitBlt(dc, x, y, width, height, bitmapDC, 0, 0, SRCCOPY);
- SelectObject(bitmapDC, oldBitmap);
- DeleteDC(bitmapDC);
- break;
- }
- return TRUE;
-
- case WM_COMMAND:
- switch (wParam)
- {
- case IDOK:
- DeleteObject(renderWareLogo);
- EndDialog(dialog, IDOK);
- return TRUE;
- }
- }
- return FALSE;
- }
-
- /**********************************************************************/
-
- /*
- * Dialog procedure for the rollercoaster menu dialog.
- */
- BOOL CALLBACK
- CoasterMenuDialogProc(HWND dialog, UINT message, WPARAM wParam, LPARAM lParam)
- {
- DRAWITEMSTRUCT FAR *drawItemStruct;
- RECT FAR *rect;
- HDC dc;
- HPEN topLeftPen;
- HPEN bottomRightPen;
- HPEN pen;
- HPEN oldPen;
- int i;
- RollerCoasterType *coaster;
- OPENFILENAME openFileName;
- char filename[_MAX_PATH];
- static int numCoasters;
- static RollerCoasterType *coasters[4];
- static RwCamera *camera = NULL;
-
- switch (message)
- {
- case WM_INITDIALOG:
- /*
- * Create the camera used in this dialog.
- */
- camera = RwCreateCamera(200, 200, NULL);
- if (camera == NULL)
- return FALSE;
- RwSetCameraBackColor(camera, CREAL(0.0), CREAL(0.0), CREAL(1.0));
- RwSetCameraViewwindow(camera, CREAL(0.4), CREAL(0.4));
- RwTiltCamera(camera, CREAL(30.0));
- RwVCMoveCamera(camera, CREAL(0.0), CREAL(0.0), CREAL(-3.0));
-
- /*
- * Attempt to load the four default rollercoasters.
- */
- numCoasters = 0;
- for (i = 0; i < 4; i++)
- {
- strcpy(filename, AppPath);
- strcat(filename, DefaultCoasterFilenames[i]);
- coasters[numCoasters] = ReadRollerCoaster(filename);
- if (coasters[numCoasters] != NULL)
- {
- DisableCoasterControlPoints(coasters[numCoasters]);
- DisableCoasterCar(coasters[numCoasters]);
- numCoasters++;
- }
- }
-
- for (i = 0; i < numCoasters; i++)
- SetDlgItemText(dialog, IDC_LABEL_ONE + i, coasters[i]->description);
-
- SetTimer(dialog, 2, 20, NULL);
-
- return TRUE;
-
- case WM_DRAWITEM:
- #if defined(__WINDOWS_386__)
- drawItemStruct = (DRAWITEMSTRUCT FAR *)MK_FP32((void*)lParam);
- #else
- drawItemStruct = (DRAWITEMSTRUCT *)lParam;
- #endif
- if (camera != NULL)
- {
- rect = &drawItemStruct->rcItem;
- dc = drawItemStruct->hDC;
-
- pen = CreatePen(PS_SOLID, 1, RGB(0, 0, 0));
- oldPen = SelectObject(dc, pen);
- MoveToEx(dc, rect->left, rect->top, NULL);
- LineTo(dc, rect->right - 1, rect->top);
- LineTo(dc, rect->right - 1, rect->bottom - 1);
- LineTo(dc, rect->left, rect->bottom - 1);
- LineTo(dc, rect->left, rect->top);
- SelectObject(dc, oldPen);
- DeleteObject(pen);
-
- if (drawItemStruct->itemState & ODS_SELECTED)
- {
- topLeftPen = CreatePen(PS_SOLID, 1, GetSysColor(COLOR_BTNSHADOW));
- bottomRightPen = CreatePen(PS_SOLID, 1, GetSysColor(COLOR_BTNHIGHLIGHT));
- }
- else
- {
- topLeftPen = CreatePen(PS_SOLID, 1, GetSysColor(COLOR_BTNHIGHLIGHT));
- bottomRightPen = CreatePen(PS_SOLID, 1, GetSysColor(COLOR_BTNSHADOW));
- }
-
- oldPen = SelectObject(dc, topLeftPen);
-
- MoveToEx(dc, rect->left + 1, rect->top + 1, NULL);
- LineTo(dc, rect->right - 2, rect->top + 1);
- MoveToEx(dc, rect->left + 1, rect->top + 2, NULL);
- LineTo(dc, rect->right - 3, rect->top + 2);
- MoveToEx(dc, rect->left + 1, rect->top + 3, NULL);
- LineTo(dc, rect->left + 1, rect->bottom - 2);
- MoveToEx(dc, rect->left + 2, rect->top + 3, NULL);
- LineTo(dc, rect->left + 2, rect->bottom - 3);
-
- SelectObject(dc, oldPen);
-
- oldPen = SelectObject(dc, bottomRightPen);
-
- MoveToEx(dc, rect->right - 2, rect->bottom - 2, NULL);
- LineTo(dc, rect->left + 1, rect->bottom - 2);
- MoveToEx(dc, rect->right - 2, rect->bottom - 3, NULL);
- LineTo(dc, rect->left + 2, rect->bottom - 3);
- MoveToEx(dc, rect->right - 2, rect->bottom - 4, NULL);
- LineTo(dc, rect->right - 2, rect->top + 2);
- MoveToEx(dc, rect->right - 3, rect->bottom - 4, NULL);
- LineTo(dc, rect->right - 3, rect->top + 3);
-
- SelectObject(dc, oldPen);
-
- DeleteObject(topLeftPen);
- DeleteObject(bottomRightPen);
-
- coaster = coasters[drawItemStruct->CtlID - IDC_ROLLER_ONE];
- if (coaster != NULL)
- {
- RwSetCameraViewport(camera,
- rect->left + 3,
- rect->top + 3,
- (rect->right - rect->left) - 6,
- (rect->bottom - rect->top) - 6);
- RwInvalidateCameraViewport(camera);
- RwBeginCameraUpdate(camera, (void *)(DWORD)dialog);
- RwClearCameraViewport(camera);
- RwRenderScene(coaster->scene);
- RwEndCameraUpdate(camera);
- RwShowCameraImage(camera, (void *)(DWORD)dc);
- }
- }
- return TRUE;
-
- case WM_TIMER:
- if (camera != NULL)
- {
- RwPushScratchMatrix();
- RwRotateMatrix(RwScratchMatrix(), CREAL(0.0), CREAL(1.0), CREAL(0.0), CREAL(10.0), rwREPLACE);
- RwTransformCamera(camera, RwScratchMatrix(), rwPOSTCONCAT);
- RwPopScratchMatrix();
- InvalidateRect(GetDlgItem(dialog, IDC_ROLLER_ONE), NULL, FALSE);
- InvalidateRect(GetDlgItem(dialog, IDC_ROLLER_TWO), NULL, FALSE);
- InvalidateRect(GetDlgItem(dialog, IDC_ROLLER_THREE), NULL, FALSE);
- InvalidateRect(GetDlgItem(dialog, IDC_ROLLER_FOUR), NULL, FALSE);
- }
- return TRUE;
-
- case WM_COMMAND:
- switch (wParam)
- {
- case IDC_ROLLER_ONE:
- case IDC_ROLLER_TWO:
- case IDC_ROLLER_THREE:
- case IDC_ROLLER_FOUR:
- strcpy(CoasterFilename, DefaultCoasterFilenames[wParam - IDC_ROLLER_ONE]);
- KillTimer(dialog, 2);
- for (i = 0; i < numCoasters; i++)
- DestroyRollerCoaster(coasters[i]);
- if (camera != NULL)
- {
- RwDestroyCamera(camera);
- camera = NULL;
- }
- EndDialog(dialog, IDOK);
- return TRUE;
-
- case IDC_ROLLER_MORE:
- KillTimer(dialog, 2);
- filename[0] = '\0';
- memset(&openFileName, '\0', sizeof(OPENFILENAME));
- openFileName.lStructSize = sizeof(OPENFILENAME);
- openFileName.hwndOwner = dialog;
- openFileName.lpstrFilter = "Rollercoasters (*.rrc)\0*.rrc\0All files (*.*)\0*.*\0\0";
- openFileName.nFilterIndex = 1;
- openFileName.lpstrFile = &filename[0];
- openFileName.nMaxFile = sizeof(filename);
- openFileName.Flags = OFN_SHOWHELP | OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST;
-
- if (GetOpenFileName(&openFileName))
- {
- strcpy(CoasterFilename, filename);
- KillTimer(dialog, 2);
- for (i = 0; i < numCoasters; i++)
- DestroyRollerCoaster(coasters[i]);
- if (camera != NULL)
- {
- RwDestroyCamera(camera);
- camera = NULL;
- }
- EndDialog(dialog, IDOK);
- }
- else
- {
- SetTimer(dialog, 2, 20, NULL);
- }
-
- return TRUE;
-
- case IDCANCEL:
- KillTimer(dialog, 2);
- for (i = 0; i < numCoasters; i++)
- DestroyRollerCoaster(coasters[i]);
- if (camera != NULL)
- {
- RwDestroyCamera(camera);
- camera = NULL;
- }
- EndDialog(dialog, IDCANCEL);
- return TRUE;
- }
- }
-
- return FALSE;
- }
-
- /**********************************************************************/
-
- /*
- * Dialog procedure for the rollercoaster menu dialog.
- */
- BOOL CALLBACK
- CoasterDescriptionDialogProc(HWND dialog, UINT message, WPARAM wParam, LPARAM lParam)
- {
- switch (message)
- {
- case WM_INITDIALOG:
- SetDlgItemText(dialog, IDC_COASTER_DESCRIPTION, CurrentCoaster->description);
- SetFocus(GetDlgItem(dialog, IDC_COASTER_DESCRIPTION));
- return TRUE;
-
- case WM_COMMAND:
- switch (wParam)
- {
- case IDOK:
- GetDlgItemText(dialog, IDC_COASTER_DESCRIPTION,
- CurrentCoaster->description,
- sizeof(CurrentCoaster->description));
- EndDialog(dialog, IDOK);
- return TRUE;
- case IDCANCEL:
- EndDialog(dialog, IDCANCEL);
- return TRUE;
- }
- }
-
- return FALSE;
- }
-
- /**********************************************************************/
-
- /*
- * Perform any necessary MS Windows application initialization. Basically,
- * this means registering the window class for this application.
- */
- 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 = NULL;
- windowClass.hCursor = LoadCursor(NULL, IDC_ARROW);
- windowClass.hbrBackground = NULL;
- windowClass.lpszMenuName = MAKEINTRESOURCE(IDR_APPMENU);
- windowClass.lpszClassName = RWROLLERCLASSNAME;
-
- return RegisterClass(&windowClass);
- }
-
- /**********************************************************************/
-
- /*
- * Perform any necessary initialization for this instance of the
- * application. This simply means creating the application's main
- * window.
- */
- 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 Init3D() with information about the version of
- * RenderWare being used.
- */
- return CreateWindow(RWROLLERCLASSNAME, "",
- WS_OVERLAPPEDWINDOW,
- CW_USEDEFAULT, CW_USEDEFAULT,
- DEFAULT_WINDOW_WIDTH, DEFAULT_WINDOW_HEIGHT,
- NULL, NULL, instance, NULL);
- }
-
- /**********************************************************************/
-
- /*
- * This function initializes the 3D (i.e. RenderWare) components of the
- * application. This function opens the RenderWare library, creates a
- * camera, a scene, a light and a matrix for spinning.
- */
- static BOOL
- Init3D(HWND window)
- {
- char buffer[_MAX_PATH];
- RwRaster *backdrop;
- RwOpenArgument arg;
- RwInt32 numOptions;
-
- /*
- * Warn the user that the display is not in one of RenderWare's native
- * rendering depths and recommend that (for best performance) they
- * switch to an 8- or 16-bit mode.
- */
- CheckDisplayDepth(window);
-
- #if defined(WIN32)
- /*
- * If we are building a Win32 executable then we will not explicitly
- * select WinG as DIB Sections are likely to ba available and DIB
- * Sections are much more super than WinG.
- */
- numOptions = 0L;
- #else
- /*
- * If we are running on Windows 3.1 then we will select WinG (so we can
- * have stretching) unless the program has been launched with the -g
- * option to disable WinG.
- */
- if (UseWinG)
- {
- arg.option = rwWINUSEWING;
- numOptions = 1L;
- }
- else
- {
- numOptions = 0L;
- }
- #endif
- if (!RwOpenExt("MSWindows", NULL, numOptions, &arg))
- {
- MessageBox(window, "Could not open the RenderWare library",
- WINDOWTITLE, MB_OK | MB_ICONSTOP | MB_APPLMODAL);
- return FALSE;
- }
-
- /*
- * By requesting that the library use WinG (or DIB Sections) we
- * wanted to enable bitmap stretching. However, we don't always
- * get what we want (for example if WinG is not installed) so we
- * must verify that we can indeed stretch efificiently before
- * enabling stretching. This function checks this.
- */
- CanStretch = AllowStretching(window);
-
- /*
- * Set up the shape path to get scripts and textures from local
- * sub-directories or from the directory from which the application
- * was run.
- */
- strcpy(buffer, AppPath);
- strcat(buffer, "SCRIPTS");
- RwSetShapePath(buffer, rwPRECONCAT);
- strcpy(buffer, AppPath);
- strcat(buffer, "TEXTURES");
- RwSetShapePath(buffer, rwPRECONCAT);
- RwSetShapePath(AppPath, rwPRECONCAT);
-
- /*
- * Install the application's optimized palette.
- */
- strcpy(buffer, AppPath);
- strcat(buffer, PALETTEFILENAME);
- CheckAndReadPalette(buffer);
-
- /*
- * Create the camera which will be used for rendering. The initial window
- * size the application will create is given by DEFAULT_WINDOW_WIDTH and
- * DEFAULT_WINDOW_HEIGHT which is currently 400x400. However, the camera
- * will be created with a maximum viewport size which is the same size
- * as the maximum window size (specified by MAXIMUM_WINDOW_WIDTH and
- * MAXIMUM_WINDOW_HEIGHT). Thus, the camera's viewport can grow as large
- * as the window.
- */
- Camera = RwCreateCamera(MAXIMUM_WINDOW_WIDTH, MAXIMUM_WINDOW_HEIGHT, NULL);
- if (!Camera)
- {
- /*
- * As with RwOpen(), the most common cause for a failure to create
- * a camera is insufficient memory so we will explicitly check for
- * this condition and report it. Otherwise a general error is issued.
- */
- if (RwGetError() == E_RW_NOMEM)
- {
- MessageBox(window,
- "Insufficient memory to create the RenderWare camera",
- WINDOWTITLE, MB_OK | MB_ICONSTOP | MB_APPLMODAL);
- }
- else
- {
- MessageBox(window, "Could not create the RenderWare camera",
- WINDOWTITLE, MB_OK | MB_ICONSTOP | MB_APPLMODAL);
- }
- RwClose();
-
- return FALSE;
- }
-
- /*
- * Set the camera's background color to blue.
- */
- RwSetCameraBackColor(Camera, CREAL(0.0), CREAL(0.0), CREAL(0.67));
-
- /*
- * By default, the camera lies on the X-Z plane and points down Z
- * into the screen. We shall retain the camera's orientation, but move
- * the camera DEFAULT_CAMERA_DISTANCE units down Z away from the screen.
- */
- RwTiltCamera(Camera, CameraTilt);
- RwVCMoveCamera(Camera, CREAL(0.0), CREAL(0.0), CameraDistance);
- RwSetCameraViewwindow(Camera, CREAL(0.8), CREAL(0.8));
-
- /*
- * Load and set the backdrop backdrop (we will consider the lack of a
- * backdrop to be non-fatal).
- */
- backdrop = RwReadRaster(BACKDROPFILENAME, rwGAMMARASTER | rwDITHERRASTER);
- if (backdrop != NULL)
- RwSetCameraBackdrop(Camera, backdrop);
-
- /*
- * Attempt to load the fourth default rollercoaster by default (Puke
- * Mountain). If we can't then we will just create a new rollercoaster
- * instead.
- */
- strcpy(buffer, AppPath);
- strcat(buffer, DefaultCoasterFilenames[3]);
- CurrentCoaster = ReadRollerCoaster(buffer);
- if (CurrentCoaster == NULL)
- {
- /*
- * Could not read the default coaster so create a new
- * coaster instead.
- */
- CurrentCoaster = CreateRollerCoaster();
- }
-
- /*
- * If we can't read the default coaster or create a new
- * one then we must give up and exit.
- */
- if (CurrentCoaster == NULL)
- {
- RwDestroyCamera(Camera);
- RwClose();
- return FALSE;
- }
- SwitchToRideView(window);
- SetWindowText(window, CurrentCoaster->description);
-
- /*
- * All the 3D components are now successfully initialized, so
- * work can begin...
- */
- ThreeDInitialized = TRUE;
-
- return TRUE;
- }
-
- /**********************************************************************/
-
- /*
- * This function shuts down the 3D (i.e. RenderWare) components of the
- * application in a polite fashion.
- */
- static void
- TidyUp3D(void)
- {
- /*
- * Destroy the current coaster.
- */
- if (CurrentCoaster)
- DestroyRollerCoaster(CurrentCoaster);
-
- /*
- * Destroy the camera's backdrop (if any). Backdrops are not
- * automatically destroyed by RwDestroyCamera() so we must
- * manually destroy the backdrop.
- */
- if (RwGetCameraBackdrop(Camera))
- RwDestroyRaster(RwGetCameraBackdrop(Camera));
-
- /*
- * Destroy the camera.
- */
- RwDestroyCamera(Camera);
-
- /*
- * Close the library. This will free up any internal resources and
- * textures loaded.
- */
- RwClose();
- }
-
- /**********************************************************************/
-
- /*
- * Render the scene and copy it to the window and device context
- * given. This function encapsulates the very common RenderWare
- * for rendering and updating the display.
- */
- static void
- RenderScene(HWND window, HDC dc)
- {
- /*
- * Setup the current camera and perform all necessary initialization
- * before rendering takes place.
- */
- RwBeginCameraUpdate(Camera, (void *)(DWORD)window);
-
- /*
- * Clear the areas of the camera's viewport which were damaged
- * last time round. If this call is not made, ghost images of
- * previous rendering will remain.
- */
- RwClearCameraViewport(Camera);
-
- /*
- * Re-render the entire scene.
- */
- RwRenderScene(CurrentCoaster->scene);
-
- /*
- * Perform all necessary housekeeping after rendering is complete.
- * After this call, the camera's image buffer will be ready to be
- * copied to the display.
- */
- RwEndCameraUpdate(Camera);
-
- /*
- * Copy the camera's image buffer to the output window.
- */
- RwShowCameraImage(Camera, (void*)(DWORD)dc);
- }
-
- /**********************************************************************/
-
- /*
- * Handle window resize. The most important job here is to change the
- * size of the camera's viewport (if preserving the aspect ratio of
- * the viewport is necessary, then the viewwindow should also be
- * changed at this point to reflect then new aspect ratio of the
- * viewport).
- */
- static void
- OnSize(HWND window, int width, int height)
- {
- HDC dc;
-
- RwWinOutputSize winOutputSize;
-
- /*
- * Set the output size (using the RwDeviceControl()) to the
- * size specified.
- */
- winOutputSize.width = (RwInt32)width;
- winOutputSize.height = (RwInt32)height;
- winOutputSize.camera = Camera;
- RwDeviceControl(rwWINSETOUTPUTSIZE, 0L, &winOutputSize, sizeof(RwWinOutputSize));
-
- if (DoStretch)
- {
- /*
- * Set the viewport (and backdrop) to half the width and height specified.
- */
- RwSetCameraViewport(Camera, 0, 0, width / 2, height / 2);
- }
- else
- {
- RwSetCameraViewport(Camera, 0, 0, width, height);
- }
-
- TrackBackdropToCamera(Camera);
-
- /*
- * When the viewport has changed size we need to re-render the
- * scene for the new viewport size.
- */
- dc = GetDC(window);
- RenderScene(window, dc);
- ReleaseDC(window, dc);
- }
-
- /**********************************************************************/
-
- /*
- * Handle menu selections.
- */
- static void
- OnMenu(HWND window, WPARAM item)
- {
- RollerCoasterType *coaster;
- HDC dc;
- OPENFILENAME openFileName;
- char filename[_MAX_PATH];
- RECT rect;
- static FARPROC dialogProcInstance;
-
- switch (item)
- {
- case IDM_FILE_NEW:
- coaster = CreateRollerCoaster();
- if (coaster != NULL)
- {
- SwitchCoaster(window, coaster);
- dc = GetDC(window);
- RenderScene(window, dc);
- ReleaseDC(window, dc);
- }
- else
- {
- MessageBox(window, "Error creating new rollercoaster", "RenderWare Roller",
- MB_OK | MB_ICONEXCLAMATION | MB_APPLMODAL);
- }
- break;
-
- case IDM_FILE_OPEN:
- dialogProcInstance = MakeProcInstance(CoasterMenuDialogProc, AppInstance);
- if (DialogBox(AppInstance, MAKEINTRESOURCE(IDD_ROLLERCOASTER_MENU),
- window, dialogProcInstance) == IDOK)
- {
- coaster = ReadRollerCoaster(CoasterFilename);
- if (coaster != NULL)
- {
- SwitchCoaster(window, coaster);
- dc = GetDC(window);
- RenderScene(window, dc);
- ReleaseDC(window, dc);
- }
- }
- FreeProcInstance(dialogProcInstance);
- break;
-
- case IDM_FILE_SAVE:
- if (CurrentCoaster->filename[0] != '\0')
- {
- if (!WriteRollerCoaster(CurrentCoaster, CurrentCoaster->filename))
- {
- MessageBox(window, "Error writing rollercoaster...", "RenderWare Rollercoaster Error", MB_OK | MB_ICONEXCLAMATION | MB_APPLMODAL);
- }
- }
- else
- {
- filename[0] = '\0';
- memset(&openFileName, '\0', sizeof(OPENFILENAME));
- openFileName.lStructSize = sizeof(OPENFILENAME);
- openFileName.hwndOwner = window;
- openFileName.lpstrFilter = "Rollercoasters (*.rrc)\0*.rrc\0All files (*.*)\0*.*\0\0";
- openFileName.lpstrFile = &filename[0];
- openFileName.nMaxFile = sizeof(filename);
- openFileName.Flags = OFN_SHOWHELP | OFN_OVERWRITEPROMPT;
-
- if (GetSaveFileName(&openFileName))
- {
- if (!WriteRollerCoaster(CurrentCoaster, filename))
- {
- MessageBox(window, "Error writing rollercoaster...", "RenderWare Rollercoaster Error", MB_OK | MB_ICONEXCLAMATION | MB_APPLMODAL);
- }
- }
- }
- break;
-
- case IDM_FILE_SAVEAS:
- filename[0] = '\0';
- memset(&openFileName, '\0', sizeof(OPENFILENAME));
- openFileName.lStructSize = sizeof(OPENFILENAME);
- openFileName.hwndOwner = window;
- openFileName.lpstrFilter = "Rollercoasters (*.rrc)\0*.rrc\0All files (*.*)\0*.*\0\0";
- openFileName.lpstrFile = &filename[0];
- openFileName.nMaxFile = sizeof(filename);
- openFileName.Flags = OFN_SHOWHELP | OFN_OVERWRITEPROMPT;
-
- if (GetSaveFileName(&openFileName))
- {
- if (!WriteRollerCoaster(CurrentCoaster, filename))
- {
- MessageBox(window, "Error writing rollercoaster...", "RenderWare Rollercoaster Error", MB_OK | MB_ICONEXCLAMATION | MB_APPLMODAL);
- }
- }
- break;
-
-
- case IDM_FILE_EXIT:
- DestroyWindow(window);
- break;
-
- case IDM_EDIT_DESCRIPTION:
- dialogProcInstance = MakeProcInstance(CoasterDescriptionDialogProc, AppInstance);
- if (DialogBox(AppInstance, MAKEINTRESOURCE(IDD_ROLLERCOASTER_DESCRIPTION),
- window, dialogProcInstance) == IDOK)
- SetWindowText(window, CurrentCoaster->description);
- FreeProcInstance(dialogProcInstance);
- break;
-
- case IDM_EDIT_SIDEVIEW:
- SwitchToElevationView(window);
- break;
-
- case IDM_EDIT_TOPVIEW:
- SwitchToPlanView(window);
- break;
-
- case IDM_VIEWPOINT_RIDE:
- SwitchToRideView(window);
- break;
-
- case IDM_VIEWPOINT_SPOTTER:
- SwitchToSpotterView(window);
- break;
-
- case IDM_VIEWPOINT_TRAIL:
- SwitchToTrailView(window);
- break;
-
- case IDM_VIEWPOINT_LEAD:
- SwitchToLeadView(window);
- break;
-
- case IDM_OPTION_STRETCH:
- if (GetMenuState(GetMenu(window), IDM_OPTION_STRETCH,
- MF_BYCOMMAND) == MF_CHECKED)
- {
- DoStretch = FALSE;
- }
- else
- {
- DoStretch = TRUE;
- }
- UpdateMenu(window);
-
- GetClientRect(window, &rect);
- OnSize(window, rect.right - rect.left, rect.bottom - rect.top);
- break;
-
- case IDM_OPTION_SHOWCAR:
- if (GetMenuState(GetMenu(window), IDM_OPTION_SHOWCAR,
- MF_BYCOMMAND) == MF_CHECKED)
- {
- ShowCar = FALSE;
- DisableCoasterCar(CurrentCoaster);
- }
- else
- {
- ShowCar = TRUE;
- EnableCoasterCar(CurrentCoaster);
- }
- UpdateMenu(window);
- break;
-
- case IDM_HELP_ABOUT:
- dialogProcInstance = MakeProcInstance(CoasterAboutDialogProc, AppInstance);
- DialogBox(AppInstance, MAKEINTRESOURCE(IDD_ABOUT),
- window, dialogProcInstance);
- FreeProcInstance(dialogProcInstance);
- break;
- }
- }
-
- /**********************************************************************/
-
- /*
- * Handle queries about the window's maximum extent.
- */
- static void
- OnGetMinMaxInfo(MINMAXINFO FAR *minmaxinfo)
- {
- /*
- * Constraint the window to the maximum size defined by the constants
- * MAXIMUM_WINDOW_WIDTH and MAXIMUM_WINDOW_HEIGHT.
- */
- minmaxinfo->ptMaxSize.x = MAXIMUM_WINDOW_WIDTH;
- minmaxinfo->ptMaxSize.y = MAXIMUM_WINDOW_HEIGHT;
- minmaxinfo->ptMaxTrackSize.x = MAXIMUM_WINDOW_WIDTH;
- minmaxinfo->ptMaxTrackSize.y = MAXIMUM_WINDOW_HEIGHT;
- }
-
- /**********************************************************************/
-
- /*
- * This functions handles the left mouse button going down. Its main
- * job is to determine the kind of action to be taken when the mouse
- * moves, such as spinning a clump, or panning the camera. This involves
- * examining the virtual keys that were depressed when the mouse button
- * went down and attempting to pick a clump under the mouse pointer
- * position.
- */
- static void
- OnLButtonDown(HWND window, int x, int y, WPARAM vKeys)
- {
- switch (CameraMode)
- {
- case cmRIDE:
- case cmSPOTTER:
- case cmTRAIL:
- case cmLEAD:
- /*
- * The left button does nothing when riding the
- * coaster.
- */
- MouseMoveMode = mmNONE;
- break;
-
- case cmELEVATION:
- case cmPLAN:
- /*
- * If a control point is picked, move the control
- * point, otherwise, move the camera.
- */
- if (DoStretch)
- ControlPoint = IsCoasterControlPointPicked(CurrentCoaster, Camera, x / 2, y / 2);
- else
- ControlPoint = IsCoasterControlPointPicked(CurrentCoaster, Camera, x, y);
- if (ControlPoint == 0)
- {
- if (vKeys & MK_SHIFT)
- MouseMoveMode = mmALTMOVECAMERA;
- else
- MouseMoveMode = mmMOVECAMERA;
- }
- else
- {
- MouseMoveMode = mmMOVECONTROL;
- }
- break;
- }
-
- /*
- * If any form of action is to be taken on mouse move, remember the
- * the current x and y position of the mouse and capture future
- * mouse movement.
- */
- if (MouseMoveMode != mmNONE)
- {
- SetCapture(window);
- LastX = x;
- LastY = y;
- KillTimer(window, 1);
- }
- }
-
- /**********************************************************************/
-
- /*
- * This functions handles the right mouse button going down. Its main
- * job is to determine the kind of action to be taken when the mouse
- * moves such as panning the camera.
- */
- static void
- OnRButtonDown(HWND window, int x, int y, WPARAM vKeys)
- {
- MouseMoveMode = mmMOVELIGHT;
-
- /*
- * If any form of action is to be taken on mouse move, remember the
- * the current x and y position of the mouse and capture future
- * mouse movement.
- */
- if (MouseMoveMode != mmNONE)
- {
- SetCapture(window);
- LastX = x;
- LastY = y;
- }
- }
-
- /**********************************************************************/
-
- /*
- * Handle a movement of the mouse. If a previous left or right mouse
- * button down event has set a mouse move mode then this function will
- * take the necessary actions. For example, pan and zooming the camera,
- * panning the light, dragging or spinning a clump etc.
- */
- static void
- OnMouseMove(HWND window, int x, int y)
- {
- HDC dc;
- RwV3d position;
- RwV3d newPos;
-
- /*
- * MouseMoveMode tells us what kind of action to perform.
- */
- switch (MouseMoveMode)
- {
- case mmNONE:
- break;
-
- case mmMOVECAMERA:
- switch (CameraMode)
- {
- case cmNONE:
- case cmRIDE:
- case cmSPOTTER:
- case cmTRAIL:
- case cmLEAD:
- break;
-
- case cmELEVATION:
- RwPushScratchMatrix();
- RwRotateMatrix(RwScratchMatrix(),
- CREAL(0.0),
- CREAL(1.0),
- CREAL(0.0),
- RDiv(INT2REAL(LastX - x), CREAL(5.0)),
- rwREPLACE);
- RwTransformCamera(Camera, RwScratchMatrix(), rwPOSTCONCAT);
- RwPopScratchMatrix();
- RwVCMoveCamera(Camera,
- CREAL(0.0),
- CREAL(0.0),
- RDiv(INT2REAL(LastY - y), CREAL(50.0)));
- RwGetCameraPosition(Camera, &position);
- if (position.x < CREAL(-1.5))
- position.x = CREAL(-1.5);
- if (position.x > CREAL( 1.5))
- position.x = CREAL( 1.5);
- if (position.z < CREAL(-1.5))
- position.z = CREAL(-1.5);
- if (position.z > CREAL( 1.5))
- position.z = CREAL( 1.5);
- RwSetCameraPosition(Camera, position.x, position.y, position.z);
- TrackBackdropToCamera(Camera);
- break;
-
- case cmPLAN:
- RwVCMoveCamera(Camera,
- RDiv(INT2REAL(LastX - x), CREAL(50.0)),
- RDiv(INT2REAL(y - LastY), CREAL(50.0)),
- CREAL(0.0));
- RwGetCameraPosition(Camera, &position);
- if (position.x < CREAL(-1.0))
- position.x = CREAL(-1.0);
- if (position.x > CREAL( 1.0))
- position.x = CREAL( 1.0);
- if (position.z < CREAL(-1.0))
- position.z = CREAL(-1.0);
- if (position.z > CREAL( 1.0))
- position.z = CREAL( 1.0);
- RwSetCameraPosition(Camera, position.x, position.y, position.z);
- break;
- }
- break;
-
- case mmALTMOVECAMERA:
- switch (CameraMode)
- {
- case cmNONE:
- case cmRIDE:
- case cmSPOTTER:
- case cmTRAIL:
- case cmLEAD:
- break;
-
- case cmELEVATION:
- RwVCMoveCamera(Camera,
- CREAL(0.0),
- RDiv(INT2REAL(y - LastY), CREAL(50.0)),
- CREAL(0.0));
- RwGetCameraPosition(Camera, &position);
- if (position.y < DEFAULTGROUNDLEVEL)
- position.y = DEFAULTGROUNDLEVEL;
- if (position.y > DEFAULTSKYLEVEL)
- position.y = DEFAULTSKYLEVEL;
- RwSetCameraPosition(Camera, position.x, position.y, position.z);
- TrackBackdropToCamera(Camera);
- break;
-
- case cmPLAN:
- RwVCMoveCamera(Camera,
- CREAL(0.0),
- CREAL(0.0),
- RDiv(INT2REAL(y - LastY), CREAL(50.0)));
- RwGetCameraPosition(Camera, &position);
- if (position.y < DEFAULTGROUNDLEVEL)
- position.y = DEFAULTGROUNDLEVEL;
- if (position.y > DEFAULTSKYLEVEL)
- position.y = DEFAULTSKYLEVEL;
- RwSetCameraPosition(Camera, position.x, position.y, position.z);
- break;
- }
- break;
-
- case mmMOVECONTROL:
- RwPushScratchMatrix();
- /*
- * This function (from pick.c) returns the new position for a clump which lies under
- * the given viewport coordinates. This allows as to drag control points exactly
- * under the mouse pointer.
- */
- if (DoStretch)
- GetClumpPositionUnderPointer(COASTERCONTROLPOINT(CurrentCoaster, ControlPoint),
- Camera, x / 2, y / 2, &newPos);
- else
- GetClumpPositionUnderPointer(COASTERCONTROLPOINT(CurrentCoaster, ControlPoint),
- Camera, x, y, &newPos);
- RwTranslateMatrix(RwScratchMatrix(), newPos.x, newPos.y, newPos.z, rwREPLACE);
- TransformCoasterControlPoint(CurrentCoaster, ControlPoint, RwScratchMatrix());
- RwPopScratchMatrix();
- break;
-
- case mmMOVELIGHT:
- /*
- * We are panning the light about the origin. We will rotate
- * the light about the Y axis for movements of the mouse in
- * X and rotate the light about the X axis for movements of
- * the mouse in Y. In this case we will ignore the effects
- * of camera orientation changes.
- */
- RwPushScratchMatrix();
- /*
- * Replace the CTM with a rotation matrix about Y. The number
- * of degrees of rotation is given by the mouse X delta.
- */
- RwRotateMatrix(RwScratchMatrix(), CREAL(0.0), CREAL(1.0), CREAL(0.0),
- INT2REAL(LastX - x), rwREPLACE);
-
- /*
- * Postconcat another rotation onto the CTM. The new rotation
- * is a rotation about X, the angle being given by the mouse
- * Y delta.
- */
- RwRotateMatrix(RwScratchMatrix(), CREAL(1.0), CREAL(0.0), CREAL(0.0),
- INT2REAL(LastY - y), rwPOSTCONCAT);
-
- /*
- * Transform the light by the resultant rotations.
- */
- RwTransformLight(CurrentCoaster->light, RwScratchMatrix(), rwPOSTCONCAT);
- RwPopScratchMatrix();
- break;
- }
-
- if (MouseMoveMode != mmNONE)
- {
- /*
- * Re-render the scene and copy the results to the display.
- */
- dc = GetDC(window);
- RenderScene(window, dc);
- ReleaseDC(window, dc);
-
- /*
- * Remember the current X and Y for next time.
- */
- LastX = x;
- LastY = y;
- }
- }
-
- /**********************************************************************/
-
- /*
- * Handle the left mouse button comming back up. The basic action is
- * to turn off mouse move actions and release mouse capture.
- */
- static void
- OnLButtonUp(HWND window)
- {
- HDC dc;
-
- /*
- * If we were engaged in a mouse move action and the button has come
- * back up, then terminate the action and release mouse capture.
- */
- switch (MouseMoveMode)
- {
- case mmNONE:
- break;
-
- case mmMOVECAMERA:
- case mmALTMOVECAMERA:
- MouseMoveMode = mmNONE;
- ReleaseCapture();
- switch (CameraMode)
- {
- case cmRIDE:
- case cmSPOTTER:
- case cmTRAIL:
- case cmLEAD:
- break;
-
- case cmELEVATION:
- RwGetCameraPosition(Camera, &CurrentCoaster->elevationPosition);
- break;
-
- case cmPLAN:
- RwGetCameraPosition(Camera, &CurrentCoaster->planPosition);
- break;
- }
- SetTimer(window, 1, 20, NULL);
- break;
-
- case mmMOVECONTROL:
- MouseMoveMode = mmNONE;
- ReleaseCapture();
- UpdateCoasterClump(CurrentCoaster);
- dc = GetDC(window);
- RenderScene(window, dc);
- ReleaseDC(window, dc);
- SetTimer(window, 1, 20, NULL);
- break;
- }
- }
-
- /**********************************************************************/
-
- /*
- * Handle the right mouse button comming back up. The basic action is
- * to turn of mouse move actions and release mouse capture.
- */
- static void
- OnRButtonUp(HWND window)
- {
- /*
- * If we were engaged in a mouse move action and the button has come
- * back up, then terminate the action and release mouse capture.
- */
- if (MouseMoveMode != mmNONE)
- {
- MouseMoveMode = mmNONE;
- ReleaseCapture();
- }
- }
-
- /**********************************************************************/
-
- /*
- * Handle an MS Window's drop message, this function will attempt to
- * load the file dropped as a RenderWare clump. If that fails, it will
- * then attempt to load the file as a raster and make it the camera's
- * backdrop.
- */
- static void
- OnDrop(HWND window, HDROP drop)
- {
- int i;
- int numFiles;
- char path[_MAX_PATH];
- HDC dc;
- RwClump *clump;
-
- /*
- * Get the number of dropped files.
- */
- numFiles = DragQueryFile(drop, (UINT)-1, NULL, 0U);
-
- /*
- * Attempt to load each file in turn.
- */
- for (i = 0; i < numFiles; i++)
- {
- /*
- * LoadClumpOrBackdrop() is called to attempt to load either a
- * clump or texture from the file. If a texture is read then a
- * sprite using that texture is created and returned.
- */
- DragQueryFile(drop, i, path, _MAX_PATH);
-
- clump = RwReadShape(path);
- if (clump)
- RwAddClumpToScene(CurrentCoaster->scene, clump);
- }
- DragFinish(drop);
-
- /*
- * As new objects have been loaded we must re-render the scene.
- */
- dc = GetDC(window);
- RenderScene(window, dc);
- ReleaseDC(window, dc);
- }
-
- /**********************************************************************/
-
- /*
- * Handle the WM_PAINT message by simply copying the rendering
- * already performed (an stored in the camera's image buffer) to the
- * output window. There is no need to re-render as nothing in the
- * scene has changed since the last render. HandleSize() re-renders
- * when the viewport changes and HandleDrop() re-renders when
- * clumps are added.
- */
- static void
- OnPaint(HWND window)
- {
- HDC dc;
- PAINTSTRUCT paintStruct;
-
- dc = BeginPaint(window, &paintStruct);
-
- /*
- * The truly optimal thing to do would be to get the damaged area
- * of the window that needs updating and set that to be the damaged
- * area of the viewport. If this was done then only the portion of
- * viewport corresponding to damaged area of the window would be
- * copied. However, as WM_PAINTs are rare in comparison to timer
- * expiries or mouse moves (where the real rendering effort goes)
- * there is little to be gained from damaging only a portion of
- * the display. Therefore, we invalidate the entire viewport and
- * copy it all to the window.
- */
- RwInvalidateCameraViewport(Camera);
-
- /*
- * Copy the viewport to the display.
- */
- RwShowCameraImage(Camera, (void*)(DWORD)dc);
-
- EndPaint(window, &paintStruct);
- }
-
- /**********************************************************************/
-
- /*
- * Handle MS Window's timer expiry. This function will perform any
- * animation actions necessary, including spinning clumps and animating
- * textures.
- */
- static void
- OnTimer(HWND window)
- {
- HDC dc;
- RwReal x;
- RwReal y;
- RwReal z;
-
- if (MouseMoveMode == mmNONE)
- {
- switch (CameraMode)
- {
- case cmRIDE:
- UpdateViewParameters(CurrentCoaster);
- RwSetCameraLookUp(Camera, CREAL(0.0), CREAL(1.0), CREAL(0.0));
- RwSetCameraLookAt(Camera,
- CurrentCoaster->tAt.x,
- CurrentCoaster->tAt.y,
- CurrentCoaster->tAt.z);
- x = RAdd(CurrentCoaster->tPosition.x, RMul(CurrentCoaster->tUp.x, CREAL(0.1)));
- y = RAdd(CurrentCoaster->tPosition.y, RMul(CurrentCoaster->tUp.y, CREAL(0.1)));
- z = RAdd(CurrentCoaster->tPosition.z, RMul(CurrentCoaster->tUp.z, CREAL(0.1)));
- RwSetCameraPosition(Camera, x, y, z);
- TrackBackdropToCamera(Camera);
- UpdateCoasterVelocity(CurrentCoaster);
- break;
-
- case cmSPOTTER:
- UpdateViewParameters(CurrentCoaster);
- RwSetCameraPosition(Camera,
- CurrentCoaster->tPosition.x,
- CurrentCoaster->tPosition.y,
- CurrentCoaster->tPosition.z);
- RwSetCameraLookUp(Camera, CREAL(0.0), CREAL(1.0), CREAL(0.0));
- RwSetCameraLookAt(Camera, CREAL(0.0), CREAL(0.0), CREAL(1.0));
- RwSetCameraLookUp(Camera, CREAL(0.0), CREAL(1.0), CREAL(0.0));
- RwPanCamera(Camera, CameraAngle);
- RwTiltCamera(Camera, CREAL(40.0));
- RwVCMoveCamera(Camera, CREAL(0.0), CREAL(0.0), CREAL(-0.20));
- TrackBackdropToCamera(Camera);
- UpdateCoasterVelocity(CurrentCoaster);
-
- CameraAngle = RAdd(CameraAngle, CREAL(5.0));
- if (CameraAngle > CREAL(360.0))
- CameraAngle = RSub(CameraAngle, CREAL(360.0));
- break;
-
- case cmTRAIL:
- UpdateViewParameters(CurrentCoaster);
- RwSetCameraPosition(Camera,
- CurrentCoaster->tPosition.x,
- CurrentCoaster->tPosition.y,
- CurrentCoaster->tPosition.z);
- RwSetCameraLookUp(Camera, CREAL(0.0), CREAL(1.0), CREAL(0.0));
- RwSetCameraLookAt(Camera,
- CurrentCoaster->tAt.x,
- CurrentCoaster->tAt.y,
- CurrentCoaster->tAt.z);
- RwSetCameraLookUp(Camera,
- CurrentCoaster->tUp.x,
- CurrentCoaster->tUp.y,
- CurrentCoaster->tUp.z);
- RwTiltCamera(Camera, CREAL(45.0));
- RwVCMoveCamera(Camera, CREAL(0.0), CREAL(0.0), CREAL(-0.15));
- TrackBackdropToCamera(Camera);
- UpdateCoasterVelocity(CurrentCoaster);
- break;
-
- case cmLEAD:
- UpdateViewParameters(CurrentCoaster);
- RwSetCameraPosition(Camera,
- CurrentCoaster->tPosition.x,
- CurrentCoaster->tPosition.y,
- CurrentCoaster->tPosition.z);
- RwSetCameraLookUp(Camera, CREAL(0.0), CREAL(1.0), CREAL(0.0));
- RwSetCameraLookAt(Camera,
- CurrentCoaster->tAt.x,
- CurrentCoaster->tAt.y,
- CurrentCoaster->tAt.z);
- RwSetCameraLookUp(Camera,
- CurrentCoaster->tUp.x,
- CurrentCoaster->tUp.y,
- CurrentCoaster->tUp.z);
- RwPanCamera(Camera, CREAL(180.0));
- RwTiltCamera(Camera, CREAL(60.0));
- RwVCMoveCamera(Camera, CREAL(0.0), CREAL(0.0), CREAL(-0.15));
- TrackBackdropToCamera(Camera);
- UpdateCoasterVelocity(CurrentCoaster);
- break;
-
- case cmELEVATION:
- case cmPLAN:
- UpdateViewParameters(CurrentCoaster);
- UpdateCoasterVelocity(CurrentCoaster);
- break;
- }
- }
-
- /*
- * Re-render the scene and copy the results to the display.
- */
- dc = GetDC(window);
- RenderScene(window, dc);
- ReleaseDC(window, dc);
- }
-
- /**********************************************************************/
-
- /*
- * The window procedure for this application's window.
- */
- LRESULT CALLBACK
- MainWndProc(HWND window, UINT message, WPARAM wParam, LPARAM lParam)
- {
- #if defined(WIN32)
- POINTS point;
- #else
- POINT point;
- #endif
-
- switch (message)
- {
- case WM_CREATE:
- /*
- * Clumps are loaded into the scene by drag and drop.
- * So make this window a drop site.
- */
- DragAcceptFiles(window, TRUE);
-
- /*
- * 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_GETMINMAXINFO:
- /*
- * The MK_FP32() is necessary under Watcom to convert
- * an MS Windows 16 bit far pointer to a 32 bit far pointer.
- */
- #if defined(__WINDOWS_386__)
- OnGetMinMaxInfo((MINMAXINFO FAR*)MK_FP32((void*)lParam));
- #else
- OnGetMinMaxInfo((MINMAXINFO FAR*)lParam);
- #endif
- return 0L;
-
- case WM_SIZE:
- if (ThreeDInitialized)
- OnSize(window, LOWORD(lParam), HIWORD(lParam));
- return 0L;
-
- case WM_DROPFILES:
- if (ThreeDInitialized)
- OnDrop(window, (HDROP)wParam);
- return 0L;
-
- case WM_COMMAND:
- if (LOWORD(lParam) == 0)
- {
- KillTimer(window, 1);
- OnMenu(window, wParam);
- SetTimer(window, 1, 20, NULL);
- }
- return 0L;
-
- case WM_LBUTTONDOWN:
- if (ThreeDInitialized)
- {
- #if defined(WIN32)
- point = MAKEPOINTS(lParam);
- #else
- point = MAKEPOINT(lParam);
- #endif
- OnLButtonDown(window, point.x, point.y, wParam);
- }
- return 0L;
-
- case WM_RBUTTONDOWN:
- if (ThreeDInitialized)
- {
- #if defined(WIN32)
- point = MAKEPOINTS(lParam);
- #else
- point = MAKEPOINT(lParam);
- #endif
- OnRButtonDown(window, point.x, point.y, wParam);
- }
- return 0L;
-
- case WM_MOUSEMOVE:
- if (ThreeDInitialized)
- {
- if (MouseMoveMode != mmNONE)
- {
- #if defined(WIN32)
- point = MAKEPOINTS(lParam);
- #else
- point = MAKEPOINT(lParam);
- #endif
- OnMouseMove(window, point.x, point.y);
- }
- }
- return 0L;
-
- case WM_LBUTTONUP:
- if (ThreeDInitialized)
- {
- OnLButtonUp(window);
- }
- return 0L;
-
- case WM_RBUTTONUP:
- if (ThreeDInitialized)
- OnRButtonUp(window);
- return 0L;
-
- case WM_PAINT:
- if (ThreeDInitialized)
- OnPaint(window);
- return 0L;
-
- case WM_TIMER:
- if (ThreeDInitialized)
- OnTimer(window);
- return 0L;
-
- case WM_DESTROY:
- /*
- * The window is going away so it is no longer a drop site.
- */
- DragAcceptFiles(window, FALSE);
-
- /*
- * Turn the timer off.
- */
- KillTimer(window, 1);
-
- /*
- * Quit message handling.
- */
- PostQuitMessage(0);
- return 0L;
- }
-
- /*
- * Let Windows handle all other messages.
- */
- return DefWindowProc(window, message, wParam, lParam);
- }
-
- /**********************************************************************/
-
- /*
- * Parse the command line arguments.
- */
- static void
- ParseCommandLineArguments(LPSTR cmdLine)
- {
- char *c;
- char *option;
-
- c = cmdLine;
-
- while (*c != '\0')
- {
- option = strchr(c, '-');
- if (option == NULL)
- option = strchr(c, '/');
- if (option == NULL)
- return;
-
- if (++option == '\0')
- return;
-
- switch (*option)
- {
- case 'g':
- case 'G':
- UseWinG = !UseWinG;
- break;
- }
-
- c = (option + 1);
- }
- }
-
- /**********************************************************************/
-
- /*
- * MS Windows application entry point.
- */
- int PASCAL
- WinMain(HANDLE instance, HANDLE prevInstance, LPSTR cmdLine, int cmdShow)
- {
- MSG message;
- HWND window;
- char buffer[_MAX_PATH];
- int pathLen;
- char drive[_MAX_DRIVE];
- char dir[_MAX_DIR];
-
- /*
- * Remember the instance handle in a global variable for later use.
- */
- AppInstance = instance;
-
- if (prevInstance)
- {
- /*
- * Only allow one viewer application to run at any one time.
- */
- MessageBox(NULL, "The RenderWare Rollercoaster is already running...",
- WINDOWTITLE, MB_OK | MB_APPLMODAL | MB_ICONSTOP);
- return FALSE;
- }
-
- /*
- * Parse the command line arguments.
- */
- ParseCommandLineArguments(cmdLine);
-
- /*
- * Register the window class.
- */
- if (!InitApplication(instance))
- {
- return FALSE;
- }
-
- /*
- * Create the window.
- */
- window = InitInstance(instance);
- if (window == NULL)
- return FALSE;
-
- /*
- * Identify the directory from which the application is being
- * run. We will use this for getting hold of scripts and
- * textures, and also for loading coaster files. We ensure that
- * the path identified ends in a backslash.
- */
- GetModuleFileName(instance, buffer, sizeof(buffer));
- _splitpath(buffer, drive, dir, NULL, NULL); /* Caution, PC specific function. */
- strcpy(AppPath, drive);
- strcat(AppPath, dir);
- pathLen = strlen(AppPath);
- if (pathLen > 0)
- {
- if (AppPath[pathLen - 1] != '\\')
- {
- AppPath[pathLen] = '\\';
- AppPath[pathLen + 1] = '\0';
- }
- }
-
- /*
- * Initialize the 3D (RenderWare) components of the app.
- */
- if (!Init3D(window))
- {
- DestroyWindow(window);
- return FALSE;
- }
-
- /*
- * Show the window, and refresh it.
- */
- ShowWindow(window, cmdShow);
- UpdateWindow(window);
-
- /*
- * Enter the message processing loop.
- */
- while (GetMessage(&message, NULL, 0U, 0U))
- {
- TranslateMessage(&message);
- DispatchMessage(&message);
- }
-
- /*
- * Tidy up the 3D (RenderWare) components of the application.
- */
- TidyUp3D();
-
- return message.wParam;
- }
-
- /**********************************************************************/
-