mirror of
https://github.com/nzp-team/fteqw.git
synced 2024-11-25 05:11:35 +00:00
tweaked console completion to be less spammy and to show descriptions for commands where available.
added a few descriptions to a few cvars. tweaked strzone/strunzone, added memalloc/memfree/memcpy/memset (use pr_dumpplatform to dump out a new defs). tweaked android to use a smaller audio buffer, hopefully reducing latency slightly. let me know if this results in bugs... git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@4005 fc73d0e0-1445-4013-8a0c-d673dee63da5
This commit is contained in:
parent
8e77971422
commit
53116a9763
25 changed files with 616 additions and 185 deletions
|
@ -44,25 +44,25 @@ cvar_t rcon_address = SCVARF("rcon_address", "", CVAR_NOUNSAFEEXPAND);
|
|||
|
||||
cvar_t cl_timeout = SCVAR("cl_timeout", "60");
|
||||
|
||||
cvar_t cl_shownet = SCVAR("cl_shownet","0"); // can be 0, 1, or 2
|
||||
cvar_t cl_shownet = CVAR("cl_shownet","0", "Debugging var. 0 shows nothing. 1 shows incoming packet sizes. 2 shows individual messages. 3 shows entities too."); // can be 0, 1, or 2
|
||||
|
||||
cvar_t cl_pure = CVARD("cl_pure", "0", "If enabled, the filesystem will be restricted to allow only the content of the current server.");
|
||||
cvar_t cl_sbar = CVARFC("cl_sbar", "0", CVAR_ARCHIVE, CL_Sbar_Callback);
|
||||
cvar_t cl_hudswap = CVARF("cl_hudswap", "0", CVAR_ARCHIVE);
|
||||
cvar_t cl_maxfps = CVARF("cl_maxfps", "500", CVAR_ARCHIVE);
|
||||
cvar_t cl_idlefps = CVARF("cl_idlefps", "0", CVAR_ARCHIVE);
|
||||
cvar_t cl_yieldcpu = CVARF("cl_yieldcpu", "0", CVAR_ARCHIVE);
|
||||
cvar_t cl_idlefps = CVARF("cl_idlefps", "0", CVAR_ARCHIVE, "This is the maximum framerate to attain while idle/paused.");
|
||||
cvar_t cl_yieldcpu = CVARFD("cl_yieldcpu", "0", CVAR_ARCHIVE, "Attempt to yield between frames. This can resolve issues with certain drivers and background software, but can mean less consistant frame times. Will reduce power consumption/heat generation so should be set on laptops or similar (over-hot/battery powered) devices.");
|
||||
cvar_t cl_nopext = CVARF("cl_nopext", "0", CVAR_ARCHIVE);
|
||||
cvar_t cl_pext_mask = CVAR("cl_pext_mask", "0xffffffff");
|
||||
cvar_t cl_nolerp = CVARD("cl_nolerp", "0", "Disables interpolation. If set, missiles/monsters will be smoother, but they may be more laggy. Does not affect players. A value of 2 means 'interpolate only in single-player/coop'.");
|
||||
cvar_t cl_nolerp_netquake = CVARD("cl_nolerp_netquake", "0", "Disables interpolation when connected to an NQ server. Does affect players, even the local player. You probably don't want to set this.");
|
||||
cvar_t hud_tracking_show = CVAR("hud_tracking_show", "1");
|
||||
|
||||
cvar_t cl_defaultport = CVARAF("cl_defaultport", STRINGIFY(PORT_QWSERVER), "port", 0);
|
||||
cvar_t cl_defaultport = CVARAFD("cl_defaultport", STRINGIFY(PORT_QWSERVER), "port", 0, "The default port to connect to servers.\nQW: "STRINGIFY(PORT_QWSERVER)", NQ: "STRINGIFY(PORT_NQSERVER)", Q2: "STRINGIFY(PORT_Q2SERVER)".");
|
||||
|
||||
cvar_t cfg_save_name = CVARF("cfg_save_name", "fte", CVAR_ARCHIVE);
|
||||
|
||||
cvar_t cl_splitscreen = CVAR("cl_splitscreen", "0");
|
||||
cvar_t cl_splitscreen = CVARD("cl_splitscreen", "0", "Enables splitscreen support. See also: allow_splitscreen, in_rawinput*, the \"p\" command.");
|
||||
|
||||
cvar_t lookspring = CVARF("lookspring","0", CVAR_ARCHIVE);
|
||||
cvar_t lookstrafe = CVARF("lookstrafe","0", CVAR_ARCHIVE);
|
||||
|
@ -116,7 +116,7 @@ cvar_t noaim = CVARF("noaim", "", CVAR_ARCHIVE | CVAR_USERINFO);
|
|||
cvar_t msg = CVARF("msg", "1", CVAR_ARCHIVE | CVAR_USERINFO);
|
||||
cvar_t b_switch = CVARF("b_switch", "", CVAR_ARCHIVE | CVAR_USERINFO);
|
||||
cvar_t w_switch = CVARF("w_switch", "", CVAR_ARCHIVE | CVAR_USERINFO);
|
||||
cvar_t cl_nofake = CVAR("cl_nofake", "2");
|
||||
cvar_t cl_nofake = CVARD("cl_nofake", "2", "value 0: permits \\r chars in chat messages\nvalue 1: blocks all \\r chars\nvalue 2: allows \\r chars, but only from teammates");
|
||||
cvar_t cl_chatsound = CVAR("cl_chatsound","1");
|
||||
cvar_t cl_enemychatsound = CVAR("cl_enemychatsound", "misc/talk.wav");
|
||||
cvar_t cl_teamchatsound = CVAR("cl_teamchatsound", "misc/talk.wav");
|
||||
|
@ -152,7 +152,7 @@ cvar_t cl_countpendingpl = SCVAR("cl_countpendingpl", "0");
|
|||
cvar_t cl_standardchat = SCVARF("cl_standardchat", "0", CVAR_ARCHIVE);
|
||||
cvar_t msg_filter = SCVAR("msg_filter", "0"); //0 for neither, 1 for mm1, 2 for mm2, 3 for both
|
||||
cvar_t cl_standardmsg = SCVARF("cl_standardmsg", "0", CVAR_ARCHIVE);
|
||||
cvar_t cl_parsewhitetext = SCVAR("cl_parsewhitetext", "1");
|
||||
cvar_t cl_parsewhitetext = CVARD("cl_parsewhitetext", "1", "When parsing chat messages, enable support for messages like: red{white}red");
|
||||
|
||||
cvar_t cl_dlemptyterminate = SCVAR("cl_dlemptyterminate", "1");
|
||||
|
||||
|
@ -3770,6 +3770,8 @@ void Host_Init (quakeparms_t *parms)
|
|||
int i;
|
||||
int qrc, hrc, def;
|
||||
#endif
|
||||
extern cvar_t com_parseutf8;
|
||||
com_parseutf8.ival = 1;
|
||||
|
||||
COM_InitArgv (parms->argc, parms->argv);
|
||||
|
||||
|
|
|
@ -562,7 +562,6 @@ void Con_PrintCon (console_t *con, char *txt)
|
|||
conchar_t expanded[4096];
|
||||
conchar_t *c;
|
||||
conline_t *oc;
|
||||
static int cr;
|
||||
|
||||
COM_ParseFunString(CON_WHITEMASK, txt, expanded, sizeof(expanded), false);
|
||||
|
||||
|
@ -574,10 +573,10 @@ void Con_PrintCon (console_t *con, char *txt)
|
|||
switch (*c & (CON_CHARMASK))
|
||||
{
|
||||
case '\r':
|
||||
cr = true;
|
||||
con->cr = true;
|
||||
break;
|
||||
case '\n':
|
||||
cr = false;
|
||||
con->cr = false;
|
||||
while (con->linecount >= con_maxlines.ival)
|
||||
{
|
||||
if (con->oldest == con->current)
|
||||
|
@ -616,10 +615,10 @@ void Con_PrintCon (console_t *con, char *txt)
|
|||
con->display = con->current;
|
||||
break;
|
||||
default:
|
||||
if (cr)
|
||||
if (con->cr)
|
||||
{
|
||||
con->current->length = 0;
|
||||
cr = false;
|
||||
con->cr = false;
|
||||
}
|
||||
|
||||
if (selstartline == con->current)
|
||||
|
@ -798,9 +797,11 @@ DRAWING
|
|||
Con_DrawInput
|
||||
|
||||
The input line scrolls horizontally if typing goes beyond the right edge
|
||||
y is the bottom of the input
|
||||
return value is the top of the region
|
||||
================
|
||||
*/
|
||||
void Con_DrawInput (int left, int right, int y)
|
||||
int Con_DrawInput (int left, int right, int y)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
extern qboolean ActiveApp;
|
||||
|
@ -808,9 +809,9 @@ void Con_DrawInput (int left, int right, int y)
|
|||
int i;
|
||||
int lhs, rhs;
|
||||
int p;
|
||||
unsigned char *text, *fname;
|
||||
unsigned char *text, *fname = NULL;
|
||||
extern int con_commandmatch;
|
||||
conchar_t maskedtext[MAXCMDLINE];
|
||||
conchar_t maskedtext[2048];
|
||||
conchar_t *endmtext;
|
||||
conchar_t *cursor;
|
||||
conchar_t *cchar;
|
||||
|
@ -818,11 +819,13 @@ void Con_DrawInput (int left, int right, int y)
|
|||
|
||||
int x;
|
||||
|
||||
y -= Font_CharHeight();
|
||||
|
||||
if (key_dest != key_console && con_current->vislines != vid.height)
|
||||
return; // don't draw anything (always draw if not active)
|
||||
return y; // don't draw anything (always draw if not active)
|
||||
|
||||
if (!con_current->linebuffered)
|
||||
return; //fixme: draw any unfinished lines of the current console instead.
|
||||
return y; //fixme: draw any unfinished lines of the current console instead.
|
||||
|
||||
text = key_lines[edit_line];
|
||||
|
||||
|
@ -833,9 +836,9 @@ void Con_DrawInput (int left, int right, int y)
|
|||
|
||||
i = text[key_linepos];
|
||||
text[key_linepos] = 0;
|
||||
cursor = COM_ParseFunString(CON_WHITEMASK, text, maskedtext, sizeof(maskedtext)-1*sizeof(conchar_t), true);
|
||||
cursor = COM_ParseFunString(CON_WHITEMASK, text, maskedtext, sizeof(maskedtext) - sizeof(maskedtext[0]), true);
|
||||
text[key_linepos] = i;
|
||||
endmtext = COM_ParseFunString(CON_WHITEMASK, text, maskedtext, sizeof(maskedtext)-1*sizeof(conchar_t), true);
|
||||
endmtext = COM_ParseFunString(CON_WHITEMASK, text, maskedtext, sizeof(maskedtext) - sizeof(maskedtext[0]), true);
|
||||
|
||||
endmtext[1] = 0;
|
||||
|
||||
|
@ -859,9 +862,11 @@ void Con_DrawInput (int left, int right, int y)
|
|||
fname = Cmd_CompleteCommand(text+cmdstart, true, true, con_commandmatch);
|
||||
if (fname) //we can compleate it to:
|
||||
{
|
||||
for (p = key_linepos-cmdstart; fname[p]>' '; p++)
|
||||
for (p = min(strlen(fname), key_linepos-cmdstart); fname[p]>' '; p++)
|
||||
maskedtext[p+cmdstart] = (unsigned int)fname[p] | (COLOR_GREEN<<CON_FGSHIFT);
|
||||
maskedtext[p+cmdstart] = '\0';
|
||||
if (p < key_linepos-cmdstart)
|
||||
p = key_linepos-cmdstart;
|
||||
maskedtext[p+cmdstart] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -914,6 +919,81 @@ void Con_DrawInput (int left, int right, int y)
|
|||
{
|
||||
rhs = Font_DrawChar(rhs, y, *cchar);
|
||||
}
|
||||
|
||||
/*if its getting completed to something, show some help about the command that is going to be used*/
|
||||
if (!text[1])
|
||||
con_commandmatch = 0;
|
||||
if (con_commandmatch && Cmd_IsCommand(text+(text[1] == '/'?2:1)))
|
||||
{
|
||||
cvar_t *var;
|
||||
char *desc = NULL;
|
||||
if (!desc)
|
||||
{
|
||||
var = Cvar_FindVar(fname);
|
||||
if (var && var->description)
|
||||
desc = var->description;
|
||||
}
|
||||
if (!desc)
|
||||
{
|
||||
desc = Cmd_Describe(fname);
|
||||
}
|
||||
|
||||
if (desc)
|
||||
{
|
||||
int lines;
|
||||
conchar_t *starts[8];
|
||||
conchar_t *ends[8];
|
||||
conchar_t *end;
|
||||
end = maskedtext;
|
||||
|
||||
end = COM_ParseFunString((COLOR_YELLOW<<CON_FGSHIFT), va("%s: %s", fname, desc), end, (maskedtext+sizeof(maskedtext)/sizeof(maskedtext[0])-1-end)*sizeof(maskedtext[0]), true);
|
||||
lines = Font_LineBreaks(maskedtext, end, right - left, 8, starts, ends);
|
||||
while(lines-->0)
|
||||
{
|
||||
rhs = left;
|
||||
y -= Font_CharHeight();
|
||||
for (cchar = starts[lines]; cchar < ends[lines]; cchar++)
|
||||
{
|
||||
rhs = Font_DrawChar(rhs, y, *cchar);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*just above that, we have the tab completion list*/
|
||||
if (con_commandmatch && con_displaypossibilities.value)
|
||||
{
|
||||
int lines;
|
||||
conchar_t *starts[32];
|
||||
conchar_t *ends[32];
|
||||
conchar_t *end;
|
||||
char *cmd;
|
||||
int cmdstart;
|
||||
cmdstart = text[1] == '/'?2:1;
|
||||
end = maskedtext;
|
||||
|
||||
for (i = 1; ; i++)
|
||||
{
|
||||
cmd = Cmd_CompleteCommand (text+cmdstart, true, true, i);
|
||||
if (!cmd)
|
||||
break;
|
||||
|
||||
end = COM_ParseFunString((COLOR_GREEN<<CON_FGSHIFT), va("%s\t", cmd), end, (maskedtext+sizeof(maskedtext)/sizeof(maskedtext[0])-1-end)*sizeof(maskedtext[0]), true);
|
||||
}
|
||||
|
||||
lines = Font_LineBreaks(maskedtext, end, right - left, 32, starts, ends);
|
||||
while(lines-->0)
|
||||
{
|
||||
rhs = left;
|
||||
y -= Font_CharHeight();
|
||||
for (cchar = starts[lines]; cchar < ends[lines]; cchar++)
|
||||
{
|
||||
rhs = Font_DrawChar(rhs, y, *cchar);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return y;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1304,8 +1384,7 @@ void Con_DrawConsole (int lines, qboolean noback)
|
|||
|
||||
y -= Font_CharHeight();
|
||||
haveprogress = Con_DrawProgress(x, ex - x, y) != y;
|
||||
y -= Font_CharHeight();
|
||||
Con_DrawInput (x, ex - x, y);
|
||||
y = Con_DrawInput (x, ex - x, y);
|
||||
|
||||
if (selactive)
|
||||
{
|
||||
|
|
|
@ -266,9 +266,9 @@ int rawkbdcount;
|
|||
RAWINPUT *raw;
|
||||
int ribuffersize;
|
||||
|
||||
cvar_t in_rawinput = SCVAR("in_rawinput", "0");
|
||||
cvar_t in_rawinput_keyboard = SCVAR("in_rawinput_keyboard", "0");
|
||||
cvar_t in_rawinput_rdp = SCVAR("in_rawinput_rdp", "0");
|
||||
cvar_t in_rawinput = CVARD("in_rawinput", "0", "Enables rawinput support for mice in XP onwards. Rawinput permits independant device identification (ie: splitscreen clients can each have their own mouse)");
|
||||
cvar_t in_rawinput_keyboard = SCVAR("in_rawinput_keyboard", "0", "Enables rawinput support for keyboards in XP onwards as well as just mice. Requires in_rawinput to be set.");
|
||||
cvar_t in_rawinput_rdp = CVARD("in_rawinput_rdp", "0", "Activate Remote Desktop Protocol devices too.");
|
||||
|
||||
void IN_RawInput_MouseDeRegister(void);
|
||||
int IN_RawInput_MouseRegister(void);
|
||||
|
|
|
@ -251,7 +251,7 @@ qboolean Cmd_IsCommand (char *line)
|
|||
|
||||
int PaddedPrint (char *s, int x)
|
||||
{
|
||||
Con_Printf ("%s\t", s);
|
||||
Con_Printf ("^4%s\t", s);
|
||||
x+=strlen(s);
|
||||
|
||||
return x;
|
||||
|
@ -268,22 +268,6 @@ void CompleteCommand (qboolean force)
|
|||
if (*s == '\\' || *s == '/')
|
||||
s++;
|
||||
|
||||
if (!force && con_displaypossibilities.value)
|
||||
{
|
||||
int x=0;
|
||||
for (i = 1; ; i++)
|
||||
{
|
||||
cmd = Cmd_CompleteCommand (s, true, true, i);
|
||||
if (!cmd)
|
||||
break;
|
||||
if (i == 1)
|
||||
Con_Printf("---------\n");
|
||||
x = PaddedPrint(cmd, x);
|
||||
}
|
||||
if (i != 1)
|
||||
Con_Printf("\n");
|
||||
}
|
||||
|
||||
cmd = Cmd_CompleteCommand (s, true, true, 2);
|
||||
if (!cmd || force)
|
||||
{
|
||||
|
@ -311,6 +295,8 @@ void CompleteCommand (qboolean force)
|
|||
}
|
||||
}
|
||||
key_lines[edit_line][key_linepos] = 0;
|
||||
if (!con_commandmatch)
|
||||
con_commandmatch = 1;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -330,6 +316,8 @@ void CompleteCommand (qboolean force)
|
|||
|
||||
key_lines[edit_line][key_linepos] = 0;
|
||||
|
||||
if (!con_commandmatch)
|
||||
con_commandmatch = 1;
|
||||
return; //don't alter con_commandmatch if we compleated a tiny bit more
|
||||
}
|
||||
}
|
||||
|
@ -533,7 +521,7 @@ void Key_Console (unsigned int unicode, int key)
|
|||
CompleteCommand (false);
|
||||
return;
|
||||
}
|
||||
if (key != K_SHIFT)
|
||||
if (key != K_SHIFT && con_commandmatch)
|
||||
con_commandmatch=1;
|
||||
|
||||
if (key == K_LEFTARROW)
|
||||
|
|
|
@ -1843,6 +1843,11 @@ static void P_ImportEffectInfo_f(void)
|
|||
ptype->looks.type = PT_BEAM;
|
||||
ptype->looks.blendmode = BM_ADD;
|
||||
}
|
||||
// else if (!strcmp(arg[1], "snow"))
|
||||
// {
|
||||
// ptype->looks.type = PT_NORMAL;
|
||||
// ptype->looks.blendmode = BM_BLEND;
|
||||
// }
|
||||
else
|
||||
{
|
||||
Con_Printf("effectinfo type %s not supported\n", arg[1]);
|
||||
|
@ -1963,6 +1968,8 @@ static void P_ImportEffectInfo_f(void)
|
|||
;
|
||||
else if (!strcmp(arg[0], "rotate") && args == 2)
|
||||
;
|
||||
else if (!strcmp(arg[0], "rotate") && args == 4)
|
||||
;
|
||||
#endif
|
||||
else
|
||||
Con_Printf("Particle effect token not recognised, or invalid args: %s %s %s %s %s %s\n", arg[0], args<2?"":arg[1], args<3?"":arg[2], args<4?"":arg[3], args<5?"":arg[4], args<6?"":arg[5]);
|
||||
|
|
|
@ -4334,6 +4334,12 @@ static struct {
|
|||
{"skel_ragupdate", PF_skel_ragedit, 281},// (FTE_QC_RAGDOLL)
|
||||
{"skel_mmap", PF_skel_mmap, 282},// (FTE_QC_RAGDOLL)
|
||||
{"skel_set_bone_world", PF_skel_set_bone_world, 283},
|
||||
|
||||
{"memalloc", PF_memalloc, 384},
|
||||
{"memfree", PF_memfree, 385},
|
||||
{"memcpy", PF_memcpy, 386},
|
||||
{"memset", PF_memset, 387},
|
||||
|
||||
//300
|
||||
{"clearscene", PF_R_ClearScene, 300}, // #300 void() clearscene (EXT_CSQC)
|
||||
{"addentities", PF_R_AddEntityMask, 301}, // #301 void(float mask) addentities (EXT_CSQC)
|
||||
|
|
|
@ -1756,6 +1756,8 @@ void Surf_SetupFrame(void)
|
|||
leaf = RMod_PointInLeaf (cl.worldmodel, r_origin);
|
||||
r_viewcluster = r_viewcluster2 = leaf->cluster;
|
||||
|
||||
r_viewcontents = 0;//leaf->contents;
|
||||
|
||||
// check above and below so crossing solid water doesn't draw wrong
|
||||
if (!leaf->contents)
|
||||
{ // look down a bit
|
||||
|
@ -1779,8 +1781,6 @@ void Surf_SetupFrame(void)
|
|||
(leaf->cluster != r_viewcluster2) )
|
||||
r_viewcluster2 = leaf->cluster;
|
||||
}
|
||||
|
||||
r_viewcontents = leaf->contents;
|
||||
}
|
||||
#endif
|
||||
else if (cl.worldmodel && cl.worldmodel->fromgame == fg_doom3)
|
||||
|
|
|
@ -239,8 +239,11 @@ cvar_t gl_contrast = CVAR ("gl_contrast", "1");
|
|||
cvar_t gl_detail = CVARF ("gl_detail", "0",
|
||||
CVAR_ARCHIVE);
|
||||
cvar_t gl_detailscale = CVAR ("gl_detailscale", "5");
|
||||
cvar_t gl_font = CVARF ("gl_font", "",
|
||||
CVAR_RENDERERCALLBACK);
|
||||
cvar_t gl_font = CVARFD ("gl_font", "",
|
||||
CVAR_RENDERERCALLBACK, ("Specifies the font file to use. a value such as FONT:ALTFONT specifies an alternative font to be used when ^^a is used."
|
||||
"When using TTF fonts, you will likely need to scale text to at least 150% - vid_conautoscale 1.5 will do this."
|
||||
"TTF fonts may be loaded from your windows directory. \'gl_font cour\' loads eg: c:\\windows\\fonts\\cour.ttf."
|
||||
));
|
||||
cvar_t gl_lateswap = CVAR ("gl_lateswap", "0");
|
||||
cvar_t gl_lerpimages = CVARF ("gl_lerpimages", "1", CVAR_ARCHIVE);
|
||||
//cvar_t gl_lightmapmode = SCVARF("gl_lightmapmode", "",
|
||||
|
|
|
@ -106,7 +106,7 @@ void Font_BeginScaledString(struct font_s *font, float vx, float vy, float *px,
|
|||
void Font_Transform(int vx, int vy, int *px, int *py);
|
||||
int Font_CharHeight(void);
|
||||
int Font_CharWidth(unsigned int charcode);
|
||||
int Font_CharEndCoord(int x, unsigned int charcode);
|
||||
int Font_CharEndCoord(struct font_s *font, int x, unsigned int charcode);
|
||||
int Font_DrawChar(int px, int py, unsigned int charcode);
|
||||
float Font_DrawScaleChar(float px, float py, float cw, float ch, unsigned int charcode); /*avoid using*/
|
||||
void Font_EndString(struct font_s *font);
|
||||
|
|
|
@ -80,20 +80,20 @@ cvar_t snd_noextraupdate = CVARAF( "s_noextraupdate", "0",
|
|||
"snd_noextraupdate", 0);
|
||||
cvar_t snd_show = CVARAF( "s_show", "0",
|
||||
"snd_show", 0);
|
||||
cvar_t snd_khz = CVARAF( "s_khz", "44",
|
||||
"snd_khz", CVAR_ARCHIVE);
|
||||
cvar_t snd_khz = CVARAFD( "s_khz", "44",
|
||||
"snd_khz", CVAR_ARCHIVE, "Sound speed, in kilohertz. Common values are 11, 22, 44, 48.");
|
||||
cvar_t snd_inactive = CVARAFD( "s_inactive", "0",
|
||||
"snd_inactive", 0,
|
||||
"Play sound while application is inactive (ex. tabbed out)."
|
||||
"Play sound while application is inactive (ex. tabbed out). Needs a snd_restart if changed."
|
||||
); //set if you want sound even when tabbed out.
|
||||
cvar_t _snd_mixahead = CVARAF( "s_mixahead", "0.08",
|
||||
"_snd_mixahead", CVAR_ARCHIVE);
|
||||
cvar_t _snd_mixahead = CVARAFD( "s_mixahead", "0.08",
|
||||
"_snd_mixahead", CVAR_ARCHIVE, "Specifies how many seconds to prebuffer audio. Lower values give less latency, but might result in crackling. Different hardware/drivers have different tolerances.");
|
||||
cvar_t snd_leftisright = CVARAF( "s_swapstereo", "0",
|
||||
"snd_leftisright", CVAR_ARCHIVE);
|
||||
cvar_t snd_eax = CVARAF( "s_eax", "0",
|
||||
"snd_eax", 0);
|
||||
cvar_t snd_speakers = CVARAF( "s_numspeakers", "2",
|
||||
"snd_numspeakers", 0);
|
||||
cvar_t snd_speakers = CVARAFD( "s_numspeakers", "2",
|
||||
"snd_numspeakers", 0, "Number of hardware audio channels to use. "DISTRIBUTION" supports up to 6.");
|
||||
cvar_t snd_buffersize = CVARAF( "s_buffersize", "0",
|
||||
"snd_buffersize", 0);
|
||||
cvar_t snd_samplebits = CVARAF( "s_bits", "16",
|
||||
|
@ -109,8 +109,8 @@ cvar_t snd_linearresample = CVARAF( "s_linearresample", "1",
|
|||
cvar_t snd_linearresample_stream = CVARAF( "s_linearresample_stream", "0",
|
||||
"snd_linearresample_stream", 0);
|
||||
|
||||
cvar_t snd_usemultipledevices = CVARAF( "s_multipledevices", "0",
|
||||
"snd_multipledevices", 0);
|
||||
cvar_t snd_usemultipledevices = CVARAFD( "s_multipledevices", "0",
|
||||
"snd_multipledevices", 0, "If enabled, all output sound devices in your computer will be initialised for playback, not just the default device.");
|
||||
cvar_t snd_driver = CVARAF( "s_driver", "",
|
||||
"snd_driver", 0);
|
||||
|
||||
|
|
|
@ -988,6 +988,7 @@ typedef struct cmd_function_s
|
|||
{
|
||||
struct cmd_function_s *next;
|
||||
char *name;
|
||||
char *description;
|
||||
xcommand_t function;
|
||||
|
||||
qbyte restriction; //restriction of admin level
|
||||
|
@ -1679,6 +1680,23 @@ qboolean Cmd_Exists (char *cmd_name)
|
|||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
============
|
||||
Cmd_Exists
|
||||
============
|
||||
*/
|
||||
char *Cmd_Describe (char *cmd_name)
|
||||
{
|
||||
cmd_function_t *cmd;
|
||||
|
||||
for (cmd=cmd_functions ; cmd ; cmd=cmd->next)
|
||||
{
|
||||
if (!Q_strcmp (cmd_name,cmd->name))
|
||||
return cmd->description;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
|
@ -1734,8 +1752,13 @@ char *Cmd_CompleteCommand (char *partial, qboolean fullonly, qboolean caseinsens
|
|||
|
||||
cvar_group_t *grp;
|
||||
cvar_t *cvar;
|
||||
char *sp;
|
||||
|
||||
len = Q_strlen(partial);
|
||||
sp = strchr(partial, ' ');
|
||||
if (sp)
|
||||
len = sp - partial;
|
||||
else
|
||||
len = Q_strlen(partial);
|
||||
|
||||
if (!len)
|
||||
return NULL;
|
||||
|
@ -1756,17 +1779,17 @@ char *Cmd_CompleteCommand (char *partial, qboolean fullonly, qboolean caseinsens
|
|||
if (caseinsens)
|
||||
{
|
||||
for (cmd=cmd_functions ; cmd ; cmd=cmd->next)
|
||||
if (!Q_strncasecmp (partial,cmd->name, len))
|
||||
if (!Q_strncasecmp (partial,cmd->name, len) && (matchnum == -1 || !partial[len] || strlen(cmd->name) == len))
|
||||
Cmd_CompleteCheck(cmd->name, &match);
|
||||
for (a=cmd_alias ; a ; a=a->next)
|
||||
if (!Q_strncasecmp (partial, a->name, len))
|
||||
if (!Q_strncasecmp (partial, a->name, len) && (matchnum == -1 || !partial[len] || strlen(a->name) == len))
|
||||
Cmd_CompleteCheck(a->name, &match);
|
||||
for (grp=cvar_groups ; grp ; grp=grp->next)
|
||||
for (cvar=grp->cvars ; cvar ; cvar=cvar->next)
|
||||
{
|
||||
if (!Q_strncasecmp (partial,cvar->name, len))
|
||||
if (!Q_strncasecmp (partial,cvar->name, len) && (matchnum == -1 || !partial[len] || strlen(cvar->name) == len))
|
||||
Cmd_CompleteCheck(cvar->name, &match);
|
||||
if (cvar->name2 && !Q_strncasecmp (partial,cvar->name2, len))
|
||||
if (cvar->name2 && !Q_strncasecmp (partial,cvar->name2, len) && (matchnum == -1 || !partial[len] || strlen(cvar->name2) == len))
|
||||
Cmd_CompleteCheck(cvar->name2, &match);
|
||||
}
|
||||
|
||||
|
@ -1774,17 +1797,17 @@ char *Cmd_CompleteCommand (char *partial, qboolean fullonly, qboolean caseinsens
|
|||
else
|
||||
{
|
||||
for (cmd=cmd_functions ; cmd ; cmd=cmd->next)
|
||||
if (!Q_strncmp (partial,cmd->name, len))
|
||||
if (!Q_strncmp (partial,cmd->name, len) && (matchnum == -1 || !partial[len] || strlen(cmd->name) == len))
|
||||
Cmd_CompleteCheck(cmd->name, &match);
|
||||
for (a=cmd_alias ; a ; a=a->next)
|
||||
if (!Q_strncmp (partial, a->name, len))
|
||||
if (!Q_strncmp (partial, a->name, len) && (matchnum == -1 || !partial[len] || strlen(a->name) == len))
|
||||
Cmd_CompleteCheck(a->name, &match);
|
||||
for (grp=cvar_groups ; grp ; grp=grp->next)
|
||||
for (cvar=grp->cvars ; cvar ; cvar=cvar->next)
|
||||
{
|
||||
if (!Q_strncmp (partial,cvar->name, len))
|
||||
if (!Q_strncmp (partial,cvar->name, len) && (matchnum == -1 || !partial[len] || strlen(cvar->name) == len))
|
||||
Cmd_CompleteCheck(cvar->name, &match);
|
||||
if (cvar->name2 && !Q_strncmp (partial,cvar->name2, len))
|
||||
if (cvar->name2 && !Q_strncmp (partial,cvar->name2, len) && (matchnum == -1 || !partial[len] || strlen(cvar->name2) == len))
|
||||
Cmd_CompleteCheck(cvar->name2, &match);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -84,6 +84,8 @@ qboolean Cmd_AddCommand (char *cmd_name, xcommand_t function);
|
|||
qboolean Cmd_Exists (char *cmd_name);
|
||||
// used by the cvar code to check for cvar / command name overlap
|
||||
|
||||
char *Cmd_Describe (char *cmd_name);
|
||||
|
||||
char *Cmd_CompleteCommand (char *partial, qboolean fullonly, qboolean caseinsens, int matchnum);
|
||||
qboolean Cmd_IsCommand (char *line);
|
||||
// attempts to match a partial command for automatic command line completion
|
||||
|
|
|
@ -112,6 +112,7 @@ typedef struct console_s
|
|||
conline_t *oldest;
|
||||
conline_t *current; // line where next message will be printed
|
||||
int x; // offset in current line for next print
|
||||
int cr;
|
||||
conline_t *display; // bottom of console displays this line
|
||||
int subline;
|
||||
int vislines; // pixel lines
|
||||
|
|
|
@ -84,7 +84,11 @@ typedef struct cvar_s
|
|||
bucket_t hbn1, hbn2;
|
||||
} cvar_t;
|
||||
|
||||
#ifdef MINIMAL
|
||||
#define CVARAFDC(ConsoleName,Value,ConsoleName2,Flags,Description,Callback) {ConsoleName, Value, NULL, Flags, 0, 0, 0, ConsoleName2, Callback, NULL}
|
||||
#else
|
||||
#define CVARAFDC(ConsoleName,Value,ConsoleName2,Flags,Description,Callback) {ConsoleName, Value, NULL, Flags, 0, 0, 0, ConsoleName2, Callback, Description}
|
||||
#endif
|
||||
#define CVARAFD(ConsoleName,Value,ConsoleName2,Flags,Description)CVARAFDC(ConsoleName, Value, ConsoleName2, Flags, Description, NULL)
|
||||
#define CVARAFC(ConsoleName,Value,ConsoleName2,Flags,Callback) CVARAFC(ConsoleName, Value, ConsoleName2, Flags, NULL, Callback)
|
||||
#define CVARAF(ConsoleName,Value,ConsoleName2,Flags) CVARAFDC(ConsoleName, Value, ConsoleName2, Flags, NULL, NULL)
|
||||
|
|
|
@ -186,12 +186,12 @@ void SockadrToNetadr (struct sockaddr_qstorage *s, netadr_t *a)
|
|||
a->port = ((struct sockaddr_ipx *)s)->sa_socket;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
Con_Printf("SockadrToNetadr: bad socket family - %i", ((struct sockaddr*)s)->sa_family);
|
||||
case AF_UNSPEC:
|
||||
memset(a, 0, sizeof(*a));
|
||||
a->type = NA_INVALID;
|
||||
break;
|
||||
default:
|
||||
Sys_Error("SockadrToNetadr: bad socket family");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -293,7 +293,9 @@ qboolean NET_CompareBaseAdr (netadr_t a, netadr_t b)
|
|||
|
||||
qboolean NET_AddressSmellsFunny(netadr_t a)
|
||||
{
|
||||
#ifdef IPPROTO_IPV6
|
||||
int i;
|
||||
#endif
|
||||
|
||||
//rejects certain blacklisted addresses
|
||||
switch(a.type)
|
||||
|
@ -342,9 +344,11 @@ qboolean NET_AddressSmellsFunny(netadr_t a)
|
|||
char *NET_AdrToString (char *s, int len, netadr_t a)
|
||||
{
|
||||
char *rs = s;
|
||||
qboolean doneblank;
|
||||
char *p;
|
||||
int i;
|
||||
#ifdef IPPROTO_IPV6
|
||||
qboolean doneblank;
|
||||
#endif
|
||||
|
||||
switch(a.type)
|
||||
{
|
||||
|
@ -1577,6 +1581,12 @@ int FTENET_Generic_GetLocalAddress(ftenet_generic_connection_t *con, netadr_t *o
|
|||
continue;
|
||||
}
|
||||
|
||||
if (itr->ai_addr->sa_family == AF_INET
|
||||
|| itr->ai_addr->sa_family == AF_INET6
|
||||
#ifdef USEIPX
|
||||
|| itr->ai_addr->sa_family == AF_IPX
|
||||
#endif
|
||||
)
|
||||
if (idx++ == count)
|
||||
{
|
||||
SockadrToNetadr((struct sockaddr_qstorage*)itr->ai_addr, out);
|
||||
|
@ -1831,7 +1841,7 @@ ftenet_generic_connection_t *FTENET_Generic_EstablishConnection(int adrfamily, i
|
|||
temp = NetadrToSockadr(&adr, &qs);
|
||||
family = ((struct sockaddr*)&qs)->sa_family;
|
||||
|
||||
#ifdef IPV6_V6ONLY
|
||||
#if defined(IPPROTO_IPV6) && defined(IPV6_V6ONLY)
|
||||
if (isserver && family == AF_INET && net_hybriddualstack.ival && !((struct sockaddr_in*)&qs)->sin_addr.s_addr)
|
||||
{
|
||||
unsigned long _false = false;
|
||||
|
@ -1875,7 +1885,7 @@ ftenet_generic_connection_t *FTENET_Generic_EstablishConnection(int adrfamily, i
|
|||
return NULL;
|
||||
}
|
||||
|
||||
#ifdef IPV6_V6ONLY
|
||||
#if defined(IPPROTO_IPV6) && defined(IPV6_V6ONLY)
|
||||
if (family == AF_INET6)
|
||||
setsockopt(newsocket, IPPROTO_IPV6, IPV6_V6ONLY, (char *)&_true, sizeof(_true));
|
||||
#endif
|
||||
|
|
|
@ -715,6 +715,47 @@ void QCBUILTIN PF_registercvar (progfuncs_t *prinst, struct globalvars_s *pr_glo
|
|||
|
||||
//Cvars
|
||||
////////////////////////////////////////////////////
|
||||
//memory stuff
|
||||
void QCBUILTIN PF_memalloc (progfuncs_t *prinst, struct globalvars_s *pr_globals)
|
||||
{
|
||||
void *ptr = prinst->AddressableAlloc(prinst, G_INT(OFS_PARM0));
|
||||
G_INT(OFS_RETURN) = (char*)ptr - prinst->stringtable;
|
||||
}
|
||||
void QCBUILTIN PF_memfree (progfuncs_t *prinst, struct globalvars_s *pr_globals)
|
||||
{
|
||||
prinst->AddressableFree(prinst, prinst->stringtable + G_INT(OFS_PARM0));
|
||||
}
|
||||
void QCBUILTIN PF_memcpy (progfuncs_t *prinst, struct globalvars_s *pr_globals)
|
||||
{
|
||||
int dst = G_INT(OFS_PARM0);
|
||||
int src = G_INT(OFS_PARM1);
|
||||
int size = G_INT(OFS_PARM2);
|
||||
if (dst < 0 || dst+size >= prinst->stringtablesize)
|
||||
{
|
||||
PR_BIError(prinst, "PF_memcpy: invalid dest\n");
|
||||
return;
|
||||
}
|
||||
if (src < 0 || src+size >= prinst->stringtablesize)
|
||||
{
|
||||
PR_BIError(prinst, "PF_memcpy: invalid source\n");
|
||||
return;
|
||||
}
|
||||
memcpy(prinst->stringtable + dst, prinst->stringtable + src, size);
|
||||
}
|
||||
void QCBUILTIN PF_memset (progfuncs_t *prinst, struct globalvars_s *pr_globals)
|
||||
{
|
||||
int dst = G_INT(OFS_PARM0);
|
||||
int val = G_INT(OFS_PARM1);
|
||||
int size = G_INT(OFS_PARM2);
|
||||
if (dst < 0 || dst+size >= prinst->stringtablesize)
|
||||
{
|
||||
PR_BIError(prinst, "PF_memcpy: invalid dest\n");
|
||||
return;
|
||||
}
|
||||
memset(prinst->stringtable + dst, val, size);
|
||||
}
|
||||
//memory stuff
|
||||
////////////////////////////////////////////////////
|
||||
//File access
|
||||
|
||||
#define MAX_QC_FILES 256
|
||||
|
@ -1817,8 +1858,12 @@ void QCBUILTIN PF_vtos (progfuncs_t *prinst, struct globalvars_s *pr_globals)
|
|||
RETURN_TSTRING(pr_string_temp);
|
||||
}
|
||||
|
||||
|
||||
void QCBUILTIN PF_forgetstring(progfuncs_t *prinst, struct globalvars_s *pr_globals)
|
||||
{
|
||||
#if 1
|
||||
prinst->AddressableFree(prinst, prinst->stringtable + G_INT(OFS_PARM0));
|
||||
#else
|
||||
char *s=PR_RemoveProgsString(prinst, G_INT(OFS_PARM0));
|
||||
if (!s)
|
||||
{
|
||||
|
@ -1838,7 +1883,7 @@ void QCBUILTIN PF_forgetstring(progfuncs_t *prinst, struct globalvars_s *pr_glob
|
|||
}
|
||||
((int *)s)[0] = 0xabcd1234;
|
||||
Z_TagFree(s);
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
void QCBUILTIN PF_dupstring(progfuncs_t *prinst, struct globalvars_s *pr_globals) //frik_file
|
||||
|
@ -1856,11 +1901,21 @@ void QCBUILTIN PF_dupstring(progfuncs_t *prinst, struct globalvars_s *pr_globals
|
|||
}
|
||||
len++; /*for the null*/
|
||||
|
||||
#if 1
|
||||
buf = prinst->AddressableAlloc(prinst, len);
|
||||
if (!buf)
|
||||
{
|
||||
G_INT(OFS_RETURN) = 0;
|
||||
return;
|
||||
}
|
||||
G_INT(OFS_RETURN) = (char*)buf - prinst->stringtable;
|
||||
#else
|
||||
buf = Z_TagMalloc(len+8, Z_QC_TAG);
|
||||
RETURN_SSTRING(buf+8);
|
||||
((int *)buf)[0] = PRSTR;
|
||||
((int *)buf)[1] = len;
|
||||
buf += 8;
|
||||
#endif
|
||||
|
||||
len = 0;
|
||||
for (i = 0; i < *prinst->callargc; i++)
|
||||
|
@ -3663,6 +3718,7 @@ lh_extension_t QSG_Extensions[] = {
|
|||
{"FTE_FORCEINFOKEY", 1, NULL, {"forceinfokey"}},
|
||||
{"FTE_GFX_QUAKE3SHADERS"},
|
||||
{"FTE_ISBACKBUFFERED", 1, NULL, {"isbackbuffered"}},
|
||||
{"FTE_MEMALLOC", 4, NULL, {"memalloc", "memfree", "memcpy", "memset"}},
|
||||
#ifndef NOMEDIA
|
||||
{"FTE_MEDIA_AVI"}, //playfilm supports avi files.
|
||||
{"FTE_MEDIA_CIN"}, //playfilm command supports q2 cin files.
|
||||
|
|
|
@ -298,6 +298,11 @@ void QCBUILTIN PF_bufstr_add (progfuncs_t *prinst, struct globalvars_s *pr_glob
|
|||
void QCBUILTIN PF_bufstr_free (progfuncs_t *prinst, struct globalvars_s *pr_globals);
|
||||
void QCBUILTIN PF_buf_cvarlist (progfuncs_t *prinst, struct globalvars_s *pr_globals);
|
||||
|
||||
void QCBUILTIN PF_memalloc (progfuncs_t *prinst, struct globalvars_s *pr_globals);
|
||||
void QCBUILTIN PF_memfree (progfuncs_t *prinst, struct globalvars_s *pr_globals);
|
||||
void QCBUILTIN PF_memcpy (progfuncs_t *prinst, struct globalvars_s *pr_globals);
|
||||
void QCBUILTIN PF_memset (progfuncs_t *prinst, struct globalvars_s *pr_globals);
|
||||
|
||||
void QCBUILTIN PF_calltimeofday (progfuncs_t *prinst, struct globalvars_s *pr_globals);
|
||||
|
||||
void QCBUILTIN PF_whichpack (progfuncs_t *prinst, struct globalvars_s *pr_globals);
|
||||
|
|
|
@ -114,7 +114,10 @@ public class FTEDroidActivity extends Activity
|
|||
|
||||
int sspeed = 11025;
|
||||
int speakers = 1;
|
||||
int sz = 4*AudioTrack.getMinBufferSize(sspeed, ((speakers==2)?AudioFormat.CHANNEL_CONFIGURATION_STEREO:AudioFormat.CHANNEL_CONFIGURATION_MONO), AudioFormat.ENCODING_PCM_16BIT);
|
||||
int sz = 2*AudioTrack.getMinBufferSize(sspeed, ((speakers==2)?AudioFormat.CHANNEL_CONFIGURATION_STEREO:AudioFormat.CHANNEL_CONFIGURATION_MONO), AudioFormat.ENCODING_PCM_16BIT);
|
||||
|
||||
// if (sz < sspeed * 0.05)
|
||||
// sz = sspeed * 0.05;
|
||||
|
||||
AudioTrack at = new AudioTrack(AudioManager.STREAM_MUSIC, sspeed, ((speakers==2)?AudioFormat.CHANNEL_CONFIGURATION_STEREO:AudioFormat.CHANNEL_CONFIGURATION_MONO), AudioFormat.ENCODING_PCM_16BIT, sz, AudioTrack.MODE_STREAM);
|
||||
|
||||
|
|
|
@ -16,7 +16,7 @@ void Font_BeginScaledString(struct font_s *font, float vx, float vy, float *px,
|
|||
void Font_Transform(int vx, int vy, int *px, int *py);
|
||||
int Font_CharHeight(void);
|
||||
int Font_CharWidth(unsigned int charcode);
|
||||
int Font_CharEndCoord(int x, unsigned int charcode);
|
||||
int Font_CharEndCoord(struct font_s *font, int x, unsigned int charcode);
|
||||
int Font_DrawChar(int px, int py, unsigned int charcode);
|
||||
float Font_DrawScaleChar(float px, float py, float cw, float ch, unsigned int charcode); /*avoid using*/
|
||||
void Font_EndString(struct font_s *font);
|
||||
|
@ -189,6 +189,7 @@ typedef struct font_s
|
|||
FT_Face face;
|
||||
void *membuf;
|
||||
#endif
|
||||
struct font_s *alt;
|
||||
} font_t;
|
||||
|
||||
typedef struct {
|
||||
|
@ -901,6 +902,7 @@ struct font_s *Font_LoadFont(int height, char *fontfilename)
|
|||
struct font_s *f;
|
||||
int i = 0;
|
||||
int defaultplane;
|
||||
char *aname;
|
||||
|
||||
f = Z_Malloc(sizeof(*f));
|
||||
f->charheight = height;
|
||||
|
@ -1026,6 +1028,12 @@ struct font_s *Font_LoadFont(int height, char *fontfilename)
|
|||
return f;
|
||||
}
|
||||
|
||||
aname = strstr(fontfilename, ":");
|
||||
if (aname)
|
||||
{
|
||||
*aname = 0;
|
||||
f->alt = Font_LoadFont(height, aname+1);
|
||||
}
|
||||
if (!Font_LoadFreeTypeFont(f, height, fontfilename))
|
||||
{
|
||||
if (*fontfilename)
|
||||
|
@ -1046,6 +1054,8 @@ struct font_s *Font_LoadFont(int height, char *fontfilename)
|
|||
f->chars[i].texplane = BITMAPPLANE;
|
||||
}
|
||||
}
|
||||
if (aname)
|
||||
*aname = ':';
|
||||
|
||||
defaultplane = BITMAPPLANE;/*assume the bitmap plane - don't use the fallback as people don't think to use com_parseutf8*/
|
||||
if (!TEXVALID(f->singletexture))
|
||||
|
@ -1146,17 +1156,20 @@ int Font_CharHeight(void)
|
|||
This is where the character ends.
|
||||
Note: this function supports tabs - x must always be based off 0, with Font_LineDraw actually used to draw the line.
|
||||
*/
|
||||
int Font_CharEndCoord(int x, unsigned int charcode)
|
||||
int Font_CharEndCoord(struct font_s *font, int x, unsigned int charcode)
|
||||
{
|
||||
struct charcache_s *c;
|
||||
#define TABWIDTH (8*20)
|
||||
if ((charcode&CON_CHARMASK) == '\t')
|
||||
return x + ((TABWIDTH - (x % TABWIDTH)) % TABWIDTH);
|
||||
|
||||
c = Font_GetChar(curfont, (CHARIDXTYPE)(charcode&CON_CHARMASK));
|
||||
if ((charcode & CON_2NDCHARSETTEXT) && font->alt)
|
||||
font = font->alt;
|
||||
|
||||
c = Font_GetChar(font, (CHARIDXTYPE)(charcode&CON_CHARMASK));
|
||||
if (!c)
|
||||
{
|
||||
c = Font_TryLoadGlyph(curfont, (CHARIDXTYPE)(charcode&CON_CHARMASK));
|
||||
c = Font_TryLoadGlyph(font, (CHARIDXTYPE)(charcode&CON_CHARMASK));
|
||||
if (!c)
|
||||
return x+0;
|
||||
}
|
||||
|
@ -1168,6 +1181,9 @@ int Font_CharEndCoord(int x, unsigned int charcode)
|
|||
int Font_CharWidth(unsigned int charcode)
|
||||
{
|
||||
struct charcache_s *c;
|
||||
struct font_s *font = curfont;
|
||||
if ((charcode & CON_2NDCHARSETTEXT) && font->alt)
|
||||
font = font->alt;
|
||||
|
||||
c = Font_GetChar(curfont, (CHARIDXTYPE)(charcode&CON_CHARMASK));
|
||||
if (!c)
|
||||
|
@ -1190,6 +1206,7 @@ int Font_LineBreaks(conchar_t *start, conchar_t *end, int maxpixelwidth, int max
|
|||
int l, bt;
|
||||
int px;
|
||||
int foundlines = 0;
|
||||
struct font_s *font = curfont;
|
||||
|
||||
while (start < end)
|
||||
{
|
||||
|
@ -1199,7 +1216,7 @@ int Font_LineBreaks(conchar_t *start, conchar_t *end, int maxpixelwidth, int max
|
|||
l++;
|
||||
if (start+l >= end || (start[l-1]&CON_CHARMASK) == '\n')
|
||||
break;
|
||||
px = Font_CharEndCoord(px, start[l]);
|
||||
px = Font_CharEndCoord(font, px, start[l]);
|
||||
}
|
||||
//if we did get to the end
|
||||
if (px > maxpixelwidth)
|
||||
|
@ -1234,19 +1251,21 @@ int Font_LineBreaks(conchar_t *start, conchar_t *end, int maxpixelwidth, int max
|
|||
int Font_LineWidth(conchar_t *start, conchar_t *end)
|
||||
{
|
||||
int x = 0;
|
||||
struct font_s *font = curfont;
|
||||
for (; start < end; start++)
|
||||
{
|
||||
x = Font_CharEndCoord(x, *start);
|
||||
x = Font_CharEndCoord(font, x, *start);
|
||||
}
|
||||
return x;
|
||||
}
|
||||
void Font_LineDraw(int x, int y, conchar_t *start, conchar_t *end)
|
||||
{
|
||||
int lx = 0;
|
||||
struct font_s *font = curfont;
|
||||
for (; start < end; start++)
|
||||
{
|
||||
Font_DrawChar(x+lx, y, *start);
|
||||
lx = Font_CharEndCoord(lx, *start);
|
||||
lx = Font_CharEndCoord(font, lx, *start);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1283,18 +1302,23 @@ int Font_DrawChar(int px, int py, unsigned int charcode)
|
|||
float sx, sy, sw, sh;
|
||||
int col;
|
||||
int v;
|
||||
struct font_s *font = curfont;
|
||||
if ((charcode & CON_2NDCHARSETTEXT) && font->alt)
|
||||
font = font->alt;
|
||||
|
||||
//crash if there is no current font.
|
||||
c = Font_GetChar(curfont, (CHARIDXTYPE)(charcode&CON_CHARMASK));
|
||||
c = Font_GetChar(font, (CHARIDXTYPE)(charcode&CON_CHARMASK));
|
||||
if (!c)
|
||||
{
|
||||
c = Font_TryLoadGlyph(curfont, (CHARIDXTYPE)(charcode&CON_CHARMASK));
|
||||
c = Font_TryLoadGlyph(font, (CHARIDXTYPE)(charcode&CON_CHARMASK));
|
||||
if (!c)
|
||||
return px;
|
||||
}
|
||||
|
||||
nextx = px + c->advance;
|
||||
|
||||
if ((charcode & CON_CHARMASK) == '\t')
|
||||
return px + ((TABWIDTH - (px % TABWIDTH)) % TABWIDTH);
|
||||
if ((charcode & CON_CHARMASK) == ' ')
|
||||
return nextx;
|
||||
|
||||
|
@ -1335,23 +1359,23 @@ int Font_DrawChar(int px, int py, unsigned int charcode)
|
|||
case DEFAULTPLANE:
|
||||
sx = ((px+c->left)*(int)vid.width) / (float)vid.rotpixelwidth;
|
||||
sy = ((py+c->top)*(int)vid.height) / (float)vid.rotpixelheight;
|
||||
sw = ((curfont->charheight)*vid.width) / (float)vid.rotpixelwidth;
|
||||
sh = ((curfont->charheight)*vid.height) / (float)vid.rotpixelheight;
|
||||
sw = ((font->charheight)*vid.width) / (float)vid.rotpixelwidth;
|
||||
sh = ((font->charheight)*vid.height) / (float)vid.rotpixelheight;
|
||||
v = Font_BeginChar(fontplanes.defaultfont);
|
||||
break;
|
||||
case BITMAPPLANE:
|
||||
sx = ((px+c->left)*(int)vid.width) / (float)vid.rotpixelwidth;
|
||||
sy = ((py+c->top)*(int)vid.height) / (float)vid.rotpixelheight;
|
||||
sw = ((curfont->charheight)*vid.width) / (float)vid.rotpixelwidth;
|
||||
sh = ((curfont->charheight)*vid.height) / (float)vid.rotpixelheight;
|
||||
v = Font_BeginChar(curfont->singletexture);
|
||||
sw = ((font->charheight)*vid.width) / (float)vid.rotpixelwidth;
|
||||
sh = ((font->charheight)*vid.height) / (float)vid.rotpixelheight;
|
||||
v = Font_BeginChar(font->singletexture);
|
||||
break;
|
||||
case SINGLEPLANE:
|
||||
sx = ((px+c->left)*(int)vid.width) / (float)vid.rotpixelwidth;
|
||||
sy = ((py+c->top)*(int)vid.height) / (float)vid.rotpixelheight;
|
||||
sw = ((c->bmw)*vid.width) / (float)vid.rotpixelwidth;
|
||||
sh = ((c->bmh)*vid.height) / (float)vid.rotpixelheight;
|
||||
v = Font_BeginChar(curfont->singletexture);
|
||||
v = Font_BeginChar(font->singletexture);
|
||||
break;
|
||||
default:
|
||||
sx = ((px+c->left)*(int)vid.width) / (float)vid.rotpixelwidth;
|
||||
|
@ -1402,16 +1426,19 @@ float Font_DrawScaleChar(float px, float py, float cw, float ch, unsigned int ch
|
|||
float sx, sy, sw, sh;
|
||||
int col;
|
||||
int v;
|
||||
struct font_s *font = curfont;
|
||||
if ((charcode & CON_2NDCHARSETTEXT) && font->alt)
|
||||
font = font->alt;
|
||||
|
||||
cw /= curfont->charheight;
|
||||
ch /= curfont->charheight;
|
||||
cw /= font->charheight;
|
||||
ch /= font->charheight;
|
||||
|
||||
|
||||
//crash if there is no current font.
|
||||
c = Font_GetChar(curfont, (CHARIDXTYPE)(charcode&CON_CHARMASK));
|
||||
c = Font_GetChar(font, (CHARIDXTYPE)(charcode&CON_CHARMASK));
|
||||
if (!c)
|
||||
{
|
||||
c = Font_TryLoadGlyph(curfont, (CHARIDXTYPE)(charcode&CON_CHARMASK));
|
||||
c = Font_TryLoadGlyph(font, (CHARIDXTYPE)(charcode&CON_CHARMASK));
|
||||
if (!c)
|
||||
return px;
|
||||
}
|
||||
|
@ -1457,13 +1484,13 @@ float Font_DrawScaleChar(float px, float py, float cw, float ch, unsigned int ch
|
|||
{
|
||||
sx = ((px+c->left));
|
||||
sy = ((py+c->top));
|
||||
sw = ((curfont->charheight*cw));
|
||||
sh = ((curfont->charheight*ch));
|
||||
sw = ((font->charheight*cw));
|
||||
sh = ((font->charheight*ch));
|
||||
|
||||
if (c->texplane == DEFAULTPLANE)
|
||||
v = Font_BeginChar(fontplanes.defaultfont);
|
||||
else
|
||||
v = Font_BeginChar(curfont->singletexture);
|
||||
v = Font_BeginChar(font->singletexture);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -294,7 +294,7 @@ reeval:
|
|||
|
||||
//store a value to a pointer
|
||||
case OP_STOREP_IF:
|
||||
if ((unsigned int)OPB->_int >= addressableused)
|
||||
if ((unsigned int)OPB->_int >= prinst->addressableused)
|
||||
{
|
||||
pr_xstatement = st-pr_statements;
|
||||
PR_RunError (progfuncs, "bad pointer write in %s", PR_StringToNative(progfuncs, pr_xfunction->s_name));
|
||||
|
@ -303,7 +303,7 @@ reeval:
|
|||
ptr->_float = (float)OPA->_int;
|
||||
break;
|
||||
case OP_STOREP_FI:
|
||||
if ((unsigned int)OPB->_int >= addressableused)
|
||||
if ((unsigned int)OPB->_int >= prinst->addressableused)
|
||||
{
|
||||
pr_xstatement = st-pr_statements;
|
||||
PR_RunError (progfuncs, "bad pointer write in %s", PR_StringToNative(progfuncs, pr_xfunction->s_name));
|
||||
|
@ -313,7 +313,7 @@ reeval:
|
|||
break;
|
||||
case OP_STOREP_I:
|
||||
case OP_GSTOREP_I:
|
||||
if ((unsigned int)OPB->_int >= addressableused)
|
||||
if ((unsigned int)OPB->_int >= prinst->addressableused)
|
||||
{
|
||||
pr_xstatement = st-pr_statements;
|
||||
PR_RunError (progfuncs, "bad pointer write in %s", PR_StringToNative(progfuncs, pr_xfunction->s_name));
|
||||
|
@ -331,17 +331,17 @@ reeval:
|
|||
case OP_GSTOREP_S:
|
||||
case OP_STOREP_FNC: // pointers
|
||||
case OP_GSTOREP_FNC:
|
||||
if ((unsigned int)OPB->_int >= addressableused)
|
||||
if ((unsigned int)OPB->_int >= prinst->addressableused)
|
||||
{
|
||||
pr_xstatement = st-pr_statements;
|
||||
PR_RunError (progfuncs, "bad pointer write in %s (%x >= %x)", PR_StringToNative(progfuncs, pr_xfunction->s_name), OPB->_int, addressableused);
|
||||
PR_RunError (progfuncs, "bad pointer write in %s (%x >= %x)", PR_StringToNative(progfuncs, pr_xfunction->s_name), OPB->_int, prinst->addressableused);
|
||||
}
|
||||
ptr = QCPOINTER(OPB);
|
||||
ptr->_int = OPA->_int;
|
||||
break;
|
||||
case OP_STOREP_V:
|
||||
case OP_GSTOREP_V:
|
||||
if ((unsigned int)OPB->_int >= addressableused)
|
||||
if ((unsigned int)OPB->_int >= prinst->addressableused)
|
||||
{
|
||||
pr_xstatement = st-pr_statements;
|
||||
PR_RunError (progfuncs, "bad pointer write in %s", PR_StringToNative(progfuncs, pr_xfunction->s_name));
|
||||
|
@ -353,7 +353,7 @@ reeval:
|
|||
break;
|
||||
|
||||
case OP_STOREP_C: //store character in a string
|
||||
if ((unsigned int)OPB->_int >= addressableused)
|
||||
if ((unsigned int)OPB->_int >= prinst->addressableused)
|
||||
{
|
||||
pr_xstatement = st-pr_statements;
|
||||
PR_RunError (progfuncs, "bad pointer write in %s", PR_StringToNative(progfuncs, pr_xfunction->s_name));
|
||||
|
@ -371,7 +371,7 @@ reeval:
|
|||
OPB->_vector[2] *= OPA->_float;
|
||||
break;
|
||||
case OP_MULSTOREP_F: // e.f *= f
|
||||
if ((unsigned int)OPB->_int >= addressableused)
|
||||
if ((unsigned int)OPB->_int >= prinst->addressableused)
|
||||
{
|
||||
pr_xstatement = st-pr_statements;
|
||||
PR_RunError (progfuncs, "bad pointer write in %s", PR_StringToNative(progfuncs, pr_xfunction->s_name));
|
||||
|
@ -380,7 +380,7 @@ reeval:
|
|||
OPC->_float = (ptr->_float *= OPA->_float);
|
||||
break;
|
||||
case OP_MULSTOREP_VF: // e.v *= f
|
||||
if ((unsigned int)OPB->_int >= addressableused)
|
||||
if ((unsigned int)OPB->_int >= prinst->addressableused)
|
||||
{
|
||||
pr_xstatement = st-pr_statements;
|
||||
PR_RunError (progfuncs, "bad pointer write in %s", PR_StringToNative(progfuncs, pr_xfunction->s_name));
|
||||
|
@ -395,7 +395,7 @@ reeval:
|
|||
OPB->_float /= OPA->_float;
|
||||
break;
|
||||
case OP_DIVSTOREP_F: // e.f /= f
|
||||
if ((unsigned int)OPB->_int >= addressableused)
|
||||
if ((unsigned int)OPB->_int >= prinst->addressableused)
|
||||
{
|
||||
pr_xstatement = st-pr_statements;
|
||||
PR_RunError (progfuncs, "bad pointer write in %s", PR_StringToNative(progfuncs, pr_xfunction->s_name));
|
||||
|
@ -413,7 +413,7 @@ reeval:
|
|||
OPB->_vector[2] += OPA->_vector[2];
|
||||
break;
|
||||
case OP_ADDSTOREP_F: // e.f += f
|
||||
if ((unsigned int)OPB->_int >= addressableused)
|
||||
if ((unsigned int)OPB->_int >= prinst->addressableused)
|
||||
{
|
||||
pr_xstatement = st-pr_statements;
|
||||
PR_RunError (progfuncs, "bad pointer write in %s", PR_StringToNative(progfuncs, pr_xfunction->s_name));
|
||||
|
@ -422,7 +422,7 @@ reeval:
|
|||
OPC->_float = (ptr->_float += OPA->_float);
|
||||
break;
|
||||
case OP_ADDSTOREP_V: // e.v += v
|
||||
if ((unsigned int)OPB->_int >= addressableused)
|
||||
if ((unsigned int)OPB->_int >= prinst->addressableused)
|
||||
{
|
||||
pr_xstatement = st-pr_statements;
|
||||
PR_RunError (progfuncs, "bad pointer write in %s", PR_StringToNative(progfuncs, pr_xfunction->s_name));
|
||||
|
@ -442,7 +442,7 @@ reeval:
|
|||
OPB->_vector[2] -= OPA->_vector[2];
|
||||
break;
|
||||
case OP_SUBSTOREP_F: // e.f -= f
|
||||
if ((unsigned int)OPB->_int >= addressableused)
|
||||
if ((unsigned int)OPB->_int >= prinst->addressableused)
|
||||
{
|
||||
pr_xstatement = st-pr_statements;
|
||||
PR_RunError (progfuncs, "bad pointer write in %s", PR_StringToNative(progfuncs, pr_xfunction->s_name));
|
||||
|
@ -451,7 +451,7 @@ reeval:
|
|||
OPC->_float = (ptr->_float -= OPA->_float);
|
||||
break;
|
||||
case OP_SUBSTOREP_V: // e.v -= v
|
||||
if ((unsigned int)OPB->_int >= addressableused)
|
||||
if ((unsigned int)OPB->_int >= prinst->addressableused)
|
||||
{
|
||||
pr_xstatement = st-pr_statements;
|
||||
PR_RunError (progfuncs, "bad pointer write in %s", PR_StringToNative(progfuncs, pr_xfunction->s_name));
|
||||
|
@ -818,7 +818,7 @@ reeval:
|
|||
break;
|
||||
case OP_LOADP_C: //load character from a string
|
||||
i = (unsigned int)OPA->_int + (unsigned int)OPB->_float;
|
||||
if ((unsigned int)i >= addressableused)
|
||||
if ((unsigned int)i >= prinst->addressableused)
|
||||
{
|
||||
i = (unsigned int)OPB->_float;
|
||||
ptr = (eval_t*)PR_StringToNative(progfuncs, OPA->_int);
|
||||
|
@ -840,7 +840,7 @@ reeval:
|
|||
case OP_LOADP_S:
|
||||
case OP_LOADP_FNC:
|
||||
i = OPA->_int + OPB->_int*4;
|
||||
if ((unsigned int)i >= addressableused)
|
||||
if ((unsigned int)i >= prinst->addressableused)
|
||||
{
|
||||
pr_xstatement = st-pr_statements;
|
||||
PR_RunError (progfuncs, "bad pointer read in %s", PR_StringToNative(progfuncs, pr_xfunction->s_name));
|
||||
|
@ -851,7 +851,7 @@ reeval:
|
|||
|
||||
case OP_LOADP_V:
|
||||
i = OPA->_int + OPB->_int*4;
|
||||
if ((unsigned int)i >= addressableused)
|
||||
if ((unsigned int)i >= prinst->addressableused)
|
||||
{
|
||||
pr_xstatement = st-pr_statements;
|
||||
PR_RunError (progfuncs, "bad pointer read in %s", PR_StringToNative(progfuncs, pr_xfunction->s_name));
|
||||
|
@ -914,7 +914,7 @@ reeval:
|
|||
OPB->_float = (float)((int)OPB->_float | (int)OPA->_float);
|
||||
break;
|
||||
case OP_BITSETP: // .b (+) a
|
||||
if ((unsigned int)OPB->_int >= addressableused)
|
||||
if ((unsigned int)OPB->_int >= prinst->addressableused)
|
||||
{
|
||||
pr_xstatement = st-pr_statements;
|
||||
PR_RunError (progfuncs, "bad pointer write in %s", PR_StringToNative(progfuncs, pr_xfunction->s_name));
|
||||
|
@ -926,7 +926,7 @@ reeval:
|
|||
OPB->_float = (float)((int)OPB->_float & ~((int)OPA->_float));
|
||||
break;
|
||||
case OP_BITCLRP: // .b (-) a
|
||||
if ((unsigned int)OPB->_int >= addressableused)
|
||||
if ((unsigned int)OPB->_int >= prinst->addressableused)
|
||||
{
|
||||
pr_xstatement = st-pr_statements;
|
||||
PR_RunError (progfuncs, "bad pointer write in %s", PR_StringToNative(progfuncs, pr_xfunction->s_name));
|
||||
|
|
|
@ -76,10 +76,10 @@ void PRAddressableRelocate(progfuncs_t *progfuncs, char *oldb, char *newb, int o
|
|||
//for 64bit systems. :)
|
||||
//addressable memory is memory available to the vm itself for writing.
|
||||
//once allocated, it cannot be freed for the lifetime of the VM.
|
||||
void *PRAddressableAlloc(progfuncs_t *progfuncs, int ammount)
|
||||
void *PRAddressableExtend(progfuncs_t *progfuncs, int ammount)
|
||||
{
|
||||
ammount = (ammount + 4)&~3; //round up to 4
|
||||
if (addressableused + ammount > addressablesize)
|
||||
if (prinst->addressableused + ammount > prinst->addressablesize)
|
||||
{
|
||||
/*only do this if the caller states that it can cope with addressable-block relocations/resizes*/
|
||||
if (externs->addressablerelocated)
|
||||
|
@ -89,74 +89,277 @@ void *PRAddressableAlloc(progfuncs_t *progfuncs, int ammount)
|
|||
#if 0//def _DEBUG
|
||||
int oldtot = addressablesize;
|
||||
#endif
|
||||
int newsize = (addressableused + ammount + 4096) & ~(4096-1);
|
||||
newblock = VirtualAlloc (NULL, addressablesize, MEM_RESERVE, PAGE_NOACCESS);
|
||||
int newsize = (prinst->addressableused + ammount + 4096) & ~(4096-1);
|
||||
newblock = VirtualAlloc (NULL, prinst->addressablesize, MEM_RESERVE, PAGE_NOACCESS);
|
||||
if (newblock)
|
||||
{
|
||||
VirtualAlloc (newblock, addressableused, MEM_COMMIT, PAGE_READWRITE);
|
||||
memcpy(newblock, addressablehunk, addressableused);
|
||||
VirtualAlloc (newblock, prinst->addressableused, MEM_COMMIT, PAGE_READWRITE);
|
||||
memcpy(newblock, prinst->addressablehunk, prinst->addressableused);
|
||||
#if 0//def _DEBUG
|
||||
VirtualAlloc (addressablehunk, oldtot, MEM_RESERVE, PAGE_NOACCESS);
|
||||
VirtualAlloc (prinst->addressablehunk, oldtot, MEM_RESERVE, PAGE_NOACCESS);
|
||||
#else
|
||||
VirtualFree (addressablehunk, 0, MEM_RELEASE);
|
||||
VirtualFree (prinst->addressablehunk, 0, MEM_RELEASE);
|
||||
#endif
|
||||
PRAddressableRelocate(progfuncs, addressablehunk, newblock, addressableused);
|
||||
addressablehunk = newblock;
|
||||
addressablesize = newsize;
|
||||
PRAddressableRelocate(progfuncs, prinst->addressablehunk, newblock, prinst->addressableused);
|
||||
prinst->addressablehunk = newblock;
|
||||
prinst->addressablesize = newsize;
|
||||
}
|
||||
#else
|
||||
char *newblock;
|
||||
int newsize = (addressableused + ammount + 1024*1024) & ~(1024*1024-1);
|
||||
newblock = realloc(newblock, addressablesize);
|
||||
int newsize = (prinst->addressableused + ammount + 1024*1024) & ~(1024*1024-1);
|
||||
newblock = realloc(newblock, prinst->addressablesize);
|
||||
if (newblock)
|
||||
{
|
||||
PRAddressableRelocate(progfuncs, addressablehunk, newblock, addressableused);
|
||||
addressablehunk = newblock;
|
||||
addressablesize = newsize;
|
||||
PRAddressableRelocate(progfuncs, prinst->addressablehunk, newblock, prinst->addressableused);
|
||||
prinst->addressablehunk = newblock;
|
||||
prinst->addressablesize = newsize;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
if (addressableused + ammount > addressablesize)
|
||||
if (prinst->addressableused + ammount > prinst->addressablesize)
|
||||
Sys_Error("Not enough addressable memory for progs VM");
|
||||
}
|
||||
|
||||
addressableused += ammount;
|
||||
prinst->addressableused += ammount;
|
||||
|
||||
#ifdef _WIN32
|
||||
if (!VirtualAlloc (addressablehunk, addressableused, MEM_COMMIT, PAGE_READWRITE))
|
||||
if (!VirtualAlloc (prinst->addressablehunk, prinst->addressableused, MEM_COMMIT, PAGE_READWRITE))
|
||||
Sys_Error("VirtualAlloc failed. Blame windows.");
|
||||
#endif
|
||||
|
||||
return &addressablehunk[addressableused-ammount];
|
||||
return &prinst->addressablehunk[prinst->addressableused-ammount];
|
||||
}
|
||||
|
||||
|
||||
#define MARKER 0xF1E3E3E7u
|
||||
typedef struct
|
||||
{
|
||||
unsigned int next;
|
||||
unsigned int prev;
|
||||
unsigned int size;
|
||||
} qcmemfreeblock_t;
|
||||
typedef struct
|
||||
{
|
||||
unsigned int marker;
|
||||
unsigned int size;
|
||||
} qcmemusedblock_t;
|
||||
static void PF_fmem_unlink(progfuncs_t *pr, qcmemfreeblock_t *p)
|
||||
{
|
||||
qcmemfreeblock_t *np;
|
||||
if (p->prev)
|
||||
{
|
||||
np = (qcmemfreeblock_t*)(pr->stringtable + p->prev);
|
||||
np->next = p->next;
|
||||
}
|
||||
else
|
||||
pr->inst->mfreelist = p->next;
|
||||
if (p->next)
|
||||
{
|
||||
np = (qcmemfreeblock_t*)(pr->stringtable + p->next);
|
||||
np->prev = p->prev;
|
||||
}
|
||||
}
|
||||
static void *PR_memalloc (progfuncs_t *progfuncs, unsigned int size)
|
||||
{
|
||||
qcmemfreeblock_t *p, *np;
|
||||
qcmemusedblock_t *ub = NULL;
|
||||
unsigned int b,n;
|
||||
/*round size up*/
|
||||
size = (size+sizeof(qcmemusedblock_t) + 63) & ~63;
|
||||
|
||||
b = prinst->mfreelist;
|
||||
while (b)
|
||||
{
|
||||
if (b < 0 || b >= prinst->addressableused)
|
||||
{
|
||||
printf("PF_memalloc: memory corruption\n");
|
||||
PR_StackTrace(progfuncs);
|
||||
return NULL;
|
||||
}
|
||||
p = (qcmemfreeblock_t*)(progfuncs->stringtable + b);
|
||||
if (p->size >= size)
|
||||
{
|
||||
if (p->next && p->next < b + p->size ||
|
||||
p->next >= prinst->addressableused ||
|
||||
b + p->size >= prinst->addressableused ||
|
||||
p->prev >= b)
|
||||
{
|
||||
printf("PF_memalloc: memory corruption\n");
|
||||
PR_StackTrace(progfuncs);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ub = (qcmemusedblock_t*)p;
|
||||
if (p->size > size + 63)
|
||||
{
|
||||
/*make a new header just after it, with basically the same properties, and shift the important fields over*/
|
||||
n = b + size;
|
||||
np = (qcmemfreeblock_t*)(progfuncs->stringtable + b + size);
|
||||
np->prev = p->prev;
|
||||
np->next = p->next;
|
||||
np->size = p->size - size;
|
||||
if (np->prev)
|
||||
{
|
||||
p = (qcmemfreeblock_t*)(progfuncs->stringtable + np->prev);
|
||||
p->next = n;
|
||||
}
|
||||
else
|
||||
prinst->mfreelist = n;
|
||||
if (p->next)
|
||||
{
|
||||
p = (qcmemfreeblock_t*)(progfuncs->stringtable + np->next);
|
||||
p->prev = n;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
size = p->size; /*alloc the entire block*/
|
||||
/*unlink this entry*/
|
||||
PF_fmem_unlink(progfuncs, p);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*assign more space*/
|
||||
if (!ub)
|
||||
{
|
||||
ub = PRAddressableExtend(progfuncs, size);
|
||||
if (!ub)
|
||||
{
|
||||
printf("PF_memalloc: memory exausted\n");
|
||||
PR_StackTrace(progfuncs);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
memset(ub, 0, size);
|
||||
ub->marker = MARKER;
|
||||
ub->size = size;
|
||||
return ub+1;
|
||||
}
|
||||
static void PR_memfree (progfuncs_t *progfuncs, void *memptr)
|
||||
{
|
||||
qcmemusedblock_t *ub;
|
||||
qcmemfreeblock_t *p, *np;
|
||||
unsigned int l, ln;
|
||||
unsigned int size;
|
||||
unsigned int ptr = memptr?((char*)memptr - progfuncs->stringtable):0;
|
||||
|
||||
/*freeing NULL is ignored*/
|
||||
if (!ptr)
|
||||
return;
|
||||
if (ptr < sizeof(qcmemusedblock_t) || ptr >= prinst->addressableused)
|
||||
{
|
||||
printf("PF_memfree: pointer invalid - out of range (%u >= %u)\n", ptr, prinst->addressableused);
|
||||
PR_StackTrace(progfuncs);
|
||||
return;
|
||||
}
|
||||
|
||||
ub = (qcmemusedblock_t*)(progfuncs->stringtable + ptr);
|
||||
ub--;
|
||||
ptr = (char*)ub - progfuncs->stringtable;
|
||||
if (ub->marker != MARKER || ub->size <= sizeof(*ub) || ptr + ub->size > (unsigned int)prinst->addressableused)
|
||||
{
|
||||
printf("PF_memfree: memory corruption or double free\n");
|
||||
PR_StackTrace(progfuncs);
|
||||
return;
|
||||
}
|
||||
ub->marker = 0;
|
||||
size = ub->size;
|
||||
|
||||
for (ln = prinst->mfreelist, l = 0; ;)
|
||||
{
|
||||
if (ln < 0 || ln >= prinst->addressableused)
|
||||
{
|
||||
printf("PF_memfree: memory corruption\n");
|
||||
PR_StackTrace(progfuncs);
|
||||
return;
|
||||
}
|
||||
if (!ln || ln >= ptr)
|
||||
{
|
||||
np = (qcmemfreeblock_t*)(progfuncs->stringtable + l);
|
||||
if (l && l+np->size>ptr)
|
||||
{
|
||||
printf("PF_memfree: double free\n");
|
||||
PR_StackTrace(progfuncs);
|
||||
return;
|
||||
}
|
||||
|
||||
/*generate the free block, now we know its proper values*/
|
||||
p = (qcmemfreeblock_t*)(progfuncs->stringtable + ptr);
|
||||
p->prev = l;
|
||||
p->next = ln;
|
||||
p->size = size;
|
||||
|
||||
/*update the next's previous*/
|
||||
if (p->next)
|
||||
{
|
||||
np = (qcmemfreeblock_t*)(progfuncs->stringtable + p->next);
|
||||
np->prev = p->prev;
|
||||
|
||||
/*extend this block and kill the next if they are adjacent*/
|
||||
if (p->next == ptr + size)
|
||||
{
|
||||
p->size += np->size;
|
||||
PF_fmem_unlink(progfuncs, np);
|
||||
}
|
||||
}
|
||||
|
||||
/*update the link to get here*/
|
||||
if (!l)
|
||||
prinst->mfreelist = ptr;
|
||||
else
|
||||
{
|
||||
np = (qcmemfreeblock_t*)(progfuncs->stringtable + l);
|
||||
np->next = ptr;
|
||||
|
||||
/*we're adjacent to the previous block, so merge them by killing the newly freed region*/
|
||||
if (l + np->size == ptr)
|
||||
{
|
||||
np->size += size;
|
||||
PF_fmem_unlink(progfuncs, p);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
l = ln;
|
||||
p = (qcmemfreeblock_t*)(progfuncs->stringtable + l);
|
||||
ln = p->next;
|
||||
}
|
||||
}
|
||||
|
||||
void PRAddressableFlush(progfuncs_t *progfuncs, int totalammount)
|
||||
{
|
||||
addressableused = 0;
|
||||
prinst->addressableused = 0;
|
||||
if (totalammount < 0) //flush
|
||||
{
|
||||
totalammount = addressablesize;
|
||||
totalammount = prinst->addressablesize;
|
||||
// return;
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
if (addressablehunk && addressablesize != totalammount)
|
||||
if (prinst->addressablehunk && prinst->addressablesize != totalammount)
|
||||
{
|
||||
VirtualFree(addressablehunk, 0, MEM_RELEASE); //doesn't this look complicated? :p
|
||||
addressablehunk = NULL;
|
||||
VirtualFree(prinst->addressablehunk, 0, MEM_RELEASE); //doesn't this look complicated? :p
|
||||
prinst->addressablehunk = NULL;
|
||||
}
|
||||
if (!addressablehunk)
|
||||
addressablehunk = VirtualAlloc (addressablehunk, totalammount, MEM_RESERVE, PAGE_NOACCESS);
|
||||
if (!prinst->addressablehunk)
|
||||
prinst->addressablehunk = VirtualAlloc (prinst->addressablehunk, totalammount, MEM_RESERVE, PAGE_NOACCESS);
|
||||
#else
|
||||
if (addressablehunk)
|
||||
free(addressablehunk);
|
||||
addressablehunk = malloc(totalammount); //linux will allocate-on-use anyway, which is handy.
|
||||
// memset(addressablehunk, 0xff, totalammount);
|
||||
if (prinst->addressablehunk && prinst->addressablesize != totalammount)
|
||||
{
|
||||
free(prinst->addressablehunk);
|
||||
prinst->addressablehunk = NULL;
|
||||
}
|
||||
if (!prinst->addressablehunk)
|
||||
prinst->addressablehunk = malloc(totalammount); //linux will allocate-on-use anyway, which is handy.
|
||||
// memset(prinst->addressablehunk, 0xff, totalammount);
|
||||
#endif
|
||||
if (!addressablehunk)
|
||||
if (!prinst->addressablehunk)
|
||||
Sys_Error("Out of memory\n");
|
||||
addressablesize = totalammount;
|
||||
prinst->addressablesize = totalammount;
|
||||
}
|
||||
|
||||
int PR_InitEnts(progfuncs_t *progfuncs, int max_ents)
|
||||
|
@ -170,7 +373,7 @@ int PR_InitEnts(progfuncs_t *progfuncs, int max_ents)
|
|||
prinst->edicttable = PRHunkAlloc(progfuncs, maxedicts*sizeof(struct edicts_s *));
|
||||
sv_edicts = PRHunkAlloc(progfuncs, externs->edictsize);
|
||||
prinst->edicttable[0] = sv_edicts;
|
||||
((edictrun_t*)prinst->edicttable[0])->fields = PRAddressableAlloc(progfuncs, max_fields_size);
|
||||
((edictrun_t*)prinst->edicttable[0])->fields = PRAddressableExtend(progfuncs, max_fields_size);
|
||||
QC_ClearEdict(progfuncs, sv_edicts);
|
||||
sv_num_edicts = 1;
|
||||
|
||||
|
@ -505,7 +708,7 @@ string_t PR_StringToProgs (progfuncs_t *progfuncs, char *str)
|
|||
if (!str)
|
||||
return 0;
|
||||
|
||||
if (str >= progfuncs->stringtable && str < progfuncs->stringtable + addressableused)
|
||||
if (str >= progfuncs->stringtable && str < progfuncs->stringtable + prinst->addressableused)
|
||||
return str - progfuncs->stringtable;
|
||||
|
||||
for (i = prinst->numallocedstrings-1; i >= 0; i--)
|
||||
|
@ -615,7 +818,7 @@ char *ASMCALL PR_StringToNative (progfuncs_t *progfuncs, string_t str)
|
|||
}
|
||||
}
|
||||
|
||||
if (str >= addressableused)
|
||||
if ((unsigned int)str >= (unsigned int)prinst->addressableused)
|
||||
{
|
||||
printf("invalid string offset %x\n", str);
|
||||
PR_StackTrace(progfuncs);
|
||||
|
@ -803,8 +1006,9 @@ progfuncs_t deffuncs = {
|
|||
PR_QueryField,
|
||||
QC_ClearEdict,
|
||||
QC_FindPrefixedGlobals,
|
||||
PRAddressableAlloc,
|
||||
PR_AllocTempStringLen
|
||||
PR_memalloc,
|
||||
PR_AllocTempStringLen,
|
||||
PR_memfree,
|
||||
};
|
||||
#undef printf
|
||||
|
||||
|
@ -859,6 +1063,7 @@ progexterns_t defexterns = {
|
|||
#undef extensionbuiltin
|
||||
#undef field
|
||||
#undef shares
|
||||
#undef maxedicts
|
||||
#undef sv_num_edicts
|
||||
|
||||
|
||||
|
@ -875,10 +1080,10 @@ void CloseProgs(progfuncs_t *inst)
|
|||
|
||||
f = inst->parms->memfree;
|
||||
|
||||
for ( i=1 ; i<inst->maxedicts; i++)
|
||||
for ( i=1 ; i<inst->inst->maxedicts; i++)
|
||||
{
|
||||
e = (edictrun_t *)(inst->prinst->edicttable[i]);
|
||||
inst->prinst->edicttable[i] = NULL;
|
||||
e = (edictrun_t *)(inst->inst->edicttable[i]);
|
||||
inst->inst->edicttable[i] = NULL;
|
||||
if (e)
|
||||
{
|
||||
// e->entnum = i;
|
||||
|
@ -889,17 +1094,17 @@ void CloseProgs(progfuncs_t *inst)
|
|||
PRHunkFree(inst, 0);
|
||||
|
||||
#ifdef _WIN32
|
||||
VirtualFree(inst->addressablehunk, 0, MEM_RELEASE); //doesn't this look complicated? :p
|
||||
VirtualFree(inst->inst->addressablehunk, 0, MEM_RELEASE); //doesn't this look complicated? :p
|
||||
#else
|
||||
free(inst->addressablehunk);
|
||||
free(inst->inst->addressablehunk);
|
||||
#endif
|
||||
|
||||
if (inst->prinst->allocedstrings)
|
||||
f(inst->prinst->allocedstrings);
|
||||
inst->prinst->allocedstrings = NULL;
|
||||
if (inst->prinst->tempstrings)
|
||||
f(inst->prinst->tempstrings);
|
||||
inst->prinst->tempstrings = NULL;
|
||||
if (inst->inst->allocedstrings)
|
||||
f(inst->inst->allocedstrings);
|
||||
inst->inst->allocedstrings = NULL;
|
||||
if (inst->inst->tempstrings)
|
||||
f(inst->inst->tempstrings);
|
||||
inst->inst->tempstrings = NULL;
|
||||
|
||||
|
||||
/*
|
||||
|
@ -910,11 +1115,11 @@ void CloseProgs(progfuncs_t *inst)
|
|||
inst->prinst->extensionbuiltin = eb;
|
||||
}
|
||||
*/
|
||||
if (inst->prinst->field)
|
||||
f(inst->prinst->field);
|
||||
if (inst->prinst->shares)
|
||||
f(inst->prinst->shares); //free memory
|
||||
f(inst->prinst);
|
||||
if (inst->inst->field)
|
||||
f(inst->inst->field);
|
||||
if (inst->inst->shares)
|
||||
f(inst->inst->shares); //free memory
|
||||
f(inst->inst);
|
||||
f(inst);
|
||||
}
|
||||
|
||||
|
@ -955,15 +1160,17 @@ progfuncs_t * InitProgs(progexterns_t *ext)
|
|||
}
|
||||
#undef memalloc
|
||||
#undef pr_trace
|
||||
#undef pr_progstate
|
||||
#undef pr_argc
|
||||
funcs = ext->memalloc(sizeof(progfuncs_t));
|
||||
memcpy(funcs, &deffuncs, sizeof(progfuncs_t));
|
||||
|
||||
funcs->prinst = ext->memalloc(sizeof(prinst_t));
|
||||
memset(funcs->prinst,0, sizeof(prinst_t));
|
||||
funcs->inst = ext->memalloc(sizeof(prinst_t));
|
||||
memset(funcs->inst,0, sizeof(prinst_t));
|
||||
|
||||
funcs->pr_trace = &funcs->prinst->pr_trace;
|
||||
funcs->progstate = &funcs->pr_progstate;
|
||||
funcs->callargc = &funcs->pr_argc;
|
||||
funcs->pr_trace = &funcs->inst->pr_trace;
|
||||
funcs->progstate = &funcs->inst->progstate;
|
||||
funcs->callargc = &funcs->inst->pr_argc;
|
||||
|
||||
funcs->parms = ext;
|
||||
|
||||
|
|
|
@ -38,7 +38,7 @@ edictrun_t *ED_AllocIntoTable (progfuncs_t *progfuncs, int num)
|
|||
|
||||
prinst->edicttable[num] = *(struct edict_s **)&e = (void*)memalloc(externs->edictsize);
|
||||
memset(e, 0, externs->edictsize);
|
||||
e->fields = PRAddressableAlloc(progfuncs, fields_size);
|
||||
e->fields = PRAddressableExtend(progfuncs, fields_size);
|
||||
e->entnum = num;
|
||||
QC_ClearEdict(progfuncs, (struct edict_s*)e);
|
||||
|
||||
|
@ -996,7 +996,10 @@ char *ED_NewString (progfuncs_t *progfuncs, char *string, int minlength)
|
|||
|
||||
l = strlen(string) + 1;
|
||||
|
||||
newc = PRAddressableAlloc (progfuncs, l<minlength?minlength:l);
|
||||
newc = progfuncs->AddressableAlloc (progfuncs, l<minlength?minlength:l);
|
||||
if (!newc)
|
||||
return progfuncs->stringtable;
|
||||
|
||||
new_p = newc;
|
||||
|
||||
for (i=0 ; i< l ; i++)
|
||||
|
@ -2586,12 +2589,12 @@ retry:
|
|||
}
|
||||
|
||||
len=sizeof(char)*pr_progs->numstrings;
|
||||
s = PRAddressableAlloc(progfuncs, len);
|
||||
s = PRAddressableExtend(progfuncs, len);
|
||||
memcpy(s, pr_strings, len);
|
||||
pr_strings = (char *)s;
|
||||
|
||||
len=sizeof(float)*pr_progs->numglobals;
|
||||
s = PRAddressableAlloc(progfuncs, len);
|
||||
s = PRAddressableExtend(progfuncs, len);
|
||||
memcpy(s, pr_globals, len);
|
||||
glob = pr_globals = (float *)s;
|
||||
|
||||
|
|
|
@ -46,7 +46,7 @@ typedef unsigned char qbyte;
|
|||
|
||||
//extern progfuncs_t *progfuncs;
|
||||
|
||||
#define prinst progfuncs->prinst
|
||||
#define prinst progfuncs->inst
|
||||
#define externs progfuncs->parms
|
||||
|
||||
#include "pr_comp.h"
|
||||
|
@ -87,7 +87,7 @@ extern QCC_opcode_t pr_opcodes[]; // sized by initialization
|
|||
int PRHunkMark(progfuncs_t *progfuncs);
|
||||
void PRHunkFree(progfuncs_t *progfuncs, int mark);
|
||||
void *PRHunkAlloc(progfuncs_t *progfuncs, int size);
|
||||
void *PRAddressableAlloc(progfuncs_t *progfuncs, int ammount);
|
||||
void *PRAddressableExtend(progfuncs_t *progfuncs, int ammount);
|
||||
|
||||
#ifdef printf
|
||||
#undef LIKEPRINTF
|
||||
|
@ -432,12 +432,10 @@ var(unsigned int, max_fields_size);
|
|||
|
||||
|
||||
//initlib.c
|
||||
int mfreelist;
|
||||
var(char *, addressablehunk);
|
||||
#define addressablehunk prinst->addressablehunk
|
||||
var(unsigned int, addressableused);
|
||||
#define addressableused prinst->addressableused
|
||||
var(unsigned int, addressablesize);
|
||||
#define addressablesize prinst->addressablesize
|
||||
|
||||
|
||||
//var(extensionbuiltin_t *, extensionbuiltin);
|
||||
|
|
|
@ -109,7 +109,7 @@ struct progfuncs_s {
|
|||
pbool (*Decompile) (progfuncs_t *prinst, char *fname);
|
||||
|
||||
|
||||
struct prinst_s *prinst; //internal variables. Leave alone.
|
||||
struct prinst_s *inst; //internal variables. Leave alone.
|
||||
|
||||
int *callargc; //number of args of built-in call
|
||||
void (*RegisterBuiltin) (progfuncs_t *prinst, char *, builtin_t);
|
||||
|
@ -139,9 +139,10 @@ struct progfuncs_s {
|
|||
void (*EntClear) (progfuncs_t *progfuncs, struct edict_s *e);
|
||||
void (*FindPrefixGlobals) (progfuncs_t *progfuncs, char *prefix, void (*found) (progfuncs_t *progfuncs, char *name, union eval_s *val, etype_t type) );
|
||||
|
||||
void *(*AddressableAlloc) (progfuncs_t *progfuncs, int ammount); /*returns memory within the qc block, use stringtoprogs to get a usable qc pointer/string*/
|
||||
void *(*AddressableAlloc) (progfuncs_t *progfuncs, unsigned int ammount); /*returns memory within the qc block, use stringtoprogs to get a usable qc pointer/string*/
|
||||
|
||||
string_t (*AllocTempString) (progfuncs_t *prinst, char **str, unsigned int len);
|
||||
void (*AddressableFree) (progfuncs_t *progfuncs, void *mem); /*frees a block of addressable memory*/
|
||||
};
|
||||
|
||||
typedef struct progexterns_s {
|
||||
|
|
|
@ -8938,6 +8938,12 @@ BuiltinList_t BuiltinList[] = { //nq qw h2 ebfs
|
|||
{"skel_mmap", PF_skel_mmap, 0, 0, 0, 282, "float*(float skel)"},// (FTE_QC_RAGDOLL)
|
||||
{"skel_set_bone_world",PF_skel_set_bone_world,0,0, 0, 283, "void(entity ent, float bonenum, vector org, optional vector angorfwd, optional vector right, optional vector up)"},
|
||||
|
||||
{"memalloc", PF_memalloc, 0, 0, 0, 384, "void*(int size)"},
|
||||
{"memfree", PF_memfree, 0, 0, 0, 385, "void(void *ptr)"},
|
||||
{"memcpy", PF_memcpy, 0, 0, 0, 386, "void(void *dst, void *src, int size)"},
|
||||
{"memset", PF_memset, 0, 0, 0, 387, "void(void *dst, int val, int size)"},
|
||||
|
||||
|
||||
// {"cvar_setlatch", PF_cvar_setlatch, 0, 0, 0, 284, "void(string cvarname, optional string value)"}, //72
|
||||
|
||||
|
||||
|
|
Loading…
Reference in a new issue