- // saving project will cause a save prefs
- g_PrefsDlg.m_strLastProject = buf;
- g_PrefsDlg.m_nLastProjectVer = IntForKey( g_qeglobals.d_project_entity, "version" );
- QE_SaveProject(buf);
- }
- else
- {
- // update preferences::LastProject with path of this successfully-loaded project
- // save preferences
- Sys_Printf("Setting current project in prefs to \"%s\"\n", g_PrefsDlg.m_strLastProject.GetBuffer() );
- g_PrefsDlg.m_strLastProject = projectfile;
- g_PrefsDlg.SavePrefs();
- }
-
- return true;
-}
-
-/*
-===========
-QE_SaveProject
-TTimo: whenever QE_SaveProject is called, prefs are updated and saved with the path to the project
-===========
-*/
-qboolean QE_SaveProject (const char* filename)
-{
- Sys_Printf("Save project file '%s'\n", filename);
-
- xmlNodePtr node;
- xmlDocPtr doc = xmlNewDoc((xmlChar *)"1.0");
- // create DTD node
- xmlCreateIntSubset(doc, (xmlChar *)"project", NULL, (xmlChar *)"project.dtd");
- // create project node
- doc->children->next = xmlNewDocNode(doc, NULL, (xmlChar *)"project", NULL);
-
- for(epair_t* epair = g_qeglobals.d_project_entity->epairs; epair != NULL; epair = epair->next)
- {
- node = xmlNewChild(doc->children->next, NULL, (xmlChar *)"key", NULL);
- xmlSetProp(node, (xmlChar*)"name", (xmlChar*)epair->key);
- xmlSetProp(node, (xmlChar*)"value", (xmlChar*)epair->value);
- }
-
- CreateDirectoryPath(filename);
- if (xmlSaveFormatFile(filename, doc, 1) != -1)
- {
- xmlFreeDoc(doc);
- Sys_Printf("Setting current project in prefs to \"%s\"\n", filename );
- g_PrefsDlg.m_strLastProject = filename;
- g_PrefsDlg.SavePrefs();
- return TRUE;
- }
- else
- {
- xmlFreeDoc(doc);
- Sys_FPrintf(SYS_ERR, "failed to save project file: \"%s\"\n", filename);
- return FALSE;
- }
-}
-
-
-
-/*
-===========
-QE_KeyDown
-===========
-*/
-#define SPEED_MOVE 32
-#define SPEED_TURN 22.5
-
-
-/*
-===============
-ConnectEntities
-
-Sets target / targetname on the two entities selected
-from the first selected to the secon
-===============
-*/
-void ConnectEntities (void)
-{
- entity_t *e1, *e2;
- const char *target;
- char *newtarg = NULL;
-
- if (g_qeglobals.d_select_count != 2)
- {
- Sys_Status ("Must have two brushes selected", 0);
- Sys_Beep ();
- return;
- }
-
- e1 = g_qeglobals.d_select_order[0]->owner;
- e2 = g_qeglobals.d_select_order[1]->owner;
-
- if (e1 == world_entity || e2 == world_entity)
- {
- Sys_Status ("Can't connect to the world", 0);
- Sys_Beep ();
- return;
- }
-
- if (e1 == e2)
- {
- Sys_Status ("Brushes are from same entity", 0);
- Sys_Beep ();
- return;
- }
-
- target = ValueForKey (e1, "target");
- if (target && target[0])
- newtarg = g_strdup(target);
- else
- {
- target = ValueForKey(e2, "targetname");
- if(target && target[0])
- newtarg = g_strdup(target);
- else
- Entity_Connect(e1, e2);
- }
-
- if(newtarg != NULL)
- {
- SetKeyValue(e1, "target", newtarg);
- SetKeyValue(e2, "targetname", newtarg);
- g_free(newtarg);
- }
-
- Sys_UpdateWindows (W_XY | W_CAMERA);
-
- Select_Deselect();
- Select_Brush (g_qeglobals.d_select_order[1]);
-}
-
-qboolean QE_SingleBrush (bool bQuiet)
-{
- if ( (selected_brushes.next == &selected_brushes)
- || (selected_brushes.next->next != &selected_brushes) )
- {
- if (!bQuiet)
- {
- Sys_Printf ("Error: you must have a single brush selected\n");
- }
- return false;
- }
- if (selected_brushes.next->owner->eclass->fixedsize)
- {
- if (!bQuiet)
- {
- Sys_Printf ("Error: you cannot manipulate fixed size entities\n");
- }
- return false;
- }
-
- return true;
-}
-
-void QE_InitVFS (void)
-{
- // VFS initialization -----------------------
- // we will call vfsInitDirectory, giving the directories to look in (for files in pk3's and for standalone files)
- // we need to call in order, the mod ones first, then the base ones .. they will be searched in this order
- // *nix systems have a dual filesystem in ~/.q3a, which is searched first .. so we need to add that too
- Str directory,prefabs;
-
- // TTimo: let's leave this to HL mode for now
- if (g_pGameDescription->mGameFile == "hl.game")
- {
- // Hydra: we search the "gametools" path first so that we can provide editor
- // specific pk3's wads and misc files for use by the editor.
- // the relevant map compiler tools will NOT use this directory, so this helps
- // to ensure that editor files are not used/required in release versions of maps
- // it also helps keep your editor files all in once place, with the editor modules,
- // plugins, scripts and config files.
- // it also helps when testing maps, as you'll know your files won't/can't be used
- // by the game engine itself.
-
- // <gametools>
- directory = g_pGameDescription->mGameToolsPath;
- vfsInitDirectory(directory.GetBuffer());
- }
-
- // NOTE TTimo about the mymkdir calls .. this is a bit dirty, but a safe thing on *nix
-
- // if we have a mod dir
- if (*ValueForKey(g_qeglobals.d_project_entity, "gamename") != '\0')
- {
-
-#if defined (__linux__) || defined (__APPLE__)
- // ~/.<gameprefix>/<fs_game>
- directory = g_qeglobals.m_strHomeGame.GetBuffer();
- Q_mkdir (directory.GetBuffer (), 0775);
- directory += ValueForKey(g_qeglobals.d_project_entity, "gamename");
- Q_mkdir (directory.GetBuffer (), 0775);
- vfsInitDirectory(directory.GetBuffer());
- AddSlash (directory);
- prefabs = directory;
- // also create the maps dir, it will be used as prompt for load/save
- directory += "/maps";
- Q_mkdir (directory, 0775);
- // and the prefabs dir
- prefabs += "/prefabs";
- Q_mkdir (prefabs, 0775);
-
-#endif
-
- // <fs_basepath>/<fs_game>
- directory = g_pGameDescription->mEnginePath;
- directory += ValueForKey(g_qeglobals.d_project_entity, "gamename");
- Q_mkdir (directory.GetBuffer (), 0775);
- vfsInitDirectory(directory.GetBuffer());
- AddSlash(directory);
- prefabs = directory;
- // also create the maps dir, it will be used as prompt for load/save
- directory += "/maps";
- Q_mkdir (directory.GetBuffer (), 0775);
- // and the prefabs dir
- prefabs += "/prefabs";
- Q_mkdir (prefabs, 0775);
- }
-
-#if defined (__linux__) || defined (__APPLE__)
- // ~/.<gameprefix>/<fs_main>
- directory = g_qeglobals.m_strHomeGame.GetBuffer();
- directory += g_pGameDescription->mBaseGame;
- vfsInitDirectory (directory.GetBuffer ());
-#endif
-
- // <fs_basepath>/<fs_main>
- directory = g_pGameDescription->mEnginePath;
- directory += g_pGameDescription->mBaseGame;
- vfsInitDirectory(directory.GetBuffer());
-}
-
-void QE_Init (void)
-{
- /*
- ** initialize variables
- */
- g_qeglobals.d_gridsize = 8;
- g_qeglobals.d_showgrid = true;
-
- QE_InitVFS();
-
- Eclass_Init();
- FillClassList(); // list in entity window
- Map_Init();
-
- FillTextureMenu();
- FillBSPMenu();
-
- /*
- ** other stuff
- */
- Z_Init ();
-}
-
-void WINAPI QE_ConvertDOSToUnixName( char *dst, const char *src )
-{
- while ( *src )
- {
- if ( *src == '\\' )
- *dst = '/';
- else
- *dst = *src;
- dst++; src++;
- }
- *dst = 0;
-}
-
-int g_numbrushes, g_numentities;
-
-void QE_CountBrushesAndUpdateStatusBar( void )
-{
- static int s_lastbrushcount, s_lastentitycount;
- static qboolean s_didonce;
-
- //entity_t *e;
- brush_t *b, *next;
-
- g_numbrushes = 0;
- g_numentities = 0;
-
- if ( active_brushes.next != NULL )
- {
- for ( b = active_brushes.next ; b != NULL && b != &active_brushes ; b=next)
- {
- next = b->next;
- if (b->brush_faces )
- {
- if ( !b->owner->eclass->fixedsize)
- g_numbrushes++;
- else
- g_numentities++;
- }
- }
- }
-/*
- if ( entities.next != NULL )
- {
- for ( e = entities.next ; e != &entities && g_numentities != MAX_MAP_ENTITIES ; e = e->next)
- {
- g_numentities++;
- }
- }
-*/
- if ( ( ( g_numbrushes != s_lastbrushcount ) || ( g_numentities != s_lastentitycount ) ) || ( !s_didonce ) )
- {
- Sys_UpdateStatusBar();
-
- s_lastbrushcount = g_numbrushes;
- s_lastentitycount = g_numentities;
- s_didonce = true;
- }
-}
-
-char com_token[1024];
-qboolean com_eof;
-
-/*
-================
-I_FloatTime
-================
-*/
-double I_FloatTime (void)
-{
- time_t t;
-
- time (&t);
-
- return t;
-#if 0
-// more precise, less portable
- struct timeval tp;
- struct timezone tzp;
- static int secbase;
-
- gettimeofday(&tp, &tzp);
-
- if (!secbase)
- {
- secbase = tp.tv_sec;
- return tp.tv_usec/1000000.0;
- }
-
- return (tp.tv_sec - secbase) + tp.tv_usec/1000000.0;
-#endif
-}
-
-
-/*
-==============
-COM_Parse
-
-Parse a token out of a string
-==============
-*/
-char *COM_Parse (char *data)
-{
- int c;
- int len;
-
- len = 0;
- com_token[0] = 0;
-
- if (!data)
- return NULL;
-
-// skip whitespace
-skipwhite:
- while ( (c = *data) <= ' ')
- {
- if (c == 0)
- {
- com_eof = true;
- return NULL; // end of file;
- }
- data++;
- }
-
-// skip // comments
- if (c=='/' && data[1] == '/')
- {
- while (*data && *data != '\n')
- data++;
- goto skipwhite;
- }
-
-
-// handle quoted strings specially
- if (c == '\"')
- {
- data++;
- do
- {
- c = *data++;
- if (c=='\"')
- {
- com_token[len] = 0;
- return data;
- }
- com_token[len] = c;
- len++;
- } while (1);
- }
-
-// parse single characters
- if (c=='{' || c=='}'|| c==')'|| c=='(' || c=='\'' || c==':')
- {
- com_token[len] = c;
- len++;
- com_token[len] = 0;
- return data+1;
- }
-
-// parse a regular word
- do
- {
- com_token[len] = c;
- data++;
- len++;
- c = *data;
- if (c=='{' || c=='}'|| c==')'|| c=='(' || c=='\'' || c==':')
- break;
- } while (c>32);
-
- com_token[len] = 0;
- return data;
-}
-
-char* Get_COM_Token()
-{
- return com_token;
-}
-
-/*
-=============================================================================
-
- MISC FUNCTIONS
-
-=============================================================================
-*/
-
-
-int argc;
-char *argv[MAX_NUM_ARGVS];
-
-/*
-============
-ParseCommandLine
-============
-*/
-void ParseCommandLine (char *lpCmdLine)
-{
- argc = 1;
- argv[0] = "programname";
-
- while (*lpCmdLine && (argc < MAX_NUM_ARGVS))
- {
- while (*lpCmdLine && ((*lpCmdLine <= 32) || (*lpCmdLine > 126)))
- lpCmdLine++;
-
- if (*lpCmdLine)
- {
- argv[argc] = lpCmdLine;
- argc++;
-
- while (*lpCmdLine && ((*lpCmdLine > 32) && (*lpCmdLine <= 126)))
- lpCmdLine++;
-
- if (*lpCmdLine)
- {
- *lpCmdLine = 0;
- lpCmdLine++;
- }
-
- }
- }
-}
-
-
-
-/*
-=================
-CheckParm
-
-Checks for the given parameter in the program's command line arguments
-Returns the argument number (1 to argc-1) or 0 if not present
-=================
-*/
-int CheckParm (const char *check)
-{
- int i;
-
- for (i = 1;i<argc;i++)
- {
- if ( stricmp(check, argv[i]) )
- return i;
- }
-
- return 0;
-}
-
-
-
-
-/*
-==============
-ParseNum / ParseHex
-==============
-*/
-int ParseHex (const char *hex)
-{
- const char *str;
- int num;
-
- num = 0;
- str = hex;
-
- while (*str)
- {
- num <<= 4;
- if (*str >= '0' && *str <= '9')
- num += *str-'0';
- else if (*str >= 'a' && *str <= 'f')
- num += 10 + *str-'a';
- else if (*str >= 'A' && *str <= 'F')
- num += 10 + *str-'A';
- else
- Error ("Bad hex number: %s",hex);
- str++;
- }
-
- return num;
-}
-
-
-int ParseNum (const char *str)
-{
- if (str[0] == '$')
- return ParseHex (str+1);
- if (str[0] == '0' && str[1] == 'x')
- return ParseHex (str+2);
- return atol (str);
-}