home *** CD-ROM | disk | FTP | other *** search
/ NEXT Generation 27 / NEXT27.iso / pc / demos / emperor / dx3.exe / SDK / SAMPLES / DS3DVIEW / VIEWER.CPP < prev    next >
C/C++ Source or Header  |  1996-08-28  |  33KB  |  896 lines

  1. /*==========================================================================
  2.  *
  3.  *  Copyright (C) 1995-1996 Microsoft Corporation. All Rights Reserved.
  4.  *
  5.  *  File: viewer.cpp
  6.  *
  7.  ***************************************************************************/
  8.  
  9.  
  10.  
  11. #define INITGUID
  12. #include "d3drmwin.h"
  13. #include "resource.h"
  14.  
  15. #include <windows.h>
  16. #include <stdio.h>
  17. #include <string.h>
  18. #include <malloc.h>
  19. #include <math.h>
  20. #include <direct.h>
  21.  
  22. #include "rlds3d.h"
  23. #include "file.h"
  24.  
  25.  
  26. static char ViewerClass[32] = "ViewerClass";
  27.  
  28. static BOOL FirstInstance(HANDLE);
  29. static BOOL AnyInstance(HANDLE, HWND*);
  30. long FAR PASCAL WindowProc(HWND, UINT, WPARAM, LPARAM);
  31. static void Idle();
  32.  
  33. BOOL CALLBACK WaitBoxDlgProc(HWND, UINT, WPARAM, LPARAM);
  34.  
  35. BOOL AboutBoxOn = FALSE;
  36.  
  37.  
  38. /*
  39.  * Initialization, message loop
  40.  */
  41.  
  42. int PASCAL WinMain
  43.     (HANDLE this_inst, HANDLE prev_inst, LPSTR cmdline, int cmdshow)
  44. {
  45.     MSG         msg;
  46.     int         idle;
  47.     int         done = FALSE;
  48.     HACCEL      accel;
  49.  
  50.  
  51.         DWORD           prev_tick;
  52.         DWORD           this_tick;
  53.         D3DVALUE        time_delta;
  54.  
  55.     prev_inst = prev_inst;
  56.     cmdline = cmdline;
  57.  
  58.         // Register our class if necessary
  59.     if (!prev_inst) {
  60.                 // Do the stuff for if this is the first instance of the program.
  61.                 if (!FirstInstance(this_inst)) return FALSE;
  62.         }
  63.  
  64.         // Create our window and get it's handle (needs to be done whether we're first or not)
  65.         HWND win;
  66.     if (!AnyInstance(this_inst, &win)) return FALSE;
  67.  
  68.         // Initialize the RLDS3D interface
  69.         if (!RLDS3D_Initialize(win, this_inst)) {
  70.                 // If it doesn't initialize then we don't have anything we need to clean up, so we just exit
  71.                 exit(-1);
  72.         }
  73.  
  74.         // Show our window!
  75.     ShowWindow(win, cmdshow);
  76.     UpdateWindow(win);
  77.  
  78.         // Load accelerators
  79.     accel = LoadAccelerators(this_inst, "ViewerAccel");
  80.  
  81.         prev_tick = timeGetTime();
  82.  
  83.  
  84.     while (!done)
  85.     {   idle = TRUE;
  86.         while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
  87.         {   idle = FALSE;
  88.             if (msg.message == WM_QUIT)
  89.             {   done = TRUE;
  90.                 break;
  91.             }
  92.  
  93.             if (!TranslateAccelerator(msg.hwnd, accel, &msg))
  94.             {
  95.                 TranslateMessage(&msg);
  96.                 DispatchMessage(&msg);
  97.             }
  98.  
  99.         }
  100.                 if (idle) Idle();
  101.                 this_tick = timeGetTime();
  102.                 time_delta = D3DVAL((float)((this_tick - prev_tick)/1000.0));
  103.                 prev_tick = this_tick;
  104.                 RLDS3D_Render(time_delta);
  105.     }
  106.         RLDS3D_Deinitialize();
  107.         return msg.wParam;
  108. }
  109.  
  110. /*
  111.  * Register window class for the application, and do any other
  112.  * application initialization
  113.  */
  114. static BOOL FirstInstance(HANDLE this_inst)
  115. {
  116.     WNDCLASS    wc;
  117.     BOOL        rc;
  118.  
  119.     /*
  120.      * set up and register window class
  121.      */
  122.     wc.style = CS_HREDRAW | CS_VREDRAW;
  123.     wc.lpfnWndProc = WindowProc;
  124.     wc.cbClsExtra = 0;
  125.     wc.cbWndExtra = 0;
  126.     wc.hInstance = this_inst;
  127.     wc.hIcon = LoadIcon(this_inst, "ViewerIcon");
  128.     wc.hCursor = LoadCursor(NULL, IDC_ARROW);
  129.     wc.hbrBackground = GetStockObject(WHITE_BRUSH);
  130.     wc.lpszMenuName = "ViewerMenu";
  131.     wc.lpszClassName = ViewerClass;
  132.     rc = RegisterClass(&wc);
  133.  
  134.     return rc;
  135. }
  136.  
  137. /*
  138.  * Do work required for every instance of the application:
  139.  * create the window, initialize data
  140.  */
  141. static BOOL AnyInstance(HANDLE this_inst, HWND* window_handle)
  142. {
  143.     HWND win;
  144.     char szCaption[] = "DirectSound3D Demo";
  145.  
  146.     /*
  147.      * create main window
  148.      */
  149.     win =
  150.         CreateWindow
  151.         (   ViewerClass,                /* class */
  152.             szCaption,                  /* caption */
  153.             WS_OVERLAPPEDWINDOW,        /* style */
  154.             CW_USEDEFAULT,              /* init. x pos */
  155.             CW_USEDEFAULT,              /* init. y pos */
  156.             400,                        /* init. x size */
  157.             400,                        /* init. y size */
  158.             NULL,                       /* parent window */
  159.             NULL,                       /* menu handle */
  160.             this_inst,                  /* program handle */
  161.             NULL                        /* create parms */
  162.         );
  163.  
  164.  
  165.     if (!win) return FALSE;
  166.         *window_handle = win;
  167.     return TRUE;
  168. }
  169.  
  170. /*
  171.  * Processes messages for the about dialog.
  172.  */
  173. BOOL FAR PASCAL AboutDlgProc
  174.     (HWND win, unsigned msg, WORD wparam, LONG lparam)
  175. {
  176.     lparam = lparam;
  177.  
  178.     switch (msg)
  179.     {
  180.     case WM_INITDIALOG:
  181.         return TRUE;
  182.  
  183.     case WM_COMMAND:
  184.         if (wparam == IDOK)
  185.         {
  186.             AboutBoxOn = FALSE;
  187.             EndDialog(win, TRUE);
  188.             return TRUE;
  189.         }
  190.         break;
  191.     case WM_CLOSE:
  192.         {
  193.             AboutBoxOn = FALSE;
  194.             EndDialog(win, TRUE);
  195.             return FALSE;
  196.         }
  197.         break;
  198.     }
  199.     return FALSE;
  200. }
  201.  
  202. static int
  203.     left_drag = FALSE, right_drag = FALSE,
  204.     last_x, last_y;
  205.  
  206. static void Idle()
  207. {
  208.         // Stop selected item being dragged from rotating/moving
  209.     if (left_drag) {
  210.                 RLDS3D_SetSelectedRotRelToCam(D3DVAL(0.0), D3DVAL(1.0), D3DVAL(0.0), D3DVAL(0.0));
  211.         }
  212.     if (right_drag) {
  213.                 RLDS3D_SetSelectedVelRelToCam(D3DVAL(0.0), D3DVAL(0.0), D3DVAL(0.0));
  214.         }               
  215. }
  216.  
  217. static int FillModeToMenuItem(D3DRMFILLMODE fm)
  218. {
  219.     switch (fm) {
  220.     case D3DRMFILL_POINTS:
  221.         return 2;
  222.  
  223.     case D3DRMFILL_WIREFRAME:
  224.         return 3;
  225.  
  226.     case D3DRMFILL_SOLID:
  227.         return 4;
  228.     }
  229.     return -1;
  230. }
  231.  
  232. // Sets the polygon fill mode and checks/unchecks the appropriate menu items
  233. static void SetFillMode(HWND win, D3DRMFILLMODE fm)
  234. {
  235.     HMENU menu;
  236.     D3DRMFILLMODE oldfm = RLDS3D_GetPolygonFillMode();
  237.     menu = GetMenu(win);
  238.     menu = GetSubMenu(menu, 2);
  239.     CheckMenuItem(menu, FillModeToMenuItem(oldfm),
  240.                   MF_BYPOSITION|MF_UNCHECKED);
  241.     CheckMenuItem(menu, FillModeToMenuItem(fm),
  242.                   MF_BYPOSITION|MF_CHECKED);
  243.         RLDS3D_SetPolygonFillMode(fm);
  244. }
  245.  
  246. static int ShadeModeToMenuItem(D3DRMSHADEMODE sm)
  247. {
  248.     switch (sm) {
  249.     case D3DRMSHADE_FLAT:
  250.         return 6;
  251.  
  252.     case D3DRMSHADE_GOURAUD:
  253.         return 7;
  254.  
  255.     case D3DRMSHADE_PHONG:
  256.         return 8;
  257.     }
  258.     return -1;
  259. }
  260.  
  261. // Sets the polygon shade mode and checks/unchecks the appropriate menu items
  262. static void SetShadeMode(HWND win, D3DRMSHADEMODE sm)
  263. {
  264.     HMENU menu;
  265.     D3DRMSHADEMODE oldsm = RLDS3D_GetPolygonShadeMode();
  266.  
  267.     menu = GetMenu(win);
  268.     menu = GetSubMenu(menu, 2);
  269.     CheckMenuItem(menu, ShadeModeToMenuItem(oldsm),
  270.                   MF_BYPOSITION|MF_UNCHECKED);
  271.     CheckMenuItem(menu, ShadeModeToMenuItem(sm),
  272.                   MF_BYPOSITION|MF_CHECKED);
  273.         RLDS3D_SetPolygonShadeMode(sm);
  274. }
  275.  
  276. // Sets the rendering model and checks/unchecks the appropriate menu items
  277. static void SetModel(HWND win, D3DRMCOLORMODEL model)
  278. {
  279.     HMENU menu;
  280.     D3DRMCOLORMODEL oldModel = RLDS3D_GetColourModel();
  281.  
  282.     if (oldModel == model) return;
  283.  
  284.     RLDS3D_SetColourModel(model);
  285.     
  286.     menu = GetMenu(win);
  287.     menu = GetSubMenu(menu, 2);
  288.     CheckMenuItem(menu, 9 + (int) oldModel, MF_BYPOSITION|MF_UNCHECKED);
  289.     CheckMenuItem(menu, 9 + (int) model, MF_BYPOSITION|MF_CHECKED);
  290. }
  291.  
  292. // Toggles dithering and checks/unchecks menu item
  293. static void ToggleDither(HWND win)
  294. {
  295.     HMENU menu;
  296.     int dither = RLDS3D_GetDither();
  297.     int checked;
  298.     dither = !dither;
  299.         RLDS3D_SetDither(dither);
  300.  
  301.     menu = GetMenu(win);
  302.     menu = GetSubMenu(menu, 2);
  303.  
  304.     if (dither) checked = MF_CHECKED;
  305.     else checked = MF_UNCHECKED;
  306.  
  307.     CheckMenuItem(menu, 13, MF_BYPOSITION|checked);
  308. }
  309.  
  310. // Toggles texture filtering and checks/unchecks menu item
  311. static void ToggleTextureFiltering(HWND win)
  312. {
  313.     HMENU menu;
  314.     D3DRMTEXTUREQUALITY tq = RLDS3D_GetTextureQuality();
  315.     int checked;
  316.     if (tq == D3DRMTEXTURE_NEAREST)
  317.         tq = D3DRMTEXTURE_LINEAR;
  318.     else
  319.         tq = D3DRMTEXTURE_NEAREST;
  320.  
  321.     RLDS3D_SetTextureQuality(tq);
  322.     menu = GetMenu(win);
  323.     menu = GetSubMenu(menu, 2);
  324.  
  325.     if (tq == D3DRMTEXTURE_LINEAR) checked = MF_CHECKED;
  326.     else checked = MF_UNCHECKED;
  327.  
  328.     CheckMenuItem(menu, 14, MF_BYPOSITION|checked);
  329. }
  330.  
  331. // Ditto for lighting
  332. static void ToggleLighting(HWND win)
  333. {
  334.     HMENU menu;
  335.     menu = GetMenu(win);
  336.     menu = GetSubMenu(menu, 2);
  337.     if (RLDS3D_GetLighting()) {
  338.             CheckMenuItem(menu, 0, (MF_BYPOSITION | MF_UNCHECKED));
  339.                 RLDS3D_SetLighting(FALSE);
  340.         }
  341.         else {
  342.             CheckMenuItem(menu, 0, (MF_BYPOSITION | MF_CHECKED));
  343.                 RLDS3D_SetLighting(TRUE);
  344.         }
  345. }
  346.  
  347. /*
  348. ** Windows procs for the sound param dlg boxes
  349. */
  350.  
  351. BOOL CALLBACK WaitBoxDlgProc(HWND win, UINT msg, WPARAM wparam, LPARAM lparam) {
  352.         return FALSE;
  353. };
  354.  
  355. BOOL CALLBACK GlobalParamDlgProc(HWND win, UINT msg, WPARAM wparam, LPARAM lparam)
  356. {
  357.     lparam = lparam;
  358.  
  359.     char lpszTS[100];
  360.  
  361.     switch (msg)
  362.     {
  363.                 case WM_INITDIALOG:
  364.                         {
  365.                                 // Set up our edit fields appropriately
  366.                 D3DVALUE temp;
  367.                                 RLDS3D_GetDistanceFactor(&temp);
  368.                                 sprintf(lpszTS, "%f",temp);
  369.                                 SendDlgItemMessage(win, IDC_DISTANCEFACTOR, WM_SETTEXT, 0, (LPARAM) lpszTS);
  370.                                 SendDlgItemMessage(win, IDC_DISTANCEFACTOR, EM_SETLIMITTEXT, 10, 0);
  371.                                 RLDS3D_GetRolloffFactor(&temp);
  372.                                 sprintf(lpszTS, "%f",temp);
  373.                                 SendDlgItemMessage(win, IDC_ROLLOFFFACTOR, WM_SETTEXT, 0, (LPARAM) lpszTS);
  374.                                 SendDlgItemMessage(win, IDC_ROLLOFFFACTOR, EM_SETLIMITTEXT, 10, 0);
  375.                                 RLDS3D_GetDopplerFactor(&temp);
  376.                                 sprintf(lpszTS, "%f",temp);
  377.                                 SendDlgItemMessage(win, IDC_DOPPLERFACTOR, WM_SETTEXT, 0, (LPARAM) lpszTS);
  378.                                 SendDlgItemMessage(win, IDC_DOPPLERFACTOR, EM_SETLIMITTEXT, 10, 0);
  379.                                 return TRUE;
  380.                         }
  381.                 case WM_CLOSE:
  382.                         EndDialog(win, TRUE);
  383.                         return FALSE;
  384.  
  385.                 case WM_COMMAND:
  386.             {
  387.                 if (HIWORD(wparam) == EN_UPDATE && LOWORD(wparam) == IDC_DOPPLERFACTOR) {
  388.                                         // Get value from edit box (get length, check lenth, set first char to length, request string, end it with 0)
  389.                     int stringlength = SendDlgItemMessage(win, IDC_DOPPLERFACTOR, EM_LINELENGTH, 0, 0);
  390.                     if (stringlength > 10) return TRUE;
  391.                     lpszTS[0] = (char)stringlength;
  392.                     SendDlgItemMessage(win, IDC_DOPPLERFACTOR, EM_GETLINE, 0, (LPARAM) lpszTS);
  393.                     lpszTS[stringlength] = 0;
  394.                                         // Set value in RLDS3D (convert string to long and go crazy with the bad boy)
  395.                                         // No real need for error checking 'cause the edit field is numbers only
  396.                                         RLDS3D_SetDopplerFactor(D3DVAL(atof(lpszTS)));
  397.                     return TRUE;
  398.                 }
  399.                 else if (HIWORD(wparam) == EN_UPDATE && LOWORD(wparam) == IDC_ROLLOFFFACTOR) {
  400.                                         // Get value from edit box (get length, check lenth, set first char to length, request string, end it with 0)
  401.                     int stringlength = SendDlgItemMessage(win, IDC_ROLLOFFFACTOR, EM_LINELENGTH, 0, 0);
  402.                     if (stringlength > 10) return TRUE;
  403.                     lpszTS[0] = (char)stringlength;
  404.                     SendDlgItemMessage(win, IDC_ROLLOFFFACTOR, EM_GETLINE, 0, (LPARAM) lpszTS);
  405.                     lpszTS[stringlength] = 0;
  406.                                         // Set value in RLDS3D (convert string to long and go crazy with the bad boy)
  407.                                         RLDS3D_SetRolloffFactor(D3DVAL(atof(lpszTS)));
  408.                     return TRUE;
  409.                 }
  410.                 else if (HIWORD(wparam) == EN_UPDATE && LOWORD(wparam) == IDC_DISTANCEFACTOR) {
  411.                                         // Get value from edit box (get length, check lenth, set first char to length, request string, end it with 0)
  412.                     int stringlength = SendDlgItemMessage(win, IDC_DISTANCEFACTOR, EM_LINELENGTH, 0, 0);
  413.                     if (stringlength > 10) return TRUE;
  414.                     lpszTS[0] = (char)stringlength;
  415.                     SendDlgItemMessage(win, IDC_DISTANCEFACTOR, EM_GETLINE, 0, (LPARAM) lpszTS);
  416.                     lpszTS[stringlength] = 0;
  417.                                         // Set value in RLDS3D (convert string to long and go crazy with the bad boy)
  418.                                         RLDS3D_SetDistanceFactor(D3DVAL(atof(lpszTS)));
  419.                     return TRUE;
  420.                 }
  421.                 else return FALSE;
  422.             }               
  423.         break;
  424.     }
  425.     return FALSE;
  426. }
  427.  
  428. HWND hSelCfgDlg = 0;
  429.  
  430. BOOL CALLBACK SelectedParamDlgProc(HWND win, UINT msg, WPARAM wparam, LPARAM lparam)
  431. {
  432.     lparam = lparam;
  433.  
  434.     char lpszTS[100];
  435.  
  436.     switch (msg)
  437.     {
  438.                 case WM_INITDIALOG:
  439.                         {
  440.                                 // Set up our edit fields appropriately
  441.                 D3DVALUE temp;
  442.                                 LONG temp2;
  443.                                 DWORD temp3, temp4;
  444.                                 // Ignores the out side cone angle for now, which is fine, because elsewhere we
  445.                                 // set it to equal the inside angle
  446.                                 RLDS3D_GetSelConeAngles(&temp3, &temp4);
  447.                                 sprintf(lpszTS, "%i",temp3);
  448.                                 SendDlgItemMessage(win, IDC_CONEANGLE, WM_SETTEXT, 0, (LPARAM) lpszTS);
  449.                                 SendDlgItemMessage(win, IDC_CONEANGLE, EM_SETLIMITTEXT, 10, 0);
  450.                                 RLDS3D_GetSelConeOutsideVolume(&temp2);
  451.                                 sprintf(lpszTS, "%i",temp2);
  452.                                 SendDlgItemMessage(win, IDC_CONEOUTSIDEVOLUME, WM_SETTEXT, 0, (LPARAM) lpszTS);
  453.                                 SendDlgItemMessage(win, IDC_CONEOUTSIDEVOLUME, EM_SETLIMITTEXT, 10, 0);
  454.                                 RLDS3D_GetSelMaximumDistance(&temp);
  455.                                 sprintf(lpszTS, "%f",temp);
  456.                                 SendDlgItemMessage(win, IDC_MAXIMUMDISTANCE, WM_SETTEXT, 0, (LPARAM) lpszTS);
  457.                                 SendDlgItemMessage(win, IDC_MAXIMUMDISTANCE, EM_SETLIMITTEXT, 10, 0);
  458.                                 RLDS3D_GetSelMinimumDistance(&temp);
  459.                                 sprintf(lpszTS, "%f",temp);
  460.                                 SendDlgItemMessage(win, IDC_MINIMUMDISTANCE, WM_SETTEXT, 0, (LPARAM) lpszTS);
  461.                                 SendDlgItemMessage(win, IDC_MINIMUMDISTANCE, EM_SETLIMITTEXT, 10, 0);
  462.                                 hSelCfgDlg = win;
  463.                                 return TRUE;
  464.                         }
  465.  
  466.                 case WM_CLOSE:
  467.                         EndDialog(win, TRUE);
  468.                         hSelCfgDlg = 0;
  469.                         return FALSE;
  470.  
  471.                 case WM_COMMAND:
  472.             {
  473.                 if (HIWORD(wparam) == EN_UPDATE && LOWORD(wparam) == IDC_CONEANGLE) {
  474.                                         // Get value from edit box (get length, check lenth, set first char to length, request string, end it with 0)
  475.                     int stringlength = SendDlgItemMessage(win, IDC_CONEANGLE, EM_LINELENGTH, 0, 0);
  476.                     if (stringlength > 10) return TRUE;
  477.                     lpszTS[0] = (char)stringlength;
  478.                     SendDlgItemMessage(win, IDC_CONEANGLE, EM_GETLINE, 0, (LPARAM) lpszTS);
  479.                     lpszTS[stringlength] = 0;
  480.                                         // Set value in RLDS3D (convert string to long and go crazy with the bad boy)
  481.                                         // No real need for error checking 'cause the edit field is numbers only
  482.                                         RLDS3D_SetSelConeAngles((DWORD)atol(lpszTS), (DWORD)atol(lpszTS));
  483.                     return TRUE;
  484.                 }
  485.                 else if (HIWORD(wparam) == EN_UPDATE && LOWORD(wparam) == IDC_CONEOUTSIDEVOLUME) {
  486.                                         // Get value from edit box (get length, check lenth, set first char to length, request string, end it with 0)
  487.                     int stringlength = SendDlgItemMessage(win, IDC_CONEOUTSIDEVOLUME, EM_LINELENGTH, 0, 0);
  488.                     if (stringlength > 10) return TRUE;
  489.                     lpszTS[0] = (char)stringlength;
  490.                     SendDlgItemMessage(win, IDC_CONEOUTSIDEVOLUME, EM_GETLINE, 0, (LPARAM) lpszTS);
  491.                     lpszTS[stringlength] = 0;
  492.                                         // Set value in RLDS3D (convert string to long and go crazy with the bad boy)
  493.                                         RLDS3D_SetSelConeOutsideVolume(atol(lpszTS));
  494.                     return TRUE;
  495.                 }
  496.                 else if (HIWORD(wparam) == EN_UPDATE && LOWORD(wparam) == IDC_MAXIMUMDISTANCE) {
  497.                                         // Get value from edit box (get length, check lenth, set first char to length, request string, end it with 0)
  498.                     int stringlength = SendDlgItemMessage(win, IDC_MAXIMUMDISTANCE, EM_LINELENGTH, 0, 0);
  499.                     if (stringlength > 10) return TRUE;
  500.                     lpszTS[0] = (char)stringlength;
  501.                     SendDlgItemMessage(win, IDC_MAXIMUMDISTANCE, EM_GETLINE, 0, (LPARAM) lpszTS);
  502.                     lpszTS[stringlength] = 0;
  503.                                         // Set value in RLDS3D (convert string to long and go crazy with the bad boy)
  504.                                         RLDS3D_SetSelMaximumDistance(D3DVAL(atof(lpszTS)));
  505.                     return TRUE;
  506.                 }
  507.                 else if (HIWORD(wparam) == EN_UPDATE && LOWORD(wparam) == IDC_MINIMUMDISTANCE) {
  508.                                         // Get value from edit box (get length, check lenth, set first char to length, request string, end it with 0)
  509.                     int stringlength = SendDlgItemMessage(win, IDC_MINIMUMDISTANCE, EM_LINELENGTH, 0, 0);
  510.                     if (stringlength > 10) return TRUE;
  511.                     lpszTS[0] = (char)stringlength;
  512.                     SendDlgItemMessage(win, IDC_MINIMUMDISTANCE, EM_GETLINE, 0, (LPARAM) lpszTS);
  513.                     lpszTS[stringlength] = 0;
  514.                                         // Set value in RLDS3D (convert string to long and go crazy with the bad boy)
  515.                                         RLDS3D_SetSelMinimumDistance(D3DVAL(atof(lpszTS)));
  516.                     return TRUE;
  517.                 }
  518.                 else return FALSE;
  519.             }               
  520.         break;
  521.     }
  522.     return FALSE;
  523. }
  524.  
  525. #define SIGN_EXTEND(w)    ((((int)(w)) << 16) >> 16)
  526.  
  527. /*
  528.  * Handle messages for the main application window
  529.  */
  530.  
  531. LONG FAR PASCAL WindowProc(HWND win, UINT msg, WPARAM wparam, LPARAM lparam)
  532. {
  533.     HANDLE inst_handle;
  534.     static HCURSOR oldCursor = NULL;
  535.  
  536.     switch (msg)
  537.     {
  538.     case WM_KEYDOWN:
  539.         {   
  540.             switch (wparam)
  541.             {
  542.                         
  543.             case 'A':
  544.                                 RLDS3D_SetCamVelRelToCam(D3DVAL(5.0), D3DVAL(0.0), D3DVAL(0.0));
  545.                 break;
  546.  
  547.             case 'Z':
  548.                                 RLDS3D_SetCamVelRelToCam(D3DVAL(-5.0), D3DVAL(0.0), D3DVAL(0.0));
  549.                 break;
  550.  
  551.             case VK_RIGHT:
  552.                                 RLDS3D_SetCamRotUp(D3DVAL(1.0));
  553.                 break;
  554.             case VK_LEFT:
  555.                                 RLDS3D_SetCamRotUp(D3DVAL(-1.0));
  556.                 break;
  557.                         case VK_UP:
  558.                                 RLDS3D_SetCamRotRight(D3DVAL(1.0));
  559.                                 break;
  560.                         case VK_DOWN:
  561.                                 RLDS3D_SetCamRotRight(D3DVAL(-1.0));
  562.                                 break;
  563.                         }
  564.         }
  565.         break;
  566.  
  567.     case WM_KEYUP:
  568.         switch (wparam)
  569.         {
  570.                 case VK_LEFT:
  571.                 case VK_RIGHT:
  572.         case VK_UP:
  573.         case VK_DOWN:
  574.                         // Stop the camera from rotating completely
  575.                         RLDS3D_SetCamRotForward(D3DVAL(0.0));
  576.                         break;
  577.             
  578.                 case 'A':
  579.                 case 'Z':
  580.                         RLDS3D_SetCamVelRelToCam(D3DVAL(0.0), D3DVAL(0.0), D3DVAL(0.0));
  581.             break;
  582.         }
  583.         break;
  584.  
  585.     case WM_LBUTTONDOWN:
  586.         {   HCURSOR hCur;
  587.             int x = LOWORD(lparam);
  588.             int y = HIWORD(lparam);
  589.             last_x = x;
  590.             last_y = y;
  591.                         BOOL bChanged = FALSE;
  592.             RLDS3D_FindAndSelectVisual(x, y, &bChanged);
  593.                         // Get rid of the Selected Object Cfg dialog if we've selected a new object
  594.                         if (bChanged && hSelCfgDlg) EndDialog(hSelCfgDlg, TRUE);
  595.             left_drag = TRUE;
  596.             SetCapture(win);
  597.             /* change to a groovy cursor */
  598.             hCur = LoadCursor(NULL, IDC_ARROW);
  599.             if (hCur) oldCursor = SetCursor(hCur);
  600.             else oldCursor = NULL;
  601.         }
  602.         break;
  603.  
  604.     case WM_LBUTTONUP:
  605.         ReleaseCapture();
  606.         left_drag = FALSE;
  607.         if (oldCursor) SetCursor(oldCursor);
  608.         break;
  609.  
  610.     case WM_RBUTTONDOWN:
  611.         {
  612.             HCURSOR hCur;
  613.             int x = LOWORD(lparam);
  614.             int y = HIWORD(lparam);
  615.             last_x = x;
  616.             last_y = y;
  617.                         BOOL bChanged = FALSE;
  618.             RLDS3D_FindAndSelectVisual(x, y, &bChanged);
  619.                         // Get rid of the Selected Object Cfg dialog if we've selected a new object
  620.                         if (bChanged && hSelCfgDlg) EndDialog(hSelCfgDlg, TRUE);
  621.             right_drag = TRUE;
  622.             SetCapture(win);
  623.             /* change to a groovy cursor */
  624.             hCur = LoadCursor(NULL, IDC_ARROW);
  625.             if (hCur) oldCursor = SetCursor(hCur);
  626.             else oldCursor = NULL;
  627.         }
  628.         break;
  629.  
  630.     case WM_RBUTTONUP:
  631.         right_drag = FALSE;
  632.         ReleaseCapture();
  633.         if (oldCursor) SetCursor(oldCursor);
  634.         break;
  635.  
  636.     case WM_MOUSEMOVE:
  637.         if ((wparam & MK_LBUTTON) && left_drag)
  638.         {   double delta_x, delta_y;
  639.             delta_x = SIGN_EXTEND(LOWORD(lparam)) - last_x;
  640.             delta_y = -SIGN_EXTEND((HIWORD(lparam)) - last_y);
  641.             last_x = SIGN_EXTEND(LOWORD(lparam));
  642.             last_y = SIGN_EXTEND(HIWORD(lparam));
  643.             {
  644.                 double delta_r = sqrt(delta_x * delta_x + delta_y * delta_y);
  645.                 double radius = 50;
  646.                 double denom;
  647.  
  648.                 denom = 0.05 * sqrt(radius * radius + delta_r * delta_r);
  649.  
  650.                 if (delta_r == 0 || denom == 0) break;
  651.                                 RLDS3D_SetSelectedRotRelToCam(D3DDivide(D3DVAL((float) delta_y), D3DVAL((float) delta_r)),
  652.                                                                                           D3DDivide(D3DVAL((float) -delta_x), D3DVAL((float) delta_r)),
  653.                                                                                           D3DVAL(0.0),
  654.                                                                                           D3DDivide(D3DVAL((float) delta_r), D3DVAL((float) denom)));
  655.             }
  656.         }
  657.         else if ((wparam & MK_RBUTTON) && right_drag)
  658.         {   double delta_x, delta_y;
  659.  
  660.             delta_x = SIGN_EXTEND(LOWORD(lparam)) - last_x;
  661.             delta_y = SIGN_EXTEND(HIWORD(lparam)) - last_y;
  662.             last_x = SIGN_EXTEND(LOWORD(lparam));
  663.             last_y = SIGN_EXTEND(HIWORD(lparam));
  664.                         RLDS3D_MoveSelectedPosByScreenCoords(delta_x, delta_y);
  665.         }
  666.         break;
  667.     case WM_COMMAND:
  668.         switch( wparam & 0xffff )
  669.         {
  670.                 case MENU_MOTION_ORBITSELECTEDOBJECT:
  671.                         {
  672.                                 RLDS3D_OrbitSelected();
  673.                         }
  674.                         break;
  675.                 case MENU_MOTION_BULLETSELECTEDOBJECT:
  676.                         {
  677.                                 RLDS3D_BulletSelected();
  678.                         }
  679.                         break;
  680.                 case MENU_SOUND_ATTACHSOUND:
  681.                         {
  682.                                 if (RLDS3D_SoundInitialized())
  683.                                 {
  684.                                         if (RLDS3D_FrameSelected()) {
  685.                                                 char* file = OpenNewSoundFile(win);
  686.                                                 if (file) RLDS3D_AttachSound(file);                                     
  687.                                         }
  688.                                         else MessageBox(win, "No object selected to attach a sound to!", "Doh!", MB_ICONEXCLAMATION);
  689.                                 }
  690.                                 else MessageBox(win, "Sound not initialized!", "Doh!", MB_ICONEXCLAMATION);
  691.                         }
  692.                         break;
  693.                 case MENU_SOUND_REMOVESOUND:
  694.                         RLDS3D_RemoveSound();
  695.                         break;
  696.                 case MENU_SOUND_REMOVEALLSOUNDS:
  697.                         RLDS3D_RemoveAllSounds();
  698.                         break;
  699.  
  700.                 case MENU_SOUND_PLAYSOUND:
  701.                         RLDS3D_PlaySound(FALSE);
  702.                         break;
  703.                 case MENU_SOUND_PLAYSOUNDLOOPING:
  704.                         RLDS3D_PlaySound(TRUE);
  705.                         break;
  706.                 case MENU_SOUND_STOPSOUND:
  707.                         RLDS3D_StopSelectedSound();
  708.                         break;
  709.                 
  710.                 case MENU_SOUND_STOPALLSOUNDS:
  711.                         RLDS3D_StopAllSounds();
  712.                         break;
  713.  
  714.                 case MENU_SOUND_SELECTEDSOUNDPROPERTIES:
  715.                         {
  716.                                 if (RLDS3D_SoundInitialized()) {
  717.                                         if (RLDS3D_SoundSelected()) {
  718.                                                 inst_handle = (HANDLE) GetWindowLong(win, GWL_HINSTANCE);
  719.                                                 HWND mydial = CreateDialog(inst_handle, "SelectedParamBox", win, (int(__stdcall*)(void))SelectedParamDlgProc);
  720.                                                 if (mydial) {
  721.                                                         ShowWindow(mydial, SW_SHOW);
  722.                                                         UpdateWindow(mydial);
  723.                                                 }
  724.                                         }
  725.                                         else MessageBox(win, "No sound currently selected", "Doh!", MB_ICONEXCLAMATION);
  726.                                 }
  727.                                 else MessageBox(win, "Sound not initialized!", "Doh!", MB_ICONEXCLAMATION);
  728.                         }
  729.                         break;
  730.                 case MENU_SOUND_GLOBALPROPERTIES:
  731.                         {
  732.                                 if (RLDS3D_SoundInitialized()) {
  733.                                         inst_handle = (HANDLE) GetWindowLong(win, GWL_HINSTANCE);
  734.                                         HWND mydial = CreateDialog(inst_handle, "GlobalParamBox", win, (int(__stdcall*)(void))GlobalParamDlgProc);
  735.                                         if (mydial) {
  736.                                                 ShowWindow(mydial, SW_SHOW);
  737.                                                 UpdateWindow(mydial);
  738.                                         }
  739.                                 }
  740.                                 else MessageBox(win, "Sound not initialized!", "Doh!", MB_ICONEXCLAMATION);
  741.                         }
  742.                         break;
  743.  
  744.                 case MENU_FILE_ABOUT:
  745.                         {
  746.                                 inst_handle = (HANDLE) GetWindowLong(win, GWL_HINSTANCE);
  747.                                 DialogBox(inst_handle,"AboutBox", win, (int(__stdcall*)(void))AboutDlgProc);
  748.                         }
  749.             break;
  750.  
  751.         case MENU_FILE_OPEN:
  752.             {   
  753.                 char *file = OpenNewFile(win);
  754.                                 if (file) {
  755.                                         RLDS3D_LoadXOF(file);
  756.                 }
  757.             }
  758.             break;
  759.  
  760.         case MENU_FILE_EXIT:
  761.             PostQuitMessage(0);
  762.             break;
  763.  
  764.         case MENU_EDIT_CUT:
  765.             RLDS3D_CutVisual();
  766.             break;
  767.  
  768.         case MENU_EDIT_COPY:
  769.             RLDS3D_CopyVisual();
  770.             break;
  771.  
  772.         case MENU_EDIT_PASTE:
  773.             RLDS3D_PasteVisual();
  774.             break;
  775.  
  776.         case MENU_EDIT_DELETE:
  777.             RLDS3D_DeleteVisual();
  778.             break;
  779.  
  780.         case MENU_EDIT_COLOUR:
  781.                         // Currently everything is handled there but the selection wheel maybe should be out here?
  782.                         RLDS3D_SetSelColour();
  783.             break;
  784.  
  785.         case MENU_EDIT_BOXES:
  786.             {
  787.                 HMENU menu;
  788.                                 if (RLDS3D_GetBoxes() == TRUE) RLDS3D_SetBoxes(FALSE); else RLDS3D_SetBoxes(TRUE);
  789.                 int checked = (RLDS3D_GetBoxes()==TRUE) ? MF_CHECKED : MF_UNCHECKED;
  790.                 menu = GetMenu(win);
  791.                 menu = GetSubMenu(menu, 1);
  792.                 CheckMenuItem(menu, MENU_EDIT_BOXES, MF_BYCOMMAND|checked);
  793.             }
  794.             break;
  795.  
  796.                 case MENU_QUALITY_LIGHTING:
  797.                         ToggleLighting(win);
  798.                         break;
  799.  
  800.                 // Fill Modes
  801.                 case MENU_QUALITY_POINTS:
  802.                         SetFillMode(win, D3DRMFILL_POINTS);
  803.                         break;
  804.  
  805.         case MENU_QUALITY_WIREFRAME:
  806.             SetFillMode(win, D3DRMFILL_WIREFRAME);
  807.             break;
  808.  
  809.         case MENU_QUALITY_SOLID:
  810.             SetFillMode(win, D3DRMFILL_SOLID);
  811.             break;
  812.  
  813.                 // Shading modes
  814.         case MENU_QUALITY_FLAT:
  815.             SetShadeMode(win, D3DRMSHADE_FLAT);
  816.             break;
  817.  
  818.         case MENU_QUALITY_GOURAUD:
  819.             SetShadeMode(win, D3DRMSHADE_GOURAUD);
  820.             break;
  821.  
  822.         case MENU_QUALITY_PHONG:
  823.             SetShadeMode(win, D3DRMSHADE_PHONG);
  824.             break;
  825.  
  826.                 // Color models
  827.         case MENU_MODEL_MONO:
  828.             SetModel(win, D3DCOLOR_MONO);
  829.             break;
  830.  
  831.         case MENU_MODEL_RGB:
  832.             SetModel(win, D3DCOLOR_RGB);
  833.             break;
  834.  
  835.         case MENU_DITHER:
  836.             ToggleDither(win);
  837.             break;
  838.  
  839.         case MENU_TEXTURE_FILTERING:
  840.             ToggleTextureFiltering(win);
  841.             break;
  842.  
  843.         case MENU_LIGHT_DIRECTIONAL:
  844.                         RLDS3D_AddDirectionalLight();
  845.                         break;
  846.         case MENU_LIGHT_PARALLEL_POINT:
  847.                         RLDS3D_AddParallelPointLight();
  848.                         break;
  849.         case MENU_LIGHT_POINT:
  850.                         RLDS3D_AddPointLight();
  851.                         break;
  852.         case MENU_LIGHT_SPOT:
  853.                         RLDS3D_AddSpotlight();
  854.                         break;
  855.         }
  856.         break;
  857.  
  858.     case WM_DESTROY:
  859.         PostQuitMessage( 0 );
  860.         break;
  861.  
  862.     case WM_SIZE:
  863.         {
  864.             int width = LOWORD(lparam);
  865.             int height = HIWORD(lparam);
  866.             RLDS3D_ResizeViewport(width, height);
  867.         }
  868.         break;
  869.  
  870.     case WM_ACTIVATE:
  871.                 {
  872.                         RLDS3D_HandleActivate(wparam);
  873.                 }
  874.         break;
  875.  
  876.     case WM_PAINT:
  877.                 if (RLDS3D_WinDevice())
  878.                 {
  879.                         RECT r;
  880.             PAINTSTRUCT ps;
  881.  
  882.             if (GetUpdateRect(win, &r, FALSE))
  883.             {   BeginPaint(win, &ps);
  884.                                 RLDS3D_HandlePaint(&ps);
  885.                 EndPaint(win, &ps);
  886.             }
  887.         }
  888.         else return DefWindowProc(win, msg, wparam, lparam);
  889.  
  890.     default:
  891.         return DefWindowProc(win, msg, wparam, lparam);
  892.     }
  893.     return 0L;
  894. }
  895.  
  896.