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

  1. /**********************************************************************
  2.  *
  3.  * File :     oswin.c
  4.  *
  5.  * Abstract : The MS Windows specific part of this demo program. 
  6.  *            This file contains all of the OS specific components
  7.  *            of the demo together with the main Windows application
  8.  *            control loop.
  9.  *
  10.  **********************************************************************
  11.  *
  12.  * This file is a product of Criterion Software Ltd.
  13.  *
  14.  * This file is provided as is with no warranties of any kind and is
  15.  * provided without any obligation on Criterion Software Ltd. or
  16.  * Canon Inc. to assist in its use or modification.
  17.  *
  18.  * Criterion Software Ltd. will not, under any
  19.  * circumstances, be liable for any lost revenue or other damages arising
  20.  * from the use of this file.
  21.  *
  22.  * Copyright (c) 1995 Criterion Software Ltd.
  23.  * All Rights Reserved.
  24.  *
  25.  * RenderWare is a trademark of Canon Inc.
  26.  *
  27.  ************************************************************************/
  28.  
  29. /*--- Include files ---*/
  30.  
  31. #define INCLUDE_SHELLAPI_H
  32.  
  33. #include <windows.h>
  34.  
  35. #include "global.h"
  36. #include "common.h"
  37.  
  38. #include "rwwin.h"
  39. #include "resource.h"
  40.  
  41. /*--- Macros and Magic Number definitions ---*/
  42.  
  43. /* Define the windows class name */
  44.  
  45. #define CYBER_CLASS_NAME "RwCyberClass"
  46.  
  47. /* Define the title that will appear on error dialogues */
  48.  
  49. #define ERROR_DIALOG_TITLE "RenderWare(tm) RwCyber Error"
  50.  
  51. /* The default size of the applications window */
  52. #define DEFAULT_WINDOW_WIDTH    640
  53. #define DEFAULT_WINDOW_HEIGHT   510
  54.  
  55. /* The maximum size of the camera that will be created */
  56. #define MAX_CAMERA_WIDTH  640
  57. #define MAX_CAMERA_HEIGHT 480
  58. /*--- Global Variable Definitions ---*/
  59.  
  60. static HWND         hGAppWindow;    /* The current window handle */
  61. static HINSTANCE    hGAppInstance;  /* The application instance handle */
  62. static HDC          PaintDC;        /* The DC to use for calls to
  63.                                        RwShowCameraImage(). This variable
  64.                                        is defined in response to WM_PAINT
  65.                                        or WM_TIMER messages */
  66.  
  67. static RwInt32      UsingDIBs;       /* If we are using DIB's then we
  68.                                        don't want to treat the Camera's image
  69.                                        buffer as an HDC */
  70.  
  71. /* The following variables are used to overlay the text on top of
  72.  * the rendered image.
  73.  */
  74.  
  75. static HFONT fGFont;    /* Font used at high detail */
  76. static HFONT fGSFont;   /* font used at low detail */
  77.  
  78. static HFONT fGOldFont; /* Old font to be restored at app clean up */
  79. static int nGOldMode;   /* Old background mode to be restored at clean up */
  80. static COLORREF nGOldTColor; /* Old text color */
  81. static HPEN pGOldPen;   /* Old pen to be restored at clean up */
  82.  
  83. /* This flag indicates whether the 3D components of the application
  84.  * have been successfully initialized as yet. It is used to guard
  85.  * the message loop handler functions from being invoked before the
  86.  * 3D components of the application are successfully initialized.
  87.  */
  88.  
  89. static BOOL nGThreeDInitialized = FALSE;
  90.  
  91. /* This flag is TRUE if the output image is being stretched (ie low detail)
  92.  * and FALSE if it is high detail */
  93.  
  94. static BOOL nGStretch = FALSE;
  95.  
  96.  
  97. /************************************************************************
  98.  *
  99.  *      Function:       OsBeginCameraUpdate()
  100.  *                      
  101.  *      Description:    Os specific version of RwBeginCameraUpdate().
  102.  *                      For MS Windows RwBeginCameraUpdate() is passed
  103.  *                      the handle to the window. We use the global
  104.  *                      handle that is setup in the main window handler.
  105.  *
  106.  *      Parameters:     Camera - the Camera to pass to RwBeginCameraUpdate()
  107.  *
  108.  *      Return Value:   None
  109.  *
  110.  ************************************************************************/
  111. void OsBeginCameraUpdate(RwCamera *Camera)
  112. {
  113.     RwBeginCameraUpdate(Camera, (void *)(DWORD)hGAppWindow);
  114. }
  115.  
  116. /************************************************************************
  117.  *
  118.  *      Function:       OsShowCameraImage()
  119.  *                      
  120.  *      Description:    Os specific version of RwShowCameraImage().
  121.  *                      For MS Windows RwShowCameraUpdate() is passed
  122.  *                      a DC to display the image. We use the global PaintDC
  123.  *                      which is either the DC returned by BeginPaint() 
  124.  *                      in response to a WM_PAINT message or the DC returned
  125.  *                      by a call to GetDC(hGAppWindow).
  126.  *
  127.  *      Parameters:     None
  128.  *
  129.  *      Return Value:   None
  130.  *
  131.  ************************************************************************/
  132. void OsShowCameraImage(void)
  133. {
  134.     RwShowCameraImage(cpGCamera, (void *)(DWORD)PaintDC);
  135. }
  136.  
  137. /************************************************************************
  138.  *
  139.  *      Function:       OsError()
  140.  *                      
  141.  *      Description:    Os specific error handler. For windows we just
  142.  *                      pop up a message box.
  143.  *
  144.  *      Parameters:     fmt - stdarg format string
  145.  *
  146.  *      Return Value:   None
  147.  *
  148.  ************************************************************************/
  149. void OsError(char *fmt, ...)
  150. {
  151.     char buffer[256];
  152.     va_list args;
  153.  
  154.     va_start(args, fmt);
  155.     vsprintf(buffer, fmt, args);
  156.     va_end(args);
  157.     MessageBox(hGAppWindow, buffer, ERROR_DIALOG_TITLE, 
  158.                MB_OK | MB_ICONSTOP | MB_APPLMODAL);
  159. }
  160.  
  161. /************************************************************************
  162.  *
  163.  *      Function:       OsOpen()
  164.  *                      
  165.  *      Description:    Os specific RwOpen(). This function opens
  166.  *                      RenderWare and sets the Shape Path
  167.  *
  168.  *      Parameters:     None
  169.  *
  170.  *      Return Value:   TRUE if successful else FALSE
  171.  *
  172.  ************************************************************************/
  173. int OsOpen(void)
  174. {
  175.     int i;
  176.     char     buffer[256];
  177. #ifndef WIN32
  178.     RwOpenArgument args;
  179.     args.option = rwWINUSEWING;
  180.  
  181.     if (!RwOpenExt("MSWindows", NULL, 1, &args))
  182. #else
  183.     if (!RwOpen("MSWindows", NULL))
  184. #endif
  185.     {
  186.         if (RwGetError() == E_RW_NOMEM)
  187.         {
  188.              OsError("Insufficient memory to open the RenderWare(tm) library");
  189.         }
  190.         else
  191.         {
  192.             OsError("Error opening the RenderWare(tm) library");
  193.         }
  194.         return FALSE;
  195.     }
  196.     GetModuleFileName(hGAppInstance, buffer, sizeof(buffer));
  197.     i = strlen(buffer);
  198.  
  199.     while(buffer[i] != '\\') 
  200.     i--;
  201.  
  202.     /* set search path so we pick up our geometry & textures */
  203.     buffer[i+1] = 0;
  204.     strcat(buffer, "TEXTURES");
  205.     RwSetShapePath(buffer, rwREPLACE);
  206.  
  207.     buffer[i+1] = 0;
  208.     strcat(buffer, "SCRIPTS");
  209.     RwSetShapePath(buffer, rwPRECONCAT);
  210.  
  211.     buffer[i+1] = 0;
  212.     strcat(buffer, ".");
  213.     RwSetShapePath(buffer, rwPRECONCAT);
  214.  
  215.     SetWindowText(hGAppWindow, "RenderWare CyberStreet");
  216.  
  217.     RwGetDeviceInfo(rwWINIMAGEISDIB, &UsingDIBs, sizeof(UsingDIBs));
  218.  
  219.     return TRUE;
  220. }
  221.  
  222. /************************************************************************
  223.  *
  224.  *      Function:       OsResetCameraViewport()
  225.  *                      
  226.  *      Description:    Reset the camera viewport to have default behaviour. 
  227.  *                      For MS Windows the viewport can be stretched so 
  228.  *                      we disable this stretching.
  229.  *
  230.  *      Parameters:     None
  231.  *
  232.  *      Return Value:   None
  233.  *
  234.  ************************************************************************/
  235. void OsResetCameraViewport()
  236. {
  237.     RwWinOutputSize winOutputSize;
  238.  
  239.     winOutputSize.width  = (RwInt32)-1;
  240.     winOutputSize.height = (RwInt32)-1;
  241.     winOutputSize.camera = cpGCamera;
  242.     RwDeviceControl(rwWINSETOUTPUTSIZE, 0L, &winOutputSize,
  243.                     sizeof(winOutputSize));
  244. }
  245.  
  246. /************************************************************************
  247.  *
  248.  *      Function:       OsSetCameraViewport()
  249.  *                      
  250.  *      Description:    Os specific RwSetCameraViewport(). For MS Windows
  251.  *                      the viewport can be stretched so we have to take 
  252.  *                      account of this before calling RwSetCameraViewport
  253.  *
  254.  *      Parameters:     None
  255.  *
  256.  *      Return Value:   None
  257.  *
  258.  ************************************************************************/
  259. void OsSetCameraViewport()
  260. {
  261.     RwWinOutputSize winOutputSize;
  262.  
  263.     if (nGStretch)
  264.     {
  265.         RwSetCameraViewport(cpGCamera, 
  266.                             PANEL_HOLE_XOFFSET, PANEL_HOLE_YOFFSET,
  267.                             PANEL_HOLE_WIDTH/2, PANEL_HOLE_HEIGHT/2);
  268.         winOutputSize.width  = PANEL_HOLE_WIDTH;
  269.         winOutputSize.height = PANEL_HOLE_HEIGHT;
  270.         winOutputSize.camera = cpGCamera;
  271.         RwDeviceControl(rwWINSETOUTPUTSIZE, 0L, &winOutputSize,
  272.                         sizeof(winOutputSize));
  273.  
  274.     }
  275.     else
  276.     {
  277.         RwSetCameraViewport(cpGCamera, 
  278.                             PANEL_HOLE_XOFFSET, PANEL_HOLE_YOFFSET, 
  279.                             PANEL_HOLE_WIDTH, PANEL_HOLE_HEIGHT);
  280.     }
  281. }
  282.  
  283. /************************************************************************
  284.  *
  285.  *      Function:       OsInit()
  286.  *                      
  287.  *      Description:    Os specific application initialisation. This function
  288.  *                      is called once the palette has been set up and
  289.  *                      performs all of the device specific initialisation
  290.  *                      and object loading
  291.  *
  292.  *      Parameters:     None
  293.  *
  294.  *      Return Value:   TRUE if successful else FALSE
  295.  *
  296.  ************************************************************************/
  297. int OsInit()
  298. {
  299.     HDC      devContext;
  300.     LOGFONT  logFont;
  301.  
  302.     /* Set up the camera viewport */
  303.     OsSetCameraViewport();
  304.  
  305.     if (!UsingDIBs)
  306.     {
  307.         /*
  308.          * Select into the DC associated with the Camera the font we'll use
  309.          * for drawing the overlay graphics.
  310.          */
  311.         devContext = (HDC)RwGetCameraImage(cpGCamera);
  312.         memset(&logFont, 0, sizeof(LOGFONT));
  313.         logFont.lfHeight = 18;
  314.         logFont.lfWeight = FW_BOLD;
  315.         logFont.lfItalic = 1;
  316.         strcpy(logFont.lfFaceName, "Arial");
  317.         fGFont = CreateFontIndirect(&logFont);
  318.         if (fGFont)
  319.         {
  320.             fGOldFont = SelectObject(devContext, fGFont);
  321.         }
  322.         logFont.lfHeight = 12;
  323.         logFont.lfWeight = FW_BOLD;
  324.         logFont.lfItalic = 1;
  325.         strcpy(logFont.lfFaceName, "Arial");
  326.         fGSFont = CreateFontIndirect(&logFont);
  327.  
  328.         nGOldMode = SetBkMode(devContext, TRANSPARENT);
  329.         nGOldTColor = SetTextColor(devContext, RGB(255,255,255));
  330.         pGOldPen = SelectObject(devContext, CreatePen(PS_SOLID, 1, RGB(255,255,255)));
  331.     }
  332.  
  333.     if (!(rpGPanel = RwReadRaster("panel", 0L))) 
  334.     {
  335.         return FALSE;
  336.     }
  337.     return (TRUE);
  338. }
  339.  
  340. /************************************************************************
  341.  *
  342.  *      Function:       OsMaxCameraWidth()
  343.  *                      
  344.  *      Description:    The maximum camera width is an OS specific
  345.  *                      feature. This function returns this information to
  346.  *                      the main body of the application
  347.  *
  348.  *      Parameters:     None
  349.  *
  350.  *      Return Value:   TRUE if successful else FALSE
  351.  *
  352.  ************************************************************************/
  353. RwInt32 OsMaxCameraWidth(void)
  354. {
  355.     return((RwInt32)MAX_CAMERA_WIDTH);
  356. }
  357.  
  358. /************************************************************************
  359.  *
  360.  *      Function:       OsMaxCameraHeight()
  361.  *                      
  362.  *      Description:    The maximum camera height is an OS specific
  363.  *                      feature. This function returns this information to
  364.  *                      the main body of the application
  365.  *
  366.  *      Parameters:     None
  367.  *
  368.  *      Return Value:   TRUE if successful else FALSE
  369.  *
  370.  ************************************************************************/
  371. RwInt32 OsMaxCameraHeight(void)
  372. {
  373.     return((RwInt32)MAX_CAMERA_HEIGHT);
  374. }
  375.  
  376. /************************************************************************
  377.  *
  378.  *      Function:       OsMaxScreenWidth()
  379.  *                      
  380.  *      Description:    The maximum screen width is an OS specific
  381.  *                      feature. This function returns this information to
  382.  *                      the main body of the application
  383.  *
  384.  *      Parameters:     None
  385.  *
  386.  *      Return Value:   TRUE if successful else FALSE
  387.  *
  388.  ************************************************************************/
  389. RwInt32 OsMaxScreenWidth(void)
  390. {
  391.     return((RwInt32)DEFAULT_WINDOW_WIDTH);
  392. }
  393.  
  394. /************************************************************************
  395.  *
  396.  *      Function:       OsMaxScreenHeight()
  397.  *                      
  398.  *      Description:    The maximum screen height is an OS specific
  399.  *                      feature. This function returns this information to
  400.  *                      the main body of the application
  401.  *
  402.  *      Parameters:     None
  403.  *
  404.  *      Return Value:   TRUE if successful else FALSE
  405.  *
  406.  ************************************************************************/
  407. RwInt32 OsMaxScreenHeight(void)
  408. {
  409.     return((RwInt32)DEFAULT_WINDOW_HEIGHT);
  410. }
  411.  
  412. /************************************************************************
  413.  *
  414.  *      Function:       OsTidy()
  415.  *                      
  416.  *      Description:    Clean up all of the stuff initialised in OsInit()
  417.  *
  418.  *      Parameters:     None
  419.  *
  420.  *      Return Value:   None
  421.  *
  422.  ************************************************************************/
  423. void OsTidy(void)
  424. {
  425.     HDC hdc;
  426.  
  427.     if (!UsingDIBs)
  428.     {
  429.         hdc = (HDC)RwGetCameraImage(cpGCamera);
  430.         DeleteObject(SelectObject(hdc, pGOldPen));
  431.         SetTextColor(hdc, nGOldTColor);
  432.         SetBkMode(hdc, nGOldMode);
  433.         if (fGFont)
  434.         {
  435.             SelectObject(hdc, fGOldFont);
  436.             DeleteObject(fGFont);
  437.         }
  438.         if (fGSFont)
  439.         {
  440.             SelectObject(hdc, fGOldFont);
  441.             DeleteObject(fGSFont);
  442.         }
  443.     }
  444. }
  445.  
  446. /************************************************************************
  447.  *
  448.  *      Function:       OsDisplayScore()
  449.  *                      
  450.  *      Description:    Overlay the score on top of the rendered image
  451.  *
  452.  *      Parameters:     dead - number of dead rats
  453.  *                      left - number of rats remaining
  454.  *
  455.  *      Return Value:   None
  456.  *
  457.  ************************************************************************/
  458. void OsDisplayScore(int dead, int left)
  459. {
  460.     HDC camDC;
  461.     char caScore[80];
  462.  
  463.     if (!UsingDIBs)
  464.     {
  465.         camDC = (HDC)RwGetCameraImage(cpGCamera);
  466.  
  467.         /* Draw up the score */
  468.         if (nGStretch) 
  469.         {
  470.             sprintf(caScore,"Left: %d", left);
  471.             TextOut(camDC, 8>>1,8>>1, caScore, strlen(caScore));
  472.             sprintf(caScore,"Dead: %d", dead);
  473.             TextOut(camDC, 100>>1,8>>1, caScore, strlen(caScore));
  474.         } 
  475.         else 
  476.         {
  477.             sprintf(caScore,"Left: %d", left);
  478.             TextOut(camDC, 8,8, caScore, strlen(caScore));
  479.             sprintf(caScore,"Dead: %d", dead);
  480.             TextOut(camDC, 100,8, caScore, strlen(caScore));
  481.         }
  482.     }
  483. }
  484.  
  485. /************************************************************************
  486.  *
  487.  *      Function:       HandleMenu()
  488.  *                      
  489.  *      Description:    Handle input from menus    
  490.  *
  491.  *      Parameters:     window - the window that the message originated from
  492.  *                      menuItemID - the menu identifier
  493.  *
  494.  *      Return Value:   None
  495.  *
  496.  ************************************************************************/
  497. static void
  498. HandleMenu(HWND window, WPARAM menuItemID)
  499. {
  500.     HDC      devContext;
  501.  
  502.     switch (menuItemID)
  503.     {
  504.         case FILE_MENU_EXIT_ITEM_ID:
  505.             DestroyWindow(window);
  506.             break;
  507.  
  508.         case OPTION_MENU_MAG_ITEM_ID:  /* Detail menu - toggle stretching */
  509.             if (nGStretch)
  510.             {
  511.                 /* Stretching currently on - turn it off */
  512.                 CheckMenuItem(GetMenu(window),
  513.                           OPTION_MENU_MAG_ITEM_ID,
  514.                           MF_BYCOMMAND | MF_CHECKED);
  515.                 nGStretch = FALSE;
  516.                 OsSetCameraViewport();
  517.  
  518.                 /* No longer stretching so use a bigger font */
  519.  
  520.                 devContext = (HDC)RwGetCameraImage(cpGCamera);
  521.                 SelectObject(devContext, fGFont);
  522.              }
  523.              else
  524.              {
  525.                 /* Stretching currently off - turn it on */  
  526.                 CheckMenuItem(GetMenu(window),
  527.                            OPTION_MENU_MAG_ITEM_ID,
  528.                             MF_BYCOMMAND | MF_UNCHECKED);
  529.                 nGStretch = TRUE;
  530.                 OsSetCameraViewport();
  531.  
  532.                 devContext = (HDC)RwGetCameraImage(cpGCamera);
  533.                 SelectObject(devContext, fGSFont);
  534.             }
  535.             break;
  536.     }
  537. }
  538.  
  539. /************************************************************************
  540.  *
  541.  *      Function:       MainWndProc()
  542.  *                      
  543.  *      Description:    Main message handler for this window   
  544.  *
  545.  *      Parameters:     window - the window that the message originated from
  546.  *                      menuItemID - the menu identifier
  547.  *
  548.  *      Return Value:   None
  549.  *
  550.  ************************************************************************/
  551. long far PASCAL
  552. MainWndProc(HWND window, UINT message, WPARAM wParam, LPARAM lParam)
  553. {
  554.     POINT point;
  555. #ifdef WIN32
  556.     POINTS points = MAKEPOINTS(lParam);
  557.     point.x = points.x;
  558.     point.y = points.y;
  559. #else
  560.     point = MAKEPOINT(lParam);
  561. #endif
  562.  
  563.   hGAppWindow = window;
  564.  
  565.   switch (message)
  566.   {
  567.     case WM_CREATE:
  568.       /*
  569.       * In this application, 3D animation is driven by window's
  570.       * timer messages, so turn a timer on.
  571.       */
  572.       SetTimer(window, 1, 20, NULL);
  573.       return 0L;
  574.  
  575.     case WM_DESTROY:
  576.       /*
  577.       * Turn the timer off.
  578.       */
  579.       KillTimer(window, 1);
  580.  
  581.       /*
  582.       * Quit message handling.
  583.       */
  584.       PostQuitMessage(0);
  585.       return 0L;
  586.  
  587.     case WM_LBUTTONDOWN:
  588.       if (nGThreeDInitialized)
  589.       {
  590.             SetCapture(window);
  591.             ClientToScreen(window, &point);
  592.             HandleLeftButtonDown((RwInt32)point.x, (RwInt32)point.y, 
  593.                                  wParam & MK_CONTROL, wParam & MK_SHIFT);
  594.       }
  595.       return 0L;
  596.  
  597.     case WM_RBUTTONDOWN:
  598.       if (nGThreeDInitialized) 
  599.       {
  600.             SetCapture(window);
  601.             ClientToScreen(window, &point);
  602.             HandleRightButtonDown((RwInt32)point.x, (RwInt32)point.y, 
  603.                                  wParam & MK_CONTROL, wParam & MK_SHIFT);
  604.       }
  605.       return 0L;
  606.  
  607.     case WM_MOUSEMOVE:
  608.       if (nGThreeDInitialized)
  609.       {
  610.             ClientToScreen(window, &point);
  611.             HandleMouseMove((RwInt32)point.x, (RwInt32)point.y);
  612.       }
  613.       return 0L;
  614.  
  615.     case WM_LBUTTONUP:
  616.       if (nGThreeDInitialized) 
  617.       {     
  618.             ReleaseCapture();
  619.             HandleLeftButtonUp();
  620.       }
  621.       return 0L;
  622.  
  623.     case WM_RBUTTONUP:
  624.       if (nGThreeDInitialized) 
  625.       {
  626.             ReleaseCapture();
  627.             HandleRightButtonUp();
  628.       }
  629.       return 0L;
  630.  
  631.     case WM_CHAR:
  632.       if (wParam == 'f')
  633.       {
  634.             ToggleFlyCamera();
  635.       }
  636.       else if (wParam == 'g')
  637.       {
  638.             GunToggle();
  639.       }
  640.       return 0L;
  641.  
  642.     case WM_COMMAND:
  643.       if (nGThreeDInitialized)
  644.       {
  645.             if (LOWORD(lParam) == 0)
  646.             {    
  647.                 HandleMenu(window, wParam);
  648.             }
  649.       }
  650.     return 0L;
  651.  
  652.  
  653.     case WM_PAINT:
  654.     {
  655.         PAINTSTRUCT ps;
  656.         if (nGThreeDInitialized)
  657.         {
  658.             PaintDC = BeginPaint(hGAppWindow, &ps);
  659.             HandlePaint();
  660.             EndPaint(hGAppWindow, &ps);
  661.         }
  662.         return 0L;
  663.     }
  664.  
  665.     case WM_TIMER:
  666.  
  667.       if (nGThreeDInitialized) 
  668.       {
  669.             PaintDC = GetDC(hGAppWindow);
  670.             HandleTimer();
  671.             ReleaseDC(hGAppWindow, PaintDC);
  672.       };
  673.       return 0L;
  674.  
  675.   };
  676.  
  677.   /*
  678.   * Let Windows handle all other messages.
  679.   */
  680.   return DefWindowProc(window, message, wParam, lParam);
  681. }
  682.  
  683.  
  684. /************************************************************************
  685.  *
  686.  *      Function:       InitApplication()
  687.  *                      
  688.  *      Description:    Perform any necessary MS Windows application 
  689.  *                      initialization. Basically, this means 
  690.  *                      registering the window class for this 
  691.  *                      application.   
  692.  *
  693.  *      Parameters:     instance - the instance handle for this instance
  694.  *
  695.  *      Return Value:   the return value from RegisterClass
  696.  *
  697.  ************************************************************************/
  698. static BOOL
  699. InitApplication(HANDLE instance)
  700. {
  701.     WNDCLASS windowClass;
  702.  
  703.     windowClass.style         = CS_BYTEALIGNWINDOW;
  704.     windowClass.lpfnWndProc   = (WNDPROC)MainWndProc;
  705.     windowClass.cbClsExtra    = 0;
  706.     windowClass.cbWndExtra    = 0;
  707.     windowClass.hInstance     = instance;
  708.     windowClass.hIcon         = LoadIcon(instance, "RW_ICON");
  709.     windowClass.hCursor       = LoadCursor(NULL, IDC_ARROW);
  710.     windowClass.hbrBackground = NULL;
  711.     windowClass.lpszMenuName  = "RWCYBER_MENU";
  712.     windowClass.lpszClassName = CYBER_CLASS_NAME;
  713.  
  714.     return RegisterClass(&windowClass);
  715. }
  716.  
  717. /************************************************************************
  718.  *
  719.  *      Function:       InitInstance()
  720.  *                      
  721.  *      Description:    Perform any necessary initialization for this 
  722.  *                      instance of the application. This simply means
  723.  *                      creating the application's main window. 
  724.  *
  725.  *      Parameters:     instance - the instance handle for this instance
  726.  *
  727.  *      Return Value:   the return value from CreateWindow
  728.  *
  729.  ************************************************************************/
  730. static HWND
  731. InitInstance(HANDLE instance)
  732. {
  733.     /*
  734.      * Create the MS Window's window instance for this application. The
  735.      * initial window size is given by DEFAULT_WINDOW_WIDTH and
  736.      * DEFAULT_WINDOW_HEIGHT. The window is not given a title as we
  737.      * set it during OsOpen() with information about the version of
  738.      * RenderWare being used.
  739.      */
  740.   
  741.     return CreateWindow(CYBER_CLASS_NAME, "",
  742.                         WS_OVERLAPPED|WS_CAPTION|WS_SYSMENU|WS_MINIMIZEBOX,
  743.                         CW_USEDEFAULT, CW_USEDEFAULT,
  744.                         DEFAULT_WINDOW_WIDTH, DEFAULT_WINDOW_HEIGHT,
  745.                         NULL, NULL, instance, NULL);
  746. }
  747.  
  748.  
  749. /************************************************************************
  750.  *
  751.  *      Function:       WinMain()
  752.  *                      
  753.  *      Description:    Ms Windows application entry point
  754.  *
  755.  *      Parameters:     instance - the instance handle for this instance
  756.  *
  757.  *      Return Value:   the return value from CreateWindow
  758.  *
  759.  ************************************************************************/
  760. int PASCAL
  761. WinMain(HANDLE instance, HANDLE prevInstance, LPSTR cmdLine, int cmdShow)
  762. {
  763.     MSG     message;
  764.     HWND    window;
  765.  
  766.     /*
  767.      * Remember the instance handle in a global variable for later use.
  768.      */
  769.      hGAppInstance = instance;
  770.  
  771.     if (prevInstance)
  772.     {
  773.         /*
  774.          * Only allow one cyberstreet to run at any one time.
  775.          */
  776.         MessageBox((HWND)0, "RwCyber is already running...",
  777.                    ERROR_DIALOG_TITLE, MB_OK | MB_ICONSTOP | MB_APPLMODAL);
  778.         return FALSE;
  779.     }
  780.  
  781.     /*
  782.      * Register the window class.
  783.      */
  784.     if (!InitApplication(instance))
  785.     {
  786.         return FALSE;
  787.     }
  788.  
  789.     /*
  790.      * Create the window.
  791.      */
  792.     if (!(window = InitInstance(instance)))
  793.     {
  794.         return FALSE;
  795.     }
  796.     hGAppWindow = window;
  797.  
  798.     /* Setup menus */
  799.  
  800.     nGStretch = FALSE;
  801.     CheckMenuItem(GetMenu(window), OPTION_MENU_MAG_ITEM_ID, MF_BYCOMMAND | MF_CHECKED);
  802.  
  803.     /*
  804.      * Initialize the 3D (RenderWare) components of the app.
  805.      */
  806.     if (!Init3D())
  807.     {
  808.         DestroyWindow(window);
  809.         return FALSE;
  810.     }
  811.     nGThreeDInitialized = TRUE;
  812.  
  813.     if (AllowStretching(window))
  814.     {
  815.         EnableMenuItem(GetMenu(window), OPTION_MENU_MAG_ITEM_ID, MF_ENABLED);
  816.     }
  817.  
  818.     /* Load all of the sound effects */
  819.  
  820. #ifdef WITH_SOUND
  821.     AllSoundsAddSound("gun.wav",0);
  822.     AllSoundsAddSound("ricochet.wav",1);
  823.     AllSoundsAddSound("squish.wav",2);
  824.     AllSoundsAddSound("squeak.wav",2);
  825.     AllSoundsAddSound("boink.wav",3);
  826.     AllSoundsAddSound("ratty.wav",2);
  827.     AllSoundsAddSound("ratty2.wav",2);
  828.     AllSoundsAddSound("clang.wav",2);
  829. #endif
  830.  
  831.     /*
  832.      * Show the window, and refresh it.
  833.      */
  834.   
  835.     ShowWindow(window, cmdShow);
  836.     UpdateWindow(window);
  837.  
  838.     /*
  839.      * Enter the message processing loop.
  840.      */
  841.      while (GetMessage(&message, (HWND)0, 0, 0))
  842.     {
  843.         TranslateMessage(&message);
  844.         DispatchMessage(&message);
  845.     }
  846.  
  847.     hGAppWindow = NULL;
  848.     /*
  849.      * Tidy up the 3D (RenderWare) components of the application.
  850.      */
  851.     TidyUp3D();
  852.  
  853.     UnregisterClass(CYBER_CLASS_NAME, instance);
  854.  
  855.     return message.wParam;
  856. }
  857.  
  858.