MAZE.C
上传用户:bangxh
上传日期:2007-01-31
资源大小:42235k
文件大小:35k
源码类别:

Windows编程

开发平台:

Visual C++

  1. /***********************************************************************
  2. File:   Maze.c
  3. Abstract:
  4.     This is the main module for MazeLords. It Contains WinMain, as well as the
  5.     WndProcs for the main modules.
  6. Contents:
  7.     InSanctuary() -- determines whether a maze position is in the Sanctuary
  8.     WinMain() -- Main windows entrypoint
  9.     WndProc() -- Main window processing entrypoint
  10.     RegisterClasses() -- Register different window classes
  11.     OneTimeInit() -- Initialization done first time window created
  12.     EachTimeInit() -- Initialization done each new game
  13.     OneTimeShutdown() -- cleanup done last time window destroyed
  14.     EachTimeShutdown() -- cleanup done each time the game is STOPped.
  15. Revision History:
  16. ************************************************************************/
  17. #define FULL_REDRAW 200
  18. #define IN_MAIN
  19. #include "winmaze.h"
  20. #include "mazproto.h"
  21. #include "net.h"
  22. int ngCmdShow;
  23. HDC hHoldDC;
  24. /*=====================================================================
  25. Function: InSanctuary()
  26. Inputs: Position
  27. Outputs: TRUE if position in Sanctuary, else FALSE
  28. Abstract:
  29.     This function is used to determine if a given position is inside
  30.     the sanctuary. If it is, then combat isn't allowed from/to that
  31.     position, with the exception of shooting drones from outside the
  32.     sanctuary.
  33. ======================================================================*/
  34. BOOL InSanctuary(
  35.     PositionType FAR *Pos
  36.     )
  37. {
  38.     BOOL bRet;
  39.     int iLeft,iTop;
  40.     iLeft = 6*X_CELLS_PER_SUBGRID+1;
  41.     iTop = 7*Y_CELLS_PER_SUBGRID+1;
  42.     bRet = ((Pos->ix >= iLeft)&&(Pos->ix <= iLeft+2));
  43.     bRet = bRet&&((Pos->iy >= iTop)&&(Pos->iy <= iTop+2));
  44.     return(bRet);
  45. }
  46. /*=====================================================================
  47. Function: WinMain()
  48. Inputs: Standard winmain inputs
  49. Outputs:success
  50. Abstract:
  51.     This is the WinMain for MazeLords. It is responsible for, among
  52.     other things, registering the windows classes, and allocating some
  53.     of the larger dynamic data structures.
  54. ======================================================================*/
  55. int PASCAL WinMain(
  56.     HINSTANCE hInstance,
  57.     HINSTANCE hPrevInstance,
  58.     LPSTR lpszCmdLine,
  59.     int nCmdShow
  60.     )
  61. {
  62.     MSG     msg;
  63.     int     i,j,nRc;
  64.     HGLOBAL hMem;
  65.     //
  66.     // DYNAMIC ALLOCATION OF GLOBAL VARS
  67.     //
  68.     hMem = GlobalAlloc(GHND,(MAX_DRAW_DIST*2+2+1) * sizeof(LPPOINT FAR *));
  69.     pPost = (LPPOINT FAR * FAR *) GlobalLock(hMem);
  70.     for(i=0;i<(MAX_DRAW_DIST*2+2+1);i++) {
  71.         hMem = GlobalAlloc(GHND,(MAX_DRAW_DIST+2+1)*sizeof(LPPOINT));
  72.         pPost[i] = (LPPOINT FAR *) GlobalLock(hMem);
  73.         for(j=0;j<(MAX_DRAW_DIST+2+1);j++) {
  74.             hMem = GlobalAlloc(GHND,2*sizeof(POINT));
  75.             pPost[i][j] = (LPPOINT) GlobalLock(hMem);
  76.             }
  77.         }
  78.     hMem = GlobalAlloc(GHND,NUM_PICS * sizeof(FullPicType FAR *));
  79.     PreStretch = (FullPicType FAR * FAR *) GlobalLock(hMem);
  80.     for(i=0;i<NUM_PICS;i++) {
  81.         hMem = GlobalAlloc(GHND,MAX_DRAW_DIST * sizeof(FullPicType));
  82.         PreStretch[i] = (FullPicType FAR *) GlobalLock(hMem);
  83.         }
  84.     hMem = GlobalAlloc(GHND,X_SIZE * sizeof(BYTE FAR *));
  85.     bMaze = (BYTE FAR * FAR *) GlobalLock(hMem);
  86.     for(i=0;i<X_SIZE;i++) {
  87.         hMem = GlobalAlloc(GHND,Y_SIZE * sizeof(BYTE));
  88.         bMaze[i] = (LPBYTE) GlobalLock(hMem);
  89.         }
  90.     hMem = GlobalAlloc(GHND,X_SUBGRIDS_PER_GRID * sizeof(SubGridType FAR *));
  91.     Grid = (SubGridType FAR * FAR *) GlobalLock(hMem);
  92.     for(i=0;i<X_SUBGRIDS_PER_GRID;i++) {
  93.         hMem = GlobalAlloc(GHND,Y_SUBGRIDS_PER_GRID * sizeof(SubGridType));
  94.         Grid[i] = (SubGridType FAR *) GlobalLock(hMem);
  95.         }
  96.     hMem = GlobalAlloc(GHND,NUM_SUBGRIDS * sizeof(SubGridCellsType));
  97.     SubGrids = (SubGridCellsType FAR *) GlobalLock(hMem);
  98.     lstrcpy(szAppName, "MAZE");
  99.     hInst = hInstance;
  100.     //
  101.     // We need to register the different windows and child
  102.     // windows we'll be using if this is the first instance
  103.     // of MazeLords.
  104.     //
  105.     if(!hPrevInstance) {
  106.       if ((nRc = RegisterClasses()) == -1) {
  107.         LoadString(hInst, IDS_ERR_REGISTER_CLASS, szString, sizeof(szString));
  108.         MessageBox((HWND)NULL, szString, (LPSTR)NULL, MB_ICONEXCLAMATION);
  109.         return nRc;
  110.         }
  111.       }
  112.     //
  113.     // Display the Main window for MazeLords
  114.     //
  115.     hWndMain = CreateWindow(
  116.                   szAppName,
  117.                   "Maze Lords",
  118.                   WS_CAPTION|WS_SYSMENU|WS_MINIMIZEBOX|WS_MAXIMIZEBOX |
  119.                              WS_THICKFRAME|WS_CLIPCHILDREN|WS_OVERLAPPED,
  120.                   CW_USEDEFAULT, 0,
  121.                   CW_USEDEFAULT, 0,
  122.                   (HWND)NULL,
  123.                   (HMENU)NULL,
  124.                   hInst,
  125.                   NULL);
  126.     OneTimeInit();
  127.     if(hWndMain == (HWND)NULL){
  128.         LoadString(hInst, IDS_ERR_CREATE_WINDOW, szString, sizeof(szString));
  129.         MessageBox((HWND)NULL, szString, "WinMain", MB_ICONEXCLAMATION);
  130.         return IDS_ERR_CREATE_WINDOW;
  131.         }
  132.     ShowWindow(hWndMain, nCmdShow);
  133.     ngCmdShow = nCmdShow;
  134.     while(GetMessage(&msg, (HWND)NULL, 0, 0)) {
  135.         TranslateMessage(&msg);
  136.         DispatchMessage(&msg);
  137.         }
  138.     UnRegisterClasses();
  139.     return msg.wParam;
  140. }
  141. /*=====================================================================
  142. Function: Wndproc()
  143. Inputs: Standard windows message processing entrypoint parms
  144. Outputs:returns Success
  145. Abstract:
  146.     This is the window procedure for the main window. It takes care of
  147.     spawning and destroying child windows, interpreting menu-item
  148.     command messages, and most of the none-movement keystrokes.
  149. ======================================================================*/
  150. LONG FAR PASCAL WndProc(
  151.     HWND hWnd,
  152.     UINT Message,
  153.     WPARAM wParam,
  154.     LPARAM lParam
  155.     )
  156. {
  157.     HMENU           hMenu=0;
  158.     HBITMAP         hBitmap=0;
  159.     HDC             hDC,hBMDC;
  160.     PAINTSTRUCT     ps;
  161.     int             nRc=0;
  162.     INT             i,j,MazexDim,MazeyDim,TopxDim,TopyDim;
  163.     UINT            uCmdId,uCmdCmd;
  164.     HWND            hCmd;
  165.     switch (Message) {
  166.         case WM_TIMER:
  167.             if ((!UserIntCount)&&(!bDemoMode)&&(bDemoEnable)) {
  168.                 StartDemo();
  169.                 }
  170.             UserIntCount = 0;
  171.             break;
  172.         case WM_INITMENU:
  173.             if (bDemoMode) {
  174.                 StopDemo();
  175.                 }
  176.             UserIntCount++;
  177.             return DefWindowProc(hWnd, Message, wParam, lParam);
  178.         case WM_COMMAND:
  179.             uCmdId = GET_WM_COMMAND_ID(wParam,lParam);
  180.             uCmdCmd = GET_WM_COMMAND_CMD(wParam,lParam);
  181.             hCmd = GET_WM_COMMAND_HWND(wParam,lParam);
  182.             hMenu = GetMenu(hWnd);
  183.             switch (uCmdId) {
  184.                 case IDT_NEWMAIL:
  185.                     ProcessNewMail();
  186.                     break;
  187.                 case IDM_F_HIGHSCORES:
  188.                     bDemoEnable = FALSE;
  189.                     MessageBox((HWND)NULL,GetStringRes(IDS_HSCONOTIMPL),
  190. GetStringRes2(IDS_HSCO),  MB_ICONHAND | MB_APPLMODAL);
  191.                     bDemoEnable = TRUE;
  192.                     break;
  193.                 case IDM_F_NEWGAME:
  194.                     bDemoEnable = FALSE;
  195.                     SetCursor(LoadCursor((HINSTANCE)NULL,IDC_WAIT));
  196.                     EachTimeInit();
  197.                     GetClientRect(hWndMain,&rMain);
  198.                     MazexDim = (rMain.right - rMain.left)/2;
  199.                     MazeyDim = (rMain.bottom - rMain.top)*2/3;
  200.                     MazexDim = MazeyDim = (MazexDim < MazeyDim) ? MazexDim : MazeyDim;
  201.                     TopxDim = (rMain.right - rMain.left)/4;
  202.                     TopyDim = (rMain.bottom - rMain.top)/3;
  203.                     TopxDim = TopyDim = (TopxDim < TopyDim) ? TopxDim : TopyDim;
  204.                     rTopView.right = rMain.right - 10;
  205.                     rTopView.bottom = rMain.bottom - 10;
  206.                     rTopView.left = rTopView.right - TopxDim;
  207.                     rTopView.top = rTopView.bottom - TopyDim;
  208.                     rText.left = rMain.left + 10;
  209.                     rText.right = rMain.right - 10 - TopxDim - 10;
  210.                     rText.top = rMain.top + 10 + MazeyDim + 10;
  211.                     rText.bottom = rMain.bottom-10;
  212.                     rScore.left = rMain.left + 10 + MazexDim +10;
  213.                     rScore.right = rMain.right - 10;
  214.                     rScore.top = rMain.top + 10;
  215.                     rScore.bottom = rMain.bottom - 10 - TopyDim - 10;
  216.                     //
  217.                     // create the 3-d view window
  218.                     //
  219.                     rMaze.left = 0;rMaze.right = 0;
  220.                     rMaze.right = MazexDim;
  221.                     rMaze.bottom = MazeyDim;
  222.                     InitMaze();
  223.                     Calc3DMaze();
  224.                     InitNetwork();
  225.                     rMaze.left = rMain.left+10;
  226.                     rMaze.top = rMain.top +10;
  227.                     rMaze.right = rMaze.left + MazexDim;
  228.                     rMaze.bottom = rMaze.top + MazeyDim;
  229.                     hWndMaze = CreateWindow((LPSTR) "MazeDrawWindow",
  230.                                             (LPSTR) "",
  231.                                             WS_CHILD | WS_DLGFRAME,
  232.                                             rMaze.left,rMaze.top,
  233.                                             rMaze.right - rMaze.left,
  234.                                             rMaze.bottom - rMaze.top,
  235.                                             hWndMain,
  236.                                             (HMENU) NULL,
  237.                                             hInst,
  238.                                             NULL);
  239.                     if(hWndMaze == (HWND)NULL) {
  240.                         return IDS_ERR_CREATE_WINDOW;
  241.                         }
  242.                     StretchBitmaps();
  243.                     GetClientRect(hWndMaze,&rMaze);
  244.                     ShowWindow(hWndMaze, ngCmdShow);
  245.                     //
  246.                     // Create the top-view window
  247.                     //
  248.                     hWndTopView = CreateWindow((LPSTR) "TopViewWindow",
  249.                                                NULL,
  250.                                                WS_CHILD | WS_DLGFRAME,
  251.                                                rTopView.left,rTopView.top,
  252.                                                rTopView.right - rTopView.left,
  253.                                                rTopView.bottom - rTopView.top,
  254.                                                hWndMain,
  255.                                                (HMENU)NULL,
  256.                                                hInst,
  257.                                                NULL);
  258.                     if(hWndTopView == (HWND)NULL) {
  259.                         LoadString(hInst, IDS_ERR_CREATE_WINDOW, szString, sizeof(szString));
  260.                         MessageBox((HWND)NULL, szString, "Main", MB_ICONEXCLAMATION);
  261.                         return IDS_ERR_CREATE_WINDOW;
  262.                         }
  263.                     GetClientRect(hWndTopView,&rTopView);
  264.                     ShowWindow(hWndTopView, ngCmdShow);
  265.                     //
  266.                     // Create the Text window
  267.                     //
  268.                     hWndText = CreateWindow((LPSTR) "TextWindow",
  269.                                             NULL,
  270.                                             WS_CHILD | WS_DLGFRAME,
  271.                                             rText.left,rText.top,
  272.                                             rText.right - rText.left,
  273.                                             rText.bottom - rText.top,
  274.                                             hWndMain,
  275.                                             (HMENU)NULL,
  276.                                             hInst,
  277.                                             NULL);
  278.                     if(hWndText == (HWND)NULL) {
  279.                         LoadString(hInst, IDS_ERR_CREATE_WINDOW, szString, sizeof(szString));
  280.                         MessageBox((HWND)NULL, szString, "Main", MB_ICONEXCLAMATION);
  281.                         return IDS_ERR_CREATE_WINDOW;
  282.                         }
  283.                     GetClientRect(hWndText,&rText);
  284.                     ShowWindow(hWndText, ngCmdShow);
  285.                     PrintTextLine(GetStringRes(IDS_SANCTUARY));
  286.                     PrintTextLine(GetStringRes(IDS_SAFEZONE));
  287.                     //
  288.                     // Create the Score window
  289.                     //
  290.                     hWndScore = CreateWindow((LPSTR) "ScoreWindow",
  291.                                              NULL,
  292.                                              WS_CHILD | WS_DLGFRAME,
  293.                                              rScore.left,rScore.top,
  294.                                              rScore.right - rScore.left,
  295.                                              rScore.bottom - rScore.top,
  296.                                              hWndMain,
  297.                                              (HMENU) NULL,
  298.                                              hInst,
  299.                                              NULL);
  300.                     if(hWndScore == (HWND)NULL) {
  301.                         LoadString(hInst, IDS_ERR_CREATE_WINDOW, szString, sizeof(szString));
  302.                         MessageBox((HWND)NULL, szString, "Main", MB_ICONEXCLAMATION);
  303.                         return IDS_ERR_CREATE_WINDOW;
  304.                         }
  305.                     GetClientRect(hWndScore,&rScore);
  306.                     ShowWindow(hWndScore, ngCmdShow);
  307.                     //
  308.                     // The game is started. reset the cursor as well.
  309.                     //
  310.                     GameStarted = TRUE;
  311.                     SetCursor(LoadCursor((HINSTANCE)NULL,IDC_ARROW));
  312.                     break;
  313.                 case IDM_F_EXIT:
  314.                     SendMessage(hWnd,WM_CLOSE,0,0);
  315.                     break;
  316.                 case IDM_O_NET:
  317.                     bNetworked = TRUE;
  318.                     CheckMenuItem(hMenu,IDM_O_NET,MF_CHECKED);
  319.                     CheckMenuItem(hMenu,IDM_O_LOCAL,MF_UNCHECKED);
  320.                     break;
  321.                 case IDM_O_LOCAL:
  322.                     bNetworked = FALSE;
  323.                     CheckMenuItem(hMenu,IDM_O_NET,MF_UNCHECKED);
  324.                     CheckMenuItem(hMenu,IDM_O_LOCAL,MF_CHECKED);
  325.                     break;
  326.                 case IDM_O_PLAYERSTRETCH:
  327.                     bPlayerPrestretch = !bPlayerPrestretch;
  328.                     CheckMenuItem(hMenu,IDM_O_PLAYERSTRETCH,
  329.                     bPlayerPrestretch?MF_CHECKED:MF_UNCHECKED);
  330.                     if (bPlayerPrestretch) {
  331.                         bDronePrestretch = TRUE;
  332.                         CheckMenuItem(hMenu,IDM_O_DRONESTRETCH,MF_CHECKED);
  333.                         }
  334.                     if (GameStarted) {
  335.                         StretchBitmaps();
  336.                         }
  337.                     break;
  338.                 case IDM_O_DRONESTRETCH:
  339.                     bDronePrestretch = !bDronePrestretch;
  340.                     CheckMenuItem(hMenu,IDM_O_DRONESTRETCH,
  341.                               bDronePrestretch?MF_CHECKED:MF_UNCHECKED);
  342.                     if (bPlayerPrestretch) {
  343.                         bDronePrestretch = TRUE;
  344.                         CheckMenuItem(hMenu,IDM_O_DRONESTRETCH,MF_CHECKED);
  345.                         }
  346.                     if (GameStarted) {
  347.                         StretchBitmaps();
  348.                         }
  349.                     break;
  350.                 case IDM_O_BITMAP:
  351.                     if (bBitmapDraw) {
  352.                         CheckMenuItem(hMenu,IDM_O_BITMAP,MF_UNCHECKED);
  353.                         bBitmapDraw = FALSE;
  354.                         hDC = hHoldDC;
  355.                         hHoldDC = hMazeDC;
  356.                         hMazeDC = hDC;
  357.                         }
  358.                     else {
  359.                         CheckMenuItem(hMenu,IDM_O_BITMAP,MF_CHECKED);
  360.                         bBitmapDraw = TRUE;
  361.                         if ((((HWND)hMaze3DBM) == (HWND)NULL)&&(GameStarted)) {
  362.                             hHoldDC = hMazeDC;
  363.                             GetClientRect(hWnd,&rMaze);
  364.                             hDC = GetDC(hWnd);
  365.                             if (hMazeDC != NULL) {
  366.                                 DeleteDC(hMazeDC);
  367.                             }
  368.                             hMazeDC = CreateCompatibleDC(hDC);
  369.                             if (hMaze3DBM != NULL) {
  370.                                 DeleteObject(hMaze3DBM);
  371.                             }
  372.                             hMaze3DBM = CreateCompatibleBitmap(hDC,rMaze.right-rMaze.left,
  373.                                                                rMaze.bottom-rMaze.top);
  374.                             SelectObject(hMazeDC,hMaze3DBM);
  375.                             ReleaseDC(hWnd,hDC);
  376.                             }
  377.                         else {
  378.                             hDC = hHoldDC;
  379.                             hHoldDC = hMazeDC;
  380.                             hMazeDC = hDC;
  381.                             }
  382.                         }
  383.                     break;
  384.                 case IDM_O_PLAYERSET:
  385.                     bDemoEnable = FALSE;
  386.                     nRc = DialogBox(hInst,"PLAY_CONF_DLG",hWnd,PlayerDlg);
  387.                     bDemoEnable = TRUE;
  388.                     break;
  389.                 case IDM_O_DRONES:
  390.                     bDemoEnable = FALSE;
  391.                     nRc = DialogBox(hInst,"DRONE_DLG", hWnd, DroneDlg);
  392.                     if (GameStarted) {
  393.                         if (uiTimer != (UINT) NULL) {
  394.                             KillTimer((HWND)NULL,uiTimer);
  395.                             }
  396.                         if ((iNumDrones)&&(iDroneSpeed != 0)) {
  397.                             if (! (uiTimer = SetTimer((HWND)NULL,0,ONE_SECOND/iDroneSpeed,MoveDrone))) {
  398.                                 MessageBox((HWND)NULL,GetStringRes(IDS_CRETMRFAIL),GetStringRes(IDS_FATALERR),
  399.                                            MB_ICONEXCLAMATION|MB_APPLMODAL);
  400.                                 SendMessage(hWndMain,WM_CLOSE,0,0);
  401.                                 }
  402.                             }
  403.                         InitDrones();
  404.                         }
  405.                     bDemoEnable = TRUE;
  406.                     break;
  407.                 case IDM_O_PAUSE:
  408.                     GamePaused = ! GamePaused;
  409.                     break;
  410.                 case IDM_F_STOP:
  411.                     if (GameStarted) {
  412.                         nRc = MessageBox((HWND)NULL, GetStringRes(IDS_ASKSTOP),
  413.                                          GetStringRes(IDS_STOP), MB_YESNO);
  414.                         //
  415.                         // If they really want to stop the game, do it...
  416.                         //
  417.                         if (nRc == IDYES) {
  418.                             SendMessage(hWndScore,WM_CLOSE,0,0);
  419.                             SendMessage(hWndText,WM_CLOSE,0,0);
  420.                             SendMessage(hWndTopView,WM_CLOSE,0,0);
  421.                             SendMessage(hWndMaze,WM_CLOSE,0,0);
  422.                             EachTimeShutdown();
  423.                             bDemoEnable = TRUE;
  424.                             }
  425.                         }
  426.                     break;
  427.                 case IDM_ABOUT:
  428.                     bDemoEnable = FALSE;
  429.                     nRc = DialogBox(hInst,"MDLG_ABOUT", hWnd, AboutDlg);
  430.                     bDemoEnable = TRUE;
  431.                     break;
  432.                 default:
  433.                     return DefWindowProc(hWnd, Message, wParam, lParam);
  434.                 }
  435.             break;
  436.         case WM_KEYDOWN:
  437.             if (bDemoMode) {
  438.                 StopDemo();
  439.                 }
  440.             UserIntCount++;
  441.             switch(wParam) {
  442.                 //
  443.                 // X = Quit the game
  444.                 //
  445.                 case 'X':
  446.                     if (!SendNetMessage(0,0,NULL,NP_LEAVINGGAME)) {
  447.                         MessageBox((HWND)NULL,GetStringRes(IDS_SNDPCKTFAIL),"WndProc",
  448.                                      MB_ICONEXCLAMATION|MB_APPLMODAL);
  449.                         }
  450.                     SendMessage(hWndMain,WM_CLOSE,0,0);
  451.                     return(0);
  452.                     break;
  453.                 //
  454.                 // movement messages go to the MazeWindow
  455.                 //
  456.                 case VK_SPACE:
  457.                 case VK_UP:
  458.                 case VK_LEFT:
  459.                 case VK_RIGHT:
  460.                 case VK_DOWN:
  461.                 case 'w':
  462.                 case 'W':
  463.                 case 's':
  464.                 case 'S':
  465.                     SendMessage(hWndMaze,WM_KEYDOWN,wParam,lParam);
  466.                     break;
  467.                 }
  468.             break;
  469.         case WM_CREATE:
  470.             //
  471.             // Set timer for 30-second intervals to go into demo-mode.
  472.             //
  473.             SetTimer(hWnd,(UINT) NULL, (UINT) (30*1000),(TIMERPROC) NULL);
  474.             //
  475.             // We decide on the basis of user interaction whether to
  476.             // start demo-mode or not.
  477.             //
  478.             UserIntCount = 0;
  479.             bDemoMode = FALSE;
  480.             CheckMenuItem(hMenu,IDM_O_NET,MF_CHECKED);
  481.             CheckMenuItem(hMenu,IDM_O_LOCAL,MF_UNCHECKED);
  482.             bNetworked = TRUE;
  483.             break;
  484.         case WM_MOVE:
  485.             break;
  486.         case WM_SIZE:
  487.             GetClientRect(hWndMain,&rMain);
  488.             MazexDim = (rMain.right - rMain.left)/2;
  489.             MazeyDim = (rMain.bottom - rMain.top)*2/3;
  490.             MazexDim = MazeyDim = (MazexDim < MazeyDim) ? MazexDim : MazeyDim;
  491.             rMaze.left = rMain.left+10;
  492.             rMaze.top = rMain.top +10;
  493.             rMaze.right = rMaze.left + MazexDim;
  494.             rMaze.bottom = rMaze.top + MazeyDim;
  495.             MoveWindow(hWndMaze,rMaze.left,rMaze.top,
  496.                        rMaze.right-rMaze.left,rMaze.bottom-rMaze.top,TRUE);
  497.             TopxDim = (rMain.right - rMain.left)/4;
  498.             TopyDim = (rMain.bottom - rMain.top)/3;
  499.             TopxDim = TopyDim = (TopxDim < TopyDim) ? TopxDim : TopyDim;
  500.             rTopView.right = rMain.right - 10;
  501.             rTopView.bottom = rMain.bottom - 10;
  502.             rTopView.left = rTopView.right - TopxDim;
  503.             rTopView.top = rTopView.bottom - TopyDim;
  504.             MoveWindow(hWndTopView,rTopView.left,rTopView.top,
  505.                        rTopView.right - rTopView.left,
  506.                        rTopView.bottom - rTopView.top,TRUE);
  507.             rText.left = rMain.left + 10;
  508.             rText.right = rMain.right - 10 - TopxDim - 10;
  509.             rText.top = rMain.top + 10 + MazeyDim + 10;
  510.             rText.bottom = rMain.bottom-10;
  511.             MoveWindow(hWndText,rText.left,rText.top,
  512.                        rText.right - rText.left,
  513.                        rText.bottom - rText.top,TRUE);
  514.             rScore.left = rMain.left + 10 + MazexDim +10;
  515.             rScore.right = rMain.right - 10;
  516.             rScore.top = rMain.top + 10;
  517.             rScore.bottom = rMain.bottom - 10 - TopyDim - 10;
  518.             MoveWindow(hWndScore,rScore.left,rScore.top,
  519.                     rScore.right - rScore.left,
  520.                     rScore.bottom - rScore.top,TRUE);
  521.             break;
  522.         case WM_PAINT:
  523.             memset(&ps, 0x00, sizeof(PAINTSTRUCT));
  524.             hDC = BeginPaint(hWnd, &ps);
  525.             SetBkMode(hDC, TRANSPARENT);
  526.             hBitmap = LoadBitmap(hInst,"MAZE");
  527.             hBMDC = CreateCompatibleDC(hDC);
  528.             SelectObject(hBMDC,hBitmap);
  529.             GetClientRect(hWndMain,&rMain);
  530.             //
  531.             // Fill the destination with the bitmap
  532.             //
  533.             for(i=rMain.left;i<rMain.right;i+=54) {
  534.                 for(j=rMain.top;j<rMain.bottom;j+=42) {
  535.                     BitBlt(hDC,i,j,54,42,
  536.                            hBMDC,0,0,
  537.                            SRCCOPY
  538.                           );
  539.                     }
  540.                 }
  541.             DeleteDC(hBMDC);
  542.             DeleteObject(hBitmap);
  543.             EndPaint(hWnd, &ps);
  544.             break;
  545.         case WM_CLOSE:
  546.             DestroyWindow(hWnd);
  547.             if (hWnd == hWndMain) {
  548.                 PostQuitMessage(0);
  549.                 EachTimeShutdown();
  550.                 OneTimeShutdown();
  551.                 }
  552.             break;
  553.         default:
  554.             return DefWindowProc(hWnd, Message, wParam, lParam);
  555.         }
  556.     return(0);
  557. }
  558. /*=====================================================================
  559. Function:RegisterClasses()
  560. Inputs: None
  561. Outputs:returns Success/failure
  562. Abstract:
  563.     This is responsible for registering the main window class and the
  564.     child window classes as well.
  565. ======================================================================*/
  566. int RegisterClasses(
  567.     void
  568.     )
  569. {
  570.     WNDCLASS   wndclass;
  571.     memset(&wndclass, 0x00, sizeof(WNDCLASS));
  572.     wndclass.style = CS_HREDRAW | CS_VREDRAW | CS_BYTEALIGNWINDOW;
  573.     wndclass.lpfnWndProc = WndProc;
  574.     wndclass.cbClsExtra = 0;
  575.     wndclass.cbWndExtra = 0;
  576.     wndclass.hInstance = hInst;
  577.     wndclass.hIcon = LoadIcon(hInst, "MAZE");
  578.     wndclass.hCursor = LoadCursor((HINSTANCE)NULL, IDC_ARROW);
  579.     wndclass.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
  580.     wndclass.lpszMenuName = szAppName;
  581.     wndclass.lpszClassName = szAppName;
  582.     if(!RegisterClass(&wndclass)) {
  583.         return(-1);
  584.         }
  585.     //
  586.     // Register the 3-d window class
  587.     //
  588.     wndclass.style = CS_HREDRAW | CS_VREDRAW | CS_NOCLOSE | CS_OWNDC | CS_BYTEALIGNWINDOW;
  589.     wndclass.lpfnWndProc = MazeWndProc;
  590.     wndclass.hIcon = (HICON)NULL;
  591.     wndclass.lpszMenuName = NULL;
  592.     wndclass.lpszClassName = (LPSTR) "MazeDrawWindow";
  593.     if(!RegisterClass(&wndclass)) {
  594.         return(-1);
  595.         }
  596.     //
  597.     // Register the top view window class
  598.     //
  599.     wndclass.lpfnWndProc = TopViewWndProc;
  600.     wndclass.lpszClassName = (LPSTR) "TopViewWindow";
  601.     if(!RegisterClass(&wndclass)) {
  602.         return(-1);
  603.         }
  604.     //
  605.     // Register the text window class
  606.     //
  607.     wndclass.lpfnWndProc = TextWndProc;
  608.     wndclass.lpszClassName = (LPSTR) "TextWindow";
  609.     if(!RegisterClass(&wndclass)) {
  610.         return(-1);
  611.         }
  612.     //
  613.     // Register the Score window class
  614.     //
  615.     wndclass.lpfnWndProc = ScoreWndProc;
  616.     wndclass.lpszClassName = (LPSTR) "ScoreWindow";
  617.     if(!RegisterClass(&wndclass)) {
  618.         return(-1);
  619.         }
  620.     return(0);
  621. }
  622. /*=====================================================================
  623. Function: UnRegisterClasses
  624. Inputs: none
  625. Outputs:none
  626. Abstract:
  627.     This deletes the windows classes we registered for MazeLords.
  628. ======================================================================*/
  629. void UnRegisterClasses(
  630.     void
  631.     )
  632. {
  633.     WNDCLASS   wndclass;
  634.     memset(&wndclass, 0x00, sizeof(WNDCLASS));
  635.     UnregisterClass(szAppName, hInst);
  636.     UnregisterClass((LPSTR) "MazeDrawWindow",hInst);
  637.     UnregisterClass((LPSTR) "TopViewWindow",hInst);
  638.     UnregisterClass((LPSTR) "TextWindow",hInst);
  639.     UnregisterClass((LPSTR) "ScoreWindow",hInst);
  640. }
  641. /*=====================================================================
  642. Function: OneTimeInit()
  643. Inputs: none
  644. Outputs:none
  645. Abstract:
  646.     This initialization routine is called the first time a game is started.
  647.     It reads in the subgrids, initializes the network, makes a mailslot,
  648.     and sets many of the global variables.
  649. ======================================================================*/
  650. void OneTimeInit()
  651. {
  652.     DWORD dwScratch,dwSize,dwType;
  653.     HMENU hMenu;
  654.     BOOL bRet;
  655.     int i,j,k;
  656. #ifdef WIN32
  657.     HKEY hKey;
  658. #endif
  659.     if (!ReadSubGrids()) {
  660.         MessageBox((HWND)NULL,GetStringRes(IDS_RDSGRDTXTFLFAIL),
  661. GetStringRes2(IDS_INITFAIL), MB_ICONEXCLAMATION);
  662.         }
  663.     dwScratch = MAX_USERNAME_LENGTH;
  664.     strcpy(ptSelf.cUserName,"<A Player>");
  665.     strcpy(ptSelf.cComputerName,"MachineName");
  666.     dwSize =MAX_COMPUTERNAME_LENGTH;
  667.     ptSelf.ulID = 0;
  668.     ptSelf.iPicNum = PIC_DEFAULT;
  669.     ptSelf.iGridNum = SUBGRID_DEFAULT;
  670.     hMenu = GetMenu(hWndMain);
  671.     EnableMenuItem(hMenu,IDM_F_STOP,MF_GRAYED);
  672.     EnableMenuItem(hMenu,IDM_O_PAUSE,MF_GRAYED);
  673. #ifdef WIN32
  674.     if (!(bRet = GetUserName(ptSelf.cUserName,&dwScratch))) {
  675.         MessageBox((HWND)NULL,GetStringRes(IDS_GETUSRNMFAIL),
  676. GetStringRes2(IDS_NETINIT), MB_ICONEXCLAMATION|MB_APPLMODAL);
  677.         }
  678.     dwType = REG_SZ;
  679.     RegOpenKeyEx(HKEY_LOCAL_MACHINE,
  680.                  "SYSTEM\CurrentControlSet\Control\ComputerName\ActiveComputerName",
  681.                  0,
  682.                  KEY_READ,
  683.                  &hKey);
  684.     RegQueryValueEx(hKey,"ComputerName",NULL,&dwType,
  685.                     ptSelf.cComputerName,&dwSize);
  686.     ptSelf.dwPID = GetCurrentProcessId();
  687. #endif
  688.     ptSelf.ulID = MemCRC((LPSTR) &ptSelf.ulID,(int) sizeof(ptSelf));
  689.     bDemoMode = FALSE;
  690.     bDemoEnable = TRUE;
  691.     iNumDrones = 10;
  692.     iDroneSpeed = 2;
  693.     iDroneMoveAlg = 1;
  694.     bBitmapDraw = FALSE;
  695.     bPlayerPrestretch = FALSE;
  696.     bDronePrestretch = FALSE;
  697.     for(i=0;i<NUM_PICS;i++) {
  698.         for (j=0;j<MAX_DRAW_DIST;j++) {
  699.             for(k=0;k<4;k++) {
  700.                 PreStretch[i][j].P[k].hBitmap = (HBITMAP)NULL;
  701.                 PreStretch[i][j].M[k].hBitmap = (HBITMAP)NULL;
  702.                 }
  703.             }
  704.         }
  705.     return;
  706. }
  707. /*=====================================================================
  708. Function: EachTimeInit()
  709. Inputs: none
  710. Outputs:none
  711. Abstract:
  712.     This function is called each time a new game is started (initially,
  713.     and any time after a STOP selection from the menu) This loads some
  714.     bitmaps, changes the state on menu-items whose validity is changed by
  715.     a game in progress, and resets some global variables.
  716. ======================================================================*/
  717. void EachTimeInit(
  718.     void
  719.     )
  720. {
  721.     HMENU hMenu;
  722.     hMenu = GetMenu(hWndMain);
  723.     EnableMenuItem(hMenu,IDM_O_NET,MF_GRAYED);
  724.     EnableMenuItem(hMenu,IDM_O_LOCAL,MF_GRAYED);
  725.     EnableMenuItem(hMenu,IDM_O_PLAYERSET,MF_GRAYED);
  726.     EnableMenuItem(hMenu,IDM_F_NEWGAME,MF_GRAYED);
  727.     EnableMenuItem(hMenu,IDM_F_STOP,MF_ENABLED);
  728.     EnableMenuItem(hMenu,IDM_O_PAUSE,MF_ENABLED);
  729.     uiTimer = (UINT) NULL;
  730.     ptDrones.next = NULL;
  731.     fptPic.next = NULL;
  732.     bSelfInSanct = TRUE;
  733.     hShotBM[0]=LoadBitmap(hInst,"SHOT1");
  734.     hShotBM[1]=LoadBitmap(hInst,"SHOT2");
  735.     hFadeBM[0]=LoadBitmap(hInst,"FADE1");
  736.     hFadeBM[1]=LoadBitmap(hInst,"FADE2");
  737.     hMaze3DBM = (HBITMAP)NULL;
  738.     hMazeDC = (HDC)NULL;
  739.     iWhisperDist = 2;
  740.     iShoutDist = 10;
  741.     iPlayersKilled = iTimesKilled = iDronesKilled = 0;
  742.     ptSelf.iScore = iKilledByDrones = 0;
  743.     GamePaused = GameStarted = FALSE;
  744.     Scores.next = NULL;
  745.     return;
  746. }
  747. /*=====================================================================
  748. Function: OneTimeShutdown()
  749. Inputs: none
  750. Outputs:none
  751. Abstract:
  752.     This function does NOTHING right now. It'll be called at the very
  753.     end of everything.
  754. ======================================================================*/
  755. void OneTimeShutdown(
  756.     void
  757.     )
  758. {
  759.     return;
  760. }
  761. /*=====================================================================
  762. Function: EachTimeShutdown()
  763. Inputs: none
  764. Outputs:none
  765. Abstract:
  766.     This function is called each time a STOP command is selected and
  767.     approved. It changes menu items to the correct state, changes some
  768.     global state variables, and notifies the network that we're quitting
  769.     the game.
  770. ======================================================================*/
  771. void EachTimeShutdown(
  772.     void
  773.     )
  774. {
  775.     HMENU hMenu;
  776.     hMenu = GetMenu(hWndMain);
  777.     DeleteObject(hShotBM[0]);
  778.     DeleteObject(hShotBM[1]);
  779.     DeleteObject(hFadeBM[0]);
  780.     DeleteObject(hFadeBM[1]);
  781.     DeleteObject(hMaze3DBM);
  782.     DeleteDC(hMazeDC);
  783.     EnableMenuItem(hMenu,IDM_O_NET,MF_ENABLED);
  784.     EnableMenuItem(hMenu,IDM_O_LOCAL,MF_ENABLED);
  785.     EnableMenuItem(hMenu,IDM_O_PLAYERSET,MF_ENABLED);
  786.     EnableMenuItem(hMenu,IDM_F_STOP,MF_GRAYED);
  787.     EnableMenuItem(hMenu,IDM_O_PAUSE,MF_GRAYED);
  788.     EnableMenuItem(hMenu,IDM_F_NEWGAME,MF_ENABLED);
  789.     if (!SendNetMessage(0,0,NULL,NP_LEAVINGGAME)) {
  790.         MessageBox((HWND)NULL,GetStringRes(IDS_SNDQUITPCKTFAIL),"EachTimeShutDown",
  791.                    MB_ICONEXCLAMATION|MB_APPLMODAL);
  792.         }
  793.     bNetworked = TRUE;
  794.     GameStarted = FALSE;
  795.     iNumDrones = 0;
  796.     iDroneSpeed = 0;
  797.     iDroneMoveAlg = 1;
  798.     bBitmapDraw = FALSE;
  799.     return;
  800. }
  801. /*=====================================================================
  802. Function: StartDemo()
  803. Inputs: none
  804. Outputs:none
  805. Abstract:
  806.     This function is responsible for causing MazeLords to enter Demo
  807.     mode.
  808. ======================================================================*/
  809. void StartDemo(
  810.     void
  811.     )
  812. {
  813.     bDemoMode = TRUE;
  814.     SetWindowText(hWndMain,GetStringRes(IDS_DEMOMODE));
  815.     SendMessage(hWndMain,WM_COMMAND,MAKELONG(IDM_F_NEWGAME,0),(LPARAM)NULL);
  816.     return;
  817. }
  818. /*=====================================================================
  819. Function: StopDemo()
  820. Inputs: none
  821. Outputs:none
  822. Abstract:
  823.     This function is responsible for ending the mazelords demo and
  824.     putting it into a state that the user can interact with.
  825. ======================================================================*/
  826. void StopDemo(
  827.     void
  828.     )
  829. {
  830.     bDemoMode = FALSE;
  831.     SendMessage(hWndScore,WM_CLOSE,0,0);
  832.     SendMessage(hWndText,WM_CLOSE,0,0);
  833.     SendMessage(hWndTopView,WM_CLOSE,0,0);
  834.     SendMessage(hWndMaze,WM_CLOSE,0,0);
  835.     EachTimeShutdown();
  836.     iNumDrones  = 10;
  837.     iDroneSpeed = 2;
  838.     bDemoEnable = TRUE;
  839.     UserIntCount++;
  840.     SetWindowText(hWndMain,"Maze Lords");
  841.     return;
  842. }
  843. /******************************************************************************
  844. *
  845. *  FUNCTION:    GetStringRes (int id INPUT ONLY)
  846. *
  847. *  COMMENTS:    Load the resource string with the ID given, and return a
  848. *               pointer to it.  Notice that the buffer is common memory so
  849. *               the string must be used before this call is made a second time.
  850. *
  851. ******************************************************************************/
  852. LPTSTR   GetStringRes (int id)
  853. {
  854.   static TCHAR buffer[MAX_PATH];
  855.   buffer[0]=0;
  856.   LoadString (GetModuleHandle (NULL), id, buffer, MAX_PATH);
  857.   return buffer;
  858. }
  859. LPTSTR   GetStringRes2 (int id)
  860. {
  861.   static TCHAR buffer[MAX_PATH];
  862.   buffer[0]=0;
  863.   LoadString (GetModuleHandle (NULL), id, buffer, MAX_PATH);
  864.   return buffer;
  865. }