home *** CD-ROM | disk | FTP | other *** search
/ PC PowerPlay 58 / pcpp58a.iso / extras / quake 3 source / Q3A_ToolSource.exe / Main / WIN_QE3.CPP < prev    next >
Encoding:
C/C++ Source or Header  |  2001-01-02  |  15.6 KB  |  660 lines

  1. #include "stdafx.h"
  2. #include "qe3.h"
  3. #include "mru.h"
  4. #include "PrefsDlg.h"
  5.  
  6. ////////////////////////////////////////////////////////////////////////////
  7. // BSP frontend plugin
  8. // global flag for BSP frontend plugin is g_qeglobals.bBSPFrontendPlugin
  9. _QERPlugBSPFrontendTable g_BSPFrontendTable;
  10. CStringArray g_BSPFrontendCommands;
  11.  
  12. extern CEdit* g_pEdit;
  13.  
  14. int    screen_width;
  15. int    screen_height;
  16. qboolean    have_quit;
  17.  
  18. int    update_bits;
  19.  
  20. HANDLE    bsp_process;
  21.  
  22. //===========================================
  23.  
  24. void Sys_MarkMapModified (void)
  25. {
  26.     char            title[1024];
  27.  
  28.     if (modified != 1)
  29.     {
  30.         modified = true;    // mark the map as changed
  31.         sprintf (title, "%s *", currentmap);
  32.  
  33.         QE_ConvertDOSToUnixName( title, title );
  34.         Sys_SetTitle (title);
  35.     }
  36. }
  37.  
  38.  
  39. void Sys_SetTitle (char *text)
  40. {
  41.     SetWindowText (g_qeglobals.d_hwndMain, text);
  42. }
  43.  
  44. HCURSOR    waitcursor;
  45.  
  46. void Sys_BeginWait (void)
  47. {
  48.     waitcursor = SetCursor (LoadCursor (NULL, IDC_WAIT));
  49. }
  50.  
  51. void Sys_EndWait (void)
  52. {
  53.     if (waitcursor)
  54.     {
  55.         SetCursor (waitcursor);
  56.         waitcursor = NULL;
  57.     }
  58. }
  59.  
  60.  
  61. void Sys_GetCursorPos (int *x, int *y)
  62. {
  63.     POINT lpPoint;
  64.  
  65.     GetCursorPos (&lpPoint);
  66.     *x = lpPoint.x;
  67.     *y = lpPoint.y;
  68. }
  69.  
  70. void Sys_SetCursorPos (int x, int y)
  71. {
  72.     SetCursorPos (x, y);
  73. }
  74.  
  75.  
  76. void Sys_Beep (void)
  77. {
  78.     MessageBeep (MB_ICONASTERISK);
  79. }
  80.  
  81. char    *TranslateString (char *buf)
  82. {
  83.     static    char    buf2[32768];
  84.     int        i, l;
  85.     char    *out;
  86.  
  87.     l = strlen(buf);
  88.     out = buf2;
  89.     for (i=0 ; i<l ; i++)
  90.     {
  91.         if (buf[i] == '\n')
  92.         {
  93.             *out++ = '\r';
  94.             *out++ = '\n';
  95.         }
  96.         else
  97.             *out++ = buf[i];
  98.     }
  99.     *out++ = 0;
  100.  
  101.     return buf2;
  102. }
  103.  
  104.  
  105. void Sys_ClearPrintf (void)
  106. {
  107.     char    text[4];
  108.     text[0] = 0;
  109.  
  110.   SendMessage (g_qeglobals.d_hwndEdit, WM_SETTEXT, 0,    (LPARAM)text);
  111. }
  112.  
  113.  
  114. #define SCROLLBACK_MAX_LINES    600
  115. #define SCROLLBACK_DEL_CHARS    500
  116.  
  117. void Sys_Printf (char *text, ...)
  118. {
  119.     va_list argptr;
  120.     char    buf[32768];
  121.     char    *out;
  122.     LRESULT    result;                // PGM
  123.     DWORD    oldPosS, oldPosE;    // PGM
  124.  
  125.     va_start (argptr,text);
  126.     vsprintf (buf, text,argptr);
  127.     va_end (argptr);
  128.  
  129.     out = TranslateString (buf);
  130.  
  131. #ifdef LATER
  132.     Sys_Status(out);
  133. #else
  134. //PGM
  135.     result = SendMessage (g_qeglobals.d_hwndEdit, EM_GETLINECOUNT, 0, 0);
  136.     if(result > SCROLLBACK_MAX_LINES)
  137.     {
  138.         char    replaceText[5];
  139.         
  140.         replaceText[0] = '\0';
  141.  
  142.         SendMessage (g_qeglobals.d_hwndEdit, WM_SETREDRAW, (WPARAM)0, (LPARAM)0);
  143.         SendMessage (g_qeglobals.d_hwndEdit, EM_GETSEL, (WPARAM)&oldPosS, (LPARAM)&oldPosE);
  144.         SendMessage (g_qeglobals.d_hwndEdit, EM_SETSEL, 0, SCROLLBACK_DEL_CHARS);
  145.         SendMessage (g_qeglobals.d_hwndEdit, EM_REPLACESEL, (WPARAM)0, (LPARAM)replaceText);
  146.         SendMessage (g_qeglobals.d_hwndEdit, EM_SETSEL, oldPosS, oldPosE);
  147.         SendMessage (g_qeglobals.d_hwndEdit, WM_SETREDRAW, (WPARAM)1, (LPARAM)0);
  148.     }
  149. //PGM
  150.  
  151.     SendMessage (g_qeglobals.d_hwndEdit, EM_REPLACESEL, 0, (LPARAM)out);
  152. #endif
  153.  
  154. }
  155.  
  156.  
  157. double Sys_DoubleTime (void)
  158. {
  159.     return clock()/ 1000.0;
  160. }
  161.  
  162. void PrintPixels (HDC hDC)
  163. {
  164.     int        i;
  165.     PIXELFORMATDESCRIPTOR p[64];
  166.  
  167.     printf ("### flags color layer\n");
  168.     for (i=1 ; i<64 ; i++)
  169.     {
  170.         if (!DescribePixelFormat ( hDC, i, sizeof(p[0]), &p[i]))
  171.             break;
  172.         printf ("%3i %5i %5i %5i\n", i,
  173.             p[i].dwFlags,
  174.             p[i].cColorBits,
  175.             p[i].bReserved);
  176.     }
  177.     printf ("%i modes\n", i-1);
  178. }
  179.  
  180.  
  181.  
  182. //==========================================================================
  183.  
  184. void QEW_StopGL( HWND hWnd, HGLRC hGLRC, HDC hDC )
  185. {
  186.   qwglMakeCurrent( NULL, NULL );
  187.   qwglDeleteContext( hGLRC );
  188.     ReleaseDC( hWnd, hDC );
  189. }
  190.         
  191. int WINAPI QEW_SetupPixelFormat(HDC hDC, qboolean zbuffer )
  192. {
  193.     static PIXELFORMATDESCRIPTOR pfd = {
  194.         sizeof(PIXELFORMATDESCRIPTOR),    // size of this pfd
  195.         1,                                              // version number
  196.         PFD_DRAW_TO_WINDOW |                  // support window
  197.         PFD_SUPPORT_OPENGL |                  // support OpenGL
  198.         PFD_DOUBLEBUFFER,                        // double buffered
  199.         PFD_TYPE_RGBA,                            // RGBA type
  200.         24,                                              // 24-bit color depth
  201.         0, 0, 0, 0, 0, 0,                  // color bits ignored
  202.         0,                                              // no alpha buffer
  203.         0,                                              // shift bit ignored
  204.         0,                                              // no accumulation buffer
  205.         0, 0, 0, 0,                                  // accum bits ignored
  206.         32,                                            // depth bits
  207.         0,                                              // no stencil buffer
  208.         0,                                              // no auxiliary buffer
  209.         PFD_MAIN_PLANE,                            // main layer
  210.         0,                                              // reserved
  211.         0, 0, 0                                        // layer masks ignored
  212.     };                              //
  213.     int pixelformat = 0;            
  214.  
  215.     zbuffer = true;
  216.     if ( !zbuffer )
  217.         pfd.cDepthBits = 0;
  218.  
  219.   if (g_PrefsDlg.m_bSGIOpenGL)
  220.   {
  221.     if ( (pixelformat = qwglChoosePixelFormat(hDC, &pfd)) == 0 )
  222.     {
  223.         printf("%d",GetLastError());
  224.       Error ("ChoosePixelFormat failed");
  225.     }
  226.   
  227.     if (!qwglSetPixelFormat(hDC, pixelformat, &pfd))
  228.       Error ("SetPixelFormat failed");
  229.   }
  230.   else
  231.   {
  232.     if ( (pixelformat = ChoosePixelFormat(hDC, &pfd)) == 0 )
  233.     {
  234.         printf("%d",GetLastError());
  235.       Error ("ChoosePixelFormat failed");
  236.     }
  237.  
  238.     if (!SetPixelFormat(hDC, pixelformat, &pfd))
  239.       Error ("SetPixelFormat failed");
  240.   }
  241.  
  242.     return pixelformat;
  243. }
  244.  
  245. /*
  246. =================
  247. Error
  248.  
  249. For abnormal program terminations
  250. =================
  251. */
  252. void Error (char *error, ...)
  253. {
  254.     va_list argptr;
  255.     char    text[1024];
  256.     char    text2[1024];
  257.     int        err;
  258.     
  259.     err = GetLastError ();
  260.     int i = qglGetError();
  261.     
  262.     va_start (argptr,error);
  263.     vsprintf (text, error,argptr);
  264.     va_end (argptr);
  265.     
  266.     sprintf (text2, "%s\nGetLastError() = %i - %i\nAn unrecoverable error has occured. Would you like to edit Preferences before exiting Q3Radiant?", text, err, i);
  267.     
  268.     if (MessageBox(g_qeglobals.d_hwndMain, text2, "Error", MB_YESNO) == IDYES)
  269.     {
  270.         g_PrefsDlg.LoadPrefs();
  271.         g_PrefsDlg.DoModal();
  272.     }
  273.     
  274.     exit (1);
  275. }
  276.  
  277.  
  278. void Warning (char *error, ...)
  279. {
  280.     va_list argptr;
  281.     char    text[1024];
  282.     int        err;
  283.  
  284.     err = GetLastError ();
  285.   int i = qglGetError();
  286.  
  287.     va_start (argptr,error);
  288.     vsprintf (text, error,argptr);
  289.     va_end (argptr);
  290.  
  291.   Sys_Printf(text);
  292. }
  293.  
  294.  
  295. /*
  296. ======================================================================
  297.  
  298. FILE DIALOGS
  299.  
  300. ======================================================================
  301. */
  302.  
  303. qboolean ConfirmModified (void)
  304. {
  305.     if (!modified)
  306.         return true;
  307.  
  308.     if (MessageBox (g_qeglobals.d_hwndMain, "This will lose changes to the map"
  309.         , "warning", MB_OKCANCEL) == IDCANCEL)
  310.         return false;
  311.     return true;
  312. }
  313.  
  314. static OPENFILENAME ofn;       /* common dialog box structure   */ 
  315. static char szDirName[MAX_PATH];    /* directory string              */ 
  316. static char szFile[260];       /* filename string               */ 
  317. static char szFileTitle[260];  /* file title string             */ 
  318. static char szFilter[260] =     /* filter string                 */ 
  319.     "Map file (*.map, *.reg)\0*.map\0*.reg\0\0";
  320. static char szProjectFilter[260] =     /* filter string                 */ 
  321.     "Q3Radiant project (*.qe4, *.prj)\0*.qe4\0*.prj\0\0";
  322. static char chReplace;         /* string separator for szFilter */ 
  323. static int i, cbString;        /* integer count variables       */ 
  324. static HANDLE hf;              /* file handle                   */ 
  325.  
  326. void OpenDialog (void)
  327. {
  328.     /* 
  329.      * Obtain the system directory name and 
  330.      * store it in szDirName. 
  331.      */ 
  332.  
  333.     strcpy (szDirName, ValueForKey (g_qeglobals.d_project_entity, "mapspath") );
  334.   if (strlen(szDirName) == 0)
  335.   {
  336.       strcpy (szDirName, ValueForKey (g_qeglobals.d_project_entity, "basepath") );
  337.       strcat (szDirName, "\\maps");
  338.   }
  339.  
  340.     /* Place the terminating null character in the szFile. */ 
  341.  
  342.     szFile[0] = '\0'; 
  343.  
  344.     /* Set the members of the OPENFILENAME structure. */ 
  345.  
  346.     ofn.lStructSize = sizeof(OPENFILENAME); 
  347.     ofn.hwndOwner = g_qeglobals.d_hwndCamera;
  348.     ofn.lpstrFilter = szFilter; 
  349.     ofn.nFilterIndex = 1; 
  350.     ofn.lpstrFile = szFile; 
  351.     ofn.nMaxFile = sizeof(szFile); 
  352.     ofn.lpstrFileTitle = szFileTitle; 
  353.     ofn.nMaxFileTitle = sizeof(szFileTitle); 
  354.     ofn.lpstrInitialDir = szDirName; 
  355.     ofn.Flags = OFN_SHOWHELP | OFN_PATHMUSTEXIST | 
  356.         OFN_FILEMUSTEXIST; 
  357.  
  358.     /* Display the Open dialog box. */ 
  359.  
  360.     if (!GetOpenFileName(&ofn))
  361.         return;    // canceled
  362.  
  363.     // Add the file in MRU.
  364.   //FIXME
  365.     AddNewItem( g_qeglobals.d_lpMruMenu, ofn.lpstrFile);
  366.  
  367.     // Refresh the File menu.
  368.   //FIXME
  369.     PlaceMenuMRUItem(g_qeglobals.d_lpMruMenu,GetSubMenu(GetMenu(g_qeglobals.d_hwndMain),0), 
  370.             ID_FILE_EXIT);
  371.  
  372.     /* Open the file. */ 
  373.  
  374.     Map_LoadFile (ofn.lpstrFile);    
  375. }
  376.  
  377. void ProjectDialog (void)
  378. {
  379.     /* 
  380.      * Obtain the system directory name and 
  381.      * store it in szDirName. 
  382.      */ 
  383.  
  384.     strcpy (szDirName, ValueForKey(g_qeglobals.d_project_entity, "basepath") );
  385.     strcat (szDirName, "\\scripts");
  386.  
  387.     /* Place the terminating null character in the szFile. */ 
  388.  
  389.     szFile[0] = '\0'; 
  390.  
  391.     /* Set the members of the OPENFILENAME structure. */ 
  392.  
  393.     ofn.lStructSize = sizeof(OPENFILENAME); 
  394.     ofn.hwndOwner = g_qeglobals.d_hwndCamera;
  395.     ofn.lpstrFilter = szProjectFilter; 
  396.     ofn.nFilterIndex = 1; 
  397.     ofn.lpstrFile = szFile; 
  398.     ofn.nMaxFile = sizeof(szFile); 
  399.     ofn.lpstrFileTitle = szFileTitle; 
  400.     ofn.nMaxFileTitle = sizeof(szFileTitle); 
  401.     ofn.lpstrInitialDir = szDirName; 
  402.     ofn.Flags = OFN_SHOWHELP | OFN_PATHMUSTEXIST | 
  403.         OFN_FILEMUSTEXIST; 
  404.  
  405.     /* Display the Open dialog box. */ 
  406.  
  407.     if (!GetOpenFileName(&ofn))
  408.         return;    // canceled
  409.  
  410.     // Refresh the File menu.
  411.     PlaceMenuMRUItem(g_qeglobals.d_lpMruMenu,GetSubMenu(GetMenu(g_qeglobals.d_hwndMain),0), 
  412.             ID_FILE_EXIT);
  413.  
  414.     /* Open the file. */ 
  415.     if (!QE_LoadProject(ofn.lpstrFile))
  416.         Error ("Couldn't load project file");
  417. }
  418.  
  419.  
  420. extern void AddSlash(CString& strPath);
  421. void SaveAsDialog (bool bRegion)
  422.     strcpy (szDirName, ValueForKey (g_qeglobals.d_project_entity, "basepath") );
  423.   CString strPath = szDirName;
  424.   AddSlash(strPath);
  425.   strPath += "maps";
  426.  
  427.     /* Place the terminating null character in the szFile. */ 
  428.  
  429.     szFile[0] = '\0'; 
  430.  
  431.     /* Set the members of the OPENFILENAME structure. */ 
  432.  
  433.     ofn.lStructSize = sizeof(OPENFILENAME); 
  434.     ofn.hwndOwner = g_qeglobals.d_hwndCamera;
  435.     ofn.lpstrFilter = szFilter; 
  436.     ofn.nFilterIndex = 1; 
  437.     ofn.lpstrFile = szFile; 
  438.     ofn.nMaxFile = sizeof(szFile); 
  439.     ofn.lpstrFileTitle = szFileTitle; 
  440.     ofn.nMaxFileTitle = sizeof(szFileTitle); 
  441.     ofn.lpstrInitialDir = strPath; 
  442.     ofn.Flags = OFN_SHOWHELP | OFN_PATHMUSTEXIST | 
  443.         OFN_FILEMUSTEXIST | OFN_OVERWRITEPROMPT; 
  444.  
  445.     /* Display the Open dialog box. */ 
  446.  
  447.     if (!GetSaveFileName(&ofn))
  448.         return;    // canceled
  449.  
  450.   if (bRegion)
  451.       DefaultExtension (ofn.lpstrFile, ".reg");
  452.   else
  453.       DefaultExtension (ofn.lpstrFile, ".map");
  454.  
  455.   if (!bRegion)
  456.   {
  457.       strcpy (currentmap, ofn.lpstrFile);
  458.     AddNewItem(g_qeglobals.d_lpMruMenu, ofn.lpstrFile);
  459.       PlaceMenuMRUItem(g_qeglobals.d_lpMruMenu,GetSubMenu(GetMenu(g_qeglobals.d_hwndMain),0),    ID_FILE_EXIT);
  460.   }
  461.     Map_SaveFile (ofn.lpstrFile, bRegion);    // ignore region
  462. }
  463.  
  464. /*
  465. =======================================================
  466.  
  467. Menu modifications
  468.  
  469. =======================================================
  470. */
  471.  
  472. /*
  473. ==================
  474. FillBSPMenu
  475.  
  476. ==================
  477. */
  478. char    *bsp_commands[256];
  479.  
  480. void FillBSPMenu (void)
  481. {
  482.     HMENU    hmenu;
  483.     epair_t    *ep;
  484.     int        i;
  485.     static int count;
  486.  
  487.     hmenu = GetSubMenu (GetMenu(g_qeglobals.d_hwndMain), MENU_BSP);
  488.  
  489.     for (i=0 ; i<count ; i++)
  490.         DeleteMenu (hmenu, CMD_BSPCOMMAND+i, MF_BYCOMMAND);
  491.     count = 0;
  492.  
  493.     if ( g_qeglobals.bBSPFrontendPlugin )
  494.     {
  495.         CString str = g_BSPFrontendTable.m_pfnGetBSPMenu();
  496.         char cTemp[1024];
  497.         strcpy(cTemp, str);
  498.         char* token = strtok(cTemp, ",;");
  499.         if (token && *token == ' ')
  500.         {
  501.             while (*token == ' ')
  502.                 token++;
  503.         }
  504.         i = 0;
  505.         // first token is menu name
  506.         ModifyMenu( GetMenu(g_qeglobals.d_hwndMain), MENU_BSP, MF_BYPOSITION, MENU_BSP, (LPCTSTR)token );
  507.         // redraw the menu bar
  508.         DrawMenuBar( g_qeglobals.d_hwndMain );
  509.         token = strtok(NULL, ",;");
  510.         while (token != NULL)
  511.         {
  512.             g_BSPFrontendCommands.Add(token);
  513.             AppendMenu (hmenu, MF_ENABLED|MF_STRING, CMD_BSPCOMMAND+i, (LPCTSTR)token );
  514.             token = strtok(NULL, ",;");
  515.             i++;
  516.         }
  517.         count = i;
  518.     }
  519.     else
  520.     {
  521.         i = 0;
  522.         for (ep = g_qeglobals.d_project_entity->epairs ; ep ; ep=ep->next)
  523.         {
  524.             if (ep->key[0] == 'b' && ep->key[1] == 's' && ep->key[2] == 'p')
  525.             {
  526.                 bsp_commands[i] = ep->key;
  527.                 AppendMenu (hmenu, MF_ENABLED|MF_STRING,
  528.                     CMD_BSPCOMMAND+i, (LPCTSTR)ep->key);
  529.                 i++;
  530.             }
  531.         }
  532.         count = i;
  533.     }
  534. }
  535.  
  536. //==============================================
  537. void AddSlash(CString& strPath)
  538. {
  539.   if (strPath.GetLength() > 0)
  540.   {
  541.     if (strPath.GetAt(strPath.GetLength()-1) != '\\')
  542.       strPath += '\\';
  543.   }
  544. }
  545.  
  546.  
  547. bool ExtractPath_and_Filename(const char* pPath, CString& strPath, CString& strFilename)
  548. {
  549.   CString strPathName = pPath;
  550.   int nSlash = strPathName.ReverseFind('\\');
  551.   if (nSlash >= 0)
  552.   {
  553.     strPath = strPathName.Left(nSlash+1);
  554.     strFilename = strPathName.Right(strPathName.GetLength() - nSlash - 1);
  555.   }
  556.   else strFilename = pPath;
  557.   return true;
  558. }
  559.  
  560.  
  561. /*
  562. ===============
  563. CheckBspProcess
  564.  
  565. See if the BSP is done yet
  566. ===============
  567. */
  568. extern void FindReplace(CString& strContents, const char* pTag, const char* pValue);
  569. extern CTime g_tBegin;
  570.  
  571. void CheckBspProcess (void)
  572. {
  573.     char    outputpath[1024];
  574.     char    temppath[512];
  575.     DWORD    exitcode;
  576.     char    *out;
  577.     BOOL    ret;
  578.  
  579.     if (!bsp_process)
  580.         return;
  581.  
  582.     ret = GetExitCodeProcess (bsp_process, &exitcode);
  583.     if (!ret)
  584.         Error ("GetExitCodeProcess failed");
  585.     if (exitcode == STILL_ACTIVE)
  586.         return;
  587.  
  588.     bsp_process = 0;
  589.  
  590.     GetTempPath(512, temppath);
  591.     sprintf (outputpath, "%sjunk.txt", temppath);
  592.  
  593.     LoadFile (outputpath, (void **)&out);
  594.     Sys_Printf ("%s", out);
  595.     Sys_Printf ("\ncompleted.\n");
  596.     free (out);
  597.  
  598.     CTime tEnd = CTime::GetCurrentTime();
  599.     CTimeSpan tElapsed = tEnd - g_tBegin;
  600.     CString strElapsed;
  601.     strElapsed.Format("Run time was %i hours, %i minutes and %i seconds", tElapsed.GetHours(), tElapsed.GetMinutes(), tElapsed.GetSeconds());
  602.     Sys_Printf(strElapsed.GetBuffer(0));
  603.  
  604.  
  605.     Sys_Beep ();
  606.     Pointfile_Check();
  607.     // run game if no PointFile and pref is set
  608.     //++timo needs to stop after BSP if leaked .. does run through vis and light instead ..
  609.     if (g_PrefsDlg.m_bRunQuake == TRUE  && !g_qeglobals.d_pointfile_display_list)
  610.     {
  611.         char cCurDir[1024];
  612.         GetCurrentDirectory(1024, cCurDir);
  613.         CString strExePath = g_PrefsDlg.m_strQuake2;
  614.         CString strOrgPath;
  615.         CString strOrgFile;
  616.         ExtractPath_and_Filename(currentmap, strOrgPath, strOrgFile);
  617.         if (g_PrefsDlg.m_bSetGame == TRUE) // run in place with set game.. don't copy map
  618.         {
  619.             CString strBasePath = ValueForKey(g_qeglobals.d_project_entity, "basepath");
  620.             strExePath += " +set game ";
  621.             strExePath += strBasePath;
  622.             WinExec(strExePath, SW_SHOW);
  623.         }
  624.         else
  625.         {
  626.             CString strCopyPath = strExePath;
  627.             char* pBuffer = strCopyPath.GetBufferSetLength(_MAX_PATH + 1);
  628.             pBuffer[strCopyPath.ReverseFind('\\') + 1] = '\0';
  629.             strCopyPath.ReleaseBuffer();
  630.             SetCurrentDirectory(strCopyPath);
  631.             CString strOrgPath;
  632.             CString strOrgFile;
  633.             ExtractPath_and_Filename(currentmap, strOrgPath, strOrgFile);
  634.             AddSlash(strCopyPath);
  635.             FindReplace(strOrgFile, ".map", ".bsp");
  636.             //++timo modified for Quake3 !!
  637.             strCopyPath += "baseq3\\maps\\";
  638.             strCopyPath += strOrgFile;
  639.             AddSlash(strOrgPath);
  640.             strOrgPath += strOrgFile;
  641.             bool bRun = (strOrgPath.CompareNoCase(strCopyPath) == 0);
  642.             if (!bRun)
  643.                 bRun = (CopyFile(strOrgPath, strCopyPath, FALSE) == TRUE);
  644.             if (bRun)
  645.             {
  646.                 FindReplace(strOrgFile, ".bsp", "");
  647.                 strExePath += " +map ";
  648.                 strExePath += strOrgFile;
  649.                 WinExec(strExePath, SW_SHOW);
  650.             }
  651.         }
  652.         SetCurrentDirectory(cCurDir);
  653.     }
  654. }
  655.  
  656. extern int    cambuttonstate;
  657.  
  658.  
  659.