535 lines
10 KiB
C++
535 lines
10 KiB
C++
|
// Filename:- materials.cpp
|
||
|
//
|
||
|
// (File contains stuff imported from SoFED to fill in the materials dialogue box, only applies to SOF)
|
||
|
//
|
||
|
#include "stdafx.h" // including these for what would otherwise be blank under Q3 keeps .PCHs working better.
|
||
|
#include "Radiant.h"
|
||
|
|
||
|
|
||
|
|
||
|
// Note: this file contains some stuff that's duplicated in other files (eg parse.cpp), but the code here has so
|
||
|
// many fiddly differences (and is only loaded to fill in one dialogue in the SOF compile-version of this editor
|
||
|
// that I've just kepy it all self-contained here, so it can be ripped out and disposed off later when the project
|
||
|
// is done.
|
||
|
|
||
|
|
||
|
#ifdef SOF // may as well hide entire file except for SOF mode
|
||
|
#include "materials.h"
|
||
|
#include "direct.h"
|
||
|
|
||
|
//#include "cmdlib.h"
|
||
|
//#include "scriplib.h"
|
||
|
|
||
|
|
||
|
#define BASEDIRNAME "base"
|
||
|
#define PATHSEPERATOR '/'
|
||
|
|
||
|
|
||
|
/*
|
||
|
=============================================================================
|
||
|
|
||
|
PARSING STUFF
|
||
|
|
||
|
=============================================================================
|
||
|
*/
|
||
|
|
||
|
typedef struct
|
||
|
{
|
||
|
char filename[1024];
|
||
|
char *buffer,*script_p,*end_p;
|
||
|
int line;
|
||
|
} script_t;
|
||
|
|
||
|
#define MAX_INCLUDES 8
|
||
|
script_t scriptstack[MAX_INCLUDES];
|
||
|
script_t *script;
|
||
|
int sof_scriptline;
|
||
|
|
||
|
char sof_token[MAXTOKEN];
|
||
|
qboolean endofscript;
|
||
|
qboolean tokenready; // only true if UnGetScriptToken was just called
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
// protos...
|
||
|
//
|
||
|
void AddScriptToStack (char *filename);
|
||
|
void LoadScriptFile (char *filename);
|
||
|
void ParseFromMemory (char *buffer, int size);
|
||
|
void UnGetScriptToken (void);
|
||
|
qboolean EndOfScript (qboolean crossline);
|
||
|
qboolean GetScriptToken (qboolean crossline);
|
||
|
qboolean ScriptTokenAvailable (void);
|
||
|
char *ExpandPath (char *path);
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
extern char sof_token[MAXTOKEN];
|
||
|
extern int sof_scriptline;
|
||
|
|
||
|
void StartTokenParsing (char *data);
|
||
|
qboolean GetToken (qboolean crossline);
|
||
|
void UngetToken (void);
|
||
|
qboolean TokenAvailable (void);
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
void Q_getwd (char *out)
|
||
|
{
|
||
|
#ifdef WIN32
|
||
|
_getcwd (out, 256);
|
||
|
strcat (out, "\\");
|
||
|
#else
|
||
|
getwd (out);
|
||
|
strcat (out, "/");
|
||
|
#endif
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
/*
|
||
|
|
||
|
qdir will hold the path up to the quake directory, including the slash
|
||
|
|
||
|
f:\quake\
|
||
|
/raid/quake/
|
||
|
|
||
|
gamedir will hold qdir + the game directory (id1, id2, etc)
|
||
|
|
||
|
*/
|
||
|
|
||
|
char qdir[1024];
|
||
|
char gamedir[1024];
|
||
|
|
||
|
void SetQdirFromPath (char *path)
|
||
|
{
|
||
|
char temp[1024];
|
||
|
char *c;
|
||
|
int len;
|
||
|
|
||
|
if (!(path[0] == '/' || path[0] == '\\' || path[1] == ':'))
|
||
|
{ // path is partial
|
||
|
Q_getwd (temp);
|
||
|
strcat (temp, path);
|
||
|
path = temp;
|
||
|
}
|
||
|
|
||
|
// search for "quake2" in path
|
||
|
#if 1
|
||
|
len = strlen(BASEDIRNAME);
|
||
|
|
||
|
for (c=path+strlen(path)-1 ; c != path ; c--)
|
||
|
{
|
||
|
if (!Q_strncasecmp (c, BASEDIRNAME, len))
|
||
|
{
|
||
|
strncpy (qdir, path, c-path);
|
||
|
Sys_Printf ("qdir: %s\n", qdir);
|
||
|
|
||
|
while (*c)
|
||
|
{
|
||
|
if (*c == '/' || *c == '\\')
|
||
|
{
|
||
|
strncpy (gamedir, path, c+1-path);
|
||
|
Sys_Printf ("gamedir: %s\n", gamedir);
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
c++;
|
||
|
}
|
||
|
|
||
|
// assert(0);
|
||
|
Error ("Gamedir at root in %s", path);
|
||
|
|
||
|
return;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// assert(0);
|
||
|
Error ("SetQdirFromPath: no '%s' in %s", BASEDIRNAME, path);
|
||
|
#else
|
||
|
len = strlen(BASEDIRNAME);
|
||
|
for (c=path+strlen(path)-1 ; c != path ; c--)
|
||
|
if (!Q_strncasecmp (c, BASEDIRNAME, len))
|
||
|
{
|
||
|
strncpy (qdir, path, c+len+1-path);
|
||
|
qprintf ("qdir: %s\n", qdir);
|
||
|
c += len+1;
|
||
|
while (*c)
|
||
|
{
|
||
|
if (*c == '/' || *c == '\\')
|
||
|
{
|
||
|
strncpy (gamedir, path, c+1-path);
|
||
|
qprintf ("gamedir: %s\n", gamedir);
|
||
|
return;
|
||
|
}
|
||
|
c++;
|
||
|
}
|
||
|
Error ("No gamedir in %s", path);
|
||
|
return;
|
||
|
}
|
||
|
Error ("SetQdirFromPath: no '%s' in %s", BASEDIRNAME, path);
|
||
|
#endif
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
materialtype_t defaultmaterialtypes[] =
|
||
|
{
|
||
|
{"gravel", MATERIAL_GRAVEL},
|
||
|
{"metal", MATERIAL_METAL},
|
||
|
{"stone", MATERIAL_STONE},
|
||
|
{"wood", MATERIAL_WOOD},
|
||
|
{NULL, 0}
|
||
|
};
|
||
|
|
||
|
materialtype_t *materialtypes = NULL;// defaultmaterialtypes;
|
||
|
|
||
|
void QFile_ReadMaterialTypes(char* filename)
|
||
|
{
|
||
|
int i;
|
||
|
FILE *f;
|
||
|
|
||
|
if (materialtypes != defaultmaterialtypes)
|
||
|
{
|
||
|
if (materialtypes)
|
||
|
free(materialtypes);
|
||
|
materialtypes = (materialtype_t*)malloc(256 * sizeof(materialtype_t));
|
||
|
}
|
||
|
|
||
|
f = fopen (filename, "rb");
|
||
|
if (!f)
|
||
|
{
|
||
|
materialtypes = defaultmaterialtypes;
|
||
|
return;
|
||
|
}
|
||
|
fclose (f);
|
||
|
|
||
|
LoadScriptFile(filename);
|
||
|
i = 0;
|
||
|
|
||
|
do
|
||
|
{
|
||
|
GetScriptToken (true);
|
||
|
if (endofscript)
|
||
|
{
|
||
|
break;
|
||
|
}
|
||
|
if (strcmp(sof_token, "material") != 0)
|
||
|
{
|
||
|
while (ScriptTokenAvailable())
|
||
|
{
|
||
|
GetScriptToken(false);
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
GetScriptToken(false);
|
||
|
materialtypes[i].name = (char*)malloc(strlen(sof_token) + 1);
|
||
|
strcpy(materialtypes[i].name, sof_token);
|
||
|
GetScriptToken (false);
|
||
|
materialtypes[i].value = atoi(sof_token);
|
||
|
}
|
||
|
}
|
||
|
while (i++ < 255);
|
||
|
|
||
|
materialtypes[i].name = NULL;
|
||
|
materialtypes[i].value = 0;
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
char *ExpandPath (char *path)
|
||
|
{
|
||
|
static char full[1024];
|
||
|
if (!qdir)
|
||
|
Error ("ExpandPath called without qdir set");
|
||
|
if (path[0] == '/' || path[0] == '\\' || path[1] == ':')
|
||
|
return path;
|
||
|
sprintf (full, "%s%s", qdir, path);
|
||
|
return full;
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
/*
|
||
|
==============
|
||
|
AddScriptToStack
|
||
|
==============
|
||
|
*/
|
||
|
void AddScriptToStack (char *filename)
|
||
|
{
|
||
|
int size;
|
||
|
|
||
|
script++;
|
||
|
if (script == &scriptstack[MAX_INCLUDES])
|
||
|
Error ("script file exceeded MAX_INCLUDES");
|
||
|
strcpy (script->filename, ExpandPath (filename) );
|
||
|
|
||
|
size = LoadFile (script->filename, (void **)&script->buffer);
|
||
|
|
||
|
printf ("entering %s\n", script->filename);
|
||
|
|
||
|
script->line = 1;
|
||
|
|
||
|
script->script_p = script->buffer;
|
||
|
script->end_p = script->buffer + size;
|
||
|
}
|
||
|
|
||
|
|
||
|
/*
|
||
|
==============
|
||
|
LoadScriptFile
|
||
|
==============
|
||
|
*/
|
||
|
void LoadScriptFile (char *filename)
|
||
|
{
|
||
|
script = scriptstack;
|
||
|
AddScriptToStack (filename);
|
||
|
|
||
|
endofscript = false;
|
||
|
tokenready = false;
|
||
|
}
|
||
|
|
||
|
|
||
|
/*
|
||
|
==============
|
||
|
ParseFromMemory
|
||
|
==============
|
||
|
*/
|
||
|
void ParseFromMemory (char *buffer, int size)
|
||
|
{
|
||
|
script = scriptstack;
|
||
|
script++;
|
||
|
if (script == &scriptstack[MAX_INCLUDES])
|
||
|
Error ("script file exceeded MAX_INCLUDES");
|
||
|
strcpy (script->filename, "memory buffer" );
|
||
|
|
||
|
script->buffer = buffer;
|
||
|
script->line = 1;
|
||
|
script->script_p = script->buffer;
|
||
|
script->end_p = script->buffer + size;
|
||
|
|
||
|
endofscript = false;
|
||
|
tokenready = false;
|
||
|
}
|
||
|
|
||
|
|
||
|
/*
|
||
|
==============
|
||
|
UnGetScriptToken
|
||
|
|
||
|
Signals that the current sof_token was not used, and should be reported
|
||
|
for the next GetScriptToken. Note that
|
||
|
|
||
|
GetScriptToken (true);
|
||
|
UnGetScriptToken ();
|
||
|
GetScriptToken (false);
|
||
|
|
||
|
could cross a line boundary.
|
||
|
==============
|
||
|
*/
|
||
|
void UnGetScriptToken (void)
|
||
|
{
|
||
|
tokenready = true;
|
||
|
}
|
||
|
|
||
|
|
||
|
qboolean EndOfScript (qboolean crossline)
|
||
|
{
|
||
|
if (!crossline)
|
||
|
Error ("Line %i is incomplete\n",sof_scriptline);
|
||
|
|
||
|
if (!strcmp (script->filename, "memory buffer"))
|
||
|
{
|
||
|
endofscript = true;
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
free (script->buffer);
|
||
|
if (script == scriptstack+1)
|
||
|
{
|
||
|
endofscript = true;
|
||
|
return false;
|
||
|
}
|
||
|
script--;
|
||
|
sof_scriptline = script->line;
|
||
|
printf ("returning to %s\n", script->filename);
|
||
|
return GetScriptToken (crossline);
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
==============
|
||
|
GetScriptToken
|
||
|
==============
|
||
|
*/
|
||
|
qboolean GetScriptToken (qboolean crossline)
|
||
|
{
|
||
|
char *token_p;
|
||
|
|
||
|
if (tokenready) // is a sof_token allready waiting?
|
||
|
{
|
||
|
tokenready = false;
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
if (script->script_p >= script->end_p)
|
||
|
return EndOfScript (crossline);
|
||
|
|
||
|
//
|
||
|
// skip space
|
||
|
//
|
||
|
skipspace:
|
||
|
while (*script->script_p <= 32)
|
||
|
{
|
||
|
if (script->script_p >= script->end_p)
|
||
|
return EndOfScript (crossline);
|
||
|
if (*script->script_p++ == '\n')
|
||
|
{
|
||
|
if (!crossline)
|
||
|
Error ("Line %i is incomplete\n",sof_scriptline);
|
||
|
sof_scriptline = script->line++;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (script->script_p >= script->end_p)
|
||
|
return EndOfScript (crossline);
|
||
|
|
||
|
// ; # // comments
|
||
|
if (*script->script_p == ';' || *script->script_p == '#'
|
||
|
|| ( script->script_p[0] == '/' && script->script_p[1] == '/') )
|
||
|
{
|
||
|
if (!crossline)
|
||
|
Error ("Line %i is incomplete\n",sof_scriptline);
|
||
|
while (*script->script_p++ != '\n')
|
||
|
if (script->script_p >= script->end_p)
|
||
|
return EndOfScript (crossline);
|
||
|
goto skipspace;
|
||
|
}
|
||
|
|
||
|
// /* */ comments
|
||
|
if (script->script_p[0] == '/' && script->script_p[1] == '*')
|
||
|
{
|
||
|
if (!crossline)
|
||
|
Error ("Line %i is incomplete\n",sof_scriptline);
|
||
|
script->script_p+=2;
|
||
|
while (script->script_p[0] != '*' && script->script_p[1] != '/')
|
||
|
{
|
||
|
script->script_p++;
|
||
|
if (script->script_p >= script->end_p)
|
||
|
return EndOfScript (crossline);
|
||
|
}
|
||
|
script->script_p += 2;
|
||
|
goto skipspace;
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// copy sof_token
|
||
|
//
|
||
|
token_p = sof_token;
|
||
|
|
||
|
if (*script->script_p == '"')
|
||
|
{
|
||
|
// quoted sof_token
|
||
|
script->script_p++;
|
||
|
while (*script->script_p != '"')
|
||
|
{
|
||
|
*token_p++ = *script->script_p++;
|
||
|
if (script->script_p == script->end_p)
|
||
|
break;
|
||
|
if (token_p == &sof_token[MAXTOKEN])
|
||
|
Error ("Token too large on line %i\n",sof_scriptline);
|
||
|
}
|
||
|
script->script_p++;
|
||
|
}
|
||
|
else // regular sof_token
|
||
|
while ( *script->script_p > 32 && *script->script_p != ';')
|
||
|
{
|
||
|
*token_p++ = *script->script_p++;
|
||
|
if (script->script_p == script->end_p)
|
||
|
break;
|
||
|
if (token_p == &sof_token[MAXTOKEN])
|
||
|
Error ("Token too large on line %i\n",sof_scriptline);
|
||
|
}
|
||
|
|
||
|
*token_p = 0;
|
||
|
|
||
|
if (!strcmp (sof_token, "$include"))
|
||
|
{
|
||
|
GetScriptToken (false);
|
||
|
AddScriptToStack (sof_token);
|
||
|
return GetScriptToken (crossline);
|
||
|
}
|
||
|
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
|
||
|
/*
|
||
|
==============
|
||
|
ScriptTokenAvailable
|
||
|
|
||
|
Returns true if there is another sof_token on the line
|
||
|
==============
|
||
|
*/
|
||
|
qboolean ScriptTokenAvailable (void)
|
||
|
{
|
||
|
char *search_p;
|
||
|
|
||
|
search_p = script->script_p;
|
||
|
|
||
|
if (search_p >= script->end_p)
|
||
|
return false;
|
||
|
|
||
|
while ( *search_p <= 32)
|
||
|
{
|
||
|
if (*search_p == '\n')
|
||
|
return false;
|
||
|
search_p++;
|
||
|
if (search_p == script->end_p)
|
||
|
return false;
|
||
|
|
||
|
}
|
||
|
|
||
|
if (*search_p == ';')
|
||
|
return false;
|
||
|
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
char *ExpandArg (char *path)
|
||
|
{
|
||
|
static char full[1024];
|
||
|
|
||
|
if (path[0] != '/' && path[0] != '\\' && path[1] != ':')
|
||
|
{
|
||
|
Q_getwd (full);
|
||
|
strcat (full, path);
|
||
|
}
|
||
|
else
|
||
|
strcpy (full, path);
|
||
|
return full;
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
#endif // #ifdef SOF
|
||
|
|
||
|
///////////////////// eof //////////////////////////
|
||
|
|
||
|
|
||
|
|