home *** CD-ROM | disk | FTP | other *** search
/ Learn 3D Graphics Programming on the PC / Learn_3D_Graphics_Programming_on_the_PC_Ferraro.iso / rwwin / rwwalk.c_ / rwwalk.bin
Text File  |  1995-11-14  |  24KB  |  836 lines

  1. /**********************************************************************
  2.  *
  3.  * File :     rwwalk.c
  4.  *
  5.  * Abstract : RenderWare Walkthrough demo. Main module
  6.  *
  7.  **********************************************************************
  8.  *
  9.  * This file is a product of Criterion Software Ltd.
  10.  *
  11.  * This file is provided as is with no warranties of any kind and is
  12.  * provided without any obligation on Criterion Software Ltd. or
  13.  * Canon Inc. to assist in its use or modification.
  14.  *
  15.  * Criterion Software Ltd. will not, under any
  16.  * circumstances, be liable for any lost revenue or other damages arising
  17.  * from the use of this file.
  18.  *
  19.  * Copyright (c) 1995 Criterion Software Ltd.
  20.  * All Rights Reserved.
  21.  *
  22.  * RenderWare is a trademark of Canon Inc.
  23.  *
  24.  ************************************************************************/
  25. /**********************************************************************
  26.  *
  27.  * Header files.
  28.  *
  29.  **********************************************************************/
  30.  
  31. #define INCLUDE_SHELLAPI_H
  32.  
  33. #include <windows.h>
  34. #include <stdio.h>
  35. #include <stdlib.h>
  36. #include <string.h>
  37. #include <math.h>
  38.  
  39. #include "rwlib.h"
  40.  
  41. #include "status.h"
  42. #include "common.h"
  43. #include "resource.h"
  44.  
  45. /**********************************************************************
  46.  *
  47.  * Application constants.
  48.  *
  49.  **********************************************************************/
  50.  
  51. #if !defined(__WINDOWS_386__)
  52. #define MK_FP32(x) (x)
  53. #endif
  54.  
  55. /*
  56.  * Uncomment the following line to give the object's in the scene
  57.  * momentum, i.e., after they have been spun by mouse move, they will
  58.  * continue to spin by an animation facility driven by the MS Windows
  59.  * timer message.
  60.  */
  61. /* #define DO_MOMENTUM */
  62.  
  63. #define DEFAULT_WINDOW_WIDTH    300
  64. #define DEFAULT_WINDOW_HEIGHT   300
  65.  
  66. #define MAXIMUM_WINDOW_WIDTH    512
  67. #define MAXIMUM_WINDOW_HEIGHT   512
  68.  
  69. #define DEFAULT_CAMERA_TILT     CREAL(0.0)
  70.  
  71. #define DEFAULT_CAMERA_HEIGHT   CREAL(0.0)
  72.  
  73. #define MAX_ANIM_TEXTURE        10
  74.  
  75. #define ERROR_DIALOG_TITLE      "RenderWare Walkthrough Error"
  76.  
  77. /*--- Ansi Declarations */
  78.  
  79. /**********************************************************************
  80.  *
  81.  * Forward functions.
  82.  *
  83.  **********************************************************************/
  84.  
  85. extern long far PASCAL MainWndProc(HWND, WORD, WORD, LONG);
  86.  
  87. /**********************************************************************
  88.  *
  89.  * Type definitions.
  90.  *
  91.  **********************************************************************/
  92.  
  93. typedef enum
  94. {
  95.     MMNoAction,
  96.     MMMoveCamera,
  97.     MMPanCamera,
  98.     MMTiltCamera,
  99.     MMDragClump
  100. }
  101. MMMode;
  102.  
  103. typedef enum
  104. {
  105.     ANNoAction,
  106.     ANMoveCamera,
  107.     ANPanCamera
  108. }
  109. ANMode;
  110.  
  111. /**********************************************************************
  112.  *
  113.  * Application global variables.
  114.  *
  115.  **********************************************************************/
  116.  
  117. static HANDLE AppInstance;
  118.  
  119. static RwScene *Scene = NULL;
  120. static RwCamera *Camera = NULL;
  121. static RwLight *Light = NULL;
  122.  
  123. static MMMode MouseMoveMode = MMNoAction;
  124. static ANMode AnimMode = ANNoAction;
  125.  
  126. static RwInt32 FirstX;
  127. static RwInt32 FirstY;
  128. static RwInt32 LastX;
  129. static RwInt32 LastY;
  130. static RwInt32 Width;
  131. static RwInt32 Height;
  132.  
  133. static RwReal CamZDelta;
  134. static RwReal CamPanDelta;
  135. static RwReal CamTilt = DEFAULT_CAMERA_TILT;
  136.  
  137. static RwTexture *TextureArray[MAX_ANIM_TEXTURE];
  138. static RwInt32 TextureCount = 0;
  139.  
  140. static RwClump *DragClump = NULL;
  141.  
  142. static BOOL ThreeDInitialized = FALSE;
  143.  
  144. /**********************************************************************
  145.  *
  146.  * Functions.
  147.  *
  148.  **********************************************************************/
  149.  
  150. /**************************************************************************
  151.     About Dialogue Box Stuff
  152. **************************************************************************/
  153. void 
  154. DlgDrawItem(DRAWITEMSTRUCT FAR * dis)
  155. {
  156.     HDC hdcMemory;
  157.     HBITMAP hbmplogo, hbmpOld;
  158.     BITMAP bm;
  159.  
  160.     hbmplogo = LoadBitmap(AppInstance, "CRITERION_LOGO");
  161.     GetObject(hbmplogo, sizeof (BITMAP), &bm);
  162.  
  163.     hdcMemory = CreateCompatibleDC(dis->hDC);
  164.     hbmpOld = SelectObject(hdcMemory, hbmplogo);
  165.  
  166.     BitBlt(dis->hDC, dis->rcItem.left, dis->rcItem.top,
  167.            dis->rcItem.right - dis->rcItem.left,
  168.            dis->rcItem.bottom - dis->rcItem.top,
  169.            hdcMemory, 0, 0, SRCCOPY);
  170.  
  171.     SelectObject(hdcMemory, hbmpOld);
  172.     DeleteDC(hdcMemory);
  173.     DeleteObject(hbmplogo);
  174. }
  175.  
  176. BOOL FAR PASCAL 
  177. AboutDlgProc(HWND hDlg, WORD message, WORD wParam, LONG lParam)
  178. {
  179.     switch (message)
  180.     {
  181.         case WM_INITDIALOG:
  182.             return TRUE;
  183.  
  184.         case WM_COMMAND:
  185.             switch (wParam)
  186.             {
  187.                 case IDOK:
  188.                 case IDCANCEL:
  189.                     EndDialog(hDlg, 0);
  190.                     return (TRUE);
  191.             }
  192.             break;
  193.  
  194.         case WM_DRAWITEM:
  195.             DlgDrawItem((DRAWITEMSTRUCT FAR *) MK_FP32((void *) lParam));
  196.             return (TRUE);
  197.     }
  198.     return (FALSE);
  199. }
  200.  
  201. /**********************************************************************/
  202. /* Handle the given menu item. */
  203. /**********************************************************************/
  204.  
  205. static void
  206. HandleMenu(HWND window, WORD menuItem)
  207. {
  208.     switch (menuItem)
  209.     {
  210.         case CM_FILEEXIT:
  211.             SendMessage(window, WM_CLOSE, 0, 0L);
  212.             break;
  213.         case CM_HELPABOUT:
  214.             KillTimer(window, 1);
  215.             DialogBox(AppInstance, "ABOUT", window, MakeProcInstance(AboutDlgProc, AppInstance));
  216.             SetTimer(window, 1, 10, NULL);
  217.             break;
  218.     }
  219. }
  220.  
  221. /**********************************************************************/
  222.  
  223. /*
  224.  * Perform any necessary MS Windows application initialization. Basically,
  225.  * this means registering the window class for this application.
  226.  */
  227. static BOOL
  228. InitApplication(HANDLE Instance)
  229. {
  230.     WNDCLASS wc;
  231.  
  232.     wc.style = CS_BYTEALIGNWINDOW;
  233.     wc.lpfnWndProc = (WNDPROC) MainWndProc;
  234.     wc.cbClsExtra = 0;
  235.     wc.cbWndExtra = 0;
  236.     wc.hInstance = Instance;
  237.     wc.hIcon = LoadIcon(Instance, "RW_ICON");
  238.     wc.hCursor = LoadCursor(NULL, IDC_ARROW);
  239.     wc.hbrBackground = NULL;
  240.     wc.lpszMenuName = "FILE_MENU";
  241.     wc.lpszClassName = "RwWalkWndClass";
  242.  
  243.     return RegisterClass(&wc);
  244. }
  245.  
  246. /**********************************************************************/
  247.  
  248. static HWND
  249. InitInstance(HANDLE Instance)
  250. {
  251.     HWND Window;
  252.  
  253.     /*
  254.      * Create the MS Windows window instance for this application. The initial
  255.      * window size is given by DEFAULT_WINDOW_WIDTH and DEFAULT_WINDOW_HEIGHT.
  256.      * However, when we create the RenderWare camera in Init3D() we specify
  257.      * a maximum camera viewport which is the same size as the screen. Thus
  258.      * the window can be maximed.
  259.      */
  260.     Window = CreateWindow("RwWalkWndClass", "RenderWare WalkThrough",
  261.                           WS_OVERLAPPEDWINDOW,
  262.                           CW_USEDEFAULT, CW_USEDEFAULT,
  263.                           DEFAULT_WINDOW_WIDTH, DEFAULT_WINDOW_HEIGHT,
  264.                           NULL, NULL, Instance, NULL);
  265.     if (!Window)
  266.     {
  267.         return NULL;
  268.     }
  269.     CheckDisplayDepth(Window);
  270.  
  271.     return Window;
  272. }
  273.  
  274. /**********************************************************************/
  275.  
  276. static RwTexture *
  277. AddAnimTextures(RwTexture * Texture)
  278. {
  279.     if (RwGetTextureNumFrames(Texture) > 1)
  280.         TextureArray[(int) (TextureCount++)] = Texture;
  281.     return Texture;
  282. }
  283.  
  284. /**********************************************************************/
  285.  
  286. static BOOL
  287. Init3D(HANDLE Instance, HWND Window)
  288. {
  289.     RwClump *Clump;
  290.     char buffer[64];
  291.     int i;
  292.  
  293.     if (!RwOpen("MSWindows", NULL))
  294.     {
  295.         if (RwGetError() == E_RW_NOMEM)
  296.         {
  297.             MessageBox(Window,
  298.                        "Insufficient memory to open the RenderWare library",
  299.                        ERROR_DIALOG_TITLE,
  300.                        MB_OK | MB_ICONSTOP | MB_APPLMODAL);
  301.         }
  302.         else
  303.         {
  304.             MessageBox(Window, "Error opening the RenderWare library",
  305.                        ERROR_DIALOG_TITLE,
  306.                        MB_OK | MB_ICONSTOP | MB_APPLMODAL);
  307.         }
  308.         return FALSE;
  309.     }
  310.  
  311. /*---    Set the shape path to enable texture loading     ---*/
  312.  
  313.     GetModuleFileName(Instance, buffer, sizeof (buffer));
  314.     i = strlen(buffer);
  315.     while (buffer[i] != '\\')
  316.         i--;
  317.     buffer[i + 1] = 0;
  318.     strcat(buffer, "TEXTURES");
  319.     RwSetShapePath(buffer, rwREPLACE);
  320.  
  321.     buffer[i + 1] = 0;
  322.     strcat(buffer, "SCRIPTS");
  323.     RwSetShapePath(buffer, rwPOSTCONCAT);
  324.  
  325.     buffer[i + 1] = 0;
  326.     strcat(buffer, ".");
  327.     RwSetShapePath(buffer, rwPOSTCONCAT);
  328.  
  329.     Camera = RwCreateCamera(MAXIMUM_WINDOW_WIDTH,
  330.                             MAXIMUM_WINDOW_HEIGHT, NULL);
  331.     if (!Camera)
  332.     {
  333.         if (RwGetError() == E_RW_NOMEM)
  334.         {
  335.             MessageBox(Window,
  336.                        "Insufficient memory to create the RenderWare camera",
  337.                        ERROR_DIALOG_TITLE,
  338.                        MB_OK | MB_ICONSTOP | MB_APPLMODAL);
  339.         }
  340.         else
  341.         {
  342.             MessageBox(Window, "Error creating the RenderWare camera",
  343.                        ERROR_DIALOG_TITLE,
  344.                        MB_OK | MB_ICONSTOP | MB_APPLMODAL);
  345.         }
  346.         return FALSE;
  347.     }
  348.  
  349.     RwSetCameraBackColor(Camera, CREAL(0.0), CREAL(0.0), CREAL(0.0));
  350.     RwSetCameraNearClipping(Camera, CREAL(0.05));
  351.     RwPanCamera(Camera, CREAL(180.0));
  352.     RwTiltCamera(Camera, CamTilt);
  353.     RwSetCameraBackColor(Camera, CREAL(0.5), CREAL(0.5), CREAL(1.0));
  354.     RwSetCameraViewwindow(Camera, CREAL(0.6), CREAL(0.6));
  355.  
  356.     Scene = RwCreateScene();
  357.     if (!Scene)
  358.     {
  359.         MessageBox(Window, "Error creating the RenderWare scene",
  360.                    ERROR_DIALOG_TITLE,
  361.                    MB_OK | MB_ICONSTOP | MB_APPLMODAL);
  362.         return FALSE;
  363.     }
  364.  
  365.     Light = RwCreateLight(rwDIRECTIONAL, CREAL(0.1), CREAL(-1.0), CREAL(-0.5),
  366.                           CREAL(1.0));
  367.     if (!Light)
  368.     {
  369.         MessageBox(Window, "Error creating the RenderWare light",
  370.                    ERROR_DIALOG_TITLE,
  371.                    MB_OK | MB_ICONSTOP | MB_APPLMODAL);
  372.         return FALSE;
  373.     }
  374.  
  375.     RwAddLightToScene(Scene, Light);
  376.  
  377.     Clump = RwReadShape("kitchen.rwx");
  378.     if (!Clump)
  379.     {
  380.         if (RwGetError() == E_RW_NOMEM)
  381.         {
  382.             MessageBox(Window,
  383.                        "Insufficient memory to read script file kitchen.rwx",
  384.                        ERROR_DIALOG_TITLE,
  385.                        MB_OK | MB_ICONSTOP | MB_APPLMODAL);
  386.         }
  387.         else
  388.         {
  389.             MessageBox(Window, "Could not read script file kitchen.rwx",
  390.                        ERROR_DIALOG_TITLE,
  391.                        MB_OK | MB_ICONSTOP | MB_APPLMODAL);
  392.         }
  393.         return FALSE;
  394.     }
  395.  
  396.     RwAddClumpToScene(Scene, Clump);
  397.     RwForAllNamedTextures(AddAnimTextures);
  398.  
  399.     ThreeDInitialized = TRUE;
  400.  
  401.     return TRUE;
  402. }
  403.  
  404. /**********************************************************************/
  405.  
  406. static void
  407. TidyUp3D()
  408. {
  409.     RwDestroyScene(Scene);
  410.     RwDestroyCamera(Camera);
  411.     RwClose();
  412. }
  413.  
  414. /**********************************************************************/
  415.  
  416. static void
  417. HandleGetMinMaxInfo(HWND Window, MINMAXINFO FAR * minmaxinfo)
  418. {
  419.     minmaxinfo->ptMaxSize.x = MAXIMUM_WINDOW_WIDTH;
  420.     minmaxinfo->ptMaxSize.y = MAXIMUM_WINDOW_HEIGHT;
  421.     minmaxinfo->ptMaxTrackSize.x = MAXIMUM_WINDOW_WIDTH;
  422.     minmaxinfo->ptMaxTrackSize.y = MAXIMUM_WINDOW_HEIGHT;
  423. }
  424.  
  425. /**********************************************************************/
  426.  
  427. static void
  428. HandleSize(HWND Window, RwInt32 Width, RwInt32 Height)
  429. {
  430.     Height = StatusAdjustHeight(Window, (int) Height);
  431.     RwSetCameraViewport(Camera, 0, 0, Width, Height);
  432.     InvalidateRect(Window, NULL, FALSE);
  433. }
  434.  
  435. /**********************************************************************/
  436.  
  437. static void
  438. HandleLeftButtonDown(HWND Window, RwInt32 x, RwInt32 y, WORD VKeys)
  439. {
  440.     RwInt32 vx, vy, vw, vh;
  441.     POINT point;
  442.     RwReal XDelta;
  443.     RwReal YDelta;
  444.  
  445.     if (VKeys & MK_SHIFT)
  446.     {
  447.         MouseMoveMode = MMPanCamera;
  448.         AnimMode = ANPanCamera;
  449.         ShowAppLeftStatus(Window, Camera, "Pan Camera");
  450.     }
  451.     else if (VKeys & MK_CONTROL)
  452.     {
  453.         MouseMoveMode = MMTiltCamera;
  454.         ShowAppLeftStatus(Window, Camera, "Tilt Camera");
  455.     }
  456.     else
  457.     {
  458.         MouseMoveMode = MMMoveCamera;
  459.         AnimMode = ANMoveCamera;
  460.         ShowAppLeftStatus(Window, Camera, "Pan and Zoom Camera");
  461.     }
  462.  
  463.     if (MouseMoveMode != MMNoAction)
  464.     {
  465.         RwGetCameraViewport(Camera, &vx, &vy, &vw, &vh);
  466.         FirstX = vx + (vw >> 1);
  467.         FirstY = vy + (vh >> 1);
  468.         point.x = (int) FirstX;
  469.         point.y = (int) FirstY;
  470.         ClientToScreen(Window, &point);
  471.         FirstX = point.x;
  472.         FirstY = point.y;
  473.         Width = vw;
  474.         Height = vh;
  475.         point.x = (int) x;
  476.         point.y = (int) y;
  477.         ClientToScreen(Window, &point);
  478.         LastX = point.x;
  479.         LastY = point.y;
  480.         XDelta = RDiv(INT2REAL(FirstX - point.x), INT2REAL(Width));
  481.         YDelta = RDiv(INT2REAL(FirstY - point.y), INT2REAL(Height));
  482.         CamZDelta = RDiv(YDelta, CREAL(2));
  483.         CamPanDelta = RMul(XDelta, CREAL(4));
  484.         SetCapture(Window);
  485.     }
  486. }
  487.  
  488. /**********************************************************************/
  489.  
  490. static void
  491. HandleRightButtonDown(HWND Window, RwInt32 x, RwInt32 y, WORD VKeys)
  492. {
  493.     RwInt32 vx, vy, vw, vh;
  494.     POINT point;
  495.     RwPickRecord Pick;
  496.     RwReal XDelta;
  497.     RwReal YDelta;
  498.  
  499.     ShowAppLeftStatus(Window, Camera, "Move Object");
  500.     RwPickScene(Scene, x, y, Camera, &Pick);
  501.     if (Pick.type == rwPICKCLUMP)
  502.     {
  503.         /* The objects in the scene which are manipulatable are tagged
  504.          * with 2. */
  505.         if (RwGetClumpTag(Pick.object.clump.clump) == 2)
  506.         {
  507.             DragClump = Pick.object.clump.clump;
  508.             MouseMoveMode = MMDragClump;
  509.         }
  510.         else
  511.         {
  512.             MouseMoveMode = MMNoAction;
  513.         }
  514.     }
  515.     else
  516.     {
  517.         MouseMoveMode = MMNoAction;
  518.     }
  519.  
  520.     if (MouseMoveMode != MMNoAction)
  521.     {
  522.         RwGetCameraViewport(Camera, &vx, &vy, &vw, &vh);
  523.         FirstX = vx + (vw >> 1);
  524.         FirstY = vy + (vh >> 1);
  525.         point.x = (int) FirstX;
  526.         point.y = (int) FirstY;
  527.         ClientToScreen(Window, &point);
  528.         FirstX = point.x;
  529.         FirstY = point.y;
  530.         Width = vw;
  531.         Height = vh;
  532.         point.x = (int) x;
  533.         point.y = (int) y;
  534.         ClientToScreen(Window, &point);
  535.         LastX = point.x;
  536.         LastY = point.y;
  537.         XDelta = RDiv(INT2REAL(FirstX - point.x), INT2REAL(Width));
  538.         YDelta = RDiv(INT2REAL(FirstY - point.y), INT2REAL(Height));
  539.         CamZDelta = RDiv(YDelta, CREAL(2));
  540.         CamPanDelta = RMul(XDelta, CREAL(6));
  541.         SetCapture(Window);
  542.     }
  543. }
  544.  
  545. /**********************************************************************/
  546.  
  547. static void
  548. HandleMouseMove(HWND Window, int x, int y)
  549. {
  550.     POINT point;
  551.     RwReal XDelta;
  552.     RwReal YDelta;
  553.  
  554.     switch (MouseMoveMode)
  555.     {
  556.         case MMNoAction:
  557.             break;
  558.  
  559.         case MMMoveCamera:
  560.             point.x = x;
  561.             point.y = y;
  562.             ClientToScreen(Window, &point);
  563.             XDelta = RDiv(INT2REAL(FirstX - point.x), INT2REAL(Width));
  564.             YDelta = RDiv(INT2REAL(FirstY - point.y), INT2REAL(Height));
  565.             CamZDelta = RDiv(YDelta, CREAL(2));
  566.             CamPanDelta = RMul(XDelta, CREAL(6));
  567.  
  568.             break;
  569.  
  570.         case MMPanCamera:
  571.             point.x = x;
  572.             point.y = y;
  573.             ClientToScreen(Window, &point);
  574.             XDelta = RDiv(INT2REAL(FirstX - point.x), INT2REAL(Width));
  575.             CamPanDelta = RMul(XDelta, CREAL(6));
  576.             break;
  577.  
  578.         case MMDragClump:
  579.             point.x = x;
  580.             point.y = y;
  581.             ClientToScreen(Window, &point);
  582.             XDelta = RDiv(INT2REAL(point.x - LastX), INT2REAL(Width));
  583.             YDelta = RDiv(INT2REAL(point.y - LastY), INT2REAL(Height));
  584.             RwPushScratchMatrix();
  585.             RwRotateMatrix(RwScratchMatrix(), CREAL(0.0), CREAL(1.0), CREAL(0.0), RMul(XDelta, CREAL(180.0)),
  586.                            rwREPLACE);
  587.             RwTransformClumpJoint(DragClump, RwScratchMatrix(),
  588.                                   rwPOSTCONCAT);
  589.             RwPopScratchMatrix();
  590.             LastX = point.x;
  591.             LastY = point.y;
  592.             break;
  593.  
  594.         case MMTiltCamera:
  595.             point.x = x;
  596.             point.y = y;
  597.             ClientToScreen(Window, &point);
  598.             YDelta = RDiv(INT2REAL(point.y - LastY), INT2REAL(Height));
  599.             RwTiltCamera(Camera, -CamTilt);
  600.             CamTilt = RAdd(CamTilt, RMul(YDelta, CREAL(30)));
  601.             if (CamTilt < CREAL(-45.0))
  602.                 CamTilt = CREAL(-45.0);
  603.             else if (CamTilt > CREAL(45.0))
  604.                 CamTilt = CREAL(45.0);
  605.             RwTiltCamera(Camera, CamTilt);
  606.             LastX = point.x;
  607.             LastY = point.y;
  608.             break;
  609.     }
  610.  
  611. }
  612.  
  613. /**********************************************************************/
  614.  
  615. static void
  616. HandleLeftButtonUp(HWND Window)
  617. {
  618.     if (MouseMoveMode != MMNoAction)
  619.     {
  620.         MouseMoveMode = MMNoAction;
  621.         AnimMode = ANNoAction;
  622.         ReleaseCapture();
  623.         ShowAppLeftStatus(Window, Camera, "");
  624.     }
  625. }
  626.  
  627. /**********************************************************************/
  628.  
  629. static void
  630. HandleRightButtonUp(HWND Window)
  631. {
  632.     if (MouseMoveMode != MMNoAction)
  633.     {
  634.         MouseMoveMode = MMNoAction;
  635.         AnimMode = ANNoAction;
  636.         ReleaseCapture();
  637.         ShowAppLeftStatus(Window, Camera, "");
  638.     }
  639. }
  640.  
  641. /**********************************************************************/
  642.  
  643. static void
  644. HandlePaint(HWND Window)
  645. {
  646.     HDC DC;
  647.     PAINTSTRUCT PS;
  648.  
  649.     DC = BeginPaint(Window, &PS);
  650.     RwInvalidateCameraViewport(Camera);
  651.     RwBeginCameraUpdate(Camera, (void *) (DWORD) Window);
  652.     RwClearCameraViewport(Camera);
  653.     RwRenderScene(Scene);
  654.     RwEndCameraUpdate(Camera);
  655.     RwShowCameraImage(Camera, (void *) (DWORD) DC);
  656.     EndPaint(Window, &PS);
  657.     ShowAppLeftStatus(Window, Camera, "");
  658.     ShowAppRightStatus(Window, Camera, "");
  659. }
  660.  
  661. /**********************************************************************/
  662.  
  663. static void
  664. HandleTimer(HWND Window)
  665. {
  666.     HDC DC;
  667.     int i;
  668.     RwV3d pos;
  669.  
  670.     if (AnimMode != ANNoAction)
  671.     {
  672.         switch (AnimMode)
  673.         {
  674.             case ANMoveCamera:
  675.                 RwTiltCamera(Camera, -CamTilt);
  676.                 RwVCMoveCamera(Camera, CREAL(0.0), CREAL(0.0), CamZDelta);
  677.                 RwPanCamera(Camera, CamPanDelta);
  678.                 RwGetCameraPosition(Camera, &pos);
  679.                 if (pos.x < CREAL(-0.75))
  680.                     pos.x = CREAL(-0.75);
  681.                 else if (pos.x > CREAL(0.75))
  682.                     pos.x = CREAL(0.75);
  683.                 if (pos.z < CREAL(-0.75))
  684.                     pos.z = CREAL(-0.75);
  685.                 else if (pos.z > CREAL(0.75))
  686.                     pos.z = CREAL(0.75);
  687.                 RwSetCameraPosition(Camera, pos.x, DEFAULT_CAMERA_HEIGHT, pos.z);
  688.                 RwTiltCamera(Camera, CamTilt);
  689.                 RwSetCameraLookUp(Camera, CREAL(0.0), CREAL(1.0), CREAL(0.0));
  690.                 break;
  691.  
  692.             case ANPanCamera:
  693.                 RwTiltCamera(Camera, -CamTilt);
  694.                 RwPanCamera(Camera, CamPanDelta);
  695.                 RwTiltCamera(Camera, CamTilt);
  696.                 break;
  697.         }
  698.  
  699.     }
  700.  
  701.     for (i = 0; i < TextureCount; i++)
  702.         RwTextureNextFrame(TextureArray[i]);
  703.  
  704.     RwInvalidateCameraViewport(Camera);
  705.     RwBeginCameraUpdate(Camera, (void *) (DWORD) Window);
  706.     RwClearCameraViewport(Camera);
  707.     RwRenderScene(Scene);
  708.     RwEndCameraUpdate(Camera);
  709.     DC = GetDC(Window);
  710.     RwShowCameraImage(Camera, (void *) (DWORD) DC);
  711.     ReleaseDC(Window, DC);
  712. }
  713.  
  714. /**********************************************************************/
  715.  
  716. long far PASCAL
  717. MainWndProc(HWND Window, WORD Message, WORD WParam, LONG LParam)
  718. {
  719.     switch (Message)
  720.     {
  721.         case WM_COMMAND:
  722.             if (LOWORD(LParam) == 0)
  723.                 HandleMenu(Window, WParam);
  724.             return 0L;
  725.  
  726.         case WM_CREATE:
  727.             SetTimer(Window, 1, 20, NULL);
  728.             break;
  729.  
  730.         case WM_GETMINMAXINFO:
  731.             HandleGetMinMaxInfo(Window, (MINMAXINFO FAR *) MK_FP32((void *) LParam));
  732.             break;
  733.  
  734.         case WM_SIZE:
  735.             if (ThreeDInitialized)
  736.                 HandleSize(Window, (RwInt32) LOWORD(LParam), (RwInt32) HIWORD(LParam));
  737.             break;
  738.  
  739.         case WM_LBUTTONDOWN:
  740.             if (ThreeDInitialized)
  741.                 HandleLeftButtonDown(Window, LOWORD(LParam), HIWORD(LParam), WParam);
  742.             break;
  743.  
  744.         case WM_RBUTTONDOWN:
  745.             if (ThreeDInitialized)
  746.                 HandleRightButtonDown(Window, (RwInt32) LOWORD(LParam), (RwInt32) HIWORD(LParam), WParam);
  747.             break;
  748.  
  749.         case WM_MOUSEMOVE:
  750.             if (ThreeDInitialized)
  751.             {
  752.                 if (MouseMoveMode != MMNoAction)
  753.                     HandleMouseMove(Window, LOWORD(LParam), HIWORD(LParam));
  754.             }
  755.             break;
  756.  
  757.         case WM_LBUTTONUP:
  758.             if (ThreeDInitialized)
  759.                 HandleLeftButtonUp(Window);
  760.             break;
  761.  
  762.         case WM_RBUTTONUP:
  763.             if (ThreeDInitialized)
  764.                 HandleRightButtonUp(Window);
  765.             break;
  766.  
  767.         case WM_PAINT:
  768.             if (ThreeDInitialized)
  769.                 HandlePaint(Window);
  770.             break;
  771.  
  772.         case WM_TIMER:
  773.             if (ThreeDInitialized)
  774.                 HandleTimer(Window);
  775.             break;
  776.  
  777.         case WM_DESTROY:
  778.             KillTimer(Window, 1);
  779.             PostQuitMessage(0);
  780.             break;
  781.  
  782.         default:
  783.             return DefWindowProc(Window, Message, WParam, LParam);
  784.     }
  785.  
  786.     return FALSE;
  787. }
  788.  
  789. /**********************************************************************/
  790.  
  791. int PASCAL
  792. WinMain(HANDLE Instance, HANDLE PrevInstance, LPSTR CmdLine, int CmdShow)
  793. {
  794.     MSG Message;
  795.     HWND Window;
  796.  
  797.     AppInstance = Instance;
  798.  
  799.     if (PrevInstance)
  800.     {
  801.         MessageBox(NULL, "RenderWare WalkThrough is already running...",
  802.                    ERROR_DIALOG_TITLE, MB_OK | MB_ICONSTOP | MB_APPLMODAL);
  803.         return FALSE;
  804.     }
  805.  
  806.     if (!InitApplication(Instance))
  807.     {
  808.         return FALSE;
  809.     }
  810.  
  811.     if (!(Window = InitInstance(Instance)))
  812.     {
  813.         return FALSE;
  814.     }
  815.  
  816.     if (!Init3D(Instance, Window))
  817.     {
  818.         DestroyWindow(Window);
  819.         return FALSE;
  820.     }
  821.  
  822.     ShowWindow(Window, CmdShow);
  823.     UpdateWindow(Window);
  824.  
  825.     while (GetMessage(&Message, (HWND) NULL, (UINT) NULL, (UINT) NULL))
  826.     {
  827.         TranslateMessage(&Message);
  828.         DispatchMessage(&Message);
  829.     }
  830.  
  831.     TidyUp3D();
  832.     UnregisterClass("RwWalkWndClass", Instance);
  833.     return Message.wParam;
  834. }
  835. /**********************************************************************/
  836.