1
0
Fork 0
forked from fte/fteqw

try to fix a couple of misc issues, both minor and major.

git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@4665 fc73d0e0-1445-4013-8a0c-d673dee63da5
This commit is contained in:
Spoike 2014-05-20 02:23:37 +00:00
parent bacf9e90ba
commit eb91fc3ac7
11 changed files with 120 additions and 37 deletions

View file

@ -342,7 +342,15 @@ void QCBUILTIN PF_cl_runningserver (pubprogfuncs_t *prinst, struct globalvars_s
#ifdef CLIENTONLY
G_FLOAT(OFS_RETURN) = false;
#else
G_FLOAT(OFS_RETURN) = sv.state != ss_dead;
if (sv.state != ss_dead)
{
if (sv.allocated_client_slots > 1)
G_FLOAT(OFS_RETURN) = true;
else
G_FLOAT(OFS_RETURN) = 0.5; //give some half-way value if we're singleplayer. NOTE: DP returns 0 in this case, which is kinda useless for things like deciding whether a 'save' menu option can be used.
}
else
G_FLOAT(OFS_RETURN) = false;
#endif
}

View file

@ -1092,12 +1092,12 @@ void QCBUILTIN PF_cl_setkeydest (pubprogfuncs_t *prinst, struct globalvars_s *pr
{
case 0:
// key_game
if (cls.state == ca_disconnected)
Key_Dest_Add(kdm_console);
if (Key_Dest_Has(kdm_menu))
{
Key_Dest_Remove(kdm_menu);
Key_Dest_Remove(kdm_message);
// Key_Dest_Remove(kdm_message);
if (cls.state == ca_disconnected)
Key_Dest_Add(kdm_console);
}
break;
case 2:

View file

@ -33,7 +33,7 @@ extern conchar_t q3codemasks[MAXQ3COLOURS];
#define CON_NONCLEARBG 0x00800000 //disabled if CON_RICHFORECOLOUR
#define CON_HALFALPHA 0x00400000 //disabled if CON_RICHFORECOLOUR
#define CON_UNUSED2 0x00200000 //disabled if CON_RICHFORECOLOUR
#define CON_LINKSPECIAL 0x00200000 //disabled if CON_RICHFORECOLOUR
#define CON_UNUSED1 0x00100000 //disabled if CON_RICHFORECOLOUR
#define CON_HIDDEN 0x00080000
#define CON_BLINKTEXT 0x00040000
@ -46,20 +46,20 @@ extern conchar_t q3codemasks[MAXQ3COLOURS];
#define CON_FGMASK 0x0F000000
#define CON_BGMASK 0xF0000000
#define CON_FGSHIFT 24
#define CON_BGSHIFT 28
#define CON_FGSHIFT 24 //second highest nibble
#define CON_BGSHIFT 28 //high nibble
#define CON_RICHFOREMASK 0xFFF00000
#define CON_RICHBSHIFT 20
#define CON_RICHBSHIFT 20 //
#define CON_RICHGSHIFT 24
#define CON_RICHRSHIFT 28
#define CON_RICHRSHIFT 28 //high nibble
#define CON_Q3MASK 0x0F100000
#define CON_WHITEMASK 0x0F000000 // must be constant. things assume this
#define CON_DEFAULTCHAR (CON_WHITEMASK | 32)
#define CON_LINKSTART (CON_HIDDEN | '[')
#define CON_LINKEND (CON_HIDDEN | ']')
#define CON_LINKSTART (CON_LINKSPECIAL | CON_HIDDEN | '[')
#define CON_LINKEND (CON_LINKSPECIAL | CON_HIDDEN | ']')
// RGBI standard colors
#define COLOR_BLACK 0

View file

@ -3551,6 +3551,16 @@ void FS_BeginManifestUpdates(void)
}
#endif
qboolean FS_FoundManifest(void *usr, ftemanifest_t *man)
{
if (!*(ftemanifest_t**)usr)
{
*(ftemanifest_t**)usr = man;
return true;
}
return false;
}
//this is potentially unsafe. needs lots of testing.
qboolean FS_ChangeGame(ftemanifest_t *man, qboolean allowreloadconfigs)
{
@ -3611,6 +3621,10 @@ qboolean FS_ChangeGame(ftemanifest_t *man, qboolean allowreloadconfigs)
man = FS_GenerateLegacyManifest(newbasedir, sizeof(newbasedir), fixedbasedir, game);
}
if (!man && isDedicated)
{ //dedicated servers have no menu code, so just pick the first fmf we could find.
FS_EnumerateKnownGames(FS_FoundManifest, &man);
}
if (!man)
{
man = FS_Manifest_Parse(NULL,

View file

@ -1095,18 +1095,19 @@ void QCBUILTIN PF_memptradd (pubprogfuncs_t *prinst, struct globalvars_s *pr_glo
typedef struct
{
pubprogfuncs_t *prinst;
qboolean dupestrings;
etype_t defaulttype;
hashtable_t tab;
void *bucketmem;
} pf_hashtab_t;
typedef struct
{
bucket_t buck;
char *name;
bucket_t buck;
char *name;
etype_t type;
union
{
vec3_t data;
char *stringdata;
vec3_t data;
char *stringdata;
};
} pf_hashentry_t;
pf_hashtab_t pf_hashtab[MAX_QC_HASHTABLES];
@ -1148,7 +1149,14 @@ void QCBUILTIN PF_hash_delete (pubprogfuncs_t *prinst, struct globalvars_s *pr_g
ent = Hash_Get(&tab->tab, name);
if (ent)
{
memcpy(G_VECTOR(OFS_RETURN), ent->data, sizeof(vec3_t));
if (ent->type == ev_string)
{
G_INT(OFS_RETURN+2) = 0;
G_INT(OFS_RETURN+1) = 0;
RETURN_TSTRING(ent->stringdata);
}
else
memcpy(G_VECTOR(OFS_RETURN), ent->data, sizeof(vec3_t));
Hash_RemoveData(&tab->tab, name, ent);
BZ_Free(ent);
}
@ -1158,13 +1166,26 @@ void QCBUILTIN PF_hash_get (pubprogfuncs_t *prinst, struct globalvars_s *pr_glob
{
pf_hashtab_t *tab = PF_hash_findtab(prinst, G_FLOAT(OFS_PARM0));
const char *name = PR_GetStringOfs(prinst, OFS_PARM1);
void *dflt = G_VECTOR(OFS_PARM2);
int type = (prinst->callargc>3)?G_FLOAT(OFS_PARM3):0;
int index = (prinst->callargc>4)?G_FLOAT(OFS_PARM4):0;
pf_hashentry_t *ent = NULL;
if (tab)
{
ent = Hash_Get(&tab->tab, name);
//skip ones that are the wrong type.
while (type != 0 && ent && ent->type != type)
ent = Hash_GetNext(&tab->tab, name, ent);
//and ones that are not the match that we're after.
while(index-->0 && ent)
{
ent = Hash_GetNext(&tab->tab, name, ent);
while (type != 0 && ent && ent->type != type)
ent = Hash_GetNext(&tab->tab, name, ent);
}
if (ent)
{
if (tab->dupestrings)
if (ent->type == ev_string)
{
G_INT(OFS_RETURN+2) = 0;
G_INT(OFS_RETURN+1) = 0;
@ -1174,7 +1195,7 @@ void QCBUILTIN PF_hash_get (pubprogfuncs_t *prinst, struct globalvars_s *pr_glob
memcpy(G_VECTOR(OFS_RETURN), ent->data, sizeof(vec3_t));
}
else
memcpy(G_VECTOR(OFS_RETURN), G_VECTOR(OFS_PARM2), sizeof(vec3_t));
memcpy(G_VECTOR(OFS_RETURN), dflt, sizeof(vec3_t));
}
}
void QCBUILTIN PF_hash_getcb (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
@ -1199,19 +1220,23 @@ void QCBUILTIN PF_hash_add (pubprogfuncs_t *prinst, struct globalvars_s *pr_glob
pf_hashtab_t *tab = PF_hash_findtab(prinst, G_FLOAT(OFS_PARM0));
const char *name = PR_GetStringOfs(prinst, OFS_PARM1);
void *data = G_VECTOR(OFS_PARM2);
qboolean replace = (prinst->callargc>3)?G_FLOAT(OFS_PARM3):false;
int flags = (prinst->callargc>3)?G_FLOAT(OFS_PARM3):0;
int type = (prinst->callargc>4)?G_FLOAT(OFS_PARM4):0;
pf_hashentry_t *ent = NULL;
if (tab)
{
if (replace)
if (!type)
type = tab->defaulttype;
if (flags & 1)
Hash_Remove(&tab->tab, name);
if (tab->dupestrings)
{
if (type == ev_string)
{ //strings copy their value out.
const char *value = PR_GetStringOfs(prinst, OFS_PARM2);
int nlen = strlen(name);
int vlen = strlen(data);
ent = BZ_Malloc(sizeof(*ent) + nlen+1 + vlen+1);
ent->name = (char*)(ent+1);
ent->type = ev_string;
ent->stringdata = ent->name+(nlen+1);
memcpy(ent->name, name, nlen+1);
memcpy(ent->stringdata, value, vlen+1);
@ -1222,6 +1247,7 @@ void QCBUILTIN PF_hash_add (pubprogfuncs_t *prinst, struct globalvars_s *pr_glob
int nlen = strlen(name);
ent = BZ_Malloc(sizeof(*ent) + nlen + 1);
ent->name = (char*)(ent+1);
ent->type = type;
memcpy(ent->name, name, nlen+1);
memcpy(ent->data, data, sizeof(vec3_t));
Hash_Add(&tab->tab, ent->name, ent, &ent->buck);
@ -1247,13 +1273,16 @@ void QCBUILTIN PF_hash_createtab (pubprogfuncs_t *prinst, struct globalvars_s *p
int i;
int numbuckets = G_FLOAT(OFS_PARM0);
qboolean dupestrings = (prinst->callargc>1)?G_FLOAT(OFS_PARM1):false;
etype_t type = (prinst->callargc>2)?G_FLOAT(OFS_PARM2):ev_vector;
if (!type)
type = ev_vector;
if (numbuckets < 4)
numbuckets = 64;
for (i = 0; i < MAX_QC_HASHTABLES; i++)
{
if (!pf_hashtab[i].prinst)
{
pf_hashtab[i].dupestrings = dupestrings;
pf_hashtab[i].defaulttype = type;
pf_hashtab[i].prinst = prinst;
pf_hashtab[i].bucketmem = Z_Malloc(Hash_BytesForBuckets(numbuckets));
Hash_InitTable(&pf_hashtab[i].tab, numbuckets, pf_hashtab[i].bucketmem);
@ -1265,6 +1294,19 @@ void QCBUILTIN PF_hash_createtab (pubprogfuncs_t *prinst, struct globalvars_s *p
return;
}
void pf_hash_savegame(void) //write the persistant table to a saved game.
{
}
void pf_hash_loadgame(void) //(re)load the persistant table.
{
}
void pf_hash_preserve(void) //map changed, make sure it can be reset properly.
{
}
void pf_hash_purge(void) //restart command was used. revert to the state at the start of the map.
{
}
//hash table stuff
////////////////////////////////////////////////////
//File access
@ -2751,7 +2793,7 @@ void QCBUILTIN PF_strlennocol (pubprogfuncs_t *prinst, struct globalvars_s *pr_g
{
const char *in = PR_GetStringOfs(prinst, OFS_PARM0);
char result[8192];
unsigned int flagged[8192];
conchar_t flagged[8192];
unsigned int len = 0;
COM_ParseFunString(CON_WHITEMASK, in, flagged, sizeof(flagged), false);
COM_DeFunString(flagged, NULL, result, sizeof(result), true);
@ -2767,7 +2809,7 @@ void QCBUILTIN PF_strdecolorize (pubprogfuncs_t *prinst, struct globalvars_s *pr
{
const char *in = PR_GetStringOfs(prinst, OFS_PARM0);
char result[8192];
unsigned int flagged[8192];
conchar_t flagged[8192];
COM_ParseFunString(CON_WHITEMASK, in, flagged, sizeof(flagged), false);
COM_DeFunString(flagged, NULL, result, sizeof(result), true);

View file

@ -24,7 +24,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "winquake.h"
#include <conio.h>
#if defined(_DEBUG) || defined(DEBUG)
#if (defined(_DEBUG) || defined(DEBUG)) && !defined(SERVERONLY)
#define CATCHCRASH
LONG CALLBACK nonmsvc_CrashExceptionHandler(PEXCEPTION_POINTERS ExceptionInfo);

View file

@ -4456,7 +4456,7 @@ TRACE(("LoadBrushModel %i\n", __LINE__));
LightLoadEntities(lightmodel->entities);
#endif
TRACE(("LoadBrushModel %i\n", __LINE__));
if (1)
if (!isDedicated)
Mod_FixupMinsMaxs();
TRACE(("LoadBrushModel %i\n", __LINE__));

View file

@ -126,13 +126,26 @@ reeval:
break;
case OP_DIV_F:
OPC->_float = OPA->_float / OPB->_float;
/* if (!OPB->_float)
{
pr_xstatement = st-pr_statements;
printf ("Division by 0 in %s\n", PR_StringToNative(&progfuncs->funcs, pr_xfunction->s_name));
PR_StackTrace (&progfuncs->funcs);
}
*/ OPC->_float = OPA->_float / OPB->_float;
break;
case OP_DIV_VF:
tmpf = OPB->_float;
OPC->_vector[0] = tmpf / OPA->_vector[0];
OPC->_vector[1] = tmpf / OPA->_vector[1];
OPC->_vector[2] = tmpf / OPA->_vector[2];
/* if (!tmpf)
{
pr_xstatement = st-pr_statements;
printf ("Division by 0 in %s\n", PR_StringToNative(&progfuncs->funcs, pr_xfunction->s_name));
PR_StackTrace (&progfuncs->funcs);
}
*/
OPC->_vector[0] = OPA->_vector[0] / tmpf;
OPC->_vector[1] = OPA->_vector[1] / tmpf;
OPC->_vector[2] = OPA->_vector[2] / tmpf;
break;
case OP_BITAND_F:

View file

@ -9361,13 +9361,13 @@ BuiltinList_t BuiltinList[] = { //nq qw h2 ebfs
{"frametoname", PF_frametoname, 0, 0, 0, 284, "string(float modidx, float framenum)"},
{"skintoname", PF_skintoname, 0, 0, 0, 285, "string(float modidx, float skin)"},
// {"cvar_setlatch", PF_cvar_setlatch, 0, 0, 0, 286, "void(string cvarname, optional string value)"},
{"hash_createtab", PF_hash_createtab, 0, 0, 0, 287, D("float(float tabsize, float stringsonly)", "Creates a hash table object with at least 'tabsize' slots. stringsonly affects the behaviour of the other hash builtins. hash table with index 0 is a game-persistant table and will NEVER be returned by this builtin (except as an error return)")},
{"hash_createtab", PF_hash_createtab, 0, 0, 0, 287, D("float(float tabsize, optional float defaulttype)", "Creates a hash table object with at least 'tabsize' slots. hash table with index 0 is a game-persistant table and will NEVER be returned by this builtin (except as an error return).")},
{"hash_destroytab", PF_hash_destroytab, 0, 0, 0, 288, D("void(float table)", "Destroys a hash table object.")},
{"hash_add", PF_hash_add, 0, 0, 0, 289, D("void(float table, string name, __variant value, optional float replace)", "Adds the given key with the given value to the table. stringsonly=1: the value MUST be a string type, and will be internally copied. stringsonly=0: the value can be any type including vectors with the single exception that temp strings are not supported if their scope doesn't last as long as the string table. Its always okay to pass temp strings for 'name' though.\nreplace=0: Multiple values may be added for a single key, they won't overwrite.\nreplace=1: previous values with this key will be discarded first.")},
{"hash_get", PF_hash_get, 0, 0, 0, 290, D("__variant(float table, string name, __variant deflt)", "looks up the specified key name in the hash table. returns deflt if key was not found. If stringsonly=1, the return value will be in the form of a tempstring, otherwise it'll be the original value argument exactly as it was.")},
{"hash_add", PF_hash_add, 0, 0, 0, 289, D("void(float table, string name, __variant value, optional float flags, optional float type)", "Adds the given key with the given value to the table.\nIf flags&HASH_REPLACE, the old value will be removed, if not set then multiple values may be added for a single key, they won't overwrite.\nThe type argument describes how the value should be stored and saved to files. While you can claim that all variables are just vectors, being more precise can result in less issues with tempstrings or saved games.")},
{"hash_get", PF_hash_get, 0, 0, 0, 290, D("__variant(float table, string name, __variant deflt, optional float requiretype, optional float index)", "looks up the specified key name in the hash table. returns deflt if key was not found. If stringsonly=1, the return value will be in the form of a tempstring, otherwise it'll be the original value argument exactly as it was. If requiretype is specified, then values not of the specified type will be ignored. Hurrah for multiple types with the same name.")},
{"hash_delete", PF_hash_delete, 0, 0, 0, 291, D("__variant(float table, string name)", "removes the named key. returns the value of the object that was destroyed, or 0 on error.")},
{"hash_getkey", PF_hash_getkey, 0, 0, 0, 292, D("string(float table, float idx)", "gets some random key name. add+delete can change return values of this, so don't blindly increment the key index if you're removing all.")},
{"hash_getcb", PF_hash_getcb, 0, 0, 0, 293, D("void(float table, void(string keyname, __variant val) callback, optional string name)", "For each item in the table that matches the name, call the callback. if name is omitted, will enumerate ALL keys.")},
{"hash_getcb", PF_hash_getcb, 0, 0, 0, 293, D("void(float table, void(string keyname, __variant val) callback, optional string name)", "For each item in the table that matches the name, call the callback. if name is omitted, will enumerate ALL keys."), true},
{"checkcommand", PF_checkcommand, 0, 0, 0, 294, D("float(string name)", "Checks to see if the supplied name is a valid command, cvar, or alias. Returns 0 if it does not exist.")},
{"argescape", PF_argescape, 0, 0, 0, 295, D("string(string s)", "Marks up a string so that it can be reliably tokenized as a single argument later.")},
@ -10551,6 +10551,10 @@ void PR_DumpPlatform_f(void)
// {"EV_STRUCT", "const float", QW|NQ, NULL, ev_struct},
// {"EV_UNION", "const float", QW|NQ, NULL, ev_union},
{"HASHT_PERSISTANT", "const float", ALL, "Special hash table index for hash_add and hash_get. Entries in this table will persist over map changes (and doesn't need to be created/deleted).", 0},
{"HASH_REPLACE", "const float", ALL, "Used with hash_add. Attempts to remove the old value instead of adding two values for a single key.", 1},
{"HASH_STRING", "const float", ALL, "Used with hash_add. Specifies that the contents of the string argument should be internally zoned.", 2},
{"STAT_HEALTH", "const float", CS, NULL, STAT_HEALTH},
{"STAT_WEAPON", "const float", CS, NULL, STAT_WEAPON},
{"STAT_AMMO", "const float", CS, NULL, STAT_AMMO},

View file

@ -1107,6 +1107,8 @@ void SV_Savegame (char *savename)
FS_FlushFSHashReally();
}
#endif
FS_FlushFSHashReally();
}
void SV_Savegame_f (void)

View file

@ -427,7 +427,7 @@ void SV_DropClient (client_t *drop)
return;
}
if (!drop->controller && drop->netchan.remote_address.type != NA_LOOPBACK)
if (!drop->controller && drop->netchan.remote_address.type != NA_INVALID && drop->netchan.remote_address.type != NA_LOOPBACK)
{
// add the disconnect
if (drop->state < cs_connected)