01 Oct 2007

This commit is contained in:
g-cont 2007-10-01 00:00:00 +04:00 committed by Alibek Omarov
parent 99c6510a87
commit cdbf0903ea
39 changed files with 1645 additions and 2049 deletions

View File

@ -13,23 +13,23 @@ SV_ClipToLinks SV_ClipMoveToEntities
Текущие задачи:
1. Создание stdlib в launch.dll (c ассертами)
2. Создание sv_utils.c - импорт для PRVM
1. Добавить поддержку текстур mip (Quake1) ОК
2. Включить все фичи нового компилера
{
vm_exec.c - добавить все расширения OK
переписать compile targets
OP_POWER_I - добавить XOR для right result
добавить новые операции в Bounds checker
}
Упорядочить функции для prvm
Подключить автонахождение смещений
добавить Info_Key\Info_Value
studioframeadvance
studiorewindframe
vm_args,
vm_argv,
vm_argc,
//==================================================
// то, что уже готово
//==================================================
+добавлена загрузка *.mip (quake1 текстуры)
+Добавлены func_areaportal
+исправлен overflow при компиляции в release
+подключена система использования gl_ext при загрузке DDS Текстур по двум критериям(наличие расширения и наличие Pow2)

View File

@ -1693,7 +1693,7 @@ fs_offset_t FS_Read (file_t* file, void* buffer, size_t buffersize)
}
ztk->zstream.next_in = &ztk->input[ztk->in_ind];
ztk->zstream.avail_in = (unsigned int)(ztk->in_len - ztk->in_ind);
ztk->zstream.avail_in = (uint)(ztk->in_len - ztk->in_ind);
// Now that we are sure we have compressed data available, we need to determine
// if it's better to inflate it in "file->buff" or directly in "buffer"

View File

@ -260,6 +260,48 @@ bool LoadLMP( char *name, char *buffer, int filesize )
return true;
}
/*
============
LoadMIP
============
*/
bool LoadMIP( char *name, char *buffer, int filesize )
{
mip_t mip;
int ofs, pixels;
if (filesize < (int)sizeof(mip))
{
MsgWarn("LoadMIP: file (%s) have invalid size\n", name );
return false;
}
Mem_Copy(&mip, buffer, sizeof(mip));
image_width = LittleLong(mip.width);
image_height = LittleLong(mip.height);
ofs = LittleLong(mip.offsets[0]);
if(!ImageValidSize( name )) return false;
image_size = image_width * image_height * 4;
pixels = image_width * image_height;
if (filesize < (int)sizeof(mip) + pixels)
{
MsgWarn("LoadMIP: file (%s) have invalid size\n", name );
return false;
}
image_rgba = (byte *)Mem_Alloc(imagepool, image_size );
image_num_layers = 1;
image_type = PF_RGBA_32;
Image_GetQ1Palette();// hardcoded
Image_Copy8bitRGBA( buffer + ofs, image_rgba, pixels );
return true;
}
/*
============
LoadPCX
@ -1478,6 +1520,7 @@ loadformat_t load_formats[] =
{"textures/%s%s.%s", "pcx", LoadPCX},
{"textures/%s%s.%s", "wal", LoadWAL},
{"textures/%s%s.%s", "lmp", LoadLMP},
{"textures/%s%s.%s", "mip", LoadMIP},
{"%s%s.%s", "dds", LoadDDS},
{"%s%s.%s", "tga", LoadTGA},
{"%s%s.%s", "jpg", LoadJPG},
@ -1485,6 +1528,7 @@ loadformat_t load_formats[] =
{"%s%s.%s", "pcx", LoadPCX},
{"%s%s.%s", "wal", LoadWAL},
{"%s%s.%s", "lmp", LoadLMP},
{"%s%s.%s", "mip", LoadMIP},
{NULL, NULL}
};

View File

@ -90,6 +90,20 @@ typedef struct lmp_s
/*
========================================================================
.MIP image format (Quake1 textures)
========================================================================
*/
typedef struct mip_s
{
char name[16];
uint width, height;
uint offsets[4]; // four mip maps stored
} mip_t;
/*
========================================================================
.TGA image format (Truevision Targa)
========================================================================

View File

@ -1545,6 +1545,7 @@ compilers_api_t Comp_GetAPI( void )
cp.BSP = CompileBSPModel;
cp.PrepareDAT = PrepareDATProgs;
cp.DAT = CompileDATProgs;
cp.DecryptDAT = PR_decode;
return cp;
}

File diff suppressed because it is too large Load Diff

View File

@ -668,27 +668,15 @@ bool PR_Precompiler(void)
}
else if (!stricmp(token, "TARGET"))
{
if (targetformat == QCF_HEXEN2 && numstatements)
PR_ParseWarning(WARN_BADTARGET, "Cannot switch from hexen2 target \'%s\'. Ignored.", msg);
else if (!stricmp(msg, "H2") || !stricmp(msg, "HEXEN2"))
{
if (numstatements)
PR_ParseWarning(WARN_BADTARGET, "Cannot switch from hexen2 target \'%s\'. Ignored.", msg);
else
targetformat = QCF_HEXEN2;
}
else if (!stricmp(msg, "KK7"))
targetformat = QCF_KK7;
else if (!stricmp(msg, "FTEDEBUG"))
targetformat = QCF_FTEDEBUG;
else if (!stricmp(msg, "FTE"))
targetformat = QCF_FTE;
else if (!stricmp(msg, "STANDARD") || !stricmp(msg, "ID"))
if (!stricmp(msg, "STANDARD"))
targetformat = QCF_STANDARD;
else if (!stricmp(msg, "ID"))
targetformat = QCF_STANDARD;
else if (!stricmp(msg, "RELEASE"))
targetformat = QCF_RELEASE;
else if (!stricmp(msg, "DEBUG"))
targetformat = QCF_FTEDEBUG;
else
PR_ParseWarning(WARN_BADTARGET, "Unknown target \'%s\'. Ignored.", msg);
targetformat = QCF_DEBUG;
else PR_ParseWarning(WARN_BADTARGET, "Unknown target \'%s\'. Ignored.", msg);
}
else if (!stricmp(token, "keyword") || !stricmp(token, "flag"))
{
@ -2552,7 +2540,7 @@ type_t *PR_ParseType (int newtype)
// int ofs;
if (PR_CheckToken ("..")) //so we don't end up with the user specifying '. .vector blah' (hexen2 added the .. token for array ranges)
if (PR_CheckToken ("..")) //so we don't end up with the user specifying '. .vector blah'
{
newt = PR_NewType("FIELD TYPE", ev_field);
newt->aux_type = PR_ParseType (false);

View File

@ -263,17 +263,23 @@ void Hash_RemoveKey(hashtable_t *table, int key)
PR_decode
================
*/
char *PR_decode(int complen, int len, int method, char *info, char *buffer)
int PR_decode(int complen, int len, int method, char *info, char **data)
{
int i;
int i;
char *buffer = *data;
if (method == 0) // copy
{
if (complen != len) Sys_Error("lengths do not match");
memcpy(buffer, info, len);
Mem_Copy(buffer, info, len);
}
else if (method == 1)// encryption
{
if (complen != len) Sys_Error("lengths do not match");
if (complen != len)
{
MsgDev(D_WARN, "lengths do not match");
return false;
}
for (i = 0; i < len; i++) buffer[i] = info[i] ^ 0xA5;
}
else if (method == 2)// compression (ZLIB)
@ -283,12 +289,19 @@ char *PR_decode(int complen, int len, int method, char *info, char *buffer)
// decompress it in one go.
if (Z_STREAM_END != inflate( &strm, Z_FINISH ))
Sys_Error("Failed block decompression\n");
{
Msg("Failed block decompression: %s\n", strm.msg );
return false;
}
inflateEnd( &strm );
Msg("inflanting %s\n", strm.msg );
}
else Sys_Error("PR_decode: Bad file encryption routine\n");
return buffer;
else
{
MsgDev(D_WARN, "PR_decode: Bad file encryption routine\n");
return false;
}
return true;
}
/*
@ -357,4 +370,21 @@ byte *PR_LoadFile(char *filename, fs_offset_t *filesizeptr, int type )
mem = FS_LoadFile( filename, filesizeptr );
return mem;
}
void PR_WriteBlock(vfile_t *handle, fs_offset_t pos, const void *data, size_t blocksize, bool compress)
{
int i, len = 0;
if (compress)
{
VFS_Write (handle, &len, sizeof(int)); // save for later
len = PR_encode(blocksize, 2, (char *)data, handle);
i = VFS_Tell(handle); // member start of block
VFS_Seek(handle, pos, SEEK_SET); // seek back
len = LittleLong(len); // block size after deflate
VFS_Write (handle, &len, sizeof(int)); // write size.
VFS_Seek(handle, i, SEEK_SET);
}
else VFS_Write (handle, data, blocksize);
}

View File

@ -60,16 +60,31 @@ TODO:
#define STRCMP(s1, s2) (((*s1)!=(*s2)) || strcmp(s1+1,s2+1))
#define STRNCMP(s1, s2, l) (((*s1)!=(*s2)) || strncmp(s1+1,s2+1,l))
#define statements16 ((dstatement16_t*) statements)
#define statements32 statements
#define qcc_globals16 ((ddef16_t*)qcc_globals)
#define qcc_globals32 qcc_globals
#define fields16 ((ddef16_t*)fields)
#define fields32 fields
#define KEYWORD(x) if(!STRCMP(name, #x) && keyword_##x) \
{ \
if (keyword_##x) \
PR_ParseWarning(WARN_KEYWORDDISABLED, "\""#x"\" keyword used as variable name%s", keywords_coexist?" - coexisting":" - disabling");\
keyword_##x=keywords_coexist; \
}
typedef uint gofs_t; // offset in global data block
typedef struct function_s function_t;
typedef char PATHSTRING[MAX_NAME];
typedef enum {
QCF_STANDARD,
QCF_HEXEN2,
QCF_FTE,
QCF_FTEDEBUG,
QCF_KK7
typedef enum
{
QCF_STANDARD, // regular quake1 progs ver. 6
QCF_RELEASE, // release extend progs ver. 7
QCF_DEBUG, // debug extended progs ver. 7
} targetformat_t;
typedef enum {
@ -190,13 +205,13 @@ typedef struct
char *name;
char *opname;
int priority;
enum
{
ASSOC_LEFT,
ASSOC_RIGHT,
ASSOC_RIGHT_RESULT
} associative;
struct type_s **type_a;
struct type_s **type_b;
struct type_s **type_c;
@ -603,9 +618,10 @@ void PR_IncludeChunk (char *data, bool duplicate, char *filename);
void PR_Warning (int type, char *file, int line, char *error, ...);
byte *PR_LoadFile(char *filename, fs_offset_t *filesizeptr, int type );
void PR_ParseErrorPrintDef (int errortype, def_t *def, char *error, ...);
char *PR_decode( int complen, int len, int method, char *info, char *buffer);
int PR_decode(int complen, int len, int method, char *info, char **buffer);
def_t *PR_GetDef (type_t *type, char *name, def_t *scope, bool allocate, int arraysize);
void PR_RemapOffsets(uint firststatement, uint laststatement, uint min, uint max, uint newmin);
void PR_WriteBlock(vfile_t *handle, fs_offset_t pos, const void *data, size_t blocksize, bool compress);
//pr_utils
bool PrepareDATProgs ( const char *dir, const char *name, byte params );

View File

@ -174,64 +174,60 @@ optimisations_t optimisations[] =
//global to store useage to, flags, codename, human-readable name, help text
compiler_flag_t compiler_flag[] = {
//keywords
{&keyword_asm, defaultkeyword, "asm", "Keyword: asm", "Disables the 'asm' keyword. Use the writeasm flag to see an example of the asm."},
{&keyword_break, defaultkeyword, "break", "Keyword: break", "Disables the 'break' keyword."},
{&keyword_case, defaultkeyword, "case", "Keyword: case", "Disables the 'case' keyword."},
{&keyword_class, defaultkeyword, "class", "Keyword: class", "Disables the 'class' keyword."},
{&keyword_const, defaultkeyword, "const", "Keyword: const", "Disables the 'const' keyword."},
{&keyword_continue, defaultkeyword, "continue", "Keyword: continue", "Disables the 'continue' keyword."},
{&keyword_default, defaultkeyword, "default", "Keyword: default", "Disables the 'default' keyword."},
{&keyword_entity, defaultkeyword, "entity", "Keyword: entity", "Disables the 'entity' keyword."},
{&keyword_enum, defaultkeyword, "enum", "Keyword: enum", "Disables the 'enum' keyword."}, //kinda like in c, but typedef not supported.
{&keyword_asm, defaultkeyword, "asm", "Keyword: asm", "Disables the 'asm' keyword. Use the writeasm flag to see an example of the asm."},
{&keyword_break, defaultkeyword, "break", "Keyword: break", "Disables the 'break' keyword."},
{&keyword_case, defaultkeyword, "case", "Keyword: case", "Disables the 'case' keyword."},
{&keyword_class, defaultkeyword, "class", "Keyword: class", "Disables the 'class' keyword."},
{&keyword_const, defaultkeyword, "const", "Keyword: const", "Disables the 'const' keyword."},
{&keyword_continue, defaultkeyword, "continue", "Keyword: continue", "Disables the 'continue' keyword."},
{&keyword_default, defaultkeyword, "default", "Keyword: default", "Disables the 'default' keyword."},
{&keyword_entity, defaultkeyword, "entity", "Keyword: entity", "Disables the 'entity' keyword."},
{&keyword_enum, defaultkeyword, "enum", "Keyword: enum", "Disables the 'enum' keyword."}, //kinda like in c, but typedef not supported.
{&keyword_enumflags, defaultkeyword, "enumflags", "Keyword: enumflags", "Disables the 'enumflags' keyword."}, //like enum, but doubles instead of adds 1.
{&keyword_extern, defaultkeyword, "extern", "Keyword: extern", "Disables the 'extern' keyword. Use only on functions inside addons."}, //function is external, don't error or warn if the body was not found
{&keyword_float, defaultkeyword, "float", "Keyword: float", "Disables the 'float' keyword. (Disables the float keyword without 'local' preceeding it)"},
{&keyword_for, defaultkeyword, "for", "Keyword: for", "Disables the 'for' keyword. Syntax: for(assignment; while; increment) {codeblock;}"},
{&keyword_goto, defaultkeyword, "goto", "Keyword: goto", "Disables the 'goto' keyword."},
{&keyword_int, defaultkeyword, "int", "Keyword: int", "Disables the 'int' keyword."},
{&keyword_integer, defaultkeyword, "integer", "Keyword: integer", "Disables the 'integer' keyword."},
{&keyword_noref, defaultkeyword, "noref", "Keyword: noref", "Disables the 'noref' keyword."}, //nowhere else references this, don't strip it.
{&keyword_nosave, defaultkeyword, "nosave", "Keyword: nosave", "Disables the 'nosave' keyword."}, //don't write the def to the output.
{&keyword_shared, defaultkeyword, "shared", "Keyword: shared", "Disables the 'shared' keyword."}, //mark global to be copied over when progs changes (part of FTE_MULTIPROGS)
{&keyword_state, nondefaultkeyword,"state", "Keyword: state", "Disables the 'state' keyword."},
{&keyword_string, defaultkeyword, "string", "Keyword: string", "Disables the 'string' keyword."},
{&keyword_struct, defaultkeyword, "struct", "Keyword: struct", "Disables the 'struct' keyword."},
{&keyword_switch, defaultkeyword, "switch", "Keyword: switch", "Disables the 'switch' keyword."},
{&keyword_thinktime, nondefaultkeyword,"thinktime", "Keyword: thinktime", "Disables the 'thinktime' keyword which is used in HexenC"},
{&keyword_typedef, defaultkeyword, "typedef", "Keyword: typedef", "Disables the 'typedef' keyword."}, //fixme
{&keyword_union, defaultkeyword, "union", "Keyword: union", "Disables the 'union' keyword."}, //you surly know what a union is!
{&keyword_var, defaultkeyword, "var", "Keyword: var", "Disables the 'var' keyword."},
{&keyword_vector, defaultkeyword, "vector", "Keyword: vector", "Disables the 'vector' keyword."},
{&keyword_extern, defaultkeyword, "extern", "Keyword: extern", "Disables the 'extern' keyword. Use only on functions inside addons."}, //function is external, don't error or warn if the body was not found
{&keyword_float, defaultkeyword, "float", "Keyword: float", "Disables the 'float' keyword. (Disables the float keyword without 'local' preceeding it)"},
{&keyword_for, defaultkeyword, "for", "Keyword: for", "Disables the 'for' keyword. Syntax: for(assignment; while; increment) {codeblock;}"},
{&keyword_goto, defaultkeyword, "goto", "Keyword: goto", "Disables the 'goto' keyword."},
{&keyword_int, defaultkeyword, "int", "Keyword: int", "Disables the 'int' keyword."},
{&keyword_integer, defaultkeyword, "integer", "Keyword: integer", "Disables the 'integer' keyword."},
{&keyword_noref, defaultkeyword, "noref", "Keyword: noref", "Disables the 'noref' keyword."}, //nowhere else references this, don't strip it.
{&keyword_nosave, defaultkeyword, "nosave", "Keyword: nosave", "Disables the 'nosave' keyword."}, //don't write the def to the output.
{&keyword_shared, defaultkeyword, "shared", "Keyword: shared", "Disables the 'shared' keyword."}, //mark global to be copied over when progs changes (part of FTE_MULTIPROGS)
{&keyword_state, nondefaultkeyword,"state", "Keyword: state", "Disables the 'state' keyword."},
{&keyword_string, defaultkeyword, "string", "Keyword: string", "Disables the 'string' keyword."},
{&keyword_struct, defaultkeyword, "struct", "Keyword: struct", "Disables the 'struct' keyword."},
{&keyword_switch, defaultkeyword, "switch", "Keyword: switch", "Disables the 'switch' keyword."},
{&keyword_thinktime, nondefaultkeyword,"thinktime","Keyword: thinktime", "Disables the 'thinktime' keyword which is used in HexenC"},
{&keyword_typedef, defaultkeyword, "typedef", "Keyword: typedef", "Disables the 'typedef' keyword."}, //fixme
{&keyword_union, defaultkeyword, "union", "Keyword: union", "Disables the 'union' keyword."}, //you surly know what a union is!
{&keyword_var, defaultkeyword, "var", "Keyword: var", "Disables the 'var' keyword."},
{&keyword_vector, defaultkeyword, "vector", "Keyword: vector", "Disables the 'vector' keyword."},
//options
{&keywords_coexist, FLAG_ASDEFAULT, "kce", "Keywords Coexist", "If you want keywords to NOT be disabled when they a variable by the same name is defined, check here."},
{&output_parms, 0, "parms", "Define offset parms", "if PARM0 PARM1 etc should be defined by the compiler. These are useful if you make use of the asm keyword for function calls, or you wish to create your own variable arguments. This is an easy way to break decompilers."}, //controls weather to define PARMx for the parms (note - this can screw over some decompilers)
{&keywords_coexist, FLAG_ASDEFAULT, "kce", "Keywords Coexist", "If you want keywords to NOT be disabled when they a variable by the same name is defined, check here."},
{&output_parms, 0, "parms", "Define offset parms", "if PARM0 PARM1 etc should be defined by the compiler. These are useful if you make use of the asm keyword for function calls, or you wish to create your own variable arguments. This is an easy way to break decompilers."}, //controls weather to define PARMx for the parms (note - this can screw over some decompilers)
{&autoprototype, 0, "autoproto", "Automatic Prototyping","Causes compilation to take two passes instead of one. The first pass, only the definitions are read. The second pass actually compiles your code. This means you never have to remember to prototype functions again."}, //so you no longer need to prototype functions and things in advance.
{&writeasm, 0, "wasm", "Dump Assembler", "Writes out a qc.asm which contains all your functions but in assembler. This is a great way to look for bugs in fteqcc, but can also be used to see exactly what your functions turn into, and thus how to optimise statements better."}, //spit out a qc.asm file, containing an assembler dump of the ENTIRE progs. (Doesn't include initialisation of constants)
{&writeasm, 0, "wasm", "Dump Assembler", "Writes out a qc.asm which contains all your functions but in assembler. This is a great way to look for bugs in fteqcc, but can also be used to see exactly what your functions turn into, and thus how to optimise statements better."}, //spit out a qc.asm file, containing an assembler dump of the ENTIRE progs. (Doesn't include initialisation of constants)
{&flag_ifstring, FLAG_MIDCOMPILE,"ifstring", "if(string) fix", "Causes if(string) to behave identically to if(string!="") This is most useful with addons of course, but also has adverse effects with FRIK_FILE's fgets, where it becomes impossible to determin the end of the file. In such a case, you can still use asm {IF string 2;RETURN} to detect eof and leave the function."}, //correction for if(string) no-ifstring to get the standard behaviour.
{&flag_laxcasts, FLAG_MIDCOMPILE,"lax", "Lax type checks", "Disables many errors (generating warnings instead) when function calls or operations refer to two normally incompatable types. This is required for reacc support, and can also allow certain (evil) mods to compile that were originally written for frikqcc."}, //Allow lax casting. This'll produce loadsa warnings of course. But allows compilation of certain dodgy code.
{&flag_laxcasts, FLAG_MIDCOMPILE,"lax", "Lax type checks", "Disables many errors (generating warnings instead) when function calls or operations refer to two normally incompatable types. This is required for reacc support, and can also allow certain (evil) mods to compile that were originally written for frikqcc."}, //Allow lax casting. This'll produce loadsa warnings of course. But allows compilation of certain dodgy code.
{&flag_hashonly, FLAG_MIDCOMPILE,"hashonly", "Hash-only constants", "Allows use of only #constant for precompiler constants, allows certain preqcc using mods to compile"},
{&opt_logicops, FLAG_MIDCOMPILE,"lo", "Logic ops", "This changes the behaviour of your code. It generates additional if operations to early-out in if statements. With this flag, the line if (0 && somefunction()) will never call the function. It can thus be considered an optimisation. However, due to the change of behaviour, it is not considered so by fteqcc. Note that due to inprecisions with floats, this flag can cause runaway loop errors within the player walk and run functions. This code is advised:\nplayer_stand1:\n if (self.velocity_x || self.velocity_y)\nplayer_run\n if (!(self.velocity_x || self.velocity_y))"},
{&opt_logicops, FLAG_MIDCOMPILE,"lo", "Logic ops", "This changes the behaviour of your code. It generates additional if operations to early-out in if statements. With this flag, the line if (0 && somefunction()) will never call the function. It can thus be considered an optimisation. However, due to the change of behaviour, it is not considered so by fteqcc. Note that due to inprecisions with floats, this flag can cause runaway loop errors within the player walk and run functions. This code is advised:\nplayer_stand1:\n if (self.velocity_x || self.velocity_y)\nplayer_run\n if (!(self.velocity_x || self.velocity_y))"},
{&flag_fasttrackarrays, FLAG_MIDCOMPILE|FLAG_ASDEFAULT,"fastarrays", "fast arrays where possible", "Generates extra instructions inside array handling functions to detect engine and use extension opcodes only in supporting engines.\nAdds a global which is set by the engine if the engine supports the extra opcodes. Note that this applies to all arrays or none."}, //correction for if(string) no-ifstring to get the standard behaviour.
{NULL}
};
struct {
struct
{
targetformat_t target;
char *name;
} targets[] = {
} targets[] =
{
{QCF_STANDARD, "standard"},
{QCF_STANDARD, "q1"},
{QCF_STANDARD, "quakec"},
{QCF_HEXEN2, "hexen2"},
{QCF_HEXEN2, "h2"},
{QCF_KK7, "kkqwsv"},
{QCF_KK7, "kk7"},
{QCF_KK7, "bigprogs"},
{QCF_KK7, "version7"},
{QCF_KK7, "kkqwsv"},
{QCF_FTE, "fte"},
{QCF_RELEASE, "release"},
{QCF_DEBUG, "debug"},
{0, NULL}
};
@ -472,18 +468,18 @@ const_t *PR_CheckCompConstDefined(char *def);
void PR_WriteData (int crc)
{
char element[MAX_NAME];
char element[MAX_NAME];
def_t *def, *comp_x, *comp_y, *comp_z;
ddef_t *dd;
dprograms_t progs;
vfile_t *h;
file_t *pr_file;
int i, num_ref, len;
bool debugtarget = false;
bool types = false;
int outputsize = 16;
int i, num_ref;
bool debugtarget = false;
bool types = false;
int outputsize = 16;
progs.blockscompressed=0;
progs.blockscompressed = 0;
if (numstatements > MAX_STATEMENTS)
Sys_Error("Too many statements - %i\nAdd \"MAX_STATEMENTS\" \"%i\" to qcc.cfg", numstatements, (numstatements+32768)&~32767);
@ -495,7 +491,6 @@ void PR_WriteData (int crc)
switch (targetformat)
{
case QCF_HEXEN2:
case QCF_STANDARD:
if (bodylessfuncs)
Msg("Warning: There are some functions without bodies.\n");
@ -505,26 +500,20 @@ void PR_WriteData (int crc)
Msg("Forcing target to FTE32 due to numpr_globals\n");
outputsize = 32;
}
else if (targetformat == QCF_HEXEN2)
{
Msg("Progs execution requires a Hexen2 compatable engine\n");
break;
}
else
{
if (numpr_globals >= 32768) //not much of a different format. Rewrite output to get it working on original executors?
Msg("An enhanced executor will be required (FTE/QF/KK)\n");
else
Msg("Progs should run on any Quake executor\n");
// not much of a different format. Rewrite output to get it working on original executors?
if (numpr_globals >= 32768)
Msg("Quake1 32bit virtual machine\nAn enhanced executor will be required\n");
else Msg("Quake1 16bit virtual machine\n");
break;
}
//intentional
targetformat = QCF_FTE;
case QCF_FTEDEBUG:
case QCF_FTE:
if (targetformat == QCF_FTEDEBUG)
// intentional falltrough
targetformat = QCF_RELEASE;
case QCF_DEBUG:
case QCF_RELEASE:
if (targetformat == QCF_DEBUG)
debugtarget = true;
if (numpr_globals > 65530)
{
Msg("Using 32 bit target due to numpr_globals\n");
@ -532,37 +521,31 @@ void PR_WriteData (int crc)
}
//compression of blocks?
if (compressoutput) progs.blockscompressed |=1; //statements
if (compressoutput) progs.blockscompressed |=2; //defs
if (compressoutput) progs.blockscompressed |=4; //fields
if (compressoutput) progs.blockscompressed |=8; //functions
if (compressoutput) progs.blockscompressed |=16; //strings
if (compressoutput) progs.blockscompressed |=32; //globals
if (compressoutput) progs.blockscompressed |=64; //line numbers
if (compressoutput) progs.blockscompressed |=128; //types
//include a type block?
types = debugtarget;//!!PR_CheckCompConstDefined("TYPES"); //useful for debugging and saving (maybe, anyway...).
if (compressoutput)
{
progs.blockscompressed |= COMP_STATEMENTS;
progs.blockscompressed |= COMP_DEFS;
progs.blockscompressed |= COMP_FIELDS;
progs.blockscompressed |= COMP_FUNCTIONS;
progs.blockscompressed |= COMP_STRINGS;
progs.blockscompressed |= COMP_GLOBALS;
progs.blockscompressed |= COMP_LINENUMS;
progs.blockscompressed |= COMP_TYPES;
}
Msg("An FTE executor will be required\n");
break;
case QCF_KK7:
if (bodylessfuncs)
Msg("Warning: There are some functions without bodies.\n");
if (numpr_globals > 65530)
Msg("Warning: Saving is not supported. Ensure all engine read fields and globals are defined early on.\n");
Msg("A KK compatable executor will be required (FTE/KK)\n");
types = debugtarget; // include a type block?
Msg("Xash3D virtual machine\n");
break;
}
//part of how compilation works. This def is always present, and never used.
// part of how compilation works. This def is always present, and never used.
def = PR_GetDef(NULL, "end_sys_globals", NULL, false, 0);
if (def) def->references++;
if(def) def->references++;
def = PR_GetDef(NULL, "end_sys_fields", NULL, false, 0);
if (def) def->references++;
if(def) def->references++;
for (def = pr.def_head.next ; def ; def = def->next)
for (def = pr.def_head.next; def; def = def->next)
{
if (def->type->type == ev_vector || (def->type->type == ev_field && def->type->aux_type->type == ev_vector))
{
@ -583,15 +566,11 @@ void PR_WriteData (int crc)
if (!def->references)
{
if (!comp_x->references || !comp_y->references || !comp_z->references)
{
//one of these vars is useless...
num_ref = 0;
}
if (!comp_x->references || !comp_y->references || !comp_z->references)
num_ref = 0; // one of these vars is useless...
}
def->references = num_ref;
if (!num_ref) num_ref = 1;
if (comp_x) comp_x->references = num_ref;
if (comp_y) comp_y->references = num_ref;
@ -607,7 +586,6 @@ void PR_WriteData (int crc)
continue;
}
}
if (def->type->type == ev_function)
{
if (opt_function_names && functions[G_FUNCTION(def->ofs)].first_statement<0)
@ -619,20 +597,17 @@ void PR_WriteData (int crc)
{
if (def->references <= 1)
PR_Warning(WARN_DEADCODE, strings + def->s_file, def->s_line, "%s is never directly called or referenced (spawn function or dead code)", def->name);
// else
// PR_Warning(WARN_DEADCODE, strings + def->s_file, def->s_line, "%s is never directly called", def->name);
}
if (opt_stripfunctions && def->timescalled >= def->references-1) //make sure it's not copied into a different var.
{ //if it ever does self.think then it could be needed for saves.
optres_stripfunctions++; //if it's only ever called explicitly, the engine doesn't need to know.
if (opt_stripfunctions && def->timescalled >= def->references-1)
{
// make sure it's not copied into a different var.
// if it ever does self.think then it could be needed for saves.
// if it's only ever called explicitly, the engine doesn't need to know.
optres_stripfunctions++;
continue;
}
// df = &functions[numfunctions];
// numfunctions++;
}
else if (def->type->type == ev_field)// && !def->constant)
else if (def->type->type == ev_field)
{
dd = &fields[numfielddefs];
numfielddefs++;
@ -646,42 +621,35 @@ void PR_WriteData (int crc)
{
if (def->type->type == ev_string)
optres_constant_names_strings += strlen(def->name);
else
optres_constant_names += strlen(def->name);
else optres_constant_names += strlen(def->name);
continue;
}
}
// if (!def->saved && def->type->type != ev_string)
// continue;
dd = &qcc_globals[numglobaldefs];
numglobaldefs++;
if (types)
dd->type = def->type-qcc_typeinfo;
else
dd->type = def->type->type;
if (types) dd->type = def->type-qcc_typeinfo;
else dd->type = def->type->type;
if ( def->saved && ((!def->initialized || def->type->type == ev_function) && def->type->type != ev_field && def->scope == NULL))
dd->type |= DEF_SAVEGLOBAL;
if (def->shared)
dd->type |= DEF_SHARED;
if (def->shared) dd->type |= DEF_SHARED;
if (opt_locals && (def->scope || !strcmp(def->name, "IMMEDIATE")))
{
dd->s_name = 0;
optres_locals += strlen(def->name);
}
else
dd->s_name = PR_CopyString (def->name);
else dd->s_name = PR_CopyString (def->name);
dd->ofs = def->ofs;
}
if (numglobaldefs > MAX_GLOBALS)
Sys_Error("Too many globals - %i\nAdd \"MAX_GLOBALS\" \"%i\" to qcc.cfg", numglobaldefs, (numglobaldefs+32768)&~32767);
strofs = (strofs+3)&~3;
strofs = (strofs + 3) & ~3;
Msg ("%6i strofs (of %i)\n", strofs, MAX_STRINGS);
Msg ("%6i numstatements (of %i)\n", numstatements, MAX_STATEMENTS);
@ -690,7 +658,7 @@ void PR_WriteData (int crc)
Msg ("%6i numfielddefs (%i unique) (of %i)\n", numfielddefs, pr.size_fields, MAX_FIELDS);
Msg ("%6i numpr_globals (of %i)\n", numpr_globals, MAX_REGS);
if (!*destfile) strcpy(destfile, "progs.dat");
if(!*destfile) strcpy(destfile, "progs.dat");
Msg("Writing %s\n", destfile);
pr_file = FS_Open( destfile, "wb" );
@ -698,11 +666,12 @@ void PR_WriteData (int crc)
VFS_Write (h, &progs, sizeof(progs));
VFS_Write (h, "\r\n\r\n", 4);
VFS_Write (h, v_copyright, strlen(v_copyright)+1);
VFS_Write (h, v_copyright, strlen(v_copyright) + 1);
VFS_Write (h, "\r\n\r\n", 4);
while(VFS_Tell(h) & 3)//this is a lame way to do it
while(VFS_Tell(h) & 3)
{
// this is a lame way to do it
VFS_Seek (h, 0, SEEK_CUR);
VFS_Write (h, "\0", 1);
}
@ -710,247 +679,127 @@ void PR_WriteData (int crc)
progs.ofs_strings = VFS_Tell(h);
progs.numstrings = strofs;
if (progs.blockscompressed&16)
{
VFS_Write (h, &len, sizeof(int)); //save for later
len = PR_encode(strofs*sizeof(char), 2, (char *)strings, h); //write
i = VFS_Tell(h);
VFS_Seek(h, progs.ofs_strings, SEEK_SET);//seek back
len = LittleLong(len);
VFS_Write (h, &len, sizeof(int)); //write size.
VFS_Seek(h, i, SEEK_SET);
}
else
VFS_Write (h, strings, strofs);
PR_WriteBlock(h, progs.ofs_strings, strings, strofs, progs.blockscompressed & COMP_STRINGS);
progs.ofs_statements = VFS_Tell(h);
progs.numstatements = numstatements;
if (targetformat == QCF_HEXEN2)
{
for (i=0 ; i<numstatements ; i++)
{
if (statements[i].op >= OP_CALL1 && statements[i].op <= OP_CALL8)
Sys_Error("Target switching produced incompatable instructions");
else if (statements[i].op >= OP_CALL1H && statements[i].op <= OP_CALL8H)
statements[i].op = statements[i].op - OP_CALL1H + OP_CALL1;
}
}
for (i = 0; i < numstatements; i++)
for (i=0 ; i<numstatements ; i++)
switch(targetformat == QCF_KK7?32:outputsize) //KK7 sucks.
switch(outputsize)
{
case 32:
for (i=0 ; i<numstatements ; i++)
for (i = 0; i < numstatements; i++)
{
statements[i].op = LittleLong/*LittleShort*/(statements[i].op);
statements[i].a = LittleLong/*LittleShort*/(statements[i].a);
statements[i].b = LittleLong/*LittleShort*/(statements[i].b);
statements[i].c = LittleLong/*LittleShort*/(statements[i].c);
statements32[i].op = LittleLong(statements32[i].op);
statements32[i].a = LittleLong(statements32[i].a);
statements32[i].b = LittleLong(statements32[i].b);
statements32[i].c = LittleLong(statements32[i].c);
}
if (progs.blockscompressed&1)
{
VFS_Write (h, &len, sizeof(int)); //save for later
len = PR_encode(numstatements*sizeof(dstatement32_t), 2, (char *)statements, h); //write
i = VFS_Tell(h);
VFS_Seek(h, progs.ofs_statements, SEEK_SET);//seek back
len = LittleLong(len);
VFS_Write (h, &len, sizeof(int)); //write size.
VFS_Seek(h, i, SEEK_SET);
}
else
VFS_Write (h, statements, numstatements*sizeof(dstatement32_t));
PR_WriteBlock(h, progs.ofs_statements, statements32, progs.numstatements*sizeof(dstatement32_t), progs.blockscompressed & COMP_STATEMENTS);
break;
case 16:
#define statements16 ((dstatement16_t*) statements)
for (i=0 ; i<numstatements ; i++) //resize as we go - scaling down
{
statements16[i].op = LittleShort((unsigned short)statements[i].op);
if (statements[i].a < 0)
statements16[i].a = LittleShort((short)statements[i].a);
else
statements16[i].a = (unsigned short)LittleShort((unsigned short)statements[i].a);
if (statements[i].b < 0)
statements16[i].b = LittleShort((short)statements[i].b);
else
statements16[i].b = (unsigned short)LittleShort((unsigned short)statements[i].b);
if (statements[i].c < 0)
statements16[i].c = LittleShort((short)statements[i].c);
else
statements16[i].c = (unsigned short)LittleShort((unsigned short)statements[i].c);
}
if (progs.blockscompressed&1)
{
VFS_Write (h, &len, sizeof(int)); //save for later
len = PR_encode(numstatements*sizeof(dstatement16_t), 2, (char *)statements16, h); //write
i = VFS_Tell(h);
VFS_Seek(h, progs.ofs_statements, SEEK_SET);//seek back
len = LittleLong(len);
VFS_Write (h, &len, sizeof(int)); //write size.
VFS_Seek(h, i, SEEK_SET);
}
else
VFS_Write (h, statements16, numstatements*sizeof(dstatement16_t));
break;
default:
Sys_Error("intsize error");
for (i = 0; i < numstatements; i++) // resize as we go - scaling down
{
statements16[i].op = LittleShort((word)statements32[i].op);
if (statements32[i].a < 0) statements16[i].a = LittleShort((short)statements32[i].a);
else statements16[i].a = (word)LittleShort((word)statements32[i].a);
if (statements32[i].b < 0) statements16[i].b = LittleShort((short)statements32[i].b);
else statements16[i].b = (word)LittleShort((word)statements32[i].b);
if (statements32[i].c < 0) statements16[i].c = LittleShort((short)statements32[i].c);
else statements16[i].c = (word)LittleShort((word)statements32[i].c);
}
PR_WriteBlock(h, progs.ofs_statements, statements16, progs.numstatements*sizeof(dstatement16_t), progs.blockscompressed & COMP_STATEMENTS);
break;
}
progs.ofs_functions = VFS_Tell(h);
progs.numfunctions = numfunctions;
for (i=0 ; i<numfunctions ; i++)
for (i = 0; i < numfunctions; i++)
{
functions[i].first_statement = LittleLong (functions[i].first_statement);
functions[i].parm_start = LittleLong (functions[i].parm_start);
functions[i].s_name = LittleLong (functions[i].s_name);
functions[i].s_file = LittleLong (functions[i].s_file);
functions[i].numparms = LittleLong ((functions[i].numparms>MAX_PARMS)?MAX_PARMS:functions[i].numparms);
functions[i].numparms = LittleLong ((functions[i].numparms > MAX_PARMS) ? MAX_PARMS : functions[i].numparms);
functions[i].locals = LittleLong (functions[i].locals);
}
if (progs.blockscompressed&8)
{
VFS_Write (h, &len, sizeof(int)); //save for later
len = PR_encode(numfunctions*sizeof(dfunction_t), 2, (char *)functions, h); //write
i = VFS_Tell(h);
VFS_Seek(h, progs.ofs_functions, SEEK_SET);//seek back
len = LittleLong(len);
VFS_Write (h, &len, sizeof(int)); //write size.
VFS_Seek(h, i, SEEK_SET);
}
else
VFS_Write (h, functions, numfunctions*sizeof(dfunction_t));
PR_WriteBlock(h, progs.ofs_functions, functions, progs.numfunctions*sizeof(dfunction_t), progs.blockscompressed & COMP_FUNCTIONS);
switch(outputsize)
{
case 32:
progs.ofs_globaldefs = VFS_Tell(h);
progs.numglobaldefs = numglobaldefs;
for (i=0 ; i<numglobaldefs ; i++)
for (i = 0; i < numglobaldefs; i++)
{
qcc_globals[i].type = LittleLong/*LittleShort*/ (qcc_globals[i].type);
qcc_globals[i].ofs = LittleLong/*LittleShort*/ (qcc_globals[i].ofs);
qcc_globals[i].s_name = LittleLong (qcc_globals[i].s_name);
qcc_globals32[i].type = LittleLong(qcc_globals32[i].type);
qcc_globals32[i].ofs = LittleLong(qcc_globals32[i].ofs);
qcc_globals32[i].s_name = LittleLong(qcc_globals32[i].s_name);
}
if (progs.blockscompressed&2)
{
VFS_Write (h, &len, sizeof(int)); //save for later
len = PR_encode(numglobaldefs*sizeof(ddef_t), 2, (char *)qcc_globals, h); //write
i = VFS_Tell(h);
VFS_Seek(h, progs.ofs_globaldefs, SEEK_SET);//seek back
len = LittleLong(len);
VFS_Write (h, &len, sizeof(int)); //write size.
VFS_Seek(h, i, SEEK_SET);
}
else
VFS_Write (h, qcc_globals, numglobaldefs*sizeof(ddef_t));
PR_WriteBlock(h, progs.ofs_globaldefs, qcc_globals32, progs.numglobaldefs*sizeof(ddef32_t), progs.blockscompressed & COMP_DEFS);
progs.ofs_fielddefs = VFS_Tell(h);
progs.numfielddefs = numfielddefs;
for (i=0 ; i<numfielddefs ; i++)
for (i = 0; i < numfielddefs; i++)
{
fields[i].type = LittleLong/*LittleShort*/ (fields[i].type);
fields[i].ofs = LittleLong/*LittleShort*/ (fields[i].ofs);
fields[i].s_name = LittleLong (fields[i].s_name);
fields32[i].type = LittleLong(fields32[i].type);
fields32[i].ofs = LittleLong(fields32[i].ofs);
fields32[i].s_name = LittleLong(fields32[i].s_name);
}
if (progs.blockscompressed&4)
{
VFS_Write (h, &len, sizeof(int)); //save for later
len = PR_encode(numfielddefs*sizeof(ddef_t), 2, (char *)fields, h); //write
i = VFS_Tell(h);
VFS_Seek(h, progs.ofs_fielddefs, SEEK_SET);//seek back
len = LittleLong(len);
VFS_Write (h, &len, sizeof(int)); //write size.
VFS_Seek(h, i, SEEK_SET);
}
else
VFS_Write (h, fields, numfielddefs*sizeof(ddef_t));
PR_WriteBlock(h, progs.ofs_fielddefs, fields32, progs.numfielddefs*sizeof(ddef32_t), progs.blockscompressed & COMP_FIELDS);
break;
case 16:
#define qcc_globals16 ((ddef16_t*)qcc_globals)
#define fields16 ((ddef16_t*)fields)
default:
progs.ofs_globaldefs = VFS_Tell(h);
progs.numglobaldefs = numglobaldefs;
for (i=0 ; i<numglobaldefs ; i++)
for (i = 0; i < numglobaldefs; i++)
{
qcc_globals16[i].type = (unsigned short)LittleShort ((unsigned short)qcc_globals[i].type);
qcc_globals16[i].ofs = (unsigned short)LittleShort ((unsigned short)qcc_globals[i].ofs);
qcc_globals16[i].s_name = LittleLong (qcc_globals[i].s_name);
qcc_globals16[i].type = (word)LittleShort ((word)qcc_globals32[i].type);
qcc_globals16[i].ofs = (word)LittleShort ((word)qcc_globals32[i].ofs);
qcc_globals16[i].s_name = LittleLong(qcc_globals32[i].s_name);
}
if (progs.blockscompressed&2)
{
VFS_Write (h, &len, sizeof(int)); //save for later
len = PR_encode(numglobaldefs*sizeof(ddef16_t), 2, (char *)qcc_globals16, h); //write
i = VFS_Tell(h);
VFS_Seek(h, progs.ofs_globaldefs, SEEK_SET);//seek back
len = LittleLong(len);
VFS_Write (h, &len, sizeof(int)); //write size.
VFS_Seek(h, i, SEEK_SET);
}
else
VFS_Write (h, qcc_globals16, numglobaldefs*sizeof(ddef16_t));
PR_WriteBlock(h, progs.ofs_globaldefs, qcc_globals16, progs.numglobaldefs*sizeof(ddef16_t), progs.blockscompressed & COMP_DEFS);
progs.ofs_fielddefs = VFS_Tell(h);
progs.numfielddefs = numfielddefs;
for (i=0 ; i<numfielddefs ; i++)
for (i = 0; i < numfielddefs; i++)
{
fields16[i].type = (unsigned short)LittleShort ((unsigned short)fields[i].type);
fields16[i].ofs = (unsigned short)LittleShort ((unsigned short)fields[i].ofs);
fields16[i].s_name = LittleLong (fields[i].s_name);
fields16[i].type = (word)LittleShort ((word)fields32[i].type);
fields16[i].ofs = (word)LittleShort ((word)fields32[i].ofs);
fields16[i].s_name = LittleLong (fields32[i].s_name);
}
if (progs.blockscompressed&4)
{
VFS_Write (h, &len, sizeof(int)); //save for later
len = PR_encode(numfielddefs*sizeof(ddef16_t), 2, (char *)fields16, h); //write
i = VFS_Tell(h);
VFS_Seek(h, progs.ofs_fielddefs, SEEK_SET);//seek back
len = LittleLong(len);
VFS_Write (h, &len, sizeof(int)); //write size.
VFS_Seek(h, i, SEEK_SET);
}
else
VFS_Write (h, fields16, numfielddefs*sizeof(ddef16_t));
PR_WriteBlock(h, progs.ofs_fielddefs, fields16, progs.numfielddefs*sizeof(ddef16_t), progs.blockscompressed & COMP_FIELDS);
break;
default:
Sys_Error("intsize error");
}
progs.ofs_globals = VFS_Tell(h);
progs.numglobals = numpr_globals;
for (i=0 ; (unsigned)i<numpr_globals ; i++)
((int *)pr_globals)[i] = LittleLong (((int *)pr_globals)[i]);
for (i = 0; (uint) i < numpr_globals; i++) ((int *)pr_globals)[i] = LittleLong (((int *)pr_globals)[i]);
if (progs.blockscompressed&32)
{
VFS_Write (h, &len, sizeof(int)); //save for later
len = PR_encode(numpr_globals*4, 2, (char *)pr_globals, h); //write
i = VFS_Tell(h);
VFS_Seek(h, progs.ofs_globals, SEEK_SET);//seek back
len = LittleLong(len);
VFS_Write (h, &len, sizeof(int)); //write size.
VFS_Seek(h, i, SEEK_SET);
}
else
VFS_Write (h, pr_globals, numpr_globals*4);
PR_WriteBlock(h, progs.ofs_globals, pr_globals, numpr_globals*4, progs.blockscompressed & COMP_GLOBALS);
if (types)
for (i=0 ; i<numtypeinfos ; i++)
if(types)
{
if (qcc_typeinfo[i].aux_type)
qcc_typeinfo[i].aux_type = (type_t*)(qcc_typeinfo[i].aux_type - qcc_typeinfo);
if (qcc_typeinfo[i].next)
qcc_typeinfo[i].next = (type_t*)(qcc_typeinfo[i].next - qcc_typeinfo);
qcc_typeinfo[i].name = (char *)PR_CopyDupBackString(qcc_typeinfo[i].name);
for (i = 0; i < numtypeinfos; i++)
{
if (qcc_typeinfo[i].aux_type)
qcc_typeinfo[i].aux_type = (type_t*)(qcc_typeinfo[i].aux_type - qcc_typeinfo);
if (qcc_typeinfo[i].next)
qcc_typeinfo[i].next = (type_t*)(qcc_typeinfo[i].next - qcc_typeinfo);
qcc_typeinfo[i].name = (char *)PR_CopyDupBackString(qcc_typeinfo[i].name);
}
}
progs.ofsfiles = 0;
@ -963,19 +812,15 @@ void PR_WriteData (int crc)
switch(targetformat)
{
case QCF_KK7:
progs.version = PROG_EXTENDEDVERSION;
break;
case QCF_STANDARD:
case QCF_HEXEN2: //urgh
progs.version = VPROGS_VERSION;
progs.version = QPROGS_VERSION; // QuakeC engine v 1.08
break;
case QCF_FTE:
case QCF_FTEDEBUG:
progs.version = PROG_EXTENDEDVERSION;
case QCF_DEBUG:
case QCF_RELEASE:
progs.version = VPROGS_VERSION;
if (outputsize == 16) progs.header = VPROGSHEADER16;
if (outputsize == 32) progs.header = VPROGSHEADER32;
else progs.header = VPROGSHEADER16;
progs.ofsbodylessfuncs = VFS_Tell(h);
progs.numbodylessfuncs = WriteBodylessFuncs(h);
@ -983,61 +828,37 @@ void PR_WriteData (int crc)
if (debugtarget)
{
progs.ofslinenums = VFS_Tell(h);
if (progs.blockscompressed&64)
{
VFS_Write (h, &len, sizeof(int)); //save for later
len = PR_encode(numstatements*sizeof(int), 2, (char *)statement_linenums, h); //write
i = VFS_Tell(h);
VFS_Seek(h, progs.ofslinenums, SEEK_SET);//seek back
len = LittleLong(len);
VFS_Write (h, &len, sizeof(int)); //write size.
VFS_Seek(h, i, SEEK_SET);
}
else VFS_Write (h, statement_linenums, numstatements * sizeof(int));
PR_WriteBlock(h, progs.ofslinenums, statement_linenums, numstatements*sizeof(int), progs.blockscompressed & COMP_LINENUMS);
}
else progs.ofslinenums = 0;
if (types)
{
progs.ofs_types = VFS_Tell(h);
if (progs.blockscompressed & 128)
{
VFS_Write (h, &len, sizeof(int)); //save for later
len = PR_encode(sizeof(type_t)*numtypeinfos, 2, (char *)qcc_typeinfo, h); //write
i = VFS_Tell(h);
VFS_Seek(h, progs.ofs_types, SEEK_SET);//seek back#
len = LittleLong(len);
VFS_Write (h, &len, sizeof(int)); //write size.
VFS_Seek(h, i, SEEK_SET);
}
else
VFS_Write (h, qcc_typeinfo, sizeof(type_t)*numtypeinfos);
progs.numtypes = numtypeinfos;
progs.numtypes = numtypeinfos;
PR_WriteBlock(h, progs.ofs_types, qcc_typeinfo, progs.numtypes*sizeof(type_t), progs.blockscompressed & COMP_TYPES);
}
else
{
progs.ofs_types = 0;
progs.numtypes = 0;
}
progs.ofsfiles = WriteSourceFiles(h, &progs, debugtarget);
break;
}
Msg ("%6i TOTAL SIZE\n", VFS_Tell(h));
progs.entityfields = pr.size_fields;
progs.crc = crc;
// byte swap the header and write it out
for (i=0 ; i<sizeof(progs)/4 ; i++)
((int *)&progs)[i] = LittleLong ( ((int *)&progs)[i] );
for (i = 0; i < sizeof(progs)/4; i++) ((int *)&progs)[i] = LittleLong (((int *)&progs)[i]);
VFS_Seek (h, 0, SEEK_SET);
VFS_Write (h, &progs, sizeof(progs));
VFS_Close (h);
VFS_Close (h); // write real file into disk
}
@ -1437,7 +1258,7 @@ int PR_FinishCompilation (void)
#define CRC_INIT_VALUE 0xffff
#define CRC_XOR_VALUE 0x0000
static unsigned short PR_crctable[256] =
static word PR_crctable[256] =
{
0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50a5, 0x60c6, 0x70e7,
0x8108, 0x9129, 0xa14a, 0xb16b, 0xc18c, 0xd1ad, 0xe1ce, 0xf1ef,
@ -1473,17 +1294,17 @@ static unsigned short PR_crctable[256] =
0x6e17, 0x7e36, 0x4e55, 0x5e74, 0x2e93, 0x3eb2, 0x0ed1, 0x1ef0
};
void PR_CRC_Init(unsigned short *crcvalue)
void PR_CRC_Init(word *crcvalue)
{
*crcvalue = CRC_INIT_VALUE;
}
void PR_CRC_ProcessByte(unsigned short *crcvalue, byte data)
void PR_CRC_ProcessByte(word *crcvalue, byte data)
{
*crcvalue = (*crcvalue << 8) ^ PR_crctable[(*crcvalue >> 8) ^ data];
}
unsigned short PR_CRC_Value(unsigned short crcvalue)
word PR_CRC_Value(word crcvalue)
{
return crcvalue ^ CRC_XOR_VALUE;
}
@ -1492,7 +1313,7 @@ unsigned short PR_CRC_Value(unsigned short crcvalue)
#define PROGDEFS_MAX_SIZE 16384
//write (to file buf) and add to the crc
void __inline Add(char *p, unsigned short *crc, char *file)
void __inline Add(char *p, word *crc, char *file)
{
char *s;
int i = strlen(file);
@ -1508,7 +1329,7 @@ void __inline Add(char *p, unsigned short *crc, char *file)
#define ADD(p) Add(p, &crc, file)
//#define ADD(p) {char *s;int i = strlen(p);for(s=p;*s;s++,i++){PR_CRC_ProcessByte(&crc, *s);file[i] = *s;}file[i]='\0';}
void __inline Add3(char *p, unsigned short *crc, char *file)
void __inline Add3(char *p, word *crc, char *file)
{
char *s;
for(s=p;*s;s++)
@ -1516,14 +1337,14 @@ void __inline Add3(char *p, unsigned short *crc, char *file)
}
#define ADD3(p) Add3(p, &crc, file)
unsigned short PR_WriteProgdefs (char *filename)
word PR_WriteProgdefs (char *filename)
{
extern int ForcedCRC;
#define ADD2(p) strncat(file, p, PROGDEFS_MAX_SIZE-1 - strlen(file)) //no crc (later changes)
char file[PROGDEFS_MAX_SIZE];
def_t *d;
int f;
unsigned short crc;
word crc;
// int c;
file[0] = '\0';
@ -1532,10 +1353,7 @@ unsigned short PR_WriteProgdefs (char *filename)
// print global vars until the first field is defined
ADD("\n/* ");
if (targetformat == QCF_HEXEN2)
ADD3("generated by hcc, do not modify");
else
ADD3("file generated by qcc, do not modify");
ADD3("file generated by qcc, do not modify");
ADD2("File generated by FTEQCC, relevent for engine modding only, the generated crc must be the same as your engine expects.");
ADD(" */\n\ntypedef struct");
ADD2(" globalvars_s");
@ -2047,7 +1865,7 @@ void PR_SetDefaultProperties (void)
if (FS_CheckParm("/Oz"))
{
targetformat = QCF_FTE;
targetformat = QCF_RELEASE;
PR_DefineName("OP_COMP_STATEMENTS");
PR_DefineName("OP_COMP_DEFS");
PR_DefineName("OP_COMP_FIELDS");
@ -2111,10 +1929,6 @@ void PR_SetDefaultProperties (void)
//Check the command line
PR_CommandLinePrecompilerOptions();
if (targetformat == QCF_HEXEN2) //force on the thinktime keyword if hexen2 progs.
keyword_thinktime = true;
if (FS_CheckParm("-debug")) //disable any debug optimisations
{
for (i = 0; optimisations[i].enabled; i++)

View File

@ -23,7 +23,7 @@ if errorlevel 1 set BUILD_ERROR=1
%MSDEV% render/render.dsp %CONFIG%"render - Win32 Debug" %build_target%
if errorlevel 1 set BUILD_ERROR=1
qcclib.exe -src vprogs -progdefs
qcclib.exe -src vprogs -progdefs -log /Oz
if errorlevel 1 set BUILD_ERROR=1
if "%BUILD_ERROR%"=="" goto build_ok

View File

@ -47,7 +47,6 @@ typedef union prvm_eval_s
int _int;
float _float;
float vector[3];
int ivector[3];
func_t function;
string_t string;
} prvm_eval_t;
@ -87,14 +86,14 @@ struct edict_s
};
#define PRVM_GETEDICTFIELDVALUE(ed, fieldoffset) (fieldoffset ? (prvm_eval_t *)((unsigned char *)ed->progs.vp + fieldoffset) : NULL)
#define PRVM_GETGLOBALFIELDVALUE(fieldoffset) (fieldoffset ? (prvm_eval_t *)((unsigned char *)prog->globals.generic + fieldoffset) : NULL)
#define PRVM_GETGLOBALFIELDVALUE(fieldoffset) (fieldoffset ? (prvm_eval_t *)((unsigned char *)prog->globals.gp + fieldoffset) : NULL)
#define PRVM_FE_CLASSNAME 8
#define PRVM_FE_CHAIN 4
#define PRVM_OP_STATE 1
#define PRVM_MAX_STACK_DEPTH 1024
#define PRVM_LOCALSTACK_SIZE 16384
#define PRVM_MAX_STACK_DEPTH 1024
#define PRVM_LOCALSTACK_SIZE 16384
#define PRVM_MAX_OPENFILES 256
#define PRVM_MAX_OPENSEARCHES 128
@ -112,6 +111,8 @@ typedef struct prvm_prog_s
ddef_t *fielddefs;
ddef_t *globaldefs;
dstatement_t *statements;
int *linenums; // debug versions only
typeinfo_t *types;
int edict_size; // in bytes
int edictareasize; // in bytes (for bound checking)
int pev_save; // used by PRVM_PUSH_GLOBALS\PRVM_POP_GLOBALS
@ -122,8 +123,8 @@ typedef struct prvm_prog_s
union
{
float *generic;
globalvars_t *server;
float *gp;
globalvars_t *sv;
} globals;
int maxknownstrings;
@ -157,6 +158,7 @@ typedef struct prvm_prog_s
int localstack_used;
word filecrc;
int intsize;
//============================================================================
// until this point everything also exists (with the pr_ prefix) in the old vm
@ -318,18 +320,33 @@ edict_t *PRVM_EDICT_NUM_ERROR(int n, char *filename, int fileline);
#define PRVM_NEXT_EDICT(e) ((e) + 1)
#define PRVM_EDICT_TO_PROG(e) (PRVM_NUM_FOR_EDICT(e))
#define PRVM_PROG_TO_EDICT(n) (PRVM_EDICT_NUM(n))
#define PRVM_PUSH_GLOBALS prog->pev_save = prog->globals.server->pev, prog->other_save = prog->globals.server->other
#define PRVM_POP_GLOBALS prog->globals.server->pev = prog->pev_save, prog->globals.server->other = prog->other_save
#define PRVM_PUSH_GLOBALS prog->pev_save = prog->globals.sv->pev, prog->other_save = prog->globals.sv->other
#define PRVM_POP_GLOBALS prog->globals.sv->pev = prog->pev_save, prog->globals.sv->other = prog->other_save
#define PRVM_ED_POINTER(p) (prvm_eval_t *)((byte *)prog->edictsfields + p->_int)
#define PRVM_EM_POINTER(p) (prvm_eval_t *)((byte *)prog->edictsfields + (p))
#define PRVM_EV_POINTER(p) (prvm_eval_t *)(((byte *)prog->edicts) + p->_int) // this is correct ???
#define PRVM_CHECK_PTR(p, size) if(prvm_boundscheck->value && (p->_int < 0 || p->_int + size > prog->edictareasize))\
{\
prog->xfunction->profile += (st - startst);\
prog->xstatement = st - prog->statements;\
PRVM_ERROR("%s attempted to write to an out of bounds edict (%i)", PRVM_NAME, p->_int);\
return;\
}
#define PRVM_CHECK_INFINITE() if (++jumpcount == 10000000)\
{\
prog->xstatement = st - prog->statements;\
PRVM_Profile(1<<30, 1000000);\
PRVM_ERROR("runaway loop counter hit limit of %d jumps\n", jumpcount, PRVM_NAME);\
}
//============================================================================
#define PRVM_G_FLOAT(o) (prog->globals.generic[o])
#define PRVM_G_INT(o) (*(int *)&prog->globals.generic[o])
#define PRVM_G_EDICT(o) (PRVM_PROG_TO_EDICT(*(int *)&prog->globals.generic[o]))
#define PRVM_G_FLOAT(o) (prog->globals.gp[o])
#define PRVM_G_INT(o) (*(int *)&prog->globals.gp[o])
#define PRVM_G_EDICT(o) (PRVM_PROG_TO_EDICT(*(int *)&prog->globals.gp[o]))
#define PRVM_G_EDICTNUM(o) PRVM_NUM_FOR_EDICT(PRVM_G_EDICT(o))
#define PRVM_G_VECTOR(o) (&prog->globals.generic[o])
#define PRVM_G_STRING(o) (PRVM_GetString(*(string_t *)&prog->globals.generic[o]))
//#define PRVM_G_FUNCTION(o) (*(func_t *)&prog->globals.generic[o])
#define PRVM_G_VECTOR(o) (&prog->globals.gp[o])
#define PRVM_G_STRING(o) (PRVM_GetString(*(string_t *)&prog->globals.gp[o]))
//#define PRVM_G_FUNCTION(o) (*(func_t *)&prog->globals.gp[o])
// FIXME: make these go away?
#define PRVM_E_FLOAT(e,o) (((float*)e->progs.vp)[o])

View File

@ -2373,8 +2373,8 @@ vectorvectors(vector, vector)
*/
void VM_vectorvectors (void)
{
DotProduct(PRVM_G_VECTOR(OFS_PARM0), prog->globals.server->v_forward);
VectorVectors(prog->globals.server->v_forward, prog->globals.server->v_right, prog->globals.server->v_up);
DotProduct(PRVM_G_VECTOR(OFS_PARM0), prog->globals.sv->v_forward);
VectorVectors(prog->globals.sv->v_forward, prog->globals.sv->v_right, prog->globals.sv->v_up);
}
/*
@ -2387,12 +2387,12 @@ makevectors(vector)
*/
void VM_makevectors (void)
{
AngleVectors(PRVM_G_VECTOR(OFS_PARM0), prog->globals.server->v_forward, prog->globals.server->v_right, prog->globals.server->v_up);
AngleVectors(PRVM_G_VECTOR(OFS_PARM0), prog->globals.sv->v_forward, prog->globals.sv->v_right, prog->globals.sv->v_up);
}
void VM_makevectors2 (void)
{
AngleVectorsFLU(PRVM_G_VECTOR(OFS_PARM0), prog->globals.server->v_forward, prog->globals.server->v_right, prog->globals.server->v_up);
AngleVectorsFLU(PRVM_G_VECTOR(OFS_PARM0), prog->globals.sv->v_forward, prog->globals.sv->v_right, prog->globals.sv->v_up);
}
// float(float number, float quantity) bitshift (EXT_BITSHIFT)

View File

@ -180,7 +180,7 @@ float getserverlistindexforkey(string key)
#define VM_SAFEPARMCOUNT(p,f)
#endif
#define VM_RETURN_EDICT(e) (((int *)prog->globals.generic)[OFS_RETURN] = PRVM_EDICT_TO_PROG(e))
#define VM_RETURN_EDICT(e) (((int *)prog->globals.gp)[OFS_RETURN] = PRVM_EDICT_TO_PROG(e))
#define e10 NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL
#define e100 e10,e10,e10,e10,e10,e10,e10,e10,e10,e10

View File

@ -528,7 +528,7 @@ char *PRVM_GlobalString (int ofs)
void *val;
static char line[128];
val = (void *)&prog->globals.generic[ofs];
val = (void *)&prog->globals.gp[ofs];
def = PRVM_ED_GlobalAtOfs(ofs);
if (!def)
sprintf (line,"GLOBAL%i", ofs);
@ -852,7 +852,7 @@ void PRVM_ED_WriteGlobals (file_t *f)
name = PRVM_GetString(def->s_name);
FS_Printf(f,"\"%s\" ", name);
FS_Printf(f,"\"%s\"\n", PRVM_UglyValueString((etype_t)type, (prvm_eval_t *)&prog->globals.generic[def->ofs]));
FS_Printf(f,"\"%s\"\n", PRVM_UglyValueString((etype_t)type, (prvm_eval_t *)&prog->globals.gp[def->ofs]));
}
FS_Print(f,"}\n");
}
@ -918,7 +918,7 @@ bool PRVM_ED_ParseEpair(edict_t *ent, ddef_t *key, const char *s)
if (ent)
val = (prvm_eval_t *)((int *)ent->progs.vp + key->ofs);
else
val = (prvm_eval_t *)((int *)prog->globals.generic + key->ofs);
val = (prvm_eval_t *)((int *)prog->globals.gp + key->ofs);
switch (key->type & ~DEF_SAVEGLOBAL)
{
case ev_string:
@ -1294,11 +1294,12 @@ PRVM_LoadProgs
*/
void PRVM_LoadProgs (const char *filename, int numedfunc, char **ed_func, int numedfields, prvm_fieldvars_t *ed_field)
{
int i;
dstatement_t *st;
ddef_t *infielddefs;
dfunction_t *dfunctions;
fs_offset_t filesize;
int i, len;
dstatement_t *st;
ddef_t *infielddefs;
dfunction_t *dfunctions;
fs_offset_t filesize;
byte *s;
if( prog->loaded )
{
@ -1310,15 +1311,26 @@ void PRVM_LoadProgs (const char *filename, int numedfunc, char **ed_func, int nu
PRVM_ERROR ("PRVM_LoadProgs: couldn't load %s for %s", filename, PRVM_NAME);
MsgDev(D_INFO, "%s programs occupy %iK.\n", PRVM_NAME, filesize/1024);
prog->filecrc = CRC_Block((unsigned char *)prog->progs, filesize);
// byte swap the header
for (i = 0;i < (int) sizeof(*prog->progs) / 4;i++)
((int *)prog->progs)[i] = LittleLong ( ((int *)prog->progs)[i] );
for (i = 0; i < (int)sizeof(*prog->progs)/4; i++) ((int *)prog->progs)[i] = LittleLong(((int *)prog->progs)[i]);
if (prog->progs->version != VPROGS_VERSION)
switch( prog->progs->version )
{
case QPROGS_VERSION:
prog->intsize = 16;
break;
case VPROGS_VERSION:
if(prog->progs->header == VPROGSHEADER16)
prog->intsize = 16;
if(prog->progs->header == VPROGSHEADER32)
prog->intsize = 32;
break;
default:
PRVM_ERROR ("%s: %s has wrong version number (%i should be %i)", PRVM_NAME, filename, prog->progs->version, VPROGS_VERSION);
break;
}
//try to recognize progs.dat by crc
switch(prog->progs->crc)
@ -1331,12 +1343,35 @@ void PRVM_LoadProgs (const char *filename, int numedfunc, char **ed_func, int nu
}
Msg("Loading %s\n", filename );
//prog->functions = (dfunction_t *)((unsigned char *)progs + progs->ofs_functions);
dfunctions = (dfunction_t *)((unsigned char *)prog->progs + prog->progs->ofs_functions);
if (prog->progs->ofslinenums) prog->linenums = (int *)((byte *)prog->progs + prog->progs->ofslinenums);
if (prog->progs->ofs_types) prog->types = (typeinfo_t *)((byte *)prog->progs + prog->progs->ofs_types);
prog->statements = (dstatement_t *)((byte *)prog->progs + prog->progs->ofs_statements);
// decompress progs if needed
if (prog->progs->blockscompressed & COMP_STATEMENTS)
{
switch(prog->intsize)
{
case 32:
len = sizeof(dstatement32_t) * prog->progs->numstatements;
break;
case 16:
default:
len = sizeof(dstatement16_t) * prog->progs->numstatements;
break;
}
s = Mem_Alloc(prog->progs_mempool, len ); //alloc memory for inflate block
Com->Compile.DecryptDAT(LittleLong(*(int*)prog->statements), len, 2, (char *)(((int *)prog->statements)+1), &s);
prog->statements = (dstatement16_t *)s;
}
Sys_Error("breakpoint\n");
dfunctions = (dfunction_t *)((byte *)prog->progs + prog->progs->ofs_functions);
prog->strings = (char *)prog->progs + prog->progs->ofs_strings;
prog->stringssize = 0;
for (i = 0;i < prog->progs->numstrings;i++)
for (i = 0; i < prog->progs->numstrings; i++)
{
if (prog->progs->ofs_strings + prog->stringssize >= (int)filesize)
PRVM_ERROR ("%s: %s strings go past end of file", PRVM_NAME, filename);
@ -1347,25 +1382,20 @@ void PRVM_LoadProgs (const char *filename, int numedfunc, char **ed_func, int nu
prog->knownstrings = NULL;
prog->knownstrings_freeable = NULL;
prog->globaldefs = (ddef_t *)((unsigned char *)prog->progs + prog->progs->ofs_globaldefs);
prog->globaldefs = (ddef_t *)((byte *)prog->progs + prog->progs->ofs_globaldefs);
// we need to expand the fielddefs list to include all the engine fields,
// so allocate a new place for it
infielddefs = (ddef_t *)((unsigned char *)prog->progs + prog->progs->ofs_fielddefs);
// ( + DPFIELDS )
infielddefs = (ddef_t *)((byte *)prog->progs + prog->progs->ofs_fielddefs);
// ( + DPFIELDS )
prog->fielddefs = (ddef_t *)Mem_Alloc(prog->progs_mempool, (prog->progs->numfielddefs + numedfields) * sizeof(ddef_t));
prog->statements = (dstatement_t *)((unsigned char *)prog->progs + prog->progs->ofs_statements);
prog->statement_profile = (double *)Mem_Alloc(prog->progs_mempool, prog->progs->numstatements * sizeof(*prog->statement_profile));
// moved edict_size calculation down below field adding code
//pr_global_struct = (globalvars_t *)((unsigned char *)progs + progs->ofs_globals);
prog->globals.generic = (float *)((unsigned char *)prog->progs + prog->progs->ofs_globals);
prog->globals.gp = (float *)((byte *)prog->progs + prog->progs->ofs_globals);
// byte swap the lumps
for (i=0 ; i<prog->progs->numstatements ; i++)
for (i = 0; i < prog->progs->numstatements; i++)
{
prog->statements[i].op = LittleShort(prog->statements[i].op);
prog->statements[i].a = LittleShort(prog->statements[i].a);
@ -1416,7 +1446,7 @@ void PRVM_LoadProgs (const char *filename, int numedfunc, char **ed_func, int nu
PRVM_ERROR("%s: %s not found in %s",PRVM_NAME, ed_func[i], filename);
for (i=0 ; i<prog->progs->numglobals ; i++)
((int *)prog->globals.generic)[i] = LittleLong (((int *)prog->globals.generic)[i]);
((int *)prog->globals.gp)[i] = LittleLong (((int *)prog->globals.gp)[i]);
// moved edict_size calculation down here, below field adding code
// LordHavoc: this no longer includes the edict_t header
@ -1725,7 +1755,7 @@ void PRVM_Global_f(void)
if( !global )
Msg( "No global '%s' in %s!\n", Cmd_Argv(2), Cmd_Argv(1) );
else
Msg( "%s: %s\n", Cmd_Argv(2), PRVM_ValueString( (etype_t)global->type, (prvm_eval_t *) &prog->globals.generic[ global->ofs ] ) );
Msg( "%s: %s\n", Cmd_Argv(2), PRVM_ValueString( (etype_t)global->type, (prvm_eval_t *) &prog->globals.gp[ global->ofs ] ) );
PRVM_End;
}
@ -1902,14 +1932,14 @@ int PRVM_SetEngineString(const char *s)
if (i >= prog->maxknownstrings)
{
const char **oldstrings = prog->knownstrings;
const unsigned char *oldstrings_freeable = prog->knownstrings_freeable;
const byte *oldstrings_freeable = prog->knownstrings_freeable;
prog->maxknownstrings += 128;
prog->knownstrings = (const char **)PRVM_Alloc(prog->maxknownstrings * sizeof(char *));
prog->knownstrings_freeable = (unsigned char *)PRVM_Alloc(prog->maxknownstrings * sizeof(unsigned char));
prog->knownstrings_freeable = (byte *)PRVM_Alloc(prog->maxknownstrings * sizeof(byte));
if (prog->numknownstrings)
{
memcpy((char **)prog->knownstrings, oldstrings, prog->numknownstrings * sizeof(char *));
memcpy((char **)prog->knownstrings_freeable, oldstrings_freeable, prog->numknownstrings * sizeof(unsigned char));
memcpy((char **)prog->knownstrings_freeable, oldstrings_freeable, prog->numknownstrings * sizeof(byte));
}
}
prog->numknownstrings++;
@ -1932,14 +1962,14 @@ int PRVM_AllocString(size_t bufferlength, char **pointer)
if (i >= prog->maxknownstrings)
{
const char **oldstrings = prog->knownstrings;
const unsigned char *oldstrings_freeable = prog->knownstrings_freeable;
const byte *oldstrings_freeable = prog->knownstrings_freeable;
prog->maxknownstrings += 128;
prog->knownstrings = (const char **)PRVM_Alloc(prog->maxknownstrings * sizeof(char *));
prog->knownstrings_freeable = (unsigned char *)PRVM_Alloc(prog->maxknownstrings * sizeof(unsigned char));
prog->knownstrings_freeable = (byte *)PRVM_Alloc(prog->maxknownstrings * sizeof(byte));
if (prog->numknownstrings)
{
memcpy((char **)prog->knownstrings, oldstrings, prog->numknownstrings * sizeof(char *));
memcpy((char **)prog->knownstrings_freeable, oldstrings_freeable, prog->numknownstrings * sizeof(unsigned char));
memcpy((char **)prog->knownstrings_freeable, oldstrings_freeable, prog->numknownstrings * sizeof(byte));
}
}
prog->numknownstrings++;

File diff suppressed because it is too large Load Diff

View File

@ -209,36 +209,36 @@ void SV_Impact (edict_t *e1, trace_t *trace)
PRVM_PUSH_GLOBALS;
prog->globals.server->time = sv.time;
prog->globals.sv->time = sv.time;
if (!e1->priv.sv->free && !e2->priv.sv->free && e1->progs.sv->touch && e1->progs.sv->solid != SOLID_NOT)
{
prog->globals.server->pev = PRVM_EDICT_TO_PROG(e1);
prog->globals.server->other = PRVM_EDICT_TO_PROG(e2);
prog->globals.server->time = sv.time;
prog->globals.server->trace_allsolid = trace->allsolid;
prog->globals.server->trace_startsolid = trace->startsolid;
prog->globals.server->trace_fraction = trace->fraction;
prog->globals.server->trace_contents = trace->contents;
VectorCopy (trace->endpos, prog->globals.server->trace_endpos);
VectorCopy (trace->plane.normal, prog->globals.server->trace_plane_normal);
prog->globals.server->trace_plane_dist = trace->plane.dist;
if (trace->ent) prog->globals.server->trace_ent = PRVM_EDICT_TO_PROG(trace->ent);
else prog->globals.server->trace_ent = PRVM_EDICT_TO_PROG(prog->edicts);
prog->globals.sv->pev = PRVM_EDICT_TO_PROG(e1);
prog->globals.sv->other = PRVM_EDICT_TO_PROG(e2);
prog->globals.sv->time = sv.time;
prog->globals.sv->trace_allsolid = trace->allsolid;
prog->globals.sv->trace_startsolid = trace->startsolid;
prog->globals.sv->trace_fraction = trace->fraction;
prog->globals.sv->trace_contents = trace->contents;
VectorCopy (trace->endpos, prog->globals.sv->trace_endpos);
VectorCopy (trace->plane.normal, prog->globals.sv->trace_plane_normal);
prog->globals.sv->trace_plane_dist = trace->plane.dist;
if (trace->ent) prog->globals.sv->trace_ent = PRVM_EDICT_TO_PROG(trace->ent);
else prog->globals.sv->trace_ent = PRVM_EDICT_TO_PROG(prog->edicts);
PRVM_ExecuteProgram (e1->progs.sv->touch, "QC function pev->touch is missing");
}
if (!e1->priv.sv->free && !e2->priv.sv->free && e2->progs.sv->touch && e2->progs.sv->solid != SOLID_NOT)
{
prog->globals.server->pev = PRVM_EDICT_TO_PROG(e2);
prog->globals.server->other = PRVM_EDICT_TO_PROG(e1);
prog->globals.server->time = sv.time;
prog->globals.server->trace_allsolid = false;
prog->globals.server->trace_startsolid = false;
prog->globals.server->trace_fraction = 1;
prog->globals.server->trace_contents = trace->contents;
VectorCopy (e2->progs.sv->origin, prog->globals.server->trace_endpos);
VectorSet (prog->globals.server->trace_plane_normal, 0, 0, 1);
prog->globals.server->trace_plane_dist = 0;
prog->globals.server->trace_ent = PRVM_EDICT_TO_PROG(e1);
prog->globals.sv->pev = PRVM_EDICT_TO_PROG(e2);
prog->globals.sv->other = PRVM_EDICT_TO_PROG(e1);
prog->globals.sv->time = sv.time;
prog->globals.sv->trace_allsolid = false;
prog->globals.sv->trace_startsolid = false;
prog->globals.sv->trace_fraction = 1;
prog->globals.sv->trace_contents = trace->contents;
VectorCopy (e2->progs.sv->origin, prog->globals.sv->trace_endpos);
VectorSet (prog->globals.sv->trace_plane_normal, 0, 0, 1);
prog->globals.sv->trace_plane_dist = 0;
prog->globals.sv->trace_ent = PRVM_EDICT_TO_PROG(e1);
PRVM_ExecuteProgram (e2->progs.sv->touch, "QC function pev->touch is missing");
}
@ -591,9 +591,9 @@ bool SV_RunThink (edict_t *ent)
if (thinktime < sv.time) thinktime = sv.time;
ent->progs.sv->nextthink = 0; //reset thinktime
prog->globals.server->time = thinktime;
prog->globals.server->pev = PRVM_EDICT_TO_PROG(ent);
prog->globals.server->other = PRVM_EDICT_TO_PROG(prog->edicts);
prog->globals.sv->time = thinktime;
prog->globals.sv->pev = PRVM_EDICT_TO_PROG(ent);
prog->globals.sv->other = PRVM_EDICT_TO_PROG(prog->edicts);
PRVM_ExecuteProgram (ent->progs.sv->think, "QC function pev->think is missing");
return !ent->priv.sv->free;
@ -606,7 +606,7 @@ SV_MoveStep
Called by monster program code.
The move will be adjusted for slopes and stairs, but if the move isn't
possible, no move is done, false is returned, and
prog->globals.server->trace_normal is set to the normal of the blocking wall
prog->globals.sv->trace_normal is set to the normal of the blocking wall
=============
*/
bool SV_MoveStep (edict_t *ent, vec3_t move, bool relink)
@ -914,8 +914,8 @@ void SV_MovePush(edict_t *pusher, float movetime)
// if the pusher has a "blocked" function, call it, otherwise just stay in place until the obstacle is gone
if (pusher->progs.sv->blocked)
{
prog->globals.server->pev = PRVM_EDICT_TO_PROG(pusher);
prog->globals.server->other = PRVM_EDICT_TO_PROG(check);
prog->globals.sv->pev = PRVM_EDICT_TO_PROG(pusher);
prog->globals.sv->other = PRVM_EDICT_TO_PROG(check);
PRVM_ExecuteProgram (pusher->progs.sv->blocked, "QC function self.blocked is missing");
}
break;
@ -995,9 +995,9 @@ void SV_PhysicsPush(edict_t *ent)
if (thinktime > oldltime && thinktime <= ent->progs.sv->ltime)
{
ent->progs.sv->nextthink = 0;
prog->globals.server->time = sv.time;
prog->globals.server->pev = PRVM_EDICT_TO_PROG(ent);
prog->globals.server->other = PRVM_EDICT_TO_PROG(prog->edicts);
prog->globals.sv->time = sv.time;
prog->globals.sv->pev = PRVM_EDICT_TO_PROG(ent);
prog->globals.sv->other = PRVM_EDICT_TO_PROG(prog->edicts);
PRVM_ExecuteProgram (ent->progs.sv->think, "QC function pev->think is missing");
}
}

View File

@ -28,9 +28,9 @@ void SV_PutClientInServer (edict_t *ent)
index = PRVM_NUM_FOR_EDICT(ent) - 1;
client = ent->priv.sv->client;
prog->globals.server->time = sv.time;
prog->globals.server->pev = PRVM_EDICT_TO_PROG(ent);
PRVM_ExecuteProgram (prog->globals.server->PutClientInServer, "QC function PutClientInServer is missing");
prog->globals.sv->time = sv.time;
prog->globals.sv->pev = PRVM_EDICT_TO_PROG(ent);
PRVM_ExecuteProgram (prog->globals.sv->PutClientInServer, "QC function PutClientInServer is missing");
ent->priv.sv->client = svs.gclients + index;
ent->priv.sv->free = false;
@ -105,7 +105,7 @@ void SV_SpawnEntities (char *mapname, char *entities, char *spawnpoint)
ent->progs.sv->movetype = MOVETYPE_PUSH;
SV_ConfigString (CS_MAXCLIENTS, va("%i", (int)(maxclients->value)));
prog->globals.server->mapname = PRVM_SetEngineString(sv.name);
prog->globals.sv->mapname = PRVM_SetEngineString(sv.name);
// spawn the rest of the entities on the map
*prog->time = sv.time;
@ -178,9 +178,9 @@ void SV_TouchTriggers (edict_t *ent)
hit = touch[i];
if (hit->priv.sv->free) continue;
prog->globals.server->pev = PRVM_EDICT_TO_PROG(hit);
prog->globals.server->other = PRVM_EDICT_TO_PROG(ent);
prog->globals.server->time = sv.time;
prog->globals.sv->pev = PRVM_EDICT_TO_PROG(hit);
prog->globals.sv->other = PRVM_EDICT_TO_PROG(ent);
prog->globals.sv->time = sv.time;
PRVM_ExecuteProgram (hit->progs.sv->touch, "QC function pev->touch is missing");
}
@ -428,11 +428,11 @@ void SV_RunFrame( void )
edict_t *ent;
// let the progs know that a new frame has started
prog->globals.server->pev = PRVM_EDICT_TO_PROG(prog->edicts);
prog->globals.server->other = PRVM_EDICT_TO_PROG(prog->edicts);
prog->globals.server->time = sv.time;
prog->globals.server->frametime = sv.frametime;
PRVM_ExecuteProgram (prog->globals.server->StartFrame, "QC function StartFrame is missing");
prog->globals.sv->pev = PRVM_EDICT_TO_PROG(prog->edicts);
prog->globals.sv->other = PRVM_EDICT_TO_PROG(prog->edicts);
prog->globals.sv->time = sv.time;
prog->globals.sv->frametime = sv.frametime;
PRVM_ExecuteProgram (prog->globals.sv->StartFrame, "QC function StartFrame is missing");
for (i = 1; i < prog->num_edicts; i++ )
{
@ -449,10 +449,10 @@ void SV_RunFrame( void )
// build the playerstate_t structures for all players
ClientEndServerFrames ();
prog->globals.server->pev = PRVM_EDICT_TO_PROG(prog->edicts);
prog->globals.server->other = PRVM_EDICT_TO_PROG(prog->edicts);
prog->globals.server->time = sv.time;
PRVM_ExecuteProgram (prog->globals.server->EndFrame, "QC function EndFrame is missing");
prog->globals.sv->pev = PRVM_EDICT_TO_PROG(prog->edicts);
prog->globals.sv->other = PRVM_EDICT_TO_PROG(prog->edicts);
prog->globals.sv->time = sv.time;
PRVM_ExecuteProgram (prog->globals.sv->EndFrame, "QC function EndFrame is missing");
// decrement prog->num_edicts if the highest number entities died
for ( ;PRVM_EDICT_NUM(prog->num_edicts - 1)->priv.sv->free; prog->num_edicts-- );
@ -466,9 +466,9 @@ bool SV_ClientConnect (edict_t *ent, char *userinfo)
ent->progs.sv->health = 100;
Msg("SV_ClientConnect()\n");
prog->globals.server->time = sv.time;
prog->globals.server->pev = PRVM_EDICT_TO_PROG(ent);
PRVM_ExecuteProgram (prog->globals.server->ClientConnect, "QC function ClientConnect is missing");
prog->globals.sv->time = sv.time;
prog->globals.sv->pev = PRVM_EDICT_TO_PROG(ent);
PRVM_ExecuteProgram (prog->globals.sv->ClientConnect, "QC function ClientConnect is missing");
return true;
}
@ -553,9 +553,9 @@ void ClientThink (edict_t *ent, usercmd_t *ucmd)
client = ent->priv.sv->client;
// call standard client pre-think
prog->globals.server->time = sv.time;
prog->globals.server->pev = PRVM_EDICT_TO_PROG(ent);
PRVM_ExecuteProgram (prog->globals.server->PlayerPreThink, "QC function PlayerPreThink is missing");
prog->globals.sv->time = sv.time;
prog->globals.sv->pev = PRVM_EDICT_TO_PROG(ent);
PRVM_ExecuteProgram (prog->globals.sv->PlayerPreThink, "QC function PlayerPreThink is missing");
VectorCopy(ent->progs.sv->origin, oldorigin);
VectorCopy(ent->progs.sv->velocity, oldvelocity);
@ -621,17 +621,17 @@ void ClientThink (edict_t *ent, usercmd_t *ucmd)
if (j != i) continue; // duplicated
if (!other->progs.sv->touch) continue;
prog->globals.server->pev = PRVM_EDICT_TO_PROG(other);
prog->globals.server->other = PRVM_EDICT_TO_PROG(ent);
prog->globals.server->time = sv.time;
prog->globals.sv->pev = PRVM_EDICT_TO_PROG(other);
prog->globals.sv->other = PRVM_EDICT_TO_PROG(ent);
prog->globals.sv->time = sv.time;
PRVM_ExecuteProgram (other->progs.sv->touch, "QC function pev->touch is missing");
}
PRVM_POP_GLOBALS;
// call standard player post-think
prog->globals.server->time = sv.time;
prog->globals.server->pev = PRVM_EDICT_TO_PROG(ent);
PRVM_ExecuteProgram (prog->globals.server->PlayerPostThink, "QC function PlayerPostThink is missing");
prog->globals.sv->time = sv.time;
prog->globals.sv->pev = PRVM_EDICT_TO_PROG(ent);
PRVM_ExecuteProgram (prog->globals.sv->PlayerPostThink, "QC function PlayerPostThink is missing");
}
/*

View File

@ -461,10 +461,10 @@ void SV_ExecuteUserCommand (char *s)
if (!u->name && sv.state == ss_game)
{
// custom client commands
prog->globals.server->pev = PRVM_EDICT_TO_PROG(sv_player);
prog->globals.server->time = sv.time;
prog->globals.server->frametime = sv.frametime;
PRVM_ExecuteProgram (prog->globals.server->ClientCommand, "QC function ClientCommand is missing");
prog->globals.sv->pev = PRVM_EDICT_TO_PROG(sv_player);
prog->globals.sv->time = sv.time;
prog->globals.sv->frametime = sv.frametime;
PRVM_ExecuteProgram (prog->globals.sv->ClientCommand, "QC function ClientCommand is missing");
}
}

View File

@ -219,7 +219,7 @@ void PF_sprint (void)
num = PRVM_G_EDICTNUM(OFS_PARM0);
if (num < 1 || num > host.maxclients || svs.clients[num - 1].state != cs_spawned)
if (num < 1 || num > maxclients->value || svs.clients[num - 1].state != cs_spawned)
{
VM_Warning("tried to centerprint to a non-client\n");
return;
@ -245,11 +245,11 @@ void PF_centerprint (void)
{
client_t *client;
int num;
char string[VM_STRINGTEMP_LENGTH];
char string[VM_STRINGTEMP_LENGTH];
num = PRVM_G_EDICTNUM(OFS_PARM0);
if(num < 1 || num > host.maxclients || svs.clients[num-1].state != cs_spawned)
if(num < 1 || num > maxclients->value || svs.clients[num-1].state != cs_spawned)
{
VM_Warning("tried to centerprint to a non-client\n");
return;
@ -353,7 +353,7 @@ void PF_droptofloor (void)
// assume failure if it returns early
PRVM_G_FLOAT(OFS_RETURN) = 0;
ent = PRVM_PROG_TO_EDICT(prog->globals.server->pev);
ent = PRVM_PROG_TO_EDICT(prog->globals.sv->pev);
if (ent == prog->edicts)
{
VM_Warning("droptofloor: can not modify world entity\n");
@ -513,16 +513,16 @@ void PF_traceline (void)
trace = SV_Trace (v1, vec3_origin, vec3_origin, v2, ent, mask );
prog->globals.server->trace_allsolid = trace.allsolid;
prog->globals.server->trace_startsolid = trace.startsolid;
prog->globals.server->trace_fraction = trace.fraction;
prog->globals.server->trace_contents = trace.contents;
prog->globals.sv->trace_allsolid = trace.allsolid;
prog->globals.sv->trace_startsolid = trace.startsolid;
prog->globals.sv->trace_fraction = trace.fraction;
prog->globals.sv->trace_contents = trace.contents;
VectorCopy (trace.endpos, prog->globals.server->trace_endpos);
VectorCopy (trace.plane.normal, prog->globals.server->trace_plane_normal);
prog->globals.server->trace_plane_dist = trace.plane.dist;
if (trace.ent) prog->globals.server->trace_ent = PRVM_EDICT_TO_PROG(trace.ent);
else prog->globals.server->trace_ent = PRVM_EDICT_TO_PROG(prog->edicts);
VectorCopy (trace.endpos, prog->globals.sv->trace_endpos);
VectorCopy (trace.plane.normal, prog->globals.sv->trace_plane_normal);
prog->globals.sv->trace_plane_dist = trace.plane.dist;
if (trace.ent) prog->globals.sv->trace_ent = PRVM_EDICT_TO_PROG(trace.ent);
else prog->globals.sv->trace_ent = PRVM_EDICT_TO_PROG(prog->edicts);
}
@ -564,17 +564,17 @@ void PF_tracebox (void)
trace = SV_Trace (v1, m1, m2, v2, ent, mask );
prog->globals.server->trace_allsolid = trace.allsolid;
prog->globals.server->trace_startsolid = trace.startsolid;
prog->globals.server->trace_fraction = trace.fraction;
prog->globals.server->trace_contents = trace.contents;
prog->globals.sv->trace_allsolid = trace.allsolid;
prog->globals.sv->trace_startsolid = trace.startsolid;
prog->globals.sv->trace_fraction = trace.fraction;
prog->globals.sv->trace_contents = trace.contents;
VectorCopy (trace.endpos, prog->globals.server->trace_endpos);
VectorCopy (trace.plane.normal, prog->globals.server->trace_plane_normal);
prog->globals.server->trace_plane_dist = trace.plane.dist;
VectorCopy (trace.endpos, prog->globals.sv->trace_endpos);
VectorCopy (trace.plane.normal, prog->globals.sv->trace_plane_normal);
prog->globals.sv->trace_plane_dist = trace.plane.dist;
if (trace.ent) prog->globals.server->trace_ent = PRVM_EDICT_TO_PROG(trace.ent);
else prog->globals.server->trace_ent = PRVM_EDICT_TO_PROG(prog->edicts);
if (trace.ent) prog->globals.sv->trace_ent = PRVM_EDICT_TO_PROG(trace.ent);
else prog->globals.sv->trace_ent = PRVM_EDICT_TO_PROG(prog->edicts);
}
/*
@ -602,16 +602,16 @@ void PF_tracetoss (void)
trace = SV_TraceToss (ent, ignore);
prog->globals.server->trace_allsolid = trace.allsolid;
prog->globals.server->trace_startsolid = trace.startsolid;
prog->globals.server->trace_fraction = trace.fraction;
prog->globals.server->trace_contents = trace.contents;
prog->globals.sv->trace_allsolid = trace.allsolid;
prog->globals.sv->trace_startsolid = trace.startsolid;
prog->globals.sv->trace_fraction = trace.fraction;
prog->globals.sv->trace_contents = trace.contents;
VectorCopy (trace.endpos, prog->globals.server->trace_endpos);
VectorCopy (trace.plane.normal, prog->globals.server->trace_plane_normal);
prog->globals.server->trace_plane_dist = trace.plane.dist;
if (trace.ent) prog->globals.server->trace_ent = PRVM_EDICT_TO_PROG(trace.ent);
else prog->globals.server->trace_ent = PRVM_EDICT_TO_PROG(prog->edicts);
VectorCopy (trace.endpos, prog->globals.sv->trace_endpos);
VectorCopy (trace.plane.normal, prog->globals.sv->trace_plane_normal);
prog->globals.sv->trace_plane_dist = trace.plane.dist;
if (trace.ent) prog->globals.sv->trace_ent = PRVM_EDICT_TO_PROG(trace.ent);
else prog->globals.sv->trace_ent = PRVM_EDICT_TO_PROG(prog->edicts);
}
void PF_create( void )
@ -678,7 +678,7 @@ void PF_walkmove (void)
// assume failure if it returns early
PRVM_G_FLOAT(OFS_RETURN) = 0;
ent = PRVM_PROG_TO_EDICT(prog->globals.server->pev);
ent = PRVM_PROG_TO_EDICT(prog->globals.sv->pev);
if (ent == prog->edicts)
{
VM_Warning("walkmove: can not modify world entity\n");
@ -704,13 +704,13 @@ void PF_walkmove (void)
// save program state, because SV_movestep may call other progs
oldf = prog->xfunction;
oldpev = prog->globals.server->pev;
oldpev = prog->globals.sv->pev;
PRVM_G_FLOAT(OFS_RETURN) = SV_MoveStep(ent, move, true);
// restore program state
prog->xfunction = oldf;
prog->globals.server->pev = oldpev;
prog->globals.sv->pev = oldpev;
}
/*
@ -754,7 +754,7 @@ void PF_aim (void)
int flags = Cvar_VariableValue( "dmflags" );
// assume failure if it returns early
VectorCopy(prog->globals.server->v_forward, PRVM_G_VECTOR(OFS_RETURN));
VectorCopy(prog->globals.sv->v_forward, PRVM_G_VECTOR(OFS_RETURN));
ent = PRVM_G_EDICT(OFS_PARM0);
if (ent == prog->edicts)
@ -773,13 +773,13 @@ void PF_aim (void)
start[2] += 20;
// try sending a trace straight
VectorCopy (prog->globals.server->v_forward, dir);
VectorCopy (prog->globals.sv->v_forward, dir);
VectorMA (start, 2048, dir, end);
tr = SV_Trace (start, vec3_origin, vec3_origin, end, ent, MASK_ALL );
if (tr.ent && ((edict_t *)tr.ent)->progs.sv->takedamage == DAMAGE_AIM && (flags & DF_NO_FRIENDLY_FIRE || ent->progs.sv->team <=0 || ent->progs.sv->team != ((edict_t *)tr.ent)->progs.sv->team))
{
VectorCopy (prog->globals.server->v_forward, PRVM_G_VECTOR(OFS_RETURN));
VectorCopy (prog->globals.sv->v_forward, PRVM_G_VECTOR(OFS_RETURN));
return;
}
@ -801,7 +801,7 @@ void PF_aim (void)
end[j] = check->progs.sv->origin[j] + 0.5 * (check->progs.sv->mins[j] + check->progs.sv->maxs[j]);
VectorSubtract (end, start, dir);
VectorNormalize (dir);
dist = DotProduct (dir, prog->globals.server->v_forward);
dist = DotProduct (dir, prog->globals.sv->v_forward);
if (dist < bestdist) continue; // to far to turn
tr = SV_Trace (start, vec3_origin, vec3_origin, end, ent, MASK_ALL );
if (tr.ent == check)
@ -815,8 +815,8 @@ void PF_aim (void)
if (bestent)
{
VectorSubtract (bestent->progs.sv->origin, ent->progs.sv->origin, dir);
dist = DotProduct (dir, prog->globals.server->v_forward);
VectorScale (prog->globals.server->v_forward, dist, end);
dist = DotProduct (dir, prog->globals.sv->v_forward);
VectorScale (prog->globals.sv->v_forward, dist, end);
end[2] = dir[2];
VectorNormalize (end);
VectorCopy (end, PRVM_G_VECTOR(OFS_RETURN));
@ -854,7 +854,7 @@ void PF_changeyaw (void)
{
edict_t *ent;
ent = PRVM_PROG_TO_EDICT(prog->globals.server->pev);
ent = PRVM_PROG_TO_EDICT(prog->globals.sv->pev);
if (ent == prog->edicts)
{
VM_Warning("changeyaw: can not modify world entity\n");
@ -878,7 +878,7 @@ void PF_changepitch (void)
{
edict_t *ent;
ent = PRVM_PROG_TO_EDICT(prog->globals.server->pev);
ent = PRVM_PROG_TO_EDICT(prog->globals.sv->pev);
if (ent == prog->edicts)
{
VM_Warning("changepitch: can not modify world entity\n");
@ -954,6 +954,12 @@ void PF_decalindex (void)
PRVM_G_FLOAT(OFS_RETURN) = SV_DecalIndex(PRVM_G_STRING(OFS_PARM0));
}
void PF_imageindex (void)
{
// it will precache new images too
PRVM_G_FLOAT(OFS_RETURN) = SV_ImageIndex(PRVM_G_STRING(OFS_PARM0));
}
void PF_getlightlevel (void)
{
edict_t *ent;
@ -1260,7 +1266,7 @@ PF_precache_sound, // #72 float precache_sound(string s)
PF_setmodel, // #73 float setmodel(entity e, string m)
PF_modelindex, // #74 float model_index(string s)
PF_decalindex, // #75 float decal_index(string s)
PF_modelframes, // #76 float model_frames(float modelindex)
PF_imageindex, // #76 float image_index(string s)
PF_setsize, // #77 void setsize(entity e, vector min, vector max)
PF_changelevel, // #78 void changelevel(string mapname, string spotname)
PF_changeyaw, // #79 void ChangeYaw( void )
@ -1291,7 +1297,7 @@ PF_areaportalstate, // #103 void areaportal_state( float num, float state )
PF_setstats, // #104 void setstats(entity e, float f, string stats)
PF_configstring, // #105 void configstring(float num, string s)
PF_makestatic, // #106 void makestatic(entity e)
VM_precache_pic, // #107 string precache_pic(string pic)
PF_modelframes, // #107 float model_frames(float modelindex)
NULL, // #108
NULL, // #109
NULL, // #110

View File

@ -242,9 +242,10 @@ void CommonMain ( void )
case IMGLIB:
CompileMod = Com->Compile.Image;
strcpy(typemod, "images" );
strcpy(searchmask[0], "*.pcx" );
strcpy(searchmask[1], "*.wal" );
strcpy(searchmask[2], "*.lmp" );
strcpy(searchmask[0], "*.pcx" ); // quake2 menu images
strcpy(searchmask[1], "*.wal" ); // quake2 textures
strcpy(searchmask[2], "*.lmp" ); // quake1 menu images
strcpy(searchmask[3], "*.mip" ); // quake1 textures
Msg("Processing images ...\n\n");
break;
case BSPLIB:

View File

@ -734,6 +734,7 @@ typedef struct compilers_api_s
bool (*BSP)( void );
bool (*PrepareDAT)( const char *dir, const char *name, byte params ); // compile dat in gamedir
bool (*DAT)( void );
bool (*DecryptDAT)( int complen, int len, int method, char *info, char **buffer); //unpacking dat
} compilers_api_t;
/*

View File

@ -14,14 +14,14 @@ a internal virtual machine like as QuakeC, but it has more extensions
==============================================================================
*/
#define PROG_EXTENDEDVERSION 7//remove
//header
#define VPROGS_VERSION 6
#define QPROGS_VERSION 6
#define VPROGS_VERSION 7
#define VPROGSHEADER16 (('6'<<24)+('1'<<16)+('C'<<8)+'Q') // little-endian "QC16"
#define VPROGSHEADER32 (('2'<<24)+('3'<<16)+('C'<<8)+'Q') // little-endian "QC32"
//global ofssets
// global ofssets
#define OFS_NULL 0
#define OFS_RETURN 1
#define OFS_PARM0 4
@ -38,6 +38,16 @@ a internal virtual machine like as QuakeC, but it has more extensions
#define DEF_SHARED (1<<14)
#define DEF_SAVEGLOBAL (1<<15)
// compression block flags
#define COMP_STATEMENTS 1
#define COMP_DEFS 2
#define COMP_FIELDS 4
#define COMP_FUNCTIONS 8
#define COMP_STRINGS 16
#define COMP_GLOBALS 32
#define COMP_LINENUMS 64
#define COMP_TYPES 128
#define MAX_PARMS 8
@ -65,8 +75,8 @@ enum {
OP_DONE, // 0
OP_MUL_F,
OP_MUL_V,
OP_MUL_FV,
OP_MUL_VF,
OP_MUL_FV, // (vec3_t) * (float)
OP_MUL_VF, // (float) * (vec3_t)
OP_DIV_F,
OP_ADD_F,
OP_ADD_V,
@ -85,10 +95,10 @@ enum {
OP_NE_E,
OP_NE_FNC,
OP_LE, // 20
OP_GE,
OP_LT,
OP_GT,
OP_LE, // = (float) <= (float);
OP_GE, // = (float) >= (float);
OP_LT, // = (float) < (float);
OP_GT, // = (float) > (float);
OP_LOAD_F,
OP_LOAD_V,
@ -121,8 +131,8 @@ enum {
OP_NOT_FNC,
OP_IF,
OP_IFNOT, // 50
OP_CALL0, // careful... hexen2 and q1 have different calling conventions
OP_CALL1, // remap hexen2 calls to OP_CALL2H
OP_CALL0,
OP_CALL1,
OP_CALL2,
OP_CALL3,
OP_CALL4,
@ -135,81 +145,57 @@ enum {
OP_AND,
OP_OR,
OP_BITAND,
OP_BITAND, // = (float) & (float); // of cource converting into integer in real code
OP_BITOR,
// these following ones are Hexen 2 constants.
OP_MULSTORE_F,
OP_MULSTORE_V,
OP_MULSTOREP_F,
OP_MULSTOREP_V,
OP_DIVSTORE_F, // 70
OP_DIVSTOREP_F,
OP_MULSTORE_F, // f *= f
OP_MULSTORE_V, // v *= f
OP_MULSTOREP_F, // e.f *= f
OP_MULSTOREP_V, // e.v *= f
OP_ADDSTORE_F,
OP_ADDSTORE_V,
OP_ADDSTOREP_F,
OP_ADDSTOREP_V,
OP_DIVSTORE_F, // f /= f
OP_DIVSTOREP_F, // e.f /= f
OP_SUBSTORE_F,
OP_SUBSTORE_V,
OP_SUBSTOREP_F,
OP_SUBSTOREP_V,
OP_ADDSTORE_F, // f += f
OP_ADDSTORE_V, // v += v
OP_ADDSTOREP_F, // e.f += f
OP_ADDSTOREP_V, // e.v += v
OP_SUBSTORE_F, // f -= f
OP_SUBSTORE_V, // v -= v
OP_SUBSTOREP_F, // e.f -= f
OP_SUBSTOREP_V, // e.v -= v
OP_FETCH_GBL_F, // 80
OP_FETCH_GBL_V,
OP_FETCH_GBL_S,
OP_FETCH_GBL_E,
OP_FETCH_GBL_FNC,
OP_FETCH_G_FNC,
OP_CSTATE,
OP_CWSTATE,
OP_THINKTIME,
OP_BITSET, // b (+) a
OP_BITSETP, // .b (+) a
OP_BITCLR, // b (-) a
OP_BITCLRP, // .b (-) a
OP_BITSET,
OP_BITSETP,
OP_BITCLR, // 90
OP_BITCLRP,
OP_RAND0,
OP_RAND1,
OP_RAND2,
OP_RANDV0,
OP_RANDV1,
OP_RANDV2,
OP_SWITCH_F,
OP_SWITCH_V,
OP_SWITCH_S, // 100
OP_SWITCH_F, // switches
OP_SWITCH_V, // 100
OP_SWITCH_S,
OP_SWITCH_E,
OP_SWITCH_FNC,
OP_CASE,
OP_CASERANGE,
// the rest are added
// mostly they are various different ways of adding two vars with conversions.
OP_CALL1H,
OP_CALL2H,
OP_CALL3H,
OP_CALL4H,
OP_CALL5H,
OP_CALL6H, // 110
OP_CALL7H,
OP_CALL8H,
OP_STORE_I,
OP_STORE_IF,
OP_STORE_FI,
OP_ADD_I,
OP_ADD_FI,
OP_ADD_IF, // 110
OP_ADD_FI, // 110
OP_ADD_IF,
OP_SUB_I,
OP_SUB_FI,
@ -220,8 +206,8 @@ enum {
OP_CP_ITOF,
OP_CP_FTOI,
OP_LOAD_I,
OP_STOREP_I,
OP_STOREP_IF, // 120
OP_STOREP_I, // 120
OP_STOREP_IF,
OP_STOREP_FI,
OP_BITAND_I,
@ -233,9 +219,9 @@ enum {
OP_NE_I,
OP_IFNOTS,
OP_IFS,
OP_IFS, // 130
OP_NOT_I, // 130
OP_NOT_I,
OP_DIV_VF,
@ -243,13 +229,13 @@ enum {
OP_RSHIFT_I,
OP_LSHIFT_I,
OP_GLOBALADDRESS,
OP_POINTER_ADD, // 32 bit pointers
OP_GLOBAL_ADD,
OP_POINTER_ADD, // pointer to 32 bit (remember to *3 for vectors)
OP_LOADA_F,
OP_LOADA_V,
OP_LOADA_S,
OP_LOADA_ENT, // 140
OP_LOADA_S, // 140
OP_LOADA_ENT,
OP_LOADA_FLD,
OP_LOADA_FNC,
OP_LOADA_I,
@ -260,25 +246,25 @@ enum {
OP_LOADP_F,
OP_LOADP_V,
OP_LOADP_S,
OP_LOADP_ENT,
OP_LOADP_FLD, // 150
OP_LOADP_ENT, // 150
OP_LOADP_FLD,
OP_LOADP_FNC,
OP_LOADP_I,
OP_LE_I,
OP_GE_I,
OP_LT_I,
OP_GT_I,
OP_LE_I, // (int)c = (int)a <= (int)b;
OP_GE_I, // (int)c = (int)a >= (int)b;
OP_LT_I, // (int)c = (int)a < (int)b;
OP_GT_I, // (int)c = (int)a > (int)b;
OP_LE_IF,
OP_GE_IF,
OP_LT_IF,
OP_GT_IF, // 160
OP_LE_IF, // (float)c = (int)a <= (float)b;
OP_GE_IF, // (float)c = (int)a >= (float)b;
OP_LT_IF, // (float)c = (int)a < (float)b;
OP_GT_IF, // (float)c = (int)a > (float)b;
OP_LE_FI,
OP_GE_FI,
OP_LT_FI,
OP_GT_FI,
OP_LE_FI, // (float)c = (float)a <= (int)b;
OP_GE_FI, // (float)c = (float)a >= (int)b;
OP_LT_FI, // (float)c = (float)a < (int)b;
OP_GT_FI, // (float)c = (float)a > (int)b;
OP_EQ_IF,
OP_EQ_FI,
@ -296,8 +282,8 @@ enum {
OP_DIV_FI,
OP_BITAND_IF,
OP_BITOR_IF,
OP_BITAND_FI,
OP_BITOR_FI, // 180
OP_BITAND_FI, // 180
OP_BITOR_FI,
OP_AND_I,
OP_OR_I,
OP_AND_IF,
@ -306,11 +292,25 @@ enum {
OP_OR_FI,
OP_NE_IF,
OP_NE_FI,
OP_BOUNDCHECK, // bounds checker from dp
// back to ones that we do use.
OP_GSTOREP_I, // 190
OP_GSTOREP_F,
OP_GSTOREP_ENT,
OP_GSTOREP_FLD, // integers
OP_GSTOREP_S,
OP_GSTOREP_FNC, // pointers
OP_GSTOREP_V,
OP_GADDRESS,
OP_GLOAD_I,
OP_GLOAD_F,
OP_GLOAD_FLD, // 200
OP_GLOAD_ENT,
OP_GLOAD_S,
OP_GLOAD_FNC,
OP_GLOAD_V,
OP_BOUNDCHECK,
OP_STOREP_P, // 190
OP_STOREP_P, // back to ones that we do use.
OP_PUSH,
OP_POP,
@ -398,7 +398,7 @@ typedef struct
uint entityfields;
//debug / version 7 extensions
// version 7 extensions
uint ofsfiles; // non list format. no comp
uint ofslinenums; // numstatements big // comp 64
uint ofsbodylessfuncs; // no comp
@ -406,7 +406,7 @@ typedef struct
uint ofs_types; // comp 128
uint numtypes;
uint blockscompressed;
uint blockscompressed; // who blocks are compressed
int header; // strange "header", erh...
} dprograms_t;

View File

@ -24,7 +24,7 @@ if errorlevel 1 set BUILD_ERROR=1
%MSDEV% render/render.dsp %CONFIG%"render - Win32 Release" %build_target%
if errorlevel 1 set BUILD_ERROR=1
qcclib.exe -src vprogs -O3
qcclib.exe -src vprogs /Oz
if errorlevel 1 set BUILD_ERROR=1
if "%BUILD_ERROR%"=="" goto build_ok
@ -56,6 +56,6 @@ if exist server.dat move server.dat D:\Xash3D\xash\server.dat
echo Build succeeded!
echo Please wait. Xash is now loading
cd D:\Xash3D\
xash.exe +map qctest -debug -log
xash.exe +map qctest -debug -log -dev 4
rem bin\bsplib -game xash +map qctest -vis -rad -full -log
:done

View File

@ -73,10 +73,9 @@ Called when a player gets 'killed' by KILLED(); [DAMAGE.QC]
void(entity who_died, entity who_killed) ClientObiturary =
{
local string deathstring;
local string who;
local float rnum, msgdt, fragnum;
local float rnum, msgdt;
rnum = random();
rnum = random_float(0, 1);
if(who_died.flags & FL_CLIENT)
{
@ -294,19 +293,23 @@ void() PutClientInServer =
setstats( pev, STAT_HEALTH, ftoa(pev->health));
setstats( pev, STAT_HELPICON, "i_help");
precache_pic( "help" );
image_index( "help" );
GetLevelParms();
};
void HelpComputer( void )
{
string help = "xv 32 yv 8 picn help ";
float layout = 0;
string help;
float layout;
if(pev->showhelp == TRUE) pev->showhelp = FALSE;
else pev->showhelp == TRUE;
else pev->showhelp = TRUE;
if(pev->showhelp == TRUE) layout |= 1;
if(pev->showhelp == TRUE)
{
layout |= 1;
help = "xv 32 yv 8 picn help ";
}
else help = "";
if(pev->health > 0) layout |= 2;

60
vprogs/compile.log Normal file
View File

@ -0,0 +1,60 @@
=======================================================================
Xash3D QuakeC Compiler started at Sep30 2007 [23:56:40]
=======================================================================
--------------------Configuration: server - Vm16 Debug--------------------
Compiling...
defs.c
main.c
damage.c
player.c
client.c
dummys.c
ents/internal.c
ents/lights.c
ents/ambient.c
ents/ccam.c
ents/triggers/triggers.c
ents/triggers/trigger_generic.c
ents/triggers/trigger_once.c
ents/triggers/trigger_sequence.c
ents/triggers/trigger_message.c
ents/triggers/trigger_counter.c
ents/triggers/trigger_teleport.c
ents/triggers/trigger_hurt.c
ents/triggers/trigger_push.c
ents/triggers/trigger_changelevel.c
ents/triggers/trigger_setskill.c
ents/triggers/trigger_secret.c
ents/funcs/funcs.c
ents/funcs/func_mover.c
ents/funcs/func_door.c
ents/funcs/func_button.c
ents/funcs/func_path_corner.c
ents/funcs/func_train.c
ents/funcs/func_areaportal.c
ents/items/items.c
impulses.c
Xash3D virtual machine
19056 strofs (of 1000000)
2799 numstatements (of 524288)
281 numfunctions (of 16384)
916 numglobaldefs (of 32768)
245 numfielddefs (218 unique) (of 2048)
927 numpr_globals (of 65536)
Writing server.dat
64748 TOTAL SIZE
17 unique precache_sounds
3 unique precache_models
optres_shortenifnots 28
optres_overlaptemps 1284
optres_nonvec_parms 479
optres_assignments 40
optres_unreferenced 52
optres_dupconstdefs 68
‘ª®¯¨à®¢ ­® ä ©«®¢: 1.
server.dat - 0 error(s), 0 warning(s)
=======================================================================
Xash3D QuakeC Compiler stopped at Sep30 2007 [23:56:40]
=======================================================================

View File

@ -12,6 +12,7 @@
| refuse to run. |
+=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-+
*/
#pragma TARGET DEBUG
// These lines CANNOT be altered/moved
// pointers to ents

View File

@ -141,6 +141,5 @@ void barrel_spawn(string netname1, string model1, string deathmessage, float dam
void() misc_explobox =
{
float f, g;
barrel_spawn("Large exploding box", "models/barrel.mdl", " was blown up by an explosive box", 750);
};

View File

@ -42,23 +42,23 @@ Then sets it moving in its direction;
void() func_train_next =
{
local entity targ;
local entity next_targ;
targ = find (world, targetname, pev->target);
next_targ = find (world, targetname, pev->target);
pev->target = targ.target;
pev->target = next_targ->target;
if (!pev->target)
Error ("train_next: no next target\n");
if (targ.wait)
pev->wait = targ.wait;
if (next_targ.wait)
pev->wait = next_targ.wait;
else
pev->wait = 0;
//sound (pev, CHAN_VOICE, pev->noise1, 1, ATTN_NORM);
func_mover_move (targ.origin - pev->mins, pev->speed, func_train_wait);
func_mover_move (next_targ.origin - pev->mins, pev->speed, func_train_wait);
};
/*
@ -70,15 +70,15 @@ Called on spawning, this function finds the trains first target and sets the tra
void() func_train_find =
{
local entity targ;
local entity next_targ;
targ = find (world, targetname, pev->target);
next_targ = find (world, targetname, pev->target);
pev->target = targ.target;
pev->target = next_targ.target;
setorigin (pev, targ.origin - pev->mins);
setorigin (pev, next_targ.origin - pev->mins);
if (!pev->targetname) // not triggered, so start immediately
if (!pev->targetname) // not triggered, so start immediately
{
pev->nextthink = pev->ltime + 0.1;
pev->think = func_train_next;

View File

@ -39,7 +39,7 @@ void() SetMovedir =
void() IEM_usetarget =
{
local entity t, oldpev, oldother;
if(pev->target)
{
t = find(world, targetname, pev->target);

View File

@ -13,27 +13,22 @@ void() trigger_counter_use =
{
pev->count = pev->count - 1; //subtract my count by one; 'ive been triggered'
if(pev->count < 0)
return;
if(pev->count != 0)
{
if (pev->count >= 4)
centerprint (pev->triggerer, pev->targ1);
else if (pev->count == 3)
centerprint (pev->triggerer, pev->targ2);
else if (pev->count == 2)
centerprint (pev->triggerer, pev->targ3);
else
centerprint (pev->triggerer, pev->targ4);
if (pev->count >= 4) centerprint (pev->triggerer, pev->targ[0]);
else if (pev->count == 3) centerprint (pev->triggerer, pev->targ[1]);
else if (pev->count == 2) centerprint (pev->triggerer, pev->targ[2]);
else centerprint (pev->triggerer, pev->targ[3]);
}
if(pev->count <= 0)
{
IEM_usetarget();
IEM_usetarget();
if(!(pev->spawnflags & TRIGGER_ONCE)) //if im a trigger_once, remove me;
remove(pev);
else
pev->count = pev->wait1; //restore old count
if(pev->spawnflags & TRIGGER_ONCE) //if im a trigger_once, remove me;
remove(pev);
else pev->count = pev->twait[0]; //restore old count
}
};
void() trigger_counter =
@ -41,18 +36,18 @@ void() trigger_counter =
if(!pev->count) //If my count not set in map default it to 1;
pev->count = 1;
pev->wait1 = pev->count; //store count levels;
pev->twait[0] = pev->count; //store count levels;
pev->use = trigger_counter_use; //my use function;
if(!pev->targ1) //if a custom message is not set use the standard ones instead;
pev->targ1 = "There are more to go...";
if(!pev->targ2)
pev->targ2 = "Only 3 more to go...";
if(!pev->targ3)
pev->targ3 = "Only 2 more to go...";
if(!pev->targ4)
pev->targ4 = "Only 1 more to go...";
if(!pev->targ[0]) //if a custom message is not set use the standard ones instead;
pev->targ[0] = "There are more to go...";
if(!pev->targ[1])
pev->targ[1] = "Only 3 more to go...";
if(!pev->targ[2])
pev->targ[2] = "Only 2 more to go...";
if(!pev->targ[3])
pev->targ[3] = "Only 1 more to go...";
pev->classname = "t_counter";
};

View File

@ -57,5 +57,5 @@ void() trigger_generic =
pev->classname = "generic";
if(!pev->delay)
pev->delay = 0.1;
pev->delay = 2;
};

View File

@ -5,31 +5,10 @@
+======================+
*/
.string targ1;
.string targ2;
.string targ3;
.string targ4;
.string targ5;
.string targ6;
.string targ7;
.string targ8;
.string oldtarg1;
.string oldtarg2;
.string oldtarg3;
.string oldtarg4;
.string oldtarg5;
.string oldtarg6;
.string oldtarg7;
.string oldtarg8;
.string targ[8];
.string oldtarg[8];
.float wait1;
.float wait2;
.float wait3;
.float wait4;
.float wait5;
.float wait6;
.float wait7;
.float wait8;
.float twait[8];
.float olddelay;
void() trigger_sequence_think;
@ -51,95 +30,29 @@ void(string seq_a, float seq_b) trigger_sequence_think1 =
void() trigger_sequence_think =
{
local string a;
local float b;
local float b, i;
if(pev->touched == FALSE)
{
pev->oldtarg1 = pev->targ1;
pev->oldtarg2 = pev->targ2;
pev->oldtarg3 = pev->targ3;
pev->oldtarg4 = pev->targ4;
pev->oldtarg5 = pev->targ5;
pev->oldtarg6 = pev->targ6;
pev->oldtarg7 = pev->targ7;
pev->oldtarg8 = pev->targ8;
for( i = 0; i < 8; i++)
{
pev->oldtarg[i] = pev->targ[i];
}
pev->delay = pev->olddelay;
return;
}
if(pev->targ1)
for(i = 0; i < 8; i++)
{
a = pev->targ1;
b = pev->wait1;
if(pev->targ[i])
{
a = pev->targ[i];
b = pev->twait[i];
pev->targ1 = pev->oldtarg1;
trigger_sequence_think1(a,b);
return;
}
else if(pev->targ2)
{
a = pev->targ2;
b = pev->wait2;
pev->targ2 = pev->oldtarg2;
trigger_sequence_think1(a,b);
return;
}
else if(pev->targ3)
{
a = pev->targ3;
b = pev->wait3;
pev->targ3 = pev->oldtarg3;
trigger_sequence_think1(a,b);
return;
}
else if(pev->targ4)
{
a = pev->targ4;
b = pev->wait4;
pev->targ4 = pev->oldtarg4;
trigger_sequence_think1(a,b);
return;
}
else if(pev->targ5)
{
a = pev->targ5;
b = pev->wait5;
pev->targ5 = pev->oldtarg5;
trigger_sequence_think1(a,b);
return;
}
else if(pev->targ6)
{
a = pev->targ6;
b = pev->wait6;
pev->targ6 = pev->oldtarg6;
trigger_sequence_think1(a,b);
return;
}
else if(pev->targ7)
{
a = pev->targ7;
b = pev->wait7;
pev->targ7 = pev->oldtarg7;
trigger_sequence_think1(a,b);
return;
}
else if(pev->targ8)
{
a = pev->targ8;
b = pev->wait8;
pev->targ8 = pev->oldtarg8;
trigger_sequence_think1(a,b);
return;
pev->targ[i] = pev->oldtarg[i];
trigger_sequence_think1(a, b);
return;
}
}
pev->touched = FALSE;

View File

@ -100,8 +100,6 @@ This function is called when the world spawns.
void worldspawn( void )
{
vector skyaxis = '32 180 20';
MsgWarn("world spawned\n");
precaches();
LightStyles_setup();
@ -109,7 +107,7 @@ void worldspawn( void )
// CS_MAXCLIENTS already sended by engine
configstring (CS_STATUSBAR, single_statusbar );
configstring (CS_SKY, "sky" );
configstring (CS_SKYROTATE, ftoa( 0 )); // rotate speed
configstring (CS_SKYROTATE, ftoa( pev->speed )); // rotate speed
configstring (CS_SKYAXIS, vtoa( pev->angles )); // rotate axis
configstring (CS_CDTRACK, ftoa( 0 ));
}

View File

@ -14,7 +14,7 @@
// client_t->anim_priority
float ANIM_BASIC = 0; // stand / run
float ANIM_PAIN = 1;
float ANIM_PAIN = 1;
float ANIM_ATTACK = 2;
float ANIM_DEATH = 3;
@ -125,14 +125,14 @@ void() PainSound =
if (pev->watertype == CONTENT_WATER && pev->waterlevel == 3)
{ // water pain sounds
if (random() <= 0.5)
if (random_float(0,1) <= 0.5)
pev->noise = "player/drown1.wav";
else
pev->noise = "player/drown2.wav";
}
else if (pev->watertype == CONTENT_SLIME || pev->watertype == CONTENT_LAVA)
{ // slime/lava pain sounds
if (random() <= 0.5)
if (random_float(0,1) <= 0.5)
pev->noise = "player/lburn1.wav";
else
pev->noise = "player/lburn2.wav";
@ -149,7 +149,7 @@ void() PainSound =
pev->pain_finished = time + 0.5;
local float rs;
rs = rint((random() * 5) + 1); // rs = 1-6
rs = random_long(0, 5);
if (rs == 1)
pev->noise = "player/pain1.wav";
@ -186,7 +186,7 @@ void () PlayerPain =
void() DeathSound =
{
local float rs;
rs = rint ((random() * 4) + 1); // rs = 1-5
rs = random_long(0, 5);
if (pev->waterlevel == 3) // water death sound
pev->noise = "player/h2odeath.wav";
@ -213,11 +213,11 @@ void () PlayerDie =
pev->movetype = MOVETYPE_TOSS;
pev->aiflags = pev->aiflags - (pev->aiflags & AI_ONGROUND);
if (pev->velocity_z < 10)
pev->velocity_z = pev->velocity_z + random()*300;
pev->velocity_z = pev->velocity_z + random_long(30, 300);
local float rand;
rand = rint ((random() * 4) + 1); // rand = 1-5
rand = random_long(0, 5);
pev->anim_priority = ANIM_DEATH;
if (rand == 1)
{

BIN
vprogs/qcclib.exe Normal file

Binary file not shown.

1
vprogs/run.bat Normal file
View File

@ -0,0 +1 @@
qcclib -log -debug

BIN
vprogs/server.dat Normal file

Binary file not shown.

View File

@ -33,8 +33,8 @@ float rint (float v) = #19;
float floor(float v) = #20;
float ceil (float v) = #21;
float fabs (float f) = #22;
float random_long( void ) = #23;
float random_float( void ) = #24;
float random_long( float min, float max ) = #23;
float random_float( float min, float max ) = #24;
// vector mathlib
vector normalize(vector v) = #31; // normalize vector
@ -81,7 +81,7 @@ float precache_sound(string s) = #72;
float setmodel(entity e, string m) = #73;
float model_index(string s) = #74;
float decal_index(string s) = #75;
float model_frames(float modelindex) = #76;
float image_index(string s) = #76;
void setsize(entity e, vector min, vector max) = #77;
void changelevel(string mapname, string spotname) = #78;
void ChangeYaw( void ) = #79;
@ -112,5 +112,6 @@ void areaportal_state( float num, float state ) = #103;
void setstats(entity e, float f, string stats) = #104;
void configstring(float num, string s) = #105;
void makestatic(entity e) = #106;
string precache_pic(string pic) = #107;
float model_frames(float modelindex) = #107;