Allow plugins to provide material interpreters.
git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@6105 fc73d0e0-1445-4013-8a0c-d673dee63da5
This commit is contained in:
parent
022e42c6c7
commit
a9a4e3c358
7 changed files with 176 additions and 60 deletions
|
@ -364,7 +364,7 @@ extern cvar_t worker_flush;
|
||||||
qboolean COM_DoWork(int thread, qboolean leavelocked);
|
qboolean COM_DoWork(int thread, qboolean leavelocked);
|
||||||
#define COM_MainThreadWork() while (COM_DoWork(0, false) && worker_flush.ival) /*called each frame to do any gl uploads or whatever*/
|
#define COM_MainThreadWork() while (COM_DoWork(0, false) && worker_flush.ival) /*called each frame to do any gl uploads or whatever*/
|
||||||
#define COM_MainThreadFlush() while (COM_DoWork(0, false)) /*make sure the main thread has done ALL work pending*/
|
#define COM_MainThreadFlush() while (COM_DoWork(0, false)) /*make sure the main thread has done ALL work pending*/
|
||||||
typedef enum
|
typedef enum wgroup_e
|
||||||
{
|
{
|
||||||
WG_MAIN = 0,
|
WG_MAIN = 0,
|
||||||
WG_LOADER = 1,
|
WG_LOADER = 1,
|
||||||
|
|
|
@ -408,6 +408,8 @@ static qboolean QDECL PlugBI_ExportInterface(const char *name, void *interfacept
|
||||||
return R_RegisterVRDriver(currentplug, interfaceptr);
|
return R_RegisterVRDriver(currentplug, interfaceptr);
|
||||||
if (!strcmp(name, plugimageloaderfuncs_name))
|
if (!strcmp(name, plugimageloaderfuncs_name))
|
||||||
return Image_RegisterLoader(currentplug, interfaceptr);
|
return Image_RegisterLoader(currentplug, interfaceptr);
|
||||||
|
if (!strcmp(name, plugmaterialloaderfuncs_name))
|
||||||
|
return Material_RegisterLoader(currentplug, interfaceptr);
|
||||||
#endif
|
#endif
|
||||||
#ifdef PACKAGEMANAGER
|
#ifdef PACKAGEMANAGER
|
||||||
if (!strcmp(name, plugupdatesourcefuncs_name))
|
if (!strcmp(name, plugupdatesourcefuncs_name))
|
||||||
|
@ -1536,6 +1538,7 @@ void Plug_Close(plugin_t *plug)
|
||||||
#ifdef HAVE_CLIENT
|
#ifdef HAVE_CLIENT
|
||||||
S_UnregisterSoundInputModule(plug);
|
S_UnregisterSoundInputModule(plug);
|
||||||
Image_RegisterLoader(plug, NULL);
|
Image_RegisterLoader(plug, NULL);
|
||||||
|
Material_RegisterLoader(plug, NULL);
|
||||||
#endif
|
#endif
|
||||||
NET_RegisterCrypto(plug, NULL);
|
NET_RegisterCrypto(plug, NULL);
|
||||||
#ifdef PACKAGEMANAGER
|
#ifdef PACKAGEMANAGER
|
||||||
|
@ -1869,6 +1872,8 @@ static void *QDECL PlugBI_GetEngineInterface(const char *interfacename, size_t s
|
||||||
COM_EnumerateFiles,
|
COM_EnumerateFiles,
|
||||||
|
|
||||||
wildcmp,
|
wildcmp,
|
||||||
|
COM_GetFileExtension,
|
||||||
|
COM_FileBase,
|
||||||
COM_CleanUpPath,
|
COM_CleanUpPath,
|
||||||
Com_BlockChecksum,
|
Com_BlockChecksum,
|
||||||
FS_LoadMallocFile,
|
FS_LoadMallocFile,
|
||||||
|
@ -2044,7 +2049,10 @@ static void *QDECL PlugBI_GetEngineInterface(const char *interfacename, size_t s
|
||||||
Sys_CreateMutex,
|
Sys_CreateMutex,
|
||||||
Sys_LockMutex,
|
Sys_LockMutex,
|
||||||
Sys_UnlockMutex,
|
Sys_UnlockMutex,
|
||||||
Sys_DestroyMutex
|
Sys_DestroyMutex,
|
||||||
|
|
||||||
|
COM_AddWork,
|
||||||
|
COM_WorkerPartialSync,
|
||||||
};
|
};
|
||||||
|
|
||||||
if (structsize == sizeof(funcs))
|
if (structsize == sizeof(funcs))
|
||||||
|
|
|
@ -149,12 +149,16 @@ qboolean Sys_ConditionSignal(void *condv); //lock first
|
||||||
qboolean Sys_ConditionBroadcast(void *condv); //lock first
|
qboolean Sys_ConditionBroadcast(void *condv); //lock first
|
||||||
void Sys_DestroyConditional(void *condv);
|
void Sys_DestroyConditional(void *condv);
|
||||||
|
|
||||||
|
enum wgroup_e;
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
void *(QDECL *CreateMutex)(void);
|
void *(QDECL *CreateMutex)(void);
|
||||||
qboolean (QDECL *LockMutex)(void *mutex);
|
qboolean (QDECL *LockMutex)(void *mutex);
|
||||||
qboolean (QDECL *UnlockMutex)(void *mutex);
|
qboolean (QDECL *UnlockMutex)(void *mutex);
|
||||||
void (QDECL *DestroyMutex)(void *mutex);
|
void (QDECL *DestroyMutex)(void *mutex);
|
||||||
|
|
||||||
|
void (*AddWork)(enum wgroup_e thread, void(*func)(void *ctx, void *data, size_t a, size_t b), void *ctx, void *data, size_t a, size_t b); //low priority
|
||||||
|
void (*WaitForCompletion)(void *priorityctx, int *address, int sleepwhilevalue);
|
||||||
#define plugthreadfuncs_name "Threading"
|
#define plugthreadfuncs_name "Threading"
|
||||||
} plugthreadfuncs_t;
|
} plugthreadfuncs_t;
|
||||||
|
|
||||||
|
|
|
@ -297,6 +297,43 @@ static qboolean Shader_LocateSource(const char *name, const char **buf, size_t *
|
||||||
static void Shader_ReadShader(parsestate_t *ps, const char *shadersource, shadercachefile_t *sourcefile);
|
static void Shader_ReadShader(parsestate_t *ps, const char *shadersource, shadercachefile_t *sourcefile);
|
||||||
static qboolean Shader_ParseShader(parsestate_t *ps, const char *parsename);
|
static qboolean Shader_ParseShader(parsestate_t *ps, const char *parsename);
|
||||||
|
|
||||||
|
|
||||||
|
static struct
|
||||||
|
{
|
||||||
|
void *module;
|
||||||
|
plugmaterialloaderfuncs_t *funcs;
|
||||||
|
} *materialloader;
|
||||||
|
static size_t materialloader_count;
|
||||||
|
qboolean Material_RegisterLoader(void *module, plugmaterialloaderfuncs_t *driver)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
if (!driver)
|
||||||
|
{
|
||||||
|
for (i = 0; i < materialloader_count; )
|
||||||
|
{
|
||||||
|
if (materialloader[i].module == module)
|
||||||
|
{
|
||||||
|
memmove(&materialloader[i], &materialloader[i+1], materialloader_count-(i+1));
|
||||||
|
materialloader_count--;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
void *n = BZ_Malloc(sizeof(*materialloader)*(materialloader_count+1));
|
||||||
|
memcpy(n, materialloader, sizeof(*materialloader)*materialloader_count);
|
||||||
|
Z_Free(materialloader);
|
||||||
|
materialloader = n;
|
||||||
|
materialloader[materialloader_count].module = module;
|
||||||
|
materialloader[materialloader_count].funcs = driver;
|
||||||
|
materialloader_count++;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//===========================================================================
|
//===========================================================================
|
||||||
|
|
||||||
static qboolean Shader_EvaluateCondition(shader_t *shader, const char **ptr)
|
static qboolean Shader_EvaluateCondition(shader_t *shader, const char **ptr)
|
||||||
|
@ -2048,13 +2085,7 @@ typedef struct sgeneric_s
|
||||||
qboolean failed;
|
qboolean failed;
|
||||||
} sgeneric_t;
|
} sgeneric_t;
|
||||||
static sgeneric_t *sgenerics;
|
static sgeneric_t *sgenerics;
|
||||||
struct sbuiltin_s
|
static struct sbuiltin_s sbuiltins[] =
|
||||||
{
|
|
||||||
int qrtype;
|
|
||||||
int apiver;
|
|
||||||
char name[MAX_QPATH];
|
|
||||||
char *body;
|
|
||||||
} sbuiltins[] =
|
|
||||||
{
|
{
|
||||||
#include "r_bishaders.h"
|
#include "r_bishaders.h"
|
||||||
{QR_NONE}
|
{QR_NONE}
|
||||||
|
@ -2155,18 +2186,29 @@ static void Shader_LoadGeneric(sgeneric_t *g, int qrtype)
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
int ver;
|
int ver;
|
||||||
for (i = 0; *sbuiltins[i].name; i++)
|
const struct sbuiltin_s *progs;
|
||||||
|
unsigned int l;
|
||||||
|
for (l = 0; l <= materialloader_count; l++)
|
||||||
{
|
{
|
||||||
if (sbuiltins[i].qrtype == qrtype && !strcmp(sbuiltins[i].name, basicname))
|
if (l == materialloader_count)
|
||||||
|
progs = sbuiltins;
|
||||||
|
else if (materialloader[l].funcs && materialloader[l].funcs->builtinshaders)
|
||||||
|
progs = materialloader[l].funcs->builtinshaders;
|
||||||
|
else
|
||||||
|
continue;
|
||||||
|
|
||||||
|
for (i = 0; *progs[i].name; i++)
|
||||||
{
|
{
|
||||||
ver = sbuiltins[i].apiver;
|
if (progs[i].qrtype == qrtype && !strcmp(progs[i].name, basicname))
|
||||||
|
{
|
||||||
|
ver = progs[i].apiver;
|
||||||
|
|
||||||
if (ver < sh_config.minver || ver > sh_config.maxver)
|
if (ver < sh_config.minver || ver > sh_config.maxver)
|
||||||
if (!(qrenderer==QR_OPENGL&&ver==110))
|
if (!(qrenderer==QR_OPENGL&&ver==110))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
TRACE(("Loading Embedded %s\n", g->name));
|
TRACE(("Loading Embedded %s\n", g->name));
|
||||||
g->failed = !Shader_LoadPermutations(g->name, &g->prog, sbuiltins[i].body, qrtype, ver, blobname);
|
g->failed = !Shader_LoadPermutations(g->name, &g->prog, progs[i].body, qrtype, ver, blobname);
|
||||||
|
|
||||||
if (g->failed)
|
if (g->failed)
|
||||||
continue;
|
continue;
|
||||||
|
@ -2174,6 +2216,7 @@ static void Shader_LoadGeneric(sgeneric_t *g, int qrtype)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
TRACE(("Program unloadable %s\n", g->name));
|
TRACE(("Program unloadable %s\n", g->name));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2489,6 +2532,17 @@ static void Shader_HLSL11ProgramName (parsestate_t *ps, const char **ptr)
|
||||||
Shader_SLProgramName(shader,pass,ptr,QR_DIRECT3D11);
|
Shader_SLProgramName(shader,pass,ptr,QR_DIRECT3D11);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void Shaderpass_BlendFunc (parsestate_t *ps, const char **ptr);
|
||||||
|
static void Shader_ProgBlendFunc (parsestate_t *ps, const char **ptr)
|
||||||
|
{
|
||||||
|
if (ps->s->prog)
|
||||||
|
{
|
||||||
|
ps->pass = ps->s->passes;
|
||||||
|
Shaderpass_BlendFunc(ps, ptr);
|
||||||
|
ps->pass = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void Shader_ReflectCube(parsestate_t *ps, const char **ptr)
|
static void Shader_ReflectCube(parsestate_t *ps, const char **ptr)
|
||||||
{
|
{
|
||||||
char *token = Shader_ParseSensString(ptr);
|
char *token = Shader_ParseSensString(ptr);
|
||||||
|
@ -2847,7 +2901,7 @@ static shaderkey_t shaderkeys[] =
|
||||||
{"glslprogram", Shader_GLSLProgramName, "fte"}, //for renderers that accept embedded glsl
|
{"glslprogram", Shader_GLSLProgramName, "fte"}, //for renderers that accept embedded glsl
|
||||||
{"hlslprogram", Shader_HLSL9ProgramName, "fte"}, //for d3d with embedded hlsl
|
{"hlslprogram", Shader_HLSL9ProgramName, "fte"}, //for d3d with embedded hlsl
|
||||||
{"hlsl11program", Shader_HLSL11ProgramName, "fte"}, //for d3d with embedded hlsl
|
{"hlsl11program", Shader_HLSL11ProgramName, "fte"}, //for d3d with embedded hlsl
|
||||||
// {"progblendfunc", Shader_ProgBlendFunc, "fte"}, //specifies the blend mode (actually just overrides the first subpasses' blendmode.
|
{"progblendfunc", Shader_ProgBlendFunc, "fte"}, //specifies the blend mode (actually just overrides the first subpasses' blendmode.
|
||||||
// {"progmap", Shader_ProgMap, "fte"}, //avoids needing extra subpasses (actually just inserts an extra pass).
|
// {"progmap", Shader_ProgMap, "fte"}, //avoids needing extra subpasses (actually just inserts an extra pass).
|
||||||
|
|
||||||
//dp compat
|
//dp compat
|
||||||
|
@ -4353,8 +4407,9 @@ static const char *Shader_Skip(const char *file, const char *shadername, const c
|
||||||
return ptr;
|
return ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void Shader_Reset(shader_t *s)
|
static void Shader_Reset(parsestate_t *ps)
|
||||||
{
|
{
|
||||||
|
shader_t *s = ps->s;
|
||||||
extern cvar_t r_refractreflect_scale;
|
extern cvar_t r_refractreflect_scale;
|
||||||
char name[MAX_QPATH];
|
char name[MAX_QPATH];
|
||||||
int id = s->id;
|
int id = s->id;
|
||||||
|
@ -4393,7 +4448,7 @@ static void Shader_Reset(shader_t *s)
|
||||||
|
|
||||||
static void Shader_Regenerate(parsestate_t *ps, const char *shortname)
|
static void Shader_Regenerate(parsestate_t *ps, const char *shortname)
|
||||||
{
|
{
|
||||||
Shader_Reset(ps->s);
|
Shader_Reset(ps);
|
||||||
|
|
||||||
if (!strcmp(shortname, "textures/common/clip") || !strcmp(shortname, "textures/common/nodraw") || !strcmp(shortname, "common/nodraw"))
|
if (!strcmp(shortname, "textures/common/clip") || !strcmp(shortname, "textures/common/nodraw") || !strcmp(shortname, "common/nodraw"))
|
||||||
Shader_DefaultScript(ps, shortname,
|
Shader_DefaultScript(ps, shortname,
|
||||||
|
@ -7279,6 +7334,12 @@ static void Shader_ReadShader(parsestate_t *ps, const char *shadersource, shader
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void Shader_LoadMaterialString(parsestate_t *ps, const char *shadertext)
|
||||||
|
{ //callback for our external material loaders.
|
||||||
|
Shader_Reset(ps);
|
||||||
|
Shader_ReadShader(ps, shadertext, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
static qboolean Shader_ParseShader(parsestate_t *ps, const char *parsename)
|
static qboolean Shader_ParseShader(parsestate_t *ps, const char *parsename)
|
||||||
{
|
{
|
||||||
size_t offset = 0, length;
|
size_t offset = 0, length;
|
||||||
|
@ -7294,8 +7355,15 @@ static qboolean Shader_ParseShader(parsestate_t *ps, const char *parsename)
|
||||||
if (!strcmp(token, ".mat") || !*token)
|
if (!strcmp(token, ".mat") || !*token)
|
||||||
{
|
{
|
||||||
char shaderfile[MAX_QPATH];
|
char shaderfile[MAX_QPATH];
|
||||||
|
size_t i;
|
||||||
if (!*token)
|
if (!*token)
|
||||||
{
|
{
|
||||||
|
for (i = 0; i < materialloader_count; i++)
|
||||||
|
{
|
||||||
|
if (materialloader[i].funcs->ReadMaterial(ps, parsename, Shader_LoadMaterialString))
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
Q_snprintfz(shaderfile, sizeof(shaderfile), "%s.mat", parsename);
|
Q_snprintfz(shaderfile, sizeof(shaderfile), "%s.mat", parsename);
|
||||||
file = COM_LoadTempMoreFile(shaderfile, &length);
|
file = COM_LoadTempMoreFile(shaderfile, &length);
|
||||||
}
|
}
|
||||||
|
@ -7303,7 +7371,7 @@ static qboolean Shader_ParseShader(parsestate_t *ps, const char *parsename)
|
||||||
file = COM_LoadTempMoreFile(parsename, &length);
|
file = COM_LoadTempMoreFile(parsename, &length);
|
||||||
if (file)
|
if (file)
|
||||||
{
|
{
|
||||||
Shader_Reset(ps->s);
|
Shader_Reset(ps);
|
||||||
token = COM_ParseExt (&file, true, false); //we need to skip over the leading {.
|
token = COM_ParseExt (&file, true, false); //we need to skip over the leading {.
|
||||||
if (*token != '{')
|
if (*token != '{')
|
||||||
token = COM_ParseExt (&file, true, false); //try again, in case we found some legacy name.
|
token = COM_ParseExt (&file, true, false); //try again, in case we found some legacy name.
|
||||||
|
@ -7331,7 +7399,7 @@ static qboolean Shader_ParseShader(parsestate_t *ps, const char *parsename)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
Shader_Reset(ps->s);
|
Shader_Reset(ps);
|
||||||
|
|
||||||
Shader_ReadShader(ps, file, sourcefile);
|
Shader_ReadShader(ps, file, sourcefile);
|
||||||
|
|
||||||
|
|
|
@ -710,6 +710,24 @@ struct shader_s
|
||||||
*/
|
*/
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct shaderparsestate_s;
|
||||||
|
struct sbuiltin_s
|
||||||
|
{
|
||||||
|
int qrtype;
|
||||||
|
int apiver;
|
||||||
|
char name[MAX_QPATH];
|
||||||
|
char *body;
|
||||||
|
};
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
const char *loadername;
|
||||||
|
qboolean (*ReadMaterial)(struct shaderparsestate_s *ps, const char *filename, void (*LoadMaterialString)(struct shaderparsestate_s *ps, const char *script));
|
||||||
|
|
||||||
|
struct sbuiltin_s *builtinshaders;
|
||||||
|
#define plugmaterialloaderfuncs_name "MaterialLoader"
|
||||||
|
} plugmaterialloaderfuncs_t;
|
||||||
|
qboolean Material_RegisterLoader(void *module, plugmaterialloaderfuncs_t *loader);
|
||||||
|
|
||||||
extern unsigned int r_numshaders;
|
extern unsigned int r_numshaders;
|
||||||
extern unsigned int r_maxshaders;
|
extern unsigned int r_maxshaders;
|
||||||
extern shader_t **r_shaders;
|
extern shader_t **r_shaders;
|
||||||
|
|
|
@ -109,7 +109,7 @@ void dumpprogblob(FILE *out, FILE *src)
|
||||||
fprintf(out, "\"");
|
fprintf(out, "\"");
|
||||||
}
|
}
|
||||||
|
|
||||||
struct shadertype_s
|
static struct shadertype_s
|
||||||
{
|
{
|
||||||
char *abrv;
|
char *abrv;
|
||||||
char *filepattern;
|
char *filepattern;
|
||||||
|
@ -126,27 +126,15 @@ struct shadertype_s
|
||||||
};
|
};
|
||||||
//tbh we should precompile the d3d shaders.
|
//tbh we should precompile the d3d shaders.
|
||||||
|
|
||||||
int main(void)
|
static void dumpprogram(FILE *c, const char *progname)
|
||||||
{
|
{
|
||||||
FILE *c, *s;
|
FILE *s;
|
||||||
char line[1024];
|
char line[1024];
|
||||||
int i, j, a;
|
int a;
|
||||||
c = fopen("../gl/r_bishaders.h", "wt");
|
printf("%25s: ", progname);
|
||||||
|
|
||||||
if (!c)
|
|
||||||
{
|
|
||||||
printf("unable to open a file\n");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
fprintf(c, "/*\nWARNING: THIS FILE IS GENERATED BY '"__FILE__"'.\nYOU SHOULD NOT EDIT THIS FILE BY HAND\n*/\n\n");
|
|
||||||
|
|
||||||
for (i = 0; *shaders[i]; i++)
|
|
||||||
{
|
|
||||||
printf("%25s: ", shaders[i]);
|
|
||||||
for (a = 0; a < sizeof(shadertype)/sizeof(shadertype[0]); a++)
|
for (a = 0; a < sizeof(shadertype)/sizeof(shadertype[0]); a++)
|
||||||
{
|
{
|
||||||
sprintf(line, shadertype[a].filepattern, shaders[i]);
|
sprintf(line, shadertype[a].filepattern, progname);
|
||||||
if (shadertype[a].apiversion == -1)
|
if (shadertype[a].apiversion == -1)
|
||||||
s = fopen(line, "rb");
|
s = fopen(line, "rb");
|
||||||
else
|
else
|
||||||
|
@ -157,7 +145,7 @@ int main(void)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
fprintf(c, "#ifdef %s\n", shadertype[a].preprocessor);
|
fprintf(c, "#ifdef %s\n", shadertype[a].preprocessor);
|
||||||
fprintf(c, "{%s, %i, \"%s\",\n", shadertype[a].rendererapi, shadertype[a].apiversion, shaders[i]);
|
fprintf(c, "{%s, %i, \"%s\",\n", shadertype[a].rendererapi, shadertype[a].apiversion, progname);
|
||||||
if (shadertype[a].apiversion == -1)
|
if (shadertype[a].apiversion == -1)
|
||||||
dumpprogblob(c,s);
|
dumpprogblob(c,s);
|
||||||
else
|
else
|
||||||
|
@ -172,6 +160,34 @@ int main(void)
|
||||||
printf("\n");
|
printf("\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int main(int argc, const char **argv)
|
||||||
|
{
|
||||||
|
FILE *c, *s;
|
||||||
|
int i, j, a;
|
||||||
|
|
||||||
|
const char *outname = ((argc>1)?argv[1]:"../gl/r_bishaders.h");
|
||||||
|
|
||||||
|
c = fopen(outname, "wt");
|
||||||
|
|
||||||
|
if (!c)
|
||||||
|
{
|
||||||
|
printf("unable to open a file\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
fprintf(c, "/*\nWARNING: THIS FILE IS GENERATED BY '"__FILE__"'.\nYOU SHOULD NOT EDIT THIS FILE BY HAND\n*/\n\n");
|
||||||
|
|
||||||
|
if (argc>2)
|
||||||
|
{ //if we're passed a file list on the commandline then just use that (generally for plugins).
|
||||||
|
for (i = 2; i < argc; i++)
|
||||||
|
dumpprogram(c, argv[i]);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{ //use our built in list.
|
||||||
|
for (i = 0; *shaders[i]; i++)
|
||||||
|
dumpprogram(c, shaders[i]);
|
||||||
|
}
|
||||||
|
|
||||||
fclose(c);
|
fclose(c);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -349,6 +349,8 @@ typedef struct //for plugins that need to read/write files...
|
||||||
|
|
||||||
//helpers
|
//helpers
|
||||||
F(int, WildCmp, (const char *wild, const char *string));
|
F(int, WildCmp, (const char *wild, const char *string));
|
||||||
|
F(const char *,GetExtension,(const char *filename, const char *ignoreext));
|
||||||
|
F(void, FileBase, (const char *in, char *out, int outlen));
|
||||||
F(void, CleanUpPath, (char *str));
|
F(void, CleanUpPath, (char *str));
|
||||||
F(unsigned int,BlockChecksum,(const void *buffer, int length)); //mostly for pack hashes.
|
F(unsigned int,BlockChecksum,(const void *buffer, int length)); //mostly for pack hashes.
|
||||||
F(qbyte*, LoadFile, (const char *fname, size_t *fsize)); //plugfuncs->Free
|
F(qbyte*, LoadFile, (const char *fname, size_t *fsize)); //plugfuncs->Free
|
||||||
|
|
Loading…
Reference in a new issue