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

  1. #include "stdafx.h"
  2. #include "qe3.h"
  3. #include "PrefsDlg.h"
  4. #include <direct.h>  
  5. #include <sys\stat.h> 
  6.  
  7. QEGlobals_t  g_qeglobals;
  8.  
  9. void WINAPI QE_CheckOpenGLForErrors(void)
  10. {
  11.   CString strMsg;
  12.   int i = qglGetError();
  13.   if (i != GL_NO_ERROR)
  14.   {
  15.     if (i == GL_OUT_OF_MEMORY)
  16.     {
  17.       //strMsg.Format("OpenGL out of memory error %s\nDo you wish to save before exiting?", qgluErrorString((GLenum)i));
  18.       if (MessageBox(g_qeglobals.d_hwndMain, strMsg, "Q3Radiant Error", MB_YESNO) == IDYES)
  19.       {
  20.         Map_SaveFile(NULL, false);
  21.       }
  22.           exit(1);
  23.     }
  24.     else
  25.     {
  26.       //strMsg.Format("Warning: OpenGL Error %s\n ", qgluErrorString((GLenum)i));
  27.           Sys_Printf (strMsg.GetBuffer(0));
  28.     }
  29.   }
  30. }
  31.  
  32.  
  33. char *ExpandReletivePath (char *p)
  34. {
  35.     static char    temp[1024];
  36.     char    *base;
  37.  
  38.     if (!p || !p[0])
  39.         return NULL;
  40.     if (p[0] == '/' || p[0] == '\\')
  41.         return p;
  42.  
  43.     base = ValueForKey(g_qeglobals.d_project_entity, "basepath");
  44.     sprintf (temp, "%s/%s", base, p);
  45.     return temp;
  46. }
  47.  
  48. char *copystring (char *s)
  49. {
  50.     char    *b;
  51.     b = (char*)malloc(strlen(s)+1);
  52.     strcpy (b,s);
  53.     return b;
  54. }
  55.  
  56.  
  57. bool DoesFileExist(const char* pBuff, long& lSize)
  58. {
  59.   CFile file;
  60.   if (file.Open(pBuff, CFile::modeRead | CFile::shareDenyNone))
  61.   {
  62.     lSize += file.GetLength();
  63.     file.Close();
  64.     return true;
  65.   }
  66.   return false;
  67. }
  68.  
  69.  
  70. void Map_Snapshot()
  71. {
  72.   CString strMsg;
  73.   // we need to do the following
  74.   // 1. make sure the snapshot directory exists (create it if it doesn't)
  75.   // 2. find out what the lastest save is based on number
  76.   // 3. inc that and save the map
  77.   CString strOrgPath, strOrgFile;
  78.   ExtractPath_and_Filename(currentmap, strOrgPath, strOrgFile);
  79.   AddSlash(strOrgPath);
  80.   strOrgPath += "snapshots";
  81.   bool bGo = true;
  82.   struct _stat Stat;
  83.   if (_stat(strOrgPath, &Stat) == -1)
  84.   {
  85.     bGo = (_mkdir(strOrgPath) != -1);
  86.   }
  87.   AddSlash(strOrgPath);
  88.   if (bGo)
  89.   {
  90.     int nCount = 0;
  91.     long lSize = 0;
  92.     CString strNewPath = strOrgPath;
  93.     strNewPath += strOrgFile;
  94.     CString strFile;
  95.     while (bGo)
  96.     {
  97.       strFile.Format("%s.%i", strNewPath, nCount);
  98.       bGo = DoesFileExist(strFile, lSize);
  99.       nCount++;
  100.     }
  101.     // strFile has the next available slot
  102.     Map_SaveFile(strFile.GetBuffer(0), false);
  103.         Sys_SetTitle (currentmap);
  104.     if (lSize > 12 * 1024 * 1024) // total size of saves > 4 mb
  105.     {
  106.       Sys_Printf("The snapshot files in the [%s] directory total more than 4 megabytes. You might consider cleaning the directory up.", strOrgPath);
  107.     }
  108.   }
  109.   else
  110.   {
  111.     strMsg.Format("Snapshot save failed.. unabled to create directory\n%s", strOrgPath);
  112.     g_pParentWnd->MessageBox(strMsg);
  113.   }
  114. }
  115. /*
  116. ===============
  117. QE_CheckAutoSave
  118.  
  119. If five minutes have passed since making a change
  120. and the map hasn't been saved, save it out.
  121. ===============
  122. */
  123.  
  124.  
  125. void QE_CheckAutoSave( void )
  126. {
  127.     static clock_t s_start;
  128.     clock_t        now;
  129.  
  130.     now = clock();
  131.  
  132.     if ( modified != 1 || !s_start)
  133.     {
  134.         s_start = now;
  135.         return;
  136.     }
  137.  
  138.     if ( now - s_start > ( CLOCKS_PER_SEC * 60 * g_PrefsDlg.m_nAutoSave))
  139.     {
  140.  
  141.     if (g_PrefsDlg.m_bAutoSave)
  142.     {
  143.       CString strMsg = g_PrefsDlg.m_bSnapShots ? "Autosaving snapshot..." : "Autosaving...";
  144.           Sys_Printf(strMsg.GetBuffer(0));
  145.       Sys_Printf("\n");
  146.           Sys_Status (strMsg.GetBuffer(0),0);
  147.  
  148.       // only snapshot if not working on a default map
  149.       if (g_PrefsDlg.m_bSnapShots && stricmp(currentmap, "unnamed.map") != 0)
  150.       {
  151.         Map_Snapshot();
  152.       }
  153.       else
  154.       {
  155.             Map_SaveFile (ValueForKey(g_qeglobals.d_project_entity, "autosave"), false);
  156.       }
  157.  
  158.           Sys_Status ("Autosaving...Saved.", 0 );
  159.           modified = 2;
  160.     }
  161.     else
  162.     {
  163.           Sys_Printf ("Autosave skipped...\n");
  164.           Sys_Status ("Autosave skipped...", 0 );
  165.     }
  166.         s_start = now;
  167.     }
  168. }
  169.  
  170.  
  171. int BuildShortPathName(const char* pPath, char* pBuffer, int nBufferLen)
  172. {
  173.   char *pFile = NULL;
  174.   int nResult = GetFullPathName(pPath, nBufferLen, pBuffer, &pFile); 
  175.   nResult = GetShortPathName(pPath, pBuffer, nBufferLen);
  176.   if (nResult == 0)
  177.     strcpy(pBuffer, pPath);                     // Use long filename
  178.   return nResult;
  179. }
  180.  
  181.  
  182.  
  183. const char *g_pPathFixups[]=
  184. {
  185.   "basepath",
  186.   "remotebasepath",
  187.   "entitypath",
  188.   "texturepath",
  189.   "autosave",
  190.   "mapspath"
  191. };
  192.  
  193. const int g_nPathFixupCount = sizeof(g_pPathFixups) / sizeof(const char*);
  194.  
  195. /*
  196. ===========
  197. QE_LoadProject
  198. ===========
  199. */
  200. qboolean QE_LoadProject (char *projectfile)
  201. {
  202.     char    *data;
  203.  
  204.     Sys_Printf ("QE_LoadProject (%s)\n", projectfile);
  205.     
  206.     if ( LoadFileNoCrash (projectfile, (void **)&data) == -1)
  207.         return false;
  208.     
  209.     g_strProject = projectfile;
  210.     
  211.     CString strData = data;
  212.     free(data);
  213.     
  214.     CString strQ2Path = g_PrefsDlg.m_strQuake2;
  215.     CString strQ2File;
  216.     ExtractPath_and_Filename(g_PrefsDlg.m_strQuake2, strQ2Path, strQ2File);
  217.     AddSlash(strQ2Path);
  218.     
  219.     
  220.     char* pBuff = new char[1024];
  221.     
  222.     BuildShortPathName(strQ2Path, pBuff, 1024);
  223.     FindReplace(strData, "__Q2PATH", pBuff);
  224.     BuildShortPathName(g_strAppPath, pBuff, 1024);
  225.     FindReplace(strData, "__QERPATH", pBuff);
  226.     
  227.     char* pFile;
  228.     if (GetFullPathName(projectfile, 1024, pBuff, &pFile))
  229.     {
  230.         g_PrefsDlg.m_strLastProject = pBuff;
  231.         BuildShortPathName(g_PrefsDlg.m_strLastProject, pBuff, 1024);
  232.         g_PrefsDlg.m_strLastProject = pBuff;
  233.         g_PrefsDlg.SavePrefs();
  234.         
  235.         ExtractPath_and_Filename(pBuff, strQ2Path, strQ2File);
  236.         int nLen = strQ2Path.GetLength();
  237.         if (nLen > 0)
  238.         {
  239.             if (strQ2Path[nLen - 1] == '\\')
  240.                 strQ2Path.SetAt(nLen-1,'\0');
  241.             char* pBuffer = strQ2Path.GetBufferSetLength(_MAX_PATH + 1);
  242.             int n = strQ2Path.ReverseFind('\\');
  243.             if (n >=0 )
  244.                 pBuffer[n + 1] = '\0';
  245.             strQ2Path.ReleaseBuffer();
  246.             FindReplace(strData, "__QEPROJPATH", strQ2Path);
  247.         }
  248.     }
  249.     
  250.     
  251.     StartTokenParsing (strData.GetBuffer(0));
  252.     g_qeglobals.d_project_entity = Entity_Parse (true);
  253.     if (!g_qeglobals.d_project_entity)
  254.         Error ("Couldn't parse %s", projectfile);
  255.  
  256.   for (int i = 0; i < g_nPathFixupCount; i++)
  257.   {
  258.     char *pPath = ValueForKey (g_qeglobals.d_project_entity, g_pPathFixups[i]);
  259.     if (pPath[0] != '\\' && pPath[0] != '/')
  260.     {
  261.         if (GetFullPathName(pPath, 1024, pBuff, &pFile))
  262.       {
  263.         SetKeyValue(g_qeglobals.d_project_entity, g_pPathFixups[i], pBuff);
  264.       }
  265.     }
  266.   }
  267.  
  268.     delete []pBuff;
  269.  
  270.     // set here some default project settings you need
  271.     if ( strlen( ValueForKey( g_qeglobals.d_project_entity, "brush_primit" ) ) == 0 )
  272.     {
  273.         SetKeyValue( g_qeglobals.d_project_entity, "brush_primit", "0" );
  274.     }
  275.  
  276.     g_qeglobals.m_bBrushPrimitMode = IntForKey( g_qeglobals.d_project_entity, "brush_primit" );
  277.  
  278.  
  279.     Eclass_InitForSourceDirectory (ValueForKey (g_qeglobals.d_project_entity, "entitypath"));
  280.     FillClassList();        // list in entity window
  281.     
  282.     Map_New();
  283.     
  284.     
  285.     FillTextureMenu();
  286.     FillBSPMenu();
  287.     
  288.     return true;
  289. }
  290.  
  291. /*
  292. ===========
  293. QE_SaveProject
  294. ===========
  295. */
  296. //extern char    *bsp_commands[256];
  297.  
  298. qboolean QE_SaveProject (const char* pProjectFile)
  299. {
  300.     //char    filename[1024];
  301.     FILE    *fp;
  302.     epair_t    *ep;
  303.  
  304.     //sprintf (filename, "%s\\%s.prj", g_projectdir, g_username);
  305.  
  306.     if (!(fp = fopen (pProjectFile, "w+")))
  307.         Error ("Could not open project file!");
  308.     
  309.     fprintf (fp, "{\n");
  310.     for (ep = g_qeglobals.d_project_entity->epairs; ep; ep=ep->next)
  311.         fprintf (fp, "\"%s\" \"%s\"\n", ep->key, ep->value);
  312.     fprintf (fp, "}\n");
  313.  
  314.     fclose (fp);
  315.     
  316.     return TRUE;
  317. }
  318.  
  319.  
  320.  
  321. /*
  322. ===========
  323. QE_KeyDown
  324. ===========
  325. */
  326. #define    SPEED_MOVE    32
  327. #define    SPEED_TURN    22.5
  328.  
  329.  
  330. /*
  331. ===============
  332. ConnectEntities
  333.  
  334. Sets target / targetname on the two entities selected
  335. from the first selected to the secon
  336. ===============
  337. */
  338. void ConnectEntities (void)
  339. {
  340.     entity_t    *e1, *e2, *e;
  341.     char        *target, *tn;
  342.     int            maxtarg, targetnum;
  343.     char        newtarg[32];
  344.  
  345.     if (g_qeglobals.d_select_count != 2)
  346.     {
  347.         Sys_Status ("Must have two brushes selected.", 0);
  348.         Sys_Beep ();
  349.         return;
  350.     }
  351.  
  352.     e1 = g_qeglobals.d_select_order[0]->owner;
  353.     e2 = g_qeglobals.d_select_order[1]->owner;
  354.  
  355.     if (e1 == world_entity || e2 == world_entity)
  356.     {
  357.         Sys_Status ("Can't connect to the world.", 0);
  358.         Sys_Beep ();
  359.         return;
  360.     }
  361.  
  362.     if (e1 == e2)
  363.     {
  364.         Sys_Status ("Brushes are from same entity.", 0);
  365.         Sys_Beep ();
  366.         return;
  367.     }
  368.  
  369.     target = ValueForKey (e1, "target");
  370.     if (target && target[0])
  371.         strcpy (newtarg, target);
  372.     else
  373.     {
  374.         target = ValueForKey (e2, "targetname");
  375.         if (target && target[0])
  376.             strcpy (newtarg, target);
  377.         else
  378.         {
  379.             // make a unique target value
  380.             maxtarg = 0;
  381.             for (e=entities.next ; e != &entities ; e=e->next)
  382.             {
  383.                 tn = ValueForKey (e, "targetname");
  384.                 if (tn && tn[0])
  385.                 {
  386.                     targetnum = atoi(tn+1);
  387.                     if (targetnum > maxtarg)
  388.                         maxtarg = targetnum;
  389.                 }
  390.             }
  391.             sprintf (newtarg, "t%i", maxtarg+1);
  392.         }
  393.     }
  394.  
  395.     SetKeyValue (e1, "target", newtarg);
  396.     SetKeyValue (e2, "targetname", newtarg);
  397.     Sys_UpdateWindows (W_XY | W_CAMERA);
  398.  
  399.     Select_Deselect();
  400.     Select_Brush (g_qeglobals.d_select_order[1]);
  401. }
  402.  
  403. qboolean QE_SingleBrush (bool bQuiet)
  404. {
  405.     if ( (selected_brushes.next == &selected_brushes)
  406.         || (selected_brushes.next->next != &selected_brushes) )
  407.     {
  408.       if (!bQuiet)
  409.     {
  410.           Sys_Printf ("Error: you must have a single brush selected\n");
  411.       }
  412.         return false;
  413.     }
  414.     if (selected_brushes.next->owner->eclass->fixedsize)
  415.     {
  416.       if (!bQuiet)
  417.       {
  418.           Sys_Printf ("Error: you cannot manipulate fixed size entities\n");
  419.       }
  420.         return false;
  421.     }
  422.  
  423.     return true;
  424. }
  425.  
  426. void QE_Init (void)
  427. {
  428.     /*
  429.     ** initialize variables
  430.     */
  431.     g_qeglobals.d_gridsize = 8;
  432.     g_qeglobals.d_showgrid = true;
  433.  
  434.     /*
  435.     ** other stuff
  436.     */
  437.     Texture_Init (true);
  438.     //Cam_Init ();
  439.     //XY_Init ();
  440.     Z_Init ();
  441. }
  442.  
  443. void WINAPI QE_ConvertDOSToUnixName( char *dst, const char *src )
  444. {
  445.     while ( *src )
  446.     {
  447.         if ( *src == '\\' )
  448.             *dst = '/';
  449.         else
  450.             *dst = *src;
  451.         dst++; src++;
  452.     }
  453.     *dst = 0;
  454. }
  455.  
  456. int g_numbrushes, g_numentities;
  457.  
  458. void QE_CountBrushesAndUpdateStatusBar( void )
  459. {
  460.     static int      s_lastbrushcount, s_lastentitycount;
  461.     static qboolean s_didonce;
  462.     
  463.     //entity_t   *e;
  464.     brush_t       *b, *next;
  465.  
  466.     g_numbrushes = 0;
  467.     g_numentities = 0;
  468.     
  469.     if ( active_brushes.next != NULL )
  470.     {
  471.         for ( b = active_brushes.next ; b != NULL && b != &active_brushes ; b=next)
  472.         {
  473.             next = b->next;
  474.             if (b->brush_faces )
  475.             {
  476.                 if ( !b->owner->eclass->fixedsize)
  477.                     g_numbrushes++;
  478.                 else
  479.                     g_numentities++;
  480.             }
  481.         }
  482.     }
  483. /*
  484.     if ( entities.next != NULL )
  485.     {
  486.         for ( e = entities.next ; e != &entities && g_numentities != MAX_MAP_ENTITIES ; e = e->next)
  487.         {
  488.             g_numentities++;
  489.         }
  490.     }
  491. */
  492.     if ( ( ( g_numbrushes != s_lastbrushcount ) || ( g_numentities != s_lastentitycount ) ) || ( !s_didonce ) )
  493.     {
  494.         Sys_UpdateStatusBar();
  495.  
  496.         s_lastbrushcount = g_numbrushes;
  497.         s_lastentitycount = g_numentities;
  498.         s_didonce = true;
  499.     }
  500. }
  501.  
  502. char        com_token[1024];
  503. qboolean    com_eof;
  504.  
  505. /*
  506. ================
  507. I_FloatTime
  508. ================
  509. */
  510. double I_FloatTime (void)
  511. {
  512.     time_t    t;
  513.     
  514.     time (&t);
  515.     
  516.     return t;
  517. #if 0
  518. // more precise, less portable
  519.     struct timeval tp;
  520.     struct timezone tzp;
  521.     static int        secbase;
  522.  
  523.     gettimeofday(&tp, &tzp);
  524.     
  525.     if (!secbase)
  526.     {
  527.         secbase = tp.tv_sec;
  528.         return tp.tv_usec/1000000.0;
  529.     }
  530.     
  531.     return (tp.tv_sec - secbase) + tp.tv_usec/1000000.0;
  532. #endif
  533. }
  534.  
  535.  
  536. /*
  537. ==============
  538. COM_Parse
  539.  
  540. Parse a token out of a string
  541. ==============
  542. */
  543. char *COM_Parse (char *data)
  544. {
  545.     int        c;
  546.     int        len;
  547.     
  548.     len = 0;
  549.     com_token[0] = 0;
  550.     
  551.     if (!data)
  552.         return NULL;
  553.         
  554. // skip whitespace
  555. skipwhite:
  556.     while ( (c = *data) <= ' ')
  557.     {
  558.         if (c == 0)
  559.         {
  560.             com_eof = true;
  561.             return NULL;            // end of file;
  562.         }
  563.         data++;
  564.     }
  565.     
  566. // skip // comments
  567.     if (c=='/' && data[1] == '/')
  568.     {
  569.         while (*data && *data != '\n')
  570.             data++;
  571.         goto skipwhite;
  572.     }
  573.     
  574.  
  575. // handle quoted strings specially
  576.     if (c == '\"')
  577.     {
  578.         data++;
  579.         do
  580.         {
  581.             c = *data++;
  582.             if (c=='\"')
  583.             {
  584.                 com_token[len] = 0;
  585.                 return data;
  586.             }
  587.             com_token[len] = c;
  588.             len++;
  589.         } while (1);
  590.     }
  591.  
  592. // parse single characters
  593.     if (c=='{' || c=='}'|| c==')'|| c=='(' || c=='\'' || c==':')
  594.     {
  595.         com_token[len] = c;
  596.         len++;
  597.         com_token[len] = 0;
  598.         return data+1;
  599.     }
  600.  
  601. // parse a regular word
  602.     do
  603.     {
  604.         com_token[len] = c;
  605.         data++;
  606.         len++;
  607.         c = *data;
  608.     if (c=='{' || c=='}'|| c==')'|| c=='(' || c=='\'' || c==':')
  609.             break;
  610.     } while (c>32);
  611.     
  612.     com_token[len] = 0;
  613.     return data;
  614. }
  615.  
  616.  
  617.  
  618. /*
  619. =============================================================================
  620.  
  621.                         MISC FUNCTIONS
  622.  
  623. =============================================================================
  624. */
  625.  
  626.  
  627. int        argc;
  628. char    *argv[MAX_NUM_ARGVS];
  629.  
  630. /*
  631. ============
  632. ParseCommandLine
  633. ============
  634. */
  635. void ParseCommandLine (char *lpCmdLine)
  636. {
  637.     argc = 1;
  638.     argv[0] = "programname";
  639.  
  640.     while (*lpCmdLine && (argc < MAX_NUM_ARGVS))
  641.     {
  642.         while (*lpCmdLine && ((*lpCmdLine <= 32) || (*lpCmdLine > 126)))
  643.             lpCmdLine++;
  644.  
  645.         if (*lpCmdLine)
  646.         {
  647.             argv[argc] = lpCmdLine;
  648.             argc++;
  649.  
  650.             while (*lpCmdLine && ((*lpCmdLine > 32) && (*lpCmdLine <= 126)))
  651.                 lpCmdLine++;
  652.  
  653.             if (*lpCmdLine)
  654.             {
  655.                 *lpCmdLine = 0;
  656.                 lpCmdLine++;
  657.             }
  658.             
  659.         }
  660.     }
  661. }
  662.  
  663.  
  664.  
  665. /*
  666. =================
  667. CheckParm
  668.  
  669. Checks for the given parameter in the program's command line arguments
  670. Returns the argument number (1 to argc-1) or 0 if not present
  671. =================
  672. */
  673. int CheckParm (char *check)
  674. {
  675.     int             i;
  676.  
  677.     for (i = 1;i<argc;i++)
  678.     {
  679.         if ( stricmp(check, argv[i]) )
  680.             return i;
  681.     }
  682.  
  683.     return 0;
  684. }
  685.  
  686.  
  687.  
  688.  
  689. /*
  690. ==============
  691. ParseNum / ParseHex
  692. ==============
  693. */
  694. int ParseHex (char *hex)
  695. {
  696.     char    *str;
  697.     int    num;
  698.  
  699.     num = 0;
  700.     str = hex;
  701.  
  702.     while (*str)
  703.     {
  704.         num <<= 4;
  705.         if (*str >= '0' && *str <= '9')
  706.             num += *str-'0';
  707.         else if (*str >= 'a' && *str <= 'f')
  708.             num += 10 + *str-'a';
  709.         else if (*str >= 'A' && *str <= 'F')
  710.             num += 10 + *str-'A';
  711.         else
  712.             Error ("Bad hex number: %s",hex);
  713.         str++;
  714.     }
  715.  
  716.     return num;
  717. }
  718.  
  719.  
  720. int ParseNum (char *str)
  721. {
  722.     if (str[0] == '$')
  723.         return ParseHex (str+1);
  724.     if (str[0] == '0' && str[1] == 'x')
  725.         return ParseHex (str+2);
  726.     return atol (str);
  727. }
  728.  
  729.  
  730.