259 lines
5.5 KiB
C
259 lines
5.5 KiB
C
/*
|
|
Copyright (C) 1996-2001 Id Software, Inc.
|
|
Copyright (C) 2002-2009 John Fitzgibbons and others
|
|
Copyright (C) 2010-2014 QuakeSpasm developers
|
|
Copyright (C) 2019 Alison G. Watson
|
|
|
|
This program is free software; you can redistribute it and/or
|
|
modify it under the terms of the GNU General Public License
|
|
as published by the Free Software Foundation; either version 2
|
|
of the License, or (at your option) any later version.
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
|
|
See the GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with this program; if not, write to the Free Software
|
|
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
|
|
*/
|
|
|
|
#include "q_defs.h"
|
|
|
|
char const *pr_strings;
|
|
char const **pr_knownstrings;
|
|
int32_t pr_maxknownstrings;
|
|
int32_t pr_numknownstrings;
|
|
|
|
/*
|
|
============
|
|
PR_ValueString
|
|
(etype_t type, eval_t *val)
|
|
|
|
Returns a string describing *data in a type specific manner
|
|
=============
|
|
*/
|
|
const char *PR_ValueString(int32_t type, eval_t *val)
|
|
{
|
|
static char line[512];
|
|
ddef_t *def;
|
|
dfunction_t *f;
|
|
|
|
type &= ~DEF_SAVEGLOBAL;
|
|
|
|
switch(type)
|
|
{
|
|
case ev_string:
|
|
sprintf(line, "%s", PR_GetString(val->string));
|
|
break;
|
|
case ev_entity:
|
|
sprintf(line, "entity %" PRIi32 "", NUM_FOR_EDICT(PROG_TO_EDICT(val->edict)));
|
|
break;
|
|
case ev_function:
|
|
f = pr_functions + val->func;
|
|
sprintf(line, "%s()", PR_GetString(f->s_name));
|
|
break;
|
|
case ev_field:
|
|
def = ED_FieldAtOfs(val->field);
|
|
sprintf(line, ".%s", PR_GetString(def->s_name));
|
|
break;
|
|
case ev_void:
|
|
sprintf(line, "void");
|
|
break;
|
|
case ev_float:
|
|
sprintf(line, "%5.1f", val->flt);
|
|
break;
|
|
case ev_vector:
|
|
sprintf(line, "'%5.1f %5.1f %5.1f'", val->vec[0], val->vec[1], val->vec[2]);
|
|
break;
|
|
case ev_pointer:
|
|
sprintf(line, "pointer");
|
|
break;
|
|
default:
|
|
sprintf(line, "bad type %" PRIi32 "", type);
|
|
break;
|
|
}
|
|
|
|
return line;
|
|
}
|
|
|
|
/*
|
|
============
|
|
PR_UglyValueString
|
|
(etype_t type, eval_t *val)
|
|
|
|
Returns a string describing *data in a type specific manner
|
|
Easier to parse than PR_ValueString
|
|
=============
|
|
*/
|
|
const char *PR_UglyValueString(int32_t type, eval_t *val)
|
|
{
|
|
static char line[512];
|
|
ddef_t *def;
|
|
dfunction_t *f;
|
|
|
|
type &= ~DEF_SAVEGLOBAL;
|
|
|
|
switch(type)
|
|
{
|
|
case ev_string:
|
|
sprintf(line, "%s", PR_GetString(val->string));
|
|
break;
|
|
case ev_entity:
|
|
sprintf(line, "%" PRIi32 "", NUM_FOR_EDICT(PROG_TO_EDICT(val->edict)));
|
|
break;
|
|
case ev_function:
|
|
f = pr_functions + val->func;
|
|
sprintf(line, "%s", PR_GetString(f->s_name));
|
|
break;
|
|
case ev_field:
|
|
def = ED_FieldAtOfs(val->field);
|
|
sprintf(line, "%s", PR_GetString(def->s_name));
|
|
break;
|
|
case ev_void:
|
|
sprintf(line, "void");
|
|
break;
|
|
case ev_float:
|
|
sprintf(line, "%f", val->flt);
|
|
break;
|
|
case ev_vector:
|
|
sprintf(line, "%f %f %f", val->vec[0], val->vec[1], val->vec[2]);
|
|
break;
|
|
default:
|
|
sprintf(line, "bad type %" PRIi32 "", type);
|
|
break;
|
|
}
|
|
|
|
return line;
|
|
}
|
|
|
|
|
|
/*
|
|
============
|
|
PR_GlobalString
|
|
|
|
Returns a string with a description and the contents of a global,
|
|
padded to 20 field width
|
|
============
|
|
*/
|
|
const char *PR_GlobalString(int32_t ofs)
|
|
{
|
|
static char line[512];
|
|
const char *s;
|
|
int32_t i;
|
|
ddef_t *def;
|
|
void *val;
|
|
|
|
val = G_VOID(ofs);
|
|
def = ED_GlobalAtOfs(ofs);
|
|
if(!def)
|
|
sprintf(line, "%" PRIi32 "(?)", ofs);
|
|
else
|
|
{
|
|
s = PR_ValueString(def->type, (eval_t *)val);
|
|
sprintf(line, "%" PRIi32 "(%s)%s", ofs, PR_GetString(def->s_name), s);
|
|
}
|
|
|
|
i = strlen(line);
|
|
for(; i < 20; i++)
|
|
strcat(line, " ");
|
|
strcat(line, " ");
|
|
|
|
return line;
|
|
}
|
|
|
|
const char *PR_GlobalStringNoContents(int32_t ofs)
|
|
{
|
|
static char line[512];
|
|
int32_t i;
|
|
ddef_t *def;
|
|
|
|
def = ED_GlobalAtOfs(ofs);
|
|
if(!def)
|
|
sprintf(line, "%" PRIi32 "(?)", ofs);
|
|
else
|
|
sprintf(line, "%" PRIi32 "(%s)", ofs, PR_GetString(def->s_name));
|
|
|
|
i = strlen(line);
|
|
for(; i < 20; i++)
|
|
strcat(line, " ");
|
|
strcat(line, " ");
|
|
|
|
return line;
|
|
}
|
|
|
|
|
|
//===========================================================================
|
|
|
|
|
|
static void PR_AllocStringSlots(void)
|
|
{
|
|
pr_maxknownstrings += 256;
|
|
Con_DPrintf2("PR_AllocStringSlots: realloc'ing for %" PRIi32 " slots\n", pr_maxknownstrings);
|
|
pr_knownstrings = Z_Realloc(pr_knownstrings, pr_maxknownstrings * sizeof(*pr_knownstrings));
|
|
}
|
|
|
|
const char *PR_GetString(int32_t num)
|
|
{
|
|
if(num >= 0 && num < progs.numstrings)
|
|
return pr_strings + num;
|
|
else if(num < 0 && num >= -pr_numknownstrings)
|
|
{
|
|
if(!pr_knownstrings[-1 - num])
|
|
{
|
|
Host_Error("PR_GetString: attempt to get a non-existent string %" PRIi32 "\n", num);
|
|
return "";
|
|
}
|
|
return pr_knownstrings[-1 - num];
|
|
}
|
|
else
|
|
{
|
|
Host_Error("PR_GetString: invalid string offset %" PRIi32 "\n", num);
|
|
return "";
|
|
}
|
|
}
|
|
|
|
int32_t PR_SetEngineString(const char *s)
|
|
{
|
|
int32_t i;
|
|
|
|
if(!s)
|
|
return 0;
|
|
if(s >= pr_strings && s <= pr_strings + progs.numstrings - 2)
|
|
return (int32_t)(s - pr_strings);
|
|
for(i = 0; i < pr_numknownstrings; i++)
|
|
{
|
|
if(pr_knownstrings[i] == s)
|
|
return -1 - i;
|
|
}
|
|
if(i >= pr_maxknownstrings)
|
|
PR_AllocStringSlots();
|
|
pr_numknownstrings++;
|
|
pr_knownstrings[i] = s;
|
|
return -1 - i;
|
|
}
|
|
|
|
int32_t PR_AllocString(int32_t size, char **ptr)
|
|
{
|
|
int32_t i;
|
|
|
|
if(!size)
|
|
return 0;
|
|
for(i = 0; i < pr_numknownstrings; i++)
|
|
{
|
|
if(!pr_knownstrings[i])
|
|
break;
|
|
}
|
|
if(i >= pr_maxknownstrings)
|
|
PR_AllocStringSlots();
|
|
pr_numknownstrings++;
|
|
pr_knownstrings[i] = (char *)Hunk_AllocName(size, "string");
|
|
if(ptr)
|
|
*ptr = (char *) pr_knownstrings[i];
|
|
return -1 - i;
|
|
}
|
|
|